blob: ecec405d310c7860102bf7c9830204c666675161 [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 = {
32 .local_ipi_id = IPI_ID_APU,
33 .remote_ipi_id = IPI_ID_PMC,
34 .buffer_base = IPI_BUFFER_APU_BASE,
35};
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/**
54 * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number
55 * @irq: Interrupt number
56 *
57 * Return: PM node index corresponding to the specified interrupt
58 */
Jay Buddhabhattia63b3542023-02-28 02:22:02 -080059enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
Tejas Patelfcb7c162019-02-27 18:44:56 +053060{
Jay Buddhabhattic06a2712022-12-22 22:27:01 -080061 enum pm_device_node_idx dev_idx = XPM_NODEIDX_DEV_MIN;
62
Tejas Patelfcb7c162019-02-27 18:44:56 +053063 assert(irq <= IRQ_MAX);
Jay Buddhabhattic06a2712022-12-22 22:27:01 -080064
65 switch (irq) {
66 case 13:
67 dev_idx = XPM_NODEIDX_DEV_GPIO;
68 break;
69 case 14:
70 dev_idx = XPM_NODEIDX_DEV_I2C_0;
71 break;
72 case 15:
73 dev_idx = XPM_NODEIDX_DEV_I2C_1;
74 break;
75 case 16:
76 dev_idx = XPM_NODEIDX_DEV_SPI_0;
77 break;
78 case 17:
79 dev_idx = XPM_NODEIDX_DEV_SPI_1;
80 break;
81 case 18:
82 dev_idx = XPM_NODEIDX_DEV_UART_0;
83 break;
84 case 19:
85 dev_idx = XPM_NODEIDX_DEV_UART_1;
86 break;
87 case 20:
88 dev_idx = XPM_NODEIDX_DEV_CAN_FD_0;
89 break;
90 case 21:
91 dev_idx = XPM_NODEIDX_DEV_CAN_FD_1;
92 break;
93 case 22:
94 case 23:
95 case 24:
96 case 25:
97 case 26:
98 dev_idx = XPM_NODEIDX_DEV_USB_0;
99 break;
100 case 37:
101 case 38:
102 case 39:
103 dev_idx = XPM_NODEIDX_DEV_TTC_0;
104 break;
105 case 40:
106 case 41:
107 case 42:
108 dev_idx = XPM_NODEIDX_DEV_TTC_1;
109 break;
110 case 43:
111 case 44:
112 case 45:
113 dev_idx = XPM_NODEIDX_DEV_TTC_2;
114 break;
115 case 46:
116 case 47:
117 case 48:
118 dev_idx = XPM_NODEIDX_DEV_TTC_3;
119 break;
120 case 56:
121 case 57:
122 dev_idx = XPM_NODEIDX_DEV_GEM_0;
123 break;
124 default:
125 dev_idx = XPM_NODEIDX_DEV_MIN;
126 break;
127 }
128
129 return dev_idx;
Tejas Patelfcb7c162019-02-27 18:44:56 +0530130}
131
132/**
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800133 * pm_client_suspend() - Client-specific suspend actions
134 *
135 * This function should contain any PU-specific actions
136 * required prior to sending suspend request to PMU
137 * Actions taken depend on the state system is suspending to.
138 */
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530139void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800140{
141 bakery_lock_get(&pm_client_secure_lock);
142
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700143 if (state == PM_STATE_SUSPEND_TO_RAM) {
Abhyuday Godhasaraedc38ae2021-08-04 23:58:46 -0700144 pm_client_set_wakeup_sources((uint32_t)proc->node_id);
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700145 }
Tejas Patelfcb7c162019-02-27 18:44:56 +0530146
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800147 /* Set powerdown request */
148 mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) |
Abhyuday Godhasara44877942021-08-05 02:59:26 -0700149 (uint32_t)proc->pwrdn_mask);
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800150
151 bakery_lock_release(&pm_client_secure_lock);
152}
153
154/**
155 * pm_client_abort_suspend() - Client-specific abort-suspend actions
156 *
157 * This function should contain any PU-specific actions
158 * required for aborting a prior suspend request
159 */
160void pm_client_abort_suspend(void)
161{
162 /* Enable interrupts at processor level (for current cpu) */
163 gicv3_cpuif_enable(plat_my_core_pos());
164
165 bakery_lock_get(&pm_client_secure_lock);
166
167 /* Clear powerdown request */
168 mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) &
Abhyuday Godhasara44877942021-08-05 02:59:26 -0700169 ~((uint32_t)primary_proc->pwrdn_mask));
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800170
171 bakery_lock_release(&pm_client_secure_lock);
172}
173
174/**
Tejas Patel7029dd82019-02-27 18:44:54 +0530175 * pm_get_cpuid() - get the local cpu ID for a global node ID
176 * @nid: node id of the processor
177 *
178 * Return: the cpu ID (starting from 0) for the subsystem
179 */
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530180static uint32_t pm_get_cpuid(uint32_t nid)
Tejas Patel7029dd82019-02-27 18:44:54 +0530181{
Abhyuday Godhasaraedc38ae2021-08-04 23:58:46 -0700182 for (size_t i = 0U; i < ARRAY_SIZE(pm_procs_all); i++) {
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700183 if (pm_procs_all[i].node_id == nid) {
Tejas Patel7029dd82019-02-27 18:44:54 +0530184 return i;
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700185 }
Tejas Patel7029dd82019-02-27 18:44:54 +0530186 }
187 return UNDEFINED_CPUID;
188}
189
190/**
191 * pm_client_wakeup() - Client-specific wakeup actions
192 *
193 * This function should contain any PU-specific actions
194 * required for waking up another APU core
195 */
196void pm_client_wakeup(const struct pm_proc *proc)
197{
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530198 uint32_t cpuid = pm_get_cpuid(proc->node_id);
Tejas Patel7029dd82019-02-27 18:44:54 +0530199
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700200 if (cpuid == UNDEFINED_CPUID) {
Tejas Patel7029dd82019-02-27 18:44:54 +0530201 return;
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700202 }
Tejas Patel7029dd82019-02-27 18:44:54 +0530203
204 bakery_lock_get(&pm_client_secure_lock);
205
206 /* clear powerdown bit for affected cpu */
207 uint32_t val = mmio_read_32(FPD_APU_PWRCTL);
208 val &= ~(proc->pwrdn_mask);
209 mmio_write_32(FPD_APU_PWRCTL, val);
210
211 bakery_lock_release(&pm_client_secure_lock);
212}
213
214/**
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800215 * pm_get_proc() - returns pointer to the proc structure
216 * @cpuid: id of the cpu whose proc struct pointer should be returned
217 *
218 * Return: pointer to a proc structure if proc is found, otherwise NULL
219 */
Venkatesh Yadav Abbarapubde87592022-05-24 11:11:12 +0530220const struct pm_proc *pm_get_proc(uint32_t cpuid)
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800221{
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700222 if (cpuid < ARRAY_SIZE(pm_procs_all)) {
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800223 return &pm_procs_all[cpuid];
Abhyuday Godhasaraddc46622021-08-05 03:14:17 -0700224 }
Tejas Patelfe0e10a2019-12-08 23:29:44 -0800225
226 return NULL;
227}