mirror of https://lore.kernel.org/linux-amlogic/
 help / color / mirror / Atom feed
* [PATCH u-boot 0/3] Add USB Support for Amlogic Meson GXL SoCs
@ 2018-03-29 13:42 Neil Armstrong
  2018-03-29 13:42 ` [PATCH u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration Neil Armstrong
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Neil Armstrong @ 2018-03-29 13:42 UTC (permalink / raw)
  To: linus-amlogic

This patchset adds support for USB for the Amlogic Meson GXL SoCs following
the work done for Linux by Martin Blumenstingl at [1] [2] [3].

The support consist of :
 - A port of dwc3-of-simple from Linux to U-boot
 - A change to support more than 2 PHYs in the DWC3 DM driver
 - An USB2 PHY Driver and an USB3 PHY Driver

The DWC3 Controller has up to 4 PHYs connected :
 - 2 USB2 PHYs and an USB3 PHY for GXL SoCs
 - 3 USB2 PHYs and an USB3 PHY for the GXM SoC Variant
This is enabled by the "usb: host: dwc3: Add support for multiple PHYs" patch.
This patch is based on the "xhci-dwc3: Couple of fixes for USB3 support"
serie from Vignesh R, on the u-boot-usb tree.

The DWC3 Controller glue is generic enough to use the dwc3-of-simple from Linux
and can be easily ported to U-Boot as a Simple-Bus with Glue-Specific clocks
and Reset lines setup.

The USB PHY driver supports the standard generic PHY interface and supports
the power-on/off calls and set the Host mode by default.
They are based on the excellent work from Martin Blumenstingl merged in linux.

[1] https://lkml.kernel.org/r/20180303184700.21480-1-martin.blumenstingl at googlemail.com
[2] https://lkml.kernel.org/r/20180128202245.25021-1-martin.blumenstingl at googlemail.com
[3] https://lkml.kernel.org/r/20180303214309.25643-1-martin.blumenstingl at googlemail.com

Neil Armstrong (3):
  usb: host: Add simple of glue driver for DWC3 USB Controllers
    integration
  usb: host: dwc3: Add support for multiple PHYs
  phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers

 drivers/phy/Kconfig          |   8 ++
 drivers/phy/Makefile         |   1 +
 drivers/phy/meson-gxl-usb2.c | 238 +++++++++++++++++++++++++++++++++++++++++++
 drivers/phy/meson-gxl-usb3.c | 201 ++++++++++++++++++++++++++++++++++++
 4 files changed, 448 insertions(+)
 create mode 100644 drivers/phy/meson-gxl-usb2.c
 create mode 100644 drivers/phy/meson-gxl-usb3.c

-- 
2.7.4

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

* [PATCH u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
  2018-03-29 13:42 [PATCH u-boot 0/3] Add USB Support for Amlogic Meson GXL SoCs Neil Armstrong
@ 2018-03-29 13:42 ` Neil Armstrong
  2018-03-29 13:52   ` Marek Vasut
  2018-03-29 13:42 ` [PATCH u-boot 2/3] usb: host: dwc3: Add support for multiple PHYs Neil Armstrong
  2018-03-29 13:42 ` [PATCH u-boot 3/3] phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers Neil Armstrong
  2 siblings, 1 reply; 13+ messages in thread
From: Neil Armstrong @ 2018-03-29 13:42 UTC (permalink / raw)
  To: linus-amlogic

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/usb/host/Kconfig          |   7 ++
 drivers/usb/host/Makefile         |   1 +
 drivers/usb/host/dwc3-of-simple.c | 187 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 195 insertions(+)
 create mode 100644 drivers/usb/host/dwc3-of-simple.c

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index a7249b7..6caa615 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -21,6 +21,13 @@ config USB_XHCI_DWC3
 	  Say Y or if your system has a Dual Role SuperSpeed
 	  USB controller based on the DesignWare USB3 IP Core.
 
+config USB_XHCI_DWC3_OF_SIMPLE
+	bool "DesignWare USB3 DRD Generic OF Simple Glue Layer"
+	select MISC
+	help
+	  Support USB2/3 functionality in simple SoC integrations with
+	  USB controller based on the DesignWare USB3 IP Core.
+
 config USB_XHCI_MVEBU
 	bool "MVEBU USB 3.0 support"
 	default y
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 9819489..abe4f90 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
 # xhci
 obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
 obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
+obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o
 obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
 obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o
 obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
diff --git a/drivers/usb/host/dwc3-of-simple.c b/drivers/usb/host/dwc3-of-simple.c
new file mode 100644
index 0000000..826a996
--- /dev/null
+++ b/drivers/usb/host/dwc3-of-simple.c
@@ -0,0 +1,187 @@
+/*
+ * dwc3-of-simple.c - OF glue layer for simple integrations
+ *
+ * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Felipe Balbi <balbi@ti.com>
+ *
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstron@baylibre.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <reset.h>
+#include <clk.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct dwc3_of_simple {
+#if CONFIG_IS_ENABLED(CLK)
+	struct clk		*clks;
+	int			num_clocks;
+#endif
+#if CONFIG_IS_ENABLED(DM_RESET)
+	struct reset_ctl	*resets;
+	int			num_resets;
+#endif
+};
+
+#if CONFIG_IS_ENABLED(DM_RESET)
+static int dwc3_of_simple_reset_init(struct udevice *dev,
+				     struct dwc3_of_simple *simple,
+				     int count)
+{
+	int i, ret, err;
+
+	if (!count)
+		return 0;
+
+	simple->resets = devm_kcalloc(dev, count, sizeof(struct reset_ctl),
+				      GFP_KERNEL);
+	if (!simple->resets)
+		return -ENOMEM;
+
+	for (i = 0; i < count; i++) {
+		ret = reset_get_by_index(dev, i, &simple->resets[i]);
+		if (ret < 0)
+			break;
+
+		ret = reset_request(&simple->resets[i]);
+		if (ret) {
+			pr_err("failed to request reset line %d\n", i);
+			reset_free(&simple->resets[i]);
+			goto reset_err;
+		}
+
+		
+		++simple->num_resets;
+	}
+
+	for (i = 0; i < simple->num_resets; i++) {
+		ret = reset_deassert(&simple->resets[i]);
+		if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
+			pr_err("failed to deassert reset line %d\n", i);
+			goto reset_err;
+		}
+	}
+
+	return 0;
+
+reset_err:
+	err = reset_release_all(simple->resets, simple->num_resets);
+	if (err)
+		pr_err("failed to disable all clocks\n");
+	
+	return ret;
+}
+#endif
+
+#if CONFIG_IS_ENABLED(CLK)
+static int dwc3_of_simple_clk_init(struct udevice *dev,
+				   struct dwc3_of_simple *simple,
+				   int count)
+{
+	int i, ret, err;
+
+	if (!count)
+		return 0;
+
+	simple->clks = devm_kcalloc(dev, count, sizeof(struct clk),
+				    GFP_KERNEL);
+	if (!simple->clks)
+		return -ENOMEM;
+
+	for (i = 0; i < count; i++) {
+		ret = clk_get_by_index(dev, i, &simple->clks[i]);
+		if (ret < 0)
+			break;
+
+		ret = clk_enable(&simple->clks[i]);
+		if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
+			pr_err("failed to enable clock %d\n", i);
+			clk_free(&simple->clks[i]);
+			goto clk_err;
+		}
+
+		++simple->num_clocks;
+	}
+
+	return 0;
+
+clk_err:
+	err = clk_release_all(simple->clks, simple->num_clocks);
+	if (err)
+		pr_err("failed to disable all clocks\n");
+	
+	return ret;
+}
+#endif
+
+static int dwc3_of_simple_probe(struct udevice *dev)
+{
+#if CONFIG_IS_ENABLED(DM_RESET) || CONFIG_IS_ENABLED(CLK)
+	struct dwc3_of_simple *simple = dev_get_platdata(dev);
+	int ret;
+#endif
+
+#if CONFIG_IS_ENABLED(CLK)
+	ret = dwc3_of_simple_clk_init(dev, simple,
+		dev_count_phandle_with_args(dev, "clocks", "#clock-cells"));
+	if (ret)
+		return ret;
+#endif
+
+#if CONFIG_IS_ENABLED(DM_RESET)
+	ret = dwc3_of_simple_reset_init(dev, simple,
+		dev_count_phandle_with_args(dev, "resets", "#reset-cells"));
+	if (ret)
+		return ret;
+#endif
+
+	return 0;
+}
+
+static int dwc3_of_simple_remove(struct udevice *dev)
+{
+#if CONFIG_IS_ENABLED(DM_RESET) || CONFIG_IS_ENABLED(CLK)
+	struct dwc3_of_simple *simple = dev_get_platdata(dev);
+	int i;
+#endif
+
+#if CONFIG_IS_ENABLED(DM_RESET)
+	for (i = 0; i < simple->num_resets; i++)
+		reset_assert(&simple->resets[i]);
+
+	if (simple->num_resets)
+		reset_release_all(simple->resets, simple->num_resets);
+#endif
+
+#if CONFIG_IS_ENABLED(CLK)
+	for (i = 0; i < simple->num_clocks; i++)
+		clk_disable(&simple->clks[i]);
+
+	if (simple->num_clocks)
+		clk_release_all(simple->clks, simple->num_clocks);
+#endif
+
+	return dm_scan_fdt_dev(dev);
+}
+
+static const struct udevice_id dwc3_of_simple_ids[] = {
+	{ .compatible = "amlogic,meson-gxl-dwc3" },
+	{ }
+};
+
+U_BOOT_DRIVER(dwc3_of_simple) = {
+	.name = "dwc3-of-simple",
+	.id = UCLASS_SIMPLE_BUS,
+	.of_match = dwc3_of_simple_ids,
+	.probe = dwc3_of_simple_probe,
+	.remove = dwc3_of_simple_remove,
+	.platdata_auto_alloc_size = sizeof(struct dwc3_of_simple),
+	.flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
-- 
2.7.4

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

* [PATCH u-boot 2/3] usb: host: dwc3: Add support for multiple PHYs
  2018-03-29 13:42 [PATCH u-boot 0/3] Add USB Support for Amlogic Meson GXL SoCs Neil Armstrong
  2018-03-29 13:42 ` [PATCH u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration Neil Armstrong
@ 2018-03-29 13:42 ` Neil Armstrong
  2018-03-29 13:53   ` Marek Vasut
  2018-03-29 13:42 ` [PATCH u-boot 3/3] phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers Neil Armstrong
  2 siblings, 1 reply; 13+ messages in thread
From: Neil Armstrong @ 2018-03-29 13:42 UTC (permalink / raw)
  To: linus-amlogic

DWC3 Ips can have more than 1 PHY for USB2 and 1 PHY for USB3, add support
for a generic number of PHYs and adapt the code to handle a generic
number of PHYs.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/usb/host/xhci-dwc3.c | 105 ++++++++++++++++++++++++-------------------
 1 file changed, 58 insertions(+), 47 deletions(-)

diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c
index 1022dd5..da29162 100644
--- a/drivers/usb/host/xhci-dwc3.c
+++ b/drivers/usb/host/xhci-dwc3.c
@@ -22,8 +22,8 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 struct xhci_dwc3_platdata {
-	struct phy usb_phy;
-	struct phy usb3_phy;
+	struct phy *usb_phys;
+	int num_phys;
 };
 
 void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
@@ -113,45 +113,74 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
 }
 
 #ifdef CONFIG_DM_USB
-static int xhci_dwc3_setup_phy(struct udevice *dev, int index, struct phy *phy)
+static int xhci_dwc3_setup_phy(struct udevice *dev, int count)
 {
-	int ret = 0;
+	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
+	int i, ret;
+
+	if (!count)
+		return 0;
 
-	ret = generic_phy_get_by_index(dev, index, phy);
-	if (ret) {
-		if (ret != -ENOENT) {
-			pr_err("Failed to get USB PHY for %s\n", dev->name);
+	plat->usb_phys = devm_kcalloc(dev, count, sizeof(struct phy),
+					GFP_KERNEL);
+	if (!plat->usb_phys)
+		return -ENOMEM;
+
+	for (i = 0; i < count; i++) {
+		ret = generic_phy_get_by_index(dev, i, &plat->usb_phys[i]);
+		if (ret && ret != -ENOENT) {
+			pr_err("Failed to get USB PHY%d for %s\n",
+			       i, dev->name);
 			return ret;
 		}
-	} else {
-		ret = generic_phy_init(phy);
+
+		++plat->num_phys;
+	}
+	
+	for (i = 0; i < plat->num_phys; i++) {
+		ret = generic_phy_init(&plat->usb_phys[i]);
 		if (ret) {
-			pr_err("Can't init USB PHY for %s\n", dev->name);
-			return ret;
+			pr_err("Can't init USB PHY%d for %s\n",
+			       i, dev->name);
+			goto phys_err;
 		}
-		ret = generic_phy_power_on(phy);
+	}
+	
+	for (i = 0; i < plat->num_phys; i++) {
+		ret = generic_phy_power_on(&plat->usb_phys[i]);
 		if (ret) {
-			pr_err("Can't power on USB PHY for %s\n", dev->name);
-			generic_phy_exit(phy);
-			return ret;
+			pr_err("Can't power USB PHY%d for %s\n",
+			       i, dev->name);
+			goto phys_err;
 		}
 	}
 
 	return 0;
+
+phys_err:
+	for (; i >= 0; i--) {
+		generic_phy_power_off(&plat->usb_phys[i]);
+		generic_phy_exit(&plat->usb_phys[i]);
+	}
+
+	return ret;
 }
 
-static int xhci_dwc3_shutdown_phy(struct phy *phy)
+static int xhci_dwc3_shutdown_phy(struct udevice *dev)
 {
-	int ret = 0;
+	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
+	int i, ret;
 
-	if (generic_phy_valid(phy)) {
-		ret = generic_phy_power_off(phy);
-		if (ret)
-			return ret;
+	for (i = 0; i < plat->num_phys; i++) {
+		if (!generic_phy_valid(&plat->usb_phys[i]))
+			continue;
 
-		ret = generic_phy_exit(phy);
-		if (ret)
-			return ret;
+		ret = generic_phy_power_off(&plat->usb_phys[i]);
+		ret |= generic_phy_exit(&plat->usb_phys[i]);
+		if (ret) {
+			pr_err("Can't shutdown USB PHY%d for %s\n",
+				i, dev->name);
+		}
 	}
 
 	return 0;
@@ -159,7 +188,6 @@ static int xhci_dwc3_shutdown_phy(struct phy *phy)
 
 static int xhci_dwc3_probe(struct udevice *dev)
 {
-	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
 	struct xhci_hcor *hcor;
 	struct xhci_hccr *hccr;
 	struct dwc3 *dwc3_reg;
@@ -170,18 +198,10 @@ static int xhci_dwc3_probe(struct udevice *dev)
 	hcor = (struct xhci_hcor *)((uintptr_t)hccr +
 			HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
 
-	ret = xhci_dwc3_setup_phy(dev, 0, &plat->usb_phy);
-	if (ret) {
-		pr_err("Failed to setup USB PHY for %s\n", dev->name);
-		return ret;
-	}
-
-	ret = xhci_dwc3_setup_phy(dev, 1, &plat->usb3_phy);
-	if (ret) {
-		pr_err("Failed to setup USB3 PHY for %s\n", dev->name);
-		xhci_dwc3_shutdown_phy(&plat->usb_phy);
+	ret = xhci_dwc3_setup_phy(dev, dev_count_phandle_with_args(
+						dev, "phys", "#phy-cells"));
+	if (ret)
 		return ret;
-	}
 
 	dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
 
@@ -199,16 +219,7 @@ static int xhci_dwc3_probe(struct udevice *dev)
 
 static int xhci_dwc3_remove(struct udevice *dev)
 {
-	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
-	int ret;
-
-	ret = xhci_dwc3_shutdown_phy(&plat->usb_phy);
-	if (ret)
-		pr_err("Can't shutdown USB PHY for %s\n", dev->name);
-
-	ret = xhci_dwc3_shutdown_phy(&plat->usb3_phy);
-	if (ret)
-		pr_err("Can't shutdown USB3 PHY for %s\n", dev->name);
+	xhci_dwc3_shutdown_phy(dev);
 
 	return xhci_deregister(dev);
 }
-- 
2.7.4

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

* [PATCH u-boot 3/3] phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers
  2018-03-29 13:42 [PATCH u-boot 0/3] Add USB Support for Amlogic Meson GXL SoCs Neil Armstrong
  2018-03-29 13:42 ` [PATCH u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration Neil Armstrong
  2018-03-29 13:42 ` [PATCH u-boot 2/3] usb: host: dwc3: Add support for multiple PHYs Neil Armstrong
@ 2018-03-29 13:42 ` Neil Armstrong
  2018-03-29 13:54   ` Marek Vasut
  2 siblings, 1 reply; 13+ messages in thread
From: Neil Armstrong @ 2018-03-29 13:42 UTC (permalink / raw)
  To: linus-amlogic

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/phy/Kconfig          |   8 ++
 drivers/phy/Makefile         |   1 +
 drivers/phy/meson-gxl-usb2.c | 238 +++++++++++++++++++++++++++++++++++++++++++
 drivers/phy/meson-gxl-usb3.c | 201 ++++++++++++++++++++++++++++++++++++
 4 files changed, 448 insertions(+)
 create mode 100644 drivers/phy/meson-gxl-usb2.c
 create mode 100644 drivers/phy/meson-gxl-usb3.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 3b9a09c..99a6d95 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -85,4 +85,12 @@ config STI_USB_PHY
 	  used by USB2 and USB3 Host controllers available on
 	  STiH407 SoC families.
 
+config MESON_GXL_USB_PHY
+	bool "Amlogic Meson GXL USB PHYs"
+	depends on PHY && ARCH_MESON && MESON_GXL
+	imply REGMAP
+	help
+	  This is the generic phy driver for the Amlogic Meson GXL
+	  USB2 and USB3 PHYS.
+
 endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 668040b..6c1610e 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_$(SPL_)NOP_PHY) += nop-phy.o
 obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o
 obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o
 obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o
+obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o meson-gxl-usb3.o
diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c
new file mode 100644
index 0000000..15c9c89
--- /dev/null
+++ b/drivers/phy/meson-gxl-usb2.c
@@ -0,0 +1,238 @@
+/*
+ * Meson GXL and GXM USB2 PHY driver
+ *
+ * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstron@baylibre.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <bitfield.h>
+#include <dm.h>
+#include <errno.h>
+#include <generic-phy.h>
+#include <regmap.h>
+#include <power/regulator.h>
+#include <clk.h>
+
+#include <linux/bitops.h>
+#include <linux/compat.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* bits [31:27] are read-only */
+#define U2P_R0							0x0
+	#define U2P_R0_BYPASS_SEL				BIT(0)
+	#define U2P_R0_BYPASS_DM_EN				BIT(1)
+	#define U2P_R0_BYPASS_DP_EN				BIT(2)
+	#define U2P_R0_TXBITSTUFF_ENH				BIT(3)
+	#define U2P_R0_TXBITSTUFF_EN				BIT(4)
+	#define U2P_R0_DM_PULLDOWN				BIT(5)
+	#define U2P_R0_DP_PULLDOWN				BIT(6)
+	#define U2P_R0_DP_VBUS_VLD_EXT_SEL			BIT(7)
+	#define U2P_R0_DP_VBUS_VLD_EXT				BIT(8)
+	#define U2P_R0_ADP_PRB_EN				BIT(9)
+	#define U2P_R0_ADP_DISCHARGE				BIT(10)
+	#define U2P_R0_ADP_CHARGE				BIT(11)
+	#define U2P_R0_DRV_VBUS					BIT(12)
+	#define U2P_R0_ID_PULLUP				BIT(13)
+	#define U2P_R0_LOOPBACK_EN_B				BIT(14)
+	#define U2P_R0_OTG_DISABLE				BIT(15)
+	#define U2P_R0_COMMON_ONN				BIT(16)
+	#define U2P_R0_FSEL_MASK				GENMASK(19, 17)
+	#define U2P_R0_REF_CLK_SEL_MASK				GENMASK(21, 20)
+	#define U2P_R0_POWER_ON_RESET				BIT(22)
+	#define U2P_R0_V_ATE_TEST_EN_B_MASK			GENMASK(24, 23)
+	#define U2P_R0_ID_SET_ID_DQ				BIT(25)
+	#define U2P_R0_ATE_RESET				BIT(26)
+	#define U2P_R0_FSV_MINUS				BIT(27)
+	#define U2P_R0_FSV_PLUS					BIT(28)
+	#define U2P_R0_BYPASS_DM_DATA				BIT(29)
+	#define U2P_R0_BYPASS_DP_DATA				BIT(30)
+
+#define U2P_R1							0x4
+	#define U2P_R1_BURN_IN_TEST				BIT(0)
+	#define U2P_R1_ACA_ENABLE				BIT(1)
+	#define U2P_R1_DCD_ENABLE				BIT(2)
+	#define U2P_R1_VDAT_SRC_EN_B				BIT(3)
+	#define U2P_R1_VDAT_DET_EN_B				BIT(4)
+	#define U2P_R1_CHARGES_SEL				BIT(5)
+	#define U2P_R1_TX_PREEMP_PULSE_TUNE			BIT(6)
+	#define U2P_R1_TX_PREEMP_AMP_TUNE_MASK			GENMASK(8, 7)
+	#define U2P_R1_TX_RES_TUNE_MASK				GENMASK(10, 9)
+	#define U2P_R1_TX_RISE_TUNE_MASK			GENMASK(12, 11)
+	#define U2P_R1_TX_VREF_TUNE_MASK			GENMASK(16, 13)
+	#define U2P_R1_TX_FSLS_TUNE_MASK			GENMASK(20, 17)
+	#define U2P_R1_TX_HSXV_TUNE_MASK			GENMASK(22, 21)
+	#define U2P_R1_OTG_TUNE_MASK				GENMASK(25, 23)
+	#define U2P_R1_SQRX_TUNE_MASK				GENMASK(28, 26)
+	#define U2P_R1_COMP_DIS_TUNE_MASK			GENMASK(31, 29)
+
+/* bits [31:14] are read-only */
+#define U2P_R2							0x8
+	#define U2P_R2_TESTDATA_IN_MASK				GENMASK(7, 0)
+	#define U2P_R2_TESTADDR_MASK				GENMASK(11, 8)
+	#define U2P_R2_TESTDATA_OUT_SEL				BIT(12)
+	#define U2P_R2_TESTCLK					BIT(13)
+	#define U2P_R2_TESTDATA_OUT_MASK			GENMASK(17, 14)
+	#define U2P_R2_ACA_PIN_RANGE_C				BIT(18)
+	#define U2P_R2_ACA_PIN_RANGE_B				BIT(19)
+	#define U2P_R2_ACA_PIN_RANGE_A				BIT(20)
+	#define U2P_R2_ACA_PIN_GND				BIT(21)
+	#define U2P_R2_ACA_PIN_FLOAT				BIT(22)
+	#define U2P_R2_CHARGE_DETECT				BIT(23)
+	#define U2P_R2_DEVICE_SESSION_VALID			BIT(24)
+	#define U2P_R2_ADP_PROBE				BIT(25)
+	#define U2P_R2_ADP_SENSE				BIT(26)
+	#define U2P_R2_SESSION_END				BIT(27)
+	#define U2P_R2_VBUS_VALID				BIT(28)
+	#define U2P_R2_B_VALID					BIT(29)
+	#define U2P_R2_A_VALID					BIT(30)
+	#define U2P_R2_ID_DIG					BIT(31)
+
+#define U2P_R3							0xc
+
+#define RESET_COMPLETE_TIME				500
+
+struct phy_meson_gxl_usb2_priv {
+	struct regmap		*regmap;
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+	struct udevice		*phy_supply;
+#endif
+#if CONFIG_IS_ENABLED(CLK)
+	struct clk		clk;
+#endif
+};
+
+static void phy_meson_gxl_usb2_reset(struct phy_meson_gxl_usb2_priv *priv)
+{
+	uint val;
+
+	regmap_read(priv->regmap, U2P_R0, &val);
+
+	/* reset the PHY and wait until settings are stabilized */
+	val |= U2P_R0_POWER_ON_RESET;
+	regmap_write(priv->regmap, U2P_R0, val);
+	udelay(RESET_COMPLETE_TIME);
+
+	val &= ~U2P_R0_POWER_ON_RESET;
+	regmap_write(priv->regmap, U2P_R0, val);
+	udelay(RESET_COMPLETE_TIME);
+}
+
+static void
+phy_meson_gxl_usb2_set_host_mode(struct phy_meson_gxl_usb2_priv *priv)
+{
+	uint val;
+
+	regmap_read(priv->regmap, U2P_R0, &val);
+	val |= U2P_R0_DM_PULLDOWN;
+	val |= U2P_R0_DP_PULLDOWN;
+	val &= ~U2P_R0_ID_PULLUP;
+	regmap_write(priv->regmap, U2P_R0, val);
+
+	phy_meson_gxl_usb2_reset(priv);
+}
+
+static int phy_meson_gxl_usb2_power_on(struct phy *phy)
+{
+	struct udevice *dev = phy->dev;
+	struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
+	uint val;
+
+	regmap_read(priv->regmap, U2P_R0, &val);
+	/* power on the PHY by taking it out of reset mode */
+	val &= ~U2P_R0_POWER_ON_RESET;
+	regmap_write(priv->regmap, U2P_R0, val);
+
+	phy_meson_gxl_usb2_set_host_mode(priv);
+
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+	if (priv->phy_supply) {
+		int ret = regulator_set_enable(priv->phy_supply, true);
+		if (ret)
+			return ret;
+	}
+#endif
+
+	return 0;
+}
+
+static int phy_meson_gxl_usb2_power_off(struct phy *phy)
+{
+	struct udevice *dev = phy->dev;
+	struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
+	uint val;
+
+	regmap_read(priv->regmap, U2P_R0, &val);
+	/* power off the PHY by putting it into reset mode */
+	val |= U2P_R0_POWER_ON_RESET;
+	regmap_write(priv->regmap, U2P_R0, val);
+
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+	if (priv->phy_supply) {
+		int ret = regulator_set_enable(priv->phy_supply, false);
+		if (ret) {
+			pr_err("Error disabling PHY supply\n");
+			return ret;
+		}
+	}
+#endif
+
+	return 0;
+}
+
+struct phy_ops meson_gxl_usb2_phy_ops = {
+	.power_on = phy_meson_gxl_usb2_power_on,
+	.power_off = phy_meson_gxl_usb2_power_off,
+};
+
+int meson_gxl_usb2_phy_probe(struct udevice *dev)
+{
+	struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = regmap_init_mem(dev, &priv->regmap);
+	if (ret)
+		return ret;
+
+#if CONFIG_IS_ENABLED(CLK)
+	ret = clk_get_by_index(dev, 0, &priv->clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_enable(&priv->clk);
+	if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
+		pr_err("failed to enable PHY clock\n");
+		clk_free(&priv->clk);
+		return ret;
+	}
+#endif
+
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+	ret = device_get_supply_regulator(dev, "phy-supply", &priv->phy_supply);
+	if (ret && ret != -ENOENT) {
+		pr_err("Failed to get PHY regulator\n");
+		return ret;
+	}
+#endif
+
+	return 0;
+}
+
+static const struct udevice_id meson_gxl_usb2_phy_ids[] = {
+	{ .compatible = "amlogic,meson-gxl-usb2-phy" },
+	{ }
+};
+
+U_BOOT_DRIVER(meson_gxl_usb2_phy) = {
+	.name = "meson_gxl_usb2_phy",
+	.id = UCLASS_PHY,
+	.of_match = meson_gxl_usb2_phy_ids,
+	.probe = meson_gxl_usb2_phy_probe,
+	.ops = &meson_gxl_usb2_phy_ops,
+	.priv_auto_alloc_size = sizeof(struct phy_meson_gxl_usb2_priv),
+};
diff --git a/drivers/phy/meson-gxl-usb3.c b/drivers/phy/meson-gxl-usb3.c
new file mode 100644
index 0000000..a385fbd
--- /dev/null
+++ b/drivers/phy/meson-gxl-usb3.c
@@ -0,0 +1,201 @@
+/*
+ * Meson GXL USB3 PHY driver
+ *
+ * Copyright (C) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstron@baylibre.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <bitfield.h>
+#include <dm.h>
+#include <errno.h>
+#include <generic-phy.h>
+#include <regmap.h>
+#include <clk.h>
+
+#include <linux/bitops.h>
+#include <linux/compat.h>
+#include <linux/bitfield.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define USB_R0							0x00
+	#define USB_R0_P30_FSEL_MASK				GENMASK(5, 0)
+	#define USB_R0_P30_PHY_RESET				BIT(6)
+	#define USB_R0_P30_TEST_POWERDOWN_HSP			BIT(7)
+	#define USB_R0_P30_TEST_POWERDOWN_SSP			BIT(8)
+	#define USB_R0_P30_ACJT_LEVEL_MASK			GENMASK(13, 9)
+	#define USB_R0_P30_TX_BOOST_LEVEL_MASK			GENMASK(16, 14)
+	#define USB_R0_P30_LANE0_TX2RX_LOOPBACK			BIT(17)
+	#define USB_R0_P30_LANE0_EXT_PCLK_REQ			BIT(18)
+	#define USB_R0_P30_PCS_RX_LOS_MASK_VAL_MASK		GENMASK(28, 19)
+	#define USB_R0_U2D_SS_SCALEDOWN_MODE_MASK		GENMASK(30, 29)
+	#define USB_R0_U2D_ACT					BIT(31)
+
+#define USB_R1							0x04
+	#define USB_R1_U3H_BIGENDIAN_GS				BIT(0)
+	#define USB_R1_U3H_PME_ENABLE				BIT(1)
+	#define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK		GENMASK(6, 2)
+	#define USB_R1_U3H_HUB_PORT_PERM_ATTACH_MASK		GENMASK(11, 7)
+	#define USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK		GENMASK(15, 12)
+	#define USB_R1_U3H_HOST_U3_PORT_DISABLE			BIT(16)
+	#define USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT	BIT(17)
+	#define USB_R1_U3H_HOST_MSI_ENABLE			BIT(18)
+	#define USB_R1_U3H_FLADJ_30MHZ_REG_MASK			GENMASK(24, 19)
+	#define USB_R1_P30_PCS_TX_SWING_FULL_MASK		GENMASK(31, 25)
+
+#define USB_R2							0x08
+	#define USB_R2_P30_CR_DATA_IN_MASK			GENMASK(15, 0)
+	#define USB_R2_P30_CR_READ				BIT(16)
+	#define USB_R2_P30_CR_WRITE				BIT(17)
+	#define USB_R2_P30_CR_CAP_ADDR				BIT(18)
+	#define USB_R2_P30_CR_CAP_DATA				BIT(19)
+	#define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK		GENMASK(25, 20)
+	#define USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK		GENMASK(31, 26)
+
+#define USB_R3							0x0c
+	#define USB_R3_P30_SSC_ENABLE				BIT(0)
+	#define USB_R3_P30_SSC_RANGE_MASK			GENMASK(3, 1)
+	#define USB_R3_P30_SSC_REF_CLK_SEL_MASK			GENMASK(12, 4)
+	#define USB_R3_P30_REF_SSP_EN				BIT(13)
+	#define USB_R3_P30_LOS_BIAS_MASK			GENMASK(18, 16)
+	#define USB_R3_P30_LOS_LEVEL_MASK			GENMASK(23, 19)
+	#define USB_R3_P30_MPLL_MULTIPLIER_MASK			GENMASK(30, 24)
+
+#define USB_R4							0x10
+	#define USB_R4_P21_PORT_RESET_0				BIT(0)
+	#define USB_R4_P21_SLEEP_M0				BIT(1)
+	#define USB_R4_MEM_PD_MASK				GENMASK(3, 2)
+	#define USB_R4_P21_ONLY					BIT(4)
+
+#define USB_R5							0x14
+	#define USB_R5_ID_DIG_SYNC				BIT(0)
+	#define USB_R5_ID_DIG_REG				BIT(1)
+	#define USB_R5_ID_DIG_CFG_MASK				GENMASK(3, 2)
+	#define USB_R5_ID_DIG_EN_0				BIT(4)
+	#define USB_R5_ID_DIG_EN_1				BIT(5)
+	#define USB_R5_ID_DIG_CURR				BIT(6)
+	#define USB_R5_ID_DIG_IRQ				BIT(7)
+	#define USB_R5_ID_DIG_TH_MASK				GENMASK(15, 8)
+	#define USB_R5_ID_DIG_CNT_MASK				GENMASK(23, 16)
+
+/* read-only register */
+#define USB_R6							0x18
+	#define USB_R6_P30_CR_DATA_OUT_MASK			GENMASK(15, 0)
+	#define USB_R6_P30_CR_ACK				BIT(16)
+
+struct phy_meson_gxl_usb3_priv {
+	struct regmap		*regmap;
+#if CONFIG_IS_ENABLED(CLK)
+	struct clk		clk;
+#endif
+};
+
+static int
+phy_meson_gxl_usb3_set_host_mode(struct phy_meson_gxl_usb3_priv *priv)
+{
+	uint val;
+
+	regmap_read(priv->regmap, USB_R0, &val);
+	val &= ~USB_R0_U2D_ACT;
+	regmap_write(priv->regmap, USB_R0, val);
+
+	regmap_read(priv->regmap, USB_R4, &val);
+	val &= ~USB_R4_P21_SLEEP_M0;
+	regmap_write(priv->regmap, USB_R4, val);
+
+	return 0;
+}
+
+static int phy_meson_gxl_usb3_power_on(struct phy *phy)
+{
+	struct udevice *dev = phy->dev;
+	struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
+	uint val;
+
+	regmap_read(priv->regmap, USB_R5, &val);
+	val |= USB_R5_ID_DIG_EN_0;
+	val |= USB_R5_ID_DIG_EN_1;
+	val &= ~USB_R5_ID_DIG_TH_MASK;
+	val |= FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff);
+	regmap_write(priv->regmap, USB_R5, val);
+
+	return phy_meson_gxl_usb3_set_host_mode(priv);
+}
+
+static int phy_meson_gxl_usb3_power_off(struct phy *phy)
+{
+	struct udevice *dev = phy->dev;
+	struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
+	uint val;
+
+	regmap_read(priv->regmap, USB_R5, &val);
+	val &= ~USB_R5_ID_DIG_EN_0;
+	val &= ~USB_R5_ID_DIG_EN_1;
+	regmap_write(priv->regmap, USB_R5, val);
+
+	return 0;
+}
+
+static int phy_meson_gxl_usb3_init(struct phy *phy)
+{
+	struct udevice *dev = phy->dev;
+	struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
+	uint val;
+
+	regmap_read(priv->regmap, USB_R1, &val);
+	val &= ~USB_R1_U3H_FLADJ_30MHZ_REG_MASK;
+	val |= FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20);
+	regmap_write(priv->regmap, USB_R1, val);
+
+	return 0;
+}
+
+struct phy_ops meson_gxl_usb3_phy_ops = {
+	.init = phy_meson_gxl_usb3_init,
+	.power_on = phy_meson_gxl_usb3_power_on,
+	.power_off = phy_meson_gxl_usb3_power_off,
+};
+
+int meson_gxl_usb3_phy_probe(struct udevice *dev)
+{
+	struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = regmap_init_mem(dev, &priv->regmap);
+	if (ret)
+		return ret;
+	
+#if CONFIG_IS_ENABLED(CLK)
+	ret = clk_get_by_index(dev, 0, &priv->clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_enable(&priv->clk);
+	if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
+		pr_err("failed to enable PHY clock\n");
+		clk_free(&priv->clk);
+		return ret;
+	}
+#endif
+
+	return 0;
+}
+
+static const struct udevice_id meson_gxl_usb3_phy_ids[] = {
+	{ .compatible = "amlogic,meson-gxl-usb3-phy" },
+	{ }
+};
+
+U_BOOT_DRIVER(meson_gxl_usb3_phy) = {
+	.name = "meson_gxl_usb3_phy",
+	.id = UCLASS_PHY,
+	.of_match = meson_gxl_usb3_phy_ids,
+	.probe = meson_gxl_usb3_phy_probe,
+	.ops = &meson_gxl_usb3_phy_ops,
+	.priv_auto_alloc_size = sizeof(struct phy_meson_gxl_usb3_priv),
+};
-- 
2.7.4

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

* [PATCH u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
  2018-03-29 13:42 ` [PATCH u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration Neil Armstrong
@ 2018-03-29 13:52   ` Marek Vasut
  2018-03-29 14:23     ` Neil Armstrong
  0 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2018-03-29 13:52 UTC (permalink / raw)
  To: linus-amlogic

On 03/29/2018 03:42 PM, Neil Armstrong wrote:
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/usb/host/Kconfig          |   7 ++
>  drivers/usb/host/Makefile         |   1 +
>  drivers/usb/host/dwc3-of-simple.c | 187 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 195 insertions(+)
>  create mode 100644 drivers/usb/host/dwc3-of-simple.c
> 
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index a7249b7..6caa615 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
>  	  Say Y or if your system has a Dual Role SuperSpeed
>  	  USB controller based on the DesignWare USB3 IP Core.
>  
> +config USB_XHCI_DWC3_OF_SIMPLE
> +	bool "DesignWare USB3 DRD Generic OF Simple Glue Layer"
> +	select MISC
> +	help
> +	  Support USB2/3 functionality in simple SoC integrations with
> +	  USB controller based on the DesignWare USB3 IP Core.
> +
>  config USB_XHCI_MVEBU
>  	bool "MVEBU USB 3.0 support"
>  	default y
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index 9819489..abe4f90 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
>  # xhci
>  obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
>  obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
> +obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o
>  obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
>  obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o
>  obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
> diff --git a/drivers/usb/host/dwc3-of-simple.c b/drivers/usb/host/dwc3-of-simple.c
> new file mode 100644
> index 0000000..826a996
> --- /dev/null
> +++ b/drivers/usb/host/dwc3-of-simple.c
> @@ -0,0 +1,187 @@
> +/*
> + * dwc3-of-simple.c - OF glue layer for simple integrations
> + *
> + * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
> + *
> + * Author: Felipe Balbi <balbi@ti.com>
> + *
> + * Copyright (C) 2018 BayLibre, SAS
> + * Author: Neil Armstrong <narmstron@baylibre.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <fdtdec.h>
> +#include <reset.h>
> +#include <clk.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +struct dwc3_of_simple {
> +#if CONFIG_IS_ENABLED(CLK)
> +	struct clk		*clks;
> +	int			num_clocks;
> +#endif
> +#if CONFIG_IS_ENABLED(DM_RESET)
> +	struct reset_ctl	*resets;
> +	int			num_resets;
> +#endif
> +};
> +
> +#if CONFIG_IS_ENABLED(DM_RESET)
> +static int dwc3_of_simple_reset_init(struct udevice *dev,
> +				     struct dwc3_of_simple *simple,
> +				     int count)
> +{
> +	int i, ret, err;
> +
> +	if (!count)
> +		return 0;
> +
> +	simple->resets = devm_kcalloc(dev, count, sizeof(struct reset_ctl),
> +				      GFP_KERNEL);
> +	if (!simple->resets)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < count; i++) {
> +		ret = reset_get_by_index(dev, i, &simple->resets[i]);
> +		if (ret < 0)
> +			break;
> +
> +		ret = reset_request(&simple->resets[i]);
> +		if (ret) {
> +			pr_err("failed to request reset line %d\n", i);
> +			reset_free(&simple->resets[i]);
> +			goto reset_err;
> +		}
> +
> +		
> +		++simple->num_resets;
> +	}
> +
> +	for (i = 0; i < simple->num_resets; i++) {
> +		ret = reset_deassert(&simple->resets[i]);
> +		if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
> +			pr_err("failed to deassert reset line %d\n", i);
> +			goto reset_err;
> +		}
> +	}
> +
> +	return 0;

This looks like some driver I've seen before. Isn't there similar code
for simple EHCI or OHCI driver already ?

-- 
Best regards,
Marek Vasut

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

* [PATCH u-boot 2/3] usb: host: dwc3: Add support for multiple PHYs
  2018-03-29 13:42 ` [PATCH u-boot 2/3] usb: host: dwc3: Add support for multiple PHYs Neil Armstrong
@ 2018-03-29 13:53   ` Marek Vasut
  2018-03-29 14:23     ` Neil Armstrong
  0 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2018-03-29 13:53 UTC (permalink / raw)
  To: linus-amlogic

On 03/29/2018 03:42 PM, Neil Armstrong wrote:
> DWC3 Ips can have more than 1 PHY for USB2 and 1 PHY for USB3, add support
> for a generic number of PHYs and adapt the code to handle a generic
> number of PHYs.
> 
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/usb/host/xhci-dwc3.c | 105 ++++++++++++++++++++++++-------------------
>  1 file changed, 58 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c
> index 1022dd5..da29162 100644
> --- a/drivers/usb/host/xhci-dwc3.c
> +++ b/drivers/usb/host/xhci-dwc3.c
> @@ -22,8 +22,8 @@
>  DECLARE_GLOBAL_DATA_PTR;
>  
>  struct xhci_dwc3_platdata {
> -	struct phy usb_phy;
> -	struct phy usb3_phy;
> +	struct phy *usb_phys;
> +	int num_phys;
>  };
>  
>  void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
> @@ -113,45 +113,74 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
>  }
>  
>  #ifdef CONFIG_DM_USB
> -static int xhci_dwc3_setup_phy(struct udevice *dev, int index, struct phy *phy)
> +static int xhci_dwc3_setup_phy(struct udevice *dev, int count)
>  {
> -	int ret = 0;
> +	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
> +	int i, ret;
> +
> +	if (!count)
> +		return 0;
>  
> -	ret = generic_phy_get_by_index(dev, index, phy);
> -	if (ret) {
> -		if (ret != -ENOENT) {
> -			pr_err("Failed to get USB PHY for %s\n", dev->name);
> +	plat->usb_phys = devm_kcalloc(dev, count, sizeof(struct phy),
> +					GFP_KERNEL);
> +	if (!plat->usb_phys)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < count; i++) {
> +		ret = generic_phy_get_by_index(dev, i, &plat->usb_phys[i]);
> +		if (ret && ret != -ENOENT) {
> +			pr_err("Failed to get USB PHY%d for %s\n",
> +			       i, dev->name);
>  			return ret;
>  		}
> -	} else {
> -		ret = generic_phy_init(phy);
> +
> +		++plat->num_phys;
> +	}
> +	
> +	for (i = 0; i < plat->num_phys; i++) {
> +		ret = generic_phy_init(&plat->usb_phys[i]);
>  		if (ret) {
> -			pr_err("Can't init USB PHY for %s\n", dev->name);
> -			return ret;
> +			pr_err("Can't init USB PHY%d for %s\n",
> +			       i, dev->name);
> +			goto phys_err;
>  		}
> -		ret = generic_phy_power_on(phy);
> +	}
> +	
> +	for (i = 0; i < plat->num_phys; i++) {
> +		ret = generic_phy_power_on(&plat->usb_phys[i]);
>  		if (ret) {
> -			pr_err("Can't power on USB PHY for %s\n", dev->name);
> -			generic_phy_exit(phy);
> -			return ret;
> +			pr_err("Can't power USB PHY%d for %s\n",
> +			       i, dev->name);
> +			goto phys_err;
>  		}
>  	}
>  
>  	return 0;
> +
> +phys_err:
> +	for (; i >= 0; i--) {
> +		generic_phy_power_off(&plat->usb_phys[i]);
> +		generic_phy_exit(&plat->usb_phys[i]);
> +	}

This will not work if all the PHYs are inited, but the power up function
fails -- at that point the phy_exit will not be called for all inited PHys.

-- 
Best regards,
Marek Vasut

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

* [PATCH u-boot 3/3] phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers
  2018-03-29 13:42 ` [PATCH u-boot 3/3] phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers Neil Armstrong
@ 2018-03-29 13:54   ` Marek Vasut
  2018-03-29 14:24     ` Neil Armstrong
  0 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2018-03-29 13:54 UTC (permalink / raw)
  To: linus-amlogic

On 03/29/2018 03:42 PM, Neil Armstrong wrote:
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/phy/Kconfig          |   8 ++
>  drivers/phy/Makefile         |   1 +
>  drivers/phy/meson-gxl-usb2.c | 238 +++++++++++++++++++++++++++++++++++++++++++
>  drivers/phy/meson-gxl-usb3.c | 201 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 448 insertions(+)
>  create mode 100644 drivers/phy/meson-gxl-usb2.c
>  create mode 100644 drivers/phy/meson-gxl-usb3.c

Commit message is missing, otherwise looks reasonable.

-- 
Best regards,
Marek Vasut

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

* [PATCH u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
  2018-03-29 13:52   ` Marek Vasut
@ 2018-03-29 14:23     ` Neil Armstrong
  2018-03-29 14:24       ` Marek Vasut
  0 siblings, 1 reply; 13+ messages in thread
From: Neil Armstrong @ 2018-03-29 14:23 UTC (permalink / raw)
  To: linus-amlogic

On 29/03/2018 15:52, Marek Vasut wrote:
> On 03/29/2018 03:42 PM, Neil Armstrong wrote:
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/usb/host/Kconfig          |   7 ++
>>  drivers/usb/host/Makefile         |   1 +
>>  drivers/usb/host/dwc3-of-simple.c | 187 ++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 195 insertions(+)
>>  create mode 100644 drivers/usb/host/dwc3-of-simple.c
>>
>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>> index a7249b7..6caa615 100644
>> --- a/drivers/usb/host/Kconfig
>> +++ b/drivers/usb/host/Kconfig
>> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
>>  	  Say Y or if your system has a Dual Role SuperSpeed
>>  	  USB controller based on the DesignWare USB3 IP Core.
>>  
>> +config USB_XHCI_DWC3_OF_SIMPLE
>> +	bool "DesignWare USB3 DRD Generic OF Simple Glue Layer"
>> +	select MISC
>> +	help
>> +	  Support USB2/3 functionality in simple SoC integrations with
>> +	  USB controller based on the DesignWare USB3 IP Core.
>> +
>>  config USB_XHCI_MVEBU
>>  	bool "MVEBU USB 3.0 support"
>>  	default y
>> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
>> index 9819489..abe4f90 100644
>> --- a/drivers/usb/host/Makefile
>> +++ b/drivers/usb/host/Makefile
>> @@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
>>  # xhci
>>  obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
>>  obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
>> +obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o
>>  obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
>>  obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o
>>  obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
>> diff --git a/drivers/usb/host/dwc3-of-simple.c b/drivers/usb/host/dwc3-of-simple.c
>> new file mode 100644
>> index 0000000..826a996
>> --- /dev/null
>> +++ b/drivers/usb/host/dwc3-of-simple.c
>> @@ -0,0 +1,187 @@
>> +/*
>> + * dwc3-of-simple.c - OF glue layer for simple integrations
>> + *
>> + * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
>> + *
>> + * Author: Felipe Balbi <balbi@ti.com>
>> + *
>> + * Copyright (C) 2018 BayLibre, SAS
>> + * Author: Neil Armstrong <narmstron@baylibre.com>
>> + *
>> + * SPDX-License-Identifier:     GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <fdtdec.h>
>> +#include <reset.h>
>> +#include <clk.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +struct dwc3_of_simple {
>> +#if CONFIG_IS_ENABLED(CLK)
>> +	struct clk		*clks;
>> +	int			num_clocks;
>> +#endif
>> +#if CONFIG_IS_ENABLED(DM_RESET)
>> +	struct reset_ctl	*resets;
>> +	int			num_resets;
>> +#endif
>> +};
>> +
>> +#if CONFIG_IS_ENABLED(DM_RESET)
>> +static int dwc3_of_simple_reset_init(struct udevice *dev,
>> +				     struct dwc3_of_simple *simple,
>> +				     int count)
>> +{
>> +	int i, ret, err;
>> +
>> +	if (!count)
>> +		return 0;
>> +
>> +	simple->resets = devm_kcalloc(dev, count, sizeof(struct reset_ctl),
>> +				      GFP_KERNEL);
>> +	if (!simple->resets)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; i < count; i++) {
>> +		ret = reset_get_by_index(dev, i, &simple->resets[i]);
>> +		if (ret < 0)
>> +			break;
>> +
>> +		ret = reset_request(&simple->resets[i]);
>> +		if (ret) {
>> +			pr_err("failed to request reset line %d\n", i);
>> +			reset_free(&simple->resets[i]);
>> +			goto reset_err;
>> +		}
>> +
>> +		
>> +		++simple->num_resets;
>> +	}
>> +
>> +	for (i = 0; i < simple->num_resets; i++) {
>> +		ret = reset_deassert(&simple->resets[i]);
>> +		if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
>> +			pr_err("failed to deassert reset line %d\n", i);
>> +			goto reset_err;
>> +		}
>> +	}
>> +
>> +	return 0;
> 
> This looks like some driver I've seen before. Isn't there similar code
> for simple EHCI or OHCI driver already ?
> 

Hi,

This is not an EHCI/OHCI driver, only the glue to init the clocks and reset,
it's the exact same as the drivers/usb/dwc3/dwc3-of-simple.c adapted to U-Boot.

yes, similar code exists in drivers/usb/host/ehci-generic.c and
drivers/usb/host/ohci-generic.c but the goal here is not to initialize the controller
but only the glue.

The device tree representation is :
glue@ {
	compatible = "amlogic,meson-gxl-dwc3";
	clocks = <>;
	resets = <>;

	dwc3@ {
		compatible = "snps,dwc3";
		clocks = <>;
		phys = <>;
	};
};

Neil

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

* [PATCH u-boot 2/3] usb: host: dwc3: Add support for multiple PHYs
  2018-03-29 13:53   ` Marek Vasut
@ 2018-03-29 14:23     ` Neil Armstrong
  0 siblings, 0 replies; 13+ messages in thread
From: Neil Armstrong @ 2018-03-29 14:23 UTC (permalink / raw)
  To: linus-amlogic

On 29/03/2018 15:53, Marek Vasut wrote:
> On 03/29/2018 03:42 PM, Neil Armstrong wrote:
>> DWC3 Ips can have more than 1 PHY for USB2 and 1 PHY for USB3, add support
>> for a generic number of PHYs and adapt the code to handle a generic
>> number of PHYs.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/usb/host/xhci-dwc3.c | 105 ++++++++++++++++++++++++-------------------
>>  1 file changed, 58 insertions(+), 47 deletions(-)
>>
>> diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c
>> index 1022dd5..da29162 100644
>> --- a/drivers/usb/host/xhci-dwc3.c
>> +++ b/drivers/usb/host/xhci-dwc3.c
>> @@ -22,8 +22,8 @@
>>  DECLARE_GLOBAL_DATA_PTR;
>>  
>>  struct xhci_dwc3_platdata {
>> -	struct phy usb_phy;
>> -	struct phy usb3_phy;
>> +	struct phy *usb_phys;
>> +	int num_phys;
>>  };
>>  
>>  void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
>> @@ -113,45 +113,74 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
>>  }
>>  
>>  #ifdef CONFIG_DM_USB
>> -static int xhci_dwc3_setup_phy(struct udevice *dev, int index, struct phy *phy)
>> +static int xhci_dwc3_setup_phy(struct udevice *dev, int count)
>>  {
>> -	int ret = 0;
>> +	struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
>> +	int i, ret;
>> +
>> +	if (!count)
>> +		return 0;
>>  
>> -	ret = generic_phy_get_by_index(dev, index, phy);
>> -	if (ret) {
>> -		if (ret != -ENOENT) {
>> -			pr_err("Failed to get USB PHY for %s\n", dev->name);
>> +	plat->usb_phys = devm_kcalloc(dev, count, sizeof(struct phy),
>> +					GFP_KERNEL);
>> +	if (!plat->usb_phys)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; i < count; i++) {
>> +		ret = generic_phy_get_by_index(dev, i, &plat->usb_phys[i]);
>> +		if (ret && ret != -ENOENT) {
>> +			pr_err("Failed to get USB PHY%d for %s\n",
>> +			       i, dev->name);
>>  			return ret;
>>  		}
>> -	} else {
>> -		ret = generic_phy_init(phy);
>> +
>> +		++plat->num_phys;
>> +	}
>> +	
>> +	for (i = 0; i < plat->num_phys; i++) {
>> +		ret = generic_phy_init(&plat->usb_phys[i]);
>>  		if (ret) {
>> -			pr_err("Can't init USB PHY for %s\n", dev->name);
>> -			return ret;
>> +			pr_err("Can't init USB PHY%d for %s\n",
>> +			       i, dev->name);
>> +			goto phys_err;
>>  		}
>> -		ret = generic_phy_power_on(phy);
>> +	}
>> +	
>> +	for (i = 0; i < plat->num_phys; i++) {
>> +		ret = generic_phy_power_on(&plat->usb_phys[i]);
>>  		if (ret) {
>> -			pr_err("Can't power on USB PHY for %s\n", dev->name);
>> -			generic_phy_exit(phy);
>> -			return ret;
>> +			pr_err("Can't power USB PHY%d for %s\n",
>> +			       i, dev->name);
>> +			goto phys_err;
>>  		}
>>  	}
>>  
>>  	return 0;
>> +
>> +phys_err:
>> +	for (; i >= 0; i--) {
>> +		generic_phy_power_off(&plat->usb_phys[i]);
>> +		generic_phy_exit(&plat->usb_phys[i]);
>> +	}
> 
> This will not work if all the PHYs are inited, but the power up function
> fails -- at that point the phy_exit will not be called for all inited PHys.
> 

Ok will split in 2 parts.

Neil

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

* [PATCH u-boot 3/3] phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers
  2018-03-29 13:54   ` Marek Vasut
@ 2018-03-29 14:24     ` Neil Armstrong
  0 siblings, 0 replies; 13+ messages in thread
From: Neil Armstrong @ 2018-03-29 14:24 UTC (permalink / raw)
  To: linus-amlogic

On 29/03/2018 15:54, Marek Vasut wrote:
> On 03/29/2018 03:42 PM, Neil Armstrong wrote:
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/phy/Kconfig          |   8 ++
>>  drivers/phy/Makefile         |   1 +
>>  drivers/phy/meson-gxl-usb2.c | 238 +++++++++++++++++++++++++++++++++++++++++++
>>  drivers/phy/meson-gxl-usb3.c | 201 ++++++++++++++++++++++++++++++++++++
>>  4 files changed, 448 insertions(+)
>>  create mode 100644 drivers/phy/meson-gxl-usb2.c
>>  create mode 100644 drivers/phy/meson-gxl-usb3.c
> 
> Commit message is missing, otherwise looks reasonable.
> 

OOps, will add in v2.

Thanks,
Neil

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

* [PATCH u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
  2018-03-29 14:23     ` Neil Armstrong
@ 2018-03-29 14:24       ` Marek Vasut
  2018-03-29 14:27         ` Neil Armstrong
  0 siblings, 1 reply; 13+ messages in thread
From: Marek Vasut @ 2018-03-29 14:24 UTC (permalink / raw)
  To: linus-amlogic

On 03/29/2018 04:23 PM, Neil Armstrong wrote:
> On 29/03/2018 15:52, Marek Vasut wrote:
>> On 03/29/2018 03:42 PM, Neil Armstrong wrote:
>>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>>> ---
>>>  drivers/usb/host/Kconfig          |   7 ++
>>>  drivers/usb/host/Makefile         |   1 +
>>>  drivers/usb/host/dwc3-of-simple.c | 187 ++++++++++++++++++++++++++++++++++++++
>>>  3 files changed, 195 insertions(+)
>>>  create mode 100644 drivers/usb/host/dwc3-of-simple.c
>>>
>>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>>> index a7249b7..6caa615 100644
>>> --- a/drivers/usb/host/Kconfig
>>> +++ b/drivers/usb/host/Kconfig
>>> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
>>>  	  Say Y or if your system has a Dual Role SuperSpeed
>>>  	  USB controller based on the DesignWare USB3 IP Core.
>>>  
>>> +config USB_XHCI_DWC3_OF_SIMPLE
>>> +	bool "DesignWare USB3 DRD Generic OF Simple Glue Layer"
>>> +	select MISC
>>> +	help
>>> +	  Support USB2/3 functionality in simple SoC integrations with
>>> +	  USB controller based on the DesignWare USB3 IP Core.
>>> +
>>>  config USB_XHCI_MVEBU
>>>  	bool "MVEBU USB 3.0 support"
>>>  	default y
>>> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
>>> index 9819489..abe4f90 100644
>>> --- a/drivers/usb/host/Makefile
>>> +++ b/drivers/usb/host/Makefile
>>> @@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
>>>  # xhci
>>>  obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
>>>  obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
>>> +obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o
>>>  obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
>>>  obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o
>>>  obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
>>> diff --git a/drivers/usb/host/dwc3-of-simple.c b/drivers/usb/host/dwc3-of-simple.c
>>> new file mode 100644
>>> index 0000000..826a996
>>> --- /dev/null
>>> +++ b/drivers/usb/host/dwc3-of-simple.c
>>> @@ -0,0 +1,187 @@
>>> +/*
>>> + * dwc3-of-simple.c - OF glue layer for simple integrations
>>> + *
>>> + * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
>>> + *
>>> + * Author: Felipe Balbi <balbi@ti.com>
>>> + *
>>> + * Copyright (C) 2018 BayLibre, SAS
>>> + * Author: Neil Armstrong <narmstron@baylibre.com>
>>> + *
>>> + * SPDX-License-Identifier:     GPL-2.0+
>>> + */
>>> +
>>> +#include <common.h>
>>> +#include <dm.h>
>>> +#include <fdtdec.h>
>>> +#include <reset.h>
>>> +#include <clk.h>
>>> +
>>> +DECLARE_GLOBAL_DATA_PTR;
>>> +
>>> +struct dwc3_of_simple {
>>> +#if CONFIG_IS_ENABLED(CLK)
>>> +	struct clk		*clks;
>>> +	int			num_clocks;
>>> +#endif
>>> +#if CONFIG_IS_ENABLED(DM_RESET)
>>> +	struct reset_ctl	*resets;
>>> +	int			num_resets;
>>> +#endif
>>> +};
>>> +
>>> +#if CONFIG_IS_ENABLED(DM_RESET)
>>> +static int dwc3_of_simple_reset_init(struct udevice *dev,
>>> +				     struct dwc3_of_simple *simple,
>>> +				     int count)
>>> +{
>>> +	int i, ret, err;
>>> +
>>> +	if (!count)
>>> +		return 0;
>>> +
>>> +	simple->resets = devm_kcalloc(dev, count, sizeof(struct reset_ctl),
>>> +				      GFP_KERNEL);
>>> +	if (!simple->resets)
>>> +		return -ENOMEM;
>>> +
>>> +	for (i = 0; i < count; i++) {
>>> +		ret = reset_get_by_index(dev, i, &simple->resets[i]);
>>> +		if (ret < 0)
>>> +			break;
>>> +
>>> +		ret = reset_request(&simple->resets[i]);
>>> +		if (ret) {
>>> +			pr_err("failed to request reset line %d\n", i);
>>> +			reset_free(&simple->resets[i]);
>>> +			goto reset_err;
>>> +		}
>>> +
>>> +		
>>> +		++simple->num_resets;
>>> +	}
>>> +
>>> +	for (i = 0; i < simple->num_resets; i++) {
>>> +		ret = reset_deassert(&simple->resets[i]);
>>> +		if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
>>> +			pr_err("failed to deassert reset line %d\n", i);
>>> +			goto reset_err;
>>> +		}
>>> +	}
>>> +
>>> +	return 0;
>>
>> This looks like some driver I've seen before. Isn't there similar code
>> for simple EHCI or OHCI driver already ?
>>
> 
> Hi,
> 
> This is not an EHCI/OHCI driver, only the glue to init the clocks and reset,
> it's the exact same as the drivers/usb/dwc3/dwc3-of-simple.c adapted to U-Boot.
> 
> yes, similar code exists in drivers/usb/host/ehci-generic.c and
> drivers/usb/host/ohci-generic.c but the goal here is not to initialize the controller
> but only the glue.

Can't we recycle that code instead of having three copies of similar stuff ?

-- 
Best regards,
Marek Vasut

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

* [PATCH u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
  2018-03-29 14:24       ` Marek Vasut
@ 2018-03-29 14:27         ` Neil Armstrong
  2018-03-29 14:31           ` Marek Vasut
  0 siblings, 1 reply; 13+ messages in thread
From: Neil Armstrong @ 2018-03-29 14:27 UTC (permalink / raw)
  To: linus-amlogic

On 29/03/2018 16:24, Marek Vasut wrote:
> On 03/29/2018 04:23 PM, Neil Armstrong wrote:
>> On 29/03/2018 15:52, Marek Vasut wrote:
>>> On 03/29/2018 03:42 PM, Neil Armstrong wrote:
>>>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>>>> ---
>>>>  drivers/usb/host/Kconfig          |   7 ++
>>>>  drivers/usb/host/Makefile         |   1 +
>>>>  drivers/usb/host/dwc3-of-simple.c | 187 ++++++++++++++++++++++++++++++++++++++
>>>>  3 files changed, 195 insertions(+)
>>>>  create mode 100644 drivers/usb/host/dwc3-of-simple.c
>>>>
>>>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>>>> index a7249b7..6caa615 100644
>>>> --- a/drivers/usb/host/Kconfig
>>>> +++ b/drivers/usb/host/Kconfig
>>>> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
>>>>  	  Say Y or if your system has a Dual Role SuperSpeed
>>>>  	  USB controller based on the DesignWare USB3 IP Core.
>>>>  
>>>> +config USB_XHCI_DWC3_OF_SIMPLE
>>>> +	bool "DesignWare USB3 DRD Generic OF Simple Glue Layer"
>>>> +	select MISC
>>>> +	help
>>>> +	  Support USB2/3 functionality in simple SoC integrations with
>>>> +	  USB controller based on the DesignWare USB3 IP Core.
>>>> +
>>>>  config USB_XHCI_MVEBU
>>>>  	bool "MVEBU USB 3.0 support"
>>>>  	default y
>>>> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
>>>> index 9819489..abe4f90 100644
>>>> --- a/drivers/usb/host/Makefile
>>>> +++ b/drivers/usb/host/Makefile
>>>> @@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
>>>>  # xhci
>>>>  obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
>>>>  obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
>>>> +obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o
>>>>  obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
>>>>  obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o
>>>>  obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
>>>> diff --git a/drivers/usb/host/dwc3-of-simple.c b/drivers/usb/host/dwc3-of-simple.c
>>>> new file mode 100644
>>>> index 0000000..826a996
>>>> --- /dev/null
>>>> +++ b/drivers/usb/host/dwc3-of-simple.c
>>>> @@ -0,0 +1,187 @@
>>>> +/*
>>>> + * dwc3-of-simple.c - OF glue layer for simple integrations
>>>> + *
>>>> + * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
>>>> + *
>>>> + * Author: Felipe Balbi <balbi@ti.com>
>>>> + *
>>>> + * Copyright (C) 2018 BayLibre, SAS
>>>> + * Author: Neil Armstrong <narmstron@baylibre.com>
>>>> + *
>>>> + * SPDX-License-Identifier:     GPL-2.0+
>>>> + */
>>>> +
>>>> +#include <common.h>
>>>> +#include <dm.h>
>>>> +#include <fdtdec.h>
>>>> +#include <reset.h>
>>>> +#include <clk.h>
>>>> +
>>>> +DECLARE_GLOBAL_DATA_PTR;
>>>> +
>>>> +struct dwc3_of_simple {
>>>> +#if CONFIG_IS_ENABLED(CLK)
>>>> +	struct clk		*clks;
>>>> +	int			num_clocks;
>>>> +#endif
>>>> +#if CONFIG_IS_ENABLED(DM_RESET)
>>>> +	struct reset_ctl	*resets;
>>>> +	int			num_resets;
>>>> +#endif
>>>> +};
>>>> +
>>>> +#if CONFIG_IS_ENABLED(DM_RESET)
>>>> +static int dwc3_of_simple_reset_init(struct udevice *dev,
>>>> +				     struct dwc3_of_simple *simple,
>>>> +				     int count)
>>>> +{
>>>> +	int i, ret, err;
>>>> +
>>>> +	if (!count)
>>>> +		return 0;
>>>> +
>>>> +	simple->resets = devm_kcalloc(dev, count, sizeof(struct reset_ctl),
>>>> +				      GFP_KERNEL);
>>>> +	if (!simple->resets)
>>>> +		return -ENOMEM;
>>>> +
>>>> +	for (i = 0; i < count; i++) {
>>>> +		ret = reset_get_by_index(dev, i, &simple->resets[i]);
>>>> +		if (ret < 0)
>>>> +			break;
>>>> +
>>>> +		ret = reset_request(&simple->resets[i]);
>>>> +		if (ret) {
>>>> +			pr_err("failed to request reset line %d\n", i);
>>>> +			reset_free(&simple->resets[i]);
>>>> +			goto reset_err;
>>>> +		}
>>>> +
>>>> +		
>>>> +		++simple->num_resets;
>>>> +	}
>>>> +
>>>> +	for (i = 0; i < simple->num_resets; i++) {
>>>> +		ret = reset_deassert(&simple->resets[i]);
>>>> +		if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
>>>> +			pr_err("failed to deassert reset line %d\n", i);
>>>> +			goto reset_err;
>>>> +		}
>>>> +	}
>>>> +
>>>> +	return 0;
>>>
>>> This looks like some driver I've seen before. Isn't there similar code
>>> for simple EHCI or OHCI driver already ?
>>>
>>
>> Hi,
>>
>> This is not an EHCI/OHCI driver, only the glue to init the clocks and reset,
>> it's the exact same as the drivers/usb/dwc3/dwc3-of-simple.c adapted to U-Boot.
>>
>> yes, similar code exists in drivers/usb/host/ehci-generic.c and
>> drivers/usb/host/ohci-generic.c but the goal here is not to initialize the controller
>> but only the glue.
> 
> Can't we recycle that code instead of having three copies of similar stuff ?
> 

Sure, where should I put this code ? the clock and resets are stored in the driver's platdata.

Neil

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

* [PATCH u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
  2018-03-29 14:27         ` Neil Armstrong
@ 2018-03-29 14:31           ` Marek Vasut
  0 siblings, 0 replies; 13+ messages in thread
From: Marek Vasut @ 2018-03-29 14:31 UTC (permalink / raw)
  To: linus-amlogic

On 03/29/2018 04:27 PM, Neil Armstrong wrote:
> On 29/03/2018 16:24, Marek Vasut wrote:
>> On 03/29/2018 04:23 PM, Neil Armstrong wrote:
>>> On 29/03/2018 15:52, Marek Vasut wrote:
>>>> On 03/29/2018 03:42 PM, Neil Armstrong wrote:
>>>>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>>>>> ---
>>>>>  drivers/usb/host/Kconfig          |   7 ++
>>>>>  drivers/usb/host/Makefile         |   1 +
>>>>>  drivers/usb/host/dwc3-of-simple.c | 187 ++++++++++++++++++++++++++++++++++++++
>>>>>  3 files changed, 195 insertions(+)
>>>>>  create mode 100644 drivers/usb/host/dwc3-of-simple.c
>>>>>
>>>>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>>>>> index a7249b7..6caa615 100644
>>>>> --- a/drivers/usb/host/Kconfig
>>>>> +++ b/drivers/usb/host/Kconfig
>>>>> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
>>>>>  	  Say Y or if your system has a Dual Role SuperSpeed
>>>>>  	  USB controller based on the DesignWare USB3 IP Core.
>>>>>  
>>>>> +config USB_XHCI_DWC3_OF_SIMPLE
>>>>> +	bool "DesignWare USB3 DRD Generic OF Simple Glue Layer"
>>>>> +	select MISC
>>>>> +	help
>>>>> +	  Support USB2/3 functionality in simple SoC integrations with
>>>>> +	  USB controller based on the DesignWare USB3 IP Core.
>>>>> +
>>>>>  config USB_XHCI_MVEBU
>>>>>  	bool "MVEBU USB 3.0 support"
>>>>>  	default y
>>>>> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
>>>>> index 9819489..abe4f90 100644
>>>>> --- a/drivers/usb/host/Makefile
>>>>> +++ b/drivers/usb/host/Makefile
>>>>> @@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
>>>>>  # xhci
>>>>>  obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
>>>>>  obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
>>>>> +obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o
>>>>>  obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
>>>>>  obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o
>>>>>  obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
>>>>> diff --git a/drivers/usb/host/dwc3-of-simple.c b/drivers/usb/host/dwc3-of-simple.c
>>>>> new file mode 100644
>>>>> index 0000000..826a996
>>>>> --- /dev/null
>>>>> +++ b/drivers/usb/host/dwc3-of-simple.c
>>>>> @@ -0,0 +1,187 @@
>>>>> +/*
>>>>> + * dwc3-of-simple.c - OF glue layer for simple integrations
>>>>> + *
>>>>> + * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
>>>>> + *
>>>>> + * Author: Felipe Balbi <balbi@ti.com>
>>>>> + *
>>>>> + * Copyright (C) 2018 BayLibre, SAS
>>>>> + * Author: Neil Armstrong <narmstron@baylibre.com>
>>>>> + *
>>>>> + * SPDX-License-Identifier:     GPL-2.0+
>>>>> + */
>>>>> +
>>>>> +#include <common.h>
>>>>> +#include <dm.h>
>>>>> +#include <fdtdec.h>
>>>>> +#include <reset.h>
>>>>> +#include <clk.h>
>>>>> +
>>>>> +DECLARE_GLOBAL_DATA_PTR;
>>>>> +
>>>>> +struct dwc3_of_simple {
>>>>> +#if CONFIG_IS_ENABLED(CLK)
>>>>> +	struct clk		*clks;
>>>>> +	int			num_clocks;
>>>>> +#endif
>>>>> +#if CONFIG_IS_ENABLED(DM_RESET)
>>>>> +	struct reset_ctl	*resets;
>>>>> +	int			num_resets;
>>>>> +#endif
>>>>> +};
>>>>> +
>>>>> +#if CONFIG_IS_ENABLED(DM_RESET)
>>>>> +static int dwc3_of_simple_reset_init(struct udevice *dev,
>>>>> +				     struct dwc3_of_simple *simple,
>>>>> +				     int count)
>>>>> +{
>>>>> +	int i, ret, err;
>>>>> +
>>>>> +	if (!count)
>>>>> +		return 0;
>>>>> +
>>>>> +	simple->resets = devm_kcalloc(dev, count, sizeof(struct reset_ctl),
>>>>> +				      GFP_KERNEL);
>>>>> +	if (!simple->resets)
>>>>> +		return -ENOMEM;
>>>>> +
>>>>> +	for (i = 0; i < count; i++) {
>>>>> +		ret = reset_get_by_index(dev, i, &simple->resets[i]);
>>>>> +		if (ret < 0)
>>>>> +			break;
>>>>> +
>>>>> +		ret = reset_request(&simple->resets[i]);
>>>>> +		if (ret) {
>>>>> +			pr_err("failed to request reset line %d\n", i);
>>>>> +			reset_free(&simple->resets[i]);
>>>>> +			goto reset_err;
>>>>> +		}
>>>>> +
>>>>> +		
>>>>> +		++simple->num_resets;
>>>>> +	}
>>>>> +
>>>>> +	for (i = 0; i < simple->num_resets; i++) {
>>>>> +		ret = reset_deassert(&simple->resets[i]);
>>>>> +		if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
>>>>> +			pr_err("failed to deassert reset line %d\n", i);
>>>>> +			goto reset_err;
>>>>> +		}
>>>>> +	}
>>>>> +
>>>>> +	return 0;
>>>>
>>>> This looks like some driver I've seen before. Isn't there similar code
>>>> for simple EHCI or OHCI driver already ?
>>>>
>>>
>>> Hi,
>>>
>>> This is not an EHCI/OHCI driver, only the glue to init the clocks and reset,
>>> it's the exact same as the drivers/usb/dwc3/dwc3-of-simple.c adapted to U-Boot.
>>>
>>> yes, similar code exists in drivers/usb/host/ehci-generic.c and
>>> drivers/usb/host/ohci-generic.c but the goal here is not to initialize the controller
>>> but only the glue.
>>
>> Can't we recycle that code instead of having three copies of similar stuff ?
>>
> 
> Sure, where should I put this code ? the clock and resets are stored in the driver's platdata.

Something-common I guess ?

-- 
Best regards,
Marek Vasut

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

end of thread, other threads:[~2018-03-29 14:31 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-29 13:42 [PATCH u-boot 0/3] Add USB Support for Amlogic Meson GXL SoCs Neil Armstrong
2018-03-29 13:42 ` [PATCH u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration Neil Armstrong
2018-03-29 13:52   ` Marek Vasut
2018-03-29 14:23     ` Neil Armstrong
2018-03-29 14:24       ` Marek Vasut
2018-03-29 14:27         ` Neil Armstrong
2018-03-29 14:31           ` Marek Vasut
2018-03-29 13:42 ` [PATCH u-boot 2/3] usb: host: dwc3: Add support for multiple PHYs Neil Armstrong
2018-03-29 13:53   ` Marek Vasut
2018-03-29 14:23     ` Neil Armstrong
2018-03-29 13:42 ` [PATCH u-boot 3/3] phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers Neil Armstrong
2018-03-29 13:54   ` Marek Vasut
2018-03-29 14:24     ` Neil Armstrong

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

all inboxes | Powered by JetHome®