blob: 6b42055d60ded128f6c42d482695f3d41378081b [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 {
Ronak Jain325bad12021-12-21 01:39:59 -0800166 .id = IOCTL_SD_DLL_RESET,
167 .api_id = PM_MMIO_WRITE,
168 },
169 {
170 .id = IOCTL_SET_SD_TAPDELAY,
171 .api_id = PM_MMIO_WRITE,
172 },
173 {
174 .id = IOCTL_SET_SD_TAPDELAY,
175 .api_id = PM_MMIO_READ,
176 },
177 {
178 .id = IOCTL_SET_PLL_FRAC_DATA,
179 .api_id = PM_PLL_SET_PARAMETER,
180 },
181 {
182 .id = IOCTL_GET_PLL_FRAC_DATA,
183 .api_id = PM_PLL_GET_PARAMETER,
184 },
185 {
186 .id = IOCTL_WRITE_GGS,
187 .api_id = PM_MMIO_WRITE,
188 },
189 {
190 .id = IOCTL_READ_GGS,
191 .api_id = PM_MMIO_READ,
192 },
193 {
194 .id = IOCTL_WRITE_PGGS,
195 .api_id = PM_MMIO_WRITE,
196 },
197 {
198 .id = IOCTL_READ_PGGS,
199 .api_id = PM_MMIO_READ,
200 },
201 {
202 .id = IOCTL_ULPI_RESET,
203 .api_id = PM_MMIO_WRITE,
204 },
205 {
206 .id = IOCTL_SET_BOOT_HEALTH_STATUS,
207 .api_id = PM_MMIO_WRITE,
208 },
209 {
210 .id = IOCTL_AFI,
211 .api_id = PM_MMIO_WRITE,
212 },
213};
214
Prasad Kummarie0783112023-04-26 11:02:07 +0530215/* Expected firmware API version to TF-A */
216static const uint8_t tfa_expected_ver_id[] = {
Ronak Jain325bad12021-12-21 01:39:59 -0800217 [PM_SELF_SUSPEND] = FW_API_BASE_VERSION,
218 [PM_REQ_WAKEUP] = FW_API_BASE_VERSION,
219 [PM_ABORT_SUSPEND] = FW_API_BASE_VERSION,
220 [PM_SET_WAKEUP_SOURCE] = FW_API_BASE_VERSION,
221 [PM_SYSTEM_SHUTDOWN] = FW_API_BASE_VERSION,
222 [PM_GET_API_VERSION] = FW_API_BASE_VERSION,
223 [PM_PLL_SET_MODE] = FW_API_BASE_VERSION,
224 [PM_PLL_GET_MODE] = FW_API_BASE_VERSION,
225 [PM_CLOCK_ENABLE] = FW_API_BASE_VERSION,
226 [PM_CLOCK_DISABLE] = FW_API_BASE_VERSION,
227 [PM_CLOCK_GETSTATE] = FW_API_BASE_VERSION,
228 [PM_PLL_SET_PARAMETER] = FW_API_BASE_VERSION,
229 [PM_PLL_GET_PARAMETER] = FW_API_BASE_VERSION,
230 [PM_CLOCK_SETDIVIDER] = FW_API_BASE_VERSION,
231 [PM_CLOCK_GETDIVIDER] = FW_API_BASE_VERSION,
232 [PM_CLOCK_SETPARENT] = FW_API_BASE_VERSION,
233 [PM_CLOCK_GETPARENT] = FW_API_BASE_VERSION,
234 [PM_MMIO_WRITE] = FW_API_BASE_VERSION,
235 [PM_MMIO_READ] = FW_API_BASE_VERSION,
236 [PM_FEATURE_CHECK] = FW_API_VERSION_2,
237};
238
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530239/* default shutdown/reboot scope is system(2) */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530240static uint32_t pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM;
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530241
242/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530243 * pm_get_shutdown_scope() - Get the currently set shutdown scope.
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530244 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530245 * Return: Shutdown scope value.
246 *
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530247 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530248uint32_t pm_get_shutdown_scope(void)
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530249{
250 return pm_shutdown_scope;
251}
252
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800253/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530254 * pm_self_suspend() - PM call for processor to suspend itself.
255 * @nid: Node id of the processor or subsystem.
256 * @latency: Requested maximum wakeup latency (not supported).
257 * @state: Requested state.
258 * @address: Resume address.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800259 *
260 * This is a blocking call, it will return only once PMU has responded.
261 * On a wakeup, resume address will be automatically set by PMU.
262 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530263 * Return: Returns status, either success or error+reason.
264 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800265 */
266enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530267 uint32_t latency,
268 uint32_t state,
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800269 uintptr_t address)
270{
271 uint32_t payload[PAYLOAD_ARG_CNT];
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530272 uint32_t cpuid = plat_my_core_pos();
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800273 const struct pm_proc *proc = pm_get_proc(cpuid);
274
275 /*
276 * Do client specific suspend operations
277 * (e.g. set powerdown request bit)
278 */
Filip Drazic4c0765a2016-07-26 12:11:33 +0200279 pm_client_suspend(proc, state);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800280 /* Send request to the PMU */
281 PM_PACK_PAYLOAD6(payload, PM_SELF_SUSPEND, proc->node_id, latency,
282 state, address, (address >> 32));
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700283 return pm_ipi_send_sync(proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800284}
285
286/**
287 * pm_req_suspend() - PM call to request for another PU or subsystem to
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530288 * be suspended gracefully.
289 * @target: Node id of the targeted PU or subsystem.
290 * @ack: Flag to specify whether acknowledge is requested.
291 * @latency: Requested wakeup latency (not supported).
292 * @state: Requested state (not supported).
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800293 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530294 * Return: Returns status, either success or error+reason.
295 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800296 */
297enum pm_ret_status pm_req_suspend(enum pm_node_id target,
298 enum pm_request_ack ack,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530299 uint32_t latency, uint32_t state)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800300{
301 uint32_t payload[PAYLOAD_ARG_CNT];
302
303 /* Send request to the PMU */
304 PM_PACK_PAYLOAD5(payload, PM_REQ_SUSPEND, target, ack, latency, state);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530305 if (ack == REQ_ACK_BLOCKING) {
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700306 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530307 } else {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800308 return pm_ipi_send(primary_proc, payload);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530309 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800310}
311
312/**
313 * pm_req_wakeup() - PM call for processor to wake up selected processor
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530314 * or subsystem.
315 * @target: Node id of the processor or subsystem to wake up.
316 * @ack: Flag to specify whether acknowledge requested.
317 * @set_address: Resume address presence indicator.
318 * 1 resume address specified, 0 otherwise.
319 * @address: Resume address.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800320 *
321 * This API function is either used to power up another APU core for SMP
322 * (by PSCI) or to power up an entirely different PU or subsystem, such
323 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
324 * automatically set by PMU.
325 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530326 * Return: Returns status, either success or error+reason.
327 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800328 */
329enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530330 uint32_t set_address,
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800331 uintptr_t address,
332 enum pm_request_ack ack)
333{
334 uint32_t payload[PAYLOAD_ARG_CNT];
335 uint64_t encoded_address;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800336
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800337
338 /* encode set Address into 1st bit of address */
339 encoded_address = address;
340 encoded_address |= !!set_address;
341
342 /* Send request to the PMU to perform the wake of the PU */
343 PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address,
344 encoded_address >> 32, ack);
345
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530346 if (ack == REQ_ACK_BLOCKING) {
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700347 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530348 } else {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800349 return pm_ipi_send(primary_proc, payload);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530350 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800351}
352
353/**
354 * pm_force_powerdown() - PM call to request for another PU or subsystem to
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530355 * be powered down forcefully.
356 * @target: Node id of the targeted PU or subsystem.
357 * @ack: Flag to specify whether acknowledge is requested.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800358 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530359 * Return: Returns status, either success or error+reason.
360 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800361 */
362enum pm_ret_status pm_force_powerdown(enum pm_node_id target,
363 enum pm_request_ack ack)
364{
365 uint32_t payload[PAYLOAD_ARG_CNT];
366
367 /* Send request to the PMU */
368 PM_PACK_PAYLOAD3(payload, PM_FORCE_POWERDOWN, target, ack);
369
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530370 if (ack == REQ_ACK_BLOCKING) {
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700371 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530372 } else {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800373 return pm_ipi_send(primary_proc, payload);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530374 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800375}
376
377/**
378 * pm_abort_suspend() - PM call to announce that a prior suspend request
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530379 * is to be aborted.
380 * @reason: Reason for the abort.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800381 *
382 * Calling PU expects the PMU to abort the initiated suspend procedure.
383 * This is a non-blocking call without any acknowledge.
384 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530385 * Return: Returns status, either success or error+reason
386 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800387 */
388enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason)
389{
390 uint32_t payload[PAYLOAD_ARG_CNT];
391
392 /*
393 * Do client specific abort suspend operations
394 * (e.g. enable interrupts and clear powerdown request bit)
395 */
396 pm_client_abort_suspend();
397 /* Send request to the PMU */
398 /* TODO: allow passing the node ID of the affected CPU */
399 PM_PACK_PAYLOAD3(payload, PM_ABORT_SUSPEND, reason,
400 primary_proc->node_id);
Abhyuday Godhasara0d9b7652021-06-24 05:49:04 -0700401 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800402}
403
404/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530405 * pm_set_wakeup_source() - PM call to specify the wakeup source while
406 * suspended.
407 * @target: Node id of the targeted PU or subsystem.
408 * @wkup_node: Node id of the wakeup peripheral.
409 * @enable: Enable or disable the specified peripheral as wake source.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800410 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530411 * Return: Returns status, either success or error+reason.
412 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800413 */
414enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
415 enum pm_node_id wkup_node,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530416 uint32_t enable)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800417{
418 uint32_t payload[PAYLOAD_ARG_CNT];
419
420 PM_PACK_PAYLOAD4(payload, PM_SET_WAKEUP_SOURCE, target, wkup_node,
421 enable);
Abhyuday Godhasara0d9b7652021-06-24 05:49:04 -0700422 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800423}
424
425/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530426 * pm_system_shutdown() - PM call to request a system shutdown or restart.
427 * @type: Shutdown or restart? 0=shutdown, 1=restart, 2=setscope.
428 * @subtype: Scope: 0=APU-subsystem, 1=PS, 2=system.
429 *
430 * Return: Returns status, either success or error+reason.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800431 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800432 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530433enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800434{
435 uint32_t payload[PAYLOAD_ARG_CNT];
436
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530437 if (type == PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
438 /* Setting scope for subsequent PSCI reboot or shutdown */
439 pm_shutdown_scope = subtype;
440 return PM_RET_SUCCESS;
441 }
442
Soren Brinkmann58fbb9b2016-09-02 09:50:54 -0700443 PM_PACK_PAYLOAD3(payload, PM_SYSTEM_SHUTDOWN, type, subtype);
Tejas Patelaf4b10e2018-02-09 02:42:59 -0800444 return pm_ipi_send_non_blocking(primary_proc, payload);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800445}
446
447/* APIs for managing PM slaves: */
448
449/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530450 * pm_req_node() - PM call to request a node with specific capabilities.
451 * @nid: Node id of the slave.
452 * @capabilities: Requested capabilities of the slave.
453 * @qos: Quality of service (not supported).
454 * @ack: Flag to specify whether acknowledge is requested.
455 *
456 * Return: Returns status, either success or error+reason.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800457 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800458 */
459enum pm_ret_status pm_req_node(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530460 uint32_t capabilities,
461 uint32_t qos,
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800462 enum pm_request_ack ack)
463{
464 uint32_t payload[PAYLOAD_ARG_CNT];
465
466 PM_PACK_PAYLOAD5(payload, PM_REQ_NODE, nid, capabilities, qos, ack);
467
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530468 if (ack == REQ_ACK_BLOCKING) {
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700469 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530470 } else {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800471 return pm_ipi_send(primary_proc, payload);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530472 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800473}
474
475/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530476 * pm_set_requirement() - PM call to set requirement for PM slaves.
477 * @nid: Node id of the slave.
478 * @capabilities: Requested capabilities of the slave.
479 * @qos: Quality of service (not supported).
480 * @ack: Flag to specify whether acknowledge is requested.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800481 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530482 * This API function is to be used for slaves a PU already has requested.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800483 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530484 * Return: Returns status, either success or error+reason.
485 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800486 */
487enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530488 uint32_t capabilities,
489 uint32_t qos,
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800490 enum pm_request_ack ack)
491{
492 uint32_t payload[PAYLOAD_ARG_CNT];
493
494 PM_PACK_PAYLOAD5(payload, PM_SET_REQUIREMENT, nid, capabilities, qos,
495 ack);
496
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530497 if (ack == REQ_ACK_BLOCKING) {
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700498 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530499 } else {
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800500 return pm_ipi_send(primary_proc, payload);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530501 }
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800502}
503
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800504/* Miscellaneous API functions */
505
506/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530507 * pm_get_api_version() - Get version number of PMU PM firmware.
508 * @version: Returns 32-bit version number of PMU Power Management Firmware.
509 *
510 * Return: Returns status, either success or error+reason.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800511 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800512 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530513enum pm_ret_status pm_get_api_version(uint32_t *version)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800514{
515 uint32_t payload[PAYLOAD_ARG_CNT];
516
517 /* Send request to the PMU */
518 PM_PACK_PAYLOAD1(payload, PM_GET_API_VERSION);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700519 return pm_ipi_send_sync(primary_proc, payload, version, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800520}
521
522/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530523 * pm_get_node_status() - PM call to request a node's current status.
524 * @nid: Node id.
525 * @ret_buff: Buffer for the return values
526 * [0] - Current power state of the node
527 * [1] - Current requirements for the node (slave nodes only)
528 * [2] - Current usage status for the node (slave nodes only)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800529 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530530 * Return: Returns status, either success or error+reason.
531 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800532 */
Anes Hadziahmetagic1caf88e2017-01-27 18:42:44 +0100533enum pm_ret_status pm_get_node_status(enum pm_node_id nid,
534 uint32_t *ret_buff)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800535{
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800536 uint32_t payload[PAYLOAD_ARG_CNT];
537
538 PM_PACK_PAYLOAD2(payload, PM_GET_NODE_STATUS, nid);
Anes Hadziahmetagic1caf88e2017-01-27 18:42:44 +0100539 return pm_ipi_send_sync(primary_proc, payload, ret_buff, 3);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800540}
541
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800542/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530543 * pm_mmio_write() - Perform write to protected mmio.
544 * @address: Address to write to.
545 * @mask: Mask to apply.
546 * @value: Value to write.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800547 *
548 * This function provides access to PM-related control registers
549 * that may not be directly accessible by a particular PU.
550 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530551 * Return: Returns status, either success or error+reason.
552 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800553 */
554enum pm_ret_status pm_mmio_write(uintptr_t address,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530555 uint32_t mask,
556 uint32_t value)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800557{
558 uint32_t payload[PAYLOAD_ARG_CNT];
559
560 /* Send request to the PMU */
561 PM_PACK_PAYLOAD4(payload, PM_MMIO_WRITE, address, mask, value);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700562 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800563}
564
565/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530566 * pm_mmio_read() - Read value from protected mmio.
567 * @address: Address to write to.
568 * @value: Value to write.
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800569 *
570 * This function provides access to PM-related control registers
571 * that may not be directly accessible by a particular PU.
572 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530573 * Return: Returns status, either success or error+reason.
574 *
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800575 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530576enum pm_ret_status pm_mmio_read(uintptr_t address, uint32_t *value)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800577{
578 uint32_t payload[PAYLOAD_ARG_CNT];
579
580 /* Send request to the PMU */
581 PM_PACK_PAYLOAD2(payload, PM_MMIO_READ, address);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700582 return pm_ipi_send_sync(primary_proc, payload, value, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800583}
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530584
585/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530586 * pm_fpga_load() - Load the bitstream into the PL. This function provides
587 * access to the xilfpga library to load the Bit-stream
588 * into PL.
589 * @address_low: lower 32-bit Linear memory space address.
590 * @address_high: higher 32-bit Linear memory space address.
591 * @size: Number of 32bit words.
592 * @flags: Additional flags or settings for the fpga operation.
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530593 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530594 * Return: Returns status, either success or error+reason.
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530595 *
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530596 */
597enum pm_ret_status pm_fpga_load(uint32_t address_low,
598 uint32_t address_high,
599 uint32_t size,
600 uint32_t flags)
601{
602 uint32_t payload[PAYLOAD_ARG_CNT];
603
604 /* Send request to the PMU */
605 PM_PACK_PAYLOAD5(payload, PM_FPGA_LOAD, address_high, address_low,
606 size, flags);
Siva Durga Prasad Paladugubf83b9c2018-02-07 13:13:01 +0530607 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530608}
609
610/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530611 * pm_fpga_get_status() - Read value from fpga status register.
612 * @value: Value to read.
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530613 *
614 * This function provides access to the xilfpga library to get
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530615 * the fpga status.
616 *
617 * Return: Returns status, either success or error+reason.
618 *
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530619 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530620enum pm_ret_status pm_fpga_get_status(uint32_t *value)
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530621{
622 uint32_t payload[PAYLOAD_ARG_CNT];
623
624 /* Send request to the PMU */
625 PM_PACK_PAYLOAD1(payload, PM_FPGA_GET_STATUS);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700626 return pm_ipi_send_sync(primary_proc, payload, value, 1);
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530627}
Soren Brinkmanncb366812016-09-22 12:21:11 -0700628
629/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530630 * pm_get_chipid() - Read silicon ID registers.
631 * @value: Buffer for return values. Must be large enough to hold 8 bytes.
Soren Brinkmanncb366812016-09-22 12:21:11 -0700632 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530633 * Return: Returns silicon ID registers.
634 *
Soren Brinkmanncb366812016-09-22 12:21:11 -0700635 */
636enum pm_ret_status pm_get_chipid(uint32_t *value)
637{
638 uint32_t payload[PAYLOAD_ARG_CNT];
639
640 /* Send request to the PMU */
641 PM_PACK_PAYLOAD1(payload, PM_GET_CHIPID);
642 return pm_ipi_send_sync(primary_proc, payload, value, 2);
643}
Soren Brinkmann84f0af42016-09-30 14:24:25 -0700644
645/**
Siva Durga Prasad Paladugude93d982018-04-30 15:49:27 +0530646 * pm_secure_rsaaes() - Load the secure images.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530647 * @address_low: lower 32-bit Linear memory space address.
648 * @address_high: higher 32-bit Linear memory space address.
649 * @size: Number of 32bit words.
650 * @flags: Additional flags or settings for the fpga operation.
Siva Durga Prasad Paladugude93d982018-04-30 15:49:27 +0530651 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530652 * This function provides access to the xilsecure library to load the
653 * authenticated, encrypted, and authenticated/encrypted images.
Siva Durga Prasad Paladugude93d982018-04-30 15:49:27 +0530654 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530655 * Return: Returns status, either success or error+reason.
Siva Durga Prasad Paladugude93d982018-04-30 15:49:27 +0530656 *
Siva Durga Prasad Paladugude93d982018-04-30 15:49:27 +0530657 */
658enum pm_ret_status pm_secure_rsaaes(uint32_t address_low,
659 uint32_t address_high,
660 uint32_t size,
661 uint32_t flags)
662{
663 uint32_t payload[PAYLOAD_ARG_CNT];
664
665 /* Send request to the PMU */
666 PM_PACK_PAYLOAD5(payload, PM_SECURE_RSA_AES, address_high, address_low,
667 size, flags);
668 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
669}
670
671/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530672 * pm_aes_engine() - Aes data blob encryption/decryption.
673 * @address_low: lower 32-bit address of the AesParams structure.
674 * @address_high: higher 32-bit address of the AesParams structure.
675 * @value: Returned output value.
676 *
Siva Durga Prasad Paladugu8bd905b2018-09-04 18:05:50 +0530677 * This function provides access to the xilsecure library to
678 * encrypt/decrypt data blobs.
679 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530680 * Return: Returns status, either success or error+reason.
Siva Durga Prasad Paladugu8bd905b2018-09-04 18:05:50 +0530681 *
Siva Durga Prasad Paladugu8bd905b2018-09-04 18:05:50 +0530682 */
683enum pm_ret_status pm_aes_engine(uint32_t address_high,
684 uint32_t address_low,
685 uint32_t *value)
686{
687 uint32_t payload[PAYLOAD_ARG_CNT];
688
689 /* Send request to the PMU */
690 PM_PACK_PAYLOAD3(payload, PM_SECURE_AES, address_high, address_low);
691 return pm_ipi_send_sync(primary_proc, payload, value, 1);
692}
693
694/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530695 * pm_get_callbackdata() - Read from IPI response buffer.
696 * @data: array of PAYLOAD_ARG_CNT elements.
697 * @count: Number of values to return.
Rajan Vaja02d18422019-03-04 11:09:39 +0530698 *
699 * Read value from ipi buffer response buffer.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530700 * Return: Returns status, either success or error.
701 *
Rajan Vaja02d18422019-03-04 11:09:39 +0530702 */
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530703enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count)
Rajan Vaja02d18422019-03-04 11:09:39 +0530704{
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530705 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vaja02d18422019-03-04 11:09:39 +0530706 /* Return if interrupt is not from PMU */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530707 if (!pm_ipi_irq_status(primary_proc)) {
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530708 return ret;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530709 }
Rajan Vaja02d18422019-03-04 11:09:39 +0530710
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530711 ret = pm_ipi_buff_read_callb(data, count);
Rajan Vaja02d18422019-03-04 11:09:39 +0530712 pm_ipi_irq_clear(primary_proc);
Naman Trivedi Manojbhaibeec83f2023-03-07 12:41:12 +0530713 return ret;
Rajan Vaja02d18422019-03-04 11:09:39 +0530714}
715
716/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530717 * pm_ioctl() - PM IOCTL API for device control and configs.
718 * @nid: Node ID of the device.
719 * @ioctl_id: ID of the requested IOCTL.
720 * @arg1: Argument 1 to requested IOCTL call.
721 * @arg2: Argument 2 to requested IOCTL call.
722 * @value: Returned output value.
Rajan Vaja5529a012018-01-17 02:39:23 -0800723 *
724 * This function calls IOCTL to firmware for device control and configuration.
725 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530726 * Return: Returns status, either success or error+reason.
727 *
Rajan Vaja5529a012018-01-17 02:39:23 -0800728 */
729enum pm_ret_status pm_ioctl(enum pm_node_id nid,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530730 uint32_t ioctl_id,
731 uint32_t arg1,
732 uint32_t arg2,
733 uint32_t *value)
Rajan Vaja5529a012018-01-17 02:39:23 -0800734{
735 return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
736}
Rajan Vaja35116132018-01-17 02:39:25 -0800737
738/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530739 * fw_api_version() - Returns API version implemented in firmware.
740 * @id: API ID to check.
741 * @version: Returned supported API version.
742 * @len: Number of words to be returned.
743 *
744 * Return: Returns status, either success or error+reason.
Ronak Jain325bad12021-12-21 01:39:59 -0800745 *
Ronak Jain325bad12021-12-21 01:39:59 -0800746 */
747static enum pm_ret_status fw_api_version(uint32_t id, uint32_t *version,
748 uint32_t len)
749{
750 uint32_t payload[PAYLOAD_ARG_CNT];
751
752 PM_PACK_PAYLOAD2(payload, PM_FEATURE_CHECK, id);
753 return pm_ipi_send_sync(primary_proc, payload, version, len);
754}
755
756/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530757 * check_api_dependency() - API to check dependent EEMI API version.
758 * @id: EEMI API ID to check.
759 *
760 * Return: Returns status, either success or error+reason.
Ronak Jain325bad12021-12-21 01:39:59 -0800761 *
Ronak Jain325bad12021-12-21 01:39:59 -0800762 */
763enum pm_ret_status check_api_dependency(uint8_t id)
764{
765 uint8_t i;
766 uint32_t version;
767 int ret;
768
769 for (i = 0U; i < ARRAY_SIZE(api_dep_table); i++) {
770 if (api_dep_table[i].id == id) {
771 if (api_dep_table[i].api_id == 0U) {
772 break;
773 }
774
775 ret = fw_api_version(api_dep_table[i].api_id,
776 &version, 1);
777 if (ret != PM_RET_SUCCESS) {
778 return ret;
779 }
780
Prasad Kummarie0783112023-04-26 11:02:07 +0530781 /* Check if fw version matches TF-A expected version */
782 if (version != tfa_expected_ver_id[api_dep_table[i].api_id]) {
Ronak Jain325bad12021-12-21 01:39:59 -0800783 return PM_RET_ERROR_NOTSUPPORTED;
784 }
785 }
786 }
787
788 return PM_RET_SUCCESS;
789}
790
791/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530792 * feature_check_tfa() - These are API's completely implemented in TF-A.
793 * @api_id: API ID to check.
794 * @version: Returned supported API version.
795 * @bit_mask: Returned supported IOCTL id version.
Ronak Jain325bad12021-12-21 01:39:59 -0800796 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530797 * Return: Returns status, either success or error+reason.
798 *
Ronak Jain325bad12021-12-21 01:39:59 -0800799 */
Prasad Kummarie0783112023-04-26 11:02:07 +0530800static enum pm_ret_status feature_check_tfa(uint32_t api_id, uint32_t *version,
Ronak Jain325bad12021-12-21 01:39:59 -0800801 uint32_t *bit_mask)
802{
803 switch (api_id) {
804 case PM_QUERY_DATA:
Ronak Jain11b084a2023-02-13 04:48:06 -0800805 *version = TFA_API_QUERY_DATA_VERSION;
Ronak Jain325bad12021-12-21 01:39:59 -0800806 bit_mask[0] = (uint32_t)(PM_QUERY_FEATURE_BITMASK);
807 bit_mask[1] = (uint32_t)(PM_QUERY_FEATURE_BITMASK >> 32);
808 return PM_RET_SUCCESS;
809 case PM_GET_CALLBACK_DATA:
810 case PM_GET_TRUSTZONE_VERSION:
811 case PM_SET_SUSPEND_MODE:
Prasad Kummarie0783112023-04-26 11:02:07 +0530812 *version = TFA_API_BASE_VERSION;
Ronak Jain325bad12021-12-21 01:39:59 -0800813 return PM_RET_SUCCESS;
814 default:
815 return PM_RET_ERROR_NO_FEATURE;
816 }
817}
818
819/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530820 * get_tfa_version_for_partial_apis() - Return TF-A version for partially.
821 * implemented APIs
822 * @api_id: API ID to check.
823 * @version: Returned supported API version.
Ronak Jain325bad12021-12-21 01:39:59 -0800824 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530825 * Return: Returns status, either success or error+reason.
826 *
Ronak Jain325bad12021-12-21 01:39:59 -0800827 */
Prasad Kummarie0783112023-04-26 11:02:07 +0530828static enum pm_ret_status get_tfa_version_for_partial_apis(uint32_t api_id,
Ronak Jain325bad12021-12-21 01:39:59 -0800829 uint32_t *version)
830{
831 switch (api_id) {
832 case PM_SELF_SUSPEND:
833 case PM_REQ_WAKEUP:
834 case PM_ABORT_SUSPEND:
835 case PM_SET_WAKEUP_SOURCE:
836 case PM_SYSTEM_SHUTDOWN:
837 case PM_GET_API_VERSION:
838 case PM_CLOCK_ENABLE:
839 case PM_CLOCK_DISABLE:
840 case PM_CLOCK_GETSTATE:
841 case PM_CLOCK_SETDIVIDER:
842 case PM_CLOCK_GETDIVIDER:
843 case PM_CLOCK_SETPARENT:
844 case PM_CLOCK_GETPARENT:
845 case PM_PLL_SET_PARAMETER:
846 case PM_PLL_GET_PARAMETER:
847 case PM_PLL_SET_MODE:
848 case PM_PLL_GET_MODE:
849 case PM_REGISTER_ACCESS:
Prasad Kummarie0783112023-04-26 11:02:07 +0530850 *version = TFA_API_BASE_VERSION;
Ronak Jain325bad12021-12-21 01:39:59 -0800851 return PM_RET_SUCCESS;
852 case PM_FEATURE_CHECK:
853 *version = FW_API_VERSION_2;
854 return PM_RET_SUCCESS;
855 default:
856 return PM_RET_ERROR_ARGS;
857 }
858}
859
860/**
861 * feature_check_partial() - These are API's partially implemented in
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530862 * TF-A and firmware both.
863 * @api_id: API ID to check.
864 * @version: Returned supported API version.
865 *
866 * Return: Returns status, either success or error+reason.
Ronak Jain325bad12021-12-21 01:39:59 -0800867 *
Ronak Jain325bad12021-12-21 01:39:59 -0800868 */
869static enum pm_ret_status feature_check_partial(uint32_t api_id,
870 uint32_t *version)
871{
872 uint32_t status;
873
874 switch (api_id) {
875 case PM_SELF_SUSPEND:
876 case PM_REQ_WAKEUP:
877 case PM_ABORT_SUSPEND:
878 case PM_SET_WAKEUP_SOURCE:
879 case PM_SYSTEM_SHUTDOWN:
880 case PM_GET_API_VERSION:
881 case PM_CLOCK_ENABLE:
882 case PM_CLOCK_DISABLE:
883 case PM_CLOCK_GETSTATE:
884 case PM_CLOCK_SETDIVIDER:
885 case PM_CLOCK_GETDIVIDER:
886 case PM_CLOCK_SETPARENT:
887 case PM_CLOCK_GETPARENT:
888 case PM_PLL_SET_PARAMETER:
889 case PM_PLL_GET_PARAMETER:
890 case PM_PLL_SET_MODE:
891 case PM_PLL_GET_MODE:
892 case PM_REGISTER_ACCESS:
893 case PM_FEATURE_CHECK:
894 status = check_api_dependency(api_id);
895 if (status != PM_RET_SUCCESS) {
896 return status;
897 }
Prasad Kummarie0783112023-04-26 11:02:07 +0530898 return get_tfa_version_for_partial_apis(api_id, version);
Ronak Jain325bad12021-12-21 01:39:59 -0800899 default:
900 return PM_RET_ERROR_NO_FEATURE;
901 }
902}
903
904/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530905 * pm_feature_check() - Returns the supported API version if supported.
906 * @api_id: API ID to check.
907 * @version: Returned supported API version.
908 * @bit_mask: Returned supported IOCTL id version.
909 * @len: Number of bytes to be returned in bit_mask variable.
Ronak Jain325bad12021-12-21 01:39:59 -0800910 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530911 * Return: Returns status, either success or error+reason.
912 *
Ronak Jain325bad12021-12-21 01:39:59 -0800913 */
914enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
915 uint32_t *bit_mask, uint8_t len)
916{
917 uint32_t ret_payload[PAYLOAD_ARG_CNT] = {0U};
918 uint32_t status;
919
Prasad Kummarie0783112023-04-26 11:02:07 +0530920 /* Get API version implemented in TF-A */
921 status = feature_check_tfa(api_id, version, bit_mask);
Ronak Jain325bad12021-12-21 01:39:59 -0800922 if (status != PM_RET_ERROR_NO_FEATURE) {
923 return status;
924 }
925
Prasad Kummarie0783112023-04-26 11:02:07 +0530926 /* Get API version implemented by firmware and TF-A both */
Ronak Jain325bad12021-12-21 01:39:59 -0800927 status = feature_check_partial(api_id, version);
928 if (status != PM_RET_ERROR_NO_FEATURE) {
929 return status;
930 }
931
932 /* Get API version implemented by firmware */
933 status = fw_api_version(api_id, ret_payload, 3);
934 /* IOCTL call may return failure whose ID is not implemented in
Prasad Kummarie0783112023-04-26 11:02:07 +0530935 * firmware but implemented in TF-A
Ronak Jain325bad12021-12-21 01:39:59 -0800936 */
937 if ((api_id != PM_IOCTL) && (status != PM_RET_SUCCESS)) {
938 return status;
939 }
940
941 *version = ret_payload[0];
942
Prasad Kummarie0783112023-04-26 11:02:07 +0530943 /* Update IOCTL bit mask which are implemented in TF-A */
Ronak Jainc443e802023-02-22 04:28:02 -0800944 if ((api_id == PM_IOCTL) || (api_id == PM_GET_OP_CHARACTERISTIC)) {
Ronak Jain325bad12021-12-21 01:39:59 -0800945 if (len < 2) {
946 return PM_RET_ERROR_ARGS;
947 }
948 bit_mask[0] = ret_payload[1];
949 bit_mask[1] = ret_payload[2];
Ronak Jainc443e802023-02-22 04:28:02 -0800950 if (api_id == PM_IOCTL) {
Prasad Kummarie0783112023-04-26 11:02:07 +0530951 /* Get IOCTL's implemented by TF-A */
952 status = tfa_ioctl_bitmask(bit_mask);
Ronak Jainc443e802023-02-22 04:28:02 -0800953 }
Ronak Jain325bad12021-12-21 01:39:59 -0800954 } else {
955 /* Requires for MISRA */
956 }
957
958 return status;
959}
960
961/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530962 * pm_clock_get_max_divisor - PM call to get max divisor.
963 * @clock_id: Clock ID.
964 * @div_type: Divisor ID (TYPE_DIV1 or TYPE_DIV2).
965 * @max_div: Maximum supported divisor.
Rajan Vajab34deca2019-03-20 01:13:21 +0530966 *
967 * This function is used by master to get maximum supported value.
968 *
969 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530970 *
Rajan Vajab34deca2019-03-20 01:13:21 +0530971 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +0530972static enum pm_ret_status pm_clock_get_max_divisor(uint32_t clock_id,
Rajan Vajab34deca2019-03-20 01:13:21 +0530973 uint8_t div_type,
974 uint32_t *max_div)
975{
976 return pm_api_clock_get_max_divisor(clock_id, div_type, max_div);
977}
978
979/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530980 * pm_clock_get_num_clocks - PM call to request number of clocks.
981 * @nclocks: Number of clocks.
Rajan Vajada959402018-07-20 03:16:27 -0700982 *
983 * This function is used by master to get number of clocks.
984 *
985 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530986 *
Rajan Vajada959402018-07-20 03:16:27 -0700987 */
988static enum pm_ret_status pm_clock_get_num_clocks(uint32_t *nclocks)
989{
990 return pm_api_clock_get_num_clocks(nclocks);
991}
992
993/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530994 * pm_clock_get_name() - PM call to request a clock's name.
995 * @clock_id: Clock ID.
996 * @name: Name of clock (max 16 bytes).
Rajan Vaja35116132018-01-17 02:39:25 -0800997 *
998 * This function is used by master to get nmae of clock specified
999 * by given clock ID.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301000 *
Rajan Vaja35116132018-01-17 02:39:25 -08001001 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301002static void pm_clock_get_name(uint32_t clock_id, char *name)
Rajan Vaja35116132018-01-17 02:39:25 -08001003{
Rajan Vajacd825682020-11-23 21:33:39 -08001004 pm_api_clock_get_name(clock_id, name);
Rajan Vaja35116132018-01-17 02:39:25 -08001005}
1006
1007/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301008 * pm_clock_get_topology() - PM call to request a clock's topology.
1009 * @clock_id: Clock ID.
1010 * @index: Topology index for next toplogy node.
1011 * @topology: Buffer to store nodes in topology and flags.
Rajan Vaja35116132018-01-17 02:39:25 -08001012 *
1013 * This function is used by master to get topology information for the
1014 * clock specified by given clock ID. Each response would return 3
1015 * topology nodes. To get next nodes, caller needs to call this API with
1016 * index of next node. Index starts from 0.
1017 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301018 * Return: Returns status, either success or error+reason.
1019 *
Rajan Vaja35116132018-01-17 02:39:25 -08001020 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301021static enum pm_ret_status pm_clock_get_topology(uint32_t clock_id,
1022 uint32_t index,
Rajan Vaja35116132018-01-17 02:39:25 -08001023 uint32_t *topology)
1024{
1025 return pm_api_clock_get_topology(clock_id, index, topology);
1026}
1027
1028/**
1029 * pm_clock_get_fixedfactor_params() - PM call to request a clock's fixed factor
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301030 * parameters for fixed clock.
1031 * @clock_id: Clock ID.
1032 * @mul: Multiplication value.
1033 * @div: Divisor value.
Rajan Vaja35116132018-01-17 02:39:25 -08001034 *
1035 * This function is used by master to get fixed factor parameers for the
1036 * fixed clock. This API is application only for the fixed clock.
1037 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301038 * Return: Returns status, either success or error+reason.
1039 *
Rajan Vaja35116132018-01-17 02:39:25 -08001040 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301041static enum pm_ret_status pm_clock_get_fixedfactor_params(uint32_t clock_id,
Rajan Vaja35116132018-01-17 02:39:25 -08001042 uint32_t *mul,
1043 uint32_t *div)
1044{
1045 return pm_api_clock_get_fixedfactor_params(clock_id, mul, div);
1046}
1047
1048/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301049 * pm_clock_get_parents() - PM call to request a clock's first 3 parents.
1050 * @clock_id: Clock ID.
1051 * @index: Index of next parent.
1052 * @parents: Parents of the given clock.
Rajan Vaja35116132018-01-17 02:39:25 -08001053 *
1054 * This function is used by master to get clock's parents information.
1055 * This API will return 3 parents with a single response. To get other
1056 * parents, master should call same API in loop with new parent index
1057 * till error is returned.
1058 *
1059 * E.g First call should have index 0 which will return parents 0, 1 and
1060 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
1061 * so on.
1062 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301063 * Return: Returns status, either success or error+reason.
1064 *
Rajan Vaja35116132018-01-17 02:39:25 -08001065 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301066static enum pm_ret_status pm_clock_get_parents(uint32_t clock_id,
1067 uint32_t index,
Rajan Vaja35116132018-01-17 02:39:25 -08001068 uint32_t *parents)
1069{
1070 return pm_api_clock_get_parents(clock_id, index, parents);
1071}
1072
1073/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301074 * pm_clock_get_attributes() - PM call to request a clock's attributes.
1075 * @clock_id: Clock ID.
1076 * @attr: Clock attributes.
Rajan Vaja35116132018-01-17 02:39:25 -08001077 *
1078 * This function is used by master to get clock's attributes
1079 * (e.g. valid, clock type, etc).
1080 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301081 * Return: Returns status, either success or error+reason.
1082 *
Rajan Vaja35116132018-01-17 02:39:25 -08001083 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301084static enum pm_ret_status pm_clock_get_attributes(uint32_t clock_id,
Rajan Vaja35116132018-01-17 02:39:25 -08001085 uint32_t *attr)
1086{
1087 return pm_api_clock_get_attributes(clock_id, attr);
1088}
1089
1090/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301091 * pm_clock_gate() - Configure clock gate.
1092 * @clock_id: Id of the clock to be configured.
1093 * @enable: Flag 0=disable (gate the clock), !0=enable (activate the clock).
Jolly Shaha5209802019-01-04 11:45:59 -08001094 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301095 * Return: Error if an argument is not valid or status as returned by the
1096 * PM controller (PMU).
1097 *
Jolly Shaha5209802019-01-04 11:45:59 -08001098 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301099static enum pm_ret_status pm_clock_gate(uint32_t clock_id,
1100 uint8_t enable)
Jolly Shaha5209802019-01-04 11:45:59 -08001101{
1102 uint32_t payload[PAYLOAD_ARG_CNT];
1103 enum pm_ret_status status;
1104 enum pm_api_id api_id;
1105
1106 /* Check if clock ID is valid and return an error if it is not */
1107 status = pm_clock_id_is_valid(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301108 if (status != PM_RET_SUCCESS) {
Jolly Shaha5209802019-01-04 11:45:59 -08001109 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301110 }
Jolly Shaha5209802019-01-04 11:45:59 -08001111
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301112 if (enable) {
Jolly Shaha5209802019-01-04 11:45:59 -08001113 api_id = PM_CLOCK_ENABLE;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301114 } else {
Jolly Shaha5209802019-01-04 11:45:59 -08001115 api_id = PM_CLOCK_DISABLE;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301116 }
Jolly Shaha5209802019-01-04 11:45:59 -08001117
1118 /* Send request to the PMU */
1119 PM_PACK_PAYLOAD2(payload, api_id, clock_id);
Mirela Simonovic64514a72018-08-24 17:09:07 +02001120 status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1121
1122 /* If action fails due to the lack of permissions filter the error */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301123 if (status == PM_RET_ERROR_ACCESS) {
Mirela Simonovic64514a72018-08-24 17:09:07 +02001124 status = PM_RET_SUCCESS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301125 }
Mirela Simonovic64514a72018-08-24 17:09:07 +02001126
1127 return status;
Jolly Shaha5209802019-01-04 11:45:59 -08001128}
1129
1130/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301131 * pm_clock_enable() - Enable the clock for given id.
1132 * @clock_id: Id of the clock to be enabled.
Rajan Vaja35116132018-01-17 02:39:25 -08001133 *
1134 * This function is used by master to enable the clock
1135 * including peripherals and PLL clocks.
1136 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301137 * Return: Error if an argument is not valid or status as returned by the
1138 * pm_clock_gate.
1139 *
Rajan Vaja35116132018-01-17 02:39:25 -08001140 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301141enum pm_ret_status pm_clock_enable(uint32_t clock_id)
Rajan Vaja35116132018-01-17 02:39:25 -08001142{
Jolly Shaha5209802019-01-04 11:45:59 -08001143 struct pm_pll *pll;
1144
1145 /* First try to handle it as a PLL */
1146 pll = pm_clock_get_pll(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301147 if (pll) {
Jolly Shaha5209802019-01-04 11:45:59 -08001148 return pm_clock_pll_enable(pll);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301149 }
Jolly Shaha5209802019-01-04 11:45:59 -08001150
1151 /* It's an on-chip clock, PMU should configure clock's gate */
1152 return pm_clock_gate(clock_id, 1);
Rajan Vaja35116132018-01-17 02:39:25 -08001153}
1154
1155/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301156 * pm_clock_disable - Disable the clock for given id.
1157 * @clock_id: Id of the clock to be disable.
Rajan Vaja35116132018-01-17 02:39:25 -08001158 *
1159 * This function is used by master to disable the clock
1160 * including peripherals and PLL clocks.
1161 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301162 * Return: Error if an argument is not valid or status as returned by the
1163 * pm_clock_gate
1164 *
Rajan Vaja35116132018-01-17 02:39:25 -08001165 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301166enum pm_ret_status pm_clock_disable(uint32_t clock_id)
Rajan Vaja35116132018-01-17 02:39:25 -08001167{
Jolly Shaha9057a02019-01-02 12:54:40 -08001168 struct pm_pll *pll;
1169
1170 /* First try to handle it as a PLL */
1171 pll = pm_clock_get_pll(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301172 if (pll) {
Jolly Shaha9057a02019-01-02 12:54:40 -08001173 return pm_clock_pll_disable(pll);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301174 }
Jolly Shaha9057a02019-01-02 12:54:40 -08001175
1176 /* It's an on-chip clock, PMU should configure clock's gate */
1177 return pm_clock_gate(clock_id, 0);
Rajan Vaja35116132018-01-17 02:39:25 -08001178}
1179
1180/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301181 * pm_clock_getstate - Get the clock state for given id.
1182 * @clock_id: Id of the clock to be queried.
1183 * @state: 1/0 (Enabled/Disabled).
Rajan Vaja35116132018-01-17 02:39:25 -08001184 *
1185 * This function is used by master to get the state of clock
1186 * including peripherals and PLL clocks.
1187 *
1188 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301189 *
Rajan Vaja35116132018-01-17 02:39:25 -08001190 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301191enum pm_ret_status pm_clock_getstate(uint32_t clock_id,
1192 uint32_t *state)
Rajan Vaja35116132018-01-17 02:39:25 -08001193{
Jolly Shah99e8ac92019-01-02 12:55:41 -08001194 struct pm_pll *pll;
1195 uint32_t payload[PAYLOAD_ARG_CNT];
1196 enum pm_ret_status status;
1197
1198 /* First try to handle it as a PLL */
1199 pll = pm_clock_get_pll(clock_id);
1200 if (pll)
1201 return pm_clock_pll_get_state(pll, state);
1202
1203 /* Check if clock ID is a valid on-chip clock */
1204 status = pm_clock_id_is_valid(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301205 if (status != PM_RET_SUCCESS) {
Jolly Shah99e8ac92019-01-02 12:55:41 -08001206 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301207 }
Jolly Shah99e8ac92019-01-02 12:55:41 -08001208
1209 /* Send request to the PMU */
1210 PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETSTATE, clock_id);
1211 return pm_ipi_send_sync(primary_proc, payload, state, 1);
Rajan Vaja35116132018-01-17 02:39:25 -08001212}
1213
1214/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301215 * pm_clock_setdivider - Set the clock divider for given id.
1216 * @clock_id: Id of the clock.
1217 * @divider: divider value.
Rajan Vaja35116132018-01-17 02:39:25 -08001218 *
1219 * This function is used by master to set divider for any clock
1220 * to achieve desired rate.
1221 *
1222 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301223 *
Rajan Vaja35116132018-01-17 02:39:25 -08001224 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301225enum pm_ret_status pm_clock_setdivider(uint32_t clock_id,
1226 uint32_t divider)
Rajan Vaja35116132018-01-17 02:39:25 -08001227{
Jolly Shah8b4c4c72019-01-04 11:49:46 -08001228 enum pm_ret_status status;
1229 enum pm_node_id nid;
1230 enum pm_clock_div_id div_id;
1231 uint32_t payload[PAYLOAD_ARG_CNT];
1232 const uint32_t div0 = 0xFFFF0000;
1233 const uint32_t div1 = 0x0000FFFF;
1234 uint32_t val;
1235
1236 /* Get PLL node ID using PLL clock ID */
1237 status = pm_clock_get_pll_node_id(clock_id, &nid);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301238 if (status == PM_RET_SUCCESS) {
Jolly Shah8b4c4c72019-01-04 11:49:46 -08001239 return pm_pll_set_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301240 }
Jolly Shah8b4c4c72019-01-04 11:49:46 -08001241
1242 /* Check if clock ID is a valid on-chip clock */
1243 status = pm_clock_id_is_valid(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301244 if (status != PM_RET_SUCCESS) {
Jolly Shah8b4c4c72019-01-04 11:49:46 -08001245 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301246 }
Jolly Shah8b4c4c72019-01-04 11:49:46 -08001247
1248 if (div0 == (divider & div0)) {
1249 div_id = PM_CLOCK_DIV0_ID;
1250 val = divider & ~div0;
1251 } else if (div1 == (divider & div1)) {
1252 div_id = PM_CLOCK_DIV1_ID;
1253 val = (divider & ~div1) >> 16;
1254 } else {
1255 return PM_RET_ERROR_ARGS;
1256 }
1257
1258 /* Send request to the PMU */
1259 PM_PACK_PAYLOAD4(payload, PM_CLOCK_SETDIVIDER, clock_id, div_id, val);
1260 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Rajan Vaja35116132018-01-17 02:39:25 -08001261}
1262
1263/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301264 * pm_clock_getdivider - Get the clock divider for given id.
1265 * @clock_id: Id of the clock.
1266 * @divider: divider value.
Rajan Vaja35116132018-01-17 02:39:25 -08001267 *
1268 * This function is used by master to get divider values
1269 * for any clock.
1270 *
1271 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301272 *
Rajan Vaja35116132018-01-17 02:39:25 -08001273 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301274enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
1275 uint32_t *divider)
Rajan Vaja35116132018-01-17 02:39:25 -08001276{
Jolly Shah4dd11762019-01-04 11:53:37 -08001277 enum pm_ret_status status;
1278 enum pm_node_id nid;
1279 uint32_t payload[PAYLOAD_ARG_CNT];
1280 uint32_t val;
1281
1282 /* Get PLL node ID using PLL clock ID */
1283 status = pm_clock_get_pll_node_id(clock_id, &nid);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301284 if (status == PM_RET_SUCCESS) {
Jolly Shah4dd11762019-01-04 11:53:37 -08001285 return pm_pll_get_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301286 }
Jolly Shah4dd11762019-01-04 11:53:37 -08001287
1288 /* Check if clock ID is a valid on-chip clock */
1289 status = pm_clock_id_is_valid(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301290 if (status != PM_RET_SUCCESS) {
Jolly Shah4dd11762019-01-04 11:53:37 -08001291 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301292 }
Jolly Shah4dd11762019-01-04 11:53:37 -08001293
1294 if (pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) {
1295 /* Send request to the PMU to get div0 */
1296 PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
1297 PM_CLOCK_DIV0_ID);
1298 status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301299 if (status != PM_RET_SUCCESS) {
Jolly Shah4dd11762019-01-04 11:53:37 -08001300 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301301 }
Jolly Shah4dd11762019-01-04 11:53:37 -08001302 *divider = val;
1303 }
1304
1305 if (pm_clock_has_div(clock_id, PM_CLOCK_DIV1_ID)) {
1306 /* Send request to the PMU to get div1 */
1307 PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
1308 PM_CLOCK_DIV1_ID);
1309 status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301310 if (status != PM_RET_SUCCESS) {
Jolly Shah4dd11762019-01-04 11:53:37 -08001311 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301312 }
Jolly Shah4dd11762019-01-04 11:53:37 -08001313 *divider |= val << 16;
1314 }
1315
1316 return status;
Rajan Vaja35116132018-01-17 02:39:25 -08001317}
1318
1319/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301320 * pm_clock_setparent - Set the clock parent for given id.
1321 * @clock_id: Id of the clock.
1322 * @parent_index: Index of the parent clock into clock's parents array.
Rajan Vaja35116132018-01-17 02:39:25 -08001323 *
1324 * This function is used by master to set parent for any clock.
1325 *
1326 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301327 *
Rajan Vaja35116132018-01-17 02:39:25 -08001328 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301329enum pm_ret_status pm_clock_setparent(uint32_t clock_id,
1330 uint32_t parent_index)
Rajan Vaja35116132018-01-17 02:39:25 -08001331{
Jolly Shah407fc0a2019-01-04 11:57:40 -08001332 struct pm_pll *pll;
1333 uint32_t payload[PAYLOAD_ARG_CNT];
1334 enum pm_ret_status status;
1335
1336 /* First try to handle it as a PLL */
1337 pll = pm_clock_get_pll_by_related_clk(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301338 if (pll) {
Jolly Shah407fc0a2019-01-04 11:57:40 -08001339 return pm_clock_pll_set_parent(pll, clock_id, parent_index);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301340 }
Jolly Shah407fc0a2019-01-04 11:57:40 -08001341
1342 /* Check if clock ID is a valid on-chip clock */
1343 status = pm_clock_id_is_valid(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301344 if (status != PM_RET_SUCCESS) {
Jolly Shah407fc0a2019-01-04 11:57:40 -08001345 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301346 }
Jolly Shah407fc0a2019-01-04 11:57:40 -08001347
1348 /* Send request to the PMU */
1349 PM_PACK_PAYLOAD3(payload, PM_CLOCK_SETPARENT, clock_id, parent_index);
1350 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Rajan Vaja35116132018-01-17 02:39:25 -08001351}
1352
1353/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301354 * pm_clock_getparent - Get the clock parent for given id.
1355 * @clock_id: Id of the clock.
1356 * @parent_index: parent index.
Rajan Vaja35116132018-01-17 02:39:25 -08001357 *
1358 * This function is used by master to get parent index
1359 * for any clock.
1360 *
1361 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301362 *
Rajan Vaja35116132018-01-17 02:39:25 -08001363 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301364enum pm_ret_status pm_clock_getparent(uint32_t clock_id,
1365 uint32_t *parent_index)
Rajan Vaja35116132018-01-17 02:39:25 -08001366{
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001367 struct pm_pll *pll;
1368 uint32_t payload[PAYLOAD_ARG_CNT];
1369 enum pm_ret_status status;
1370
1371 /* First try to handle it as a PLL */
1372 pll = pm_clock_get_pll_by_related_clk(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301373 if (pll) {
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001374 return pm_clock_pll_get_parent(pll, clock_id, parent_index);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301375 }
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001376
1377 /* Check if clock ID is a valid on-chip clock */
1378 status = pm_clock_id_is_valid(clock_id);
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301379 if (status != PM_RET_SUCCESS) {
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001380 return status;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301381 }
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001382
1383 /* Send request to the PMU */
1384 PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETPARENT, clock_id);
1385 return pm_ipi_send_sync(primary_proc, payload, parent_index, 1);
Rajan Vaja35116132018-01-17 02:39:25 -08001386}
1387
1388/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301389 * pm_pinctrl_get_num_pins - PM call to request number of pins.
1390 * @npins: Number of pins.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001391 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301392 * This function is used by master to get number of pins.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001393 *
1394 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301395 *
Rajan Vajad5dd8362018-01-30 04:16:31 -08001396 */
1397static enum pm_ret_status pm_pinctrl_get_num_pins(uint32_t *npins)
1398{
1399 return pm_api_pinctrl_get_num_pins(npins);
1400}
1401
1402/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301403 * pm_pinctrl_get_num_functions - PM call to request number of functions.
1404 * @nfuncs: Number of functions.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001405 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301406 * This function is used by master to get number of functions.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001407 *
1408 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301409 *
Rajan Vajad5dd8362018-01-30 04:16:31 -08001410 */
1411static enum pm_ret_status pm_pinctrl_get_num_functions(uint32_t *nfuncs)
1412{
1413 return pm_api_pinctrl_get_num_functions(nfuncs);
1414}
1415
1416/**
1417 * pm_pinctrl_get_num_function_groups - PM call to request number of
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301418 * function groups.
1419 * @fid: Id of function.
1420 * @ngroups: Number of function groups.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001421 *
1422 * This function is used by master to get number of function groups specified
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301423 * by given function Id.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001424 *
1425 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301426 *
Rajan Vajad5dd8362018-01-30 04:16:31 -08001427 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301428static enum pm_ret_status pm_pinctrl_get_num_function_groups(uint32_t fid,
Rajan Vajad5dd8362018-01-30 04:16:31 -08001429 uint32_t *ngroups)
1430{
1431 return pm_api_pinctrl_get_num_func_groups(fid, ngroups);
1432}
1433
1434/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301435 * pm_pinctrl_get_function_name - PM call to request function name.
1436 * @fid: Id of function.
1437 * @name: Name of function.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001438 *
1439 * This function is used by master to get name of function specified
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301440 * by given function Id.
1441 *
Rajan Vajad5dd8362018-01-30 04:16:31 -08001442 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301443static void pm_pinctrl_get_function_name(uint32_t fid, char *name)
Rajan Vajad5dd8362018-01-30 04:16:31 -08001444{
Rajan Vajacd825682020-11-23 21:33:39 -08001445 pm_api_pinctrl_get_function_name(fid, name);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001446}
1447
1448/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301449 * pm_pinctrl_get_function_groups - PM call to request function groups.
1450 * @fid: Id of function.
1451 * @index: Index of next function groups.
1452 * @groups: Function groups.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001453 *
1454 * This function is used by master to get function groups specified
1455 * by given function Id. This API will return 6 function groups with
1456 * a single response. To get other function groups, master should call
1457 * same API in loop with new function groups index till error is returned.
1458 *
1459 * E.g First call should have index 0 which will return function groups
1460 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
1461 * function groups 6, 7, 8, 9, 10 and 11 and so on.
1462 *
1463 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301464 *
Rajan Vajad5dd8362018-01-30 04:16:31 -08001465 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301466static enum pm_ret_status pm_pinctrl_get_function_groups(uint32_t fid,
1467 uint32_t index,
Rajan Vajad5dd8362018-01-30 04:16:31 -08001468 uint16_t *groups)
1469{
1470 return pm_api_pinctrl_get_function_groups(fid, index, groups);
1471}
1472
1473/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301474 * pm_pinctrl_get_pin_groups - PM call to request pin groups.
1475 * @pin_id: Id of pin.
1476 * @index: Index of next pin groups.
1477 * @groups: pin groups.
Rajan Vajad5dd8362018-01-30 04:16:31 -08001478 *
1479 * This function is used by master to get pin groups specified
1480 * by given pin Id. This API will return 6 pin groups with
1481 * a single response. To get other pin groups, master should call
1482 * same API in loop with new pin groups index till error is returned.
1483 *
1484 * E.g First call should have index 0 which will return pin groups
1485 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
1486 * pin groups 6, 7, 8, 9, 10 and 11 and so on.
1487 *
1488 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301489 *
Rajan Vajad5dd8362018-01-30 04:16:31 -08001490 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301491static enum pm_ret_status pm_pinctrl_get_pin_groups(uint32_t pin_id,
1492 uint32_t index,
Rajan Vajad5dd8362018-01-30 04:16:31 -08001493 uint16_t *groups)
1494{
1495 return pm_api_pinctrl_get_pin_groups(pin_id, index, groups);
1496}
1497
1498/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301499 * pm_query_data() - PM API for querying firmware data.
1500 * @qid: represents the query identifiers for PM.
1501 * @arg1: Argument 1 to requested IOCTL call.
1502 * @arg2: Argument 2 to requested IOCTL call.
1503 * @arg3: Argument 3 to requested IOCTL call.
1504 * @data: Returned output data.
Rajan Vaja35116132018-01-17 02:39:25 -08001505 *
1506 * This function returns requested data.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301507 *
Rajan Vaja35116132018-01-17 02:39:25 -08001508 */
Jay Buddhabhatti5b9f3912023-02-02 22:34:03 -08001509void pm_query_data(enum pm_query_ids qid, uint32_t arg1, uint32_t arg2,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301510 uint32_t arg3, uint32_t *data)
Rajan Vaja35116132018-01-17 02:39:25 -08001511{
Rajan Vaja35116132018-01-17 02:39:25 -08001512 switch (qid) {
1513 case PM_QID_CLOCK_GET_NAME:
Rajan Vajacd825682020-11-23 21:33:39 -08001514 pm_clock_get_name(arg1, (char *)data);
Rajan Vaja35116132018-01-17 02:39:25 -08001515 break;
1516 case PM_QID_CLOCK_GET_TOPOLOGY:
Rajan Vajacd825682020-11-23 21:33:39 -08001517 data[0] = pm_clock_get_topology(arg1, arg2, &data[1]);
Rajan Vaja35116132018-01-17 02:39:25 -08001518 break;
1519 case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
Rajan Vajacd825682020-11-23 21:33:39 -08001520 data[0] = pm_clock_get_fixedfactor_params(arg1, &data[1],
1521 &data[2]);
Rajan Vaja35116132018-01-17 02:39:25 -08001522 break;
1523 case PM_QID_CLOCK_GET_PARENTS:
Rajan Vajacd825682020-11-23 21:33:39 -08001524 data[0] = pm_clock_get_parents(arg1, arg2, &data[1]);
Rajan Vaja35116132018-01-17 02:39:25 -08001525 break;
1526 case PM_QID_CLOCK_GET_ATTRIBUTES:
Rajan Vajacd825682020-11-23 21:33:39 -08001527 data[0] = pm_clock_get_attributes(arg1, &data[1]);
Rajan Vaja35116132018-01-17 02:39:25 -08001528 break;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001529 case PM_QID_PINCTRL_GET_NUM_PINS:
Rajan Vajacd825682020-11-23 21:33:39 -08001530 data[0] = pm_pinctrl_get_num_pins(&data[1]);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001531 break;
1532 case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
Rajan Vajacd825682020-11-23 21:33:39 -08001533 data[0] = pm_pinctrl_get_num_functions(&data[1]);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001534 break;
1535 case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
Rajan Vajacd825682020-11-23 21:33:39 -08001536 data[0] = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001537 break;
1538 case PM_QID_PINCTRL_GET_FUNCTION_NAME:
Rajan Vajacd825682020-11-23 21:33:39 -08001539 pm_pinctrl_get_function_name(arg1, (char *)data);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001540 break;
1541 case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
Rajan Vajacd825682020-11-23 21:33:39 -08001542 data[0] = pm_pinctrl_get_function_groups(arg1, arg2,
1543 (uint16_t *)&data[1]);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001544 break;
1545 case PM_QID_PINCTRL_GET_PIN_GROUPS:
Rajan Vajacd825682020-11-23 21:33:39 -08001546 data[0] = pm_pinctrl_get_pin_groups(arg1, arg2,
1547 (uint16_t *)&data[1]);
Rajan Vajad5dd8362018-01-30 04:16:31 -08001548 break;
Rajan Vajada959402018-07-20 03:16:27 -07001549 case PM_QID_CLOCK_GET_NUM_CLOCKS:
Rajan Vajacd825682020-11-23 21:33:39 -08001550 data[0] = pm_clock_get_num_clocks(&data[1]);
Rajan Vajada959402018-07-20 03:16:27 -07001551 break;
Rajan Vajab34deca2019-03-20 01:13:21 +05301552
1553 case PM_QID_CLOCK_GET_MAX_DIVISOR:
Rajan Vajacd825682020-11-23 21:33:39 -08001554 data[0] = pm_clock_get_max_divisor(arg1, arg2, &data[1]);
Rajan Vajab34deca2019-03-20 01:13:21 +05301555 break;
Rajan Vaja35116132018-01-17 02:39:25 -08001556 default:
Rajan Vajacd825682020-11-23 21:33:39 -08001557 data[0] = PM_RET_ERROR_ARGS;
Rajan Vaja35116132018-01-17 02:39:25 -08001558 WARN("Unimplemented query service call: 0x%x\n", qid);
Venkatesh Yadav Abbarapu41886f72022-04-29 15:17:13 +05301559 break;
Rajan Vaja35116132018-01-17 02:39:25 -08001560 }
Rajan Vaja35116132018-01-17 02:39:25 -08001561}
Siva Durga Prasad Paladuguf3994cc2018-05-01 11:12:55 +05301562
1563enum pm_ret_status pm_sha_hash(uint32_t address_high,
1564 uint32_t address_low,
1565 uint32_t size,
1566 uint32_t flags)
1567{
1568 uint32_t payload[PAYLOAD_ARG_CNT];
1569
1570 /* Send request to the PMU */
1571 PM_PACK_PAYLOAD5(payload, PM_SECURE_SHA, address_high, address_low,
1572 size, flags);
1573 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1574}
1575
1576enum pm_ret_status pm_rsa_core(uint32_t address_high,
1577 uint32_t address_low,
1578 uint32_t size,
1579 uint32_t flags)
1580{
1581 uint32_t payload[PAYLOAD_ARG_CNT];
1582
1583 /* Send request to the PMU */
1584 PM_PACK_PAYLOAD5(payload, PM_SECURE_RSA, address_high, address_low,
1585 size, flags);
1586 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1587}
Siva Durga Prasad Paladugua4ed4b22018-04-30 20:06:58 +05301588
1589enum pm_ret_status pm_secure_image(uint32_t address_low,
1590 uint32_t address_high,
1591 uint32_t key_lo,
1592 uint32_t key_hi,
1593 uint32_t *value)
1594{
1595 uint32_t payload[PAYLOAD_ARG_CNT];
1596
1597 /* Send request to the PMU */
1598 PM_PACK_PAYLOAD5(payload, PM_SECURE_IMAGE, address_high, address_low,
1599 key_hi, key_lo);
1600 return pm_ipi_send_sync(primary_proc, payload, value, 2);
1601}
Siva Durga Prasad Paladugu7c6516a2018-09-04 17:41:34 +05301602
1603/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301604 * pm_fpga_read - Perform the fpga configuration readback.
1605 * @reg_numframes: Configuration register offset (or) Number of frames to read.
1606 * @address_low: lower 32-bit Linear memory space address.
1607 * @address_high: higher 32-bit Linear memory space address.
1608 * @readback_type: Type of fpga readback operation.
1609 * 0 -- Configuration Register readback.
1610 * 1 -- Configuration Data readback.
1611 * @value: Value to read.
Siva Durga Prasad Paladugu7c6516a2018-09-04 17:41:34 +05301612 *
1613 * This function provides access to the xilfpga library to read
1614 * the PL configuration.
1615 *
1616 * Return: Returns status, either success or error+reason.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301617 *
Siva Durga Prasad Paladugu7c6516a2018-09-04 17:41:34 +05301618 */
1619enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
1620 uint32_t address_low,
1621 uint32_t address_high,
1622 uint32_t readback_type,
1623 uint32_t *value)
1624{
1625 uint32_t payload[PAYLOAD_ARG_CNT];
1626
1627 /* Send request to the PMU */
1628 PM_PACK_PAYLOAD5(payload, PM_FPGA_READ, reg_numframes, address_low,
1629 address_high, readback_type);
1630 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1631}
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001632
1633/*
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301634 * pm_pll_set_parameter() - Set the PLL parameter value.
1635 * @nid: Node id of the target PLL.
1636 * @param_id: ID of the PLL parameter.
1637 * @value: Parameter value to be set.
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001638 *
1639 * Setting the parameter will have physical effect once the PLL mode is set to
1640 * integer or fractional.
1641 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301642 * Return: Error if an argument is not valid or status as returned by the
1643 * PM controller (PMU).
1644 *
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001645 */
1646enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
1647 enum pm_pll_param param_id,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301648 uint32_t value)
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001649{
1650 uint32_t payload[PAYLOAD_ARG_CNT];
1651
1652 /* Check if given node ID is a PLL node */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301653 if (nid < NODE_APLL || nid > NODE_IOPLL) {
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001654 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301655 }
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001656
1657 /* Check if parameter ID is valid and return an error if it's not */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301658 if (param_id >= PM_PLL_PARAM_MAX) {
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001659 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301660 }
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001661
1662 /* Send request to the PMU */
1663 PM_PACK_PAYLOAD4(payload, PM_PLL_SET_PARAMETER, nid, param_id, value);
1664 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1665}
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001666
1667/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301668 * pm_pll_get_parameter() - Get the PLL parameter value.
1669 * @nid: Node id of the target PLL.
1670 * @param_id: ID of the PLL parameter.
1671 * @value: Location to store the parameter value.
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001672 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301673 * Return: Error if an argument is not valid or status as returned by the
1674 * PM controller (PMU).
1675 *
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001676 */
1677enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
1678 enum pm_pll_param param_id,
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301679 uint32_t *value)
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001680{
1681 uint32_t payload[PAYLOAD_ARG_CNT];
1682
1683 /* Check if given node ID is a PLL node */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301684 if (nid < NODE_APLL || nid > NODE_IOPLL) {
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001685 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301686 }
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001687
1688 /* Check if parameter ID is valid and return an error if it's not */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301689 if (param_id >= PM_PLL_PARAM_MAX) {
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001690 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301691 }
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001692
1693 /* Send request to the PMU */
1694 PM_PACK_PAYLOAD3(payload, PM_PLL_GET_PARAMETER, nid, param_id);
1695 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1696}
Jolly Shah1f0d5852019-01-04 11:32:31 -08001697
1698/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301699 * pm_pll_set_mode() - Set the PLL mode.
1700 * @nid: Node id of the target PLL.
1701 * @mode: PLL mode to be set.
Jolly Shah1f0d5852019-01-04 11:32:31 -08001702 *
1703 * If reset mode is set the PM controller will first bypass the PLL and then
1704 * assert the reset. If integer or fractional mode is set the PM controller will
1705 * ensure that the complete PLL programming sequence is satisfied. After this
1706 * function returns success the PLL is locked and its bypass is deasserted.
1707 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301708 * Return: Error if an argument is not valid or status as returned by the
1709 * PM controller (PMU).
1710 *
Jolly Shah1f0d5852019-01-04 11:32:31 -08001711 */
1712enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode)
1713{
1714 uint32_t payload[PAYLOAD_ARG_CNT];
1715
1716 /* Check if given node ID is a PLL node */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301717 if (nid < NODE_APLL || nid > NODE_IOPLL) {
Jolly Shah1f0d5852019-01-04 11:32:31 -08001718 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301719 }
Jolly Shah1f0d5852019-01-04 11:32:31 -08001720
1721 /* Check if PLL mode is valid */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301722 if (mode >= PM_PLL_MODE_MAX) {
Jolly Shah1f0d5852019-01-04 11:32:31 -08001723 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301724 }
Jolly Shah1f0d5852019-01-04 11:32:31 -08001725
1726 /* Send request to the PMU */
1727 PM_PACK_PAYLOAD3(payload, PM_PLL_SET_MODE, nid, mode);
1728 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1729}
Jolly Shah141421e2019-01-04 11:35:48 -08001730
1731/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301732 * pm_pll_get_mode() - Get the PLL mode.
1733 * @nid: Node id of the target PLL.
1734 * @mode: Location to store the mode of the PLL.
Jolly Shah141421e2019-01-04 11:35:48 -08001735 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301736 * Return: Error if an argument is not valid or status as returned by the
1737 * PM controller (PMU).
1738 *
Jolly Shah141421e2019-01-04 11:35:48 -08001739 */
1740enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode)
1741{
1742 uint32_t payload[PAYLOAD_ARG_CNT];
1743
1744 /* Check if given node ID is a PLL node */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301745 if (nid < NODE_APLL || nid > NODE_IOPLL) {
Jolly Shah141421e2019-01-04 11:35:48 -08001746 return PM_RET_ERROR_ARGS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301747 }
Jolly Shah141421e2019-01-04 11:35:48 -08001748
1749 /* Send request to the PMU */
1750 PM_PACK_PAYLOAD2(payload, PM_PLL_GET_MODE, nid);
1751 return pm_ipi_send_sync(primary_proc, payload, mode, 1);
1752}
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001753
1754/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301755 * pm_register_access() - PM API for register read/write access data.
1756 * @register_access_id: Register_access_id which says register read/write.
1757 * @address: Address of the register to be accessed.
1758 * @mask: Mask value to be used while writing value.
1759 * @value: Value to be written to register.
1760 * @out: Returned output data.
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001761 *
1762 * This function returns requested data.
1763 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301764 * Return: Returns status, either success or error+reason.
1765 *
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001766 */
Venkatesh Yadav Abbarapue7c45382022-05-19 14:49:49 +05301767enum pm_ret_status pm_register_access(uint32_t register_access_id,
1768 uint32_t address,
1769 uint32_t mask,
1770 uint32_t value,
1771 uint32_t *out)
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001772{
1773 enum pm_ret_status ret;
1774
1775 if (((ZYNQMP_CSU_BASEADDR & address) != ZYNQMP_CSU_BASEADDR) &&
1776 ((CSUDMA_BASE & address) != CSUDMA_BASE) &&
1777 ((RSA_CORE_BASE & address) != RSA_CORE_BASE) &&
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301778 ((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE)) {
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001779 return PM_RET_ERROR_ACCESS;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +05301780 }
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001781
1782 switch (register_access_id) {
1783 case CONFIG_REG_WRITE:
1784 ret = pm_mmio_write(address, mask, value);
1785 break;
1786 case CONFIG_REG_READ:
1787 ret = pm_mmio_read(address, out);
1788 break;
1789 default:
1790 ret = PM_RET_ERROR_ARGS;
1791 WARN("Unimplemented register_access call\n\r");
Venkatesh Yadav Abbarapu41886f72022-04-29 15:17:13 +05301792 break;
Kalyani Akula6ebe4832020-11-22 22:42:10 -08001793 }
1794 return ret;
1795}
VNSL Durgadeb1a362020-11-23 04:46:04 -08001796
1797/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301798 * pm_efuse_access() - To program or read efuse bits. This function provides
1799 * access to the xilskey library to program/read
1800 * efuse bits.
1801 * @address_low: lower 32-bit Linear memory space address.
1802 * @address_high: higher 32-bit Linear memory space address.
1803 * @value: Returned output value.
VNSL Durgadeb1a362020-11-23 04:46:04 -08001804 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +05301805 * Return: Returns status, either success or error+reason.
VNSL Durgadeb1a362020-11-23 04:46:04 -08001806 *
1807 */
1808enum pm_ret_status pm_efuse_access(uint32_t address_high,
1809 uint32_t address_low,
1810 uint32_t *value)
1811{
1812 uint32_t payload[PAYLOAD_ARG_CNT];
1813
1814 /* Send request to the PMU */
1815 PM_PACK_PAYLOAD3(payload, PM_EFUSE_ACCESS, address_high, address_low);
1816
1817 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1818}