linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] usb: dwc3: add dual-role support
@ 2017-01-23 11:19 ` Roger Quadros
  2017-01-23 11:19   ` [PATCH 1/8] usb: otg-fsm: Prevent build warning "VDBG" redefined Roger Quadros
                     ` (9 more replies)
  0 siblings, 10 replies; 15+ messages in thread
From: Roger Quadros @ 2017-01-23 11:19 UTC (permalink / raw)
  To: balbi, tony
  Cc: peter.chen, vivek.gautam, linux-usb, linux-omap, linux-kernel,
	Roger Quadros

Hi,

We rely on the OTG controller block to provide us with
VBUS and ID line status via an interrupt.

This is then used to switch the controller between host, peripheral
and idle roles based on the following table.

    ID  VBUS    dual-role state
    --  ----    ---------------
    0   x       A_HOST - Host controller active
    1   0       B_IDLE - Both Host and Gadget controllers inactive
    1   1       B_PERIPHERAL - Gadget controller active

Couple of things to clarify:
- There is a small window where we can potentially miss an
event related to OTG. I've added a comment in the code where this
could happen. How can we prevent this? Is it better to just leave
the OTG events unmasked (but keep otg_irq on ARM GIC disabled)
so that any new events can be captured by the OTG event register
and interrupt re-triggered if it has not been serviced by the
previous interrupt.
- I'm running the entire dual-role state change logic inside
the threaded interrupt handler with dwc->lock (spinlock) held
but IRQs enabled. OTG events are very rare i.e. manual intervention
so I don't see this as a problem. Just wanted to double check.
- Some SoC's (e.g. Qualcomm MSM) do not have the OTG controller block
but do have both host and peripheral controllers and so can operate
in dual role mode. Current series does not address this case.
We can get dual-role to work with such SoCs if core.c can get
information about ID and VBUS somehow (private interface
from parent or directly read extcon?).

cheers,
-roger

Roger Quadros (8):
  usb: otg-fsm: Prevent build warning "VDBG" redefined
  usb: dwc3-omap: Fix missing break in dwc3_omap_set_mailbox()
  usb: dwc3: use BIT() macro where possible
  usb: dwc3: core.h: add some register definitions
  usb: dwc3: add dual-role support
  ARM: dts: dra7x-evm: Enable dual-role mode for USB1
  ARM: dts: am43xx: Enable dual-role mode for USB1
  ARM: dts: am57xx-idk: Enable dual-role mode for USB2

 arch/arm/boot/dts/am437x-gp-evm.dts      |   2 +-
 arch/arm/boot/dts/am437x-sk-evm.dts      |   2 +-
 arch/arm/boot/dts/am43x-epos-evm.dts     |   2 +-
 arch/arm/boot/dts/am57xx-idk-common.dtsi |   2 +-
 arch/arm/boot/dts/dra7-evm.dts           |   2 +-
 arch/arm/boot/dts/dra72-evm-common.dtsi  |   2 +-
 drivers/usb/common/usb-otg-fsm.c         |   7 +
 drivers/usb/dwc3/core.c                  | 583 ++++++++++++++++++++++++++++++-
 drivers/usb/dwc3/core.h                  | 312 ++++++++++++-----
 drivers/usb/dwc3/dwc3-omap.c             |  49 +--
 drivers/usb/dwc3/gadget.c                |  18 +-
 drivers/usb/dwc3/gadget.h                |  20 +-
 drivers/usb/phy/phy-fsl-usb.c            |   7 +
 include/linux/usb/otg-fsm.h              |  15 -
 14 files changed, 848 insertions(+), 175 deletions(-)

-- 
2.7.4

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

* [PATCH 1/8] usb: otg-fsm: Prevent build warning "VDBG" redefined
  2017-01-23 11:19 ` [PATCH 0/8] usb: dwc3: add dual-role support Roger Quadros
@ 2017-01-23 11:19   ` Roger Quadros
  2017-01-23 11:19   ` [PATCH 2/8] usb: dwc3-omap: Fix missing break in dwc3_omap_set_mailbox() Roger Quadros
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Roger Quadros @ 2017-01-23 11:19 UTC (permalink / raw)
  To: balbi, tony
  Cc: peter.chen, vivek.gautam, linux-usb, linux-omap, linux-kernel,
	Roger Quadros

If usb/otg-fsm.h and usb/composite.h are included together
then it results in the build warning [1].

Prevent that by defining VDBG locally.

Also get rid of MPC_LOC which doesn't seem to be used
by anyone.

[1] - warning fixed by this patch:

In file included from drivers/usb/dwc3/core.h:33,
   from drivers/usb/dwc3/ep0.c:33:
   include/linux/usb/otg-fsm.h:30:1: warning: "VDBG" redefined
   In file included from drivers/usb/dwc3/ep0.c:31:
   include/linux/usb/composite.h:615:1: warning: this is the location
   of the previous definition

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Jun Li <jun.li@nxp.com>
Acked-by: Peter Chen <peter.chen@nxp.com>
---
 drivers/usb/common/usb-otg-fsm.c |  7 +++++++
 drivers/usb/phy/phy-fsl-usb.c    |  7 +++++++
 include/linux/usb/otg-fsm.h      | 15 ---------------
 3 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/usb/common/usb-otg-fsm.c b/drivers/usb/common/usb-otg-fsm.c
index 2f537bb..b8fe31e 100644
--- a/drivers/usb/common/usb-otg-fsm.c
+++ b/drivers/usb/common/usb-otg-fsm.c
@@ -31,6 +31,13 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/otg-fsm.h>
 
+#ifdef VERBOSE
+#define VDBG(fmt, args...) pr_debug("[%s]  " fmt, \
+				 __func__, ## args)
+#else
+#define VDBG(stuff...)	do {} while (0)
+#endif
+
 /* Change USB protocol when there is a protocol change */
 static int otg_set_protocol(struct otg_fsm *fsm, int protocol)
 {
diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c
index 94eb292..a8784ec 100644
--- a/drivers/usb/phy/phy-fsl-usb.c
+++ b/drivers/usb/phy/phy-fsl-usb.c
@@ -44,6 +44,13 @@
 
 #include "phy-fsl-usb.h"
 
+#ifdef VERBOSE
+#define VDBG(fmt, args...) pr_debug("[%s]  " fmt, \
+				 __func__, ## args)
+#else
+#define VDBG(stuff...)	do {} while (0)
+#endif
+
 #define DRIVER_VERSION "Rev. 1.55"
 #define DRIVER_AUTHOR "Jerry Huang/Li Yang"
 #define DRIVER_DESC "Freescale USB OTG Transceiver Driver"
diff --git a/include/linux/usb/otg-fsm.h b/include/linux/usb/otg-fsm.h
index 7a03505..a0a8f87 100644
--- a/include/linux/usb/otg-fsm.h
+++ b/include/linux/usb/otg-fsm.h
@@ -21,21 +21,6 @@
 #include <linux/mutex.h>
 #include <linux/errno.h>
 
-#undef VERBOSE
-
-#ifdef VERBOSE
-#define VDBG(fmt, args...) pr_debug("[%s]  " fmt , \
-				 __func__, ## args)
-#else
-#define VDBG(stuff...)	do {} while (0)
-#endif
-
-#ifdef VERBOSE
-#define MPC_LOC printk("Current Location [%s]:[%d]\n", __FILE__, __LINE__)
-#else
-#define MPC_LOC do {} while (0)
-#endif
-
 #define PROTO_UNDEF	(0)
 #define PROTO_HOST	(1)
 #define PROTO_GADGET	(2)
-- 
2.7.4

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

* [PATCH 2/8] usb: dwc3-omap: Fix missing break in dwc3_omap_set_mailbox()
  2017-01-23 11:19 ` [PATCH 0/8] usb: dwc3: add dual-role support Roger Quadros
  2017-01-23 11:19   ` [PATCH 1/8] usb: otg-fsm: Prevent build warning "VDBG" redefined Roger Quadros
@ 2017-01-23 11:19   ` Roger Quadros
  2017-01-23 11:19   ` [PATCH 3/8] usb: dwc3: use BIT() macro where possible Roger Quadros
                     ` (7 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Roger Quadros @ 2017-01-23 11:19 UTC (permalink / raw)
  To: balbi, tony
  Cc: peter.chen, vivek.gautam, linux-usb, linux-omap, linux-kernel,
	Roger Quadros

We need to break from all cases if we want to treat
each one of them separately.

Fixes: d2728fb3e01f ("usb: dwc3: omap: Pass VBUS and ID events transparently")
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/usb/dwc3/dwc3-omap.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index eb1b9cb..35b6351 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -250,6 +250,7 @@ static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
 		val = dwc3_omap_read_utmi_ctrl(omap);
 		val |= USBOTGSS_UTMI_OTG_CTRL_IDDIG;
 		dwc3_omap_write_utmi_ctrl(omap, val);
+		break;
 
 	case OMAP_DWC3_VBUS_OFF:
 		val = dwc3_omap_read_utmi_ctrl(omap);
-- 
2.7.4

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

* [PATCH 3/8] usb: dwc3: use BIT() macro where possible
  2017-01-23 11:19 ` [PATCH 0/8] usb: dwc3: add dual-role support Roger Quadros
  2017-01-23 11:19   ` [PATCH 1/8] usb: otg-fsm: Prevent build warning "VDBG" redefined Roger Quadros
  2017-01-23 11:19   ` [PATCH 2/8] usb: dwc3-omap: Fix missing break in dwc3_omap_set_mailbox() Roger Quadros
@ 2017-01-23 11:19   ` Roger Quadros
  2017-01-23 11:19   ` [PATCH 4/8] usb: dwc3: core.h: add some register definitions Roger Quadros
                     ` (6 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Roger Quadros @ 2017-01-23 11:19 UTC (permalink / raw)
  To: balbi, tony
  Cc: peter.chen, vivek.gautam, linux-usb, linux-omap, linux-kernel,
	Roger Quadros

To avoid checkpatch warnings with new patches let's
start using the BIT() macro wherever possible.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/usb/dwc3/core.h      | 192 +++++++++++++++++++++----------------------
 drivers/usb/dwc3/dwc3-omap.c |  48 +++++------
 drivers/usb/dwc3/gadget.h    |  20 ++---
 3 files changed, 130 insertions(+), 130 deletions(-)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 14b7602..d514dca 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -65,7 +65,7 @@
 #define DWC3_DEVICE_EVENT_OVERFLOW		11
 
 #define DWC3_GEVNTCOUNT_MASK	0xfffc
-#define DWC3_GEVNTCOUNT_EHB	(1 << 31)
+#define DWC3_GEVNTCOUNT_EHB	BIT(31)
 #define DWC3_GSNPSID_MASK	0xffff0000
 #define DWC3_GSNPSREV_MASK	0xffff
 
@@ -175,11 +175,11 @@
 /* Global RX Threshold Configuration Register */
 #define DWC3_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 19)
 #define DWC3_GRXTHRCFG_RXPKTCNT(n) (((n) & 0xf) << 24)
-#define DWC3_GRXTHRCFG_PKTCNTSEL (1 << 29)
+#define DWC3_GRXTHRCFG_PKTCNTSEL BIT(29)
 
 /* Global Configuration Register */
 #define DWC3_GCTL_PWRDNSCALE(n)	((n) << 19)
-#define DWC3_GCTL_U2RSTECN	(1 << 16)
+#define DWC3_GCTL_U2RSTECN	BIT(16)
 #define DWC3_GCTL_RAMCLKSEL(x)	(((x) & DWC3_GCTL_CLK_MASK) << 6)
 #define DWC3_GCTL_CLK_BUS	(0)
 #define DWC3_GCTL_CLK_PIPE	(1)
@@ -192,24 +192,24 @@
 #define DWC3_GCTL_PRTCAP_DEVICE	2
 #define DWC3_GCTL_PRTCAP_OTG	3
 
-#define DWC3_GCTL_CORESOFTRESET		(1 << 11)
-#define DWC3_GCTL_SOFITPSYNC		(1 << 10)
+#define DWC3_GCTL_CORESOFTRESET		BIT(11)
+#define DWC3_GCTL_SOFITPSYNC		BIT(10)
 #define DWC3_GCTL_SCALEDOWN(n)		((n) << 4)
 #define DWC3_GCTL_SCALEDOWN_MASK	DWC3_GCTL_SCALEDOWN(3)
-#define DWC3_GCTL_DISSCRAMBLE		(1 << 3)
-#define DWC3_GCTL_U2EXIT_LFPS		(1 << 2)
-#define DWC3_GCTL_GBLHIBERNATIONEN	(1 << 1)
-#define DWC3_GCTL_DSBLCLKGTNG		(1 << 0)
+#define DWC3_GCTL_DISSCRAMBLE		BIT(3)
+#define DWC3_GCTL_U2EXIT_LFPS		BIT(2)
+#define DWC3_GCTL_GBLHIBERNATIONEN	BIT(1)
+#define DWC3_GCTL_DSBLCLKGTNG		BIT(0)
 
 /* Global User Control 1 Register */
-#define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW	(1 << 24)
+#define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW	BIT(24)
 
 /* Global USB2 PHY Configuration Register */
-#define DWC3_GUSB2PHYCFG_PHYSOFTRST	(1 << 31)
-#define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS	(1 << 30)
-#define DWC3_GUSB2PHYCFG_SUSPHY		(1 << 6)
-#define DWC3_GUSB2PHYCFG_ULPI_UTMI	(1 << 4)
-#define DWC3_GUSB2PHYCFG_ENBLSLPM	(1 << 8)
+#define DWC3_GUSB2PHYCFG_PHYSOFTRST	BIT(31)
+#define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS	BIT(30)
+#define DWC3_GUSB2PHYCFG_SUSPHY		BIT(6)
+#define DWC3_GUSB2PHYCFG_ULPI_UTMI	BIT(4)
+#define DWC3_GUSB2PHYCFG_ENBLSLPM	BIT(8)
 #define DWC3_GUSB2PHYCFG_PHYIF(n)	(n << 3)
 #define DWC3_GUSB2PHYCFG_PHYIF_MASK	DWC3_GUSB2PHYCFG_PHYIF(1)
 #define DWC3_GUSB2PHYCFG_USBTRDTIM(n)	(n << 10)
@@ -220,25 +220,25 @@
 #define UTMI_PHYIF_8_BIT		0
 
 /* Global USB2 PHY Vendor Control Register */
-#define DWC3_GUSB2PHYACC_NEWREGREQ	(1 << 25)
-#define DWC3_GUSB2PHYACC_BUSY		(1 << 23)
-#define DWC3_GUSB2PHYACC_WRITE		(1 << 22)
+#define DWC3_GUSB2PHYACC_NEWREGREQ	BIT(25)
+#define DWC3_GUSB2PHYACC_BUSY		BIT(23)
+#define DWC3_GUSB2PHYACC_WRITE		BIT(22)
 #define DWC3_GUSB2PHYACC_ADDR(n)	(n << 16)
 #define DWC3_GUSB2PHYACC_EXTEND_ADDR(n)	(n << 8)
 #define DWC3_GUSB2PHYACC_DATA(n)	(n & 0xff)
 
 /* Global USB3 PIPE Control Register */
-#define DWC3_GUSB3PIPECTL_PHYSOFTRST	(1 << 31)
-#define DWC3_GUSB3PIPECTL_U2SSINP3OK	(1 << 29)
-#define DWC3_GUSB3PIPECTL_DISRXDETINP3	(1 << 28)
-#define DWC3_GUSB3PIPECTL_REQP1P2P3	(1 << 24)
+#define DWC3_GUSB3PIPECTL_PHYSOFTRST	BIT(31)
+#define DWC3_GUSB3PIPECTL_U2SSINP3OK	BIT(29)
+#define DWC3_GUSB3PIPECTL_DISRXDETINP3	BIT(28)
+#define DWC3_GUSB3PIPECTL_REQP1P2P3	BIT(24)
 #define DWC3_GUSB3PIPECTL_DEP1P2P3(n)	((n) << 19)
 #define DWC3_GUSB3PIPECTL_DEP1P2P3_MASK	DWC3_GUSB3PIPECTL_DEP1P2P3(7)
 #define DWC3_GUSB3PIPECTL_DEP1P2P3_EN	DWC3_GUSB3PIPECTL_DEP1P2P3(1)
-#define DWC3_GUSB3PIPECTL_DEPOCHANGE	(1 << 18)
-#define DWC3_GUSB3PIPECTL_SUSPHY	(1 << 17)
-#define DWC3_GUSB3PIPECTL_LFPSFILT	(1 << 9)
-#define DWC3_GUSB3PIPECTL_RX_DETOPOLL	(1 << 8)
+#define DWC3_GUSB3PIPECTL_DEPOCHANGE	BIT(18)
+#define DWC3_GUSB3PIPECTL_SUSPHY	BIT(17)
+#define DWC3_GUSB3PIPECTL_LFPSFILT	BIT(9)
+#define DWC3_GUSB3PIPECTL_RX_DETOPOLL	BIT(8)
 #define DWC3_GUSB3PIPECTL_TX_DEEPH_MASK	DWC3_GUSB3PIPECTL_TX_DEEPH(3)
 #define DWC3_GUSB3PIPECTL_TX_DEEPH(n)	((n) << 1)
 
@@ -247,7 +247,7 @@
 #define DWC3_GTXFIFOSIZ_TXFSTADDR(n)	((n) & 0xffff0000)
 
 /* Global Event Size Registers */
-#define DWC3_GEVNTSIZ_INTMASK		(1 << 31)
+#define DWC3_GEVNTSIZ_INTMASK		BIT(31)
 #define DWC3_GEVNTSIZ_SIZE(n)		((n) & 0xffff)
 
 /* Global HWPARAMS0 Register */
@@ -288,18 +288,18 @@
 #define DWC3_MAX_HIBER_SCRATCHBUFS		15
 
 /* Global HWPARAMS6 Register */
-#define DWC3_GHWPARAMS6_EN_FPGA			(1 << 7)
+#define DWC3_GHWPARAMS6_EN_FPGA			BIT(7)
 
 /* Global HWPARAMS7 Register */
 #define DWC3_GHWPARAMS7_RAM1_DEPTH(n)	((n) & 0xffff)
 #define DWC3_GHWPARAMS7_RAM2_DEPTH(n)	(((n) >> 16) & 0xffff)
 
 /* Global Frame Length Adjustment Register */
-#define DWC3_GFLADJ_30MHZ_SDBND_SEL		(1 << 7)
+#define DWC3_GFLADJ_30MHZ_SDBND_SEL		BIT(7)
 #define DWC3_GFLADJ_30MHZ_MASK			0x3f
 
 /* Global User Control Register 2 */
-#define DWC3_GUCTL2_RST_ACTBITLATER		(1 << 14)
+#define DWC3_GUCTL2_RST_ACTBITLATER		BIT(14)
 
 /* Device Configuration Register */
 #define DWC3_DCFG_DEVADDR(addr)	((addr) << 3)
@@ -309,23 +309,23 @@
 #define DWC3_DCFG_SUPERSPEED_PLUS (5 << 0)  /* DWC_usb31 only */
 #define DWC3_DCFG_SUPERSPEED	(4 << 0)
 #define DWC3_DCFG_HIGHSPEED	(0 << 0)
-#define DWC3_DCFG_FULLSPEED	(1 << 0)
+#define DWC3_DCFG_FULLSPEED	BIT(0)
 #define DWC3_DCFG_LOWSPEED	(2 << 0)
 
 #define DWC3_DCFG_NUMP_SHIFT	17
 #define DWC3_DCFG_NUMP(n)	(((n) >> DWC3_DCFG_NUMP_SHIFT) & 0x1f)
 #define DWC3_DCFG_NUMP_MASK	(0x1f << DWC3_DCFG_NUMP_SHIFT)
-#define DWC3_DCFG_LPM_CAP	(1 << 22)
+#define DWC3_DCFG_LPM_CAP	BIT(22)
 
 /* Device Control Register */
-#define DWC3_DCTL_RUN_STOP	(1 << 31)
-#define DWC3_DCTL_CSFTRST	(1 << 30)
-#define DWC3_DCTL_LSFTRST	(1 << 29)
+#define DWC3_DCTL_RUN_STOP	BIT(31)
+#define DWC3_DCTL_CSFTRST	BIT(30)
+#define DWC3_DCTL_LSFTRST	BIT(29)
 
 #define DWC3_DCTL_HIRD_THRES_MASK	(0x1f << 24)
 #define DWC3_DCTL_HIRD_THRES(n)	((n) << 24)
 
-#define DWC3_DCTL_APPL1RES	(1 << 23)
+#define DWC3_DCTL_APPL1RES	BIT(23)
 
 /* These apply for core versions 1.87a and earlier */
 #define DWC3_DCTL_TRGTULST_MASK		(0x0f << 17)
@@ -340,15 +340,15 @@
 #define DWC3_DCTL_LPM_ERRATA_MASK	DWC3_DCTL_LPM_ERRATA(0xf)
 #define DWC3_DCTL_LPM_ERRATA(n)		((n) << 20)
 
-#define DWC3_DCTL_KEEP_CONNECT		(1 << 19)
-#define DWC3_DCTL_L1_HIBER_EN		(1 << 18)
-#define DWC3_DCTL_CRS			(1 << 17)
-#define DWC3_DCTL_CSS			(1 << 16)
+#define DWC3_DCTL_KEEP_CONNECT		BIT(19)
+#define DWC3_DCTL_L1_HIBER_EN		BIT(18)
+#define DWC3_DCTL_CRS			BIT(17)
+#define DWC3_DCTL_CSS			BIT(16)
 
-#define DWC3_DCTL_INITU2ENA		(1 << 12)
-#define DWC3_DCTL_ACCEPTU2ENA		(1 << 11)
-#define DWC3_DCTL_INITU1ENA		(1 << 10)
-#define DWC3_DCTL_ACCEPTU1ENA		(1 << 9)
+#define DWC3_DCTL_INITU2ENA		BIT(12)
+#define DWC3_DCTL_ACCEPTU2ENA		BIT(11)
+#define DWC3_DCTL_INITU1ENA		BIT(10)
+#define DWC3_DCTL_ACCEPTU1ENA		BIT(9)
 #define DWC3_DCTL_TSTCTRL_MASK		(0xf << 1)
 
 #define DWC3_DCTL_ULSTCHNGREQ_MASK	(0x0f << 5)
@@ -363,36 +363,36 @@
 #define DWC3_DCTL_ULSTCHNG_LOOPBACK	(DWC3_DCTL_ULSTCHNGREQ(11))
 
 /* Device Event Enable Register */
-#define DWC3_DEVTEN_VNDRDEVTSTRCVEDEN	(1 << 12)
-#define DWC3_DEVTEN_EVNTOVERFLOWEN	(1 << 11)
-#define DWC3_DEVTEN_CMDCMPLTEN		(1 << 10)
-#define DWC3_DEVTEN_ERRTICERREN		(1 << 9)
-#define DWC3_DEVTEN_SOFEN		(1 << 7)
-#define DWC3_DEVTEN_EOPFEN		(1 << 6)
-#define DWC3_DEVTEN_HIBERNATIONREQEVTEN	(1 << 5)
-#define DWC3_DEVTEN_WKUPEVTEN		(1 << 4)
-#define DWC3_DEVTEN_ULSTCNGEN		(1 << 3)
-#define DWC3_DEVTEN_CONNECTDONEEN	(1 << 2)
-#define DWC3_DEVTEN_USBRSTEN		(1 << 1)
-#define DWC3_DEVTEN_DISCONNEVTEN	(1 << 0)
+#define DWC3_DEVTEN_VNDRDEVTSTRCVEDEN	BIT(12)
+#define DWC3_DEVTEN_EVNTOVERFLOWEN	BIT(11)
+#define DWC3_DEVTEN_CMDCMPLTEN		BIT(10)
+#define DWC3_DEVTEN_ERRTICERREN		BIT(9)
+#define DWC3_DEVTEN_SOFEN		BIT(7)
+#define DWC3_DEVTEN_EOPFEN		BIT(6)
+#define DWC3_DEVTEN_HIBERNATIONREQEVTEN	BIT(5)
+#define DWC3_DEVTEN_WKUPEVTEN		BIT(4)
+#define DWC3_DEVTEN_ULSTCNGEN		BIT(3)
+#define DWC3_DEVTEN_CONNECTDONEEN	BIT(2)
+#define DWC3_DEVTEN_USBRSTEN		BIT(1)
+#define DWC3_DEVTEN_DISCONNEVTEN	BIT(0)
 
 /* Device Status Register */
-#define DWC3_DSTS_DCNRD			(1 << 29)
+#define DWC3_DSTS_DCNRD			BIT(29)
 
 /* This applies for core versions 1.87a and earlier */
-#define DWC3_DSTS_PWRUPREQ		(1 << 24)
+#define DWC3_DSTS_PWRUPREQ		BIT(24)
 
 /* These apply for core versions 1.94a and later */
-#define DWC3_DSTS_RSS			(1 << 25)
-#define DWC3_DSTS_SSS			(1 << 24)
+#define DWC3_DSTS_RSS			BIT(25)
+#define DWC3_DSTS_SSS			BIT(24)
 
-#define DWC3_DSTS_COREIDLE		(1 << 23)
-#define DWC3_DSTS_DEVCTRLHLT		(1 << 22)
+#define DWC3_DSTS_COREIDLE		BIT(23)
+#define DWC3_DSTS_DEVCTRLHLT		BIT(22)
 
 #define DWC3_DSTS_USBLNKST_MASK		(0x0f << 18)
 #define DWC3_DSTS_USBLNKST(n)		(((n) & DWC3_DSTS_USBLNKST_MASK) >> 18)
 
-#define DWC3_DSTS_RXFIFOEMPTY		(1 << 17)
+#define DWC3_DSTS_RXFIFOEMPTY		BIT(17)
 
 #define DWC3_DSTS_SOFFN_MASK		(0x3fff << 3)
 #define DWC3_DSTS_SOFFN(n)		(((n) & DWC3_DSTS_SOFFN_MASK) >> 3)
@@ -402,7 +402,7 @@
 #define DWC3_DSTS_SUPERSPEED_PLUS	(5 << 0) /* DWC_usb31 only */
 #define DWC3_DSTS_SUPERSPEED		(4 << 0)
 #define DWC3_DSTS_HIGHSPEED		(0 << 0)
-#define DWC3_DSTS_FULLSPEED		(1 << 0)
+#define DWC3_DSTS_FULLSPEED		BIT(0)
 #define DWC3_DSTS_LOWSPEED		(2 << 0)
 
 /* Device Generic Command Register */
@@ -420,26 +420,26 @@
 #define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK	0x10
 
 #define DWC3_DGCMD_STATUS(n)		(((n) >> 12) & 0x0F)
-#define DWC3_DGCMD_CMDACT		(1 << 10)
-#define DWC3_DGCMD_CMDIOC		(1 << 8)
+#define DWC3_DGCMD_CMDACT		BIT(10)
+#define DWC3_DGCMD_CMDIOC		BIT(8)
 
 /* Device Generic Command Parameter Register */
-#define DWC3_DGCMDPAR_FORCE_LINKPM_ACCEPT	(1 << 0)
+#define DWC3_DGCMDPAR_FORCE_LINKPM_ACCEPT	BIT(0)
 #define DWC3_DGCMDPAR_FIFO_NUM(n)		((n) << 0)
 #define DWC3_DGCMDPAR_RX_FIFO			(0 << 5)
-#define DWC3_DGCMDPAR_TX_FIFO			(1 << 5)
+#define DWC3_DGCMDPAR_TX_FIFO			BIT(5)
 #define DWC3_DGCMDPAR_LOOPBACK_DIS		(0 << 0)
-#define DWC3_DGCMDPAR_LOOPBACK_ENA		(1 << 0)
+#define DWC3_DGCMDPAR_LOOPBACK_ENA		BIT(0)
 
 /* Device Endpoint Command Register */
 #define DWC3_DEPCMD_PARAM_SHIFT		16
 #define DWC3_DEPCMD_PARAM(x)		((x) << DWC3_DEPCMD_PARAM_SHIFT)
 #define DWC3_DEPCMD_GET_RSC_IDX(x)	(((x) >> DWC3_DEPCMD_PARAM_SHIFT) & 0x7f)
 #define DWC3_DEPCMD_STATUS(x)		(((x) >> 12) & 0x0F)
-#define DWC3_DEPCMD_HIPRI_FORCERM	(1 << 11)
-#define DWC3_DEPCMD_CLEARPENDIN		(1 << 11)
-#define DWC3_DEPCMD_CMDACT		(1 << 10)
-#define DWC3_DEPCMD_CMDIOC		(1 << 8)
+#define DWC3_DEPCMD_HIPRI_FORCERM	BIT(11)
+#define DWC3_DEPCMD_CLEARPENDIN		BIT(11)
+#define DWC3_DEPCMD_CMDACT		BIT(10)
+#define DWC3_DEPCMD_CMDIOC		BIT(8)
 
 #define DWC3_DEPCMD_DEPSTARTCFG		(0x09 << 0)
 #define DWC3_DEPCMD_ENDTRANSFER		(0x08 << 0)
@@ -457,7 +457,7 @@
 #define DWC3_DEPCMD_CMD(x)		((x) & 0xf)
 
 /* The EP number goes 0..31 so ep0 is always out and ep1 is always in */
-#define DWC3_DALEPENA_EP(n)		(1 << n)
+#define DWC3_DALEPENA_EP(n)		BIT(n)
 
 #define DWC3_DEPCMD_TYPE_CONTROL	0
 #define DWC3_DEPCMD_TYPE_ISOC		1
@@ -499,8 +499,8 @@ struct dwc3_event_buffer {
 	struct dwc3		*dwc;
 };
 
-#define DWC3_EP_FLAG_STALLED	(1 << 0)
-#define DWC3_EP_FLAG_WEDGED	(1 << 1)
+#define DWC3_EP_FLAG_STALLED	BIT(0)
+#define DWC3_EP_FLAG_WEDGED	BIT(1)
 
 #define DWC3_EP_DIRECTION_TX	true
 #define DWC3_EP_DIRECTION_RX	false
@@ -549,17 +549,17 @@ struct dwc3_ep {
 
 	u32			saved_state;
 	unsigned		flags;
-#define DWC3_EP_ENABLED		(1 << 0)
-#define DWC3_EP_STALL		(1 << 1)
-#define DWC3_EP_WEDGE		(1 << 2)
-#define DWC3_EP_BUSY		(1 << 4)
-#define DWC3_EP_PENDING_REQUEST	(1 << 5)
-#define DWC3_EP_MISSED_ISOC	(1 << 6)
-#define DWC3_EP_END_TRANSFER_PENDING	(1 << 7)
-#define DWC3_EP_TRANSFER_STARTED (1 << 8)
+#define DWC3_EP_ENABLED		BIT(0)
+#define DWC3_EP_STALL		BIT(1)
+#define DWC3_EP_WEDGE		BIT(2)
+#define DWC3_EP_BUSY		BIT(4)
+#define DWC3_EP_PENDING_REQUEST	BIT(5)
+#define DWC3_EP_MISSED_ISOC	BIT(6)
+#define DWC3_EP_END_TRANSFER_PENDING	BIT(7)
+#define DWC3_EP_TRANSFER_STARTED BIT(8)
 
 	/* This last one is specific to EP0 */
-#define DWC3_EP0_DIR_IN		(1 << 31)
+#define DWC3_EP0_DIR_IN		BIT(31)
 
 	/*
 	 * IMPORTANT: we *know* we have 256 TRBs in our @trb_pool, so we will
@@ -637,13 +637,13 @@ enum dwc3_link_state {
 #define DWC3_TRB_STS_XFER_IN_PROG	4
 
 /* TRB Control */
-#define DWC3_TRB_CTRL_HWO		(1 << 0)
-#define DWC3_TRB_CTRL_LST		(1 << 1)
-#define DWC3_TRB_CTRL_CHN		(1 << 2)
-#define DWC3_TRB_CTRL_CSP		(1 << 3)
+#define DWC3_TRB_CTRL_HWO		BIT(0)
+#define DWC3_TRB_CTRL_LST		BIT(1)
+#define DWC3_TRB_CTRL_CHN		BIT(2)
+#define DWC3_TRB_CTRL_CSP		BIT(3)
 #define DWC3_TRB_CTRL_TRBCTL(n)		(((n) & 0x3f) << 4)
-#define DWC3_TRB_CTRL_ISP_IMI		(1 << 10)
-#define DWC3_TRB_CTRL_IOC		(1 << 11)
+#define DWC3_TRB_CTRL_ISP_IMI		BIT(10)
+#define DWC3_TRB_CTRL_IOC		BIT(11)
 #define DWC3_TRB_CTRL_SID_SOFN(n)	(((n) & 0xffff) << 14)
 
 #define DWC3_TRBCTL_TYPE(n)		((n) & (0x3f << 4))
@@ -1049,13 +1049,13 @@ struct dwc3_event_depevt {
 	u32	status:4;
 
 /* Within XferNotReady */
-#define DEPEVT_STATUS_TRANSFER_ACTIVE	(1 << 3)
+#define DEPEVT_STATUS_TRANSFER_ACTIVE	BIT(3)
 
 /* Within XferComplete */
-#define DEPEVT_STATUS_BUSERR	(1 << 0)
-#define DEPEVT_STATUS_SHORT	(1 << 1)
-#define DEPEVT_STATUS_IOC	(1 << 2)
-#define DEPEVT_STATUS_LST	(1 << 3)
+#define DEPEVT_STATUS_BUSERR	BIT(0)
+#define DEPEVT_STATUS_SHORT	BIT(1)
+#define DEPEVT_STATUS_IOC	BIT(2)
+#define DEPEVT_STATUS_LST	BIT(3)
 
 /* Stream event only */
 #define DEPEVT_STREAMEVT_FOUND		1
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 35b6351..fe4efb8 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -79,40 +79,40 @@
 #define USBOTGSS_DEBUG_OFFSET			0x0600
 
 /* SYSCONFIG REGISTER */
-#define USBOTGSS_SYSCONFIG_DMADISABLE		(1 << 16)
+#define USBOTGSS_SYSCONFIG_DMADISABLE		BIT(16)
 
 /* IRQ_EOI REGISTER */
-#define USBOTGSS_IRQ_EOI_LINE_NUMBER		(1 << 0)
+#define USBOTGSS_IRQ_EOI_LINE_NUMBER		BIT(0)
 
 /* IRQS0 BITS */
-#define USBOTGSS_IRQO_COREIRQ_ST		(1 << 0)
+#define USBOTGSS_IRQO_COREIRQ_ST		BIT(0)
 
 /* IRQMISC BITS */
-#define USBOTGSS_IRQMISC_DMADISABLECLR		(1 << 17)
-#define USBOTGSS_IRQMISC_OEVT			(1 << 16)
-#define USBOTGSS_IRQMISC_DRVVBUS_RISE		(1 << 13)
-#define USBOTGSS_IRQMISC_CHRGVBUS_RISE		(1 << 12)
-#define USBOTGSS_IRQMISC_DISCHRGVBUS_RISE	(1 << 11)
-#define USBOTGSS_IRQMISC_IDPULLUP_RISE		(1 << 8)
-#define USBOTGSS_IRQMISC_DRVVBUS_FALL		(1 << 5)
-#define USBOTGSS_IRQMISC_CHRGVBUS_FALL		(1 << 4)
-#define USBOTGSS_IRQMISC_DISCHRGVBUS_FALL		(1 << 3)
-#define USBOTGSS_IRQMISC_IDPULLUP_FALL		(1 << 0)
+#define USBOTGSS_IRQMISC_DMADISABLECLR		BIT(17)
+#define USBOTGSS_IRQMISC_OEVT			BIT(16)
+#define USBOTGSS_IRQMISC_DRVVBUS_RISE		BIT(13)
+#define USBOTGSS_IRQMISC_CHRGVBUS_RISE		BIT(12)
+#define USBOTGSS_IRQMISC_DISCHRGVBUS_RISE	BIT(11)
+#define USBOTGSS_IRQMISC_IDPULLUP_RISE		BIT(8)
+#define USBOTGSS_IRQMISC_DRVVBUS_FALL		BIT(5)
+#define USBOTGSS_IRQMISC_CHRGVBUS_FALL		BIT(4)
+#define USBOTGSS_IRQMISC_DISCHRGVBUS_FALL		BIT(3)
+#define USBOTGSS_IRQMISC_IDPULLUP_FALL		BIT(0)
 
 /* UTMI_OTG_STATUS REGISTER */
-#define USBOTGSS_UTMI_OTG_STATUS_DRVVBUS	(1 << 5)
-#define USBOTGSS_UTMI_OTG_STATUS_CHRGVBUS	(1 << 4)
-#define USBOTGSS_UTMI_OTG_STATUS_DISCHRGVBUS	(1 << 3)
-#define USBOTGSS_UTMI_OTG_STATUS_IDPULLUP	(1 << 0)
+#define USBOTGSS_UTMI_OTG_STATUS_DRVVBUS	BIT(5)
+#define USBOTGSS_UTMI_OTG_STATUS_CHRGVBUS	BIT(4)
+#define USBOTGSS_UTMI_OTG_STATUS_DISCHRGVBUS	BIT(3)
+#define USBOTGSS_UTMI_OTG_STATUS_IDPULLUP	BIT(0)
 
 /* UTMI_OTG_CTRL REGISTER */
-#define USBOTGSS_UTMI_OTG_CTRL_SW_MODE		(1 << 31)
-#define USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT	(1 << 9)
-#define USBOTGSS_UTMI_OTG_CTRL_TXBITSTUFFENABLE (1 << 8)
-#define USBOTGSS_UTMI_OTG_CTRL_IDDIG		(1 << 4)
-#define USBOTGSS_UTMI_OTG_CTRL_SESSEND		(1 << 3)
-#define USBOTGSS_UTMI_OTG_CTRL_SESSVALID	(1 << 2)
-#define USBOTGSS_UTMI_OTG_CTRL_VBUSVALID	(1 << 1)
+#define USBOTGSS_UTMI_OTG_CTRL_SW_MODE		BIT(31)
+#define USBOTGSS_UTMI_OTG_CTRL_POWERPRESENT	BIT(9)
+#define USBOTGSS_UTMI_OTG_CTRL_TXBITSTUFFENABLE BIT(8)
+#define USBOTGSS_UTMI_OTG_CTRL_IDDIG		BIT(4)
+#define USBOTGSS_UTMI_OTG_CTRL_SESSEND		BIT(3)
+#define USBOTGSS_UTMI_OTG_CTRL_SESSVALID	BIT(2)
+#define USBOTGSS_UTMI_OTG_CTRL_VBUSVALID	BIT(1)
 
 struct dwc3_omap {
 	struct device		*dev;
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index 3129bcf..97f53de 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -29,16 +29,16 @@ struct dwc3;
 
 /* DEPCFG parameter 1 */
 #define DWC3_DEPCFG_INT_NUM(n)		((n) << 0)
-#define DWC3_DEPCFG_XFER_COMPLETE_EN	(1 << 8)
-#define DWC3_DEPCFG_XFER_IN_PROGRESS_EN	(1 << 9)
-#define DWC3_DEPCFG_XFER_NOT_READY_EN	(1 << 10)
-#define DWC3_DEPCFG_FIFO_ERROR_EN	(1 << 11)
-#define DWC3_DEPCFG_STREAM_EVENT_EN	(1 << 13)
+#define DWC3_DEPCFG_XFER_COMPLETE_EN	BIT(8)
+#define DWC3_DEPCFG_XFER_IN_PROGRESS_EN	BIT(9)
+#define DWC3_DEPCFG_XFER_NOT_READY_EN	BIT(10)
+#define DWC3_DEPCFG_FIFO_ERROR_EN	BIT(11)
+#define DWC3_DEPCFG_STREAM_EVENT_EN	BIT(13)
 #define DWC3_DEPCFG_BINTERVAL_M1(n)	((n) << 16)
-#define DWC3_DEPCFG_STREAM_CAPABLE	(1 << 24)
+#define DWC3_DEPCFG_STREAM_CAPABLE	BIT(24)
 #define DWC3_DEPCFG_EP_NUMBER(n)	((n) << 25)
-#define DWC3_DEPCFG_BULK_BASED		(1 << 30)
-#define DWC3_DEPCFG_FIFO_BASED		(1 << 31)
+#define DWC3_DEPCFG_BULK_BASED		BIT(30)
+#define DWC3_DEPCFG_FIFO_BASED		BIT(31)
 
 /* DEPCFG parameter 0 */
 #define DWC3_DEPCFG_EP_TYPE(n)		((n) << 1)
@@ -47,10 +47,10 @@ struct dwc3;
 #define DWC3_DEPCFG_BURST_SIZE(n)	((n) << 22)
 #define DWC3_DEPCFG_DATA_SEQ_NUM(n)	((n) << 26)
 /* This applies for core versions earlier than 1.94a */
-#define DWC3_DEPCFG_IGN_SEQ_NUM		(1 << 31)
+#define DWC3_DEPCFG_IGN_SEQ_NUM		BIT(31)
 /* These apply for core versions 1.94a and later */
 #define DWC3_DEPCFG_ACTION_INIT		(0 << 30)
-#define DWC3_DEPCFG_ACTION_RESTORE	(1 << 30)
+#define DWC3_DEPCFG_ACTION_RESTORE	BIT(30)
 #define DWC3_DEPCFG_ACTION_MODIFY	(2 << 30)
 
 /* DEPXFERCFG parameter 0 */
-- 
2.7.4

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

* [PATCH 4/8] usb: dwc3: core.h: add some register definitions
  2017-01-23 11:19 ` [PATCH 0/8] usb: dwc3: add dual-role support Roger Quadros
                     ` (2 preceding siblings ...)
  2017-01-23 11:19   ` [PATCH 3/8] usb: dwc3: use BIT() macro where possible Roger Quadros
@ 2017-01-23 11:19   ` Roger Quadros
  2017-01-23 11:19   ` [PATCH 5/8] usb: dwc3: add dual-role support Roger Quadros
                     ` (5 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Roger Quadros @ 2017-01-23 11:19 UTC (permalink / raw)
  To: balbi, tony
  Cc: peter.chen, vivek.gautam, linux-usb, linux-omap, linux-kernel,
	Roger Quadros

Add OTG and GHWPARAMS6 register definitions

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/usb/dwc3/core.h | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index d514dca..fc82d2e 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -204,6 +204,15 @@
 /* Global User Control 1 Register */
 #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW	BIT(24)
 
+/* Global Status Register */
+#define DWC3_GSTS_OTG_IP	BIT(10)
+#define DWC3_GSTS_BC_IP		BIT(9)
+#define DWC3_GSTS_ADP_IP	BIT(8)
+#define DWC3_GSTS_HOST_IP	BIT(7)
+#define DWC3_GSTS_DEVICE_IP	BIT(6)
+#define DWC3_GSTS_CSR_TIMEOUT	BIT(5)
+#define DWC3_GSTS_BUS_ERR_ADDR_VLD	BIT(4)
+
 /* Global USB2 PHY Configuration Register */
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST	BIT(31)
 #define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS	BIT(30)
@@ -288,6 +297,11 @@
 #define DWC3_MAX_HIBER_SCRATCHBUFS		15
 
 /* Global HWPARAMS6 Register */
+#define DWC3_GHWPARAMS6_BCSUPPORT		BIT(14)
+#define DWC3_GHWPARAMS6_OTG3SUPPORT		BIT(13)
+#define DWC3_GHWPARAMS6_ADPSUPPORT		BIT(12)
+#define DWC3_GHWPARAMS6_HNPSUPPORT		BIT(11)
+#define DWC3_GHWPARAMS6_SRPSUPPORT		BIT(10)
 #define DWC3_GHWPARAMS6_EN_FPGA			BIT(7)
 
 /* Global HWPARAMS7 Register */
@@ -469,6 +483,74 @@
 #define DWC3_DEV_IMOD_INTERVAL_SHIFT	0
 #define DWC3_DEV_IMOD_INTERVAL_MASK	(0xffff << 0)
 
+/* OTG Configuration Register */
+#define DWC3_OCFG_DISPWRCUTTOFF		BIT(5)
+#define DWC3_OCFG_HIBDISMASK		BIT(4)
+#define DWC3_OCFG_SFTRSTMASK		BIT(3)
+#define DWC3_OCFG_OTGVERSION		BIT(2)
+#define DWC3_OCFG_HNPCAP		BIT(1)
+#define DWC3_OCFG_SRPCAP		BIT(0)
+
+/* OTG CTL Register */
+#define DWC3_OCTL_OTG3GOERR		BIT(7)
+#define DWC3_OCTL_PERIMODE		BIT(6)
+#define DWC3_OCTL_PRTPWRCTL		BIT(5)
+#define DWC3_OCTL_HNPREQ		BIT(4)
+#define DWC3_OCTL_SESREQ		BIT(3)
+#define DWC3_OCTL_TERMSELIDPULSE	BIT(2)
+#define DWC3_OCTL_DEVSETHNPEN		BIT(1)
+#define DWC3_OCTL_HSTSETHNPEN		BIT(0)
+
+/* OTG Event Register */
+#define DWC3_OEVT_DEVICEMODE		BIT(31)
+#define DWC3_OEVT_XHCIRUNSTPSET		BIT(27)
+#define DWC3_OEVT_DEVRUNSTPSET		BIT(26)
+#define DWC3_OEVT_HIBENTRY		BIT(25)
+#define DWC3_OEVT_CONIDSTSCHNG		BIT(24)
+#define DWC3_OEVT_HRRCONFNOTIF		BIT(23)
+#define DWC3_OEVT_HRRINITNOTIF		BIT(22)
+#define DWC3_OEVT_ADEVIDLE		BIT(21)
+#define DWC3_OEVT_ADEVBHOSTEND		BIT(20)
+#define DWC3_OEVT_ADEVHOST		BIT(19)
+#define DWC3_OEVT_ADEVHNPCHNG		BIT(18)
+#define DWC3_OEVT_ADEVSRPDET		BIT(17)
+#define DWC3_OEVT_ADEVSESSENDDET	BIT(16)
+#define DWC3_OEVT_BDEVBHOSTEND		BIT(11)
+#define DWC3_OEVT_BDEVHNPCHNG		BIT(10)
+#define DWC3_OEVT_BDEVSESSVLDDET	BIT(9)
+#define DWC3_OEVT_BDEVVBUSCHNG		BIT(8)
+#define DWC3_OEVT_BSESSVLD		BIT(3)
+#define DWC3_OEVT_HSTNEGSTS		BIT(2)
+#define DWC3_OEVT_SESREQSTS		BIT(1)
+#define DWC3_OEVT_ERROR			BIT(0)
+
+/* OTG Event Enable Register */
+#define DWC3_OEVTEN_XHCIRUNSTPSETEN	BIT(27)
+#define DWC3_OEVTEN_DEVRUNSTPSETEN	BIT(26)
+#define DWC3_OEVTEN_HIBENTRYEN		BIT(25)
+#define DWC3_OEVTEN_CONIDSTSCHNGEN	BIT(24)
+#define DWC3_OEVTEN_HRRCONFNOTIFEN	BIT(23)
+#define DWC3_OEVTEN_HRRINITNOTIFEN	BIT(22)
+#define DWC3_OEVTEN_ADEVIDLEEN		BIT(21)
+#define DWC3_OEVTEN_ADEVBHOSTENDEN	BIT(20)
+#define DWC3_OEVTEN_ADEVHOSTEN		BIT(19)
+#define DWC3_OEVTEN_ADEVHNPCHNGEN	BIT(18)
+#define DWC3_OEVTEN_ADEVSRPDETEN	BIT(17)
+#define DWC3_OEVTEN_ADEVSESSENDDETEN	BIT(16)
+#define DWC3_OEVTEN_BDEVHOSTENDEN	BIT(11)
+#define DWC3_OEVTEN_BDEVHNPCHNGEN	BIT(10)
+#define DWC3_OEVTEN_BDEVSESSVLDDETEN	BIT(9)
+#define DWC3_OEVTEN_BDEVVBUSCHNGE	BIT(8)
+
+/* OTG Status Register */
+#define DWC3_OSTS_DEVRUNSTP		BIT(13)
+#define DWC3_OSTS_XHCIRUNSTP		BIT(12)
+#define DWC3_OSTS_PERIPHERALSTATE	BIT(4)
+#define DWC3_OSTS_XHCIPRTPOWER		BIT(3)
+#define DWC3_OSTS_BSESVLD		BIT(2)
+#define DWC3_OSTS_VBUSVLD		BIT(1)
+#define DWC3_OSTS_CONIDSTS		BIT(0)
+
 /* Structures */
 
 struct dwc3_trb;
-- 
2.7.4

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

* [PATCH 5/8] usb: dwc3: add dual-role support
  2017-01-23 11:19 ` [PATCH 0/8] usb: dwc3: add dual-role support Roger Quadros
                     ` (3 preceding siblings ...)
  2017-01-23 11:19   ` [PATCH 4/8] usb: dwc3: core.h: add some register definitions Roger Quadros
@ 2017-01-23 11:19   ` Roger Quadros
  2017-01-23 11:19   ` [PATCH 6/8] ARM: dts: dra7x-evm: Enable dual-role mode for USB1 Roger Quadros
                     ` (4 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Roger Quadros @ 2017-01-23 11:19 UTC (permalink / raw)
  To: balbi, tony
  Cc: peter.chen, vivek.gautam, linux-usb, linux-omap, linux-kernel,
	Roger Quadros

If dr_mode is "otg" then support dual role mode of operation.

Get ID and VBUS information from the OTG controller
and put the controller in the appropriate state.

This is our dual-role state table.

ID	VBUS	dual-role state
--	----	---------------
0	x	A_HOST - Host controller active
1	0	B_IDLE - Both Host and Gadget controllers inactive
1	1	B_PERIPHERAL - Gadget controller active

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/usb/dwc3/core.c   | 583 ++++++++++++++++++++++++++++++++++++++++++++--
 drivers/usb/dwc3/core.h   |  38 ++-
 drivers/usb/dwc3/gadget.c |  18 +-
 3 files changed, 615 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 369bab1..ca8b814 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -27,6 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/ioport.h>
 #include <linux/io.h>
 #include <linux/list.h>
@@ -107,6 +108,7 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
 	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
 	reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
 	reg |= DWC3_GCTL_PRTCAPDIR(mode);
+	dwc->current_mode = mode;
 	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
 }
 
@@ -839,6 +841,495 @@ static int dwc3_core_get_phy(struct dwc3 *dwc)
 	return 0;
 }
 
+static int dwc3_drd_start_host(struct dwc3 *dwc, int on);
+static int dwc3_drd_start_gadget(struct dwc3 *dwc, int on);
+
+/* dwc->lock must be held */
+static void dwc3_drd_statemachine(struct dwc3 *dwc, int id, int vbus)
+{
+	enum usb_otg_state new_state;
+	int protocol;
+
+	if (id == dwc->otg_fsm.id && vbus == dwc->otg_fsm.b_sess_vld)
+		return;
+
+	dwc->otg_fsm.id = id;
+	dwc->otg_fsm.b_sess_vld = vbus;
+
+	if (!id) {
+		new_state = OTG_STATE_A_HOST;
+	} else{
+		if (vbus)
+			new_state = OTG_STATE_B_PERIPHERAL;
+		else
+			new_state = OTG_STATE_B_IDLE;
+	}
+
+	if (dwc->otg.state == new_state)
+		return;
+
+	protocol = dwc->otg_fsm.protocol;
+	switch (new_state) {
+	case OTG_STATE_B_IDLE:
+		if (protocol == PROTO_GADGET)
+			dwc3_drd_start_gadget(dwc, 0);
+		else if (protocol == PROTO_HOST)
+			dwc3_drd_start_host(dwc, 0);
+		dwc->otg_fsm.protocol = PROTO_UNDEF;
+		break;
+	case OTG_STATE_B_PERIPHERAL:
+		if (protocol == PROTO_HOST)
+			dwc3_drd_start_host(dwc, 0);
+
+		if (protocol != PROTO_GADGET) {
+			dwc->otg_fsm.protocol = PROTO_GADGET;
+			dwc3_drd_start_gadget(dwc, 1);
+		}
+		break;
+	case OTG_STATE_A_HOST:
+		if (protocol == PROTO_GADGET)
+			dwc3_drd_start_gadget(dwc, 0);
+
+		if (protocol != PROTO_HOST) {
+			dwc->otg_fsm.protocol = PROTO_HOST;
+			dwc3_drd_start_host(dwc, 1);
+		}
+		break;
+	default:
+		dev_err(dwc->dev, "drd: invalid usb-drd state: %s\n",
+			usb_otg_state_string(new_state));
+		return;
+	}
+
+	dwc->otg.state = new_state;
+}
+
+/* dwc->lock must be held */
+static void dwc3_otg_fsm_sync(struct dwc3 *dwc)
+{
+	u32 reg, osts;
+	int id, vbus;
+
+	/*
+	 * calling dwc3_otg_fsm_sync() during resume breaks host
+	 * if adapter was removed during suspend as xhci driver
+	 * is not prepared to see hcd removal before xhci_resume.
+	 */
+	if (dwc->otg_prevent_sync)
+		return;
+
+	do {
+		reg = dwc3_readl(dwc->regs, DWC3_OSTS);
+
+		id = !!(reg & DWC3_OSTS_CONIDSTS);
+		vbus = !!(reg & DWC3_OSTS_BSESVLD);
+
+		dwc3_drd_statemachine(dwc, id, vbus);
+		osts = dwc3_readl(dwc->regs, DWC3_OSTS);
+		/*
+		 * OTG status might have changed and if we don't re-check
+		 * here we will loose events as OTG events have been
+		 * temporarily disabled.
+		 */
+		/* FIXME: there is still a small time window where we can
+		 * miss an OTG event. i.e. from here till where we enable the
+		 * OEVTEN in OTG IRQ thread handler. Try another solution
+		 * where OEVTEN can be enabled but otg irq in GIC is disabled.
+		 * so any OTG changes can re-trigger the OTG IRQ after current
+		 * ISR ends.
+		 */
+	} while (osts != reg);
+}
+
+static void dwc3_otg_mask_irq(struct dwc3 *dwc)
+{
+	dwc->oevten = dwc3_readl(dwc->regs, DWC3_OEVTEN);
+	dwc3_writel(dwc->regs, DWC3_OEVTEN, 0);
+}
+
+static void dwc3_otg_unmask_irq(struct dwc3 *dwc)
+{
+	dwc3_writel(dwc->regs, DWC3_OEVTEN, dwc->oevten);
+}
+
+static void dwc3_otg_disable_events(struct dwc3 *dwc, u32 disable_mask)
+{
+	dwc->oevten &= ~(disable_mask);
+	dwc3_writel(dwc->regs, DWC3_OEVTEN, dwc->oevten);
+}
+
+static void dwc3_otg_enable_events(struct dwc3 *dwc, u32 enable_mask)
+{
+	dwc->oevten |= (enable_mask);
+	dwc3_writel(dwc->regs, DWC3_OEVTEN, dwc->oevten);
+}
+
+#define DWC3_OTG_ALL_EVENTS	(DWC3_OEVTEN_XHCIRUNSTPSETEN | \
+		DWC3_OEVTEN_DEVRUNSTPSETEN | DWC3_OEVTEN_HIBENTRYEN | \
+		DWC3_OEVTEN_CONIDSTSCHNGEN | DWC3_OEVTEN_HRRCONFNOTIFEN | \
+		DWC3_OEVTEN_HRRINITNOTIFEN | DWC3_OEVTEN_ADEVIDLEEN | \
+		DWC3_OEVTEN_ADEVBHOSTENDEN | DWC3_OEVTEN_ADEVHOSTEN | \
+		DWC3_OEVTEN_ADEVHNPCHNGEN | DWC3_OEVTEN_ADEVSRPDETEN | \
+		DWC3_OEVTEN_ADEVSESSENDDETEN | DWC3_OEVTEN_BDEVHOSTENDEN | \
+		DWC3_OEVTEN_BDEVHNPCHNGEN | DWC3_OEVTEN_BDEVSESSVLDDETEN | \
+		DWC3_OEVTEN_BDEVVBUSCHNGE)
+
+static irqreturn_t dwc3_otg_thread_irq(int irq, void *_dwc)
+{
+	struct dwc3 *dwc = _dwc;
+
+	spin_lock(&dwc->lock);
+	dwc3_otg_fsm_sync(dwc);
+	dwc3_otg_unmask_irq(dwc);
+	spin_unlock(&dwc->lock);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t dwc3_otg_irq(int irq, void *_dwc)
+{
+	struct dwc3 *dwc = _dwc;
+	irqreturn_t ret = IRQ_NONE;
+	u32 reg;
+
+	reg = dwc3_readl(dwc->regs, DWC3_OEVT);
+	if (reg) {
+		dwc3_writel(dwc->regs, DWC3_OEVT, reg);
+		dwc3_otg_mask_irq(dwc);
+		ret = IRQ_WAKE_THREAD;
+	}
+
+	return ret;
+}
+
+/* --------------------- Dual-Role management ------------------------------- */
+static void dwc3_otgregs_init(struct dwc3 *dwc)
+{
+	u32 reg;
+
+	/*
+	 * Prevent host/device reset from resetting OTG core.
+	 * If we don't do this then xhci_reset (USBCMD.HCRST) will reset
+	 * the signal outputs sent to the PHY, the OTG FSM logic of the
+	 * core and also the resets to the VBUS filters inside the core.
+	 */
+	reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+	reg |= DWC3_OCFG_SFTRSTMASK;
+	dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+
+	/* Disable hibernation for simplicity */
+	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+	reg &= ~DWC3_GCTL_GBLHIBERNATIONEN;
+	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+
+	/*
+	 * Initialize OTG registers as per
+	 * Figure 11-4 OTG Driver Overall Programming Flow
+	 */
+	/* OCFG.SRPCap = 0, OCFG.HNPCap = 0 */
+	reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+	reg &= ~(DWC3_OCFG_SRPCAP | DWC3_OCFG_HNPCAP);
+	dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+	/* OEVT = FFFF */
+	dwc3_writel(dwc->regs, DWC3_OEVT, ~0);
+	/* OEVTEN = 0 */
+	dwc3_otg_disable_events(dwc, DWC3_OTG_ALL_EVENTS);
+	/* OEVTEN.ConIDStsChngEn = 1. Instead we enable all events */
+	dwc3_otg_enable_events(dwc, DWC3_OTG_ALL_EVENTS);
+	/*
+	 * OCTL.PeriMode = 1, OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0,
+	 * OCTL.HNPReq = 0
+	 */
+	reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+	reg |= DWC3_OCTL_PERIMODE;
+	reg &= ~(DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN |
+		 DWC3_OCTL_HNPREQ);
+	dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+}
+
+/* dwc->lock must be held */
+static int dwc3_drd_start_host(struct dwc3 *dwc, int on)
+{
+	u32 reg;
+
+	/* switch OTG core */
+	if (on) {
+		/* As per Figure 11-10 A-Device Flow Diagram */
+		/* OCFG.HNPCap = 0, OCFG.SRPCap = 0 */
+		reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+		reg &= ~(DWC3_OCFG_SRPCAP | DWC3_OCFG_HNPCAP);
+		dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+
+		/*
+		 * OCTL.PeriMode=0, OCTL.TermSelDLPulse = 0,
+		 * OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0
+		 */
+		reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+		reg &= ~(DWC3_OCTL_PERIMODE | DWC3_OCTL_TERMSELIDPULSE |
+			 DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN);
+		dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+
+		/*
+		 * OCFG.DisPrtPwrCutoff = 0/1
+		 */
+		reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+		reg &= ~DWC3_OCFG_DISPWRCUTTOFF;
+		dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+
+		/* start the xHCI host driver */
+		spin_unlock(&dwc->lock);
+		dwc3_host_init(dwc);
+		spin_lock(&dwc->lock);
+
+		/*
+		 * OCFG.SRPCap = 1, OCFG.HNPCap = GHWPARAMS6.HNP_CAP
+		 * We don't want SRP/HNP for simple dual-role so leave
+		 * these disabled.
+		 */
+
+		/*
+		 * OEVTEN.OTGADevHostEvntEn = 1
+		 * OEVTEN.OTGADevSessEndDetEvntEn = 1
+		 * We don't want HNP/role-swap so leave these disabled.
+		 */
+
+		/* GUSB2PHYCFG.ULPIAutoRes = 1/0, GUSB2PHYCFG.SusPHY = 1 */
+		if (!dwc->dis_u2_susphy_quirk) {
+			reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+			reg |= DWC3_GUSB2PHYCFG_SUSPHY;
+			dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+		}
+
+		/* Set Port Power to enable VBUS: OCTL.PrtPwrCtl = 1 */
+		reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+		reg |= DWC3_OCTL_PRTPWRCTL;
+		dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+	} else {
+		/*
+		 * Exit from A-device flow as per
+		 * Figure 11-4 OTG Driver Overall Programming Flow
+		 */
+		/* stop the HCD */
+		spin_unlock(&dwc->lock);
+		dwc3_host_exit(dwc);
+		spin_lock(&dwc->lock);
+
+		/*
+		 * OEVTEN.OTGADevBHostEndEvntEn=0, OEVTEN.OTGADevHNPChngEvntEn=0
+		 * OEVTEN.OTGADevSessEndDetEvntEn=0,
+		 * OEVTEN.OTGADevHostEvntEn = 0
+		 * But we don't disable any OTG events
+		 */
+
+		/* OCTL.HstSetHNPEn = 0, OCTL.PrtPwrCtl=0 */
+		reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+		reg &= ~(DWC3_OCTL_HSTSETHNPEN | DWC3_OCTL_PRTPWRCTL);
+		dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+
+		/* Initialize OTG registers */
+		dwc3_otgregs_init(dwc);
+	}
+
+	return 0;
+}
+
+/* dwc->lock must be held */
+static int dwc3_drd_start_gadget(struct dwc3 *dwc, int on)
+{
+	u32 reg;
+
+	if (on)
+		dwc3_event_buffers_setup(dwc);
+
+	if (on) {
+		/* As per Figure 11-20 B-Device Flow Diagram */
+
+		/*
+		 * OCFG.HNPCap = GHWPARAMS6.HNP_CAP, OCFG.SRPCap = 1
+		 * but we set them to 0 for simple dual-role operation.
+		 */
+		reg = dwc3_readl(dwc->regs, DWC3_OCFG);
+		reg &= ~(DWC3_OCFG_SRPCAP | DWC3_OCFG_HNPCAP);
+		/* OCFG.OTGSftRstMsk = 0/1 */
+		reg |= DWC3_OCFG_SFTRSTMASK;
+		dwc3_writel(dwc->regs, DWC3_OCFG, reg);
+		/*
+		 * OCTL.PeriMode = 1
+		 * OCTL.TermSelDLPulse = 0/1, OCTL.HNPReq = 0
+		 * OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0
+		 */
+		reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+		reg |= DWC3_OCTL_PERIMODE;
+		reg &= ~(DWC3_OCTL_TERMSELIDPULSE | DWC3_OCTL_HNPREQ |
+			 DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN);
+		dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+		/* OEVTEN.OTGBDevSesVldDetEvntEn = 1 */
+		dwc3_otg_enable_events(dwc, DWC3_OEVT_BDEVSESSVLDDET);
+		/* GUSB2PHYCFG.ULPIAutoRes = 0, GUSB2PHYCFG0.SusPHY = 1 */
+		if (!dwc->dis_u2_susphy_quirk) {
+			reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+			reg |= DWC3_GUSB2PHYCFG_SUSPHY;
+			dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+		}
+		/* GCTL.GblHibernationEn = 0 */
+		reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+		reg &= ~DWC3_GCTL_GBLHIBERNATIONEN;
+		dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+
+		/* start the Peripheral driver  */
+		if (dwc->gadget_driver) {
+			__dwc3_gadget_start(dwc);
+			if (dwc->gadget_pullup)
+				dwc3_gadget_run_stop(dwc, true, false);
+		}
+	} else {
+		/*
+		 * Exit from B-device flow as per
+		 * Figure 11-4 OTG Driver Overall Programming Flow
+		 */
+		/* stop the Peripheral driver */
+		if (dwc->gadget_driver) {
+			if (dwc->gadget_pullup)
+				dwc3_gadget_run_stop(dwc, false, false);
+			spin_unlock(&dwc->lock);
+			if (dwc->gadget_driver->disconnect)
+				dwc->gadget_driver->disconnect(&dwc->gadget);
+			spin_lock(&dwc->lock);
+			__dwc3_gadget_stop(dwc);
+		}
+
+		/*
+		 * OEVTEN.OTGBDevHNPChngEvntEn = 0
+		 * OEVTEN.OTGBDevVBusChngEvntEn = 0
+		 * OEVTEN.OTGBDevBHostEndEvntEn = 0
+		 */
+		reg = dwc3_readl(dwc->regs, DWC3_OEVTEN);
+		reg &= ~(DWC3_OEVT_BDEVHNPCHNG | DWC3_OEVT_BDEVVBUSCHNG |
+			 DWC3_OEVT_BDEVBHOSTEND);
+		dwc3_writel(dwc->regs, DWC3_OEVTEN, reg);
+
+		/* OCTL.DevSetHNPEn = 0, OCTL.HNPReq = 0, OCTL.PeriMode=1 */
+		reg = dwc3_readl(dwc->regs, DWC3_OCTL);
+		reg &= ~(DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HNPREQ);
+		reg |= DWC3_OCTL_PERIMODE;
+		dwc3_writel(dwc->regs, DWC3_OCTL, reg);
+
+		/* Initialize OTG registers */
+		dwc3_otgregs_init(dwc);
+	}
+
+	return 0;
+}
+
+static int dwc3_otg_get_irq(struct dwc3 *dwc)
+{
+	struct platform_device *dwc3_pdev = to_platform_device(dwc->dev);
+	int irq;
+
+	irq = platform_get_irq_byname(dwc3_pdev, "otg");
+	if (irq > 0)
+		goto out;
+
+	if (irq == -EPROBE_DEFER)
+		goto out;
+
+	irq = platform_get_irq_byname(dwc3_pdev, "dwc_usb3");
+	if (irq > 0)
+		goto out;
+
+	if (irq == -EPROBE_DEFER)
+		goto out;
+
+	irq = platform_get_irq(dwc3_pdev, 0);
+	if (irq > 0)
+		goto out;
+
+	if (irq != -EPROBE_DEFER)
+		dev_err(dwc->dev, "missing otg IRQ\n");
+
+	if (!irq)
+		irq = -EINVAL;
+
+out:
+	return irq;
+}
+
+static int dwc3_drd_init(struct dwc3 *dwc)
+{
+	int ret, irq;
+	u32 reg;
+	unsigned long flags;
+
+	irq = dwc3_otg_get_irq(dwc);
+	if (irq < 0)
+		return irq;
+
+	dwc->otg_irq = irq;
+
+	/* disable all otg irqs */
+	dwc3_otg_disable_events(dwc, DWC3_OTG_ALL_EVENTS);
+	/* clear all events */
+	dwc3_writel(dwc->regs, DWC3_OEVT, ~0);
+
+	irq_set_status_flags(dwc->otg_irq, IRQ_NOAUTOEN);
+	ret = request_threaded_irq(dwc->otg_irq, dwc3_otg_irq,
+				   dwc3_otg_thread_irq,
+				   IRQF_SHARED, "dwc3-otg", dwc);
+	if (ret) {
+		dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
+			dwc->otg_irq, ret);
+		ret = -ENODEV;
+		return ret;
+	}
+
+	ret = dwc3_gadget_init(dwc);
+	if (ret) {
+		free_irq(dwc->otg_irq, dwc);
+		return ret;
+	}
+
+	spin_lock_irqsave(&dwc->lock, flags);
+
+	/*
+	 * As per Figure 11-4 OTG Driver Overall Programming Flow,
+	 * block "Initialize GCTL for OTG operation".
+	 */
+	/* GCTL.PrtCapDir=2'b11 */
+	dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
+	/* GUSB2PHYCFG0.SusPHY=0 */
+	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+	reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
+	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+	/* Initialize OTG registers */
+	dwc3_otgregs_init(dwc);
+
+	/* force drd state machine update the first time */
+	dwc->otg_fsm.b_sess_vld = -1;
+	dwc->otg_fsm.id = -1;
+	dwc3_otg_fsm_sync(dwc);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static void dwc3_drd_exit(struct dwc3 *dwc)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	dwc3_otg_disable_events(dwc, DWC3_OTG_ALL_EVENTS);
+	if (dwc->otg_fsm.protocol == PROTO_HOST)
+		dwc3_drd_start_host(dwc, 0);
+	dwc->otg_fsm.protocol = PROTO_UNDEF;
+	free_irq(dwc->otg_irq, dwc);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	dwc3_gadget_exit(dwc);
+}
+
+/* -------------------------------------------------------------------------- */
+
 static int dwc3_core_init_mode(struct dwc3 *dwc)
 {
 	struct device *dev = dwc->dev;
@@ -862,17 +1353,10 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
 		}
 		break;
 	case USB_DR_MODE_OTG:
-		ret = dwc3_host_init(dwc);
-		if (ret) {
-			if (ret != -EPROBE_DEFER)
-				dev_err(dev, "failed to initialize host\n");
-			return ret;
-		}
-
-		ret = dwc3_gadget_init(dwc);
+		ret = dwc3_drd_init(dwc);
 		if (ret) {
 			if (ret != -EPROBE_DEFER)
-				dev_err(dev, "failed to initialize gadget\n");
+				dev_err(dev, "failed to initialize dual-role\n");
 			return ret;
 		}
 		break;
@@ -894,8 +1378,7 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
 		dwc3_host_exit(dwc);
 		break;
 	case USB_DR_MODE_OTG:
-		dwc3_host_exit(dwc);
-		dwc3_gadget_exit(dwc);
+		dwc3_drd_exit(dwc);
 		break;
 	default:
 		/* do nothing */
@@ -1207,19 +1690,32 @@ static int dwc3_suspend_common(struct dwc3 *dwc)
 {
 	unsigned long	flags;
 
+	spin_lock_irqsave(&dwc->lock, flags);
+
 	switch (dwc->dr_mode) {
 	case USB_DR_MODE_PERIPHERAL:
-	case USB_DR_MODE_OTG:
-		spin_lock_irqsave(&dwc->lock, flags);
 		dwc3_gadget_suspend(dwc);
-		spin_unlock_irqrestore(&dwc->lock, flags);
+		break;
+	case USB_DR_MODE_OTG:
+		switch (dwc->otg_fsm.protocol) {
+		case PROTO_GADGET:
+			dwc3_gadget_suspend(dwc);
+			break;
+		case PROTO_HOST:
+		case PROTO_UNDEF:
+		default:
+			/* nothing */
+			break;
+		}
 		break;
 	case USB_DR_MODE_HOST:
+	case USB_DR_MODE_UNKNOWN:
 	default:
 		/* do nothing */
 		break;
 	}
 
+	spin_unlock_irqrestore(&dwc->lock, flags);
 	dwc3_core_exit(dwc);
 
 	return 0;
@@ -1234,19 +1730,41 @@ static int dwc3_resume_common(struct dwc3 *dwc)
 	if (ret)
 		return ret;
 
+	spin_lock_irqsave(&dwc->lock, flags);
+
 	switch (dwc->dr_mode) {
 	case USB_DR_MODE_PERIPHERAL:
-	case USB_DR_MODE_OTG:
-		spin_lock_irqsave(&dwc->lock, flags);
 		dwc3_gadget_resume(dwc);
-		spin_unlock_irqrestore(&dwc->lock, flags);
-		/* FALLTHROUGH */
+		break;
+	case USB_DR_MODE_OTG:
+		switch (dwc->otg_fsm.protocol) {
+		case PROTO_GADGET:
+			dwc3_gadget_resume(dwc);
+			break;
+		case PROTO_HOST:
+			break;
+		case PROTO_UNDEF:
+		default:
+			/* nothing */
+			break;
+		}
+		break;
 	case USB_DR_MODE_HOST:
+	case USB_DR_MODE_UNKNOWN:
 	default:
 		/* do nothing */
 		break;
 	}
 
+	/* Restore OTG state only if we're really using it */
+	if (dwc->current_mode == DWC3_GCTL_PRTCAP_OTG) {
+		dwc3_writel(dwc->regs, DWC3_OCFG, dwc->ocfg);
+		dwc3_writel(dwc->regs, DWC3_OCTL, dwc->octl);
+		dwc3_otg_unmask_irq(dwc);
+	}
+
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
 	return 0;
 }
 
@@ -1301,6 +1819,7 @@ static int dwc3_runtime_resume(struct device *dev)
 		dwc3_gadget_process_pending_events(dwc);
 		break;
 	case USB_DR_MODE_HOST:
+	case USB_DR_MODE_UNKNOWN:
 	default:
 		/* do nothing */
 		break;
@@ -1336,6 +1855,30 @@ static int dwc3_runtime_idle(struct device *dev)
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_PM_SLEEP
+static int dwc3_prepare(struct device *dev)
+{
+	struct dwc3	*dwc = dev_get_drvdata(dev);
+	unsigned long	flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	dwc->otg_prevent_sync = true;
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static void dwc3_complete(struct device *dev)
+{
+	struct dwc3	*dwc = dev_get_drvdata(dev);
+	unsigned long	flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	dwc->otg_prevent_sync = false;
+	if (dwc->dr_mode == USB_DR_MODE_OTG)
+		dwc3_otg_fsm_sync(dwc);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+}
+
 static int dwc3_suspend(struct device *dev)
 {
 	struct dwc3	*dwc = dev_get_drvdata(dev);
@@ -1373,6 +1916,10 @@ static const struct dev_pm_ops dwc3_dev_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
 	SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume,
 			dwc3_runtime_idle)
+#ifdef CONFIG_PM_SLEEP
+	.prepare = dwc3_prepare,
+	.complete = dwc3_complete,
+#endif
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index fc82d2e..8463c4c 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -35,6 +35,9 @@
 
 #include <linux/phy/phy.h>
 
+#include <linux/usb/otg.h>
+#include <linux/usb/otg-fsm.h>
+
 #define DWC3_MSG_MAX	500
 
 /* Global constants */
@@ -854,15 +857,21 @@ struct dwc3_scratchpad_array {
  * @event_buffer_list: a list of event buffers
  * @gadget: device side representation of the peripheral controller
  * @gadget_driver: pointer to the gadget driver
+ * @gadget_pullup: gadget driver's pullup request flag
  * @regs: base address for our registers
  * @regs_size: address space size
+ * @dr_mode: requested mode of operation
+ * @otg: usb otg data structure
+ * @otg-fsm: usb otg fsm data structure
+ * @otg_prevent_sync: flag to block events to otg fsm
+ * @current_mode: current mode of operation written to PRTCAPDIR
  * @fladj: frame length adjustment
  * @irq_gadget: peripheral controller's IRQ number
+ * @otg_irq: IRQ number for OTG IRQs
  * @nr_scratch: number of scratch buffers
  * @u1u2: only used on revisions <1.83a for workaround
  * @maximum_speed: maximum speed requested (mainly for testing purposes)
  * @revision: revision register contents
- * @dr_mode: requested mode of operation
  * @hsphy_mode: UTMI phy mode, one of following:
  *		- USBPHY_INTERFACE_MODE_UTMI
  *		- USBPHY_INTERFACE_MODE_UTMIW
@@ -873,6 +882,9 @@ struct dwc3_scratchpad_array {
  * @ulpi: pointer to ulpi interface
  * @dcfg: saved contents of DCFG register
  * @gctl: saved contents of GCTL register
+ * @ocfg: saved contents of OCFG register
+ * @octl: saved contents of OCTL register
+ * @oevten: saved contents of OEVTEN register
  * @isoch_delay: wValue from Set Isochronous Delay request;
  * @u2sel: parameter from Set SEL request.
  * @u2pel: parameter from Set SEL request.
@@ -964,6 +976,7 @@ struct dwc3 {
 
 	struct usb_gadget	gadget;
 	struct usb_gadget_driver *gadget_driver;
+	bool			gadget_pullup;
 
 	struct usb_phy		*usb2_phy;
 	struct usb_phy		*usb3_phy;
@@ -973,14 +986,28 @@ struct dwc3 {
 
 	struct ulpi		*ulpi;
 
+	/* used for suspend/resume */
+	u32			dcfg;
+	u32			gctl;
+	u32			ocfg;
+	u32			octl;
+	u32			oevten;
+
 	void __iomem		*regs;
 	size_t			regs_size;
 
 	enum usb_dr_mode	dr_mode;
+	struct usb_otg		otg;
+	struct otg_fsm		otg_fsm;
+	bool			otg_prevent_sync;
+	u32			current_mode;
+
 	enum usb_phy_interface	hsphy_mode;
 
 	u32			fladj;
 	u32			irq_gadget;
+	int			otg_irq;
+
 	u32			nr_scratch;
 	u32			u1u2;
 	u32			maximum_speed;
@@ -1277,6 +1304,9 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state);
 int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
 		struct dwc3_gadget_ep_cmd_params *params);
 int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param);
+int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend);
+int __dwc3_gadget_start(struct dwc3 *dwc);
+void __dwc3_gadget_stop(struct dwc3 *dwc);
 #else
 static inline int dwc3_gadget_init(struct dwc3 *dwc)
 { return 0; }
@@ -1296,6 +1326,12 @@ static inline int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
 static inline int dwc3_send_gadget_generic_command(struct dwc3 *dwc,
 		int cmd, u32 param)
 { return 0; }
+static inline int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
+{ return 0; }
+static inline int __dwc3_gadget_start(struct dwc3 *dwc)
+{ return 0; }
+static inline void __dwc3_gadget_stop(struct dwc3 *dwc)
+{ }
 #endif
 
 /* power management interface */
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 204c754c..8779f7a 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1534,7 +1534,7 @@ static int dwc3_gadget_set_selfpowered(struct usb_gadget *g,
 	return 0;
 }
 
-static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
+int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
 {
 	u32			reg;
 	u32			timeout = 500;
@@ -1542,6 +1542,10 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
 	if (pm_runtime_suspended(dwc->dev))
 		return 0;
 
+	if (dwc->dr_mode == USB_DR_MODE_OTG &&
+	    dwc->otg_fsm.protocol != PROTO_GADGET)
+		return 0;
+
 	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
 	if (is_on) {
 		if (dwc->revision <= DWC3_REVISION_187A) {
@@ -1603,6 +1607,7 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
 	}
 
 	spin_lock_irqsave(&dwc->lock, flags);
+	dwc->gadget_pullup = is_on;
 	ret = dwc3_gadget_run_stop(dwc, is_on, false);
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
@@ -1679,7 +1684,7 @@ static void dwc3_gadget_setup_nump(struct dwc3 *dwc)
 	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
 }
 
-static int __dwc3_gadget_start(struct dwc3 *dwc)
+int __dwc3_gadget_start(struct dwc3 *dwc)
 {
 	struct dwc3_ep		*dep;
 	int			ret = 0;
@@ -1812,8 +1817,11 @@ static int dwc3_gadget_start(struct usb_gadget *g,
 
 	dwc->gadget_driver	= driver;
 
-	if (pm_runtime_active(dwc->dev))
-		__dwc3_gadget_start(dwc);
+	if (pm_runtime_active(dwc->dev)) {
+		if (!(dwc->dr_mode == USB_DR_MODE_OTG &&
+		      dwc->otg_fsm.protocol != PROTO_GADGET))
+			__dwc3_gadget_start(dwc);
+	}
 
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
@@ -1827,7 +1835,7 @@ static int dwc3_gadget_start(struct usb_gadget *g,
 	return ret;
 }
 
-static void __dwc3_gadget_stop(struct dwc3 *dwc)
+void __dwc3_gadget_stop(struct dwc3 *dwc)
 {
 	dwc3_gadget_disable_irq(dwc);
 	__dwc3_gadget_ep_disable(dwc->eps[0]);
-- 
2.7.4

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

* [PATCH 6/8] ARM: dts: dra7x-evm: Enable dual-role mode for USB1
  2017-01-23 11:19 ` [PATCH 0/8] usb: dwc3: add dual-role support Roger Quadros
                     ` (4 preceding siblings ...)
  2017-01-23 11:19   ` [PATCH 5/8] usb: dwc3: add dual-role support Roger Quadros
@ 2017-01-23 11:19   ` Roger Quadros
  2017-01-26 15:56     ` Tony Lindgren
  2017-01-23 11:19   ` [PATCH 7/8] ARM: dts: am43xx: " Roger Quadros
                     ` (3 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Roger Quadros @ 2017-01-23 11:19 UTC (permalink / raw)
  To: balbi, tony
  Cc: peter.chen, vivek.gautam, linux-usb, linux-omap, linux-kernel,
	Roger Quadros

USB1 port is micro-AB type and can function as peripheral
as well as host. Enable dual-role mode for USB1.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/boot/dts/dra7-evm.dts          | 2 +-
 arch/arm/boot/dts/dra72-evm-common.dtsi | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
index 132f2be..d64e72d 100644
--- a/arch/arm/boot/dts/dra7-evm.dts
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -731,7 +731,7 @@
 };
 
 &usb1 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 	pinctrl-names = "default";
 	pinctrl-0 = <&usb1_pins>;
 };
diff --git a/arch/arm/boot/dts/dra72-evm-common.dtsi b/arch/arm/boot/dts/dra72-evm-common.dtsi
index e50fbee..dc2c328 100644
--- a/arch/arm/boot/dts/dra72-evm-common.dtsi
+++ b/arch/arm/boot/dts/dra72-evm-common.dtsi
@@ -374,7 +374,7 @@
 };
 
 &usb1 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 };
 
 &usb2 {
-- 
2.7.4

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

* [PATCH 7/8] ARM: dts: am43xx: Enable dual-role mode for USB1
  2017-01-23 11:19 ` [PATCH 0/8] usb: dwc3: add dual-role support Roger Quadros
                     ` (5 preceding siblings ...)
  2017-01-23 11:19   ` [PATCH 6/8] ARM: dts: dra7x-evm: Enable dual-role mode for USB1 Roger Quadros
@ 2017-01-23 11:19   ` Roger Quadros
  2017-01-23 11:19   ` [PATCH 8/8] ARM: dts: am57xx-idk: Enable dual-role mode for USB2 Roger Quadros
                     ` (2 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Roger Quadros @ 2017-01-23 11:19 UTC (permalink / raw)
  To: balbi, tony
  Cc: peter.chen, vivek.gautam, linux-usb, linux-omap, linux-kernel,
	Roger Quadros

USB1 port is micro-AB type and can function as peripheral
as well as host. Enable dual-role mode for USB1.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/boot/dts/am437x-gp-evm.dts  | 2 +-
 arch/arm/boot/dts/am437x-sk-evm.dts  | 2 +-
 arch/arm/boot/dts/am43x-epos-evm.dts | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts
index 957840c..74728cc 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -772,7 +772,7 @@
 };
 
 &usb1 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts b/arch/arm/boot/dts/am437x-sk-evm.dts
index 319d942..cfffce8 100644
--- a/arch/arm/boot/dts/am437x-sk-evm.dts
+++ b/arch/arm/boot/dts/am437x-sk-evm.dts
@@ -596,7 +596,7 @@
 };
 
 &usb1 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&usb1_pins>;
diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts
index 9d35c3f..8a48d9b 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -669,7 +669,7 @@
 };
 
 &usb1 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 	status = "okay";
 };
 
-- 
2.7.4

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

* [PATCH 8/8] ARM: dts: am57xx-idk: Enable dual-role mode for USB2
  2017-01-23 11:19 ` [PATCH 0/8] usb: dwc3: add dual-role support Roger Quadros
                     ` (6 preceding siblings ...)
  2017-01-23 11:19   ` [PATCH 7/8] ARM: dts: am43xx: " Roger Quadros
@ 2017-01-23 11:19   ` Roger Quadros
  2017-01-23 11:31   ` [PATCH 0/8] usb: dwc3: add dual-role support Chanwoo Choi
  2017-02-09  6:42   ` Vivek Gautam
  9 siblings, 0 replies; 15+ messages in thread
From: Roger Quadros @ 2017-01-23 11:19 UTC (permalink / raw)
  To: balbi, tony
  Cc: peter.chen, vivek.gautam, linux-usb, linux-omap, linux-kernel,
	Roger Quadros

USB port is micro-AB type and can function as peripheral
as well as host. Enable dual-role mode for USB2.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/boot/dts/am57xx-idk-common.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/am57xx-idk-common.dtsi b/arch/arm/boot/dts/am57xx-idk-common.dtsi
index 814a720..14bdb24 100644
--- a/arch/arm/boot/dts/am57xx-idk-common.dtsi
+++ b/arch/arm/boot/dts/am57xx-idk-common.dtsi
@@ -376,7 +376,7 @@
 };
 
 &usb2 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 };
 
 &mmc2 {
-- 
2.7.4

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

* Re: [PATCH 0/8] usb: dwc3: add dual-role support
  2017-01-23 11:19 ` [PATCH 0/8] usb: dwc3: add dual-role support Roger Quadros
                     ` (7 preceding siblings ...)
  2017-01-23 11:19   ` [PATCH 8/8] ARM: dts: am57xx-idk: Enable dual-role mode for USB2 Roger Quadros
@ 2017-01-23 11:31   ` Chanwoo Choi
  2017-02-09  6:42   ` Vivek Gautam
  9 siblings, 0 replies; 15+ messages in thread
From: Chanwoo Choi @ 2017-01-23 11:31 UTC (permalink / raw)
  To: Roger Quadros, balbi, Tony Lindgren
  Cc: peter.chen, vivek.gautam, linux-usb, linux-omap, linux-kernel,
	이동우

Hi Roger,

On 2017년 01월 23일 20:19, Roger Quadros wrote:
> - Some SoC's (e.g. Qualcomm MSM) do not have the OTG controller block
> but do have both host and peripheral controllers and so can operate
> in dual role mode. Current series does not address this case.
> We can get dual-role to work with such SoCs if core.c can get
> information about ID and VBUS somehow (private interface
> from parent or directly read extcon?).

Also, Exynos SoC doesn't include the physical otg block
to detect the type of external connector(HOST or Peripheral).

So, our team member and me are preparing the patches
to identify the type of external connector with extcon
This approach is not dependent on any specific SoC.

Maybe, we will send the RFC patches within this month.

-- 
Best Regards,
Chanwoo Choi
S/W R&D Center
Samsung Electronics

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

* Re: [PATCH 6/8] ARM: dts: dra7x-evm: Enable dual-role mode for USB1
  2017-01-23 11:19   ` [PATCH 6/8] ARM: dts: dra7x-evm: Enable dual-role mode for USB1 Roger Quadros
@ 2017-01-26 15:56     ` Tony Lindgren
  2017-01-26 16:33       ` Roger Quadros
  0 siblings, 1 reply; 15+ messages in thread
From: Tony Lindgren @ 2017-01-26 15:56 UTC (permalink / raw)
  To: Roger Quadros
  Cc: balbi, peter.chen, vivek.gautam, linux-usb, linux-omap, linux-kernel

* Roger Quadros <rogerq@ti.com> [170123 03:21]:
> USB1 port is micro-AB type and can function as peripheral
> as well as host. Enable dual-role mode for USB1.

Good to see this happening :) Can you please send the dts changes
separately after the driver changes have gotten merged?

Meanwhile I'll untag this thread here.

Thanks,

Tony

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

* Re: [PATCH 6/8] ARM: dts: dra7x-evm: Enable dual-role mode for USB1
  2017-01-26 15:56     ` Tony Lindgren
@ 2017-01-26 16:33       ` Roger Quadros
  0 siblings, 0 replies; 15+ messages in thread
From: Roger Quadros @ 2017-01-26 16:33 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: balbi, peter.chen, vivek.gautam, linux-usb, linux-omap, linux-kernel

On 26/01/17 17:56, Tony Lindgren wrote:
> * Roger Quadros <rogerq@ti.com> [170123 03:21]:
>> USB1 port is micro-AB type and can function as peripheral
>> as well as host. Enable dual-role mode for USB1.
> 
> Good to see this happening :) Can you please send the dts changes
> separately after the driver changes have gotten merged?
> 

Yes Tony. I won't send the dts patches again in this series.

> Meanwhile I'll untag this thread here.
> 

cheers,
-roger

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

* Re: [PATCH 0/8] usb: dwc3: add dual-role support
  2017-01-23 11:19 ` [PATCH 0/8] usb: dwc3: add dual-role support Roger Quadros
                     ` (8 preceding siblings ...)
  2017-01-23 11:31   ` [PATCH 0/8] usb: dwc3: add dual-role support Chanwoo Choi
@ 2017-02-09  6:42   ` Vivek Gautam
  2017-02-09  7:49     ` Roger Quadros
  9 siblings, 1 reply; 15+ messages in thread
From: Vivek Gautam @ 2017-02-09  6:42 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Felipe Balbi, Tony Lindgren, peter.chen, Linux USB Mailing List,
	linux-omap, linux-kernel

Hi Roger,

On Mon, Jan 23, 2017 at 4:49 PM, Roger Quadros <rogerq@ti.com> wrote:
> Hi,
>
> We rely on the OTG controller block to provide us with
> VBUS and ID line status via an interrupt.
>
> This is then used to switch the controller between host, peripheral
> and idle roles based on the following table.
>
>     ID  VBUS    dual-role state
>     --  ----    ---------------
>     0   x       A_HOST - Host controller active
>     1   0       B_IDLE - Both Host and Gadget controllers inactive
>     1   1       B_PERIPHERAL - Gadget controller active
>

Thanks for this series.
Sorry, i was held up with something else so couldn't take a look at it.
I will integrate this with my work, and add some basic extcon
support to enable passing vbus and id events to dwc3 layer to test
this out on msm platforms.


Regards
Vivek

> Couple of things to clarify:
> - There is a small window where we can potentially miss an
> event related to OTG. I've added a comment in the code where this
> could happen. How can we prevent this? Is it better to just leave
> the OTG events unmasked (but keep otg_irq on ARM GIC disabled)
> so that any new events can be captured by the OTG event register
> and interrupt re-triggered if it has not been serviced by the
> previous interrupt.
> - I'm running the entire dual-role state change logic inside
> the threaded interrupt handler with dwc->lock (spinlock) held
> but IRQs enabled. OTG events are very rare i.e. manual intervention
> so I don't see this as a problem. Just wanted to double check.
> - Some SoC's (e.g. Qualcomm MSM) do not have the OTG controller block
> but do have both host and peripheral controllers and so can operate
> in dual role mode. Current series does not address this case.
> We can get dual-role to work with such SoCs if core.c can get
> information about ID and VBUS somehow (private interface
> from parent or directly read extcon?).
>
> cheers,
> -roger
>
> Roger Quadros (8):
>   usb: otg-fsm: Prevent build warning "VDBG" redefined
>   usb: dwc3-omap: Fix missing break in dwc3_omap_set_mailbox()
>   usb: dwc3: use BIT() macro where possible
>   usb: dwc3: core.h: add some register definitions
>   usb: dwc3: add dual-role support
>   ARM: dts: dra7x-evm: Enable dual-role mode for USB1
>   ARM: dts: am43xx: Enable dual-role mode for USB1
>   ARM: dts: am57xx-idk: Enable dual-role mode for USB2
>
>  arch/arm/boot/dts/am437x-gp-evm.dts      |   2 +-
>  arch/arm/boot/dts/am437x-sk-evm.dts      |   2 +-
>  arch/arm/boot/dts/am43x-epos-evm.dts     |   2 +-
>  arch/arm/boot/dts/am57xx-idk-common.dtsi |   2 +-
>  arch/arm/boot/dts/dra7-evm.dts           |   2 +-
>  arch/arm/boot/dts/dra72-evm-common.dtsi  |   2 +-
>  drivers/usb/common/usb-otg-fsm.c         |   7 +
>  drivers/usb/dwc3/core.c                  | 583 ++++++++++++++++++++++++++++++-
>  drivers/usb/dwc3/core.h                  | 312 ++++++++++++-----
>  drivers/usb/dwc3/dwc3-omap.c             |  49 +--
>  drivers/usb/dwc3/gadget.c                |  18 +-
>  drivers/usb/dwc3/gadget.h                |  20 +-
>  drivers/usb/phy/phy-fsl-usb.c            |   7 +
>  include/linux/usb/otg-fsm.h              |  15 -
>  14 files changed, 848 insertions(+), 175 deletions(-)
>
> --
> 2.7.4
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH 0/8] usb: dwc3: add dual-role support
  2017-02-09  6:42   ` Vivek Gautam
@ 2017-02-09  7:49     ` Roger Quadros
  2017-02-09 11:38       ` Vivek Gautam
  0 siblings, 1 reply; 15+ messages in thread
From: Roger Quadros @ 2017-02-09  7:49 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: Felipe Balbi, Tony Lindgren, peter.chen, Linux USB Mailing List,
	linux-omap, linux-kernel

Vivek,

On 09/02/17 08:42, Vivek Gautam wrote:
> Hi Roger,
> 
> On Mon, Jan 23, 2017 at 4:49 PM, Roger Quadros <rogerq@ti.com> wrote:
>> Hi,
>>
>> We rely on the OTG controller block to provide us with
>> VBUS and ID line status via an interrupt.
>>
>> This is then used to switch the controller between host, peripheral
>> and idle roles based on the following table.
>>
>>     ID  VBUS    dual-role state
>>     --  ----    ---------------
>>     0   x       A_HOST - Host controller active
>>     1   0       B_IDLE - Both Host and Gadget controllers inactive
>>     1   1       B_PERIPHERAL - Gadget controller active
>>
> 
> Thanks for this series.
> Sorry, i was held up with something else so couldn't take a look at it.
> I will integrate this with my work, and add some basic extcon
> support to enable passing vbus and id events to dwc3 layer to test
> this out on msm platforms.

I already have this done for one of our platforms to workaround
a limitation with the OTG IP block on it.
I can post it today and you can give your comments.

cheers,
-roger
> 
> 
> Regards
> Vivek
> 
>> Couple of things to clarify:
>> - There is a small window where we can potentially miss an
>> event related to OTG. I've added a comment in the code where this
>> could happen. How can we prevent this? Is it better to just leave
>> the OTG events unmasked (but keep otg_irq on ARM GIC disabled)
>> so that any new events can be captured by the OTG event register
>> and interrupt re-triggered if it has not been serviced by the
>> previous interrupt.
>> - I'm running the entire dual-role state change logic inside
>> the threaded interrupt handler with dwc->lock (spinlock) held
>> but IRQs enabled. OTG events are very rare i.e. manual intervention
>> so I don't see this as a problem. Just wanted to double check.
>> - Some SoC's (e.g. Qualcomm MSM) do not have the OTG controller block
>> but do have both host and peripheral controllers and so can operate
>> in dual role mode. Current series does not address this case.
>> We can get dual-role to work with such SoCs if core.c can get
>> information about ID and VBUS somehow (private interface
>> from parent or directly read extcon?).
>>
>> cheers,
>> -roger
>>
>> Roger Quadros (8):
>>   usb: otg-fsm: Prevent build warning "VDBG" redefined
>>   usb: dwc3-omap: Fix missing break in dwc3_omap_set_mailbox()
>>   usb: dwc3: use BIT() macro where possible
>>   usb: dwc3: core.h: add some register definitions
>>   usb: dwc3: add dual-role support
>>   ARM: dts: dra7x-evm: Enable dual-role mode for USB1
>>   ARM: dts: am43xx: Enable dual-role mode for USB1
>>   ARM: dts: am57xx-idk: Enable dual-role mode for USB2
>>
>>  arch/arm/boot/dts/am437x-gp-evm.dts      |   2 +-
>>  arch/arm/boot/dts/am437x-sk-evm.dts      |   2 +-
>>  arch/arm/boot/dts/am43x-epos-evm.dts     |   2 +-
>>  arch/arm/boot/dts/am57xx-idk-common.dtsi |   2 +-
>>  arch/arm/boot/dts/dra7-evm.dts           |   2 +-
>>  arch/arm/boot/dts/dra72-evm-common.dtsi  |   2 +-
>>  drivers/usb/common/usb-otg-fsm.c         |   7 +
>>  drivers/usb/dwc3/core.c                  | 583 ++++++++++++++++++++++++++++++-
>>  drivers/usb/dwc3/core.h                  | 312 ++++++++++++-----
>>  drivers/usb/dwc3/dwc3-omap.c             |  49 +--
>>  drivers/usb/dwc3/gadget.c                |  18 +-
>>  drivers/usb/dwc3/gadget.h                |  20 +-
>>  drivers/usb/phy/phy-fsl-usb.c            |   7 +
>>  include/linux/usb/otg-fsm.h              |  15 -
>>  14 files changed, 848 insertions(+), 175 deletions(-)
>>
>> --
>> 2.7.4
>>
> 

-- 
cheers,
-roger

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

* Re: [PATCH 0/8] usb: dwc3: add dual-role support
  2017-02-09  7:49     ` Roger Quadros
@ 2017-02-09 11:38       ` Vivek Gautam
  0 siblings, 0 replies; 15+ messages in thread
From: Vivek Gautam @ 2017-02-09 11:38 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Felipe Balbi, Tony Lindgren, peter.chen, Linux USB Mailing List,
	linux-omap, linux-kernel

On Thu, Feb 9, 2017 at 1:19 PM, Roger Quadros <rogerq@ti.com> wrote:
> Vivek,
>
> On 09/02/17 08:42, Vivek Gautam wrote:
>> Hi Roger,
>>
>> On Mon, Jan 23, 2017 at 4:49 PM, Roger Quadros <rogerq@ti.com> wrote:
>>> Hi,
>>>
>>> We rely on the OTG controller block to provide us with
>>> VBUS and ID line status via an interrupt.
>>>
>>> This is then used to switch the controller between host, peripheral
>>> and idle roles based on the following table.
>>>
>>>     ID  VBUS    dual-role state
>>>     --  ----    ---------------
>>>     0   x       A_HOST - Host controller active
>>>     1   0       B_IDLE - Both Host and Gadget controllers inactive
>>>     1   1       B_PERIPHERAL - Gadget controller active
>>>
>>
>> Thanks for this series.
>> Sorry, i was held up with something else so couldn't take a look at it.
>> I will integrate this with my work, and add some basic extcon
>> support to enable passing vbus and id events to dwc3 layer to test
>> this out on msm platforms.
>
> I already have this done for one of our platforms to workaround
> a limitation with the OTG IP block on it.
> I can post it today and you can give your comments.

Okay, cool. Thanks. I will wait.


Regards
Vivek

>
> cheers,
> -roger
>>
>>
>> Regards
>> Vivek
>>
>>> Couple of things to clarify:
>>> - There is a small window where we can potentially miss an
>>> event related to OTG. I've added a comment in the code where this
>>> could happen. How can we prevent this? Is it better to just leave
>>> the OTG events unmasked (but keep otg_irq on ARM GIC disabled)
>>> so that any new events can be captured by the OTG event register
>>> and interrupt re-triggered if it has not been serviced by the
>>> previous interrupt.
>>> - I'm running the entire dual-role state change logic inside
>>> the threaded interrupt handler with dwc->lock (spinlock) held
>>> but IRQs enabled. OTG events are very rare i.e. manual intervention
>>> so I don't see this as a problem. Just wanted to double check.
>>> - Some SoC's (e.g. Qualcomm MSM) do not have the OTG controller block
>>> but do have both host and peripheral controllers and so can operate
>>> in dual role mode. Current series does not address this case.
>>> We can get dual-role to work with such SoCs if core.c can get
>>> information about ID and VBUS somehow (private interface
>>> from parent or directly read extcon?).
>>>
>>> cheers,
>>> -roger
>>>
>>> Roger Quadros (8):
>>>   usb: otg-fsm: Prevent build warning "VDBG" redefined
>>>   usb: dwc3-omap: Fix missing break in dwc3_omap_set_mailbox()
>>>   usb: dwc3: use BIT() macro where possible
>>>   usb: dwc3: core.h: add some register definitions
>>>   usb: dwc3: add dual-role support
>>>   ARM: dts: dra7x-evm: Enable dual-role mode for USB1
>>>   ARM: dts: am43xx: Enable dual-role mode for USB1
>>>   ARM: dts: am57xx-idk: Enable dual-role mode for USB2
>>>
>>>  arch/arm/boot/dts/am437x-gp-evm.dts      |   2 +-
>>>  arch/arm/boot/dts/am437x-sk-evm.dts      |   2 +-
>>>  arch/arm/boot/dts/am43x-epos-evm.dts     |   2 +-
>>>  arch/arm/boot/dts/am57xx-idk-common.dtsi |   2 +-
>>>  arch/arm/boot/dts/dra7-evm.dts           |   2 +-
>>>  arch/arm/boot/dts/dra72-evm-common.dtsi  |   2 +-
>>>  drivers/usb/common/usb-otg-fsm.c         |   7 +
>>>  drivers/usb/dwc3/core.c                  | 583 ++++++++++++++++++++++++++++++-
>>>  drivers/usb/dwc3/core.h                  | 312 ++++++++++++-----
>>>  drivers/usb/dwc3/dwc3-omap.c             |  49 +--
>>>  drivers/usb/dwc3/gadget.c                |  18 +-
>>>  drivers/usb/dwc3/gadget.h                |  20 +-
>>>  drivers/usb/phy/phy-fsl-usb.c            |   7 +
>>>  include/linux/usb/otg-fsm.h              |  15 -
>>>  14 files changed, 848 insertions(+), 175 deletions(-)
>>>
>>> --
>>> 2.7.4
>>>
>>
>
> --
> cheers,
> -roger



-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

end of thread, other threads:[~2017-02-09 11:50 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20170123112122epcas4p3af3d2f3434d02967d7c662a9ab9f3e31@epcas4p3.samsung.com>
2017-01-23 11:19 ` [PATCH 0/8] usb: dwc3: add dual-role support Roger Quadros
2017-01-23 11:19   ` [PATCH 1/8] usb: otg-fsm: Prevent build warning "VDBG" redefined Roger Quadros
2017-01-23 11:19   ` [PATCH 2/8] usb: dwc3-omap: Fix missing break in dwc3_omap_set_mailbox() Roger Quadros
2017-01-23 11:19   ` [PATCH 3/8] usb: dwc3: use BIT() macro where possible Roger Quadros
2017-01-23 11:19   ` [PATCH 4/8] usb: dwc3: core.h: add some register definitions Roger Quadros
2017-01-23 11:19   ` [PATCH 5/8] usb: dwc3: add dual-role support Roger Quadros
2017-01-23 11:19   ` [PATCH 6/8] ARM: dts: dra7x-evm: Enable dual-role mode for USB1 Roger Quadros
2017-01-26 15:56     ` Tony Lindgren
2017-01-26 16:33       ` Roger Quadros
2017-01-23 11:19   ` [PATCH 7/8] ARM: dts: am43xx: " Roger Quadros
2017-01-23 11:19   ` [PATCH 8/8] ARM: dts: am57xx-idk: Enable dual-role mode for USB2 Roger Quadros
2017-01-23 11:31   ` [PATCH 0/8] usb: dwc3: add dual-role support Chanwoo Choi
2017-02-09  6:42   ` Vivek Gautam
2017-02-09  7:49     ` Roger Quadros
2017-02-09 11:38       ` Vivek Gautam

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