blob: ece59545e409f42f16ec8a8f9993ffc757c2f88d [file] [log] [blame]
Soren Brinkmann76fcae32016-03-06 20:16:27 -08001/*
Michal Simek2a47faa2023-04-14 08:43:51 +02002 * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
Michal Simekd4ff2722023-04-20 08:01:03 +02003 * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
Soren Brinkmann76fcae32016-03-06 20:16:27 -08004 *
dp-armfa3cf0b2017-05-03 09:38:09 +01005 * SPDX-License-Identifier: BSD-3-Clause
Soren Brinkmann76fcae32016-03-06 20:16:27 -08006 */
7
8/*
9 * ZynqMP system level PM-API functions and communication with PMU via
10 * IPI interrupts
11 */
12
13#include <arch_helpers.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000014#include <plat/common/platform.h>
15
Rajan Vaja35116132018-01-17 02:39:25 -080016#include "pm_api_clock.h"
Rajan Vaja5529a012018-01-17 02:39:23 -080017#include "pm_api_ioctl.h"
Rajan Vaja0ac2be12018-01-17 02:39:21 -080018#include "pm_api_pinctrl.h"
Soren Brinkmann76fcae32016-03-06 20:16:27 -080019#include "pm_client.h"
Soren Brinkmann76fcae32016-03-06 20:16:27 -080020#include "pm_common.h"
Isla Mitchelle3631462017-07-14 10:46:32 +010021#include "pm_ipi.h"
Jay Buddhabhatti26e138a2022-12-21 23:03:35 -080022#include "zynqmp_pm_api_sys.h"
Soren Brinkmann76fcae32016-03-06 20:16:27 -080023
Ronak Jain325bad12021-12-21 01:39:59 -080024#define PM_QUERY_FEATURE_BITMASK ( \
25 (1ULL << (uint64_t)PM_QID_CLOCK_GET_NAME) | \
26 (1ULL << (uint64_t)PM_QID_CLOCK_GET_TOPOLOGY) | \
27 (1ULL << (uint64_t)PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS) | \
28 (1ULL << (uint64_t)PM_QID_CLOCK_GET_PARENTS) | \
29 (1ULL << (uint64_t)PM_QID_CLOCK_GET_ATTRIBUTES) | \
30 (1ULL << (uint64_t)PM_QID_PINCTRL_GET_NUM_PINS) | \
31 (1ULL << (uint64_t)PM_QID_PINCTRL_GET_NUM_FUNCTIONS) | \
32 (1ULL << (uint64_t)PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS) | \
33 (1ULL << (uint64_t)PM_QID_PINCTRL_GET_FUNCTION_NAME) | \
34 (1ULL << (uint64_t)PM_QID_PINCTRL_GET_FUNCTION_GROUPS) | \
35 (1ULL << (uint64_t)PM_QID_PINCTRL_GET_PIN_GROUPS) | \
36 (1ULL << (uint64_t)PM_QID_CLOCK_GET_NUM_CLOCKS) | \
37 (1ULL << (uint64_t)PM_QID_CLOCK_GET_MAX_DIVISOR))
38
39/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +053040 * typedef eemi_api_dependency - Dependent EEMI APIs which are implemented
41 * on both the TF-A and firmware.
42 * @id: EEMI API id or IOCTL id to be checked.
43 * @api_id: Dependent EEMI API.
Ronak Jain325bad12021-12-21 01:39:59 -080044 *
Ronak Jain325bad12021-12-21 01:39:59 -080045 */
46typedef struct __attribute__((packed)) {
47 uint8_t id;
48 uint8_t api_id;
49} eemi_api_dependency;
50
Prasad Kummarie0783112023-04-26 11:02:07 +053051/* Dependent APIs for TF-A to check their version from firmware */
Ronak Jain325bad12021-12-21 01:39:59 -080052static const eemi_api_dependency api_dep_table[] = {
53 {
54 .id = PM_SELF_SUSPEND,
55 .api_id = PM_SELF_SUSPEND,
56 },
57 {
58 .id = PM_REQ_WAKEUP,
59 .api_id = PM_REQ_WAKEUP,
60 },
61 {
62 .id = PM_ABORT_SUSPEND,
63 .api_id = PM_ABORT_SUSPEND,
64 },
65 {
66 .id = PM_SET_WAKEUP_SOURCE,
67 .api_id = PM_SET_WAKEUP_SOURCE,
68 },
69 {
70 .id = PM_SYSTEM_SHUTDOWN,
71 .api_id = PM_SYSTEM_SHUTDOWN,
72 },
73 {
74 .id = PM_GET_API_VERSION,
75 .api_id = PM_GET_API_VERSION,
76 },
77 {
78 .id = PM_CLOCK_ENABLE,
79 .api_id = PM_PLL_SET_MODE,
80 },
81 {
82 .id = PM_CLOCK_ENABLE,
83 .api_id = PM_CLOCK_ENABLE,
84 },
85 {
86 .id = PM_CLOCK_DISABLE,
87 .api_id = PM_PLL_SET_MODE,
88 },
89 {
90 .id = PM_CLOCK_DISABLE,
91 .api_id = PM_CLOCK_DISABLE,
92 },
93 {
94 .id = PM_CLOCK_GETSTATE,
95 .api_id = PM_PLL_GET_MODE,
96 },
97 {
98 .id = PM_CLOCK_GETSTATE,
99 .api_id = PM_CLOCK_GETSTATE,
100 },
101 {
102 .id = PM_CLOCK_SETDIVIDER,
103 .api_id = PM_PLL_SET_PARAMETER,
104 },
105 {
106 .id = PM_CLOCK_SETDIVIDER,
107 .api_id = PM_CLOCK_SETDIVIDER,
108 },
109 {
110 .id = PM_CLOCK_GETDIVIDER,
111 .api_id = PM_PLL_GET_PARAMETER,
112 },
113 {
114 .id = PM_CLOCK_GETDIVIDER,
115 .api_id = PM_CLOCK_GETDIVIDER,
116 },
117 {
118 .id = PM_CLOCK_SETPARENT,
119 .api_id = PM_PLL_SET_PARAMETER,
120 },
121 {
122 .id = PM_CLOCK_SETPARENT,
123 .api_id = PM_CLOCK_SETPARENT,
124 },
125 {
126 .id = PM_CLOCK_GETPARENT,
127 .api_id = PM_PLL_GET_PARAMETER,
128 },
129 {
130 .id = PM_CLOCK_GETPARENT,
131 .api_id = PM_CLOCK_GETPARENT,
132 },
133 {
134 .id = PM_PLL_SET_PARAMETER,
135 .api_id = PM_PLL_SET_PARAMETER,
136 },
137 {
138 .id = PM_PLL_GET_PARAMETER,
139 .api_id = PM_PLL_GET_PARAMETER,
140 },
141 {
142 .id = PM_PLL_SET_MODE,
143 .api_id = PM_PLL_SET_MODE,
144 },
145 {
146 .id = PM_PLL_GET_MODE,
147 .api_id = PM_PLL_GET_MODE,
148 },
149 {
150 .id = PM_REGISTER_ACCESS,
151 .api_id = PM_MMIO_WRITE,
152 },
153 {
154 .id = PM_REGISTER_ACCESS,
155 .api_id = PM_MMIO_READ,
156 },
157 {
158 .id = PM_FEATURE_CHECK,
159 .api_id = PM_FEATURE_CHECK,
160 },
161 {
162 .id = IOCTL_SET_TAPDELAY_BYPASS,
163 .api_id = PM_MMIO_WRITE,
164 },
165 {
166 .id = IOCTL_SET_SGMII_MODE,
167 .api_id = PM_MMIO_WRITE,
168 },
169 {
170 .id = IOCTL_SD_DLL_RESET,
171 .api_id = PM_MMIO_WRITE,
172 },
173 {
174 .id = IOCTL_SET_SD_TAPDELAY,
175 .api_id = PM_MMIO_WRITE,
176 },
177 {
178 .id = IOCTL_SET_SD_TAPDELAY,
179 .api_id = PM_MMIO_READ,
180 },
181 {
182 .id = IOCTL_SET_PLL_FRAC_DATA,
183 .api_id = PM_PLL_SET_PARAMETER,
184 },
185 {
186 .id = IOCTL_GET_PLL_FRAC_DATA,
187 .api_id = PM_PLL_GET_PARAMETER,
188 },
189 {
190 .id = IOCTL_WRITE_GGS,
191 .api_id = PM_MMIO_WRITE,
192 },
193 {
194 .id = IOCTL_READ_GGS,
195 .api_id = PM_MMIO_READ,
196 },
197 {
198 .id = IOCTL_WRITE_PGGS,
199 .api_id = PM_MMIO_WRITE,
200 },
201 {
202 .id = IOCTL_READ_PGGS,
203 .api_id = PM_MMIO_READ,
204 },
205 {
206 .id = IOCTL_ULPI_RESET,
207 .api_id = PM_MMIO_WRITE,
208 },
209 {
210 .id = IOCTL_SET_BOOT_HEALTH_STATUS,
211 .api_id = PM_MMIO_WRITE,
212 },
213 {
214 .id = IOCTL_AFI,
215 .api_id = PM_MMIO_WRITE,
216 },
217};
218
Prasad Kummarie0783112023-04-26 11:02:07 +0530219/* Expected firmware API version to TF-A */
220static const uint8_t tfa_expected_ver_id[] = {
Ronak Jain325bad12021-12-21 01:39:59 -0800221 [PM_SELF_SUSPEND] = FW_API_BASE_VERSION,
222 [PM_REQ_WAKEUP] = FW_API_BASE_VERSION,
223 [PM_ABORT_SUSPEND] = FW_API_BASE_VERSION,
224 [PM_SET_WAKEUP_SOURCE] = FW_API_BASE_VERSION,
225 [PM_SYSTEM_SHUTDOWN] = FW_API_BASE_VERSION,
226 [PM_GET_API_VERSION] = FW_API_BASE_VERSION,
227 [PM_PLL_SET_MODE] = FW_API_BASE_VERSION,
228 [PM_PLL_GET_MODE] = FW_API_BASE_VERSION,
229 [PM_CLOCK_ENABLE] = FW_API_BASE_VERSION,
230 [PM_CLOCK_DISABLE] = FW_API_BASE_VERSION,
231 [PM_CLOCK_GETSTATE] = FW_API_BASE_VERSION,
232 [PM_PLL_SET_PARAMETER] = FW_API_BASE_VERSION,
233 [PM_PLL_GET_PARAMETER] = FW_API_BASE_VERSION,
234 [PM_CLOCK_SETDIVIDER] = FW_API_BASE_VERSION,
235 [PM_CLOCK_GETDIVIDER] = FW_API_BASE_VERSION,
236 [PM_CLOCK_SETPARENT] = FW_API_BASE_VERSION,
237 [PM_CLOCK_GETPARENT] = FW_API_BASE_VERSION,
238 [PM_MMIO_WRITE] = FW_API_BASE_VERSION,
239 [PM_MMIO_READ] = FW_API_BASE_VERSION,
240 [PM_FEATURE_CHECK] = FW_API_VERSION_2,
241};
242
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530243/* default shutdown/reboot scope is system(2) */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530244static uint32_t pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM;
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530245
246/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530247 * pm_get_shutdown_scope() - Get the currently set shutdown scope.
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530248 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530249 * Return: Shutdown scope value.
250 *
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530251 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530252uint32_t pm_get_shutdown_scope(void)
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530253{
254 return pm_shutdown_scope;
255}
256
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800257/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530258 * pm_self_suspend() - PM call for processor to suspend itself.
259 * @nid: Node id of the processor or subsystem.
260 * @latency: Requested maximum wakeup latency (not supported).
261 * @state: Requested state.
262 * @address: Resume address.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800263 *
264 * This is a blocking call, it will return only once PMU has responded.
265 * On a wakeup, resume address will be automatically set by PMU.
266 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530267 * Return: Returns status, either success or error+reason.
268 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800269 */
270enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530271 uint32_t latency,
272 uint32_t state,
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800273 uintptr_t address)
274{
275 uint32_t payload[PAYLOAD_ARG_CNT];
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530276 uint32_t cpuid = plat_my_core_pos();
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800277 const struct pm_proc *proc = pm_get_proc(cpuid);
278
279 /*
280 * Do client specific suspend operations
281 * (e.g. set powerdown request bit)
282 */
Filip Drazic4c0765a2016-07-26 12:11:33 +0200283 pm_client_suspend(proc, state);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800284 /* Send request to the PMU */
285 PM_PACK_PAYLOAD6(payload, PM_SELF_SUSPEND, proc->node_id, latency,
286 state, address, (address >> 32));
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700287 return pm_ipi_send_sync(proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800288}
289
290/**
291 * pm_req_suspend() - PM call to request for another PU or subsystem to
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530292 * be suspended gracefully.
293 * @target: Node id of the targeted PU or subsystem.
294 * @ack: Flag to specify whether acknowledge is requested.
295 * @latency: Requested wakeup latency (not supported).
296 * @state: Requested state (not supported).
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800297 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530298 * Return: Returns status, either success or error+reason.
299 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800300 */
301enum pm_ret_status pm_req_suspend(enum pm_node_id target,
302 enum pm_request_ack ack,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530303 uint32_t latency, uint32_t state)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800304{
305 uint32_t payload[PAYLOAD_ARG_CNT];
306
307 /* Send request to the PMU */
308 PM_PACK_PAYLOAD5(payload, PM_REQ_SUSPEND, target, ack, latency, state);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530309 if (ack == REQ_ACK_BLOCKING) {
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700310 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530311 } else {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800312 return pm_ipi_send(primary_proc, payload);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530313 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800314}
315
316/**
317 * pm_req_wakeup() - PM call for processor to wake up selected processor
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530318 * or subsystem.
319 * @target: Node id of the processor or subsystem to wake up.
320 * @ack: Flag to specify whether acknowledge requested.
321 * @set_address: Resume address presence indicator.
322 * 1 resume address specified, 0 otherwise.
323 * @address: Resume address.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800324 *
325 * This API function is either used to power up another APU core for SMP
326 * (by PSCI) or to power up an entirely different PU or subsystem, such
327 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
328 * automatically set by PMU.
329 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530330 * Return: Returns status, either success or error+reason.
331 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800332 */
333enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530334 uint32_t set_address,
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800335 uintptr_t address,
336 enum pm_request_ack ack)
337{
338 uint32_t payload[PAYLOAD_ARG_CNT];
339 uint64_t encoded_address;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800340
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800341
342 /* encode set Address into 1st bit of address */
343 encoded_address = address;
344 encoded_address |= !!set_address;
345
346 /* Send request to the PMU to perform the wake of the PU */
347 PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address,
348 encoded_address >> 32, ack);
349
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530350 if (ack == REQ_ACK_BLOCKING) {
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700351 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530352 } else {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800353 return pm_ipi_send(primary_proc, payload);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530354 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800355}
356
357/**
358 * pm_force_powerdown() - PM call to request for another PU or subsystem to
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530359 * be powered down forcefully.
360 * @target: Node id of the targeted PU or subsystem.
361 * @ack: Flag to specify whether acknowledge is requested.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800362 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530363 * Return: Returns status, either success or error+reason.
364 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800365 */
366enum pm_ret_status pm_force_powerdown(enum pm_node_id target,
367 enum pm_request_ack ack)
368{
369 uint32_t payload[PAYLOAD_ARG_CNT];
370
371 /* Send request to the PMU */
372 PM_PACK_PAYLOAD3(payload, PM_FORCE_POWERDOWN, target, ack);
373
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530374 if (ack == REQ_ACK_BLOCKING) {
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700375 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530376 } else {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800377 return pm_ipi_send(primary_proc, payload);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530378 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800379}
380
381/**
382 * pm_abort_suspend() - PM call to announce that a prior suspend request
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530383 * is to be aborted.
384 * @reason: Reason for the abort.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800385 *
386 * Calling PU expects the PMU to abort the initiated suspend procedure.
387 * This is a non-blocking call without any acknowledge.
388 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530389 * Return: Returns status, either success or error+reason
390 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800391 */
392enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason)
393{
394 uint32_t payload[PAYLOAD_ARG_CNT];
395
396 /*
397 * Do client specific abort suspend operations
398 * (e.g. enable interrupts and clear powerdown request bit)
399 */
400 pm_client_abort_suspend();
401 /* Send request to the PMU */
402 /* TODO: allow passing the node ID of the affected CPU */
403 PM_PACK_PAYLOAD3(payload, PM_ABORT_SUSPEND, reason,
404 primary_proc->node_id);
Abhyuday Godhasara0d9b7652021-06-24 05:49:04 -0700405 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800406}
407
408/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530409 * pm_set_wakeup_source() - PM call to specify the wakeup source while
410 * suspended.
411 * @target: Node id of the targeted PU or subsystem.
412 * @wkup_node: Node id of the wakeup peripheral.
413 * @enable: Enable or disable the specified peripheral as wake source.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800414 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530415 * Return: Returns status, either success or error+reason.
416 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800417 */
418enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
419 enum pm_node_id wkup_node,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530420 uint32_t enable)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800421{
422 uint32_t payload[PAYLOAD_ARG_CNT];
423
424 PM_PACK_PAYLOAD4(payload, PM_SET_WAKEUP_SOURCE, target, wkup_node,
425 enable);
Abhyuday Godhasara0d9b7652021-06-24 05:49:04 -0700426 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800427}
428
429/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530430 * pm_system_shutdown() - PM call to request a system shutdown or restart.
431 * @type: Shutdown or restart? 0=shutdown, 1=restart, 2=setscope.
432 * @subtype: Scope: 0=APU-subsystem, 1=PS, 2=system.
433 *
434 * Return: Returns status, either success or error+reason.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800435 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800436 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530437enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800438{
439 uint32_t payload[PAYLOAD_ARG_CNT];
440
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530441 if (type == PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
442 /* Setting scope for subsequent PSCI reboot or shutdown */
443 pm_shutdown_scope = subtype;
444 return PM_RET_SUCCESS;
445 }
446
Soren Brinkmann58fbb9b2016-09-02 09:50:54 -0700447 PM_PACK_PAYLOAD3(payload, PM_SYSTEM_SHUTDOWN, type, subtype);
Tejas Patelaf4b10e2018-02-09 02:42:59 -0800448 return pm_ipi_send_non_blocking(primary_proc, payload);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800449}
450
451/* APIs for managing PM slaves: */
452
453/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530454 * pm_req_node() - PM call to request a node with specific capabilities.
455 * @nid: Node id of the slave.
456 * @capabilities: Requested capabilities of the slave.
457 * @qos: Quality of service (not supported).
458 * @ack: Flag to specify whether acknowledge is requested.
459 *
460 * Return: Returns status, either success or error+reason.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800461 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800462 */
463enum pm_ret_status pm_req_node(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530464 uint32_t capabilities,
465 uint32_t qos,
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800466 enum pm_request_ack ack)
467{
468 uint32_t payload[PAYLOAD_ARG_CNT];
469
470 PM_PACK_PAYLOAD5(payload, PM_REQ_NODE, nid, capabilities, qos, ack);
471
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530472 if (ack == REQ_ACK_BLOCKING) {
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700473 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530474 } else {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800475 return pm_ipi_send(primary_proc, payload);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530476 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800477}
478
479/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530480 * pm_set_requirement() - PM call to set requirement for PM slaves.
481 * @nid: Node id of the slave.
482 * @capabilities: Requested capabilities of the slave.
483 * @qos: Quality of service (not supported).
484 * @ack: Flag to specify whether acknowledge is requested.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800485 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530486 * This API function is to be used for slaves a PU already has requested.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800487 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530488 * Return: Returns status, either success or error+reason.
489 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800490 */
491enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530492 uint32_t capabilities,
493 uint32_t qos,
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800494 enum pm_request_ack ack)
495{
496 uint32_t payload[PAYLOAD_ARG_CNT];
497
498 PM_PACK_PAYLOAD5(payload, PM_SET_REQUIREMENT, nid, capabilities, qos,
499 ack);
500
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530501 if (ack == REQ_ACK_BLOCKING) {
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700502 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530503 } else {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800504 return pm_ipi_send(primary_proc, payload);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530505 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800506}
507
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800508/* Miscellaneous API functions */
509
510/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530511 * pm_get_api_version() - Get version number of PMU PM firmware.
512 * @version: Returns 32-bit version number of PMU Power Management Firmware.
513 *
514 * Return: Returns status, either success or error+reason.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800515 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800516 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530517enum pm_ret_status pm_get_api_version(uint32_t *version)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800518{
519 uint32_t payload[PAYLOAD_ARG_CNT];
520
521 /* Send request to the PMU */
522 PM_PACK_PAYLOAD1(payload, PM_GET_API_VERSION);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700523 return pm_ipi_send_sync(primary_proc, payload, version, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800524}
525
526/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530527 * pm_get_node_status() - PM call to request a node's current status.
528 * @nid: Node id.
529 * @ret_buff: Buffer for the return values
530 * [0] - Current power state of the node
531 * [1] - Current requirements for the node (slave nodes only)
532 * [2] - Current usage status for the node (slave nodes only)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800533 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530534 * Return: Returns status, either success or error+reason.
535 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800536 */
Anes Hadziahmetagic1caf88e2017-01-27 18:42:44 +0100537enum pm_ret_status pm_get_node_status(enum pm_node_id nid,
538 uint32_t *ret_buff)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800539{
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800540 uint32_t payload[PAYLOAD_ARG_CNT];
541
542 PM_PACK_PAYLOAD2(payload, PM_GET_NODE_STATUS, nid);
Anes Hadziahmetagic1caf88e2017-01-27 18:42:44 +0100543 return pm_ipi_send_sync(primary_proc, payload, ret_buff, 3);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800544}
545
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800546/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530547 * pm_mmio_write() - Perform write to protected mmio.
548 * @address: Address to write to.
549 * @mask: Mask to apply.
550 * @value: Value to write.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800551 *
552 * This function provides access to PM-related control registers
553 * that may not be directly accessible by a particular PU.
554 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530555 * Return: Returns status, either success or error+reason.
556 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800557 */
558enum pm_ret_status pm_mmio_write(uintptr_t address,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530559 uint32_t mask,
560 uint32_t value)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800561{
562 uint32_t payload[PAYLOAD_ARG_CNT];
563
564 /* Send request to the PMU */
565 PM_PACK_PAYLOAD4(payload, PM_MMIO_WRITE, address, mask, value);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700566 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800567}
568
569/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530570 * pm_mmio_read() - Read value from protected mmio.
571 * @address: Address to write to.
572 * @value: Value to write.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800573 *
574 * This function provides access to PM-related control registers
575 * that may not be directly accessible by a particular PU.
576 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530577 * Return: Returns status, either success or error+reason.
578 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800579 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530580enum pm_ret_status pm_mmio_read(uintptr_t address, uint32_t *value)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800581{
582 uint32_t payload[PAYLOAD_ARG_CNT];
583
584 /* Send request to the PMU */
585 PM_PACK_PAYLOAD2(payload, PM_MMIO_READ, address);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700586 return pm_ipi_send_sync(primary_proc, payload, value, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800587}
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530588
589/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530590 * pm_fpga_load() - Load the bitstream into the PL. This function provides
591 * access to the xilfpga library to load the Bit-stream
592 * into PL.
593 * @address_low: lower 32-bit Linear memory space address.
594 * @address_high: higher 32-bit Linear memory space address.
595 * @size: Number of 32bit words.
596 * @flags: Additional flags or settings for the fpga operation.
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530597 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530598 * Return: Returns status, either success or error+reason.
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530599 *
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530600 */
601enum pm_ret_status pm_fpga_load(uint32_t address_low,
602 uint32_t address_high,
603 uint32_t size,
604 uint32_t flags)
605{
606 uint32_t payload[PAYLOAD_ARG_CNT];
607
608 /* Send request to the PMU */
609 PM_PACK_PAYLOAD5(payload, PM_FPGA_LOAD, address_high, address_low,
610 size, flags);
Siva Durga Prasad Paladugubf83b9c2018-02-07 13:13:01 +0530611 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530612}
613
614/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530615 * pm_fpga_get_status() - Read value from fpga status register.
616 * @value: Value to read.
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530617 *
618 * This function provides access to the xilfpga library to get
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530619 * the fpga status.
620 *
621 * Return: Returns status, either success or error+reason.
622 *
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530623 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530624enum pm_ret_status pm_fpga_get_status(uint32_t *value)
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530625{
626 uint32_t payload[PAYLOAD_ARG_CNT];
627
628 /* Send request to the PMU */
629 PM_PACK_PAYLOAD1(payload, PM_FPGA_GET_STATUS);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700630 return pm_ipi_send_sync(primary_proc, payload, value, 1);
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530631}
Soren Brinkmanncb366812016-09-22 12:21:11 -0700632
633/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530634 * pm_get_chipid() - Read silicon ID registers.
635 * @value: Buffer for return values. Must be large enough to hold 8 bytes.
Soren Brinkmanncb366812016-09-22 12:21:11 -0700636 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530637 * Return: Returns silicon ID registers.
638 *
Soren Brinkmanncb366812016-09-22 12:21:11 -0700639 */
640enum pm_ret_status pm_get_chipid(uint32_t *value)
641{
642 uint32_t payload[PAYLOAD_ARG_CNT];
643
644 /* Send request to the PMU */
645 PM_PACK_PAYLOAD1(payload, PM_GET_CHIPID);
646 return pm_ipi_send_sync(primary_proc, payload, value, 2);
647}
Soren Brinkmann84f0af42016-09-30 14:24:25 -0700648
649/**
Siva Durga Prasad Paladugude93d982018-04-30 15:49:27 +0530650 * pm_secure_rsaaes() - Load the secure images.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530651 * @address_low: lower 32-bit Linear memory space address.
652 * @address_high: higher 32-bit Linear memory space address.
653 * @size: Number of 32bit words.
654 * @flags: Additional flags or settings for the fpga operation.
Siva Durga Prasad Paladugude93d982018-04-30 15:49:27 +0530655 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530656 * This function provides access to the xilsecure library to load the
657 * authenticated, encrypted, and authenticated/encrypted images.
Siva Durga Prasad Paladugude93d982018-04-30 15:49:27 +0530658 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530659 * Return: Returns status, either success or error+reason.
Siva Durga Prasad Paladugude93d982018-04-30 15:49:27 +0530660 *
Siva Durga Prasad Paladugude93d982018-04-30 15:49:27 +0530661 */
662enum pm_ret_status pm_secure_rsaaes(uint32_t address_low,
663 uint32_t address_high,
664 uint32_t size,
665 uint32_t flags)
666{
667 uint32_t payload[PAYLOAD_ARG_CNT];
668
669 /* Send request to the PMU */
670 PM_PACK_PAYLOAD5(payload, PM_SECURE_RSA_AES, address_high, address_low,
671 size, flags);
672 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
673}
674
675/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530676 * pm_aes_engine() - Aes data blob encryption/decryption.
677 * @address_low: lower 32-bit address of the AesParams structure.
678 * @address_high: higher 32-bit address of the AesParams structure.
679 * @value: Returned output value.
680 *
Siva Durga Prasad Paladugu8bd905b2018-09-04 18:05:50 +0530681 * This function provides access to the xilsecure library to
682 * encrypt/decrypt data blobs.
683 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530684 * Return: Returns status, either success or error+reason.
Siva Durga Prasad Paladugu8bd905b2018-09-04 18:05:50 +0530685 *
Siva Durga Prasad Paladugu8bd905b2018-09-04 18:05:50 +0530686 */
687enum pm_ret_status pm_aes_engine(uint32_t address_high,
688 uint32_t address_low,
689 uint32_t *value)
690{
691 uint32_t payload[PAYLOAD_ARG_CNT];
692
693 /* Send request to the PMU */
694 PM_PACK_PAYLOAD3(payload, PM_SECURE_AES, address_high, address_low);
695 return pm_ipi_send_sync(primary_proc, payload, value, 1);
696}
697
698/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530699 * pm_get_callbackdata() - Read from IPI response buffer.
700 * @data: array of PAYLOAD_ARG_CNT elements.
701 * @count: Number of values to return.
Rajan Vaja02d18422019-03-04 11:09:39 +0530702 *
703 * Read value from ipi buffer response buffer.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530704 * Return: Returns status, either success or error.
705 *
Rajan Vaja02d18422019-03-04 11:09:39 +0530706 */
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530707enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count)
Rajan Vaja02d18422019-03-04 11:09:39 +0530708{
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530709 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vaja02d18422019-03-04 11:09:39 +0530710 /* Return if interrupt is not from PMU */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530711 if (!pm_ipi_irq_status(primary_proc)) {
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530712 return ret;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530713 }
Rajan Vaja02d18422019-03-04 11:09:39 +0530714
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530715 ret = pm_ipi_buff_read_callb(data, count);
Rajan Vaja02d18422019-03-04 11:09:39 +0530716 pm_ipi_irq_clear(primary_proc);
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530717 return ret;
Rajan Vaja02d18422019-03-04 11:09:39 +0530718}
719
720/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530721 * pm_ioctl() - PM IOCTL API for device control and configs.
722 * @nid: Node ID of the device.
723 * @ioctl_id: ID of the requested IOCTL.
724 * @arg1: Argument 1 to requested IOCTL call.
725 * @arg2: Argument 2 to requested IOCTL call.
726 * @value: Returned output value.
Rajan Vaja5529a012018-01-17 02:39:23 -0800727 *
728 * This function calls IOCTL to firmware for device control and configuration.
729 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530730 * Return: Returns status, either success or error+reason.
731 *
Rajan Vaja5529a012018-01-17 02:39:23 -0800732 */
733enum pm_ret_status pm_ioctl(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530734 uint32_t ioctl_id,
735 uint32_t arg1,
736 uint32_t arg2,
737 uint32_t *value)
Rajan Vaja5529a012018-01-17 02:39:23 -0800738{
739 return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
740}
Rajan Vaja35116132018-01-17 02:39:25 -0800741
742/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530743 * fw_api_version() - Returns API version implemented in firmware.
744 * @id: API ID to check.
745 * @version: Returned supported API version.
746 * @len: Number of words to be returned.
747 *
748 * Return: Returns status, either success or error+reason.
Ronak Jain325bad12021-12-21 01:39:59 -0800749 *
Ronak Jain325bad12021-12-21 01:39:59 -0800750 */
751static enum pm_ret_status fw_api_version(uint32_t id, uint32_t *version,
752 uint32_t len)
753{
754 uint32_t payload[PAYLOAD_ARG_CNT];
755
756 PM_PACK_PAYLOAD2(payload, PM_FEATURE_CHECK, id);
757 return pm_ipi_send_sync(primary_proc, payload, version, len);
758}
759
760/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530761 * check_api_dependency() - API to check dependent EEMI API version.
762 * @id: EEMI API ID to check.
763 *
764 * Return: Returns status, either success or error+reason.
Ronak Jain325bad12021-12-21 01:39:59 -0800765 *
Ronak Jain325bad12021-12-21 01:39:59 -0800766 */
767enum pm_ret_status check_api_dependency(uint8_t id)
768{
769 uint8_t i;
770 uint32_t version;
771 int ret;
772
773 for (i = 0U; i < ARRAY_SIZE(api_dep_table); i++) {
774 if (api_dep_table[i].id == id) {
775 if (api_dep_table[i].api_id == 0U) {
776 break;
777 }
778
779 ret = fw_api_version(api_dep_table[i].api_id,
780 &version, 1);
781 if (ret != PM_RET_SUCCESS) {
782 return ret;
783 }
784
Prasad Kummarie0783112023-04-26 11:02:07 +0530785 /* Check if fw version matches TF-A expected version */
786 if (version != tfa_expected_ver_id[api_dep_table[i].api_id]) {
Ronak Jain325bad12021-12-21 01:39:59 -0800787 return PM_RET_ERROR_NOTSUPPORTED;
788 }
789 }
790 }
791
792 return PM_RET_SUCCESS;
793}
794
795/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530796 * feature_check_tfa() - These are API's completely implemented in TF-A.
797 * @api_id: API ID to check.
798 * @version: Returned supported API version.
799 * @bit_mask: Returned supported IOCTL id version.
Ronak Jain325bad12021-12-21 01:39:59 -0800800 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530801 * Return: Returns status, either success or error+reason.
802 *
Ronak Jain325bad12021-12-21 01:39:59 -0800803 */
Prasad Kummarie0783112023-04-26 11:02:07 +0530804static enum pm_ret_status feature_check_tfa(uint32_t api_id, uint32_t *version,
Ronak Jain325bad12021-12-21 01:39:59 -0800805 uint32_t *bit_mask)
806{
807 switch (api_id) {
808 case PM_QUERY_DATA:
Ronak Jain11b084a2023-02-13 04:48:06 -0800809 *version = TFA_API_QUERY_DATA_VERSION;
Ronak Jain325bad12021-12-21 01:39:59 -0800810 bit_mask[0] = (uint32_t)(PM_QUERY_FEATURE_BITMASK);
811 bit_mask[1] = (uint32_t)(PM_QUERY_FEATURE_BITMASK >> 32);
812 return PM_RET_SUCCESS;
813 case PM_GET_CALLBACK_DATA:
814 case PM_GET_TRUSTZONE_VERSION:
815 case PM_SET_SUSPEND_MODE:
Prasad Kummarie0783112023-04-26 11:02:07 +0530816 *version = TFA_API_BASE_VERSION;
Ronak Jain325bad12021-12-21 01:39:59 -0800817 return PM_RET_SUCCESS;
818 default:
819 return PM_RET_ERROR_NO_FEATURE;
820 }
821}
822
823/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530824 * get_tfa_version_for_partial_apis() - Return TF-A version for partially.
825 * implemented APIs
826 * @api_id: API ID to check.
827 * @version: Returned supported API version.
Ronak Jain325bad12021-12-21 01:39:59 -0800828 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530829 * Return: Returns status, either success or error+reason.
830 *
Ronak Jain325bad12021-12-21 01:39:59 -0800831 */
Prasad Kummarie0783112023-04-26 11:02:07 +0530832static enum pm_ret_status get_tfa_version_for_partial_apis(uint32_t api_id,
Ronak Jain325bad12021-12-21 01:39:59 -0800833 uint32_t *version)
834{
835 switch (api_id) {
836 case PM_SELF_SUSPEND:
837 case PM_REQ_WAKEUP:
838 case PM_ABORT_SUSPEND:
839 case PM_SET_WAKEUP_SOURCE:
840 case PM_SYSTEM_SHUTDOWN:
841 case PM_GET_API_VERSION:
842 case PM_CLOCK_ENABLE:
843 case PM_CLOCK_DISABLE:
844 case PM_CLOCK_GETSTATE:
845 case PM_CLOCK_SETDIVIDER:
846 case PM_CLOCK_GETDIVIDER:
847 case PM_CLOCK_SETPARENT:
848 case PM_CLOCK_GETPARENT:
849 case PM_PLL_SET_PARAMETER:
850 case PM_PLL_GET_PARAMETER:
851 case PM_PLL_SET_MODE:
852 case PM_PLL_GET_MODE:
853 case PM_REGISTER_ACCESS:
Prasad Kummarie0783112023-04-26 11:02:07 +0530854 *version = TFA_API_BASE_VERSION;
Ronak Jain325bad12021-12-21 01:39:59 -0800855 return PM_RET_SUCCESS;
856 case PM_FEATURE_CHECK:
857 *version = FW_API_VERSION_2;
858 return PM_RET_SUCCESS;
859 default:
860 return PM_RET_ERROR_ARGS;
861 }
862}
863
864/**
865 * feature_check_partial() - These are API's partially implemented in
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530866 * TF-A and firmware both.
867 * @api_id: API ID to check.
868 * @version: Returned supported API version.
869 *
870 * Return: Returns status, either success or error+reason.
Ronak Jain325bad12021-12-21 01:39:59 -0800871 *
Ronak Jain325bad12021-12-21 01:39:59 -0800872 */
873static enum pm_ret_status feature_check_partial(uint32_t api_id,
874 uint32_t *version)
875{
876 uint32_t status;
877
878 switch (api_id) {
879 case PM_SELF_SUSPEND:
880 case PM_REQ_WAKEUP:
881 case PM_ABORT_SUSPEND:
882 case PM_SET_WAKEUP_SOURCE:
883 case PM_SYSTEM_SHUTDOWN:
884 case PM_GET_API_VERSION:
885 case PM_CLOCK_ENABLE:
886 case PM_CLOCK_DISABLE:
887 case PM_CLOCK_GETSTATE:
888 case PM_CLOCK_SETDIVIDER:
889 case PM_CLOCK_GETDIVIDER:
890 case PM_CLOCK_SETPARENT:
891 case PM_CLOCK_GETPARENT:
892 case PM_PLL_SET_PARAMETER:
893 case PM_PLL_GET_PARAMETER:
894 case PM_PLL_SET_MODE:
895 case PM_PLL_GET_MODE:
896 case PM_REGISTER_ACCESS:
897 case PM_FEATURE_CHECK:
898 status = check_api_dependency(api_id);
899 if (status != PM_RET_SUCCESS) {
900 return status;
901 }
Prasad Kummarie0783112023-04-26 11:02:07 +0530902 return get_tfa_version_for_partial_apis(api_id, version);
Ronak Jain325bad12021-12-21 01:39:59 -0800903 default:
904 return PM_RET_ERROR_NO_FEATURE;
905 }
906}
907
908/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530909 * pm_feature_check() - Returns the supported API version if supported.
910 * @api_id: API ID to check.
911 * @version: Returned supported API version.
912 * @bit_mask: Returned supported IOCTL id version.
913 * @len: Number of bytes to be returned in bit_mask variable.
Ronak Jain325bad12021-12-21 01:39:59 -0800914 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530915 * Return: Returns status, either success or error+reason.
916 *
Ronak Jain325bad12021-12-21 01:39:59 -0800917 */
918enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
919 uint32_t *bit_mask, uint8_t len)
920{
921 uint32_t ret_payload[PAYLOAD_ARG_CNT] = {0U};
922 uint32_t status;
923
Prasad Kummarie0783112023-04-26 11:02:07 +0530924 /* Get API version implemented in TF-A */
925 status = feature_check_tfa(api_id, version, bit_mask);
Ronak Jain325bad12021-12-21 01:39:59 -0800926 if (status != PM_RET_ERROR_NO_FEATURE) {
927 return status;
928 }
929
Prasad Kummarie0783112023-04-26 11:02:07 +0530930 /* Get API version implemented by firmware and TF-A both */
Ronak Jain325bad12021-12-21 01:39:59 -0800931 status = feature_check_partial(api_id, version);
932 if (status != PM_RET_ERROR_NO_FEATURE) {
933 return status;
934 }
935
936 /* Get API version implemented by firmware */
937 status = fw_api_version(api_id, ret_payload, 3);
938 /* IOCTL call may return failure whose ID is not implemented in
Prasad Kummarie0783112023-04-26 11:02:07 +0530939 * firmware but implemented in TF-A
Ronak Jain325bad12021-12-21 01:39:59 -0800940 */
941 if ((api_id != PM_IOCTL) && (status != PM_RET_SUCCESS)) {
942 return status;
943 }
944
945 *version = ret_payload[0];
946
Prasad Kummarie0783112023-04-26 11:02:07 +0530947 /* Update IOCTL bit mask which are implemented in TF-A */
Ronak Jainc443e802023-02-22 04:28:02 -0800948 if ((api_id == PM_IOCTL) || (api_id == PM_GET_OP_CHARACTERISTIC)) {
Ronak Jain325bad12021-12-21 01:39:59 -0800949 if (len < 2) {
950 return PM_RET_ERROR_ARGS;
951 }
952 bit_mask[0] = ret_payload[1];
953 bit_mask[1] = ret_payload[2];
Ronak Jainc443e802023-02-22 04:28:02 -0800954 if (api_id == PM_IOCTL) {
Prasad Kummarie0783112023-04-26 11:02:07 +0530955 /* Get IOCTL's implemented by TF-A */
956 status = tfa_ioctl_bitmask(bit_mask);
Ronak Jainc443e802023-02-22 04:28:02 -0800957 }
Ronak Jain325bad12021-12-21 01:39:59 -0800958 } else {
959 /* Requires for MISRA */
960 }
961
962 return status;
963}
964
965/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530966 * pm_clock_get_max_divisor - PM call to get max divisor.
967 * @clock_id: Clock ID.
968 * @div_type: Divisor ID (TYPE_DIV1 or TYPE_DIV2).
969 * @max_div: Maximum supported divisor.
Rajan Vajab34deca2019-03-20 01:13:21 +0530970 *
971 * This function is used by master to get maximum supported value.
972 *
973 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530974 *
Rajan Vajab34deca2019-03-20 01:13:21 +0530975 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530976static enum pm_ret_status pm_clock_get_max_divisor(uint32_t clock_id,
Rajan Vajab34deca2019-03-20 01:13:21 +0530977 uint8_t div_type,
978 uint32_t *max_div)
979{
980 return pm_api_clock_get_max_divisor(clock_id, div_type, max_div);
981}
982
983/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530984 * pm_clock_get_num_clocks - PM call to request number of clocks.
985 * @nclocks: Number of clocks.
Rajan Vajada959402018-07-20 03:16:27 -0700986 *
987 * This function is used by master to get number of clocks.
988 *
989 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530990 *
Rajan Vajada959402018-07-20 03:16:27 -0700991 */
992static enum pm_ret_status pm_clock_get_num_clocks(uint32_t *nclocks)
993{
994 return pm_api_clock_get_num_clocks(nclocks);
995}
996
997/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530998 * pm_clock_get_name() - PM call to request a clock's name.
999 * @clock_id: Clock ID.
1000 * @name: Name of clock (max 16 bytes).
Rajan Vaja35116132018-01-17 02:39:25 -08001001 *
1002 * This function is used by master to get nmae of clock specified
1003 * by given clock ID.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301004 *
Rajan Vaja35116132018-01-17 02:39:25 -08001005 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301006static void pm_clock_get_name(uint32_t clock_id, char *name)
Rajan Vaja35116132018-01-17 02:39:25 -08001007{
Rajan Vajacd825682020-11-23 21:33:39 -08001008 pm_api_clock_get_name(clock_id, name);
Rajan Vaja35116132018-01-17 02:39:25 -08001009}
1010
1011/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301012 * pm_clock_get_topology() - PM call to request a clock's topology.
1013 * @clock_id: Clock ID.
1014 * @index: Topology index for next toplogy node.
1015 * @topology: Buffer to store nodes in topology and flags.
Rajan Vaja35116132018-01-17 02:39:25 -08001016 *
1017 * This function is used by master to get topology information for the
1018 * clock specified by given clock ID. Each response would return 3
1019 * topology nodes. To get next nodes, caller needs to call this API with
1020 * index of next node. Index starts from 0.
1021 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301022 * Return: Returns status, either success or error+reason.
1023 *
Rajan Vaja35116132018-01-17 02:39:25 -08001024 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301025static enum pm_ret_status pm_clock_get_topology(uint32_t clock_id,
1026 uint32_t index,
Rajan Vaja35116132018-01-17 02:39:25 -08001027 uint32_t *topology)
1028{
1029 return pm_api_clock_get_topology(clock_id, index, topology);
1030}
1031
1032/**
1033 * pm_clock_get_fixedfactor_params() - PM call to request a clock's fixed factor
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301034 * parameters for fixed clock.
1035 * @clock_id: Clock ID.
1036 * @mul: Multiplication value.
1037 * @div: Divisor value.
Rajan Vaja35116132018-01-17 02:39:25 -08001038 *
1039 * This function is used by master to get fixed factor parameers for the
1040 * fixed clock. This API is application only for the fixed clock.
1041 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301042 * Return: Returns status, either success or error+reason.
1043 *
Rajan Vaja35116132018-01-17 02:39:25 -08001044 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301045static enum pm_ret_status pm_clock_get_fixedfactor_params(uint32_t clock_id,
Rajan Vaja35116132018-01-17 02:39:25 -08001046 uint32_t *mul,
1047 uint32_t *div)
1048{
1049 return pm_api_clock_get_fixedfactor_params(clock_id, mul, div);
1050}
1051
1052/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301053 * pm_clock_get_parents() - PM call to request a clock's first 3 parents.
1054 * @clock_id: Clock ID.
1055 * @index: Index of next parent.
1056 * @parents: Parents of the given clock.
Rajan Vaja35116132018-01-17 02:39:25 -08001057 *
1058 * This function is used by master to get clock's parents information.
1059 * This API will return 3 parents with a single response. To get other
1060 * parents, master should call same API in loop with new parent index
1061 * till error is returned.
1062 *
1063 * E.g First call should have index 0 which will return parents 0, 1 and
1064 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
1065 * so on.
1066 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301067 * Return: Returns status, either success or error+reason.
1068 *
Rajan Vaja35116132018-01-17 02:39:25 -08001069 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301070static enum pm_ret_status pm_clock_get_parents(uint32_t clock_id,
1071 uint32_t index,
Rajan Vaja35116132018-01-17 02:39:25 -08001072 uint32_t *parents)
1073{
1074 return pm_api_clock_get_parents(clock_id, index, parents);
1075}
1076
1077/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301078 * pm_clock_get_attributes() - PM call to request a clock's attributes.
1079 * @clock_id: Clock ID.
1080 * @attr: Clock attributes.
Rajan Vaja35116132018-01-17 02:39:25 -08001081 *
1082 * This function is used by master to get clock's attributes
1083 * (e.g. valid, clock type, etc).
1084 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301085 * Return: Returns status, either success or error+reason.
1086 *
Rajan Vaja35116132018-01-17 02:39:25 -08001087 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301088static enum pm_ret_status pm_clock_get_attributes(uint32_t clock_id,
Rajan Vaja35116132018-01-17 02:39:25 -08001089 uint32_t *attr)
1090{
1091 return pm_api_clock_get_attributes(clock_id, attr);
1092}
1093
1094/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301095 * pm_clock_gate() - Configure clock gate.
1096 * @clock_id: Id of the clock to be configured.
1097 * @enable: Flag 0=disable (gate the clock), !0=enable (activate the clock).
Jolly Shaha5209802019-01-04 11:45:59 -08001098 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301099 * Return: Error if an argument is not valid or status as returned by the
1100 * PM controller (PMU).
1101 *
Jolly Shaha5209802019-01-04 11:45:59 -08001102 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301103static enum pm_ret_status pm_clock_gate(uint32_t clock_id,
1104 uint8_t enable)
Jolly Shaha5209802019-01-04 11:45:59 -08001105{
1106 uint32_t payload[PAYLOAD_ARG_CNT];
1107 enum pm_ret_status status;
1108 enum pm_api_id api_id;
1109
1110 /* Check if clock ID is valid and return an error if it is not */
1111 status = pm_clock_id_is_valid(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301112 if (status != PM_RET_SUCCESS) {
Jolly Shaha5209802019-01-04 11:45:59 -08001113 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301114 }
Jolly Shaha5209802019-01-04 11:45:59 -08001115
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301116 if (enable) {
Jolly Shaha5209802019-01-04 11:45:59 -08001117 api_id = PM_CLOCK_ENABLE;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301118 } else {
Jolly Shaha5209802019-01-04 11:45:59 -08001119 api_id = PM_CLOCK_DISABLE;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301120 }
Jolly Shaha5209802019-01-04 11:45:59 -08001121
1122 /* Send request to the PMU */
1123 PM_PACK_PAYLOAD2(payload, api_id, clock_id);
Mirela Simonovic64514a72018-08-24 17:09:07 +02001124 status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1125
1126 /* If action fails due to the lack of permissions filter the error */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301127 if (status == PM_RET_ERROR_ACCESS) {
Mirela Simonovic64514a72018-08-24 17:09:07 +02001128 status = PM_RET_SUCCESS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301129 }
Mirela Simonovic64514a72018-08-24 17:09:07 +02001130
1131 return status;
Jolly Shaha5209802019-01-04 11:45:59 -08001132}
1133
1134/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301135 * pm_clock_enable() - Enable the clock for given id.
1136 * @clock_id: Id of the clock to be enabled.
Rajan Vaja35116132018-01-17 02:39:25 -08001137 *
1138 * This function is used by master to enable the clock
1139 * including peripherals and PLL clocks.
1140 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301141 * Return: Error if an argument is not valid or status as returned by the
1142 * pm_clock_gate.
1143 *
Rajan Vaja35116132018-01-17 02:39:25 -08001144 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301145enum pm_ret_status pm_clock_enable(uint32_t clock_id)
Rajan Vaja35116132018-01-17 02:39:25 -08001146{
Jolly Shaha5209802019-01-04 11:45:59 -08001147 struct pm_pll *pll;
1148
1149 /* First try to handle it as a PLL */
1150 pll = pm_clock_get_pll(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301151 if (pll) {
Jolly Shaha5209802019-01-04 11:45:59 -08001152 return pm_clock_pll_enable(pll);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301153 }
Jolly Shaha5209802019-01-04 11:45:59 -08001154
1155 /* It's an on-chip clock, PMU should configure clock's gate */
1156 return pm_clock_gate(clock_id, 1);
Rajan Vaja35116132018-01-17 02:39:25 -08001157}
1158
1159/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301160 * pm_clock_disable - Disable the clock for given id.
1161 * @clock_id: Id of the clock to be disable.
Rajan Vaja35116132018-01-17 02:39:25 -08001162 *
1163 * This function is used by master to disable the clock
1164 * including peripherals and PLL clocks.
1165 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301166 * Return: Error if an argument is not valid or status as returned by the
1167 * pm_clock_gate
1168 *
Rajan Vaja35116132018-01-17 02:39:25 -08001169 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301170enum pm_ret_status pm_clock_disable(uint32_t clock_id)
Rajan Vaja35116132018-01-17 02:39:25 -08001171{
Jolly Shaha9057a02019-01-02 12:54:40 -08001172 struct pm_pll *pll;
1173
1174 /* First try to handle it as a PLL */
1175 pll = pm_clock_get_pll(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301176 if (pll) {
Jolly Shaha9057a02019-01-02 12:54:40 -08001177 return pm_clock_pll_disable(pll);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301178 }
Jolly Shaha9057a02019-01-02 12:54:40 -08001179
1180 /* It's an on-chip clock, PMU should configure clock's gate */
1181 return pm_clock_gate(clock_id, 0);
Rajan Vaja35116132018-01-17 02:39:25 -08001182}
1183
1184/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301185 * pm_clock_getstate - Get the clock state for given id.
1186 * @clock_id: Id of the clock to be queried.
1187 * @state: 1/0 (Enabled/Disabled).
Rajan Vaja35116132018-01-17 02:39:25 -08001188 *
1189 * This function is used by master to get the state of clock
1190 * including peripherals and PLL clocks.
1191 *
1192 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301193 *
Rajan Vaja35116132018-01-17 02:39:25 -08001194 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301195enum pm_ret_status pm_clock_getstate(uint32_t clock_id,
1196 uint32_t *state)
Rajan Vaja35116132018-01-17 02:39:25 -08001197{
Jolly Shah99e8ac92019-01-02 12:55:41 -08001198 struct pm_pll *pll;
1199 uint32_t payload[PAYLOAD_ARG_CNT];
1200 enum pm_ret_status status;
1201
1202 /* First try to handle it as a PLL */
1203 pll = pm_clock_get_pll(clock_id);
1204 if (pll)
1205 return pm_clock_pll_get_state(pll, state);
1206
1207 /* Check if clock ID is a valid on-chip clock */
1208 status = pm_clock_id_is_valid(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301209 if (status != PM_RET_SUCCESS) {
Jolly Shah99e8ac92019-01-02 12:55:41 -08001210 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301211 }
Jolly Shah99e8ac92019-01-02 12:55:41 -08001212
1213 /* Send request to the PMU */
1214 PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETSTATE, clock_id);
1215 return pm_ipi_send_sync(primary_proc, payload, state, 1);
Rajan Vaja35116132018-01-17 02:39:25 -08001216}
1217
1218/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301219 * pm_clock_setdivider - Set the clock divider for given id.
1220 * @clock_id: Id of the clock.
1221 * @divider: divider value.
Rajan Vaja35116132018-01-17 02:39:25 -08001222 *
1223 * This function is used by master to set divider for any clock
1224 * to achieve desired rate.
1225 *
1226 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301227 *
Rajan Vaja35116132018-01-17 02:39:25 -08001228 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301229enum pm_ret_status pm_clock_setdivider(uint32_t clock_id,
1230 uint32_t divider)
Rajan Vaja35116132018-01-17 02:39:25 -08001231{
Jolly Shah8b4c4c72019-01-04 11:49:46 -08001232 enum pm_ret_status status;
1233 enum pm_node_id nid;
1234 enum pm_clock_div_id div_id;
1235 uint32_t payload[PAYLOAD_ARG_CNT];
1236 const uint32_t div0 = 0xFFFF0000;
1237 const uint32_t div1 = 0x0000FFFF;
1238 uint32_t val;
1239
1240 /* Get PLL node ID using PLL clock ID */
1241 status = pm_clock_get_pll_node_id(clock_id, &nid);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301242 if (status == PM_RET_SUCCESS) {
Jolly Shah8b4c4c72019-01-04 11:49:46 -08001243 return pm_pll_set_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301244 }
Jolly Shah8b4c4c72019-01-04 11:49:46 -08001245
1246 /* Check if clock ID is a valid on-chip clock */
1247 status = pm_clock_id_is_valid(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301248 if (status != PM_RET_SUCCESS) {
Jolly Shah8b4c4c72019-01-04 11:49:46 -08001249 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301250 }
Jolly Shah8b4c4c72019-01-04 11:49:46 -08001251
1252 if (div0 == (divider & div0)) {
1253 div_id = PM_CLOCK_DIV0_ID;
1254 val = divider & ~div0;
1255 } else if (div1 == (divider & div1)) {
1256 div_id = PM_CLOCK_DIV1_ID;
1257 val = (divider & ~div1) >> 16;
1258 } else {
1259 return PM_RET_ERROR_ARGS;
1260 }
1261
1262 /* Send request to the PMU */
1263 PM_PACK_PAYLOAD4(payload, PM_CLOCK_SETDIVIDER, clock_id, div_id, val);
1264 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Rajan Vaja35116132018-01-17 02:39:25 -08001265}
1266
1267/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301268 * pm_clock_getdivider - Get the clock divider for given id.
1269 * @clock_id: Id of the clock.
1270 * @divider: divider value.
Rajan Vaja35116132018-01-17 02:39:25 -08001271 *
1272 * This function is used by master to get divider values
1273 * for any clock.
1274 *
1275 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301276 *
Rajan Vaja35116132018-01-17 02:39:25 -08001277 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301278enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
1279 uint32_t *divider)
Rajan Vaja35116132018-01-17 02:39:25 -08001280{
Jolly Shah4dd11762019-01-04 11:53:37 -08001281 enum pm_ret_status status;
1282 enum pm_node_id nid;
1283 uint32_t payload[PAYLOAD_ARG_CNT];
1284 uint32_t val;
1285
1286 /* Get PLL node ID using PLL clock ID */
1287 status = pm_clock_get_pll_node_id(clock_id, &nid);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301288 if (status == PM_RET_SUCCESS) {
Jolly Shah4dd11762019-01-04 11:53:37 -08001289 return pm_pll_get_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301290 }
Jolly Shah4dd11762019-01-04 11:53:37 -08001291
1292 /* Check if clock ID is a valid on-chip clock */
1293 status = pm_clock_id_is_valid(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301294 if (status != PM_RET_SUCCESS) {
Jolly Shah4dd11762019-01-04 11:53:37 -08001295 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301296 }
Jolly Shah4dd11762019-01-04 11:53:37 -08001297
1298 if (pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) {
1299 /* Send request to the PMU to get div0 */
1300 PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
1301 PM_CLOCK_DIV0_ID);
1302 status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301303 if (status != PM_RET_SUCCESS) {
Jolly Shah4dd11762019-01-04 11:53:37 -08001304 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301305 }
Jolly Shah4dd11762019-01-04 11:53:37 -08001306 *divider = val;
1307 }
1308
1309 if (pm_clock_has_div(clock_id, PM_CLOCK_DIV1_ID)) {
1310 /* Send request to the PMU to get div1 */
1311 PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
1312 PM_CLOCK_DIV1_ID);
1313 status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301314 if (status != PM_RET_SUCCESS) {
Jolly Shah4dd11762019-01-04 11:53:37 -08001315 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301316 }
Jolly Shah4dd11762019-01-04 11:53:37 -08001317 *divider |= val << 16;
1318 }
1319
1320 return status;
Rajan Vaja35116132018-01-17 02:39:25 -08001321}
1322
1323/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301324 * pm_clock_setrate - Set the clock rate for given id.
1325 * @clock_id: Id of the clock.
1326 * @rate: rate value in hz.
Rajan Vaja35116132018-01-17 02:39:25 -08001327 *
1328 * This function is used by master to set rate for any clock.
1329 *
1330 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301331 *
Rajan Vaja35116132018-01-17 02:39:25 -08001332 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301333enum pm_ret_status pm_clock_setrate(uint32_t clock_id,
Rajan Vaja35116132018-01-17 02:39:25 -08001334 uint64_t rate)
1335{
Jolly Shahc1391812019-01-02 13:39:30 -08001336 return PM_RET_ERROR_NOTSUPPORTED;
Rajan Vaja35116132018-01-17 02:39:25 -08001337}
1338
1339/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301340 * pm_clock_getrate - Get the clock rate for given id.
1341 * @clock_id: Id of the clock.
1342 * @rate: rate value in hz.
Rajan Vaja35116132018-01-17 02:39:25 -08001343 *
1344 * This function is used by master to get rate
1345 * for any clock.
1346 *
1347 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301348 *
Rajan Vaja35116132018-01-17 02:39:25 -08001349 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301350enum pm_ret_status pm_clock_getrate(uint32_t clock_id,
Rajan Vaja35116132018-01-17 02:39:25 -08001351 uint64_t *rate)
1352{
Jolly Shahc1391812019-01-02 13:39:30 -08001353 return PM_RET_ERROR_NOTSUPPORTED;
Rajan Vaja35116132018-01-17 02:39:25 -08001354}
1355
1356/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301357 * pm_clock_setparent - Set the clock parent for given id.
1358 * @clock_id: Id of the clock.
1359 * @parent_index: Index of the parent clock into clock's parents array.
Rajan Vaja35116132018-01-17 02:39:25 -08001360 *
1361 * This function is used by master to set parent for any clock.
1362 *
1363 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301364 *
Rajan Vaja35116132018-01-17 02:39:25 -08001365 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301366enum pm_ret_status pm_clock_setparent(uint32_t clock_id,
1367 uint32_t parent_index)
Rajan Vaja35116132018-01-17 02:39:25 -08001368{
Jolly Shah407fc0a2019-01-04 11:57:40 -08001369 struct pm_pll *pll;
1370 uint32_t payload[PAYLOAD_ARG_CNT];
1371 enum pm_ret_status status;
1372
1373 /* First try to handle it as a PLL */
1374 pll = pm_clock_get_pll_by_related_clk(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301375 if (pll) {
Jolly Shah407fc0a2019-01-04 11:57:40 -08001376 return pm_clock_pll_set_parent(pll, clock_id, parent_index);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301377 }
Jolly Shah407fc0a2019-01-04 11:57:40 -08001378
1379 /* Check if clock ID is a valid on-chip clock */
1380 status = pm_clock_id_is_valid(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301381 if (status != PM_RET_SUCCESS) {
Jolly Shah407fc0a2019-01-04 11:57:40 -08001382 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301383 }
Jolly Shah407fc0a2019-01-04 11:57:40 -08001384
1385 /* Send request to the PMU */
1386 PM_PACK_PAYLOAD3(payload, PM_CLOCK_SETPARENT, clock_id, parent_index);
1387 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Rajan Vaja35116132018-01-17 02:39:25 -08001388}
1389
1390/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301391 * pm_clock_getparent - Get the clock parent for given id.
1392 * @clock_id: Id of the clock.
1393 * @parent_index: parent index.
Rajan Vaja35116132018-01-17 02:39:25 -08001394 *
1395 * This function is used by master to get parent index
1396 * for any clock.
1397 *
1398 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301399 *
Rajan Vaja35116132018-01-17 02:39:25 -08001400 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301401enum pm_ret_status pm_clock_getparent(uint32_t clock_id,
1402 uint32_t *parent_index)
Rajan Vaja35116132018-01-17 02:39:25 -08001403{
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001404 struct pm_pll *pll;
1405 uint32_t payload[PAYLOAD_ARG_CNT];
1406 enum pm_ret_status status;
1407
1408 /* First try to handle it as a PLL */
1409 pll = pm_clock_get_pll_by_related_clk(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301410 if (pll) {
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001411 return pm_clock_pll_get_parent(pll, clock_id, parent_index);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301412 }
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001413
1414 /* Check if clock ID is a valid on-chip clock */
1415 status = pm_clock_id_is_valid(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301416 if (status != PM_RET_SUCCESS) {
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001417 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301418 }
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001419
1420 /* Send request to the PMU */
1421 PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETPARENT, clock_id);
1422 return pm_ipi_send_sync(primary_proc, payload, parent_index, 1);
Rajan Vaja35116132018-01-17 02:39:25 -08001423}
1424
1425/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301426 * pm_pinctrl_get_num_pins - PM call to request number of pins.
1427 * @npins: Number of pins.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001428 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301429 * This function is used by master to get number of pins.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001430 *
1431 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301432 *
Rajan Vajad5dd8362018-01-30 04:16:31 -08001433 */
1434static enum pm_ret_status pm_pinctrl_get_num_pins(uint32_t *npins)
1435{
1436 return pm_api_pinctrl_get_num_pins(npins);
1437}
1438
1439/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301440 * pm_pinctrl_get_num_functions - PM call to request number of functions.
1441 * @nfuncs: Number of functions.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001442 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301443 * This function is used by master to get number of functions.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001444 *
1445 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301446 *
Rajan Vajad5dd8362018-01-30 04:16:31 -08001447 */
1448static enum pm_ret_status pm_pinctrl_get_num_functions(uint32_t *nfuncs)
1449{
1450 return pm_api_pinctrl_get_num_functions(nfuncs);
1451}
1452
1453/**
1454 * pm_pinctrl_get_num_function_groups - PM call to request number of
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301455 * function groups.
1456 * @fid: Id of function.
1457 * @ngroups: Number of function groups.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001458 *
1459 * This function is used by master to get number of function groups specified
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301460 * by given function Id.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001461 *
1462 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301463 *
Rajan Vajad5dd8362018-01-30 04:16:31 -08001464 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301465static enum pm_ret_status pm_pinctrl_get_num_function_groups(uint32_t fid,
Rajan Vajad5dd8362018-01-30 04:16:31 -08001466 uint32_t *ngroups)
1467{
1468 return pm_api_pinctrl_get_num_func_groups(fid, ngroups);
1469}
1470
1471/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301472 * pm_pinctrl_get_function_name - PM call to request function name.
1473 * @fid: Id of function.
1474 * @name: Name of function.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001475 *
1476 * This function is used by master to get name of function specified
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301477 * by given function Id.
1478 *
Rajan Vajad5dd8362018-01-30 04:16:31 -08001479 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301480static void pm_pinctrl_get_function_name(uint32_t fid, char *name)
Rajan Vajad5dd8362018-01-30 04:16:31 -08001481{
Rajan Vajacd825682020-11-23 21:33:39 -08001482 pm_api_pinctrl_get_function_name(fid, name);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001483}
1484
1485/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301486 * pm_pinctrl_get_function_groups - PM call to request function groups.
1487 * @fid: Id of function.
1488 * @index: Index of next function groups.
1489 * @groups: Function groups.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001490 *
1491 * This function is used by master to get function groups specified
1492 * by given function Id. This API will return 6 function groups with
1493 * a single response. To get other function groups, master should call
1494 * same API in loop with new function groups index till error is returned.
1495 *
1496 * E.g First call should have index 0 which will return function groups
1497 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
1498 * function groups 6, 7, 8, 9, 10 and 11 and so on.
1499 *
1500 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301501 *
Rajan Vajad5dd8362018-01-30 04:16:31 -08001502 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301503static enum pm_ret_status pm_pinctrl_get_function_groups(uint32_t fid,
1504 uint32_t index,
Rajan Vajad5dd8362018-01-30 04:16:31 -08001505 uint16_t *groups)
1506{
1507 return pm_api_pinctrl_get_function_groups(fid, index, groups);
1508}
1509
1510/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301511 * pm_pinctrl_get_pin_groups - PM call to request pin groups.
1512 * @pin_id: Id of pin.
1513 * @index: Index of next pin groups.
1514 * @groups: pin groups.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001515 *
1516 * This function is used by master to get pin groups specified
1517 * by given pin Id. This API will return 6 pin groups with
1518 * a single response. To get other pin groups, master should call
1519 * same API in loop with new pin groups index till error is returned.
1520 *
1521 * E.g First call should have index 0 which will return pin groups
1522 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
1523 * pin groups 6, 7, 8, 9, 10 and 11 and so on.
1524 *
1525 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301526 *
Rajan Vajad5dd8362018-01-30 04:16:31 -08001527 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301528static enum pm_ret_status pm_pinctrl_get_pin_groups(uint32_t pin_id,
1529 uint32_t index,
Rajan Vajad5dd8362018-01-30 04:16:31 -08001530 uint16_t *groups)
1531{
1532 return pm_api_pinctrl_get_pin_groups(pin_id, index, groups);
1533}
1534
1535/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301536 * pm_query_data() - PM API for querying firmware data.
1537 * @qid: represents the query identifiers for PM.
1538 * @arg1: Argument 1 to requested IOCTL call.
1539 * @arg2: Argument 2 to requested IOCTL call.
1540 * @arg3: Argument 3 to requested IOCTL call.
1541 * @data: Returned output data.
Rajan Vaja35116132018-01-17 02:39:25 -08001542 *
1543 * This function returns requested data.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301544 *
Rajan Vaja35116132018-01-17 02:39:25 -08001545 */
Jay Buddhabhatti5b9f3912023-02-02 22:34:03 -08001546void pm_query_data(enum pm_query_ids qid, uint32_t arg1, uint32_t arg2,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301547 uint32_t arg3, uint32_t *data)
Rajan Vaja35116132018-01-17 02:39:25 -08001548{
Rajan Vaja35116132018-01-17 02:39:25 -08001549 switch (qid) {
1550 case PM_QID_CLOCK_GET_NAME:
Rajan Vajacd825682020-11-23 21:33:39 -08001551 pm_clock_get_name(arg1, (char *)data);
Rajan Vaja35116132018-01-17 02:39:25 -08001552 break;
1553 case PM_QID_CLOCK_GET_TOPOLOGY:
Rajan Vajacd825682020-11-23 21:33:39 -08001554 data[0] = pm_clock_get_topology(arg1, arg2, &data[1]);
Rajan Vaja35116132018-01-17 02:39:25 -08001555 break;
1556 case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
Rajan Vajacd825682020-11-23 21:33:39 -08001557 data[0] = pm_clock_get_fixedfactor_params(arg1, &data[1],
1558 &data[2]);
Rajan Vaja35116132018-01-17 02:39:25 -08001559 break;
1560 case PM_QID_CLOCK_GET_PARENTS:
Rajan Vajacd825682020-11-23 21:33:39 -08001561 data[0] = pm_clock_get_parents(arg1, arg2, &data[1]);
Rajan Vaja35116132018-01-17 02:39:25 -08001562 break;
1563 case PM_QID_CLOCK_GET_ATTRIBUTES:
Rajan Vajacd825682020-11-23 21:33:39 -08001564 data[0] = pm_clock_get_attributes(arg1, &data[1]);
Rajan Vaja35116132018-01-17 02:39:25 -08001565 break;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001566 case PM_QID_PINCTRL_GET_NUM_PINS:
Rajan Vajacd825682020-11-23 21:33:39 -08001567 data[0] = pm_pinctrl_get_num_pins(&data[1]);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001568 break;
1569 case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
Rajan Vajacd825682020-11-23 21:33:39 -08001570 data[0] = pm_pinctrl_get_num_functions(&data[1]);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001571 break;
1572 case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
Rajan Vajacd825682020-11-23 21:33:39 -08001573 data[0] = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001574 break;
1575 case PM_QID_PINCTRL_GET_FUNCTION_NAME:
Rajan Vajacd825682020-11-23 21:33:39 -08001576 pm_pinctrl_get_function_name(arg1, (char *)data);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001577 break;
1578 case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
Rajan Vajacd825682020-11-23 21:33:39 -08001579 data[0] = pm_pinctrl_get_function_groups(arg1, arg2,
1580 (uint16_t *)&data[1]);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001581 break;
1582 case PM_QID_PINCTRL_GET_PIN_GROUPS:
Rajan Vajacd825682020-11-23 21:33:39 -08001583 data[0] = pm_pinctrl_get_pin_groups(arg1, arg2,
1584 (uint16_t *)&data[1]);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001585 break;
Rajan Vajada959402018-07-20 03:16:27 -07001586 case PM_QID_CLOCK_GET_NUM_CLOCKS:
Rajan Vajacd825682020-11-23 21:33:39 -08001587 data[0] = pm_clock_get_num_clocks(&data[1]);
Rajan Vajada959402018-07-20 03:16:27 -07001588 break;
Rajan Vajab34deca2019-03-20 01:13:21 +05301589
1590 case PM_QID_CLOCK_GET_MAX_DIVISOR:
Rajan Vajacd825682020-11-23 21:33:39 -08001591 data[0] = pm_clock_get_max_divisor(arg1, arg2, &data[1]);
Rajan Vajab34deca2019-03-20 01:13:21 +05301592 break;
Rajan Vaja35116132018-01-17 02:39:25 -08001593 default:
Rajan Vajacd825682020-11-23 21:33:39 -08001594 data[0] = PM_RET_ERROR_ARGS;
Rajan Vaja35116132018-01-17 02:39:25 -08001595 WARN("Unimplemented query service call: 0x%x\n", qid);
Venkatesh Yadav Abbarapu41886f72022-04-29 15:17:13 +05301596 break;
Rajan Vaja35116132018-01-17 02:39:25 -08001597 }
Rajan Vaja35116132018-01-17 02:39:25 -08001598}
Siva Durga Prasad Paladuguf3994cc2018-05-01 11:12:55 +05301599
1600enum pm_ret_status pm_sha_hash(uint32_t address_high,
1601 uint32_t address_low,
1602 uint32_t size,
1603 uint32_t flags)
1604{
1605 uint32_t payload[PAYLOAD_ARG_CNT];
1606
1607 /* Send request to the PMU */
1608 PM_PACK_PAYLOAD5(payload, PM_SECURE_SHA, address_high, address_low,
1609 size, flags);
1610 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1611}
1612
1613enum pm_ret_status pm_rsa_core(uint32_t address_high,
1614 uint32_t address_low,
1615 uint32_t size,
1616 uint32_t flags)
1617{
1618 uint32_t payload[PAYLOAD_ARG_CNT];
1619
1620 /* Send request to the PMU */
1621 PM_PACK_PAYLOAD5(payload, PM_SECURE_RSA, address_high, address_low,
1622 size, flags);
1623 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1624}
Siva Durga Prasad Paladugua4ed4b22018-04-30 20:06:58 +05301625
1626enum pm_ret_status pm_secure_image(uint32_t address_low,
1627 uint32_t address_high,
1628 uint32_t key_lo,
1629 uint32_t key_hi,
1630 uint32_t *value)
1631{
1632 uint32_t payload[PAYLOAD_ARG_CNT];
1633
1634 /* Send request to the PMU */
1635 PM_PACK_PAYLOAD5(payload, PM_SECURE_IMAGE, address_high, address_low,
1636 key_hi, key_lo);
1637 return pm_ipi_send_sync(primary_proc, payload, value, 2);
1638}
Siva Durga Prasad Paladugu7c6516a2018-09-04 17:41:34 +05301639
1640/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301641 * pm_fpga_read - Perform the fpga configuration readback.
1642 * @reg_numframes: Configuration register offset (or) Number of frames to read.
1643 * @address_low: lower 32-bit Linear memory space address.
1644 * @address_high: higher 32-bit Linear memory space address.
1645 * @readback_type: Type of fpga readback operation.
1646 * 0 -- Configuration Register readback.
1647 * 1 -- Configuration Data readback.
1648 * @value: Value to read.
Siva Durga Prasad Paladugu7c6516a2018-09-04 17:41:34 +05301649 *
1650 * This function provides access to the xilfpga library to read
1651 * the PL configuration.
1652 *
1653 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301654 *
Siva Durga Prasad Paladugu7c6516a2018-09-04 17:41:34 +05301655 */
1656enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
1657 uint32_t address_low,
1658 uint32_t address_high,
1659 uint32_t readback_type,
1660 uint32_t *value)
1661{
1662 uint32_t payload[PAYLOAD_ARG_CNT];
1663
1664 /* Send request to the PMU */
1665 PM_PACK_PAYLOAD5(payload, PM_FPGA_READ, reg_numframes, address_low,
1666 address_high, readback_type);
1667 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1668}
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001669
1670/*
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301671 * pm_pll_set_parameter() - Set the PLL parameter value.
1672 * @nid: Node id of the target PLL.
1673 * @param_id: ID of the PLL parameter.
1674 * @value: Parameter value to be set.
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001675 *
1676 * Setting the parameter will have physical effect once the PLL mode is set to
1677 * integer or fractional.
1678 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301679 * Return: Error if an argument is not valid or status as returned by the
1680 * PM controller (PMU).
1681 *
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001682 */
1683enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
1684 enum pm_pll_param param_id,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301685 uint32_t value)
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001686{
1687 uint32_t payload[PAYLOAD_ARG_CNT];
1688
1689 /* Check if given node ID is a PLL node */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301690 if (nid < NODE_APLL || nid > NODE_IOPLL) {
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001691 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301692 }
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001693
1694 /* Check if parameter ID is valid and return an error if it's not */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301695 if (param_id >= PM_PLL_PARAM_MAX) {
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001696 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301697 }
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001698
1699 /* Send request to the PMU */
1700 PM_PACK_PAYLOAD4(payload, PM_PLL_SET_PARAMETER, nid, param_id, value);
1701 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1702}
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001703
1704/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301705 * pm_pll_get_parameter() - Get the PLL parameter value.
1706 * @nid: Node id of the target PLL.
1707 * @param_id: ID of the PLL parameter.
1708 * @value: Location to store the parameter value.
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001709 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301710 * Return: Error if an argument is not valid or status as returned by the
1711 * PM controller (PMU).
1712 *
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001713 */
1714enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
1715 enum pm_pll_param param_id,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301716 uint32_t *value)
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001717{
1718 uint32_t payload[PAYLOAD_ARG_CNT];
1719
1720 /* Check if given node ID is a PLL node */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301721 if (nid < NODE_APLL || nid > NODE_IOPLL) {
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001722 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301723 }
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001724
1725 /* Check if parameter ID is valid and return an error if it's not */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301726 if (param_id >= PM_PLL_PARAM_MAX) {
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001727 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301728 }
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001729
1730 /* Send request to the PMU */
1731 PM_PACK_PAYLOAD3(payload, PM_PLL_GET_PARAMETER, nid, param_id);
1732 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1733}
Jolly Shah1f0d5852019-01-04 11:32:31 -08001734
1735/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301736 * pm_pll_set_mode() - Set the PLL mode.
1737 * @nid: Node id of the target PLL.
1738 * @mode: PLL mode to be set.
Jolly Shah1f0d5852019-01-04 11:32:31 -08001739 *
1740 * If reset mode is set the PM controller will first bypass the PLL and then
1741 * assert the reset. If integer or fractional mode is set the PM controller will
1742 * ensure that the complete PLL programming sequence is satisfied. After this
1743 * function returns success the PLL is locked and its bypass is deasserted.
1744 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301745 * Return: Error if an argument is not valid or status as returned by the
1746 * PM controller (PMU).
1747 *
Jolly Shah1f0d5852019-01-04 11:32:31 -08001748 */
1749enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode)
1750{
1751 uint32_t payload[PAYLOAD_ARG_CNT];
1752
1753 /* Check if given node ID is a PLL node */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301754 if (nid < NODE_APLL || nid > NODE_IOPLL) {
Jolly Shah1f0d5852019-01-04 11:32:31 -08001755 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301756 }
Jolly Shah1f0d5852019-01-04 11:32:31 -08001757
1758 /* Check if PLL mode is valid */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301759 if (mode >= PM_PLL_MODE_MAX) {
Jolly Shah1f0d5852019-01-04 11:32:31 -08001760 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301761 }
Jolly Shah1f0d5852019-01-04 11:32:31 -08001762
1763 /* Send request to the PMU */
1764 PM_PACK_PAYLOAD3(payload, PM_PLL_SET_MODE, nid, mode);
1765 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1766}
Jolly Shah141421e2019-01-04 11:35:48 -08001767
1768/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301769 * pm_pll_get_mode() - Get the PLL mode.
1770 * @nid: Node id of the target PLL.
1771 * @mode: Location to store the mode of the PLL.
Jolly Shah141421e2019-01-04 11:35:48 -08001772 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301773 * Return: Error if an argument is not valid or status as returned by the
1774 * PM controller (PMU).
1775 *
Jolly Shah141421e2019-01-04 11:35:48 -08001776 */
1777enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode)
1778{
1779 uint32_t payload[PAYLOAD_ARG_CNT];
1780
1781 /* Check if given node ID is a PLL node */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301782 if (nid < NODE_APLL || nid > NODE_IOPLL) {
Jolly Shah141421e2019-01-04 11:35:48 -08001783 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301784 }
Jolly Shah141421e2019-01-04 11:35:48 -08001785
1786 /* Send request to the PMU */
1787 PM_PACK_PAYLOAD2(payload, PM_PLL_GET_MODE, nid);
1788 return pm_ipi_send_sync(primary_proc, payload, mode, 1);
1789}
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001790
1791/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301792 * pm_register_access() - PM API for register read/write access data.
1793 * @register_access_id: Register_access_id which says register read/write.
1794 * @address: Address of the register to be accessed.
1795 * @mask: Mask value to be used while writing value.
1796 * @value: Value to be written to register.
1797 * @out: Returned output data.
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001798 *
1799 * This function returns requested data.
1800 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301801 * Return: Returns status, either success or error+reason.
1802 *
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001803 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301804enum pm_ret_status pm_register_access(uint32_t register_access_id,
1805 uint32_t address,
1806 uint32_t mask,
1807 uint32_t value,
1808 uint32_t *out)
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001809{
1810 enum pm_ret_status ret;
1811
1812 if (((ZYNQMP_CSU_BASEADDR & address) != ZYNQMP_CSU_BASEADDR) &&
1813 ((CSUDMA_BASE & address) != CSUDMA_BASE) &&
1814 ((RSA_CORE_BASE & address) != RSA_CORE_BASE) &&
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301815 ((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE)) {
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001816 return PM_RET_ERROR_ACCESS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301817 }
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001818
1819 switch (register_access_id) {
1820 case CONFIG_REG_WRITE:
1821 ret = pm_mmio_write(address, mask, value);
1822 break;
1823 case CONFIG_REG_READ:
1824 ret = pm_mmio_read(address, out);
1825 break;
1826 default:
1827 ret = PM_RET_ERROR_ARGS;
1828 WARN("Unimplemented register_access call\n\r");
Venkatesh Yadav Abbarapu41886f72022-04-29 15:17:13 +05301829 break;
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001830 }
1831 return ret;
1832}
VNSL Durgadeb1a362020-11-23 04:46:04 -08001833
1834/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301835 * pm_efuse_access() - To program or read efuse bits. This function provides
1836 * access to the xilskey library to program/read
1837 * efuse bits.
1838 * @address_low: lower 32-bit Linear memory space address.
1839 * @address_high: higher 32-bit Linear memory space address.
1840 * @value: Returned output value.
VNSL Durgadeb1a362020-11-23 04:46:04 -08001841 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301842 * Return: Returns status, either success or error+reason.
VNSL Durgadeb1a362020-11-23 04:46:04 -08001843 *
1844 */
1845enum pm_ret_status pm_efuse_access(uint32_t address_high,
1846 uint32_t address_low,
1847 uint32_t *value)
1848{
1849 uint32_t payload[PAYLOAD_ARG_CNT];
1850
1851 /* Send request to the PMU */
1852 PM_PACK_PAYLOAD3(payload, PM_EFUSE_ACCESS, address_high, address_low);
1853
1854 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1855}