[U-Boot] [PATCH 4/5] usb: ci_udc: support variants with hostpc register

Stephen Warren swarren at wwwdotorg.org
Fri Apr 25 01:52:39 CEST 2014


From: Stephen Warren <swarren at nvidia.com>

Tegra's USB controller appears to be a variant of the ChipIdea
controller; perhaps derived from it, or simply a different version of
the IP core to what U-Boot supports today.

In this variant, at least the following difference are present:
- Some registers are moved about.
- Setup transaction completion is reported in a separate 'epsetupstat'
  register, rather than in 'epstat' (which still exists, perhaps for
  other transaction types).
- USB connection speed is reported in a separate 'hostpc1_devlc'
  register, rather than 'portsc'.
- The registers used by ci_udc.c begin at offset 0x130 from the USB
  register base, rather than offset 0x140. However, this is handled
  by the associated EHCI controller driver, since the register address
  is stored in controller.ctrl->hcor.

Introduce define CONFIG_CI_UDC_HAS_HOSTPC to indicate which variant of
the controller should be supported. The "HAS_HOSTPC" part of this name
mirrors the similar "has_hostpc" field used by the Linux EHCI controller
core to represent the presence/absence of the hostpc1_devlc register.

Signed-off-by: Stephen Warren <swarren at nvidia.com>
---
 drivers/usb/gadget/ci_udc.c | 15 +++++++++++
 drivers/usb/gadget/ci_udc.h | 65 ++++++++++++++++++++++++++++++++-------------
 2 files changed, 62 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c
index fd751a242639..02d3fdade86c 100644
--- a/drivers/usb/gadget/ci_udc.c
+++ b/drivers/usb/gadget/ci_udc.c
@@ -416,7 +416,11 @@ static void handle_setup(void)
 
 	ci_invalidate_qh(0);
 	memcpy(&r, head->setup_data, sizeof(struct usb_ctrlrequest));
+#ifdef CONFIG_CI_UDC_HAS_HOSTPC
+	writel(EPT_RX(0), &udc->epsetupstat);
+#else
 	writel(EPT_RX(0), &udc->epstat);
+#endif
 	DBG("handle setup %s, %x, %x index %x value %x\n", reqname(r.bRequest),
 	    r.bRequestType, r.bRequest, r.wIndex, r.wValue);
 
@@ -483,6 +487,9 @@ static void stop_activity(void)
 	struct ept_queue_head *head;
 	struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
 	writel(readl(&udc->epcomp), &udc->epcomp);
+#ifdef CONFIG_CI_UDC_HAS_HOSTPC
+	writel(readl(&udc->epsetupstat), &udc->epsetupstat);
+#endif
 	writel(readl(&udc->epstat), &udc->epstat);
 	writel(0xffffffff, &udc->epflush);
 
@@ -524,7 +531,11 @@ void udc_irq(void)
 		int max = 64;
 		int speed = USB_SPEED_FULL;
 
+#ifdef CONFIG_CI_UDC_HAS_HOSTPC
+		bit = (readl(&udc->hostpc1_devlc) >> 25) & 3;
+#else
 		bit = (readl(&udc->portsc) >> 26) & 3;
+#endif
 		DBG("-- portchange %x %s\n", bit, (bit == 2) ? "High" : "Full");
 		if (bit == 2) {
 			speed = USB_SPEED_HIGH;
@@ -541,7 +552,11 @@ void udc_irq(void)
 		printf("<UEI %x>\n", readl(&udc->epcomp));
 
 	if ((n & STS_UI) || (n & STS_UEI)) {
+#ifdef CONFIG_CI_UDC_HAS_HOSTPC
+		n = readl(&udc->epsetupstat);
+#else
 		n = readl(&udc->epstat);
+#endif
 		if (n & EPT_RX(0))
 			handle_setup();
 
diff --git a/drivers/usb/gadget/ci_udc.h b/drivers/usb/gadget/ci_udc.h
index 42f6ef4ab30a..4425fd934570 100644
--- a/drivers/usb/gadget/ci_udc.h
+++ b/drivers/usb/gadget/ci_udc.h
@@ -8,45 +8,74 @@
 
 #define NUM_ENDPOINTS		6
 
+#ifdef CONFIG_CI_UDC_HAS_HOSTPC
+struct ci_udc {
+	u32 usbcmd;		/* 0x130 */
+	u32 usbsts;		/* 0x134 */
+	u32 pad1[3];
+	u32 devaddr;		/* 0x144 */
+	u32 epinitaddr;		/* 0x148 */
+	u32 pad2[10];
+	u32 portsc;		/* 0x174 */
+	u32 pad178[(0x1b4 - (0x174 + 4)) / 4];
+	u32 hostpc1_devlc;	/* 0x1b4 */
+	u32 pad1b8[(0x1f8 - (0x1b4 + 4)) / 4];
+	u32 usbmode;		/* 0x1f8 */
+	u32 pad1fc[(0x208 - (0x1f8 + 4)) / 4];
+	u32 epsetupstat;	/* 0x208 */
+	u32 epprime;		/* 0x20c */
+	u32 epflush;		/* 0x210 */
+	u32 epstat;		/* 0x214 */
+	u32 epcomp;		/* 0x218 */
+	u32 epctrl[16];		/* 0x21c */
+};
+#else
 struct ci_udc {
-#define MICRO_8FRAME	0x8
-#define USBCMD_ITC(x)	((((x) > 0xff) ? 0xff : x) << 16)
-#define USBCMD_FS2	(1 << 15)
-#define USBCMD_RST	(1 << 1)
-#define USBCMD_RUN	(1)
 	u32 usbcmd;		/* 0x140 */
-#define STS_SLI		(1 << 8)
-#define STS_URI		(1 << 6)
-#define STS_PCI		(1 << 2)
-#define STS_UEI		(1 << 1)
-#define STS_UI		(1 << 0)
 	u32 usbsts;		/* 0x144 */
 	u32 pad1[3];
 	u32 devaddr;		/* 0x154 */
 	u32 epinitaddr;		/* 0x158 */
 	u32 pad2[10];
-#define PTS_ENABLE	2
-#define PTS(x)		(((x) & 0x3) << 30)
-#define PFSC		(1 << 24)
 	u32 portsc;		/* 0x184 */
 	u32 pad3[8];
-#define USBMODE_DEVICE	2
 	u32 usbmode;		/* 0x1a8 */
 	u32 epstat;		/* 0x1ac */
-#define EPT_TX(x)	(1 << (((x) & 0xffff) + 16))
-#define EPT_RX(x)	(1 << ((x) & 0xffff))
 	u32 epprime;		/* 0x1b0 */
 	u32 epflush;		/* 0x1b4 */
 	u32 pad4;
 	u32 epcomp;		/* 0x1bc */
+	u32 epctrl[16];		/* 0x1c0 */
+};
+
+#define PTS_ENABLE	2
+#define PTS(x)		(((x) & 0x3) << 30)
+#define PFSC		(1 << 24)
+#endif
+
+#define MICRO_8FRAME	0x8
+#define USBCMD_ITC(x)	((((x) > 0xff) ? 0xff : x) << 16)
+#define USBCMD_FS2	(1 << 15)
+#define USBCMD_RST	(1 << 1)
+#define USBCMD_RUN	(1)
+
+#define STS_SLI		(1 << 8)
+#define STS_URI		(1 << 6)
+#define STS_PCI		(1 << 2)
+#define STS_UEI		(1 << 1)
+#define STS_UI		(1 << 0)
+
+#define USBMODE_DEVICE	2
+
+#define EPT_TX(x)	(1 << (((x) & 0xffff) + 16))
+#define EPT_RX(x)	(1 << ((x) & 0xffff))
+
 #define CTRL_TXE	(1 << 23)
 #define CTRL_TXR	(1 << 22)
 #define CTRL_RXE	(1 << 7)
 #define CTRL_RXR	(1 << 6)
 #define CTRL_TXT_BULK	(2 << 18)
 #define CTRL_RXT_BULK	(2 << 2)
-	u32 epctrl[16];		/* 0x1c0 */
-};
 
 struct ci_ep {
 	struct usb_ep ep;
-- 
1.8.1.5



More information about the U-Boot mailing list