summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPadmarao Begari <[email protected]>2026-05-14 15:52:19 +0530
committerMichal Simek <[email protected]>2026-06-08 10:50:05 +0200
commitf2390069d45b3490cfd87de6d6bac6e646796b6b (patch)
tree04eb60c4af8fa8af1889a64ca05935495da730f7
parent7188742e7e9b512834dcadb4ee45b6a21e23db42 (diff)
firmware: zynqmp: Add PMC PGGS register read API
Add zynqmp_pm_get_pmc_global_pggs_reg() to read PMC Global PGGS3 and PGGS4 registers via firmware IOCTL. Supports IOCTL_READ_PGGS as the preferred path and falls back to IOCTL_READ_REG for older PLM firmware versions that do not support IOCTL_READ_PGGS. Signed-off-by: Padmarao Begari <[email protected]> Signed-off-by: Michal Simek <[email protected]> Link: https://lore.kernel.org/r/[email protected]
-rw-r--r--drivers/firmware/firmware-zynqmp.c54
-rw-r--r--include/zynqmp_firmware.h4
2 files changed, 57 insertions, 1 deletions
diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index fb583580ebe..ea14ed4ef95 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -3,7 +3,7 @@
* Xilinx Zynq MPSoC Firmware driver
*
* Copyright (C) 2018-2019 Xilinx, Inc.
- * Copyright (C) 2022 - 2025, Advanced Micro Devices, Inc.
+ * Copyright (C) 2022 - 2026, Advanced Micro Devices, Inc.
*/
#include <asm/arch/hardware.h>
@@ -197,6 +197,58 @@ int zynqmp_pm_ufs_cal_reg(u32 *value)
*value = readl(PMXC_EFUSE_CACHE_BASE_ADDRESS + PMXC_UFS_CAL_1_OFFSET);
return 0;
}
+#endif /* CONFIG_ARCH_VERSAL2 */
+
+#if defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL2)
+u32 zynqmp_pm_get_pmc_global_pggs_reg(u32 reg_addr)
+{
+ int ret;
+ u32 value = 0;
+ u32 ret_payload[PAYLOAD_ARG_CNT];
+
+ if (reg_addr == PMC_GLOBAL_PGGS3_REG) {
+ value = 0;
+ } else if (reg_addr == PMC_GLOBAL_PGGS4_REG) {
+ value = 1;
+ } else {
+ printf("%s: not supported pggs register 0x%x\n",
+ __func__, reg_addr);
+ return 0;
+ }
+
+ ret = zynqmp_pm_is_function_supported(PM_IOCTL, IOCTL_READ_PGGS);
+ if (ret) {
+ ret = zynqmp_pm_is_function_supported(PM_IOCTL, IOCTL_READ_REG);
+ if (ret) {
+ printf("%s: IOCTL_READ_REG is not supported : %d\n"
+ , __func__, ret);
+ return 0;
+ }
+
+ /* find node ID from the pggs3 offset */
+ value = PM_REG_PGGS3 + value;
+
+ ret = xilinx_pm_request(PM_IOCTL, value,
+ IOCTL_READ_REG, 0, 0, 0, 0,
+ ret_payload);
+ if (ret) {
+ printf("%s: node 0x%x get pggs register failed\n",
+ __func__, value);
+ return 0;
+ }
+ } else {
+ ret = xilinx_pm_request(PM_IOCTL, PMC_GLOBAL_PGGS3_REG_NODE,
+ IOCTL_READ_PGGS, value, 0, 0, 0,
+ ret_payload);
+ if (ret) {
+ printf("%s: node 0x%x get pggs register failed\n",
+ __func__, PMC_GLOBAL_PGGS3_REG_NODE);
+ return 0;
+ }
+ }
+
+ return ret_payload[1];
+}
#endif
int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config, u32 value)
diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h
index f5e72625e53..0e545e3db1b 100644
--- a/include/zynqmp_firmware.h
+++ b/include/zynqmp_firmware.h
@@ -470,6 +470,7 @@ int zynqmp_pm_ufs_sram_csr_read(u32 *value);
int zynqmp_pm_ufs_sram_csr_write(u32 *value);
int zynqmp_pm_ufs_cal_reg(u32 *value);
u32 zynqmp_pm_get_pmc_multi_boot_reg(void);
+u32 zynqmp_pm_get_pmc_global_pggs_reg(u32 reg_addr);
/* Type of Config Object */
#define PM_CONFIG_OBJECT_TYPE_BASE 0x1U
@@ -534,4 +535,7 @@ extern smc_call_handler_t __data smc_call_handler;
#define PM_DEV_OSPI (0x1822402aU)
+#define PM_REG_PGGS3 0x30004003
+#define PMC_GLOBAL_PGGS3_REG_NODE 0x1824C005
+
#endif /* _ZYNQMP_FIRMWARE_H_ */