summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2025-12-19 10:30:53 -0600
committerTom Rini <[email protected]>2025-12-19 10:30:53 -0600
commit2aeaa3c4f53b11b97e2797eb3a0a7b603f60dc72 (patch)
treef815ca39666d1bb8b5be752afcf1f400695ed93b
parentadbbf5982d26801224b10cd847dc468f8b5e4095 (diff)
parent0b880fc95dbaed88dd55060730857b8f52765c57 (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.dtsi3
-rw-r--r--arch/arm/dts/versal-net-mini-ospi.dtsi3
-rw-r--r--arch/arm/dts/zynqmp-sc-vn-p-b2197-00-revA.dtso3
-rw-r--r--arch/arm/mach-versal2/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-zynqmp/Kconfig2
-rw-r--r--board/amd/versal2/board.c22
-rw-r--r--board/xilinx/common/board.c23
-rw-r--r--board/xilinx/mbv/board.c14
-rw-r--r--common/memtop.c2
-rw-r--r--configs/amd_versal2_virt_defconfig5
-rw-r--r--configs/xilinx_mbv32_defconfig19
-rw-r--r--configs/xilinx_versal_virt_defconfig1
-rw-r--r--configs/xilinx_zynqmp_virt_defconfig1
-rw-r--r--drivers/clk/Kconfig2
-rw-r--r--drivers/clk/clk_versal.c49
-rw-r--r--drivers/firmware/firmware-zynqmp.c36
-rw-r--r--drivers/i2c/i2c-cdns.c11
-rw-r--r--drivers/spi/cadence_ospi_versal.c7
-rw-r--r--drivers/spi/cadence_qspi.c23
-rw-r--r--drivers/spi/cadence_qspi.h2
-rw-r--r--include/dt-bindings/power/xlnx-versal-power.h54
-rw-r--r--include/zynqmp_firmware.h8
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(&regs);
+
+ 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(&regs->status, CDNS_I2C_STATUS_RXDV,
+ true, CDNS_I2C_RXDV_TIMEOUT_MS, false);
+ if (err)
+ return err;
+
while (readl(&regs->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_ */