blob: f651880cf9dda73953685f8cb8cb8ec7b1d79e77 [file] [log] [blame]
Soren Brinkmann76fcae32016-03-06 20:16:27 -08001/*
Rajan Vaja83687612018-01-17 02:39:20 -08002 * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
Soren Brinkmann76fcae32016-03-06 20:16:27 -08003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Soren Brinkmann76fcae32016-03-06 20:16:27 -08005 */
6
7/*
8 * ZynqMP system level PM-API functions and communication with PMU via
9 * IPI interrupts
10 */
11
12#include <arch_helpers.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000013#include <plat/common/platform.h>
14
Rajan Vaja35116132018-01-17 02:39:25 -080015#include "pm_api_clock.h"
Rajan Vaja5529a012018-01-17 02:39:23 -080016#include "pm_api_ioctl.h"
Rajan Vaja0ac2be12018-01-17 02:39:21 -080017#include "pm_api_pinctrl.h"
Isla Mitchelle3631462017-07-14 10:46:32 +010018#include "pm_api_sys.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"
Soren Brinkmann76fcae32016-03-06 20:16:27 -080022
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +053023/* default shutdown/reboot scope is system(2) */
24static unsigned int pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM;
25
26/**
27 * pm_get_shutdown_scope() - Get the currently set shutdown scope
28 *
29 * @return Shutdown scope value
30 */
31unsigned int pm_get_shutdown_scope(void)
32{
33 return pm_shutdown_scope;
34}
35
Soren Brinkmann76fcae32016-03-06 20:16:27 -080036/**
37 * Assigning of argument values into array elements.
38 */
39#define PM_PACK_PAYLOAD1(pl, arg0) { \
40 pl[0] = (uint32_t)(arg0); \
41}
42
43#define PM_PACK_PAYLOAD2(pl, arg0, arg1) { \
44 pl[1] = (uint32_t)(arg1); \
45 PM_PACK_PAYLOAD1(pl, arg0); \
46}
47
48#define PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2) { \
49 pl[2] = (uint32_t)(arg2); \
50 PM_PACK_PAYLOAD2(pl, arg0, arg1); \
51}
52
53#define PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3) { \
54 pl[3] = (uint32_t)(arg3); \
55 PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2); \
56}
57
58#define PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4) { \
59 pl[4] = (uint32_t)(arg4); \
60 PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3); \
61}
62
63#define PM_PACK_PAYLOAD6(pl, arg0, arg1, arg2, arg3, arg4, arg5) { \
64 pl[5] = (uint32_t)(arg5); \
65 PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4); \
66}
67
68/**
69 * pm_self_suspend() - PM call for processor to suspend itself
70 * @nid Node id of the processor or subsystem
71 * @latency Requested maximum wakeup latency (not supported)
Filip Drazic0bd9d0c2016-07-20 17:17:39 +020072 * @state Requested state
Soren Brinkmann76fcae32016-03-06 20:16:27 -080073 * @address Resume address
74 *
75 * This is a blocking call, it will return only once PMU has responded.
76 * On a wakeup, resume address will be automatically set by PMU.
77 *
78 * @return Returns status, either success or error+reason
79 */
80enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
81 unsigned int latency,
82 unsigned int state,
83 uintptr_t address)
84{
85 uint32_t payload[PAYLOAD_ARG_CNT];
86 unsigned int cpuid = plat_my_core_pos();
87 const struct pm_proc *proc = pm_get_proc(cpuid);
88
89 /*
90 * Do client specific suspend operations
91 * (e.g. set powerdown request bit)
92 */
Filip Drazic4c0765a2016-07-26 12:11:33 +020093 pm_client_suspend(proc, state);
Soren Brinkmann76fcae32016-03-06 20:16:27 -080094 /* Send request to the PMU */
95 PM_PACK_PAYLOAD6(payload, PM_SELF_SUSPEND, proc->node_id, latency,
96 state, address, (address >> 32));
Soren Brinkmannd6c9e032016-09-22 11:35:47 -070097 return pm_ipi_send_sync(proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -080098}
99
100/**
101 * pm_req_suspend() - PM call to request for another PU or subsystem to
102 * be suspended gracefully.
103 * @target Node id of the targeted PU or subsystem
104 * @ack Flag to specify whether acknowledge is requested
105 * @latency Requested wakeup latency (not supported)
106 * @state Requested state (not supported)
107 *
108 * @return Returns status, either success or error+reason
109 */
110enum pm_ret_status pm_req_suspend(enum pm_node_id target,
111 enum pm_request_ack ack,
112 unsigned int latency, unsigned int state)
113{
114 uint32_t payload[PAYLOAD_ARG_CNT];
115
116 /* Send request to the PMU */
117 PM_PACK_PAYLOAD5(payload, PM_REQ_SUSPEND, target, ack, latency, state);
118 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700119 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800120 else
121 return pm_ipi_send(primary_proc, payload);
122}
123
124/**
125 * pm_req_wakeup() - PM call for processor to wake up selected processor
126 * or subsystem
127 * @target Node id of the processor or subsystem to wake up
128 * @ack Flag to specify whether acknowledge requested
129 * @set_address Resume address presence indicator
130 * 1 resume address specified, 0 otherwise
131 * @address Resume address
132 *
133 * This API function is either used to power up another APU core for SMP
134 * (by PSCI) or to power up an entirely different PU or subsystem, such
135 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
136 * automatically set by PMU.
137 *
138 * @return Returns status, either success or error+reason
139 */
140enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
141 unsigned int set_address,
142 uintptr_t address,
143 enum pm_request_ack ack)
144{
145 uint32_t payload[PAYLOAD_ARG_CNT];
146 uint64_t encoded_address;
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800147
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800148
149 /* encode set Address into 1st bit of address */
150 encoded_address = address;
151 encoded_address |= !!set_address;
152
153 /* Send request to the PMU to perform the wake of the PU */
154 PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address,
155 encoded_address >> 32, ack);
156
157 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700158 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800159 else
160 return pm_ipi_send(primary_proc, payload);
161}
162
163/**
164 * pm_force_powerdown() - PM call to request for another PU or subsystem to
165 * be powered down forcefully
166 * @target Node id of the targeted PU or subsystem
167 * @ack Flag to specify whether acknowledge is requested
168 *
169 * @return Returns status, either success or error+reason
170 */
171enum pm_ret_status pm_force_powerdown(enum pm_node_id target,
172 enum pm_request_ack ack)
173{
174 uint32_t payload[PAYLOAD_ARG_CNT];
175
176 /* Send request to the PMU */
177 PM_PACK_PAYLOAD3(payload, PM_FORCE_POWERDOWN, target, ack);
178
179 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700180 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800181 else
182 return pm_ipi_send(primary_proc, payload);
183}
184
185/**
186 * pm_abort_suspend() - PM call to announce that a prior suspend request
187 * is to be aborted.
188 * @reason Reason for the abort
189 *
190 * Calling PU expects the PMU to abort the initiated suspend procedure.
191 * This is a non-blocking call without any acknowledge.
192 *
193 * @return Returns status, either success or error+reason
194 */
195enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason)
196{
197 uint32_t payload[PAYLOAD_ARG_CNT];
198
199 /*
200 * Do client specific abort suspend operations
201 * (e.g. enable interrupts and clear powerdown request bit)
202 */
203 pm_client_abort_suspend();
204 /* Send request to the PMU */
205 /* TODO: allow passing the node ID of the affected CPU */
206 PM_PACK_PAYLOAD3(payload, PM_ABORT_SUSPEND, reason,
207 primary_proc->node_id);
208 return pm_ipi_send(primary_proc, payload);
209}
210
211/**
212 * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
213 * @target Node id of the targeted PU or subsystem
214 * @wkup_node Node id of the wakeup peripheral
215 * @enable Enable or disable the specified peripheral as wake source
216 *
217 * @return Returns status, either success or error+reason
218 */
219enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
220 enum pm_node_id wkup_node,
221 unsigned int enable)
222{
223 uint32_t payload[PAYLOAD_ARG_CNT];
224
225 PM_PACK_PAYLOAD4(payload, PM_SET_WAKEUP_SOURCE, target, wkup_node,
226 enable);
227 return pm_ipi_send(primary_proc, payload);
228}
229
230/**
231 * pm_system_shutdown() - PM call to request a system shutdown or restart
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530232 * @type Shutdown or restart? 0=shutdown, 1=restart, 2=setscope
233 * @subtype Scope: 0=APU-subsystem, 1=PS, 2=system
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800234 *
235 * @return Returns status, either success or error+reason
236 */
Soren Brinkmann58fbb9b2016-09-02 09:50:54 -0700237enum pm_ret_status pm_system_shutdown(unsigned int type, unsigned int subtype)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800238{
239 uint32_t payload[PAYLOAD_ARG_CNT];
240
Siva Durga Prasad Paladugu1f80d3f2018-04-30 15:56:10 +0530241 if (type == PMF_SHUTDOWN_TYPE_SETSCOPE_ONLY) {
242 /* Setting scope for subsequent PSCI reboot or shutdown */
243 pm_shutdown_scope = subtype;
244 return PM_RET_SUCCESS;
245 }
246
Soren Brinkmann58fbb9b2016-09-02 09:50:54 -0700247 PM_PACK_PAYLOAD3(payload, PM_SYSTEM_SHUTDOWN, type, subtype);
Tejas Patelaf4b10e2018-02-09 02:42:59 -0800248 return pm_ipi_send_non_blocking(primary_proc, payload);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800249}
250
251/* APIs for managing PM slaves: */
252
253/**
254 * pm_req_node() - PM call to request a node with specific capabilities
255 * @nid Node id of the slave
256 * @capabilities Requested capabilities of the slave
257 * @qos Quality of service (not supported)
258 * @ack Flag to specify whether acknowledge is requested
259 *
260 * @return Returns status, either success or error+reason
261 */
262enum pm_ret_status pm_req_node(enum pm_node_id nid,
263 unsigned int capabilities,
264 unsigned int qos,
265 enum pm_request_ack ack)
266{
267 uint32_t payload[PAYLOAD_ARG_CNT];
268
269 PM_PACK_PAYLOAD5(payload, PM_REQ_NODE, nid, capabilities, qos, ack);
270
271 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700272 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800273 else
274 return pm_ipi_send(primary_proc, payload);
275}
276
277/**
278 * pm_set_requirement() - PM call to set requirement for PM slaves
279 * @nid Node id of the slave
280 * @capabilities Requested capabilities of the slave
281 * @qos Quality of service (not supported)
282 * @ack Flag to specify whether acknowledge is requested
283 *
284 * This API function is to be used for slaves a PU already has requested
285 *
286 * @return Returns status, either success or error+reason
287 */
288enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
289 unsigned int capabilities,
290 unsigned int qos,
291 enum pm_request_ack ack)
292{
293 uint32_t payload[PAYLOAD_ARG_CNT];
294
295 PM_PACK_PAYLOAD5(payload, PM_SET_REQUIREMENT, nid, capabilities, qos,
296 ack);
297
298 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700299 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800300 else
301 return pm_ipi_send(primary_proc, payload);
302}
303
304/**
305 * pm_release_node() - PM call to release a node
306 * @nid Node id of the slave
307 *
308 * @return Returns status, either success or error+reason
309 */
310enum pm_ret_status pm_release_node(enum pm_node_id nid)
311{
312 uint32_t payload[PAYLOAD_ARG_CNT];
313
314 PM_PACK_PAYLOAD2(payload, PM_RELEASE_NODE, nid);
315 return pm_ipi_send(primary_proc, payload);
316}
317
318/**
319 * pm_set_max_latency() - PM call to set wakeup latency requirements
320 * @nid Node id of the slave
321 * @latency Requested maximum wakeup latency
322 *
323 * @return Returns status, either success or error+reason
324 */
325enum pm_ret_status pm_set_max_latency(enum pm_node_id nid,
326 unsigned int latency)
327{
328 uint32_t payload[PAYLOAD_ARG_CNT];
329
330 PM_PACK_PAYLOAD3(payload, PM_SET_MAX_LATENCY, nid, latency);
331 return pm_ipi_send(primary_proc, payload);
332}
333
334/* Miscellaneous API functions */
335
336/**
337 * pm_get_api_version() - Get version number of PMU PM firmware
338 * @version Returns 32-bit version number of PMU Power Management Firmware
339 *
340 * @return Returns status, either success or error+reason
341 */
342enum pm_ret_status pm_get_api_version(unsigned int *version)
343{
344 uint32_t payload[PAYLOAD_ARG_CNT];
345
346 /* Send request to the PMU */
347 PM_PACK_PAYLOAD1(payload, PM_GET_API_VERSION);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700348 return pm_ipi_send_sync(primary_proc, payload, version, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800349}
350
351/**
352 * pm_set_configuration() - PM call to set system configuration
353 * @phys_addr Physical 32-bit address of data structure in memory
354 *
355 * @return Returns status, either success or error+reason
356 */
357enum pm_ret_status pm_set_configuration(unsigned int phys_addr)
358{
359 return PM_RET_ERROR_NOTSUPPORTED;
360}
361
362/**
Filip Drazicf2ddd912017-03-15 11:50:47 +0100363 * pm_init_finalize() - Call to notify PMU firmware that master has power
364 * management enabled and that it has finished its
365 * initialization
366 *
367 * @return Status returned by the PMU firmware
368 */
369enum pm_ret_status pm_init_finalize(void)
370{
371 uint32_t payload[PAYLOAD_ARG_CNT];
372
373 /* Send request to the PMU */
374 PM_PACK_PAYLOAD1(payload, PM_INIT_FINALIZE);
375 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
376}
377
378/**
Anes Hadziahmetagic1caf88e2017-01-27 18:42:44 +0100379 * pm_get_node_status() - PM call to request a node's current status
380 * @nid Node id
381 * @ret_buff Buffer for the return values:
382 * [0] - Current power state of the node
383 * [1] - Current requirements for the node (slave nodes only)
384 * [2] - Current usage status for the node (slave nodes only)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800385 *
386 * @return Returns status, either success or error+reason
387 */
Anes Hadziahmetagic1caf88e2017-01-27 18:42:44 +0100388enum pm_ret_status pm_get_node_status(enum pm_node_id nid,
389 uint32_t *ret_buff)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800390{
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800391 uint32_t payload[PAYLOAD_ARG_CNT];
392
393 PM_PACK_PAYLOAD2(payload, PM_GET_NODE_STATUS, nid);
Anes Hadziahmetagic1caf88e2017-01-27 18:42:44 +0100394 return pm_ipi_send_sync(primary_proc, payload, ret_buff, 3);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800395}
396
397/**
398 * pm_register_notifier() - Register the PU to be notified of PM events
399 * @nid Node id of the slave
400 * @event The event to be notified about
401 * @wake Wake up on event
402 * @enable Enable or disable the notifier
403 *
404 * @return Returns status, either success or error+reason
405 */
406enum pm_ret_status pm_register_notifier(enum pm_node_id nid,
407 unsigned int event,
408 unsigned int wake,
409 unsigned int enable)
410{
Anes Hadziahmetagicc95ae092016-05-12 16:17:34 +0200411 uint32_t payload[PAYLOAD_ARG_CNT];
412
413 PM_PACK_PAYLOAD5(payload, PM_REGISTER_NOTIFIER,
414 nid, event, wake, enable);
415
Soren Brinkmanna1b0a902016-09-30 11:30:21 -0700416 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800417}
418
419/**
Anes Hadziahmetagic92aee012016-05-12 16:17:30 +0200420 * pm_get_op_characteristic() - PM call to request operating characteristics
421 * of a node
422 * @nid Node id of the slave
423 * @type Type of the operating characteristic
424 * (power, temperature and latency)
425 * @result Returns the operating characteristic for the requested node,
426 * specified by the type
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800427 *
428 * @return Returns status, either success or error+reason
429 */
430enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid,
Anes Hadziahmetagic92aee012016-05-12 16:17:30 +0200431 enum pm_opchar_type type,
432 uint32_t *result)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800433{
Anes Hadziahmetagic92aee012016-05-12 16:17:30 +0200434 uint32_t payload[PAYLOAD_ARG_CNT];
435
436 /* Send request to the PMU */
437 PM_PACK_PAYLOAD3(payload, PM_GET_OP_CHARACTERISTIC, nid, type);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700438 return pm_ipi_send_sync(primary_proc, payload, result, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800439}
440
441/* Direct-Control API functions */
442
443/**
444 * pm_reset_assert() - Assert reset
445 * @reset Reset ID
446 * @assert Assert (1) or de-assert (0)
447 *
448 * @return Returns status, either success or error+reason
449 */
450enum pm_ret_status pm_reset_assert(unsigned int reset,
451 unsigned int assert)
452{
453 uint32_t payload[PAYLOAD_ARG_CNT];
454
455 /* Send request to the PMU */
456 PM_PACK_PAYLOAD3(payload, PM_RESET_ASSERT, reset, assert);
457 return pm_ipi_send(primary_proc, payload);
458}
459
460/**
461 * pm_reset_get_status() - Get current status of a reset line
462 * @reset Reset ID
463 * @reset_status Returns current status of selected reset line
464 *
465 * @return Returns status, either success or error+reason
466 */
467enum pm_ret_status pm_reset_get_status(unsigned int reset,
468 unsigned int *reset_status)
469{
470 uint32_t payload[PAYLOAD_ARG_CNT];
471
472 /* Send request to the PMU */
473 PM_PACK_PAYLOAD2(payload, PM_RESET_GET_STATUS, reset);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700474 return pm_ipi_send_sync(primary_proc, payload, reset_status, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800475}
476
477/**
478 * pm_mmio_write() - Perform write to protected mmio
479 * @address Address to write to
480 * @mask Mask to apply
481 * @value Value to write
482 *
483 * This function provides access to PM-related control registers
484 * that may not be directly accessible by a particular PU.
485 *
486 * @return Returns status, either success or error+reason
487 */
488enum pm_ret_status pm_mmio_write(uintptr_t address,
489 unsigned int mask,
490 unsigned int value)
491{
492 uint32_t payload[PAYLOAD_ARG_CNT];
493
494 /* Send request to the PMU */
495 PM_PACK_PAYLOAD4(payload, PM_MMIO_WRITE, address, mask, value);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700496 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800497}
498
499/**
500 * pm_mmio_read() - Read value from protected mmio
501 * @address Address to write to
502 * @value Value to write
503 *
504 * This function provides access to PM-related control registers
505 * that may not be directly accessible by a particular PU.
506 *
507 * @return Returns status, either success or error+reason
508 */
509enum pm_ret_status pm_mmio_read(uintptr_t address, unsigned int *value)
510{
511 uint32_t payload[PAYLOAD_ARG_CNT];
512
513 /* Send request to the PMU */
514 PM_PACK_PAYLOAD2(payload, PM_MMIO_READ, address);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700515 return pm_ipi_send_sync(primary_proc, payload, value, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800516}
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530517
518/**
519 * pm_fpga_load() - Load the bitstream into the PL.
520 *
521 * This function provides access to the xilfpga library to load
522 * the Bit-stream into PL.
523 *
524 * address_low: lower 32-bit Linear memory space address
525 *
526 * address_high: higher 32-bit Linear memory space address
527 *
528 * size: Number of 32bit words
529 *
530 * @return Returns status, either success or error+reason
531 */
532enum pm_ret_status pm_fpga_load(uint32_t address_low,
533 uint32_t address_high,
534 uint32_t size,
535 uint32_t flags)
536{
537 uint32_t payload[PAYLOAD_ARG_CNT];
538
539 /* Send request to the PMU */
540 PM_PACK_PAYLOAD5(payload, PM_FPGA_LOAD, address_high, address_low,
541 size, flags);
Siva Durga Prasad Paladugubf83b9c2018-02-07 13:13:01 +0530542 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530543}
544
545/**
546 * pm_fpga_get_status() - Read value from fpga status register
547 * @value Value to read
548 *
549 * This function provides access to the xilfpga library to get
550 * the fpga status
551 * @return Returns status, either success or error+reason
552 */
553enum pm_ret_status pm_fpga_get_status(unsigned int *value)
554{
555 uint32_t payload[PAYLOAD_ARG_CNT];
556
557 /* Send request to the PMU */
558 PM_PACK_PAYLOAD1(payload, PM_FPGA_GET_STATUS);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700559 return pm_ipi_send_sync(primary_proc, payload, value, 1);
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530560}
Soren Brinkmanncb366812016-09-22 12:21:11 -0700561
562/**
563 * pm_get_chipid() - Read silicon ID registers
564 * @value Buffer for return values. Must be large enough
565 * to hold 8 bytes.
566 *
567 * @return Returns silicon ID registers
568 */
569enum pm_ret_status pm_get_chipid(uint32_t *value)
570{
571 uint32_t payload[PAYLOAD_ARG_CNT];
572
573 /* Send request to the PMU */
574 PM_PACK_PAYLOAD1(payload, PM_GET_CHIPID);
575 return pm_ipi_send_sync(primary_proc, payload, value, 2);
576}
Soren Brinkmann84f0af42016-09-30 14:24:25 -0700577
578/**
Siva Durga Prasad Paladugude93d982018-04-30 15:49:27 +0530579 * pm_secure_rsaaes() - Load the secure images.
580 *
581 * This function provides access to the xilsecure library to load
582 * the authenticated, encrypted, and authenicated/encrypted images.
583 *
584 * address_low: lower 32-bit Linear memory space address
585 *
586 * address_high: higher 32-bit Linear memory space address
587 *
588 * size: Number of 32bit words
589 *
590 * @return Returns status, either success or error+reason
591 */
592enum pm_ret_status pm_secure_rsaaes(uint32_t address_low,
593 uint32_t address_high,
594 uint32_t size,
595 uint32_t flags)
596{
597 uint32_t payload[PAYLOAD_ARG_CNT];
598
599 /* Send request to the PMU */
600 PM_PACK_PAYLOAD5(payload, PM_SECURE_RSA_AES, address_high, address_low,
601 size, flags);
602 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
603}
604
605/**
Siva Durga Prasad Paladugu8bd905b2018-09-04 18:05:50 +0530606 * pm_aes_engine() - Aes data blob encryption/decryption
607 * This function provides access to the xilsecure library to
608 * encrypt/decrypt data blobs.
609 *
610 * address_low: lower 32-bit address of the AesParams structure
611 *
612 * address_high: higher 32-bit address of the AesParams structure
613 *
614 * value: Returned output value
615 *
616 * @return Returns status, either success or error+reason
617 */
618enum pm_ret_status pm_aes_engine(uint32_t address_high,
619 uint32_t address_low,
620 uint32_t *value)
621{
622 uint32_t payload[PAYLOAD_ARG_CNT];
623
624 /* Send request to the PMU */
625 PM_PACK_PAYLOAD3(payload, PM_SECURE_AES, address_high, address_low);
626 return pm_ipi_send_sync(primary_proc, payload, value, 1);
627}
628
629/**
Rajan Vaja83687612018-01-17 02:39:20 -0800630 * pm_pinctrl_request() - Request Pin from firmware
631 * @pin Pin number to request
632 *
633 * This function requests pin from firmware.
634 *
635 * @return Returns status, either success or error+reason.
636 */
637enum pm_ret_status pm_pinctrl_request(unsigned int pin)
638{
639 return PM_RET_SUCCESS;
640}
641
642/**
643 * pm_pinctrl_release() - Release Pin from firmware
644 * @pin Pin number to release
645 *
646 * This function releases pin from firmware.
647 *
648 * @return Returns status, either success or error+reason.
649 */
650enum pm_ret_status pm_pinctrl_release(unsigned int pin)
651{
652 return PM_RET_SUCCESS;
653}
654
655/**
656 * pm_pinctrl_get_function() - Read function id set for the given pin
657 * @pin Pin number
658 * @nid Node ID of function currently set for given pin
659 *
660 * This function provides the function currently set for the given pin.
661 *
662 * @return Returns status, either success or error+reason
663 */
664enum pm_ret_status pm_pinctrl_get_function(unsigned int pin,
665 enum pm_node_id *nid)
666{
Rajan Vaja0ac2be12018-01-17 02:39:21 -0800667 return pm_api_pinctrl_get_function(pin, nid);
Rajan Vaja83687612018-01-17 02:39:20 -0800668}
669
670/**
671 * pm_pinctrl_set_function() - Set function id set for the given pin
672 * @pin Pin number
673 * @nid Node ID of function to set for given pin
674 *
675 * This function provides the function currently set for the given pin.
676 *
677 * @return Returns status, either success or error+reason
678 */
679enum pm_ret_status pm_pinctrl_set_function(unsigned int pin,
680 enum pm_node_id nid)
681{
Jolly Shah69fb5bf2018-02-07 16:25:41 -0800682 return pm_api_pinctrl_set_function(pin, (unsigned int)nid);
Rajan Vaja83687612018-01-17 02:39:20 -0800683}
684
685/**
686 * pm_pinctrl_get_config() - Read value of requested config param for given pin
687 * @pin Pin number
688 * @param Parameter values to be read
689 * @value Buffer for configuration Parameter value
690 *
691 * This function provides the configuration parameter value for the given pin.
692 *
693 * @return Returns status, either success or error+reason
694 */
695enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
696 unsigned int param,
697 unsigned int *value)
698{
Rajan Vaja5e139e72018-01-17 02:39:22 -0800699 return pm_api_pinctrl_get_config(pin, param, value);
Rajan Vaja83687612018-01-17 02:39:20 -0800700}
701
702/**
703 * pm_pinctrl_set_config() - Read value of requested config param for given pin
704 * @pin Pin number
705 * @param Parameter to set
706 * @value Parameter value to set
707 *
708 * This function provides the configuration parameter value for the given pin.
709 *
710 * @return Returns status, either success or error+reason
711 */
712enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
713 unsigned int param,
714 unsigned int value)
715{
Rajan Vaja5e139e72018-01-17 02:39:22 -0800716 return pm_api_pinctrl_set_config(pin, param, value);
Rajan Vaja83687612018-01-17 02:39:20 -0800717}
Rajan Vaja5529a012018-01-17 02:39:23 -0800718
719/**
720 * pm_ioctl() - PM IOCTL API for device control and configs
721 * @node_id Node ID of the device
722 * @ioctl_id ID of the requested IOCTL
723 * @arg1 Argument 1 to requested IOCTL call
724 * @arg2 Argument 2 to requested IOCTL call
725 * @out Returned output value
726 *
727 * This function calls IOCTL to firmware for device control and configuration.
728 *
729 * @return Returns status, either success or error+reason
730 */
731enum pm_ret_status pm_ioctl(enum pm_node_id nid,
732 unsigned int ioctl_id,
733 unsigned int arg1,
734 unsigned int arg2,
735 unsigned int *value)
736{
737 return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
738}
Rajan Vaja35116132018-01-17 02:39:25 -0800739
740/**
Rajan Vajada959402018-07-20 03:16:27 -0700741 * pm_clock_get_num_clocks - PM call to request number of clocks
742 * @nclockss: Number of clocks
743 *
744 * This function is used by master to get number of clocks.
745 *
746 * Return: Returns status, either success or error+reason.
747 */
748static enum pm_ret_status pm_clock_get_num_clocks(uint32_t *nclocks)
749{
750 return pm_api_clock_get_num_clocks(nclocks);
751}
752
753/**
Rajan Vaja35116132018-01-17 02:39:25 -0800754 * pm_clock_get_name() - PM call to request a clock's name
755 * @clock_id Clock ID
756 * @name Name of clock (max 16 bytes)
757 *
758 * This function is used by master to get nmae of clock specified
759 * by given clock ID.
760 *
761 * @return Returns status, either success or error+reason
762 */
763static enum pm_ret_status pm_clock_get_name(unsigned int clock_id, char *name)
764{
765 return pm_api_clock_get_name(clock_id, name);
766}
767
768/**
769 * pm_clock_get_topology() - PM call to request a clock's topology
770 * @clock_id Clock ID
771 * @index Topology index for next toplogy node
772 * @topology Buffer to store nodes in topology and flags
773 *
774 * This function is used by master to get topology information for the
775 * clock specified by given clock ID. Each response would return 3
776 * topology nodes. To get next nodes, caller needs to call this API with
777 * index of next node. Index starts from 0.
778 *
779 * @return Returns status, either success or error+reason
780 */
781static enum pm_ret_status pm_clock_get_topology(unsigned int clock_id,
782 unsigned int index,
783 uint32_t *topology)
784{
785 return pm_api_clock_get_topology(clock_id, index, topology);
786}
787
788/**
789 * pm_clock_get_fixedfactor_params() - PM call to request a clock's fixed factor
790 * parameters for fixed clock
791 * @clock_id Clock ID
792 * @mul Multiplication value
793 * @div Divisor value
794 *
795 * This function is used by master to get fixed factor parameers for the
796 * fixed clock. This API is application only for the fixed clock.
797 *
798 * @return Returns status, either success or error+reason
799 */
800static enum pm_ret_status pm_clock_get_fixedfactor_params(unsigned int clock_id,
801 uint32_t *mul,
802 uint32_t *div)
803{
804 return pm_api_clock_get_fixedfactor_params(clock_id, mul, div);
805}
806
807/**
808 * pm_clock_get_parents() - PM call to request a clock's first 3 parents
809 * @clock_id Clock ID
810 * @index Index of next parent
811 * @parents Parents of the given clock
812 *
813 * This function is used by master to get clock's parents information.
814 * This API will return 3 parents with a single response. To get other
815 * parents, master should call same API in loop with new parent index
816 * till error is returned.
817 *
818 * E.g First call should have index 0 which will return parents 0, 1 and
819 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
820 * so on.
821 *
822 * @return Returns status, either success or error+reason
823 */
824static enum pm_ret_status pm_clock_get_parents(unsigned int clock_id,
825 unsigned int index,
826 uint32_t *parents)
827{
828 return pm_api_clock_get_parents(clock_id, index, parents);
829}
830
831/**
832 * pm_clock_get_attributes() - PM call to request a clock's attributes
833 * @clock_id Clock ID
834 * @attr Clock attributes
835 *
836 * This function is used by master to get clock's attributes
837 * (e.g. valid, clock type, etc).
838 *
839 * @return Returns status, either success or error+reason
840 */
841static enum pm_ret_status pm_clock_get_attributes(unsigned int clock_id,
842 uint32_t *attr)
843{
844 return pm_api_clock_get_attributes(clock_id, attr);
845}
846
847/**
Jolly Shaha5209802019-01-04 11:45:59 -0800848 * pm_clock_gate() - Configure clock gate
849 * @clock_id Id of the clock to be configured
850 * @enable Flag 0=disable (gate the clock), !0=enable (activate the clock)
851 *
852 * @return Error if an argument is not valid or status as returned by the
853 * PM controller (PMU)
854 */
855static enum pm_ret_status pm_clock_gate(unsigned int clock_id,
856 unsigned char enable)
857{
858 uint32_t payload[PAYLOAD_ARG_CNT];
859 enum pm_ret_status status;
860 enum pm_api_id api_id;
861
862 /* Check if clock ID is valid and return an error if it is not */
863 status = pm_clock_id_is_valid(clock_id);
864 if (status != PM_RET_SUCCESS)
865 return status;
866
867 if (enable)
868 api_id = PM_CLOCK_ENABLE;
869 else
870 api_id = PM_CLOCK_DISABLE;
871
872 /* Send request to the PMU */
873 PM_PACK_PAYLOAD2(payload, api_id, clock_id);
874 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
875}
876
877/**
Rajan Vaja35116132018-01-17 02:39:25 -0800878 * pm_clock_enable() - Enable the clock for given id
879 * @clock_id: Id of the clock to be enabled
880 *
881 * This function is used by master to enable the clock
882 * including peripherals and PLL clocks.
883 *
Jolly Shaha5209802019-01-04 11:45:59 -0800884 * @return: Error if an argument is not valid or status as returned by the
885 * pm_clock_gate
Rajan Vaja35116132018-01-17 02:39:25 -0800886 */
Rajan Vaja35116132018-01-17 02:39:25 -0800887enum pm_ret_status pm_clock_enable(unsigned int clock_id)
888{
Jolly Shaha5209802019-01-04 11:45:59 -0800889 struct pm_pll *pll;
890
891 /* First try to handle it as a PLL */
892 pll = pm_clock_get_pll(clock_id);
893 if (pll)
894 return pm_clock_pll_enable(pll);
895
896 /* It's an on-chip clock, PMU should configure clock's gate */
897 return pm_clock_gate(clock_id, 1);
Rajan Vaja35116132018-01-17 02:39:25 -0800898}
899
900/**
901 * pm_clock_disable - Disable the clock for given id
902 * @clock_id: Id of the clock to be disable
903 *
904 * This function is used by master to disable the clock
905 * including peripherals and PLL clocks.
906 *
Jolly Shaha9057a02019-01-02 12:54:40 -0800907 * @return: Error if an argument is not valid or status as returned by the
908 * pm_clock_gate
Rajan Vaja35116132018-01-17 02:39:25 -0800909 */
Rajan Vaja35116132018-01-17 02:39:25 -0800910enum pm_ret_status pm_clock_disable(unsigned int clock_id)
911{
Jolly Shaha9057a02019-01-02 12:54:40 -0800912 struct pm_pll *pll;
913
914 /* First try to handle it as a PLL */
915 pll = pm_clock_get_pll(clock_id);
916 if (pll)
917 return pm_clock_pll_disable(pll);
918
919 /* It's an on-chip clock, PMU should configure clock's gate */
920 return pm_clock_gate(clock_id, 0);
Rajan Vaja35116132018-01-17 02:39:25 -0800921}
922
923/**
924 * pm_clock_getstate - Get the clock state for given id
925 * @clock_id: Id of the clock to be queried
926 * @state: 1/0 (Enabled/Disabled)
927 *
928 * This function is used by master to get the state of clock
929 * including peripherals and PLL clocks.
930 *
931 * Return: Returns status, either success or error+reason.
932 */
933enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
934 unsigned int *state)
935{
Jolly Shah99e8ac92019-01-02 12:55:41 -0800936 struct pm_pll *pll;
937 uint32_t payload[PAYLOAD_ARG_CNT];
938 enum pm_ret_status status;
939
940 /* First try to handle it as a PLL */
941 pll = pm_clock_get_pll(clock_id);
942 if (pll)
943 return pm_clock_pll_get_state(pll, state);
944
945 /* Check if clock ID is a valid on-chip clock */
946 status = pm_clock_id_is_valid(clock_id);
947 if (status != PM_RET_SUCCESS)
948 return status;
949
950 /* Send request to the PMU */
951 PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETSTATE, clock_id);
952 return pm_ipi_send_sync(primary_proc, payload, state, 1);
Rajan Vaja35116132018-01-17 02:39:25 -0800953}
954
955/**
956 * pm_clock_setdivider - Set the clock divider for given id
957 * @clock_id: Id of the clock
958 * @divider: divider value
959 *
960 * This function is used by master to set divider for any clock
961 * to achieve desired rate.
962 *
963 * Return: Returns status, either success or error+reason.
964 */
965enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
966 unsigned int divider)
967{
Jolly Shah8b4c4c72019-01-04 11:49:46 -0800968 enum pm_ret_status status;
969 enum pm_node_id nid;
970 enum pm_clock_div_id div_id;
971 uint32_t payload[PAYLOAD_ARG_CNT];
972 const uint32_t div0 = 0xFFFF0000;
973 const uint32_t div1 = 0x0000FFFF;
974 uint32_t val;
975
976 /* Get PLL node ID using PLL clock ID */
977 status = pm_clock_get_pll_node_id(clock_id, &nid);
978 if (status == PM_RET_SUCCESS)
979 return pm_pll_set_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
980
981 /* Check if clock ID is a valid on-chip clock */
982 status = pm_clock_id_is_valid(clock_id);
983 if (status != PM_RET_SUCCESS)
984 return status;
985
986 if (div0 == (divider & div0)) {
987 div_id = PM_CLOCK_DIV0_ID;
988 val = divider & ~div0;
989 } else if (div1 == (divider & div1)) {
990 div_id = PM_CLOCK_DIV1_ID;
991 val = (divider & ~div1) >> 16;
992 } else {
993 return PM_RET_ERROR_ARGS;
994 }
995
996 /* Send request to the PMU */
997 PM_PACK_PAYLOAD4(payload, PM_CLOCK_SETDIVIDER, clock_id, div_id, val);
998 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Rajan Vaja35116132018-01-17 02:39:25 -0800999}
1000
1001/**
1002 * pm_clock_getdivider - Get the clock divider for given id
1003 * @clock_id: Id of the clock
1004 * @divider: divider value
1005 *
1006 * This function is used by master to get divider values
1007 * for any clock.
1008 *
1009 * Return: Returns status, either success or error+reason.
1010 */
1011enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
1012 unsigned int *divider)
1013{
Jolly Shah4dd11762019-01-04 11:53:37 -08001014 enum pm_ret_status status;
1015 enum pm_node_id nid;
1016 uint32_t payload[PAYLOAD_ARG_CNT];
1017 uint32_t val;
1018
1019 /* Get PLL node ID using PLL clock ID */
1020 status = pm_clock_get_pll_node_id(clock_id, &nid);
1021 if (status == PM_RET_SUCCESS)
1022 return pm_pll_get_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
1023
1024 /* Check if clock ID is a valid on-chip clock */
1025 status = pm_clock_id_is_valid(clock_id);
1026 if (status != PM_RET_SUCCESS)
1027 return status;
1028
1029 if (pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) {
1030 /* Send request to the PMU to get div0 */
1031 PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
1032 PM_CLOCK_DIV0_ID);
1033 status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
1034 if (status != PM_RET_SUCCESS)
1035 return status;
1036 *divider = val;
1037 }
1038
1039 if (pm_clock_has_div(clock_id, PM_CLOCK_DIV1_ID)) {
1040 /* Send request to the PMU to get div1 */
1041 PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
1042 PM_CLOCK_DIV1_ID);
1043 status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
1044 if (status != PM_RET_SUCCESS)
1045 return status;
1046 *divider |= val << 16;
1047 }
1048
1049 return status;
Rajan Vaja35116132018-01-17 02:39:25 -08001050}
1051
1052/**
1053 * pm_clock_setrate - Set the clock rate for given id
1054 * @clock_id: Id of the clock
1055 * @rate: rate value in hz
1056 *
1057 * This function is used by master to set rate for any clock.
1058 *
1059 * Return: Returns status, either success or error+reason.
1060 */
1061enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
1062 uint64_t rate)
1063{
Jolly Shahc1391812019-01-02 13:39:30 -08001064 return PM_RET_ERROR_NOTSUPPORTED;
Rajan Vaja35116132018-01-17 02:39:25 -08001065}
1066
1067/**
1068 * pm_clock_getrate - Get the clock rate for given id
1069 * @clock_id: Id of the clock
1070 * @rate: rate value in hz
1071 *
1072 * This function is used by master to get rate
1073 * for any clock.
1074 *
1075 * Return: Returns status, either success or error+reason.
1076 */
1077enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
1078 uint64_t *rate)
1079{
Jolly Shahc1391812019-01-02 13:39:30 -08001080 return PM_RET_ERROR_NOTSUPPORTED;
Rajan Vaja35116132018-01-17 02:39:25 -08001081}
1082
1083/**
1084 * pm_clock_setparent - Set the clock parent for given id
1085 * @clock_id: Id of the clock
Jolly Shah407fc0a2019-01-04 11:57:40 -08001086 * @parent_index: Index of the parent clock into clock's parents array
Rajan Vaja35116132018-01-17 02:39:25 -08001087 *
1088 * This function is used by master to set parent for any clock.
1089 *
1090 * Return: Returns status, either success or error+reason.
1091 */
1092enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
Jolly Shah407fc0a2019-01-04 11:57:40 -08001093 unsigned int parent_index)
Rajan Vaja35116132018-01-17 02:39:25 -08001094{
Jolly Shah407fc0a2019-01-04 11:57:40 -08001095 struct pm_pll *pll;
1096 uint32_t payload[PAYLOAD_ARG_CNT];
1097 enum pm_ret_status status;
1098
1099 /* First try to handle it as a PLL */
1100 pll = pm_clock_get_pll_by_related_clk(clock_id);
1101 if (pll)
1102 return pm_clock_pll_set_parent(pll, clock_id, parent_index);
1103
1104 /* Check if clock ID is a valid on-chip clock */
1105 status = pm_clock_id_is_valid(clock_id);
1106 if (status != PM_RET_SUCCESS)
1107 return status;
1108
1109 /* Send request to the PMU */
1110 PM_PACK_PAYLOAD3(payload, PM_CLOCK_SETPARENT, clock_id, parent_index);
1111 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Rajan Vaja35116132018-01-17 02:39:25 -08001112}
1113
1114/**
1115 * pm_clock_getparent - Get the clock parent for given id
1116 * @clock_id: Id of the clock
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001117 * @parent_index: parent index
Rajan Vaja35116132018-01-17 02:39:25 -08001118 *
1119 * This function is used by master to get parent index
1120 * for any clock.
1121 *
1122 * Return: Returns status, either success or error+reason.
1123 */
1124enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001125 unsigned int *parent_index)
Rajan Vaja35116132018-01-17 02:39:25 -08001126{
Jolly Shah7c8e79c2019-01-02 13:44:25 -08001127 struct pm_pll *pll;
1128 uint32_t payload[PAYLOAD_ARG_CNT];
1129 enum pm_ret_status status;
1130
1131 /* First try to handle it as a PLL */
1132 pll = pm_clock_get_pll_by_related_clk(clock_id);
1133 if (pll)
1134 return pm_clock_pll_get_parent(pll, clock_id, parent_index);
1135
1136 /* Check if clock ID is a valid on-chip clock */
1137 status = pm_clock_id_is_valid(clock_id);
1138 if (status != PM_RET_SUCCESS)
1139 return status;
1140
1141 /* Send request to the PMU */
1142 PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETPARENT, clock_id);
1143 return pm_ipi_send_sync(primary_proc, payload, parent_index, 1);
Rajan Vaja35116132018-01-17 02:39:25 -08001144}
1145
1146/**
Rajan Vajad5dd8362018-01-30 04:16:31 -08001147 * pm_pinctrl_get_num_pins - PM call to request number of pins
1148 * @npins: Number of pins
1149 *
1150 * This function is used by master to get number of pins
1151 *
1152 * Return: Returns status, either success or error+reason.
1153 */
1154static enum pm_ret_status pm_pinctrl_get_num_pins(uint32_t *npins)
1155{
1156 return pm_api_pinctrl_get_num_pins(npins);
1157}
1158
1159/**
1160 * pm_pinctrl_get_num_functions - PM call to request number of functions
1161 * @nfuncs: Number of functions
1162 *
1163 * This function is used by master to get number of functions
1164 *
1165 * Return: Returns status, either success or error+reason.
1166 */
1167static enum pm_ret_status pm_pinctrl_get_num_functions(uint32_t *nfuncs)
1168{
1169 return pm_api_pinctrl_get_num_functions(nfuncs);
1170}
1171
1172/**
1173 * pm_pinctrl_get_num_function_groups - PM call to request number of
1174 * function groups
1175 * @fid: Id of function
1176 * @ngroups: Number of function groups
1177 *
1178 * This function is used by master to get number of function groups specified
1179 * by given function Id
1180 *
1181 * Return: Returns status, either success or error+reason.
1182 */
1183static enum pm_ret_status pm_pinctrl_get_num_function_groups(unsigned int fid,
1184 uint32_t *ngroups)
1185{
1186 return pm_api_pinctrl_get_num_func_groups(fid, ngroups);
1187}
1188
1189/**
1190 * pm_pinctrl_get_function_name - PM call to request function name
1191 * @fid: Id of function
1192 * @name: Name of function
1193 *
1194 * This function is used by master to get name of function specified
1195 * by given function Id
1196 *
1197 * Return: Returns status, either success or error+reason.
1198 */
1199static enum pm_ret_status pm_pinctrl_get_function_name(unsigned int fid,
1200 char *name)
1201{
1202 return pm_api_pinctrl_get_function_name(fid, name);
1203}
1204
1205/**
1206 * pm_pinctrl_get_function_groups - PM call to request function groups
1207 * @fid: Id of function
1208 * @index: Index of next function groups
1209 * @groups: Function groups
1210 *
1211 * This function is used by master to get function groups specified
1212 * by given function Id. This API will return 6 function groups with
1213 * a single response. To get other function groups, master should call
1214 * same API in loop with new function groups index till error is returned.
1215 *
1216 * E.g First call should have index 0 which will return function groups
1217 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
1218 * function groups 6, 7, 8, 9, 10 and 11 and so on.
1219 *
1220 * Return: Returns status, either success or error+reason.
1221 */
1222static enum pm_ret_status pm_pinctrl_get_function_groups(unsigned int fid,
1223 unsigned int index,
1224 uint16_t *groups)
1225{
1226 return pm_api_pinctrl_get_function_groups(fid, index, groups);
1227}
1228
1229/**
1230 * pm_pinctrl_get_pin_groups - PM call to request pin groups
1231 * @pin_id: Id of pin
1232 * @index: Index of next pin groups
1233 * @groups: pin groups
1234 *
1235 * This function is used by master to get pin groups specified
1236 * by given pin Id. This API will return 6 pin groups with
1237 * a single response. To get other pin groups, master should call
1238 * same API in loop with new pin groups index till error is returned.
1239 *
1240 * E.g First call should have index 0 which will return pin groups
1241 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
1242 * pin groups 6, 7, 8, 9, 10 and 11 and so on.
1243 *
1244 * Return: Returns status, either success or error+reason.
1245 */
1246static enum pm_ret_status pm_pinctrl_get_pin_groups(unsigned int pin_id,
1247 unsigned int index,
1248 uint16_t *groups)
1249{
1250 return pm_api_pinctrl_get_pin_groups(pin_id, index, groups);
1251}
1252
1253/**
Rajan Vaja35116132018-01-17 02:39:25 -08001254 * pm_query_data() - PM API for querying firmware data
1255 * @arg1 Argument 1 to requested IOCTL call
1256 * @arg2 Argument 2 to requested IOCTL call
1257 * @arg3 Argument 3 to requested IOCTL call
1258 * @arg4 Argument 4 to requested IOCTL call
1259 * @data Returned output data
1260 *
1261 * This function returns requested data.
1262 *
1263 * @return Returns status, either success or error+reason
1264 */
1265enum pm_ret_status pm_query_data(enum pm_query_id qid,
1266 unsigned int arg1,
1267 unsigned int arg2,
1268 unsigned int arg3,
1269 unsigned int *data)
1270{
1271 enum pm_ret_status ret;
1272
1273 switch (qid) {
1274 case PM_QID_CLOCK_GET_NAME:
1275 ret = pm_clock_get_name(arg1, (char *)data);
1276 break;
1277 case PM_QID_CLOCK_GET_TOPOLOGY:
1278 ret = pm_clock_get_topology(arg1, arg2, &data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001279 data[0] = (unsigned int)ret;
Rajan Vaja35116132018-01-17 02:39:25 -08001280 break;
1281 case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
1282 ret = pm_clock_get_fixedfactor_params(arg1, &data[1], &data[2]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001283 data[0] = (unsigned int)ret;
Rajan Vaja35116132018-01-17 02:39:25 -08001284 break;
1285 case PM_QID_CLOCK_GET_PARENTS:
1286 ret = pm_clock_get_parents(arg1, arg2, &data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001287 data[0] = (unsigned int)ret;
Rajan Vaja35116132018-01-17 02:39:25 -08001288 break;
1289 case PM_QID_CLOCK_GET_ATTRIBUTES:
1290 ret = pm_clock_get_attributes(arg1, &data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001291 data[0] = (unsigned int)ret;
Rajan Vaja35116132018-01-17 02:39:25 -08001292 break;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001293 case PM_QID_PINCTRL_GET_NUM_PINS:
1294 ret = pm_pinctrl_get_num_pins(&data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001295 data[0] = (unsigned int)ret;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001296 break;
1297 case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
1298 ret = pm_pinctrl_get_num_functions(&data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001299 data[0] = (unsigned int)ret;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001300 break;
1301 case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
1302 ret = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001303 data[0] = (unsigned int)ret;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001304 break;
1305 case PM_QID_PINCTRL_GET_FUNCTION_NAME:
1306 ret = pm_pinctrl_get_function_name(arg1, (char *)data);
1307 break;
1308 case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
1309 ret = pm_pinctrl_get_function_groups(arg1, arg2,
1310 (uint16_t *)&data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001311 data[0] = (unsigned int)ret;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001312 break;
1313 case PM_QID_PINCTRL_GET_PIN_GROUPS:
1314 ret = pm_pinctrl_get_pin_groups(arg1, arg2,
1315 (uint16_t *)&data[1]);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001316 data[0] = (unsigned int)ret;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001317 break;
Rajan Vajada959402018-07-20 03:16:27 -07001318 case PM_QID_CLOCK_GET_NUM_CLOCKS:
1319 ret = pm_clock_get_num_clocks(&data[1]);
1320 data[0] = (unsigned int)ret;
1321 break;
Rajan Vaja35116132018-01-17 02:39:25 -08001322 default:
1323 ret = PM_RET_ERROR_ARGS;
1324 WARN("Unimplemented query service call: 0x%x\n", qid);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08001325 break;
Rajan Vaja35116132018-01-17 02:39:25 -08001326 }
1327
1328 return ret;
1329}
Siva Durga Prasad Paladuguf3994cc2018-05-01 11:12:55 +05301330
1331enum pm_ret_status pm_sha_hash(uint32_t address_high,
1332 uint32_t address_low,
1333 uint32_t size,
1334 uint32_t flags)
1335{
1336 uint32_t payload[PAYLOAD_ARG_CNT];
1337
1338 /* Send request to the PMU */
1339 PM_PACK_PAYLOAD5(payload, PM_SECURE_SHA, address_high, address_low,
1340 size, flags);
1341 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1342}
1343
1344enum pm_ret_status pm_rsa_core(uint32_t address_high,
1345 uint32_t address_low,
1346 uint32_t size,
1347 uint32_t flags)
1348{
1349 uint32_t payload[PAYLOAD_ARG_CNT];
1350
1351 /* Send request to the PMU */
1352 PM_PACK_PAYLOAD5(payload, PM_SECURE_RSA, address_high, address_low,
1353 size, flags);
1354 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1355}
Siva Durga Prasad Paladugua4ed4b22018-04-30 20:06:58 +05301356
1357enum pm_ret_status pm_secure_image(uint32_t address_low,
1358 uint32_t address_high,
1359 uint32_t key_lo,
1360 uint32_t key_hi,
1361 uint32_t *value)
1362{
1363 uint32_t payload[PAYLOAD_ARG_CNT];
1364
1365 /* Send request to the PMU */
1366 PM_PACK_PAYLOAD5(payload, PM_SECURE_IMAGE, address_high, address_low,
1367 key_hi, key_lo);
1368 return pm_ipi_send_sync(primary_proc, payload, value, 2);
1369}
Siva Durga Prasad Paladugu7c6516a2018-09-04 17:41:34 +05301370
1371/**
1372 * pm_fpga_read - Perform the fpga configuration readback
1373 *
1374 * @reg_numframes: Configuration register offset (or) Number of frames to read
1375 * @address_low: lower 32-bit Linear memory space address
1376 * @address_high: higher 32-bit Linear memory space address
1377 * @readback_type: Type of fpga readback operation
1378 * 0 -- Configuration Register readback
1379 * 1 -- Configuration Data readback
1380 * @value: Value to read
1381 *
1382 * This function provides access to the xilfpga library to read
1383 * the PL configuration.
1384 *
1385 * Return: Returns status, either success or error+reason.
1386 */
1387enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
1388 uint32_t address_low,
1389 uint32_t address_high,
1390 uint32_t readback_type,
1391 uint32_t *value)
1392{
1393 uint32_t payload[PAYLOAD_ARG_CNT];
1394
1395 /* Send request to the PMU */
1396 PM_PACK_PAYLOAD5(payload, PM_FPGA_READ, reg_numframes, address_low,
1397 address_high, readback_type);
1398 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1399}
Jolly Shaha7cc5ee2019-01-02 12:27:00 -08001400
1401/*
1402 * pm_pll_set_parameter() - Set the PLL parameter value
1403 * @nid Node id of the target PLL
1404 * @param_id ID of the PLL parameter
1405 * @value Parameter value to be set
1406 *
1407 * Setting the parameter will have physical effect once the PLL mode is set to
1408 * integer or fractional.
1409 *
1410 * @return Error if an argument is not valid or status as returned by the
1411 * PM controller (PMU)
1412 */
1413enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
1414 enum pm_pll_param param_id,
1415 unsigned int value)
1416{
1417 uint32_t payload[PAYLOAD_ARG_CNT];
1418
1419 /* Check if given node ID is a PLL node */
1420 if (nid < NODE_APLL || nid > NODE_IOPLL)
1421 return PM_RET_ERROR_ARGS;
1422
1423 /* Check if parameter ID is valid and return an error if it's not */
1424 if (param_id >= PM_PLL_PARAM_MAX)
1425 return PM_RET_ERROR_ARGS;
1426
1427 /* Send request to the PMU */
1428 PM_PACK_PAYLOAD4(payload, PM_PLL_SET_PARAMETER, nid, param_id, value);
1429 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1430}
Jolly Shahcb2f45d2019-01-04 11:28:38 -08001431
1432/**
1433 * pm_pll_get_parameter() - Get the PLL parameter value
1434 * @nid Node id of the target PLL
1435 * @param_id ID of the PLL parameter
1436 * @value Location to store the parameter value
1437 *
1438 * @return Error if an argument is not valid or status as returned by the
1439 * PM controller (PMU)
1440 */
1441enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
1442 enum pm_pll_param param_id,
1443 unsigned int *value)
1444{
1445 uint32_t payload[PAYLOAD_ARG_CNT];
1446
1447 /* Check if given node ID is a PLL node */
1448 if (nid < NODE_APLL || nid > NODE_IOPLL)
1449 return PM_RET_ERROR_ARGS;
1450
1451 /* Check if parameter ID is valid and return an error if it's not */
1452 if (param_id >= PM_PLL_PARAM_MAX)
1453 return PM_RET_ERROR_ARGS;
1454
1455 /* Send request to the PMU */
1456 PM_PACK_PAYLOAD3(payload, PM_PLL_GET_PARAMETER, nid, param_id);
1457 return pm_ipi_send_sync(primary_proc, payload, value, 1);
1458}
Jolly Shah1f0d5852019-01-04 11:32:31 -08001459
1460/**
1461 * pm_pll_set_mode() - Set the PLL mode
1462 * @nid Node id of the target PLL
1463 * @mode PLL mode to be set
1464 *
1465 * If reset mode is set the PM controller will first bypass the PLL and then
1466 * assert the reset. If integer or fractional mode is set the PM controller will
1467 * ensure that the complete PLL programming sequence is satisfied. After this
1468 * function returns success the PLL is locked and its bypass is deasserted.
1469 *
1470 * @return Error if an argument is not valid or status as returned by the
1471 * PM controller (PMU)
1472 */
1473enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode)
1474{
1475 uint32_t payload[PAYLOAD_ARG_CNT];
1476
1477 /* Check if given node ID is a PLL node */
1478 if (nid < NODE_APLL || nid > NODE_IOPLL)
1479 return PM_RET_ERROR_ARGS;
1480
1481 /* Check if PLL mode is valid */
1482 if (mode >= PM_PLL_MODE_MAX)
1483 return PM_RET_ERROR_ARGS;
1484
1485 /* Send request to the PMU */
1486 PM_PACK_PAYLOAD3(payload, PM_PLL_SET_MODE, nid, mode);
1487 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
1488}
Jolly Shah141421e2019-01-04 11:35:48 -08001489
1490/**
1491 * pm_pll_get_mode() - Get the PLL mode
1492 * @nid Node id of the target PLL
1493 * @mode Location to store the mode of the PLL
1494 *
1495 * @return Error if an argument is not valid or status as returned by the
1496 * PM controller (PMU)
1497 */
1498enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode)
1499{
1500 uint32_t payload[PAYLOAD_ARG_CNT];
1501
1502 /* Check if given node ID is a PLL node */
1503 if (nid < NODE_APLL || nid > NODE_IOPLL)
1504 return PM_RET_ERROR_ARGS;
1505
1506 /* Send request to the PMU */
1507 PM_PACK_PAYLOAD2(payload, PM_PLL_GET_MODE, nid);
1508 return pm_ipi_send_sync(primary_proc, payload, mode, 1);
1509}