diff options
| author | Michal Simek <[email protected]> | 2026-06-23 14:53:38 +0200 |
|---|---|---|
| committer | Michal Simek <[email protected]> | 2026-07-08 08:55:51 +0200 |
| commit | 4b62fc1b7e9e6ead90bbc5a5c9e82b8ee03fbfef (patch) | |
| tree | 6316b74448430425283b7c2a1d85cc71150d304d /drivers/firmware | |
| parent | 9048a9c44d5ffc99a38227df4167d401f7129aae (diff) | |
arm64: zynqmp: Decouple MMIO accessors from firmware
zynqmp_mmio_read() and zynqmp_mmio_write() selected between direct MMIO
and the firmware (PM_MMIO_READ/WRITE) interface with an in-function
IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE) / current_el() check. Generic arch
code should not carry firmware-specific ifdefs, and with SCMI the access
method changes again.
Split the accessors like the multiboot and bootmode hooks: the weak
default in arch/arm/mach-zynqmp does the direct MMIO access (used in SPL,
at EL3 and when no firmware is present), while firmware-zynqmp.c provides
a strong definition that issues the firmware call and falls back to the
direct access in SPL/EL3 where the SMC path is unavailable. The raw MMIO
primitives zynqmp_mmio_rawread() and zynqmp_mmio_rawwrite() are exported
for the shared fallback, and the read-modify-write helper now uses the
raw read instead of routing through the firmware-aware accessor.
The firmware-vs-MMIO decision is selected at link time, so adding SCMI
later only requires a third strong definition with no changes to generic
code.
Signed-off-by: Michal Simek <[email protected]>
Link: https://patch.msgid.link/d532df144d2c8e34be835bad6d0de3b26befdf01.1782219202.git.michal.simek@amd.com
Diffstat (limited to 'drivers/firmware')
| -rw-r--r-- | drivers/firmware/firmware-zynqmp.c | 31 |
1 files changed, 31 insertions, 0 deletions
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) { |
