11 #include <linux/module.h>
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
18 #include <linux/slab.h>
24 #define to_chdat(c) ((struct tusb_omap_dma_ch *)(c)->private_data)
87 static inline int tusb_omap_use_shared_dmareq(
struct tusb_omap_dma_ch *chdat)
92 dev_dbg(chdat->
musb->controller,
"ep%i dmareq0 is busy for ep%i\n",
93 chdat->
epnum, reg & 0xf);
98 reg = (1 << 4) | chdat->
epnum;
107 static inline void tusb_omap_free_shared_dmareq(
struct tusb_omap_dma_ch *chdat)
111 if ((reg & 0xf) != chdat->
epnum) {
113 chdat->
epnum, reg & 0xf);
123 static void tusb_omap_dma_cb(
int lch,
u16 ch_status,
void *
data)
131 void __iomem *ep_conf = hw_ep->conf;
133 unsigned long remaining,
flags,
pio;
147 chdat->
epnum, chdat->
tx ?
"tx" :
"rx",
160 chdat->
tx ?
"tx" :
"rx", chdat->
ch,
171 if (pio > 0 && pio < 32) {
191 tusb_omap_free_shared_dmareq(chdat);
221 spin_unlock_irqrestore(&musb->
lock, flags);
224 static int tusb_omap_dma_program(
struct dma_channel *channel,
u16 packet_sz,
229 struct musb *musb = chdat->
musb;
233 void __iomem *ep_conf = hw_ep->conf;
237 int src_burst, dst_burst;
243 if (
unlikely(dma_addr & 0x1) || (len < 32) || (len > packet_sz))
268 chdat->
tx ?
"tx" :
"rx", chdat->
ch,
285 if (tusb_omap_use_shared_dmareq(chdat) != 0) {
289 if (tusb_dma->
ch < 0) {
298 dmareq = tusb_dma->
dmareq;
318 if ((dma_addr & 0x3) == 0) {
320 dma_params.elem_count = 8;
323 dma_params.elem_count = 16;
324 fifo = hw_ep->fifo_async;
329 dev_dbg(musb->
controller,
"ep%i %s dma ch%i dma: %08x len: %u(%u) packet_sz: %i(%i)\n",
330 chdat->
epnum, chdat->
tx ?
"tx" :
"rx",
339 dma_params.src_start = (
unsigned long)dma_addr;
340 dma_params.src_ei = 0;
341 dma_params.src_fi = 0;
344 dma_params.dst_start = (
unsigned long)fifo;
345 dma_params.dst_ei = 1;
346 dma_params.dst_fi = -31;
348 dma_params.trigger = sync_dev;
350 dma_params.src_or_dst_synch = 0;
356 dma_params.src_start = (
unsigned long)fifo;
357 dma_params.src_ei = 1;
358 dma_params.src_fi = -31;
361 dma_params.dst_start = (
unsigned long)dma_addr;
362 dma_params.dst_ei = 0;
363 dma_params.dst_fi = 0;
365 dma_params.trigger = sync_dev;
367 dma_params.src_or_dst_synch = 1;
373 dev_dbg(musb->
controller,
"ep%i %s using %i-bit %s dma from 0x%08lx to 0x%08lx\n",
374 chdat->
epnum, chdat->
tx ?
"tx" :
"rx",
376 ((dma_addr & 0x3) == 0) ?
"sync" :
"async",
377 dma_params.src_start, dma_params.dst_start);
427 static int tusb_omap_dma_abort(
struct dma_channel *channel)
433 if (tusb_dma->
ch >= 0) {
448 static inline int tusb_omap_dma_allocate_dmareq(
struct tusb_omap_dma_ch *chdat)
451 int i, dmareq_nr = -1;
453 const int sync_dev[6] = {
463 int cur = (reg & (0xf << (i * 5))) >> (i * 5);
473 reg |= (chdat->
epnum << (dmareq_nr * 5));
475 reg |= ((1 << 4) << (dmareq_nr * 5));
478 chdat->
dmareq = dmareq_nr;
484 static inline void tusb_omap_dma_free_dmareq(
struct tusb_omap_dma_ch *chdat)
488 if (!chdat || chdat->
dmareq < 0)
492 reg &= ~(0x1f << (chdat->
dmareq * 5));
507 const char *dev_name;
516 musb = tusb_dma->
musb;
521 reg &= ~(1 << hw_ep->
epnum);
523 reg &= ~(1 << (hw_ep->
epnum + 15));
527 if (hw_ep->
epnum == 0) {
547 dev_name =
"TUSB transmit";
550 dev_name =
"TUSB receive";
555 chdat->
hw_ep = hw_ep;
566 ret = tusb_omap_dma_allocate_dmareq(chdat);
571 tusb_omap_dma_cb, channel, &chdat->
ch);
574 }
else if (tusb_dma->
ch == -1) {
580 tusb_omap_dma_cb,
NULL, &tusb_dma->
ch);
590 chdat->
tx ?
"tx" :
"rx",
591 chdat->
ch >= 0 ?
"dedicated" :
"shared",
592 chdat->
ch >= 0 ? chdat->
ch : tusb_dma->
ch,
599 tusb_omap_dma_free_dmareq(chdat);
607 static void tusb_omap_dma_release(
struct dma_channel *channel)
610 struct musb *musb = chdat->
musb;
618 reg |= (1 << chdat->
epnum);
620 reg |= (1 << (chdat->
epnum + 15));
625 reg |= (1 << chdat->
epnum);
627 reg |= (1 << (chdat->
epnum + 15));
632 if (chdat->
ch >= 0) {
639 tusb_omap_dma_free_dmareq(chdat);
692 tusb_dma->
controller.start = tusb_omap_dma_start;
693 tusb_dma->
controller.stop = tusb_omap_dma_stop;
694 tusb_dma->
controller.channel_alloc = tusb_omap_dma_allocate;
695 tusb_dma->
controller.channel_release = tusb_omap_dma_release;
696 tusb_dma->
controller.channel_program = tusb_omap_dma_program;
697 tusb_dma->
controller.channel_abort = tusb_omap_dma_abort;
710 dma_channel_pool[
i] =
ch;