cadence_qspi_apb_enable_linear_mode() currently selects between a firmware request and direct register access based on IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE).
Introduce zynqmp_pm_ospi_enable_linear_mode(bool enable) with weak default implementations for Versal, Versal Net, and Versal Gen 2, and a firmware-backed override in firmware-zynqmp.c, guarded to those platforms since ZynqMP has no OSPI AXI mux to select. This removes the firmware-specific conditional from the driver while preserving existing behavior. Use a boolean argument instead of PM_OSPI_MUX_SEL_* values so the weak default implementations remain independent of zynqmp_firmware.h and firmware-specific definitions. zynqmp_pm_ospi_enable_linear_mode() only calls xilinx_pm_request(), so it lives outside the CONFIG_ZYNQMP_IPI-guarded block, same as the other wrapper functions above it. Signed-off-by: Akshay Belsare <[email protected]> --- arch/arm/mach-versal-net/cpu.c | 12 +++++++++ .../mach-versal-net/include/mach/sys_proto.h | 2 ++ arch/arm/mach-versal/cpu.c | 12 +++++++++ arch/arm/mach-versal/include/mach/sys_proto.h | 2 ++ arch/arm/mach-versal2/cpu.c | 12 +++++++++ .../arm/mach-versal2/include/mach/sys_proto.h | 2 ++ drivers/firmware/firmware-zynqmp.c | 11 ++++++++ drivers/spi/cadence_ospi_versal.c | 27 +++++-------------- 8 files changed, 60 insertions(+), 20 deletions(-) diff --git a/arch/arm/mach-versal-net/cpu.c b/arch/arm/mach-versal-net/cpu.c index 1555751da2e..f5c8e684dda 100644 --- a/arch/arm/mach-versal-net/cpu.c +++ b/arch/arm/mach-versal-net/cpu.c @@ -238,6 +238,18 @@ bool soc_detection(void) return true; } +__weak int zynqmp_pm_ospi_enable_linear_mode(bool enable) +{ + if (enable) + writel(readl(VERSAL_AXI_MUX_SEL) | + VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL); + else + writel(readl(VERSAL_AXI_MUX_SEL) & + ~VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL); + + return 0; +} + U_BOOT_DRVINFO(soc_xilinx_versal_net) = { .name = "soc_xilinx_versal_net", }; diff --git a/arch/arm/mach-versal-net/include/mach/sys_proto.h b/arch/arm/mach-versal-net/include/mach/sys_proto.h index 4907dae1108..2682b0faeea 100644 --- a/arch/arm/mach-versal-net/include/mach/sys_proto.h +++ b/arch/arm/mach-versal-net/include/mach/sys_proto.h @@ -13,3 +13,5 @@ void versal_net_timer_setup(void); u8 versal_net_get_bootmode(void); /* Direct MMIO read of the bootmode register (EL3 / no-firmware path) */ u32 versal_net_bootmode_reg(void); +/* Overridable OSPI AXI-mux select: weak MMIO default, firmware override */ +int zynqmp_pm_ospi_enable_linear_mode(bool enable); diff --git a/arch/arm/mach-versal/cpu.c b/arch/arm/mach-versal/cpu.c index 7521d45bc1a..3ec51bf560e 100644 --- a/arch/arm/mach-versal/cpu.c +++ b/arch/arm/mach-versal/cpu.c @@ -178,6 +178,18 @@ u8 __weak versal_get_bootmode(void) return reg & BOOT_MODES_MASK; } +__weak int zynqmp_pm_ospi_enable_linear_mode(bool enable) +{ + if (enable) + writel(readl(VERSAL_AXI_MUX_SEL) | + VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL); + else + writel(readl(VERSAL_AXI_MUX_SEL) & + ~VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL); + + return 0; +} + U_BOOT_DRVINFO(soc_xilinx_versal) = { .name = "soc_xilinx_versal", }; diff --git a/arch/arm/mach-versal/include/mach/sys_proto.h b/arch/arm/mach-versal/include/mach/sys_proto.h index cb373e6fad9..da357abaaee 100644 --- a/arch/arm/mach-versal/include/mach/sys_proto.h +++ b/arch/arm/mach-versal/include/mach/sys_proto.h @@ -27,5 +27,7 @@ u8 versal_get_bootmode(void); u32 versal_bootmode_reg(void); /* EL3 clock/timer register setup, called from board_early_init_r() */ void versal_timer_setup(void); +/* Overridable OSPI AXI-mux select: weak MMIO default, firmware override */ +int zynqmp_pm_ospi_enable_linear_mode(bool enable); #endif /* _ASM_ARCH_SYS_PROTO_H */ diff --git a/arch/arm/mach-versal2/cpu.c b/arch/arm/mach-versal2/cpu.c index 19baa1331bd..c2173161fd7 100644 --- a/arch/arm/mach-versal2/cpu.c +++ b/arch/arm/mach-versal2/cpu.c @@ -311,6 +311,18 @@ bool soc_detection(void) return true; } +__weak int zynqmp_pm_ospi_enable_linear_mode(bool enable) +{ + if (enable) + writel(readl(VERSAL_AXI_MUX_SEL) | + VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL); + else + writel(readl(VERSAL_AXI_MUX_SEL) & + ~VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL); + + return 0; +} + U_BOOT_DRVINFO(soc_amd_versal2) = { .name = "soc_amd_versal2", }; diff --git a/arch/arm/mach-versal2/include/mach/sys_proto.h b/arch/arm/mach-versal2/include/mach/sys_proto.h index d678adf9c26..30db724bc2c 100644 --- a/arch/arm/mach-versal2/include/mach/sys_proto.h +++ b/arch/arm/mach-versal2/include/mach/sys_proto.h @@ -21,6 +21,8 @@ u32 versal2_multi_boot_reg(void); u8 versal2_get_bootmode(void); /* EL3 clock/timer register setup, called from board_early_init_r() */ void versal2_timer_setup(void); +/* Overridable OSPI AXI-mux select: weak MMIO default, firmware override */ +int zynqmp_pm_ospi_enable_linear_mode(bool enable); int zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us); int zynqmp_pm_wait_sram_init_done(u32 timeout_us); diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index dad7fd086bf..d09e92de1b0 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -858,6 +858,17 @@ int zynqmp_pm_ospi_init(void) ZYNQMP_PM_MAX_QOS, ZYNQMP_PM_REQUEST_ACK_NO); } +#if defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL_NET) || \ + defined(CONFIG_ARCH_VERSAL2) +int zynqmp_pm_ospi_enable_linear_mode(bool enable) +{ + u32 select = enable ? PM_OSPI_MUX_SEL_LINEAR : PM_OSPI_MUX_SEL_DMA; + + return xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI, IOCTL_OSPI_MUX_SELECT, + select, 0, 0, 0, NULL); +} +#endif + static const struct udevice_id zynqmp_firmware_ids[] = { { .compatible = "xlnx,zynqmp-firmware", .data = (ulong)smc_call_legacy }, { .compatible = "xlnx,versal-firmware", .data = (ulong)smc_call_legacy}, diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index e6f4ba49e77..602a7f4884c 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -12,8 +12,8 @@ #include <asm/gpio.h> #include <asm/cache.h> #include <cpu_func.h> -#include <zynqmp_firmware.h> #include <asm/arch/hardware.h> +#include <asm/arch/sys_proto.h> #include "cadence_qspi.h" int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, @@ -200,25 +200,12 @@ int cadence_qspi_flash_reset(struct udevice *dev) void cadence_qspi_apb_enable_linear_mode(bool enable) { - if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE)) { - if (enable) - /* ahb read mode */ - xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI, - IOCTL_OSPI_MUX_SELECT, - PM_OSPI_MUX_SEL_LINEAR, 0, 0, 0, NULL); - else - /* DMA mode */ - xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI, - IOCTL_OSPI_MUX_SELECT, - PM_OSPI_MUX_SEL_DMA, 0, 0, 0, NULL); - } else { - if (enable) - writel(readl(VERSAL_AXI_MUX_SEL) | - VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL); - else - writel(readl(VERSAL_AXI_MUX_SEL) & - ~VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL); - } + int ret; + + /* ahb read mode vs. DMA mode */ + ret = zynqmp_pm_ospi_enable_linear_mode(enable); + if (ret) + printf("%s: failed to select OSPI mux mode: %d\n", __func__, ret); } int cadence_device_reset(struct udevice *bus) -- 2.25.1
