xref: /rk3399_ARM-atf/plat/xilinx/versal/pm_service/pm_client.c (revision fbb32695a27536818004e60772bd4240ae3cec1b)
1c73a90e5STejas Patel /*
2c73a90e5STejas Patel  * Copyright (c) 2019, Xilinx, Inc. All rights reserved.
3c73a90e5STejas Patel  *
4c73a90e5STejas Patel  * SPDX-License-Identifier: BSD-3-Clause
5c73a90e5STejas Patel  */
6c73a90e5STejas Patel 
7c73a90e5STejas Patel /*
8c73a90e5STejas Patel  * APU specific definition of processors in the subsystem as well as functions
9c73a90e5STejas Patel  * for getting information about and changing state of the APU.
10c73a90e5STejas Patel  */
11c73a90e5STejas Patel 
12c73a90e5STejas Patel #include <plat_ipi.h>
13c73a90e5STejas Patel #include <platform_def.h>
14c73a90e5STejas Patel #include <versal_def.h>
15c73a90e5STejas Patel #include <lib/bakery_lock.h>
16*fbb32695STejas Patel #include <lib/mmio.h>
17*fbb32695STejas Patel #include <drivers/arm/gicv3.h>
18*fbb32695STejas Patel #include <plat/common/platform.h>
19c73a90e5STejas Patel #include "pm_client.h"
20c73a90e5STejas Patel 
21c73a90e5STejas Patel DEFINE_BAKERY_LOCK(pm_client_secure_lock);
22c73a90e5STejas Patel 
23c73a90e5STejas Patel static const struct pm_ipi apu_ipi = {
24c73a90e5STejas Patel 	.local_ipi_id = IPI_ID_APU,
25c73a90e5STejas Patel 	.remote_ipi_id = IPI_ID_PMC,
26c73a90e5STejas Patel 	.buffer_base = IPI_BUFFER_APU_BASE,
27c73a90e5STejas Patel };
28c73a90e5STejas Patel 
29c73a90e5STejas Patel /* Order in pm_procs_all array must match cpu ids */
30c73a90e5STejas Patel static const struct pm_proc pm_procs_all[] = {
31c73a90e5STejas Patel 	{
32c73a90e5STejas Patel 		.node_id = XPM_DEVID_ACPU_0,
33c73a90e5STejas Patel 		.ipi = &apu_ipi,
34*fbb32695STejas Patel 		.pwrdn_mask = APU_0_PWRCTL_CPUPWRDWNREQ_MASK,
35c73a90e5STejas Patel 	},
36c73a90e5STejas Patel 	{
37c73a90e5STejas Patel 		.node_id = XPM_DEVID_ACPU_1,
38c73a90e5STejas Patel 		.ipi = &apu_ipi,
39*fbb32695STejas Patel 		.pwrdn_mask = APU_1_PWRCTL_CPUPWRDWNREQ_MASK,
40c73a90e5STejas Patel 	}
41c73a90e5STejas Patel };
42c73a90e5STejas Patel 
43c73a90e5STejas Patel const struct pm_proc *primary_proc = &pm_procs_all[0];
44*fbb32695STejas Patel 
45*fbb32695STejas Patel /**
46*fbb32695STejas Patel  * pm_client_suspend() - Client-specific suspend actions
47*fbb32695STejas Patel  *
48*fbb32695STejas Patel  * This function should contain any PU-specific actions
49*fbb32695STejas Patel  * required prior to sending suspend request to PMU
50*fbb32695STejas Patel  * Actions taken depend on the state system is suspending to.
51*fbb32695STejas Patel  */
52*fbb32695STejas Patel void pm_client_suspend(const struct pm_proc *proc, unsigned int state)
53*fbb32695STejas Patel {
54*fbb32695STejas Patel 	bakery_lock_get(&pm_client_secure_lock);
55*fbb32695STejas Patel 
56*fbb32695STejas Patel 	/* Set powerdown request */
57*fbb32695STejas Patel 	mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) |
58*fbb32695STejas Patel 		      proc->pwrdn_mask);
59*fbb32695STejas Patel 
60*fbb32695STejas Patel 	bakery_lock_release(&pm_client_secure_lock);
61*fbb32695STejas Patel }
62*fbb32695STejas Patel 
63*fbb32695STejas Patel /**
64*fbb32695STejas Patel  * pm_client_abort_suspend() - Client-specific abort-suspend actions
65*fbb32695STejas Patel  *
66*fbb32695STejas Patel  * This function should contain any PU-specific actions
67*fbb32695STejas Patel  * required for aborting a prior suspend request
68*fbb32695STejas Patel  */
69*fbb32695STejas Patel void pm_client_abort_suspend(void)
70*fbb32695STejas Patel {
71*fbb32695STejas Patel 	/* Enable interrupts at processor level (for current cpu) */
72*fbb32695STejas Patel 	gicv3_cpuif_enable(plat_my_core_pos());
73*fbb32695STejas Patel 
74*fbb32695STejas Patel 	bakery_lock_get(&pm_client_secure_lock);
75*fbb32695STejas Patel 
76*fbb32695STejas Patel 	/* Clear powerdown request */
77*fbb32695STejas Patel 	mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) &
78*fbb32695STejas Patel 		      ~primary_proc->pwrdn_mask);
79*fbb32695STejas Patel 
80*fbb32695STejas Patel 	bakery_lock_release(&pm_client_secure_lock);
81*fbb32695STejas Patel }
82*fbb32695STejas Patel 
83*fbb32695STejas Patel /**
84*fbb32695STejas Patel  * pm_get_proc() - returns pointer to the proc structure
85*fbb32695STejas Patel  * @cpuid:	id of the cpu whose proc struct pointer should be returned
86*fbb32695STejas Patel  *
87*fbb32695STejas Patel  * Return: pointer to a proc structure if proc is found, otherwise NULL
88*fbb32695STejas Patel  */
89*fbb32695STejas Patel const struct pm_proc *pm_get_proc(unsigned int cpuid)
90*fbb32695STejas Patel {
91*fbb32695STejas Patel 	if (cpuid < ARRAY_SIZE(pm_procs_all))
92*fbb32695STejas Patel 		return &pm_procs_all[cpuid];
93*fbb32695STejas Patel 
94*fbb32695STejas Patel 	return NULL;
95*fbb32695STejas Patel }
96