All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jean-Jacques Hiblot <jjhiblot@ti.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v3 7/8] dwc3-generic: Handle the PHYs, the clocks and the reset lines
Date: Tue, 25 Sep 2018 11:03:22 +0200	[thread overview]
Message-ID: <1537866203-7717-8-git-send-email-jjhiblot@ti.com> (raw)
In-Reply-To: <1537866203-7717-1-git-send-email-jjhiblot@ti.com>

This make the driver more generic. At this point this driver can replace
the dwc3-of-simple implementation.
Make the description in the Kconfig more generic too.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
---

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc3/Kconfig        |   7 +-
 drivers/usb/dwc3/dwc3-generic.c | 160 +++++++++++++++++++++++++++++++++-------
 2 files changed, 137 insertions(+), 30 deletions(-)

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index 943b763..bbd8105 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -38,10 +38,11 @@ config USB_DWC3_OMAP
 	  Say 'Y' here if you have one such device
 
 config USB_DWC3_GENERIC
-	bool "Xilinx ZynqMP and similar Platforms"
-	depends on DM_USB && USB_DWC3
+	bool "Generic implementation of a DWC3 wrapper (aka dwc3 glue)"
+	depends on DM_USB && USB_DWC3 && MISC
 	help
-	  Some platforms can reuse this DWC3 generic implementation.
+	  Select this for Xilinx ZynqMP and similar Platforms.
+	  This wrapper supports Host and Peripheral operation modes.
 
 config USB_DWC3_UNIPHIER
 	bool "DesignWare USB3 Host Support on UniPhier Platforms"
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 3ec0c0e..2c27dbc 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -11,59 +11,86 @@
 #include <dm.h>
 #include <dm/device-internal.h>
 #include <dm/lists.h>
-#include <linux/usb/otg.h>
-#include <linux/compat.h>
+#include <dwc3-uboot.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <malloc.h>
 #include <usb.h>
 #include "core.h"
 #include "gadget.h"
-#include "linux-compat.h"
+#include <reset.h>
+#include <clk.h>
 
 #ifdef CONFIG_DM_USB_DEV
 
+struct dwc3_generic_peripheral {
+	struct dwc3 dwc3;
+	struct phy *phys;
+	int num_phys;
+	fdt_addr_t base;
+};
+
 int dm_usb_gadget_handle_interrupts(struct udevice *dev)
 {
-	struct dwc3 *priv = dev_get_priv(dev);
+	struct dwc3_generic_peripheral *priv = dev_get_priv(dev);
+	struct dwc3 *dwc3 = &priv->dwc3;
 
-	dwc3_gadget_uboot_handle_interrupt(priv);
+	dwc3_gadget_uboot_handle_interrupt(dwc3);
 
 	return 0;
 }
 
 static int dwc3_generic_peripheral_probe(struct udevice *dev)
 {
-	struct dwc3 *priv = dev_get_priv(dev);
+	int rc;
+	struct dwc3_generic_peripheral *priv = dev_get_priv(dev);
+	struct dwc3 *dwc3 = &priv->dwc3;
+
+	rc = dwc3_setup_phy(dev, &priv->phys, &priv->num_phys);
+	if (rc)
+		return rc;
+
+	dwc3->regs = map_physmem(priv->base, DWC3_OTG_REGS_END, MAP_NOCACHE);
+	dwc3->regs += DWC3_GLOBALS_REGS_START;
+	dwc3->dev = dev;
+
+	rc =  dwc3_init(dwc3);
+	if (rc) {
+		unmap_physmem(dwc3->regs, MAP_NOCACHE);
+		return rc;
+	}
 
-	return dwc3_init(priv);
+	return 0;
 }
 
 static int dwc3_generic_peripheral_remove(struct udevice *dev)
 {
-	struct dwc3 *priv = dev_get_priv(dev);
+	struct dwc3_generic_peripheral *priv = dev_get_priv(dev);
+	struct dwc3 *dwc3 = &priv->dwc3;
 
-	dwc3_remove(priv);
+	dwc3_remove(dwc3);
+	dwc3_shutdown_phy(dev, priv->phys, priv->num_phys);
+	unmap_physmem(dwc3->regs, MAP_NOCACHE);
 
 	return 0;
 }
 
 static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice *dev)
 {
-	struct dwc3 *priv = dev_get_priv(dev);
+	struct dwc3_generic_peripheral *priv = dev_get_priv(dev);
+	struct dwc3 *dwc3 = &priv->dwc3;
 	int node = dev_of_offset(dev);
 
-	priv->regs = (void *)devfdt_get_addr(dev);
-	priv->regs += DWC3_GLOBALS_REGS_START;
+	priv->base = devfdt_get_addr(dev);
 
-	priv->maximum_speed = usb_get_maximum_speed(node);
-	if (priv->maximum_speed == USB_SPEED_UNKNOWN) {
+	dwc3->maximum_speed = usb_get_maximum_speed(node);
+	if (dwc3->maximum_speed == USB_SPEED_UNKNOWN) {
 		pr_err("Invalid usb maximum speed\n");
 		return -ENODEV;
 	}
 
-	priv->dr_mode = usb_get_dr_mode(node);
-	if (priv->dr_mode == USB_DR_MODE_UNKNOWN) {
+	dwc3->dr_mode = usb_get_dr_mode(node);
+	if (dwc3->dr_mode == USB_DR_MODE_UNKNOWN) {
 		pr_err("Invalid usb mode setup\n");
 		return -ENODEV;
 	}
@@ -77,13 +104,16 @@ U_BOOT_DRIVER(dwc3_generic_peripheral) = {
 	.ofdata_to_platdata = dwc3_generic_peripheral_ofdata_to_platdata,
 	.probe = dwc3_generic_peripheral_probe,
 	.remove = dwc3_generic_peripheral_remove,
-	.platdata_auto_alloc_size = sizeof(struct usb_platdata),
-	.priv_auto_alloc_size = sizeof(struct dwc3),
+	.priv_auto_alloc_size = sizeof(struct dwc3_generic_peripheral),
 };
-
 #endif
 
-static int dwc3_generic_bind(struct udevice *parent)
+struct dwc3_glue_data {
+	struct clk_bulk		clks;
+	struct reset_ctl_bulk	resets;
+};
+
+static int dwc3_glue_bind(struct udevice *parent)
 {
 	const void *fdt = gd->fdt_blob;
 	int node;
@@ -94,29 +124,32 @@ static int dwc3_generic_bind(struct udevice *parent)
 		const char *name = fdt_get_name(fdt, node, NULL);
 		enum usb_dr_mode dr_mode;
 		struct udevice *dev;
-		const char *driver;
+		const char *driver = NULL;
 
 		debug("%s: subnode name: %s\n", __func__, name);
-		if (strncmp(name, "dwc3@", 4))
-			continue;
 
 		dr_mode = usb_get_dr_mode(node);
 
 		switch (dr_mode) {
 		case USB_DR_MODE_PERIPHERAL:
 		case USB_DR_MODE_OTG:
+#ifdef CONFIG_DM_USB_DEV
 			debug("%s: dr_mode: OTG or Peripheral\n", __func__);
 			driver = "dwc3-generic-peripheral";
+#endif
 			break;
 		case USB_DR_MODE_HOST:
 			debug("%s: dr_mode: HOST\n", __func__);
-			driver = "dwc3-generic-host";
+			driver = "xhci-dwc3";
 			break;
 		default:
 			debug("%s: unsupported dr_mode\n", __func__);
 			return -ENODEV;
 		};
 
+		if (!driver)
+			continue;
+
 		ret = device_bind_driver_to_node(parent, driver, name,
 						 offset_to_ofnode(node), &dev);
 		if (ret) {
@@ -129,7 +162,76 @@ static int dwc3_generic_bind(struct udevice *parent)
 	return 0;
 }
 
-static const struct udevice_id dwc3_generic_ids[] = {
+static int dwc3_glue_reset_init(struct udevice *dev,
+				struct dwc3_glue_data *glue)
+{
+	int ret;
+
+	ret = reset_get_bulk(dev, &glue->resets);
+	if (ret == -ENOTSUPP)
+		return 0;
+	else if (ret)
+		return ret;
+
+	ret = reset_deassert_bulk(&glue->resets);
+	if (ret) {
+		reset_release_bulk(&glue->resets);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int dwc3_glue_clk_init(struct udevice *dev,
+			      struct dwc3_glue_data *glue)
+{
+	int ret;
+
+	ret = clk_get_bulk(dev, &glue->clks);
+	if (ret == -ENOSYS)
+		return 0;
+	if (ret)
+		return ret;
+
+#if CONFIG_IS_ENABLED(CLK)
+	ret = clk_enable_bulk(&glue->clks);
+	if (ret) {
+		clk_release_bulk(&glue->clks);
+		return ret;
+	}
+#endif
+
+	return 0;
+}
+
+static int dwc3_glue_probe(struct udevice *dev)
+{
+	struct dwc3_glue_data *glue = dev_get_platdata(dev);
+	int ret;
+
+	ret = dwc3_glue_clk_init(dev, glue);
+	if (ret)
+		return ret;
+
+	ret = dwc3_glue_reset_init(dev, glue);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int dwc3_glue_remove(struct udevice *dev)
+{
+	struct dwc3_glue_data *glue = dev_get_platdata(dev);
+
+	reset_release_bulk(&glue->resets);
+
+	clk_release_bulk(&glue->clks);
+
+	return dm_scan_fdt_dev(dev);
+}
+
+static const struct udevice_id dwc3_glue_ids[] = {
 	{ .compatible = "xlnx,zynqmp-dwc3" },
 	{ }
 };
@@ -137,6 +239,10 @@ static const struct udevice_id dwc3_generic_ids[] = {
 U_BOOT_DRIVER(dwc3_generic_wrapper) = {
 	.name	= "dwc3-generic-wrapper",
 	.id	= UCLASS_MISC,
-	.of_match = dwc3_generic_ids,
-	.bind = dwc3_generic_bind,
+	.of_match = dwc3_glue_ids,
+	.bind = dwc3_glue_bind,
+	.probe = dwc3_glue_probe,
+	.remove = dwc3_glue_remove,
+	.platdata_auto_alloc_size = sizeof(struct dwc3_glue_data),
+
 };
-- 
2.7.4

  parent reply	other threads:[~2018-09-25  9:03 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-25  9:03 [U-Boot] [PATCH v3 0/8] Improvements for the dwc3_generic driver Jean-Jacques Hiblot
2018-09-25  9:03 ` [U-Boot] [PATCH v3 1/8] usb: gadget: Do not call board_usb_xxx() directly in USB gadget drivers Jean-Jacques Hiblot
2018-09-25  9:03 ` [U-Boot] [PATCH v3 2/8] usb: introduce a separate config option for DM USB device Jean-Jacques Hiblot
2018-09-25  9:03 ` [U-Boot] [PATCH v3 3/8] usb: udc: implement DM versions of usb_gadget_initialize()/_release()/_handle_interrupt() Jean-Jacques Hiblot
2018-09-25  9:03 ` [U-Boot] [PATCH v3 4/8] dwc3_generic: do not probe the USB device driver when it's bound Jean-Jacques Hiblot
2018-09-25  9:03 ` [U-Boot] [PATCH v3 5/8] dwc3: move phy operation to core.c Jean-Jacques Hiblot
2018-09-25  9:03 ` [U-Boot] [PATCH v3 6/8] configs: evb-rk3328: Enable CONFIG_USB_DWC3 Jean-Jacques Hiblot
2018-09-25  9:03 ` Jean-Jacques Hiblot [this message]
2018-09-25  9:03 ` [U-Boot] [PATCH v3 8/8] dwc3-generic: Add select_dr_mode operation Jean-Jacques Hiblot
2018-09-25 11:28 ` [U-Boot] [PATCH v3 0/8] Improvements for the dwc3_generic driver Lukasz Majewski
2018-10-01 12:51   ` Lukasz Majewski
2018-10-01 13:26     ` Philipp Tomsich
2018-10-08  2:07       ` Kever Yang
2018-10-22 10:45         ` Jean-Jacques Hiblot
2018-10-09 14:29 ` Loic Devulder
2018-10-22 15:55   ` Jean-Jacques Hiblot
2018-10-22 16:16     ` Lukasz Majewski
2018-10-22 16:24       ` Jean-Jacques Hiblot
2018-10-26 10:25         ` Jean-Jacques Hiblot
2018-10-28 20:50           ` Lukasz Majewski
2018-11-01  9:27             ` Michal Simek
2018-11-01 15:56               ` Lukasz Majewski
2018-11-01 16:06                 ` Tom Rini
2018-11-01 16:55                   ` Lukasz Majewski
2018-11-16 14:49                     ` Jean-Jacques Hiblot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1537866203-7717-8-git-send-email-jjhiblot@ti.com \
    --to=jjhiblot@ti.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.