diff options
| author | Tom Rini <[email protected]> | 2025-12-19 10:30:53 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2025-12-19 10:30:53 -0600 |
| commit | 2aeaa3c4f53b11b97e2797eb3a0a7b603f60dc72 (patch) | |
| tree | f815ca39666d1bb8b5be752afcf1f400695ed93b | |
| parent | adbbf5982d26801224b10cd847dc468f8b5e4095 (diff) | |
| parent | 0b880fc95dbaed88dd55060730857b8f52765c57 (diff) | |
Merge tag 'xilinx-for-v2026.04-rc1' of https://source.denx.de/u-boot/custodians/u-boot-microblaze into next
AMD/Xilinx/FPGA changes for v2026.04-rc1
xilinx:
- Sync ESRT with detected GUID
- DT cleanups
- Add logic for FRU information multiple times
- Enable more drivers pca9541, usb5744
- Enable more commands
- Cleanup firmware DT bindings
firmware:
- Add enhancement SMC format support
clk/versal:
- Various cleanups
- Add support for Versal Gen 2
i2c:
- cdns: Add timeout for RXDV status bit polling
spi:
- cadence: Remove cdns,is-dma DT property
- cadence: Remove duplicated return
- cadence_versal: Update flash reset delay
memtop:
- Update max memory reserved spaces to 64
Versal Gen 2:
- Aligned addresses with default memory map
- Add support for reading multiboot value
MB-V:
- Make SPL smaller
- Add support for SPI
- Move SPL to run out of BRAM
ZynqMP:
- Change default load address for BL32
| -rw-r--r-- | arch/arm/dts/versal-mini-ospi.dtsi | 3 | ||||
| -rw-r--r-- | arch/arm/dts/versal-net-mini-ospi.dtsi | 3 | ||||
| -rw-r--r-- | arch/arm/dts/zynqmp-sc-vn-p-b2197-00-revA.dtso | 3 | ||||
| -rw-r--r-- | arch/arm/mach-versal2/include/mach/hardware.h | 4 | ||||
| -rw-r--r-- | arch/arm/mach-zynqmp/Kconfig | 2 | ||||
| -rw-r--r-- | board/amd/versal2/board.c | 22 | ||||
| -rw-r--r-- | board/xilinx/common/board.c | 23 | ||||
| -rw-r--r-- | board/xilinx/mbv/board.c | 14 | ||||
| -rw-r--r-- | common/memtop.c | 2 | ||||
| -rw-r--r-- | configs/amd_versal2_virt_defconfig | 5 | ||||
| -rw-r--r-- | configs/xilinx_mbv32_defconfig | 19 | ||||
| -rw-r--r-- | configs/xilinx_versal_virt_defconfig | 1 | ||||
| -rw-r--r-- | configs/xilinx_zynqmp_virt_defconfig | 1 | ||||
| -rw-r--r-- | drivers/clk/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/clk/clk_versal.c | 49 | ||||
| -rw-r--r-- | drivers/firmware/firmware-zynqmp.c | 36 | ||||
| -rw-r--r-- | drivers/i2c/i2c-cdns.c | 11 | ||||
| -rw-r--r-- | drivers/spi/cadence_ospi_versal.c | 7 | ||||
| -rw-r--r-- | drivers/spi/cadence_qspi.c | 23 | ||||
| -rw-r--r-- | drivers/spi/cadence_qspi.h | 2 | ||||
| -rw-r--r-- | include/dt-bindings/power/xlnx-versal-power.h | 54 | ||||
| -rw-r--r-- | include/zynqmp_firmware.h | 8 |
22 files changed, 188 insertions, 106 deletions
diff --git a/arch/arm/dts/versal-mini-ospi.dtsi b/arch/arm/dts/versal-mini-ospi.dtsi index eec2a08e7c7..8429dc585d5 100644 --- a/arch/arm/dts/versal-mini-ospi.dtsi +++ b/arch/arm/dts/versal-mini-ospi.dtsi @@ -29,7 +29,7 @@ }; ospi: spi@f1010000 { - compatible = "cdns,qspi-nor"; + compatible = "xlnx,versal-ospi-1.0", "cdns,qspi-nor"; status = "okay"; reg = <0 0xf1010000 0 0x10000 0 0xc0000000 0 0x20000000>; clock-names = "ref_clk", "pclk"; @@ -38,7 +38,6 @@ num-cs = <1>; cdns,fifo-depth = <256>; cdns,fifo-width = <4>; - cdns,is-dma = <1>; cdns,trigger-address = <0xc0000000>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/dts/versal-net-mini-ospi.dtsi b/arch/arm/dts/versal-net-mini-ospi.dtsi index 1c94b352dc9..78404960f2f 100644 --- a/arch/arm/dts/versal-net-mini-ospi.dtsi +++ b/arch/arm/dts/versal-net-mini-ospi.dtsi @@ -43,7 +43,7 @@ }; ospi: spi@f1010000 { - compatible = "cdns,qspi-nor"; + compatible = "xlnx,versal-ospi-1.0", "cdns,qspi-nor"; status = "okay"; reg = <0 0xf1010000 0 0x10000>, <0 0xc0000000 0 0x20000000>; clock-names = "ref_clk", "pclk"; @@ -52,7 +52,6 @@ num-cs = <1>; cdns,fifo-depth = <256>; cdns,fifo-width = <4>; - cdns,is-dma = <1>; cdns,is-stig-pgm = <1>; cdns,trigger-address = <0xc0000000>; #address-cells = <1>; diff --git a/arch/arm/dts/zynqmp-sc-vn-p-b2197-00-revA.dtso b/arch/arm/dts/zynqmp-sc-vn-p-b2197-00-revA.dtso index c1945ea6f8d..5a4e5f09250 100644 --- a/arch/arm/dts/zynqmp-sc-vn-p-b2197-00-revA.dtso +++ b/arch/arm/dts/zynqmp-sc-vn-p-b2197-00-revA.dtso @@ -13,9 +13,6 @@ /plugin/; &{/} { - #address-cells = <2>; - #size-cells = <2>; - compatible = "xlnx,zynqmp-sc-vn-p-b2197-revA", "xlnx,zynqmp-sc-vn-p-b2197", "xlnx,zynqmp"; diff --git a/arch/arm/mach-versal2/include/mach/hardware.h b/arch/arm/mach-versal2/include/mach/hardware.h index 7ca2bbb7550..81a0df89357 100644 --- a/arch/arm/mach-versal2/include/mach/hardware.h +++ b/arch/arm/mach-versal2/include/mach/hardware.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2016 - 2022, Xilinx, Inc. - * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. + * Copyright (C) 2022 - 2025, Advanced Micro Devices, Inc. */ #ifndef __ASSEMBLY__ @@ -73,6 +73,8 @@ struct crp_regs { #define JTAG_MODE 0x00000000 #define BOOT_MODE_USE_ALT 0x100 #define BOOT_MODE_ALT_SHIFT 12 +#define PMC_MULTI_BOOT_REG 0xF1110004 +#define PMC_MULTI_BOOT_MASK 0x1FFF enum versal2_platform { VERSAL2_SILICON = 0, diff --git a/arch/arm/mach-zynqmp/Kconfig b/arch/arm/mach-zynqmp/Kconfig index 151cfada436..8a4356bc060 100644 --- a/arch/arm/mach-zynqmp/Kconfig +++ b/arch/arm/mach-zynqmp/Kconfig @@ -138,7 +138,7 @@ config BL31_LOAD_ADDR config BL32_LOAD_ADDR hex "Load address of BL32 image (mostly secure OS)" - default 0 + default 0x60000000 help The load address for the BL32 image. This value is used to build the FIT image header that places BL32 in memory where it will run. diff --git a/board/amd/versal2/board.c b/board/amd/versal2/board.c index 7d91d288d2e..1fd05a1157a 100644 --- a/board/amd/versal2/board.c +++ b/board/amd/versal2/board.c @@ -21,6 +21,7 @@ #include <dm/device.h> #include <dm/uclass.h> #include <versalpl.h> +#include <zynqmp_firmware.h> #include "../../xilinx/common/board.h" #include <linux/bitfield.h> @@ -180,6 +181,23 @@ static u8 versal2_get_bootmode(void) return bootmode; } +static u32 versal2_multi_boot(void) +{ + u8 bootmode = versal2_get_bootmode(); + u32 reg = 0; + + /* Mostly workaround for QEMU CI pipeline */ + if (bootmode == JTAG_MODE) + return 0; + + if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE) && current_el() != 3) + reg = zynqmp_pm_get_pmc_multi_boot_reg(); + else + reg = readl(PMC_MULTI_BOOT_REG); + + return reg & PMC_MULTI_BOOT_MASK; +} + static int boot_targets_setup(void) { u8 bootmode; @@ -319,6 +337,7 @@ static int boot_targets_setup(void) int board_late_init(void) { int ret; + u32 multiboot; if (!(gd->flags & GD_FLG_ENV_DEFAULT)) { debug("Saved variables - Skipping\n"); @@ -328,6 +347,9 @@ int board_late_init(void) if (!IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)) return 0; + multiboot = versal2_multi_boot(); + env_set_hex("multiboot", multiboot); + if (IS_ENABLED(CONFIG_DISTRO_DEFAULTS)) { ret = boot_targets_setup(); if (ret) diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 26facb6daea..d022308f943 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -70,6 +70,8 @@ struct efi_capsule_update_info update_info = { #define EEPROM_HDR_ETH_ALEN ETH_ALEN #define EEPROM_HDR_UUID_LEN 16 +#define EEPROM_FRU_READ_RETRY 5 + struct xilinx_board_description { u32 header; char manufacturer[EEPROM_HDR_MANUFACTURER_LEN + 1]; @@ -207,8 +209,14 @@ static int xilinx_read_eeprom_fru(struct udevice *dev, char *name, debug("%s: I2C EEPROM read pass data at %p\n", __func__, fru_content); - ret = dm_i2c_read(dev, 0, (uchar *)fru_content, - eeprom_size); + i = 0; + do { + ret = dm_i2c_read(dev, 0, (uchar *)fru_content, + eeprom_size); + if (!ret) + break; + } while (++i < EEPROM_FRU_READ_RETRY && ret == -ETIMEDOUT); + if (ret) { debug("%s: I2C EEPROM read failed\n", __func__); goto end; @@ -766,6 +774,17 @@ int fwu_platform_hook(struct udevice *dev, struct fwu_data *data) /* Copy image type GUID */ memcpy(&fw_images[0].image_type_id, &img_entry->image_type_guid, 16); + if (IS_ENABLED(CONFIG_EFI_ESRT)) { + efi_status_t ret; + + /* Rebuild the ESRT to reflect any updated FW images. */ + ret = efi_esrt_populate(); + if (ret != EFI_SUCCESS) { + log_warning("ESRT update failed\n"); + return ret; + } + } + return 0; } diff --git a/board/xilinx/mbv/board.c b/board/xilinx/mbv/board.c index ed3fe16af7b..2b0005955ca 100644 --- a/board/xilinx/mbv/board.c +++ b/board/xilinx/mbv/board.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * (C) Copyright 2023, Advanced Micro Devices, Inc. + * (C) Copyright 2023-2025, Advanced Micro Devices, Inc. * * Michal Simek <[email protected]> */ @@ -8,9 +8,15 @@ #include <spl.h> #ifdef CONFIG_SPL -u32 spl_boot_device(void) +void board_boot_order(u32 *spl_boot_list) { - /* RISC-V QEMU only supports RAM as SPL boot device */ - return BOOT_DEVICE_RAM; + u32 i = 0; + + if (CONFIG_IS_ENABLED(SPI_FLASH_SUPPORT)) + spl_boot_list[i++] = BOOT_DEVICE_SPI; + + if (CONFIG_IS_ENABLED(RAM_SUPPORT)) + spl_boot_list[i++] = BOOT_DEVICE_RAM; + } #endif diff --git a/common/memtop.c b/common/memtop.c index bff27d8211e..8ad394193f3 100644 --- a/common/memtop.c +++ b/common/memtop.c @@ -9,7 +9,7 @@ #include <asm/types.h> -#define MEM_RGN_COUNT 16 +#define MEM_RGN_COUNT 64 struct region { phys_addr_t base; diff --git a/configs/amd_versal2_virt_defconfig b/configs/amd_versal2_virt_defconfig index caf4aefe898..0344089030c 100644 --- a/configs/amd_versal2_virt_defconfig +++ b/configs/amd_versal2_virt_defconfig @@ -11,6 +11,7 @@ CONFIG_OF_LIBFDT_OVERLAY=y CONFIG_DM_RESET=y CONFIG_SYS_BOOTM_LEN=0x6400000 CONFIG_SYS_LOAD_ADDR=0x8000000 +CONFIG_XILINX_OF_BOARD_DTB_ADDR=0x1000000 CONFIG_CMD_FRU=y CONFIG_SYS_MEMTEST_START=0x00000000 CONFIG_SYS_MEMTEST_END=0x00001000 @@ -75,6 +76,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SIMPLE_PM_BUS=y CONFIG_CLK_CCF=y CONFIG_CLK_SCMI=y +CONFIG_CLK_VERSAL=y CONFIG_DFU_RAM=y CONFIG_ARM_FFA_TRANSPORT=y CONFIG_FPGA_XILINX=y @@ -82,6 +84,7 @@ CONFIG_FPGA_VERSALPL=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_CADENCE=y CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA9541=y CONFIG_I2C_MUX_PCA954x=y CONFIG_DM_MAILBOX=y CONFIG_ZYNQMP_IPI=y @@ -136,6 +139,7 @@ CONFIG_ZYNQ_SPI=y CONFIG_ZYNQMP_GQSPI=y CONFIG_SPI_STACKED_PARALLEL=y CONFIG_SYSRESET=y +CONFIG_SYSRESET_CMD_POWEROFF=y CONFIG_SYSRESET_PSCI=y CONFIG_TEE=y CONFIG_OPTEE=y @@ -147,6 +151,7 @@ CONFIG_USB_XHCI_DWC3=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GENERIC=y CONFIG_USB_ULPI=y +CONFIG_USB_ONBOARD_HUB=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_MANUFACTURER="Xilinx" CONFIG_USB_GADGET_VENDOR_NUM=0x03FD diff --git a/configs/xilinx_mbv32_defconfig b/configs/xilinx_mbv32_defconfig index 88d9e5ce6b2..42dc5fb282a 100644 --- a/configs/xilinx_mbv32_defconfig +++ b/configs/xilinx_mbv32_defconfig @@ -6,18 +6,17 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x81200000 CONFIG_ENV_SIZE=0x20000 CONFIG_DEFAULT_DEVICE_TREE="xilinx-mbv32" CONFIG_SPL_STACK=0x80200000 -CONFIG_SPL_BSS_START_ADDR=0x84000000 -CONFIG_SPL_BSS_MAX_SIZE=0x80000 +CONFIG_SPL_TEXT_BASE=0x0 +CONFIG_SPL_BSS_START_ADDR=0xf000 +CONFIG_SPL_BSS_MAX_SIZE=0x1000 CONFIG_SYS_BOOTM_LEN=0x800000 CONFIG_SYS_LOAD_ADDR=0x80200000 -CONFIG_SPL_SIZE_LIMIT=0x40000 +CONFIG_SPL_SIZE_LIMIT=0x10000 CONFIG_SPL=y -CONFIG_DEBUG_UART_BASE=0x40600000 -CONFIG_DEBUG_UART_CLOCK=100000000 CONFIG_SYS_CLK_FREQ=100000000 CONFIG_BOOT_SCRIPT_OFFSET=0x0 -CONFIG_DEBUG_UART=y CONFIG_TARGET_XILINX_MBV=y +# CONFIG_RISCV_ISA_F is not set # CONFIG_SPL_SMP is not set CONFIG_REMAKE_ELF=y CONFIG_FIT=y @@ -27,10 +26,13 @@ CONFIG_DISPLAY_CPUINFO=y CONFIG_DISPLAY_BOARDINFO=y # CONFIG_BOARD_INIT is not set # CONFIG_BOARD_LATE_INIT is not set -CONFIG_SPL_MAX_SIZE=0x40000 +CONFIG_SPL_MAX_SIZE=0xf000 # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_HAVE_INIT_STACK=y CONFIG_SPL_SYS_MALLOC=y +CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y +CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x80000000 +CONFIG_SPL_SYS_MALLOC_SIZE=0x200000 # CONFIG_CMD_MII is not set CONFIG_CMD_SNTP=y CONFIG_CMD_TIMER=y @@ -39,11 +41,8 @@ CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_DM_MTD=y CONFIG_DM_RTC=y CONFIG_RTC_EMULATION=y -CONFIG_DEBUG_UART_ANNOUNCE=y -CONFIG_DEBUG_UART_SKIP_INIT=y CONFIG_XILINX_UARTLITE=y CONFIG_XILINX_TIMER=y # CONFIG_BINMAN_FDT is not set CONFIG_BINMAN_DTB="./arch/riscv/dts/xilinx-binman.dtb" CONFIG_PANIC_HANG=y -CONFIG_SPL_GZIP=y diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index bd6bfb7deac..652121e27a0 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -89,6 +89,7 @@ CONFIG_FPGA_VERSALPL=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_CADENCE=y CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA9541=y CONFIG_I2C_MUX_PCA954x=y CONFIG_DM_MAILBOX=y CONFIG_ZYNQMP_IPI=y diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 525744b0f61..fc610fd4af5 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -140,6 +140,7 @@ CONFIG_SLG7XL45106_I2C_GPO=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_CADENCE=y CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA9541=y CONFIG_I2C_MUX_PCA954x=y CONFIG_LED=y CONFIG_LED_GPIO=y diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index b884a02bdeb..85cc472b4cb 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -224,7 +224,7 @@ config CLK_VERSACLOCK config CLK_VERSAL bool "Enable clock driver support for Versal" - depends on (ARCH_VERSAL || ARCH_VERSAL_NET) + depends on (ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2) depends on ZYNQMP_FIRMWARE help This clock driver adds support for clock realted settings for diff --git a/drivers/clk/clk_versal.c b/drivers/clk/clk_versal.c index c62a747036d..78a2410ca21 100644 --- a/drivers/clk/clk_versal.c +++ b/drivers/clk/clk_versal.c @@ -106,8 +106,8 @@ struct versal_clk_priv { struct versal_clock *clk; }; -static ulong pl_alt_ref_clk __section(".data"); -static ulong ref_clk __section(".data"); +static ulong __data pl_alt_ref_clk; +static ulong __data ref_clk; struct versal_pm_query_data { u32 qid; @@ -116,8 +116,8 @@ struct versal_pm_query_data { u32 arg3; }; -static struct versal_clock *clock __section(".data"); -static unsigned int clock_max_idx __section(".data"); +static struct versal_clock __data *clock; +static unsigned int __data clock_max_idx; #define PM_QUERY_DATA 35 @@ -136,6 +136,25 @@ static int versal_pm_query_legacy(struct versal_pm_query_data qdata, return qdata.qid == PM_QID_CLOCK_GET_NAME ? 0 : ret; } +static int versal_pm_query_enhanced(struct versal_pm_query_data qdata, + u32 *ret_payload) +{ + int ret; + + ret = smc_call_handler(PM_QUERY_DATA, qdata.qid, qdata.arg1, qdata.arg2, + qdata.arg3, 0, 0, ret_payload); + + if (qdata.qid == PM_QID_CLOCK_GET_NAME) { + ret_payload[0] = ret_payload[1]; + ret_payload[1] = ret_payload[2]; + ret_payload[2] = ret_payload[3]; + ret_payload[3] = ret_payload[4]; + ret_payload[4] = 0; + } + + return ret; +} + static inline int versal_is_valid_clock(u32 clk_id) { if (clk_id >= clock_max_idx) @@ -712,11 +731,12 @@ static int versal_clk_probe(struct udevice *dev) static ulong versal_clk_get_rate(struct clk *clk) { struct versal_clk_priv *priv = dev_get_priv(clk->dev); - u32 id = clk->id; + u32 id = clk_get_id(clk); u32 clk_id; u64 clk_rate = 0; - debug("%s\n", __func__); + if (id >= clock_max_idx) + return -ENODEV; clk_id = priv->clk[id].clk_id; @@ -728,13 +748,14 @@ static ulong versal_clk_get_rate(struct clk *clk) static ulong versal_clk_set_rate(struct clk *clk, ulong rate) { struct versal_clk_priv *priv = dev_get_priv(clk->dev); - u32 id = clk->id; + u32 id = clk_get_id(clk); u32 clk_id; u64 clk_rate = 0; u32 div; int ret; - debug("%s\n", __func__); + if (id >= clock_max_idx) + return -ENODEV; clk_id = priv->clk[id].clk_id; @@ -758,7 +779,7 @@ static ulong versal_clk_set_rate(struct clk *clk, ulong rate) } while (((clk_id >> NODE_SUBCLASS_SHIFT) & NODE_CLASS_MASK) != NODE_SUBCLASS_CLOCK_REF); - printf("Clock didn't has Divisors:0x%x\n", priv->clk[id].clk_id); + printf("Clock has no divider: 0x%x\n", clk_id); return clk_rate; } @@ -766,14 +787,17 @@ static ulong versal_clk_set_rate(struct clk *clk, ulong rate) static int versal_clk_enable(struct clk *clk) { struct versal_clk_priv *priv = dev_get_priv(clk->dev); + u32 id = clk_get_id(clk); u32 clk_id; - clk_id = priv->clk[clk->id].clk_id; + if (id >= clock_max_idx) + return -ENODEV; + + clk_id = priv->clk[id].clk_id; - if (versal_clock_gate(clk_id)) { + if (versal_clock_gate(clk_id)) return xilinx_pm_request(PM_CLOCK_ENABLE, clk_id, 0, 0, 0, 0, 0, NULL); - } return 0; } @@ -789,6 +813,7 @@ static struct clk_ops versal_clk_ops = { static const struct udevice_id versal_clk_ids[] = { { .compatible = "xlnx,versal-clk", .data = (ulong)versal_pm_query_legacy }, + { .compatible = "xlnx,versal2-clk", .data = (ulong)versal_pm_query_enhanced }, { } }; diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 3742467caee..f8a9945c1da 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -16,6 +16,7 @@ #include <zynqmp_firmware.h> #include <asm/cache.h> #include <asm/ptrace.h> +#include <linux/bitfield.h> #if defined(CONFIG_ZYNQMP_IPI) #include <mailbox.h> @@ -247,6 +248,7 @@ u32 zynqmp_pm_get_bootmode_reg(void) return ret_payload[1]; } +#if defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL2) u32 zynqmp_pm_get_pmc_multi_boot_reg(void) { int ret; @@ -270,6 +272,7 @@ u32 zynqmp_pm_get_pmc_multi_boot_reg(void) return ret_payload[1]; } +#endif int zynqmp_pm_feature(const u32 api_id) { @@ -451,6 +454,38 @@ static int smc_call_legacy(u32 api_id, u32 arg0, u32 arg1, u32 arg2, return (ret_payload) ? ret_payload[0] : 0; } +static int smc_call_enhanced(u32 api_id, u32 arg0, u32 arg1, u32 arg2, + u32 arg3, u32 arg4, u32 arg5, u32 *ret_payload) +{ + struct pt_regs regs; + u32 module_id = FIELD_GET(PLM_MODULE_ID_MASK, api_id); + + if (module_id == 0) + module_id = PM_MODULE_ID; + + regs.regs[0] = PM_SIP_SVC | PASS_THROUGH_FW_CMD_ID; + regs.regs[1] = ((u64)arg0 << 32U) | + FIELD_PREP(PLM_MODULE_ID_MASK, module_id) | + (api_id & API_ID_MASK); + regs.regs[2] = arg1 | ((u64)arg2 << 32); + regs.regs[3] = arg3 | ((u64)arg4 << 32); + regs.regs[4] = arg5; + + smc_call(®s); + + if (ret_payload) { + ret_payload[0] = regs.regs[0]; + ret_payload[1] = upper_32_bits(regs.regs[0]); + ret_payload[2] = (u32)regs.regs[1]; + ret_payload[3] = upper_32_bits(regs.regs[1]); + ret_payload[4] = (u32)regs.regs[2]; + ret_payload[5] = upper_32_bits((u32)regs.regs[2]); + ret_payload[6] = (u32)regs.regs[3]; + } + + return regs.regs[0]; +} + int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4, u32 arg5, u32 *ret_payload) { @@ -494,6 +529,7 @@ 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}, { .compatible = "xlnx,versal-net-firmware", .data = (ulong)smc_call_legacy }, + { .compatible = "xlnx,versal2-firmware", .data = (ulong)smc_call_enhanced}, { } }; diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c index 3f7cf8533ec..4e9d4e44899 100644 --- a/drivers/i2c/i2c-cdns.c +++ b/drivers/i2c/i2c-cdns.c @@ -85,6 +85,8 @@ struct cdns_i2c_regs { #define CDNS_I2C_ARB_LOST_MAX_RETRIES 10 +#define CDNS_I2C_RXDV_TIMEOUT_MS 1000 + #ifdef DEBUG static void cdns_i2c_debug_status(struct cdns_i2c_regs *cdns_i2c) { @@ -349,6 +351,11 @@ static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, hold_quirk = (i2c_bus->quirks & CDNS_I2C_BROKEN_HOLD_BIT) && updatetx; while (recv_count && !is_arbitration_lost(regs)) { + int err = wait_for_bit_le32(®s->status, CDNS_I2C_STATUS_RXDV, + true, CDNS_I2C_RXDV_TIMEOUT_MS, false); + if (err) + return err; + while (readl(®s->status) & CDNS_I2C_STATUS_RXDV) { if (recv_count < i2c_bus->fifo_depth && !i2c_bus->hold_flag) { @@ -452,6 +459,10 @@ static int cdns_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, ret = cdns_i2c_write_data(i2c_bus, msg->addr, msg->buf, msg->len); } + + if (ret == -ETIMEDOUT) + return ret; + if (ret == -EAGAIN) { msg = message; nmsgs = num_msgs; diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index 0efbbf56a5e..a00642d09d3 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -15,7 +15,6 @@ #include <zynqmp_firmware.h> #include <asm/arch/hardware.h> #include "cadence_qspi.h" -#include <dt-bindings/power/xlnx-versal-power.h> int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) @@ -178,15 +177,15 @@ int cadence_qspi_flash_reset(struct udevice *dev) /* Disable Tri-state */ writel((readl(BANK0_TRI) & ~BIT(FLASH_RESET_GPIO)), BANK0_TRI); - udelay(1); + udelay(5); /* Set value 0 to pin */ writel((readl(BANK0_OUTPUT) & ~BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT); - udelay(10); + udelay(150); /* Set value 1 to pin */ writel((readl(BANK0_OUTPUT) | BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT); - udelay(10); + udelay(1200); return 0; } diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 9b45cab9c04..d1404e13810 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -20,7 +20,6 @@ #include <linux/time.h> #include <zynqmp_firmware.h> #include "cadence_qspi.h" -#include <dt-bindings/power/xlnx-versal-power.h> #define CQSPI_STIG_READ 0 #define CQSPI_STIG_WRITE 1 @@ -29,6 +28,7 @@ /* Quirks */ #define CQSPI_DISABLE_STIG_MODE BIT(0) +#define CQSPI_DMA_MODE BIT(1) __weak int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) @@ -210,7 +210,6 @@ static int cadence_spi_probe(struct udevice *bus) priv->regbase = plat->regbase; priv->ahbbase = plat->ahbbase; - priv->is_dma = plat->is_dma; priv->is_decoded_cs = plat->is_decoded_cs; priv->fifo_depth = plat->fifo_depth; priv->fifo_width = plat->fifo_width; @@ -227,6 +226,11 @@ static int cadence_spi_probe(struct udevice *bus) priv->tslch_ns = plat->tslch_ns; priv->quirks = plat->quirks; + if (priv->quirks & CQSPI_DMA_MODE) { + priv->is_dma = true; + debug("Cadence QSPI: DMA mode enabled\n"); + } + if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE)) xilinx_pm_request(PM_REQUEST_NODE, PM_DEV_OSPI, ZYNQMP_PM_CAPABILITY_ACCESS, ZYNQMP_PM_MAX_QOS, @@ -265,8 +269,6 @@ static int cadence_spi_probe(struct udevice *bus) /* Reset ospi flash device */ return cadence_qspi_flash_reset(bus); - - return 0; } static int cadence_spi_remove(struct udevice *dev) @@ -412,8 +414,6 @@ static int cadence_spi_of_to_plat(struct udevice *bus) if (plat->ahbsize >= SZ_8M) priv->use_dac_mode = true; - plat->is_dma = dev_read_bool(bus, "cdns,is-dma"); - /* All other parameters are embedded in the child node */ subnode = cadence_qspi_get_subnode(bus); if (!ofnode_valid(subnode)) { @@ -473,6 +473,10 @@ static const struct cqspi_driver_platdata cdns_qspi = { .quirks = CQSPI_DISABLE_STIG_MODE, }; +static const struct cqspi_driver_platdata cdns_xilinx_qspi = { + .quirks = CQSPI_DMA_MODE, +}; + static const struct udevice_id cadence_spi_ids[] = { { .compatible = "cdns,qspi-nor", @@ -482,7 +486,12 @@ static const struct udevice_id cadence_spi_ids[] = { .compatible = "ti,am654-ospi" }, { - .compatible = "amd,versal2-ospi" + .compatible = "amd,versal2-ospi", + .data = (ulong)&cdns_xilinx_qspi, + }, + { + .compatible = "xlnx,versal-ospi-1.0", + .data = (ulong)&cdns_xilinx_qspi, }, { } }; diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index 879e7f8dbfb..1e9081c2d17 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -223,8 +223,6 @@ struct cadence_spi_plat { u32 tchsh_ns; u32 tslch_ns; u32 quirks; - - bool is_dma; }; struct cadence_spi_priv { diff --git a/include/dt-bindings/power/xlnx-versal-power.h b/include/dt-bindings/power/xlnx-versal-power.h deleted file mode 100644 index 51d1def6773..00000000000 --- a/include/dt-bindings/power/xlnx-versal-power.h +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2019 - 2021 Xilinx, Inc. - */ - -#ifndef _DT_BINDINGS_VERSAL_POWER_H -#define _DT_BINDINGS_VERSAL_POWER_H - -#define PM_DEV_RPU0_0 (0x18110005U) -#define PM_DEV_RPU0_1 (0x18110006U) -#define PM_DEV_OCM_0 (0x18314007U) -#define PM_DEV_OCM_1 (0x18314008U) -#define PM_DEV_OCM_2 (0x18314009U) -#define PM_DEV_OCM_3 (0x1831400aU) -#define PM_DEV_TCM_0_A (0x1831800bU) -#define PM_DEV_TCM_0_B (0x1831800cU) -#define PM_DEV_TCM_1_A (0x1831800dU) -#define PM_DEV_TCM_1_B (0x1831800eU) -#define PM_DEV_USB_0 (0x18224018U) -#define PM_DEV_GEM_0 (0x18224019U) -#define PM_DEV_GEM_1 (0x1822401aU) -#define PM_DEV_SPI_0 (0x1822401bU) -#define PM_DEV_SPI_1 (0x1822401cU) -#define PM_DEV_I2C_0 (0x1822401dU) -#define PM_DEV_I2C_1 (0x1822401eU) -#define PM_DEV_CAN_FD_0 (0x1822401fU) -#define PM_DEV_CAN_FD_1 (0x18224020U) -#define PM_DEV_UART_0 (0x18224021U) -#define PM_DEV_UART_1 (0x18224022U) -#define PM_DEV_GPIO (0x18224023U) -#define PM_DEV_TTC_0 (0x18224024U) -#define PM_DEV_TTC_1 (0x18224025U) -#define PM_DEV_TTC_2 (0x18224026U) -#define PM_DEV_TTC_3 (0x18224027U) -#define PM_DEV_SWDT_FPD (0x18224029U) -#define PM_DEV_OSPI (0x1822402aU) -#define PM_DEV_QSPI (0x1822402bU) -#define PM_DEV_GPIO_PMC (0x1822402cU) -#define PM_DEV_I2C_PMC (0x1822402dU) -#define PM_DEV_SDIO_0 (0x1822402eU) -#define PM_DEV_SDIO_1 (0x1822402fU) -#define PM_DEV_RTC (0x18224034U) -#define PM_DEV_ADMA_0 (0x18224035U) -#define PM_DEV_ADMA_1 (0x18224036U) -#define PM_DEV_ADMA_2 (0x18224037U) -#define PM_DEV_ADMA_3 (0x18224038U) -#define PM_DEV_ADMA_4 (0x18224039U) -#define PM_DEV_ADMA_5 (0x1822403aU) -#define PM_DEV_ADMA_6 (0x1822403bU) -#define PM_DEV_ADMA_7 (0x1822403cU) -#define PM_DEV_AMS_ROOT (0x18224055U) -#define PM_DEV_AI (0x18224072U) - -#endif diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h index 7f93241b193..05df49f292a 100644 --- a/include/zynqmp_firmware.h +++ b/include/zynqmp_firmware.h @@ -521,4 +521,12 @@ typedef int (*smc_call_handler_t)(u32 api_id, u32 arg0, u32 arg1, u32 arg2, extern smc_call_handler_t __data smc_call_handler; +#define PM_MODULE_ID 2 + +#define PASS_THROUGH_FW_CMD_ID GENMASK(11, 0) +#define PLM_MODULE_ID_MASK GENMASK(15, 8) +#define API_ID_MASK GENMASK(7, 0) + +#define PM_DEV_OSPI (0x1822402aU) + #endif /* _ZYNQMP_FIRMWARE_H_ */ |
