blob: 9ad21a1a6f9fd62e23a72fbd0056a4798b0ceae6 [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>
Tejas Patel354fe572018-12-14 00:55:37 -080014#include <plat_ipi.h>
15#include <platform_def.h>
16#include <versal_def.h>
17#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 <drivers/arm/gicv3.h>
Tejas Patelfcb7c162019-02-27 18:44:56 +053021#include <drivers/arm/gic_common.h>
Tejas Patelfe0e10a2019-12-08 23:29:44 -080022#include <plat/common/platform.h>
Tejas Patelfcb7c162019-02-27 18:44:56 +053023#include "pm_api_sys.h"
Tejas Patel354fe572018-12-14 00:55:37 -080024#include "pm_client.h"
Tanmay Shahb145e122022-03-23 12:43:45 -070025#include "pm_defs.h"
Tejas Patel354fe572018-12-14 00:55:37 -080026
Tejas Patel7029dd82019-02-27 18:44:54 +053027#define UNDEFINED_CPUID (~0)
28
Tejas Patel354fe572018-12-14 00:55:37 -080029DEFINE_BAKERY_LOCK(pm_client_secure_lock);
30
31static const struct pm_ipi apu_ipi = {
Michal Simek3a63f052023-04-25 14:21:20 +020032 .local_ipi_id = IPI_LOCAL_ID,
33 .remote_ipi_id = IPI_REMOTE_ID,
Michal Simek9a8da502023-04-25 14:04:02 +020034 .buffer_base = IPI_BUFFER_LOCAL_BASE,
Tejas Patel354fe572018-12-14 00:55:37 -080035};
36
37/* Order in pm_procs_all array must match cpu ids */
38static const struct pm_proc pm_procs_all[] = {
39 {
40 .node_id = XPM_DEVID_ACPU_0,
41 .ipi = &apu_ipi,
Tejas Patelfe0e10a2019-12-08 23:29:44 -080042 .pwrdn_mask = APU_0_PWRCTL_CPUPWRDWNREQ_MASK,
Tejas Patel354fe572018-12-14 00:55:37 -080043 },
44 {
45 .node_id = XPM_DEVID_ACPU_1,
46 .ipi = &apu_ipi,
Tejas Patelfe0e10a2019-12-08 23:29:44 -080047 .pwrdn_mask = APU_1_PWRCTL_CPUPWRDWNREQ_MASK,
Tejas Patel354fe572018-12-14 00:55:37 -080048 }
49};
50
51const struct pm_proc *primary_proc = &pm_procs_all[0];
Tejas Patelfe0e10a2019-12-08 23:29:44 -080052
Tejas Patelfcb7c162019-02-27 18:44:56 +053053/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +053054 * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number.
55 * @irq: Interrupt number
Tejas Patelfcb7c162019-02-27 18:44:56 +053056 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +053057 * Return: PM node index corresponding to the specified interrupt.
58 *
Tejas Patelfcb7c162019-02-27 18:44:56 +053059 */
Jay Buddhabhattia63b3542023-02-28 02:22:02 -080060enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
Tejas Patelfcb7c162019-02-27 18:44:56 +053061{
Jay Buddhabhattic06a2712022-12-22 22:27:01 -080062 enum pm_device_node_idx dev_idx = XPM_NODEIDX_DEV_MIN;
63
Tejas Patelfcb7c162019-02-27 18:44:56 +053064 assert(irq <= IRQ_MAX);
Jay Buddhabhattic06a2712022-12-22 22:27:01 -080065
66 switch (irq) {
67 case 13:
68 dev_idx = XPM_NODEIDX_DEV_GPIO;
69 break;
70 case 14:
71 dev_idx = XPM_NODEIDX_DEV_I2C_0;
72 break;
73 case 15:
74 dev_idx = XPM_NODEIDX_DEV_I2C_1;
75 break;
76 case 16:
77 dev_idx = XPM_NODEIDX_DEV_SPI_0;
78 break;
79 case 17:
80 dev_idx = XPM_NODEIDX_DEV_SPI_1;
81 break;
82 case 18:
83 dev_idx = XPM_NODEIDX_DEV_UART_0;
84 break;
85 case 19:
86 dev_idx = XPM_NODEIDX_DEV_UART_1;
87 break;
88 case 20:
89 dev_idx = XPM_NODEIDX_DEV_CAN_FD_0;
90 break;
91 case 21:
92 dev_idx = XPM_NODEIDX_DEV_CAN_FD_1;
93 break;
94 case 22:
95 case 23:
96 case 24:
97 case 25:
98 case 26:
99 dev_idx = XPM_NODEIDX_DEV_USB_0;
100 break;
101 case 37:
102 case 38:
103 case 39:
104 dev_idx = XPM_NODEIDX_DEV_TTC_0;
105 break;
106 case 40:
107 case 41:
108 case 42:
109 dev_idx = XPM_NODEIDX_DEV_TTC_1;
110 break;
111 case 43:
112 case 44:
113 case 45:
114 dev_idx = XPM_NODEIDX_DEV_TTC_2;
115 break;
116 case 46:
117 case 47:
118 case 48:
119 dev_idx = XPM_NODEIDX_DEV_TTC_3;
120 break;
121 case 56:
122 case 57:
123 dev_idx = XPM_NODEIDX_DEV_GEM_0;
124 break;
Jay Buddhabhattib31b9202023-06-12 04:36:38 -0700125 case 58:
126 case 59:
127 dev_idx = XPM_NODEIDX_DEV_GEM_1;
128 break;
129 case 60:
130 dev_idx = XPM_NODEIDX_DEV_ADMA_0;
131 break;
132 case 61:
133 dev_idx = XPM_NODEIDX_DEV_ADMA_1;
134 break;
135 case 62:
136 dev_idx = XPM_NODEIDX_DEV_ADMA_2;
137 break;
138 case 63:
139 dev_idx = XPM_NODEIDX_DEV_ADMA_3;
140 break;
141 case 64:
142 dev_idx = XPM_NODEIDX_DEV_ADMA_4;
143 break;
144 case 65:
145 dev_idx = XPM_NODEIDX_DEV_ADMA_5;
146 break;
147 case 66:
148 dev_idx = XPM_NODEIDX_DEV_ADMA_6;
149 break;
150 case 67:
151 dev_idx = XPM_NODEIDX_DEV_ADMA_7;
152 break;
153 case 74:
154 dev_idx = XPM_NODEIDX_DEV_USB_0;
155 break;
156 case 126:
157 case 127:
158 dev_idx = XPM_NODEIDX_DEV_SDIO_0;
159 break;
160 case 128:
161 case 129:
162 dev_idx = XPM_NODEIDX_DEV_SDIO_1;
163 break;
164 case 142:
165 dev_idx = XPM_NODEIDX_DEV_RTC;
166 break;
Jay Buddhabhattic06a2712022-12-22 22:27:01 -0800167 default:
168 dev_idx = XPM_NODEIDX_DEV_MIN;
169 break;
170 }
171
172 return dev_idx;
Tejas Patelfcb7c162019-02-27 18:44:56 +0530173}
174
175/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530176 * pm_client_suspend() - Client-specific suspend actions.
177 * @proc: processor which need to suspend.
178 * @state: desired suspend state.
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800179 *
180 * This function should contain any PU-specific actions
181 * required prior to sending suspend request to PMU
182 * Actions taken depend on the state system is suspending to.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530183 *
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800184 */
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530185void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800186{
187 bakery_lock_get(&pm_client_secure_lock);
188
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700189 if (state == PM_STATE_SUSPEND_TO_RAM) {
Abhyuday Godhasaraedc38ae2021-08-04 23:58:46 -0700190 pm_client_set_wakeup_sources((uint32_t)proc->node_id);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700191 }
Tejas Patelfcb7c162019-02-27 18:44:56 +0530192
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800193 /* Set powerdown request */
194 mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) |
Abhyuday Godhasara44877942021-08-05 02:59:26 -0700195 (uint32_t)proc->pwrdn_mask);
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800196
197 bakery_lock_release(&pm_client_secure_lock);
198}
199
200/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530201 * pm_client_abort_suspend() - Client-specific abort-suspend actions.
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800202 *
203 * This function should contain any PU-specific actions
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530204 * required for aborting a prior suspend request.
205 *
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800206 */
207void pm_client_abort_suspend(void)
208{
209 /* Enable interrupts at processor level (for current cpu) */
210 gicv3_cpuif_enable(plat_my_core_pos());
211
212 bakery_lock_get(&pm_client_secure_lock);
213
214 /* Clear powerdown request */
215 mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) &
Abhyuday Godhasara44877942021-08-05 02:59:26 -0700216 ~((uint32_t)primary_proc->pwrdn_mask));
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800217
218 bakery_lock_release(&pm_client_secure_lock);
219}
220
221/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530222 * pm_get_cpuid() - get the local cpu ID for a global node ID.
223 * @nid: node id of the processor.
Tejas Patel7029dd82019-02-27 18:44:54 +0530224 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530225 * Return: the cpu ID (starting from 0) for the subsystem.
226 *
Tejas Patel7029dd82019-02-27 18:44:54 +0530227 */
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530228static uint32_t pm_get_cpuid(uint32_t nid)
Tejas Patel7029dd82019-02-27 18:44:54 +0530229{
Abhyuday Godhasaraedc38ae2021-08-04 23:58:46 -0700230 for (size_t i = 0U; i < ARRAY_SIZE(pm_procs_all); i++) {
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700231 if (pm_procs_all[i].node_id == nid) {
Tejas Patel7029dd82019-02-27 18:44:54 +0530232 return i;
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700233 }
Tejas Patel7029dd82019-02-27 18:44:54 +0530234 }
235 return UNDEFINED_CPUID;
236}
237
238/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530239 * pm_client_wakeup() - Client-specific wakeup actions.
240 * @proc: Processor which need to wakeup.
Tejas Patel7029dd82019-02-27 18:44:54 +0530241 *
242 * This function should contain any PU-specific actions
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530243 * required for waking up another APU core.
244 *
Tejas Patel7029dd82019-02-27 18:44:54 +0530245 */
246void pm_client_wakeup(const struct pm_proc *proc)
247{
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530248 uint32_t cpuid = pm_get_cpuid(proc->node_id);
Tejas Patel7029dd82019-02-27 18:44:54 +0530249
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700250 if (cpuid == UNDEFINED_CPUID) {
Tejas Patel7029dd82019-02-27 18:44:54 +0530251 return;
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700252 }
Tejas Patel7029dd82019-02-27 18:44:54 +0530253
254 bakery_lock_get(&pm_client_secure_lock);
255
256 /* clear powerdown bit for affected cpu */
257 uint32_t val = mmio_read_32(FPD_APU_PWRCTL);
258 val &= ~(proc->pwrdn_mask);
259 mmio_write_32(FPD_APU_PWRCTL, val);
260
261 bakery_lock_release(&pm_client_secure_lock);
262}
263
264/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530265 * pm_get_proc() - returns pointer to the proc structure.
266 * @cpuid: id of the cpu whose proc struct pointer should be returned.
267 *
268 * Return: pointer to a proc structure if proc is found, otherwise NULL.
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800269 *
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800270 */
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530271const struct pm_proc *pm_get_proc(uint32_t cpuid)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800272{
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700273 if (cpuid < ARRAY_SIZE(pm_procs_all)) {
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800274 return &pm_procs_all[cpuid];
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700275 }
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800276
277 return NULL;
278}