Dear all:
Mcasp transfer data by EDMA in ARM. In the begining , the mcasp can transfer data. When the hard disk or nand flash read and write large block data by multithreading, the tx can't tansfer data but rx can receive data. Otherwise, the TXEVT is normal.
Moreover,Mcasp can't transfer data when syslink.ko is loaded or engine_open() is called.
The EDMA is ping-pong structure and interrupt period is 4 ms.
Following is that EDMA request configuration:
static int ys_tdm_dma_request(int id, int buf_size, int tx_channel, int rx_channel, int fifo_address) {
//init tx
tx_dma_params_arry[id]->area = dma_alloc_writecombine(NULL, buf_size, &tx_dma_params_arry[id]->addr, GFP_KERNEL);
tx_dma_params_arry[id]->ping_size = buf_size >> 1;
tx_dma_params_arry[id]->asp_channel = edma_alloc_channel(tx_channel, NULL, NULL,EVENTQ_DEFAULT);
tx_dma_params_arry[id]->slot_link[0] = edma_alloc_slot(EDMA_CTLR(tx_dma_params_arry[id]->asp_channel), EDMA_SLOT_ANY);
tx_dma_params_arry[id]->slot_link[1] = edma_alloc_slot(EDMA_CTLR(tx_dma_params_arry[id]->asp_channel), EDMA_SLOT_ANY);
edma_link(tx_dma_params_arry[id]->slot_link[0], tx_dma_params_arry[id]->slot_link[1]);
edma_link(tx_dma_params_arry[id]->slot_link[1], tx_dma_params_arry[id]->slot_link[0]);
edma_read_slot(tx_dma_params_arry[id]->slot_link[0], &p_ram);
p_ram.opt |= EDMA_TCC(EDMA_CHAN_SLOT(tx_dma_params_arry[id]->asp_channel));
edma_write_slot(tx_dma_params_arry[id]->slot_link[0], &p_ram);
edma_read_slot(tx_dma_params_arry[id]->slot_link[1], &p_ram);
p_ram.opt |= EDMA_TCC(EDMA_CHAN_SLOT(tx_dma_params_arry[id]->asp_channel));
edma_write_slot(tx_dma_params_arry[id]->slot_link[1], &p_ram);
//init rx
rx_dma_params_arry[id]->area = dma_alloc_writecombine(NULL, buf_size, &rx_dma_params_arry[id]->addr, GFP_KERNEL);
rx_dma_params_arry[id]->ping_size = buf_size >> 1;
if(id == YSTDM_PRI_ID)
rx_dma_params_arry[id]->asp_channel = edma_alloc_channel(rx_channel, ys_tdm_dma_irq_pri,NULL, EVENTQ_DEFAULT); //分配channel,RX的channel
else if(id == YSTDM_FX_ID)
rx_dma_params_arry[id]->asp_channel = edma_alloc_channel(rx_channel, ys_tdm_dma_irq_fx ,NULL, EVENTQ_DEFAULT); //分配channel,RX的channel
rx_dma_params_arry[id]->slot_link[0] = edma_alloc_slot(EDMA_CTLR(rx_dma_params_arry[id]->asp_channel), EDMA_SLOT_ANY);
rx_dma_params_arry[id]->slot_link[1] = edma_alloc_slot( EDMA_CTLR(rx_dma_params_arry[id]->asp_channel), EDMA_SLOT_ANY);
/** circle ping-pong buffers */
edma_link(rx_dma_params_arry[id]->slot_link[0], rx_dma_params_arry[id]->slot_link[1]);
edma_link(rx_dma_params_arry[id]->slot_link[1], rx_dma_params_arry[id]->slot_link[0]);
edma_read_slot(rx_dma_params_arry[id]->slot_link[0], &p_ram);
p_ram.opt |= TCINTEN | EDMA_TCC(EDMA_CHAN_SLOT(rx_dma_params_arry[id]->asp_channel));
edma_write_slot(rx_dma_params_arry[id]->slot_link[0], &p_ram);
edma_read_slot(rx_dma_params_arry[id]->slot_link[1], &p_ram);
p_ram.opt |= TCINTEN | EDMA_TCC(EDMA_CHAN_SLOT(rx_dma_params_arry[id]->asp_channel));
edma_write_slot(rx_dma_params_arry[id]->slot_link[1], &p_ram);
return 0;
}