1 // SPDX-License-Identifier: GPL-2.0+
3 * Xilinx Zynq MPSoC Firmware layer
5 * Copyright (C) 2014-2018 Xilinx, Inc.
7 * Michal Simek <michal.simek@xilinx.com>
8 * Davorin Mista <davorin.mista@aggios.com>
9 * Jolly Shah <jollys@xilinx.com>
10 * Rajan Vaja <rajanv@xilinx.com>
13 #include <linux/arm-smccc.h>
14 #include <linux/compiler.h>
15 #include <linux/init.h>
16 #include <linux/module.h>
18 #include <linux/slab.h>
19 #include <linux/uaccess.h>
21 #include <linux/firmware/xilinx/zynqmp/firmware.h>
22 #include <linux/firmware/xilinx/zynqmp/firmware-debug.h>
24 static unsigned long register_address;
27 * zynqmp_pm_ret_code - Convert PMU-FW error codes to Linux error codes
28 * @ret_status: PMUFW return code
30 * Return: corresponding Linux error code
32 static int zynqmp_pm_ret_code(u32 ret_status)
36 case XST_PM_DOUBLE_REQ:
38 case XST_PM_NO_ACCESS:
40 case XST_PM_ABORT_SUSPEND:
44 case XST_PM_INVALID_NODE:
50 static noinline int do_fw_call_fail(u64 arg0, u64 arg1, u64 arg2,
57 * PM function call wrapper
58 * Invoke do_fw_call_smc or do_fw_call_hvc, depending on the configuration
60 static int (*do_fw_call)(u64, u64, u64, u32 *ret_payload) = do_fw_call_fail;
63 * do_fw_call_smc - Call system-level platform management layer (SMC)
64 * @arg0: Argument 0 to SMC call
65 * @arg1: Argument 1 to SMC call
66 * @arg2: Argument 2 to SMC call
67 * @ret_payload: Returned value array
69 * Return: Returns status, either success or error+reason
71 * Invoke platform management function via SMC call (no hypervisor present)
73 static noinline int do_fw_call_smc(u64 arg0, u64 arg1, u64 arg2,
76 struct arm_smccc_res res;
78 arm_smccc_smc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res);
81 ret_payload[0] = lower_32_bits(res.a0);
82 ret_payload[1] = upper_32_bits(res.a0);
83 ret_payload[2] = lower_32_bits(res.a1);
84 ret_payload[3] = upper_32_bits(res.a1);
85 ret_payload[4] = lower_32_bits(res.a2);
88 return zynqmp_pm_ret_code((enum pm_ret_status)res.a0);
92 * do_fw_call_hvc - Call system-level platform management layer (HVC)
93 * @arg0: Argument 0 to HVC call
94 * @arg1: Argument 1 to HVC call
95 * @arg2: Argument 2 to HVC call
96 * @ret_payload: Returned value array
98 * Return: Returns status, either success or error+reason
100 * Invoke platform management function via HVC
101 * HVC-based for communication through hypervisor
102 * (no direct communication with ATF)
104 static noinline int do_fw_call_hvc(u64 arg0, u64 arg1, u64 arg2,
107 struct arm_smccc_res res;
109 arm_smccc_hvc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res);
112 ret_payload[0] = lower_32_bits(res.a0);
113 ret_payload[1] = upper_32_bits(res.a0);
114 ret_payload[2] = lower_32_bits(res.a1);
115 ret_payload[3] = upper_32_bits(res.a1);
116 ret_payload[4] = lower_32_bits(res.a2);
119 return zynqmp_pm_ret_code((enum pm_ret_status)res.a0);
123 * zynqmp_pm_invoke_fn - Invoke the system-level platform management layer
124 * caller function depending on the configuration
125 * @pm_api_id: Requested PM-API call
126 * @arg0: Argument 0 to requested PM-API call
127 * @arg1: Argument 1 to requested PM-API call
128 * @arg2: Argument 2 to requested PM-API call
129 * @arg3: Argument 3 to requested PM-API call
130 * @ret_payload: Returned value array
132 * Return: Returns status, either success or error+reason
134 * Invoke platform management function for SMC or HVC call, depending on
136 * Following SMC Calling Convention (SMCCC) for SMC64:
137 * Pm Function Identifier,
138 * PM_SIP_SVC + PM_API_ID =
139 * ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT)
140 * ((SMC_64) << FUNCID_CC_SHIFT)
141 * ((SIP_START) << FUNCID_OEN_SHIFT)
142 * ((PM_API_ID) & FUNCID_NUM_MASK))
144 * PM_SIP_SVC - Registered ZynqMP SIP Service Call
145 * PM_API_ID - Platform Management API ID
147 int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1,
148 u32 arg2, u32 arg3, u32 *ret_payload)
151 * Added SIP service call Function Identifier
152 * Make sure to stay in x0 register
156 smc_arg[0] = PM_SIP_SVC | pm_api_id;
157 smc_arg[1] = ((u64)arg1 << 32) | arg0;
158 smc_arg[2] = ((u64)arg3 << 32) | arg2;
160 return do_fw_call(smc_arg[0], smc_arg[1], smc_arg[2], ret_payload);
163 static u32 pm_api_version;
164 static u32 pm_tz_version;
167 * zynqmp_pm_get_api_version - Get version number of PMU PM firmware
168 * @version: Returned version value
170 * Return: Returns status, either success or error+reason
172 static int zynqmp_pm_get_api_version(u32 *version)
174 u32 ret_payload[PAYLOAD_ARG_CNT];
180 /* Check is PM API version already verified */
181 if (pm_api_version > 0) {
182 *version = pm_api_version;
185 ret = zynqmp_pm_invoke_fn(PM_GET_API_VERSION, 0, 0, 0, 0, ret_payload);
186 *version = ret_payload[1];
192 * zynqmp_pm_get_trustzone_version - Get secure trustzone firmware version
193 * @version: Returned version value
195 * Return: Returns status, either success or error+reason
197 static int zynqmp_pm_get_trustzone_version(u32 *version)
199 u32 ret_payload[PAYLOAD_ARG_CNT];
205 /* Check is PM trustzone version already verified */
206 if (pm_tz_version > 0) {
207 *version = pm_tz_version;
210 ret = zynqmp_pm_invoke_fn(PM_GET_TRUSTZONE_VERSION, 0, 0,
212 *version = ret_payload[1];
218 * zynqmp_pm_get_chipid - Get silicon ID registers
219 * @idcode: IDCODE register
220 * @version: version register
222 * Return: Returns the status of the operation and the idcode and version
223 * registers in @idcode and @version.
225 static int zynqmp_pm_get_chipid(u32 *idcode, u32 *version)
227 u32 ret_payload[PAYLOAD_ARG_CNT];
230 if (!idcode || !version)
233 ret = zynqmp_pm_invoke_fn(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
234 *idcode = ret_payload[1];
235 *version = ret_payload[2];
241 * get_set_conduit_method - Choose SMC or HVC based communication
242 * @np: Pointer to the device_node structure
244 * Use SMC or HVC-based functions to communicate with EL2/EL3
246 * Return: Returns 0 on success or error code
248 static int get_set_conduit_method(struct device_node *np)
252 if (of_property_read_string(np, "method", &method)) {
253 pr_warn("%s missing \"method\" property\n", __func__);
257 if (!strcmp("hvc", method)) {
258 do_fw_call = do_fw_call_hvc;
259 } else if (!strcmp("smc", method)) {
260 do_fw_call = do_fw_call_smc;
262 pr_warn("%s Invalid \"method\" property: %s\n",
271 * zynqmp_pm_reset_assert - Request setting of reset (1 - assert, 0 - release)
272 * @reset: Reset to be configured
273 * @assert_flag: Flag stating should reset be asserted (1) or
276 * Return: Returns status, either success or error+reason
278 static int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset,
279 const enum zynqmp_pm_reset_action assert_flag)
281 return zynqmp_pm_invoke_fn(PM_RESET_ASSERT, reset, assert_flag,
286 * zynqmp_pm_reset_get_status - Get status of the reset
287 * @reset: Reset whose status should be returned
288 * @status: Returned status
290 * Return: Returns status, either success or error+reason
292 static int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset,
295 u32 ret_payload[PAYLOAD_ARG_CNT];
301 ret = zynqmp_pm_invoke_fn(PM_RESET_GET_STATUS, reset, 0,
303 *status = ret_payload[1];
309 * zynqmp_pm_fpga_load - Perform the fpga load
310 * @address: Address to write to
311 * @size: pl bitstream size
313 * BIT(0) - Bit-stream type.
314 * 0 - Full Bit-stream.
315 * 1 - Partial Bit-stream.
316 * BIT(1) - Authentication.
319 * BIT(2) - Encryption.
323 * The current implementation supports only Full Bit-stream.
325 * This function provides access to xilfpga library to transfer
326 * the required bitstream into PL.
328 * Return: Returns status, either success or error+reason
330 static int zynqmp_pm_fpga_load(const u64 address, const u32 size,
333 return zynqmp_pm_invoke_fn(PM_FPGA_LOAD, (u32)address,
334 ((u32)(address >> 32)), size, flags, NULL);
338 * zynqmp_pm_fpga_get_status - Read value from PCAP status register
339 * @value: Value to read
341 * This function provides access to the xilfpga library to get
344 * Return: Returns status, either success or error+reason
346 static int zynqmp_pm_fpga_get_status(u32 *value)
348 u32 ret_payload[PAYLOAD_ARG_CNT];
354 ret = zynqmp_pm_invoke_fn(PM_FPGA_GET_STATUS, 0, 0, 0, 0, ret_payload);
355 *value = ret_payload[1];
361 * zynqmp_pm_fpga_read - Perform the fpga configuration readback
362 * @reg_numframes: Configuration register offset (or) Number of frames to read
363 * @phys_address: Physical Address of the buffer
364 * @readback_type: Type of fpga readback operation
365 * @value: Value to read
367 * This function provides access to xilfpga library to perform
368 * fpga configuration readback.
370 * Return: Returns status, either success or error+reason
372 static int zynqmp_pm_fpga_read(const u32 reg_numframes, const u64 phys_address,
373 u32 readback_type, u32 *value)
375 u32 ret_payload[PAYLOAD_ARG_CNT];
381 ret = zynqmp_pm_invoke_fn(PM_FPGA_READ, reg_numframes,
382 lower_32_bits(phys_address),
383 upper_32_bits(phys_address), readback_type,
385 *value = ret_payload[1];
391 * zynqmp_pm_request_suspend - PM call to request for another PU or subsystem to
392 * be suspended gracefully.
393 * @node: Node ID of the targeted PU or subsystem
394 * @ack: Flag to specify whether acknowledge is requested
395 * @latency: Requested wakeup latency (not supported)
396 * @state: Requested state (not supported)
398 * Return: Returns status, either success or error+reason
400 static int zynqmp_pm_request_suspend(const u32 node,
401 const enum zynqmp_pm_request_ack ack,
405 return zynqmp_pm_invoke_fn(PM_REQUEST_SUSPEND, node, ack,
406 latency, state, NULL);
410 * zynqmp_pm_force_powerdown - PM call to request for another PU or subsystem to
411 * be powered down forcefully
412 * @target: Node ID of the targeted PU or subsystem
413 * @ack: Flag to specify whether acknowledge is requested
415 * Return: Returns status, either success or error+reason
417 static int zynqmp_pm_force_powerdown(const u32 target,
418 const enum zynqmp_pm_request_ack ack)
420 return zynqmp_pm_invoke_fn(PM_FORCE_POWERDOWN, target, ack, 0, 0, NULL);
424 * zynqmp_pm_request_wakeup - PM call to wake up selected master or subsystem
425 * @node: Node ID of the master or subsystem
426 * @set_addr: Specifies whether the address argument is relevant
427 * @address: Address from which to resume when woken up
428 * @ack: Flag to specify whether acknowledge requested
430 * Return: Returns status, either success or error+reason
432 static int zynqmp_pm_request_wakeup(const u32 node,
435 const enum zynqmp_pm_request_ack ack)
437 /* set_addr flag is encoded into 1st bit of address */
438 return zynqmp_pm_invoke_fn(PM_REQUEST_WAKEUP, node, address | set_addr,
439 address >> 32, ack, NULL);
443 * zynqmp_pm_set_wakeup_source - PM call to specify the wakeup source
445 * @target: Node ID of the targeted PU or subsystem
446 * @wakeup_node:Node ID of the wakeup peripheral
447 * @enable: Enable or disable the specified peripheral as wake source
449 * Return: Returns status, either success or error+reason
451 static int zynqmp_pm_set_wakeup_source(const u32 target,
452 const u32 wakeup_node,
455 return zynqmp_pm_invoke_fn(PM_SET_WAKEUP_SOURCE, target,
456 wakeup_node, enable, 0, NULL);
460 * zynqmp_pm_system_shutdown - PM call to request a system shutdown or restart
461 * @type: Shutdown or restart? 0 for shutdown, 1 for restart
462 * @subtype: Specifies which system should be restarted or shut down
464 * Return: Returns status, either success or error+reason
466 static int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype)
468 return zynqmp_pm_invoke_fn(PM_SYSTEM_SHUTDOWN, type, subtype,
473 * zynqmp_pm_request_node - PM call to request a node with specific capabilities
474 * @node: Node ID of the slave
475 * @capabilities: Requested capabilities of the slave
476 * @qos: Quality of service (not supported)
477 * @ack: Flag to specify whether acknowledge is requested
479 * Return: Returns status, either success or error+reason
481 static int zynqmp_pm_request_node(const u32 node, const u32 capabilities,
483 const enum zynqmp_pm_request_ack ack)
485 return zynqmp_pm_invoke_fn(PM_REQUEST_NODE, node, capabilities,
490 * zynqmp_pm_release_node - PM call to release a node
491 * @node: Node ID of the slave
493 * Return: Returns status, either success or error+reason
495 static int zynqmp_pm_release_node(const u32 node)
497 return zynqmp_pm_invoke_fn(PM_RELEASE_NODE, node, 0, 0, 0, NULL);
501 * zynqmp_pm_set_requirement - PM call to set requirement for PM slaves
502 * @node: Node ID of the slave
503 * @capabilities: Requested capabilities of the slave
504 * @qos: Quality of service (not supported)
505 * @ack: Flag to specify whether acknowledge is requested
507 * This API function is to be used for slaves a PU already has requested
509 * Return: Returns status, either success or error+reason
511 static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities,
513 const enum zynqmp_pm_request_ack ack)
515 return zynqmp_pm_invoke_fn(PM_SET_REQUIREMENT, node, capabilities,
520 * zynqmp_pm_set_max_latency - PM call to set wakeup latency requirements
521 * @node: Node ID of the slave
522 * @latency: Requested maximum wakeup latency
524 * Return: Returns status, either success or error+reason
526 static int zynqmp_pm_set_max_latency(const u32 node, const u32 latency)
528 return zynqmp_pm_invoke_fn(PM_SET_MAX_LATENCY, node, latency,
533 * zynqmp_pm_set_configuration - PM call to set system configuration
534 * @physical_addr: Physical 32-bit address of data structure in memory
536 * Return: Returns status, either success or error+reason
538 static int zynqmp_pm_set_configuration(const u32 physical_addr)
540 return zynqmp_pm_invoke_fn(PM_SET_CONFIGURATION, physical_addr, 0,
545 * zynqmp_pm_get_node_status - PM call to request a node's current power state
546 * @node: ID of the component or sub-system in question
547 * @status: Current operating state of the requested node
548 * @requirements: Current requirements asserted on the node,
549 * used for slave nodes only.
550 * @usage: Usage information, used for slave nodes only:
551 * PM_USAGE_NO_MASTER - No master is currently using
553 * PM_USAGE_CURRENT_MASTER - Only requesting master is
554 * currently using the node
555 * PM_USAGE_OTHER_MASTER - Only other masters are
556 * currently using the node
557 * PM_USAGE_BOTH_MASTERS - Both the current and at least
558 * one other master is currently
561 * Return: Returns status, either success or error+reason
563 static int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
564 u32 *const requirements, u32 *const usage)
566 u32 ret_payload[PAYLOAD_ARG_CNT];
572 ret = zynqmp_pm_invoke_fn(PM_GET_NODE_STATUS, node, 0, 0,
574 if (ret_payload[0] == XST_PM_SUCCESS) {
575 *status = ret_payload[1];
577 *requirements = ret_payload[2];
579 *usage = ret_payload[3];
586 * zynqmp_pm_get_operating_characteristic - PM call to request operating
587 * characteristic information
588 * @node: Node ID of the slave
589 * @type: Type of the operating characteristic requested
590 * @result: Used to return the requsted operating characteristic
592 * Return: Returns status, either success or error+reason
594 static int zynqmp_pm_get_operating_characteristic(const u32 node,
595 const enum zynqmp_pm_opchar_type type,
598 u32 ret_payload[PAYLOAD_ARG_CNT];
604 ret = zynqmp_pm_invoke_fn(PM_GET_OPERATING_CHARACTERISTIC,
605 node, type, 0, 0, ret_payload);
606 if (ret_payload[0] == XST_PM_SUCCESS)
607 *result = ret_payload[1];
613 * zynqmp_pm_init_finalize - PM call to informi firmware that the caller master
614 * has initialized its own power management
616 * Return: Returns status, either success or error+reason
618 static int zynqmp_pm_init_finalize(void)
620 return zynqmp_pm_invoke_fn(PM_PM_INIT_FINALIZE, 0, 0, 0, 0, NULL);
624 * zynqmp_pm_set_suspend_mode - Set system suspend mode
626 * @mode: Mode to set for system suspend
628 * Return: Returns status, either success or error+reason
630 static int zynqmp_pm_set_suspend_mode(u32 mode)
632 return zynqmp_pm_invoke_fn(PM_SET_SUSPEND_MODE, mode, 0, 0, 0, NULL);
636 * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash
637 * @address: Address of the data/ Address of output buffer where
638 * hash should be stored.
639 * @size: Size of the data.
641 * BIT(0) - for initializing csudma driver and SHA3(Here address
642 * and size inputs can be NULL).
643 * BIT(1) - to call Sha3_Update API which can be called multiple
644 * times when data is not contiguous.
645 * BIT(2) - to get final hash of the whole updated data.
646 * Hash will be overwritten at provided address with
649 * Return: Returns status, either success or error code.
651 static int zynqmp_pm_sha_hash(const u64 address, const u32 size,
654 u32 lower_32_bits = (u32)address;
655 u32 upper_32_bits = (u32)(address >> 32);
657 return zynqmp_pm_invoke_fn(PM_SECURE_SHA, upper_32_bits, lower_32_bits,
662 * zynqmp_pm_rsa - Access RSA hardware to encrypt/decrypt the data with RSA.
663 * @address: Address of the data
664 * @size: Size of the data.
666 * BIT(0) - Encryption/Decryption
667 * 0 - RSA decryption with private key
668 * 1 - RSA encryption with public key.
670 * Return: Returns status, either success or error code.
672 static int zynqmp_pm_rsa(const u64 address, const u32 size, const u32 flags)
674 u32 lower_32_bits = (u32)address;
675 u32 upper_32_bits = (u32)(address >> 32);
677 return zynqmp_pm_invoke_fn(PM_SECURE_RSA, upper_32_bits, lower_32_bits,
682 * zynqmp_pm_aes - Access AES hardware to encrypt/decrypt the data using
684 * @address: Address of the AesParams structure.
685 * @out: Returned output value
687 * Return: Returns status, either success or error code.
689 static int zynqmp_pm_aes_engine(const u64 address, u32 *out)
691 u32 ret_payload[PAYLOAD_ARG_CNT];
697 ret = zynqmp_pm_invoke_fn(PM_SECURE_AES, upper_32_bits(address),
698 lower_32_bits(address),
700 *out = ret_payload[1];
705 * zynqmp_pm_pinctrl_request - Request Pin from firmware
706 * @pin: Pin number to request
708 * This function requests pin from firmware.
710 * Return: Returns status, either success or error+reason.
712 static int zynqmp_pm_pinctrl_request(const u32 pin)
714 return zynqmp_pm_invoke_fn(PM_PINCTRL_REQUEST, pin, 0, 0, 0, NULL);
718 * zynqmp_pm_pinctrl_release - Inform firmware that Pin control is released
719 * @pin: Pin number to release
721 * This function release pin from firmware.
723 * Return: Returns status, either success or error+reason.
725 static int zynqmp_pm_pinctrl_release(const u32 pin)
727 return zynqmp_pm_invoke_fn(PM_PINCTRL_RELEASE, pin, 0, 0, 0, NULL);
731 * zynqmp_pm_pinctrl_get_function - Read function id set for the given pin
733 * @id: Buffer to store function ID
735 * This function provides the function currently set for the given pin.
737 * Return: Returns status, either success or error+reason
739 static int zynqmp_pm_pinctrl_get_function(const u32 pin, u32 *id)
741 u32 ret_payload[PAYLOAD_ARG_CNT];
747 ret = zynqmp_pm_invoke_fn(PM_PINCTRL_GET_FUNCTION, pin, 0,
749 *id = ret_payload[1];
755 * zynqmp_pm_pinctrl_set_function - Set requested function for the pin
757 * @id: Function ID to set
759 * This function sets requested function for the given pin.
761 * Return: Returns status, either success or error+reason.
763 static int zynqmp_pm_pinctrl_set_function(const u32 pin, const u32 id)
765 return zynqmp_pm_invoke_fn(PM_PINCTRL_SET_FUNCTION, pin, id,
770 * zynqmp_pm_pinctrl_get_config - Get configuration parameter for the pin
772 * @param: Parameter to get
773 * @value: Buffer to store parameter value
775 * This function gets requested configuration parameter for the given pin.
777 * Return: Returns status, either success or error+reason.
779 static int zynqmp_pm_pinctrl_get_config(const u32 pin, const u32 param,
782 u32 ret_payload[PAYLOAD_ARG_CNT];
788 ret = zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_GET, pin, param,
790 *value = ret_payload[1];
796 * zynqmp_pm_pinctrl_set_config - Set configuration parameter for the pin
798 * @param: Parameter to set
799 * @value: Parameter value to set
801 * This function sets requested configuration parameter for the given pin.
803 * Return: Returns status, either success or error+reason.
805 static int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param,
808 return zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_SET, pin,
809 param, value, 0, NULL);
813 * zynqmp_pm_ioctl - PM IOCTL API for device control and configs
814 * @node_id: Node ID of the device
815 * @ioctl_id: ID of the requested IOCTL
816 * @arg1: Argument 1 to requested IOCTL call
817 * @arg2: Argument 2 to requested IOCTL call
818 * @out: Returned output value
820 * This function calls IOCTL to firmware for device control and configuration.
822 * Return: Returns status, either success or error+reason
824 static int zynqmp_pm_ioctl(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2,
827 return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, ioctl_id,
832 * zynqmp_pm_config_reg_access - PM Config API for Config register access
833 * @register_access_id: ID of the requested REGISTER_ACCESS
834 * @address: Address of the register to be accessed
835 * @mask: Mask to be written to the register
836 * @value: Value to be written to the register
837 * @out: Returned output value
839 * This function calls REGISTER_ACCESS to configure CSU/PMU registers.
841 * Return: Returns status, either success or error+reason
844 static int zynqmp_pm_config_reg_access(u32 register_access_id, u32 address,
845 u32 mask, u32 value, u32 *out)
847 return zynqmp_pm_invoke_fn(PM_REGISTER_ACCESS, register_access_id,
848 address, mask, value, out);
851 static int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out)
853 return zynqmp_pm_invoke_fn(PM_QUERY_DATA, qdata.qid, qdata.arg1,
854 qdata.arg2, qdata.arg3, out);
858 * zynqmp_pm_clock_enable - Enable the clock for given id
859 * @clock_id: ID of the clock to be enabled
861 * This function is used by master to enable the clock
862 * including peripherals and PLL clocks.
864 * Return: Returns status, either success or error+reason.
866 static int zynqmp_pm_clock_enable(u32 clock_id)
868 return zynqmp_pm_invoke_fn(PM_CLOCK_ENABLE, clock_id, 0, 0, 0, NULL);
872 * zynqmp_pm_clock_disable - Disable the clock for given id
873 * @clock_id: ID of the clock to be disable
875 * This function is used by master to disable the clock
876 * including peripherals and PLL clocks.
878 * Return: Returns status, either success or error+reason.
880 static int zynqmp_pm_clock_disable(u32 clock_id)
882 return zynqmp_pm_invoke_fn(PM_CLOCK_DISABLE, clock_id, 0, 0, 0, NULL);
886 * zynqmp_pm_clock_getstate - Get the clock state for given id
887 * @clock_id: ID of the clock to be queried
888 * @state: 1/0 (Enabled/Disabled)
890 * This function is used by master to get the state of clock
891 * including peripherals and PLL clocks.
893 * Return: Returns status, either success or error+reason.
895 static int zynqmp_pm_clock_getstate(u32 clock_id, u32 *state)
897 u32 ret_payload[PAYLOAD_ARG_CNT];
900 ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETSTATE, clock_id, 0,
902 *state = ret_payload[1];
908 * zynqmp_pm_clock_setdivider - Set the clock divider for given id
909 * @clock_id: ID of the clock
910 * @divider: divider value.
912 * This function is used by master to set divider for any clock
913 * to achieve desired rate.
915 * Return: Returns status, either success or error+reason.
917 static int zynqmp_pm_clock_setdivider(u32 clock_id, u32 divider)
919 return zynqmp_pm_invoke_fn(PM_CLOCK_SETDIVIDER, clock_id, divider,
924 * zynqmp_pm_clock_getdivider - Get the clock divider for given id
925 * @clock_id: ID of the clock
926 * @divider: divider value.
928 * This function is used by master to get divider values
931 * Return: Returns status, either success or error+reason.
933 static int zynqmp_pm_clock_getdivider(u32 clock_id, u32 *divider)
935 u32 ret_payload[PAYLOAD_ARG_CNT];
938 ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETDIVIDER, clock_id, 0,
940 *divider = ret_payload[1];
946 * zynqmp_pm_clock_setrate - Set the clock rate for given id
947 * @clock_id: ID of the clock
948 * @rate: rate value in hz
950 * This function is used by master to set rate for any clock.
952 * Return: Returns status, either success or error+reason.
954 static int zynqmp_pm_clock_setrate(u32 clock_id, u64 rate)
956 return zynqmp_pm_invoke_fn(PM_CLOCK_SETRATE, clock_id,
958 (rate >> 32) & 0xFFFFFFFF,
963 * zynqmp_pm_clock_getrate - Get the clock rate for given id
964 * @clock_id: ID of the clock
965 * @rate: rate value in hz
967 * This function is used by master to get rate
970 * Return: Returns status, either success or error+reason.
972 static int zynqmp_pm_clock_getrate(u32 clock_id, u64 *rate)
974 u32 ret_payload[PAYLOAD_ARG_CNT];
977 ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETRATE, clock_id, 0,
979 *rate = ((u64)ret_payload[2] << 32) | ret_payload[1];
985 * zynqmp_pm_clock_setparent - Set the clock parent for given id
986 * @clock_id: ID of the clock
987 * @parent_id: parent id
989 * This function is used by master to set parent for any clock.
991 * Return: Returns status, either success or error+reason.
993 static int zynqmp_pm_clock_setparent(u32 clock_id, u32 parent_id)
995 return zynqmp_pm_invoke_fn(PM_CLOCK_SETPARENT, clock_id,
996 parent_id, 0, 0, NULL);
1000 * zynqmp_pm_clock_getparent - Get the clock parent for given id
1001 * @clock_id: ID of the clock
1002 * @parent_id: parent id
1004 * This function is used by master to get parent index
1007 * Return: Returns status, either success or error+reason.
1009 static int zynqmp_pm_clock_getparent(u32 clock_id, u32 *parent_id)
1011 u32 ret_payload[PAYLOAD_ARG_CNT];
1014 ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETPARENT, clock_id, 0,
1016 *parent_id = ret_payload[1];
1022 * zynqmp_pm_efuse_access - Provides access to efuse memory.
1023 * @address: Address of the efuse params structure
1024 * @out: Returned output value
1026 * Return: Returns status, either success or error code.
1028 static int zynqmp_pm_efuse_access(const u64 address, u32 *out)
1030 u32 ret_payload[PAYLOAD_ARG_CNT];
1036 ret = zynqmp_pm_invoke_fn(PM_EFUSE_ACCESS, upper_32_bits(address),
1037 lower_32_bits(address), 0, 0, ret_payload);
1038 *out = ret_payload[1];
1043 static const struct zynqmp_eemi_ops eemi_ops = {
1044 .get_api_version = zynqmp_pm_get_api_version,
1045 .get_chipid = zynqmp_pm_get_chipid,
1046 .reset_assert = zynqmp_pm_reset_assert,
1047 .reset_get_status = zynqmp_pm_reset_get_status,
1048 .fpga_load = zynqmp_pm_fpga_load,
1049 .fpga_get_status = zynqmp_pm_fpga_get_status,
1050 .fpga_read = zynqmp_pm_fpga_read,
1051 .sha_hash = zynqmp_pm_sha_hash,
1052 .rsa = zynqmp_pm_rsa,
1053 .request_suspend = zynqmp_pm_request_suspend,
1054 .force_powerdown = zynqmp_pm_force_powerdown,
1055 .request_wakeup = zynqmp_pm_request_wakeup,
1056 .set_wakeup_source = zynqmp_pm_set_wakeup_source,
1057 .system_shutdown = zynqmp_pm_system_shutdown,
1058 .request_node = zynqmp_pm_request_node,
1059 .release_node = zynqmp_pm_release_node,
1060 .set_requirement = zynqmp_pm_set_requirement,
1061 .set_max_latency = zynqmp_pm_set_max_latency,
1062 .set_configuration = zynqmp_pm_set_configuration,
1063 .get_node_status = zynqmp_pm_get_node_status,
1064 .get_operating_characteristic = zynqmp_pm_get_operating_characteristic,
1065 .init_finalize = zynqmp_pm_init_finalize,
1066 .set_suspend_mode = zynqmp_pm_set_suspend_mode,
1067 .ioctl = zynqmp_pm_ioctl,
1068 .query_data = zynqmp_pm_query_data,
1069 .pinctrl_request = zynqmp_pm_pinctrl_request,
1070 .pinctrl_release = zynqmp_pm_pinctrl_release,
1071 .pinctrl_get_function = zynqmp_pm_pinctrl_get_function,
1072 .pinctrl_set_function = zynqmp_pm_pinctrl_set_function,
1073 .pinctrl_get_config = zynqmp_pm_pinctrl_get_config,
1074 .pinctrl_set_config = zynqmp_pm_pinctrl_set_config,
1075 .clock_enable = zynqmp_pm_clock_enable,
1076 .clock_disable = zynqmp_pm_clock_disable,
1077 .clock_getstate = zynqmp_pm_clock_getstate,
1078 .clock_setdivider = zynqmp_pm_clock_setdivider,
1079 .clock_getdivider = zynqmp_pm_clock_getdivider,
1080 .clock_setrate = zynqmp_pm_clock_setrate,
1081 .clock_getrate = zynqmp_pm_clock_getrate,
1082 .clock_setparent = zynqmp_pm_clock_setparent,
1083 .clock_getparent = zynqmp_pm_clock_getparent,
1084 .register_access = zynqmp_pm_config_reg_access,
1085 .aes = zynqmp_pm_aes_engine,
1086 .efuse_access = zynqmp_pm_efuse_access,
1090 * zynqmp_pm_get_eemi_ops - Get eemi ops functions
1092 * Return: - pointer of eemi_ops structure
1094 const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void)
1098 EXPORT_SYMBOL_GPL(zynqmp_pm_get_eemi_ops);
1101 * struct zynqmp_pm_shutdown_scope - Struct for shutdown scope
1102 * @subtype: Shutdown subtype
1103 * @name: Matching string for scope argument
1105 * This struct encapsulates mapping between shutdown scope ID and string.
1107 struct zynqmp_pm_shutdown_scope {
1108 const enum zynqmp_pm_shutdown_subtype subtype;
1112 static struct zynqmp_pm_shutdown_scope shutdown_scopes[] = {
1113 [ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM] = {
1114 .subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM,
1115 .name = "subsystem",
1117 [ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY] = {
1118 .subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY,
1121 [ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM] = {
1122 .subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM,
1127 static struct zynqmp_pm_shutdown_scope *selected_scope =
1128 &shutdown_scopes[ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM];
1131 * zynqmp_pm_is_shutdown_scope_valid - Check if shutdown scope string is valid
1132 * @scope_string: Shutdown scope string
1134 * Return: Return pointer to matching shutdown scope struct from
1135 * array of available options in system if string is valid,
1136 * otherwise returns NULL.
1138 static struct zynqmp_pm_shutdown_scope*
1139 zynqmp_pm_is_shutdown_scope_valid(const char *scope_string)
1143 for (count = 0; count < ARRAY_SIZE(shutdown_scopes); count++)
1144 if (sysfs_streq(scope_string, shutdown_scopes[count].name))
1145 return &shutdown_scopes[count];
1151 * shutdown_scope_show - Show shutdown_scope sysfs attribute
1152 * @kobj: Kobject structure
1153 * @attr: Kobject attribute structure
1154 * @buf: Requested available shutdown_scope attributes string
1156 * User-space interface for viewing the available scope options for system
1157 * shutdown. Scope option for next shutdown call is marked with [].
1159 * Usage: cat /sys/firmware/zynqmp/shutdown_scope
1161 * Return: Number of bytes printed into the buffer.
1163 static ssize_t shutdown_scope_show(struct kobject *kobj,
1164 struct kobj_attribute *attr,
1169 for (i = 0; i < ARRAY_SIZE(shutdown_scopes); i++) {
1170 if (&shutdown_scopes[i] == selected_scope) {
1172 strcat(buf, shutdown_scopes[i].name);
1175 strcat(buf, shutdown_scopes[i].name);
1185 * shutdown_scope_store - Store shutdown_scope sysfs attribute
1186 * @kobj: Kobject structure
1187 * @attr: Kobject attribute structure
1188 * @buf: User entered shutdown_scope attribute string
1189 * @count: Buffer size
1191 * User-space interface for setting the scope for the next system shutdown.
1192 * Usage: echo <scope> > /sys/firmware/zynqmp/shutdown_scope
1194 * The Linux shutdown functionality implemented via PSCI system_off does not
1195 * include an option to set a scope, i.e. which parts of the system to shut
1198 * This API function allows to set the shutdown scope for the next shutdown
1199 * request by passing it to the ATF running in EL3. When the next shutdown
1200 * is performed, the platform specific portion of PSCI-system_off can use
1201 * the chosen shutdown scope.
1203 * subsystem: Only the APU along with all of its peripherals not used by other
1204 * processing units will be shut down. This may result in the FPD
1205 * power domain being shut down provided that no other processing
1206 * unit uses FPD peripherals or DRAM.
1207 * ps_only: The complete PS will be shut down, including the RPU, PMU, etc.
1208 * Only the PL domain (FPGA) remains untouched.
1209 * system: The complete system/device is shut down.
1211 * Return: count argument if request succeeds, the corresponding error
1214 static ssize_t shutdown_scope_store(struct kobject *kobj,
1215 struct kobj_attribute *attr,
1216 const char *buf, size_t count)
1219 struct zynqmp_pm_shutdown_scope *scope;
1221 scope = zynqmp_pm_is_shutdown_scope_valid(buf);
1225 ret = zynqmp_pm_system_shutdown(ZYNQMP_PM_SHUTDOWN_TYPE_SETSCOPE_ONLY,
1228 pr_err("unable to set shutdown scope %s\n", buf);
1232 selected_scope = scope;
1237 static struct kobj_attribute zynqmp_attr_shutdown_scope =
1238 __ATTR_RW(shutdown_scope);
1241 * health_status_store - Store health_status sysfs attribute
1242 * @kobj: Kobject structure
1243 * @attr: Kobject attribute structure
1244 * @buf: User entered health_status attribute string
1245 * @count: Buffer size
1247 * User-space interface for setting the boot health status.
1248 * Usage: echo <value> > /sys/firmware/zynqmp/health_status
1251 * 1 - Set healthy bit to 1
1252 * 0 - Unset healthy bit
1254 * Return: count argument if request succeeds, the corresponding error
1257 static ssize_t health_status_store(struct kobject *kobj,
1258 struct kobj_attribute *attr,
1259 const char *buf, size_t count)
1264 ret = kstrtouint(buf, 10, &value);
1268 ret = zynqmp_pm_ioctl(0, IOCTL_SET_BOOT_HEALTH_STATUS, value, 0, NULL);
1270 pr_err("unable to set healthy bit value to %u\n", value);
1277 static struct kobj_attribute zynqmp_attr_health_status =
1278 __ATTR_WO(health_status);
1281 * config_reg_store - Write config_reg sysfs attribute
1282 * @kobj: Kobject structure
1283 * @attr: Kobject attribute structure
1284 * @buf: User entered health_status attribute string
1285 * @count: Buffer size
1287 * User-space interface for setting the config register.
1289 * To write any CSU/PMU register
1290 * echo <address> <mask> <values> > /sys/firmware/zynqmp/config_reg
1292 * echo 0x345AB234 0xFFFFFFFF 0x1234ABCD > /sys/firmware/zynqmp/config_reg
1294 * To Read any CSU/PMU register, write address to the variable like below
1295 * echo <address> > /sys/firmware/zynqmp/config_reg
1297 * Return: count argument if request succeeds, the corresponding error
1300 static ssize_t config_reg_store(struct kobject *kobj,
1301 struct kobj_attribute *attr,
1302 const char *buf, size_t count)
1304 char *kern_buff, *inbuf, *tok;
1305 unsigned long address, value, mask;
1308 kern_buff = kzalloc(count, GFP_KERNEL);
1312 ret = strlcpy(kern_buff, buf, count);
1320 /* Read the addess */
1321 tok = strsep(&inbuf, " ");
1326 ret = kstrtol(tok, 16, &address);
1331 /* Read the write value */
1332 tok = strsep(&inbuf, " ");
1334 * If parameter provided is only address, then its a read operation.
1335 * Store the address in a global variable and retrieve whenever
1339 register_address = address;
1342 register_address = address;
1344 ret = kstrtol(tok, 16, &mask);
1349 tok = strsep(&inbuf, " ");
1354 ret = kstrtol(tok, 16, &value);
1359 ret = zynqmp_pm_config_reg_access(CONFIG_REG_WRITE, address,
1362 pr_err("unable to write value to %lx\n", value);
1371 * config_reg_show - Read config_reg sysfs attribute
1372 * @kobj: Kobject structure
1373 * @attr: Kobject attribute structure
1374 * @buf: User entered health_status attribute string
1376 * User-space interface for getting the config register.
1378 * To Read any CSU/PMU register, write address to the variable like below
1379 * echo <address> > /sys/firmware/zynqmp/config_reg
1381 * Then Read the address using below command
1382 * cat /sys/firmware/zynqmp/config_reg
1384 * Return: number of chars written to buf.
1386 static ssize_t config_reg_show(struct kobject *kobj,
1387 struct kobj_attribute *attr,
1391 u32 ret_payload[PAYLOAD_ARG_CNT];
1393 ret = zynqmp_pm_config_reg_access(CONFIG_REG_READ, register_address,
1398 return sprintf(buf, "0x%x\n", ret_payload[1]);
1401 static struct kobj_attribute zynqmp_attr_config_reg =
1402 __ATTR_RW(config_reg);
1404 static struct attribute *attrs[] = {
1405 &zynqmp_attr_shutdown_scope.attr,
1406 &zynqmp_attr_health_status.attr,
1407 &zynqmp_attr_config_reg.attr,
1411 static const struct attribute_group attr_group = {
1416 static int zynqmp_pm_sysfs_init(void)
1418 struct kobject *zynqmp_kobj;
1421 zynqmp_kobj = kobject_create_and_add("zynqmp", firmware_kobj);
1423 pr_err("zynqmp: Firmware kobj add failed.\n");
1427 ret = sysfs_create_group(zynqmp_kobj, &attr_group);
1429 pr_err("%s() sysfs creation fail with error %d\n",
1434 ret = zynqmp_pm_ggs_init(zynqmp_kobj);
1436 pr_err("%s() GGS init fail with error %d\n",
1444 static int __init zynqmp_plat_init(void)
1446 struct device_node *np;
1449 np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp");
1454 /* We're running on a ZynqMP machine, the PM node is mandatory. */
1455 np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp-firmware");
1457 pr_warn("%s: pm node not found\n", __func__);
1461 ret = get_set_conduit_method(np);
1467 /* Check PM API version number */
1468 zynqmp_pm_get_api_version(&pm_api_version);
1469 if (pm_api_version < ZYNQMP_PM_VERSION) {
1470 panic("%s Platform Management API version error. Expected: v%d.%d - Found: v%d.%d\n",
1472 ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR,
1473 pm_api_version >> 16, pm_api_version & 0xFFFF);
1476 pr_info("%s Platform Management API v%d.%d\n", __func__,
1477 pm_api_version >> 16, pm_api_version & 0xFFFF);
1479 /* Check trustzone version number */
1480 ret = zynqmp_pm_get_trustzone_version(&pm_tz_version);
1482 panic("Legacy trustzone found without version support\n");
1484 if (pm_tz_version < ZYNQMP_TZ_VERSION)
1485 panic("%s Trustzone version error. Expected: v%d.%d - Found: v%d.%d\n",
1487 ZYNQMP_TZ_VERSION_MAJOR, ZYNQMP_TZ_VERSION_MINOR,
1488 pm_tz_version >> 16, pm_tz_version & 0xFFFF);
1490 pr_info("%s Trustzone version v%d.%d\n", __func__,
1491 pm_tz_version >> 16, pm_tz_version & 0xFFFF);
1497 early_initcall(zynqmp_plat_init);
1499 static int zynqmp_firmware_init(void)
1503 ret = zynqmp_pm_sysfs_init();
1505 pr_err("%s() sysfs init fail with error %d\n", __func__, ret);
1509 zynqmp_pm_api_debugfs_init();
1513 device_initcall(zynqmp_firmware_init);