RE: [PATCH] MUSB: Workaround for simultaneous TX and RX usage

2008-08-12 Thread Gadiyar, Anand
> On Mon, Aug 04, 2008 at 06:48:22PM +0530, ext Gadiyar, Anand wrote:
> > MUSB RTL v1.4 has a hardware issue which results in a DMA controller
> > hang when TX and RX DMA channels are simultaneously enabled. This
> > affects at least OMAP2430 and OMAP34XX.
> >
> > Since RX transfers are in Mode 0 and anyway result in one DMA interrupt
> > per packet, we can use System DMA to unload the RX fifos. MUSB DMA can
> > be used for all TX channels as before.
> >
> > Tested with full-duplex TX and RX transfers using g_ether. Runs for 24
> > hours without a hang. Without this patch, the hang occurs within minutes.
> 
> I just don't like that amount of ifdefs, as we were discussing out of
> the list we should use runtime checks where possible.
> 
> Let's wait on this one since Anand will send another patch set later on
> this week.

Updated patch coming up. Run-time checks are still not implemented. It would
be nice to have, but I fail to see on what basis I can have the runtime check.
Suggestions are welcome.

I've left in only two #ifdefs - one for the dma callback function, and the other
for the call to omap_request_dma(). The other ifdefs are now gone - replaced 
with
runtime checks based on whether a system DMA channel has been acquired.

Also fixed a small bug which would make this patch not compile.

- Anand

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] MUSB: Workaround for simultaneous TX and RX usage

2008-08-05 Thread Felipe Balbi
On Mon, Aug 04, 2008 at 06:48:22PM +0530, ext Gadiyar, Anand wrote:
> MUSB RTL v1.4 has a hardware issue which results in a DMA controller
> hang when TX and RX DMA channels are simultaneously enabled. This
> affects at least OMAP2430 and OMAP34XX.
> 
> Since RX transfers are in Mode 0 and anyway result in one DMA interrupt
> per packet, we can use System DMA to unload the RX fifos. MUSB DMA can
> be used for all TX channels as before.
> 
> Tested with full-duplex TX and RX transfers using g_ether. Runs for 24
> hours without a hang. Without this patch, the hang occurs within minutes.

I just don't like that amount of ifdefs, as we were discussing out of
the list we should use runtime checks where possible.

Let's wait on this one since Anand will send another patch set later on
this week.

-- 
balbi
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] MUSB: Workaround for simultaneous TX and RX usage

2008-08-04 Thread Bryan Wu
On Mon, Aug 4, 2008 at 9:18 PM, Gadiyar, Anand <[EMAIL PROTECTED]> wrote:
> MUSB RTL v1.4 has a hardware issue which results in a DMA controller
> hang when TX and RX DMA channels are simultaneously enabled. This
> affects at least OMAP2430 and OMAP34XX.
>
> Since RX transfers are in Mode 0 and anyway result in one DMA interrupt
> per packet, we can use System DMA to unload the RX fifos. MUSB DMA can
> be used for all TX channels as before.
>

Hi Gadiyar,

We also found some similar issue on Blackfin with the MUSB+musbhsdma.
Some time DMA mode 1 interrupt lost and system hang.

But if we use the PIO mode and rewrite the
musb_read_fifo/musb_write_fifo to use DMA polling method,
the issue is gone.

Any idea about this?

-Bryan

> Tested with full-duplex TX and RX transfers using g_ether. Runs for 24
> hours without a hang. Without this patch, the hang occurs within minutes.
>
> Signed-off-by: Anand Gadiyar <[EMAIL PROTECTED]>
> ---
> This issue was first reported by Jon Hunter on [1]
>
> [1] http://marc.info/?l=linux-omap&m=119634480534453&w=2
>
>  drivers/usb/musb/Kconfig |8 +
>  drivers/usb/musb/musbhsdma.c |  174 
> +++
>  2 files changed, 153 insertions(+), 29 deletions(-)
>
> Index: testing/drivers/usb/musb/musbhsdma.c
> ===
> --- testing.orig/drivers/usb/musb/musbhsdma.c
> +++ testing/drivers/usb/musb/musbhsdma.c
> @@ -34,6 +34,7 @@
>  #include 
>  #include 
>  #include "musb_core.h"
> +#include 
>
>  #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
>  #include "omap2430.h"
> @@ -64,6 +65,9 @@
>
>  #define MUSB_HSDMA_CHANNELS8
>
> +#define MUSB_FIFO_ADDRESS(epnum)   \
> +   ((unsigned long) (OMAP_HSOTG_BASE + MUSB_FIFO_OFFSET(epnum)))
> +
>  struct musb_dma_controller;
>
>  struct musb_dma_channel {
> @@ -75,6 +79,10 @@ struct musb_dma_channel {
>u8  bIndex;
>u8  epnum;
>u8  transmit;
> +
> +#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX
> +   int sysdma_channel;
> +#endif
>  };
>
>  struct musb_dma_controller {
> @@ -93,6 +101,10 @@ static int dma_controller_start(struct d
>return 0;
>  }
>
> +#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX
> +static void musb_sysdma_completion(int lch, u16 ch_status, void *data);
> +#endif
> +
>  static void dma_channel_release(struct dma_channel *pChannel);
>
>  static int dma_controller_stop(struct dma_controller *c)
> @@ -144,6 +156,30 @@ static struct dma_channel *dma_channel_a
>/* Tx => mode 1; Rx => mode 0 */
>pChannel->desired_mode = transmit;
>pChannel->actual_len = 0;
> +   pImplChannel->sysdma_channel = -1;
> +
> +#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX
> +   if (!transmit) {
> +   int ret;
> +   ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE,
> +   "MUSB SysDMA", musb_sysdma_completion,
> +   (void *) pImplChannel,
> +   &(pImplChannel->sysdma_channel));
> +/* FIXME: Decide on the correct private data to use */
> +
> +   if (ret) {
> +   printk(KERN_ERR "request_dma failed:"
> +   " %d\n", ret);
> +   controller->bmUsedChannels &=
> +   ~(1 << bBit);
> +   pChannel->status =
> +   
> MUSB_DMA_STATUS_UNKNOWN;
> +   pImplChannel->sysdma_channel = -1;
> +   pChannel = NULL;
> +   }
> +   }
> +#endif
> +
>break;
>}
>}
> @@ -163,6 +199,14 @@ static void dma_channel_release(struct d
>~(1 << pImplChannel->bIndex);
>
>pChannel->status = MUSB_DMA_STATUS_UNKNOWN;
> +
> +#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX
> +   if (pImplChannel->sysdma_channel != -1) {
> +   omap_stop_dma(pImplChannel->sysdma_channel);
> +   omap_free_dma(pImplChannel->sysdma_channel);
> +   pImplChannel->sysdma_channel = -1;
> +   }
> +#endif
>  }
>
>  static void configure_channel(struct dma_channel *pChannel,
> @@ -179,43 +223,108 @@ static void configure_channel(struct dma
>DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
>pChannel, packet_sz, dma_addr, len, mode);
>
> -   if (mode) {
> -   csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
> -   BUG_ON(len < packet_sz);
> +#ifdef 

RE: [PATCH] MUSB: Workaround for simultaneous TX and RX usage

2008-08-04 Thread Gadiyar, Anand
> On Mon, Aug 04, 2008 at 06:48:22PM +0530, ext Gadiyar, Anand wrote:
> > MUSB RTL v1.4 has a hardware issue which results in a DMA controller
> > hang when TX and RX DMA channels are simultaneously enabled. This
> > affects at least OMAP2430 and OMAP34XX.
> >
> > Since RX transfers are in Mode 0 and anyway result in one DMA interrupt
> > per packet, we can use System DMA to unload the RX fifos. MUSB DMA can
> > be used for all TX channels as before.
> >
> > Tested with full-duplex TX and RX transfers using g_ether. Runs for 24
> > hours without a hang. Without this patch, the hang occurs within minutes.
>
> This patch is not applying against linux-omap musb neither musb on
> greg's queue. Could you please refresh it ? It's better to use the
> version on greg's queue, if it fails for linux-omap I can prepare a
> clean patch to avoid conflicts later.
>
> --
> balbi
>

Okay! I had prepared this Friday evening and it seemed to apply for me.
I'll check again and re-send.

- Anand
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] MUSB: Workaround for simultaneous TX and RX usage

2008-08-04 Thread Felipe Balbi
On Mon, Aug 04, 2008 at 06:48:22PM +0530, ext Gadiyar, Anand wrote:
> MUSB RTL v1.4 has a hardware issue which results in a DMA controller
> hang when TX and RX DMA channels are simultaneously enabled. This
> affects at least OMAP2430 and OMAP34XX.
> 
> Since RX transfers are in Mode 0 and anyway result in one DMA interrupt
> per packet, we can use System DMA to unload the RX fifos. MUSB DMA can
> be used for all TX channels as before.
> 
> Tested with full-duplex TX and RX transfers using g_ether. Runs for 24
> hours without a hang. Without this patch, the hang occurs within minutes.

This patch is not applying against linux-omap musb neither musb on
greg's queue. Could you please refresh it ? It's better to use the
version on greg's queue, if it fails for linux-omap I can prepare a
clean patch to avoid conflicts later.

-- 
balbi
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] MUSB: Workaround for simultaneous TX and RX usage

2008-08-04 Thread Gadiyar, Anand
MUSB RTL v1.4 has a hardware issue which results in a DMA controller
hang when TX and RX DMA channels are simultaneously enabled. This
affects at least OMAP2430 and OMAP34XX.

Since RX transfers are in Mode 0 and anyway result in one DMA interrupt
per packet, we can use System DMA to unload the RX fifos. MUSB DMA can
be used for all TX channels as before.

Tested with full-duplex TX and RX transfers using g_ether. Runs for 24
hours without a hang. Without this patch, the hang occurs within minutes.

Signed-off-by: Anand Gadiyar <[EMAIL PROTECTED]>
---
This issue was first reported by Jon Hunter on [1]

[1] http://marc.info/?l=linux-omap&m=119634480534453&w=2

 drivers/usb/musb/Kconfig |8 +
 drivers/usb/musb/musbhsdma.c |  174 +++
 2 files changed, 153 insertions(+), 29 deletions(-)

Index: testing/drivers/usb/musb/musbhsdma.c
===
--- testing.orig/drivers/usb/musb/musbhsdma.c
+++ testing/drivers/usb/musb/musbhsdma.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include "musb_core.h"
+#include 

 #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
 #include "omap2430.h"
@@ -64,6 +65,9 @@

 #define MUSB_HSDMA_CHANNELS8

+#define MUSB_FIFO_ADDRESS(epnum)   \
+   ((unsigned long) (OMAP_HSOTG_BASE + MUSB_FIFO_OFFSET(epnum)))
+
 struct musb_dma_controller;

 struct musb_dma_channel {
@@ -75,6 +79,10 @@ struct musb_dma_channel {
u8  bIndex;
u8  epnum;
u8  transmit;
+
+#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX
+   int sysdma_channel;
+#endif
 };

 struct musb_dma_controller {
@@ -93,6 +101,10 @@ static int dma_controller_start(struct d
return 0;
 }

+#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX
+static void musb_sysdma_completion(int lch, u16 ch_status, void *data);
+#endif
+
 static void dma_channel_release(struct dma_channel *pChannel);

 static int dma_controller_stop(struct dma_controller *c)
@@ -144,6 +156,30 @@ static struct dma_channel *dma_channel_a
/* Tx => mode 1; Rx => mode 0 */
pChannel->desired_mode = transmit;
pChannel->actual_len = 0;
+   pImplChannel->sysdma_channel = -1;
+
+#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX
+   if (!transmit) {
+   int ret;
+   ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE,
+   "MUSB SysDMA", musb_sysdma_completion,
+   (void *) pImplChannel,
+   &(pImplChannel->sysdma_channel));
+/* FIXME: Decide on the correct private data to use */
+
+   if (ret) {
+   printk(KERN_ERR "request_dma failed:"
+   " %d\n", ret);
+   controller->bmUsedChannels &=
+   ~(1 << bBit);
+   pChannel->status =
+   MUSB_DMA_STATUS_UNKNOWN;
+   pImplChannel->sysdma_channel = -1;
+   pChannel = NULL;
+   }
+   }
+#endif
+
break;
}
}
@@ -163,6 +199,14 @@ static void dma_channel_release(struct d
~(1 << pImplChannel->bIndex);

pChannel->status = MUSB_DMA_STATUS_UNKNOWN;
+
+#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX
+   if (pImplChannel->sysdma_channel != -1) {
+   omap_stop_dma(pImplChannel->sysdma_channel);
+   omap_free_dma(pImplChannel->sysdma_channel);
+   pImplChannel->sysdma_channel = -1;
+   }
+#endif
 }

 static void configure_channel(struct dma_channel *pChannel,
@@ -179,43 +223,108 @@ static void configure_channel(struct dma
DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
pChannel, packet_sz, dma_addr, len, mode);

-   if (mode) {
-   csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
-   BUG_ON(len < packet_sz);
+#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX
+   if (pImplChannel->sysdma_channel != -1) {
+   /* System DMA */
+   /* RX: set src = FIFO */
+
+   omap_set_dma_transfer_params(pImplChannel->sysdma_channel,
+   OMAP_DMA_DATA_TYPE_S8,
+   len, 1, /* One frame */
+   OMAP_DMA_SYNC_ELEMENT,
+   OMAP24XX_DMA_NO_DEVICE,
+   0); /* Src Sync */
+
+   omap_set_dma_src_params(pImplCh