[PATCH v2 3/4] usb: dwc3: xilinx: Add Versal2 MMI USB 3.2 controller support

Radhey Shyam Pandey posted 4 patches 1 day, 14 hours ago
[PATCH v2 3/4] usb: dwc3: xilinx: Add Versal2 MMI USB 3.2 controller support
Posted by Radhey Shyam Pandey 1 day, 14 hours ago
Multi-media integrated (MMI) USB3.2 DRD IP is usb3.1 gen2 controller
which support following speed SSP (10-Gbps), SuperSpeed(5-Gbps),
high-speed(480-Mbps), full-speed(12-Mbps), and low-speed(1.5-Mbps)
operation modes.

USB2 and USB3 PHY support Physical connectivity via the Type-C
connectivity. The MMI USB controller does not have a dedicated wrapper
register space, so ioremap is skipped via the map_resource config flag.

The driver handles clock and reset initialization. In this initial
version typec reversibility is not implemented and it is assumed that
USB3 PHY TCA mux programming is done by MMI configuration data object
(CDOs) and TI PD controller is configured using external tiva programmer
on VEK385 evaluation board.

Tested host mode with mass storage device.

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
---
- Introduce xlnx,usb-syscon phandle to access UDH address space
  which is wrapper subsystem IP for USB, DP and HDCP.
- Split config struct refactoring into separate patch (2/4).
- Remove unused regmap/syscon fields and parsing code; defer to
  patch that first consumes them.
- Fix error message capitalization to lowercase ("reset", "deassert").
---
 drivers/usb/dwc3/dwc3-xilinx.c | 50 ++++++++++++++++++++++++++++++----
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
index bb59b56726e7..f2dee28bdc65 100644
--- a/drivers/usb/dwc3/dwc3-xilinx.c
+++ b/drivers/usb/dwc3/dwc3-xilinx.c
@@ -46,6 +46,7 @@ struct dwc3_xlnx;
 
 struct dwc3_xlnx_config {
 	int				(*pltfm_init)(struct dwc3_xlnx *data);
+	bool				map_resource;
 };
 
 struct dwc3_xlnx {
@@ -93,6 +94,29 @@ static void dwc3_xlnx_set_coherency(struct dwc3_xlnx *priv_data, u32 coherency_o
 	}
 }
 
+static int dwc3_xlnx_init_versal2(struct dwc3_xlnx *priv_data)
+{
+	struct device		*dev = priv_data->dev;
+	struct reset_control	*crst;
+	int			ret;
+
+	crst = devm_reset_control_get_optional_exclusive(dev, NULL);
+	if (IS_ERR(crst))
+		return dev_err_probe(dev, PTR_ERR(crst),
+				     "failed to get reset signal\n");
+
+	/* assert and deassert reset */
+	ret = reset_control_assert(crst);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "failed to assert reset\n");
+
+	ret = reset_control_deassert(crst);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "failed to deassert reset\n");
+
+	return 0;
+}
+
 static int dwc3_xlnx_init_versal(struct dwc3_xlnx *priv_data)
 {
 	struct device		*dev = priv_data->dev;
@@ -250,10 +274,16 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
 
 static const struct dwc3_xlnx_config zynqmp_config = {
 	.pltfm_init = dwc3_xlnx_init_zynqmp,
+	.map_resource = true,
 };
 
 static const struct dwc3_xlnx_config versal_config = {
 	.pltfm_init = dwc3_xlnx_init_versal,
+	.map_resource = true,
+};
+
+static const struct dwc3_xlnx_config versal2_config = {
+	.pltfm_init = dwc3_xlnx_init_versal2,
 };
 
 static const struct of_device_id dwc3_xlnx_of_match[] = {
@@ -265,6 +295,10 @@ static const struct of_device_id dwc3_xlnx_of_match[] = {
 		.compatible = "xlnx,versal-dwc3",
 		.data = &versal_config,
 	},
+	{
+		.compatible = "xlnx,versal2-mmi-dwc3",
+		.data = &versal2_config,
+	},
 	{ /* Sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, dwc3_xlnx_of_match);
@@ -299,19 +333,23 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
 	struct dwc3_xlnx		*priv_data;
 	struct device			*dev = &pdev->dev;
 	struct device_node		*np = dev->of_node;
-	void __iomem			*regs;
 	int				ret;
 
 	priv_data = devm_kzalloc(dev, sizeof(*priv_data), GFP_KERNEL);
 	if (!priv_data)
 		return -ENOMEM;
 
-	regs = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(regs))
-		return dev_err_probe(dev, PTR_ERR(regs), "failed to map registers\n");
-
 	priv_data->dwc3_config = device_get_match_data(dev);
-	priv_data->regs = regs;
+
+	if (priv_data->dwc3_config->map_resource) {
+		void __iomem *regs;
+
+		regs = devm_platform_ioremap_resource(pdev, 0);
+		if (IS_ERR(regs))
+			return dev_err_probe(dev, PTR_ERR(regs),
+					     "failed to map registers\n");
+		priv_data->regs = regs;
+	}
 	priv_data->dev = dev;
 
 	platform_set_drvdata(pdev, priv_data);
-- 
2.43.0