This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

L138: DMA driven data transfer for USB 2.0

Other Parts Discussed in Thread: OMAP-L138

Hi,

I have been working on USB driver for L138. The current driver is using FIFO for data transfer.

I would like to enable the DMA so that the data transfer is DMA driven.

Not sure any implementation example that I can look at in Linux. If there is, kindly let me know the folder and the file in specific.

Thanks !!!

rgds,

kc Wong

  • Not sure if this helps. I believe the Linux USB driver has PIO and DMA support. Hard to tell with the many config options. Config flags of interest for OMAP-L138:

    # CONFIG_MUSB_PIO_ONLY is not set
    CONFIG_USB_TI_CPPI41_DMA_HW=y
    CONFIG_USB_TI_CPPI41_DMA=y

    Source:
    http://arago-project.org/git/projects/?p=linux-davinci.git;a=tree
     drivers/usb/musb/musb_core.c
     drivers/usb/musb/musb_gadget.c
     drivers/usb/musb/musb_dma.h
    and any other file that calls the macro "is_dma_capable()" seems to messing with DMA.

    You are a better programmer than me if you can figure out the Linux USB driver. Hopefully somebody can suggest a simpler USB DMA reference. Maybe U-Boot?

  • Actually, I am not familiar with Linux USB driver as well. Thus, I am getting the below book, hopefully it can help me to undestand the Linux USB stack better.

    http://www.amazon.com/Bootstrap-Yourself-Linux-USB-Stack-Validate/dp/1435457862/ref=sr_1_1?ie=UTF8&s=books&qid=1306910882&sr=1-1

    The DMA for USB 2.0 on OMAP L138 is what is called Communications Port programming Interface (CPPI) 4.1. I don't get much information online.

    The only document I have at this moment is the "OMAP-L1x Processor Universal Serial Bus 2.0 Controller User Guide (SPRUFM9H)".

    I will have a look on those source files you suggested. Thanks Norman.

  • HI,

    I have been reading "OMAP-L1x Processor Universal Serial Bus 2.0 Controller User Guide (SPRUFM9H)". It is still not clear to me how does CPPI DMA interrupt handling work ? The only section in this doument that mentions about it is 2.8.9. As I look at the Table 27 and Table 28 in section 2.8.13, the CPPI DMA interrupt is not in either table.

    I wonder how to handle CPPI DMA interrupt ? For example, how to enable/disable CPPI DMA interrupt. In section 2.8.9, it says the DMA interrupt is not maskable, does it mean that it cannot be disabled ?

    If there is an ISR for CPPI DMA , what is the event number to install the ISR ? Like USB0_INT, it is corresponding to event 58.

    I don't really understand section 2.8.9 ???

    2.8.9 CPPI DMA Transfer Interrupt Handling

     

     

    The CPPI DMA 4.1 Interrupt handling mechanism does not go through the PDR interrupt handler built into the core. The DMA interrupt line is directly routed to the Interrupt Dispatcher in a PDR compliant manner. The DMA interrupt is not maskable. The firmware needs to use queues reserved by hardware as Completion Queues, if required for the DMA interrupt to be generated on a completion of a transfer.

    Queues 24 and 25 are reserved by hardware for DMA transmit operations and queues 26 and 27 are reserved by hardware for DMA receive operations. If firmware uses these queues as Completion Queues, an interrupt will be generated when the transfer completes. If you need not to generate an interrupt, firmware is required to use queues that are not reserved as Completion Queues.

     

    rgds,

    kc Wong

  • Wong

    As mentioned in the document Section 2.11 Interrupt support,

    1) The USB0_INT (for ARM:58, for DSP:19) is interrupt number for USB2.0 controller.

    2) There is no explicit another interrupt number for DMA. The USB2.0 controller interrupt (i.e, USB0_INT) is only interrupt for both DMA and musb.

    3) To get the DMA completion qeueue interrupt you have to use the Tx completion queues(24 & 25) and Rx completion Queues (26 & 27) and in the US20_INT_HANDLER( ) , you must check the Queue Pending Register-0 (refer section 4.84) and check corresponding bits for completion queue# is set (bit 24,25,26,27). 

    4) If you do not want to get the DMA completion queue interrupt then you can use any free non interrupting queues other than (Q# 24,25,26,27).

    Let us know if anything is required.

    Regards

    Ravi B

  • Thanks, Ravi.

    So, I guess the Queue Pending Register-0 actually acts like the status register for CPPI DMA.

    And the interrupt generated will still map to the same ISR that corresponding to USB0_INT.

    1) I guess the CPPI DMA is not orignated from Mentor USB core. So, it will work regardless of PDR is enabled (CTRLR.UINT = 0) or not, right ?

    2) When CPPI DMA is used for data transfer, do we normally still turn on the endpoint interrupt to service RXPKTRDY and TXPKTRDY ???

    3) I guees not for question 2. But if we turn off the  endpoint interrupt, how about the SENTSTALL ?

  • On page 56 fo doucment "SPRUFM9H- July 2010", there is a note that I don't understand.

     

     

     

     

     

     

     

     

    NOTE:

     

    All descriptors (regardless of type) must be allocated at addresses that are naturally aligned to the smallest power of 2 that is equal to or greater than the descriptor size.

     

     

     

     I am trying to align each descriptor to 4-byte boundary, is this sufficient ?

    rgds,

    kc Wong

     

  • I would guess that you have to align to 32 or 64 bytes:

    Host Packet Descriptor, size of 32 or 48, align to 32 or 64
    Host Buffer Descriptor, size of 32, align to 32
    Teardown Descriptor, size of 32,  align to 32

    Essentially bottom 5 or 6 bits of address are 0.

     

  • Thanks Norman. I think I understand now.

    I think this is due to the fact that only upper 27 bits are used to indicate the descriptor pointer in Queue Manager Queue N Control Register D (CTRLD[0] - CTRLD[63]). The lower 5 bytes are for descriptor size.

    So, as descriptors are resided in Memory Region. I think I cannot static allocate the Memory Region using array as below, right ?

     HostBufferDescriptor MEMORY_REGION_0[NUMBER_OF_DESCRIPTOR];

     The compiler may guanrantee 4-byte alignment, but not 32-byte alignment, right ? I have to use dynamic allocator (malloc) to allocate the Memory Region ?

  • It's been a while since I manually aligned memory. The compiler will generally align to sizeof int. So an array is not guaranteed to be aligned to 32 bytes. In Linux, one of the kernel mallocs would return 4096 byte pages. A huge waste if you only need one or two descriptors. Other times, I have use assembler to align, allocate and export memory. Your compiler should have alignment pragmas. You could also align a specific segment in linker scripts. That's a bit hard to maintain though.

     

  • Ya, I think I will use dynamic allocator (malloc) and make adjustment on the start address with the below macros. More portable across different compiler.

    #define ALIGNMENT 32

    #define ALIGN(x)  (((x)+ALIGNMENT-1)&(~(ALIGNMENT-1)))

  • Just need some clarification ...

    I know Memory Region is used to host both Host Packet Descriptor and Host Buffer Descriptor.

    How about the Teardown Descriptor ?

    rgds,

    kc Wong

  • More questions on Teardown Descriptor ...

    I know software can initiate teardown event by setting a bit in either TXGCRn.TX_TEARDOWN or RXGCRn.RX_TEARDOWN. Will the hardware (either USB controller or CDMA controller) initiate teardown event ?

    I know when the channel teardown completes, the teardown descriptor is written to the Completion Queue, which is determined in either TXGCRn.TXDEFAULT_QNUM or RXGCRn.RX_DEFAULT_RQ_QNUM. How about submission queue ?

    Is there a submit queue for teardown descriptor ? Because I don't see a way to tell CDMA controller about the submit queue for teardown descriptor.