linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] Make dwc3 use Generic PHY Framework and misc cleanup
@ 2013-09-02 15:43 Kishon Vijay Abraham I
  2013-09-02 15:43 ` [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY Kishon Vijay Abraham I
                   ` (6 more replies)
  0 siblings, 7 replies; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-02 15:43 UTC (permalink / raw)
  To: rogerq, kishon, balbi
  Cc: bcousson, tony, rob.herring, pawel.moll, mark.rutland, linux,
	grant.likely, s.nawrocki, galak, swarren, ian.campbell, rob,
	george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Modified dwc3 core to find PHYs only if the platform indicates that it has
to use a PHY. Adapted DWC3 and USB3 PHY to use Generic PHY framework. Also
changed the name of USB3 PHY driver to PIPE3 PHY driver since the same driver
has to be used for SATA and PCIE too.

This series also includes a bunch of misc cleanups and also renamed
omap_control_usb to omap_control_phy (done on top of rogers patches [1])

Did g_zero enumeration testing on OMAP4 PANDA and did xhci testing in
OMAP5 uEvm.

I have pushed this branch to http://git.gitorious.org/linuxphy/linuxphy.git
dwc3_generic_phy

[1] -> git://github.com/rogerq/linux.git usb-control-module

Kishon Vijay Abraham I (7):
  usb: dwc3: get "usb_phy" only if the platform indicates the presence
    of PHY
  usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  drivers: phy: usb3/pipe3: Adapt pipe3 driver to Generic PHY Framework
  Documentation: dt bindings: move ..usb/usb-phy.txt to
    ..phy/omap-phy.txt
  phy: omap-usb2: move omap_usb.h from linux/usb/ to linux/phy/
  arm/dts: added dt properties to adapt to the new phy framwork
  drivers: phy: renamed struct omap_control_usb to struct
    omap_control_phy

 .../bindings/{usb/usb-phy.txt => phy/omap-phy.txt} |    7 +-
 Documentation/devicetree/bindings/usb/dwc3.txt     |    6 +-
 arch/arm/boot/dts/omap5.dtsi                       |    5 +-
 drivers/phy/Kconfig                                |   22 +-
 drivers/phy/Makefile                               |    2 +
 drivers/{usb => }/phy/phy-omap-control.c           |  164 +++++++--------
 .../phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c}   |  212 +++++++++++---------
 drivers/phy/phy-omap-usb2.c                        |   10 +-
 drivers/usb/dwc3/Kconfig                           |    2 +
 drivers/usb/dwc3/core.c                            |  109 ++++++----
 drivers/usb/dwc3/core.h                            |    7 +
 drivers/usb/dwc3/platform_data.h                   |    1 +
 drivers/usb/musb/omap2430.c                        |    2 +-
 drivers/usb/phy/Kconfig                            |   11 -
 drivers/usb/phy/Makefile                           |    2 -
 drivers/usb/phy/phy-twl6030-usb.c                  |    2 +-
 .../omap_control_usb.h => phy/omap_control_phy.h}  |   32 +--
 include/linux/{usb/omap_usb.h => phy/omap_pipe3.h} |   33 +--
 include/linux/{usb => phy}/omap_usb.h              |    3 -
 19 files changed, 348 insertions(+), 284 deletions(-)
 rename Documentation/devicetree/bindings/{usb/usb-phy.txt => phy/omap-phy.txt} (88%)
 rename drivers/{usb => }/phy/phy-omap-control.c (55%)
 rename drivers/{usb/phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c} (55%)
 rename include/linux/{usb/omap_control_usb.h => phy/omap_control_phy.h} (69%)
 copy include/linux/{usb/omap_usb.h => phy/omap_pipe3.h} (52%)
 rename include/linux/{usb => phy}/omap_usb.h (95%)

-- 
1.7.10.4


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

* [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY
  2013-09-02 15:43 [PATCH 0/7] Make dwc3 use Generic PHY Framework and misc cleanup Kishon Vijay Abraham I
@ 2013-09-02 15:43 ` Kishon Vijay Abraham I
  2013-09-12 10:36   ` Roger Quadros
  2013-09-02 15:43 ` [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework Kishon Vijay Abraham I
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-02 15:43 UTC (permalink / raw)
  To: rogerq, kishon, balbi
  Cc: bcousson, tony, rob.herring, pawel.moll, mark.rutland, linux,
	grant.likely, s.nawrocki, galak, swarren, ian.campbell, rob,
	george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

There can be systems which does not have a external usb_phy, so get
usb_phy only if usb-phy property is added in the case of dt boot or if
platform_data indicates the presence of PHY. Also remove checking if
return value is -ENXIO since it's now changed to always enable usb_phy layer.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/usb/dwc3/Kconfig         |    1 +
 drivers/usb/dwc3/core.c          |   60 +++++++++++++++++---------------------
 drivers/usb/dwc3/platform_data.h |    1 +
 3 files changed, 28 insertions(+), 34 deletions(-)

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index f969ea2..cfc16dd 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -2,6 +2,7 @@ config USB_DWC3
 	tristate "DesignWare USB3 DRD Core Support"
 	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
 	depends on EXTCON
+	select USB_PHY
 	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
 	help
 	  Say Y or M here if your system has a Dual Role SuperSpeed
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 474162e..428c29e 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -387,16 +387,38 @@ static int dwc3_probe(struct platform_device *pdev)
 	if (node) {
 		dwc->maximum_speed = of_usb_get_maximum_speed(node);
 
-		dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
-		dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
+		if (of_property_read_bool(node, "usb-phy")) {
+			dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev,
+				"usb-phy", 0);
+			if (IS_ERR(dwc->usb2_phy))
+				return PTR_ERR(dwc->usb2_phy);
+			dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev,
+				"usb-phy", 1);
+			if (IS_ERR(dwc->usb3_phy))
+				return PTR_ERR(dwc->usb3_phy);
+		} else {
+			dwc->usb2_phy = NULL;
+			dwc->usb3_phy = NULL;
+		}
 
 		dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
 		dwc->dr_mode = of_usb_get_dr_mode(node);
 	} else if (pdata) {
 		dwc->maximum_speed = pdata->maximum_speed;
 
-		dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
-		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
+		if (pdata->has_phy) {
+			dwc->usb2_phy = devm_usb_get_phy(dev,
+				USB_PHY_TYPE_USB2);
+			if (IS_ERR(dwc->usb2_phy))
+				return PTR_ERR(dwc->usb2_phy);
+			dwc->usb3_phy = devm_usb_get_phy(dev,
+				USB_PHY_TYPE_USB3);
+			if (IS_ERR(dwc->usb3_phy))
+				return PTR_ERR(dwc->usb3_phy);
+		} else {
+			dwc->usb2_phy = NULL;
+			dwc->usb3_phy = NULL;
+		}
 
 		dwc->needs_fifo_resize = pdata->tx_fifo_resize;
 		dwc->dr_mode = pdata->dr_mode;
@@ -409,36 +431,6 @@ static int dwc3_probe(struct platform_device *pdev)
 	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
 		dwc->maximum_speed = USB_SPEED_SUPER;
 
-	if (IS_ERR(dwc->usb2_phy)) {
-		ret = PTR_ERR(dwc->usb2_phy);
-
-		/*
-		 * if -ENXIO is returned, it means PHY layer wasn't
-		 * enabled, so it makes no sense to return -EPROBE_DEFER
-		 * in that case, since no PHY driver will ever probe.
-		 */
-		if (ret == -ENXIO)
-			return ret;
-
-		dev_err(dev, "no usb2 phy configured\n");
-		return -EPROBE_DEFER;
-	}
-
-	if (IS_ERR(dwc->usb3_phy)) {
-		ret = PTR_ERR(dwc->usb3_phy);
-
-		/*
-		 * if -ENXIO is returned, it means PHY layer wasn't
-		 * enabled, so it makes no sense to return -EPROBE_DEFER
-		 * in that case, since no PHY driver will ever probe.
-		 */
-		if (ret == -ENXIO)
-			return ret;
-
-		dev_err(dev, "no usb3 phy configured\n");
-		return -EPROBE_DEFER;
-	}
-
 	dwc->xhci_resources[0].start = res->start;
 	dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
 					DWC3_XHCI_REGS_END;
diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
index 7db34f0..5a5e068 100644
--- a/drivers/usb/dwc3/platform_data.h
+++ b/drivers/usb/dwc3/platform_data.h
@@ -24,4 +24,5 @@ struct dwc3_platform_data {
 	enum usb_device_speed maximum_speed;
 	enum usb_dr_mode dr_mode;
 	bool tx_fifo_resize;
+	bool has_phy;
 };
-- 
1.7.10.4


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

* [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-09-02 15:43 [PATCH 0/7] Make dwc3 use Generic PHY Framework and misc cleanup Kishon Vijay Abraham I
  2013-09-02 15:43 ` [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY Kishon Vijay Abraham I
@ 2013-09-02 15:43 ` Kishon Vijay Abraham I
  2013-09-12  9:27   ` Vivek Gautam
                     ` (2 more replies)
  2013-09-02 15:43 ` [PATCH 3/7] drivers: phy: usb3/pipe3: Adapt pipe3 driver to " Kishon Vijay Abraham I
                   ` (4 subsequent siblings)
  6 siblings, 3 replies; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-02 15:43 UTC (permalink / raw)
  To: rogerq, kishon, balbi
  Cc: bcousson, tony, rob.herring, pawel.moll, mark.rutland, linux,
	grant.likely, s.nawrocki, galak, swarren, ian.campbell, rob,
	george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
power_on and power_off the following APIs are used phy_init(), phy_exit(),
phy_power_on() and phy_power_off().

However using the old USB phy library wont be removed till the PHYs of all
other SoC's using dwc3 core is adapted to the Generic PHY Framework.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
 drivers/usb/dwc3/Kconfig                       |    1 +
 drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
 drivers/usb/dwc3/core.h                        |    7 ++++
 4 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
index e807635..471366d 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -6,11 +6,13 @@ Required properties:
  - compatible: must be "snps,dwc3"
  - reg : Address and length of the register set for the device
  - interrupts: Interrupts used by the dwc3 controller.
+
+Optional properties:
  - usb-phy : array of phandle for the PHY device.  The first element
    in the array is expected to be a handle to the USB2/HS PHY and
    the second element is expected to be a handle to the USB3/SS PHY
-
-Optional properties:
+ - phys: from the *Generic PHY* bindings
+ - phy-names: from the *Generic PHY* bindings
  - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
 
 This is usually a subnode to DWC3 glue to which it is connected.
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index cfc16dd..ad7ce83 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -3,6 +3,7 @@ config USB_DWC3
 	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
 	depends on EXTCON
 	select USB_PHY
+	select GENERIC_PHY
 	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
 	help
 	  Say Y or M here if your system has a Dual Role SuperSpeed
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 428c29e..485d365 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
 
 	usb_phy_init(dwc->usb2_phy);
 	usb_phy_init(dwc->usb3_phy);
+
+	if (dwc->usb2_generic_phy)
+		phy_init(dwc->usb2_generic_phy);
+	if (dwc->usb3_generic_phy)
+		phy_init(dwc->usb3_generic_phy);
+
 	mdelay(100);
 
 	/* Clear USB3 PHY reset */
@@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
 {
 	usb_phy_shutdown(dwc->usb2_phy);
 	usb_phy_shutdown(dwc->usb3_phy);
+
+	if (dwc->usb2_generic_phy)
+		phy_power_off(dwc->usb2_generic_phy);
+	if (dwc->usb3_generic_phy)
+		phy_power_off(dwc->usb3_generic_phy);
 }
 
 #define DWC3_ALIGN_MASK		(16 - 1)
@@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
 		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
 	}
 
+	if (of_property_read_bool(node, "phys") || pdata->has_phy) {
+		dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
+		if (IS_ERR(dwc->usb2_generic_phy)) {
+			dev_err(dev, "no usb2 phy configured yet");
+			return PTR_ERR(dwc->usb2_generic_phy);
+		}
+
+		dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
+		if (IS_ERR(dwc->usb3_generic_phy)) {
+			dev_err(dev, "no usb3 phy configured yet");
+			return PTR_ERR(dwc->usb3_generic_phy);
+		}
+	} else {
+		dwc->usb2_generic_phy = NULL;
+		dwc->usb3_generic_phy = NULL;
+	}
+
 	/* default to superspeed if no maximum_speed passed */
 	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
 		dwc->maximum_speed = USB_SPEED_SUPER;
@@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)
 	usb_phy_set_suspend(dwc->usb2_phy, 0);
 	usb_phy_set_suspend(dwc->usb3_phy, 0);
 
+	if (dwc->usb2_generic_phy)
+		phy_power_on(dwc->usb2_generic_phy);
+	if (dwc->usb3_generic_phy)
+		phy_power_on(dwc->usb3_generic_phy);
+
 	spin_lock_init(&dwc->lock);
 	platform_set_drvdata(pdev, dwc);
 
@@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)
 	usb_phy_set_suspend(dwc->usb2_phy, 1);
 	usb_phy_set_suspend(dwc->usb3_phy, 1);
 
+	if (dwc->usb2_generic_phy)
+		phy_power_off(dwc->usb2_generic_phy);
+	if (dwc->usb3_generic_phy)
+		phy_power_off(dwc->usb3_generic_phy);
+
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
@@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)
 	usb_phy_shutdown(dwc->usb3_phy);
 	usb_phy_shutdown(dwc->usb2_phy);
 
+	if (dwc->usb2_generic_phy)
+		phy_exit(dwc->usb2_generic_phy);
+	if (dwc->usb3_generic_phy)
+		phy_exit(dwc->usb3_generic_phy);
+
 	return 0;
 }
 
@@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
 
 	usb_phy_init(dwc->usb3_phy);
 	usb_phy_init(dwc->usb2_phy);
+
+	if (dwc->usb2_generic_phy)
+		phy_init(dwc->usb2_generic_phy);
+	if (dwc->usb3_generic_phy)
+		phy_init(dwc->usb3_generic_phy);
+
 	msleep(100);
 
 	spin_lock_irqsave(&dwc->lock, flags);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index f8af8d4..01ec7d7 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -31,6 +31,8 @@
 #include <linux/usb/gadget.h>
 #include <linux/usb/otg.h>
 
+#include <linux/phy/phy.h>
+
 /* Global constants */
 #define DWC3_EP0_BOUNCE_SIZE	512
 #define DWC3_ENDPOINTS_NUM	32
@@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
  * @dr_mode: requested mode of operation
  * @usb2_phy: pointer to USB2 PHY
  * @usb3_phy: pointer to USB3 PHY
+ * @usb2_generic_phy: pointer to USB2 PHY
+ * @usb3_generic_phy: pointer to USB3 PHY
  * @dcfg: saved contents of DCFG register
  * @gctl: saved contents of GCTL register
  * @is_selfpowered: true when we are selfpowered
@@ -665,6 +669,9 @@ struct dwc3 {
 	struct usb_phy		*usb2_phy;
 	struct usb_phy		*usb3_phy;
 
+	struct phy		*usb2_generic_phy;
+	struct phy		*usb3_generic_phy;
+
 	void __iomem		*regs;
 	size_t			regs_size;
 
-- 
1.7.10.4


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

* [PATCH 3/7] drivers: phy: usb3/pipe3: Adapt pipe3 driver to Generic PHY Framework
  2013-09-02 15:43 [PATCH 0/7] Make dwc3 use Generic PHY Framework and misc cleanup Kishon Vijay Abraham I
  2013-09-02 15:43 ` [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY Kishon Vijay Abraham I
  2013-09-02 15:43 ` [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework Kishon Vijay Abraham I
@ 2013-09-02 15:43 ` Kishon Vijay Abraham I
  2013-09-12 11:19   ` Roger Quadros
  2013-09-02 15:43 ` [PATCH 4/7] Documentation: dt bindings: move ..usb/usb-phy.txt to ..phy/omap-phy.txt Kishon Vijay Abraham I
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-02 15:43 UTC (permalink / raw)
  To: rogerq, kishon, balbi
  Cc: bcousson, tony, rob.herring, pawel.moll, mark.rutland, linux,
	grant.likely, s.nawrocki, galak, swarren, ian.campbell, rob,
	george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Adapted omap-usb3 PHY driver to Generic PHY Framework and moved phy-omap-usb3
driver in drivers/usb/phy to drivers/phy and also renamed the file to
phy-omap-pipe3 since this same driver will be used for SATA PHY and
PCIE PHY.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 Documentation/devicetree/bindings/usb/usb-phy.txt  |    5 +-
 drivers/phy/Kconfig                                |   10 +
 drivers/phy/Makefile                               |    1 +
 .../phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c}   |  206 +++++++++++---------
 drivers/usb/phy/Kconfig                            |   11 --
 drivers/usb/phy/Makefile                           |    1 -
 include/linux/phy/omap_pipe3.h                     |   52 +++++
 7 files changed, 177 insertions(+), 109 deletions(-)
 rename drivers/{usb/phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c} (57%)
 create mode 100644 include/linux/phy/omap_pipe3.h

diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt
index c0245c8..36bdb17 100644
--- a/Documentation/devicetree/bindings/usb/usb-phy.txt
+++ b/Documentation/devicetree/bindings/usb/usb-phy.txt
@@ -21,10 +21,11 @@ usb2phy@4a0ad080 {
 	#phy-cells = <0>;
 };
 
-OMAP USB3 PHY
+OMAP PIPE3 PHY
 
 Required properties:
- - compatible: Should be "ti,omap-usb3"
+ - compatible: Should be "ti,omap-usb3", "ti,omap-pipe3", "ti,omap-sata"
+   or "ti,omap-pcie"
  - reg : Address and length of the register set for the device.
  - reg-names: The names of the register addresses corresponding to the registers
    filled in "reg".
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index ac239ac..5c2e7a0 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -27,6 +27,16 @@ config OMAP_USB2
 	  The USB OTG controller communicates with the comparator using this
 	  driver.
 
+config OMAP_PIPE3
+	tristate "OMAP PIPE3 PHY Driver"
+	select GENERIC_PHY
+	select OMAP_CONTROL_USB
+	help
+	  Enable this to support the PIPE3 PHY that is part of SOC. This
+	  driver takes care of all the PHY functionality apart from comparator.
+	  This driver interacts with the "OMAP Control PHY Driver" to power
+	  on/off the PHY.
+
 config TWL4030_USB
 	tristate "TWL4030 USB Transceiver Driver"
 	depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 0dd8a98..48bf9f2 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -4,4 +4,5 @@
 
 obj-$(CONFIG_GENERIC_PHY)	+= phy-core.o
 obj-$(CONFIG_OMAP_USB2)		+= phy-omap-usb2.o
+obj-$(CONFIG_OMAP_PIPE3)	+= phy-omap-pipe3.o
 obj-$(CONFIG_TWL4030_USB)	+= phy-twl4030-usb.o
diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/phy/phy-omap-pipe3.c
similarity index 57%
rename from drivers/usb/phy/phy-omap-usb3.c
rename to drivers/phy/phy-omap-pipe3.c
index 4004f82..ee9a901 100644
--- a/drivers/usb/phy/phy-omap-usb3.c
+++ b/drivers/phy/phy-omap-pipe3.c
@@ -1,5 +1,5 @@
 /*
- * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP.
+ * omap-pipe3 - PHY driver for SATA, USB and PCIE in OMAP platforms
  *
  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
  * This program is free software; you can redistribute it and/or modify
@@ -19,7 +19,8 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/usb/omap_usb.h>
+#include <linux/phy/omap_pipe3.h>
+#include <linux/phy/phy.h>
 #include <linux/of.h>
 #include <linux/clk.h>
 #include <linux/err.h>
@@ -52,17 +53,17 @@
 
 /*
  * This is an Empirical value that works, need to confirm the actual
- * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status
- * to be correctly reflected in the USB3PHY_PLL_STATUS register.
+ * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status
+ * to be correctly reflected in the PIPE3PHY_PLL_STATUS register.
  */
 # define PLL_IDLE_TIME  100;
 
-struct usb_dpll_map {
+struct pipe3_dpll_map {
 	unsigned long rate;
-	struct usb_dpll_params params;
+	struct pipe3_dpll_params params;
 };
 
-static struct usb_dpll_map dpll_map[] = {
+static struct pipe3_dpll_map dpll_map[] = {
 	{12000000, {1250, 5, 4, 20, 0} },	/* 12 MHz */
 	{16800000, {3125, 20, 4, 20, 0} },	/* 16.8 MHz */
 	{19200000, {1172, 8, 4, 20, 65537} },	/* 19.2 MHz */
@@ -71,7 +72,7 @@ static struct usb_dpll_map dpll_map[] = {
 	{38400000, {3125, 47, 4, 20, 92843} },	/* 38.4 MHz */
 };
 
-static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
+static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(unsigned long rate)
 {
 	int i;
 
@@ -83,110 +84,113 @@ static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
 	return 0;
 }
 
-static int omap_usb3_suspend(struct usb_phy *x, int suspend)
+static int omap_pipe3_power_off(struct phy *x)
 {
-	struct omap_usb *phy = phy_to_omapusb(x);
-	int	val;
+	struct omap_pipe3 *phy = phy_get_drvdata(x);
+	int val;
 	int timeout = PLL_IDLE_TIME;
 
-	if (suspend && !phy->is_suspended) {
-		val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
-		val |= PLL_IDLE;
-		omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
-
-		do {
-			val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
-			if (val & PLL_TICOPWDN)
-				break;
-			udelay(1);
-		} while (--timeout);
-
-		omap_control_usb_phy_power(phy->control_dev, 0);
-
-		phy->is_suspended	= 1;
-	} else if (!suspend && phy->is_suspended) {
-		phy->is_suspended	= 0;
-
-		val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
-		val &= ~PLL_IDLE;
-		omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
-
-		do {
-			val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
-			if (!(val & PLL_TICOPWDN))
-				break;
-			udelay(1);
-		} while (--timeout);
-	}
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
+	val |= PLL_IDLE;
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
+
+	do {
+		val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
+		if (val & PLL_TICOPWDN)
+			break;
+		udelay(1);
+	} while (--timeout);
+
+	omap_control_usb_phy_power(phy->control_dev, 0);
+
+	return 0;
+}
+
+static int omap_pipe3_power_on(struct phy *x)
+{
+	struct omap_pipe3 *phy = phy_get_drvdata(x);
+	int val;
+	int timeout = PLL_IDLE_TIME;
+
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
+	val &= ~PLL_IDLE;
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
+
+	do {
+		val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
+		if (!(val & PLL_TICOPWDN))
+			break;
+		udelay(1);
+	} while (--timeout);
 
 	return 0;
 }
 
-static void omap_usb_dpll_relock(struct omap_usb *phy)
+static void omap_pipe3_dpll_relock(struct omap_pipe3 *phy)
 {
 	u32		val;
 	unsigned long	timeout;
 
-	omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
 
 	timeout = jiffies + msecs_to_jiffies(20);
 	do {
-		val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
+		val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
 		if (val & PLL_LOCK)
 			break;
 	} while (!WARN_ON(time_after(jiffies, timeout)));
 }
 
-static int omap_usb_dpll_lock(struct omap_usb *phy)
+static int omap_pipe3_dpll_lock(struct omap_pipe3 *phy)
 {
 	u32			val;
 	unsigned long		rate;
-	struct usb_dpll_params *dpll_params;
+	struct pipe3_dpll_params *dpll_params;
 
 	rate = clk_get_rate(phy->sys_clk);
-	dpll_params = omap_usb3_get_dpll_params(rate);
+	dpll_params = omap_pipe3_get_dpll_params(rate);
 	if (!dpll_params) {
 		dev_err(phy->dev,
 			  "No DPLL configuration for %lu Hz SYS CLK\n", rate);
 		return -EINVAL;
 	}
 
-	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
 	val &= ~PLL_REGN_MASK;
 	val |= dpll_params->n << PLL_REGN_SHIFT;
-	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
 
-	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
 	val &= ~PLL_SELFREQDCO_MASK;
 	val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
-	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
 
-	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
 	val &= ~PLL_REGM_MASK;
 	val |= dpll_params->m << PLL_REGM_SHIFT;
-	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
 
-	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
 	val &= ~PLL_REGM_F_MASK;
 	val |= dpll_params->mf << PLL_REGM_F_SHIFT;
-	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
 
-	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
+	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
 	val &= ~PLL_SD_MASK;
 	val |= dpll_params->sd << PLL_SD_SHIFT;
-	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
+	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
 
-	omap_usb_dpll_relock(phy);
+	omap_pipe3_dpll_relock(phy);
 
 	return 0;
 }
 
-static int omap_usb3_init(struct usb_phy *x)
+static int omap_pipe3_init(struct phy *x)
 {
-	struct omap_usb	*phy = phy_to_omapusb(x);
+	struct omap_pipe3 *phy = phy_get_drvdata(x);
 	int ret;
 
-	ret = omap_usb_dpll_lock(phy);
+	ret = omap_pipe3_dpll_lock(phy);
 	if (ret)
 		return ret;
 
@@ -195,9 +199,18 @@ static int omap_usb3_init(struct usb_phy *x)
 	return 0;
 }
 
-static int omap_usb3_probe(struct platform_device *pdev)
+static struct phy_ops ops = {
+	.init		= omap_pipe3_init,
+	.power_on	= omap_pipe3_power_on,
+	.power_off	= omap_pipe3_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int omap_pipe3_probe(struct platform_device *pdev)
 {
-	struct omap_usb *phy;
+	struct omap_pipe3 *phy;
+	struct phy *generic_phy;
+	struct phy_provider *phy_provider;
 	struct resource *res;
 	struct device_node *node = pdev->dev.of_node;
 	struct device_node *control_node;
@@ -208,7 +221,7 @@ static int omap_usb3_probe(struct platform_device *pdev)
 
 	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
 	if (!phy) {
-		dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n");
+		dev_err(&pdev->dev, "unable to alloc mem for OMAP PIPE3 PHY\n");
 		return -ENOMEM;
 	}
 
@@ -219,13 +232,6 @@ static int omap_usb3_probe(struct platform_device *pdev)
 
 	phy->dev		= &pdev->dev;
 
-	phy->phy.dev		= phy->dev;
-	phy->phy.label		= "omap-usb3";
-	phy->phy.init		= omap_usb3_init;
-	phy->phy.set_suspend	= omap_usb3_suspend;
-	phy->phy.type		= USB_PHY_TYPE_USB3;
-
-	phy->is_suspended	= 1;
 	phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
 	if (IS_ERR(phy->wkupclk)) {
 		dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
@@ -251,6 +257,11 @@ static int omap_usb3_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "Failed to get control device phandle\n");
 		return -EINVAL;
 	}
+	phy_provider = devm_of_phy_provider_register(phy->dev,
+			of_phy_simple_xlate);
+	if (IS_ERR(phy_provider))
+		return PTR_ERR(phy_provider);
+
 	control_pdev = of_find_device_by_node(control_node);
 	if (!control_pdev) {
 		dev_err(&pdev->dev, "Failed to get control device\n");
@@ -260,23 +271,27 @@ static int omap_usb3_probe(struct platform_device *pdev)
 	phy->control_dev = &control_pdev->dev;
 
 	omap_control_usb_phy_power(phy->control_dev, 0);
-	usb_add_phy_dev(&phy->phy);
 
 	platform_set_drvdata(pdev, phy);
-
 	pm_runtime_enable(phy->dev);
+
+	generic_phy = devm_phy_create(phy->dev, &ops, NULL);
+	if (IS_ERR(generic_phy))
+		return PTR_ERR(generic_phy);
+
+	phy_set_drvdata(generic_phy, phy);
+
 	pm_runtime_get(&pdev->dev);
 
 	return 0;
 }
 
-static int omap_usb3_remove(struct platform_device *pdev)
+static int omap_pipe3_remove(struct platform_device *pdev)
 {
-	struct omap_usb *phy = platform_get_drvdata(pdev);
+	struct omap_pipe3 *phy = platform_get_drvdata(pdev);
 
 	clk_unprepare(phy->wkupclk);
 	clk_unprepare(phy->optclk);
-	usb_remove_phy(&phy->phy);
 	if (!pm_runtime_suspended(&pdev->dev))
 		pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
@@ -286,10 +301,9 @@ static int omap_usb3_remove(struct platform_device *pdev)
 
 #ifdef CONFIG_PM_RUNTIME
 
-static int omap_usb3_runtime_suspend(struct device *dev)
+static int omap_pipe3_runtime_suspend(struct device *dev)
 {
-	struct platform_device	*pdev = to_platform_device(dev);
-	struct omap_usb	*phy = platform_get_drvdata(pdev);
+	struct omap_pipe3	*phy = dev_get_drvdata(dev);
 
 	clk_disable(phy->wkupclk);
 	clk_disable(phy->optclk);
@@ -297,11 +311,10 @@ static int omap_usb3_runtime_suspend(struct device *dev)
 	return 0;
 }
 
-static int omap_usb3_runtime_resume(struct device *dev)
+static int omap_pipe3_runtime_resume(struct device *dev)
 {
 	u32 ret = 0;
-	struct platform_device	*pdev = to_platform_device(dev);
-	struct omap_usb	*phy = platform_get_drvdata(pdev);
+	struct omap_pipe3	*phy = dev_get_drvdata(dev);
 
 	ret = clk_enable(phy->optclk);
 	if (ret) {
@@ -324,38 +337,41 @@ err1:
 	return ret;
 }
 
-static const struct dev_pm_ops omap_usb3_pm_ops = {
-	SET_RUNTIME_PM_OPS(omap_usb3_runtime_suspend, omap_usb3_runtime_resume,
-		NULL)
+static const struct dev_pm_ops omap_pipe3_pm_ops = {
+	SET_RUNTIME_PM_OPS(omap_pipe3_runtime_suspend,
+		omap_pipe3_runtime_resume, NULL)
 };
 
-#define DEV_PM_OPS     (&omap_usb3_pm_ops)
+#define DEV_PM_OPS     (&omap_pipe3_pm_ops)
 #else
 #define DEV_PM_OPS     NULL
 #endif
 
 #ifdef CONFIG_OF
-static const struct of_device_id omap_usb3_id_table[] = {
+static const struct of_device_id omap_pipe3_id_table[] = {
+	{ .compatible = "ti,omap-pipe3" },
+	{ .compatible = "ti,omap-sata" },
+	{ .compatible = "ti,omap-pcie" },
 	{ .compatible = "ti,omap-usb3" },
 	{}
 };
-MODULE_DEVICE_TABLE(of, omap_usb3_id_table);
+MODULE_DEVICE_TABLE(of, omap_pipe3_id_table);
 #endif
 
-static struct platform_driver omap_usb3_driver = {
-	.probe		= omap_usb3_probe,
-	.remove		= omap_usb3_remove,
+static struct platform_driver omap_pipe3_driver = {
+	.probe		= omap_pipe3_probe,
+	.remove		= omap_pipe3_remove,
 	.driver		= {
-		.name	= "omap-usb3",
+		.name	= "omap-pipe3",
 		.owner	= THIS_MODULE,
 		.pm	= DEV_PM_OPS,
-		.of_match_table = of_match_ptr(omap_usb3_id_table),
+		.of_match_table = of_match_ptr(omap_pipe3_id_table),
 	},
 };
 
-module_platform_driver(omap_usb3_driver);
+module_platform_driver(omap_pipe3_driver);
 
-MODULE_ALIAS("platform: omap_usb3");
+MODULE_ALIAS("platform: omap_pipe3");
 MODULE_AUTHOR("Texas Instruments Inc.");
-MODULE_DESCRIPTION("OMAP USB3 phy driver");
+MODULE_DESCRIPTION("OMAP PIPE3 phy driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index d69cdad..0210e03 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -66,17 +66,6 @@ config OMAP_CONTROL_USB
 	  power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an
 	  additional register to power on USB3 PHY.
 
-config OMAP_USB3
-	tristate "OMAP USB3 PHY Driver"
-	depends on ARCH_OMAP2PLUS || COMPILE_TEST
-	select OMAP_CONTROL_USB
-	select USB_PHY
-	help
-	  Enable this to support the USB3 PHY that is part of SOC. This
-	  driver takes care of all the PHY functionality apart from comparator.
-	  This driver interacts with the "OMAP Control USB Driver" to power
-	  on/off the PHY.
-
 config AM335X_CONTROL_USB
 	tristate
 
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 51968d7..d1c9683 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -13,7 +13,6 @@ obj-$(CONFIG_ISP1301_OMAP)		+= phy-isp1301-omap.o
 obj-$(CONFIG_MV_U3D_PHY)		+= phy-mv-u3d-usb.o
 obj-$(CONFIG_NOP_USB_XCEIV)		+= phy-generic.o
 obj-$(CONFIG_OMAP_CONTROL_USB)		+= phy-omap-control.o
-obj-$(CONFIG_OMAP_USB3)			+= phy-omap-usb3.o
 obj-$(CONFIG_SAMSUNG_USBPHY)		+= phy-samsung-usb.o
 obj-$(CONFIG_SAMSUNG_USB2PHY)		+= phy-samsung-usb2.o
 obj-$(CONFIG_SAMSUNG_USB3PHY)		+= phy-samsung-usb3.o
diff --git a/include/linux/phy/omap_pipe3.h b/include/linux/phy/omap_pipe3.h
new file mode 100644
index 0000000..7329056
--- /dev/null
+++ b/include/linux/phy/omap_pipe3.h
@@ -0,0 +1,52 @@
+/*
+ * omap_pipe3.h -- omap pipe3 phy header file
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __DRIVERS_OMAP_PIPE3_H
+#define __DRIVERS_OMAP_PIPE3_H
+
+#include <linux/io.h>
+
+struct pipe3_dpll_params {
+	u16	m;
+	u8	n;
+	u8	freq:3;
+	u8	sd;
+	u32	mf;
+};
+
+struct omap_pipe3 {
+	void __iomem		*pll_ctrl_base;
+	struct device		*dev;
+	struct device		*control_dev;
+	struct clk		*wkupclk;
+	struct clk		*sys_clk;
+	struct clk		*optclk;
+};
+
+static inline u32 omap_pipe3_readl(void __iomem *addr, unsigned offset)
+{
+	return __raw_readl(addr + offset);
+}
+
+static inline void omap_pipe3_writel(void __iomem *addr, unsigned offset,
+	u32 data)
+{
+	__raw_writel(data, addr + offset);
+}
+
+#endif /* __DRIVERS_OMAP_PIPE3_H */
-- 
1.7.10.4


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

* [PATCH 4/7] Documentation: dt bindings: move ..usb/usb-phy.txt to ..phy/omap-phy.txt
  2013-09-02 15:43 [PATCH 0/7] Make dwc3 use Generic PHY Framework and misc cleanup Kishon Vijay Abraham I
                   ` (2 preceding siblings ...)
  2013-09-02 15:43 ` [PATCH 3/7] drivers: phy: usb3/pipe3: Adapt pipe3 driver to " Kishon Vijay Abraham I
@ 2013-09-02 15:43 ` Kishon Vijay Abraham I
  2013-09-12 13:23   ` Roger Quadros
  2013-09-02 15:43 ` [PATCH 5/7] phy: omap-usb2: move omap_usb.h from linux/usb/ to linux/phy/ Kishon Vijay Abraham I
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-02 15:43 UTC (permalink / raw)
  To: rogerq, kishon, balbi
  Cc: bcousson, tony, rob.herring, pawel.moll, mark.rutland, linux,
	grant.likely, s.nawrocki, galak, swarren, ian.campbell, rob,
	george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Since now we have a separate folder for phy, move the PHY dt binding
documentation of OMAP to that folder.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 .../devicetree/bindings/{usb/usb-phy.txt => phy/omap-phy.txt}        |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename Documentation/devicetree/bindings/{usb/usb-phy.txt => phy/omap-phy.txt} (96%)

diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/phy/omap-phy.txt
similarity index 96%
rename from Documentation/devicetree/bindings/usb/usb-phy.txt
rename to Documentation/devicetree/bindings/phy/omap-phy.txt
index 36bdb17..2c485ee 100644
--- a/Documentation/devicetree/bindings/usb/usb-phy.txt
+++ b/Documentation/devicetree/bindings/phy/omap-phy.txt
@@ -1,4 +1,4 @@
-USB PHY
+OMAP PHY: DT DOCUMENTATION FOR PHYs in OMAP PLATFORM
 
 OMAP USB2 PHY
 
-- 
1.7.10.4


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

* [PATCH 5/7] phy: omap-usb2: move omap_usb.h from linux/usb/ to linux/phy/
  2013-09-02 15:43 [PATCH 0/7] Make dwc3 use Generic PHY Framework and misc cleanup Kishon Vijay Abraham I
                   ` (3 preceding siblings ...)
  2013-09-02 15:43 ` [PATCH 4/7] Documentation: dt bindings: move ..usb/usb-phy.txt to ..phy/omap-phy.txt Kishon Vijay Abraham I
@ 2013-09-02 15:43 ` Kishon Vijay Abraham I
  2013-09-02 15:43 ` [PATCH 6/7] arm/dts: added dt properties to adapt to the new phy framwork Kishon Vijay Abraham I
  2013-09-02 15:43 ` [PATCH 7/7] drivers: phy: renamed struct omap_control_usb to struct omap_control_phy Kishon Vijay Abraham I
  6 siblings, 0 replies; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-02 15:43 UTC (permalink / raw)
  To: rogerq, kishon, balbi
  Cc: bcousson, tony, rob.herring, pawel.moll, mark.rutland, linux,
	grant.likely, s.nawrocki, galak, swarren, ian.campbell, rob,
	george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

No functional change. Moved omap_usb.h from linux/usb/ to linux/phy/.
Also removed the unused members of struct omap_usb (after phy-omap-pipe3
started using it's own header file)

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/phy/phy-omap-usb2.c           |    2 +-
 drivers/usb/phy/phy-twl6030-usb.c     |    2 +-
 include/linux/{usb => phy}/omap_usb.h |    3 ---
 3 files changed, 2 insertions(+), 5 deletions(-)
 rename include/linux/{usb => phy}/omap_usb.h (95%)

diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
index b25d623..6c78584 100644
--- a/drivers/phy/phy-omap-usb2.c
+++ b/drivers/phy/phy-omap-usb2.c
@@ -21,7 +21,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/io.h>
-#include <linux/usb/omap_usb.h>
+#include <linux/phy/omap_usb.h>
 #include <linux/usb/phy_companion.h>
 #include <linux/clk.h>
 #include <linux/err.h>
diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c
index 16dbc93..b5ad3eb 100644
--- a/drivers/usb/phy/phy-twl6030-usb.c
+++ b/drivers/usb/phy/phy-twl6030-usb.c
@@ -26,8 +26,8 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/usb/musb-omap.h>
+#include <linux/phy/omap_usb.h>
 #include <linux/usb/phy_companion.h>
-#include <linux/usb/omap_usb.h>
 #include <linux/i2c/twl.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
diff --git a/include/linux/usb/omap_usb.h b/include/linux/phy/omap_usb.h
similarity index 95%
rename from include/linux/usb/omap_usb.h
rename to include/linux/phy/omap_usb.h
index 6ae2936..19d343c3 100644
--- a/include/linux/usb/omap_usb.h
+++ b/include/linux/phy/omap_usb.h
@@ -33,13 +33,10 @@ struct usb_dpll_params {
 struct omap_usb {
 	struct usb_phy		phy;
 	struct phy_companion	*comparator;
-	void __iomem		*pll_ctrl_base;
 	struct device		*dev;
 	struct device		*control_dev;
 	struct clk		*wkupclk;
-	struct clk		*sys_clk;
 	struct clk		*optclk;
-	u8			is_suspended:1;
 };
 
 #define	phy_to_omapusb(x)	container_of((x), struct omap_usb, phy)
-- 
1.7.10.4


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

* [PATCH 6/7] arm/dts: added dt properties to adapt to the new phy framwork
  2013-09-02 15:43 [PATCH 0/7] Make dwc3 use Generic PHY Framework and misc cleanup Kishon Vijay Abraham I
                   ` (4 preceding siblings ...)
  2013-09-02 15:43 ` [PATCH 5/7] phy: omap-usb2: move omap_usb.h from linux/usb/ to linux/phy/ Kishon Vijay Abraham I
@ 2013-09-02 15:43 ` Kishon Vijay Abraham I
  2013-09-12 13:28   ` Roger Quadros
  2013-09-02 15:43 ` [PATCH 7/7] drivers: phy: renamed struct omap_control_usb to struct omap_control_phy Kishon Vijay Abraham I
  6 siblings, 1 reply; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-02 15:43 UTC (permalink / raw)
  To: rogerq, kishon, balbi
  Cc: bcousson, tony, rob.herring, pawel.moll, mark.rutland, linux,
	grant.likely, s.nawrocki, galak, swarren, ian.campbell, rob,
	george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 arch/arm/boot/dts/omap5.dtsi |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 94abef5..9fe71ff 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -651,7 +651,8 @@
 				compatible = "snps,dwc3";
 				reg = <0x4a030000 0x10000>;
 				interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
-				usb-phy = <&usb2_phy>, <&usb3_phy>;
+				phys = <&usb2_phy>, <&usb3_phy>;
+				phy-names = "usb2-phy", "usb3-phy";
 				tx-fifo-resize;
 			};
 		};
@@ -667,6 +668,7 @@
 				compatible = "ti,omap-usb2";
 				reg = <0x4a084000 0x7c>;
 				ctrl-module = <&omap_control_usb2phy>;
+				#phy-cells = <0>;
 			};
 
 			usb3_phy: usb3phy@4a084400 {
@@ -676,6 +678,7 @@
 				      <0x4a084c00 0x40>;
 				reg-names = "phy_rx", "phy_tx", "pll_ctrl";
 				ctrl-module = <&omap_control_usb3phy>;
+				#phy-cells = <0>;
 			};
 		};
 
-- 
1.7.10.4


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

* [PATCH 7/7] drivers: phy: renamed struct omap_control_usb to struct omap_control_phy
  2013-09-02 15:43 [PATCH 0/7] Make dwc3 use Generic PHY Framework and misc cleanup Kishon Vijay Abraham I
                   ` (5 preceding siblings ...)
  2013-09-02 15:43 ` [PATCH 6/7] arm/dts: added dt properties to adapt to the new phy framwork Kishon Vijay Abraham I
@ 2013-09-02 15:43 ` Kishon Vijay Abraham I
  2013-09-12 13:42   ` Roger Quadros
  6 siblings, 1 reply; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-02 15:43 UTC (permalink / raw)
  To: rogerq, kishon, balbi
  Cc: bcousson, tony, rob.herring, pawel.moll, mark.rutland, linux,
	grant.likely, s.nawrocki, galak, swarren, ian.campbell, rob,
	george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

renamed struct omap_control_usb to struct omap_control_phy since it can
be used to control PHY of USB, SATA and PCIE. Also moved the driver and
include files under *phy* and made the corresponding changes in the users
of phy-omap-control.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/phy/Kconfig                                |   14 +-
 drivers/phy/Makefile                               |    1 +
 drivers/{usb => }/phy/phy-omap-control.c           |  164 ++++++++++----------
 drivers/phy/phy-omap-pipe3.c                       |    8 +-
 drivers/phy/phy-omap-usb2.c                        |    8 +-
 drivers/usb/musb/omap2430.c                        |    2 +-
 drivers/usb/phy/Makefile                           |    1 -
 .../omap_control_usb.h => phy/omap_control_phy.h}  |   32 ++--
 8 files changed, 120 insertions(+), 110 deletions(-)
 rename drivers/{usb => }/phy/phy-omap-control.c (55%)
 rename include/linux/{usb/omap_control_usb.h => phy/omap_control_phy.h} (69%)

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 5c2e7a0..fd11294 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -15,12 +15,22 @@ config GENERIC_PHY
 	  phy users can obtain reference to the PHY. All the users of this
 	  framework should select this config.
 
+config OMAP_CONTROL_PHY
+	tristate "OMAP CONTROL PHY Driver"
+	depends on ARCH_OMAP2PLUS || COMPILE_TEST
+	help
+	  Enable this to add support for the PHY part present in the control
+	  module. This driver has API to power on the USB2 PHY and to write to
+	  the mailbox. The mailbox is present only in omap4 and the register to
+	  power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has
+	  additional registers to power on PIPE3 PHYs.
+
 config OMAP_USB2
 	tristate "OMAP USB2 PHY Driver"
 	depends on ARCH_OMAP2PLUS
 	select GENERIC_PHY
 	select USB_PHY
-	select OMAP_CONTROL_USB
+	select OMAP_CONTROL_PHY
 	help
 	  Enable this to support the transceiver that is part of SOC. This
 	  driver takes care of all the PHY functionality apart from comparator.
@@ -30,7 +40,7 @@ config OMAP_USB2
 config OMAP_PIPE3
 	tristate "OMAP PIPE3 PHY Driver"
 	select GENERIC_PHY
-	select OMAP_CONTROL_USB
+	select OMAP_CONTROL_PHY
 	help
 	  Enable this to support the PIPE3 PHY that is part of SOC. This
 	  driver takes care of all the PHY functionality apart from comparator.
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 48bf9f2..f0127f6 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_GENERIC_PHY)	+= phy-core.o
+obj-$(CONFIG_OMAP_CONTROL_PHY)	+= phy-omap-control.o
 obj-$(CONFIG_OMAP_USB2)		+= phy-omap-usb2.o
 obj-$(CONFIG_OMAP_PIPE3)	+= phy-omap-pipe3.o
 obj-$(CONFIG_TWL4030_USB)	+= phy-twl4030-usb.o
diff --git a/drivers/usb/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c
similarity index 55%
rename from drivers/usb/phy/phy-omap-control.c
rename to drivers/phy/phy-omap-control.c
index 1a7e19a..ece3573 100644
--- a/drivers/usb/phy/phy-omap-control.c
+++ b/drivers/phy/phy-omap-control.c
@@ -1,5 +1,5 @@
 /*
- * omap-control-usb.c - The USB part of control module.
+ * phy-omap-control.c - The USB part of control module.
  *
  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
  * This program is free software; you can redistribute it and/or modify
@@ -24,36 +24,36 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/clk.h>
-#include <linux/usb/omap_control_usb.h>
+#include <linux/phy/omap_control_phy.h>
 
 /**
- * omap_control_usb_phy_power - power on/off the phy using control module reg
+ * omap_control_phy_power - power on/off the phy using control module reg
  * @dev: the control module device
  * @on: 0 or 1, based on powering on or off the PHY
  */
-void omap_control_usb_phy_power(struct device *dev, int on)
+void omap_control_phy_power(struct device *dev, int on)
 {
 	u32 val, val_aux;
 	unsigned long rate;
-	struct omap_control_usb	*control_usb;
+	struct omap_control_phy	*control_phy;
 
 	if (IS_ERR(dev) || !dev) {
 		pr_err("%s: invalid device\n", __func__);
 		return;
 	}
 
-	control_usb = dev_get_drvdata(dev);
-	if (!control_usb) {
+	control_phy = dev_get_drvdata(dev);
+	if (!control_phy) {
 		dev_err(dev, "%s: invalid control usb device\n", __func__);
 		return;
 	}
 
-	if (control_usb->type == OMAP_CTRL_TYPE_OMAP4)
+	if (control_phy->type == OMAP_CTRL_TYPE_OMAP4)
 		return;
 
-	val = readl(control_usb->power);
+	val = readl(control_phy->power);
 
-	switch (control_usb->type) {
+	switch (control_phy->type) {
 	case OMAP_CTRL_TYPE_USB2:
 		if (on)
 			val &= ~OMAP_CTRL_DEV_PHY_PD;
@@ -62,24 +62,24 @@ void omap_control_usb_phy_power(struct device *dev, int on)
 		break;
 
 	case OMAP_CTRL_TYPE_USB3:
-		rate = clk_get_rate(control_usb->sys_clk);
+		rate = clk_get_rate(control_phy->sys_clk);
 		rate = rate/1000000;
 
 		if (on) {
-			val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK |
-					OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK);
-			val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON <<
-				OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
-			val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT;
+			val &= ~(OMAP_CTRL_PIPE3_PWRCTL_CLK_CMD_MASK |
+					OMAP_CTRL_PIPE3_PWRCTL_CLK_FREQ_MASK);
+			val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON <<
+				OMAP_CTRL_PIPE3_PWRCTL_CLK_CMD_SHIFT;
+			val |= rate << OMAP_CTRL_PIPE3_PWRCTL_CLK_FREQ_SHIFT;
 		} else {
-			val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK;
-			val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF <<
-				OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
+			val &= ~OMAP_CTRL_PIPE3_PWRCTL_CLK_CMD_MASK;
+			val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF <<
+				OMAP_CTRL_PIPE3_PWRCTL_CLK_CMD_SHIFT;
 		}
 		break;
 
 	case OMAP_CTRL_TYPE_DRA7:
-		val_aux = readl(control_usb->power_aux);
+		val_aux = readl(control_phy->power_aux);
 		if (on) {
 			val &= ~OMAP_CTRL_USB2_PHY_PD;
 			val_aux |= 0x100;
@@ -88,70 +88,70 @@ void omap_control_usb_phy_power(struct device *dev, int on)
 			val_aux &= ~0x100;
 		}
 
-		writel(val_aux, control_usb->power_aux);
+		writel(val_aux, control_phy->power_aux);
 		break;
 	default:
 		dev_err(dev, "%s: type %d not recognized\n",
-					__func__, control_usb->type);
+					__func__, control_phy->type);
 		break;
 	}
 
-	writel(val, control_usb->power);
+	writel(val, control_phy->power);
 }
-EXPORT_SYMBOL_GPL(omap_control_usb_phy_power);
+EXPORT_SYMBOL_GPL(omap_control_phy_power);
 
 /**
  * omap_control_usb_host_mode - set AVALID, VBUSVALID and ID pin in grounded
- * @ctrl_usb: struct omap_control_usb *
+ * @ctrl_phy: struct omap_control_phy *
  *
  * Writes to the mailbox register to notify the usb core that a usb
  * device has been connected.
  */
-static void omap_control_usb_host_mode(struct omap_control_usb *ctrl_usb)
+static void omap_control_usb_host_mode(struct omap_control_phy *ctrl_phy)
 {
 	u32 val;
 
-	val = readl(ctrl_usb->otghs_control);
+	val = readl(ctrl_phy->otghs_control);
 	val &= ~(OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND);
 	val |= OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID;
-	writel(val, ctrl_usb->otghs_control);
+	writel(val, ctrl_phy->otghs_control);
 }
 
 /**
  * omap_control_usb_device_mode - set AVALID, VBUSVALID and ID pin in high
  * impedance
- * @ctrl_usb: struct omap_control_usb *
+ * @ctrl_phy: struct omap_control_phy *
  *
  * Writes to the mailbox register to notify the usb core that it has been
  * connected to a usb host.
  */
-static void omap_control_usb_device_mode(struct omap_control_usb *ctrl_usb)
+static void omap_control_usb_device_mode(struct omap_control_phy *ctrl_phy)
 {
 	u32 val;
 
-	val = readl(ctrl_usb->otghs_control);
+	val = readl(ctrl_phy->otghs_control);
 	val &= ~OMAP_CTRL_DEV_SESSEND;
 	val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_AVALID |
 		OMAP_CTRL_DEV_VBUSVALID;
-	writel(val, ctrl_usb->otghs_control);
+	writel(val, ctrl_phy->otghs_control);
 }
 
 /**
  * omap_control_usb_set_sessionend - Enable SESSIONEND and IDIG to high
  * impedance
- * @ctrl_usb: struct omap_control_usb *
+ * @ctrl_phy: struct omap_control_phy *
  *
  * Writes to the mailbox register to notify the usb core it's now in
  * disconnected state.
  */
-static void omap_control_usb_set_sessionend(struct omap_control_usb *ctrl_usb)
+static void omap_control_usb_set_sessionend(struct omap_control_phy *ctrl_phy)
 {
 	u32 val;
 
-	val = readl(ctrl_usb->otghs_control);
+	val = readl(ctrl_phy->otghs_control);
 	val &= ~(OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID);
 	val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND;
-	writel(val, ctrl_usb->otghs_control);
+	writel(val, ctrl_phy->otghs_control);
 }
 
 /**
@@ -166,30 +166,30 @@ static void omap_control_usb_set_sessionend(struct omap_control_usb *ctrl_usb)
 void omap_control_usb_set_mode(struct device *dev,
 	enum omap_control_usb_mode mode)
 {
-	struct omap_control_usb	*ctrl_usb;
+	struct omap_control_phy	*ctrl_phy;
 
 	if (IS_ERR(dev) || !dev)
 		return;
 
-	ctrl_usb = dev_get_drvdata(dev);
+	ctrl_phy = dev_get_drvdata(dev);
 
-	if (!ctrl_usb) {
+	if (!ctrl_phy) {
 		dev_err(dev, "Invalid control usb device\n");
 		return;
 	}
 
-	if (ctrl_usb->type != OMAP_CTRL_TYPE_OMAP4)
+	if (ctrl_phy->type != OMAP_CTRL_TYPE_OMAP4)
 		return;
 
 	switch (mode) {
 	case USB_MODE_HOST:
-		omap_control_usb_host_mode(ctrl_usb);
+		omap_control_usb_host_mode(ctrl_phy);
 		break;
 	case USB_MODE_DEVICE:
-		omap_control_usb_device_mode(ctrl_usb);
+		omap_control_usb_device_mode(ctrl_phy);
 		break;
 	case USB_MODE_DISCONNECT:
-		omap_control_usb_set_sessionend(ctrl_usb);
+		omap_control_usb_set_sessionend(ctrl_phy);
 		break;
 	default:
 		dev_vdbg(dev, "invalid omap control usb mode\n");
@@ -197,77 +197,77 @@ void omap_control_usb_set_mode(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(omap_control_usb_set_mode);
 
-static const struct of_device_id omap_control_usb_id_table[];
+static const struct of_device_id omap_control_phy_id_table[];
 
-static int omap_control_usb_probe(struct platform_device *pdev)
+static int omap_control_phy_probe(struct platform_device *pdev)
 {
 	struct resource	*res;
 	const struct of_device_id *of_id;
-	struct omap_control_usb *control_usb;
+	struct omap_control_phy *control_phy;
 
-	of_id = of_match_device(omap_control_usb_id_table, &pdev->dev);
+	of_id = of_match_device(omap_control_phy_id_table, &pdev->dev);
 	if (!of_id)
 		return -EINVAL;
 
-	control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb),
+	control_phy = devm_kzalloc(&pdev->dev, sizeof(*control_phy),
 		GFP_KERNEL);
-	if (!control_usb) {
+	if (!control_phy) {
 		dev_err(&pdev->dev, "unable to alloc memory for control usb\n");
 		return -ENOMEM;
 	}
 
-	control_usb->dev = &pdev->dev;
-	control_usb->type = *(enum omap_control_usb_type *)of_id->data;
+	control_phy->dev = &pdev->dev;
+	control_phy->type = *(enum omap_control_phy_type *)of_id->data;
 
-	if (control_usb->type == OMAP_CTRL_TYPE_OMAP4) {
+	if (control_phy->type == OMAP_CTRL_TYPE_OMAP4) {
 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 			"otghs_control");
-		control_usb->otghs_control = devm_ioremap_resource(
+		control_phy->otghs_control = devm_ioremap_resource(
 			&pdev->dev, res);
-		if (IS_ERR(control_usb->otghs_control))
-			return PTR_ERR(control_usb->otghs_control);
+		if (IS_ERR(control_phy->otghs_control))
+			return PTR_ERR(control_phy->otghs_control);
 	} else {
 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 				"power");
-		control_usb->power = devm_ioremap_resource(&pdev->dev, res);
-		if (IS_ERR(control_usb->power)) {
+		control_phy->power = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(control_phy->power)) {
 			dev_err(&pdev->dev, "Couldn't get power register\n");
-			return PTR_ERR(control_usb->power);
+			return PTR_ERR(control_phy->power);
 		}
 	}
 
-	if (control_usb->type == OMAP_CTRL_TYPE_USB3) {
-		control_usb->sys_clk = devm_clk_get(control_usb->dev,
+	if (control_phy->type == OMAP_CTRL_TYPE_USB3) {
+		control_phy->sys_clk = devm_clk_get(control_phy->dev,
 			"sys_clkin");
-		if (IS_ERR(control_usb->sys_clk)) {
+		if (IS_ERR(control_phy->sys_clk)) {
 			pr_err("%s: unable to get sys_clkin\n", __func__);
 			return -EINVAL;
 		}
 	}
 
-	if (control_usb->type == OMAP_CTRL_TYPE_DRA7) {
+	if (control_phy->type == OMAP_CTRL_TYPE_DRA7) {
 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 				"power_aux");
-		control_usb->power_aux = devm_ioremap_resource(&pdev->dev, res);
-		if (IS_ERR(control_usb->power_aux)) {
+		control_phy->power_aux = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(control_phy->power_aux)) {
 			dev_err(&pdev->dev, "Couldn't get power_aux register\n");
-			return PTR_ERR(control_usb->power_aux);
+			return PTR_ERR(control_phy->power_aux);
 		}
 	}
 
-	dev_set_drvdata(control_usb->dev, control_usb);
+	dev_set_drvdata(control_phy->dev, control_phy);
 
 	return 0;
 }
 
 #ifdef CONFIG_OF
 
-static const enum omap_control_usb_type omap4_data = OMAP_CTRL_TYPE_OMAP4;
-static const enum omap_control_usb_type usb2_data = OMAP_CTRL_TYPE_USB2;
-static const enum omap_control_usb_type usb3_data = OMAP_CTRL_TYPE_USB3;
-static const enum omap_control_usb_type dra7_data = OMAP_CTRL_TYPE_DRA7;
+static const enum omap_control_phy_type omap4_data = OMAP_CTRL_TYPE_OMAP4;
+static const enum omap_control_phy_type usb2_data = OMAP_CTRL_TYPE_USB2;
+static const enum omap_control_phy_type usb3_data = OMAP_CTRL_TYPE_USB3;
+static const enum omap_control_phy_type dra7_data = OMAP_CTRL_TYPE_DRA7;
 
-static const struct of_device_id omap_control_usb_id_table[] = {
+static const struct of_device_id omap_control_phy_id_table[] = {
 	{
 		.compatible = "ti,omap4-control-usb",
 		.data = &omap4_data,
@@ -286,31 +286,31 @@ static const struct of_device_id omap_control_usb_id_table[] = {
 	},
 	{},
 };
-MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
+MODULE_DEVICE_TABLE(of, omap_control_phy_id_table);
 #endif
 
-static struct platform_driver omap_control_usb_driver = {
-	.probe		= omap_control_usb_probe,
+static struct platform_driver omap_control_phy_driver = {
+	.probe		= omap_control_phy_probe,
 	.driver		= {
 		.name	= "omap-control-usb",
 		.owner	= THIS_MODULE,
-		.of_match_table = of_match_ptr(omap_control_usb_id_table),
+		.of_match_table = of_match_ptr(omap_control_phy_id_table),
 	},
 };
 
-static int __init omap_control_usb_init(void)
+static int __init omap_control_phy_init(void)
 {
-	return platform_driver_register(&omap_control_usb_driver);
+	return platform_driver_register(&omap_control_phy_driver);
 }
-subsys_initcall(omap_control_usb_init);
+subsys_initcall(omap_control_phy_init);
 
-static void __exit omap_control_usb_exit(void)
+static void __exit omap_control_phy_exit(void)
 {
-	platform_driver_unregister(&omap_control_usb_driver);
+	platform_driver_unregister(&omap_control_phy_driver);
 }
-module_exit(omap_control_usb_exit);
+module_exit(omap_control_phy_exit);
 
-MODULE_ALIAS("platform: omap_control_usb");
+MODULE_ALIAS("platform: omap_control_phy");
 MODULE_AUTHOR("Texas Instruments Inc.");
 MODULE_DESCRIPTION("OMAP Control Module USB Driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-omap-pipe3.c b/drivers/phy/phy-omap-pipe3.c
index ee9a901..63de0f8 100644
--- a/drivers/phy/phy-omap-pipe3.c
+++ b/drivers/phy/phy-omap-pipe3.c
@@ -26,7 +26,7 @@
 #include <linux/err.h>
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
-#include <linux/usb/omap_control_usb.h>
+#include <linux/phy/omap_control_phy.h>
 #include <linux/of_platform.h>
 
 #define	PLL_STATUS		0x00000004
@@ -101,7 +101,7 @@ static int omap_pipe3_power_off(struct phy *x)
 		udelay(1);
 	} while (--timeout);
 
-	omap_control_usb_phy_power(phy->control_dev, 0);
+	omap_control_phy_power(phy->control_dev, 0);
 
 	return 0;
 }
@@ -194,7 +194,7 @@ static int omap_pipe3_init(struct phy *x)
 	if (ret)
 		return ret;
 
-	omap_control_usb_phy_power(phy->control_dev, 1);
+	omap_control_phy_power(phy->control_dev, 1);
 
 	return 0;
 }
@@ -270,7 +270,7 @@ static int omap_pipe3_probe(struct platform_device *pdev)
 
 	phy->control_dev = &control_pdev->dev;
 
-	omap_control_usb_phy_power(phy->control_dev, 0);
+	omap_control_phy_power(phy->control_dev, 0);
 
 	platform_set_drvdata(pdev, phy);
 	pm_runtime_enable(phy->dev);
diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
index 6c78584..d3ea81d 100644
--- a/drivers/phy/phy-omap-usb2.c
+++ b/drivers/phy/phy-omap-usb2.c
@@ -27,7 +27,7 @@
 #include <linux/err.h>
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
-#include <linux/usb/omap_control_usb.h>
+#include <linux/phy/omap_control_phy.h>
 #include <linux/of_platform.h>
 #include <linux/phy/phy.h>
 
@@ -102,7 +102,7 @@ static int omap_usb_power_off(struct phy *x)
 {
 	struct omap_usb *phy = phy_get_drvdata(x);
 
-	omap_control_usb_phy_power(phy->control_dev, 0);
+	omap_control_phy_power(phy->control_dev, 0);
 
 	return 0;
 }
@@ -111,7 +111,7 @@ static int omap_usb_power_on(struct phy *x)
 {
 	struct omap_usb *phy = phy_get_drvdata(x);
 
-	omap_control_usb_phy_power(phy->control_dev, 1);
+	omap_control_phy_power(phy->control_dev, 1);
 
 	return 0;
 }
@@ -172,7 +172,7 @@ static int omap_usb2_probe(struct platform_device *pdev)
 	if (IS_ERR(phy_provider))
 		return PTR_ERR(phy_provider);
 
-	omap_control_usb_phy_power(phy->control_dev, 0);
+	omap_control_phy_power(phy->control_dev, 0);
 
 	otg->set_host		= omap_usb_set_host;
 	otg->set_peripheral	= omap_usb_set_peripheral;
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 9eab645..4f5ef0b 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -37,7 +37,7 @@
 #include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/usb/musb-omap.h>
-#include <linux/usb/omap_control_usb.h>
+#include <linux/phy/omap_control_phy.h>
 #include <linux/of_platform.h>
 
 #include "musb_core.h"
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index d1c9683..255cda9 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -12,7 +12,6 @@ obj-$(CONFIG_FSL_USB2_OTG)		+= phy-fsl-usb2.o
 obj-$(CONFIG_ISP1301_OMAP)		+= phy-isp1301-omap.o
 obj-$(CONFIG_MV_U3D_PHY)		+= phy-mv-u3d-usb.o
 obj-$(CONFIG_NOP_USB_XCEIV)		+= phy-generic.o
-obj-$(CONFIG_OMAP_CONTROL_USB)		+= phy-omap-control.o
 obj-$(CONFIG_SAMSUNG_USBPHY)		+= phy-samsung-usb.o
 obj-$(CONFIG_SAMSUNG_USB2PHY)		+= phy-samsung-usb2.o
 obj-$(CONFIG_SAMSUNG_USB3PHY)		+= phy-samsung-usb3.o
diff --git a/include/linux/usb/omap_control_usb.h b/include/linux/phy/omap_control_phy.h
similarity index 69%
rename from include/linux/usb/omap_control_usb.h
rename to include/linux/phy/omap_control_phy.h
index 8008e8d..9d6b08f 100644
--- a/include/linux/usb/omap_control_usb.h
+++ b/include/linux/phy/omap_control_phy.h
@@ -1,5 +1,5 @@
 /*
- * omap_control_usb.h - Header file for the USB part of control module.
+ * omap_control_phy.h - Header file for the USB part of control module.
  *
  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
  * This program is free software; you can redistribute it and/or modify
@@ -16,17 +16,17 @@
  *
  */
 
-#ifndef __OMAP_CONTROL_USB_H__
-#define __OMAP_CONTROL_USB_H__
+#ifndef __OMAP_CONTROL_PHY_H__
+#define __OMAP_CONTROL_PHY_H__
 
-enum omap_control_usb_type {
+enum omap_control_phy_type {
 	OMAP_CTRL_TYPE_OMAP4 = 1,	/* Mailbox OTGHS_CONTROL */
 	OMAP_CTRL_TYPE_USB2,	/* USB2_PHY, power down in CONTROL_DEV_CONF */
 	OMAP_CTRL_TYPE_USB3,	/* USB3_PHY, DPLL & seperate Rx/Tx power */
 	OMAP_CTRL_TYPE_DRA7,	/* USB2 PHY, power and power_aux e.g. DRA7 */
 };
 
-struct omap_control_usb {
+struct omap_control_phy {
 	struct device *dev;
 
 	u32 __iomem *otghs_control;
@@ -35,7 +35,7 @@ struct omap_control_usb {
 
 	struct clk *sys_clk;
 
-	enum omap_control_usb_type type;
+	enum omap_control_phy_type type;
 };
 
 enum omap_control_usb_mode {
@@ -53,24 +53,24 @@ enum omap_control_usb_mode {
 #define	OMAP_CTRL_DEV_SESSEND		BIT(3)
 #define	OMAP_CTRL_DEV_IDDIG		BIT(4)
 
-#define	OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK	0x003FC000
-#define	OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT	0xE
+#define	OMAP_CTRL_PIPE3_PWRCTL_CLK_CMD_MASK	0x003FC000
+#define	OMAP_CTRL_PIPE3_PWRCTL_CLK_CMD_SHIFT	0xE
 
-#define	OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK	0xFFC00000
-#define	OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT	0x16
+#define	OMAP_CTRL_PIPE3_PWRCTL_CLK_FREQ_MASK	0xFFC00000
+#define	OMAP_CTRL_PIPE3_PWRCTL_CLK_FREQ_SHIFT	0x16
 
-#define	OMAP_CTRL_USB3_PHY_TX_RX_POWERON	0x3
-#define	OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF	0x0
+#define	OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON	0x3
+#define	OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF	0x0
 
 #define OMAP_CTRL_USB2_PHY_PD		BIT(28)
 
-#if IS_ENABLED(CONFIG_OMAP_CONTROL_USB)
-extern void omap_control_usb_phy_power(struct device *dev, int on);
+#if IS_ENABLED(CONFIG_OMAP_CONTROL_PHY)
+extern void omap_control_phy_power(struct device *dev, int on);
 extern void omap_control_usb_set_mode(struct device *dev,
 	enum omap_control_usb_mode mode);
 #else
 
-static inline void omap_control_usb_phy_power(struct device *dev, int on)
+static inline void omap_control_phy_power(struct device *dev, int on)
 {
 }
 
@@ -80,4 +80,4 @@ static inline void omap_control_usb_set_mode(struct device *dev,
 }
 #endif
 
-#endif	/* __OMAP_CONTROL_USB_H__ */
+#endif	/* __OMAP_CONTROL_PHY_H__ */
-- 
1.7.10.4


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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-09-02 15:43 ` [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework Kishon Vijay Abraham I
@ 2013-09-12  9:27   ` Vivek Gautam
  2013-09-12 10:10     ` Kishon Vijay Abraham I
  2013-09-12 13:19   ` Roger Quadros
  2013-10-11 15:09   ` Roger Quadros
  2 siblings, 1 reply; 47+ messages in thread
From: Vivek Gautam @ 2013-09-12  9:27 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: rogerq, Felipe Balbi, bcousson, Tony Lindgren, Rob Herring,
	Pawel Moll, Mark Rutland, Russell King - ARM Linux, Grant Likely,
	Sylwester Nawrocki, galak, Stephen Warren, Ian Campbell,
	Rob Landley, george.cherian, Greg KH, linux-doc, linux-omap,
	devicetree, Linux USB Mailing List, linux-arm-kernel,
	linux-kernel

Hi Kishon,


On Mon, Sep 2, 2013 at 9:13 PM, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
> power_on and power_off the following APIs are used phy_init(), phy_exit(),
> phy_power_on() and phy_power_off().
>
> However using the old USB phy library wont be removed till the PHYs of all
> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>  drivers/usb/dwc3/Kconfig                       |    1 +
>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>  drivers/usb/dwc3/core.h                        |    7 ++++
>  4 files changed, 61 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
> index e807635..471366d 100644
> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
> @@ -6,11 +6,13 @@ Required properties:
>   - compatible: must be "snps,dwc3"
>   - reg : Address and length of the register set for the device
>   - interrupts: Interrupts used by the dwc3 controller.
> +
> +Optional properties:
>   - usb-phy : array of phandle for the PHY device.  The first element
>     in the array is expected to be a handle to the USB2/HS PHY and
>     the second element is expected to be a handle to the USB3/SS PHY
> -
> -Optional properties:
> + - phys: from the *Generic PHY* bindings
> + - phy-names: from the *Generic PHY* bindings
>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>
>  This is usually a subnode to DWC3 glue to which it is connected.
> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> index cfc16dd..ad7ce83 100644
> --- a/drivers/usb/dwc3/Kconfig
> +++ b/drivers/usb/dwc3/Kconfig
> @@ -3,6 +3,7 @@ config USB_DWC3
>         depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>         depends on EXTCON
>         select USB_PHY
> +       select GENERIC_PHY
>         select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>         help
>           Say Y or M here if your system has a Dual Role SuperSpeed
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 428c29e..485d365 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>
>         usb_phy_init(dwc->usb2_phy);
>         usb_phy_init(dwc->usb3_phy);
> +
> +       if (dwc->usb2_generic_phy)
> +               phy_init(dwc->usb2_generic_phy);
> +       if (dwc->usb3_generic_phy)
> +               phy_init(dwc->usb3_generic_phy);
> +
>         mdelay(100);
>
>         /* Clear USB3 PHY reset */
> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>  {
>         usb_phy_shutdown(dwc->usb2_phy);
>         usb_phy_shutdown(dwc->usb3_phy);
> +
> +       if (dwc->usb2_generic_phy)
> +               phy_power_off(dwc->usb2_generic_phy);
> +       if (dwc->usb3_generic_phy)
> +               phy_power_off(dwc->usb3_generic_phy);
>  }
>
>  #define DWC3_ALIGN_MASK                (16 - 1)
> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>                 dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>         }
>
> +       if (of_property_read_bool(node, "phys") || pdata->has_phy) {
> +               dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
> +               if (IS_ERR(dwc->usb2_generic_phy)) {
> +                       dev_err(dev, "no usb2 phy configured yet");
> +                       return PTR_ERR(dwc->usb2_generic_phy);
> +               }

I have a doubt here.
As i can see in the current phy drivers structuring, for OMAP there
are two phy drivers :
omap phy-omap-usb2 (talking to musb controller)
and phy-omap-usb3(talking to dwc3 controller).

Now dwc3 controller requests both usb2-phy (supported by phy-omap-usb2
?) and usb3-phy (supported by phy-omap-usb3 ?).
But phy-omap-usb2 is not the one designated to talk to DWC3
controller, then why does still DWC3 want to request usb2-phy, which
end of the day will be phy-omap-usb2.
May be i am wrong here since i don't have knowledge about OMAP h/w architecture.

Is it like phy-omap-usb2 includes UTMI phys for both musb controller
as well as dwc3 controller ?
Because if it is just for musb controller then which usb2-phy will
DWC3 be getting when it requests that type of phy.

As of now phy-samsung-usb3 driver is the interface for both UTMI+ and
PIPE3 phys for DWC3 DRD controller, and phy-samsung-usb2 driver is the
interface
for a separate USB 2.0 controller itself (not DWC3). So we have
something to correct things up for Samsung, since dwc3 initializing
the phy-samsung-usb2 is not a valid scenerio.

Can you please clarify things here ?
Thanks !!

> +
> +               dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
> +               if (IS_ERR(dwc->usb3_generic_phy)) {
> +                       dev_err(dev, "no usb3 phy configured yet");
> +                       return PTR_ERR(dwc->usb3_generic_phy);
> +               }
> +       } else {
> +               dwc->usb2_generic_phy = NULL;
> +               dwc->usb3_generic_phy = NULL;
> +       }
> +

[...]


-- 
Best Regards
Vivek

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-09-12  9:27   ` Vivek Gautam
@ 2013-09-12 10:10     ` Kishon Vijay Abraham I
  2013-09-12 10:27       ` Vivek Gautam
  0 siblings, 1 reply; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-12 10:10 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: rogerq, Felipe Balbi, bcousson, Tony Lindgren, Rob Herring,
	Pawel Moll, Mark Rutland, Russell King - ARM Linux, Grant Likely,
	Sylwester Nawrocki, galak, Stephen Warren, Ian Campbell,
	Rob Landley, george.cherian, Greg KH, linux-doc, linux-omap,
	devicetree, Linux USB Mailing List, linux-arm-kernel,
	linux-kernel

On Thursday 12 September 2013 02:57 PM, Vivek Gautam wrote:
> Hi Kishon,
> 
> 
> On Mon, Sep 2, 2013 at 9:13 PM, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>> phy_power_on() and phy_power_off().
>>
>> However using the old USB phy library wont be removed till the PHYs of all
>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>>  drivers/usb/dwc3/Kconfig                       |    1 +
>>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>>  drivers/usb/dwc3/core.h                        |    7 ++++
>>  4 files changed, 61 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>> index e807635..471366d 100644
>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>> @@ -6,11 +6,13 @@ Required properties:
>>   - compatible: must be "snps,dwc3"
>>   - reg : Address and length of the register set for the device
>>   - interrupts: Interrupts used by the dwc3 controller.
>> +
>> +Optional properties:
>>   - usb-phy : array of phandle for the PHY device.  The first element
>>     in the array is expected to be a handle to the USB2/HS PHY and
>>     the second element is expected to be a handle to the USB3/SS PHY
>> -
>> -Optional properties:
>> + - phys: from the *Generic PHY* bindings
>> + - phy-names: from the *Generic PHY* bindings
>>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>
>>  This is usually a subnode to DWC3 glue to which it is connected.
>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>> index cfc16dd..ad7ce83 100644
>> --- a/drivers/usb/dwc3/Kconfig
>> +++ b/drivers/usb/dwc3/Kconfig
>> @@ -3,6 +3,7 @@ config USB_DWC3
>>         depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>         depends on EXTCON
>>         select USB_PHY
>> +       select GENERIC_PHY
>>         select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>         help
>>           Say Y or M here if your system has a Dual Role SuperSpeed
>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>> index 428c29e..485d365 100644
>> --- a/drivers/usb/dwc3/core.c
>> +++ b/drivers/usb/dwc3/core.c
>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>
>>         usb_phy_init(dwc->usb2_phy);
>>         usb_phy_init(dwc->usb3_phy);
>> +
>> +       if (dwc->usb2_generic_phy)
>> +               phy_init(dwc->usb2_generic_phy);
>> +       if (dwc->usb3_generic_phy)
>> +               phy_init(dwc->usb3_generic_phy);
>> +
>>         mdelay(100);
>>
>>         /* Clear USB3 PHY reset */
>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>>  {
>>         usb_phy_shutdown(dwc->usb2_phy);
>>         usb_phy_shutdown(dwc->usb3_phy);
>> +
>> +       if (dwc->usb2_generic_phy)
>> +               phy_power_off(dwc->usb2_generic_phy);
>> +       if (dwc->usb3_generic_phy)
>> +               phy_power_off(dwc->usb3_generic_phy);
>>  }
>>
>>  #define DWC3_ALIGN_MASK                (16 - 1)
>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>>                 dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>>         }
>>
>> +       if (of_property_read_bool(node, "phys") || pdata->has_phy) {
>> +               dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>> +               if (IS_ERR(dwc->usb2_generic_phy)) {
>> +                       dev_err(dev, "no usb2 phy configured yet");
>> +                       return PTR_ERR(dwc->usb2_generic_phy);
>> +               }
> 
> I have a doubt here.
> As i can see in the current phy drivers structuring, for OMAP there
> are two phy drivers :
> omap phy-omap-usb2 (talking to musb controller)

It talks to dwc3 controller also ;-)

> and phy-omap-usb3(talking to dwc3 controller).
> 
> Now dwc3 controller requests both usb2-phy (supported by phy-omap-usb2
> ?) and usb3-phy (supported by phy-omap-usb3 ?).
> But phy-omap-usb2 is not the one designated to talk to DWC3
> controller, then why does still DWC3 want to request usb2-phy, which
> end of the day will be phy-omap-usb2.
> May be i am wrong here since i don't have knowledge about OMAP h/w architecture.
> 
> Is it like phy-omap-usb2 includes UTMI phys for both musb controller
> as well as dwc3 controller ?

right. It's needed for dwc3 too. The same USB2 PHY IP is used for both MUSB in
OMAP2+ platforms and DWC3 in OMAP5.

Thanks
Kishon

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-09-12 10:10     ` Kishon Vijay Abraham I
@ 2013-09-12 10:27       ` Vivek Gautam
  2013-10-10 10:28         ` Kishon Vijay Abraham I
  0 siblings, 1 reply; 47+ messages in thread
From: Vivek Gautam @ 2013-09-12 10:27 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: rogerq, Felipe Balbi, bcousson, Tony Lindgren, Rob Herring,
	Pawel Moll, Mark Rutland, Russell King - ARM Linux, Grant Likely,
	Sylwester Nawrocki, galak, Stephen Warren, Ian Campbell,
	Rob Landley, george.cherian, Greg KH, linux-doc, linux-omap,
	devicetree, Linux USB Mailing List, linux-arm-kernel,
	linux-kernel

On Thu, Sep 12, 2013 at 3:40 PM, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> On Thursday 12 September 2013 02:57 PM, Vivek Gautam wrote:
>> Hi Kishon,
>>
>>
>> On Mon, Sep 2, 2013 at 9:13 PM, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>>> phy_power_on() and phy_power_off().
>>>
>>> However using the old USB phy library wont be removed till the PHYs of all
>>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>>>  drivers/usb/dwc3/Kconfig                       |    1 +
>>>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>>>  drivers/usb/dwc3/core.h                        |    7 ++++
>>>  4 files changed, 61 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>>> index e807635..471366d 100644
>>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>>> @@ -6,11 +6,13 @@ Required properties:
>>>   - compatible: must be "snps,dwc3"
>>>   - reg : Address and length of the register set for the device
>>>   - interrupts: Interrupts used by the dwc3 controller.
>>> +
>>> +Optional properties:
>>>   - usb-phy : array of phandle for the PHY device.  The first element
>>>     in the array is expected to be a handle to the USB2/HS PHY and
>>>     the second element is expected to be a handle to the USB3/SS PHY
>>> -
>>> -Optional properties:
>>> + - phys: from the *Generic PHY* bindings
>>> + - phy-names: from the *Generic PHY* bindings
>>>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>>
>>>  This is usually a subnode to DWC3 glue to which it is connected.
>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>>> index cfc16dd..ad7ce83 100644
>>> --- a/drivers/usb/dwc3/Kconfig
>>> +++ b/drivers/usb/dwc3/Kconfig
>>> @@ -3,6 +3,7 @@ config USB_DWC3
>>>         depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>>         depends on EXTCON
>>>         select USB_PHY
>>> +       select GENERIC_PHY
>>>         select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>>         help
>>>           Say Y or M here if your system has a Dual Role SuperSpeed
>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>> index 428c29e..485d365 100644
>>> --- a/drivers/usb/dwc3/core.c
>>> +++ b/drivers/usb/dwc3/core.c
>>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>>
>>>         usb_phy_init(dwc->usb2_phy);
>>>         usb_phy_init(dwc->usb3_phy);
>>> +
>>> +       if (dwc->usb2_generic_phy)
>>> +               phy_init(dwc->usb2_generic_phy);
>>> +       if (dwc->usb3_generic_phy)
>>> +               phy_init(dwc->usb3_generic_phy);
>>> +
>>>         mdelay(100);
>>>
>>>         /* Clear USB3 PHY reset */
>>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>>>  {
>>>         usb_phy_shutdown(dwc->usb2_phy);
>>>         usb_phy_shutdown(dwc->usb3_phy);
>>> +
>>> +       if (dwc->usb2_generic_phy)
>>> +               phy_power_off(dwc->usb2_generic_phy);
>>> +       if (dwc->usb3_generic_phy)
>>> +               phy_power_off(dwc->usb3_generic_phy);
>>>  }
>>>
>>>  #define DWC3_ALIGN_MASK                (16 - 1)
>>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>>>                 dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>>>         }
>>>
>>> +       if (of_property_read_bool(node, "phys") || pdata->has_phy) {
>>> +               dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>>> +               if (IS_ERR(dwc->usb2_generic_phy)) {
>>> +                       dev_err(dev, "no usb2 phy configured yet");
>>> +                       return PTR_ERR(dwc->usb2_generic_phy);
>>> +               }
>>
>> I have a doubt here.
>> As i can see in the current phy drivers structuring, for OMAP there
>> are two phy drivers :
>> omap phy-omap-usb2 (talking to musb controller)
>
> It talks to dwc3 controller also ;-)

Ok

>
>> and phy-omap-usb3(talking to dwc3 controller).
>>
>> Now dwc3 controller requests both usb2-phy (supported by phy-omap-usb2
>> ?) and usb3-phy (supported by phy-omap-usb3 ?).
>> But phy-omap-usb2 is not the one designated to talk to DWC3
>> controller, then why does still DWC3 want to request usb2-phy, which
>> end of the day will be phy-omap-usb2.
>> May be i am wrong here since i don't have knowledge about OMAP h/w architecture.
>>
>> Is it like phy-omap-usb2 includes UTMI phys for both musb controller
>> as well as dwc3 controller ?
>
> right. It's needed for dwc3 too. The same USB2 PHY IP is used for both MUSB in
> OMAP2+ platforms and DWC3 in OMAP5.

Ok, but on Samsung's exynos5 series of SoCs, the USB2.0 controller has
a separate USB-PHY interface talking to phy-samsung-usb2 driver;
and DWC3 drd controller has separate USB-PHY interface (including both
UTMI+ and PIPE3 control registers) talking to phy-samsung-usb3 driver.
So in this case DWC3 doesn't need phy-samsung-usb2 at all. It's phy is
configured by just phy-samsung-usb3 driver only.
So don't you think DWC3 driver should have the flexibility to have
either (mostly usb3-phy) _or_ both "usb2-phy" and "usb3-phy".
Thereby,in case of Samsung driver, DWC3 will just have "usb3-phy" and
that will be enough to get things working.
Want your opinions about it.


-- 
Best Regards
Vivek

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

* Re: [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY
  2013-09-02 15:43 ` [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY Kishon Vijay Abraham I
@ 2013-09-12 10:36   ` Roger Quadros
  2013-09-12 10:47     ` Vivek Gautam
  0 siblings, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-09-12 10:36 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Hi Kishon,

On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
> There can be systems which does not have a external usb_phy, so get
> usb_phy only if usb-phy property is added in the case of dt boot or if
> platform_data indicates the presence of PHY. Also remove checking if
> return value is -ENXIO since it's now changed to always enable usb_phy layer.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  drivers/usb/dwc3/Kconfig         |    1 +
>  drivers/usb/dwc3/core.c          |   60 +++++++++++++++++---------------------
>  drivers/usb/dwc3/platform_data.h |    1 +
>  3 files changed, 28 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> index f969ea2..cfc16dd 100644
> --- a/drivers/usb/dwc3/Kconfig
> +++ b/drivers/usb/dwc3/Kconfig
> @@ -2,6 +2,7 @@ config USB_DWC3
>  	tristate "DesignWare USB3 DRD Core Support"
>  	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>  	depends on EXTCON
> +	select USB_PHY
>  	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>  	help
>  	  Say Y or M here if your system has a Dual Role SuperSpeed
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 474162e..428c29e 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -387,16 +387,38 @@ static int dwc3_probe(struct platform_device *pdev)
>  	if (node) {
>  		dwc->maximum_speed = of_usb_get_maximum_speed(node);
>  
> -		dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
> -		dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
> +		if (of_property_read_bool(node, "usb-phy")) {
> +			dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev,
> +				"usb-phy", 0);
> +			if (IS_ERR(dwc->usb2_phy))
> +				return PTR_ERR(dwc->usb2_phy);
> +			dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev,
> +				"usb-phy", 1);
> +			if (IS_ERR(dwc->usb3_phy))
> +				return PTR_ERR(dwc->usb3_phy);

Some DWC3 instances use only usb2_phy. e.g. on DRA7 the 2nd dwc3 instance doesn't use usb3_phy.
This needs to be a valid case and driver shouldn't error out.

> +		} else {
> +			dwc->usb2_phy = NULL;
> +			dwc->usb3_phy = NULL;
> +		}
>  
>  		dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
>  		dwc->dr_mode = of_usb_get_dr_mode(node);
>  	} else if (pdata) {
>  		dwc->maximum_speed = pdata->maximum_speed;
>  
> -		dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
> -		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
> +		if (pdata->has_phy) {
> +			dwc->usb2_phy = devm_usb_get_phy(dev,
> +				USB_PHY_TYPE_USB2);
> +			if (IS_ERR(dwc->usb2_phy))
> +				return PTR_ERR(dwc->usb2_phy);
> +			dwc->usb3_phy = devm_usb_get_phy(dev,
> +				USB_PHY_TYPE_USB3);
> +			if (IS_ERR(dwc->usb3_phy))
> +				return PTR_ERR(dwc->usb3_phy);

same here?

> +		} else {
> +			dwc->usb2_phy = NULL;
> +			dwc->usb3_phy = NULL;
> +		}
>  
>  		dwc->needs_fifo_resize = pdata->tx_fifo_resize;
>  		dwc->dr_mode = pdata->dr_mode;
> @@ -409,36 +431,6 @@ static int dwc3_probe(struct platform_device *pdev)
>  	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
>  		dwc->maximum_speed = USB_SPEED_SUPER;
>  
> -	if (IS_ERR(dwc->usb2_phy)) {
> -		ret = PTR_ERR(dwc->usb2_phy);
> -
> -		/*
> -		 * if -ENXIO is returned, it means PHY layer wasn't
> -		 * enabled, so it makes no sense to return -EPROBE_DEFER
> -		 * in that case, since no PHY driver will ever probe.
> -		 */
> -		if (ret == -ENXIO)
> -			return ret;
> -
> -		dev_err(dev, "no usb2 phy configured\n");
> -		return -EPROBE_DEFER;
> -	}
> -
> -	if (IS_ERR(dwc->usb3_phy)) {
> -		ret = PTR_ERR(dwc->usb3_phy);
> -
> -		/*
> -		 * if -ENXIO is returned, it means PHY layer wasn't
> -		 * enabled, so it makes no sense to return -EPROBE_DEFER
> -		 * in that case, since no PHY driver will ever probe.
> -		 */
> -		if (ret == -ENXIO)
> -			return ret;
> -
> -		dev_err(dev, "no usb3 phy configured\n");
> -		return -EPROBE_DEFER;
> -	}
> -
>  	dwc->xhci_resources[0].start = res->start;
>  	dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
>  					DWC3_XHCI_REGS_END;
> diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
> index 7db34f0..5a5e068 100644
> --- a/drivers/usb/dwc3/platform_data.h
> +++ b/drivers/usb/dwc3/platform_data.h
> @@ -24,4 +24,5 @@ struct dwc3_platform_data {
>  	enum usb_device_speed maximum_speed;
>  	enum usb_dr_mode dr_mode;
>  	bool tx_fifo_resize;
> +	bool has_phy;
>  };
> 

cheers,
-roger

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

* Re: [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY
  2013-09-12 10:36   ` Roger Quadros
@ 2013-09-12 10:47     ` Vivek Gautam
  2013-09-12 11:04       ` Roger Quadros
  2013-09-17 15:45       ` Felipe Balbi
  0 siblings, 2 replies; 47+ messages in thread
From: Vivek Gautam @ 2013-09-12 10:47 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Kishon Vijay Abraham I, Felipe Balbi, Benoit Cousson,
	Tony Lindgren, Rob Herring, Pawel Moll, Mark Rutland,
	Russell King - ARM Linux, Grant Likely, Sylwester Nawrocki,
	Kumar Gala, Stephen Warren, Ian Campbell, Rob Landley,
	george.cherian, Greg KH, linux-doc, linux-omap, devicetree,
	Linux USB Mailing List, linux-arm-kernel, linux-kernel

On Thu, Sep 12, 2013 at 4:06 PM, Roger Quadros <rogerq@ti.com> wrote:
> Hi Kishon,
>
> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>> There can be systems which does not have a external usb_phy, so get
>> usb_phy only if usb-phy property is added in the case of dt boot or if
>> platform_data indicates the presence of PHY. Also remove checking if
>> return value is -ENXIO since it's now changed to always enable usb_phy layer.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>>  drivers/usb/dwc3/Kconfig         |    1 +
>>  drivers/usb/dwc3/core.c          |   60 +++++++++++++++++---------------------
>>  drivers/usb/dwc3/platform_data.h |    1 +
>>  3 files changed, 28 insertions(+), 34 deletions(-)
>>
>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>> index f969ea2..cfc16dd 100644
>> --- a/drivers/usb/dwc3/Kconfig
>> +++ b/drivers/usb/dwc3/Kconfig
>> @@ -2,6 +2,7 @@ config USB_DWC3
>>       tristate "DesignWare USB3 DRD Core Support"
>>       depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>       depends on EXTCON
>> +     select USB_PHY
>>       select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>       help
>>         Say Y or M here if your system has a Dual Role SuperSpeed
>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>> index 474162e..428c29e 100644
>> --- a/drivers/usb/dwc3/core.c
>> +++ b/drivers/usb/dwc3/core.c
>> @@ -387,16 +387,38 @@ static int dwc3_probe(struct platform_device *pdev)
>>       if (node) {
>>               dwc->maximum_speed = of_usb_get_maximum_speed(node);
>>
>> -             dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
>> -             dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
>> +             if (of_property_read_bool(node, "usb-phy")) {
>> +                     dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev,
>> +                             "usb-phy", 0);
>> +                     if (IS_ERR(dwc->usb2_phy))
>> +                             return PTR_ERR(dwc->usb2_phy);
>> +                     dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev,
>> +                             "usb-phy", 1);
>> +                     if (IS_ERR(dwc->usb3_phy))
>> +                             return PTR_ERR(dwc->usb3_phy);
>
> Some DWC3 instances use only usb2_phy. e.g. on DRA7 the 2nd dwc3 instance doesn't use usb3_phy.
> This needs to be a valid case and driver shouldn't error out.

So, i think adding flexibility to DWC3 to have either
usb2-phy/usb3-phy or both of them seems to be valid point.
Any suggestions ?

>
>> +             } else {
>> +                     dwc->usb2_phy = NULL;
>> +                     dwc->usb3_phy = NULL;
>> +             }
>>
>>               dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
>>               dwc->dr_mode = of_usb_get_dr_mode(node);
>>       } else if (pdata) {
>>               dwc->maximum_speed = pdata->maximum_speed;
>>
>> -             dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
>> -             dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>> +             if (pdata->has_phy) {
>> +                     dwc->usb2_phy = devm_usb_get_phy(dev,
>> +                             USB_PHY_TYPE_USB2);
>> +                     if (IS_ERR(dwc->usb2_phy))
>> +                             return PTR_ERR(dwc->usb2_phy);
>> +                     dwc->usb3_phy = devm_usb_get_phy(dev,
>> +                             USB_PHY_TYPE_USB3);
>> +                     if (IS_ERR(dwc->usb3_phy))
>> +                             return PTR_ERR(dwc->usb3_phy);
>
> same here?
>
>> +             } else {
>> +                     dwc->usb2_phy = NULL;
>> +                     dwc->usb3_phy = NULL;
>> +             }
>>
>>               dwc->needs_fifo_resize = pdata->tx_fifo_resize;
>>               dwc->dr_mode = pdata->dr_mode;
>> @@ -409,36 +431,6 @@ static int dwc3_probe(struct platform_device *pdev)
>>       if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
>>               dwc->maximum_speed = USB_SPEED_SUPER;
>>
>> -     if (IS_ERR(dwc->usb2_phy)) {
>> -             ret = PTR_ERR(dwc->usb2_phy);
>> -
>> -             /*
>> -              * if -ENXIO is returned, it means PHY layer wasn't
>> -              * enabled, so it makes no sense to return -EPROBE_DEFER
>> -              * in that case, since no PHY driver will ever probe.
>> -              */
>> -             if (ret == -ENXIO)
>> -                     return ret;
>> -
>> -             dev_err(dev, "no usb2 phy configured\n");
>> -             return -EPROBE_DEFER;
>> -     }
>> -
>> -     if (IS_ERR(dwc->usb3_phy)) {
>> -             ret = PTR_ERR(dwc->usb3_phy);
>> -
>> -             /*
>> -              * if -ENXIO is returned, it means PHY layer wasn't
>> -              * enabled, so it makes no sense to return -EPROBE_DEFER
>> -              * in that case, since no PHY driver will ever probe.
>> -              */
>> -             if (ret == -ENXIO)
>> -                     return ret;
>> -
>> -             dev_err(dev, "no usb3 phy configured\n");
>> -             return -EPROBE_DEFER;
>> -     }
>> -
>>       dwc->xhci_resources[0].start = res->start;
>>       dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
>>                                       DWC3_XHCI_REGS_END;
>> diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
>> index 7db34f0..5a5e068 100644
>> --- a/drivers/usb/dwc3/platform_data.h
>> +++ b/drivers/usb/dwc3/platform_data.h
>> @@ -24,4 +24,5 @@ struct dwc3_platform_data {
>>       enum usb_device_speed maximum_speed;
>>       enum usb_dr_mode dr_mode;
>>       bool tx_fifo_resize;
>> +     bool has_phy;
>>  };
>>
>
> cheers,
> -roger
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
Best Regards
Vivek

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

* Re: [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY
  2013-09-12 10:47     ` Vivek Gautam
@ 2013-09-12 11:04       ` Roger Quadros
  2013-09-12 11:26         ` Vivek Gautam
  2013-09-17 15:45       ` Felipe Balbi
  1 sibling, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-09-12 11:04 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: Kishon Vijay Abraham I, Felipe Balbi, Benoit Cousson,
	Tony Lindgren, Rob Herring, Pawel Moll, Mark Rutland,
	Russell King - ARM Linux, Grant Likely, Sylwester Nawrocki,
	Kumar Gala, Stephen Warren, Ian Campbell, Rob Landley,
	george.cherian, Greg KH, linux-doc, linux-omap, devicetree,
	Linux USB Mailing List, linux-arm-kernel, linux-kernel

Hi,

On 09/12/2013 01:47 PM, Vivek Gautam wrote:
> On Thu, Sep 12, 2013 at 4:06 PM, Roger Quadros <rogerq@ti.com> wrote:
>> Hi Kishon,
>>
>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>>> There can be systems which does not have a external usb_phy, so get
>>> usb_phy only if usb-phy property is added in the case of dt boot or if
>>> platform_data indicates the presence of PHY. Also remove checking if
>>> return value is -ENXIO since it's now changed to always enable usb_phy layer.
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>>  drivers/usb/dwc3/Kconfig         |    1 +
>>>  drivers/usb/dwc3/core.c          |   60 +++++++++++++++++---------------------
>>>  drivers/usb/dwc3/platform_data.h |    1 +
>>>  3 files changed, 28 insertions(+), 34 deletions(-)
>>>
>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>>> index f969ea2..cfc16dd 100644
>>> --- a/drivers/usb/dwc3/Kconfig
>>> +++ b/drivers/usb/dwc3/Kconfig
>>> @@ -2,6 +2,7 @@ config USB_DWC3
>>>       tristate "DesignWare USB3 DRD Core Support"
>>>       depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>>       depends on EXTCON
>>> +     select USB_PHY
>>>       select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>>       help
>>>         Say Y or M here if your system has a Dual Role SuperSpeed
>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>> index 474162e..428c29e 100644
>>> --- a/drivers/usb/dwc3/core.c
>>> +++ b/drivers/usb/dwc3/core.c
>>> @@ -387,16 +387,38 @@ static int dwc3_probe(struct platform_device *pdev)
>>>       if (node) {
>>>               dwc->maximum_speed = of_usb_get_maximum_speed(node);
>>>
>>> -             dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
>>> -             dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
>>> +             if (of_property_read_bool(node, "usb-phy")) {
>>> +                     dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev,
>>> +                             "usb-phy", 0);
>>> +                     if (IS_ERR(dwc->usb2_phy))
>>> +                             return PTR_ERR(dwc->usb2_phy);
>>> +                     dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev,
>>> +                             "usb-phy", 1);
>>> +                     if (IS_ERR(dwc->usb3_phy))
>>> +                             return PTR_ERR(dwc->usb3_phy);
>>
>> Some DWC3 instances use only usb2_phy. e.g. on DRA7 the 2nd dwc3 instance doesn't use usb3_phy.
>> This needs to be a valid case and driver shouldn't error out.
> 
> So, i think adding flexibility to DWC3 to have either
> usb2-phy/usb3-phy or both of them seems to be valid point.
> Any suggestions ?
> 

For high speed operation we need only usb2_phy but for super speed we need both usb2_phy
and usb3_phy.

Why would a dwc3 controller use only usb3_phy? A USB3.0 interface has to be compatible with
USB2.0 as well, no?

cheers,
-roger


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

* Re: [PATCH 3/7] drivers: phy: usb3/pipe3: Adapt pipe3 driver to Generic PHY Framework
  2013-09-02 15:43 ` [PATCH 3/7] drivers: phy: usb3/pipe3: Adapt pipe3 driver to " Kishon Vijay Abraham I
@ 2013-09-12 11:19   ` Roger Quadros
  2013-09-16  3:01     ` Kishon Vijay Abraham I
  0 siblings, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-09-12 11:19 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Hi Kishon,

On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
> Adapted omap-usb3 PHY driver to Generic PHY Framework and moved phy-omap-usb3
> driver in drivers/usb/phy to drivers/phy and also renamed the file to
> phy-omap-pipe3 since this same driver will be used for SATA PHY and
> PCIE PHY.

I would suggest to split the renaming and PHY adaptation into 2 separate patches.

> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  Documentation/devicetree/bindings/usb/usb-phy.txt  |    5 +-
>  drivers/phy/Kconfig                                |   10 +
>  drivers/phy/Makefile                               |    1 +
>  .../phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c}   |  206 +++++++++++---------

how about naming it to phy-ti-pipe3.c as it is used on OMAP as well as non-OMAP e.g. DRA7.

>  drivers/usb/phy/Kconfig                            |   11 --
>  drivers/usb/phy/Makefile                           |    1 -
>  include/linux/phy/omap_pipe3.h                     |   52 +++++
>  7 files changed, 177 insertions(+), 109 deletions(-)
>  rename drivers/{usb/phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c} (57%)
>  create mode 100644 include/linux/phy/omap_pipe3.h
> 
> diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt
> index c0245c8..36bdb17 100644
> --- a/Documentation/devicetree/bindings/usb/usb-phy.txt
> +++ b/Documentation/devicetree/bindings/usb/usb-phy.txt
> @@ -21,10 +21,11 @@ usb2phy@4a0ad080 {
>  	#phy-cells = <0>;
>  };
>  
> -OMAP USB3 PHY
> +OMAP PIPE3 PHY
>  
>  Required properties:
> - - compatible: Should be "ti,omap-usb3"
> + - compatible: Should be "ti,omap-usb3", "ti,omap-pipe3", "ti,omap-sata"
> +   or "ti,omap-pcie"
>   - reg : Address and length of the register set for the device.
>   - reg-names: The names of the register addresses corresponding to the registers
>     filled in "reg".
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index ac239ac..5c2e7a0 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -27,6 +27,16 @@ config OMAP_USB2
>  	  The USB OTG controller communicates with the comparator using this
>  	  driver.
>  
> +config OMAP_PIPE3
> +	tristate "OMAP PIPE3 PHY Driver"
> +	select GENERIC_PHY
> +	select OMAP_CONTROL_USB
how about
	depends on OMAP_CONTROL_USB

Also, if this is TI/OMAP it might as well depend on ARCH_OMAP.

> +	help
> +	  Enable this to support the PIPE3 PHY that is part of SOC. This

worth mentioning TI OMAP/DRA SoCs.

> +	  driver takes care of all the PHY functionality apart from comparator.
> +	  This driver interacts with the "OMAP Control PHY Driver" to power
> +	  on/off the PHY.
> +
>  config TWL4030_USB
>  	tristate "TWL4030 USB Transceiver Driver"
>  	depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index 0dd8a98..48bf9f2 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -4,4 +4,5 @@
>  
>  obj-$(CONFIG_GENERIC_PHY)	+= phy-core.o
>  obj-$(CONFIG_OMAP_USB2)		+= phy-omap-usb2.o
> +obj-$(CONFIG_OMAP_PIPE3)	+= phy-omap-pipe3.o
>  obj-$(CONFIG_TWL4030_USB)	+= phy-twl4030-usb.o
> diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/phy/phy-omap-pipe3.c
> similarity index 57%
> rename from drivers/usb/phy/phy-omap-usb3.c
> rename to drivers/phy/phy-omap-pipe3.c
> index 4004f82..ee9a901 100644
> --- a/drivers/usb/phy/phy-omap-usb3.c
> +++ b/drivers/phy/phy-omap-pipe3.c
> @@ -1,5 +1,5 @@
>  /*
> - * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP.
> + * omap-pipe3 - PHY driver for SATA, USB and PCIE in OMAP platforms
>   *
>   * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
>   * This program is free software; you can redistribute it and/or modify
> @@ -19,7 +19,8 @@
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
>  #include <linux/slab.h>
> -#include <linux/usb/omap_usb.h>
> +#include <linux/phy/omap_pipe3.h>
> +#include <linux/phy/phy.h>
>  #include <linux/of.h>
>  #include <linux/clk.h>
>  #include <linux/err.h>
> @@ -52,17 +53,17 @@
>  
>  /*
>   * This is an Empirical value that works, need to confirm the actual
> - * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status
> - * to be correctly reflected in the USB3PHY_PLL_STATUS register.
> + * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status
> + * to be correctly reflected in the PIPE3PHY_PLL_STATUS register.
>   */
>  # define PLL_IDLE_TIME  100;
>  
> -struct usb_dpll_map {
> +struct pipe3_dpll_map {
>  	unsigned long rate;
> -	struct usb_dpll_params params;
> +	struct pipe3_dpll_params params;
>  };
>  
> -static struct usb_dpll_map dpll_map[] = {
> +static struct pipe3_dpll_map dpll_map[] = {
>  	{12000000, {1250, 5, 4, 20, 0} },	/* 12 MHz */
>  	{16800000, {3125, 20, 4, 20, 0} },	/* 16.8 MHz */
>  	{19200000, {1172, 8, 4, 20, 65537} },	/* 19.2 MHz */
> @@ -71,7 +72,7 @@ static struct usb_dpll_map dpll_map[] = {
>  	{38400000, {3125, 47, 4, 20, 92843} },	/* 38.4 MHz */
>  };
>  
> -static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
> +static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(unsigned long rate)
>  {
>  	int i;
>  
> @@ -83,110 +84,113 @@ static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
>  	return 0;
>  }
>  
> -static int omap_usb3_suspend(struct usb_phy *x, int suspend)
> +static int omap_pipe3_power_off(struct phy *x)
>  {
> -	struct omap_usb *phy = phy_to_omapusb(x);
> -	int	val;
> +	struct omap_pipe3 *phy = phy_get_drvdata(x);
> +	int val;
>  	int timeout = PLL_IDLE_TIME;
>  
> -	if (suspend && !phy->is_suspended) {
> -		val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
> -		val |= PLL_IDLE;
> -		omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
> -
> -		do {
> -			val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
> -			if (val & PLL_TICOPWDN)
> -				break;
> -			udelay(1);
> -		} while (--timeout);
> -
> -		omap_control_usb_phy_power(phy->control_dev, 0);
> -
> -		phy->is_suspended	= 1;
> -	} else if (!suspend && phy->is_suspended) {
> -		phy->is_suspended	= 0;
> -
> -		val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
> -		val &= ~PLL_IDLE;
> -		omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
> -
> -		do {
> -			val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
> -			if (!(val & PLL_TICOPWDN))
> -				break;
> -			udelay(1);
> -		} while (--timeout);
> -	}
> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
> +	val |= PLL_IDLE;
> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
> +
> +	do {
> +		val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
> +		if (val & PLL_TICOPWDN)
> +			break;
> +		udelay(1);

Is it better to sleep instead of udelay?

> +	} while (--timeout);
> +
> +	omap_control_usb_phy_power(phy->control_dev, 0);
> +
> +	return 0;
> +}
> +
> +static int omap_pipe3_power_on(struct phy *x)
> +{
> +	struct omap_pipe3 *phy = phy_get_drvdata(x);
> +	int val;
> +	int timeout = PLL_IDLE_TIME;
> +
> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
> +	val &= ~PLL_IDLE;
> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
> +
> +	do {
> +		val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
> +		if (!(val & PLL_TICOPWDN))
> +			break;
> +		udelay(1);

here too.

> +	} while (--timeout);
>  
>  	return 0;
>  }
>  
> -static void omap_usb_dpll_relock(struct omap_usb *phy)
> +static void omap_pipe3_dpll_relock(struct omap_pipe3 *phy)
>  {
>  	u32		val;
>  	unsigned long	timeout;
>  
> -	omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
>  
>  	timeout = jiffies + msecs_to_jiffies(20);
>  	do {
> -		val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
> +		val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>  		if (val & PLL_LOCK)
>  			break;
>  	} while (!WARN_ON(time_after(jiffies, timeout)));
>  }
>  
> -static int omap_usb_dpll_lock(struct omap_usb *phy)
> +static int omap_pipe3_dpll_lock(struct omap_pipe3 *phy)
>  {
>  	u32			val;
>  	unsigned long		rate;
> -	struct usb_dpll_params *dpll_params;
> +	struct pipe3_dpll_params *dpll_params;
>  
>  	rate = clk_get_rate(phy->sys_clk);
> -	dpll_params = omap_usb3_get_dpll_params(rate);
> +	dpll_params = omap_pipe3_get_dpll_params(rate);
>  	if (!dpll_params) {
>  		dev_err(phy->dev,
>  			  "No DPLL configuration for %lu Hz SYS CLK\n", rate);
>  		return -EINVAL;
>  	}
>  
> -	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>  	val &= ~PLL_REGN_MASK;
>  	val |= dpll_params->n << PLL_REGN_SHIFT;
> -	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>  
> -	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>  	val &= ~PLL_SELFREQDCO_MASK;
>  	val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
> -	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>  
> -	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>  	val &= ~PLL_REGM_MASK;
>  	val |= dpll_params->m << PLL_REGM_SHIFT;
> -	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>  
> -	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
>  	val &= ~PLL_REGM_F_MASK;
>  	val |= dpll_params->mf << PLL_REGM_F_SHIFT;
> -	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
>  
> -	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
>  	val &= ~PLL_SD_MASK;
>  	val |= dpll_params->sd << PLL_SD_SHIFT;
> -	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
>  
> -	omap_usb_dpll_relock(phy);
> +	omap_pipe3_dpll_relock(phy);
>  
>  	return 0;
>  }
>  
> -static int omap_usb3_init(struct usb_phy *x)
> +static int omap_pipe3_init(struct phy *x)
>  {
> -	struct omap_usb	*phy = phy_to_omapusb(x);
> +	struct omap_pipe3 *phy = phy_get_drvdata(x);
>  	int ret;
>  
> -	ret = omap_usb_dpll_lock(phy);
> +	ret = omap_pipe3_dpll_lock(phy);
>  	if (ret)
>  		return ret;
>  
> @@ -195,9 +199,18 @@ static int omap_usb3_init(struct usb_phy *x)
>  	return 0;
>  }
>  
> -static int omap_usb3_probe(struct platform_device *pdev)
> +static struct phy_ops ops = {
> +	.init		= omap_pipe3_init,
> +	.power_on	= omap_pipe3_power_on,
> +	.power_off	= omap_pipe3_power_off,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static int omap_pipe3_probe(struct platform_device *pdev)
>  {
> -	struct omap_usb *phy;
> +	struct omap_pipe3 *phy;
> +	struct phy *generic_phy;
> +	struct phy_provider *phy_provider;
>  	struct resource *res;
>  	struct device_node *node = pdev->dev.of_node;
>  	struct device_node *control_node;
> @@ -208,7 +221,7 @@ static int omap_usb3_probe(struct platform_device *pdev)
>  
>  	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
>  	if (!phy) {
> -		dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n");
> +		dev_err(&pdev->dev, "unable to alloc mem for OMAP PIPE3 PHY\n");
>  		return -ENOMEM;
>  	}
>  
> @@ -219,13 +232,6 @@ static int omap_usb3_probe(struct platform_device *pdev)
>  
>  	phy->dev		= &pdev->dev;
>  
> -	phy->phy.dev		= phy->dev;
> -	phy->phy.label		= "omap-usb3";
> -	phy->phy.init		= omap_usb3_init;
> -	phy->phy.set_suspend	= omap_usb3_suspend;
> -	phy->phy.type		= USB_PHY_TYPE_USB3;
> -
> -	phy->is_suspended	= 1;
>  	phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");

As this is no longer USB specific, we need to make the clock binding generic as well.

>  	if (IS_ERR(phy->wkupclk)) {
>  		dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
> @@ -251,6 +257,11 @@ static int omap_usb3_probe(struct platform_device *pdev)
>  		dev_err(&pdev->dev, "Failed to get control device phandle\n");
>  		return -EINVAL;
>  	}
> +	phy_provider = devm_of_phy_provider_register(phy->dev,
> +			of_phy_simple_xlate);
> +	if (IS_ERR(phy_provider))
> +		return PTR_ERR(phy_provider);
> +
>  	control_pdev = of_find_device_by_node(control_node);
>  	if (!control_pdev) {
>  		dev_err(&pdev->dev, "Failed to get control device\n");
> @@ -260,23 +271,27 @@ static int omap_usb3_probe(struct platform_device *pdev)
>  	phy->control_dev = &control_pdev->dev;
>  
>  	omap_control_usb_phy_power(phy->control_dev, 0);
> -	usb_add_phy_dev(&phy->phy);
>  
>  	platform_set_drvdata(pdev, phy);
> -
>  	pm_runtime_enable(phy->dev);
> +
> +	generic_phy = devm_phy_create(phy->dev, &ops, NULL);
> +	if (IS_ERR(generic_phy))
> +		return PTR_ERR(generic_phy);
> +
> +	phy_set_drvdata(generic_phy, phy);
> +
>  	pm_runtime_get(&pdev->dev);
>  
>  	return 0;
>  }
>  
> -static int omap_usb3_remove(struct platform_device *pdev)
> +static int omap_pipe3_remove(struct platform_device *pdev)
>  {
> -	struct omap_usb *phy = platform_get_drvdata(pdev);
> +	struct omap_pipe3 *phy = platform_get_drvdata(pdev);
>  
>  	clk_unprepare(phy->wkupclk);
>  	clk_unprepare(phy->optclk);
> -	usb_remove_phy(&phy->phy);
>  	if (!pm_runtime_suspended(&pdev->dev))
>  		pm_runtime_put(&pdev->dev);
>  	pm_runtime_disable(&pdev->dev);
> @@ -286,10 +301,9 @@ static int omap_usb3_remove(struct platform_device *pdev)
>  
>  #ifdef CONFIG_PM_RUNTIME
>  
> -static int omap_usb3_runtime_suspend(struct device *dev)
> +static int omap_pipe3_runtime_suspend(struct device *dev)
>  {
> -	struct platform_device	*pdev = to_platform_device(dev);
> -	struct omap_usb	*phy = platform_get_drvdata(pdev);
> +	struct omap_pipe3	*phy = dev_get_drvdata(dev);
>  
>  	clk_disable(phy->wkupclk);
>  	clk_disable(phy->optclk);
> @@ -297,11 +311,10 @@ static int omap_usb3_runtime_suspend(struct device *dev)
>  	return 0;
>  }
>  
> -static int omap_usb3_runtime_resume(struct device *dev)
> +static int omap_pipe3_runtime_resume(struct device *dev)
>  {
>  	u32 ret = 0;
> -	struct platform_device	*pdev = to_platform_device(dev);
> -	struct omap_usb	*phy = platform_get_drvdata(pdev);
> +	struct omap_pipe3	*phy = dev_get_drvdata(dev);
>  
>  	ret = clk_enable(phy->optclk);
>  	if (ret) {
> @@ -324,38 +337,41 @@ err1:
>  	return ret;
>  }
>  
> -static const struct dev_pm_ops omap_usb3_pm_ops = {
> -	SET_RUNTIME_PM_OPS(omap_usb3_runtime_suspend, omap_usb3_runtime_resume,
> -		NULL)
> +static const struct dev_pm_ops omap_pipe3_pm_ops = {
> +	SET_RUNTIME_PM_OPS(omap_pipe3_runtime_suspend,
> +		omap_pipe3_runtime_resume, NULL)
>  };
>  
> -#define DEV_PM_OPS     (&omap_usb3_pm_ops)
> +#define DEV_PM_OPS     (&omap_pipe3_pm_ops)
>  #else
>  #define DEV_PM_OPS     NULL
>  #endif
>  
>  #ifdef CONFIG_OF
> -static const struct of_device_id omap_usb3_id_table[] = {
> +static const struct of_device_id omap_pipe3_id_table[] = {
> +	{ .compatible = "ti,omap-pipe3" },

why do you need "omap-pipe3", isn't sata, pcie and usb3 sufficient?

> +	{ .compatible = "ti,omap-sata" },
> +	{ .compatible = "ti,omap-pcie" },
>  	{ .compatible = "ti,omap-usb3" },
>  	{}
>  };
> -MODULE_DEVICE_TABLE(of, omap_usb3_id_table);
> +MODULE_DEVICE_TABLE(of, omap_pipe3_id_table);
>  #endif
>  
> -static struct platform_driver omap_usb3_driver = {
> -	.probe		= omap_usb3_probe,
> -	.remove		= omap_usb3_remove,
> +static struct platform_driver omap_pipe3_driver = {
> +	.probe		= omap_pipe3_probe,
> +	.remove		= omap_pipe3_remove,
>  	.driver		= {
> -		.name	= "omap-usb3",
> +		.name	= "omap-pipe3",
>  		.owner	= THIS_MODULE,
>  		.pm	= DEV_PM_OPS,
> -		.of_match_table = of_match_ptr(omap_usb3_id_table),
> +		.of_match_table = of_match_ptr(omap_pipe3_id_table),
>  	},
>  };
>  
> -module_platform_driver(omap_usb3_driver);
> +module_platform_driver(omap_pipe3_driver);
>  
> -MODULE_ALIAS("platform: omap_usb3");
> +MODULE_ALIAS("platform: omap_pipe3");
>  MODULE_AUTHOR("Texas Instruments Inc.");
> -MODULE_DESCRIPTION("OMAP USB3 phy driver");
> +MODULE_DESCRIPTION("OMAP PIPE3 phy driver");
>  MODULE_LICENSE("GPL v2");
> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
> index d69cdad..0210e03 100644
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -66,17 +66,6 @@ config OMAP_CONTROL_USB
>  	  power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an
>  	  additional register to power on USB3 PHY.
>  
> -config OMAP_USB3
> -	tristate "OMAP USB3 PHY Driver"
> -	depends on ARCH_OMAP2PLUS || COMPILE_TEST
> -	select OMAP_CONTROL_USB
> -	select USB_PHY
> -	help
> -	  Enable this to support the USB3 PHY that is part of SOC. This
> -	  driver takes care of all the PHY functionality apart from comparator.
> -	  This driver interacts with the "OMAP Control USB Driver" to power
> -	  on/off the PHY.
> -
>  config AM335X_CONTROL_USB
>  	tristate
>  
> diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
> index 51968d7..d1c9683 100644
> --- a/drivers/usb/phy/Makefile
> +++ b/drivers/usb/phy/Makefile
> @@ -13,7 +13,6 @@ obj-$(CONFIG_ISP1301_OMAP)		+= phy-isp1301-omap.o
>  obj-$(CONFIG_MV_U3D_PHY)		+= phy-mv-u3d-usb.o
>  obj-$(CONFIG_NOP_USB_XCEIV)		+= phy-generic.o
>  obj-$(CONFIG_OMAP_CONTROL_USB)		+= phy-omap-control.o
> -obj-$(CONFIG_OMAP_USB3)			+= phy-omap-usb3.o
>  obj-$(CONFIG_SAMSUNG_USBPHY)		+= phy-samsung-usb.o
>  obj-$(CONFIG_SAMSUNG_USB2PHY)		+= phy-samsung-usb2.o
>  obj-$(CONFIG_SAMSUNG_USB3PHY)		+= phy-samsung-usb3.o
> diff --git a/include/linux/phy/omap_pipe3.h b/include/linux/phy/omap_pipe3.h
> new file mode 100644
> index 0000000..7329056
> --- /dev/null
> +++ b/include/linux/phy/omap_pipe3.h

ti_pipe3.h ?

> @@ -0,0 +1,52 @@
> +/*
> + * omap_pipe3.h -- omap pipe3 phy header file
> + *
> + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * Author: Kishon Vijay Abraham I <kishon@ti.com>
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#ifndef __DRIVERS_OMAP_PIPE3_H
> +#define __DRIVERS_OMAP_PIPE3_H
> +
> +#include <linux/io.h>
> +
> +struct pipe3_dpll_params {
> +	u16	m;
> +	u8	n;
> +	u8	freq:3;
> +	u8	sd;
> +	u32	mf;
> +};
> +
> +struct omap_pipe3 {
> +	void __iomem		*pll_ctrl_base;
> +	struct device		*dev;
> +	struct device		*control_dev;
> +	struct clk		*wkupclk;
> +	struct clk		*sys_clk;

sysclk. To be consistent with others?

> +	struct clk		*optclk;
> +};
> +
> +static inline u32 omap_pipe3_readl(void __iomem *addr, unsigned offset)
> +{
> +	return __raw_readl(addr + offset);
> +}
> +
> +static inline void omap_pipe3_writel(void __iomem *addr, unsigned offset,
> +	u32 data)
> +{
> +	__raw_writel(data, addr + offset);
> +}
> +
> +#endif /* __DRIVERS_OMAP_PIPE3_H */
> 

cheers,
-roger


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

* Re: [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY
  2013-09-12 11:04       ` Roger Quadros
@ 2013-09-12 11:26         ` Vivek Gautam
  2013-09-12 13:11           ` Roger Quadros
  0 siblings, 1 reply; 47+ messages in thread
From: Vivek Gautam @ 2013-09-12 11:26 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Kishon Vijay Abraham I, Felipe Balbi, Benoit Cousson,
	Tony Lindgren, Rob Herring, Pawel Moll, Mark Rutland,
	Russell King - ARM Linux, Grant Likely, Sylwester Nawrocki,
	Kumar Gala, Stephen Warren, Ian Campbell, Rob Landley,
	george.cherian, Greg KH, linux-doc, linux-omap, devicetree,
	Linux USB Mailing List, linux-arm-kernel, linux-kernel

Hi,


On Thu, Sep 12, 2013 at 4:34 PM, Roger Quadros <rogerq@ti.com> wrote:
> Hi,
>
> On 09/12/2013 01:47 PM, Vivek Gautam wrote:
>> On Thu, Sep 12, 2013 at 4:06 PM, Roger Quadros <rogerq@ti.com> wrote:
>>> Hi Kishon,
>>>
>>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>>>> There can be systems which does not have a external usb_phy, so get
>>>> usb_phy only if usb-phy property is added in the case of dt boot or if
>>>> platform_data indicates the presence of PHY. Also remove checking if
>>>> return value is -ENXIO since it's now changed to always enable usb_phy layer.
>>>>
>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>> ---
>>>>  drivers/usb/dwc3/Kconfig         |    1 +
>>>>  drivers/usb/dwc3/core.c          |   60 +++++++++++++++++---------------------
>>>>  drivers/usb/dwc3/platform_data.h |    1 +
>>>>  3 files changed, 28 insertions(+), 34 deletions(-)
>>>>
>>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>>>> index f969ea2..cfc16dd 100644
>>>> --- a/drivers/usb/dwc3/Kconfig
>>>> +++ b/drivers/usb/dwc3/Kconfig
>>>> @@ -2,6 +2,7 @@ config USB_DWC3
>>>>       tristate "DesignWare USB3 DRD Core Support"
>>>>       depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>>>       depends on EXTCON
>>>> +     select USB_PHY
>>>>       select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>>>       help
>>>>         Say Y or M here if your system has a Dual Role SuperSpeed
>>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>>> index 474162e..428c29e 100644
>>>> --- a/drivers/usb/dwc3/core.c
>>>> +++ b/drivers/usb/dwc3/core.c
>>>> @@ -387,16 +387,38 @@ static int dwc3_probe(struct platform_device *pdev)
>>>>       if (node) {
>>>>               dwc->maximum_speed = of_usb_get_maximum_speed(node);
>>>>
>>>> -             dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
>>>> -             dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
>>>> +             if (of_property_read_bool(node, "usb-phy")) {
>>>> +                     dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev,
>>>> +                             "usb-phy", 0);
>>>> +                     if (IS_ERR(dwc->usb2_phy))
>>>> +                             return PTR_ERR(dwc->usb2_phy);
>>>> +                     dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev,
>>>> +                             "usb-phy", 1);
>>>> +                     if (IS_ERR(dwc->usb3_phy))
>>>> +                             return PTR_ERR(dwc->usb3_phy);
>>>
>>> Some DWC3 instances use only usb2_phy. e.g. on DRA7 the 2nd dwc3 instance doesn't use usb3_phy.
>>> This needs to be a valid case and driver shouldn't error out.
>>
>> So, i think adding flexibility to DWC3 to have either
>> usb2-phy/usb3-phy or both of them seems to be valid point.
>> Any suggestions ?
>>
>
> For high speed operation we need only usb2_phy but for super speed we need both usb2_phy
> and usb3_phy.
>
> Why would a dwc3 controller use only usb3_phy? A USB3.0 interface has to be compatible with
> USB2.0 as well, no?

True and for that reason we need both UTMI+ interface as well as PIPE3
interface, right ?
But as also mentioned in the thread:
https://lkml.org/lkml/2013/9/12/181, on Samsung exynos5
architecturally same block is managing UTMI+ and PIPE3 interfaces,
which is handled by phy-samsung-usb3 driver and denoted by "usb3_phy:
usbphy@12100000" node in "arch/arm/boot/dts/exynos5250.dtsi".

So on exynos5250, DWC3 really needs just usb3-phy, which is compatible
for USB 2.0 as well.

>
> cheers,
> -roger
>



-- 
Best Regards
Vivek

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

* Re: [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY
  2013-09-12 11:26         ` Vivek Gautam
@ 2013-09-12 13:11           ` Roger Quadros
  2013-09-16  8:40             ` Vivek Gautam
  0 siblings, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-09-12 13:11 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: Kishon Vijay Abraham I, Felipe Balbi, Benoit Cousson,
	Tony Lindgren, Rob Herring, Pawel Moll, Mark Rutland,
	Russell King - ARM Linux, Grant Likely, Sylwester Nawrocki,
	Kumar Gala, Stephen Warren, Ian Campbell, Rob Landley,
	george.cherian, Greg KH, linux-doc, linux-omap, devicetree,
	Linux USB Mailing List, linux-arm-kernel, linux-kernel

On 09/12/2013 02:26 PM, Vivek Gautam wrote:
> Hi,
> 
> 
> On Thu, Sep 12, 2013 at 4:34 PM, Roger Quadros <rogerq@ti.com> wrote:
>> Hi,
>>
>> On 09/12/2013 01:47 PM, Vivek Gautam wrote:
>>> On Thu, Sep 12, 2013 at 4:06 PM, Roger Quadros <rogerq@ti.com> wrote:
>>>> Hi Kishon,
>>>>
>>>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>>>>> There can be systems which does not have a external usb_phy, so get
>>>>> usb_phy only if usb-phy property is added in the case of dt boot or if
>>>>> platform_data indicates the presence of PHY. Also remove checking if
>>>>> return value is -ENXIO since it's now changed to always enable usb_phy layer.
>>>>>
>>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>>> ---
>>>>>  drivers/usb/dwc3/Kconfig         |    1 +
>>>>>  drivers/usb/dwc3/core.c          |   60 +++++++++++++++++---------------------
>>>>>  drivers/usb/dwc3/platform_data.h |    1 +
>>>>>  3 files changed, 28 insertions(+), 34 deletions(-)
>>>>>
>>>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>>>>> index f969ea2..cfc16dd 100644
>>>>> --- a/drivers/usb/dwc3/Kconfig
>>>>> +++ b/drivers/usb/dwc3/Kconfig
>>>>> @@ -2,6 +2,7 @@ config USB_DWC3
>>>>>       tristate "DesignWare USB3 DRD Core Support"
>>>>>       depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>>>>       depends on EXTCON
>>>>> +     select USB_PHY
>>>>>       select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>>>>       help
>>>>>         Say Y or M here if your system has a Dual Role SuperSpeed
>>>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>>>> index 474162e..428c29e 100644
>>>>> --- a/drivers/usb/dwc3/core.c
>>>>> +++ b/drivers/usb/dwc3/core.c
>>>>> @@ -387,16 +387,38 @@ static int dwc3_probe(struct platform_device *pdev)
>>>>>       if (node) {
>>>>>               dwc->maximum_speed = of_usb_get_maximum_speed(node);
>>>>>
>>>>> -             dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
>>>>> -             dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
>>>>> +             if (of_property_read_bool(node, "usb-phy")) {
>>>>> +                     dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev,
>>>>> +                             "usb-phy", 0);
>>>>> +                     if (IS_ERR(dwc->usb2_phy))
>>>>> +                             return PTR_ERR(dwc->usb2_phy);
>>>>> +                     dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev,
>>>>> +                             "usb-phy", 1);
>>>>> +                     if (IS_ERR(dwc->usb3_phy))
>>>>> +                             return PTR_ERR(dwc->usb3_phy);
>>>>
>>>> Some DWC3 instances use only usb2_phy. e.g. on DRA7 the 2nd dwc3 instance doesn't use usb3_phy.
>>>> This needs to be a valid case and driver shouldn't error out.
>>>
>>> So, i think adding flexibility to DWC3 to have either
>>> usb2-phy/usb3-phy or both of them seems to be valid point.
>>> Any suggestions ?
>>>
>>
>> For high speed operation we need only usb2_phy but for super speed we need both usb2_phy
>> and usb3_phy.
>>
>> Why would a dwc3 controller use only usb3_phy? A USB3.0 interface has to be compatible with
>> USB2.0 as well, no?
> 
> True and for that reason we need both UTMI+ interface as well as PIPE3
> interface, right ?
> But as also mentioned in the thread:
> https://lkml.org/lkml/2013/9/12/181, on Samsung exynos5
> architecturally same block is managing UTMI+ and PIPE3 interfaces,
> which is handled by phy-samsung-usb3 driver and denoted by "usb3_phy:
> usbphy@12100000" node in "arch/arm/boot/dts/exynos5250.dtsi".
> 
> So on exynos5250, DWC3 really needs just usb3-phy, which is compatible
> for USB 2.0 as well.

I'm not familiar with exynos5250 dwc3, but looking at the dts file I can see both usb3_phy
and usb2_phy nodes and both are referenced in the dwc3 node.

The ehci and ohci controllers don't reference any PHY.

cheers,
-roger

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-09-02 15:43 ` [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework Kishon Vijay Abraham I
  2013-09-12  9:27   ` Vivek Gautam
@ 2013-09-12 13:19   ` Roger Quadros
  2013-09-16  2:52     ` Kishon Vijay Abraham I
  2013-10-11 15:09   ` Roger Quadros
  2 siblings, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-09-12 13:19 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
> power_on and power_off the following APIs are used phy_init(), phy_exit(),
> phy_power_on() and phy_power_off().
> 
> However using the old USB phy library wont be removed till the PHYs of all
> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>  drivers/usb/dwc3/Kconfig                       |    1 +
>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>  drivers/usb/dwc3/core.h                        |    7 ++++
>  4 files changed, 61 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
> index e807635..471366d 100644
> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
> @@ -6,11 +6,13 @@ Required properties:
>   - compatible: must be "snps,dwc3"
>   - reg : Address and length of the register set for the device
>   - interrupts: Interrupts used by the dwc3 controller.
> +
> +Optional properties:
>   - usb-phy : array of phandle for the PHY device.  The first element
>     in the array is expected to be a handle to the USB2/HS PHY and
>     the second element is expected to be a handle to the USB3/SS PHY
> -
> -Optional properties:
> + - phys: from the *Generic PHY* bindings
> + - phy-names: from the *Generic PHY* bindings
>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>  
>  This is usually a subnode to DWC3 glue to which it is connected.
> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> index cfc16dd..ad7ce83 100644
> --- a/drivers/usb/dwc3/Kconfig
> +++ b/drivers/usb/dwc3/Kconfig
> @@ -3,6 +3,7 @@ config USB_DWC3
>  	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>  	depends on EXTCON
>  	select USB_PHY
> +	select GENERIC_PHY
>  	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>  	help
>  	  Say Y or M here if your system has a Dual Role SuperSpeed
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 428c29e..485d365 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>  
>  	usb_phy_init(dwc->usb2_phy);
>  	usb_phy_init(dwc->usb3_phy);
> +
> +	if (dwc->usb2_generic_phy)
> +		phy_init(dwc->usb2_generic_phy);
> +	if (dwc->usb3_generic_phy)
> +		phy_init(dwc->usb3_generic_phy);
> +
>  	mdelay(100);
>  
>  	/* Clear USB3 PHY reset */
> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>  {
>  	usb_phy_shutdown(dwc->usb2_phy);
>  	usb_phy_shutdown(dwc->usb3_phy);
> +
> +	if (dwc->usb2_generic_phy)
> +		phy_power_off(dwc->usb2_generic_phy);
> +	if (dwc->usb3_generic_phy)
> +		phy_power_off(dwc->usb3_generic_phy);
>  }
>  
>  #define DWC3_ALIGN_MASK		(16 - 1)
> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>  		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>  	}
>  
> +	if (of_property_read_bool(node, "phys") || pdata->has_phy) {
> +		dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
> +		if (IS_ERR(dwc->usb2_generic_phy)) {
> +			dev_err(dev, "no usb2 phy configured yet");
> +			return PTR_ERR(dwc->usb2_generic_phy);
> +		}
> +
> +		dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
> +		if (IS_ERR(dwc->usb3_generic_phy)) {
> +			dev_err(dev, "no usb3 phy configured yet");
> +			return PTR_ERR(dwc->usb3_generic_phy);
> +		}
> +	} else {
> +		dwc->usb2_generic_phy = NULL;
> +		dwc->usb3_generic_phy = NULL;
> +	}
> +
>  	/* default to superspeed if no maximum_speed passed */
>  	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
>  		dwc->maximum_speed = USB_SPEED_SUPER;
> @@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)
>  	usb_phy_set_suspend(dwc->usb2_phy, 0);
>  	usb_phy_set_suspend(dwc->usb3_phy, 0);
>  
> +	if (dwc->usb2_generic_phy)
> +		phy_power_on(dwc->usb2_generic_phy);
> +	if (dwc->usb3_generic_phy)
> +		phy_power_on(dwc->usb3_generic_phy);
> +
>  	spin_lock_init(&dwc->lock);
>  	platform_set_drvdata(pdev, dwc);
>  
> @@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)
>  	usb_phy_set_suspend(dwc->usb2_phy, 1);
>  	usb_phy_set_suspend(dwc->usb3_phy, 1);
>  
> +	if (dwc->usb2_generic_phy)

if (IS_ERR())

> +		phy_power_off(dwc->usb2_generic_phy);
> +	if (dwc->usb3_generic_phy)

if (IS_ERR())

here and everywhere else in this patch.

> +		phy_power_off(dwc->usb3_generic_phy);
> +
>  	pm_runtime_put(&pdev->dev);
>  	pm_runtime_disable(&pdev->dev);
>  
> @@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)
>  	usb_phy_shutdown(dwc->usb3_phy);
>  	usb_phy_shutdown(dwc->usb2_phy);
>  
> +	if (dwc->usb2_generic_phy)
> +		phy_exit(dwc->usb2_generic_phy);
> +	if (dwc->usb3_generic_phy)
> +		phy_exit(dwc->usb3_generic_phy);
> +
>  	return 0;
>  }
>  
> @@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
>  
>  	usb_phy_init(dwc->usb3_phy);
>  	usb_phy_init(dwc->usb2_phy);
> +
> +	if (dwc->usb2_generic_phy)
> +		phy_init(dwc->usb2_generic_phy);
> +	if (dwc->usb3_generic_phy)
> +		phy_init(dwc->usb3_generic_phy);
> +
>  	msleep(100);
>  
>  	spin_lock_irqsave(&dwc->lock, flags);
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index f8af8d4..01ec7d7 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -31,6 +31,8 @@
>  #include <linux/usb/gadget.h>
>  #include <linux/usb/otg.h>
>  
> +#include <linux/phy/phy.h>
> +
>  /* Global constants */
>  #define DWC3_EP0_BOUNCE_SIZE	512
>  #define DWC3_ENDPOINTS_NUM	32
> @@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
>   * @dr_mode: requested mode of operation
>   * @usb2_phy: pointer to USB2 PHY
>   * @usb3_phy: pointer to USB3 PHY
> + * @usb2_generic_phy: pointer to USB2 PHY
> + * @usb3_generic_phy: pointer to USB3 PHY

Why duplicate usbX_phy and usbX_generic_phy? Can't we just have one
for each type and call it usbX_phy?

>   * @dcfg: saved contents of DCFG register
>   * @gctl: saved contents of GCTL register
>   * @is_selfpowered: true when we are selfpowered
> @@ -665,6 +669,9 @@ struct dwc3 {
>  	struct usb_phy		*usb2_phy;
>  	struct usb_phy		*usb3_phy;
>  
> +	struct phy		*usb2_generic_phy;
> +	struct phy		*usb3_generic_phy;
> +
>  	void __iomem		*regs;
>  	size_t			regs_size;
>  
> 

cheers,
-roger


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

* Re: [PATCH 4/7] Documentation: dt bindings: move ..usb/usb-phy.txt to ..phy/omap-phy.txt
  2013-09-02 15:43 ` [PATCH 4/7] Documentation: dt bindings: move ..usb/usb-phy.txt to ..phy/omap-phy.txt Kishon Vijay Abraham I
@ 2013-09-12 13:23   ` Roger Quadros
  2013-09-16  3:04     ` Kishon Vijay Abraham I
  0 siblings, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-09-12 13:23 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
> Since now we have a separate folder for phy, move the PHY dt binding
> documentation of OMAP to that folder.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  .../devicetree/bindings/{usb/usb-phy.txt => phy/omap-phy.txt}        |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>  rename Documentation/devicetree/bindings/{usb/usb-phy.txt => phy/omap-phy.txt} (96%)
> 
> diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/phy/omap-phy.txt
> similarity index 96%
> rename from Documentation/devicetree/bindings/usb/usb-phy.txt
> rename to Documentation/devicetree/bindings/phy/omap-phy.txt
> index 36bdb17..2c485ee 100644
> --- a/Documentation/devicetree/bindings/usb/usb-phy.txt
> +++ b/Documentation/devicetree/bindings/phy/omap-phy.txt

ti-phy.txt?

> @@ -1,4 +1,4 @@
> -USB PHY
> +OMAP PHY: DT DOCUMENTATION FOR PHYs in OMAP PLATFORM

TI PHY: PHYs in Texas Instruments SoCs

cheers,
-roger


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

* Re: [PATCH 6/7] arm/dts: added dt properties to adapt to the new phy framwork
  2013-09-02 15:43 ` [PATCH 6/7] arm/dts: added dt properties to adapt to the new phy framwork Kishon Vijay Abraham I
@ 2013-09-12 13:28   ` Roger Quadros
  0 siblings, 0 replies; 47+ messages in thread
From: Roger Quadros @ 2013-09-12 13:28 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Hi,

Need some commit log.

cheers,
-roger

On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  arch/arm/boot/dts/omap5.dtsi |    5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
> index 94abef5..9fe71ff 100644
> --- a/arch/arm/boot/dts/omap5.dtsi
> +++ b/arch/arm/boot/dts/omap5.dtsi
> @@ -651,7 +651,8 @@
>  				compatible = "snps,dwc3";
>  				reg = <0x4a030000 0x10000>;
>  				interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
> -				usb-phy = <&usb2_phy>, <&usb3_phy>;
> +				phys = <&usb2_phy>, <&usb3_phy>;
> +				phy-names = "usb2-phy", "usb3-phy";
>  				tx-fifo-resize;
>  			};
>  		};
> @@ -667,6 +668,7 @@
>  				compatible = "ti,omap-usb2";
>  				reg = <0x4a084000 0x7c>;
>  				ctrl-module = <&omap_control_usb2phy>;
> +				#phy-cells = <0>;
>  			};
>  
>  			usb3_phy: usb3phy@4a084400 {
> @@ -676,6 +678,7 @@
>  				      <0x4a084c00 0x40>;
>  				reg-names = "phy_rx", "phy_tx", "pll_ctrl";
>  				ctrl-module = <&omap_control_usb3phy>;
> +				#phy-cells = <0>;
>  			};
>  		};
>  
> 


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

* Re: [PATCH 7/7] drivers: phy: renamed struct omap_control_usb to struct omap_control_phy
  2013-09-02 15:43 ` [PATCH 7/7] drivers: phy: renamed struct omap_control_usb to struct omap_control_phy Kishon Vijay Abraham I
@ 2013-09-12 13:42   ` Roger Quadros
  2013-09-16  3:06     ` Kishon Vijay Abraham I
  0 siblings, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-09-12 13:42 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Hi,

On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
> renamed struct omap_control_usb to struct omap_control_phy since it can
> be used to control PHY of USB, SATA and PCIE. Also moved the driver and
> include files under *phy* and made the corresponding changes in the users
> of phy-omap-control.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  drivers/phy/Kconfig                                |   14 +-
>  drivers/phy/Makefile                               |    1 +
>  drivers/{usb => }/phy/phy-omap-control.c           |  164 ++++++++++----------
>  drivers/phy/phy-omap-pipe3.c                       |    8 +-
>  drivers/phy/phy-omap-usb2.c                        |    8 +-
>  drivers/usb/musb/omap2430.c                        |    2 +-
>  drivers/usb/phy/Makefile                           |    1 -
>  .../omap_control_usb.h => phy/omap_control_phy.h}  |   32 ++--
>  8 files changed, 120 insertions(+), 110 deletions(-)
>  rename drivers/{usb => }/phy/phy-omap-control.c (55%)
>  rename include/linux/{usb/omap_control_usb.h => phy/omap_control_phy.h} (69%)
> 
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 5c2e7a0..fd11294 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -15,12 +15,22 @@ config GENERIC_PHY
>  	  phy users can obtain reference to the PHY. All the users of this
>  	  framework should select this config.
>  
> +config OMAP_CONTROL_PHY
> +	tristate "OMAP CONTROL PHY Driver"
> +	depends on ARCH_OMAP2PLUS || COMPILE_TEST
> +	help
> +	  Enable this to add support for the PHY part present in the control
> +	  module. This driver has API to power on the USB2 PHY and to write to
> +	  the mailbox. The mailbox is present only in omap4 and the register to
> +	  power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has
> +	  additional registers to power on PIPE3 PHYs.
> +
>  config OMAP_USB2
>  	tristate "OMAP USB2 PHY Driver"
>  	depends on ARCH_OMAP2PLUS
>  	select GENERIC_PHY
>  	select USB_PHY
> -	select OMAP_CONTROL_USB
> +	select OMAP_CONTROL_PHY
>  	help
>  	  Enable this to support the transceiver that is part of SOC. This
>  	  driver takes care of all the PHY functionality apart from comparator.
> @@ -30,7 +40,7 @@ config OMAP_USB2
>  config OMAP_PIPE3
>  	tristate "OMAP PIPE3 PHY Driver"
>  	select GENERIC_PHY
> -	select OMAP_CONTROL_USB
> +	select OMAP_CONTROL_PHY
>  	help
>  	  Enable this to support the PIPE3 PHY that is part of SOC. This
>  	  driver takes care of all the PHY functionality apart from comparator.
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index 48bf9f2..f0127f6 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -3,6 +3,7 @@
>  #
>  
>  obj-$(CONFIG_GENERIC_PHY)	+= phy-core.o
> +obj-$(CONFIG_OMAP_CONTROL_PHY)	+= phy-omap-control.o
>  obj-$(CONFIG_OMAP_USB2)		+= phy-omap-usb2.o
>  obj-$(CONFIG_OMAP_PIPE3)	+= phy-omap-pipe3.o
>  obj-$(CONFIG_TWL4030_USB)	+= phy-twl4030-usb.o
> diff --git a/drivers/usb/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c
> similarity index 55%
> rename from drivers/usb/phy/phy-omap-control.c
> rename to drivers/phy/phy-omap-control.c
> index 1a7e19a..ece3573 100644
> --- a/drivers/usb/phy/phy-omap-control.c
> +++ b/drivers/phy/phy-omap-control.c
> @@ -1,5 +1,5 @@
>  /*
> - * omap-control-usb.c - The USB part of control module.
> + * phy-omap-control.c - The USB part of control module.
>   *
>   * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
>   * This program is free software; you can redistribute it and/or modify
> @@ -24,36 +24,36 @@
>  #include <linux/err.h>
>  #include <linux/io.h>
>  #include <linux/clk.h>
> -#include <linux/usb/omap_control_usb.h>
> +#include <linux/phy/omap_control_phy.h>
>  

<snip>

>  #ifdef CONFIG_OF
>  
> -static const enum omap_control_usb_type omap4_data = OMAP_CTRL_TYPE_OMAP4;
> -static const enum omap_control_usb_type usb2_data = OMAP_CTRL_TYPE_USB2;
> -static const enum omap_control_usb_type usb3_data = OMAP_CTRL_TYPE_USB3;
> -static const enum omap_control_usb_type dra7_data = OMAP_CTRL_TYPE_DRA7;
> +static const enum omap_control_phy_type omap4_data = OMAP_CTRL_TYPE_OMAP4;
> +static const enum omap_control_phy_type usb2_data = OMAP_CTRL_TYPE_USB2;
> +static const enum omap_control_phy_type usb3_data = OMAP_CTRL_TYPE_USB3;
> +static const enum omap_control_phy_type dra7_data = OMAP_CTRL_TYPE_DRA7;
>  
> -static const struct of_device_id omap_control_usb_id_table[] = {
> +static const struct of_device_id omap_control_phy_id_table[] = {
>  	{
>  		.compatible = "ti,omap4-control-usb",
>  		.data = &omap4_data,
> @@ -286,31 +286,31 @@ static const struct of_device_id omap_control_usb_id_table[] = {
>  	},
>  	{},
>  };
> -MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
> +MODULE_DEVICE_TABLE(of, omap_control_phy_id_table);
>  #endif
>  
> -static struct platform_driver omap_control_usb_driver = {
> -	.probe		= omap_control_usb_probe,
> +static struct platform_driver omap_control_phy_driver = {
> +	.probe		= omap_control_phy_probe,
>  	.driver		= {
>  		.name	= "omap-control-usb",
>  		.owner	= THIS_MODULE,
> -		.of_match_table = of_match_ptr(omap_control_usb_id_table),
> +		.of_match_table = of_match_ptr(omap_control_phy_id_table),
>  	},
>  };
>  
> -static int __init omap_control_usb_init(void)
> +static int __init omap_control_phy_init(void)
>  {
> -	return platform_driver_register(&omap_control_usb_driver);
> +	return platform_driver_register(&omap_control_phy_driver);
>  }
> -subsys_initcall(omap_control_usb_init);
> +subsys_initcall(omap_control_phy_init);

Any specific reason for having this as subsys_initcall?

If not then you can use module_platform_driver().

>  
> -static void __exit omap_control_usb_exit(void)
> +static void __exit omap_control_phy_exit(void)
>  {
> -	platform_driver_unregister(&omap_control_usb_driver);
> +	platform_driver_unregister(&omap_control_phy_driver);
>  }
> -module_exit(omap_control_usb_exit);
> +module_exit(omap_control_phy_exit);
>  
> -MODULE_ALIAS("platform: omap_control_usb");
> +MODULE_ALIAS("platform: omap_control_phy");
>  MODULE_AUTHOR("Texas Instruments Inc.");
>  MODULE_DESCRIPTION("OMAP Control Module USB Driver");
>  MODULE_LICENSE("GPL v2");

cheers,
-roger


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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-09-12 13:19   ` Roger Quadros
@ 2013-09-16  2:52     ` Kishon Vijay Abraham I
  2013-09-16  7:25       ` Roger Quadros
  0 siblings, 1 reply; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-16  2:52 UTC (permalink / raw)
  To: Roger Quadros
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

On Thursday 12 September 2013 06:49 PM, Roger Quadros wrote:
> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>> phy_power_on() and phy_power_off().
>>
>> However using the old USB phy library wont be removed till the PHYs of all
>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>>   Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>>   drivers/usb/dwc3/Kconfig                       |    1 +
>>   drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>>   drivers/usb/dwc3/core.h                        |    7 ++++
>>   4 files changed, 61 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>> index e807635..471366d 100644
>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>> @@ -6,11 +6,13 @@ Required properties:
>>    - compatible: must be "snps,dwc3"
>>    - reg : Address and length of the register set for the device
>>    - interrupts: Interrupts used by the dwc3 controller.
>> +
>> +Optional properties:
>>    - usb-phy : array of phandle for the PHY device.  The first element
>>      in the array is expected to be a handle to the USB2/HS PHY and
>>      the second element is expected to be a handle to the USB3/SS PHY
>> -
>> -Optional properties:
>> + - phys: from the *Generic PHY* bindings
>> + - phy-names: from the *Generic PHY* bindings
>>    - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>
>>   This is usually a subnode to DWC3 glue to which it is connected.
>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>> index cfc16dd..ad7ce83 100644
>> --- a/drivers/usb/dwc3/Kconfig
>> +++ b/drivers/usb/dwc3/Kconfig
>> @@ -3,6 +3,7 @@ config USB_DWC3
>>   	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>   	depends on EXTCON
>>   	select USB_PHY
>> +	select GENERIC_PHY
>>   	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>   	help
>>   	  Say Y or M here if your system has a Dual Role SuperSpeed
>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>> index 428c29e..485d365 100644
>> --- a/drivers/usb/dwc3/core.c
>> +++ b/drivers/usb/dwc3/core.c
>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>
>>   	usb_phy_init(dwc->usb2_phy);
>>   	usb_phy_init(dwc->usb3_phy);
>> +
>> +	if (dwc->usb2_generic_phy)
>> +		phy_init(dwc->usb2_generic_phy);
>> +	if (dwc->usb3_generic_phy)
>> +		phy_init(dwc->usb3_generic_phy);
>> +
>>   	mdelay(100);
>>
>>   	/* Clear USB3 PHY reset */
>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>>   {
>>   	usb_phy_shutdown(dwc->usb2_phy);
>>   	usb_phy_shutdown(dwc->usb3_phy);
>> +
>> +	if (dwc->usb2_generic_phy)
>> +		phy_power_off(dwc->usb2_generic_phy);
>> +	if (dwc->usb3_generic_phy)
>> +		phy_power_off(dwc->usb3_generic_phy);
>>   }
>>
>>   #define DWC3_ALIGN_MASK		(16 - 1)
>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>>   		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>>   	}
>>
>> +	if (of_property_read_bool(node, "phys") || pdata->has_phy) {
>> +		dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>> +		if (IS_ERR(dwc->usb2_generic_phy)) {
>> +			dev_err(dev, "no usb2 phy configured yet");
>> +			return PTR_ERR(dwc->usb2_generic_phy);
>> +		}
>> +
>> +		dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
>> +		if (IS_ERR(dwc->usb3_generic_phy)) {
>> +			dev_err(dev, "no usb3 phy configured yet");
>> +			return PTR_ERR(dwc->usb3_generic_phy);
>> +		}
>> +	} else {
>> +		dwc->usb2_generic_phy = NULL;
>> +		dwc->usb3_generic_phy = NULL;
>> +	}
>> +
>>   	/* default to superspeed if no maximum_speed passed */
>>   	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
>>   		dwc->maximum_speed = USB_SPEED_SUPER;
>> @@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)
>>   	usb_phy_set_suspend(dwc->usb2_phy, 0);
>>   	usb_phy_set_suspend(dwc->usb3_phy, 0);
>>
>> +	if (dwc->usb2_generic_phy)
>> +		phy_power_on(dwc->usb2_generic_phy);
>> +	if (dwc->usb3_generic_phy)
>> +		phy_power_on(dwc->usb3_generic_phy);
>> +
>>   	spin_lock_init(&dwc->lock);
>>   	platform_set_drvdata(pdev, dwc);
>>
>> @@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)
>>   	usb_phy_set_suspend(dwc->usb2_phy, 1);
>>   	usb_phy_set_suspend(dwc->usb3_phy, 1);
>>
>> +	if (dwc->usb2_generic_phy)
>
> if (IS_ERR())

I assign NULL to usb2_generic_phy and usb3_generic_phy in case the dts 
entry doesn't have a *phys* property.
The IS_ERR of usb2_generic_phy is treated as an error condition and 
probe will fail.
>
>> +		phy_power_off(dwc->usb2_generic_phy);
>> +	if (dwc->usb3_generic_phy)
>
> if (IS_ERR())
>
> here and everywhere else in this patch.
>
>> +		phy_power_off(dwc->usb3_generic_phy);
>> +
>>   	pm_runtime_put(&pdev->dev);
>>   	pm_runtime_disable(&pdev->dev);
>>
>> @@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)
>>   	usb_phy_shutdown(dwc->usb3_phy);
>>   	usb_phy_shutdown(dwc->usb2_phy);
>>
>> +	if (dwc->usb2_generic_phy)
>> +		phy_exit(dwc->usb2_generic_phy);
>> +	if (dwc->usb3_generic_phy)
>> +		phy_exit(dwc->usb3_generic_phy);
>> +
>>   	return 0;
>>   }
>>
>> @@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
>>
>>   	usb_phy_init(dwc->usb3_phy);
>>   	usb_phy_init(dwc->usb2_phy);
>> +
>> +	if (dwc->usb2_generic_phy)
>> +		phy_init(dwc->usb2_generic_phy);
>> +	if (dwc->usb3_generic_phy)
>> +		phy_init(dwc->usb3_generic_phy);
>> +
>>   	msleep(100);
>>
>>   	spin_lock_irqsave(&dwc->lock, flags);
>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>> index f8af8d4..01ec7d7 100644
>> --- a/drivers/usb/dwc3/core.h
>> +++ b/drivers/usb/dwc3/core.h
>> @@ -31,6 +31,8 @@
>>   #include <linux/usb/gadget.h>
>>   #include <linux/usb/otg.h>
>>
>> +#include <linux/phy/phy.h>
>> +
>>   /* Global constants */
>>   #define DWC3_EP0_BOUNCE_SIZE	512
>>   #define DWC3_ENDPOINTS_NUM	32
>> @@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
>>    * @dr_mode: requested mode of operation
>>    * @usb2_phy: pointer to USB2 PHY
>>    * @usb3_phy: pointer to USB3 PHY
>> + * @usb2_generic_phy: pointer to USB2 PHY
>> + * @usb3_generic_phy: pointer to USB3 PHY
>
> Why duplicate usbX_phy and usbX_generic_phy? Can't we just have one
> for each type and call it usbX_phy?

There was an already existing phy library in usb which usesusb_phy. 
There might still be users using the existing usb phy library. Until all 
the users have completely migrated to the generic PHY framework, this 
would co-exist.

Thanks
Kishon

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

* Re: [PATCH 3/7] drivers: phy: usb3/pipe3: Adapt pipe3 driver to Generic PHY Framework
  2013-09-12 11:19   ` Roger Quadros
@ 2013-09-16  3:01     ` Kishon Vijay Abraham I
  2013-09-16  7:37       ` Roger Quadros
  0 siblings, 1 reply; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-16  3:01 UTC (permalink / raw)
  To: Roger Quadros
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

On Thursday 12 September 2013 04:49 PM, Roger Quadros wrote:
> Hi Kishon,
>
> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>> Adapted omap-usb3 PHY driver to Generic PHY Framework and moved phy-omap-usb3
>> driver in drivers/usb/phy to drivers/phy and also renamed the file to
>> phy-omap-pipe3 since this same driver will be used for SATA PHY and
>> PCIE PHY.
>
> I would suggest to split the renaming and PHY adaptation into 2 separate patches.

Alright.
>
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>>   Documentation/devicetree/bindings/usb/usb-phy.txt  |    5 +-
>>   drivers/phy/Kconfig                                |   10 +
>>   drivers/phy/Makefile                               |    1 +
>>   .../phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c}   |  206 +++++++++++---------
>
> how about naming it to phy-ti-pipe3.c as it is used on OMAP as well as non-OMAP e.g. DRA7.

hmm.. I thought it would be consistent with other PHY drivers 
(phy-omap-usb2). Moreover DRA7 is OMAP based platform ;-) Maybe we 
should reserve that for later?
>
>>   drivers/usb/phy/Kconfig                            |   11 --
>>   drivers/usb/phy/Makefile                           |    1 -
>>   include/linux/phy/omap_pipe3.h                     |   52 +++++
>>   7 files changed, 177 insertions(+), 109 deletions(-)
>>   rename drivers/{usb/phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c} (57%)
>>   create mode 100644 include/linux/phy/omap_pipe3.h
>>
>> diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt
>> index c0245c8..36bdb17 100644
>> --- a/Documentation/devicetree/bindings/usb/usb-phy.txt
>> +++ b/Documentation/devicetree/bindings/usb/usb-phy.txt
>> @@ -21,10 +21,11 @@ usb2phy@4a0ad080 {
>>   	#phy-cells = <0>;
>>   };
>>
>> -OMAP USB3 PHY
>> +OMAP PIPE3 PHY
>>
>>   Required properties:
>> - - compatible: Should be "ti,omap-usb3"
>> + - compatible: Should be "ti,omap-usb3", "ti,omap-pipe3", "ti,omap-sata"
>> +   or "ti,omap-pcie"
>>    - reg : Address and length of the register set for the device.
>>    - reg-names: The names of the register addresses corresponding to the registers
>>      filled in "reg".
>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>> index ac239ac..5c2e7a0 100644
>> --- a/drivers/phy/Kconfig
>> +++ b/drivers/phy/Kconfig
>> @@ -27,6 +27,16 @@ config OMAP_USB2
>>   	  The USB OTG controller communicates with the comparator using this
>>   	  driver.
>>
>> +config OMAP_PIPE3
>> +	tristate "OMAP PIPE3 PHY Driver"
>> +	select GENERIC_PHY
>> +	select OMAP_CONTROL_USB
> how about
> 	depends on OMAP_CONTROL_USB

 From whatever I could make out from comments of Greg in my Generic PHY 
Framework, it's better to do a select of dependent modules instead of 
depends on.
>
> Also, if this is TI/OMAP it might as well depend on ARCH_OMAP.
>
>> +	help
>> +	  Enable this to support the PIPE3 PHY that is part of SOC. This
>
> worth mentioning TI OMAP/DRA SoCs.

right.
>
>> +	  driver takes care of all the PHY functionality apart from comparator.
>> +	  This driver interacts with the "OMAP Control PHY Driver" to power
>> +	  on/off the PHY.
>> +
>>   config TWL4030_USB
>>   	tristate "TWL4030 USB Transceiver Driver"
>>   	depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>> index 0dd8a98..48bf9f2 100644
>> --- a/drivers/phy/Makefile
>> +++ b/drivers/phy/Makefile
>> @@ -4,4 +4,5 @@
>>
>>   obj-$(CONFIG_GENERIC_PHY)	+= phy-core.o
>>   obj-$(CONFIG_OMAP_USB2)		+= phy-omap-usb2.o
>> +obj-$(CONFIG_OMAP_PIPE3)	+= phy-omap-pipe3.o
>>   obj-$(CONFIG_TWL4030_USB)	+= phy-twl4030-usb.o
>> diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/phy/phy-omap-pipe3.c
>> similarity index 57%
>> rename from drivers/usb/phy/phy-omap-usb3.c
>> rename to drivers/phy/phy-omap-pipe3.c
>> index 4004f82..ee9a901 100644
>> --- a/drivers/usb/phy/phy-omap-usb3.c
>> +++ b/drivers/phy/phy-omap-pipe3.c
>> @@ -1,5 +1,5 @@
>>   /*
>> - * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP.
>> + * omap-pipe3 - PHY driver for SATA, USB and PCIE in OMAP platforms
>>    *
>>    * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
>>    * This program is free software; you can redistribute it and/or modify
>> @@ -19,7 +19,8 @@
>>   #include <linux/module.h>
>>   #include <linux/platform_device.h>
>>   #include <linux/slab.h>
>> -#include <linux/usb/omap_usb.h>
>> +#include <linux/phy/omap_pipe3.h>
>> +#include <linux/phy/phy.h>
>>   #include <linux/of.h>
>>   #include <linux/clk.h>
>>   #include <linux/err.h>
>> @@ -52,17 +53,17 @@
>>
>>   /*
>>    * This is an Empirical value that works, need to confirm the actual
>> - * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status
>> - * to be correctly reflected in the USB3PHY_PLL_STATUS register.
>> + * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status
>> + * to be correctly reflected in the PIPE3PHY_PLL_STATUS register.
>>    */
>>   # define PLL_IDLE_TIME  100;
>>
>> -struct usb_dpll_map {
>> +struct pipe3_dpll_map {
>>   	unsigned long rate;
>> -	struct usb_dpll_params params;
>> +	struct pipe3_dpll_params params;
>>   };
>>
>> -static struct usb_dpll_map dpll_map[] = {
>> +static struct pipe3_dpll_map dpll_map[] = {
>>   	{12000000, {1250, 5, 4, 20, 0} },	/* 12 MHz */
>>   	{16800000, {3125, 20, 4, 20, 0} },	/* 16.8 MHz */
>>   	{19200000, {1172, 8, 4, 20, 65537} },	/* 19.2 MHz */
>> @@ -71,7 +72,7 @@ static struct usb_dpll_map dpll_map[] = {
>>   	{38400000, {3125, 47, 4, 20, 92843} },	/* 38.4 MHz */
>>   };
>>
>> -static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
>> +static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(unsigned long rate)
>>   {
>>   	int i;
>>
>> @@ -83,110 +84,113 @@ static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
>>   	return 0;
>>   }
>>
>> -static int omap_usb3_suspend(struct usb_phy *x, int suspend)
>> +static int omap_pipe3_power_off(struct phy *x)
>>   {
>> -	struct omap_usb *phy = phy_to_omapusb(x);
>> -	int	val;
>> +	struct omap_pipe3 *phy = phy_get_drvdata(x);
>> +	int val;
>>   	int timeout = PLL_IDLE_TIME;
>>
>> -	if (suspend && !phy->is_suspended) {
>> -		val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>> -		val |= PLL_IDLE;
>> -		omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>> -
>> -		do {
>> -			val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
>> -			if (val & PLL_TICOPWDN)
>> -				break;
>> -			udelay(1);
>> -		} while (--timeout);
>> -
>> -		omap_control_usb_phy_power(phy->control_dev, 0);
>> -
>> -		phy->is_suspended	= 1;
>> -	} else if (!suspend && phy->is_suspended) {
>> -		phy->is_suspended	= 0;
>> -
>> -		val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>> -		val &= ~PLL_IDLE;
>> -		omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>> -
>> -		do {
>> -			val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
>> -			if (!(val & PLL_TICOPWDN))
>> -				break;
>> -			udelay(1);
>> -		} while (--timeout);
>> -	}
>> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>> +	val |= PLL_IDLE;
>> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>> +
>> +	do {
>> +		val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>> +		if (val & PLL_TICOPWDN)
>> +			break;
>> +		udelay(1);
>
> Is it better to sleep instead of udelay?

hmm.. yeah, I guess this function wont be called from interrupt context.
>
>> +	} while (--timeout);
>> +
>> +	omap_control_usb_phy_power(phy->control_dev, 0);
>> +
>> +	return 0;
>> +}
>> +
>> +static int omap_pipe3_power_on(struct phy *x)
>> +{
>> +	struct omap_pipe3 *phy = phy_get_drvdata(x);
>> +	int val;
>> +	int timeout = PLL_IDLE_TIME;
>> +
>> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>> +	val &= ~PLL_IDLE;
>> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>> +
>> +	do {
>> +		val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>> +		if (!(val & PLL_TICOPWDN))
>> +			break;
>> +		udelay(1);
>
> here too.

Ok.
>
>> +	} while (--timeout);
>>
>>   	return 0;
>>   }
>>
>> -static void omap_usb_dpll_relock(struct omap_usb *phy)
>> +static void omap_pipe3_dpll_relock(struct omap_pipe3 *phy)
>>   {
>>   	u32		val;
>>   	unsigned long	timeout;
>>
>> -	omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
>> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
>>
>>   	timeout = jiffies + msecs_to_jiffies(20);
>>   	do {
>> -		val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
>> +		val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>>   		if (val & PLL_LOCK)
>>   			break;
>>   	} while (!WARN_ON(time_after(jiffies, timeout)));
>>   }
>>
>> -static int omap_usb_dpll_lock(struct omap_usb *phy)
>> +static int omap_pipe3_dpll_lock(struct omap_pipe3 *phy)
>>   {
>>   	u32			val;
>>   	unsigned long		rate;
>> -	struct usb_dpll_params *dpll_params;
>> +	struct pipe3_dpll_params *dpll_params;
>>
>>   	rate = clk_get_rate(phy->sys_clk);
>> -	dpll_params = omap_usb3_get_dpll_params(rate);
>> +	dpll_params = omap_pipe3_get_dpll_params(rate);
>>   	if (!dpll_params) {
>>   		dev_err(phy->dev,
>>   			  "No DPLL configuration for %lu Hz SYS CLK\n", rate);
>>   		return -EINVAL;
>>   	}
>>
>> -	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>   	val &= ~PLL_REGN_MASK;
>>   	val |= dpll_params->n << PLL_REGN_SHIFT;
>> -	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>
>> -	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>   	val &= ~PLL_SELFREQDCO_MASK;
>>   	val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
>> -	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>
>> -	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>   	val &= ~PLL_REGM_MASK;
>>   	val |= dpll_params->m << PLL_REGM_SHIFT;
>> -	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>
>> -	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
>> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
>>   	val &= ~PLL_REGM_F_MASK;
>>   	val |= dpll_params->mf << PLL_REGM_F_SHIFT;
>> -	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
>> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
>>
>> -	val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
>> +	val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
>>   	val &= ~PLL_SD_MASK;
>>   	val |= dpll_params->sd << PLL_SD_SHIFT;
>> -	omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
>> +	omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
>>
>> -	omap_usb_dpll_relock(phy);
>> +	omap_pipe3_dpll_relock(phy);
>>
>>   	return 0;
>>   }
>>
>> -static int omap_usb3_init(struct usb_phy *x)
>> +static int omap_pipe3_init(struct phy *x)
>>   {
>> -	struct omap_usb	*phy = phy_to_omapusb(x);
>> +	struct omap_pipe3 *phy = phy_get_drvdata(x);
>>   	int ret;
>>
>> -	ret = omap_usb_dpll_lock(phy);
>> +	ret = omap_pipe3_dpll_lock(phy);
>>   	if (ret)
>>   		return ret;
>>
>> @@ -195,9 +199,18 @@ static int omap_usb3_init(struct usb_phy *x)
>>   	return 0;
>>   }
>>
>> -static int omap_usb3_probe(struct platform_device *pdev)
>> +static struct phy_ops ops = {
>> +	.init		= omap_pipe3_init,
>> +	.power_on	= omap_pipe3_power_on,
>> +	.power_off	= omap_pipe3_power_off,
>> +	.owner		= THIS_MODULE,
>> +};
>> +
>> +static int omap_pipe3_probe(struct platform_device *pdev)
>>   {
>> -	struct omap_usb *phy;
>> +	struct omap_pipe3 *phy;
>> +	struct phy *generic_phy;
>> +	struct phy_provider *phy_provider;
>>   	struct resource *res;
>>   	struct device_node *node = pdev->dev.of_node;
>>   	struct device_node *control_node;
>> @@ -208,7 +221,7 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>
>>   	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
>>   	if (!phy) {
>> -		dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n");
>> +		dev_err(&pdev->dev, "unable to alloc mem for OMAP PIPE3 PHY\n");
>>   		return -ENOMEM;
>>   	}
>>
>> @@ -219,13 +232,6 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>
>>   	phy->dev		= &pdev->dev;
>>
>> -	phy->phy.dev		= phy->dev;
>> -	phy->phy.label		= "omap-usb3";
>> -	phy->phy.init		= omap_usb3_init;
>> -	phy->phy.set_suspend	= omap_usb3_suspend;
>> -	phy->phy.type		= USB_PHY_TYPE_USB3;
>> -
>> -	phy->is_suspended	= 1;
>>   	phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
>
> As this is no longer USB specific, we need to make the clock binding generic as well.

right. Its also needed when we have the same driver work for sata and 
pcie. Maybe do that in a separate patch?
>
>>   	if (IS_ERR(phy->wkupclk)) {
>>   		dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
>> @@ -251,6 +257,11 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>   		dev_err(&pdev->dev, "Failed to get control device phandle\n");
>>   		return -EINVAL;
>>   	}
>> +	phy_provider = devm_of_phy_provider_register(phy->dev,
>> +			of_phy_simple_xlate);
>> +	if (IS_ERR(phy_provider))
>> +		return PTR_ERR(phy_provider);
>> +
>>   	control_pdev = of_find_device_by_node(control_node);
>>   	if (!control_pdev) {
>>   		dev_err(&pdev->dev, "Failed to get control device\n");
>> @@ -260,23 +271,27 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>   	phy->control_dev = &control_pdev->dev;
>>
>>   	omap_control_usb_phy_power(phy->control_dev, 0);
>> -	usb_add_phy_dev(&phy->phy);
>>
>>   	platform_set_drvdata(pdev, phy);
>> -
>>   	pm_runtime_enable(phy->dev);
>> +
>> +	generic_phy = devm_phy_create(phy->dev, &ops, NULL);
>> +	if (IS_ERR(generic_phy))
>> +		return PTR_ERR(generic_phy);
>> +
>> +	phy_set_drvdata(generic_phy, phy);
>> +
>>   	pm_runtime_get(&pdev->dev);
>>
>>   	return 0;
>>   }
>>
>> -static int omap_usb3_remove(struct platform_device *pdev)
>> +static int omap_pipe3_remove(struct platform_device *pdev)
>>   {
>> -	struct omap_usb *phy = platform_get_drvdata(pdev);
>> +	struct omap_pipe3 *phy = platform_get_drvdata(pdev);
>>
>>   	clk_unprepare(phy->wkupclk);
>>   	clk_unprepare(phy->optclk);
>> -	usb_remove_phy(&phy->phy);
>>   	if (!pm_runtime_suspended(&pdev->dev))
>>   		pm_runtime_put(&pdev->dev);
>>   	pm_runtime_disable(&pdev->dev);
>> @@ -286,10 +301,9 @@ static int omap_usb3_remove(struct platform_device *pdev)
>>
>>   #ifdef CONFIG_PM_RUNTIME
>>
>> -static int omap_usb3_runtime_suspend(struct device *dev)
>> +static int omap_pipe3_runtime_suspend(struct device *dev)
>>   {
>> -	struct platform_device	*pdev = to_platform_device(dev);
>> -	struct omap_usb	*phy = platform_get_drvdata(pdev);
>> +	struct omap_pipe3	*phy = dev_get_drvdata(dev);
>>
>>   	clk_disable(phy->wkupclk);
>>   	clk_disable(phy->optclk);
>> @@ -297,11 +311,10 @@ static int omap_usb3_runtime_suspend(struct device *dev)
>>   	return 0;
>>   }
>>
>> -static int omap_usb3_runtime_resume(struct device *dev)
>> +static int omap_pipe3_runtime_resume(struct device *dev)
>>   {
>>   	u32 ret = 0;
>> -	struct platform_device	*pdev = to_platform_device(dev);
>> -	struct omap_usb	*phy = platform_get_drvdata(pdev);
>> +	struct omap_pipe3	*phy = dev_get_drvdata(dev);
>>
>>   	ret = clk_enable(phy->optclk);
>>   	if (ret) {
>> @@ -324,38 +337,41 @@ err1:
>>   	return ret;
>>   }
>>
>> -static const struct dev_pm_ops omap_usb3_pm_ops = {
>> -	SET_RUNTIME_PM_OPS(omap_usb3_runtime_suspend, omap_usb3_runtime_resume,
>> -		NULL)
>> +static const struct dev_pm_ops omap_pipe3_pm_ops = {
>> +	SET_RUNTIME_PM_OPS(omap_pipe3_runtime_suspend,
>> +		omap_pipe3_runtime_resume, NULL)
>>   };
>>
>> -#define DEV_PM_OPS     (&omap_usb3_pm_ops)
>> +#define DEV_PM_OPS     (&omap_pipe3_pm_ops)
>>   #else
>>   #define DEV_PM_OPS     NULL
>>   #endif
>>
>>   #ifdef CONFIG_OF
>> -static const struct of_device_id omap_usb3_id_table[] = {
>> +static const struct of_device_id omap_pipe3_id_table[] = {
>> +	{ .compatible = "ti,omap-pipe3" },
>
> why do you need "omap-pipe3", isn't sata, pcie and usb3 sufficient?

I thought it would be better if everyone uses omap-pipe3 and added pcie, 
sata if there are any specific settings (for pcie or sata) that should 
be done.
>
>> +	{ .compatible = "ti,omap-sata" },
>> +	{ .compatible = "ti,omap-pcie" },
>>   	{ .compatible = "ti,omap-usb3" },
>>   	{}
>>   };
>> -MODULE_DEVICE_TABLE(of, omap_usb3_id_table);
>> +MODULE_DEVICE_TABLE(of, omap_pipe3_id_table);
>>   #endif
>>
>> -static struct platform_driver omap_usb3_driver = {
>> -	.probe		= omap_usb3_probe,
>> -	.remove		= omap_usb3_remove,
>> +static struct platform_driver omap_pipe3_driver = {
>> +	.probe		= omap_pipe3_probe,
>> +	.remove		= omap_pipe3_remove,
>>   	.driver		= {
>> -		.name	= "omap-usb3",
>> +		.name	= "omap-pipe3",
>>   		.owner	= THIS_MODULE,
>>   		.pm	= DEV_PM_OPS,
>> -		.of_match_table = of_match_ptr(omap_usb3_id_table),
>> +		.of_match_table = of_match_ptr(omap_pipe3_id_table),
>>   	},
>>   };
>>
>> -module_platform_driver(omap_usb3_driver);
>> +module_platform_driver(omap_pipe3_driver);
>>
>> -MODULE_ALIAS("platform: omap_usb3");
>> +MODULE_ALIAS("platform: omap_pipe3");
>>   MODULE_AUTHOR("Texas Instruments Inc.");
>> -MODULE_DESCRIPTION("OMAP USB3 phy driver");
>> +MODULE_DESCRIPTION("OMAP PIPE3 phy driver");
>>   MODULE_LICENSE("GPL v2");
>> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
>> index d69cdad..0210e03 100644
>> --- a/drivers/usb/phy/Kconfig
>> +++ b/drivers/usb/phy/Kconfig
>> @@ -66,17 +66,6 @@ config OMAP_CONTROL_USB
>>   	  power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an
>>   	  additional register to power on USB3 PHY.
>>
>> -config OMAP_USB3
>> -	tristate "OMAP USB3 PHY Driver"
>> -	depends on ARCH_OMAP2PLUS || COMPILE_TEST
>> -	select OMAP_CONTROL_USB
>> -	select USB_PHY
>> -	help
>> -	  Enable this to support the USB3 PHY that is part of SOC. This
>> -	  driver takes care of all the PHY functionality apart from comparator.
>> -	  This driver interacts with the "OMAP Control USB Driver" to power
>> -	  on/off the PHY.
>> -
>>   config AM335X_CONTROL_USB
>>   	tristate
>>
>> diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
>> index 51968d7..d1c9683 100644
>> --- a/drivers/usb/phy/Makefile
>> +++ b/drivers/usb/phy/Makefile
>> @@ -13,7 +13,6 @@ obj-$(CONFIG_ISP1301_OMAP)		+= phy-isp1301-omap.o
>>   obj-$(CONFIG_MV_U3D_PHY)		+= phy-mv-u3d-usb.o
>>   obj-$(CONFIG_NOP_USB_XCEIV)		+= phy-generic.o
>>   obj-$(CONFIG_OMAP_CONTROL_USB)		+= phy-omap-control.o
>> -obj-$(CONFIG_OMAP_USB3)			+= phy-omap-usb3.o
>>   obj-$(CONFIG_SAMSUNG_USBPHY)		+= phy-samsung-usb.o
>>   obj-$(CONFIG_SAMSUNG_USB2PHY)		+= phy-samsung-usb2.o
>>   obj-$(CONFIG_SAMSUNG_USB3PHY)		+= phy-samsung-usb3.o
>> diff --git a/include/linux/phy/omap_pipe3.h b/include/linux/phy/omap_pipe3.h
>> new file mode 100644
>> index 0000000..7329056
>> --- /dev/null
>> +++ b/include/linux/phy/omap_pipe3.h
>
> ti_pipe3.h ?
>
>> @@ -0,0 +1,52 @@
>> +/*
>> + * omap_pipe3.h -- omap pipe3 phy header file
>> + *
>> + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * Author: Kishon Vijay Abraham I <kishon@ti.com>
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + */
>> +
>> +#ifndef __DRIVERS_OMAP_PIPE3_H
>> +#define __DRIVERS_OMAP_PIPE3_H
>> +
>> +#include <linux/io.h>
>> +
>> +struct pipe3_dpll_params {
>> +	u16	m;
>> +	u8	n;
>> +	u8	freq:3;
>> +	u8	sd;
>> +	u32	mf;
>> +};
>> +
>> +struct omap_pipe3 {
>> +	void __iomem		*pll_ctrl_base;
>> +	struct device		*dev;
>> +	struct device		*control_dev;
>> +	struct clk		*wkupclk;
>> +	struct clk		*sys_clk;
>
> sysclk. To be consistent with others?

Ok.

Thanks
Kishon

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

* Re: [PATCH 4/7] Documentation: dt bindings: move ..usb/usb-phy.txt to ..phy/omap-phy.txt
  2013-09-12 13:23   ` Roger Quadros
@ 2013-09-16  3:04     ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-16  3:04 UTC (permalink / raw)
  To: Roger Quadros
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

On Thursday 12 September 2013 06:53 PM, Roger Quadros wrote:
> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>> Since now we have a separate folder for phy, move the PHY dt binding
>> documentation of OMAP to that folder.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>>   .../devicetree/bindings/{usb/usb-phy.txt => phy/omap-phy.txt}        |    2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>   rename Documentation/devicetree/bindings/{usb/usb-phy.txt => phy/omap-phy.txt} (96%)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/phy/omap-phy.txt
>> similarity index 96%
>> rename from Documentation/devicetree/bindings/usb/usb-phy.txt
>> rename to Documentation/devicetree/bindings/phy/omap-phy.txt
>> index 36bdb17..2c485ee 100644
>> --- a/Documentation/devicetree/bindings/usb/usb-phy.txt
>> +++ b/Documentation/devicetree/bindings/phy/omap-phy.txt
>
> ti-phy.txt?

maybe wait for that later?

Thanks
Kishon

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

* Re: [PATCH 7/7] drivers: phy: renamed struct omap_control_usb to struct omap_control_phy
  2013-09-12 13:42   ` Roger Quadros
@ 2013-09-16  3:06     ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-09-16  3:06 UTC (permalink / raw)
  To: Roger Quadros
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

On Thursday 12 September 2013 07:12 PM, Roger Quadros wrote:
> Hi,
>
> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>> renamed struct omap_control_usb to struct omap_control_phy since it can
>> be used to control PHY of USB, SATA and PCIE. Also moved the driver and
>> include files under *phy* and made the corresponding changes in the users
>> of phy-omap-control.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>>   drivers/phy/Kconfig                                |   14 +-
>>   drivers/phy/Makefile                               |    1 +
>>   drivers/{usb => }/phy/phy-omap-control.c           |  164 ++++++++++----------
>>   drivers/phy/phy-omap-pipe3.c                       |    8 +-
>>   drivers/phy/phy-omap-usb2.c                        |    8 +-
>>   drivers/usb/musb/omap2430.c                        |    2 +-
>>   drivers/usb/phy/Makefile                           |    1 -
>>   .../omap_control_usb.h => phy/omap_control_phy.h}  |   32 ++--
>>   8 files changed, 120 insertions(+), 110 deletions(-)
>>   rename drivers/{usb => }/phy/phy-omap-control.c (55%)
>>   rename include/linux/{usb/omap_control_usb.h => phy/omap_control_phy.h} (69%)
>>
>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>> index 5c2e7a0..fd11294 100644
>> --- a/drivers/phy/Kconfig
>> +++ b/drivers/phy/Kconfig
>> @@ -15,12 +15,22 @@ config GENERIC_PHY
>>   	  phy users can obtain reference to the PHY. All the users of this
>>   	  framework should select this config.
>>
>> +config OMAP_CONTROL_PHY
>> +	tristate "OMAP CONTROL PHY Driver"
>> +	depends on ARCH_OMAP2PLUS || COMPILE_TEST
>> +	help
>> +	  Enable this to add support for the PHY part present in the control
>> +	  module. This driver has API to power on the USB2 PHY and to write to
>> +	  the mailbox. The mailbox is present only in omap4 and the register to
>> +	  power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has
>> +	  additional registers to power on PIPE3 PHYs.
>> +
>>   config OMAP_USB2
>>   	tristate "OMAP USB2 PHY Driver"
>>   	depends on ARCH_OMAP2PLUS
>>   	select GENERIC_PHY
>>   	select USB_PHY
>> -	select OMAP_CONTROL_USB
>> +	select OMAP_CONTROL_PHY
>>   	help
>>   	  Enable this to support the transceiver that is part of SOC. This
>>   	  driver takes care of all the PHY functionality apart from comparator.
>> @@ -30,7 +40,7 @@ config OMAP_USB2
>>   config OMAP_PIPE3
>>   	tristate "OMAP PIPE3 PHY Driver"
>>   	select GENERIC_PHY
>> -	select OMAP_CONTROL_USB
>> +	select OMAP_CONTROL_PHY
>>   	help
>>   	  Enable this to support the PIPE3 PHY that is part of SOC. This
>>   	  driver takes care of all the PHY functionality apart from comparator.
>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>> index 48bf9f2..f0127f6 100644
>> --- a/drivers/phy/Makefile
>> +++ b/drivers/phy/Makefile
>> @@ -3,6 +3,7 @@
>>   #
>>
>>   obj-$(CONFIG_GENERIC_PHY)	+= phy-core.o
>> +obj-$(CONFIG_OMAP_CONTROL_PHY)	+= phy-omap-control.o
>>   obj-$(CONFIG_OMAP_USB2)		+= phy-omap-usb2.o
>>   obj-$(CONFIG_OMAP_PIPE3)	+= phy-omap-pipe3.o
>>   obj-$(CONFIG_TWL4030_USB)	+= phy-twl4030-usb.o
>> diff --git a/drivers/usb/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c
>> similarity index 55%
>> rename from drivers/usb/phy/phy-omap-control.c
>> rename to drivers/phy/phy-omap-control.c
>> index 1a7e19a..ece3573 100644
>> --- a/drivers/usb/phy/phy-omap-control.c
>> +++ b/drivers/phy/phy-omap-control.c
>> @@ -1,5 +1,5 @@
>>   /*
>> - * omap-control-usb.c - The USB part of control module.
>> + * phy-omap-control.c - The USB part of control module.
>>    *
>>    * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
>>    * This program is free software; you can redistribute it and/or modify
>> @@ -24,36 +24,36 @@
>>   #include <linux/err.h>
>>   #include <linux/io.h>
>>   #include <linux/clk.h>
>> -#include <linux/usb/omap_control_usb.h>
>> +#include <linux/phy/omap_control_phy.h>
>>
>
> <snip>
>
>>   #ifdef CONFIG_OF
>>
>> -static const enum omap_control_usb_type omap4_data = OMAP_CTRL_TYPE_OMAP4;
>> -static const enum omap_control_usb_type usb2_data = OMAP_CTRL_TYPE_USB2;
>> -static const enum omap_control_usb_type usb3_data = OMAP_CTRL_TYPE_USB3;
>> -static const enum omap_control_usb_type dra7_data = OMAP_CTRL_TYPE_DRA7;
>> +static const enum omap_control_phy_type omap4_data = OMAP_CTRL_TYPE_OMAP4;
>> +static const enum omap_control_phy_type usb2_data = OMAP_CTRL_TYPE_USB2;
>> +static const enum omap_control_phy_type usb3_data = OMAP_CTRL_TYPE_USB3;
>> +static const enum omap_control_phy_type dra7_data = OMAP_CTRL_TYPE_DRA7;
>>
>> -static const struct of_device_id omap_control_usb_id_table[] = {
>> +static const struct of_device_id omap_control_phy_id_table[] = {
>>   	{
>>   		.compatible = "ti,omap4-control-usb",
>>   		.data = &omap4_data,
>> @@ -286,31 +286,31 @@ static const struct of_device_id omap_control_usb_id_table[] = {
>>   	},
>>   	{},
>>   };
>> -MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
>> +MODULE_DEVICE_TABLE(of, omap_control_phy_id_table);
>>   #endif
>>
>> -static struct platform_driver omap_control_usb_driver = {
>> -	.probe		= omap_control_usb_probe,
>> +static struct platform_driver omap_control_phy_driver = {
>> +	.probe		= omap_control_phy_probe,
>>   	.driver		= {
>>   		.name	= "omap-control-usb",
>>   		.owner	= THIS_MODULE,
>> -		.of_match_table = of_match_ptr(omap_control_usb_id_table),
>> +		.of_match_table = of_match_ptr(omap_control_phy_id_table),
>>   	},
>>   };
>>
>> -static int __init omap_control_usb_init(void)
>> +static int __init omap_control_phy_init(void)
>>   {
>> -	return platform_driver_register(&omap_control_usb_driver);
>> +	return platform_driver_register(&omap_control_phy_driver);
>>   }
>> -subsys_initcall(omap_control_usb_init);
>> +subsys_initcall(omap_control_phy_init);
>
> Any specific reason for having this as subsys_initcall?

No. I think this driver was written when probe defer mechanism was not 
introduced in the kernel.
>
> If not then you can use module_platform_driver().

right.

Thanks
Kishon

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-09-16  2:52     ` Kishon Vijay Abraham I
@ 2013-09-16  7:25       ` Roger Quadros
  0 siblings, 0 replies; 47+ messages in thread
From: Roger Quadros @ 2013-09-16  7:25 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Hi,

On 09/16/2013 05:52 AM, Kishon Vijay Abraham I wrote:
> On Thursday 12 September 2013 06:49 PM, Roger Quadros wrote:
>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>>> phy_power_on() and phy_power_off().
>>>
>>> However using the old USB phy library wont be removed till the PHYs of all
>>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>>   Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>>>   drivers/usb/dwc3/Kconfig                       |    1 +
>>>   drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>>>   drivers/usb/dwc3/core.h                        |    7 ++++
>>>   4 files changed, 61 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>>> index e807635..471366d 100644
>>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>>> @@ -6,11 +6,13 @@ Required properties:
>>>    - compatible: must be "snps,dwc3"
>>>    - reg : Address and length of the register set for the device
>>>    - interrupts: Interrupts used by the dwc3 controller.
>>> +
>>> +Optional properties:
>>>    - usb-phy : array of phandle for the PHY device.  The first element
>>>      in the array is expected to be a handle to the USB2/HS PHY and
>>>      the second element is expected to be a handle to the USB3/SS PHY
>>> -
>>> -Optional properties:
>>> + - phys: from the *Generic PHY* bindings
>>> + - phy-names: from the *Generic PHY* bindings
>>>    - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>>
>>>   This is usually a subnode to DWC3 glue to which it is connected.
>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>>> index cfc16dd..ad7ce83 100644
>>> --- a/drivers/usb/dwc3/Kconfig
>>> +++ b/drivers/usb/dwc3/Kconfig
>>> @@ -3,6 +3,7 @@ config USB_DWC3
>>>       depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>>       depends on EXTCON
>>>       select USB_PHY
>>> +    select GENERIC_PHY
>>>       select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>>       help
>>>         Say Y or M here if your system has a Dual Role SuperSpeed
>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>> index 428c29e..485d365 100644
>>> --- a/drivers/usb/dwc3/core.c
>>> +++ b/drivers/usb/dwc3/core.c
>>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>>
>>>       usb_phy_init(dwc->usb2_phy);
>>>       usb_phy_init(dwc->usb3_phy);
>>> +
>>> +    if (dwc->usb2_generic_phy)
>>> +        phy_init(dwc->usb2_generic_phy);
>>> +    if (dwc->usb3_generic_phy)
>>> +        phy_init(dwc->usb3_generic_phy);
>>> +
>>>       mdelay(100);
>>>
>>>       /* Clear USB3 PHY reset */
>>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>>>   {
>>>       usb_phy_shutdown(dwc->usb2_phy);
>>>       usb_phy_shutdown(dwc->usb3_phy);
>>> +
>>> +    if (dwc->usb2_generic_phy)
>>> +        phy_power_off(dwc->usb2_generic_phy);
>>> +    if (dwc->usb3_generic_phy)
>>> +        phy_power_off(dwc->usb3_generic_phy);
>>>   }
>>>
>>>   #define DWC3_ALIGN_MASK        (16 - 1)
>>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>>>           dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>>>       }
>>>
>>> +    if (of_property_read_bool(node, "phys") || pdata->has_phy) {
>>> +        dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>>> +        if (IS_ERR(dwc->usb2_generic_phy)) {
>>> +            dev_err(dev, "no usb2 phy configured yet");
>>> +            return PTR_ERR(dwc->usb2_generic_phy);
>>> +        }
>>> +
>>> +        dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
>>> +        if (IS_ERR(dwc->usb3_generic_phy)) {
>>> +            dev_err(dev, "no usb3 phy configured yet");
>>> +            return PTR_ERR(dwc->usb3_generic_phy);
>>> +        }
>>> +    } else {
>>> +        dwc->usb2_generic_phy = NULL;
>>> +        dwc->usb3_generic_phy = NULL;
>>> +    }
>>> +
>>>       /* default to superspeed if no maximum_speed passed */
>>>       if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
>>>           dwc->maximum_speed = USB_SPEED_SUPER;
>>> @@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)
>>>       usb_phy_set_suspend(dwc->usb2_phy, 0);
>>>       usb_phy_set_suspend(dwc->usb3_phy, 0);
>>>
>>> +    if (dwc->usb2_generic_phy)
>>> +        phy_power_on(dwc->usb2_generic_phy);
>>> +    if (dwc->usb3_generic_phy)
>>> +        phy_power_on(dwc->usb3_generic_phy);
>>> +
>>>       spin_lock_init(&dwc->lock);
>>>       platform_set_drvdata(pdev, dwc);
>>>
>>> @@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)
>>>       usb_phy_set_suspend(dwc->usb2_phy, 1);
>>>       usb_phy_set_suspend(dwc->usb3_phy, 1);
>>>
>>> +    if (dwc->usb2_generic_phy)
>>
>> if (IS_ERR())
> 
> I assign NULL to usb2_generic_phy and usb3_generic_phy in case the dts entry doesn't have a *phys* property.
> The IS_ERR of usb2_generic_phy is treated as an error condition and probe will fail.

OK.

>>
>>> +        phy_power_off(dwc->usb2_generic_phy);
>>> +    if (dwc->usb3_generic_phy)
>>
>> if (IS_ERR())
>>
>> here and everywhere else in this patch.
>>
>>> +        phy_power_off(dwc->usb3_generic_phy);
>>> +
>>>       pm_runtime_put(&pdev->dev);
>>>       pm_runtime_disable(&pdev->dev);
>>>
>>> @@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)
>>>       usb_phy_shutdown(dwc->usb3_phy);
>>>       usb_phy_shutdown(dwc->usb2_phy);
>>>
>>> +    if (dwc->usb2_generic_phy)
>>> +        phy_exit(dwc->usb2_generic_phy);
>>> +    if (dwc->usb3_generic_phy)
>>> +        phy_exit(dwc->usb3_generic_phy);
>>> +
>>>       return 0;
>>>   }
>>>
>>> @@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
>>>
>>>       usb_phy_init(dwc->usb3_phy);
>>>       usb_phy_init(dwc->usb2_phy);
>>> +
>>> +    if (dwc->usb2_generic_phy)
>>> +        phy_init(dwc->usb2_generic_phy);
>>> +    if (dwc->usb3_generic_phy)
>>> +        phy_init(dwc->usb3_generic_phy);
>>> +
>>>       msleep(100);
>>>
>>>       spin_lock_irqsave(&dwc->lock, flags);
>>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>>> index f8af8d4..01ec7d7 100644
>>> --- a/drivers/usb/dwc3/core.h
>>> +++ b/drivers/usb/dwc3/core.h
>>> @@ -31,6 +31,8 @@
>>>   #include <linux/usb/gadget.h>
>>>   #include <linux/usb/otg.h>
>>>
>>> +#include <linux/phy/phy.h>
>>> +
>>>   /* Global constants */
>>>   #define DWC3_EP0_BOUNCE_SIZE    512
>>>   #define DWC3_ENDPOINTS_NUM    32
>>> @@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
>>>    * @dr_mode: requested mode of operation
>>>    * @usb2_phy: pointer to USB2 PHY
>>>    * @usb3_phy: pointer to USB3 PHY
>>> + * @usb2_generic_phy: pointer to USB2 PHY
>>> + * @usb3_generic_phy: pointer to USB3 PHY
>>
>> Why duplicate usbX_phy and usbX_generic_phy? Can't we just have one
>> for each type and call it usbX_phy?
> 
> There was an already existing phy library in usb which usesusb_phy. There might still be users using the existing usb phy library. Until all the users have completely migrated to the generic PHY framework, this would co-exist.
> 
OK.

cheers,
-roger

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

* Re: [PATCH 3/7] drivers: phy: usb3/pipe3: Adapt pipe3 driver to Generic PHY Framework
  2013-09-16  3:01     ` Kishon Vijay Abraham I
@ 2013-09-16  7:37       ` Roger Quadros
  2013-10-11 15:02         ` Roger Quadros
  0 siblings, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-09-16  7:37 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

On 09/16/2013 06:01 AM, Kishon Vijay Abraham I wrote:
> On Thursday 12 September 2013 04:49 PM, Roger Quadros wrote:
>> Hi Kishon,
>>
>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>>> Adapted omap-usb3 PHY driver to Generic PHY Framework and moved phy-omap-usb3
>>> driver in drivers/usb/phy to drivers/phy and also renamed the file to
>>> phy-omap-pipe3 since this same driver will be used for SATA PHY and
>>> PCIE PHY.
>>
>> I would suggest to split the renaming and PHY adaptation into 2 separate patches.
> 
> Alright.
>>
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>>   Documentation/devicetree/bindings/usb/usb-phy.txt  |    5 +-
>>>   drivers/phy/Kconfig                                |   10 +
>>>   drivers/phy/Makefile                               |    1 +
>>>   .../phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c}   |  206 +++++++++++---------
>>
>> how about naming it to phy-ti-pipe3.c as it is used on OMAP as well as non-OMAP e.g. DRA7.
> 
> hmm.. I thought it would be consistent with other PHY drivers (phy-omap-usb2). Moreover DRA7 is OMAP based platform ;-) Maybe we should reserve that for later?

OK. Up to you.

>>
>>>   drivers/usb/phy/Kconfig                            |   11 --
>>>   drivers/usb/phy/Makefile                           |    1 -
>>>   include/linux/phy/omap_pipe3.h                     |   52 +++++
>>>   7 files changed, 177 insertions(+), 109 deletions(-)
>>>   rename drivers/{usb/phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c} (57%)
>>>   create mode 100644 include/linux/phy/omap_pipe3.h
>>>
>>> diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt
>>> index c0245c8..36bdb17 100644
>>> --- a/Documentation/devicetree/bindings/usb/usb-phy.txt
>>> +++ b/Documentation/devicetree/bindings/usb/usb-phy.txt
>>> @@ -21,10 +21,11 @@ usb2phy@4a0ad080 {
>>>       #phy-cells = <0>;
>>>   };
>>>
>>> -OMAP USB3 PHY
>>> +OMAP PIPE3 PHY
>>>
>>>   Required properties:
>>> - - compatible: Should be "ti,omap-usb3"
>>> + - compatible: Should be "ti,omap-usb3", "ti,omap-pipe3", "ti,omap-sata"
>>> +   or "ti,omap-pcie"
>>>    - reg : Address and length of the register set for the device.
>>>    - reg-names: The names of the register addresses corresponding to the registers
>>>      filled in "reg".
>>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>>> index ac239ac..5c2e7a0 100644
>>> --- a/drivers/phy/Kconfig
>>> +++ b/drivers/phy/Kconfig
>>> @@ -27,6 +27,16 @@ config OMAP_USB2
>>>         The USB OTG controller communicates with the comparator using this
>>>         driver.
>>>
>>> +config OMAP_PIPE3
>>> +    tristate "OMAP PIPE3 PHY Driver"
>>> +    select GENERIC_PHY
>>> +    select OMAP_CONTROL_USB
>> how about
>>     depends on OMAP_CONTROL_USB
> 
> From whatever I could make out from comments of Greg in my Generic PHY Framework, it's better to do a select of dependent modules instead of depends on.

You can use select, provided the item you are selecting doesn't depend on anything else.
As OMAP_CONTROL_USB depends on ARCH_OMAP2PLUS, your configuration will fail if a user enables
OMAP_PIPE3 on non OMAP configuration.

Further, in this case since it is OMAP related driver, there is no point in showing/building it
if OMAP platform is not selected, so you at least need [depends on "ARCH_OMAP2PLUS"] to fix
both issue I mentioned.

>>
>> Also, if this is TI/OMAP it might as well depend on ARCH_OMAP.
>>
>>> +    help
>>> +      Enable this to support the PIPE3 PHY that is part of SOC. This
>>
>> worth mentioning TI OMAP/DRA SoCs.
> 
> right.
>>
>>> +      driver takes care of all the PHY functionality apart from comparator.
>>> +      This driver interacts with the "OMAP Control PHY Driver" to power
>>> +      on/off the PHY.
>>> +
>>>   config TWL4030_USB
>>>       tristate "TWL4030 USB Transceiver Driver"
>>>       depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
>>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>>> index 0dd8a98..48bf9f2 100644
>>> --- a/drivers/phy/Makefile
>>> +++ b/drivers/phy/Makefile
>>> @@ -4,4 +4,5 @@
>>>
>>>   obj-$(CONFIG_GENERIC_PHY)    += phy-core.o
>>>   obj-$(CONFIG_OMAP_USB2)        += phy-omap-usb2.o
>>> +obj-$(CONFIG_OMAP_PIPE3)    += phy-omap-pipe3.o
>>>   obj-$(CONFIG_TWL4030_USB)    += phy-twl4030-usb.o
>>> diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/phy/phy-omap-pipe3.c
>>> similarity index 57%
>>> rename from drivers/usb/phy/phy-omap-usb3.c
>>> rename to drivers/phy/phy-omap-pipe3.c
>>> index 4004f82..ee9a901 100644
>>> --- a/drivers/usb/phy/phy-omap-usb3.c
>>> +++ b/drivers/phy/phy-omap-pipe3.c
>>> @@ -1,5 +1,5 @@
>>>   /*
>>> - * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP.
>>> + * omap-pipe3 - PHY driver for SATA, USB and PCIE in OMAP platforms
>>>    *
>>>    * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
>>>    * This program is free software; you can redistribute it and/or modify
>>> @@ -19,7 +19,8 @@
>>>   #include <linux/module.h>
>>>   #include <linux/platform_device.h>
>>>   #include <linux/slab.h>
>>> -#include <linux/usb/omap_usb.h>
>>> +#include <linux/phy/omap_pipe3.h>
>>> +#include <linux/phy/phy.h>
>>>   #include <linux/of.h>
>>>   #include <linux/clk.h>
>>>   #include <linux/err.h>
>>> @@ -52,17 +53,17 @@
>>>
>>>   /*
>>>    * This is an Empirical value that works, need to confirm the actual
>>> - * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status
>>> - * to be correctly reflected in the USB3PHY_PLL_STATUS register.
>>> + * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status
>>> + * to be correctly reflected in the PIPE3PHY_PLL_STATUS register.
>>>    */
>>>   # define PLL_IDLE_TIME  100;
>>>
>>> -struct usb_dpll_map {
>>> +struct pipe3_dpll_map {
>>>       unsigned long rate;
>>> -    struct usb_dpll_params params;
>>> +    struct pipe3_dpll_params params;
>>>   };
>>>
>>> -static struct usb_dpll_map dpll_map[] = {
>>> +static struct pipe3_dpll_map dpll_map[] = {
>>>       {12000000, {1250, 5, 4, 20, 0} },    /* 12 MHz */
>>>       {16800000, {3125, 20, 4, 20, 0} },    /* 16.8 MHz */
>>>       {19200000, {1172, 8, 4, 20, 65537} },    /* 19.2 MHz */
>>> @@ -71,7 +72,7 @@ static struct usb_dpll_map dpll_map[] = {
>>>       {38400000, {3125, 47, 4, 20, 92843} },    /* 38.4 MHz */
>>>   };
>>>
>>> -static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
>>> +static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(unsigned long rate)
>>>   {
>>>       int i;
>>>
>>> @@ -83,110 +84,113 @@ static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
>>>       return 0;
>>>   }
>>>
>>> -static int omap_usb3_suspend(struct usb_phy *x, int suspend)
>>> +static int omap_pipe3_power_off(struct phy *x)
>>>   {
>>> -    struct omap_usb *phy = phy_to_omapusb(x);
>>> -    int    val;
>>> +    struct omap_pipe3 *phy = phy_get_drvdata(x);
>>> +    int val;
>>>       int timeout = PLL_IDLE_TIME;
>>>
>>> -    if (suspend && !phy->is_suspended) {
>>> -        val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>> -        val |= PLL_IDLE;
>>> -        omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>> -
>>> -        do {
>>> -            val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
>>> -            if (val & PLL_TICOPWDN)
>>> -                break;
>>> -            udelay(1);
>>> -        } while (--timeout);
>>> -
>>> -        omap_control_usb_phy_power(phy->control_dev, 0);
>>> -
>>> -        phy->is_suspended    = 1;
>>> -    } else if (!suspend && phy->is_suspended) {
>>> -        phy->is_suspended    = 0;
>>> -
>>> -        val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>> -        val &= ~PLL_IDLE;
>>> -        omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>> -
>>> -        do {
>>> -            val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
>>> -            if (!(val & PLL_TICOPWDN))
>>> -                break;
>>> -            udelay(1);
>>> -        } while (--timeout);
>>> -    }
>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>> +    val |= PLL_IDLE;
>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>> +
>>> +    do {
>>> +        val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>>> +        if (val & PLL_TICOPWDN)
>>> +            break;
>>> +        udelay(1);
>>
>> Is it better to sleep instead of udelay?
> 
> hmm.. yeah, I guess this function wont be called from interrupt context.
>>
>>> +    } while (--timeout);
>>> +
>>> +    omap_control_usb_phy_power(phy->control_dev, 0);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int omap_pipe3_power_on(struct phy *x)
>>> +{
>>> +    struct omap_pipe3 *phy = phy_get_drvdata(x);
>>> +    int val;
>>> +    int timeout = PLL_IDLE_TIME;
>>> +
>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>> +    val &= ~PLL_IDLE;
>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>> +
>>> +    do {
>>> +        val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>>> +        if (!(val & PLL_TICOPWDN))
>>> +            break;
>>> +        udelay(1);
>>
>> here too.
> 
> Ok.
>>
>>> +    } while (--timeout);
>>>
>>>       return 0;
>>>   }
>>>
>>> -static void omap_usb_dpll_relock(struct omap_usb *phy)
>>> +static void omap_pipe3_dpll_relock(struct omap_pipe3 *phy)
>>>   {
>>>       u32        val;
>>>       unsigned long    timeout;
>>>
>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
>>>
>>>       timeout = jiffies + msecs_to_jiffies(20);
>>>       do {
>>> -        val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
>>> +        val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>           if (val & PLL_LOCK)
>>>               break;
>>>       } while (!WARN_ON(time_after(jiffies, timeout)));
>>>   }
>>>
>>> -static int omap_usb_dpll_lock(struct omap_usb *phy)
>>> +static int omap_pipe3_dpll_lock(struct omap_pipe3 *phy)
>>>   {
>>>       u32            val;
>>>       unsigned long        rate;
>>> -    struct usb_dpll_params *dpll_params;
>>> +    struct pipe3_dpll_params *dpll_params;
>>>
>>>       rate = clk_get_rate(phy->sys_clk);
>>> -    dpll_params = omap_usb3_get_dpll_params(rate);
>>> +    dpll_params = omap_pipe3_get_dpll_params(rate);
>>>       if (!dpll_params) {
>>>           dev_err(phy->dev,
>>>                 "No DPLL configuration for %lu Hz SYS CLK\n", rate);
>>>           return -EINVAL;
>>>       }
>>>
>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>>       val &= ~PLL_REGN_MASK;
>>>       val |= dpll_params->n << PLL_REGN_SHIFT;
>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>>
>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>       val &= ~PLL_SELFREQDCO_MASK;
>>>       val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>
>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>>       val &= ~PLL_REGM_MASK;
>>>       val |= dpll_params->m << PLL_REGM_SHIFT;
>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>>
>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
>>>       val &= ~PLL_REGM_F_MASK;
>>>       val |= dpll_params->mf << PLL_REGM_F_SHIFT;
>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
>>>
>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
>>>       val &= ~PLL_SD_MASK;
>>>       val |= dpll_params->sd << PLL_SD_SHIFT;
>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
>>>
>>> -    omap_usb_dpll_relock(phy);
>>> +    omap_pipe3_dpll_relock(phy);
>>>
>>>       return 0;
>>>   }
>>>
>>> -static int omap_usb3_init(struct usb_phy *x)
>>> +static int omap_pipe3_init(struct phy *x)
>>>   {
>>> -    struct omap_usb    *phy = phy_to_omapusb(x);
>>> +    struct omap_pipe3 *phy = phy_get_drvdata(x);
>>>       int ret;
>>>
>>> -    ret = omap_usb_dpll_lock(phy);
>>> +    ret = omap_pipe3_dpll_lock(phy);
>>>       if (ret)
>>>           return ret;
>>>
>>> @@ -195,9 +199,18 @@ static int omap_usb3_init(struct usb_phy *x)
>>>       return 0;
>>>   }
>>>
>>> -static int omap_usb3_probe(struct platform_device *pdev)
>>> +static struct phy_ops ops = {
>>> +    .init        = omap_pipe3_init,
>>> +    .power_on    = omap_pipe3_power_on,
>>> +    .power_off    = omap_pipe3_power_off,
>>> +    .owner        = THIS_MODULE,
>>> +};
>>> +
>>> +static int omap_pipe3_probe(struct platform_device *pdev)
>>>   {
>>> -    struct omap_usb *phy;
>>> +    struct omap_pipe3 *phy;
>>> +    struct phy *generic_phy;
>>> +    struct phy_provider *phy_provider;
>>>       struct resource *res;
>>>       struct device_node *node = pdev->dev.of_node;
>>>       struct device_node *control_node;
>>> @@ -208,7 +221,7 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>>
>>>       phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
>>>       if (!phy) {
>>> -        dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n");
>>> +        dev_err(&pdev->dev, "unable to alloc mem for OMAP PIPE3 PHY\n");
>>>           return -ENOMEM;
>>>       }
>>>
>>> @@ -219,13 +232,6 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>>
>>>       phy->dev        = &pdev->dev;
>>>
>>> -    phy->phy.dev        = phy->dev;
>>> -    phy->phy.label        = "omap-usb3";
>>> -    phy->phy.init        = omap_usb3_init;
>>> -    phy->phy.set_suspend    = omap_usb3_suspend;
>>> -    phy->phy.type        = USB_PHY_TYPE_USB3;
>>> -
>>> -    phy->is_suspended    = 1;
>>>       phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
>>
>> As this is no longer USB specific, we need to make the clock binding generic as well.
> 
> right. Its also needed when we have the same driver work for sata and pcie. Maybe do that in a separate patch?

OK. up to you.
>>
>>>       if (IS_ERR(phy->wkupclk)) {
>>>           dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
>>> @@ -251,6 +257,11 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>>           dev_err(&pdev->dev, "Failed to get control device phandle\n");
>>>           return -EINVAL;
>>>       }
>>> +    phy_provider = devm_of_phy_provider_register(phy->dev,
>>> +            of_phy_simple_xlate);
>>> +    if (IS_ERR(phy_provider))
>>> +        return PTR_ERR(phy_provider);
>>> +
>>>       control_pdev = of_find_device_by_node(control_node);
>>>       if (!control_pdev) {
>>>           dev_err(&pdev->dev, "Failed to get control device\n");
>>> @@ -260,23 +271,27 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>>       phy->control_dev = &control_pdev->dev;
>>>
>>>       omap_control_usb_phy_power(phy->control_dev, 0);
>>> -    usb_add_phy_dev(&phy->phy);
>>>
>>>       platform_set_drvdata(pdev, phy);
>>> -
>>>       pm_runtime_enable(phy->dev);
>>> +
>>> +    generic_phy = devm_phy_create(phy->dev, &ops, NULL);
>>> +    if (IS_ERR(generic_phy))
>>> +        return PTR_ERR(generic_phy);
>>> +
>>> +    phy_set_drvdata(generic_phy, phy);
>>> +
>>>       pm_runtime_get(&pdev->dev);
>>>
>>>       return 0;
>>>   }
>>>
>>> -static int omap_usb3_remove(struct platform_device *pdev)
>>> +static int omap_pipe3_remove(struct platform_device *pdev)
>>>   {
>>> -    struct omap_usb *phy = platform_get_drvdata(pdev);
>>> +    struct omap_pipe3 *phy = platform_get_drvdata(pdev);
>>>
>>>       clk_unprepare(phy->wkupclk);
>>>       clk_unprepare(phy->optclk);
>>> -    usb_remove_phy(&phy->phy);
>>>       if (!pm_runtime_suspended(&pdev->dev))
>>>           pm_runtime_put(&pdev->dev);
>>>       pm_runtime_disable(&pdev->dev);
>>> @@ -286,10 +301,9 @@ static int omap_usb3_remove(struct platform_device *pdev)
>>>
>>>   #ifdef CONFIG_PM_RUNTIME
>>>
>>> -static int omap_usb3_runtime_suspend(struct device *dev)
>>> +static int omap_pipe3_runtime_suspend(struct device *dev)
>>>   {
>>> -    struct platform_device    *pdev = to_platform_device(dev);
>>> -    struct omap_usb    *phy = platform_get_drvdata(pdev);
>>> +    struct omap_pipe3    *phy = dev_get_drvdata(dev);
>>>
>>>       clk_disable(phy->wkupclk);
>>>       clk_disable(phy->optclk);
>>> @@ -297,11 +311,10 @@ static int omap_usb3_runtime_suspend(struct device *dev)
>>>       return 0;
>>>   }
>>>
>>> -static int omap_usb3_runtime_resume(struct device *dev)
>>> +static int omap_pipe3_runtime_resume(struct device *dev)
>>>   {
>>>       u32 ret = 0;
>>> -    struct platform_device    *pdev = to_platform_device(dev);
>>> -    struct omap_usb    *phy = platform_get_drvdata(pdev);
>>> +    struct omap_pipe3    *phy = dev_get_drvdata(dev);
>>>
>>>       ret = clk_enable(phy->optclk);
>>>       if (ret) {
>>> @@ -324,38 +337,41 @@ err1:
>>>       return ret;
>>>   }
>>>
>>> -static const struct dev_pm_ops omap_usb3_pm_ops = {
>>> -    SET_RUNTIME_PM_OPS(omap_usb3_runtime_suspend, omap_usb3_runtime_resume,
>>> -        NULL)
>>> +static const struct dev_pm_ops omap_pipe3_pm_ops = {
>>> +    SET_RUNTIME_PM_OPS(omap_pipe3_runtime_suspend,
>>> +        omap_pipe3_runtime_resume, NULL)
>>>   };
>>>
>>> -#define DEV_PM_OPS     (&omap_usb3_pm_ops)
>>> +#define DEV_PM_OPS     (&omap_pipe3_pm_ops)
>>>   #else
>>>   #define DEV_PM_OPS     NULL
>>>   #endif
>>>
>>>   #ifdef CONFIG_OF
>>> -static const struct of_device_id omap_usb3_id_table[] = {
>>> +static const struct of_device_id omap_pipe3_id_table[] = {
>>> +    { .compatible = "ti,omap-pipe3" },
>>
>> why do you need "omap-pipe3", isn't sata, pcie and usb3 sufficient?
> 
> I thought it would be better if everyone uses omap-pipe3 and added pcie, sata if there are any specific settings (for pcie or sata) that should be done.

We can always add specialized options later when needed. AFAIK just the
DPLL data is different among the different PHYs.
>>
>>> +    { .compatible = "ti,omap-sata" },
>>> +    { .compatible = "ti,omap-pcie" },
>>>       { .compatible = "ti,omap-usb3" },

I think compatible strings should be improved to indicate that it is a PHY.

e.g. "ti,omap-phy-sata" or just "ti,pipe3-phy-sata"

>>>       {}
>>>   };
>>> -MODULE_DEVICE_TABLE(of, omap_usb3_id_table);
>>> +MODULE_DEVICE_TABLE(of, omap_pipe3_id_table);
>>>   #endif

cheers,
-roger


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

* Re: [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY
  2013-09-12 13:11           ` Roger Quadros
@ 2013-09-16  8:40             ` Vivek Gautam
  0 siblings, 0 replies; 47+ messages in thread
From: Vivek Gautam @ 2013-09-16  8:40 UTC (permalink / raw)
  To: Roger Quadros, Sylwester Nawrocki
  Cc: Kishon Vijay Abraham I, Felipe Balbi, Benoit Cousson,
	Tony Lindgren, Rob Herring, Pawel Moll, Mark Rutland,
	Russell King - ARM Linux, Grant Likely, Kumar Gala,
	Stephen Warren, Ian Campbell, Rob Landley, george.cherian,
	Greg KH, linux-doc, linux-omap, devicetree,
	Linux USB Mailing List, linux-arm-kernel, linux-kernel

Hi,


On Thu, Sep 12, 2013 at 6:41 PM, Roger Quadros <rogerq@ti.com> wrote:
> On 09/12/2013 02:26 PM, Vivek Gautam wrote:
>> Hi,
>>
>>
>> On Thu, Sep 12, 2013 at 4:34 PM, Roger Quadros <rogerq@ti.com> wrote:
>>> Hi,
>>>
>>> On 09/12/2013 01:47 PM, Vivek Gautam wrote:
>>>> On Thu, Sep 12, 2013 at 4:06 PM, Roger Quadros <rogerq@ti.com> wrote:
>>>>> Hi Kishon,
>>>>>
>>>>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>>>>>> There can be systems which does not have a external usb_phy, so get
>>>>>> usb_phy only if usb-phy property is added in the case of dt boot or if
>>>>>> platform_data indicates the presence of PHY. Also remove checking if
>>>>>> return value is -ENXIO since it's now changed to always enable usb_phy layer.
>>>>>>
>>>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>>>> ---
>>>>>>  drivers/usb/dwc3/Kconfig         |    1 +
>>>>>>  drivers/usb/dwc3/core.c          |   60 +++++++++++++++++---------------------
>>>>>>  drivers/usb/dwc3/platform_data.h |    1 +
>>>>>>  3 files changed, 28 insertions(+), 34 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>>>>>> index f969ea2..cfc16dd 100644
>>>>>> --- a/drivers/usb/dwc3/Kconfig
>>>>>> +++ b/drivers/usb/dwc3/Kconfig
>>>>>> @@ -2,6 +2,7 @@ config USB_DWC3
>>>>>>       tristate "DesignWare USB3 DRD Core Support"
>>>>>>       depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>>>>>       depends on EXTCON
>>>>>> +     select USB_PHY
>>>>>>       select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>>>>>       help
>>>>>>         Say Y or M here if your system has a Dual Role SuperSpeed
>>>>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>>>>> index 474162e..428c29e 100644
>>>>>> --- a/drivers/usb/dwc3/core.c
>>>>>> +++ b/drivers/usb/dwc3/core.c
>>>>>> @@ -387,16 +387,38 @@ static int dwc3_probe(struct platform_device *pdev)
>>>>>>       if (node) {
>>>>>>               dwc->maximum_speed = of_usb_get_maximum_speed(node);
>>>>>>
>>>>>> -             dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
>>>>>> -             dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
>>>>>> +             if (of_property_read_bool(node, "usb-phy")) {
>>>>>> +                     dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev,
>>>>>> +                             "usb-phy", 0);
>>>>>> +                     if (IS_ERR(dwc->usb2_phy))
>>>>>> +                             return PTR_ERR(dwc->usb2_phy);
>>>>>> +                     dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev,
>>>>>> +                             "usb-phy", 1);
>>>>>> +                     if (IS_ERR(dwc->usb3_phy))
>>>>>> +                             return PTR_ERR(dwc->usb3_phy);
>>>>>
>>>>> Some DWC3 instances use only usb2_phy. e.g. on DRA7 the 2nd dwc3 instance doesn't use usb3_phy.
>>>>> This needs to be a valid case and driver shouldn't error out.
>>>>
>>>> So, i think adding flexibility to DWC3 to have either
>>>> usb2-phy/usb3-phy or both of them seems to be valid point.
>>>> Any suggestions ?
>>>>
>>>
>>> For high speed operation we need only usb2_phy but for super speed we need both usb2_phy
>>> and usb3_phy.
>>>
>>> Why would a dwc3 controller use only usb3_phy? A USB3.0 interface has to be compatible with
>>> USB2.0 as well, no?
>>
>> True and for that reason we need both UTMI+ interface as well as PIPE3
>> interface, right ?
>> But as also mentioned in the thread:
>> https://lkml.org/lkml/2013/9/12/181, on Samsung exynos5
>> architecturally same block is managing UTMI+ and PIPE3 interfaces,
>> which is handled by phy-samsung-usb3 driver and denoted by "usb3_phy:
>> usbphy@12100000" node in "arch/arm/boot/dts/exynos5250.dtsi".
>>
>> So on exynos5250, DWC3 really needs just usb3-phy, which is compatible
>> for USB 2.0 as well.
>
> I'm not familiar with exynos5250 dwc3, but looking at the dts file I can see both usb3_phy
> and usb2_phy nodes and both are referenced in the dwc3 node.

Right, and that's what we intend to fix.
Exynos5250 dwc3 is not in the need of both usb2_phy and usb3_phy.
In fact usb3_phy handle (which is served by phy-samsung-usb3 driver)
sets up the UTMI+ as well as PIPE3 phy on DWC3.
I know this looks different from the usual OMAP style of phy for dwc3.

Hi Sylwester,
  any suggestions here ? As contained in the exynos5250 user manual
too, there's only one block of PHY handling both UTMI+ and PIPE3
interfaces, and the set of registers (same base address) also indicate
one block of PHY. So we have the usb3_phy (phy-samsung-usb3 driver)
which setup the entire PHY require for DWC3 operation, and thereby we
__shouldn't__ need usb2_phy (phy-samsung-usb2 driver which actually
setup the PHY for a separate USB 2.0 controller on exynos5250) for
DWC3.

>
> The ehci and ohci controllers don't reference any PHY.

ehci-s5p and ohci-exynos are not using devm_usb_get_phy_by_phandle()
api until now, so they don't need to have the PHY handlers in their
node.

>
> cheers,
> -roger



-- 
Best Regards
Vivek

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

* Re: [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY
  2013-09-12 10:47     ` Vivek Gautam
  2013-09-12 11:04       ` Roger Quadros
@ 2013-09-17 15:45       ` Felipe Balbi
  1 sibling, 0 replies; 47+ messages in thread
From: Felipe Balbi @ 2013-09-17 15:45 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: Roger Quadros, Kishon Vijay Abraham I, Felipe Balbi,
	Benoit Cousson, Tony Lindgren, Rob Herring, Pawel Moll,
	Mark Rutland, Russell King - ARM Linux, Grant Likely,
	Sylwester Nawrocki, Kumar Gala, Stephen Warren, Ian Campbell,
	Rob Landley, george.cherian, Greg KH, linux-doc, linux-omap,
	devicetree, Linux USB Mailing List, linux-arm-kernel,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3233 bytes --]

Hi,

On Thu, Sep 12, 2013 at 04:17:08PM +0530, Vivek Gautam wrote:
> On Thu, Sep 12, 2013 at 4:06 PM, Roger Quadros <rogerq@ti.com> wrote:
> > Hi Kishon,
> >
> > On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
> >> There can be systems which does not have a external usb_phy, so get
> >> usb_phy only if usb-phy property is added in the case of dt boot or if
> >> platform_data indicates the presence of PHY. Also remove checking if
> >> return value is -ENXIO since it's now changed to always enable usb_phy layer.
> >>
> >> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> >> ---
> >>  drivers/usb/dwc3/Kconfig         |    1 +
> >>  drivers/usb/dwc3/core.c          |   60 +++++++++++++++++---------------------
> >>  drivers/usb/dwc3/platform_data.h |    1 +
> >>  3 files changed, 28 insertions(+), 34 deletions(-)
> >>
> >> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> >> index f969ea2..cfc16dd 100644
> >> --- a/drivers/usb/dwc3/Kconfig
> >> +++ b/drivers/usb/dwc3/Kconfig
> >> @@ -2,6 +2,7 @@ config USB_DWC3
> >>       tristate "DesignWare USB3 DRD Core Support"
> >>       depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
> >>       depends on EXTCON
> >> +     select USB_PHY
> >>       select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
> >>       help
> >>         Say Y or M here if your system has a Dual Role SuperSpeed
> >> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> >> index 474162e..428c29e 100644
> >> --- a/drivers/usb/dwc3/core.c
> >> +++ b/drivers/usb/dwc3/core.c
> >> @@ -387,16 +387,38 @@ static int dwc3_probe(struct platform_device *pdev)
> >>       if (node) {
> >>               dwc->maximum_speed = of_usb_get_maximum_speed(node);
> >>
> >> -             dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
> >> -             dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
> >> +             if (of_property_read_bool(node, "usb-phy")) {
> >> +                     dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev,
> >> +                             "usb-phy", 0);
> >> +                     if (IS_ERR(dwc->usb2_phy))
> >> +                             return PTR_ERR(dwc->usb2_phy);
> >> +                     dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev,
> >> +                             "usb-phy", 1);
> >> +                     if (IS_ERR(dwc->usb3_phy))
> >> +                             return PTR_ERR(dwc->usb3_phy);
> >
> > Some DWC3 instances use only usb2_phy. e.g. on DRA7 the 2nd dwc3 instance doesn't use usb3_phy.
> > This needs to be a valid case and driver shouldn't error out.
> 
> So, i think adding flexibility to DWC3 to have either
> usb2-phy/usb3-phy or both of them seems to be valid point.
> Any suggestions ?

I've gone through that. There's no easy way to make USB3 PHY optional.

For platforms which actually have the USB3 side of things, not
initializing the PHY kills dwc3.

I've been trying to understand what it is that the USB3 PHY generates
and gets backfed into dwc3, but so far no luck.

I even have a patch for that, which I have dropped when I found out
about this problem.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-09-12 10:27       ` Vivek Gautam
@ 2013-10-10 10:28         ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-10-10 10:28 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: rogerq, Felipe Balbi, bcousson, Tony Lindgren, Rob Herring,
	Pawel Moll, Mark Rutland, Russell King - ARM Linux, Grant Likely,
	Sylwester Nawrocki, galak, Stephen Warren, Ian Campbell,
	Rob Landley, george.cherian, Greg KH, linux-doc, linux-omap,
	devicetree, Linux USB Mailing List, linux-arm-kernel,
	linux-kernel

On Thursday 12 September 2013 03:57 PM, Vivek Gautam wrote:
> On Thu, Sep 12, 2013 at 3:40 PM, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>> On Thursday 12 September 2013 02:57 PM, Vivek Gautam wrote:
>>> Hi Kishon,
>>>
>>>
>>> On Mon, Sep 2, 2013 at 9:13 PM, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>>>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>>>> phy_power_on() and phy_power_off().
>>>>
>>>> However using the old USB phy library wont be removed till the PHYs of all
>>>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>>>
>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>> ---
>>>>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>>>>  drivers/usb/dwc3/Kconfig                       |    1 +
>>>>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>>>>  drivers/usb/dwc3/core.h                        |    7 ++++
>>>>  4 files changed, 61 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>>>> index e807635..471366d 100644
>>>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>>>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>>>> @@ -6,11 +6,13 @@ Required properties:
>>>>   - compatible: must be "snps,dwc3"
>>>>   - reg : Address and length of the register set for the device
>>>>   - interrupts: Interrupts used by the dwc3 controller.
>>>> +
>>>> +Optional properties:
>>>>   - usb-phy : array of phandle for the PHY device.  The first element
>>>>     in the array is expected to be a handle to the USB2/HS PHY and
>>>>     the second element is expected to be a handle to the USB3/SS PHY
>>>> -
>>>> -Optional properties:
>>>> + - phys: from the *Generic PHY* bindings
>>>> + - phy-names: from the *Generic PHY* bindings
>>>>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>>>
>>>>  This is usually a subnode to DWC3 glue to which it is connected.
>>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>>>> index cfc16dd..ad7ce83 100644
>>>> --- a/drivers/usb/dwc3/Kconfig
>>>> +++ b/drivers/usb/dwc3/Kconfig
>>>> @@ -3,6 +3,7 @@ config USB_DWC3
>>>>         depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>>>         depends on EXTCON
>>>>         select USB_PHY
>>>> +       select GENERIC_PHY
>>>>         select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>>>         help
>>>>           Say Y or M here if your system has a Dual Role SuperSpeed
>>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>>> index 428c29e..485d365 100644
>>>> --- a/drivers/usb/dwc3/core.c
>>>> +++ b/drivers/usb/dwc3/core.c
>>>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>>>
>>>>         usb_phy_init(dwc->usb2_phy);
>>>>         usb_phy_init(dwc->usb3_phy);
>>>> +
>>>> +       if (dwc->usb2_generic_phy)
>>>> +               phy_init(dwc->usb2_generic_phy);
>>>> +       if (dwc->usb3_generic_phy)
>>>> +               phy_init(dwc->usb3_generic_phy);
>>>> +
>>>>         mdelay(100);
>>>>
>>>>         /* Clear USB3 PHY reset */
>>>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>>>>  {
>>>>         usb_phy_shutdown(dwc->usb2_phy);
>>>>         usb_phy_shutdown(dwc->usb3_phy);
>>>> +
>>>> +       if (dwc->usb2_generic_phy)
>>>> +               phy_power_off(dwc->usb2_generic_phy);
>>>> +       if (dwc->usb3_generic_phy)
>>>> +               phy_power_off(dwc->usb3_generic_phy);
>>>>  }
>>>>
>>>>  #define DWC3_ALIGN_MASK                (16 - 1)
>>>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>>>>                 dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>>>>         }
>>>>
>>>> +       if (of_property_read_bool(node, "phys") || pdata->has_phy) {
>>>> +               dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>>>> +               if (IS_ERR(dwc->usb2_generic_phy)) {
>>>> +                       dev_err(dev, "no usb2 phy configured yet");
>>>> +                       return PTR_ERR(dwc->usb2_generic_phy);
>>>> +               }
>>>
>>> I have a doubt here.
>>> As i can see in the current phy drivers structuring, for OMAP there
>>> are two phy drivers :
>>> omap phy-omap-usb2 (talking to musb controller)
>>
>> It talks to dwc3 controller also ;-)
> 
> Ok
> 
>>
>>> and phy-omap-usb3(talking to dwc3 controller).
>>>
>>> Now dwc3 controller requests both usb2-phy (supported by phy-omap-usb2
>>> ?) and usb3-phy (supported by phy-omap-usb3 ?).
>>> But phy-omap-usb2 is not the one designated to talk to DWC3
>>> controller, then why does still DWC3 want to request usb2-phy, which
>>> end of the day will be phy-omap-usb2.
>>> May be i am wrong here since i don't have knowledge about OMAP h/w architecture.
>>>
>>> Is it like phy-omap-usb2 includes UTMI phys for both musb controller
>>> as well as dwc3 controller ?
>>
>> right. It's needed for dwc3 too. The same USB2 PHY IP is used for both MUSB in
>> OMAP2+ platforms and DWC3 in OMAP5.
> 
> Ok, but on Samsung's exynos5 series of SoCs, the USB2.0 controller has
> a separate USB-PHY interface talking to phy-samsung-usb2 driver;
> and DWC3 drd controller has separate USB-PHY interface (including both
> UTMI+ and PIPE3 control registers) talking to phy-samsung-usb3 driver.
> So in this case DWC3 doesn't need phy-samsung-usb2 at all. It's phy is
> configured by just phy-samsung-usb3 driver only.
> So don't you think DWC3 driver should have the flexibility to have
> either (mostly usb3-phy) _or_ both "usb2-phy" and "usb3-phy".
> Thereby,in case of Samsung driver, DWC3 will just have "usb3-phy" and
> that will be enough to get things working.
> Want your opinions about it.

Should we have separate properties to indicate whether it has a usb2-phy or
usb3-phy instead of checking for *phys* property?

Thanks
Kishon

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

* Re: [PATCH 3/7] drivers: phy: usb3/pipe3: Adapt pipe3 driver to Generic PHY Framework
  2013-09-16  7:37       ` Roger Quadros
@ 2013-10-11 15:02         ` Roger Quadros
  2013-10-14  9:19           ` Kishon Vijay Abraham I
  0 siblings, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-10-11 15:02 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

On 09/16/2013 10:37 AM, Roger Quadros wrote:
> On 09/16/2013 06:01 AM, Kishon Vijay Abraham I wrote:
>> On Thursday 12 September 2013 04:49 PM, Roger Quadros wrote:
>>> Hi Kishon,
>>>
>>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>>>> Adapted omap-usb3 PHY driver to Generic PHY Framework and moved phy-omap-usb3
>>>> driver in drivers/usb/phy to drivers/phy and also renamed the file to
>>>> phy-omap-pipe3 since this same driver will be used for SATA PHY and
>>>> PCIE PHY.
>>>
>>> I would suggest to split the renaming and PHY adaptation into 2 separate patches.
>>
>> Alright.
>>>
>>>>
>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>> ---
>>>>   Documentation/devicetree/bindings/usb/usb-phy.txt  |    5 +-
>>>>   drivers/phy/Kconfig                                |   10 +
>>>>   drivers/phy/Makefile                               |    1 +
>>>>   .../phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c}   |  206 +++++++++++---------
>>>
>>> how about naming it to phy-ti-pipe3.c as it is used on OMAP as well as non-OMAP e.g. DRA7.
>>
>> hmm.. I thought it would be consistent with other PHY drivers (phy-omap-usb2). Moreover DRA7 is OMAP based platform ;-) Maybe we should reserve that for later?
> 
> OK. Up to you.
> 
>>>
>>>>   drivers/usb/phy/Kconfig                            |   11 --
>>>>   drivers/usb/phy/Makefile                           |    1 -
>>>>   include/linux/phy/omap_pipe3.h                     |   52 +++++
>>>>   7 files changed, 177 insertions(+), 109 deletions(-)
>>>>   rename drivers/{usb/phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c} (57%)
>>>>   create mode 100644 include/linux/phy/omap_pipe3.h
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt
>>>> index c0245c8..36bdb17 100644
>>>> --- a/Documentation/devicetree/bindings/usb/usb-phy.txt
>>>> +++ b/Documentation/devicetree/bindings/usb/usb-phy.txt
>>>> @@ -21,10 +21,11 @@ usb2phy@4a0ad080 {
>>>>       #phy-cells = <0>;
>>>>   };
>>>>
>>>> -OMAP USB3 PHY
>>>> +OMAP PIPE3 PHY
>>>>
>>>>   Required properties:
>>>> - - compatible: Should be "ti,omap-usb3"
>>>> + - compatible: Should be "ti,omap-usb3", "ti,omap-pipe3", "ti,omap-sata"
>>>> +   or "ti,omap-pcie"
>>>>    - reg : Address and length of the register set for the device.
>>>>    - reg-names: The names of the register addresses corresponding to the registers
>>>>      filled in "reg".
>>>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>>>> index ac239ac..5c2e7a0 100644
>>>> --- a/drivers/phy/Kconfig
>>>> +++ b/drivers/phy/Kconfig
>>>> @@ -27,6 +27,16 @@ config OMAP_USB2
>>>>         The USB OTG controller communicates with the comparator using this
>>>>         driver.
>>>>
>>>> +config OMAP_PIPE3
>>>> +    tristate "OMAP PIPE3 PHY Driver"
>>>> +    select GENERIC_PHY
>>>> +    select OMAP_CONTROL_USB
>>> how about
>>>     depends on OMAP_CONTROL_USB
>>
>> From whatever I could make out from comments of Greg in my Generic PHY Framework, it's better to do a select of dependent modules instead of depends on.
> 
> You can use select, provided the item you are selecting doesn't depend on anything else.
> As OMAP_CONTROL_USB depends on ARCH_OMAP2PLUS, your configuration will fail if a user enables
> OMAP_PIPE3 on non OMAP configuration.
> 
> Further, in this case since it is OMAP related driver, there is no point in showing/building it
> if OMAP platform is not selected, so you at least need [depends on "ARCH_OMAP2PLUS"] to fix
> both issue I mentioned.
> 
>>>
>>> Also, if this is TI/OMAP it might as well depend on ARCH_OMAP.
>>>
>>>> +    help
>>>> +      Enable this to support the PIPE3 PHY that is part of SOC. This
>>>
>>> worth mentioning TI OMAP/DRA SoCs.
>>
>> right.
>>>
>>>> +      driver takes care of all the PHY functionality apart from comparator.
>>>> +      This driver interacts with the "OMAP Control PHY Driver" to power
>>>> +      on/off the PHY.
>>>> +
>>>>   config TWL4030_USB
>>>>       tristate "TWL4030 USB Transceiver Driver"
>>>>       depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
>>>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>>>> index 0dd8a98..48bf9f2 100644
>>>> --- a/drivers/phy/Makefile
>>>> +++ b/drivers/phy/Makefile
>>>> @@ -4,4 +4,5 @@
>>>>
>>>>   obj-$(CONFIG_GENERIC_PHY)    += phy-core.o
>>>>   obj-$(CONFIG_OMAP_USB2)        += phy-omap-usb2.o
>>>> +obj-$(CONFIG_OMAP_PIPE3)    += phy-omap-pipe3.o
>>>>   obj-$(CONFIG_TWL4030_USB)    += phy-twl4030-usb.o
>>>> diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/phy/phy-omap-pipe3.c
>>>> similarity index 57%
>>>> rename from drivers/usb/phy/phy-omap-usb3.c
>>>> rename to drivers/phy/phy-omap-pipe3.c
>>>> index 4004f82..ee9a901 100644
>>>> --- a/drivers/usb/phy/phy-omap-usb3.c
>>>> +++ b/drivers/phy/phy-omap-pipe3.c
>>>> @@ -1,5 +1,5 @@
>>>>   /*
>>>> - * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP.
>>>> + * omap-pipe3 - PHY driver for SATA, USB and PCIE in OMAP platforms
>>>>    *
>>>>    * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
>>>>    * This program is free software; you can redistribute it and/or modify
>>>> @@ -19,7 +19,8 @@
>>>>   #include <linux/module.h>
>>>>   #include <linux/platform_device.h>
>>>>   #include <linux/slab.h>
>>>> -#include <linux/usb/omap_usb.h>
>>>> +#include <linux/phy/omap_pipe3.h>
>>>> +#include <linux/phy/phy.h>
>>>>   #include <linux/of.h>
>>>>   #include <linux/clk.h>
>>>>   #include <linux/err.h>
>>>> @@ -52,17 +53,17 @@
>>>>
>>>>   /*
>>>>    * This is an Empirical value that works, need to confirm the actual
>>>> - * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status
>>>> - * to be correctly reflected in the USB3PHY_PLL_STATUS register.
>>>> + * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status
>>>> + * to be correctly reflected in the PIPE3PHY_PLL_STATUS register.
>>>>    */
>>>>   # define PLL_IDLE_TIME  100;
>>>>
>>>> -struct usb_dpll_map {
>>>> +struct pipe3_dpll_map {
>>>>       unsigned long rate;
>>>> -    struct usb_dpll_params params;
>>>> +    struct pipe3_dpll_params params;
>>>>   };
>>>>
>>>> -static struct usb_dpll_map dpll_map[] = {
>>>> +static struct pipe3_dpll_map dpll_map[] = {
>>>>       {12000000, {1250, 5, 4, 20, 0} },    /* 12 MHz */
>>>>       {16800000, {3125, 20, 4, 20, 0} },    /* 16.8 MHz */
>>>>       {19200000, {1172, 8, 4, 20, 65537} },    /* 19.2 MHz */
>>>> @@ -71,7 +72,7 @@ static struct usb_dpll_map dpll_map[] = {
>>>>       {38400000, {3125, 47, 4, 20, 92843} },    /* 38.4 MHz */
>>>>   };
>>>>
>>>> -static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
>>>> +static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(unsigned long rate)
>>>>   {
>>>>       int i;
>>>>
>>>> @@ -83,110 +84,113 @@ static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
>>>>       return 0;
>>>>   }
>>>>
>>>> -static int omap_usb3_suspend(struct usb_phy *x, int suspend)
>>>> +static int omap_pipe3_power_off(struct phy *x)
>>>>   {
>>>> -    struct omap_usb *phy = phy_to_omapusb(x);
>>>> -    int    val;
>>>> +    struct omap_pipe3 *phy = phy_get_drvdata(x);
>>>> +    int val;
>>>>       int timeout = PLL_IDLE_TIME;
>>>>
>>>> -    if (suspend && !phy->is_suspended) {
>>>> -        val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>> -        val |= PLL_IDLE;
>>>> -        omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>> -
>>>> -        do {
>>>> -            val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>> -            if (val & PLL_TICOPWDN)
>>>> -                break;
>>>> -            udelay(1);
>>>> -        } while (--timeout);
>>>> -
>>>> -        omap_control_usb_phy_power(phy->control_dev, 0);
>>>> -
>>>> -        phy->is_suspended    = 1;
>>>> -    } else if (!suspend && phy->is_suspended) {
>>>> -        phy->is_suspended    = 0;
>>>> -
>>>> -        val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>> -        val &= ~PLL_IDLE;
>>>> -        omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>> -
>>>> -        do {
>>>> -            val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>> -            if (!(val & PLL_TICOPWDN))
>>>> -                break;
>>>> -            udelay(1);
>>>> -        } while (--timeout);
>>>> -    }
>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>> +    val |= PLL_IDLE;
>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>> +
>>>> +    do {
>>>> +        val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>> +        if (val & PLL_TICOPWDN)
>>>> +            break;
>>>> +        udelay(1);
>>>
>>> Is it better to sleep instead of udelay?
>>
>> hmm.. yeah, I guess this function wont be called from interrupt context.
>>>
>>>> +    } while (--timeout);
>>>> +
>>>> +    omap_control_usb_phy_power(phy->control_dev, 0);
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>> +static int omap_pipe3_power_on(struct phy *x)
>>>> +{
>>>> +    struct omap_pipe3 *phy = phy_get_drvdata(x);
>>>> +    int val;
>>>> +    int timeout = PLL_IDLE_TIME;
>>>> +
>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>> +    val &= ~PLL_IDLE;
>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>> +
>>>> +    do {
>>>> +        val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>> +        if (!(val & PLL_TICOPWDN))
>>>> +            break;
>>>> +        udelay(1);
>>>
>>> here too.
>>
>> Ok.
>>>
>>>> +    } while (--timeout);
>>>>
>>>>       return 0;
>>>>   }
>>>>
>>>> -static void omap_usb_dpll_relock(struct omap_usb *phy)
>>>> +static void omap_pipe3_dpll_relock(struct omap_pipe3 *phy)
>>>>   {
>>>>       u32        val;
>>>>       unsigned long    timeout;
>>>>
>>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
>>>>
>>>>       timeout = jiffies + msecs_to_jiffies(20);
>>>>       do {
>>>> -        val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>> +        val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>>           if (val & PLL_LOCK)
>>>>               break;
>>>>       } while (!WARN_ON(time_after(jiffies, timeout)));
>>>>   }
>>>>
>>>> -static int omap_usb_dpll_lock(struct omap_usb *phy)
>>>> +static int omap_pipe3_dpll_lock(struct omap_pipe3 *phy)
>>>>   {
>>>>       u32            val;
>>>>       unsigned long        rate;
>>>> -    struct usb_dpll_params *dpll_params;
>>>> +    struct pipe3_dpll_params *dpll_params;
>>>>
>>>>       rate = clk_get_rate(phy->sys_clk);
>>>> -    dpll_params = omap_usb3_get_dpll_params(rate);
>>>> +    dpll_params = omap_pipe3_get_dpll_params(rate);
>>>>       if (!dpll_params) {
>>>>           dev_err(phy->dev,
>>>>                 "No DPLL configuration for %lu Hz SYS CLK\n", rate);
>>>>           return -EINVAL;
>>>>       }
>>>>
>>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>>>       val &= ~PLL_REGN_MASK;
>>>>       val |= dpll_params->n << PLL_REGN_SHIFT;
>>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>>>
>>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>>       val &= ~PLL_SELFREQDCO_MASK;
>>>>       val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
>>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>>
>>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>>>       val &= ~PLL_REGM_MASK;
>>>>       val |= dpll_params->m << PLL_REGM_SHIFT;
>>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>>>
>>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
>>>>       val &= ~PLL_REGM_F_MASK;
>>>>       val |= dpll_params->mf << PLL_REGM_F_SHIFT;
>>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
>>>>
>>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
>>>>       val &= ~PLL_SD_MASK;
>>>>       val |= dpll_params->sd << PLL_SD_SHIFT;
>>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
>>>>
>>>> -    omap_usb_dpll_relock(phy);
>>>> +    omap_pipe3_dpll_relock(phy);
>>>>
>>>>       return 0;
>>>>   }
>>>>
>>>> -static int omap_usb3_init(struct usb_phy *x)
>>>> +static int omap_pipe3_init(struct phy *x)
>>>>   {
>>>> -    struct omap_usb    *phy = phy_to_omapusb(x);
>>>> +    struct omap_pipe3 *phy = phy_get_drvdata(x);
>>>>       int ret;
>>>>
>>>> -    ret = omap_usb_dpll_lock(phy);
>>>> +    ret = omap_pipe3_dpll_lock(phy);
>>>>       if (ret)
>>>>           return ret;
>>>>
>>>> @@ -195,9 +199,18 @@ static int omap_usb3_init(struct usb_phy *x)
>>>>       return 0;
>>>>   }
>>>>
>>>> -static int omap_usb3_probe(struct platform_device *pdev)
>>>> +static struct phy_ops ops = {
>>>> +    .init        = omap_pipe3_init,
>>>> +    .power_on    = omap_pipe3_power_on,
>>>> +    .power_off    = omap_pipe3_power_off,
>>>> +    .owner        = THIS_MODULE,
>>>> +};
>>>> +
>>>> +static int omap_pipe3_probe(struct platform_device *pdev)
>>>>   {
>>>> -    struct omap_usb *phy;
>>>> +    struct omap_pipe3 *phy;
>>>> +    struct phy *generic_phy;
>>>> +    struct phy_provider *phy_provider;
>>>>       struct resource *res;
>>>>       struct device_node *node = pdev->dev.of_node;
>>>>       struct device_node *control_node;
>>>> @@ -208,7 +221,7 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>>>
>>>>       phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
>>>>       if (!phy) {
>>>> -        dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n");
>>>> +        dev_err(&pdev->dev, "unable to alloc mem for OMAP PIPE3 PHY\n");
>>>>           return -ENOMEM;
>>>>       }
>>>>
>>>> @@ -219,13 +232,6 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>>>
>>>>       phy->dev        = &pdev->dev;
>>>>
>>>> -    phy->phy.dev        = phy->dev;
>>>> -    phy->phy.label        = "omap-usb3";
>>>> -    phy->phy.init        = omap_usb3_init;
>>>> -    phy->phy.set_suspend    = omap_usb3_suspend;
>>>> -    phy->phy.type        = USB_PHY_TYPE_USB3;
>>>> -
>>>> -    phy->is_suspended    = 1;
>>>>       phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
>>>
>>> As this is no longer USB specific, we need to make the clock binding generic as well.
>>
>> right. Its also needed when we have the same driver work for sata and pcie. Maybe do that in a separate patch?
> 
> OK. up to you.
>>>
>>>>       if (IS_ERR(phy->wkupclk)) {
>>>>           dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
>>>> @@ -251,6 +257,11 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>>>           dev_err(&pdev->dev, "Failed to get control device phandle\n");
>>>>           return -EINVAL;
>>>>       }
>>>> +    phy_provider = devm_of_phy_provider_register(phy->dev,
>>>> +            of_phy_simple_xlate);
>>>> +    if (IS_ERR(phy_provider))
>>>> +        return PTR_ERR(phy_provider);
>>>> +
>>>>       control_pdev = of_find_device_by_node(control_node);
>>>>       if (!control_pdev) {
>>>>           dev_err(&pdev->dev, "Failed to get control device\n");
>>>> @@ -260,23 +271,27 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>>>       phy->control_dev = &control_pdev->dev;
>>>>
>>>>       omap_control_usb_phy_power(phy->control_dev, 0);
>>>> -    usb_add_phy_dev(&phy->phy);
>>>>
>>>>       platform_set_drvdata(pdev, phy);
>>>> -
>>>>       pm_runtime_enable(phy->dev);
>>>> +
>>>> +    generic_phy = devm_phy_create(phy->dev, &ops, NULL);
>>>> +    if (IS_ERR(generic_phy))
>>>> +        return PTR_ERR(generic_phy);
>>>> +
>>>> +    phy_set_drvdata(generic_phy, phy);
>>>> +
>>>>       pm_runtime_get(&pdev->dev);
>>>>
>>>>       return 0;
>>>>   }
>>>>
>>>> -static int omap_usb3_remove(struct platform_device *pdev)
>>>> +static int omap_pipe3_remove(struct platform_device *pdev)
>>>>   {
>>>> -    struct omap_usb *phy = platform_get_drvdata(pdev);
>>>> +    struct omap_pipe3 *phy = platform_get_drvdata(pdev);
>>>>
>>>>       clk_unprepare(phy->wkupclk);
>>>>       clk_unprepare(phy->optclk);
>>>> -    usb_remove_phy(&phy->phy);
>>>>       if (!pm_runtime_suspended(&pdev->dev))
>>>>           pm_runtime_put(&pdev->dev);
>>>>       pm_runtime_disable(&pdev->dev);
>>>> @@ -286,10 +301,9 @@ static int omap_usb3_remove(struct platform_device *pdev)
>>>>
>>>>   #ifdef CONFIG_PM_RUNTIME
>>>>
>>>> -static int omap_usb3_runtime_suspend(struct device *dev)
>>>> +static int omap_pipe3_runtime_suspend(struct device *dev)
>>>>   {
>>>> -    struct platform_device    *pdev = to_platform_device(dev);
>>>> -    struct omap_usb    *phy = platform_get_drvdata(pdev);
>>>> +    struct omap_pipe3    *phy = dev_get_drvdata(dev);
>>>>
>>>>       clk_disable(phy->wkupclk);
>>>>       clk_disable(phy->optclk);
>>>> @@ -297,11 +311,10 @@ static int omap_usb3_runtime_suspend(struct device *dev)
>>>>       return 0;
>>>>   }
>>>>
>>>> -static int omap_usb3_runtime_resume(struct device *dev)
>>>> +static int omap_pipe3_runtime_resume(struct device *dev)
>>>>   {
>>>>       u32 ret = 0;
>>>> -    struct platform_device    *pdev = to_platform_device(dev);
>>>> -    struct omap_usb    *phy = platform_get_drvdata(pdev);
>>>> +    struct omap_pipe3    *phy = dev_get_drvdata(dev);
>>>>
>>>>       ret = clk_enable(phy->optclk);
>>>>       if (ret) {
>>>> @@ -324,38 +337,41 @@ err1:
>>>>       return ret;
>>>>   }
>>>>
>>>> -static const struct dev_pm_ops omap_usb3_pm_ops = {
>>>> -    SET_RUNTIME_PM_OPS(omap_usb3_runtime_suspend, omap_usb3_runtime_resume,
>>>> -        NULL)
>>>> +static const struct dev_pm_ops omap_pipe3_pm_ops = {
>>>> +    SET_RUNTIME_PM_OPS(omap_pipe3_runtime_suspend,
>>>> +        omap_pipe3_runtime_resume, NULL)
>>>>   };
>>>>
>>>> -#define DEV_PM_OPS     (&omap_usb3_pm_ops)
>>>> +#define DEV_PM_OPS     (&omap_pipe3_pm_ops)
>>>>   #else
>>>>   #define DEV_PM_OPS     NULL
>>>>   #endif
>>>>
>>>>   #ifdef CONFIG_OF
>>>> -static const struct of_device_id omap_usb3_id_table[] = {
>>>> +static const struct of_device_id omap_pipe3_id_table[] = {
>>>> +    { .compatible = "ti,omap-pipe3" },
>>>
>>> why do you need "omap-pipe3", isn't sata, pcie and usb3 sufficient?
>>
>> I thought it would be better if everyone uses omap-pipe3 and added pcie, sata if there are any specific settings (for pcie or sata) that should be done.
> 
> We can always add specialized options later when needed. AFAIK just the
> DPLL data is different among the different PHYs.
>>>
>>>> +    { .compatible = "ti,omap-sata" },
>>>> +    { .compatible = "ti,omap-pcie" },
>>>>       { .compatible = "ti,omap-usb3" },
> 
> I think compatible strings should be improved to indicate that it is a PHY.
> 
> e.g. "ti,omap-phy-sata" or just "ti,pipe3-phy-sata"
> 

Please remove "ti,omap-pcie" for now, you can add it later whenever you add
dpll settings for pcie.

Also, please change the newly added compatible strings to

"ti,phy-pipe3-usb3" and "ti,phy-pipe3-sata"

Also you need to rearrange the patches so that the DT binding document is first
moded from usb/ to phy/ and then the change is done for pipe3.

cheers,
-roger

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-09-02 15:43 ` [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework Kishon Vijay Abraham I
  2013-09-12  9:27   ` Vivek Gautam
  2013-09-12 13:19   ` Roger Quadros
@ 2013-10-11 15:09   ` Roger Quadros
  2013-10-14  9:26     ` Kishon Vijay Abraham I
  2 siblings, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-10-11 15:09 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Hi,

On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
> power_on and power_off the following APIs are used phy_init(), phy_exit(),
> phy_power_on() and phy_power_off().
> 
> However using the old USB phy library wont be removed till the PHYs of all
> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>  drivers/usb/dwc3/Kconfig                       |    1 +
>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>  drivers/usb/dwc3/core.h                        |    7 ++++
>  4 files changed, 61 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
> index e807635..471366d 100644
> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
> @@ -6,11 +6,13 @@ Required properties:
>   - compatible: must be "snps,dwc3"
>   - reg : Address and length of the register set for the device
>   - interrupts: Interrupts used by the dwc3 controller.
> +
> +Optional properties:
>   - usb-phy : array of phandle for the PHY device.  The first element
>     in the array is expected to be a handle to the USB2/HS PHY and
>     the second element is expected to be a handle to the USB3/SS PHY
> -
> -Optional properties:
> + - phys: from the *Generic PHY* bindings
> + - phy-names: from the *Generic PHY* bindings
>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>  
>  This is usually a subnode to DWC3 glue to which it is connected.
> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> index cfc16dd..ad7ce83 100644
> --- a/drivers/usb/dwc3/Kconfig
> +++ b/drivers/usb/dwc3/Kconfig
> @@ -3,6 +3,7 @@ config USB_DWC3
>  	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>  	depends on EXTCON
>  	select USB_PHY
> +	select GENERIC_PHY
>  	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>  	help
>  	  Say Y or M here if your system has a Dual Role SuperSpeed
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 428c29e..485d365 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>  
>  	usb_phy_init(dwc->usb2_phy);
>  	usb_phy_init(dwc->usb3_phy);

How about adding
+	if (dwc->usb2_phy)
+		usb_phy_init(dwc->usb2_phy);
+	if (dwc->usb3_phy)
+		usb_phy_init(dwc->usb3_phy);

both usb phy and generic phy shouldn't be present together.

> +
> +	if (dwc->usb2_generic_phy)
> +		phy_init(dwc->usb2_generic_phy);
> +	if (dwc->usb3_generic_phy)
> +		phy_init(dwc->usb3_generic_phy);
> +
>  	mdelay(100);
>  
>  	/* Clear USB3 PHY reset */
> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>  {
>  	usb_phy_shutdown(dwc->usb2_phy);
>  	usb_phy_shutdown(dwc->usb3_phy);

here as well

> +
> +	if (dwc->usb2_generic_phy)
> +		phy_power_off(dwc->usb2_generic_phy);
> +	if (dwc->usb3_generic_phy)
> +		phy_power_off(dwc->usb3_generic_phy);
>  }
>  
>  #define DWC3_ALIGN_MASK		(16 - 1)
> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>  		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>  	}
>  
> +	if (of_property_read_bool(node, "phys") || pdata->has_phy) {
> +		dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
> +		if (IS_ERR(dwc->usb2_generic_phy)) {
> +			dev_err(dev, "no usb2 phy configured yet");
> +			return PTR_ERR(dwc->usb2_generic_phy);
> +		}
> +
> +		dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
> +		if (IS_ERR(dwc->usb3_generic_phy)) {
> +			dev_err(dev, "no usb3 phy configured yet");
> +			return PTR_ERR(dwc->usb3_generic_phy);
> +		}

better to add
+		/* Don't use USB PHY if generic PHY was found */
+		dwc->usb2_phy = dwc->usb3_phy = NULL;

> +	} else {

not required as we've used kzalloc for dwc.

> +		dwc->usb2_generic_phy = NULL;
> +		dwc->usb3_generic_phy = NULL;
> +	}
> +
>  	/* default to superspeed if no maximum_speed passed */
>  	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
>  		dwc->maximum_speed = USB_SPEED_SUPER;
> @@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)

if (dwc->usb2_phy)

>  	usb_phy_set_suspend(dwc->usb2_phy, 0);

if (dwc->usb3_phy)

>  	usb_phy_set_suspend(dwc->usb3_phy, 0);
>  
> +	if (dwc->usb2_generic_phy)
> +		phy_power_on(dwc->usb2_generic_phy);
> +	if (dwc->usb3_generic_phy)
> +		phy_power_on(dwc->usb3_generic_phy);
> +
>  	spin_lock_init(&dwc->lock);
>  	platform_set_drvdata(pdev, dwc);
>  
> @@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)

if (dwc->usb2_phy)
>  	usb_phy_set_suspend(dwc->usb2_phy, 1);

if (dwc->usb3_phy)
>  	usb_phy_set_suspend(dwc->usb3_phy, 1);
>  
> +	if (dwc->usb2_generic_phy)
> +		phy_power_off(dwc->usb2_generic_phy);
> +	if (dwc->usb3_generic_phy)
> +		phy_power_off(dwc->usb3_generic_phy);
> +
>  	pm_runtime_put(&pdev->dev);
>  	pm_runtime_disable(&pdev->dev);
>  
> @@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)

if (dwc->usb3_phy)
>  	usb_phy_shutdown(dwc->usb3_phy);

if (dwc->usb2_phy)
>  	usb_phy_shutdown(dwc->usb2_phy);
>  
> +	if (dwc->usb2_generic_phy)
> +		phy_exit(dwc->usb2_generic_phy);
> +	if (dwc->usb3_generic_phy)
> +		phy_exit(dwc->usb3_generic_phy);
> +
>  	return 0;
>  }
>  
> @@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
>  

if (dwc->usb3_phy)
>  	usb_phy_init(dwc->usb3_phy);

if (dwc->usb2_phy)
>  	usb_phy_init(dwc->usb2_phy);
> +
> +	if (dwc->usb2_generic_phy)
> +		phy_init(dwc->usb2_generic_phy);
> +	if (dwc->usb3_generic_phy)
> +		phy_init(dwc->usb3_generic_phy);
> +
>  	msleep(100);
>  
>  	spin_lock_irqsave(&dwc->lock, flags);
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index f8af8d4..01ec7d7 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -31,6 +31,8 @@
>  #include <linux/usb/gadget.h>
>  #include <linux/usb/otg.h>
>  
> +#include <linux/phy/phy.h>
> +
>  /* Global constants */
>  #define DWC3_EP0_BOUNCE_SIZE	512
>  #define DWC3_ENDPOINTS_NUM	32
> @@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
>   * @dr_mode: requested mode of operation
>   * @usb2_phy: pointer to USB2 PHY
>   * @usb3_phy: pointer to USB3 PHY
> + * @usb2_generic_phy: pointer to USB2 PHY
> + * @usb3_generic_phy: pointer to USB3 PHY
>   * @dcfg: saved contents of DCFG register
>   * @gctl: saved contents of GCTL register
>   * @is_selfpowered: true when we are selfpowered
> @@ -665,6 +669,9 @@ struct dwc3 {
>  	struct usb_phy		*usb2_phy;
>  	struct usb_phy		*usb3_phy;
>  
> +	struct phy		*usb2_generic_phy;
> +	struct phy		*usb3_generic_phy;
> +
>  	void __iomem		*regs;
>  	size_t			regs_size;
>  
> 

cheers,
-roger

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

* Re: [PATCH 3/7] drivers: phy: usb3/pipe3: Adapt pipe3 driver to Generic PHY Framework
  2013-10-11 15:02         ` Roger Quadros
@ 2013-10-14  9:19           ` Kishon Vijay Abraham I
  2013-10-14  9:31             ` Roger Quadros
  0 siblings, 1 reply; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-10-14  9:19 UTC (permalink / raw)
  To: Roger Quadros
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Hi Roger,

On Friday 11 October 2013 08:32 PM, Roger Quadros wrote:
> On 09/16/2013 10:37 AM, Roger Quadros wrote:
>> On 09/16/2013 06:01 AM, Kishon Vijay Abraham I wrote:
>>> On Thursday 12 September 2013 04:49 PM, Roger Quadros wrote:
>>>> Hi Kishon,
>>>>
>>>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>>>>> Adapted omap-usb3 PHY driver to Generic PHY Framework and moved phy-omap-usb3
>>>>> driver in drivers/usb/phy to drivers/phy and also renamed the file to
>>>>> phy-omap-pipe3 since this same driver will be used for SATA PHY and
>>>>> PCIE PHY.
>>>>
>>>> I would suggest to split the renaming and PHY adaptation into 2 separate patches.
>>>
>>> Alright.
>>>>
>>>>>
>>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>>> ---
>>>>>   Documentation/devicetree/bindings/usb/usb-phy.txt  |    5 +-
>>>>>   drivers/phy/Kconfig                                |   10 +
>>>>>   drivers/phy/Makefile                               |    1 +
>>>>>   .../phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c}   |  206 +++++++++++---------
>>>>
>>>> how about naming it to phy-ti-pipe3.c as it is used on OMAP as well as non-OMAP e.g. DRA7.
>>>
>>> hmm.. I thought it would be consistent with other PHY drivers (phy-omap-usb2). Moreover DRA7 is OMAP based platform ;-) Maybe we should reserve that for later?
>>
>> OK. Up to you.
>>
>>>>
>>>>>   drivers/usb/phy/Kconfig                            |   11 --
>>>>>   drivers/usb/phy/Makefile                           |    1 -
>>>>>   include/linux/phy/omap_pipe3.h                     |   52 +++++
>>>>>   7 files changed, 177 insertions(+), 109 deletions(-)
>>>>>   rename drivers/{usb/phy/phy-omap-usb3.c => phy/phy-omap-pipe3.c} (57%)
>>>>>   create mode 100644 include/linux/phy/omap_pipe3.h
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt
>>>>> index c0245c8..36bdb17 100644
>>>>> --- a/Documentation/devicetree/bindings/usb/usb-phy.txt
>>>>> +++ b/Documentation/devicetree/bindings/usb/usb-phy.txt
>>>>> @@ -21,10 +21,11 @@ usb2phy@4a0ad080 {
>>>>>       #phy-cells = <0>;
>>>>>   };
>>>>>
>>>>> -OMAP USB3 PHY
>>>>> +OMAP PIPE3 PHY
>>>>>
>>>>>   Required properties:
>>>>> - - compatible: Should be "ti,omap-usb3"
>>>>> + - compatible: Should be "ti,omap-usb3", "ti,omap-pipe3", "ti,omap-sata"
>>>>> +   or "ti,omap-pcie"
>>>>>    - reg : Address and length of the register set for the device.
>>>>>    - reg-names: The names of the register addresses corresponding to the registers
>>>>>      filled in "reg".
>>>>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>>>>> index ac239ac..5c2e7a0 100644
>>>>> --- a/drivers/phy/Kconfig
>>>>> +++ b/drivers/phy/Kconfig
>>>>> @@ -27,6 +27,16 @@ config OMAP_USB2
>>>>>         The USB OTG controller communicates with the comparator using this
>>>>>         driver.
>>>>>
>>>>> +config OMAP_PIPE3
>>>>> +    tristate "OMAP PIPE3 PHY Driver"
>>>>> +    select GENERIC_PHY
>>>>> +    select OMAP_CONTROL_USB
>>>> how about
>>>>     depends on OMAP_CONTROL_USB
>>>
>>> From whatever I could make out from comments of Greg in my Generic PHY Framework, it's better to do a select of dependent modules instead of depends on.
>>
>> You can use select, provided the item you are selecting doesn't depend on anything else.
>> As OMAP_CONTROL_USB depends on ARCH_OMAP2PLUS, your configuration will fail if a user enables
>> OMAP_PIPE3 on non OMAP configuration.
>>
>> Further, in this case since it is OMAP related driver, there is no point in showing/building it
>> if OMAP platform is not selected, so you at least need [depends on "ARCH_OMAP2PLUS"] to fix
>> both issue I mentioned.
>>
>>>>
>>>> Also, if this is TI/OMAP it might as well depend on ARCH_OMAP.
>>>>
>>>>> +    help
>>>>> +      Enable this to support the PIPE3 PHY that is part of SOC. This
>>>>
>>>> worth mentioning TI OMAP/DRA SoCs.
>>>
>>> right.
>>>>
>>>>> +      driver takes care of all the PHY functionality apart from comparator.
>>>>> +      This driver interacts with the "OMAP Control PHY Driver" to power
>>>>> +      on/off the PHY.
>>>>> +
>>>>>   config TWL4030_USB
>>>>>       tristate "TWL4030 USB Transceiver Driver"
>>>>>       depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
>>>>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>>>>> index 0dd8a98..48bf9f2 100644
>>>>> --- a/drivers/phy/Makefile
>>>>> +++ b/drivers/phy/Makefile
>>>>> @@ -4,4 +4,5 @@
>>>>>
>>>>>   obj-$(CONFIG_GENERIC_PHY)    += phy-core.o
>>>>>   obj-$(CONFIG_OMAP_USB2)        += phy-omap-usb2.o
>>>>> +obj-$(CONFIG_OMAP_PIPE3)    += phy-omap-pipe3.o
>>>>>   obj-$(CONFIG_TWL4030_USB)    += phy-twl4030-usb.o
>>>>> diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/phy/phy-omap-pipe3.c
>>>>> similarity index 57%
>>>>> rename from drivers/usb/phy/phy-omap-usb3.c
>>>>> rename to drivers/phy/phy-omap-pipe3.c
>>>>> index 4004f82..ee9a901 100644
>>>>> --- a/drivers/usb/phy/phy-omap-usb3.c
>>>>> +++ b/drivers/phy/phy-omap-pipe3.c
>>>>> @@ -1,5 +1,5 @@
>>>>>   /*
>>>>> - * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP.
>>>>> + * omap-pipe3 - PHY driver for SATA, USB and PCIE in OMAP platforms
>>>>>    *
>>>>>    * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
>>>>>    * This program is free software; you can redistribute it and/or modify
>>>>> @@ -19,7 +19,8 @@
>>>>>   #include <linux/module.h>
>>>>>   #include <linux/platform_device.h>
>>>>>   #include <linux/slab.h>
>>>>> -#include <linux/usb/omap_usb.h>
>>>>> +#include <linux/phy/omap_pipe3.h>
>>>>> +#include <linux/phy/phy.h>
>>>>>   #include <linux/of.h>
>>>>>   #include <linux/clk.h>
>>>>>   #include <linux/err.h>
>>>>> @@ -52,17 +53,17 @@
>>>>>
>>>>>   /*
>>>>>    * This is an Empirical value that works, need to confirm the actual
>>>>> - * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status
>>>>> - * to be correctly reflected in the USB3PHY_PLL_STATUS register.
>>>>> + * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status
>>>>> + * to be correctly reflected in the PIPE3PHY_PLL_STATUS register.
>>>>>    */
>>>>>   # define PLL_IDLE_TIME  100;
>>>>>
>>>>> -struct usb_dpll_map {
>>>>> +struct pipe3_dpll_map {
>>>>>       unsigned long rate;
>>>>> -    struct usb_dpll_params params;
>>>>> +    struct pipe3_dpll_params params;
>>>>>   };
>>>>>
>>>>> -static struct usb_dpll_map dpll_map[] = {
>>>>> +static struct pipe3_dpll_map dpll_map[] = {
>>>>>       {12000000, {1250, 5, 4, 20, 0} },    /* 12 MHz */
>>>>>       {16800000, {3125, 20, 4, 20, 0} },    /* 16.8 MHz */
>>>>>       {19200000, {1172, 8, 4, 20, 65537} },    /* 19.2 MHz */
>>>>> @@ -71,7 +72,7 @@ static struct usb_dpll_map dpll_map[] = {
>>>>>       {38400000, {3125, 47, 4, 20, 92843} },    /* 38.4 MHz */
>>>>>   };
>>>>>
>>>>> -static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
>>>>> +static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(unsigned long rate)
>>>>>   {
>>>>>       int i;
>>>>>
>>>>> @@ -83,110 +84,113 @@ static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
>>>>>       return 0;
>>>>>   }
>>>>>
>>>>> -static int omap_usb3_suspend(struct usb_phy *x, int suspend)
>>>>> +static int omap_pipe3_power_off(struct phy *x)
>>>>>   {
>>>>> -    struct omap_usb *phy = phy_to_omapusb(x);
>>>>> -    int    val;
>>>>> +    struct omap_pipe3 *phy = phy_get_drvdata(x);
>>>>> +    int val;
>>>>>       int timeout = PLL_IDLE_TIME;
>>>>>
>>>>> -    if (suspend && !phy->is_suspended) {
>>>>> -        val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>>> -        val |= PLL_IDLE;
>>>>> -        omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>>> -
>>>>> -        do {
>>>>> -            val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>>> -            if (val & PLL_TICOPWDN)
>>>>> -                break;
>>>>> -            udelay(1);
>>>>> -        } while (--timeout);
>>>>> -
>>>>> -        omap_control_usb_phy_power(phy->control_dev, 0);
>>>>> -
>>>>> -        phy->is_suspended    = 1;
>>>>> -    } else if (!suspend && phy->is_suspended) {
>>>>> -        phy->is_suspended    = 0;
>>>>> -
>>>>> -        val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>>> -        val &= ~PLL_IDLE;
>>>>> -        omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>>> -
>>>>> -        do {
>>>>> -            val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>>> -            if (!(val & PLL_TICOPWDN))
>>>>> -                break;
>>>>> -            udelay(1);
>>>>> -        } while (--timeout);
>>>>> -    }
>>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>>> +    val |= PLL_IDLE;
>>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>>> +
>>>>> +    do {
>>>>> +        val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>>> +        if (val & PLL_TICOPWDN)
>>>>> +            break;
>>>>> +        udelay(1);
>>>>
>>>> Is it better to sleep instead of udelay?
>>>
>>> hmm.. yeah, I guess this function wont be called from interrupt context.
>>>>
>>>>> +    } while (--timeout);
>>>>> +
>>>>> +    omap_control_usb_phy_power(phy->control_dev, 0);
>>>>> +
>>>>> +    return 0;
>>>>> +}
>>>>> +
>>>>> +static int omap_pipe3_power_on(struct phy *x)
>>>>> +{
>>>>> +    struct omap_pipe3 *phy = phy_get_drvdata(x);
>>>>> +    int val;
>>>>> +    int timeout = PLL_IDLE_TIME;
>>>>> +
>>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>>> +    val &= ~PLL_IDLE;
>>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>>> +
>>>>> +    do {
>>>>> +        val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>>> +        if (!(val & PLL_TICOPWDN))
>>>>> +            break;
>>>>> +        udelay(1);
>>>>
>>>> here too.
>>>
>>> Ok.
>>>>
>>>>> +    } while (--timeout);
>>>>>
>>>>>       return 0;
>>>>>   }
>>>>>
>>>>> -static void omap_usb_dpll_relock(struct omap_usb *phy)
>>>>> +static void omap_pipe3_dpll_relock(struct omap_pipe3 *phy)
>>>>>   {
>>>>>       u32        val;
>>>>>       unsigned long    timeout;
>>>>>
>>>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
>>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
>>>>>
>>>>>       timeout = jiffies + msecs_to_jiffies(20);
>>>>>       do {
>>>>> -        val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>>> +        val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
>>>>>           if (val & PLL_LOCK)
>>>>>               break;
>>>>>       } while (!WARN_ON(time_after(jiffies, timeout)));
>>>>>   }
>>>>>
>>>>> -static int omap_usb_dpll_lock(struct omap_usb *phy)
>>>>> +static int omap_pipe3_dpll_lock(struct omap_pipe3 *phy)
>>>>>   {
>>>>>       u32            val;
>>>>>       unsigned long        rate;
>>>>> -    struct usb_dpll_params *dpll_params;
>>>>> +    struct pipe3_dpll_params *dpll_params;
>>>>>
>>>>>       rate = clk_get_rate(phy->sys_clk);
>>>>> -    dpll_params = omap_usb3_get_dpll_params(rate);
>>>>> +    dpll_params = omap_pipe3_get_dpll_params(rate);
>>>>>       if (!dpll_params) {
>>>>>           dev_err(phy->dev,
>>>>>                 "No DPLL configuration for %lu Hz SYS CLK\n", rate);
>>>>>           return -EINVAL;
>>>>>       }
>>>>>
>>>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>>>>       val &= ~PLL_REGN_MASK;
>>>>>       val |= dpll_params->n << PLL_REGN_SHIFT;
>>>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>>>>
>>>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
>>>>>       val &= ~PLL_SELFREQDCO_MASK;
>>>>>       val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
>>>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
>>>>>
>>>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
>>>>>       val &= ~PLL_REGM_MASK;
>>>>>       val |= dpll_params->m << PLL_REGM_SHIFT;
>>>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
>>>>>
>>>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
>>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
>>>>>       val &= ~PLL_REGM_F_MASK;
>>>>>       val |= dpll_params->mf << PLL_REGM_F_SHIFT;
>>>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
>>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
>>>>>
>>>>> -    val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
>>>>> +    val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
>>>>>       val &= ~PLL_SD_MASK;
>>>>>       val |= dpll_params->sd << PLL_SD_SHIFT;
>>>>> -    omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
>>>>> +    omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
>>>>>
>>>>> -    omap_usb_dpll_relock(phy);
>>>>> +    omap_pipe3_dpll_relock(phy);
>>>>>
>>>>>       return 0;
>>>>>   }
>>>>>
>>>>> -static int omap_usb3_init(struct usb_phy *x)
>>>>> +static int omap_pipe3_init(struct phy *x)
>>>>>   {
>>>>> -    struct omap_usb    *phy = phy_to_omapusb(x);
>>>>> +    struct omap_pipe3 *phy = phy_get_drvdata(x);
>>>>>       int ret;
>>>>>
>>>>> -    ret = omap_usb_dpll_lock(phy);
>>>>> +    ret = omap_pipe3_dpll_lock(phy);
>>>>>       if (ret)
>>>>>           return ret;
>>>>>
>>>>> @@ -195,9 +199,18 @@ static int omap_usb3_init(struct usb_phy *x)
>>>>>       return 0;
>>>>>   }
>>>>>
>>>>> -static int omap_usb3_probe(struct platform_device *pdev)
>>>>> +static struct phy_ops ops = {
>>>>> +    .init        = omap_pipe3_init,
>>>>> +    .power_on    = omap_pipe3_power_on,
>>>>> +    .power_off    = omap_pipe3_power_off,
>>>>> +    .owner        = THIS_MODULE,
>>>>> +};
>>>>> +
>>>>> +static int omap_pipe3_probe(struct platform_device *pdev)
>>>>>   {
>>>>> -    struct omap_usb *phy;
>>>>> +    struct omap_pipe3 *phy;
>>>>> +    struct phy *generic_phy;
>>>>> +    struct phy_provider *phy_provider;
>>>>>       struct resource *res;
>>>>>       struct device_node *node = pdev->dev.of_node;
>>>>>       struct device_node *control_node;
>>>>> @@ -208,7 +221,7 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>>>>
>>>>>       phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
>>>>>       if (!phy) {
>>>>> -        dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n");
>>>>> +        dev_err(&pdev->dev, "unable to alloc mem for OMAP PIPE3 PHY\n");
>>>>>           return -ENOMEM;
>>>>>       }
>>>>>
>>>>> @@ -219,13 +232,6 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>>>>
>>>>>       phy->dev        = &pdev->dev;
>>>>>
>>>>> -    phy->phy.dev        = phy->dev;
>>>>> -    phy->phy.label        = "omap-usb3";
>>>>> -    phy->phy.init        = omap_usb3_init;
>>>>> -    phy->phy.set_suspend    = omap_usb3_suspend;
>>>>> -    phy->phy.type        = USB_PHY_TYPE_USB3;
>>>>> -
>>>>> -    phy->is_suspended    = 1;
>>>>>       phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
>>>>
>>>> As this is no longer USB specific, we need to make the clock binding generic as well.
>>>
>>> right. Its also needed when we have the same driver work for sata and pcie. Maybe do that in a separate patch?
>>
>> OK. up to you.
>>>>
>>>>>       if (IS_ERR(phy->wkupclk)) {
>>>>>           dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
>>>>> @@ -251,6 +257,11 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>>>>           dev_err(&pdev->dev, "Failed to get control device phandle\n");
>>>>>           return -EINVAL;
>>>>>       }
>>>>> +    phy_provider = devm_of_phy_provider_register(phy->dev,
>>>>> +            of_phy_simple_xlate);
>>>>> +    if (IS_ERR(phy_provider))
>>>>> +        return PTR_ERR(phy_provider);
>>>>> +
>>>>>       control_pdev = of_find_device_by_node(control_node);
>>>>>       if (!control_pdev) {
>>>>>           dev_err(&pdev->dev, "Failed to get control device\n");
>>>>> @@ -260,23 +271,27 @@ static int omap_usb3_probe(struct platform_device *pdev)
>>>>>       phy->control_dev = &control_pdev->dev;
>>>>>
>>>>>       omap_control_usb_phy_power(phy->control_dev, 0);
>>>>> -    usb_add_phy_dev(&phy->phy);
>>>>>
>>>>>       platform_set_drvdata(pdev, phy);
>>>>> -
>>>>>       pm_runtime_enable(phy->dev);
>>>>> +
>>>>> +    generic_phy = devm_phy_create(phy->dev, &ops, NULL);
>>>>> +    if (IS_ERR(generic_phy))
>>>>> +        return PTR_ERR(generic_phy);
>>>>> +
>>>>> +    phy_set_drvdata(generic_phy, phy);
>>>>> +
>>>>>       pm_runtime_get(&pdev->dev);
>>>>>
>>>>>       return 0;
>>>>>   }
>>>>>
>>>>> -static int omap_usb3_remove(struct platform_device *pdev)
>>>>> +static int omap_pipe3_remove(struct platform_device *pdev)
>>>>>   {
>>>>> -    struct omap_usb *phy = platform_get_drvdata(pdev);
>>>>> +    struct omap_pipe3 *phy = platform_get_drvdata(pdev);
>>>>>
>>>>>       clk_unprepare(phy->wkupclk);
>>>>>       clk_unprepare(phy->optclk);
>>>>> -    usb_remove_phy(&phy->phy);
>>>>>       if (!pm_runtime_suspended(&pdev->dev))
>>>>>           pm_runtime_put(&pdev->dev);
>>>>>       pm_runtime_disable(&pdev->dev);
>>>>> @@ -286,10 +301,9 @@ static int omap_usb3_remove(struct platform_device *pdev)
>>>>>
>>>>>   #ifdef CONFIG_PM_RUNTIME
>>>>>
>>>>> -static int omap_usb3_runtime_suspend(struct device *dev)
>>>>> +static int omap_pipe3_runtime_suspend(struct device *dev)
>>>>>   {
>>>>> -    struct platform_device    *pdev = to_platform_device(dev);
>>>>> -    struct omap_usb    *phy = platform_get_drvdata(pdev);
>>>>> +    struct omap_pipe3    *phy = dev_get_drvdata(dev);
>>>>>
>>>>>       clk_disable(phy->wkupclk);
>>>>>       clk_disable(phy->optclk);
>>>>> @@ -297,11 +311,10 @@ static int omap_usb3_runtime_suspend(struct device *dev)
>>>>>       return 0;
>>>>>   }
>>>>>
>>>>> -static int omap_usb3_runtime_resume(struct device *dev)
>>>>> +static int omap_pipe3_runtime_resume(struct device *dev)
>>>>>   {
>>>>>       u32 ret = 0;
>>>>> -    struct platform_device    *pdev = to_platform_device(dev);
>>>>> -    struct omap_usb    *phy = platform_get_drvdata(pdev);
>>>>> +    struct omap_pipe3    *phy = dev_get_drvdata(dev);
>>>>>
>>>>>       ret = clk_enable(phy->optclk);
>>>>>       if (ret) {
>>>>> @@ -324,38 +337,41 @@ err1:
>>>>>       return ret;
>>>>>   }
>>>>>
>>>>> -static const struct dev_pm_ops omap_usb3_pm_ops = {
>>>>> -    SET_RUNTIME_PM_OPS(omap_usb3_runtime_suspend, omap_usb3_runtime_resume,
>>>>> -        NULL)
>>>>> +static const struct dev_pm_ops omap_pipe3_pm_ops = {
>>>>> +    SET_RUNTIME_PM_OPS(omap_pipe3_runtime_suspend,
>>>>> +        omap_pipe3_runtime_resume, NULL)
>>>>>   };
>>>>>
>>>>> -#define DEV_PM_OPS     (&omap_usb3_pm_ops)
>>>>> +#define DEV_PM_OPS     (&omap_pipe3_pm_ops)
>>>>>   #else
>>>>>   #define DEV_PM_OPS     NULL
>>>>>   #endif
>>>>>
>>>>>   #ifdef CONFIG_OF
>>>>> -static const struct of_device_id omap_usb3_id_table[] = {
>>>>> +static const struct of_device_id omap_pipe3_id_table[] = {
>>>>> +    { .compatible = "ti,omap-pipe3" },
>>>>
>>>> why do you need "omap-pipe3", isn't sata, pcie and usb3 sufficient?
>>>
>>> I thought it would be better if everyone uses omap-pipe3 and added pcie, sata if there are any specific settings (for pcie or sata) that should be done.
>>
>> We can always add specialized options later when needed. AFAIK just the
>> DPLL data is different among the different PHYs.
>>>>
>>>>> +    { .compatible = "ti,omap-sata" },
>>>>> +    { .compatible = "ti,omap-pcie" },
>>>>>       { .compatible = "ti,omap-usb3" },
>>
>> I think compatible strings should be improved to indicate that it is a PHY.
>>
>> e.g. "ti,omap-phy-sata" or just "ti,pipe3-phy-sata"
>>
> 
> Please remove "ti,omap-pcie" for now, you can add it later whenever you add
> dpll settings for pcie.
> 
> Also, please change the newly added compatible strings to
> 
> "ti,phy-pipe3-usb3" and "ti,phy-pipe3-sata"

No, I think we should have omap in the compatible since this PHY is specific to
OMAP.
> 
> Also you need to rearrange the patches so that the DT binding document is first
> moded from usb/ to phy/ and then the change is done for pipe3.

Ok.

Thanks
Kishon

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-11 15:09   ` Roger Quadros
@ 2013-10-14  9:26     ` Kishon Vijay Abraham I
  2013-10-14 10:21       ` Roger Quadros
  0 siblings, 1 reply; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-10-14  9:26 UTC (permalink / raw)
  To: Roger Quadros
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Hi Roger,

On Friday 11 October 2013 08:39 PM, Roger Quadros wrote:
> Hi,
> 
> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>> phy_power_on() and phy_power_off().
>>
>> However using the old USB phy library wont be removed till the PHYs of all
>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>>  drivers/usb/dwc3/Kconfig                       |    1 +
>>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>>  drivers/usb/dwc3/core.h                        |    7 ++++
>>  4 files changed, 61 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>> index e807635..471366d 100644
>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>> @@ -6,11 +6,13 @@ Required properties:
>>   - compatible: must be "snps,dwc3"
>>   - reg : Address and length of the register set for the device
>>   - interrupts: Interrupts used by the dwc3 controller.
>> +
>> +Optional properties:
>>   - usb-phy : array of phandle for the PHY device.  The first element
>>     in the array is expected to be a handle to the USB2/HS PHY and
>>     the second element is expected to be a handle to the USB3/SS PHY
>> -
>> -Optional properties:
>> + - phys: from the *Generic PHY* bindings
>> + - phy-names: from the *Generic PHY* bindings
>>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>  
>>  This is usually a subnode to DWC3 glue to which it is connected.
>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>> index cfc16dd..ad7ce83 100644
>> --- a/drivers/usb/dwc3/Kconfig
>> +++ b/drivers/usb/dwc3/Kconfig
>> @@ -3,6 +3,7 @@ config USB_DWC3
>>  	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>  	depends on EXTCON
>>  	select USB_PHY
>> +	select GENERIC_PHY
>>  	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>  	help
>>  	  Say Y or M here if your system has a Dual Role SuperSpeed
>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>> index 428c29e..485d365 100644
>> --- a/drivers/usb/dwc3/core.c
>> +++ b/drivers/usb/dwc3/core.c
>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>  
>>  	usb_phy_init(dwc->usb2_phy);
>>  	usb_phy_init(dwc->usb3_phy);
> 
> How about adding
> +	if (dwc->usb2_phy)
> +		usb_phy_init(dwc->usb2_phy);
> +	if (dwc->usb3_phy)
> +		usb_phy_init(dwc->usb3_phy);

Thankfully that usb_phy_init will check if phy is NULL.
> 
> both usb phy and generic phy shouldn't be present together.

ok.
> 
>> +
>> +	if (dwc->usb2_generic_phy)
>> +		phy_init(dwc->usb2_generic_phy);
>> +	if (dwc->usb3_generic_phy)
>> +		phy_init(dwc->usb3_generic_phy);
>> +
>>  	mdelay(100);
>>  
>>  	/* Clear USB3 PHY reset */
>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>>  {
>>  	usb_phy_shutdown(dwc->usb2_phy);
>>  	usb_phy_shutdown(dwc->usb3_phy);
> 
> here as well
> 
>> +
>> +	if (dwc->usb2_generic_phy)
>> +		phy_power_off(dwc->usb2_generic_phy);
>> +	if (dwc->usb3_generic_phy)
>> +		phy_power_off(dwc->usb3_generic_phy);
>>  }
>>  
>>  #define DWC3_ALIGN_MASK		(16 - 1)
>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>>  		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>>  	}
>>  
>> +	if (of_property_read_bool(node, "phys") || pdata->has_phy) {
>> +		dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>> +		if (IS_ERR(dwc->usb2_generic_phy)) {
>> +			dev_err(dev, "no usb2 phy configured yet");
>> +			return PTR_ERR(dwc->usb2_generic_phy);
>> +		}
>> +
>> +		dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
>> +		if (IS_ERR(dwc->usb3_generic_phy)) {
>> +			dev_err(dev, "no usb3 phy configured yet");
>> +			return PTR_ERR(dwc->usb3_generic_phy);
>> +		}
> 
> better to add
> +		/* Don't use USB PHY if generic PHY was found */
> +		dwc->usb2_phy = dwc->usb3_phy = NULL;

ok.
> 
>> +	} else {
> 
> not required as we've used kzalloc for dwc.
> 
>> +		dwc->usb2_generic_phy = NULL;
>> +		dwc->usb3_generic_phy = NULL;
>> +	}
>> +
>>  	/* default to superspeed if no maximum_speed passed */
>>  	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
>>  		dwc->maximum_speed = USB_SPEED_SUPER;
>> @@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)
> 
> if (dwc->usb2_phy)
> 
>>  	usb_phy_set_suspend(dwc->usb2_phy, 0);
> 
> if (dwc->usb3_phy)
> 
>>  	usb_phy_set_suspend(dwc->usb3_phy, 0);
>>  
>> +	if (dwc->usb2_generic_phy)
>> +		phy_power_on(dwc->usb2_generic_phy);
>> +	if (dwc->usb3_generic_phy)
>> +		phy_power_on(dwc->usb3_generic_phy);
>> +
>>  	spin_lock_init(&dwc->lock);
>>  	platform_set_drvdata(pdev, dwc);
>>  
>> @@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)
> 
> if (dwc->usb2_phy)
>>  	usb_phy_set_suspend(dwc->usb2_phy, 1);
> 
> if (dwc->usb3_phy)
>>  	usb_phy_set_suspend(dwc->usb3_phy, 1);
>>  
>> +	if (dwc->usb2_generic_phy)
>> +		phy_power_off(dwc->usb2_generic_phy);
>> +	if (dwc->usb3_generic_phy)
>> +		phy_power_off(dwc->usb3_generic_phy);
>> +
>>  	pm_runtime_put(&pdev->dev);
>>  	pm_runtime_disable(&pdev->dev);
>>  
>> @@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)
> 
> if (dwc->usb3_phy)
>>  	usb_phy_shutdown(dwc->usb3_phy);
> 
> if (dwc->usb2_phy)
>>  	usb_phy_shutdown(dwc->usb2_phy);
>>  
>> +	if (dwc->usb2_generic_phy)
>> +		phy_exit(dwc->usb2_generic_phy);
>> +	if (dwc->usb3_generic_phy)
>> +		phy_exit(dwc->usb3_generic_phy);
>> +
>>  	return 0;
>>  }
>>  
>> @@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
>>  
> 
> if (dwc->usb3_phy)
>>  	usb_phy_init(dwc->usb3_phy);
> 
> if (dwc->usb2_phy)
>>  	usb_phy_init(dwc->usb2_phy);
>> +
>> +	if (dwc->usb2_generic_phy)
>> +		phy_init(dwc->usb2_generic_phy);
>> +	if (dwc->usb3_generic_phy)
>> +		phy_init(dwc->usb3_generic_phy);
>> +
>>  	msleep(100);
>>  
>>  	spin_lock_irqsave(&dwc->lock, flags);
>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>> index f8af8d4..01ec7d7 100644
>> --- a/drivers/usb/dwc3/core.h
>> +++ b/drivers/usb/dwc3/core.h
>> @@ -31,6 +31,8 @@
>>  #include <linux/usb/gadget.h>
>>  #include <linux/usb/otg.h>
>>  
>> +#include <linux/phy/phy.h>
>> +
>>  /* Global constants */
>>  #define DWC3_EP0_BOUNCE_SIZE	512
>>  #define DWC3_ENDPOINTS_NUM	32
>> @@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
>>   * @dr_mode: requested mode of operation
>>   * @usb2_phy: pointer to USB2 PHY
>>   * @usb3_phy: pointer to USB3 PHY
>> + * @usb2_generic_phy: pointer to USB2 PHY
>> + * @usb3_generic_phy: pointer to USB3 PHY
>>   * @dcfg: saved contents of DCFG register
>>   * @gctl: saved contents of GCTL register
>>   * @is_selfpowered: true when we are selfpowered
>> @@ -665,6 +669,9 @@ struct dwc3 {
>>  	struct usb_phy		*usb2_phy;
>>  	struct usb_phy		*usb3_phy;
>>  
>> +	struct phy		*usb2_generic_phy;
>> +	struct phy		*usb3_generic_phy;
>> +
>>  	void __iomem		*regs;
>>  	size_t			regs_size;
>>  
>>

Do you have any suggestions on how to get only individual PHYs? like only
usb2phy or usb3phy?

Thanks
Kishon

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

* Re: [PATCH 3/7] drivers: phy: usb3/pipe3: Adapt pipe3 driver to Generic PHY Framework
  2013-10-14  9:19           ` Kishon Vijay Abraham I
@ 2013-10-14  9:31             ` Roger Quadros
  0 siblings, 0 replies; 47+ messages in thread
From: Roger Quadros @ 2013-10-14  9:31 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: balbi, bcousson, tony, rob.herring, pawel.moll, mark.rutland,
	linux, grant.likely, s.nawrocki, galak, swarren, ian.campbell,
	rob, george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

Kishon,

On 10/14/2013 12:19 PM, Kishon Vijay Abraham I wrote:
> Hi Roger,
> 
> On Friday 11 October 2013 08:32 PM, Roger Quadros wrote:
>> On 09/16/2013 10:37 AM, Roger Quadros wrote:
>>> On 09/16/2013 06:01 AM, Kishon Vijay Abraham I wrote:
>>>> On Thursday 12 September 2013 04:49 PM, Roger Quadros wrote:
>>>>> Hi Kishon,
>>>>>
>>>>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:

>>>>>>   #ifdef CONFIG_OF
>>>>>> -static const struct of_device_id omap_usb3_id_table[] = {
>>>>>> +static const struct of_device_id omap_pipe3_id_table[] = {
>>>>>> +    { .compatible = "ti,omap-pipe3" },
>>>>>
>>>>> why do you need "omap-pipe3", isn't sata, pcie and usb3 sufficient?
>>>>
>>>> I thought it would be better if everyone uses omap-pipe3 and added pcie, sata if there are any specific settings (for pcie or sata) that should be done.
>>>
>>> We can always add specialized options later when needed. AFAIK just the
>>> DPLL data is different among the different PHYs.
>>>>>
>>>>>> +    { .compatible = "ti,omap-sata" },
>>>>>> +    { .compatible = "ti,omap-pcie" },
>>>>>>       { .compatible = "ti,omap-usb3" },
>>>
>>> I think compatible strings should be improved to indicate that it is a PHY.
>>>
>>> e.g. "ti,omap-phy-sata" or just "ti,pipe3-phy-sata"
>>>
>>
>> Please remove "ti,omap-pcie" for now, you can add it later whenever you add
>> dpll settings for pcie.
>>
>> Also, please change the newly added compatible strings to
>>
>> "ti,phy-pipe3-usb3" and "ti,phy-pipe3-sata"
> 
> No, I think we should have omap in the compatible since this PHY is specific to
> OMAP.

DRA7x and an am43x are not OMAP so I was suggesting not to use it for new PHY types.
We still preserve just "ti,omap-usb3" for backward compatibility.

cheers,
-roger


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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-14  9:26     ` Kishon Vijay Abraham I
@ 2013-10-14 10:21       ` Roger Quadros
  2013-10-15  5:31         ` Kishon Vijay Abraham I
  2013-10-15 11:57         ` Felipe Balbi
  0 siblings, 2 replies; 47+ messages in thread
From: Roger Quadros @ 2013-10-14 10:21 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, balbi, Vivek Gautam
  Cc: bcousson, tony, rob.herring, pawel.moll, mark.rutland, linux,
	grant.likely, s.nawrocki, galak, swarren, ian.campbell, rob,
	george.cherian, gregkh, linux-doc, linux-omap, devicetree,
	linux-usb, linux-arm-kernel, linux-kernel

+Vivek

On 10/14/2013 12:26 PM, Kishon Vijay Abraham I wrote:
> Hi Roger,
> 
> On Friday 11 October 2013 08:39 PM, Roger Quadros wrote:
>> Hi,
>>
>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>>> phy_power_on() and phy_power_off().
>>>
>>> However using the old USB phy library wont be removed till the PHYs of all
>>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>>>  drivers/usb/dwc3/Kconfig                       |    1 +
>>>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>>>  drivers/usb/dwc3/core.h                        |    7 ++++
>>>  4 files changed, 61 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>>> index e807635..471366d 100644
>>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>>> @@ -6,11 +6,13 @@ Required properties:
>>>   - compatible: must be "snps,dwc3"
>>>   - reg : Address and length of the register set for the device
>>>   - interrupts: Interrupts used by the dwc3 controller.
>>> +
>>> +Optional properties:
>>>   - usb-phy : array of phandle for the PHY device.  The first element
>>>     in the array is expected to be a handle to the USB2/HS PHY and
>>>     the second element is expected to be a handle to the USB3/SS PHY
>>> -
>>> -Optional properties:
>>> + - phys: from the *Generic PHY* bindings
>>> + - phy-names: from the *Generic PHY* bindings
>>>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>>  
>>>  This is usually a subnode to DWC3 glue to which it is connected.
>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>>> index cfc16dd..ad7ce83 100644
>>> --- a/drivers/usb/dwc3/Kconfig
>>> +++ b/drivers/usb/dwc3/Kconfig
>>> @@ -3,6 +3,7 @@ config USB_DWC3
>>>  	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>>  	depends on EXTCON
>>>  	select USB_PHY
>>> +	select GENERIC_PHY
>>>  	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>>  	help
>>>  	  Say Y or M here if your system has a Dual Role SuperSpeed
>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>> index 428c29e..485d365 100644
>>> --- a/drivers/usb/dwc3/core.c
>>> +++ b/drivers/usb/dwc3/core.c
>>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>>  
>>>  	usb_phy_init(dwc->usb2_phy);
>>>  	usb_phy_init(dwc->usb3_phy);
>>
>> How about adding
>> +	if (dwc->usb2_phy)
>> +		usb_phy_init(dwc->usb2_phy);
>> +	if (dwc->usb3_phy)
>> +		usb_phy_init(dwc->usb3_phy);
> 
> Thankfully that usb_phy_init will check if phy is NULL.
>>
>> both usb phy and generic phy shouldn't be present together.
> 
> ok.
>>
>>> +
>>> +	if (dwc->usb2_generic_phy)
>>> +		phy_init(dwc->usb2_generic_phy);
>>> +	if (dwc->usb3_generic_phy)
>>> +		phy_init(dwc->usb3_generic_phy);
>>> +
>>>  	mdelay(100);
>>>  
>>>  	/* Clear USB3 PHY reset */
>>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>>>  {
>>>  	usb_phy_shutdown(dwc->usb2_phy);
>>>  	usb_phy_shutdown(dwc->usb3_phy);
>>
>> here as well
>>
>>> +
>>> +	if (dwc->usb2_generic_phy)
>>> +		phy_power_off(dwc->usb2_generic_phy);
>>> +	if (dwc->usb3_generic_phy)
>>> +		phy_power_off(dwc->usb3_generic_phy);
>>>  }
>>>  
>>>  #define DWC3_ALIGN_MASK		(16 - 1)
>>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>>>  		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>>>  	}
>>>  
>>> +	if (of_property_read_bool(node, "phys") || pdata->has_phy) {
>>> +		dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>>> +		if (IS_ERR(dwc->usb2_generic_phy)) {
>>> +			dev_err(dev, "no usb2 phy configured yet");
>>> +			return PTR_ERR(dwc->usb2_generic_phy);
>>> +		}
>>> +
>>> +		dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
>>> +		if (IS_ERR(dwc->usb3_generic_phy)) {
>>> +			dev_err(dev, "no usb3 phy configured yet");
>>> +			return PTR_ERR(dwc->usb3_generic_phy);
>>> +		}
>>
>> better to add
>> +		/* Don't use USB PHY if generic PHY was found */
>> +		dwc->usb2_phy = dwc->usb3_phy = NULL;
> 
> ok.
>>
>>> +	} else {
>>
>> not required as we've used kzalloc for dwc.
>>
>>> +		dwc->usb2_generic_phy = NULL;
>>> +		dwc->usb3_generic_phy = NULL;
>>> +	}
>>> +
>>>  	/* default to superspeed if no maximum_speed passed */
>>>  	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
>>>  		dwc->maximum_speed = USB_SPEED_SUPER;
>>> @@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)
>>
>> if (dwc->usb2_phy)
>>
>>>  	usb_phy_set_suspend(dwc->usb2_phy, 0);
>>
>> if (dwc->usb3_phy)
>>
>>>  	usb_phy_set_suspend(dwc->usb3_phy, 0);
>>>  
>>> +	if (dwc->usb2_generic_phy)
>>> +		phy_power_on(dwc->usb2_generic_phy);
>>> +	if (dwc->usb3_generic_phy)
>>> +		phy_power_on(dwc->usb3_generic_phy);
>>> +
>>>  	spin_lock_init(&dwc->lock);
>>>  	platform_set_drvdata(pdev, dwc);
>>>  
>>> @@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)
>>
>> if (dwc->usb2_phy)
>>>  	usb_phy_set_suspend(dwc->usb2_phy, 1);
>>
>> if (dwc->usb3_phy)
>>>  	usb_phy_set_suspend(dwc->usb3_phy, 1);
>>>  
>>> +	if (dwc->usb2_generic_phy)
>>> +		phy_power_off(dwc->usb2_generic_phy);
>>> +	if (dwc->usb3_generic_phy)
>>> +		phy_power_off(dwc->usb3_generic_phy);
>>> +
>>>  	pm_runtime_put(&pdev->dev);
>>>  	pm_runtime_disable(&pdev->dev);
>>>  
>>> @@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)
>>
>> if (dwc->usb3_phy)
>>>  	usb_phy_shutdown(dwc->usb3_phy);
>>
>> if (dwc->usb2_phy)
>>>  	usb_phy_shutdown(dwc->usb2_phy);
>>>  
>>> +	if (dwc->usb2_generic_phy)
>>> +		phy_exit(dwc->usb2_generic_phy);
>>> +	if (dwc->usb3_generic_phy)
>>> +		phy_exit(dwc->usb3_generic_phy);
>>> +
>>>  	return 0;
>>>  }
>>>  
>>> @@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
>>>  
>>
>> if (dwc->usb3_phy)
>>>  	usb_phy_init(dwc->usb3_phy);
>>
>> if (dwc->usb2_phy)
>>>  	usb_phy_init(dwc->usb2_phy);
>>> +
>>> +	if (dwc->usb2_generic_phy)
>>> +		phy_init(dwc->usb2_generic_phy);
>>> +	if (dwc->usb3_generic_phy)
>>> +		phy_init(dwc->usb3_generic_phy);
>>> +
>>>  	msleep(100);
>>>  
>>>  	spin_lock_irqsave(&dwc->lock, flags);
>>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>>> index f8af8d4..01ec7d7 100644
>>> --- a/drivers/usb/dwc3/core.h
>>> +++ b/drivers/usb/dwc3/core.h
>>> @@ -31,6 +31,8 @@
>>>  #include <linux/usb/gadget.h>
>>>  #include <linux/usb/otg.h>
>>>  
>>> +#include <linux/phy/phy.h>
>>> +
>>>  /* Global constants */
>>>  #define DWC3_EP0_BOUNCE_SIZE	512
>>>  #define DWC3_ENDPOINTS_NUM	32
>>> @@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
>>>   * @dr_mode: requested mode of operation
>>>   * @usb2_phy: pointer to USB2 PHY
>>>   * @usb3_phy: pointer to USB3 PHY
>>> + * @usb2_generic_phy: pointer to USB2 PHY
>>> + * @usb3_generic_phy: pointer to USB3 PHY
>>>   * @dcfg: saved contents of DCFG register
>>>   * @gctl: saved contents of GCTL register
>>>   * @is_selfpowered: true when we are selfpowered
>>> @@ -665,6 +669,9 @@ struct dwc3 {
>>>  	struct usb_phy		*usb2_phy;
>>>  	struct usb_phy		*usb3_phy;
>>>  
>>> +	struct phy		*usb2_generic_phy;
>>> +	struct phy		*usb3_generic_phy;
>>> +
>>>  	void __iomem		*regs;
>>>  	size_t			regs_size;
>>>  
>>>
> 
> Do you have any suggestions on how to get only individual PHYs? like only
> usb2phy or usb3phy?

My earlier understanding was that both PHYs are needed only if .speed is "super-speed"
and only usb2phy is needed for "high-speed". But as per Vivek's email it seems
Samsung's exynos5 SoC doesn't need usb2phy for "super-speed".

So to keeps things flexible, I can propose the following approach
- if speed == 'high-speed' usb2phy must be present. usb3phy will be ignored if supplied.
- if speed == 'super-speed' usb3phy must be present and usb2phy is optional but must be
initialized if supplied.
- if speed is not specified, we default to 'super-speed'.

Felipe, does this address the issue you were facing with OMAP5?

cheers,
-roger

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-14 10:21       ` Roger Quadros
@ 2013-10-15  5:31         ` Kishon Vijay Abraham I
  2013-10-15  7:57           ` Roger Quadros
  2013-10-15 11:58           ` Felipe Balbi
  2013-10-15 11:57         ` Felipe Balbi
  1 sibling, 2 replies; 47+ messages in thread
From: Kishon Vijay Abraham I @ 2013-10-15  5:31 UTC (permalink / raw)
  To: Roger Quadros
  Cc: balbi, Vivek Gautam, bcousson, tony, rob.herring, pawel.moll,
	mark.rutland, linux, grant.likely, s.nawrocki, galak, swarren,
	ian.campbell, rob, george.cherian, gregkh, linux-doc, linux-omap,
	devicetree, linux-usb, linux-arm-kernel, linux-kernel

Hi Roger,

On Monday 14 October 2013 03:51 PM, Roger Quadros wrote:
> +Vivek
> 
> On 10/14/2013 12:26 PM, Kishon Vijay Abraham I wrote:
>> Hi Roger,
>>
>> On Friday 11 October 2013 08:39 PM, Roger Quadros wrote:
>>> Hi,
>>>
>>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>>>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>>>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>>>> phy_power_on() and phy_power_off().
>>>>
>>>> However using the old USB phy library wont be removed till the PHYs of all
>>>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>>>
>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>> ---
>>>>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>>>>  drivers/usb/dwc3/Kconfig                       |    1 +
>>>>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>>>>  drivers/usb/dwc3/core.h                        |    7 ++++
>>>>  4 files changed, 61 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>>>> index e807635..471366d 100644
>>>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>>>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>>>> @@ -6,11 +6,13 @@ Required properties:
>>>>   - compatible: must be "snps,dwc3"
>>>>   - reg : Address and length of the register set for the device
>>>>   - interrupts: Interrupts used by the dwc3 controller.
>>>> +
>>>> +Optional properties:
>>>>   - usb-phy : array of phandle for the PHY device.  The first element
>>>>     in the array is expected to be a handle to the USB2/HS PHY and
>>>>     the second element is expected to be a handle to the USB3/SS PHY
>>>> -
>>>> -Optional properties:
>>>> + - phys: from the *Generic PHY* bindings
>>>> + - phy-names: from the *Generic PHY* bindings
>>>>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>>>  
>>>>  This is usually a subnode to DWC3 glue to which it is connected.
>>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>>>> index cfc16dd..ad7ce83 100644
>>>> --- a/drivers/usb/dwc3/Kconfig
>>>> +++ b/drivers/usb/dwc3/Kconfig
>>>> @@ -3,6 +3,7 @@ config USB_DWC3
>>>>  	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>>>  	depends on EXTCON
>>>>  	select USB_PHY
>>>> +	select GENERIC_PHY
>>>>  	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>>>  	help
>>>>  	  Say Y or M here if your system has a Dual Role SuperSpeed
>>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>>> index 428c29e..485d365 100644
>>>> --- a/drivers/usb/dwc3/core.c
>>>> +++ b/drivers/usb/dwc3/core.c
>>>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>>>  
>>>>  	usb_phy_init(dwc->usb2_phy);
>>>>  	usb_phy_init(dwc->usb3_phy);
>>>
>>> How about adding
>>> +	if (dwc->usb2_phy)
>>> +		usb_phy_init(dwc->usb2_phy);
>>> +	if (dwc->usb3_phy)
>>> +		usb_phy_init(dwc->usb3_phy);
>>
>> Thankfully that usb_phy_init will check if phy is NULL.
>>>
>>> both usb phy and generic phy shouldn't be present together.
>>
>> ok.
>>>
>>>> +
>>>> +	if (dwc->usb2_generic_phy)
>>>> +		phy_init(dwc->usb2_generic_phy);
>>>> +	if (dwc->usb3_generic_phy)
>>>> +		phy_init(dwc->usb3_generic_phy);
>>>> +
>>>>  	mdelay(100);
>>>>  
>>>>  	/* Clear USB3 PHY reset */
>>>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>>>>  {
>>>>  	usb_phy_shutdown(dwc->usb2_phy);
>>>>  	usb_phy_shutdown(dwc->usb3_phy);
>>>
>>> here as well
>>>
>>>> +
>>>> +	if (dwc->usb2_generic_phy)
>>>> +		phy_power_off(dwc->usb2_generic_phy);
>>>> +	if (dwc->usb3_generic_phy)
>>>> +		phy_power_off(dwc->usb3_generic_phy);
>>>>  }
>>>>  
>>>>  #define DWC3_ALIGN_MASK		(16 - 1)
>>>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>>>>  		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>>>>  	}
>>>>  
>>>> +	if (of_property_read_bool(node, "phys") || pdata->has_phy) {
>>>> +		dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>>>> +		if (IS_ERR(dwc->usb2_generic_phy)) {
>>>> +			dev_err(dev, "no usb2 phy configured yet");
>>>> +			return PTR_ERR(dwc->usb2_generic_phy);
>>>> +		}
>>>> +
>>>> +		dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
>>>> +		if (IS_ERR(dwc->usb3_generic_phy)) {
>>>> +			dev_err(dev, "no usb3 phy configured yet");
>>>> +			return PTR_ERR(dwc->usb3_generic_phy);
>>>> +		}
>>>
>>> better to add
>>> +		/* Don't use USB PHY if generic PHY was found */
>>> +		dwc->usb2_phy = dwc->usb3_phy = NULL;
>>
>> ok.
>>>
>>>> +	} else {
>>>
>>> not required as we've used kzalloc for dwc.
>>>
>>>> +		dwc->usb2_generic_phy = NULL;
>>>> +		dwc->usb3_generic_phy = NULL;
>>>> +	}
>>>> +
>>>>  	/* default to superspeed if no maximum_speed passed */
>>>>  	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
>>>>  		dwc->maximum_speed = USB_SPEED_SUPER;
>>>> @@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)
>>>
>>> if (dwc->usb2_phy)
>>>
>>>>  	usb_phy_set_suspend(dwc->usb2_phy, 0);
>>>
>>> if (dwc->usb3_phy)
>>>
>>>>  	usb_phy_set_suspend(dwc->usb3_phy, 0);
>>>>  
>>>> +	if (dwc->usb2_generic_phy)
>>>> +		phy_power_on(dwc->usb2_generic_phy);
>>>> +	if (dwc->usb3_generic_phy)
>>>> +		phy_power_on(dwc->usb3_generic_phy);
>>>> +
>>>>  	spin_lock_init(&dwc->lock);
>>>>  	platform_set_drvdata(pdev, dwc);
>>>>  
>>>> @@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)
>>>
>>> if (dwc->usb2_phy)
>>>>  	usb_phy_set_suspend(dwc->usb2_phy, 1);
>>>
>>> if (dwc->usb3_phy)
>>>>  	usb_phy_set_suspend(dwc->usb3_phy, 1);
>>>>  
>>>> +	if (dwc->usb2_generic_phy)
>>>> +		phy_power_off(dwc->usb2_generic_phy);
>>>> +	if (dwc->usb3_generic_phy)
>>>> +		phy_power_off(dwc->usb3_generic_phy);
>>>> +
>>>>  	pm_runtime_put(&pdev->dev);
>>>>  	pm_runtime_disable(&pdev->dev);
>>>>  
>>>> @@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)
>>>
>>> if (dwc->usb3_phy)
>>>>  	usb_phy_shutdown(dwc->usb3_phy);
>>>
>>> if (dwc->usb2_phy)
>>>>  	usb_phy_shutdown(dwc->usb2_phy);
>>>>  
>>>> +	if (dwc->usb2_generic_phy)
>>>> +		phy_exit(dwc->usb2_generic_phy);
>>>> +	if (dwc->usb3_generic_phy)
>>>> +		phy_exit(dwc->usb3_generic_phy);
>>>> +
>>>>  	return 0;
>>>>  }
>>>>  
>>>> @@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
>>>>  
>>>
>>> if (dwc->usb3_phy)
>>>>  	usb_phy_init(dwc->usb3_phy);
>>>
>>> if (dwc->usb2_phy)
>>>>  	usb_phy_init(dwc->usb2_phy);
>>>> +
>>>> +	if (dwc->usb2_generic_phy)
>>>> +		phy_init(dwc->usb2_generic_phy);
>>>> +	if (dwc->usb3_generic_phy)
>>>> +		phy_init(dwc->usb3_generic_phy);
>>>> +
>>>>  	msleep(100);
>>>>  
>>>>  	spin_lock_irqsave(&dwc->lock, flags);
>>>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>>>> index f8af8d4..01ec7d7 100644
>>>> --- a/drivers/usb/dwc3/core.h
>>>> +++ b/drivers/usb/dwc3/core.h
>>>> @@ -31,6 +31,8 @@
>>>>  #include <linux/usb/gadget.h>
>>>>  #include <linux/usb/otg.h>
>>>>  
>>>> +#include <linux/phy/phy.h>
>>>> +
>>>>  /* Global constants */
>>>>  #define DWC3_EP0_BOUNCE_SIZE	512
>>>>  #define DWC3_ENDPOINTS_NUM	32
>>>> @@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
>>>>   * @dr_mode: requested mode of operation
>>>>   * @usb2_phy: pointer to USB2 PHY
>>>>   * @usb3_phy: pointer to USB3 PHY
>>>> + * @usb2_generic_phy: pointer to USB2 PHY
>>>> + * @usb3_generic_phy: pointer to USB3 PHY
>>>>   * @dcfg: saved contents of DCFG register
>>>>   * @gctl: saved contents of GCTL register
>>>>   * @is_selfpowered: true when we are selfpowered
>>>> @@ -665,6 +669,9 @@ struct dwc3 {
>>>>  	struct usb_phy		*usb2_phy;
>>>>  	struct usb_phy		*usb3_phy;
>>>>  
>>>> +	struct phy		*usb2_generic_phy;
>>>> +	struct phy		*usb3_generic_phy;
>>>> +
>>>>  	void __iomem		*regs;
>>>>  	size_t			regs_size;
>>>>  
>>>>
>>
>> Do you have any suggestions on how to get only individual PHYs? like only
>> usb2phy or usb3phy?
> 
> My earlier understanding was that both PHYs are needed only if .speed is "super-speed"
> and only usb2phy is needed for "high-speed". But as per Vivek's email it seems
> Samsung's exynos5 SoC doesn't need usb2phy for "super-speed".
> 
> So to keeps things flexible, I can propose the following approach
> - if speed == 'high-speed' usb2phy must be present. usb3phy will be ignored if supplied.
> - if speed == 'super-speed' usb3phy must be present and usb2phy is optional but must be
> initialized if supplied.
> - if speed is not specified, we default to 'super-speed'.
> 
> Felipe, does this address the issue you were facing with OMAP5?

IIRC, even if the speed is high speed, you still need to power on the USB3 PHY.
Or else even high speed mode wasn't working in OMAP5.

Thanks
Kishon

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-15  5:31         ` Kishon Vijay Abraham I
@ 2013-10-15  7:57           ` Roger Quadros
  2013-10-15 12:00             ` Felipe Balbi
  2013-10-15 11:58           ` Felipe Balbi
  1 sibling, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-10-15  7:57 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: balbi, Vivek Gautam, bcousson, tony, rob.herring, pawel.moll,
	mark.rutland, linux, grant.likely, s.nawrocki, galak, swarren,
	ian.campbell, rob, george.cherian, gregkh, linux-doc, linux-omap,
	devicetree, linux-usb, linux-arm-kernel, linux-kernel

On 10/15/2013 08:31 AM, Kishon Vijay Abraham I wrote:
> Hi Roger,
> 
> On Monday 14 October 2013 03:51 PM, Roger Quadros wrote:
>> +Vivek
>>
>> On 10/14/2013 12:26 PM, Kishon Vijay Abraham I wrote:
>>> Hi Roger,
>>>
>>> On Friday 11 October 2013 08:39 PM, Roger Quadros wrote:
>>>> Hi,
>>>>
>>>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>>>>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>>>>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>>>>> phy_power_on() and phy_power_off().
>>>>>
>>>>> However using the old USB phy library wont be removed till the PHYs of all
>>>>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>>>>
>>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>>> ---
>>>>>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>>>>>  drivers/usb/dwc3/Kconfig                       |    1 +
>>>>>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>>>>>  drivers/usb/dwc3/core.h                        |    7 ++++
>>>>>  4 files changed, 61 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>>>>> index e807635..471366d 100644
>>>>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>>>>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>>>>> @@ -6,11 +6,13 @@ Required properties:
>>>>>   - compatible: must be "snps,dwc3"
>>>>>   - reg : Address and length of the register set for the device
>>>>>   - interrupts: Interrupts used by the dwc3 controller.
>>>>> +
>>>>> +Optional properties:
>>>>>   - usb-phy : array of phandle for the PHY device.  The first element
>>>>>     in the array is expected to be a handle to the USB2/HS PHY and
>>>>>     the second element is expected to be a handle to the USB3/SS PHY
>>>>> -
>>>>> -Optional properties:
>>>>> + - phys: from the *Generic PHY* bindings
>>>>> + - phy-names: from the *Generic PHY* bindings
>>>>>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>>>>  
>>>>>  This is usually a subnode to DWC3 glue to which it is connected.
>>>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>>>>> index cfc16dd..ad7ce83 100644
>>>>> --- a/drivers/usb/dwc3/Kconfig
>>>>> +++ b/drivers/usb/dwc3/Kconfig
>>>>> @@ -3,6 +3,7 @@ config USB_DWC3
>>>>>  	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>>>>  	depends on EXTCON
>>>>>  	select USB_PHY
>>>>> +	select GENERIC_PHY
>>>>>  	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>>>>  	help
>>>>>  	  Say Y or M here if your system has a Dual Role SuperSpeed
>>>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>>>> index 428c29e..485d365 100644
>>>>> --- a/drivers/usb/dwc3/core.c
>>>>> +++ b/drivers/usb/dwc3/core.c
>>>>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>>>>  
>>>>>  	usb_phy_init(dwc->usb2_phy);
>>>>>  	usb_phy_init(dwc->usb3_phy);
>>>>
>>>> How about adding
>>>> +	if (dwc->usb2_phy)
>>>> +		usb_phy_init(dwc->usb2_phy);
>>>> +	if (dwc->usb3_phy)
>>>> +		usb_phy_init(dwc->usb3_phy);
>>>
>>> Thankfully that usb_phy_init will check if phy is NULL.
>>>>
>>>> both usb phy and generic phy shouldn't be present together.
>>>
>>> ok.
>>>>
>>>>> +
>>>>> +	if (dwc->usb2_generic_phy)
>>>>> +		phy_init(dwc->usb2_generic_phy);
>>>>> +	if (dwc->usb3_generic_phy)
>>>>> +		phy_init(dwc->usb3_generic_phy);
>>>>> +
>>>>>  	mdelay(100);
>>>>>  
>>>>>  	/* Clear USB3 PHY reset */
>>>>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>>>>>  {
>>>>>  	usb_phy_shutdown(dwc->usb2_phy);
>>>>>  	usb_phy_shutdown(dwc->usb3_phy);
>>>>
>>>> here as well
>>>>
>>>>> +
>>>>> +	if (dwc->usb2_generic_phy)
>>>>> +		phy_power_off(dwc->usb2_generic_phy);
>>>>> +	if (dwc->usb3_generic_phy)
>>>>> +		phy_power_off(dwc->usb3_generic_phy);
>>>>>  }
>>>>>  
>>>>>  #define DWC3_ALIGN_MASK		(16 - 1)
>>>>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>>>>>  		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>>>>>  	}
>>>>>  
>>>>> +	if (of_property_read_bool(node, "phys") || pdata->has_phy) {
>>>>> +		dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>>>>> +		if (IS_ERR(dwc->usb2_generic_phy)) {
>>>>> +			dev_err(dev, "no usb2 phy configured yet");
>>>>> +			return PTR_ERR(dwc->usb2_generic_phy);
>>>>> +		}
>>>>> +
>>>>> +		dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
>>>>> +		if (IS_ERR(dwc->usb3_generic_phy)) {
>>>>> +			dev_err(dev, "no usb3 phy configured yet");
>>>>> +			return PTR_ERR(dwc->usb3_generic_phy);
>>>>> +		}
>>>>
>>>> better to add
>>>> +		/* Don't use USB PHY if generic PHY was found */
>>>> +		dwc->usb2_phy = dwc->usb3_phy = NULL;
>>>
>>> ok.
>>>>
>>>>> +	} else {
>>>>
>>>> not required as we've used kzalloc for dwc.
>>>>
>>>>> +		dwc->usb2_generic_phy = NULL;
>>>>> +		dwc->usb3_generic_phy = NULL;
>>>>> +	}
>>>>> +
>>>>>  	/* default to superspeed if no maximum_speed passed */
>>>>>  	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
>>>>>  		dwc->maximum_speed = USB_SPEED_SUPER;
>>>>> @@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)
>>>>
>>>> if (dwc->usb2_phy)
>>>>
>>>>>  	usb_phy_set_suspend(dwc->usb2_phy, 0);
>>>>
>>>> if (dwc->usb3_phy)
>>>>
>>>>>  	usb_phy_set_suspend(dwc->usb3_phy, 0);
>>>>>  
>>>>> +	if (dwc->usb2_generic_phy)
>>>>> +		phy_power_on(dwc->usb2_generic_phy);
>>>>> +	if (dwc->usb3_generic_phy)
>>>>> +		phy_power_on(dwc->usb3_generic_phy);
>>>>> +
>>>>>  	spin_lock_init(&dwc->lock);
>>>>>  	platform_set_drvdata(pdev, dwc);
>>>>>  
>>>>> @@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)
>>>>
>>>> if (dwc->usb2_phy)
>>>>>  	usb_phy_set_suspend(dwc->usb2_phy, 1);
>>>>
>>>> if (dwc->usb3_phy)
>>>>>  	usb_phy_set_suspend(dwc->usb3_phy, 1);
>>>>>  
>>>>> +	if (dwc->usb2_generic_phy)
>>>>> +		phy_power_off(dwc->usb2_generic_phy);
>>>>> +	if (dwc->usb3_generic_phy)
>>>>> +		phy_power_off(dwc->usb3_generic_phy);
>>>>> +
>>>>>  	pm_runtime_put(&pdev->dev);
>>>>>  	pm_runtime_disable(&pdev->dev);
>>>>>  
>>>>> @@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)
>>>>
>>>> if (dwc->usb3_phy)
>>>>>  	usb_phy_shutdown(dwc->usb3_phy);
>>>>
>>>> if (dwc->usb2_phy)
>>>>>  	usb_phy_shutdown(dwc->usb2_phy);
>>>>>  
>>>>> +	if (dwc->usb2_generic_phy)
>>>>> +		phy_exit(dwc->usb2_generic_phy);
>>>>> +	if (dwc->usb3_generic_phy)
>>>>> +		phy_exit(dwc->usb3_generic_phy);
>>>>> +
>>>>>  	return 0;
>>>>>  }
>>>>>  
>>>>> @@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
>>>>>  
>>>>
>>>> if (dwc->usb3_phy)
>>>>>  	usb_phy_init(dwc->usb3_phy);
>>>>
>>>> if (dwc->usb2_phy)
>>>>>  	usb_phy_init(dwc->usb2_phy);
>>>>> +
>>>>> +	if (dwc->usb2_generic_phy)
>>>>> +		phy_init(dwc->usb2_generic_phy);
>>>>> +	if (dwc->usb3_generic_phy)
>>>>> +		phy_init(dwc->usb3_generic_phy);
>>>>> +
>>>>>  	msleep(100);
>>>>>  
>>>>>  	spin_lock_irqsave(&dwc->lock, flags);
>>>>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>>>>> index f8af8d4..01ec7d7 100644
>>>>> --- a/drivers/usb/dwc3/core.h
>>>>> +++ b/drivers/usb/dwc3/core.h
>>>>> @@ -31,6 +31,8 @@
>>>>>  #include <linux/usb/gadget.h>
>>>>>  #include <linux/usb/otg.h>
>>>>>  
>>>>> +#include <linux/phy/phy.h>
>>>>> +
>>>>>  /* Global constants */
>>>>>  #define DWC3_EP0_BOUNCE_SIZE	512
>>>>>  #define DWC3_ENDPOINTS_NUM	32
>>>>> @@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
>>>>>   * @dr_mode: requested mode of operation
>>>>>   * @usb2_phy: pointer to USB2 PHY
>>>>>   * @usb3_phy: pointer to USB3 PHY
>>>>> + * @usb2_generic_phy: pointer to USB2 PHY
>>>>> + * @usb3_generic_phy: pointer to USB3 PHY
>>>>>   * @dcfg: saved contents of DCFG register
>>>>>   * @gctl: saved contents of GCTL register
>>>>>   * @is_selfpowered: true when we are selfpowered
>>>>> @@ -665,6 +669,9 @@ struct dwc3 {
>>>>>  	struct usb_phy		*usb2_phy;
>>>>>  	struct usb_phy		*usb3_phy;
>>>>>  
>>>>> +	struct phy		*usb2_generic_phy;
>>>>> +	struct phy		*usb3_generic_phy;
>>>>> +
>>>>>  	void __iomem		*regs;
>>>>>  	size_t			regs_size;
>>>>>  
>>>>>
>>>
>>> Do you have any suggestions on how to get only individual PHYs? like only
>>> usb2phy or usb3phy?
>>
>> My earlier understanding was that both PHYs are needed only if .speed is "super-speed"
>> and only usb2phy is needed for "high-speed". But as per Vivek's email it seems
>> Samsung's exynos5 SoC doesn't need usb2phy for "super-speed".
>>
>> So to keeps things flexible, I can propose the following approach
>> - if speed == 'high-speed' usb2phy must be present. usb3phy will be ignored if supplied.
>> - if speed == 'super-speed' usb3phy must be present and usb2phy is optional but must be
>> initialized if supplied.
>> - if speed is not specified, we default to 'super-speed'.
>>
>> Felipe, does this address the issue you were facing with OMAP5?
> 
> IIRC, even if the speed is high speed, you still need to power on the USB3 PHY.
> Or else even high speed mode wasn't working in OMAP5.

Maybe for OMAP5 we can somehow indicate to dwc3 core code that only 'super-speed' mode
is supported by the platform. I'm not aware of any OMAP5 platform using the USB port as 'high-speed'.

So there needs to be some mechanism for dwc3-<platform>.c to indicate to dwc3-core.c the
speeds supported by the platform. e.g. via of_dev_auxdata through of_platform_populate()?

If such data is not supplied, we assume that both speeds are supported.

cheers,
-roger

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-14 10:21       ` Roger Quadros
  2013-10-15  5:31         ` Kishon Vijay Abraham I
@ 2013-10-15 11:57         ` Felipe Balbi
  2013-10-15 12:10           ` Roger Quadros
  1 sibling, 1 reply; 47+ messages in thread
From: Felipe Balbi @ 2013-10-15 11:57 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Kishon Vijay Abraham I, balbi, Vivek Gautam, bcousson, tony,
	rob.herring, pawel.moll, mark.rutland, linux, grant.likely,
	s.nawrocki, galak, swarren, ian.campbell, rob, george.cherian,
	gregkh, linux-doc, linux-omap, devicetree, linux-usb,
	linux-arm-kernel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 9342 bytes --]

Hi,

On Mon, Oct 14, 2013 at 01:21:29PM +0300, Roger Quadros wrote:
> +Vivek
> 
> On 10/14/2013 12:26 PM, Kishon Vijay Abraham I wrote:
> > Hi Roger,
> > 
> > On Friday 11 October 2013 08:39 PM, Roger Quadros wrote:
> >> Hi,
> >>
> >> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
> >>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
> >>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
> >>> phy_power_on() and phy_power_off().
> >>>
> >>> However using the old USB phy library wont be removed till the PHYs of all
> >>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
> >>>
> >>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> >>> ---
> >>>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
> >>>  drivers/usb/dwc3/Kconfig                       |    1 +
> >>>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
> >>>  drivers/usb/dwc3/core.h                        |    7 ++++
> >>>  4 files changed, 61 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
> >>> index e807635..471366d 100644
> >>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
> >>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
> >>> @@ -6,11 +6,13 @@ Required properties:
> >>>   - compatible: must be "snps,dwc3"
> >>>   - reg : Address and length of the register set for the device
> >>>   - interrupts: Interrupts used by the dwc3 controller.
> >>> +
> >>> +Optional properties:
> >>>   - usb-phy : array of phandle for the PHY device.  The first element
> >>>     in the array is expected to be a handle to the USB2/HS PHY and
> >>>     the second element is expected to be a handle to the USB3/SS PHY
> >>> -
> >>> -Optional properties:
> >>> + - phys: from the *Generic PHY* bindings
> >>> + - phy-names: from the *Generic PHY* bindings
> >>>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
> >>>  
> >>>  This is usually a subnode to DWC3 glue to which it is connected.
> >>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> >>> index cfc16dd..ad7ce83 100644
> >>> --- a/drivers/usb/dwc3/Kconfig
> >>> +++ b/drivers/usb/dwc3/Kconfig
> >>> @@ -3,6 +3,7 @@ config USB_DWC3
> >>>  	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
> >>>  	depends on EXTCON
> >>>  	select USB_PHY
> >>> +	select GENERIC_PHY
> >>>  	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
> >>>  	help
> >>>  	  Say Y or M here if your system has a Dual Role SuperSpeed
> >>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> >>> index 428c29e..485d365 100644
> >>> --- a/drivers/usb/dwc3/core.c
> >>> +++ b/drivers/usb/dwc3/core.c
> >>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
> >>>  
> >>>  	usb_phy_init(dwc->usb2_phy);
> >>>  	usb_phy_init(dwc->usb3_phy);
> >>
> >> How about adding
> >> +	if (dwc->usb2_phy)
> >> +		usb_phy_init(dwc->usb2_phy);
> >> +	if (dwc->usb3_phy)
> >> +		usb_phy_init(dwc->usb3_phy);
> > 
> > Thankfully that usb_phy_init will check if phy is NULL.
> >>
> >> both usb phy and generic phy shouldn't be present together.
> > 
> > ok.
> >>
> >>> +
> >>> +	if (dwc->usb2_generic_phy)
> >>> +		phy_init(dwc->usb2_generic_phy);
> >>> +	if (dwc->usb3_generic_phy)
> >>> +		phy_init(dwc->usb3_generic_phy);
> >>> +
> >>>  	mdelay(100);
> >>>  
> >>>  	/* Clear USB3 PHY reset */
> >>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
> >>>  {
> >>>  	usb_phy_shutdown(dwc->usb2_phy);
> >>>  	usb_phy_shutdown(dwc->usb3_phy);
> >>
> >> here as well
> >>
> >>> +
> >>> +	if (dwc->usb2_generic_phy)
> >>> +		phy_power_off(dwc->usb2_generic_phy);
> >>> +	if (dwc->usb3_generic_phy)
> >>> +		phy_power_off(dwc->usb3_generic_phy);
> >>>  }
> >>>  
> >>>  #define DWC3_ALIGN_MASK		(16 - 1)
> >>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
> >>>  		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
> >>>  	}
> >>>  
> >>> +	if (of_property_read_bool(node, "phys") || pdata->has_phy) {
> >>> +		dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
> >>> +		if (IS_ERR(dwc->usb2_generic_phy)) {
> >>> +			dev_err(dev, "no usb2 phy configured yet");
> >>> +			return PTR_ERR(dwc->usb2_generic_phy);
> >>> +		}
> >>> +
> >>> +		dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
> >>> +		if (IS_ERR(dwc->usb3_generic_phy)) {
> >>> +			dev_err(dev, "no usb3 phy configured yet");
> >>> +			return PTR_ERR(dwc->usb3_generic_phy);
> >>> +		}
> >>
> >> better to add
> >> +		/* Don't use USB PHY if generic PHY was found */
> >> +		dwc->usb2_phy = dwc->usb3_phy = NULL;
> > 
> > ok.
> >>
> >>> +	} else {
> >>
> >> not required as we've used kzalloc for dwc.
> >>
> >>> +		dwc->usb2_generic_phy = NULL;
> >>> +		dwc->usb3_generic_phy = NULL;
> >>> +	}
> >>> +
> >>>  	/* default to superspeed if no maximum_speed passed */
> >>>  	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
> >>>  		dwc->maximum_speed = USB_SPEED_SUPER;
> >>> @@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)
> >>
> >> if (dwc->usb2_phy)
> >>
> >>>  	usb_phy_set_suspend(dwc->usb2_phy, 0);
> >>
> >> if (dwc->usb3_phy)
> >>
> >>>  	usb_phy_set_suspend(dwc->usb3_phy, 0);
> >>>  
> >>> +	if (dwc->usb2_generic_phy)
> >>> +		phy_power_on(dwc->usb2_generic_phy);
> >>> +	if (dwc->usb3_generic_phy)
> >>> +		phy_power_on(dwc->usb3_generic_phy);
> >>> +
> >>>  	spin_lock_init(&dwc->lock);
> >>>  	platform_set_drvdata(pdev, dwc);
> >>>  
> >>> @@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)
> >>
> >> if (dwc->usb2_phy)
> >>>  	usb_phy_set_suspend(dwc->usb2_phy, 1);
> >>
> >> if (dwc->usb3_phy)
> >>>  	usb_phy_set_suspend(dwc->usb3_phy, 1);
> >>>  
> >>> +	if (dwc->usb2_generic_phy)
> >>> +		phy_power_off(dwc->usb2_generic_phy);
> >>> +	if (dwc->usb3_generic_phy)
> >>> +		phy_power_off(dwc->usb3_generic_phy);
> >>> +
> >>>  	pm_runtime_put(&pdev->dev);
> >>>  	pm_runtime_disable(&pdev->dev);
> >>>  
> >>> @@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)
> >>
> >> if (dwc->usb3_phy)
> >>>  	usb_phy_shutdown(dwc->usb3_phy);
> >>
> >> if (dwc->usb2_phy)
> >>>  	usb_phy_shutdown(dwc->usb2_phy);
> >>>  
> >>> +	if (dwc->usb2_generic_phy)
> >>> +		phy_exit(dwc->usb2_generic_phy);
> >>> +	if (dwc->usb3_generic_phy)
> >>> +		phy_exit(dwc->usb3_generic_phy);
> >>> +
> >>>  	return 0;
> >>>  }
> >>>  
> >>> @@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
> >>>  
> >>
> >> if (dwc->usb3_phy)
> >>>  	usb_phy_init(dwc->usb3_phy);
> >>
> >> if (dwc->usb2_phy)
> >>>  	usb_phy_init(dwc->usb2_phy);
> >>> +
> >>> +	if (dwc->usb2_generic_phy)
> >>> +		phy_init(dwc->usb2_generic_phy);
> >>> +	if (dwc->usb3_generic_phy)
> >>> +		phy_init(dwc->usb3_generic_phy);
> >>> +
> >>>  	msleep(100);
> >>>  
> >>>  	spin_lock_irqsave(&dwc->lock, flags);
> >>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> >>> index f8af8d4..01ec7d7 100644
> >>> --- a/drivers/usb/dwc3/core.h
> >>> +++ b/drivers/usb/dwc3/core.h
> >>> @@ -31,6 +31,8 @@
> >>>  #include <linux/usb/gadget.h>
> >>>  #include <linux/usb/otg.h>
> >>>  
> >>> +#include <linux/phy/phy.h>
> >>> +
> >>>  /* Global constants */
> >>>  #define DWC3_EP0_BOUNCE_SIZE	512
> >>>  #define DWC3_ENDPOINTS_NUM	32
> >>> @@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
> >>>   * @dr_mode: requested mode of operation
> >>>   * @usb2_phy: pointer to USB2 PHY
> >>>   * @usb3_phy: pointer to USB3 PHY
> >>> + * @usb2_generic_phy: pointer to USB2 PHY
> >>> + * @usb3_generic_phy: pointer to USB3 PHY
> >>>   * @dcfg: saved contents of DCFG register
> >>>   * @gctl: saved contents of GCTL register
> >>>   * @is_selfpowered: true when we are selfpowered
> >>> @@ -665,6 +669,9 @@ struct dwc3 {
> >>>  	struct usb_phy		*usb2_phy;
> >>>  	struct usb_phy		*usb3_phy;
> >>>  
> >>> +	struct phy		*usb2_generic_phy;
> >>> +	struct phy		*usb3_generic_phy;
> >>> +
> >>>  	void __iomem		*regs;
> >>>  	size_t			regs_size;
> >>>  
> >>>
> > 
> > Do you have any suggestions on how to get only individual PHYs? like only
> > usb2phy or usb3phy?
> 
> My earlier understanding was that both PHYs are needed only if .speed is "super-speed"
> and only usb2phy is needed for "high-speed". But as per Vivek's email it seems
> Samsung's exynos5 SoC doesn't need usb2phy for "super-speed".
> 
> So to keeps things flexible, I can propose the following approach
> - if speed == 'high-speed' usb2phy must be present. usb3phy will be ignored if supplied.
> - if speed == 'super-speed' usb3phy must be present and usb2phy is optional but must be
> initialized if supplied.
> - if speed is not specified, we default to 'super-speed'.
> 
> Felipe, does this address the issue you were facing with OMAP5?

on OMAP5 we cannot skip USB3 PHY initialization. But then it becomes a
question of supporting a test feature (in OMAP5 case it would be cool to
force controller to lower speeds for testing) or coping with a broken
DTS.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-15  5:31         ` Kishon Vijay Abraham I
  2013-10-15  7:57           ` Roger Quadros
@ 2013-10-15 11:58           ` Felipe Balbi
  1 sibling, 0 replies; 47+ messages in thread
From: Felipe Balbi @ 2013-10-15 11:58 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Roger Quadros, balbi, Vivek Gautam, bcousson, tony, rob.herring,
	pawel.moll, mark.rutland, linux, grant.likely, s.nawrocki, galak,
	swarren, ian.campbell, rob, george.cherian, gregkh, linux-doc,
	linux-omap, devicetree, linux-usb, linux-arm-kernel,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 9609 bytes --]

On Tue, Oct 15, 2013 at 11:01:16AM +0530, Kishon Vijay Abraham I wrote:
> Hi Roger,
> 
> On Monday 14 October 2013 03:51 PM, Roger Quadros wrote:
> > +Vivek
> > 
> > On 10/14/2013 12:26 PM, Kishon Vijay Abraham I wrote:
> >> Hi Roger,
> >>
> >> On Friday 11 October 2013 08:39 PM, Roger Quadros wrote:
> >>> Hi,
> >>>
> >>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
> >>>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
> >>>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
> >>>> phy_power_on() and phy_power_off().
> >>>>
> >>>> However using the old USB phy library wont be removed till the PHYs of all
> >>>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
> >>>>
> >>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> >>>> ---
> >>>>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
> >>>>  drivers/usb/dwc3/Kconfig                       |    1 +
> >>>>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
> >>>>  drivers/usb/dwc3/core.h                        |    7 ++++
> >>>>  4 files changed, 61 insertions(+), 2 deletions(-)
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
> >>>> index e807635..471366d 100644
> >>>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
> >>>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
> >>>> @@ -6,11 +6,13 @@ Required properties:
> >>>>   - compatible: must be "snps,dwc3"
> >>>>   - reg : Address and length of the register set for the device
> >>>>   - interrupts: Interrupts used by the dwc3 controller.
> >>>> +
> >>>> +Optional properties:
> >>>>   - usb-phy : array of phandle for the PHY device.  The first element
> >>>>     in the array is expected to be a handle to the USB2/HS PHY and
> >>>>     the second element is expected to be a handle to the USB3/SS PHY
> >>>> -
> >>>> -Optional properties:
> >>>> + - phys: from the *Generic PHY* bindings
> >>>> + - phy-names: from the *Generic PHY* bindings
> >>>>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
> >>>>  
> >>>>  This is usually a subnode to DWC3 glue to which it is connected.
> >>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> >>>> index cfc16dd..ad7ce83 100644
> >>>> --- a/drivers/usb/dwc3/Kconfig
> >>>> +++ b/drivers/usb/dwc3/Kconfig
> >>>> @@ -3,6 +3,7 @@ config USB_DWC3
> >>>>  	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
> >>>>  	depends on EXTCON
> >>>>  	select USB_PHY
> >>>> +	select GENERIC_PHY
> >>>>  	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
> >>>>  	help
> >>>>  	  Say Y or M here if your system has a Dual Role SuperSpeed
> >>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> >>>> index 428c29e..485d365 100644
> >>>> --- a/drivers/usb/dwc3/core.c
> >>>> +++ b/drivers/usb/dwc3/core.c
> >>>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
> >>>>  
> >>>>  	usb_phy_init(dwc->usb2_phy);
> >>>>  	usb_phy_init(dwc->usb3_phy);
> >>>
> >>> How about adding
> >>> +	if (dwc->usb2_phy)
> >>> +		usb_phy_init(dwc->usb2_phy);
> >>> +	if (dwc->usb3_phy)
> >>> +		usb_phy_init(dwc->usb3_phy);
> >>
> >> Thankfully that usb_phy_init will check if phy is NULL.
> >>>
> >>> both usb phy and generic phy shouldn't be present together.
> >>
> >> ok.
> >>>
> >>>> +
> >>>> +	if (dwc->usb2_generic_phy)
> >>>> +		phy_init(dwc->usb2_generic_phy);
> >>>> +	if (dwc->usb3_generic_phy)
> >>>> +		phy_init(dwc->usb3_generic_phy);
> >>>> +
> >>>>  	mdelay(100);
> >>>>  
> >>>>  	/* Clear USB3 PHY reset */
> >>>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
> >>>>  {
> >>>>  	usb_phy_shutdown(dwc->usb2_phy);
> >>>>  	usb_phy_shutdown(dwc->usb3_phy);
> >>>
> >>> here as well
> >>>
> >>>> +
> >>>> +	if (dwc->usb2_generic_phy)
> >>>> +		phy_power_off(dwc->usb2_generic_phy);
> >>>> +	if (dwc->usb3_generic_phy)
> >>>> +		phy_power_off(dwc->usb3_generic_phy);
> >>>>  }
> >>>>  
> >>>>  #define DWC3_ALIGN_MASK		(16 - 1)
> >>>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
> >>>>  		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
> >>>>  	}
> >>>>  
> >>>> +	if (of_property_read_bool(node, "phys") || pdata->has_phy) {
> >>>> +		dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
> >>>> +		if (IS_ERR(dwc->usb2_generic_phy)) {
> >>>> +			dev_err(dev, "no usb2 phy configured yet");
> >>>> +			return PTR_ERR(dwc->usb2_generic_phy);
> >>>> +		}
> >>>> +
> >>>> +		dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
> >>>> +		if (IS_ERR(dwc->usb3_generic_phy)) {
> >>>> +			dev_err(dev, "no usb3 phy configured yet");
> >>>> +			return PTR_ERR(dwc->usb3_generic_phy);
> >>>> +		}
> >>>
> >>> better to add
> >>> +		/* Don't use USB PHY if generic PHY was found */
> >>> +		dwc->usb2_phy = dwc->usb3_phy = NULL;
> >>
> >> ok.
> >>>
> >>>> +	} else {
> >>>
> >>> not required as we've used kzalloc for dwc.
> >>>
> >>>> +		dwc->usb2_generic_phy = NULL;
> >>>> +		dwc->usb3_generic_phy = NULL;
> >>>> +	}
> >>>> +
> >>>>  	/* default to superspeed if no maximum_speed passed */
> >>>>  	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
> >>>>  		dwc->maximum_speed = USB_SPEED_SUPER;
> >>>> @@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)
> >>>
> >>> if (dwc->usb2_phy)
> >>>
> >>>>  	usb_phy_set_suspend(dwc->usb2_phy, 0);
> >>>
> >>> if (dwc->usb3_phy)
> >>>
> >>>>  	usb_phy_set_suspend(dwc->usb3_phy, 0);
> >>>>  
> >>>> +	if (dwc->usb2_generic_phy)
> >>>> +		phy_power_on(dwc->usb2_generic_phy);
> >>>> +	if (dwc->usb3_generic_phy)
> >>>> +		phy_power_on(dwc->usb3_generic_phy);
> >>>> +
> >>>>  	spin_lock_init(&dwc->lock);
> >>>>  	platform_set_drvdata(pdev, dwc);
> >>>>  
> >>>> @@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)
> >>>
> >>> if (dwc->usb2_phy)
> >>>>  	usb_phy_set_suspend(dwc->usb2_phy, 1);
> >>>
> >>> if (dwc->usb3_phy)
> >>>>  	usb_phy_set_suspend(dwc->usb3_phy, 1);
> >>>>  
> >>>> +	if (dwc->usb2_generic_phy)
> >>>> +		phy_power_off(dwc->usb2_generic_phy);
> >>>> +	if (dwc->usb3_generic_phy)
> >>>> +		phy_power_off(dwc->usb3_generic_phy);
> >>>> +
> >>>>  	pm_runtime_put(&pdev->dev);
> >>>>  	pm_runtime_disable(&pdev->dev);
> >>>>  
> >>>> @@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)
> >>>
> >>> if (dwc->usb3_phy)
> >>>>  	usb_phy_shutdown(dwc->usb3_phy);
> >>>
> >>> if (dwc->usb2_phy)
> >>>>  	usb_phy_shutdown(dwc->usb2_phy);
> >>>>  
> >>>> +	if (dwc->usb2_generic_phy)
> >>>> +		phy_exit(dwc->usb2_generic_phy);
> >>>> +	if (dwc->usb3_generic_phy)
> >>>> +		phy_exit(dwc->usb3_generic_phy);
> >>>> +
> >>>>  	return 0;
> >>>>  }
> >>>>  
> >>>> @@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
> >>>>  
> >>>
> >>> if (dwc->usb3_phy)
> >>>>  	usb_phy_init(dwc->usb3_phy);
> >>>
> >>> if (dwc->usb2_phy)
> >>>>  	usb_phy_init(dwc->usb2_phy);
> >>>> +
> >>>> +	if (dwc->usb2_generic_phy)
> >>>> +		phy_init(dwc->usb2_generic_phy);
> >>>> +	if (dwc->usb3_generic_phy)
> >>>> +		phy_init(dwc->usb3_generic_phy);
> >>>> +
> >>>>  	msleep(100);
> >>>>  
> >>>>  	spin_lock_irqsave(&dwc->lock, flags);
> >>>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> >>>> index f8af8d4..01ec7d7 100644
> >>>> --- a/drivers/usb/dwc3/core.h
> >>>> +++ b/drivers/usb/dwc3/core.h
> >>>> @@ -31,6 +31,8 @@
> >>>>  #include <linux/usb/gadget.h>
> >>>>  #include <linux/usb/otg.h>
> >>>>  
> >>>> +#include <linux/phy/phy.h>
> >>>> +
> >>>>  /* Global constants */
> >>>>  #define DWC3_EP0_BOUNCE_SIZE	512
> >>>>  #define DWC3_ENDPOINTS_NUM	32
> >>>> @@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
> >>>>   * @dr_mode: requested mode of operation
> >>>>   * @usb2_phy: pointer to USB2 PHY
> >>>>   * @usb3_phy: pointer to USB3 PHY
> >>>> + * @usb2_generic_phy: pointer to USB2 PHY
> >>>> + * @usb3_generic_phy: pointer to USB3 PHY
> >>>>   * @dcfg: saved contents of DCFG register
> >>>>   * @gctl: saved contents of GCTL register
> >>>>   * @is_selfpowered: true when we are selfpowered
> >>>> @@ -665,6 +669,9 @@ struct dwc3 {
> >>>>  	struct usb_phy		*usb2_phy;
> >>>>  	struct usb_phy		*usb3_phy;
> >>>>  
> >>>> +	struct phy		*usb2_generic_phy;
> >>>> +	struct phy		*usb3_generic_phy;
> >>>> +
> >>>>  	void __iomem		*regs;
> >>>>  	size_t			regs_size;
> >>>>  
> >>>>
> >>
> >> Do you have any suggestions on how to get only individual PHYs? like only
> >> usb2phy or usb3phy?
> > 
> > My earlier understanding was that both PHYs are needed only if .speed is "super-speed"
> > and only usb2phy is needed for "high-speed". But as per Vivek's email it seems
> > Samsung's exynos5 SoC doesn't need usb2phy for "super-speed".
> > 
> > So to keeps things flexible, I can propose the following approach
> > - if speed == 'high-speed' usb2phy must be present. usb3phy will be ignored if supplied.
> > - if speed == 'super-speed' usb3phy must be present and usb2phy is optional but must be
> > initialized if supplied.
> > - if speed is not specified, we default to 'super-speed'.
> > 
> > Felipe, does this address the issue you were facing with OMAP5?
> 
> IIRC, even if the speed is high speed, you still need to power on the USB3 PHY.
> Or else even high speed mode wasn't working in OMAP5.

right

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-15  7:57           ` Roger Quadros
@ 2013-10-15 12:00             ` Felipe Balbi
  0 siblings, 0 replies; 47+ messages in thread
From: Felipe Balbi @ 2013-10-15 12:00 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Kishon Vijay Abraham I, balbi, Vivek Gautam, bcousson, tony,
	rob.herring, pawel.moll, mark.rutland, linux, grant.likely,
	s.nawrocki, galak, swarren, ian.campbell, rob, george.cherian,
	gregkh, linux-doc, linux-omap, devicetree, linux-usb,
	linux-arm-kernel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 10767 bytes --]

On Tue, Oct 15, 2013 at 10:57:16AM +0300, Roger Quadros wrote:
> On 10/15/2013 08:31 AM, Kishon Vijay Abraham I wrote:
> > Hi Roger,
> > 
> > On Monday 14 October 2013 03:51 PM, Roger Quadros wrote:
> >> +Vivek
> >>
> >> On 10/14/2013 12:26 PM, Kishon Vijay Abraham I wrote:
> >>> Hi Roger,
> >>>
> >>> On Friday 11 October 2013 08:39 PM, Roger Quadros wrote:
> >>>> Hi,
> >>>>
> >>>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
> >>>>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
> >>>>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
> >>>>> phy_power_on() and phy_power_off().
> >>>>>
> >>>>> However using the old USB phy library wont be removed till the PHYs of all
> >>>>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
> >>>>>
> >>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> >>>>> ---
> >>>>>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
> >>>>>  drivers/usb/dwc3/Kconfig                       |    1 +
> >>>>>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
> >>>>>  drivers/usb/dwc3/core.h                        |    7 ++++
> >>>>>  4 files changed, 61 insertions(+), 2 deletions(-)
> >>>>>
> >>>>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
> >>>>> index e807635..471366d 100644
> >>>>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
> >>>>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
> >>>>> @@ -6,11 +6,13 @@ Required properties:
> >>>>>   - compatible: must be "snps,dwc3"
> >>>>>   - reg : Address and length of the register set for the device
> >>>>>   - interrupts: Interrupts used by the dwc3 controller.
> >>>>> +
> >>>>> +Optional properties:
> >>>>>   - usb-phy : array of phandle for the PHY device.  The first element
> >>>>>     in the array is expected to be a handle to the USB2/HS PHY and
> >>>>>     the second element is expected to be a handle to the USB3/SS PHY
> >>>>> -
> >>>>> -Optional properties:
> >>>>> + - phys: from the *Generic PHY* bindings
> >>>>> + - phy-names: from the *Generic PHY* bindings
> >>>>>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
> >>>>>  
> >>>>>  This is usually a subnode to DWC3 glue to which it is connected.
> >>>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> >>>>> index cfc16dd..ad7ce83 100644
> >>>>> --- a/drivers/usb/dwc3/Kconfig
> >>>>> +++ b/drivers/usb/dwc3/Kconfig
> >>>>> @@ -3,6 +3,7 @@ config USB_DWC3
> >>>>>  	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
> >>>>>  	depends on EXTCON
> >>>>>  	select USB_PHY
> >>>>> +	select GENERIC_PHY
> >>>>>  	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
> >>>>>  	help
> >>>>>  	  Say Y or M here if your system has a Dual Role SuperSpeed
> >>>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> >>>>> index 428c29e..485d365 100644
> >>>>> --- a/drivers/usb/dwc3/core.c
> >>>>> +++ b/drivers/usb/dwc3/core.c
> >>>>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
> >>>>>  
> >>>>>  	usb_phy_init(dwc->usb2_phy);
> >>>>>  	usb_phy_init(dwc->usb3_phy);
> >>>>
> >>>> How about adding
> >>>> +	if (dwc->usb2_phy)
> >>>> +		usb_phy_init(dwc->usb2_phy);
> >>>> +	if (dwc->usb3_phy)
> >>>> +		usb_phy_init(dwc->usb3_phy);
> >>>
> >>> Thankfully that usb_phy_init will check if phy is NULL.
> >>>>
> >>>> both usb phy and generic phy shouldn't be present together.
> >>>
> >>> ok.
> >>>>
> >>>>> +
> >>>>> +	if (dwc->usb2_generic_phy)
> >>>>> +		phy_init(dwc->usb2_generic_phy);
> >>>>> +	if (dwc->usb3_generic_phy)
> >>>>> +		phy_init(dwc->usb3_generic_phy);
> >>>>> +
> >>>>>  	mdelay(100);
> >>>>>  
> >>>>>  	/* Clear USB3 PHY reset */
> >>>>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
> >>>>>  {
> >>>>>  	usb_phy_shutdown(dwc->usb2_phy);
> >>>>>  	usb_phy_shutdown(dwc->usb3_phy);
> >>>>
> >>>> here as well
> >>>>
> >>>>> +
> >>>>> +	if (dwc->usb2_generic_phy)
> >>>>> +		phy_power_off(dwc->usb2_generic_phy);
> >>>>> +	if (dwc->usb3_generic_phy)
> >>>>> +		phy_power_off(dwc->usb3_generic_phy);
> >>>>>  }
> >>>>>  
> >>>>>  #define DWC3_ALIGN_MASK		(16 - 1)
> >>>>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
> >>>>>  		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
> >>>>>  	}
> >>>>>  
> >>>>> +	if (of_property_read_bool(node, "phys") || pdata->has_phy) {
> >>>>> +		dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
> >>>>> +		if (IS_ERR(dwc->usb2_generic_phy)) {
> >>>>> +			dev_err(dev, "no usb2 phy configured yet");
> >>>>> +			return PTR_ERR(dwc->usb2_generic_phy);
> >>>>> +		}
> >>>>> +
> >>>>> +		dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
> >>>>> +		if (IS_ERR(dwc->usb3_generic_phy)) {
> >>>>> +			dev_err(dev, "no usb3 phy configured yet");
> >>>>> +			return PTR_ERR(dwc->usb3_generic_phy);
> >>>>> +		}
> >>>>
> >>>> better to add
> >>>> +		/* Don't use USB PHY if generic PHY was found */
> >>>> +		dwc->usb2_phy = dwc->usb3_phy = NULL;
> >>>
> >>> ok.
> >>>>
> >>>>> +	} else {
> >>>>
> >>>> not required as we've used kzalloc for dwc.
> >>>>
> >>>>> +		dwc->usb2_generic_phy = NULL;
> >>>>> +		dwc->usb3_generic_phy = NULL;
> >>>>> +	}
> >>>>> +
> >>>>>  	/* default to superspeed if no maximum_speed passed */
> >>>>>  	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
> >>>>>  		dwc->maximum_speed = USB_SPEED_SUPER;
> >>>>> @@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)
> >>>>
> >>>> if (dwc->usb2_phy)
> >>>>
> >>>>>  	usb_phy_set_suspend(dwc->usb2_phy, 0);
> >>>>
> >>>> if (dwc->usb3_phy)
> >>>>
> >>>>>  	usb_phy_set_suspend(dwc->usb3_phy, 0);
> >>>>>  
> >>>>> +	if (dwc->usb2_generic_phy)
> >>>>> +		phy_power_on(dwc->usb2_generic_phy);
> >>>>> +	if (dwc->usb3_generic_phy)
> >>>>> +		phy_power_on(dwc->usb3_generic_phy);
> >>>>> +
> >>>>>  	spin_lock_init(&dwc->lock);
> >>>>>  	platform_set_drvdata(pdev, dwc);
> >>>>>  
> >>>>> @@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)
> >>>>
> >>>> if (dwc->usb2_phy)
> >>>>>  	usb_phy_set_suspend(dwc->usb2_phy, 1);
> >>>>
> >>>> if (dwc->usb3_phy)
> >>>>>  	usb_phy_set_suspend(dwc->usb3_phy, 1);
> >>>>>  
> >>>>> +	if (dwc->usb2_generic_phy)
> >>>>> +		phy_power_off(dwc->usb2_generic_phy);
> >>>>> +	if (dwc->usb3_generic_phy)
> >>>>> +		phy_power_off(dwc->usb3_generic_phy);
> >>>>> +
> >>>>>  	pm_runtime_put(&pdev->dev);
> >>>>>  	pm_runtime_disable(&pdev->dev);
> >>>>>  
> >>>>> @@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)
> >>>>
> >>>> if (dwc->usb3_phy)
> >>>>>  	usb_phy_shutdown(dwc->usb3_phy);
> >>>>
> >>>> if (dwc->usb2_phy)
> >>>>>  	usb_phy_shutdown(dwc->usb2_phy);
> >>>>>  
> >>>>> +	if (dwc->usb2_generic_phy)
> >>>>> +		phy_exit(dwc->usb2_generic_phy);
> >>>>> +	if (dwc->usb3_generic_phy)
> >>>>> +		phy_exit(dwc->usb3_generic_phy);
> >>>>> +
> >>>>>  	return 0;
> >>>>>  }
> >>>>>  
> >>>>> @@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
> >>>>>  
> >>>>
> >>>> if (dwc->usb3_phy)
> >>>>>  	usb_phy_init(dwc->usb3_phy);
> >>>>
> >>>> if (dwc->usb2_phy)
> >>>>>  	usb_phy_init(dwc->usb2_phy);
> >>>>> +
> >>>>> +	if (dwc->usb2_generic_phy)
> >>>>> +		phy_init(dwc->usb2_generic_phy);
> >>>>> +	if (dwc->usb3_generic_phy)
> >>>>> +		phy_init(dwc->usb3_generic_phy);
> >>>>> +
> >>>>>  	msleep(100);
> >>>>>  
> >>>>>  	spin_lock_irqsave(&dwc->lock, flags);
> >>>>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> >>>>> index f8af8d4..01ec7d7 100644
> >>>>> --- a/drivers/usb/dwc3/core.h
> >>>>> +++ b/drivers/usb/dwc3/core.h
> >>>>> @@ -31,6 +31,8 @@
> >>>>>  #include <linux/usb/gadget.h>
> >>>>>  #include <linux/usb/otg.h>
> >>>>>  
> >>>>> +#include <linux/phy/phy.h>
> >>>>> +
> >>>>>  /* Global constants */
> >>>>>  #define DWC3_EP0_BOUNCE_SIZE	512
> >>>>>  #define DWC3_ENDPOINTS_NUM	32
> >>>>> @@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
> >>>>>   * @dr_mode: requested mode of operation
> >>>>>   * @usb2_phy: pointer to USB2 PHY
> >>>>>   * @usb3_phy: pointer to USB3 PHY
> >>>>> + * @usb2_generic_phy: pointer to USB2 PHY
> >>>>> + * @usb3_generic_phy: pointer to USB3 PHY
> >>>>>   * @dcfg: saved contents of DCFG register
> >>>>>   * @gctl: saved contents of GCTL register
> >>>>>   * @is_selfpowered: true when we are selfpowered
> >>>>> @@ -665,6 +669,9 @@ struct dwc3 {
> >>>>>  	struct usb_phy		*usb2_phy;
> >>>>>  	struct usb_phy		*usb3_phy;
> >>>>>  
> >>>>> +	struct phy		*usb2_generic_phy;
> >>>>> +	struct phy		*usb3_generic_phy;
> >>>>> +
> >>>>>  	void __iomem		*regs;
> >>>>>  	size_t			regs_size;
> >>>>>  
> >>>>>
> >>>
> >>> Do you have any suggestions on how to get only individual PHYs? like only
> >>> usb2phy or usb3phy?
> >>
> >> My earlier understanding was that both PHYs are needed only if .speed is "super-speed"
> >> and only usb2phy is needed for "high-speed". But as per Vivek's email it seems
> >> Samsung's exynos5 SoC doesn't need usb2phy for "super-speed".
> >>
> >> So to keeps things flexible, I can propose the following approach
> >> - if speed == 'high-speed' usb2phy must be present. usb3phy will be ignored if supplied.
> >> - if speed == 'super-speed' usb3phy must be present and usb2phy is optional but must be
> >> initialized if supplied.
> >> - if speed is not specified, we default to 'super-speed'.
> >>
> >> Felipe, does this address the issue you were facing with OMAP5?
> > 
> > IIRC, even if the speed is high speed, you still need to power on the USB3 PHY.
> > Or else even high speed mode wasn't working in OMAP5.
> 
> Maybe for OMAP5 we can somehow indicate to dwc3 core code that only 'super-speed' mode
> is supported by the platform. I'm not aware of any OMAP5 platform using the USB port as 'high-speed'.
> 
> So there needs to be some mechanism for dwc3-<platform>.c to indicate
> to dwc3-core.c the speeds supported by the platform. e.g. via
> of_dev_auxdata through of_platform_populate()?

that's not the problem. We can temm dwc3 core that dwc3-omap supports
full, high and super speeds, but nothing prevents the user from passing
speed = highspeed on their DTS right ? Even for OMAP5. Now comes the
question, do we assume that's a broken DTB and don't support it ? Or do
we require nop xceiv for highspeed-only implementations ?

If you think of it, not wiring the superspeed side of a *superspeed*
controller is quite an abomination :-)

cheers

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-15 11:57         ` Felipe Balbi
@ 2013-10-15 12:10           ` Roger Quadros
  2013-10-15 13:19             ` Felipe Balbi
  0 siblings, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-10-15 12:10 UTC (permalink / raw)
  To: balbi
  Cc: Kishon Vijay Abraham I, Vivek Gautam, bcousson, tony,
	rob.herring, pawel.moll, mark.rutland, linux, grant.likely,
	s.nawrocki, galak, swarren, ian.campbell, rob, george.cherian,
	gregkh, linux-doc, linux-omap, devicetree, linux-usb,
	linux-arm-kernel, linux-kernel

On 10/15/2013 02:57 PM, Felipe Balbi wrote:
> Hi,
> 
> On Mon, Oct 14, 2013 at 01:21:29PM +0300, Roger Quadros wrote:
>> +Vivek
>>
>> On 10/14/2013 12:26 PM, Kishon Vijay Abraham I wrote:
>>> Hi Roger,
>>>
>>> On Friday 11 October 2013 08:39 PM, Roger Quadros wrote:
>>>> Hi,
>>>>
>>>> On 09/02/2013 06:43 PM, Kishon Vijay Abraham I wrote:
>>>>> Adapted dwc3 core to use the Generic PHY Framework. So for init, exit,
>>>>> power_on and power_off the following APIs are used phy_init(), phy_exit(),
>>>>> phy_power_on() and phy_power_off().
>>>>>
>>>>> However using the old USB phy library wont be removed till the PHYs of all
>>>>> other SoC's using dwc3 core is adapted to the Generic PHY Framework.
>>>>>
>>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>>> ---
>>>>>  Documentation/devicetree/bindings/usb/dwc3.txt |    6 ++-
>>>>>  drivers/usb/dwc3/Kconfig                       |    1 +
>>>>>  drivers/usb/dwc3/core.c                        |   49 ++++++++++++++++++++++++
>>>>>  drivers/usb/dwc3/core.h                        |    7 ++++
>>>>>  4 files changed, 61 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
>>>>> index e807635..471366d 100644
>>>>> --- a/Documentation/devicetree/bindings/usb/dwc3.txt
>>>>> +++ b/Documentation/devicetree/bindings/usb/dwc3.txt
>>>>> @@ -6,11 +6,13 @@ Required properties:
>>>>>   - compatible: must be "snps,dwc3"
>>>>>   - reg : Address and length of the register set for the device
>>>>>   - interrupts: Interrupts used by the dwc3 controller.
>>>>> +
>>>>> +Optional properties:
>>>>>   - usb-phy : array of phandle for the PHY device.  The first element
>>>>>     in the array is expected to be a handle to the USB2/HS PHY and
>>>>>     the second element is expected to be a handle to the USB3/SS PHY
>>>>> -
>>>>> -Optional properties:
>>>>> + - phys: from the *Generic PHY* bindings
>>>>> + - phy-names: from the *Generic PHY* bindings
>>>>>   - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
>>>>>  
>>>>>  This is usually a subnode to DWC3 glue to which it is connected.
>>>>> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
>>>>> index cfc16dd..ad7ce83 100644
>>>>> --- a/drivers/usb/dwc3/Kconfig
>>>>> +++ b/drivers/usb/dwc3/Kconfig
>>>>> @@ -3,6 +3,7 @@ config USB_DWC3
>>>>>  	depends on (USB || USB_GADGET) && GENERIC_HARDIRQS && HAS_DMA
>>>>>  	depends on EXTCON
>>>>>  	select USB_PHY
>>>>> +	select GENERIC_PHY
>>>>>  	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
>>>>>  	help
>>>>>  	  Say Y or M here if your system has a Dual Role SuperSpeed
>>>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>>>> index 428c29e..485d365 100644
>>>>> --- a/drivers/usb/dwc3/core.c
>>>>> +++ b/drivers/usb/dwc3/core.c
>>>>> @@ -82,6 +82,12 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
>>>>>  
>>>>>  	usb_phy_init(dwc->usb2_phy);
>>>>>  	usb_phy_init(dwc->usb3_phy);
>>>>
>>>> How about adding
>>>> +	if (dwc->usb2_phy)
>>>> +		usb_phy_init(dwc->usb2_phy);
>>>> +	if (dwc->usb3_phy)
>>>> +		usb_phy_init(dwc->usb3_phy);
>>>
>>> Thankfully that usb_phy_init will check if phy is NULL.
>>>>
>>>> both usb phy and generic phy shouldn't be present together.
>>>
>>> ok.
>>>>
>>>>> +
>>>>> +	if (dwc->usb2_generic_phy)
>>>>> +		phy_init(dwc->usb2_generic_phy);
>>>>> +	if (dwc->usb3_generic_phy)
>>>>> +		phy_init(dwc->usb3_generic_phy);
>>>>> +
>>>>>  	mdelay(100);
>>>>>  
>>>>>  	/* Clear USB3 PHY reset */
>>>>> @@ -343,6 +349,11 @@ static void dwc3_core_exit(struct dwc3 *dwc)
>>>>>  {
>>>>>  	usb_phy_shutdown(dwc->usb2_phy);
>>>>>  	usb_phy_shutdown(dwc->usb3_phy);
>>>>
>>>> here as well
>>>>
>>>>> +
>>>>> +	if (dwc->usb2_generic_phy)
>>>>> +		phy_power_off(dwc->usb2_generic_phy);
>>>>> +	if (dwc->usb3_generic_phy)
>>>>> +		phy_power_off(dwc->usb3_generic_phy);
>>>>>  }
>>>>>  
>>>>>  #define DWC3_ALIGN_MASK		(16 - 1)
>>>>> @@ -427,6 +438,23 @@ static int dwc3_probe(struct platform_device *pdev)
>>>>>  		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>>>>>  	}
>>>>>  
>>>>> +	if (of_property_read_bool(node, "phys") || pdata->has_phy) {
>>>>> +		dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
>>>>> +		if (IS_ERR(dwc->usb2_generic_phy)) {
>>>>> +			dev_err(dev, "no usb2 phy configured yet");
>>>>> +			return PTR_ERR(dwc->usb2_generic_phy);
>>>>> +		}
>>>>> +
>>>>> +		dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
>>>>> +		if (IS_ERR(dwc->usb3_generic_phy)) {
>>>>> +			dev_err(dev, "no usb3 phy configured yet");
>>>>> +			return PTR_ERR(dwc->usb3_generic_phy);
>>>>> +		}
>>>>
>>>> better to add
>>>> +		/* Don't use USB PHY if generic PHY was found */
>>>> +		dwc->usb2_phy = dwc->usb3_phy = NULL;
>>>
>>> ok.
>>>>
>>>>> +	} else {
>>>>
>>>> not required as we've used kzalloc for dwc.
>>>>
>>>>> +		dwc->usb2_generic_phy = NULL;
>>>>> +		dwc->usb3_generic_phy = NULL;
>>>>> +	}
>>>>> +
>>>>>  	/* default to superspeed if no maximum_speed passed */
>>>>>  	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
>>>>>  		dwc->maximum_speed = USB_SPEED_SUPER;
>>>>> @@ -450,6 +478,11 @@ static int dwc3_probe(struct platform_device *pdev)
>>>>
>>>> if (dwc->usb2_phy)
>>>>
>>>>>  	usb_phy_set_suspend(dwc->usb2_phy, 0);
>>>>
>>>> if (dwc->usb3_phy)
>>>>
>>>>>  	usb_phy_set_suspend(dwc->usb3_phy, 0);
>>>>>  
>>>>> +	if (dwc->usb2_generic_phy)
>>>>> +		phy_power_on(dwc->usb2_generic_phy);
>>>>> +	if (dwc->usb3_generic_phy)
>>>>> +		phy_power_on(dwc->usb3_generic_phy);
>>>>> +
>>>>>  	spin_lock_init(&dwc->lock);
>>>>>  	platform_set_drvdata(pdev, dwc);
>>>>>  
>>>>> @@ -576,6 +609,11 @@ static int dwc3_remove(struct platform_device *pdev)
>>>>
>>>> if (dwc->usb2_phy)
>>>>>  	usb_phy_set_suspend(dwc->usb2_phy, 1);
>>>>
>>>> if (dwc->usb3_phy)
>>>>>  	usb_phy_set_suspend(dwc->usb3_phy, 1);
>>>>>  
>>>>> +	if (dwc->usb2_generic_phy)
>>>>> +		phy_power_off(dwc->usb2_generic_phy);
>>>>> +	if (dwc->usb3_generic_phy)
>>>>> +		phy_power_off(dwc->usb3_generic_phy);
>>>>> +
>>>>>  	pm_runtime_put(&pdev->dev);
>>>>>  	pm_runtime_disable(&pdev->dev);
>>>>>  
>>>>> @@ -673,6 +711,11 @@ static int dwc3_suspend(struct device *dev)
>>>>
>>>> if (dwc->usb3_phy)
>>>>>  	usb_phy_shutdown(dwc->usb3_phy);
>>>>
>>>> if (dwc->usb2_phy)
>>>>>  	usb_phy_shutdown(dwc->usb2_phy);
>>>>>  
>>>>> +	if (dwc->usb2_generic_phy)
>>>>> +		phy_exit(dwc->usb2_generic_phy);
>>>>> +	if (dwc->usb3_generic_phy)
>>>>> +		phy_exit(dwc->usb3_generic_phy);
>>>>> +
>>>>>  	return 0;
>>>>>  }
>>>>>  
>>>>> @@ -683,6 +726,12 @@ static int dwc3_resume(struct device *dev)
>>>>>  
>>>>
>>>> if (dwc->usb3_phy)
>>>>>  	usb_phy_init(dwc->usb3_phy);
>>>>
>>>> if (dwc->usb2_phy)
>>>>>  	usb_phy_init(dwc->usb2_phy);
>>>>> +
>>>>> +	if (dwc->usb2_generic_phy)
>>>>> +		phy_init(dwc->usb2_generic_phy);
>>>>> +	if (dwc->usb3_generic_phy)
>>>>> +		phy_init(dwc->usb3_generic_phy);
>>>>> +
>>>>>  	msleep(100);
>>>>>  
>>>>>  	spin_lock_irqsave(&dwc->lock, flags);
>>>>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>>>>> index f8af8d4..01ec7d7 100644
>>>>> --- a/drivers/usb/dwc3/core.h
>>>>> +++ b/drivers/usb/dwc3/core.h
>>>>> @@ -31,6 +31,8 @@
>>>>>  #include <linux/usb/gadget.h>
>>>>>  #include <linux/usb/otg.h>
>>>>>  
>>>>> +#include <linux/phy/phy.h>
>>>>> +
>>>>>  /* Global constants */
>>>>>  #define DWC3_EP0_BOUNCE_SIZE	512
>>>>>  #define DWC3_ENDPOINTS_NUM	32
>>>>> @@ -613,6 +615,8 @@ struct dwc3_scratchpad_array {
>>>>>   * @dr_mode: requested mode of operation
>>>>>   * @usb2_phy: pointer to USB2 PHY
>>>>>   * @usb3_phy: pointer to USB3 PHY
>>>>> + * @usb2_generic_phy: pointer to USB2 PHY
>>>>> + * @usb3_generic_phy: pointer to USB3 PHY
>>>>>   * @dcfg: saved contents of DCFG register
>>>>>   * @gctl: saved contents of GCTL register
>>>>>   * @is_selfpowered: true when we are selfpowered
>>>>> @@ -665,6 +669,9 @@ struct dwc3 {
>>>>>  	struct usb_phy		*usb2_phy;
>>>>>  	struct usb_phy		*usb3_phy;
>>>>>  
>>>>> +	struct phy		*usb2_generic_phy;
>>>>> +	struct phy		*usb3_generic_phy;
>>>>> +
>>>>>  	void __iomem		*regs;
>>>>>  	size_t			regs_size;
>>>>>  
>>>>>
>>>
>>> Do you have any suggestions on how to get only individual PHYs? like only
>>> usb2phy or usb3phy?
>>
>> My earlier understanding was that both PHYs are needed only if .speed is "super-speed"
>> and only usb2phy is needed for "high-speed". But as per Vivek's email it seems
>> Samsung's exynos5 SoC doesn't need usb2phy for "super-speed".
>>
>> So to keeps things flexible, I can propose the following approach
>> - if speed == 'high-speed' usb2phy must be present. usb3phy will be ignored if supplied.
>> - if speed == 'super-speed' usb3phy must be present and usb2phy is optional but must be
>> initialized if supplied.
>> - if speed is not specified, we default to 'super-speed'.
>>
>> Felipe, does this address the issue you were facing with OMAP5?
> 
> on OMAP5 we cannot skip USB3 PHY initialization. But then it becomes a
> question of supporting a test feature (in OMAP5 case it would be cool to
> force controller to lower speeds for testing) or coping with a broken
> DTS.
> 

I don't think we can protect ourselves from all possible broken configurations of DTS.
I would vote for simplicity and maximum flexibility.

So IMO we should just depend on DTS to provide the phys that are needed by the platform.
In the driver we initialize whatever PHY is provided and don't complain if any or even all PHYs are missing.

If this is not good enough then could you please suggest an alternative? Thanks.

cheers,
-roger

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-15 12:10           ` Roger Quadros
@ 2013-10-15 13:19             ` Felipe Balbi
  2013-10-15 13:48               ` Roger Quadros
  0 siblings, 1 reply; 47+ messages in thread
From: Felipe Balbi @ 2013-10-15 13:19 UTC (permalink / raw)
  To: Roger Quadros
  Cc: balbi, Kishon Vijay Abraham I, Vivek Gautam, bcousson, tony,
	rob.herring, pawel.moll, mark.rutland, linux, grant.likely,
	s.nawrocki, galak, swarren, ian.campbell, rob, george.cherian,
	gregkh, linux-doc, linux-omap, devicetree, linux-usb,
	linux-arm-kernel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 6026 bytes --]

Hi,

On Tue, Oct 15, 2013 at 03:10:42PM +0300, Roger Quadros wrote:
> >>>>> @@ -665,6 +669,9 @@ struct dwc3 {
> >>>>>  	struct usb_phy		*usb2_phy;
> >>>>>  	struct usb_phy		*usb3_phy;
> >>>>>  
> >>>>> +	struct phy		*usb2_generic_phy;
> >>>>> +	struct phy		*usb3_generic_phy;
> >>>>> +
> >>>>>  	void __iomem		*regs;
> >>>>>  	size_t			regs_size;
> >>>>>  
> >>>>>
> >>>
> >>> Do you have any suggestions on how to get only individual PHYs? like only
> >>> usb2phy or usb3phy?
> >>
> >> My earlier understanding was that both PHYs are needed only if .speed is "super-speed"
> >> and only usb2phy is needed for "high-speed". But as per Vivek's email it seems
> >> Samsung's exynos5 SoC doesn't need usb2phy for "super-speed".
> >>
> >> So to keeps things flexible, I can propose the following approach
> >> - if speed == 'high-speed' usb2phy must be present. usb3phy will be ignored if supplied.
> >> - if speed == 'super-speed' usb3phy must be present and usb2phy is optional but must be
> >> initialized if supplied.
> >> - if speed is not specified, we default to 'super-speed'.
> >>
> >> Felipe, does this address the issue you were facing with OMAP5?
> > 
> > on OMAP5 we cannot skip USB3 PHY initialization. But then it becomes a
> > question of supporting a test feature (in OMAP5 case it would be cool to
> > force controller to lower speeds for testing) or coping with a broken
> > DTS.
> > 
> 
> I don't think we can protect ourselves from all possible broken
> configurations of DTS.
> I would vote for simplicity and maximum flexibility.
> 
> So IMO we should just depend on DTS to provide the phys that are
> needed by the platform.
> In the driver we initialize whatever PHY is provided and don't
> complain if any or even all PHYs are missing.

considering that DTS is an ABI, I really think eventually we *will* have
broken DTBs burned into ROM and we will have to find ways to work with
those too. Same thing already happens today with ACPI tables.

> If this is not good enough then could you please suggest an
> alternative? Thanks.

The alternative would be to mandate nop xceiv for the "missing" PHY, but
that doesn't solve anything, really, as DTS authors might still forget
about the NOP xceiv and you can argue that forcing NOP xceiv would be a
SW configuration.

So, perhaps we go with the approach that all PHYs are optional, and
here's my original patch which makes USB3 PHY optional:

commit 979b84f96e4b7559b596b2933ae198aba267f260
Author: Felipe Balbi <balbi@ti.com>
Date:   Sun Jun 30 18:39:23 2013 +0300

    usb: dwc3: core: make USB3 PHY optional
    
    If we want a port to work at any speed lower
    than Superspeed, it makes no sense to even
    initialize/power up the USB3 transceiver,
    provided it won't be used.
    
    We can use the oportunity to save some power
    and leave the superspeed transceiver powered
    off.
    
    There is at least one such case which is
    Texas Instruments' AM437x which has one
    of its USB3 ports without a matching USB3
    PHY (that port is hardwired to work on USB2
    only).
    
    Signed-off-by: Felipe Balbi <balbi@ti.com>

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 74f9cf0..7a5ab93 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -387,16 +387,34 @@ static int dwc3_probe(struct platform_device *pdev)
 	if (node) {
 		dwc->maximum_speed = of_usb_get_maximum_speed(node);
 
-		dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
-		dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
+		switch (dwc->maximum_speed) {
+		case USB_SPEED_SUPER:
+			dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
+			dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
+			break;
+		case USB_SPEED_HIGH:
+		case USB_SPEED_FULL:
+		case USB_SPEED_LOW:
+			dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
+			break;
+		}
 
 		dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
 		dwc->dr_mode = of_usb_get_dr_mode(node);
 	} else if (pdata) {
 		dwc->maximum_speed = pdata->maximum_speed;
 
-		dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
-		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
+		switch (dwc->maximum_speed) {
+		case USB_SPEED_SUPER:
+			dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
+			dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
+			break;
+		case USB_SPEED_HIGH:
+		case USB_SPEED_FULL:
+		case USB_SPEED_LOW:
+			dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
+			break;
+		}
 
 		dwc->needs_fifo_resize = pdata->tx_fifo_resize;
 		dwc->dr_mode = pdata->dr_mode;
@@ -424,19 +442,21 @@ static int dwc3_probe(struct platform_device *pdev)
 		return -EPROBE_DEFER;
 	}
 
-	if (IS_ERR(dwc->usb3_phy)) {
-		ret = PTR_ERR(dwc->usb3_phy);
+	if (dwc->maximum_speed == USB_SPEED_SUPER) {
+		if (IS_ERR(dwc->usb3_phy)) {
+			ret = PTR_ERR(dwc->usb3_phy);
 
-		/*
-		 * if -ENXIO is returned, it means PHY layer wasn't
-		 * enabled, so it makes no sense to return -EPROBE_DEFER
-		 * in that case, since no PHY driver will ever probe.
-		 */
-		if (ret == -ENXIO)
-			return ret;
+			/*
+			 * if -ENXIO is returned, it means PHY layer wasn't
+			 * enabled, so it makes no sense to return -EPROBE_DEFER
+			 * in that case, since no PHY driver will ever probe.
+			 */
+			if (ret == -ENXIO)
+				return ret;
 
-		dev_err(dev, "no usb3 phy configured\n");
-		return -EPROBE_DEFER;
+			dev_err(dev, "no usb3 phy configured\n");
+			return -EPROBE_DEFER;
+		}
 	}
 
 	dwc->xhci_resources[0].start = res->start;


what you guys are saying though, is that every PHY should be optional.

Do we have any device which doesn't provide USB2 PHY, only USB3 ? Dude,
that's so non-standard! USB *must* be backwards compatible so I'd expect
USB2 PHY to always be available.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-15 13:19             ` Felipe Balbi
@ 2013-10-15 13:48               ` Roger Quadros
  2013-10-15 13:56                 ` Felipe Balbi
  0 siblings, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-10-15 13:48 UTC (permalink / raw)
  To: balbi, Vivek Gautam
  Cc: Kishon Vijay Abraham I, bcousson, tony, rob.herring, pawel.moll,
	mark.rutland, linux, grant.likely, s.nawrocki, galak, swarren,
	ian.campbell, rob, george.cherian, gregkh, linux-doc, linux-omap,
	devicetree, linux-usb, linux-arm-kernel, linux-kernel

On 10/15/2013 04:19 PM, Felipe Balbi wrote:
> Hi,
> 
> On Tue, Oct 15, 2013 at 03:10:42PM +0300, Roger Quadros wrote:
>>>>>>> @@ -665,6 +669,9 @@ struct dwc3 {
>>>>>>>  	struct usb_phy		*usb2_phy;
>>>>>>>  	struct usb_phy		*usb3_phy;
>>>>>>>  
>>>>>>> +	struct phy		*usb2_generic_phy;
>>>>>>> +	struct phy		*usb3_generic_phy;
>>>>>>> +
>>>>>>>  	void __iomem		*regs;
>>>>>>>  	size_t			regs_size;
>>>>>>>  
>>>>>>>
>>>>>
>>>>> Do you have any suggestions on how to get only individual PHYs? like only
>>>>> usb2phy or usb3phy?
>>>>
>>>> My earlier understanding was that both PHYs are needed only if .speed is "super-speed"
>>>> and only usb2phy is needed for "high-speed". But as per Vivek's email it seems
>>>> Samsung's exynos5 SoC doesn't need usb2phy for "super-speed".
>>>>
>>>> So to keeps things flexible, I can propose the following approach
>>>> - if speed == 'high-speed' usb2phy must be present. usb3phy will be ignored if supplied.
>>>> - if speed == 'super-speed' usb3phy must be present and usb2phy is optional but must be
>>>> initialized if supplied.
>>>> - if speed is not specified, we default to 'super-speed'.
>>>>
>>>> Felipe, does this address the issue you were facing with OMAP5?
>>>
>>> on OMAP5 we cannot skip USB3 PHY initialization. But then it becomes a
>>> question of supporting a test feature (in OMAP5 case it would be cool to
>>> force controller to lower speeds for testing) or coping with a broken
>>> DTS.
>>>
>>
>> I don't think we can protect ourselves from all possible broken
>> configurations of DTS.
>> I would vote for simplicity and maximum flexibility.
>>
>> So IMO we should just depend on DTS to provide the phys that are
>> needed by the platform.
>> In the driver we initialize whatever PHY is provided and don't
>> complain if any or even all PHYs are missing.
> 
> considering that DTS is an ABI, I really think eventually we *will* have
> broken DTBs burned into ROM and we will have to find ways to work with
> those too. Same thing already happens today with ACPI tables.
> 
>> If this is not good enough then could you please suggest an
>> alternative? Thanks.
> 
> The alternative would be to mandate nop xceiv for the "missing" PHY, but
> that doesn't solve anything, really, as DTS authors might still forget
> about the NOP xceiv and you can argue that forcing NOP xceiv would be a
> SW configuration.
> 
> So, perhaps we go with the approach that all PHYs are optional, and
> here's my original patch which makes USB3 PHY optional:
> 
> commit 979b84f96e4b7559b596b2933ae198aba267f260
> Author: Felipe Balbi <balbi@ti.com>
> Date:   Sun Jun 30 18:39:23 2013 +0300
> 
>     usb: dwc3: core: make USB3 PHY optional
>     
>     If we want a port to work at any speed lower
>     than Superspeed, it makes no sense to even
>     initialize/power up the USB3 transceiver,
>     provided it won't be used.
>     
>     We can use the oportunity to save some power
>     and leave the superspeed transceiver powered
>     off.
>     
>     There is at least one such case which is
>     Texas Instruments' AM437x which has one
>     of its USB3 ports without a matching USB3
>     PHY (that port is hardwired to work on USB2
>     only).
>     
>     Signed-off-by: Felipe Balbi <balbi@ti.com>
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 74f9cf0..7a5ab93 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -387,16 +387,34 @@ static int dwc3_probe(struct platform_device *pdev)
>  	if (node) {
>  		dwc->maximum_speed = of_usb_get_maximum_speed(node);
>  
> -		dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
> -		dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
> +		switch (dwc->maximum_speed) {
> +		case USB_SPEED_SUPER:
> +			dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
> +			dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
> +			break;
> +		case USB_SPEED_HIGH:
> +		case USB_SPEED_FULL:
> +		case USB_SPEED_LOW:
> +			dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
> +			break;
> +		}
>  
>  		dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
>  		dwc->dr_mode = of_usb_get_dr_mode(node);
>  	} else if (pdata) {
>  		dwc->maximum_speed = pdata->maximum_speed;
>  
> -		dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
> -		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
> +		switch (dwc->maximum_speed) {
> +		case USB_SPEED_SUPER:
> +			dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
> +			dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
> +			break;
> +		case USB_SPEED_HIGH:
> +		case USB_SPEED_FULL:
> +		case USB_SPEED_LOW:
> +			dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
> +			break;
> +		}

What if we try to get both PHYs irrespective of 'maximum_speed' but based
on presence of phandle/pdata. That way there is some control in the adaptation code (dts/pdata)
as to which PHYs needs to be initialized for that particular instance.

This is because there doesn't seem to be a consensus between different designs.
e.g. omap5 needs both phys for 'high-speed' whereas exynos5250 needs just the
usb3 phy for 'super-speed'

>  
>  		dwc->needs_fifo_resize = pdata->tx_fifo_resize;
>  		dwc->dr_mode = pdata->dr_mode;
> @@ -424,19 +442,21 @@ static int dwc3_probe(struct platform_device *pdev)
>  		return -EPROBE_DEFER;
>  	}
>  
> -	if (IS_ERR(dwc->usb3_phy)) {
> -		ret = PTR_ERR(dwc->usb3_phy);
> +	if (dwc->maximum_speed == USB_SPEED_SUPER) {
> +		if (IS_ERR(dwc->usb3_phy)) {
> +			ret = PTR_ERR(dwc->usb3_phy);
>  
> -		/*
> -		 * if -ENXIO is returned, it means PHY layer wasn't
> -		 * enabled, so it makes no sense to return -EPROBE_DEFER
> -		 * in that case, since no PHY driver will ever probe.
> -		 */
> -		if (ret == -ENXIO)
> -			return ret;
> +			/*
> +			 * if -ENXIO is returned, it means PHY layer wasn't
> +			 * enabled, so it makes no sense to return -EPROBE_DEFER
> +			 * in that case, since no PHY driver will ever probe.
> +			 */
> +			if (ret == -ENXIO)
> +				return ret;
>  
> -		dev_err(dev, "no usb3 phy configured\n");
> -		return -EPROBE_DEFER;
> +			dev_err(dev, "no usb3 phy configured\n");
> +			return -EPROBE_DEFER;
> +		}
>  	}
>  
>  	dwc->xhci_resources[0].start = res->start;
> 
> 
> what you guys are saying though, is that every PHY should be optional.
> 
> Do we have any device which doesn't provide USB2 PHY, only USB3 ? Dude,
> that's so non-standard! USB *must* be backwards compatible so I'd expect
> USB2 PHY to always be available.
> 

Maybe the USB2 PHY hardware is there on the Exynos5250 but it just doesn't have discrete power control.
Vivek?

cheers,
-roger

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-15 13:48               ` Roger Quadros
@ 2013-10-15 13:56                 ` Felipe Balbi
  2013-10-15 14:03                   ` Roger Quadros
  0 siblings, 1 reply; 47+ messages in thread
From: Felipe Balbi @ 2013-10-15 13:56 UTC (permalink / raw)
  To: Roger Quadros
  Cc: balbi, Vivek Gautam, Kishon Vijay Abraham I, bcousson, tony,
	rob.herring, pawel.moll, mark.rutland, linux, grant.likely,
	s.nawrocki, galak, swarren, ian.campbell, rob, george.cherian,
	gregkh, linux-doc, linux-omap, devicetree, linux-usb,
	linux-arm-kernel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 7581 bytes --]

Hi,

On Tue, Oct 15, 2013 at 04:48:51PM +0300, Roger Quadros wrote:
> On 10/15/2013 04:19 PM, Felipe Balbi wrote:
> > Hi,
> > 
> > On Tue, Oct 15, 2013 at 03:10:42PM +0300, Roger Quadros wrote:
> >>>>>>> @@ -665,6 +669,9 @@ struct dwc3 {
> >>>>>>>  	struct usb_phy		*usb2_phy;
> >>>>>>>  	struct usb_phy		*usb3_phy;
> >>>>>>>  
> >>>>>>> +	struct phy		*usb2_generic_phy;
> >>>>>>> +	struct phy		*usb3_generic_phy;
> >>>>>>> +
> >>>>>>>  	void __iomem		*regs;
> >>>>>>>  	size_t			regs_size;
> >>>>>>>  
> >>>>>>>
> >>>>>
> >>>>> Do you have any suggestions on how to get only individual PHYs? like only
> >>>>> usb2phy or usb3phy?
> >>>>
> >>>> My earlier understanding was that both PHYs are needed only if .speed is "super-speed"
> >>>> and only usb2phy is needed for "high-speed". But as per Vivek's email it seems
> >>>> Samsung's exynos5 SoC doesn't need usb2phy for "super-speed".
> >>>>
> >>>> So to keeps things flexible, I can propose the following approach
> >>>> - if speed == 'high-speed' usb2phy must be present. usb3phy will be ignored if supplied.
> >>>> - if speed == 'super-speed' usb3phy must be present and usb2phy is optional but must be
> >>>> initialized if supplied.
> >>>> - if speed is not specified, we default to 'super-speed'.
> >>>>
> >>>> Felipe, does this address the issue you were facing with OMAP5?
> >>>
> >>> on OMAP5 we cannot skip USB3 PHY initialization. But then it becomes a
> >>> question of supporting a test feature (in OMAP5 case it would be cool to
> >>> force controller to lower speeds for testing) or coping with a broken
> >>> DTS.
> >>>
> >>
> >> I don't think we can protect ourselves from all possible broken
> >> configurations of DTS.
> >> I would vote for simplicity and maximum flexibility.
> >>
> >> So IMO we should just depend on DTS to provide the phys that are
> >> needed by the platform.
> >> In the driver we initialize whatever PHY is provided and don't
> >> complain if any or even all PHYs are missing.
> > 
> > considering that DTS is an ABI, I really think eventually we *will* have
> > broken DTBs burned into ROM and we will have to find ways to work with
> > those too. Same thing already happens today with ACPI tables.
> > 
> >> If this is not good enough then could you please suggest an
> >> alternative? Thanks.
> > 
> > The alternative would be to mandate nop xceiv for the "missing" PHY, but
> > that doesn't solve anything, really, as DTS authors might still forget
> > about the NOP xceiv and you can argue that forcing NOP xceiv would be a
> > SW configuration.
> > 
> > So, perhaps we go with the approach that all PHYs are optional, and
> > here's my original patch which makes USB3 PHY optional:
> > 
> > commit 979b84f96e4b7559b596b2933ae198aba267f260
> > Author: Felipe Balbi <balbi@ti.com>
> > Date:   Sun Jun 30 18:39:23 2013 +0300
> > 
> >     usb: dwc3: core: make USB3 PHY optional
> >     
> >     If we want a port to work at any speed lower
> >     than Superspeed, it makes no sense to even
> >     initialize/power up the USB3 transceiver,
> >     provided it won't be used.
> >     
> >     We can use the oportunity to save some power
> >     and leave the superspeed transceiver powered
> >     off.
> >     
> >     There is at least one such case which is
> >     Texas Instruments' AM437x which has one
> >     of its USB3 ports without a matching USB3
> >     PHY (that port is hardwired to work on USB2
> >     only).
> >     
> >     Signed-off-by: Felipe Balbi <balbi@ti.com>
> > 
> > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> > index 74f9cf0..7a5ab93 100644
> > --- a/drivers/usb/dwc3/core.c
> > +++ b/drivers/usb/dwc3/core.c
> > @@ -387,16 +387,34 @@ static int dwc3_probe(struct platform_device *pdev)
> >  	if (node) {
> >  		dwc->maximum_speed = of_usb_get_maximum_speed(node);
> >  
> > -		dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
> > -		dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
> > +		switch (dwc->maximum_speed) {
> > +		case USB_SPEED_SUPER:
> > +			dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
> > +			dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
> > +			break;
> > +		case USB_SPEED_HIGH:
> > +		case USB_SPEED_FULL:
> > +		case USB_SPEED_LOW:
> > +			dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
> > +			break;
> > +		}
> >  
> >  		dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
> >  		dwc->dr_mode = of_usb_get_dr_mode(node);
> >  	} else if (pdata) {
> >  		dwc->maximum_speed = pdata->maximum_speed;
> >  
> > -		dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
> > -		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
> > +		switch (dwc->maximum_speed) {
> > +		case USB_SPEED_SUPER:
> > +			dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
> > +			dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
> > +			break;
> > +		case USB_SPEED_HIGH:
> > +		case USB_SPEED_FULL:
> > +		case USB_SPEED_LOW:
> > +			dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
> > +			break;
> > +		}
> 
> What if we try to get both PHYs irrespective of 'maximum_speed' but based
> on presence of phandle/pdata. That way there is some control in the adaptation code (dts/pdata)
> as to which PHYs needs to be initialized for that particular instance.
> 
> This is because there doesn't seem to be a consensus between different designs.
> e.g. omap5 needs both phys for 'high-speed' whereas exynos5250 needs just the
> usb3 phy for 'super-speed'

sure, can you write such a patch ? If it gets to my inbox in a couple
hours I guess I can still review and take it upstream on v3.13,
otherwise it's only on v3.14 :-(

> 
> >  
> >  		dwc->needs_fifo_resize = pdata->tx_fifo_resize;
> >  		dwc->dr_mode = pdata->dr_mode;
> > @@ -424,19 +442,21 @@ static int dwc3_probe(struct platform_device *pdev)
> >  		return -EPROBE_DEFER;
> >  	}
> >  
> > -	if (IS_ERR(dwc->usb3_phy)) {
> > -		ret = PTR_ERR(dwc->usb3_phy);
> > +	if (dwc->maximum_speed == USB_SPEED_SUPER) {
> > +		if (IS_ERR(dwc->usb3_phy)) {
> > +			ret = PTR_ERR(dwc->usb3_phy);
> >  
> > -		/*
> > -		 * if -ENXIO is returned, it means PHY layer wasn't
> > -		 * enabled, so it makes no sense to return -EPROBE_DEFER
> > -		 * in that case, since no PHY driver will ever probe.
> > -		 */
> > -		if (ret == -ENXIO)
> > -			return ret;
> > +			/*
> > +			 * if -ENXIO is returned, it means PHY layer wasn't
> > +			 * enabled, so it makes no sense to return -EPROBE_DEFER
> > +			 * in that case, since no PHY driver will ever probe.
> > +			 */
> > +			if (ret == -ENXIO)
> > +				return ret;
> >  
> > -		dev_err(dev, "no usb3 phy configured\n");
> > -		return -EPROBE_DEFER;
> > +			dev_err(dev, "no usb3 phy configured\n");
> > +			return -EPROBE_DEFER;
> > +		}
> >  	}
> >  
> >  	dwc->xhci_resources[0].start = res->start;
> > 
> > 
> > what you guys are saying though, is that every PHY should be optional.
> > 
> > Do we have any device which doesn't provide USB2 PHY, only USB3 ? Dude,
> > that's so non-standard! USB *must* be backwards compatible so I'd expect
> > USB2 PHY to always be available.
> > 
> 
> Maybe the USB2 PHY hardware is there on the Exynos5250 but it just
> doesn't have discrete power control.  Vivek?

I'd really like to hear that answer :-) But patch can come before that,
though.

cheers

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-15 13:56                 ` Felipe Balbi
@ 2013-10-15 14:03                   ` Roger Quadros
  2013-10-15 14:12                     ` Felipe Balbi
  0 siblings, 1 reply; 47+ messages in thread
From: Roger Quadros @ 2013-10-15 14:03 UTC (permalink / raw)
  To: balbi
  Cc: Vivek Gautam, Kishon Vijay Abraham I, bcousson, tony,
	rob.herring, pawel.moll, mark.rutland, linux, grant.likely,
	s.nawrocki, galak, swarren, ian.campbell, rob, george.cherian,
	gregkh, linux-doc, linux-omap, devicetree, linux-usb,
	linux-arm-kernel, linux-kernel

On 10/15/2013 04:56 PM, Felipe Balbi wrote:
> Hi,
> 
> On Tue, Oct 15, 2013 at 04:48:51PM +0300, Roger Quadros wrote:
>> On 10/15/2013 04:19 PM, Felipe Balbi wrote:
>>> Hi,
>>>
>>> On Tue, Oct 15, 2013 at 03:10:42PM +0300, Roger Quadros wrote:
>>>>>>>>> @@ -665,6 +669,9 @@ struct dwc3 {
>>>>>>>>>  	struct usb_phy		*usb2_phy;
>>>>>>>>>  	struct usb_phy		*usb3_phy;
>>>>>>>>>  
>>>>>>>>> +	struct phy		*usb2_generic_phy;
>>>>>>>>> +	struct phy		*usb3_generic_phy;
>>>>>>>>> +
>>>>>>>>>  	void __iomem		*regs;
>>>>>>>>>  	size_t			regs_size;
>>>>>>>>>  
>>>>>>>>>
>>>>>>>
>>>>>>> Do you have any suggestions on how to get only individual PHYs? like only
>>>>>>> usb2phy or usb3phy?
>>>>>>
>>>>>> My earlier understanding was that both PHYs are needed only if .speed is "super-speed"
>>>>>> and only usb2phy is needed for "high-speed". But as per Vivek's email it seems
>>>>>> Samsung's exynos5 SoC doesn't need usb2phy for "super-speed".
>>>>>>
>>>>>> So to keeps things flexible, I can propose the following approach
>>>>>> - if speed == 'high-speed' usb2phy must be present. usb3phy will be ignored if supplied.
>>>>>> - if speed == 'super-speed' usb3phy must be present and usb2phy is optional but must be
>>>>>> initialized if supplied.
>>>>>> - if speed is not specified, we default to 'super-speed'.
>>>>>>
>>>>>> Felipe, does this address the issue you were facing with OMAP5?
>>>>>
>>>>> on OMAP5 we cannot skip USB3 PHY initialization. But then it becomes a
>>>>> question of supporting a test feature (in OMAP5 case it would be cool to
>>>>> force controller to lower speeds for testing) or coping with a broken
>>>>> DTS.
>>>>>
>>>>
>>>> I don't think we can protect ourselves from all possible broken
>>>> configurations of DTS.
>>>> I would vote for simplicity and maximum flexibility.
>>>>
>>>> So IMO we should just depend on DTS to provide the phys that are
>>>> needed by the platform.
>>>> In the driver we initialize whatever PHY is provided and don't
>>>> complain if any or even all PHYs are missing.
>>>
>>> considering that DTS is an ABI, I really think eventually we *will* have
>>> broken DTBs burned into ROM and we will have to find ways to work with
>>> those too. Same thing already happens today with ACPI tables.
>>>
>>>> If this is not good enough then could you please suggest an
>>>> alternative? Thanks.
>>>
>>> The alternative would be to mandate nop xceiv for the "missing" PHY, but
>>> that doesn't solve anything, really, as DTS authors might still forget
>>> about the NOP xceiv and you can argue that forcing NOP xceiv would be a
>>> SW configuration.
>>>
>>> So, perhaps we go with the approach that all PHYs are optional, and
>>> here's my original patch which makes USB3 PHY optional:
>>>
>>> commit 979b84f96e4b7559b596b2933ae198aba267f260
>>> Author: Felipe Balbi <balbi@ti.com>
>>> Date:   Sun Jun 30 18:39:23 2013 +0300
>>>
>>>     usb: dwc3: core: make USB3 PHY optional
>>>     
>>>     If we want a port to work at any speed lower
>>>     than Superspeed, it makes no sense to even
>>>     initialize/power up the USB3 transceiver,
>>>     provided it won't be used.
>>>     
>>>     We can use the oportunity to save some power
>>>     and leave the superspeed transceiver powered
>>>     off.
>>>     
>>>     There is at least one such case which is
>>>     Texas Instruments' AM437x which has one
>>>     of its USB3 ports without a matching USB3
>>>     PHY (that port is hardwired to work on USB2
>>>     only).
>>>     
>>>     Signed-off-by: Felipe Balbi <balbi@ti.com>
>>>
>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>> index 74f9cf0..7a5ab93 100644
>>> --- a/drivers/usb/dwc3/core.c
>>> +++ b/drivers/usb/dwc3/core.c
>>> @@ -387,16 +387,34 @@ static int dwc3_probe(struct platform_device *pdev)
>>>  	if (node) {
>>>  		dwc->maximum_speed = of_usb_get_maximum_speed(node);
>>>  
>>> -		dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
>>> -		dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
>>> +		switch (dwc->maximum_speed) {
>>> +		case USB_SPEED_SUPER:
>>> +			dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
>>> +			dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
>>> +			break;
>>> +		case USB_SPEED_HIGH:
>>> +		case USB_SPEED_FULL:
>>> +		case USB_SPEED_LOW:
>>> +			dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
>>> +			break;
>>> +		}
>>>  
>>>  		dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
>>>  		dwc->dr_mode = of_usb_get_dr_mode(node);
>>>  	} else if (pdata) {
>>>  		dwc->maximum_speed = pdata->maximum_speed;
>>>  
>>> -		dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
>>> -		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>>> +		switch (dwc->maximum_speed) {
>>> +		case USB_SPEED_SUPER:
>>> +			dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
>>> +			dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
>>> +			break;
>>> +		case USB_SPEED_HIGH:
>>> +		case USB_SPEED_FULL:
>>> +		case USB_SPEED_LOW:
>>> +			dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
>>> +			break;
>>> +		}
>>
>> What if we try to get both PHYs irrespective of 'maximum_speed' but based
>> on presence of phandle/pdata. That way there is some control in the adaptation code (dts/pdata)
>> as to which PHYs needs to be initialized for that particular instance.
>>
>> This is because there doesn't seem to be a consensus between different designs.
>> e.g. omap5 needs both phys for 'high-speed' whereas exynos5250 needs just the
>> usb3 phy for 'super-speed'
> 
> sure, can you write such a patch ? If it gets to my inbox in a couple
> hours I guess I can still review and take it upstream on v3.13,
> otherwise it's only on v3.14 :-(

As this patch from Kishon is already touching this area, it would be best if
he can send a v2 with this feature.

cheers,
-roger

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

* Re: [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework
  2013-10-15 14:03                   ` Roger Quadros
@ 2013-10-15 14:12                     ` Felipe Balbi
  0 siblings, 0 replies; 47+ messages in thread
From: Felipe Balbi @ 2013-10-15 14:12 UTC (permalink / raw)
  To: Roger Quadros
  Cc: balbi, Vivek Gautam, Kishon Vijay Abraham I, bcousson, tony,
	rob.herring, pawel.moll, mark.rutland, linux, grant.likely,
	s.nawrocki, galak, swarren, ian.campbell, rob, george.cherian,
	gregkh, linux-doc, linux-omap, devicetree, linux-usb,
	linux-arm-kernel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 6443 bytes --]

On Tue, Oct 15, 2013 at 05:03:50PM +0300, Roger Quadros wrote:
> On 10/15/2013 04:56 PM, Felipe Balbi wrote:
> > Hi,
> > 
> > On Tue, Oct 15, 2013 at 04:48:51PM +0300, Roger Quadros wrote:
> >> On 10/15/2013 04:19 PM, Felipe Balbi wrote:
> >>> Hi,
> >>>
> >>> On Tue, Oct 15, 2013 at 03:10:42PM +0300, Roger Quadros wrote:
> >>>>>>>>> @@ -665,6 +669,9 @@ struct dwc3 {
> >>>>>>>>>  	struct usb_phy		*usb2_phy;
> >>>>>>>>>  	struct usb_phy		*usb3_phy;
> >>>>>>>>>  
> >>>>>>>>> +	struct phy		*usb2_generic_phy;
> >>>>>>>>> +	struct phy		*usb3_generic_phy;
> >>>>>>>>> +
> >>>>>>>>>  	void __iomem		*regs;
> >>>>>>>>>  	size_t			regs_size;
> >>>>>>>>>  
> >>>>>>>>>
> >>>>>>>
> >>>>>>> Do you have any suggestions on how to get only individual PHYs? like only
> >>>>>>> usb2phy or usb3phy?
> >>>>>>
> >>>>>> My earlier understanding was that both PHYs are needed only if .speed is "super-speed"
> >>>>>> and only usb2phy is needed for "high-speed". But as per Vivek's email it seems
> >>>>>> Samsung's exynos5 SoC doesn't need usb2phy for "super-speed".
> >>>>>>
> >>>>>> So to keeps things flexible, I can propose the following approach
> >>>>>> - if speed == 'high-speed' usb2phy must be present. usb3phy will be ignored if supplied.
> >>>>>> - if speed == 'super-speed' usb3phy must be present and usb2phy is optional but must be
> >>>>>> initialized if supplied.
> >>>>>> - if speed is not specified, we default to 'super-speed'.
> >>>>>>
> >>>>>> Felipe, does this address the issue you were facing with OMAP5?
> >>>>>
> >>>>> on OMAP5 we cannot skip USB3 PHY initialization. But then it becomes a
> >>>>> question of supporting a test feature (in OMAP5 case it would be cool to
> >>>>> force controller to lower speeds for testing) or coping with a broken
> >>>>> DTS.
> >>>>>
> >>>>
> >>>> I don't think we can protect ourselves from all possible broken
> >>>> configurations of DTS.
> >>>> I would vote for simplicity and maximum flexibility.
> >>>>
> >>>> So IMO we should just depend on DTS to provide the phys that are
> >>>> needed by the platform.
> >>>> In the driver we initialize whatever PHY is provided and don't
> >>>> complain if any or even all PHYs are missing.
> >>>
> >>> considering that DTS is an ABI, I really think eventually we *will* have
> >>> broken DTBs burned into ROM and we will have to find ways to work with
> >>> those too. Same thing already happens today with ACPI tables.
> >>>
> >>>> If this is not good enough then could you please suggest an
> >>>> alternative? Thanks.
> >>>
> >>> The alternative would be to mandate nop xceiv for the "missing" PHY, but
> >>> that doesn't solve anything, really, as DTS authors might still forget
> >>> about the NOP xceiv and you can argue that forcing NOP xceiv would be a
> >>> SW configuration.
> >>>
> >>> So, perhaps we go with the approach that all PHYs are optional, and
> >>> here's my original patch which makes USB3 PHY optional:
> >>>
> >>> commit 979b84f96e4b7559b596b2933ae198aba267f260
> >>> Author: Felipe Balbi <balbi@ti.com>
> >>> Date:   Sun Jun 30 18:39:23 2013 +0300
> >>>
> >>>     usb: dwc3: core: make USB3 PHY optional
> >>>     
> >>>     If we want a port to work at any speed lower
> >>>     than Superspeed, it makes no sense to even
> >>>     initialize/power up the USB3 transceiver,
> >>>     provided it won't be used.
> >>>     
> >>>     We can use the oportunity to save some power
> >>>     and leave the superspeed transceiver powered
> >>>     off.
> >>>     
> >>>     There is at least one such case which is
> >>>     Texas Instruments' AM437x which has one
> >>>     of its USB3 ports without a matching USB3
> >>>     PHY (that port is hardwired to work on USB2
> >>>     only).
> >>>     
> >>>     Signed-off-by: Felipe Balbi <balbi@ti.com>
> >>>
> >>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> >>> index 74f9cf0..7a5ab93 100644
> >>> --- a/drivers/usb/dwc3/core.c
> >>> +++ b/drivers/usb/dwc3/core.c
> >>> @@ -387,16 +387,34 @@ static int dwc3_probe(struct platform_device *pdev)
> >>>  	if (node) {
> >>>  		dwc->maximum_speed = of_usb_get_maximum_speed(node);
> >>>  
> >>> -		dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
> >>> -		dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
> >>> +		switch (dwc->maximum_speed) {
> >>> +		case USB_SPEED_SUPER:
> >>> +			dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
> >>> +			dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
> >>> +			break;
> >>> +		case USB_SPEED_HIGH:
> >>> +		case USB_SPEED_FULL:
> >>> +		case USB_SPEED_LOW:
> >>> +			dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
> >>> +			break;
> >>> +		}
> >>>  
> >>>  		dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
> >>>  		dwc->dr_mode = of_usb_get_dr_mode(node);
> >>>  	} else if (pdata) {
> >>>  		dwc->maximum_speed = pdata->maximum_speed;
> >>>  
> >>> -		dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
> >>> -		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
> >>> +		switch (dwc->maximum_speed) {
> >>> +		case USB_SPEED_SUPER:
> >>> +			dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
> >>> +			dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
> >>> +			break;
> >>> +		case USB_SPEED_HIGH:
> >>> +		case USB_SPEED_FULL:
> >>> +		case USB_SPEED_LOW:
> >>> +			dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
> >>> +			break;
> >>> +		}
> >>
> >> What if we try to get both PHYs irrespective of 'maximum_speed' but based
> >> on presence of phandle/pdata. That way there is some control in the adaptation code (dts/pdata)
> >> as to which PHYs needs to be initialized for that particular instance.
> >>
> >> This is because there doesn't seem to be a consensus between different designs.
> >> e.g. omap5 needs both phys for 'high-speed' whereas exynos5250 needs just the
> >> usb3 phy for 'super-speed'
> > 
> > sure, can you write such a patch ? If it gets to my inbox in a couple
> > hours I guess I can still review and take it upstream on v3.13,
> > otherwise it's only on v3.14 :-(
> 
> As this patch from Kishon is already touching this area, it would be best if
> he can send a v2 with this feature.

Alright, and so I'll wait a little longer.

cheers

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

end of thread, other threads:[~2013-10-15 14:13 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-09-02 15:43 [PATCH 0/7] Make dwc3 use Generic PHY Framework and misc cleanup Kishon Vijay Abraham I
2013-09-02 15:43 ` [PATCH 1/7] usb: dwc3: get "usb_phy" only if the platform indicates the presence of PHY Kishon Vijay Abraham I
2013-09-12 10:36   ` Roger Quadros
2013-09-12 10:47     ` Vivek Gautam
2013-09-12 11:04       ` Roger Quadros
2013-09-12 11:26         ` Vivek Gautam
2013-09-12 13:11           ` Roger Quadros
2013-09-16  8:40             ` Vivek Gautam
2013-09-17 15:45       ` Felipe Balbi
2013-09-02 15:43 ` [PATCH 2/7] usb: dwc3: adapt dwc3 core to use Generic PHY Framework Kishon Vijay Abraham I
2013-09-12  9:27   ` Vivek Gautam
2013-09-12 10:10     ` Kishon Vijay Abraham I
2013-09-12 10:27       ` Vivek Gautam
2013-10-10 10:28         ` Kishon Vijay Abraham I
2013-09-12 13:19   ` Roger Quadros
2013-09-16  2:52     ` Kishon Vijay Abraham I
2013-09-16  7:25       ` Roger Quadros
2013-10-11 15:09   ` Roger Quadros
2013-10-14  9:26     ` Kishon Vijay Abraham I
2013-10-14 10:21       ` Roger Quadros
2013-10-15  5:31         ` Kishon Vijay Abraham I
2013-10-15  7:57           ` Roger Quadros
2013-10-15 12:00             ` Felipe Balbi
2013-10-15 11:58           ` Felipe Balbi
2013-10-15 11:57         ` Felipe Balbi
2013-10-15 12:10           ` Roger Quadros
2013-10-15 13:19             ` Felipe Balbi
2013-10-15 13:48               ` Roger Quadros
2013-10-15 13:56                 ` Felipe Balbi
2013-10-15 14:03                   ` Roger Quadros
2013-10-15 14:12                     ` Felipe Balbi
2013-09-02 15:43 ` [PATCH 3/7] drivers: phy: usb3/pipe3: Adapt pipe3 driver to " Kishon Vijay Abraham I
2013-09-12 11:19   ` Roger Quadros
2013-09-16  3:01     ` Kishon Vijay Abraham I
2013-09-16  7:37       ` Roger Quadros
2013-10-11 15:02         ` Roger Quadros
2013-10-14  9:19           ` Kishon Vijay Abraham I
2013-10-14  9:31             ` Roger Quadros
2013-09-02 15:43 ` [PATCH 4/7] Documentation: dt bindings: move ..usb/usb-phy.txt to ..phy/omap-phy.txt Kishon Vijay Abraham I
2013-09-12 13:23   ` Roger Quadros
2013-09-16  3:04     ` Kishon Vijay Abraham I
2013-09-02 15:43 ` [PATCH 5/7] phy: omap-usb2: move omap_usb.h from linux/usb/ to linux/phy/ Kishon Vijay Abraham I
2013-09-02 15:43 ` [PATCH 6/7] arm/dts: added dt properties to adapt to the new phy framwork Kishon Vijay Abraham I
2013-09-12 13:28   ` Roger Quadros
2013-09-02 15:43 ` [PATCH 7/7] drivers: phy: renamed struct omap_control_usb to struct omap_control_phy Kishon Vijay Abraham I
2013-09-12 13:42   ` Roger Quadros
2013-09-16  3:06     ` Kishon Vijay Abraham I

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).