* Patch [2/2] DaVinci CPPI TX DMA tasklet
@ 2008-08-21 13:58 Swaminathan S
2008-08-21 14:25 ` Felipe Balbi
[not found] ` <1219327122-28334-1-git-send-email-swami.iyer-l0cyMroinI0@public.gmane.org>
0 siblings, 2 replies; 10+ messages in thread
From: Swaminathan S @ 2008-08-21 13:58 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
felipe.balbi-xNZwKgViW5gAvxtiuMwx3w
Signed-off-by: Swaminathan S <swami.iyer-l0cyMroinI0@public.gmane.org>
This patch implements a tasklet to poll for TX Endpoint FIFO
empty status before completing a transfer. This is required
in the context of DaVinci CPPI DMA Tx transfers. CPPI
DMA engine generates completion interrupt before the data
actually moves out of TX FIFO and the driver needs to save the
Data toggle after ensuring that the FIFO is empty.
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index d443a61..9dd24c3 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -421,6 +421,12 @@ int __init musb_platform_init(struct musb *musb)
musb_readb(tibase, DAVINCI_USB_CTRL_REG));
musb->isr = davinci_interrupt;
+#ifdef CONFIG_USB_MUSB_HDRC_HCD
+#ifdef CONFIG_ARCH_DAVINCI
+ tasklet_init(&musb->fifo_check, musb_fifo_check_tasklet,
+ (unsigned long)musb);
+#endif
+#endif
return 0;
}
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 08e421f..c17681b 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -154,7 +154,8 @@ static inline void cppi_host_txdma_start(struct musb_hw_ep *ep)
/* NOTE: no locks here; caller should lock and select EP */
txcsr = musb_readw(ep->regs, MUSB_TXCSR);
- txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS;
+ txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE |
+ MUSB_TXCSR_H_WZC_BITS;
musb_writew(ep->regs, MUSB_TXCSR, txcsr);
}
@@ -356,6 +357,7 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
usb_hcd_unlink_urb_from_ep(musb_to_hcd(musb), urb);
qh->is_ready = 0;
+ qh->num_req--;
__musb_giveback(musb, urb, status);
qh->is_ready = ready;
@@ -688,14 +690,15 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
| MUSB_TXCSR_TXPKTRDY
);
csr |= MUSB_TXCSR_MODE;
-
- if (usb_gettoggle(urb->dev,
- qh->epnum, 1))
- csr |= MUSB_TXCSR_H_WR_DATATOGGLE
- | MUSB_TXCSR_H_DATATOGGLE;
- else
- csr |= MUSB_TXCSR_CLRDATATOG;
-
+ if (hw_ep->tx_reinit) {
+ if (usb_gettoggle(urb->dev,
+ qh->epnum, 1))
+ csr |= MUSB_TXCSR_H_WR_DATATOGGLE
+ | MUSB_TXCSR_H_DATATOGGLE;
+ else
+ csr |= MUSB_TXCSR_CLRDATATOG;
+ hw_ep->tx_reinit = 0;
+ }
/* twice in case of double packet buffering */
musb_writew(epio, MUSB_TXCSR, csr);
/* REVISIT may need to clear FLUSHFIFO ... */
@@ -1235,6 +1238,9 @@ void musb_host_tx(struct musb *musb, u8 epnum)
/* REVISIT may need to clear FLUSHFIFO ... */
musb_writew(epio, MUSB_TXCSR, tx_csr);
musb_writeb(epio, MUSB_TXINTERVAL, 0);
+#ifdef CONFIG_ARCH_DAVINCI
+ hw_ep->fifo_flush_check = 0;
+#endif
done = true;
}
@@ -1298,8 +1304,20 @@ void musb_host_tx(struct musb *musb, u8 epnum)
/* set status */
urb->status = status;
urb->actual_length = qh->offset;
+#ifdef CONFIG_ARCH_DAVINCI
+ /* Check for FIFO empty status. If not wait for the same
+ * before completing the urb. This ensures that the toggle
+ * status is correctly preserved and data will not be lost.
+ */
+ if (((tx_csr & MUSB_TXCSR_FIFONOTEMPTY) ||
+ (tx_csr & MUSB_TXCSR_TXPKTRDY)) &&
+ (qh->num_req == 1)) {
+ hw_ep->fifo_flush_check = 1;
+ tasklet_schedule(&musb->fifo_check);
+ goto finish;
+ }
+#endif
musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT);
-
} else if (!(tx_csr & MUSB_TXCSR_DMAENAB)) {
/* WARN_ON(!buf); */
@@ -1776,6 +1794,7 @@ static int musb_urb_enqueue(
*/
if (qh) {
urb->hcpriv = qh;
+ qh->num_req++;
return 0;
}
@@ -1891,6 +1910,7 @@ static int musb_urb_enqueue(
if (ret == 0) {
urb->hcpriv = qh;
+ qh->num_req = 1;
/* FIXME set urb->start_frame for iso/intr, it's tested in
* musb_start_urb(), but otherwise only konicawc cares ...
*/
@@ -1959,6 +1979,9 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in)
musb_writew(epio, MUSB_TXCSR, csr);
/* flush cpu writebuffer */
csr = musb_readw(epio, MUSB_TXCSR);
+#ifdef CONFIG_ARCH_DAVINCI
+ ep->fifo_flush_check = 0;
+#endif
}
if (status == 0)
musb_advance_schedule(ep->musb, urb, ep, is_in);
@@ -2132,6 +2155,46 @@ static int musb_bus_suspend(struct usb_hcd *hcd)
return 0;
}
+#ifdef CONFIG_ARCH_DAVINCI
+/* Tasklet routine to handle the completion request. Check for Fifo status
+ * before completing the request. Avoids false completions when data is still
+ * in the fifo
+ */
+void musb_fifo_check_tasklet(unsigned long data)
+{
+ struct musb *musb = (struct musb *)data;
+ u8 epnum = 1, sch_tsklt = 0;
+ struct musb_hw_ep *hw_ep = NULL;
+ unsigned long flags;
+ u16 csr;
+ struct musb_qh *qh;
+
+ do {
+ hw_ep = &(musb->endpoints[epnum++]);
+ spin_lock_irqsave(&musb->lock, flags);
+ if (hw_ep->fifo_flush_check) {
+ csr = musb_readw(hw_ep->regs, MUSB_TXCSR);
+ if (((csr & MUSB_TXCSR_FIFONOTEMPTY) ||
+ (csr & MUSB_TXCSR_TXPKTRDY)))
+ sch_tsklt = 1;
+ else {
+ hw_ep->fifo_flush_check = 0;
+ qh = hw_ep->out_qh;
+ musb_advance_schedule(musb, next_urb(qh),
+ hw_ep, USB_DIR_OUT);
+ DBG(6, "Completed Tasklet %d\n", hw_ep->epnum);
+ }
+ }
+
+ spin_unlock_irqrestore(&musb->lock, flags);
+ } while (epnum < MUSB_C_NUM_EPS);
+
+ if (sch_tsklt)
+ tasklet_schedule(&musb->fifo_check);
+}
+#endif
+
+
static int musb_bus_resume(struct usb_hcd *hcd)
{
/* resuming child port does the work */
@@ -2164,3 +2227,4 @@ const struct hc_driver musb_hc_driver = {
/* .start_port_reset = NULL, */
/* .hub_irq_enable = NULL, */
};
+
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: Patch [2/2] DaVinci CPPI TX DMA tasklet
2008-08-21 13:58 Patch [2/2] DaVinci CPPI TX DMA tasklet Swaminathan S
@ 2008-08-21 14:25 ` Felipe Balbi
[not found] ` <1219327122-28334-1-git-send-email-swami.iyer-l0cyMroinI0@public.gmane.org>
1 sibling, 0 replies; 10+ messages in thread
From: Felipe Balbi @ 2008-08-21 14:25 UTC (permalink / raw)
To: ext Swaminathan S; +Cc: linux-omap, linux-usb, felipe.balbi
On Thu, Aug 21, 2008 at 07:28:42PM +0530, ext Swaminathan S wrote:
>
> Signed-off-by: Swaminathan S <swami.iyer@ti.com>
>
> This patch implements a tasklet to poll for TX Endpoint FIFO
> empty status before completing a transfer. This is required
> in the context of DaVinci CPPI DMA Tx transfers. CPPI
> DMA engine generates completion interrupt before the data
> actually moves out of TX FIFO and the driver needs to save the
> Data toggle after ensuring that the FIFO is empty.
same comments from before.
> diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
> index d443a61..9dd24c3 100644
> --- a/drivers/usb/musb/davinci.c
> +++ b/drivers/usb/musb/davinci.c
> @@ -421,6 +421,12 @@ int __init musb_platform_init(struct musb *musb)
> musb_readb(tibase, DAVINCI_USB_CTRL_REG));
>
> musb->isr = davinci_interrupt;
> +#ifdef CONFIG_USB_MUSB_HDRC_HCD
use if (is_host_capable()) instead.
> + if (hw_ep->fifo_flush_check) {
> + csr = musb_readw(hw_ep->regs, MUSB_TXCSR);
> + if (((csr & MUSB_TXCSR_FIFONOTEMPTY) ||
> + (csr & MUSB_TXCSR_TXPKTRDY)))
> + sch_tsklt = 1;
> + else {
put {} on both branches.
> +
this new line is unnecessary
this was just a primary overview. I wanna test more this patch since it
changes a bit musb_ep_program() which would affect all archs using musb.
I'll leave my n810 testing during this weekend and get back to you later
on.
--
balbi
^ permalink raw reply [flat|nested] 10+ messages in thread[parent not found: <1219327122-28334-1-git-send-email-swami.iyer-l0cyMroinI0@public.gmane.org>]
* Re: Patch [2/2] DaVinci CPPI TX DMA tasklet
[not found] ` <1219327122-28334-1-git-send-email-swami.iyer-l0cyMroinI0@public.gmane.org>
@ 2008-08-21 15:09 ` Dmitry Krivoschekov
2008-08-21 19:15 ` David Brownell
2008-08-22 1:31 ` Subbrathnam, Swaminathan
0 siblings, 2 replies; 10+ messages in thread
From: Dmitry Krivoschekov @ 2008-08-21 15:09 UTC (permalink / raw)
To: Swaminathan S
Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA,
felipe.balbi-xNZwKgViW5gAvxtiuMwx3w
Hi Swami,
Swaminathan S wrote:
> Signed-off-by: Swaminathan S <swami.iyer-l0cyMroinI0@public.gmane.org>
>
> This patch implements a tasklet to poll for TX Endpoint FIFO
> empty status before completing a transfer. This is required
> in the context of DaVinci CPPI DMA Tx transfers. CPPI
> DMA engine generates completion interrupt before the data
> actually moves out of TX FIFO
I guess the DMA interrupt is generated after the data have been moved
from a s/w buffer to TX FIFO.
> and the driver needs to save the
> Data toggle after ensuring that the FIFO is empty.
why don't rely on an endpoint interrupt which is generated after a USB
transaction is complete?
Thanks,
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: Patch [2/2] DaVinci CPPI TX DMA tasklet
2008-08-21 15:09 ` Dmitry Krivoschekov
@ 2008-08-21 19:15 ` David Brownell
[not found] ` <200808211215.37760.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-08-22 1:31 ` Subbrathnam, Swaminathan
1 sibling, 1 reply; 10+ messages in thread
From: David Brownell @ 2008-08-21 19:15 UTC (permalink / raw)
To: Dmitry Krivoschekov, Swaminathan S
Cc: linux-omap, linux-usb, felipe.balbi, Kevin Hilman
On Thursday 21 August 2008, Dmitry Krivoschekov wrote:
> why don't rely on an endpoint interrupt which is generated
> after a USB transaction is complete?
That's what I thought *was* working a couple years ago...
I take it that something broke since then? Or is this
a corner case which didn't always work right?
I'm not sure this would be appropriate for mainline
until the DaVinci code can run there. There are a
bunch of arch/arm/mach-davinci updates needed first.
I know Kevin was looking at some of this, but just
now I think enabling MUSB on a 2.6.27-rc4 DaVinci
config means a broken build.
- Dave
^ permalink raw reply [flat|nested] 10+ messages in thread* RE: Patch [2/2] DaVinci CPPI TX DMA tasklet
2008-08-21 15:09 ` Dmitry Krivoschekov
2008-08-21 19:15 ` David Brownell
@ 2008-08-22 1:31 ` Subbrathnam, Swaminathan
2008-08-22 7:23 ` Felipe Balbi
1 sibling, 1 reply; 10+ messages in thread
From: Subbrathnam, Swaminathan @ 2008-08-22 1:31 UTC (permalink / raw)
To: Dmitry Krivoschekov
Cc: linux-omap@vger.kernel.org, linux-usb@vger.kernel.org,
felipe.balbi@nokia.com
Hi Dmitry,
Comments inlined.
swami
________________________________________
From: Dmitry Krivoschekov [dmitry.krivoschekov@gmail.com]
Sent: Thursday, August 21, 2008 8:39 PM
To: Subbrathnam, Swaminathan
Cc: linux-omap@vger.kernel.org; linux-usb@vger.kernel.org; felipe.balbi@nokia.com
Subject: Re: Patch [2/2] DaVinci CPPI TX DMA tasklet
Hi Swami,
Swaminathan S wrote:
> Signed-off-by: Swaminathan S <swami.iyer@ti.com>
>
> This patch implements a tasklet to poll for TX Endpoint FIFO
> empty status before completing a transfer. This is required
> in the context of DaVinci CPPI DMA Tx transfers. CPPI
> DMA engine generates completion interrupt before the data
> actually moves out of TX FIFO
I guess the DMA interrupt is generated after the data have been moved
from a s/w buffer to TX FIFO.
<Swami> Yes. This being an external DMA (unlike Mentor DMA) that was
the designed behavior.
> and the driver needs to save the
> Data toggle after ensuring that the FIFO is empty.
why don't rely on an endpoint interrupt which is generated after a USB
transaction is complete?
<Swami> When in DMA mode (mode 1) Endpoint interrupt does not get
generated (only DMA completion interrupt) and hence cannot rely on that.
Thanks,
Dmitry
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Patch [2/2] DaVinci CPPI TX DMA tasklet
2008-08-22 1:31 ` Subbrathnam, Swaminathan
@ 2008-08-22 7:23 ` Felipe Balbi
[not found] ` <20080822072308.GB9474-f9ZlEuEWxVfta4EC/59zMBl4MBrZKKet0E9HWUfgJXw@public.gmane.org>
0 siblings, 1 reply; 10+ messages in thread
From: Felipe Balbi @ 2008-08-22 7:23 UTC (permalink / raw)
To: ext Subbrathnam, Swaminathan
Cc: Dmitry Krivoschekov, linux-omap@vger.kernel.org,
linux-usb@vger.kernel.org, felipe.balbi@nokia.com
On Fri, Aug 22, 2008 at 07:01:26AM +0530, ext Subbrathnam, Swaminathan wrote:
> <Swami> When in DMA mode (mode 1) Endpoint interrupt does not get
> generated (only DMA completion interrupt) and hence cannot rely on that.
afaict, endpoint interrupt is generated case we get a short packet. Then
dma engine won't send that last short packet and an enpoint interrupt
will be generated, from that point you decide if you wanna use PIO or
reprogram the dma for mode 0.
--
balbi
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-08-22 9:12 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-21 13:58 Patch [2/2] DaVinci CPPI TX DMA tasklet Swaminathan S
2008-08-21 14:25 ` Felipe Balbi
[not found] ` <1219327122-28334-1-git-send-email-swami.iyer-l0cyMroinI0@public.gmane.org>
2008-08-21 15:09 ` Dmitry Krivoschekov
2008-08-21 19:15 ` David Brownell
[not found] ` <200808211215.37760.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-08-22 1:47 ` Subbrathnam, Swaminathan
[not found] ` <FCCFB4CDC6E5564B9182F639FC3560870229F52486-/tLxBxkBPtCIQmiDNMet8wC/G2K4zDHf@public.gmane.org>
2008-08-22 3:24 ` David Brownell
2008-08-22 7:21 ` Felipe Balbi
2008-08-22 1:31 ` Subbrathnam, Swaminathan
2008-08-22 7:23 ` Felipe Balbi
[not found] ` <20080822072308.GB9474-f9ZlEuEWxVfta4EC/59zMBl4MBrZKKet0E9HWUfgJXw@public.gmane.org>
2008-08-22 9:12 ` Subbrathnam, Swaminathan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.