All of lore.kernel.org
 help / color / mirror / Atom feed
From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
To: Felipe Balbi <balbi@ti.com>
Cc: David Cohen <david.a.cohen@linux.intel.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Stephen Boyd <sboyd@codeaurora.org>,
	Baolu Lu <baolu.lu@linux.intel.com>,
	Paul Bolle <pebolle@tiscali.nl>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCHv3 10/12] usb: dwc3: add ULPI interface support
Date: Wed, 29 Apr 2015 11:30:31 +0300	[thread overview]
Message-ID: <1430296233-144245-3-git-send-email-heikki.krogerus@linux.intel.com> (raw)
In-Reply-To: <20150429082113.GC25288@kuha.fi.intel.com>

Registers DWC3's ULPI interface with the ULPI bus when it's
available.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: David Cohen <david.a.cohen@linux.intel.com>
---
 drivers/usb/dwc3/Kconfig  |  7 ++++
 drivers/usb/dwc3/Makefile |  4 +++
 drivers/usb/dwc3/core.c   | 19 +++++++++-
 drivers/usb/dwc3/core.h   | 14 ++++++++
 drivers/usb/dwc3/ulpi.c   | 91 +++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 134 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/dwc3/ulpi.c

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index 827c4f8..6f92b36 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -11,6 +11,13 @@ config USB_DWC3
 
 if USB_DWC3
 
+config USB_DWC3_ULPI
+	bool "Register ULPI PHY Interface"
+	depends on USB_ULPI_BUS
+	help
+	  Select this if you have ULPI type PHY attached to your DWC3
+	  controller.
+
 choice
 	bool "DWC3 Mode Selection"
 	default USB_DWC3_DUAL_ROLE if (USB && USB_GADGET)
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 46172f4..c7076e3 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -15,6 +15,10 @@ ifneq ($(filter y,$(CONFIG_USB_DWC3_GADGET) $(CONFIG_USB_DWC3_DUAL_ROLE)),)
 	dwc3-y				+= gadget.o ep0.o
 endif
 
+ifneq ($(CONFIG_USB_DWC3_ULPI),)
+	dwc3-y				+= ulpi.o
+endif
+
 ifneq ($(CONFIG_DEBUG_FS),)
 	dwc3-y				+= debugfs.o
 endif
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index fdeff5e..adff5ab 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -444,13 +444,28 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
 	case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
 		if (!strncmp(dwc->hsphy_interface, "utmi", 4)) {
 			reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
+			break;
 		} else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
 			reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
+			dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 		} else {
 			dev_warn(dwc->dev, "HSPHY Interface not defined\n");
-			break;
+
+			/* Relying on default value. */
+			if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI))
+				break;
 		}
 		/* FALLTHROUGH */
+	case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
+		/* Soft reset here to sync the clocks */
+		ret = dwc3_soft_reset(dwc);
+		if (ret)
+			return ret;
+
+		ret = dwc3_ulpi_init(dwc);
+		if (ret)
+			return ret;
+		/* FALLTHROUGH */
 	default:
 		break;
 	}
@@ -999,6 +1014,7 @@ err2:
 
 err1:
 	dwc3_free_event_buffers(dwc);
+	dwc3_ulpi_exit(dwc);
 
 err0:
 	/*
@@ -1034,6 +1050,7 @@ static int dwc3_remove(struct platform_device *pdev)
 	phy_power_off(dwc->usb3_generic_phy);
 
 	dwc3_core_exit(dwc);
+	dwc3_ulpi_exit(dwc);
 
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 7b3ab64..d70da20 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -30,6 +30,7 @@
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/otg.h>
+#include <linux/ulpi/interface.h>
 
 #include <linux/phy/phy.h>
 
@@ -661,6 +662,7 @@ struct dwc3_scratchpad_array {
  * @usb3_phy: pointer to USB3 PHY
  * @usb2_generic_phy: pointer to USB2 PHY
  * @usb3_generic_phy: pointer to USB3 PHY
+ * @ulpi: pointer to ulpi interface
  * @dcfg: saved contents of DCFG register
  * @gctl: saved contents of GCTL register
  * @isoch_delay: wValue from Set Isochronous Delay request;
@@ -749,6 +751,8 @@ struct dwc3 {
 	struct phy		*usb2_generic_phy;
 	struct phy		*usb3_generic_phy;
 
+	struct ulpi		*ulpi;
+
 	void __iomem		*regs;
 	size_t			regs_size;
 
@@ -1047,4 +1051,14 @@ static inline int dwc3_gadget_resume(struct dwc3 *dwc)
 }
 #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */
 
+#if IS_ENABLED(CONFIG_USB_DWC3_ULPI)
+int dwc3_ulpi_init(struct dwc3 *dwc);
+void dwc3_ulpi_exit(struct dwc3 *dwc);
+#else
+static inline int dwc3_ulpi_init(struct dwc3 *dwc)
+{ return 0; }
+static inline void dwc3_ulpi_exit(struct dwc3 *dwc)
+{ }
+#endif
+
 #endif /* __DRIVERS_USB_DWC3_CORE_H */
diff --git a/drivers/usb/dwc3/ulpi.c b/drivers/usb/dwc3/ulpi.c
new file mode 100644
index 0000000..4dfcc81
--- /dev/null
+++ b/drivers/usb/dwc3/ulpi.c
@@ -0,0 +1,91 @@
+/**
+ * ulpi.c - DesignWare USB3 Controller's ULPI PHY interface
+ *
+ * Copyright (C) 2015 Intel Corporation
+ *
+ * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/ulpi/regs.h>
+
+#include "core.h"
+#include "io.h"
+
+#define DWC3_ULPI_ADDR(a) \
+		((a >= ULPI_EXT_VENDOR_SPECIFIC) ? \
+		DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \
+		DWC3_GUSB2PHYACC_EXTEND_ADDR(a) : DWC3_GUSB2PHYACC_ADDR(a))
+
+static int dwc3_ulpi_busyloop(struct dwc3 *dwc)
+{
+	unsigned count = 1000;
+	u32 reg;
+
+	while (count--) {
+		reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0));
+		if (!(reg & DWC3_GUSB2PHYACC_BUSY))
+			return 0;
+		cpu_relax();
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int dwc3_ulpi_read(struct ulpi_ops *ops, u8 addr)
+{
+	struct dwc3 *dwc = dev_get_drvdata(ops->dev);
+	u32 reg;
+	int ret;
+
+	reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
+	dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
+
+	ret = dwc3_ulpi_busyloop(dwc);
+	if (ret)
+		return ret;
+
+	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0));
+
+	return DWC3_GUSB2PHYACC_DATA(reg);
+}
+
+static int dwc3_ulpi_write(struct ulpi_ops *ops, u8 addr, u8 val)
+{
+	struct dwc3 *dwc = dev_get_drvdata(ops->dev);
+	u32 reg;
+
+	reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
+	reg |= DWC3_GUSB2PHYACC_WRITE | val;
+	dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
+
+	return dwc3_ulpi_busyloop(dwc);
+}
+
+static struct ulpi_ops dwc3_ulpi = {
+	.read = dwc3_ulpi_read,
+	.write = dwc3_ulpi_write,
+};
+
+int dwc3_ulpi_init(struct dwc3 *dwc)
+{
+	/* Register the interface */
+	dwc->ulpi = ulpi_register_interface(dwc->dev, &dwc3_ulpi);
+	if (IS_ERR(dwc->ulpi)) {
+		dev_err(dwc->dev, "failed to register ULPI interface");
+		return PTR_ERR(dwc->ulpi);
+	}
+
+	return 0;
+}
+
+void dwc3_ulpi_exit(struct dwc3 *dwc)
+{
+	if (dwc->ulpi) {
+		ulpi_unregister_interface(dwc->ulpi);
+		dwc->ulpi = NULL;
+	}
+}
-- 
2.1.4


  parent reply	other threads:[~2015-04-29  8:30 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-28 13:24 [PATCHv3 00/12] usb: ulpi bus Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 01/11] usb: add bus type for USB ULPI Heikki Krogerus
2015-04-29 20:13   ` Felipe Balbi
2015-04-30 10:37     ` Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 02/11] usb: dwc3: USB2 PHY register access bits Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 03/11] usb: dwc3: ULPI or UTMI+ select Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 04/11] usb: dwc3: store driver data earlier Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 05/11] usb: dwc3: cache hwparams earlier Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 06/11] usb: dwc3: soft reset to it's own function Heikki Krogerus
2015-04-28 17:22   ` Felipe Balbi
2015-04-29  8:16     ` Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 07/11] usb: dwc3: setup phys earlier Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 08/11] usb: dwc3: add hsphy_interface property Heikki Krogerus
2015-04-28 17:13   ` Felipe Balbi
2015-04-29  8:04     ` Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 09/11] usb: dwc3: pci: add quirk for Baytrails Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 10/11] phy: helpers for USB ULPI PHY registering Heikki Krogerus
2015-04-28 13:24 ` [PATCHv3 11/11] phy: add driver for TI TUSB1210 ULPI PHY Heikki Krogerus
2015-04-28 17:17 ` [PATCHv3 00/12] usb: ulpi bus Felipe Balbi
2015-04-29  8:21   ` Heikki Krogerus
2015-04-29  8:30     ` [PATCHv3 08/12] usb: dwc3: add hsphy_interface property Heikki Krogerus
2015-04-29 15:03       ` Felipe Balbi
2015-04-30 10:33         ` Heikki Krogerus
2015-04-29  8:30     ` [PATCHv3 09/12] usb: dwc3: pci: add quirk for Baytrails Heikki Krogerus
2015-04-29  8:30     ` Heikki Krogerus [this message]
2015-04-29 15:04       ` [PATCHv3 10/12] usb: dwc3: add ULPI interface support Felipe Balbi
2015-04-30 10:34         ` Heikki Krogerus
2015-04-30 14:54           ` Felipe Balbi
2015-05-04 12:03             ` Heikki Krogerus
2015-05-05 15:02               ` Felipe Balbi
2015-04-29  8:30     ` [PATCHv3 11/12] phy: helpers for USB ULPI PHY registering Heikki Krogerus
2015-04-29  8:30     ` [PATCHv3 12/12] phy: add driver for TI TUSB1210 ULPI PHY Heikki Krogerus
  -- strict thread matches above, loose matches on Subject: below --
2015-03-19 11:48 [PATCHv2 10/12] usb: dwc3: add ULPI interface support Heikki Krogerus
2015-03-20 12:20 ` [PATCHv3 " Heikki Krogerus

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=1430296233-144245-3-git-send-email-heikki.krogerus@linux.intel.com \
    --to=heikki.krogerus@linux.intel.com \
    --cc=balbi@ti.com \
    --cc=baolu.lu@linux.intel.com \
    --cc=david.a.cohen@linux.intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=pebolle@tiscali.nl \
    --cc=sboyd@codeaurora.org \
    /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.