aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/renesas_usbhs/common.c2
-rw-r--r--drivers/usb/renesas_usbhs/common.h35
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c380
-rw-r--r--drivers/usb/renesas_usbhs/fifo.h24
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c70
-rw-r--r--drivers/usb/renesas_usbhs/pipe.c4
-rw-r--r--drivers/usb/renesas_usbhs/pipe.h4
-rw-r--r--include/linux/usb/renesas_usbhs.h17
8 files changed, 533 insertions, 3 deletions
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c
index e510b29216b3..665259aec871 100644
--- a/drivers/usb/renesas_usbhs/common.c
+++ b/drivers/usb/renesas_usbhs/common.c
@@ -304,6 +304,8 @@ static int __devinit usbhs_probe(struct platform_device *pdev)
304 priv->dparam->pipe_type = usbhsc_default_pipe_type; 304 priv->dparam->pipe_type = usbhsc_default_pipe_type;
305 priv->dparam->pipe_size = ARRAY_SIZE(usbhsc_default_pipe_type); 305 priv->dparam->pipe_size = ARRAY_SIZE(usbhsc_default_pipe_type);
306 } 306 }
307 if (!priv->dparam->pio_dma_border)
308 priv->dparam->pio_dma_border = 64; /* 64byte */
307 309
308 /* FIXME */ 310 /* FIXME */
309 /* runtime power control ? */ 311 /* runtime power control ? */
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h
index 06d7239a044d..b410463a1212 100644
--- a/drivers/usb/renesas_usbhs/common.h
+++ b/drivers/usb/renesas_usbhs/common.h
@@ -36,6 +36,12 @@ struct usbhs_priv;
36#define CFIFO 0x0014 36#define CFIFO 0x0014
37#define CFIFOSEL 0x0020 37#define CFIFOSEL 0x0020
38#define CFIFOCTR 0x0022 38#define CFIFOCTR 0x0022
39#define D0FIFO 0x0100
40#define D0FIFOSEL 0x0028
41#define D0FIFOCTR 0x002A
42#define D1FIFO 0x0120
43#define D1FIFOSEL 0x002C
44#define D1FIFOCTR 0x002E
39#define INTENB0 0x0030 45#define INTENB0 0x0030
40#define INTENB1 0x0032 46#define INTENB1 0x0032
41#define BRDYENB 0x0036 47#define BRDYENB 0x0036
@@ -60,6 +66,30 @@ struct usbhs_priv;
60#define PIPEMAXP 0x006C 66#define PIPEMAXP 0x006C
61#define PIPEPERI 0x006E 67#define PIPEPERI 0x006E
62#define PIPEnCTR 0x0070 68#define PIPEnCTR 0x0070
69#define PIPE1TRE 0x0090
70#define PIPE1TRN 0x0092
71#define PIPE2TRE 0x0094
72#define PIPE2TRN 0x0096
73#define PIPE3TRE 0x0098
74#define PIPE3TRN 0x009A
75#define PIPE4TRE 0x009C
76#define PIPE4TRN 0x009E
77#define PIPE5TRE 0x00A0
78#define PIPE5TRN 0x00A2
79#define PIPEBTRE 0x00A4
80#define PIPEBTRN 0x00A6
81#define PIPECTRE 0x00A8
82#define PIPECTRN 0x00AA
83#define PIPEDTRE 0x00AC
84#define PIPEDTRN 0x00AE
85#define PIPEETRE 0x00B0
86#define PIPEETRN 0x00B2
87#define PIPEFTRE 0x00B4
88#define PIPEFTRN 0x00B6
89#define PIPE9TRE 0x00B8
90#define PIPE9TRN 0x00BA
91#define PIPEATRE 0x00BC
92#define PIPEATRN 0x00BE
63 93
64/* SYSCFG */ 94/* SYSCFG */
65#define SCKE (1 << 10) /* USB Module Clock Enable */ 95#define SCKE (1 << 10) /* USB Module Clock Enable */
@@ -78,6 +108,7 @@ struct usbhs_priv;
78#define RHST_HIGH_SPEED 3 /* High-speed connection */ 108#define RHST_HIGH_SPEED 3 /* High-speed connection */
79 109
80/* CFIFOSEL */ 110/* CFIFOSEL */
111#define DREQE (1 << 12) /* DMA Transfer Request Enable */
81#define MBW_32 (0x2 << 10) /* CFIFO Port Access Bit Width */ 112#define MBW_32 (0x2 << 10) /* CFIFO Port Access Bit Width */
82 113
83/* CFIFOCTR */ 114/* CFIFOCTR */
@@ -164,6 +195,10 @@ struct usbhs_priv;
164 195
165#define CCPL (1 << 2) /* Control Transfer End Enable */ 196#define CCPL (1 << 2) /* Control Transfer End Enable */
166 197
198/* PIPEnTRE */
199#define TRENB (1 << 9) /* Transaction Counter Enable */
200#define TRCLR (1 << 8) /* Transaction Counter Clear */
201
167/* FRMNUM */ 202/* FRMNUM */
168#define FRNM_MASK (0x7FF) 203#define FRNM_MASK (0x7FF)
169 204
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 14baaad20b79..2016a2448ccb 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -20,6 +20,8 @@
20#include "./pipe.h" 20#include "./pipe.h"
21 21
22#define usbhsf_get_cfifo(p) (&((p)->fifo_info.cfifo)) 22#define usbhsf_get_cfifo(p) (&((p)->fifo_info.cfifo))
23#define usbhsf_get_d0fifo(p) (&((p)->fifo_info.d0fifo))
24#define usbhsf_get_d1fifo(p) (&((p)->fifo_info.d1fifo))
23 25
24#define usbhsf_fifo_is_busy(f) ((f)->pipe) /* see usbhs_pipe_select_fifo */ 26#define usbhsf_fifo_is_busy(f) ((f)->pipe) /* see usbhs_pipe_select_fifo */
25 27
@@ -43,6 +45,7 @@ static struct usbhs_pkt_handle usbhsf_null_handler = {
43 45
44void usbhs_pkt_init(struct usbhs_pkt *pkt) 46void usbhs_pkt_init(struct usbhs_pkt *pkt)
45{ 47{
48 pkt->dma = DMA_ADDR_INVALID;
46 INIT_LIST_HEAD(&pkt->node); 49 INIT_LIST_HEAD(&pkt->node);
47} 50}
48 51
@@ -136,6 +139,9 @@ int __usbhs_pkt_handler(struct usbhs_pipe *pipe, int type)
136 case USBHSF_PKT_TRY_RUN: 139 case USBHSF_PKT_TRY_RUN:
137 func = pkt->handler->try_run; 140 func = pkt->handler->try_run;
138 break; 141 break;
142 case USBHSF_PKT_DMA_DONE:
143 func = pkt->handler->dma_done;
144 break;
139 default: 145 default:
140 dev_err(dev, "unknown pkt hander\n"); 146 dev_err(dev, "unknown pkt hander\n");
141 goto __usbhs_pkt_handler_end; 147 goto __usbhs_pkt_handler_end;
@@ -508,6 +514,330 @@ struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler = {
508}; 514};
509 515
510/* 516/*
517 * DMA fifo functions
518 */
519static struct dma_chan *usbhsf_dma_chan_get(struct usbhs_fifo *fifo,
520 struct usbhs_pkt *pkt)
521{
522 if (&usbhs_fifo_dma_push_handler == pkt->handler)
523 return fifo->tx_chan;
524
525 if (&usbhs_fifo_dma_pop_handler == pkt->handler)
526 return fifo->rx_chan;
527
528 return NULL;
529}
530
531static struct usbhs_fifo *usbhsf_get_dma_fifo(struct usbhs_priv *priv,
532 struct usbhs_pkt *pkt)
533{
534 struct usbhs_fifo *fifo;
535
536 /* DMA :: D0FIFO */
537 fifo = usbhsf_get_d0fifo(priv);
538 if (usbhsf_dma_chan_get(fifo, pkt) &&
539 !usbhsf_fifo_is_busy(fifo))
540 return fifo;
541
542 /* DMA :: D1FIFO */
543 fifo = usbhsf_get_d1fifo(priv);
544 if (usbhsf_dma_chan_get(fifo, pkt) &&
545 !usbhsf_fifo_is_busy(fifo))
546 return fifo;
547
548 return NULL;
549}
550
551#define usbhsf_dma_start(p, f) __usbhsf_dma_ctrl(p, f, DREQE)
552#define usbhsf_dma_stop(p, f) __usbhsf_dma_ctrl(p, f, 0)
553static void __usbhsf_dma_ctrl(struct usbhs_pipe *pipe,
554 struct usbhs_fifo *fifo,
555 u16 dreqe)
556{
557 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
558
559 usbhs_bset(priv, fifo->sel, DREQE, dreqe);
560}
561
562#define usbhsf_dma_map(p) __usbhsf_dma_map_ctrl(p, 1)
563#define usbhsf_dma_unmap(p) __usbhsf_dma_map_ctrl(p, 0)
564static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map)
565{
566 struct usbhs_pipe *pipe = pkt->pipe;
567 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
568 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
569
570 return info->dma_map_ctrl(pkt, map);
571}
572
573static void usbhsf_dma_complete(void *arg);
574static void usbhsf_dma_prepare_tasklet(unsigned long data)
575{
576 struct usbhs_pkt *pkt = (struct usbhs_pkt *)data;
577 struct usbhs_pipe *pipe = pkt->pipe;
578 struct usbhs_fifo *fifo = usbhs_pipe_to_fifo(pipe);
579 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
580 struct scatterlist sg;
581 struct dma_async_tx_descriptor *desc;
582 struct dma_chan *chan = usbhsf_dma_chan_get(fifo, pkt);
583 struct device *dev = usbhs_priv_to_dev(priv);
584 enum dma_data_direction dir;
585 dma_cookie_t cookie;
586
587 dir = usbhs_pipe_is_dir_in(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
588
589 sg_init_table(&sg, 1);
590 sg_set_page(&sg, virt_to_page(pkt->dma),
591 pkt->length, offset_in_page(pkt->dma));
592 sg_dma_address(&sg) = pkt->dma + pkt->actual;
593 sg_dma_len(&sg) = pkt->trans;
594
595 desc = chan->device->device_prep_slave_sg(chan, &sg, 1, dir,
596 DMA_PREP_INTERRUPT |
597 DMA_CTRL_ACK);
598 if (!desc)
599 return;
600
601 desc->callback = usbhsf_dma_complete;
602 desc->callback_param = pipe;
603
604 cookie = desc->tx_submit(desc);
605 if (cookie < 0) {
606 dev_err(dev, "Failed to submit dma descriptor\n");
607 return;
608 }
609
610 dev_dbg(dev, " %s %d (%d/ %d)\n",
611 fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
612
613 usbhsf_dma_start(pipe, fifo);
614 dma_async_issue_pending(chan);
615}
616
617static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)
618{
619 struct usbhs_pipe *pipe = pkt->pipe;
620 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
621 struct usbhs_fifo *fifo;
622 int len = pkt->length - pkt->actual;
623 int ret;
624
625 if (usbhs_pipe_is_busy(pipe))
626 return 0;
627
628 /* use PIO if packet is less than pio_dma_border or pipe is DCP */
629 if ((len < usbhs_get_dparam(priv, pio_dma_border)) ||
630 usbhs_pipe_is_dcp(pipe))
631 goto usbhsf_pio_prepare_push;
632
633 if (len % 4) /* 32bit alignment */
634 goto usbhsf_pio_prepare_push;
635
636 /* get enable DMA fifo */
637 fifo = usbhsf_get_dma_fifo(priv, pkt);
638 if (!fifo)
639 goto usbhsf_pio_prepare_push;
640
641 if (usbhsf_dma_map(pkt) < 0)
642 goto usbhsf_pio_prepare_push;
643
644 ret = usbhsf_fifo_select(pipe, fifo, 0);
645 if (ret < 0)
646 goto usbhsf_pio_prepare_push_unmap;
647
648 pkt->trans = len;
649
650 tasklet_init(&fifo->tasklet,
651 usbhsf_dma_prepare_tasklet,
652 (unsigned long)pkt);
653
654 tasklet_schedule(&fifo->tasklet);
655
656 return 0;
657
658usbhsf_pio_prepare_push_unmap:
659 usbhsf_dma_unmap(pkt);
660usbhsf_pio_prepare_push:
661 /*
662 * change handler to PIO
663 */
664 pkt->handler = &usbhs_fifo_pio_push_handler;
665
666 return pkt->handler->prepare(pkt, is_done);
667}
668
669static int usbhsf_dma_push_done(struct usbhs_pkt *pkt, int *is_done)
670{
671 struct usbhs_pipe *pipe = pkt->pipe;
672
673 pkt->actual = pkt->trans;
674
675 *is_done = !pkt->zero; /* send zero packet ? */
676
677 usbhsf_dma_stop(pipe, pipe->fifo);
678 usbhsf_dma_unmap(pkt);
679 usbhsf_fifo_unselect(pipe, pipe->fifo);
680
681 return 0;
682}
683
684struct usbhs_pkt_handle usbhs_fifo_dma_push_handler = {
685 .prepare = usbhsf_dma_prepare_push,
686 .dma_done = usbhsf_dma_push_done,
687};
688
689static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done)
690{
691 struct usbhs_pipe *pipe = pkt->pipe;
692 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
693 struct usbhs_fifo *fifo;
694 int len, ret;
695
696 if (usbhs_pipe_is_busy(pipe))
697 return 0;
698
699 if (usbhs_pipe_is_dcp(pipe))
700 goto usbhsf_pio_prepare_pop;
701
702 /* get enable DMA fifo */
703 fifo = usbhsf_get_dma_fifo(priv, pkt);
704 if (!fifo)
705 goto usbhsf_pio_prepare_pop;
706
707 ret = usbhsf_fifo_select(pipe, fifo, 0);
708 if (ret < 0)
709 goto usbhsf_pio_prepare_pop;
710
711 /* use PIO if packet is less than pio_dma_border */
712 len = usbhsf_fifo_rcv_len(priv, fifo);
713 len = min(pkt->length - pkt->actual, len);
714 if (len % 4) /* 32bit alignment */
715 goto usbhsf_pio_prepare_pop_unselect;
716
717 if (len < usbhs_get_dparam(priv, pio_dma_border))
718 goto usbhsf_pio_prepare_pop_unselect;
719
720 ret = usbhsf_fifo_barrier(priv, fifo);
721 if (ret < 0)
722 goto usbhsf_pio_prepare_pop_unselect;
723
724 if (usbhsf_dma_map(pkt) < 0)
725 goto usbhsf_pio_prepare_pop_unselect;
726
727 /* DMA */
728
729 /*
730 * usbhs_fifo_dma_pop_handler :: prepare
731 * enabled irq to come here.
732 * but it is no longer needed for DMA. disable it.
733 */
734 usbhsf_rx_irq_ctrl(pipe, 0);
735
736 pkt->trans = len;
737
738 tasklet_init(&fifo->tasklet,
739 usbhsf_dma_prepare_tasklet,
740 (unsigned long)pkt);
741
742 tasklet_schedule(&fifo->tasklet);
743
744 return 0;
745
746usbhsf_pio_prepare_pop_unselect:
747 usbhsf_fifo_unselect(pipe, fifo);
748usbhsf_pio_prepare_pop:
749
750 /*
751 * change handler to PIO
752 */
753 pkt->handler = &usbhs_fifo_pio_pop_handler;
754
755 return pkt->handler->try_run(pkt, is_done);
756}
757
758static int usbhsf_dma_pop_done(struct usbhs_pkt *pkt, int *is_done)
759{
760 struct usbhs_pipe *pipe = pkt->pipe;
761 int maxp = usbhs_pipe_get_maxpacket(pipe);
762
763 usbhsf_dma_stop(pipe, pipe->fifo);
764 usbhsf_dma_unmap(pkt);
765 usbhsf_fifo_unselect(pipe, pipe->fifo);
766
767 pkt->actual += pkt->trans;
768
769 if ((pkt->actual == pkt->length) || /* receive all data */
770 (pkt->trans < maxp)) { /* short packet */
771 *is_done = 1;
772 } else {
773 /* re-enable */
774 usbhsf_prepare_pop(pkt, is_done);
775 }
776
777 return 0;
778}
779
780struct usbhs_pkt_handle usbhs_fifo_dma_pop_handler = {
781 .prepare = usbhsf_prepare_pop,
782 .try_run = usbhsf_dma_try_pop,
783 .dma_done = usbhsf_dma_pop_done
784};
785
786/*
787 * DMA setting
788 */
789static bool usbhsf_dma_filter(struct dma_chan *chan, void *param)
790{
791 struct sh_dmae_slave *slave = param;
792
793 /*
794 * FIXME
795 *
796 * usbhs doesn't recognize id = 0 as valid DMA
797 */
798 if (0 == slave->slave_id)
799 return false;
800
801 chan->private = slave;
802
803 return true;
804}
805
806static void usbhsf_dma_quit(struct usbhs_priv *priv, struct usbhs_fifo *fifo)
807{
808 if (fifo->tx_chan)
809 dma_release_channel(fifo->tx_chan);
810 if (fifo->rx_chan)
811 dma_release_channel(fifo->rx_chan);
812
813 fifo->tx_chan = NULL;
814 fifo->rx_chan = NULL;
815}
816
817static void usbhsf_dma_init(struct usbhs_priv *priv,
818 struct usbhs_fifo *fifo)
819{
820 struct device *dev = usbhs_priv_to_dev(priv);
821 dma_cap_mask_t mask;
822
823 dma_cap_zero(mask);
824 dma_cap_set(DMA_SLAVE, mask);
825 fifo->tx_chan = dma_request_channel(mask, usbhsf_dma_filter,
826 &fifo->tx_slave);
827
828 dma_cap_zero(mask);
829 dma_cap_set(DMA_SLAVE, mask);
830 fifo->rx_chan = dma_request_channel(mask, usbhsf_dma_filter,
831 &fifo->rx_slave);
832
833 if (fifo->tx_chan || fifo->rx_chan)
834 dev_info(dev, "enable DMAEngine (%s%s%s)\n",
835 fifo->name,
836 fifo->tx_chan ? "[TX]" : " ",
837 fifo->rx_chan ? "[RX]" : " ");
838}
839
840/*
511 * irq functions 841 * irq functions
512 */ 842 */
513static int usbhsf_irq_empty(struct usbhs_priv *priv, 843static int usbhsf_irq_empty(struct usbhs_priv *priv,
@@ -570,6 +900,19 @@ static int usbhsf_irq_ready(struct usbhs_priv *priv,
570 return 0; 900 return 0;
571} 901}
572 902
903static void usbhsf_dma_complete(void *arg)
904{
905 struct usbhs_pipe *pipe = arg;
906 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
907 struct device *dev = usbhs_priv_to_dev(priv);
908 int ret;
909
910 ret = usbhs_pkt_dmadone(pipe);
911 if (ret < 0)
912 dev_err(dev, "dma_complete run_error %d : %d\n",
913 usbhs_pipe_number(pipe), ret);
914}
915
573/* 916/*
574 * fifo init 917 * fifo init
575 */ 918 */
@@ -577,6 +920,8 @@ void usbhs_fifo_init(struct usbhs_priv *priv)
577{ 920{
578 struct usbhs_mod *mod = usbhs_mod_get_current(priv); 921 struct usbhs_mod *mod = usbhs_mod_get_current(priv);
579 struct usbhs_fifo *cfifo = usbhsf_get_cfifo(priv); 922 struct usbhs_fifo *cfifo = usbhsf_get_cfifo(priv);
923 struct usbhs_fifo *d0fifo = usbhsf_get_d0fifo(priv);
924 struct usbhs_fifo *d1fifo = usbhsf_get_d1fifo(priv);
580 925
581 mod->irq_empty = usbhsf_irq_empty; 926 mod->irq_empty = usbhsf_irq_empty;
582 mod->irq_ready = usbhsf_irq_ready; 927 mod->irq_ready = usbhsf_irq_ready;
@@ -584,6 +929,19 @@ void usbhs_fifo_init(struct usbhs_priv *priv)
584 mod->irq_brdysts = 0; 929 mod->irq_brdysts = 0;
585 930
586 cfifo->pipe = NULL; 931 cfifo->pipe = NULL;
932 cfifo->tx_chan = NULL;
933 cfifo->rx_chan = NULL;
934
935 d0fifo->pipe = NULL;
936 d0fifo->tx_chan = NULL;
937 d0fifo->rx_chan = NULL;
938
939 d1fifo->pipe = NULL;
940 d1fifo->tx_chan = NULL;
941 d1fifo->rx_chan = NULL;
942
943 usbhsf_dma_init(priv, usbhsf_get_d0fifo(priv));
944 usbhsf_dma_init(priv, usbhsf_get_d1fifo(priv));
587} 945}
588 946
589void usbhs_fifo_quit(struct usbhs_priv *priv) 947void usbhs_fifo_quit(struct usbhs_priv *priv)
@@ -594,6 +952,9 @@ void usbhs_fifo_quit(struct usbhs_priv *priv)
594 mod->irq_ready = NULL; 952 mod->irq_ready = NULL;
595 mod->irq_bempsts = 0; 953 mod->irq_bempsts = 0;
596 mod->irq_brdysts = 0; 954 mod->irq_brdysts = 0;
955
956 usbhsf_dma_quit(priv, usbhsf_get_d0fifo(priv));
957 usbhsf_dma_quit(priv, usbhsf_get_d1fifo(priv));
597} 958}
598 959
599int usbhs_fifo_probe(struct usbhs_priv *priv) 960int usbhs_fifo_probe(struct usbhs_priv *priv)
@@ -602,10 +963,29 @@ int usbhs_fifo_probe(struct usbhs_priv *priv)
602 963
603 /* CFIFO */ 964 /* CFIFO */
604 fifo = usbhsf_get_cfifo(priv); 965 fifo = usbhsf_get_cfifo(priv);
966 fifo->name = "CFIFO";
605 fifo->port = CFIFO; 967 fifo->port = CFIFO;
606 fifo->sel = CFIFOSEL; 968 fifo->sel = CFIFOSEL;
607 fifo->ctr = CFIFOCTR; 969 fifo->ctr = CFIFOCTR;
608 970
971 /* D0FIFO */
972 fifo = usbhsf_get_d0fifo(priv);
973 fifo->name = "D0FIFO";
974 fifo->port = D0FIFO;
975 fifo->sel = D0FIFOSEL;
976 fifo->ctr = D0FIFOCTR;
977 fifo->tx_slave.slave_id = usbhs_get_dparam(priv, d0_tx_id);
978 fifo->rx_slave.slave_id = usbhs_get_dparam(priv, d0_rx_id);
979
980 /* D1FIFO */
981 fifo = usbhsf_get_d1fifo(priv);
982 fifo->name = "D1FIFO";
983 fifo->port = D1FIFO;
984 fifo->sel = D1FIFOSEL;
985 fifo->ctr = D1FIFOCTR;
986 fifo->tx_slave.slave_id = usbhs_get_dparam(priv, d1_tx_id);
987 fifo->rx_slave.slave_id = usbhs_get_dparam(priv, d1_rx_id);
988
609 return 0; 989 return 0;
610} 990}
611 991
diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h
index 94db269f84c2..ed6d8e56c13c 100644
--- a/drivers/usb/renesas_usbhs/fifo.h
+++ b/drivers/usb/renesas_usbhs/fifo.h
@@ -17,18 +17,33 @@
17#ifndef RENESAS_USB_FIFO_H 17#ifndef RENESAS_USB_FIFO_H
18#define RENESAS_USB_FIFO_H 18#define RENESAS_USB_FIFO_H
19 19
20#include <linux/interrupt.h>
21#include <linux/sh_dma.h>
22#include <asm/dma.h>
20#include "pipe.h" 23#include "pipe.h"
21 24
25#define DMA_ADDR_INVALID (~(dma_addr_t)0)
26
22struct usbhs_fifo { 27struct usbhs_fifo {
28 char *name;
23 u32 port; /* xFIFO */ 29 u32 port; /* xFIFO */
24 u32 sel; /* xFIFOSEL */ 30 u32 sel; /* xFIFOSEL */
25 u32 ctr; /* xFIFOCTR */ 31 u32 ctr; /* xFIFOCTR */
26 32
27 struct usbhs_pipe *pipe; 33 struct usbhs_pipe *pipe;
34 struct tasklet_struct tasklet;
35
36 struct dma_chan *tx_chan;
37 struct dma_chan *rx_chan;
38
39 struct sh_dmae_slave tx_slave;
40 struct sh_dmae_slave rx_slave;
28}; 41};
29 42
30struct usbhs_fifo_info { 43struct usbhs_fifo_info {
31 struct usbhs_fifo cfifo; 44 struct usbhs_fifo cfifo;
45 struct usbhs_fifo d0fifo;
46 struct usbhs_fifo d1fifo;
32}; 47};
33 48
34struct usbhs_pkt_handle; 49struct usbhs_pkt_handle;
@@ -36,8 +51,10 @@ struct usbhs_pkt {
36 struct list_head node; 51 struct list_head node;
37 struct usbhs_pipe *pipe; 52 struct usbhs_pipe *pipe;
38 struct usbhs_pkt_handle *handler; 53 struct usbhs_pkt_handle *handler;
54 dma_addr_t dma;
39 void *buf; 55 void *buf;
40 int length; 56 int length;
57 int trans;
41 int actual; 58 int actual;
42 int zero; 59 int zero;
43}; 60};
@@ -45,6 +62,7 @@ struct usbhs_pkt {
45struct usbhs_pkt_handle { 62struct usbhs_pkt_handle {
46 int (*prepare)(struct usbhs_pkt *pkt, int *is_done); 63 int (*prepare)(struct usbhs_pkt *pkt, int *is_done);
47 int (*try_run)(struct usbhs_pkt *pkt, int *is_done); 64 int (*try_run)(struct usbhs_pkt *pkt, int *is_done);
65 int (*dma_done)(struct usbhs_pkt *pkt, int *is_done);
48}; 66};
49 67
50/* 68/*
@@ -61,12 +79,17 @@ void usbhs_fifo_quit(struct usbhs_priv *priv);
61enum { 79enum {
62 USBHSF_PKT_PREPARE, 80 USBHSF_PKT_PREPARE,
63 USBHSF_PKT_TRY_RUN, 81 USBHSF_PKT_TRY_RUN,
82 USBHSF_PKT_DMA_DONE,
64}; 83};
65 84
66extern struct usbhs_pkt_handle usbhs_fifo_pio_push_handler; 85extern struct usbhs_pkt_handle usbhs_fifo_pio_push_handler;
67extern struct usbhs_pkt_handle usbhs_fifo_pio_pop_handler; 86extern struct usbhs_pkt_handle usbhs_fifo_pio_pop_handler;
68extern struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler; 87extern struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler;
69 88
89extern struct usbhs_pkt_handle usbhs_fifo_dma_push_handler;
90extern struct usbhs_pkt_handle usbhs_fifo_dma_pop_handler;
91
92
70void usbhs_pkt_init(struct usbhs_pkt *pkt); 93void usbhs_pkt_init(struct usbhs_pkt *pkt);
71void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, 94void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
72 struct usbhs_pkt_handle *handler, 95 struct usbhs_pkt_handle *handler,
@@ -76,5 +99,6 @@ int __usbhs_pkt_handler(struct usbhs_pipe *pipe, int type);
76 99
77#define usbhs_pkt_start(p) __usbhs_pkt_handler(p, USBHSF_PKT_PREPARE) 100#define usbhs_pkt_start(p) __usbhs_pkt_handler(p, USBHSF_PKT_PREPARE)
78#define usbhs_pkt_run(p) __usbhs_pkt_handler(p, USBHSF_PKT_TRY_RUN) 101#define usbhs_pkt_run(p) __usbhs_pkt_handler(p, USBHSF_PKT_TRY_RUN)
102#define usbhs_pkt_dmadone(p) __usbhs_pkt_handler(p, USBHSF_PKT_DMA_DONE)
79 103
80#endif /* RENESAS_USB_FIFO_H */ 104#endif /* RENESAS_USB_FIFO_H */
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 89d2b16fbb10..31d28dc78aa3 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -160,6 +160,71 @@ static void usbhsg_queue_done(struct usbhs_pkt *pkt)
160 usbhsg_queue_pop(uep, ureq, 0); 160 usbhsg_queue_pop(uep, ureq, 0);
161} 161}
162 162
163static int usbhsg_dma_map(struct device *dev,
164 struct usbhs_pkt *pkt,
165 enum dma_data_direction dir)
166{
167 struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt);
168 struct usb_request *req = &ureq->req;
169
170 if (pkt->dma != DMA_ADDR_INVALID) {
171 dev_err(dev, "dma is already mapped\n");
172 return -EIO;
173 }
174
175 if (req->dma == DMA_ADDR_INVALID) {
176 pkt->dma = dma_map_single(dev, pkt->buf, pkt->length, dir);
177 } else {
178 dma_sync_single_for_device(dev, req->dma, req->length, dir);
179 pkt->dma = req->dma;
180 }
181
182 if (dma_mapping_error(dev, pkt->dma)) {
183 dev_err(dev, "dma mapping error %x\n", pkt->dma);
184 return -EIO;
185 }
186
187 return 0;
188}
189
190static int usbhsg_dma_unmap(struct device *dev,
191 struct usbhs_pkt *pkt,
192 enum dma_data_direction dir)
193{
194 struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt);
195 struct usb_request *req = &ureq->req;
196
197 if (pkt->dma == DMA_ADDR_INVALID) {
198 dev_err(dev, "dma is not mapped\n");
199 return -EIO;
200 }
201
202 if (req->dma == DMA_ADDR_INVALID)
203 dma_unmap_single(dev, pkt->dma, pkt->length, dir);
204 else
205 dma_sync_single_for_cpu(dev, req->dma, req->length, dir);
206
207 pkt->dma = DMA_ADDR_INVALID;
208
209 return 0;
210}
211
212static int usbhsg_dma_map_ctrl(struct usbhs_pkt *pkt, int map)
213{
214 struct usbhs_pipe *pipe = pkt->pipe;
215 struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe);
216 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
217 struct device *dev = usbhsg_gpriv_to_dev(gpriv);
218 enum dma_data_direction dir;
219
220 dir = usbhs_pipe_is_dir_in(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
221
222 if (map)
223 return usbhsg_dma_map(dev, pkt, dir);
224 else
225 return usbhsg_dma_unmap(dev, pkt, dir);
226}
227
163/* 228/*
164 * USB_TYPE_STANDARD / clear feature functions 229 * USB_TYPE_STANDARD / clear feature functions
165 */ 230 */
@@ -434,6 +499,8 @@ static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep,
434 499
435 usbhs_pkt_init(usbhsg_ureq_to_pkt(ureq)); 500 usbhs_pkt_init(usbhsg_ureq_to_pkt(ureq));
436 501
502 ureq->req.dma = DMA_ADDR_INVALID;
503
437 return &ureq->req; 504 return &ureq->req;
438} 505}
439 506
@@ -569,7 +636,8 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
569 * pipe initialize and enable DCP 636 * pipe initialize and enable DCP
570 */ 637 */
571 usbhs_pipe_init(priv, 638 usbhs_pipe_init(priv,
572 usbhsg_queue_done); 639 usbhsg_queue_done,
640 usbhsg_dma_map_ctrl);
573 usbhs_fifo_init(priv); 641 usbhs_fifo_init(priv);
574 usbhsg_uep_init(gpriv); 642 usbhsg_uep_init(gpriv);
575 643
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c
index c0505876fd8c..d0ae846632cd 100644
--- a/drivers/usb/renesas_usbhs/pipe.c
+++ b/drivers/usb/renesas_usbhs/pipe.c
@@ -532,7 +532,8 @@ static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
532} 532}
533 533
534void usbhs_pipe_init(struct usbhs_priv *priv, 534void usbhs_pipe_init(struct usbhs_priv *priv,
535 void (*done)(struct usbhs_pkt *pkt)) 535 void (*done)(struct usbhs_pkt *pkt),
536 int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map))
536{ 537{
537 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv); 538 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
538 struct device *dev = usbhs_priv_to_dev(priv); 539 struct device *dev = usbhs_priv_to_dev(priv);
@@ -572,6 +573,7 @@ void usbhs_pipe_init(struct usbhs_priv *priv,
572 } 573 }
573 574
574 info->done = done; 575 info->done = done;
576 info->dma_map_ctrl = dma_map_ctrl;
575} 577}
576 578
577struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, 579struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h
index 484adbed6dfb..35e100477e55 100644
--- a/drivers/usb/renesas_usbhs/pipe.h
+++ b/drivers/usb/renesas_usbhs/pipe.h
@@ -44,6 +44,7 @@ struct usbhs_pipe_info {
44 int bufnmb_last; /* FIXME : driver needs good allocator */ 44 int bufnmb_last; /* FIXME : driver needs good allocator */
45 45
46 void (*done)(struct usbhs_pkt *pkt); 46 void (*done)(struct usbhs_pkt *pkt);
47 int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map);
47}; 48};
48 49
49/* 50/*
@@ -82,7 +83,8 @@ void usbhs_pipe_remove(struct usbhs_priv *priv);
82int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); 83int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe);
83int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe); 84int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe);
84void usbhs_pipe_init(struct usbhs_priv *priv, 85void usbhs_pipe_init(struct usbhs_priv *priv,
85 void (*done)(struct usbhs_pkt *pkt)); 86 void (*done)(struct usbhs_pkt *pkt),
87 int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map));
86int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe); 88int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe);
87void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe); 89void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe);
88int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe); 90int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe);
diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h
index 3a7f1d982dd6..8977431259c6 100644
--- a/include/linux/usb/renesas_usbhs.h
+++ b/include/linux/usb/renesas_usbhs.h
@@ -110,6 +110,23 @@ struct renesas_usbhs_driver_param {
110 * delay time from notify_hotplug callback 110 * delay time from notify_hotplug callback
111 */ 111 */
112 int detection_delay; 112 int detection_delay;
113
114 /*
115 * option:
116 *
117 * dma id for dmaengine
118 */
119 int d0_tx_id;
120 int d0_rx_id;
121 int d1_tx_id;
122 int d1_rx_id;
123
124 /*
125 * option:
126 *
127 * pio <--> dma border.
128 */
129 int pio_dma_border; /* default is 64byte */
113}; 130};
114 131
115/* 132/*