[PATCH 6/9] USB: musb: introduce new MUSB_POLL_DMA option for BF52x anomaly handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Bryan Wu <cooloney@xxxxxxxxxx>

- MUSB_POLL_DMA option use DMA polling method to do FIFO read/write
   when we usb PIO mode. Adding this because pure PIO mode is no very
   stable during the USB testing
- Add ANOMALY_05000380 handling for BF527 (< 0.2 silicon)

Signed-off-by: Bryan Wu <cooloney@xxxxxxxxxx>
Signed-off-by: Mike Frysinger <vapier@xxxxxxxxxx>
---
 drivers/usb/musb/Kconfig    |    8 ++++++++
 drivers/usb/musb/blackfin.c |   42 +++++++++++++++++++++++++++++++++++++++++-
 drivers/usb/musb/blackfin.h |    2 +-
 3 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index b66e854..afd8289 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -148,6 +148,14 @@ config MUSB_PIO_ONLY
 	  you can still disable it at run time using the "use_dma=n" module
 	  parameter.
 
+config MUSB_DMA_POLL
+	bool 'Using DMA polling in MUSB PIO mode'
+	depends on MUSB_PIO_ONLY && BLACKFIN
+	default y if BLACKFIN
+	help
+	  Using DMA busy loop polling to copy to/from FIFO. Because pure
+	  PIO mode sometimes is also unstable in our testing.
+
 config USB_INVENTRA_DMA
 	bool
 	depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index 817afc5..2b42864 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -30,6 +30,10 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
 {
 	void __iomem *fifo = hw_ep->fifo;
 	void __iomem *epio = hw_ep->regs;
+#if defined(CONFIG_MUSB_DMA_POLL) && (!ANOMALY_05000380)
+	u8 epnum = hw_ep->epnum;
+	u16 dma_reg = 0;
+#endif
 
 	prefetch((u8 *)src);
 
@@ -40,12 +44,48 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
 
 	dump_fifo_data(src, len);
 
+#if defined(CONFIG_MUSB_DMA_POLL) && (!ANOMALY_05000380)
+	flush_dcache_range((unsigned int)src,
+		(unsigned int)(src + len));
+
+	/* Setup DMA address register */
+	dma_reg = (u16) ((u32) src & 0xFFFF);
+	bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg);
+	SSYNC();
+
+	dma_reg = (u16) (((u32) src >> 16) & 0xFFFF);
+	bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg);
+	SSYNC();
+
+	/* Setup DMA count register */
+	bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len);
+	bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0);
+	SSYNC();
+
+	/* Enable the DMA */
+	dma_reg = (epnum << 4) | DMA_ENA | INT_ENA | DIRECTION;
+	bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg);
+	SSYNC();
+
+	/* Wait for compelete */
+	while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum)))
+		cpu_relax();
+
+	/* acknowledge dma interrupt */
+	bfin_write_USB_DMA_INTERRUPT(1 << epnum);
+	SSYNC();
+
+	/* Reset DMA */
+	bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0);
+	SSYNC();
+#else
 	if (unlikely((unsigned long)src & 0x01))
 		outsw_8((unsigned long)fifo, src,
 			len & 0x01 ? (len >> 1) + 1 : len >> 1);
 	else
 		outsw((unsigned long)fifo, src,
 			len & 0x01 ? (len >> 1) + 1 : len >> 1);
+#endif
 }
 
 /*
@@ -55,7 +95,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
 {
 	void __iomem *fifo = hw_ep->fifo;
 
-#ifdef CONFIG_BF52x
+#if defined(CONFIG_MUSB_DMA_POLL)
 	u8 epnum = hw_ep->epnum;
 	u16 dma_reg = 0;
 
diff --git a/drivers/usb/musb/blackfin.h b/drivers/usb/musb/blackfin.h
index a240c1e..159fdea 100644
--- a/drivers/usb/musb/blackfin.h
+++ b/drivers/usb/musb/blackfin.h
@@ -32,7 +32,7 @@ static void dump_fifo_data(u8 *buf, u16 len)
 #define dump_fifo_data(buf, len)	do {} while (0)
 #endif
 
-#ifdef CONFIG_BF52x
+#if defined(CONFIG_MUSB_DMA_POLL)
 
 #define USB_DMA_BASE		USB_DMA_INTERRUPT
 #define USB_DMAx_CTRL		0x04
-- 
1.6.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux