mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* ehci patches
@ 2012-04-12 19:40 Sascha Hauer
  2012-04-12 19:40 ` [PATCH 1/4] USB ehci: make cache handling simpler Sascha Hauer
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Sascha Hauer @ 2012-04-12 19:40 UTC (permalink / raw)
  To: barebox

The following patches contain some changes for the ehci driver.
Most interesting for all ehci users is the speed up on initialization
based on a patch I found on the U-Boot list. Also, the i.MX53 LOCO
gets USB support.

Sascha

----------------------------------------------------------------
Sascha Hauer (4):
      USB ehci: make cache handling simpler
      USB ehci: speed up initialization
      ARM i.MX53: Setup USB clocks
      ARM i.MX53 LOCO: Add USB support

 arch/arm/boards/freescale-mx53-loco/board.c |   17 +++++
 arch/arm/mach-imx/imx53.c                   |   17 ++++-
 drivers/usb/core/usb.c                      |    2 +-
 drivers/usb/host/ehci-hcd.c                 |   98 +++++++++------------------
 4 files changed, 63 insertions(+), 71 deletions(-)

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 1/4] USB ehci: make cache handling simpler
  2012-04-12 19:40 ehci patches Sascha Hauer
@ 2012-04-12 19:40 ` Sascha Hauer
  2012-04-12 19:40 ` [PATCH 2/4] USB ehci: speed up initialization Sascha Hauer
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2012-04-12 19:40 UTC (permalink / raw)
  To: barebox

for chache handling the ehci driver iterates over the hardware lists
of QHs/TDs. As we have a fixed number of maximum entries in this lists
we can allocate them as arrays and and clean/invalidate the arrays
instead which is much simpler. While at it, move the allocation to
ehci_probe so that we do not lose memory each time ehci_init is called.
Also, use memalign to allocate the QHs/TDs.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/host/ehci-hcd.c |   96 ++++++++++++++-----------------------------
 1 file changed, 30 insertions(+), 66 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 81e3a42..505d919 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -42,13 +42,16 @@ struct ehci_priv {
 	struct ehci_hcor *hcor;
 	struct usb_host host;
 	struct QH *qh_list;
-	void *qhp;
+	struct qTD *td;
 	int portreset;
 	unsigned long flags;
 };
 
 #define to_ehci(ptr) container_of(ptr, struct ehci_priv, host)
 
+#define NUM_QH	2
+#define NUM_TD	3
+
 static struct descriptor {
 	struct usb_hub_descriptor hub;
 	struct usb_device_descriptor device;
@@ -125,10 +128,11 @@ static struct descriptor {
  */
 static void flush_invalidate(void *addr, int size, int flush)
 {
-	if (flush)
+	if (flush) {
 		dma_flush_range((unsigned long)addr, (unsigned long)(addr + size));
-	else
+	} else {
 		dma_inv_range((unsigned long)addr, (unsigned long)(addr + size));
+	}
 }
 
 static void cache_qtd(struct qTD *qtd, int flush)
@@ -136,76 +140,39 @@ static void cache_qtd(struct qTD *qtd, int flush)
 	u32 *ptr = (u32 *)qtd->qt_buffer[0];
 	int len = (qtd->qt_token & 0x7fff0000) >> 16;
 
-	flush_invalidate(qtd, sizeof(struct qTD), flush);
 	if (ptr && len)
 		flush_invalidate(ptr, len, flush);
 }
 
-
-static inline struct QH *qh_addr(struct QH *qh)
+static void cache_qh(struct ehci_priv *ehci, int flush)
 {
-	return (struct QH *)((u32)qh & 0xffffffe0);
-}
-
-static void cache_qh(struct QH *qh, int flush)
-{
-	struct qTD *qtd;
-	struct qTD *next;
-	static struct qTD *first_qtd;
-
-	/*
-	 * Walk the QH list and flush/invalidate all entries
-	 */
-	while (1) {
-		flush_invalidate(qh_addr(qh), sizeof(struct QH), flush);
-		if ((u32)qh & QH_LINK_TYPE_QH)
-			break;
-		qh = qh_addr(qh);
-		qh = (struct QH *)qh->qh_link;
-	}
-	qh = qh_addr(qh);
+	int i;
 
-	/*
-	 * Save first qTD pointer, needed for invalidating pass on this QH
-	 */
-	if (flush)
-		first_qtd = qtd = (struct qTD *)(*(u32 *)&qh->qh_overlay &
-						 0xffffffe0);
-	else
-		qtd = first_qtd;
+	flush_invalidate(ehci->qh_list, sizeof(struct QH) * NUM_QH, flush);
+	flush_invalidate(ehci->td, sizeof(struct qTD) * NUM_TD, flush);
 
-	/*
-	 * Walk the qTD list and flush/invalidate all entries
-	 */
-	while (1) {
-		if (qtd == NULL)
-			break;
-		cache_qtd(qtd, flush);
-		next = (struct qTD *)((u32)qtd->qt_next & 0xffffffe0);
-		if (next == qtd)
-			break;
-		qtd = next;
-	}
+	for (i = 0; i < NUM_TD; i ++)
+		cache_qtd(&ehci->td[i], flush);
 }
 
-static inline void ehci_flush_dcache(struct QH *qh)
+static inline void ehci_flush_dcache(struct ehci_priv *ehci)
 {
-	cache_qh(qh, 1);
+	cache_qh(ehci, 1);
 }
 
-static inline void ehci_invalidate_dcache(struct QH *qh)
+static inline void ehci_invalidate_dcache(struct ehci_priv *ehci)
 {
-	cache_qh(qh, 0);
+	cache_qh(ehci, 0);
 }
 #else /* CONFIG_MMU */
 /*
  *
  */
-static inline void ehci_flush_dcache(struct QH *qh)
+static inline void ehci_flush_dcache(struct ehci_priv *ehci)
 {
 }
 
-static inline void ehci_invalidate_dcache(struct QH *qh)
+static inline void ehci_invalidate_dcache(struct ehci_priv *ehci)
 {
 }
 #endif /* CONFIG_MMU */
@@ -299,8 +266,6 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	uint32_t cmd;
 	int ret = 0;
 	uint64_t start, timeout_val;
-	static struct QH __qh __attribute__((aligned(32)));
-	static struct qTD __td[3] __attribute__((aligned(32)));
 
 	debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe,
 	      buffer, length, req);
@@ -311,10 +276,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		      le16_to_cpu(req->value), le16_to_cpu(req->value),
 		      le16_to_cpu(req->index));
 
-	memset(&__qh, 0, sizeof(struct QH));
-	memset(&__td, 0, sizeof(struct qTD) * 3);
+	memset(&ehci->qh_list[1], 0, sizeof(struct QH));
+	memset(ehci->td, 0, sizeof(struct qTD) * NUM_TD);
 
-	qh = &__qh;
+	qh = &ehci->qh_list[1];
 	qh->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
 	c = (usb_pipespeed(pipe) != USB_SPEED_HIGH &&
 	     usb_pipeendpoint(pipe) == 0) ? 1 : 0;
@@ -341,7 +306,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	    usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
 
 	if (req != NULL) {
-		td = &__td[0];
+		td = &ehci->td[0];
 
 		td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
 		td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
@@ -360,7 +325,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	}
 
 	if (length > 0 || req == NULL) {
-		td = &__td[1];
+		td = &ehci->td[1];
 
 		td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
 		td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
@@ -380,7 +345,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	}
 
 	if (req) {
-		td = &__td[2];
+		td = &ehci->td[2];
 
 		td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
 		td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
@@ -398,7 +363,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	ehci->qh_list->qh_link = cpu_to_hc32((uint32_t) qh | QH_LINK_TYPE_QH);
 
 	/* Flush dcache */
-	ehci_flush_dcache(ehci->qh_list);
+	ehci_flush_dcache(ehci);
 
 	usbsts = ehci_readl(&ehci->hcor->or_usbsts);
 	ehci_writel(&ehci->hcor->or_usbsts, (usbsts & 0x3f));
@@ -420,7 +385,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	vtd = td;
 	do {
 		/* Invalidate dcache */
-		ehci_invalidate_dcache(ehci->qh_list);
+		ehci_invalidate_dcache(ehci);
 		token = hc32_to_cpu(vtd->qt_token);
 		if (is_timeout(start, timeout_val)) {
 			/* Disable async schedule. */
@@ -802,10 +767,6 @@ static int ehci_init(struct usb_host *host)
 	if (ehci_reset(ehci) != 0)
 		return -1;
 
-	/* Set head of reclaim list */
-	ehci->qhp = xzalloc(sizeof(struct QH) + 32);
-	ehci->qh_list = (struct QH *)(((unsigned long)ehci->qhp + 32) & ~31);
-
 	ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
 	ehci->qh_list->qh_endpt1 = cpu_to_hc32((1 << 15) | (USB_SPEED_HIGH << 12));
 	ehci->qh_list->qh_curtd = cpu_to_hc32(QT_NEXT_TERMINATE);
@@ -917,6 +878,9 @@ static int ehci_probe(struct device_d *dev)
 	ehci->hccr = dev_request_mem_region(dev, 0);
 	ehci->hcor = dev_request_mem_region(dev, 1);
 
+	ehci->qh_list = xmemalign(32, sizeof(struct QH) * NUM_QH);
+	ehci->td = xmemalign(32, sizeof(struct qTD) * NUM_TD);
+
 	host->init = ehci_init;
 	host->submit_int_msg = submit_int_msg;
 	host->submit_control_msg = submit_control_msg;
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 2/4] USB ehci: speed up initialization
  2012-04-12 19:40 ehci patches Sascha Hauer
  2012-04-12 19:40 ` [PATCH 1/4] USB ehci: make cache handling simpler Sascha Hauer
@ 2012-04-12 19:40 ` Sascha Hauer
  2012-04-12 19:40 ` [PATCH 3/4] ARM i.MX53: Setup USB clocks Sascha Hauer
  2012-04-12 19:40 ` [PATCH 4/4] ARM i.MX53 LOCO: Add USB support Sascha Hauer
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2012-04-12 19:40 UTC (permalink / raw)
  To: barebox

This is based on the following U-Boot commit:

commit 5f4b4f2fed3ab8590c8c06b78642f8c1467acacf
Author: Vincent Palatin <vpalatin@chromium.org>
Date:   Mon Dec 5 14:52:22 2011 -0800

    ehci: speed up initialization

    According to EHCI specification v1.0, the controller should stabilize
    the power on a port at most 20 ms after the port power bit transition.
    So, we put this setting in the virtual descriptor corresponding field,
    (bPwrOn2PwrGood = 10 => 10 x 2ms = 20ms), this saves about 500ms at each
    controller initialization/enumeration.

    Signed-off-by: Vincent Palatin <vpalatin@chromium.org>

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/core/usb.c      |    2 +-
 drivers/usb/host/ehci-hcd.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 7039a2c..ba23e0e 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -934,8 +934,8 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
 	for (i = 0; i < dev->maxchild; i++) {
 		usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
 		USB_HUB_PRINTF("port %d returns %lX\n", i + 1, dev->status);
-		wait_ms(hub->desc.bPwrOn2PwrGood * 2);
 	}
+	mdelay(20);
 }
 
 #define MAX_TRIES 5
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 505d919..ae2b41e 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -64,7 +64,7 @@ static struct descriptor {
 		0x29,		/* bDescriptorType: hub descriptor */
 		2,		/* bNrPorts -- runtime modified */
 		0,		/* wHubCharacteristics */
-		0xff,		/* bPwrOn2PwrGood */
+		10,		/* bPwrOn2PwrGood */
 		0,		/* bHubCntrCurrent */
 		{},		/* Device removable */
 		{}		/* at most 7 ports! XXX */
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 3/4] ARM i.MX53: Setup USB clocks
  2012-04-12 19:40 ehci patches Sascha Hauer
  2012-04-12 19:40 ` [PATCH 1/4] USB ehci: make cache handling simpler Sascha Hauer
  2012-04-12 19:40 ` [PATCH 2/4] USB ehci: speed up initialization Sascha Hauer
@ 2012-04-12 19:40 ` Sascha Hauer
  2012-04-12 19:40 ` [PATCH 4/4] ARM i.MX53 LOCO: Add USB support Sascha Hauer
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2012-04-12 19:40 UTC (permalink / raw)
  To: barebox

- get USB PHY clock from OSC (24MHz)
- adjust USB clock to 54MHz

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/imx53.c |   17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-imx/imx53.c b/arch/arm/mach-imx/imx53.c
index 8742c46..b5dbc39 100644
--- a/arch/arm/mach-imx/imx53.c
+++ b/arch/arm/mach-imx/imx53.c
@@ -154,10 +154,15 @@ void imx53_init_lowlevel(unsigned int cpufreq_mhz)
 
 	writel(0x00016154, ccm + MX5_CCM_CBCMR);
 
-	/* change uart clk parent to pll2 */
 	r = readl(ccm + MX5_CCM_CSCMR1);
-	r &= ~(3 << 24);
-	r |= (1 << 24);
+
+	/* change uart clk parent to pll2 */
+	r &= ~MX5_CCM_CSCMR1_UART_CLK_SEL_MASK;
+	r |= 1 << MX5_CCM_CSCMR1_UART_CLK_SEL_OFFSET;
+
+	/* USB phy clock from osc */
+	r &= ~(1 << MX5_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET);
+
 	writel(r, ccm + MX5_CCM_CSCMR1);
 
 	/* make sure change is effective */
@@ -187,6 +192,12 @@ void imx53_init_lowlevel(unsigned int cpufreq_mhz)
 	r &= ~MX5_CCM_CSCDR1_ESDHC3_MX53_CLK_PODF_MASK;
 	r |= 1 << MX5_CCM_CSCDR1_ESDHC3_MX53_CLK_PODF_OFFSET;
 
+	r &= ~MX5_CCM_CSCDR1_USBOH3_CLK_PRED_MASK;
+	r &= ~MX5_CCM_CSCDR1_USBOH3_CLK_PODF_MASK;
+
+	r |= 3 << MX5_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET;
+	r |= 1 << MX5_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET;
+
 	writel(r, ccm + MX5_CCM_CSCDR1);
 
 	/* Restore the default values in the Gate registers */
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 4/4] ARM i.MX53 LOCO: Add USB support
  2012-04-12 19:40 ehci patches Sascha Hauer
                   ` (2 preceding siblings ...)
  2012-04-12 19:40 ` [PATCH 3/4] ARM i.MX53: Setup USB clocks Sascha Hauer
@ 2012-04-12 19:40 ` Sascha Hauer
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2012-04-12 19:40 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/boards/freescale-mx53-loco/board.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/boards/freescale-mx53-loco/board.c b/arch/arm/boards/freescale-mx53-loco/board.c
index 6ae597a..78e8f9a 100644
--- a/arch/arm/boards/freescale-mx53-loco/board.c
+++ b/arch/arm/boards/freescale-mx53-loco/board.c
@@ -95,6 +95,8 @@ static struct pad_desc loco_pads[] = {
 	/* I2C0 */
 	MX53_PAD_CSI0_DAT8__I2C1_SDA,
 	MX53_PAD_CSI0_DAT9__I2C1_SCL,
+
+	MX53_PAD_PATA_DA_2__GPIO7_8,
 };
 
 static struct i2c_board_info i2c_devices[] = {
@@ -149,6 +151,7 @@ static void loco_fec_reset(void)
 #define LOCO_SD3_CD			IMX_GPIO_NR(3, 11)
 #define LOCO_SD3_WP			IMX_GPIO_NR(3, 12)
 #define LOCO_SD1_CD			IMX_GPIO_NR(3, 13)
+#define MX53_LOCO_USB_PWREN		IMX_GPIO_NR(7, 8)
 
 static struct esdhc_platform_data loco_sd1_data = {
 	.cd_gpio = LOCO_SD1_CD,
@@ -163,8 +166,19 @@ static struct esdhc_platform_data loco_sd3_data = {
 	.wp_type = ESDHC_WP_GPIO,
 };
 
+static void loco_ehci_init(void)
+{
+	/* USB PWR enable */
+	gpio_direction_output(MX53_LOCO_USB_PWREN, 0);
+	gpio_set_value(MX53_LOCO_USB_PWREN, 1);
+
+	writel(0, MX53_OTG_BASE_ADDR + 0x384); /* setup portsc */
+	add_generic_usb_ehci_device(1, MX53_OTG_BASE_ADDR + 0x200, NULL);
+}
+
 static int loco_devices_init(void)
 {
+
 	imx53_iim_register_fec_ethaddr();
 	imx53_add_fec(&fec_info);
 	imx53_add_mmc0(&loco_sd1_data);
@@ -172,6 +186,9 @@ static int loco_devices_init(void)
 	i2c_register_board_info(0, i2c_devices, ARRAY_SIZE(i2c_devices));
 	imx53_add_i2c0(NULL);
 
+	if (IS_ENABLED(CONFIG_USB_EHCI))
+		loco_ehci_init();
+
 	loco_fec_reset();
 
 	set_silicon_rev(imx_silicon_revision());
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

end of thread, other threads:[~2012-04-12 19:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-12 19:40 ehci patches Sascha Hauer
2012-04-12 19:40 ` [PATCH 1/4] USB ehci: make cache handling simpler Sascha Hauer
2012-04-12 19:40 ` [PATCH 2/4] USB ehci: speed up initialization Sascha Hauer
2012-04-12 19:40 ` [PATCH 3/4] ARM i.MX53: Setup USB clocks Sascha Hauer
2012-04-12 19:40 ` [PATCH 4/4] ARM i.MX53 LOCO: Add USB support Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox