devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] ufs: Add support for AMD Versal Gen2 UFS
@ 2025-09-19 12:38 Ajay Neeli
  2025-09-19 12:38 ` [PATCH 1/5] dt-bindings: ufs: amd-versal2: Add support for AMD Versal Gen 2 UFS Host Controller Ajay Neeli
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Ajay Neeli @ 2025-09-19 12:38 UTC (permalink / raw)
  To: martin.petersen, James.Bottomley, robh, krzk+dt, conor+dt,
	pedrom.sousa
  Cc: alim.akhtar, avri.altman, bvanassche, linux-scsi, devicetree, git,
	michal.simek, srinivas.goud, radhey.shyam.pandey, Ajay Neeli

This patch series adds support for the AMD Versal Gen2 UFS, including:
- Device tree bindings and driver implementation.
- Secure read support for the secure retrieval of UFS calibration values.
- Vendor-specific interrupts support to the UFS core, enabling handling
  of interrupt bits that are not defined in UFSHCI specification,
  to avoid unhandled interrupts.

Ajay Neeli (1):
  firmware: xilinx: Add APIs for UFS PHY initialization

Izhar Ameer Shaikh (1):
  firmware: xilinx: Add support for secure read/write ioctl interface

Sai Krishna Potthuri (3):
  dt-bindings: ufs: amd-versal2: Add support for AMD Versal Gen 2 UFS
    Host Controller
  ufs: core: Add vendor specific ops to handle interrupts
  ufs: amd-versal2: Add AMD Versal Gen 2 UFS support

 .../devicetree/bindings/ufs/amd,versal2-ufs.yaml   |  61 +++
 MAINTAINERS                                        |   7 +
 drivers/firmware/xilinx/Makefile                   |   2 +-
 drivers/firmware/xilinx/zynqmp-ufs.c               | 118 +++++
 drivers/firmware/xilinx/zynqmp.c                   |  46 ++
 drivers/ufs/core/ufshcd-priv.h                     |   8 +
 drivers/ufs/core/ufshcd.c                          |   3 +
 drivers/ufs/host/Kconfig                           |  13 +
 drivers/ufs/host/Makefile                          |   1 +
 drivers/ufs/host/ufs-amd-versal2.c                 | 589 +++++++++++++++++++++
 drivers/ufs/host/ufshcd-dwc.h                      |  49 ++
 drivers/ufs/host/ufshci-dwc.h                      |   5 +
 include/linux/firmware/xlnx-zynqmp-ufs.h           |  38 ++
 include/linux/firmware/xlnx-zynqmp.h               |  16 +
 include/ufs/ufshcd.h                               |   2 +
 include/ufs/ufshci.h                               |   3 +
 include/ufs/unipro.h                               |   1 +
 17 files changed, 961 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml
 create mode 100644 drivers/firmware/xilinx/zynqmp-ufs.c
 create mode 100644 drivers/ufs/host/ufs-amd-versal2.c
 create mode 100644 include/linux/firmware/xlnx-zynqmp-ufs.h

-- 
1.8.3.1


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

* [PATCH 1/5] dt-bindings: ufs: amd-versal2: Add support for AMD Versal Gen 2 UFS Host Controller
  2025-09-19 12:38 [PATCH 0/5] ufs: Add support for AMD Versal Gen2 UFS Ajay Neeli
@ 2025-09-19 12:38 ` Ajay Neeli
  2025-09-22 19:46   ` Rob Herring
  2025-09-19 12:38 ` [PATCH 2/5] firmware: xilinx: Add support for secure read/write ioctl interface Ajay Neeli
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Ajay Neeli @ 2025-09-19 12:38 UTC (permalink / raw)
  To: martin.petersen, James.Bottomley, robh, krzk+dt, conor+dt,
	pedrom.sousa
  Cc: alim.akhtar, avri.altman, bvanassche, linux-scsi, devicetree, git,
	michal.simek, srinivas.goud, radhey.shyam.pandey,
	Sai Krishna Potthuri, Ajay Neeli

From: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>

Add devicetree document for AMD Versal Gen 2 UFS Host Controller.
This includes clocks and clock-names as mandated by UFS common bindings.

Signed-off-by: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
Co-developed-by: Ajay Neeli <ajay.neeli@amd.com>
Signed-off-by: Ajay Neeli <ajay.neeli@amd.com>
---
 .../devicetree/bindings/ufs/amd,versal2-ufs.yaml   | 61 ++++++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml

diff --git a/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml b/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml
new file mode 100644
index 0000000..9f55949
--- /dev/null
+++ b/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ufs/amd,versal2-ufs.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: AMD Versal Gen 2 UFS Host Controller
+
+maintainers:
+  - Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
+
+allOf:
+  - $ref: ufs-common.yaml
+
+properties:
+  compatible:
+    const: amd,versal2-ufs
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: core
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 2
+
+  reset-names:
+    items:
+      - const: ufshc
+      - const: ufsphy
+
+required:
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    ufs@f10b0000 {
+        compatible = "amd,versal2-ufs";
+        reg = <0xf10b0000 0x1000>;
+        clocks = <&ufs_core_clk>;
+        clock-names = "core";
+        resets = <&scmi_reset 4>, <&scmi_reset 35>;
+        reset-names = "ufshc", "ufsphy";
+        interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+        freq-table-hz = <0 0>;
+    };
-- 
1.8.3.1


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

* [PATCH 2/5] firmware: xilinx: Add support for secure read/write ioctl interface
  2025-09-19 12:38 [PATCH 0/5] ufs: Add support for AMD Versal Gen2 UFS Ajay Neeli
  2025-09-19 12:38 ` [PATCH 1/5] dt-bindings: ufs: amd-versal2: Add support for AMD Versal Gen 2 UFS Host Controller Ajay Neeli
@ 2025-09-19 12:38 ` Ajay Neeli
  2025-09-19 12:38 ` [PATCH 3/5] firmware: xilinx: Add APIs for UFS PHY initialization Ajay Neeli
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Ajay Neeli @ 2025-09-19 12:38 UTC (permalink / raw)
  To: martin.petersen, James.Bottomley, robh, krzk+dt, conor+dt,
	pedrom.sousa
  Cc: alim.akhtar, avri.altman, bvanassche, linux-scsi, devicetree, git,
	michal.simek, srinivas.goud, radhey.shyam.pandey,
	Izhar Ameer Shaikh, Ajay Neeli

From: Izhar Ameer Shaikh <izhar.ameer.shaikh@amd.com>

Add support for a generic ioctl read/write interface using which users
can request firmware to perform read/write operations on a protected and
secure address space.

The functionality is introduced through the means of two new IOCTL IDs
which extend the existing PM_IOCTL EEMI API:
 - IOCTL_READ_REG
 - IOCTL_MASK_WRITE_REG

The caller only passes the node id of the given device and an offset.
The base address is not exposed to the caller and internally retrieved
by the firmware. Firmware will enforce an access policy on the incoming
read/write request.

Signed-off-by: Izhar Ameer Shaikh <izhar.ameer.shaikh@amd.com>
Reviewed-by: Tanmay Shah <tanmay.shah@amd.com>
Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Signed-off-by: Ajay Neeli <ajay.neeli@amd.com>
Acked-by: Senthil Nathan Thangaraj <senthilnathan.thangaraj@amd.com>
---
 drivers/firmware/xilinx/zynqmp.c     | 46 ++++++++++++++++++++++++++++++++++++
 include/linux/firmware/xlnx-zynqmp.h | 15 ++++++++++++
 2 files changed, 61 insertions(+)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 7356e86..2422922 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -1617,6 +1617,52 @@ int zynqmp_pm_get_feature_config(enum pm_feature_config_id id,
 }
 
 /**
+ * zynqmp_pm_sec_read_reg - PM call to securely read from given offset
+ *		of the node
+ * @node_id:	Node Id of the device
+ * @offset:	Offset to be used (20-bit)
+ * @ret_value:	Output data read from the given offset after
+ *		firmware access policy is successfully enforced
+ *
+ * Return:	Returns 0 on success or error value on failure
+ */
+int zynqmp_pm_sec_read_reg(u32 node_id, u32 offset, u32 *ret_value)
+{
+	u32 ret_payload[PAYLOAD_ARG_CNT];
+	u32 count = 1;
+	int ret;
+
+	if (!ret_value)
+		return -EINVAL;
+
+	ret = zynqmp_pm_invoke_fn(PM_IOCTL, ret_payload, 4, node_id, IOCTL_READ_REG,
+				  offset, count);
+
+	*ret_value = ret_payload[1];
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_sec_read_reg);
+
+/**
+ * zynqmp_pm_sec_mask_write_reg - PM call to securely write to given offset
+ *		of the node
+ * @node_id:	Node Id of the device
+ * @offset:	Offset to be used (20-bit)
+ * @mask:	Mask to be used
+ * @value:	Value to be written
+ *
+ * Return:	Returns 0 on success or error value on failure
+ */
+int zynqmp_pm_sec_mask_write_reg(const u32 node_id, const u32 offset, u32 mask,
+				 u32 value)
+{
+	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 5, node_id, IOCTL_MASK_WRITE_REG,
+				   offset, mask, value);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_sec_mask_write_reg);
+
+/**
  * zynqmp_pm_set_sd_config - PM call to set value of SD config registers
  * @node:	SD node ID
  * @config:	The config type of SD registers
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index 6d4dbc1..f441eea 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -241,6 +241,7 @@ enum pm_ioctl_id {
 	IOCTL_GET_FEATURE_CONFIG = 27,
 	/* IOCTL for Secure Read/Write Interface */
 	IOCTL_READ_REG = 28,
+	IOCTL_MASK_WRITE_REG = 29,
 	/* Dynamic SD/GEM configuration */
 	IOCTL_SET_SD_CONFIG = 30,
 	IOCTL_SET_GEM_CONFIG = 31,
@@ -620,6 +621,9 @@ int zynqmp_pm_register_notifier(const u32 node, const u32 event,
 int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id);
 int zynqmp_pm_set_feature_config(enum pm_feature_config_id id, u32 value);
 int zynqmp_pm_get_feature_config(enum pm_feature_config_id id, u32 *payload);
+int zynqmp_pm_sec_read_reg(u32 node_id, u32 offset, u32 *ret_value);
+int zynqmp_pm_sec_mask_write_reg(const u32 node_id, const u32 offset,
+				 u32 mask, u32 value);
 int zynqmp_pm_register_sgi(u32 sgi_num, u32 reset);
 int zynqmp_pm_force_pwrdwn(const u32 target,
 			   const enum zynqmp_pm_request_ack ack);
@@ -922,6 +926,17 @@ static inline int zynqmp_pm_request_wake(const u32 node,
 	return -ENODEV;
 }
 
+static inline int zynqmp_pm_sec_read_reg(u32 node_id, u32 offset, u32 *ret_value)
+{
+	return -ENODEV;
+}
+
+static inline int zynqmp_pm_sec_mask_write_reg(const u32 node_id, const u32 offset,
+					       u32 mask, u32 value)
+{
+	return -ENODEV;
+}
+
 static inline int zynqmp_pm_get_rpu_mode(u32 node_id, enum rpu_oper_mode *rpu_mode)
 {
 	return -ENODEV;
-- 
1.8.3.1


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

* [PATCH 3/5] firmware: xilinx: Add APIs for UFS PHY initialization
  2025-09-19 12:38 [PATCH 0/5] ufs: Add support for AMD Versal Gen2 UFS Ajay Neeli
  2025-09-19 12:38 ` [PATCH 1/5] dt-bindings: ufs: amd-versal2: Add support for AMD Versal Gen 2 UFS Host Controller Ajay Neeli
  2025-09-19 12:38 ` [PATCH 2/5] firmware: xilinx: Add support for secure read/write ioctl interface Ajay Neeli
@ 2025-09-19 12:38 ` Ajay Neeli
  2025-09-19 12:38 ` [PATCH 4/5] ufs: core: Add vendor specific ops to handle interrupts Ajay Neeli
  2025-09-19 12:38 ` [PATCH 5/5] ufs: amd-versal2: Add AMD Versal Gen 2 UFS support Ajay Neeli
  4 siblings, 0 replies; 12+ messages in thread
From: Ajay Neeli @ 2025-09-19 12:38 UTC (permalink / raw)
  To: martin.petersen, James.Bottomley, robh, krzk+dt, conor+dt,
	pedrom.sousa
  Cc: alim.akhtar, avri.altman, bvanassche, linux-scsi, devicetree, git,
	michal.simek, srinivas.goud, radhey.shyam.pandey, Ajay Neeli

- Add APIs for UFS PHY initialization.
- Verify M-PHY TX-RX configuration readiness.
- Confirm SRAM initialization and Set SRAM bypass.
- Retrieve UFS calibration values.

Signed-off-by: Ajay Neeli <ajay.neeli@amd.com>
Acked-by: Senthil Nathan Thangaraj <senthilnathan.thangaraj@amd.com>
---
 drivers/firmware/xilinx/Makefile         |   2 +-
 drivers/firmware/xilinx/zynqmp-ufs.c     | 118 +++++++++++++++++++++++++++++++
 include/linux/firmware/xlnx-zynqmp-ufs.h |  38 ++++++++++
 include/linux/firmware/xlnx-zynqmp.h     |   1 +
 4 files changed, 158 insertions(+), 1 deletion(-)
 create mode 100644 drivers/firmware/xilinx/zynqmp-ufs.c
 create mode 100644 include/linux/firmware/xlnx-zynqmp-ufs.h

diff --git a/drivers/firmware/xilinx/Makefile b/drivers/firmware/xilinx/Makefile
index 875a537..70f8f02 100644
--- a/drivers/firmware/xilinx/Makefile
+++ b/drivers/firmware/xilinx/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for Xilinx firmwares
 
-obj-$(CONFIG_ZYNQMP_FIRMWARE) += zynqmp.o
+obj-$(CONFIG_ZYNQMP_FIRMWARE) += zynqmp.o zynqmp-ufs.o
 obj-$(CONFIG_ZYNQMP_FIRMWARE_DEBUG) += zynqmp-debug.o
diff --git a/drivers/firmware/xilinx/zynqmp-ufs.c b/drivers/firmware/xilinx/zynqmp-ufs.c
new file mode 100644
index 0000000..85da8a8
--- /dev/null
+++ b/drivers/firmware/xilinx/zynqmp-ufs.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Firmware Layer for UFS APIs
+ *
+ * Copyright (C) 2025 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/firmware/xlnx-zynqmp.h>
+#include <linux/module.h>
+
+/* Register Node IDs */
+#define PM_REGNODE_PMC_IOU_SLCR		0x30000002 /* PMC IOU SLCR */
+#define PM_REGNODE_EFUSE_CACHE		0x30000003 /* EFUSE Cache */
+
+/* Register Offsets for PMC IOU SLCR */
+#define SRAM_CSR_OFFSET			0x104C /* SRAM Control and Status */
+#define TXRX_CFGRDY_OFFSET		0x1054 /* M-PHY TX-RX Config ready */
+
+/* Masks for SRAM Control and Status Register */
+#define SRAM_CSR_INIT_DONE_MASK		BIT(0) /* SRAM initialization done */
+#define SRAM_CSR_EXT_LD_DONE_MASK	BIT(1) /* SRAM External load done */
+#define SRAM_CSR_BYPASS_MASK		BIT(2) /* Bypass SRAM interface */
+
+/* Mask to check M-PHY TX-RX configuration readiness */
+#define TX_RX_CFG_RDY_MASK		GENMASK(3, 0)
+
+/* Register Offsets for EFUSE Cache */
+#define UFS_CAL_1_OFFSET		0xBE8 /* UFS Calibration Value */
+
+/**
+ * zynqmp_pm_is_mphy_tx_rx_config_ready - check M-PHY TX-RX config readiness
+ * @is_ready:	Store output status (true/false)
+ *
+ * Return:	Returns 0 on success or error value on failure.
+ */
+int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready)
+{
+	u32 regval;
+	int ret;
+
+	if (!is_ready)
+		return -EINVAL;
+
+	ret = zynqmp_pm_sec_read_reg(PM_REGNODE_PMC_IOU_SLCR, TXRX_CFGRDY_OFFSET, &regval);
+	if (ret)
+		return ret;
+
+	regval &= TX_RX_CFG_RDY_MASK;
+	if (regval)
+		*is_ready = true;
+	else
+		*is_ready = false;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_is_mphy_tx_rx_config_ready);
+
+/**
+ * zynqmp_pm_is_sram_init_done - check SRAM initialization
+ * @is_done:	Store output status (true/false)
+ *
+ * Return:	Returns 0 on success or error value on failure.
+ */
+int zynqmp_pm_is_sram_init_done(bool *is_done)
+{
+	u32 regval;
+	int ret;
+
+	if (!is_done)
+		return -EINVAL;
+
+	ret = zynqmp_pm_sec_read_reg(PM_REGNODE_PMC_IOU_SLCR, SRAM_CSR_OFFSET, &regval);
+	if (ret)
+		return ret;
+
+	regval &= SRAM_CSR_INIT_DONE_MASK;
+	if (regval)
+		*is_done = true;
+	else
+		*is_done = false;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_is_sram_init_done);
+
+/**
+ * zynqmp_pm_set_sram_bypass - Set SRAM bypass Control
+ *
+ * Return:	Returns 0 on success or error value on failure.
+ */
+int zynqmp_pm_set_sram_bypass(void)
+{
+	u32 sram_csr;
+	int ret;
+
+	ret = zynqmp_pm_sec_read_reg(PM_REGNODE_PMC_IOU_SLCR, SRAM_CSR_OFFSET, &sram_csr);
+	if (ret)
+		return ret;
+
+	sram_csr &= ~SRAM_CSR_EXT_LD_DONE_MASK;
+	sram_csr |= SRAM_CSR_BYPASS_MASK;
+
+	return zynqmp_pm_sec_mask_write_reg(PM_REGNODE_PMC_IOU_SLCR, SRAM_CSR_OFFSET,
+					    GENMASK(2, 1), sram_csr);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_set_sram_bypass);
+
+/**
+ * zynqmp_pm_get_ufs_calibration_values - Read UFS calibration values
+ * @val:	Store the calibration value
+ *
+ * Return:	Returns 0 on success or error value on failure.
+ */
+int zynqmp_pm_get_ufs_calibration_values(u32 *val)
+{
+	return zynqmp_pm_sec_read_reg(PM_REGNODE_EFUSE_CACHE, UFS_CAL_1_OFFSET, val);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_get_ufs_calibration_values);
diff --git a/include/linux/firmware/xlnx-zynqmp-ufs.h b/include/linux/firmware/xlnx-zynqmp-ufs.h
new file mode 100644
index 0000000..d3538dd
--- /dev/null
+++ b/include/linux/firmware/xlnx-zynqmp-ufs.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Firmware layer for UFS APIs.
+ *
+ * Copyright (c) 2025 Advanced Micro Devices, Inc.
+ */
+
+#ifndef __FIRMWARE_XLNX_ZYNQMP_UFS_H__
+#define __FIRMWARE_XLNX_ZYNQMP_UFS_H__
+
+#if IS_REACHABLE(CONFIG_ZYNQMP_FIRMWARE)
+int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready);
+int zynqmp_pm_is_sram_init_done(bool *is_done);
+int zynqmp_pm_set_sram_bypass(void);
+int zynqmp_pm_get_ufs_calibration_values(u32 *val);
+#else
+static inline int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready)
+{
+	return -ENODEV;
+}
+
+static inline int zynqmp_pm_is_sram_init_done(bool *is_done)
+{
+	return -ENODEV;
+}
+
+static inline int zynqmp_pm_set_sram_bypass(void)
+{
+	return -ENODEV;
+}
+
+static inline int zynqmp_pm_get_ufs_calibration_values(u32 *val)
+{
+	return -ENODEV;
+}
+#endif
+
+#endif /* __FIRMWARE_XLNX_ZYNQMP_UFS_H__ */
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index f441eea..604a03f 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -16,6 +16,7 @@
 #include <linux/types.h>
 
 #include <linux/err.h>
+#include <linux/firmware/xlnx-zynqmp-ufs.h>
 
 #define ZYNQMP_PM_VERSION_MAJOR	1
 #define ZYNQMP_PM_VERSION_MINOR	0
-- 
1.8.3.1


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

* [PATCH 4/5] ufs: core: Add vendor specific ops to handle interrupts
  2025-09-19 12:38 [PATCH 0/5] ufs: Add support for AMD Versal Gen2 UFS Ajay Neeli
                   ` (2 preceding siblings ...)
  2025-09-19 12:38 ` [PATCH 3/5] firmware: xilinx: Add APIs for UFS PHY initialization Ajay Neeli
@ 2025-09-19 12:38 ` Ajay Neeli
  2025-09-19 17:34   ` Bart Van Assche
  2025-09-19 12:38 ` [PATCH 5/5] ufs: amd-versal2: Add AMD Versal Gen 2 UFS support Ajay Neeli
  4 siblings, 1 reply; 12+ messages in thread
From: Ajay Neeli @ 2025-09-19 12:38 UTC (permalink / raw)
  To: martin.petersen, James.Bottomley, robh, krzk+dt, conor+dt,
	pedrom.sousa
  Cc: alim.akhtar, avri.altman, bvanassche, linux-scsi, devicetree, git,
	michal.simek, srinivas.goud, radhey.shyam.pandey,
	Sai Krishna Potthuri, Ajay Neeli

From: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>

Some vendors will define their own interrupts, current interrupt service
routine handles only interrupts defined by the JEDEC standard.
Add provision to handle vendor specific interrupts by defining vendor
specific vops.

Signed-off-by: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
Signed-off-by: Ajay Neeli <ajay.neeli@amd.com>
---
 drivers/ufs/core/ufshcd-priv.h | 8 ++++++++
 drivers/ufs/core/ufshcd.c      | 3 +++
 include/ufs/ufshcd.h           | 2 ++
 include/ufs/ufshci.h           | 3 +++
 4 files changed, 16 insertions(+)

diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h
index d0a2c96..04a31f0 100644
--- a/drivers/ufs/core/ufshcd-priv.h
+++ b/drivers/ufs/core/ufshcd-priv.h
@@ -118,6 +118,14 @@ static inline u32 ufshcd_vops_get_ufs_hci_version(struct ufs_hba *hba)
 	return ufshcd_readl(hba, REG_UFS_VERSION);
 }
 
+static inline irqreturn_t ufshcd_vops_isr(struct ufs_hba *hba, u32 intr_status)
+{
+	if (hba->vops && hba->vops->isr)
+		return hba->vops->isr(hba, intr_status);
+
+	return 0;
+}
+
 static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba, bool up,
 					       unsigned long target_freq,
 					       enum ufs_notify_change_status status)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 5442bb8..7a6dde8 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -7069,6 +7069,9 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
 	if (intr_status & MCQ_CQ_EVENT_STATUS)
 		retval |= ufshcd_handle_mcq_cq_events(hba);
 
+	if (intr_status & UFSHCD_VENDOR_IS_MASK)
+		retval |= ufshcd_vops_isr(hba, intr_status);
+
 	return retval;
 }
 
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index 1d39437..64c958e 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -337,6 +337,7 @@ struct ufs_pwr_mode_info {
  * @config_esi: called to config Event Specific Interrupt
  * @config_scsi_dev: called to configure SCSI device parameters
  * @freq_to_gear_speed: called to map clock frequency to the max supported gear speed
+ * @isr: called to handle vendor specific interrupts
  */
 struct ufs_hba_variant_ops {
 	const char *name;
@@ -386,6 +387,7 @@ struct ufs_hba_variant_ops {
 	int	(*config_esi)(struct ufs_hba *hba);
 	void	(*config_scsi_dev)(struct scsi_device *sdev);
 	u32	(*freq_to_gear_speed)(struct ufs_hba *hba, unsigned long freq);
+	irqreturn_t	(*isr)(struct ufs_hba *hba, u32 intr_status);
 };
 
 /* clock gating state  */
diff --git a/include/ufs/ufshci.h b/include/ufs/ufshci.h
index 612500a..2844772 100644
--- a/include/ufs/ufshci.h
+++ b/include/ufs/ufshci.h
@@ -185,6 +185,9 @@ static inline u32 ufshci_version(u32 major, u32 minor)
 #define CRYPTO_ENGINE_FATAL_ERROR		0x40000
 #define MCQ_CQ_EVENT_STATUS			0x100000
 
+/* Other than above mentioned bits are treated as Vendor specific status bits */
+#define UFSHCD_VENDOR_IS_MASK			0xFFE8F000
+
 #define UFSHCD_UIC_HIBERN8_MASK	(UIC_HIBERNATE_ENTER |\
 				UIC_HIBERNATE_EXIT)
 
-- 
1.8.3.1


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

* [PATCH 5/5] ufs: amd-versal2: Add AMD Versal Gen 2 UFS support
  2025-09-19 12:38 [PATCH 0/5] ufs: Add support for AMD Versal Gen2 UFS Ajay Neeli
                   ` (3 preceding siblings ...)
  2025-09-19 12:38 ` [PATCH 4/5] ufs: core: Add vendor specific ops to handle interrupts Ajay Neeli
@ 2025-09-19 12:38 ` Ajay Neeli
  2025-09-19 17:44   ` Bart Van Assche
  4 siblings, 1 reply; 12+ messages in thread
From: Ajay Neeli @ 2025-09-19 12:38 UTC (permalink / raw)
  To: martin.petersen, James.Bottomley, robh, krzk+dt, conor+dt,
	pedrom.sousa
  Cc: alim.akhtar, avri.altman, bvanassche, linux-scsi, devicetree, git,
	michal.simek, srinivas.goud, radhey.shyam.pandey,
	Sai Krishna Potthuri, Ajay Neeli

From: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>

Add UFS AMD Versal Gen 2 platform support on top of the UFSHCD DWC and
UFSHCD platform driver. UFS AMD Versal Gen 2 platform requires specific
configurations like M-PHY/RMMI/UniPro and vendor specific registers
programming before doing the UIC_LINKSTARTUP.

Signed-off-by: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
Signed-off-by: Ajay Neeli <ajay.neeli@amd.com>
---
 MAINTAINERS                        |   7 +
 drivers/ufs/host/Kconfig           |  13 +
 drivers/ufs/host/Makefile          |   1 +
 drivers/ufs/host/ufs-amd-versal2.c | 589 +++++++++++++++++++++++++++++++++++++
 drivers/ufs/host/ufshcd-dwc.h      |  49 +++
 drivers/ufs/host/ufshci-dwc.h      |   5 +
 include/ufs/unipro.h               |   1 +
 7 files changed, 665 insertions(+)
 create mode 100644 drivers/ufs/host/ufs-amd-versal2.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 05325fa..63bb457 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -25453,6 +25453,13 @@ F:	Documentation/devicetree/bindings/ufs/
 F:	Documentation/scsi/ufs.rst
 F:	drivers/ufs/core/
 
+UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER AMD VERSAL2
+M:	Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
+M:	Ajay Neeli <ajay.neeli@amd.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml
+F:	drivers/ufs/host/ufs-amd-versal2.c
+
 UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER DWC HOOKS
 M:	Pedro Sousa <pedrom.sousa@synopsys.com>
 L:	linux-scsi@vger.kernel.org
diff --git a/drivers/ufs/host/Kconfig b/drivers/ufs/host/Kconfig
index 191fbd7..7d5117b 100644
--- a/drivers/ufs/host/Kconfig
+++ b/drivers/ufs/host/Kconfig
@@ -154,3 +154,16 @@ config SCSI_UFS_ROCKCHIP
 
 	  Select this if you have UFS controller on Rockchip chipset.
 	  If unsure, say N.
+
+config SCSI_UFS_AMD_VERSAL2
+	tristate "AMD Versal Gen 2 UFS controller platform driver"
+	depends on SCSI_UFSHCD_PLATFORM && (ARCH_ZYNQMP || COMPILE_TEST)
+	help
+	  This selects the AMD Versal Gen 2 specific additions on top of
+	  the UFSHCD DWC and UFSHCD platform driver. UFS host on AMD
+	  Versal Gen 2 needs some vendor specific configurations like PHY
+	  and vendor specific register accesses before accessing the
+	  hardware.
+
+	  Select this if you have UFS controller on AMD Versal Gen 2 SoC.
+	  If unsure, say N.
diff --git a/drivers/ufs/host/Makefile b/drivers/ufs/host/Makefile
index 2f97feb..65d8bb2 100644
--- a/drivers/ufs/host/Makefile
+++ b/drivers/ufs/host/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_SCSI_UFS_RENESAS) += ufs-renesas.o
 obj-$(CONFIG_SCSI_UFS_ROCKCHIP) += ufs-rockchip.o
 obj-$(CONFIG_SCSI_UFS_SPRD) += ufs-sprd.o
 obj-$(CONFIG_SCSI_UFS_TI_J721E) += ti-j721e-ufs.o
+obj-$(CONFIG_SCSI_UFS_AMD_VERSAL2) += ufs-amd-versal2.o ufshcd-dwc.o
diff --git a/drivers/ufs/host/ufs-amd-versal2.c b/drivers/ufs/host/ufs-amd-versal2.c
new file mode 100644
index 0000000..fdae3ed
--- /dev/null
+++ b/drivers/ufs/host/ufs-amd-versal2.c
@@ -0,0 +1,589 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Advanced Micro Devices, Inc.
+ *
+ * Authors: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/firmware/xlnx-zynqmp.h>
+#include <linux/irqreturn.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <ufs/unipro.h>
+
+#include "ufshcd-dwc.h"
+#include "ufshcd-pltfrm.h"
+#include "ufshci-dwc.h"
+
+#define MPHY_FAST_RX_AFE_CAL		BIT(2)
+#define MPHY_FW_CALIB_CFG_VAL		BIT(8)
+
+#define MPHY_RX_OVRD_EN			BIT(3)
+#define MPHY_RX_OVRD_VAL		BIT(2)
+#define MPHY_RX_ACK_MASK		BIT(0)
+
+#define TIMEOUT_MICROSEC	1000000
+
+struct ufs_versal2_host {
+	struct ufs_hba *hba;
+	struct reset_control *rstc;
+	struct reset_control *rstphy;
+	u32 phy_mode;
+	unsigned long host_clk;
+	u8 attcompval0;
+	u8 attcompval1;
+	u8 ctlecompval0;
+	u8 ctlecompval1;
+};
+
+static int ufs_versal2_phy_reg_write(struct ufs_hba *hba, u32 addr, u32 val)
+{
+	static struct ufshcd_dme_attr_val phy_write_attrs[] = {
+		{ UIC_ARG_MIB(CBCREGADDRLSB), 0, DME_LOCAL },
+		{ UIC_ARG_MIB(CBCREGADDRMSB), 0, DME_LOCAL },
+		{ UIC_ARG_MIB(CBCREGWRLSB), 0, DME_LOCAL },
+		{ UIC_ARG_MIB(CBCREGWRMSB), 0, DME_LOCAL },
+		{ UIC_ARG_MIB(CBCREGRDWRSEL), 1, DME_LOCAL },
+		{ UIC_ARG_MIB(VS_MPHYCFGUPDT), 1, DME_LOCAL }
+	};
+
+	phy_write_attrs[0].mib_val = (u8)addr;
+	phy_write_attrs[1].mib_val = (u8)(addr >> 8);
+	phy_write_attrs[2].mib_val = (u8)val;
+	phy_write_attrs[3].mib_val = (u8)(val >> 8);
+
+	return ufshcd_dwc_dme_set_attrs(hba, phy_write_attrs, ARRAY_SIZE(phy_write_attrs));
+}
+
+static int ufs_versal2_phy_reg_read(struct ufs_hba *hba, u32 addr, u32 *val)
+{
+	u32 mib_val;
+	int ret;
+	static struct ufshcd_dme_attr_val phy_read_attrs[] = {
+		{ UIC_ARG_MIB(CBCREGADDRLSB), 0, DME_LOCAL },
+		{ UIC_ARG_MIB(CBCREGADDRMSB), 0, DME_LOCAL },
+		{ UIC_ARG_MIB(CBCREGRDWRSEL), 0, DME_LOCAL },
+		{ UIC_ARG_MIB(VS_MPHYCFGUPDT), 1, DME_LOCAL }
+	};
+
+	phy_read_attrs[0].mib_val = (u8)addr;
+	phy_read_attrs[1].mib_val = (u8)(addr >> 8);
+
+	ret = ufshcd_dwc_dme_set_attrs(hba, phy_read_attrs, ARRAY_SIZE(phy_read_attrs));
+	if (ret)
+		return ret;
+
+	ret = ufshcd_dme_get(hba, UIC_ARG_MIB(CBCREGRDLSB), &mib_val);
+	if (ret)
+		return ret;
+
+	*val = mib_val;
+	ret = ufshcd_dme_get(hba, UIC_ARG_MIB(CBCREGRDMSB), &mib_val);
+	if (ret)
+		return ret;
+
+	*val |= (mib_val << 8);
+
+	return 0;
+}
+
+static int ufs_versal2_enable_phy(struct ufs_hba *hba)
+{
+	u32 offset, reg;
+	int ret;
+
+	ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_MPHYDISABLE), 0);
+	if (ret)
+		return ret;
+
+	ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_MPHYCFGUPDT), 1);
+	if (ret)
+		return ret;
+
+	/* Check Tx/Rx FSM states */
+	for (offset = 0; offset < 2; offset++) {
+		u32 time_left, mibsel;
+
+		time_left = TIMEOUT_MICROSEC;
+		mibsel = UIC_ARG_MIB_SEL(MTX_FSM_STATE, UIC_ARG_MPHY_TX_GEN_SEL_INDEX(offset));
+		do {
+			ret = ufshcd_dme_get(hba, mibsel, &reg);
+			if (ret)
+				return ret;
+
+			if (reg == TX_STATE_HIBERN8 || reg == TX_STATE_SLEEP ||
+			    reg == TX_STATE_LSBURST)
+				break;
+
+			time_left--;
+			usleep_range(1, 5);
+		} while (time_left);
+
+		if (!time_left) {
+			dev_err(hba->dev, "Invalid Tx FSM state.\n");
+			return -ETIMEDOUT;
+		}
+
+		time_left = TIMEOUT_MICROSEC;
+		mibsel = UIC_ARG_MIB_SEL(MRX_FSM_STATE, UIC_ARG_MPHY_RX_GEN_SEL_INDEX(offset));
+		do {
+			ret = ufshcd_dme_get(hba, mibsel, &reg);
+			if (ret)
+				return ret;
+
+			if (reg == RX_STATE_HIBERN8 || reg == RX_STATE_SLEEP ||
+			    reg == RX_STATE_LSBURST)
+				break;
+
+			time_left--;
+			usleep_range(1, 5);
+		} while (time_left);
+
+		if (!time_left) {
+			dev_err(hba->dev, "Invalid Rx FSM state.\n");
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int ufs_versal2_setup_phy(struct ufs_hba *hba)
+{
+	struct ufs_versal2_host *host = ufshcd_get_variant(hba);
+	int ret;
+	u32 reg;
+
+	/* Bypass RX-AFE offset calibrations (ATT/CTLE) */
+	ret = ufs_versal2_phy_reg_read(hba, FAST_FLAGS(0), &reg);
+	if (ret)
+		return ret;
+
+	reg |= MPHY_FAST_RX_AFE_CAL;
+	ret = ufs_versal2_phy_reg_write(hba, FAST_FLAGS(0), reg);
+	if (ret)
+		return ret;
+
+	ret = ufs_versal2_phy_reg_read(hba, FAST_FLAGS(1), &reg);
+	if (ret)
+		return ret;
+
+	reg |= MPHY_FAST_RX_AFE_CAL;
+	ret = ufs_versal2_phy_reg_write(hba, FAST_FLAGS(1), reg);
+	if (ret)
+		return ret;
+
+	/* Program ATT and CTLE compensation values */
+	if (host->attcompval0) {
+		ret = ufs_versal2_phy_reg_write(hba, RX_AFE_ATT_IDAC(0), host->attcompval0);
+		if (ret)
+			return ret;
+	}
+
+	if (host->attcompval1) {
+		ret = ufs_versal2_phy_reg_write(hba, RX_AFE_ATT_IDAC(1), host->attcompval1);
+		if (ret)
+			return ret;
+	}
+
+	if (host->ctlecompval0) {
+		ret = ufs_versal2_phy_reg_write(hba, RX_AFE_CTLE_IDAC(0), host->ctlecompval0);
+		if (ret)
+			return ret;
+	}
+
+	if (host->ctlecompval1) {
+		ret = ufs_versal2_phy_reg_write(hba, RX_AFE_CTLE_IDAC(1), host->ctlecompval1);
+		if (ret)
+			return ret;
+	}
+
+	ret = ufs_versal2_phy_reg_read(hba, FW_CALIB_CCFG(0), &reg);
+	if (ret)
+		return ret;
+
+	reg |= MPHY_FW_CALIB_CFG_VAL;
+	ret = ufs_versal2_phy_reg_write(hba, FW_CALIB_CCFG(0), reg);
+	if (ret)
+		return ret;
+
+	ret = ufs_versal2_phy_reg_read(hba, FW_CALIB_CCFG(1), &reg);
+	if (ret)
+		return ret;
+
+	reg |= MPHY_FW_CALIB_CFG_VAL;
+	return ufs_versal2_phy_reg_write(hba, FW_CALIB_CCFG(1), reg);
+}
+
+static int ufs_versal2_phy_init(struct ufs_hba *hba)
+{
+	struct ufs_versal2_host *host = ufshcd_get_variant(hba);
+	u32 time_left;
+	bool is_ready;
+	int ret;
+	static const struct ufshcd_dme_attr_val rmmi_attrs[] = {
+		{ UIC_ARG_MIB(CBREFCLKCTRL2), CBREFREFCLK_GATE_OVR_EN, DME_LOCAL },
+		{ UIC_ARG_MIB(CBCRCTRL), 1, DME_LOCAL },
+		{ UIC_ARG_MIB(CBC10DIRECTCONF2), 1, DME_LOCAL },
+		{ UIC_ARG_MIB(VS_MPHYCFGUPDT), 1, DME_LOCAL }
+	};
+
+	/* Wait for Tx/Rx config_rdy */
+	time_left = TIMEOUT_MICROSEC;
+	do {
+		time_left--;
+		ret = zynqmp_pm_is_mphy_tx_rx_config_ready(&is_ready);
+		if (ret)
+			return ret;
+
+		if (!is_ready)
+			break;
+
+		usleep_range(1, 5);
+	} while (time_left);
+
+	if (!time_left) {
+		dev_err(hba->dev, "Tx/Rx configuration signal busy.\n");
+		return -ETIMEDOUT;
+	}
+
+	ret = ufshcd_dwc_dme_set_attrs(hba, rmmi_attrs, ARRAY_SIZE(rmmi_attrs));
+	if (ret)
+		return ret;
+
+	ret = reset_control_deassert(host->rstphy);
+	if (ret) {
+		dev_err(hba->dev, "ufsphy reset deassert failed, err = %d\n", ret);
+		return ret;
+	}
+
+	/* Wait for SRAM init done */
+	time_left = TIMEOUT_MICROSEC;
+	do {
+		time_left--;
+		ret = zynqmp_pm_is_sram_init_done(&is_ready);
+		if (ret)
+			return ret;
+
+		if (is_ready)
+			break;
+
+		usleep_range(1, 5);
+	} while (time_left);
+
+	if (!time_left) {
+		dev_err(hba->dev, "SRAM initialization failed.\n");
+		return -ETIMEDOUT;
+	}
+
+	ret = ufs_versal2_setup_phy(hba);
+	if (ret)
+		return ret;
+
+	return ufs_versal2_enable_phy(hba);
+}
+
+static int ufs_versal2_init(struct ufs_hba *hba)
+{
+	struct ufs_versal2_host *host;
+	struct device *dev = hba->dev;
+	struct ufs_clk_info *clki;
+	int ret;
+	u32 cal;
+
+	host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
+	if (!host)
+		return -ENOMEM;
+
+	host->hba = hba;
+	ufshcd_set_variant(hba, host);
+
+	host->phy_mode = UFSHCD_DWC_PHY_MODE_ROM;
+
+	list_for_each_entry(clki, &hba->clk_list_head, list) {
+		if (!strcmp(clki->name, "core"))
+			host->host_clk = clk_get_rate(clki->clk);
+	}
+
+	host->rstc = devm_reset_control_get_exclusive(dev, "ufshc");
+	if (IS_ERR(host->rstc)) {
+		dev_err(dev, "failed to get reset ctrl: ufshc\n");
+		return PTR_ERR(host->rstc);
+	}
+
+	host->rstphy = devm_reset_control_get_exclusive(dev, "ufsphy");
+	if (IS_ERR(host->rstphy)) {
+		dev_err(dev, "failed to get reset ctrl: ufsphy\n");
+		return PTR_ERR(host->rstphy);
+	}
+
+	ret = zynqmp_pm_get_ufs_calibration_values(&cal);
+	if (ret) {
+		dev_err(dev, "failed to read calibration values\n");
+		return ret;
+	}
+
+	host->attcompval0 = (u8)cal;
+	host->attcompval1 = (u8)(cal >> 8);
+	host->ctlecompval0 = (u8)(cal >> 16);
+	host->ctlecompval1 = (u8)(cal >> 24);
+
+	hba->quirks |= UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING;
+
+	return 0;
+}
+
+static int ufs_versal2_hce_enable_notify(struct ufs_hba *hba,
+					 enum ufs_notify_change_status status)
+{
+	struct ufs_versal2_host *host = ufshcd_get_variant(hba);
+	struct device *dev = hba->dev;
+	int ret;
+
+	switch (status) {
+	case PRE_CHANGE:
+		if (host->phy_mode) {
+			dev_err(dev, "Invalid phy-mode %d.\n", host->phy_mode);
+			return -EINVAL;
+		}
+
+		ret = reset_control_assert(host->rstc);
+		if (ret) {
+			dev_err(hba->dev, "ufshc reset assert failed, err = %d\n", ret);
+			return ret;
+		}
+
+		ret = reset_control_assert(host->rstphy);
+		if (ret) {
+			dev_err(hba->dev, "ufsphy reset assert failed, err = %d\n", ret);
+			return ret;
+		}
+
+		ret = zynqmp_pm_set_sram_bypass();
+		if (ret) {
+			dev_err(dev, "Bypass SRAM interface failed, err = %d\n", ret);
+			return ret;
+		}
+
+		ret = reset_control_deassert(host->rstc);
+		if (ret)
+			dev_err(hba->dev, "ufshc reset deassert failed, err = %d\n", ret);
+
+		break;
+	case 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;
+}
+
+static irqreturn_t ufs_versal2_isr(struct ufs_hba *hba, u32 intr_status)
+{
+	u32 mask;
+
+	mask = DWC_UFS_CARD_INSERT_STATUS | DWC_UFS_CARD_REMOVE_STATUS |
+		DWC_UFS_CARD_TOGGLE_STATUS;
+	if (intr_status & mask)
+		return IRQ_HANDLED;
+
+	return IRQ_NONE;
+}
+
+static int ufs_versal2_link_startup_notify(struct ufs_hba *hba,
+					   enum ufs_notify_change_status status)
+{
+	struct ufs_versal2_host *host = ufshcd_get_variant(hba);
+	int ret = 0;
+
+	switch (status) {
+	case PRE_CHANGE:
+		if (host->host_clk)
+			ufshcd_writel(hba, host->host_clk / 1000000, DWC_UFS_REG_HCLKDIV);
+
+		break;
+	case POST_CHANGE:
+		ret = ufshcd_dwc_link_startup_notify(hba, status);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int ufs_versal2_phy_ratesel(struct ufs_hba *hba, u32 activelanes, u32 rx_req)
+{
+	u32 time_left, reg, lane;
+	int ret;
+
+	for (lane = 0; lane < activelanes; lane++) {
+		time_left = TIMEOUT_MICROSEC;
+		ret = ufs_versal2_phy_reg_read(hba, RX_OVRD_IN_1(lane), &reg);
+		if (ret)
+			return ret;
+
+		reg |= MPHY_RX_OVRD_EN;
+		if (rx_req)
+			reg |= MPHY_RX_OVRD_VAL;
+		else
+			reg &= ~MPHY_RX_OVRD_VAL;
+
+		ret = ufs_versal2_phy_reg_write(hba, RX_OVRD_IN_1(lane), reg);
+		if (ret)
+			return ret;
+
+		do {
+			ret = ufs_versal2_phy_reg_read(hba, RX_PCS_OUT(lane), &reg);
+			if (ret)
+				return ret;
+
+			reg &= MPHY_RX_ACK_MASK;
+			if (reg == rx_req)
+				break;
+
+			time_left--;
+			usleep_range(1, 5);
+		} while (time_left);
+
+		if (!time_left) {
+			dev_err(hba->dev, "Invalid Rx Ack value.\n");
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int ufs_versal2_pwr_change_notify(struct ufs_hba *hba, enum ufs_notify_change_status status,
+					 const struct ufs_pa_layer_attr *dev_max_params,
+					 struct ufs_pa_layer_attr *dev_req_params)
+{
+	struct ufs_versal2_host *host = ufshcd_get_variant(hba);
+	u32 lane, reg, rate = 0;
+	int ret = 0;
+
+	if (status == PRE_CHANGE) {
+		memcpy(dev_req_params, dev_max_params, sizeof(struct ufs_pa_layer_attr));
+
+		/* If it is not a calibrated part, switch PWRMODE to SLOW_MODE */
+		if (!host->attcompval0 && !host->attcompval1 && !host->ctlecompval0 &&
+		    !host->ctlecompval1) {
+			dev_req_params->pwr_rx = SLOW_MODE;
+			dev_req_params->pwr_tx = SLOW_MODE;
+			return 0;
+		}
+
+		if (dev_req_params->pwr_rx == SLOW_MODE || dev_req_params->pwr_rx == SLOWAUTO_MODE)
+			return 0;
+
+		if (dev_req_params->hs_rate == PA_HS_MODE_B)
+			rate = 1;
+
+		 /* Select the rate */
+		ret = ufshcd_dme_set(hba, UIC_ARG_MIB(CBRATESEL), rate);
+		if (ret)
+			return ret;
+
+		ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_MPHYCFGUPDT), 1);
+		if (ret)
+			return ret;
+
+		ret = ufs_versal2_phy_ratesel(hba, dev_req_params->lane_tx, 1);
+		if (ret)
+			return ret;
+
+		ret = ufs_versal2_phy_ratesel(hba, dev_req_params->lane_tx, 0);
+		if (ret)
+			return ret;
+
+		/* Remove rx_req override */
+		for (lane = 0; lane < dev_req_params->lane_tx; lane++) {
+			ret = ufs_versal2_phy_reg_read(hba, RX_OVRD_IN_1(lane), &reg);
+			if (ret)
+				return ret;
+
+			reg &= ~MPHY_RX_OVRD_EN;
+			ret = ufs_versal2_phy_reg_write(hba, RX_OVRD_IN_1(lane), reg);
+			if (ret)
+				return ret;
+		}
+
+		if (dev_req_params->lane_tx == UFS_LANE_2 && dev_req_params->lane_rx == UFS_LANE_2)
+			ret = ufshcd_dme_configure_adapt(hba, dev_req_params->gear_tx,
+							 PA_INITIAL_ADAPT);
+	}
+
+	return ret;
+}
+
+static struct ufs_hba_variant_ops ufs_versal2_hba_vops = {
+	.name			= "ufs-versal2-pltfm",
+	.init			= ufs_versal2_init,
+	.link_startup_notify	= ufs_versal2_link_startup_notify,
+	.hce_enable_notify	= ufs_versal2_hce_enable_notify,
+	.isr			= ufs_versal2_isr,
+	.pwr_change_notify	= ufs_versal2_pwr_change_notify,
+};
+
+static const struct of_device_id ufs_versal2_pltfm_match[] = {
+	{
+		.compatible = "amd,versal2-ufs",
+		.data = &ufs_versal2_hba_vops,
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ufs_versal2_pltfm_match);
+
+static int ufs_versal2_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	/* Perform generic probe */
+	ret = ufshcd_pltfrm_init(pdev, &ufs_versal2_hba_vops);
+	if (ret)
+		dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", ret);
+
+	return ret;
+}
+
+static void ufs_versal2_remove(struct platform_device *pdev)
+{
+	struct ufs_hba *hba = platform_get_drvdata(pdev);
+
+	pm_runtime_get_sync(&(pdev)->dev);
+	ufshcd_remove(hba);
+}
+
+static const struct dev_pm_ops ufs_versal2_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
+	SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
+};
+
+static struct platform_driver ufs_versal2_pltfm = {
+	.probe		= ufs_versal2_probe,
+	.remove		= ufs_versal2_remove,
+	.driver		= {
+		.name	= "ufshcd-versal2",
+		.pm	= &ufs_versal2_pm_ops,
+		.of_match_table	= of_match_ptr(ufs_versal2_pltfm_match),
+	},
+};
+
+module_platform_driver(ufs_versal2_pltfm);
+
+MODULE_AUTHOR("Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>");
+MODULE_DESCRIPTION("AMD Versal Gen 2 UFS Host Controller driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/ufs/host/ufshcd-dwc.h b/drivers/ufs/host/ufshcd-dwc.h
index ad91ea5..379f3cf 100644
--- a/drivers/ufs/host/ufshcd-dwc.h
+++ b/drivers/ufs/host/ufshcd-dwc.h
@@ -12,6 +12,55 @@
 
 #include <ufs/ufshcd.h>
 
+/* PHY modes */
+#define UFSHCD_DWC_PHY_MODE_ROM         0
+
+/* RMMI Attributes */
+#define CBREFCLKCTRL2		0x8132
+#define CBCRCTRL		0x811F
+#define CBC10DIRECTCONF2	0x810E
+#define CBRATESEL		0x8114
+#define CBCREGADDRLSB		0x8116
+#define CBCREGADDRMSB		0x8117
+#define CBCREGWRLSB		0x8118
+#define CBCREGWRMSB		0x8119
+#define CBCREGRDLSB		0x811A
+#define CBCREGRDMSB		0x811B
+#define CBCREGRDWRSEL		0x811C
+
+#define CBREFREFCLK_GATE_OVR_EN		BIT(7)
+
+/* M-PHY Attributes */
+#define MTX_FSM_STATE		0x41
+#define MRX_FSM_STATE		0xC1
+
+/* M-PHY registers */
+#define RX_OVRD_IN_1(n)		(0x3006 + ((n) * 0x100))
+#define RX_PCS_OUT(n)		(0x300F + ((n) * 0x100))
+#define FAST_FLAGS(n)		(0x401C + ((n) * 0x100))
+#define RX_AFE_ATT_IDAC(n)	(0x4000 + ((n) * 0x100))
+#define RX_AFE_CTLE_IDAC(n)	(0x4001 + ((n) * 0x100))
+#define FW_CALIB_CCFG(n)	(0x404D + ((n) * 0x100))
+
+/* Tx/Rx FSM state */
+enum rx_fsm_state {
+	RX_STATE_DISABLED = 0,
+	RX_STATE_HIBERN8 = 1,
+	RX_STATE_SLEEP = 2,
+	RX_STATE_STALL = 3,
+	RX_STATE_LSBURST = 4,
+	RX_STATE_HSBURST = 5,
+};
+
+enum tx_fsm_state {
+	TX_STATE_DISABLED = 0,
+	TX_STATE_HIBERN8 = 1,
+	TX_STATE_SLEEP = 2,
+	TX_STATE_STALL = 3,
+	TX_STATE_LSBURST = 4,
+	TX_STATE_HSBURST = 5,
+};
+
 struct ufshcd_dme_attr_val {
 	u32 attr_sel;
 	u32 mib_val;
diff --git a/drivers/ufs/host/ufshci-dwc.h b/drivers/ufs/host/ufshci-dwc.h
index 6c290e2..96b1a61 100644
--- a/drivers/ufs/host/ufshci-dwc.h
+++ b/drivers/ufs/host/ufshci-dwc.h
@@ -15,6 +15,11 @@ enum dwc_specific_registers {
 	DWC_UFS_REG_HCLKDIV	= 0xFC,
 };
 
+/* DWC HC specific interrupt mask */
+#define DWC_UFS_CARD_INSERT_STATUS	BIT(29)
+#define DWC_UFS_CARD_REMOVE_STATUS	BIT(30)
+#define DWC_UFS_CARD_TOGGLE_STATUS	BIT(31)
+
 /* Clock Divider Values: Hex equivalent of frequency in MHz */
 enum clk_div_values {
 	DWC_UFS_REG_HCLKDIV_DIV_62_5	= 0x3e,
diff --git a/include/ufs/unipro.h b/include/ufs/unipro.h
index 360e124..faf1c47 100644
--- a/include/ufs/unipro.h
+++ b/include/ufs/unipro.h
@@ -174,6 +174,7 @@
 #define VS_POWERSTATE		0xD083
 #define VS_MPHYCFGUPDT		0xD085
 #define VS_DEBUGOMC		0xD09E
+#define VS_MPHYDISABLE		0xD0C1
 
 #define PA_GRANULARITY_MIN_VAL	1
 #define PA_GRANULARITY_MAX_VAL	6
-- 
1.8.3.1


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

* Re: [PATCH 4/5] ufs: core: Add vendor specific ops to handle interrupts
  2025-09-19 12:38 ` [PATCH 4/5] ufs: core: Add vendor specific ops to handle interrupts Ajay Neeli
@ 2025-09-19 17:34   ` Bart Van Assche
  2025-10-06 12:30     ` Neeli, Ajay
  0 siblings, 1 reply; 12+ messages in thread
From: Bart Van Assche @ 2025-09-19 17:34 UTC (permalink / raw)
  To: Ajay Neeli, martin.petersen, James.Bottomley, robh, krzk+dt,
	conor+dt, pedrom.sousa
  Cc: alim.akhtar, avri.altman, linux-scsi, devicetree, git,
	michal.simek, srinivas.goud, radhey.shyam.pandey,
	Sai Krishna Potthuri

On 9/19/25 5:38 AM, Ajay Neeli wrote:
> Some vendors will define their own interrupts, current interrupt service
> routine handles only interrupts defined by the JEDEC standard.
> Add provision to handle vendor specific interrupts by defining vendor
> specific vops.

Yikes. Please comply to the standard or contribute to the standard
instead of using reserved interrupt status bits for vendor-specific
purposes.

> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
> index 5442bb8..7a6dde8 100644
> --- a/drivers/ufs/core/ufshcd.c
> +++ b/drivers/ufs/core/ufshcd.c
> @@ -7069,6 +7069,9 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
>   	if (intr_status & MCQ_CQ_EVENT_STATUS)
>   		retval |= ufshcd_handle_mcq_cq_events(hba);
>   
> +	if (intr_status & UFSHCD_VENDOR_IS_MASK)
> +		retval |= ufshcd_vops_isr(hba, intr_status);
> +
>   	return retval;
>   }

[ ... ]

> diff --git a/include/ufs/ufshci.h b/include/ufs/ufshci.h
> index 612500a..2844772 100644
> --- a/include/ufs/ufshci.h
> +++ b/include/ufs/ufshci.h
> @@ -185,6 +185,9 @@ static inline u32 ufshci_version(u32 major, u32 minor)
>   #define CRYPTO_ENGINE_FATAL_ERROR		0x40000
>   #define MCQ_CQ_EVENT_STATUS			0x100000
>   
> +/* Other than above mentioned bits are treated as Vendor specific status bits */
> +#define UFSHCD_VENDOR_IS_MASK			0xFFE8F000

That's a violation of the UFSHCI standard. In the UFSHCI standard bits
31:22 and 15:13 are marked as reserved and hence must not be marked as
"vendor specific". Please either drop this patch or remove the
UFSHCD_VENDOR_IS_MASK definition from this patch and remove the
"if (intr_status & UFSHCD_VENDOR_IS_MASK)" condition from the interrupt
handler.

Bart.

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

* Re: [PATCH 5/5] ufs: amd-versal2: Add AMD Versal Gen 2 UFS support
  2025-09-19 12:38 ` [PATCH 5/5] ufs: amd-versal2: Add AMD Versal Gen 2 UFS support Ajay Neeli
@ 2025-09-19 17:44   ` Bart Van Assche
  2025-10-06 12:45     ` Neeli, Ajay
  0 siblings, 1 reply; 12+ messages in thread
From: Bart Van Assche @ 2025-09-19 17:44 UTC (permalink / raw)
  To: Ajay Neeli, martin.petersen, James.Bottomley, robh, krzk+dt,
	conor+dt, pedrom.sousa
  Cc: alim.akhtar, avri.altman, linux-scsi, devicetree, git,
	michal.simek, srinivas.goud, radhey.shyam.pandey,
	Sai Krishna Potthuri

On 9/19/25 5:38 AM, Ajay Neeli wrote:
> +#include "ufshcd-dwc.h"
> +#include "ufshcd-pltfrm.h"
> +#include "ufshci-dwc.h"

The *-dwc.h header files are for Synopsys Designware UFS host
controllers only and hence should not be included in the implementation
of the AMD Versal UFS host controller.

> diff --git a/drivers/ufs/host/ufshcd-dwc.h b/drivers/ufs/host/ufshcd-dwc.h
> index ad91ea5..379f3cf 100644
> --- a/drivers/ufs/host/ufshcd-dwc.h
> +++ b/drivers/ufs/host/ufshcd-dwc.h
> @@ -12,6 +12,55 @@
>   
>   #include <ufs/ufshcd.h>
>   
> +/* PHY modes */
> +#define UFSHCD_DWC_PHY_MODE_ROM         0

Please do not modify header files from other controller vendors.

Thanks,

Bart.

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

* Re: [PATCH 1/5] dt-bindings: ufs: amd-versal2: Add support for AMD Versal Gen 2 UFS Host Controller
  2025-09-19 12:38 ` [PATCH 1/5] dt-bindings: ufs: amd-versal2: Add support for AMD Versal Gen 2 UFS Host Controller Ajay Neeli
@ 2025-09-22 19:46   ` Rob Herring
  2025-10-06 12:30     ` Neeli, Ajay
  0 siblings, 1 reply; 12+ messages in thread
From: Rob Herring @ 2025-09-22 19:46 UTC (permalink / raw)
  To: Ajay Neeli
  Cc: martin.petersen, James.Bottomley, krzk+dt, conor+dt, pedrom.sousa,
	alim.akhtar, avri.altman, bvanassche, linux-scsi, devicetree, git,
	michal.simek, srinivas.goud, radhey.shyam.pandey,
	Sai Krishna Potthuri

On Fri, Sep 19, 2025 at 06:08:31PM +0530, Ajay Neeli wrote:
> From: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
> 
> Add devicetree document for AMD Versal Gen 2 UFS Host Controller.
> This includes clocks and clock-names as mandated by UFS common bindings.
> 
> Signed-off-by: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
> Co-developed-by: Ajay Neeli <ajay.neeli@amd.com>
> Signed-off-by: Ajay Neeli <ajay.neeli@amd.com>
> ---
>  .../devicetree/bindings/ufs/amd,versal2-ufs.yaml   | 61 ++++++++++++++++++++++
>  1 file changed, 61 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml
> 
> diff --git a/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml b/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml
> new file mode 100644
> index 0000000..9f55949
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml
> @@ -0,0 +1,61 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/ufs/amd,versal2-ufs.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: AMD Versal Gen 2 UFS Host Controller
> +
> +maintainers:
> +  - Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
> +
> +allOf:
> +  - $ref: ufs-common.yaml
> +
> +properties:
> +  compatible:
> +    const: amd,versal2-ufs

2 is versal2 or gen 2? I read it as the former, but everything else in 
this patchset says the latter. compatibles should be based on SoC names, 
not versions. Or does "gen 2" mean Gen 2 UFS specification (if there is 
such a thing)?

> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  clock-names:
> +    items:
> +      - const: core
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  resets:
> +    maxItems: 2
> +
> +  reset-names:
> +    items:
> +      - const: ufshc
> +      - const: ufsphy

"ufs" part is redundant. Drop.

> +
> +required:
> +  - reg
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    ufs@f10b0000 {
> +        compatible = "amd,versal2-ufs";
> +        reg = <0xf10b0000 0x1000>;
> +        clocks = <&ufs_core_clk>;
> +        clock-names = "core";
> +        resets = <&scmi_reset 4>, <&scmi_reset 35>;
> +        reset-names = "ufshc", "ufsphy";
> +        interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
> +        freq-table-hz = <0 0>;
> +    };
> -- 
> 1.8.3.1
> 

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

* RE: [PATCH 1/5] dt-bindings: ufs: amd-versal2: Add support for AMD Versal Gen 2 UFS Host Controller
  2025-09-22 19:46   ` Rob Herring
@ 2025-10-06 12:30     ` Neeli, Ajay
  0 siblings, 0 replies; 12+ messages in thread
From: Neeli, Ajay @ 2025-10-06 12:30 UTC (permalink / raw)
  To: Rob Herring
  Cc: martin.petersen@oracle.com, James.Bottomley@hansenpartnership.com,
	krzk+dt@kernel.org, conor+dt@kernel.org,
	pedrom.sousa@synopsys.com, alim.akhtar@samsung.com,
	avri.altman@wdc.com, bvanassche@acm.org,
	linux-scsi@vger.kernel.org, devicetree@vger.kernel.org,
	git (AMD-Xilinx), Simek, Michal, Goud, Srinivas,
	Pandey, Radhey Shyam, Potthuri, Sai Krishna

[Public]

> -----Original Message-----
> From: Rob Herring <robh@kernel.org>
> Sent: Tuesday, September 23, 2025 1:16 AM
> To: Neeli, Ajay <Ajay.Neeli@amd.com>
> Cc: martin.petersen@oracle.com; James.Bottomley@hansenpartnership.com; krzk+dt@kernel.org; conor+dt@kernel.org;
> pedrom.sousa@synopsys.com; alim.akhtar@samsung.com; avri.altman@wdc.com; bvanassche@acm.org; linux-
> scsi@vger.kernel.org; devicetree@vger.kernel.org; git (AMD-Xilinx) <git@amd.com>; Simek, Michal
> <michal.simek@amd.com>; Goud, Srinivas <srinivas.goud@amd.com>; Pandey, Radhey Shyam
> <radhey.shyam.pandey@amd.com>; Potthuri, Sai Krishna <sai.krishna.potthuri@amd.com>
> Subject: Re: [PATCH 1/5] dt-bindings: ufs: amd-versal2: Add support for AMD Versal Gen 2 UFS Host Controller
>
> Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or
> responding.
>
>
> On Fri, Sep 19, 2025 at 06:08:31PM +0530, Ajay Neeli wrote:
> > From: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
> >
> > Add devicetree document for AMD Versal Gen 2 UFS Host Controller.
> > This includes clocks and clock-names as mandated by UFS common bindings.
> >
> > Signed-off-by: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
> > Co-developed-by: Ajay Neeli <ajay.neeli@amd.com>
> > Signed-off-by: Ajay Neeli <ajay.neeli@amd.com>
> > ---
> >  .../devicetree/bindings/ufs/amd,versal2-ufs.yaml   | 61 ++++++++++++++++++++++
> >  1 file changed, 61 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml
> b/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml
> > new file mode 100644
> > index 0000000..9f55949
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml
> > @@ -0,0 +1,61 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/ufs/amd,versal2-ufs.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: AMD Versal Gen 2 UFS Host Controller
> > +
> > +maintainers:
> > +  - Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
> > +
> > +allOf:
> > +  - $ref: ufs-common.yaml
> > +
> > +properties:
> > +  compatible:
> > +    const: amd,versal2-ufs
>
> 2 is versal2 or gen 2? I read it as the former, but everything else in
> this patchset says the latter. compatibles should be based on SoC names,
> not versions. Or does "gen 2" mean Gen 2 UFS specification (if there is
> such a thing)?

Both "versal2" and "AMD Versal Gen 2" refer to the AMD Versal SoC generation, not the UFS specification.
As per AMD team guidelines, we use "versal2" for short names and in compatibility strings,
while "AMD Versal Gen 2" is used in commit messages and documentation

We will maintain the compatibility name as amd,versal2-ufs but add documentation to specify
that "versal2" refers to the AMD Versal SoC generation, not the UFS specification.

>
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    maxItems: 1
> > +
> > +  clock-names:
> > +    items:
> > +      - const: core
> > +
> > +  power-domains:
> > +    maxItems: 1
> > +
> > +  resets:
> > +    maxItems: 2
> > +
> > +  reset-names:
> > +    items:
> > +      - const: ufshc
> > +      - const: ufsphy
>
> "ufs" part is redundant. Drop.

Sure, will drop

>
> > +
> > +required:
> > +  - reg
> > +  - clocks
> > +  - clock-names
> > +  - resets
> > +  - reset-names
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    ufs@f10b0000 {
> > +        compatible = "amd,versal2-ufs";
> > +        reg = <0xf10b0000 0x1000>;
> > +        clocks = <&ufs_core_clk>;
> > +        clock-names = "core";
> > +        resets = <&scmi_reset 4>, <&scmi_reset 35>;
> > +        reset-names = "ufshc", "ufsphy";
> > +        interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
> > +        freq-table-hz = <0 0>;
> > +    };
> > --
> > 1.8.3.1
> >

Regards,
Ajay

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

* RE: [PATCH 4/5] ufs: core: Add vendor specific ops to handle interrupts
  2025-09-19 17:34   ` Bart Van Assche
@ 2025-10-06 12:30     ` Neeli, Ajay
  0 siblings, 0 replies; 12+ messages in thread
From: Neeli, Ajay @ 2025-10-06 12:30 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: alim.akhtar@samsung.com, avri.altman@wdc.com,
	linux-scsi@vger.kernel.org, devicetree@vger.kernel.org,
	git (AMD-Xilinx), Simek, Michal, Goud, Srinivas,
	Pandey, Radhey Shyam, Potthuri, Sai Krishna,
	martin.petersen@oracle.com, James.Bottomley@HansenPartnership.com,
	robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
	pedrom.sousa@synopsys.com

[Public]

> -----Original Message-----
> From: Bart Van Assche <bvanassche@acm.org>
> Sent: Friday, September 19, 2025 11:05 PM
> To: Neeli, Ajay <Ajay.Neeli@amd.com>; martin.petersen@oracle.com; James.Bottomley@HansenPartnership.com;
> robh@kernel.org; krzk+dt@kernel.org; conor+dt@kernel.org; pedrom.sousa@synopsys.com
> Cc: alim.akhtar@samsung.com; avri.altman@wdc.com; linux-scsi@vger.kernel.org; devicetree@vger.kernel.org; git (AMD-
> Xilinx) <git@amd.com>; Simek, Michal <michal.simek@amd.com>; Goud, Srinivas <srinivas.goud@amd.com>; Pandey,
> Radhey Shyam <radhey.shyam.pandey@amd.com>; Potthuri, Sai Krishna <sai.krishna.potthuri@amd.com>
> Subject: Re: [PATCH 4/5] ufs: core: Add vendor specific ops to handle interrupts
>
> Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or
> responding.
>
>
> On 9/19/25 5:38 AM, Ajay Neeli wrote:
> > Some vendors will define their own interrupts, current interrupt service
> > routine handles only interrupts defined by the JEDEC standard.
> > Add provision to handle vendor specific interrupts by defining vendor
> > specific vops.
>
> Yikes. Please comply to the standard or contribute to the standard
> instead of using reserved interrupt status bits for vendor-specific
> purposes.
>
> > diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
> > index 5442bb8..7a6dde8 100644
> > --- a/drivers/ufs/core/ufshcd.c
> > +++ b/drivers/ufs/core/ufshcd.c
> > @@ -7069,6 +7069,9 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
> >       if (intr_status & MCQ_CQ_EVENT_STATUS)
> >               retval |= ufshcd_handle_mcq_cq_events(hba);
> >
> > +     if (intr_status & UFSHCD_VENDOR_IS_MASK)
> > +             retval |= ufshcd_vops_isr(hba, intr_status);
> > +
> >       return retval;
> >   }
>
> [ ... ]
>
> > diff --git a/include/ufs/ufshci.h b/include/ufs/ufshci.h
> > index 612500a..2844772 100644
> > --- a/include/ufs/ufshci.h
> > +++ b/include/ufs/ufshci.h
> > @@ -185,6 +185,9 @@ static inline u32 ufshci_version(u32 major, u32 minor)
> >   #define CRYPTO_ENGINE_FATAL_ERROR           0x40000
> >   #define MCQ_CQ_EVENT_STATUS                 0x100000
> >
> > +/* Other than above mentioned bits are treated as Vendor specific status bits */
> > +#define UFSHCD_VENDOR_IS_MASK                        0xFFE8F000
>
> That's a violation of the UFSHCI standard. In the UFSHCI standard bits
> 31:22 and 15:13 are marked as reserved and hence must not be marked as
> "vendor specific". Please either drop this patch or remove the
> UFSHCD_VENDOR_IS_MASK definition from this patch and remove the
> "if (intr_status & UFSHCD_VENDOR_IS_MASK)" condition from the interrupt
> handler.
>
> Bart.

Sure, will drop the patch and avoid using reserved interrupt status bits for vendor-specific purposes

Regards,
Ajay.

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

* RE: [PATCH 5/5] ufs: amd-versal2: Add AMD Versal Gen 2 UFS support
  2025-09-19 17:44   ` Bart Van Assche
@ 2025-10-06 12:45     ` Neeli, Ajay
  0 siblings, 0 replies; 12+ messages in thread
From: Neeli, Ajay @ 2025-10-06 12:45 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: alim.akhtar@samsung.com, avri.altman@wdc.com,
	linux-scsi@vger.kernel.org, devicetree@vger.kernel.org,
	git (AMD-Xilinx), Simek, Michal, Goud, Srinivas,
	Pandey, Radhey Shyam, Potthuri, Sai Krishna, krzk+dt@kernel.org,
	martin.petersen@oracle.com, pedrom.sousa@synopsys.com,
	James.Bottomley@HansenPartnership.com, robh@kernel.org,
	conor+dt@kernel.org

[Public]

> -----Original Message-----
> From: Bart Van Assche <bvanassche@acm.org>
> Sent: Friday, September 19, 2025 11:15 PM
> To: Neeli, Ajay <Ajay.Neeli@amd.com>; martin.petersen@oracle.com; James.Bottomley@HansenPartnership.com;
> robh@kernel.org; krzk+dt@kernel.org; conor+dt@kernel.org; pedrom.sousa@synopsys.com
> Cc: alim.akhtar@samsung.com; avri.altman@wdc.com; linux-scsi@vger.kernel.org; devicetree@vger.kernel.org; git (AMD-
> Xilinx) <git@amd.com>; Simek, Michal <michal.simek@amd.com>; Goud, Srinivas <srinivas.goud@amd.com>; Pandey,
> Radhey Shyam <radhey.shyam.pandey@amd.com>; Potthuri, Sai Krishna <sai.krishna.potthuri@amd.com>
> Subject: Re: [PATCH 5/5] ufs: amd-versal2: Add AMD Versal Gen 2 UFS support
>
> Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or
> responding.
>
>
> On 9/19/25 5:38 AM, Ajay Neeli wrote:
> > +#include "ufshcd-dwc.h"
> > +#include "ufshcd-pltfrm.h"
> > +#include "ufshci-dwc.h"
>
> The *-dwc.h header files are for Synopsys Designware UFS host
> controllers only and hence should not be included in the implementation
> of the AMD Versal UFS host controller.

AMD Versal Gen2 UFS Host controller is built on top of DWC Synopsys UFS host controller,
which is why included those header files in the implementation.

>
> > diff --git a/drivers/ufs/host/ufshcd-dwc.h b/drivers/ufs/host/ufshcd-dwc.h
> > index ad91ea5..379f3cf 100644
> > --- a/drivers/ufs/host/ufshcd-dwc.h
> > +++ b/drivers/ufs/host/ufshcd-dwc.h
> > @@ -12,6 +12,55 @@
> >
> >   #include <ufs/ufshcd.h>
> >
> > +/* PHY modes */
> > +#define UFSHCD_DWC_PHY_MODE_ROM         0
>
> Please do not modify header files from other controller vendors.

Sure, will add the macro to the driver source file instead

Regards,
Ajay.



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

end of thread, other threads:[~2025-10-06 12:45 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-19 12:38 [PATCH 0/5] ufs: Add support for AMD Versal Gen2 UFS Ajay Neeli
2025-09-19 12:38 ` [PATCH 1/5] dt-bindings: ufs: amd-versal2: Add support for AMD Versal Gen 2 UFS Host Controller Ajay Neeli
2025-09-22 19:46   ` Rob Herring
2025-10-06 12:30     ` Neeli, Ajay
2025-09-19 12:38 ` [PATCH 2/5] firmware: xilinx: Add support for secure read/write ioctl interface Ajay Neeli
2025-09-19 12:38 ` [PATCH 3/5] firmware: xilinx: Add APIs for UFS PHY initialization Ajay Neeli
2025-09-19 12:38 ` [PATCH 4/5] ufs: core: Add vendor specific ops to handle interrupts Ajay Neeli
2025-09-19 17:34   ` Bart Van Assche
2025-10-06 12:30     ` Neeli, Ajay
2025-09-19 12:38 ` [PATCH 5/5] ufs: amd-versal2: Add AMD Versal Gen 2 UFS support Ajay Neeli
2025-09-19 17:44   ` Bart Van Assche
2025-10-06 12:45     ` Neeli, Ajay

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).