blob: 3f3e830629961edbcaddb6a4dbfe19eb4e9940a9 [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>
13#include <platform.h>
Rajan Vaja35116132018-01-17 02:39:25 -080014#include "pm_api_clock.h"
Rajan Vaja5529a012018-01-17 02:39:23 -080015#include "pm_api_ioctl.h"
Rajan Vaja0ac2be12018-01-17 02:39:21 -080016#include "pm_api_pinctrl.h"
Isla Mitchelle3631462017-07-14 10:46:32 +010017#include "pm_api_sys.h"
Soren Brinkmann76fcae32016-03-06 20:16:27 -080018#include "pm_client.h"
Soren Brinkmann76fcae32016-03-06 20:16:27 -080019#include "pm_common.h"
Isla Mitchelle3631462017-07-14 10:46:32 +010020#include "pm_ipi.h"
Soren Brinkmann76fcae32016-03-06 20:16:27 -080021
22/**
23 * Assigning of argument values into array elements.
24 */
25#define PM_PACK_PAYLOAD1(pl, arg0) { \
26 pl[0] = (uint32_t)(arg0); \
27}
28
29#define PM_PACK_PAYLOAD2(pl, arg0, arg1) { \
30 pl[1] = (uint32_t)(arg1); \
31 PM_PACK_PAYLOAD1(pl, arg0); \
32}
33
34#define PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2) { \
35 pl[2] = (uint32_t)(arg2); \
36 PM_PACK_PAYLOAD2(pl, arg0, arg1); \
37}
38
39#define PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3) { \
40 pl[3] = (uint32_t)(arg3); \
41 PM_PACK_PAYLOAD3(pl, arg0, arg1, arg2); \
42}
43
44#define PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4) { \
45 pl[4] = (uint32_t)(arg4); \
46 PM_PACK_PAYLOAD4(pl, arg0, arg1, arg2, arg3); \
47}
48
49#define PM_PACK_PAYLOAD6(pl, arg0, arg1, arg2, arg3, arg4, arg5) { \
50 pl[5] = (uint32_t)(arg5); \
51 PM_PACK_PAYLOAD5(pl, arg0, arg1, arg2, arg3, arg4); \
52}
53
54/**
55 * pm_self_suspend() - PM call for processor to suspend itself
56 * @nid Node id of the processor or subsystem
57 * @latency Requested maximum wakeup latency (not supported)
Filip Drazic0bd9d0c2016-07-20 17:17:39 +020058 * @state Requested state
Soren Brinkmann76fcae32016-03-06 20:16:27 -080059 * @address Resume address
60 *
61 * This is a blocking call, it will return only once PMU has responded.
62 * On a wakeup, resume address will be automatically set by PMU.
63 *
64 * @return Returns status, either success or error+reason
65 */
66enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
67 unsigned int latency,
68 unsigned int state,
69 uintptr_t address)
70{
71 uint32_t payload[PAYLOAD_ARG_CNT];
72 unsigned int cpuid = plat_my_core_pos();
73 const struct pm_proc *proc = pm_get_proc(cpuid);
74
75 /*
76 * Do client specific suspend operations
77 * (e.g. set powerdown request bit)
78 */
Filip Drazic4c0765a2016-07-26 12:11:33 +020079 pm_client_suspend(proc, state);
Soren Brinkmann76fcae32016-03-06 20:16:27 -080080 /* Send request to the PMU */
81 PM_PACK_PAYLOAD6(payload, PM_SELF_SUSPEND, proc->node_id, latency,
82 state, address, (address >> 32));
Soren Brinkmannd6c9e032016-09-22 11:35:47 -070083 return pm_ipi_send_sync(proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -080084}
85
86/**
87 * pm_req_suspend() - PM call to request for another PU or subsystem to
88 * be suspended gracefully.
89 * @target Node id of the targeted PU or subsystem
90 * @ack Flag to specify whether acknowledge is requested
91 * @latency Requested wakeup latency (not supported)
92 * @state Requested state (not supported)
93 *
94 * @return Returns status, either success or error+reason
95 */
96enum pm_ret_status pm_req_suspend(enum pm_node_id target,
97 enum pm_request_ack ack,
98 unsigned int latency, unsigned int state)
99{
100 uint32_t payload[PAYLOAD_ARG_CNT];
101
102 /* Send request to the PMU */
103 PM_PACK_PAYLOAD5(payload, PM_REQ_SUSPEND, target, ack, latency, state);
104 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700105 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800106 else
107 return pm_ipi_send(primary_proc, payload);
108}
109
110/**
111 * pm_req_wakeup() - PM call for processor to wake up selected processor
112 * or subsystem
113 * @target Node id of the processor or subsystem to wake up
114 * @ack Flag to specify whether acknowledge requested
115 * @set_address Resume address presence indicator
116 * 1 resume address specified, 0 otherwise
117 * @address Resume address
118 *
119 * This API function is either used to power up another APU core for SMP
120 * (by PSCI) or to power up an entirely different PU or subsystem, such
121 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be
122 * automatically set by PMU.
123 *
124 * @return Returns status, either success or error+reason
125 */
126enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
127 unsigned int set_address,
128 uintptr_t address,
129 enum pm_request_ack ack)
130{
131 uint32_t payload[PAYLOAD_ARG_CNT];
132 uint64_t encoded_address;
133 const struct pm_proc *proc = pm_get_proc_by_node(target);
134
135 /* invoke APU-specific code for waking up another APU core */
136 pm_client_wakeup(proc);
137
138 /* encode set Address into 1st bit of address */
139 encoded_address = address;
140 encoded_address |= !!set_address;
141
142 /* Send request to the PMU to perform the wake of the PU */
143 PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address,
144 encoded_address >> 32, ack);
145
146 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700147 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800148 else
149 return pm_ipi_send(primary_proc, payload);
150}
151
152/**
153 * pm_force_powerdown() - PM call to request for another PU or subsystem to
154 * be powered down forcefully
155 * @target Node id of the targeted PU or subsystem
156 * @ack Flag to specify whether acknowledge is requested
157 *
158 * @return Returns status, either success or error+reason
159 */
160enum pm_ret_status pm_force_powerdown(enum pm_node_id target,
161 enum pm_request_ack ack)
162{
163 uint32_t payload[PAYLOAD_ARG_CNT];
164
165 /* Send request to the PMU */
166 PM_PACK_PAYLOAD3(payload, PM_FORCE_POWERDOWN, target, ack);
167
168 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700169 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800170 else
171 return pm_ipi_send(primary_proc, payload);
172}
173
174/**
175 * pm_abort_suspend() - PM call to announce that a prior suspend request
176 * is to be aborted.
177 * @reason Reason for the abort
178 *
179 * Calling PU expects the PMU to abort the initiated suspend procedure.
180 * This is a non-blocking call without any acknowledge.
181 *
182 * @return Returns status, either success or error+reason
183 */
184enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason)
185{
186 uint32_t payload[PAYLOAD_ARG_CNT];
187
188 /*
189 * Do client specific abort suspend operations
190 * (e.g. enable interrupts and clear powerdown request bit)
191 */
192 pm_client_abort_suspend();
193 /* Send request to the PMU */
194 /* TODO: allow passing the node ID of the affected CPU */
195 PM_PACK_PAYLOAD3(payload, PM_ABORT_SUSPEND, reason,
196 primary_proc->node_id);
197 return pm_ipi_send(primary_proc, payload);
198}
199
200/**
201 * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended
202 * @target Node id of the targeted PU or subsystem
203 * @wkup_node Node id of the wakeup peripheral
204 * @enable Enable or disable the specified peripheral as wake source
205 *
206 * @return Returns status, either success or error+reason
207 */
208enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
209 enum pm_node_id wkup_node,
210 unsigned int enable)
211{
212 uint32_t payload[PAYLOAD_ARG_CNT];
213
214 PM_PACK_PAYLOAD4(payload, PM_SET_WAKEUP_SOURCE, target, wkup_node,
215 enable);
216 return pm_ipi_send(primary_proc, payload);
217}
218
219/**
220 * pm_system_shutdown() - PM call to request a system shutdown or restart
221 * @restart Shutdown or restart? 0 for shutdown, 1 for restart
222 *
223 * @return Returns status, either success or error+reason
224 */
Soren Brinkmann58fbb9b2016-09-02 09:50:54 -0700225enum pm_ret_status pm_system_shutdown(unsigned int type, unsigned int subtype)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800226{
227 uint32_t payload[PAYLOAD_ARG_CNT];
228
Soren Brinkmann58fbb9b2016-09-02 09:50:54 -0700229 PM_PACK_PAYLOAD3(payload, PM_SYSTEM_SHUTDOWN, type, subtype);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800230 return pm_ipi_send(primary_proc, payload);
231}
232
233/* APIs for managing PM slaves: */
234
235/**
236 * pm_req_node() - PM call to request a node with specific capabilities
237 * @nid Node id of the slave
238 * @capabilities Requested capabilities of the slave
239 * @qos Quality of service (not supported)
240 * @ack Flag to specify whether acknowledge is requested
241 *
242 * @return Returns status, either success or error+reason
243 */
244enum pm_ret_status pm_req_node(enum pm_node_id nid,
245 unsigned int capabilities,
246 unsigned int qos,
247 enum pm_request_ack ack)
248{
249 uint32_t payload[PAYLOAD_ARG_CNT];
250
251 PM_PACK_PAYLOAD5(payload, PM_REQ_NODE, nid, capabilities, qos, ack);
252
253 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700254 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800255 else
256 return pm_ipi_send(primary_proc, payload);
257}
258
259/**
260 * pm_set_requirement() - PM call to set requirement for PM slaves
261 * @nid Node id of the slave
262 * @capabilities Requested capabilities of the slave
263 * @qos Quality of service (not supported)
264 * @ack Flag to specify whether acknowledge is requested
265 *
266 * This API function is to be used for slaves a PU already has requested
267 *
268 * @return Returns status, either success or error+reason
269 */
270enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
271 unsigned int capabilities,
272 unsigned int qos,
273 enum pm_request_ack ack)
274{
275 uint32_t payload[PAYLOAD_ARG_CNT];
276
277 PM_PACK_PAYLOAD5(payload, PM_SET_REQUIREMENT, nid, capabilities, qos,
278 ack);
279
280 if (ack == REQ_ACK_BLOCKING)
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700281 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800282 else
283 return pm_ipi_send(primary_proc, payload);
284}
285
286/**
287 * pm_release_node() - PM call to release a node
288 * @nid Node id of the slave
289 *
290 * @return Returns status, either success or error+reason
291 */
292enum pm_ret_status pm_release_node(enum pm_node_id nid)
293{
294 uint32_t payload[PAYLOAD_ARG_CNT];
295
296 PM_PACK_PAYLOAD2(payload, PM_RELEASE_NODE, nid);
297 return pm_ipi_send(primary_proc, payload);
298}
299
300/**
301 * pm_set_max_latency() - PM call to set wakeup latency requirements
302 * @nid Node id of the slave
303 * @latency Requested maximum wakeup latency
304 *
305 * @return Returns status, either success or error+reason
306 */
307enum pm_ret_status pm_set_max_latency(enum pm_node_id nid,
308 unsigned int latency)
309{
310 uint32_t payload[PAYLOAD_ARG_CNT];
311
312 PM_PACK_PAYLOAD3(payload, PM_SET_MAX_LATENCY, nid, latency);
313 return pm_ipi_send(primary_proc, payload);
314}
315
316/* Miscellaneous API functions */
317
318/**
319 * pm_get_api_version() - Get version number of PMU PM firmware
320 * @version Returns 32-bit version number of PMU Power Management Firmware
321 *
322 * @return Returns status, either success or error+reason
323 */
324enum pm_ret_status pm_get_api_version(unsigned int *version)
325{
326 uint32_t payload[PAYLOAD_ARG_CNT];
327
328 /* Send request to the PMU */
329 PM_PACK_PAYLOAD1(payload, PM_GET_API_VERSION);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700330 return pm_ipi_send_sync(primary_proc, payload, version, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800331}
332
333/**
334 * pm_set_configuration() - PM call to set system configuration
335 * @phys_addr Physical 32-bit address of data structure in memory
336 *
337 * @return Returns status, either success or error+reason
338 */
339enum pm_ret_status pm_set_configuration(unsigned int phys_addr)
340{
341 return PM_RET_ERROR_NOTSUPPORTED;
342}
343
344/**
345 * pm_get_node_status() - PM call to request a node's current power state
346 * @nid Node id of the slave
347 *
348 * @return Returns status, either success or error+reason
349 */
350enum pm_ret_status pm_get_node_status(enum pm_node_id nid)
351{
352 /* TODO: Add power state argument!! */
353 uint32_t payload[PAYLOAD_ARG_CNT];
354
355 PM_PACK_PAYLOAD2(payload, PM_GET_NODE_STATUS, nid);
356 return pm_ipi_send(primary_proc, payload);
357}
358
359/**
360 * pm_register_notifier() - Register the PU to be notified of PM events
361 * @nid Node id of the slave
362 * @event The event to be notified about
363 * @wake Wake up on event
364 * @enable Enable or disable the notifier
365 *
366 * @return Returns status, either success or error+reason
367 */
368enum pm_ret_status pm_register_notifier(enum pm_node_id nid,
369 unsigned int event,
370 unsigned int wake,
371 unsigned int enable)
372{
Anes Hadziahmetagicc95ae092016-05-12 16:17:34 +0200373 uint32_t payload[PAYLOAD_ARG_CNT];
374
375 PM_PACK_PAYLOAD5(payload, PM_REGISTER_NOTIFIER,
376 nid, event, wake, enable);
377
Soren Brinkmanna1b0a902016-09-30 11:30:21 -0700378 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800379}
380
381/**
Anes Hadziahmetagic92aee012016-05-12 16:17:30 +0200382 * pm_get_op_characteristic() - PM call to request operating characteristics
383 * of a node
384 * @nid Node id of the slave
385 * @type Type of the operating characteristic
386 * (power, temperature and latency)
387 * @result Returns the operating characteristic for the requested node,
388 * specified by the type
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800389 *
390 * @return Returns status, either success or error+reason
391 */
392enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid,
Anes Hadziahmetagic92aee012016-05-12 16:17:30 +0200393 enum pm_opchar_type type,
394 uint32_t *result)
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800395{
Anes Hadziahmetagic92aee012016-05-12 16:17:30 +0200396 uint32_t payload[PAYLOAD_ARG_CNT];
397
398 /* Send request to the PMU */
399 PM_PACK_PAYLOAD3(payload, PM_GET_OP_CHARACTERISTIC, nid, type);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700400 return pm_ipi_send_sync(primary_proc, payload, result, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800401}
402
403/* Direct-Control API functions */
404
405/**
406 * pm_reset_assert() - Assert reset
407 * @reset Reset ID
408 * @assert Assert (1) or de-assert (0)
409 *
410 * @return Returns status, either success or error+reason
411 */
412enum pm_ret_status pm_reset_assert(unsigned int reset,
413 unsigned int assert)
414{
415 uint32_t payload[PAYLOAD_ARG_CNT];
416
417 /* Send request to the PMU */
418 PM_PACK_PAYLOAD3(payload, PM_RESET_ASSERT, reset, assert);
419 return pm_ipi_send(primary_proc, payload);
420}
421
422/**
423 * pm_reset_get_status() - Get current status of a reset line
424 * @reset Reset ID
425 * @reset_status Returns current status of selected reset line
426 *
427 * @return Returns status, either success or error+reason
428 */
429enum pm_ret_status pm_reset_get_status(unsigned int reset,
430 unsigned int *reset_status)
431{
432 uint32_t payload[PAYLOAD_ARG_CNT];
433
434 /* Send request to the PMU */
435 PM_PACK_PAYLOAD2(payload, PM_RESET_GET_STATUS, reset);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700436 return pm_ipi_send_sync(primary_proc, payload, reset_status, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800437}
438
439/**
440 * pm_mmio_write() - Perform write to protected mmio
441 * @address Address to write to
442 * @mask Mask to apply
443 * @value Value to write
444 *
445 * This function provides access to PM-related control registers
446 * that may not be directly accessible by a particular PU.
447 *
448 * @return Returns status, either success or error+reason
449 */
450enum pm_ret_status pm_mmio_write(uintptr_t address,
451 unsigned int mask,
452 unsigned int value)
453{
454 uint32_t payload[PAYLOAD_ARG_CNT];
455
456 /* Send request to the PMU */
457 PM_PACK_PAYLOAD4(payload, PM_MMIO_WRITE, address, mask, value);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700458 return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800459}
460
461/**
462 * pm_mmio_read() - Read value from protected mmio
463 * @address Address to write to
464 * @value Value to write
465 *
466 * This function provides access to PM-related control registers
467 * that may not be directly accessible by a particular PU.
468 *
469 * @return Returns status, either success or error+reason
470 */
471enum pm_ret_status pm_mmio_read(uintptr_t address, unsigned int *value)
472{
473 uint32_t payload[PAYLOAD_ARG_CNT];
474
475 /* Send request to the PMU */
476 PM_PACK_PAYLOAD2(payload, PM_MMIO_READ, address);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700477 return pm_ipi_send_sync(primary_proc, payload, value, 1);
Soren Brinkmann76fcae32016-03-06 20:16:27 -0800478}
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530479
480/**
481 * pm_fpga_load() - Load the bitstream into the PL.
482 *
483 * This function provides access to the xilfpga library to load
484 * the Bit-stream into PL.
485 *
486 * address_low: lower 32-bit Linear memory space address
487 *
488 * address_high: higher 32-bit Linear memory space address
489 *
490 * size: Number of 32bit words
491 *
492 * @return Returns status, either success or error+reason
493 */
494enum pm_ret_status pm_fpga_load(uint32_t address_low,
495 uint32_t address_high,
496 uint32_t size,
497 uint32_t flags)
498{
499 uint32_t payload[PAYLOAD_ARG_CNT];
500
501 /* Send request to the PMU */
502 PM_PACK_PAYLOAD5(payload, PM_FPGA_LOAD, address_high, address_low,
503 size, flags);
504 return pm_ipi_send(primary_proc, payload);
505}
506
507/**
508 * pm_fpga_get_status() - Read value from fpga status register
509 * @value Value to read
510 *
511 * This function provides access to the xilfpga library to get
512 * the fpga status
513 * @return Returns status, either success or error+reason
514 */
515enum pm_ret_status pm_fpga_get_status(unsigned int *value)
516{
517 uint32_t payload[PAYLOAD_ARG_CNT];
518
519 /* Send request to the PMU */
520 PM_PACK_PAYLOAD1(payload, PM_FPGA_GET_STATUS);
Soren Brinkmannd6c9e032016-09-22 11:35:47 -0700521 return pm_ipi_send_sync(primary_proc, payload, value, 1);
Nava kishore Manne68d460c2016-08-20 23:18:09 +0530522}
Soren Brinkmanncb366812016-09-22 12:21:11 -0700523
524/**
525 * pm_get_chipid() - Read silicon ID registers
526 * @value Buffer for return values. Must be large enough
527 * to hold 8 bytes.
528 *
529 * @return Returns silicon ID registers
530 */
531enum pm_ret_status pm_get_chipid(uint32_t *value)
532{
533 uint32_t payload[PAYLOAD_ARG_CNT];
534
535 /* Send request to the PMU */
536 PM_PACK_PAYLOAD1(payload, PM_GET_CHIPID);
537 return pm_ipi_send_sync(primary_proc, payload, value, 2);
538}
Soren Brinkmann84f0af42016-09-30 14:24:25 -0700539
540/**
541 * pm_get_callbackdata() - Read from IPI response buffer
542 * @data - array of PAYLOAD_ARG_CNT elements
543 *
544 * Read value from ipi buffer response buffer.
545 */
546void pm_get_callbackdata(uint32_t *data, size_t count)
547{
Soren Brinkmann84f0af42016-09-30 14:24:25 -0700548 pm_ipi_buff_read_callb(data, count);
Wendy Liang328105c2017-10-03 23:21:11 -0700549 pm_ipi_irq_clear(primary_proc);
Soren Brinkmann84f0af42016-09-30 14:24:25 -0700550}
Rajan Vaja83687612018-01-17 02:39:20 -0800551
552/**
553 * pm_pinctrl_request() - Request Pin from firmware
554 * @pin Pin number to request
555 *
556 * This function requests pin from firmware.
557 *
558 * @return Returns status, either success or error+reason.
559 */
560enum pm_ret_status pm_pinctrl_request(unsigned int pin)
561{
562 return PM_RET_SUCCESS;
563}
564
565/**
566 * pm_pinctrl_release() - Release Pin from firmware
567 * @pin Pin number to release
568 *
569 * This function releases pin from firmware.
570 *
571 * @return Returns status, either success or error+reason.
572 */
573enum pm_ret_status pm_pinctrl_release(unsigned int pin)
574{
575 return PM_RET_SUCCESS;
576}
577
578/**
579 * pm_pinctrl_get_function() - Read function id set for the given pin
580 * @pin Pin number
581 * @nid Node ID of function currently set for given pin
582 *
583 * This function provides the function currently set for the given pin.
584 *
585 * @return Returns status, either success or error+reason
586 */
587enum pm_ret_status pm_pinctrl_get_function(unsigned int pin,
588 enum pm_node_id *nid)
589{
Rajan Vaja0ac2be12018-01-17 02:39:21 -0800590 return pm_api_pinctrl_get_function(pin, nid);
Rajan Vaja83687612018-01-17 02:39:20 -0800591}
592
593/**
594 * pm_pinctrl_set_function() - Set function id set for the given pin
595 * @pin Pin number
596 * @nid Node ID of function to set for given pin
597 *
598 * This function provides the function currently set for the given pin.
599 *
600 * @return Returns status, either success or error+reason
601 */
602enum pm_ret_status pm_pinctrl_set_function(unsigned int pin,
603 enum pm_node_id nid)
604{
Rajan Vaja0ac2be12018-01-17 02:39:21 -0800605 return pm_api_pinctrl_set_function(pin, nid);
Rajan Vaja83687612018-01-17 02:39:20 -0800606}
607
608/**
609 * pm_pinctrl_get_config() - Read value of requested config param for given pin
610 * @pin Pin number
611 * @param Parameter values to be read
612 * @value Buffer for configuration Parameter value
613 *
614 * This function provides the configuration parameter value for the given pin.
615 *
616 * @return Returns status, either success or error+reason
617 */
618enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
619 unsigned int param,
620 unsigned int *value)
621{
Rajan Vaja5e139e72018-01-17 02:39:22 -0800622 return pm_api_pinctrl_get_config(pin, param, value);
Rajan Vaja83687612018-01-17 02:39:20 -0800623}
624
625/**
626 * pm_pinctrl_set_config() - Read value of requested config param for given pin
627 * @pin Pin number
628 * @param Parameter to set
629 * @value Parameter value to set
630 *
631 * This function provides the configuration parameter value for the given pin.
632 *
633 * @return Returns status, either success or error+reason
634 */
635enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
636 unsigned int param,
637 unsigned int value)
638{
Rajan Vaja5e139e72018-01-17 02:39:22 -0800639 return pm_api_pinctrl_set_config(pin, param, value);
Rajan Vaja83687612018-01-17 02:39:20 -0800640}
Rajan Vaja5529a012018-01-17 02:39:23 -0800641
642/**
643 * pm_ioctl() - PM IOCTL API for device control and configs
644 * @node_id Node ID of the device
645 * @ioctl_id ID of the requested IOCTL
646 * @arg1 Argument 1 to requested IOCTL call
647 * @arg2 Argument 2 to requested IOCTL call
648 * @out Returned output value
649 *
650 * This function calls IOCTL to firmware for device control and configuration.
651 *
652 * @return Returns status, either success or error+reason
653 */
654enum pm_ret_status pm_ioctl(enum pm_node_id nid,
655 unsigned int ioctl_id,
656 unsigned int arg1,
657 unsigned int arg2,
658 unsigned int *value)
659{
660 return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
661}
Rajan Vaja35116132018-01-17 02:39:25 -0800662
663/**
664 * pm_clock_get_name() - PM call to request a clock's name
665 * @clock_id Clock ID
666 * @name Name of clock (max 16 bytes)
667 *
668 * This function is used by master to get nmae of clock specified
669 * by given clock ID.
670 *
671 * @return Returns status, either success or error+reason
672 */
673static enum pm_ret_status pm_clock_get_name(unsigned int clock_id, char *name)
674{
675 return pm_api_clock_get_name(clock_id, name);
676}
677
678/**
679 * pm_clock_get_topology() - PM call to request a clock's topology
680 * @clock_id Clock ID
681 * @index Topology index for next toplogy node
682 * @topology Buffer to store nodes in topology and flags
683 *
684 * This function is used by master to get topology information for the
685 * clock specified by given clock ID. Each response would return 3
686 * topology nodes. To get next nodes, caller needs to call this API with
687 * index of next node. Index starts from 0.
688 *
689 * @return Returns status, either success or error+reason
690 */
691static enum pm_ret_status pm_clock_get_topology(unsigned int clock_id,
692 unsigned int index,
693 uint32_t *topology)
694{
695 return pm_api_clock_get_topology(clock_id, index, topology);
696}
697
698/**
699 * pm_clock_get_fixedfactor_params() - PM call to request a clock's fixed factor
700 * parameters for fixed clock
701 * @clock_id Clock ID
702 * @mul Multiplication value
703 * @div Divisor value
704 *
705 * This function is used by master to get fixed factor parameers for the
706 * fixed clock. This API is application only for the fixed clock.
707 *
708 * @return Returns status, either success or error+reason
709 */
710static enum pm_ret_status pm_clock_get_fixedfactor_params(unsigned int clock_id,
711 uint32_t *mul,
712 uint32_t *div)
713{
714 return pm_api_clock_get_fixedfactor_params(clock_id, mul, div);
715}
716
717/**
718 * pm_clock_get_parents() - PM call to request a clock's first 3 parents
719 * @clock_id Clock ID
720 * @index Index of next parent
721 * @parents Parents of the given clock
722 *
723 * This function is used by master to get clock's parents information.
724 * This API will return 3 parents with a single response. To get other
725 * parents, master should call same API in loop with new parent index
726 * till error is returned.
727 *
728 * E.g First call should have index 0 which will return parents 0, 1 and
729 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
730 * so on.
731 *
732 * @return Returns status, either success or error+reason
733 */
734static enum pm_ret_status pm_clock_get_parents(unsigned int clock_id,
735 unsigned int index,
736 uint32_t *parents)
737{
738 return pm_api_clock_get_parents(clock_id, index, parents);
739}
740
741/**
742 * pm_clock_get_attributes() - PM call to request a clock's attributes
743 * @clock_id Clock ID
744 * @attr Clock attributes
745 *
746 * This function is used by master to get clock's attributes
747 * (e.g. valid, clock type, etc).
748 *
749 * @return Returns status, either success or error+reason
750 */
751static enum pm_ret_status pm_clock_get_attributes(unsigned int clock_id,
752 uint32_t *attr)
753{
754 return pm_api_clock_get_attributes(clock_id, attr);
755}
756
757/**
758 * pm_clock_enable() - Enable the clock for given id
759 * @clock_id: Id of the clock to be enabled
760 *
761 * This function is used by master to enable the clock
762 * including peripherals and PLL clocks.
763 *
764 * Return: Returns status, either success or error+reason.
765 */
766
767enum pm_ret_status pm_clock_enable(unsigned int clock_id)
768{
769 return pm_api_clock_enable(clock_id);
770}
771
772/**
773 * pm_clock_disable - Disable the clock for given id
774 * @clock_id: Id of the clock to be disable
775 *
776 * This function is used by master to disable the clock
777 * including peripherals and PLL clocks.
778 *
779 * Return: Returns status, either success or error+reason.
780 */
781
782enum pm_ret_status pm_clock_disable(unsigned int clock_id)
783{
784 return pm_api_clock_disable(clock_id);
785}
786
787/**
788 * pm_clock_getstate - Get the clock state for given id
789 * @clock_id: Id of the clock to be queried
790 * @state: 1/0 (Enabled/Disabled)
791 *
792 * This function is used by master to get the state of clock
793 * including peripherals and PLL clocks.
794 *
795 * Return: Returns status, either success or error+reason.
796 */
797enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
798 unsigned int *state)
799{
800 return pm_api_clock_getstate(clock_id, state);
801}
802
803/**
804 * pm_clock_setdivider - Set the clock divider for given id
805 * @clock_id: Id of the clock
806 * @divider: divider value
807 *
808 * This function is used by master to set divider for any clock
809 * to achieve desired rate.
810 *
811 * Return: Returns status, either success or error+reason.
812 */
813enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
814 unsigned int divider)
815{
816 return pm_api_clock_setdivider(clock_id, divider);
817}
818
819/**
820 * pm_clock_getdivider - Get the clock divider for given id
821 * @clock_id: Id of the clock
822 * @divider: divider value
823 *
824 * This function is used by master to get divider values
825 * for any clock.
826 *
827 * Return: Returns status, either success or error+reason.
828 */
829enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
830 unsigned int *divider)
831{
832 return pm_api_clock_getdivider(clock_id, divider);
833}
834
835/**
836 * pm_clock_setrate - Set the clock rate for given id
837 * @clock_id: Id of the clock
838 * @rate: rate value in hz
839 *
840 * This function is used by master to set rate for any clock.
841 *
842 * Return: Returns status, either success or error+reason.
843 */
844enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
845 uint64_t rate)
846{
847 return pm_api_clock_setrate(clock_id, rate);
848}
849
850/**
851 * pm_clock_getrate - Get the clock rate for given id
852 * @clock_id: Id of the clock
853 * @rate: rate value in hz
854 *
855 * This function is used by master to get rate
856 * for any clock.
857 *
858 * Return: Returns status, either success or error+reason.
859 */
860enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
861 uint64_t *rate)
862{
863 return pm_api_clock_getrate(clock_id, rate);
864}
865
866/**
867 * pm_clock_setparent - Set the clock parent for given id
868 * @clock_id: Id of the clock
869 * @parent_id: parent id
870 *
871 * This function is used by master to set parent for any clock.
872 *
873 * Return: Returns status, either success or error+reason.
874 */
875enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
876 unsigned int parent_id)
877{
878 return pm_api_clock_setparent(clock_id, parent_id);
879}
880
881/**
882 * pm_clock_getparent - Get the clock parent for given id
883 * @clock_id: Id of the clock
884 * @parent_id: parent id
885 *
886 * This function is used by master to get parent index
887 * for any clock.
888 *
889 * Return: Returns status, either success or error+reason.
890 */
891enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
892 unsigned int *parent_id)
893{
894 return pm_api_clock_getparent(clock_id, parent_id);
895}
896
897/**
Rajan Vajad5dd8362018-01-30 04:16:31 -0800898 * pm_pinctrl_get_num_pins - PM call to request number of pins
899 * @npins: Number of pins
900 *
901 * This function is used by master to get number of pins
902 *
903 * Return: Returns status, either success or error+reason.
904 */
905static enum pm_ret_status pm_pinctrl_get_num_pins(uint32_t *npins)
906{
907 return pm_api_pinctrl_get_num_pins(npins);
908}
909
910/**
911 * pm_pinctrl_get_num_functions - PM call to request number of functions
912 * @nfuncs: Number of functions
913 *
914 * This function is used by master to get number of functions
915 *
916 * Return: Returns status, either success or error+reason.
917 */
918static enum pm_ret_status pm_pinctrl_get_num_functions(uint32_t *nfuncs)
919{
920 return pm_api_pinctrl_get_num_functions(nfuncs);
921}
922
923/**
924 * pm_pinctrl_get_num_function_groups - PM call to request number of
925 * function groups
926 * @fid: Id of function
927 * @ngroups: Number of function groups
928 *
929 * This function is used by master to get number of function groups specified
930 * by given function Id
931 *
932 * Return: Returns status, either success or error+reason.
933 */
934static enum pm_ret_status pm_pinctrl_get_num_function_groups(unsigned int fid,
935 uint32_t *ngroups)
936{
937 return pm_api_pinctrl_get_num_func_groups(fid, ngroups);
938}
939
940/**
941 * pm_pinctrl_get_function_name - PM call to request function name
942 * @fid: Id of function
943 * @name: Name of function
944 *
945 * This function is used by master to get name of function specified
946 * by given function Id
947 *
948 * Return: Returns status, either success or error+reason.
949 */
950static enum pm_ret_status pm_pinctrl_get_function_name(unsigned int fid,
951 char *name)
952{
953 return pm_api_pinctrl_get_function_name(fid, name);
954}
955
956/**
957 * pm_pinctrl_get_function_groups - PM call to request function groups
958 * @fid: Id of function
959 * @index: Index of next function groups
960 * @groups: Function groups
961 *
962 * This function is used by master to get function groups specified
963 * by given function Id. This API will return 6 function groups with
964 * a single response. To get other function groups, master should call
965 * same API in loop with new function groups index till error is returned.
966 *
967 * E.g First call should have index 0 which will return function groups
968 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
969 * function groups 6, 7, 8, 9, 10 and 11 and so on.
970 *
971 * Return: Returns status, either success or error+reason.
972 */
973static enum pm_ret_status pm_pinctrl_get_function_groups(unsigned int fid,
974 unsigned int index,
975 uint16_t *groups)
976{
977 return pm_api_pinctrl_get_function_groups(fid, index, groups);
978}
979
980/**
981 * pm_pinctrl_get_pin_groups - PM call to request pin groups
982 * @pin_id: Id of pin
983 * @index: Index of next pin groups
984 * @groups: pin groups
985 *
986 * This function is used by master to get pin groups specified
987 * by given pin Id. This API will return 6 pin groups with
988 * a single response. To get other pin groups, master should call
989 * same API in loop with new pin groups index till error is returned.
990 *
991 * E.g First call should have index 0 which will return pin groups
992 * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
993 * pin groups 6, 7, 8, 9, 10 and 11 and so on.
994 *
995 * Return: Returns status, either success or error+reason.
996 */
997static enum pm_ret_status pm_pinctrl_get_pin_groups(unsigned int pin_id,
998 unsigned int index,
999 uint16_t *groups)
1000{
1001 return pm_api_pinctrl_get_pin_groups(pin_id, index, groups);
1002}
1003
1004/**
Rajan Vaja35116132018-01-17 02:39:25 -08001005 * pm_query_data() - PM API for querying firmware data
1006 * @arg1 Argument 1 to requested IOCTL call
1007 * @arg2 Argument 2 to requested IOCTL call
1008 * @arg3 Argument 3 to requested IOCTL call
1009 * @arg4 Argument 4 to requested IOCTL call
1010 * @data Returned output data
1011 *
1012 * This function returns requested data.
1013 *
1014 * @return Returns status, either success or error+reason
1015 */
1016enum pm_ret_status pm_query_data(enum pm_query_id qid,
1017 unsigned int arg1,
1018 unsigned int arg2,
1019 unsigned int arg3,
1020 unsigned int *data)
1021{
1022 enum pm_ret_status ret;
1023
1024 switch (qid) {
1025 case PM_QID_CLOCK_GET_NAME:
1026 ret = pm_clock_get_name(arg1, (char *)data);
1027 break;
1028 case PM_QID_CLOCK_GET_TOPOLOGY:
1029 ret = pm_clock_get_topology(arg1, arg2, &data[1]);
1030 data[0] = ret;
1031 break;
1032 case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
1033 ret = pm_clock_get_fixedfactor_params(arg1, &data[1], &data[2]);
1034 data[0] = ret;
1035 break;
1036 case PM_QID_CLOCK_GET_PARENTS:
1037 ret = pm_clock_get_parents(arg1, arg2, &data[1]);
1038 data[0] = ret;
1039 break;
1040 case PM_QID_CLOCK_GET_ATTRIBUTES:
1041 ret = pm_clock_get_attributes(arg1, &data[1]);
1042 data[0] = ret;
1043 break;
Rajan Vajad5dd8362018-01-30 04:16:31 -08001044 case PM_QID_PINCTRL_GET_NUM_PINS:
1045 ret = pm_pinctrl_get_num_pins(&data[1]);
1046 data[0] = ret;
1047 break;
1048 case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
1049 ret = pm_pinctrl_get_num_functions(&data[1]);
1050 data[0] = ret;
1051 break;
1052 case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
1053 ret = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
1054 data[0] = ret;
1055 break;
1056 case PM_QID_PINCTRL_GET_FUNCTION_NAME:
1057 ret = pm_pinctrl_get_function_name(arg1, (char *)data);
1058 break;
1059 case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
1060 ret = pm_pinctrl_get_function_groups(arg1, arg2,
1061 (uint16_t *)&data[1]);
1062 data[0] = ret;
1063 break;
1064 case PM_QID_PINCTRL_GET_PIN_GROUPS:
1065 ret = pm_pinctrl_get_pin_groups(arg1, arg2,
1066 (uint16_t *)&data[1]);
1067 data[0] = ret;
1068 break;
Rajan Vaja35116132018-01-17 02:39:25 -08001069 default:
1070 ret = PM_RET_ERROR_ARGS;
1071 WARN("Unimplemented query service call: 0x%x\n", qid);
1072 }
1073
1074 return ret;
1075}