blob: ccbfe770dd085596f5b2bd4195b3993e84f8ceea [file] [log] [blame]
Tejas Patel354fe572018-12-14 00:55:37 -08001/*
Tanmay Shahb145e122022-03-23 12:43:45 -07002 * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
Jay Buddhabhatti6a44ad02023-02-28 01:23:04 -08003 * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
Tejas Patel354fe572018-12-14 00:55:37 -08004 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8/*
9 * APU specific definition of processors in the subsystem as well as functions
10 * for getting information about and changing state of the APU.
11 */
12
Tejas Patelfcb7c162019-02-27 18:44:56 +053013#include <assert.h>
Prasad Kummari536e1102023-06-22 10:50:02 +053014
15#include <drivers/arm/gic_common.h>
16#include <drivers/arm/gicv3.h>
Tejas Patel354fe572018-12-14 00:55:37 -080017#include <lib/bakery_lock.h>
Tejas Patelfe0e10a2019-12-08 23:29:44 -080018#include <lib/mmio.h>
Tejas Patelfcb7c162019-02-27 18:44:56 +053019#include <lib/utils.h>
Tejas Patelfe0e10a2019-12-08 23:29:44 -080020#include <plat/common/platform.h>
Prasad Kummari536e1102023-06-22 10:50:02 +053021
22#include <plat_ipi.h>
23#include <platform_def.h>
Tejas Patelfcb7c162019-02-27 18:44:56 +053024#include "pm_api_sys.h"
Tejas Patel354fe572018-12-14 00:55:37 -080025#include "pm_client.h"
Tanmay Shahb145e122022-03-23 12:43:45 -070026#include "pm_defs.h"
Prasad Kummari536e1102023-06-22 10:50:02 +053027#include <versal_def.h>
Tejas Patel354fe572018-12-14 00:55:37 -080028
Tejas Patel7029dd82019-02-27 18:44:54 +053029#define UNDEFINED_CPUID (~0)
30
Tejas Patel354fe572018-12-14 00:55:37 -080031DEFINE_BAKERY_LOCK(pm_client_secure_lock);
32
33static const struct pm_ipi apu_ipi = {
Michal Simek3a63f052023-04-25 14:21:20 +020034 .local_ipi_id = IPI_LOCAL_ID,
35 .remote_ipi_id = IPI_REMOTE_ID,
Michal Simek9a8da502023-04-25 14:04:02 +020036 .buffer_base = IPI_BUFFER_LOCAL_BASE,
Tejas Patel354fe572018-12-14 00:55:37 -080037};
38
39/* Order in pm_procs_all array must match cpu ids */
40static const struct pm_proc pm_procs_all[] = {
41 {
42 .node_id = XPM_DEVID_ACPU_0,
43 .ipi = &apu_ipi,
Tejas Patelfe0e10a2019-12-08 23:29:44 -080044 .pwrdn_mask = APU_0_PWRCTL_CPUPWRDWNREQ_MASK,
Tejas Patel354fe572018-12-14 00:55:37 -080045 },
46 {
47 .node_id = XPM_DEVID_ACPU_1,
48 .ipi = &apu_ipi,
Tejas Patelfe0e10a2019-12-08 23:29:44 -080049 .pwrdn_mask = APU_1_PWRCTL_CPUPWRDWNREQ_MASK,
Tejas Patel354fe572018-12-14 00:55:37 -080050 }
51};
52
53const struct pm_proc *primary_proc = &pm_procs_all[0];
Tejas Patelfe0e10a2019-12-08 23:29:44 -080054
Tejas Patelfcb7c162019-02-27 18:44:56 +053055/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +053056 * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number.
57 * @irq: Interrupt number
Tejas Patelfcb7c162019-02-27 18:44:56 +053058 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +053059 * Return: PM node index corresponding to the specified interrupt.
60 *
Tejas Patelfcb7c162019-02-27 18:44:56 +053061 */
Jay Buddhabhattia63b3542023-02-28 02:22:02 -080062enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
Tejas Patelfcb7c162019-02-27 18:44:56 +053063{
Jay Buddhabhattic06a2712022-12-22 22:27:01 -080064 enum pm_device_node_idx dev_idx = XPM_NODEIDX_DEV_MIN;
65
Tejas Patelfcb7c162019-02-27 18:44:56 +053066 assert(irq <= IRQ_MAX);
Jay Buddhabhattic06a2712022-12-22 22:27:01 -080067
68 switch (irq) {
69 case 13:
70 dev_idx = XPM_NODEIDX_DEV_GPIO;
71 break;
72 case 14:
73 dev_idx = XPM_NODEIDX_DEV_I2C_0;
74 break;
75 case 15:
76 dev_idx = XPM_NODEIDX_DEV_I2C_1;
77 break;
78 case 16:
79 dev_idx = XPM_NODEIDX_DEV_SPI_0;
80 break;
81 case 17:
82 dev_idx = XPM_NODEIDX_DEV_SPI_1;
83 break;
84 case 18:
85 dev_idx = XPM_NODEIDX_DEV_UART_0;
86 break;
87 case 19:
88 dev_idx = XPM_NODEIDX_DEV_UART_1;
89 break;
90 case 20:
91 dev_idx = XPM_NODEIDX_DEV_CAN_FD_0;
92 break;
93 case 21:
94 dev_idx = XPM_NODEIDX_DEV_CAN_FD_1;
95 break;
96 case 22:
97 case 23:
98 case 24:
99 case 25:
100 case 26:
101 dev_idx = XPM_NODEIDX_DEV_USB_0;
102 break;
103 case 37:
104 case 38:
105 case 39:
106 dev_idx = XPM_NODEIDX_DEV_TTC_0;
107 break;
108 case 40:
109 case 41:
110 case 42:
111 dev_idx = XPM_NODEIDX_DEV_TTC_1;
112 break;
113 case 43:
114 case 44:
115 case 45:
116 dev_idx = XPM_NODEIDX_DEV_TTC_2;
117 break;
118 case 46:
119 case 47:
120 case 48:
121 dev_idx = XPM_NODEIDX_DEV_TTC_3;
122 break;
123 case 56:
124 case 57:
125 dev_idx = XPM_NODEIDX_DEV_GEM_0;
126 break;
Jay Buddhabhattib31b9202023-06-12 04:36:38 -0700127 case 58:
128 case 59:
129 dev_idx = XPM_NODEIDX_DEV_GEM_1;
130 break;
131 case 60:
132 dev_idx = XPM_NODEIDX_DEV_ADMA_0;
133 break;
134 case 61:
135 dev_idx = XPM_NODEIDX_DEV_ADMA_1;
136 break;
137 case 62:
138 dev_idx = XPM_NODEIDX_DEV_ADMA_2;
139 break;
140 case 63:
141 dev_idx = XPM_NODEIDX_DEV_ADMA_3;
142 break;
143 case 64:
144 dev_idx = XPM_NODEIDX_DEV_ADMA_4;
145 break;
146 case 65:
147 dev_idx = XPM_NODEIDX_DEV_ADMA_5;
148 break;
149 case 66:
150 dev_idx = XPM_NODEIDX_DEV_ADMA_6;
151 break;
152 case 67:
153 dev_idx = XPM_NODEIDX_DEV_ADMA_7;
154 break;
155 case 74:
156 dev_idx = XPM_NODEIDX_DEV_USB_0;
157 break;
158 case 126:
159 case 127:
160 dev_idx = XPM_NODEIDX_DEV_SDIO_0;
161 break;
162 case 128:
163 case 129:
164 dev_idx = XPM_NODEIDX_DEV_SDIO_1;
165 break;
166 case 142:
167 dev_idx = XPM_NODEIDX_DEV_RTC;
168 break;
Jay Buddhabhattic06a2712022-12-22 22:27:01 -0800169 default:
170 dev_idx = XPM_NODEIDX_DEV_MIN;
171 break;
172 }
173
174 return dev_idx;
Tejas Patelfcb7c162019-02-27 18:44:56 +0530175}
176
177/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530178 * pm_client_suspend() - Client-specific suspend actions.
179 * @proc: processor which need to suspend.
180 * @state: desired suspend state.
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800181 *
182 * This function should contain any PU-specific actions
183 * required prior to sending suspend request to PMU
184 * Actions taken depend on the state system is suspending to.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530185 *
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800186 */
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530187void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800188{
189 bakery_lock_get(&pm_client_secure_lock);
190
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700191 if (state == PM_STATE_SUSPEND_TO_RAM) {
Abhyuday Godhasaraedc38ae2021-08-04 23:58:46 -0700192 pm_client_set_wakeup_sources((uint32_t)proc->node_id);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700193 }
Tejas Patelfcb7c162019-02-27 18:44:56 +0530194
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800195 /* Set powerdown request */
196 mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) |
Abhyuday Godhasara44877942021-08-05 02:59:26 -0700197 (uint32_t)proc->pwrdn_mask);
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800198
199 bakery_lock_release(&pm_client_secure_lock);
200}
201
202/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530203 * pm_client_abort_suspend() - Client-specific abort-suspend actions.
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800204 *
205 * This function should contain any PU-specific actions
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530206 * required for aborting a prior suspend request.
207 *
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800208 */
209void pm_client_abort_suspend(void)
210{
211 /* Enable interrupts at processor level (for current cpu) */
212 gicv3_cpuif_enable(plat_my_core_pos());
213
214 bakery_lock_get(&pm_client_secure_lock);
215
216 /* Clear powerdown request */
217 mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) &
Abhyuday Godhasara44877942021-08-05 02:59:26 -0700218 ~((uint32_t)primary_proc->pwrdn_mask));
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800219
220 bakery_lock_release(&pm_client_secure_lock);
221}
222
223/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530224 * pm_get_cpuid() - get the local cpu ID for a global node ID.
225 * @nid: node id of the processor.
Tejas Patel7029dd82019-02-27 18:44:54 +0530226 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530227 * Return: the cpu ID (starting from 0) for the subsystem.
228 *
Tejas Patel7029dd82019-02-27 18:44:54 +0530229 */
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530230static uint32_t pm_get_cpuid(uint32_t nid)
Tejas Patel7029dd82019-02-27 18:44:54 +0530231{
Abhyuday Godhasaraedc38ae2021-08-04 23:58:46 -0700232 for (size_t i = 0U; i < ARRAY_SIZE(pm_procs_all); i++) {
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700233 if (pm_procs_all[i].node_id == nid) {
Tejas Patel7029dd82019-02-27 18:44:54 +0530234 return i;
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700235 }
Tejas Patel7029dd82019-02-27 18:44:54 +0530236 }
237 return UNDEFINED_CPUID;
238}
239
240/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530241 * pm_client_wakeup() - Client-specific wakeup actions.
242 * @proc: Processor which need to wakeup.
Tejas Patel7029dd82019-02-27 18:44:54 +0530243 *
244 * This function should contain any PU-specific actions
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530245 * required for waking up another APU core.
246 *
Tejas Patel7029dd82019-02-27 18:44:54 +0530247 */
248void pm_client_wakeup(const struct pm_proc *proc)
249{
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530250 uint32_t cpuid = pm_get_cpuid(proc->node_id);
Tejas Patel7029dd82019-02-27 18:44:54 +0530251
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700252 if (cpuid == UNDEFINED_CPUID) {
Tejas Patel7029dd82019-02-27 18:44:54 +0530253 return;
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700254 }
Tejas Patel7029dd82019-02-27 18:44:54 +0530255
256 bakery_lock_get(&pm_client_secure_lock);
257
258 /* clear powerdown bit for affected cpu */
259 uint32_t val = mmio_read_32(FPD_APU_PWRCTL);
260 val &= ~(proc->pwrdn_mask);
261 mmio_write_32(FPD_APU_PWRCTL, val);
262
263 bakery_lock_release(&pm_client_secure_lock);
264}
265
266/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530267 * pm_get_proc() - returns pointer to the proc structure.
268 * @cpuid: id of the cpu whose proc struct pointer should be returned.
269 *
270 * Return: pointer to a proc structure if proc is found, otherwise NULL.
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800271 *
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800272 */
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530273const struct pm_proc *pm_get_proc(uint32_t cpuid)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800274{
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700275 if (cpuid < ARRAY_SIZE(pm_procs_all)) {
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800276 return &pm_procs_all[cpuid];
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700277 }
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800278
279 return NULL;
280}