I have written a driver for a UART in omap4460 panda board running on Linux platform.I have enabled DMA in FIFO mode in UART.My user application transfers 100 bytes of data from user space to kernel buffer(DMA buffer).
As soon as the DMA channel is enabled, data from DMA buffer is copied to FIFO which is then transmitted to TSR of UART.Since my FIFO size is 64bytes,only 64 bytes is transmitted to TSR.
What should I do to transfer remaining bytes from DMA buffer to FIFO?/ IS there any overflow occuring?
Edit: Added some part of configuration code below represents the UART configuration
/* Software reset */
iowrite32(0x2,uart_vbaddr + UART_SYSC);
while((ioread32(uart_vbaddr + UART_SYSS) & 0x1)== 0);
/* FIFOs and DMA Settings */
lcr = ioread32(uart_vbaddr + UART_LCR);
iowrite32(UART_MODE_B,uart_vbaddr + UART_LCR);
efr = ioread32(uart_vbaddr + UART_EFR);
iowrite32(0x10,uart_vbaddr + UART_EFR);/
iowrite32(UART_MODE_A,uart_vbaddr + UART_LCR);
mcr = ioread32(uart_vbaddr + UART_MCR);
iowrite32(0x40,uart_vbaddr + UART_MCR);
iowrite32(0x09,uart_vbaddr + UART_FCR);//FIFO not getting enabled here
iowrite32(UART_MODE_B,uart_vbaddr + UART_LCR);
iowrite32(0x2,uart_vbaddr + UART_TLR);//to set for 8 spaces
iowrite32(0x0,uart_vbaddr + UART_SCR);
iowrite32(efr,uart_vbaddr + UART_EFR);
iowrite32(UART_MODE_A,uart_vbaddr + UART_LCR);
iowrite32(mcr,uart_vbaddr + UART_MCR);
iowrite32(lcr,uart_vbaddr + UART_LCR);
/* Protocol Baudrate and interrupt settings */
dll = divisor & 0xFF;
dlh = divisor >> 8;
iowrite32(0x7, uart_vbaddr + UART_MDR1);
mdrdelay();
iowrite32(UART_MODE_B, uart_vbaddr + UART_LCR);
iowrite32(dll,uart_vbaddr);
iowrite32(dlh,uart_vbaddr + UART_DLH);
iowrite32(lcr_val , uart_vbaddr + UART_LCR);
iowrite32(0, uart_vbaddr + UART_MDR1);
mdrdelay();
iowrite32(0x09,uart_vbaddr + UART_FCR);//So renabling the FIFO again
DMA is configured in the HW SYNC mode.with BS =0 ans FS =0.ie to transfer element by element for each DMA request.
Code below gives the DMA configuration
/* Set the Read Port & Write Port access in CSDP */
csdp_val &= 0x00000000;
iowrite32(csdp_val,dma_map + DMA_CSDP(dma_cha_line));
/* Set the Channel Source & Destination start address */
iowrite32(bus_addr,dma_map + DMA_CSSA(dma_cha_line));
iowrite32(UART4_BASE,dma_map + DMA_CSDA(dma_cha_line));
/* CCR configuration */
ccr_val=ioread32(dma_map+DMA_CCR(dma_cha_line))
ccr_val |= (0x1 << 24);//Source triggers on the DMA
/*Frame(5) and Block(18) Synchronisation */
ccr_val &= ~(0x1 << 5);//FS
ccr_val &= ~(0x1 << 18);//BS
ccr_val |= (0x17);//CCR[4:0]
ccr_val |= (0x1 << 19);//CCR [19:20]
ccr_val &= ~(0x1 << 20);//CCR [19:20]
ccr_val |= (0x1 << 12);//source - post incremented 12:13
ccr_val &= ~(0x1 << 13);
ccr_val &= ~(0x3 << 14);//destination- constant address mode 14:15
iowrite32(ccr_val,dma_map + DMA_CCR(dma_cha_line));
ccr_val = ioread32(dma_map + DMA_CCR(dma_cha_line));
Finally after this initialiasitation.channel is enabled.
Please suggest me if there is any wrong in the initialization as I am getting only 64 bytes also I am unable to trigger the DMA request in any of the mode given in [TRM]http://www.ti.com/lit/ug/swpu235ab/swpu235ab.pdf
Edit:Code revised for Element Synchronisation. 1.In TRM this sentence was observed frequently.What settings?
The DMA settings must correspond to the system LH DMA controller settings to ensure correct operation of this logic.
2.Is this configuration correct ? :
ccr_val |= (0x1 << 24);//Source triggers on the DMA
To regenrate the DMA request again,shouldn't I configure the DMA as destination triggered instead of source
ccr_val |= (0x1 << 24);//Destination triggers on the DMA ?
I had tried both the methods,unfortunately the results are same
3.There are 3 ways to configure the trigger level of FIFO.ie FCR/TLR/MDR3 registers.
In this code I have setup using TLR registers.This TLR setup is verified with Interrupt mode.