summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-zynqmp/cpu.c49
-rw-r--r--arch/arm/mach-zynqmp/include/mach/sys_proto.h3
-rw-r--r--drivers/firmware/firmware-zynqmp.c31
3 files changed, 48 insertions, 35 deletions
diff --git a/arch/arm/mach-zynqmp/cpu.c b/arch/arm/mach-zynqmp/cpu.c
index e6f2e0b3ee0..088cc962189 100644
--- a/arch/arm/mach-zynqmp/cpu.c
+++ b/arch/arm/mach-zynqmp/cpu.c
@@ -172,15 +172,19 @@ unsigned int zynqmp_get_silicon_version(void)
return ZYNQMP_CSU_VERSION_SILICON;
}
-static int zynqmp_mmio_rawwrite(const u32 address,
- const u32 mask,
- const u32 value)
+int zynqmp_mmio_rawread(const u32 address, u32 *value)
+{
+ *value = readl((ulong)address);
+ return 0;
+}
+
+int zynqmp_mmio_rawwrite(const u32 address, const u32 mask, const u32 value)
{
u32 data;
u32 value_local = value;
int ret;
- ret = zynqmp_mmio_read(address, &data);
+ ret = zynqmp_mmio_rawread(address, &data);
if (ret)
return ret;
@@ -191,48 +195,23 @@ static int zynqmp_mmio_rawwrite(const u32 address,
return 0;
}
-static int zynqmp_mmio_rawread(const u32 address, u32 *value)
-{
- *value = readl((ulong)address);
- return 0;
-}
-
-int zynqmp_mmio_write(const u32 address,
- const u32 mask,
- const u32 value)
+int __weak zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value)
{
if (IS_ENABLED(CONFIG_XPL_BUILD) || current_el() == 3)
return zynqmp_mmio_rawwrite(address, mask, value);
-#if defined(CONFIG_ZYNQMP_FIRMWARE)
- else
- return xilinx_pm_request(PM_MMIO_WRITE, address, mask,
- value, 0, 0, 0, NULL);
-#endif
return -EINVAL;
}
-int zynqmp_mmio_read(const u32 address, u32 *value)
+int __weak zynqmp_mmio_read(const u32 address, u32 *value)
{
- u32 ret = -EINVAL;
-
if (!value)
- return ret;
-
- if (IS_ENABLED(CONFIG_XPL_BUILD) || current_el() == 3) {
- ret = zynqmp_mmio_rawread(address, value);
- }
-#if defined(CONFIG_ZYNQMP_FIRMWARE)
- else {
- u32 ret_payload[PAYLOAD_ARG_CNT];
+ return -EINVAL;
- ret = xilinx_pm_request(PM_MMIO_READ, address, 0, 0,
- 0, 0, 0, ret_payload);
- *value = ret_payload[1];
- }
-#endif
+ if (IS_ENABLED(CONFIG_XPL_BUILD) || current_el() == 3)
+ return zynqmp_mmio_rawread(address, value);
- return ret;
+ return -EINVAL;
}
void zynqmp_timer_setup(void)
diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h
index 723e7593cf7..d2bb10ffcbb 100644
--- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h
+++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h
@@ -56,5 +56,8 @@ void tcm_init(enum tcm_mode mode);
#endif
/* EL3 clock/timer register setup, called from board_early_init_r() */
void zynqmp_timer_setup(void);
+/* Direct MMIO accessors (EL3/SPL or no-firmware path) */
+int zynqmp_mmio_rawread(const u32 address, u32 *value);
+int zynqmp_mmio_rawwrite(const u32 address, const u32 mask, const u32 value);
#endif /* _ASM_ARCH_SYS_PROTO_H */
diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index 4c4f4c19ae4..6052a31b5b4 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -373,6 +373,37 @@ u8 versal_net_get_bootmode(void)
}
#endif
+#if defined(CONFIG_ARCH_ZYNQMP)
+int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value)
+{
+ /* At EL3 or in SPL the firmware (SMC) path is unavailable */
+ if (IS_ENABLED(CONFIG_XPL_BUILD) || current_el() == 3)
+ return zynqmp_mmio_rawwrite(address, mask, value);
+
+ return xilinx_pm_request(PM_MMIO_WRITE, address, mask, value,
+ 0, 0, 0, NULL);
+}
+
+int zynqmp_mmio_read(const u32 address, u32 *value)
+{
+ u32 ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ if (!value)
+ return -EINVAL;
+
+ /* At EL3 or in SPL the firmware (SMC) path is unavailable */
+ if (IS_ENABLED(CONFIG_XPL_BUILD) || current_el() == 3)
+ return zynqmp_mmio_rawread(address, value);
+
+ ret = xilinx_pm_request(PM_MMIO_READ, address, 0, 0, 0, 0, 0,
+ ret_payload);
+ *value = ret_payload[1];
+
+ return ret;
+}
+#endif
+
#if defined(CONFIG_ARCH_VERSAL2)
u32 versal2_pmc_multi_boot(void)
{