Date:2011-04-19 03:15:16 (12 years 11 months ago)
Author:Lars C.
Commit:ef7f1fc4516f6bd90c75ec41123e4f79000003d1
Message:udc

Files: drivers/usb/gadget/jz4740_udc.c (19 diffs)

Change Details

drivers/usb/gadget/jz4740_udc.c
5858#define JZ_REG_UDC_INMAXP 0x10 /* EP1-2 IN Max Pkt Size 16-bit */
5959#define JZ_REG_UDC_INCSR 0x12 /* EP1-2 IN CSR LSB 8/16bit */
6060#define JZ_REG_UDC_INCSRH 0x13 /* EP1-2 IN CSR MSB 8-bit */
61
6162#define JZ_REG_UDC_OUTMAXP 0x14 /* EP1 OUT Max Pkt Size 16-bit */
6263#define JZ_REG_UDC_OUTCSR 0x16 /* EP1 OUT CSR LSB 8/16bit */
6364#define JZ_REG_UDC_OUTCSRH 0x17 /* EP1 OUT CSR MSB 8-bit */
...... 
116117#define USB_INCSR_UNDERRUN 0x04
117118#define USB_INCSR_FFNOTEMPT 0x02
118119#define USB_INCSR_INPKTRDY 0x01
120
119121#define USB_OUTCSRH_AUTOCLR 0x80
120122#define USB_OUTCSRH_ISO 0x40
121123#define USB_OUTCSRH_DMAREQENAB 0x20
...... 
153155# define DEBUG_SETUP(fmt,args...) do {} while(0)
154156#endif
155157
156static unsigned int use_dma = 0; /* 1: use DMA, 0: use PIO */
157
158module_param(use_dma, int, 0);
159MODULE_PARM_DESC(use_dma, "DMA mode enable flag");
160
161158static struct jz4740_udc jz4740_udc_controller;
162159
163160/*
...... 
252249    DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
253250
254251    buf = req->req.buf + req->req.actual;
255    prefetch(buf);
256252
257253    length = req->req.length - req->req.actual;
258254    if (length > count)
...... 
261257
262258    DEBUG("Write %d (count %d), fifo %x\n", length, count, ep->fifo);
263259
264    nlong = length >> 2;
265    nbyte = length & 0x3;
266    while (nlong--) {
267        writel(*((uint32_t *)buf), fifo);
268        buf += 4;
269    }
270    while (nbyte--)
271        writeb(*buf++, fifo);
260    memcpy_toio(fifo, buf, length);
272261
273262    return length;
274263}
...... 
282271    DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
283272
284273    buf = req->req.buf + req->req.actual;
285    prefetchw(buf);
286274
287275    length = req->req.length - req->req.actual;
288276    if (length > count)
289277        length = count;
290278    req->req.actual += length;
291279
292    DEBUG("Read %d, fifo %x\n", length, ep->fifo);
293    nlong = length >> 2;
294    nbyte = length & 0x3;
295    while (nlong--) {
296        *((uint32_t *)buf) = readl(fifo);
297        buf += 4;
298    }
299    while (nbyte--)
300        *buf++ = readb(fifo);
280    memcpy_fromio(buf, fifo, length);
301281
302282    return length;
303283}
...... 
378358    for (i = 0; i < UDC_MAX_ENDPOINTS; i++) {
379359        struct jz4740_ep *ep = &dev->ep[i];
380360
381        jz_udc_set_index(dev, ep_index(ep));
361        jz_udc_select_ep(ep);
382362        flush(ep);
383363    }
384364
...... 
486466
487467        ep->stopped = 1;
488468
489        jz_udc_set_index(dev, ep_index(ep));
469        jz_udc_select_ep(ep);
490470        nuke(ep, -ESHUTDOWN);
491471    }
492472
...... 
536516
537517/*-------------------------------------------------------------------------*/
538518
539/*
540 * Starting DMA using mode 1
541 */
542static void kick_dma(struct jz4740_ep *ep, struct jz4740_request *req)
543{
544    struct jz4740_udc *dev = ep->dev;
545    uint32_t count = req->req.length;
546    uint32_t physaddr = virt_to_phys((void *)req->req.buf);
547
548    DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
549
550    jz_udc_select_ep(ep);
551
552    if (ep_is_in(ep)) { /* Bulk-IN transfer using DMA channel 1 */
553        ep->reg_addr = JZ_REG_UDC_ADDR1;
554
555        dma_cache_wback_inv((unsigned long)req->req.buf, count);
556
557        pio_irq_enable(ep);
558
559        usb_writeb(dev, JZ_REG_UDC_INCSRH,
560               USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET | USB_INCSRH_DMAREQMODE);
561
562        usb_writel(dev, JZ_REG_UDC_ADDR1, physaddr);
563        usb_writel(dev, JZ_REG_UDC_COUNT1, count);
564        usb_writel(dev, JZ_REG_UDC_CNTL1, USB_CNTL_ENA | USB_CNTL_DIR_IN | USB_CNTL_MODE_1 |
565               USB_CNTL_INTR_EN | USB_CNTL_BURST_16 | USB_CNTL_EP(ep_index(ep)));
566    }
567    else { /* Bulk-OUT transfer using DMA channel 2 */
568        ep->reg_addr = JZ_REG_UDC_ADDR2;
569
570        dma_cache_wback_inv((unsigned long)req->req.buf, count);
571
572        pio_irq_enable(ep);
573
574        usb_setb(dev, JZ_REG_UDC_OUTCSRH,
575             USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE);
576
577        usb_writel(dev, JZ_REG_UDC_ADDR2, physaddr);
578        usb_writel(dev, JZ_REG_UDC_COUNT2, count);
579        usb_writel(dev, JZ_REG_UDC_CNTL2, USB_CNTL_ENA | USB_CNTL_MODE_1 |
580               USB_CNTL_INTR_EN | USB_CNTL_BURST_16 | USB_CNTL_EP(ep_index(ep)));
581    }
582}
583
584/*-------------------------------------------------------------------------*/
585
586519/** Write request to FIFO (max write == maxp size)
587520 * Return: 0 = still running, 1 = completed, negative = errno
588521 * NOTE: INDEX register must be set for EP
...... 
596529    DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
597530    max = le16_to_cpu(ep->desc->wMaxPacketSize);
598531
599    if (use_dma) {
600        uint32_t dma_count;
601
602        /* DMA interrupt generated due to the last packet loaded into the FIFO */
603
604        dma_count = usb_readl(dev, ep->reg_addr) - physaddr;
605        req->req.actual += dma_count;
606
607        if (dma_count % max) {
608            /* If the last packet is less than MAXP, set INPKTRDY manually */
609            usb_setb(dev, ep->csr, USB_INCSR_INPKTRDY);
610        }
611
612        done(ep, req, 0);
613        if (list_empty(&ep->queue)) {
614            pio_irq_disable(ep);
615            return 1;
616        }
617        else {
618            /* advance the request queue */
619            req = list_entry(ep->queue.next, struct jz4740_request, queue);
620            kick_dma(ep, req);
621            return 0;
622        }
623    }
624
625    /*
626     * PIO mode handling starts here ...
627     */
628
629532    csr = usb_readb(dev, ep->csr);
630533
631534    if (!(csr & USB_INCSR_FFNOTEMPT)) {
...... 
678581    uint32_t csr;
679582    unsigned count, is_short;
680583
681#if 0
682    uint32_t physaddr = virt_to_phys((void *)req->req.buf);
683
684    if (use_dma) {
685        uint32_t dma_count;
686
687        /* DMA interrupt generated due to a packet less than MAXP loaded into the FIFO */
688
689        dma_count = usb_readl(dev, ep->reg_addr) - physaddr;
690        req->req.actual += dma_count;
691
692        /* Disable interrupt and DMA */
693        pio_irq_disable(ep);
694        usb_writel(dev, JZ_REG_UDC_CNTL2, 0);
695
696        /* Read all bytes from this packet */
697        count = usb_readw(dev, JZ_REG_UDC_OUTCOUNT);
698        count = read_packet(ep, req, count);
699
700        if (count) {
701            /* If the last packet is greater than zero, clear OUTPKTRDY manually */
702            usb_clearb(dev, ep->csr, USB_OUTCSR_OUTPKTRDY);
703        }
704        done(ep, req, 0);
705
706        if (!list_empty(&ep->queue)) {
707            /* advance the request queue */
708            req = list_entry(ep->queue.next, struct jz4740_request, queue);
709            kick_dma(ep, req);
710        }
711
712        return 1;
713    }
714#endif
715    /*
716     * PIO mode handling starts here ...
717     */
718
719584    /* make sure there's a packet in the FIFO. */
720585    csr = usb_readb(dev, ep->csr);
721586    if (!(csr & USB_OUTCSR_OUTPKTRDY)) {
...... 
786651    ep->stopped = stopped;
787652}
788653
654static inline unsigned int jz4740_udc_ep_irq_enable_reg(struct jz4740_ep *ep)
655{
656    if (ep_is_in(ep))
657        return JZ_REG_UDC_INTRINE;
658    else
659        return JZ_REG_UDC_INTROUTE;
660}
661
789662/** Enable EP interrupt */
790663static void pio_irq_enable(struct jz4740_ep *ep)
791664{
792    uint8_t index = ep_index(ep);
793    struct jz4740_udc *dev = ep->dev;
794665    DEBUG("%s: EP%d %s\n", __FUNCTION__, ep_index(ep), ep_is_in(ep) ? "IN": "OUT");
795666
796    if (ep_is_in(ep)) {
797        switch (index) {
798        case 1:
799        case 2:
800            usb_setw(dev, JZ_REG_UDC_INTRINE, BIT(index));
801            break;
802        default:
803            DEBUG("Unknown endpoint: %d\n", index);
804            break;
805        }
806    }
807    else {
808        switch (index) {
809        case 1:
810            usb_setw(dev, JZ_REG_UDC_INTROUTE, BIT(index));
811            break;
812        default:
813            DEBUG("Unknown endpoint: %d\n", index);
814            break;
815        }
816    }
667    usb_setw(ep->dev, jz4740_udc_ep_irq_enable_reg(ep), BIT(ep_index(ep)));
817668}
818669
819670/** Disable EP interrupt */
820671static void pio_irq_disable(struct jz4740_ep *ep)
821672{
822    uint8_t index = ep_index(ep);
823
824673    DEBUG("%s: EP%d %s\n", __FUNCTION__, ep_index(ep), ep_is_in(ep) ? "IN": "OUT");
825674
826    if (ep_is_in(ep)) {
827        switch (ep_index(ep)) {
828        case 1:
829        case 2:
830            usb_clearw(ep->dev, JZ_REG_UDC_INTRINE, BIT(index));
831            break;
832        default:
833            DEBUG("Unknown endpoint: %d\n", index);
834            break;
835        }
836    }
837    else {
838        switch (ep_index(ep)) {
839        case 1:
840            usb_clearw(ep->dev, JZ_REG_UDC_INTROUTE, BIT(index));
841            break;
842        default:
843            DEBUG("Unknown endpoint: %d\n", index);
844            break;
845        }
846    }
675    usb_clearw(ep->dev, jz4740_udc_ep_irq_enable_reg(ep), BIT(ep_index(ep)));
847676}
848677
849678/*
...... 
899728    struct jz4740_request *req;
900729    DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
901730
902    jz_udc_set_index(dev, ep_index(ep));
731    jz_udc_select_ep(ep);
903732
904733    csr = usb_readb(dev, ep->csr);
905734    DEBUG("%s: %d, csr %x\n", __FUNCTION__, ep_idx, csr);
...... 
935764    if (ep->desc) {
936765        uint32_t csr;
937766
938        if (use_dma) {
939            /* DMA starts here ... */
940            if (!list_empty(&ep->queue)) {
941                req = list_first_entry(&ep->queue, struct jz4740_request, queue);
942                read_fifo(ep, req);
943            }
944            return;
945        }
946
947        /*
948         * PIO mode starts here ...
949         */
950
951767        while ((csr = usb_readb(dev, ep->csr)) &
952768               (USB_OUTCSR_OUTPKTRDY | USB_OUTCSR_SENTSTALL)) {
953769            DEBUG("%s: %x\n", __FUNCTION__, csr);
...... 
11941010{
11951011    struct jz4740_request *req;
11961012
1197    DEBUG("%s, %p\n", __FUNCTION__, ep);
1198
11991013    req = container_of(_req, struct jz4740_request, req);
12001014    WARN_ON(!list_empty(&req->queue));
1015
12011016    kfree(req);
12021017}
12031018
...... 
12551070            list_add_tail(&req->queue, &ep->queue);
12561071            jz4740_ep0_kick(dev, ep);
12571072            req = 0;
1258        } else if (use_dma) {
1259            /* DMA */
1260            kick_dma(ep, req);
12611073        }
1262        /* PIO */
12631074        else if (ep_is_in(ep)) {
12641075            /* EP1 & EP2 */
12651076            jz_udc_select_ep(ep);
...... 
16511462            return -EOPNOTSUPP;
16521463        }
16531464
1654        jz_udc_set_index(dev, ep_index(qep));
1465        jz_udc_select_ep(ep);
16551466
16561467        /* Return status on next IN token */
16571468        switch (qep->type) {
...... 
20281839        struct jz4740_ep *ep;
20291840        ep_num = (usb_readl(jz4740_udc, JZ_REG_UDC_CNTL1) >> 4) & 0xf;
20301841        ep = &jz4740_udc->ep[ep_num + 1];
2031        jz_udc_set_index(jz4740_udc, ep_num);
1842        jz_udc_select_ep(ep);
20321843        usb_setb(jz4740_udc, ep->csr, USB_INCSR_INPKTRDY);
20331844/* jz4740_in_epn(jz4740_udc, ep_num, intr_in);*/
20341845    }
...... 
23382149    return 0;
23392150}
23402151
2341static const struct dev_pm_ops jz4740_udc_pm_ops = {
2342    .suspend = jz4740_udc_suspend,
2343    .resume = jz4740_udc_resume,
2344};
2345
2152static SIMPLE_DEV_PM_OPS(jz4740_udc_pm_ops, jz4740_udc_suspend, jz4740_udc_resume);
23462153#define JZ4740_UDC_PM_OPS (&jz4740_udc_pm_ops)
23472154
23482155#else

Archive Download the corresponding diff file



interactive