Hi all,
I need to convert the raw video data captured by dm6467 from yuv422 to yuyv422 using edma3 link
src data type yuv422:

dst data type yuyv422:

C code:
struct timeval dma_begin_t;
struct timeval dma_end_t;
static void callMe(unsigned lch, u16 ch_status, void *data)
{
int elapse;
switch(ch_status)
{
case DMA_COMPLETE:
irqraised1 = 1;
do_gettimeofday(&dma_end_t);
elapse = 1000000 * (dma_end_t.tv_sec - dma_begin_t.tv_sec) + (dma_end_t.tv_usec - dma_begin_t.tv_usec); //us
printk("in callme dma absync transf consume %d us\n", elapse);
break;
case DMA_CC_ERROR:
irqraised1 = -1;
printk ("\nFrom callMe : DMA_CC_ERROR occured "
"on Channel %d\n", lch);
break;
default:
break;
}
}
/*
* yuv422->yuyv422 use dma link
*
* width is the width of the video resolution
* height is the height of the video resolution
* dst is destination address of dma transfer
* src is source address of dma transfer
*/
int dm646x_edma_transf_sort_e(dma_addr_t dst, dma_addr_t src, int width, int height)
{
int channel1 = -1;//transfer Y data
int channel2 = -1;//transfer UV data
u16 ch_status = 0;
int ret_val = -1;
int i,j;
int acnt = 1;
int ccnt = 64;
int bcnt = width*height/ccnt;
s16 srcbidx = 1;
s16 srccidx = bcnt;
s16 dstbidx = 2;
s16 dstcidx = 2*bcnt;
struct edmacc_param param_set;
struct timeval Start_Val,End_Val;
unsigned int timeuse;
channel1 = edma_alloc_channel(EDMA_CHANNEL_ANY, callMe, (void*)ch_status,
EVENTQ_DEFAULT);
if (channel1 < 0)
{
return ret_val;
}
edma_set_src(channel1, src, INCR, W8BIT); //Y
edma_set_dest(channel1, dst, INCR, W8BIT);
edma_set_src_index(channel1, srcbidx, srccidx);
edma_set_dest_index(channel1, dstbidx, dstcidx);
edma_set_transfer_params(channel1, acnt, bcnt, ccnt, 0, ABSYNC);
/* Enable the Interrupts on Channel 1 */
edma_read_slot(channel1, ¶m_set);
param_set.opt |= (1 << ITCINTEN_SHIFT);
param_set.opt |= (1 << TCINTEN_SHIFT);
param_set.opt |= EDMA_TCC(EDMA_CHAN_SLOT(channel1));
edma_write_slot(channel1, ¶m_set);
/* Request a Link Channel 2 */
ret_val = edma_alloc_slot(0, EDMA_SLOT_ANY);
if (ret_val < 0)
{
printk ("\ndm646x_edma_tranf_sort_e::edma_alloc_slot "
"failed for channel2, error:%d\n", ret_val);
return ret_val;
}
channel2 = ret_val;
edma_set_src(channel2, src+width*height, INCR, W8BIT); //UV
edma_set_dest(channel2, dst+1, INCR, W8BIT);
edma_set_src_index(channel2, srcbidx, srccidx);
edma_set_dest_index(channel2, dstbidx, dstcidx);
edma_set_transfer_params(channel2, acnt, bcnt, ccnt, 0, ABSYNC);
/* Enable the Interrupts on Channel 2 */
edma_read_slot(channel2, ¶m_set);
param_set.opt |= (1 << ITCINTEN_SHIFT);
param_set.opt |= (1 << TCINTEN_SHIFT);
param_set.opt |= EDMA_TCC(EDMA_CHAN_SLOT(channel1));
edma_write_slot(channel2, ¶m_set);
/* Link both the channels */
edma_link(channel1, channel2);
do_gettimeofday(&Start_Val);
for (i = 0; i < 2*ccnt; i++)
{
irqraised1 = 0;
do_gettimeofday(&dma_begin_t);
ret_val = edma_start(channel1);
if (ret_val != 0)
{
printk("davinci_start_dma failed. \n");
}
while (irqraised1 == 0u);
/* Check the status of the completed transfer */
if (irqraised1 < 0)
{
/* Some error occured, break from the FOR loop. */
printk("Event Miss Occured!!!\n");
}
}
do_gettimeofday(&End_Val);
timeuse = 1000000 * (End_Val.tv_sec - Start_Val.tv_sec) + (End_Val.tv_usec - Start_Val.tv_usec); //us
printk("dma link transf consume %d us\n", timeuse);
if (ret_val == 0)
{
edma_stop(channel1);
edma_free_channel(channel1);
edma_stop(channel2);
edma_free_slot(channel2);
edma_free_channel(channel2);
}
return ret_val;
}
The data is transfered correct, Here is the trouble:
The func callMe() is called 128 times, consume 340*128=43,520us
(in callme dma absync transf consume 340 us
in callme dma absync transf consume 330 us
in callme dma absync transf consume 330 us
…
in callme dma absync transf consume 350 us
),
But the total process consume 662,103us
(dma link transf consume 662103 us)
This performance can’t achieve requirement, I wanna know whether there is somewhere to optimize, or some better idea. Thanks!