U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] ufs: amd-versal2: Cleanup firmware interface
@ 2026-07-30  6:49 Michal Simek
  2026-07-30  6:49 ` [PATCH 1/3] ufs: amd-versal2: Perform controller reset in the init callback Michal Simek
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Michal Simek @ 2026-07-30  6:49 UTC (permalink / raw)
  To: u-boot, git
  Cc: Alexey Charkov, Anshul Dalal, Bhupesh Sharma, Ilias Apalodimas,
	Johan Jonker, Neha Malcom Francis, Neil Armstrong,
	Padmarao Begari, Pranav Sanwal, Pranav Tilak, Sean Anderson,
	Tom Rini

Hi,

the first patch mainly alignment with Linux kernel version. Issue was
related to IRQ handling which is not valid reason for U-Boot but still
correcting sequence make sense.

The second patch is moving firmware handling out of UFS driver. UFS driver
cares about delivering functionality. And doesn't really matter how exactly
it is done. If it is done via firmware interface, via IO polling or in a
different way. That's why move loops out of UFS driver to be able to use
different interfaces for it.

The third patch is just Kconfig update.

The series is based on
https://patchwork.ozlabs.org/project/uboot/patch/6419fe4f6f1f451aee624c7762b7aa690d50e498.1784870711.git.michal.simek@amd.com/

Thanks,
Michal


Michal Simek (3):
  ufs: amd-versal2: Perform controller reset in the init callback
  xilinx: versal2: Clean UFS firmware interface
  ufs: amd-versal2: Remove ZYNQMP_FIRMWARE dependency

 arch/arm/mach-versal2/cpu.c                   |  34 +++--
 arch/arm/mach-versal2/include/mach/hardware.h |   5 +
 .../arm/mach-versal2/include/mach/sys_proto.h |   8 +-
 drivers/firmware/firmware-zynqmp.c            |  72 ++++++----
 drivers/ufs/Kconfig                           |   2 +-
 drivers/ufs/ufs-amd-versal2.c                 | 129 ++++++------------
 6 files changed, 119 insertions(+), 131 deletions(-)

---
base-commit: 7e24149aacb83335fa997e2457144f23ba5e1bda

-- 
2.43.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] ufs: amd-versal2: Perform controller reset in the init callback
  2026-07-30  6:49 [PATCH 0/3] ufs: amd-versal2: Cleanup firmware interface Michal Simek
@ 2026-07-30  6:49 ` Michal Simek
  2026-07-30  6:49 ` [PATCH 2/3] xilinx: versal2: Clean UFS firmware interface Michal Simek
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Michal Simek @ 2026-07-30  6:49 UTC (permalink / raw)
  To: u-boot, git
  Cc: Bhupesh Sharma, Neha Malcom Francis, Neil Armstrong, Pranav Tilak,
	Tom Rini

Move the controller/PHY reset and SRAM-bypass sequence from
hce_enable_notify(PRE_CHANGE) into ufs_versal2_init().
The reset sequence releases the host controller from reset, and the UFS
core reads the capability and version registers right after .init() and
before ufshcd_hba_enable() (the only caller of hce_enable_notify()).
Doing the reset in .init() ensures those registers are read after the
controller is out of reset, and keeps the driver aligned with Linux.
ufs_versal2_phy_init() stays in POST_CHANGE.

Signed-off-by: Michal Simek <michal.simek@amd.com>
---

 drivers/ufs/ufs-amd-versal2.c | 86 ++++++++++++++++-------------------
 1 file changed, 38 insertions(+), 48 deletions(-)

diff --git a/drivers/ufs/ufs-amd-versal2.c b/drivers/ufs/ufs-amd-versal2.c
index 25af9dd63cca..986147848bda 100644
--- a/drivers/ufs/ufs-amd-versal2.c
+++ b/drivers/ufs/ufs-amd-versal2.c
@@ -301,7 +301,7 @@ static int ufs_versal2_init(struct ufs_hba *hba)
 	struct ufs_versal2_priv *priv = dev_get_priv(hba->dev);
 	struct clk clk;
 	unsigned long core_clk_rate = 0;
-	u32 cal;
+	u32 cal, sram_csr;
 	int ret = 0;
 
 	priv->phy_mode = UFSHCD_DWC_PHY_MODE_ROM;
@@ -331,6 +331,41 @@ static int ufs_versal2_init(struct ufs_hba *hba)
 		return PTR_ERR(priv->rstphy);
 	}
 
+	/* Assert RST_UFS Reset for UFS block in PMX_IOU */
+	ret = reset_assert(priv->rstc);
+	if (ret) {
+		dev_err(hba->dev, "host reset assert failed, err = %d\n", ret);
+		return ret;
+	}
+
+	/* Assert PHY reset */
+	ret = reset_assert(priv->rstphy);
+	if (ret) {
+		dev_err(hba->dev, "phy reset assert failed, err = %d\n", ret);
+		return ret;
+	}
+
+	ret = zynqmp_pm_ufs_sram_csr_read(&sram_csr);
+	if (ret)
+		return ret;
+
+	if (!priv->phy_mode) {
+		sram_csr &= ~SRAM_CSR_EXT_LD_DONE_MASK;
+		sram_csr |= SRAM_CSR_BYPASS_MASK;
+	} else {
+		dev_err(hba->dev, "Invalid phy-mode %d.\n", priv->phy_mode);
+		return -EINVAL;
+	}
+
+	ret = zynqmp_pm_ufs_sram_csr_write(&sram_csr);
+	if (ret)
+		return ret;
+
+	/* De Assert RST_UFS Reset for UFS block in PMX_IOU */
+	ret = reset_deassert(priv->rstc);
+	if (ret)
+		dev_err(hba->dev, "host reset deassert failed, err = %d\n", ret);
+
 	ret = zynqmp_pm_ufs_cal_reg(&cal);
 	if (ret)
 		return ret;
@@ -346,57 +381,12 @@ static int ufs_versal2_init(struct ufs_hba *hba)
 static int ufs_versal2_hce_enable_notify(struct ufs_hba *hba,
 					 enum ufs_notify_change_status status)
 {
-	struct ufs_versal2_priv *priv = dev_get_priv(hba->dev);
-	u32 sram_csr;
-	int ret;
-
-	switch (status) {
-	case PRE_CHANGE:
-		/* Assert RST_UFS Reset for UFS block in PMX_IOU */
-		ret = reset_assert(priv->rstc);
-		if (ret) {
-			dev_err(hba->dev, "ufshc reset assert failed, err = %d\n", ret);
-			return ret;
-		}
-
-		/* Assert PHY reset */
-		ret = reset_assert(priv->rstphy);
-		if (ret) {
-			dev_err(hba->dev, "ufsphy reset assert failed, err = %d\n", ret);
-			return ret;
-		}
-
-		ret = zynqmp_pm_ufs_sram_csr_read(&sram_csr);
-		if (ret)
-			return ret;
-
-		if (!priv->phy_mode) {
-			sram_csr &= ~SRAM_CSR_EXT_LD_DONE_MASK;
-			sram_csr |= SRAM_CSR_BYPASS_MASK;
-		} else {
-			dev_err(hba->dev, "Invalid phy-mode %d.\n", priv->phy_mode);
-			return -EINVAL;
-		}
-
-		ret = zynqmp_pm_ufs_sram_csr_write(&sram_csr);
-		if (ret)
-			return ret;
-
-		/* De Assert RST_UFS Reset for UFS block in PMX_IOU */
-		ret = reset_deassert(priv->rstc);
-		if (ret)
-			dev_err(hba->dev, "ufshc reset deassert failed, err = %d\n", ret);
+	int ret = 0;
 
-		break;
-	case POST_CHANGE:
+	if (status == POST_CHANGE) {
 		ret = ufs_versal2_phy_init(hba);
 		if (ret)
 			dev_err(hba->dev, "Phy init failed (%d)\n", ret);
-
-		break;
-	default:
-		ret = -EINVAL;
-		break;
 	}
 
 	return ret;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] xilinx: versal2: Clean UFS firmware interface
  2026-07-30  6:49 [PATCH 0/3] ufs: amd-versal2: Cleanup firmware interface Michal Simek
  2026-07-30  6:49 ` [PATCH 1/3] ufs: amd-versal2: Perform controller reset in the init callback Michal Simek
@ 2026-07-30  6:49 ` Michal Simek
  2026-07-30  6:49 ` [PATCH 3/3] ufs: amd-versal2: Remove ZYNQMP_FIRMWARE dependency Michal Simek
  2026-08-11 12:53 ` [PATCH 0/3] ufs: amd-versal2: Cleanup firmware interface Michal Simek
  3 siblings, 0 replies; 5+ messages in thread
From: Michal Simek @ 2026-07-30  6:49 UTC (permalink / raw)
  To: u-boot, git
  Cc: Bhupesh Sharma, Ilias Apalodimas, Neha Malcom Francis,
	Neil Armstrong, Padmarao Begari, Pranav Sanwal, Pranav Tilak,
	Sean Anderson, Tom Rini

The M-PHY and SRAM readiness poll loops move out of the UFS controller
driver and into the firmware backend, exposed as blocking waits with
a caller-owned timeout budget. This keeps the UFS driver backend-agnostic
and lets an other backends offload the wait to the platform in a single
call instead of round-tripping every poll.

set_sram_bypass() now performs the SRAM_CSR read-modify-write in the
firmware layer.

Hook up functions are also update to reflect their usage.

Signed-off-by: Michal Simek <michal.simek@amd.com>
---

 arch/arm/mach-versal2/cpu.c                   | 34 ++++++---
 arch/arm/mach-versal2/include/mach/hardware.h |  5 ++
 .../arm/mach-versal2/include/mach/sys_proto.h |  8 +-
 drivers/firmware/firmware-zynqmp.c            | 72 +++++++++++-------
 drivers/ufs/ufs-amd-versal2.c                 | 73 +++++--------------
 5 files changed, 95 insertions(+), 97 deletions(-)

diff --git a/arch/arm/mach-versal2/cpu.c b/arch/arm/mach-versal2/cpu.c
index 01efa7b79282..d72f66f4fbac 100644
--- a/arch/arm/mach-versal2/cpu.c
+++ b/arch/arm/mach-versal2/cpu.c
@@ -11,6 +11,7 @@
 #include <malloc.h>
 #include <time.h>
 #include <vsprintf.h>
+#include <wait_bit.h>
 #include <asm/armv8/mmu.h>
 #include <asm/cache.h>
 #include <asm/global_data.h>
@@ -160,25 +161,40 @@ u8 __weak versal2_get_bootmode(void)
 	return bootmode;
 }
 
-int __weak zynqmp_pm_ufs_get_txrx_cfgrdy(u32 *value)
+/*
+ * Wait for the M-PHY TX/RX config-ready status to settle (all bits cleared) or
+ * @timeout_us to elapse. The direct-MMIO fallback owns the poll loop, mirroring
+ * the EEMI backend; the timeout budget is owned by the caller.
+ */
+int __weak zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us)
 {
-	*value = readl(PMXC_SLCR_BASE_ADDRESS + PMXC_TX_RX_CFG_RDY);
-	return 0;
+	return wait_for_bit_le32((void *)(uintptr_t)(PMXC_SLCR_BASE_ADDRESS +
+						     PMXC_TX_RX_CFG_RDY),
+				 TX_RX_CFG_RDY_MASK, false, timeout_us / 1000,
+				 false);
 }
 
-int __weak zynqmp_pm_ufs_sram_csr_read(u32 *value)
+int __weak zynqmp_pm_wait_sram_init_done(u32 timeout_us)
 {
-	*value = readl(PMXC_SLCR_BASE_ADDRESS + PMXC_SRAM_CSR);
-	return 0;
+	return wait_for_bit_le32((void *)(uintptr_t)(PMXC_SLCR_BASE_ADDRESS +
+						     PMXC_SRAM_CSR),
+				 SRAM_CSR_INIT_DONE_MASK, true, timeout_us / 1000,
+				 false);
 }
 
-int __weak zynqmp_pm_ufs_sram_csr_write(u32 *value)
+int __weak zynqmp_pm_set_sram_bypass(void)
 {
-	writel(*value, PMXC_SLCR_BASE_ADDRESS + PMXC_SRAM_CSR);
+	u32 sram_csr;
+
+	sram_csr = readl(PMXC_SLCR_BASE_ADDRESS + PMXC_SRAM_CSR);
+	sram_csr &= ~SRAM_CSR_EXT_LD_DONE_MASK;
+	sram_csr |= SRAM_CSR_BYPASS_MASK;
+	writel(sram_csr, PMXC_SLCR_BASE_ADDRESS + PMXC_SRAM_CSR);
+
 	return 0;
 }
 
-int __weak zynqmp_pm_ufs_cal_reg(u32 *value)
+int __weak zynqmp_pm_get_ufs_calibration_values(u32 *value)
 {
 	*value = readl(PMXC_EFUSE_CACHE_BASE_ADDRESS + PMXC_UFS_CAL_1_OFFSET);
 	return 0;
diff --git a/arch/arm/mach-versal2/include/mach/hardware.h b/arch/arm/mach-versal2/include/mach/hardware.h
index 7977529fd6c1..4ff732d660fd 100644
--- a/arch/arm/mach-versal2/include/mach/hardware.h
+++ b/arch/arm/mach-versal2/include/mach/hardware.h
@@ -65,6 +65,11 @@
 #define PMXC_SRAM_CSR			0x4C
 #define PMXC_TX_RX_CFG_RDY		0x54
 
+#define SRAM_CSR_INIT_DONE_MASK		BIT(0)
+#define SRAM_CSR_EXT_LD_DONE_MASK	BIT(1)
+#define SRAM_CSR_BYPASS_MASK		BIT(2)
+#define TX_RX_CFG_RDY_MASK		GENMASK(3, 0)
+
 #define PMC_GLOBAL_PGGS3_REG	0xF111005C
 #define PMC_GLOBAL_PGGS4_REG	0xF1110060
 
diff --git a/arch/arm/mach-versal2/include/mach/sys_proto.h b/arch/arm/mach-versal2/include/mach/sys_proto.h
index c1dfd184d865..d678adf9c267 100644
--- a/arch/arm/mach-versal2/include/mach/sys_proto.h
+++ b/arch/arm/mach-versal2/include/mach/sys_proto.h
@@ -22,9 +22,9 @@ u8 versal2_get_bootmode(void);
 /* EL3 clock/timer register setup, called from board_early_init_r() */
 void versal2_timer_setup(void);
 
-int zynqmp_pm_ufs_get_txrx_cfgrdy(u32 *value);
-int zynqmp_pm_ufs_sram_csr_read(u32 *value);
-int zynqmp_pm_ufs_sram_csr_write(u32 *value);
-int zynqmp_pm_ufs_cal_reg(u32 *value);
+int zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us);
+int zynqmp_pm_wait_sram_init_done(u32 timeout_us);
+int zynqmp_pm_set_sram_bypass(void);
+int zynqmp_pm_get_ufs_calibration_values(u32 *value);
 
 #endif /* _ASM_ARCH_SYS_PROTO_H */
diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index 2bdb1c4d9f89..fae66ccb3d83 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -19,6 +19,7 @@
 #include <asm/ptrace.h>
 #include <asm/system.h>
 #include <linux/bitfield.h>
+#include <linux/delay.h>
 
 #if defined(CONFIG_ZYNQMP_IPI)
 #include <mailbox.h>
@@ -175,51 +176,60 @@ unsigned int zynqmp_firmware_version(void)
 };
 
 #if defined(CONFIG_ARCH_VERSAL2)
-int zynqmp_pm_ufs_get_txrx_cfgrdy(u32 *value)
+/*
+ * Poll the M-PHY TX/RX config-ready status until it settles or @timeout_us
+ * elapses. Legacy EEMI firmware only offers the per-read status primitive, so
+ * the poll loop lives here rather than in the UFS driver; the timeout budget is
+ * owned by the caller.
+ */
+int zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us)
 {
 	u32 ret_payload[PAYLOAD_ARG_CNT];
 	int ret;
 
-	if (!value)
-		return -EINVAL;
+	while (timeout_us--) {
+		ret = xilinx_pm_request(PM_IOCTL, PM_REGNODE_PMC_IOU_SLCR,
+					IOCTL_READ_REG, TXRX_CFGRDY_OFFSET, 0, 0,
+					0, ret_payload);
+		if (ret)
+			return ret;
 
-	ret = xilinx_pm_request(PM_IOCTL, PM_REGNODE_PMC_IOU_SLCR,
-				IOCTL_READ_REG, TXRX_CFGRDY_OFFSET, 0, 0,
-				0, ret_payload);
-	if (ret)
-		return ret;
+		if (!(ret_payload[1] & TX_RX_CFG_RDY_MASK))
+			return 0;
 
-	*value = ret_payload[1];
+		udelay(1);
+	}
 
-	return ret;
+	return -ETIMEDOUT;
 }
 
-int zynqmp_pm_ufs_sram_csr_read(u32 *value)
+int zynqmp_pm_wait_sram_init_done(u32 timeout_us)
 {
 	u32 ret_payload[PAYLOAD_ARG_CNT];
 	int ret;
 
-	if (!value)
-		return -EINVAL;
+	while (timeout_us--) {
+		ret = xilinx_pm_request(PM_IOCTL, PM_REGNODE_PMC_IOU_SLCR,
+					IOCTL_READ_REG, SRAM_CSR_OFFSET, 0, 0,
+					0, ret_payload);
+		if (ret)
+			return ret;
 
-	ret = xilinx_pm_request(PM_IOCTL, PM_REGNODE_PMC_IOU_SLCR,
-				IOCTL_READ_REG, SRAM_CSR_OFFSET, 0, 0,
-				0, ret_payload);
-	if (ret)
-		return ret;
+		if (ret_payload[1] & SRAM_CSR_INIT_DONE_MASK)
+			return 0;
 
-	*value = ret_payload[1];
+		udelay(1);
+	}
 
-	return ret;
+	return -ETIMEDOUT;
 }
 
-int zynqmp_pm_ufs_sram_csr_write(u32 *value)
+int zynqmp_pm_set_sram_bypass(void)
 {
+	u32 ret_payload[PAYLOAD_ARG_CNT];
+	u32 sram_csr;
 	int ret;
 
-	if (!value)
-		return -EINVAL;
-
 	ret = zynqmp_pm_is_function_supported(PM_IOCTL, IOCTL_MASK_WRITE_REG);
 	if (ret) {
 		printf("%s: IOCTL_MASK_WRITE_REG is not supported : %d\n"
@@ -228,15 +238,21 @@ int zynqmp_pm_ufs_sram_csr_write(u32 *value)
 	}
 
 	ret = xilinx_pm_request(PM_IOCTL, PM_REGNODE_PMC_IOU_SLCR,
-				IOCTL_MASK_WRITE_REG, SRAM_CSR_OFFSET,
-				GENMASK(2, 1), *value, 0, NULL);
+				IOCTL_READ_REG, SRAM_CSR_OFFSET, 0, 0,
+				0, ret_payload);
 	if (ret)
 		return ret;
 
-	return ret;
+	sram_csr = ret_payload[1];
+	sram_csr &= ~SRAM_CSR_EXT_LD_DONE_MASK;
+	sram_csr |= SRAM_CSR_BYPASS_MASK;
+
+	return xilinx_pm_request(PM_IOCTL, PM_REGNODE_PMC_IOU_SLCR,
+				 IOCTL_MASK_WRITE_REG, SRAM_CSR_OFFSET,
+				 GENMASK(2, 1), sram_csr, 0, NULL);
 }
 
-int zynqmp_pm_ufs_cal_reg(u32 *value)
+int zynqmp_pm_get_ufs_calibration_values(u32 *value)
 {
 	u32 ret_payload[PAYLOAD_ARG_CNT];
 	int ret;
diff --git a/drivers/ufs/ufs-amd-versal2.c b/drivers/ufs/ufs-amd-versal2.c
index 986147848bda..48854792cbf3 100644
--- a/drivers/ufs/ufs-amd-versal2.c
+++ b/drivers/ufs/ufs-amd-versal2.c
@@ -20,10 +20,6 @@
 #include "ufshcd-dwc.h"
 #include "ufshci-dwc.h"
 
-#define SRAM_CSR_INIT_DONE_MASK		BIT(0)
-#define SRAM_CSR_EXT_LD_DONE_MASK	BIT(1)
-#define SRAM_CSR_BYPASS_MASK		BIT(2)
-
 #define MPHY_FAST_RX_AFE_CAL		BIT(2)
 #define MPHY_FW_CALIB_CFG_VAL		BIT(8)
 
@@ -31,8 +27,6 @@
 #define MPHY_RX_OVRD_VAL		BIT(2)
 #define MPHY_RX_ACK_MASK		BIT(0)
 
-#define TX_RX_CFG_RDY_MASK		GENMASK(3, 0)
-
 #define TIMEOUT_MICROSEC		1000000L
 
 struct ufs_versal2_priv {
@@ -229,7 +223,6 @@ static int ufs_versal2_setup_phy(struct ufs_hba *hba)
 static int ufs_versal2_phy_init(struct ufs_hba *hba)
 {
 	struct ufs_versal2_priv *priv = dev_get_priv(hba->dev);
-	u32 reg, time_left;
 	int ret;
 	static const struct ufshcd_dme_attr_val rmmi_attrs[] = {
 		{ UIC_ARG_MIB(CBREFCLKCTRL2), CBREFREFCLK_GATE_OVR_EN, DME_LOCAL },
@@ -238,24 +231,15 @@ static int ufs_versal2_phy_init(struct ufs_hba *hba)
 		{ UIC_ARG_MIB(VS_MPHYCFGUPDT), 1, DME_LOCAL }
 	};
 
-	/* Wait for Tx/Rx config_rdy */
-	time_left = TIMEOUT_MICROSEC;
-	do {
-		time_left--;
-		ret = zynqmp_pm_ufs_get_txrx_cfgrdy(&reg);
-		if (ret)
-			return ret;
-
-		reg &= TX_RX_CFG_RDY_MASK;
-		if (!reg)
-			break;
-
-		mdelay(5);
-	} while (time_left);
-
-	if (!time_left) {
+	/*
+	 * Wait for Tx/Rx config_rdy. The poll loop lives in the firmware
+	 * backend (IO, EEMI or SCMI) so this driver stays backend-agnostic;
+	 * the timeout budget stays here with the consumer.
+	 */
+	ret = zynqmp_pm_wait_mphy_tx_rx_config_ready(TIMEOUT_MICROSEC);
+	if (ret) {
 		dev_err(hba->dev, "Tx/Rx configuration signal busy.\n");
-		return -ETIMEDOUT;
+		return ret;
 	}
 
 	ret = ufshcd_dwc_dme_set_attrs(hba, rmmi_attrs, ARRAY_SIZE(rmmi_attrs));
@@ -269,24 +253,11 @@ static int ufs_versal2_phy_init(struct ufs_hba *hba)
 		return ret;
 	}
 
-	/* Wait for SRAM init done */
-	time_left = TIMEOUT_MICROSEC;
-	do {
-		time_left--;
-		ret = zynqmp_pm_ufs_sram_csr_read(&reg);
-		if (ret)
-			return ret;
-
-		reg &= SRAM_CSR_INIT_DONE_MASK;
-		if (reg)
-			break;
-
-		mdelay(5);
-	} while (time_left);
-
-	if (!time_left) {
+	/* Wait for SRAM init done (poll handled by the firmware backend). */
+	ret = zynqmp_pm_wait_sram_init_done(TIMEOUT_MICROSEC);
+	if (ret) {
 		dev_err(hba->dev, "SRAM initialization failed.\n");
-		return -ETIMEDOUT;
+		return ret;
 	}
 
 	ret = ufs_versal2_setup_phy(hba);
@@ -301,7 +272,7 @@ static int ufs_versal2_init(struct ufs_hba *hba)
 	struct ufs_versal2_priv *priv = dev_get_priv(hba->dev);
 	struct clk clk;
 	unsigned long core_clk_rate = 0;
-	u32 cal, sram_csr;
+	u32 cal;
 	int ret = 0;
 
 	priv->phy_mode = UFSHCD_DWC_PHY_MODE_ROM;
@@ -345,28 +316,18 @@ static int ufs_versal2_init(struct ufs_hba *hba)
 		return ret;
 	}
 
-	ret = zynqmp_pm_ufs_sram_csr_read(&sram_csr);
-	if (ret)
+	ret = zynqmp_pm_set_sram_bypass();
+	if (ret) {
+		dev_err(hba->dev, "Bypass SRAM interface failed, err = %d\n", ret);
 		return ret;
-
-	if (!priv->phy_mode) {
-		sram_csr &= ~SRAM_CSR_EXT_LD_DONE_MASK;
-		sram_csr |= SRAM_CSR_BYPASS_MASK;
-	} else {
-		dev_err(hba->dev, "Invalid phy-mode %d.\n", priv->phy_mode);
-		return -EINVAL;
 	}
 
-	ret = zynqmp_pm_ufs_sram_csr_write(&sram_csr);
-	if (ret)
-		return ret;
-
 	/* De Assert RST_UFS Reset for UFS block in PMX_IOU */
 	ret = reset_deassert(priv->rstc);
 	if (ret)
 		dev_err(hba->dev, "host reset deassert failed, err = %d\n", ret);
 
-	ret = zynqmp_pm_ufs_cal_reg(&cal);
+	ret = zynqmp_pm_get_ufs_calibration_values(&cal);
 	if (ret)
 		return ret;
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] ufs: amd-versal2: Remove ZYNQMP_FIRMWARE dependency
  2026-07-30  6:49 [PATCH 0/3] ufs: amd-versal2: Cleanup firmware interface Michal Simek
  2026-07-30  6:49 ` [PATCH 1/3] ufs: amd-versal2: Perform controller reset in the init callback Michal Simek
  2026-07-30  6:49 ` [PATCH 2/3] xilinx: versal2: Clean UFS firmware interface Michal Simek
@ 2026-07-30  6:49 ` Michal Simek
  2026-08-11 12:53 ` [PATCH 0/3] ufs: amd-versal2: Cleanup firmware interface Michal Simek
  3 siblings, 0 replies; 5+ messages in thread
From: Michal Simek @ 2026-07-30  6:49 UTC (permalink / raw)
  To: u-boot, git
  Cc: Alexey Charkov, Anshul Dalal, Bhupesh Sharma, Johan Jonker,
	Neha Malcom Francis, Neil Armstrong, Tom Rini

There are EEMI firmware hooks available but they are also IO versions of it
that's why remove ZYNQMP_FIRMWARE depency from UFS driver.

Signed-off-by: Michal Simek <michal.simek@amd.com>
---

 drivers/ufs/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig
index c1b84bd75597..6dffdc00b32e 100644
--- a/drivers/ufs/Kconfig
+++ b/drivers/ufs/Kconfig
@@ -10,7 +10,7 @@ config UFS
 
 config UFS_AMD_VERSAL2
 	bool "AMD Versal Gen 2 UFS controller platform driver"
-	depends on UFS && ZYNQMP_FIRMWARE
+	depends on UFS && ARCH_VERSAL2
 	help
 	  This selects the AMD specific additions to UFSHCD platform driver.
 	  UFS host on AMD needs some vendor specific configuration before accessing
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/3] ufs: amd-versal2: Cleanup firmware interface
  2026-07-30  6:49 [PATCH 0/3] ufs: amd-versal2: Cleanup firmware interface Michal Simek
                   ` (2 preceding siblings ...)
  2026-07-30  6:49 ` [PATCH 3/3] ufs: amd-versal2: Remove ZYNQMP_FIRMWARE dependency Michal Simek
@ 2026-08-11 12:53 ` Michal Simek
  3 siblings, 0 replies; 5+ messages in thread
From: Michal Simek @ 2026-08-11 12:53 UTC (permalink / raw)
  To: u-boot, git
  Cc: Alexey Charkov, Anshul Dalal, Bhupesh Sharma, Ilias Apalodimas,
	Johan Jonker, Neha Malcom Francis, Neil Armstrong,
	Padmarao Begari, Pranav Sanwal, Pranav Tilak, Sean Anderson,
	Tom Rini



On 7/30/26 08:49, Michal Simek wrote:
> Hi,
> 
> the first patch mainly alignment with Linux kernel version. Issue was
> related to IRQ handling which is not valid reason for U-Boot but still
> correcting sequence make sense.
> 
> The second patch is moving firmware handling out of UFS driver. UFS driver
> cares about delivering functionality. And doesn't really matter how exactly
> it is done. If it is done via firmware interface, via IO polling or in a
> different way. That's why move loops out of UFS driver to be able to use
> different interfaces for it.
> 
> The third patch is just Kconfig update.
> 
> The series is based on
> https://patchwork.ozlabs.org/project/uboot/patch/6419fe4f6f1f451aee624c7762b7aa690d50e498.1784870711.git.michal.simek@amd.com/
> 
> Thanks,
> Michal
> 
> 
> Michal Simek (3):
>    ufs: amd-versal2: Perform controller reset in the init callback
>    xilinx: versal2: Clean UFS firmware interface
>    ufs: amd-versal2: Remove ZYNQMP_FIRMWARE dependency
> 
>   arch/arm/mach-versal2/cpu.c                   |  34 +++--
>   arch/arm/mach-versal2/include/mach/hardware.h |   5 +
>   .../arm/mach-versal2/include/mach/sys_proto.h |   8 +-
>   drivers/firmware/firmware-zynqmp.c            |  72 ++++++----
>   drivers/ufs/Kconfig                           |   2 +-
>   drivers/ufs/ufs-amd-versal2.c                 | 129 ++++++------------
>   6 files changed, 119 insertions(+), 131 deletions(-)
> 
> ---
> base-commit: 7e24149aacb83335fa997e2457144f23ba5e1bda
> 

applied.
M

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-08-11 12:53 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30  6:49 [PATCH 0/3] ufs: amd-versal2: Cleanup firmware interface Michal Simek
2026-07-30  6:49 ` [PATCH 1/3] ufs: amd-versal2: Perform controller reset in the init callback Michal Simek
2026-07-30  6:49 ` [PATCH 2/3] xilinx: versal2: Clean UFS firmware interface Michal Simek
2026-07-30  6:49 ` [PATCH 3/3] ufs: amd-versal2: Remove ZYNQMP_FIRMWARE dependency Michal Simek
2026-08-11 12:53 ` [PATCH 0/3] ufs: amd-versal2: Cleanup firmware interface Michal Simek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox