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.

The problem of PCIE DMA memory read

Hi all:

I use DM8168 pcie x2 to control a EP device, the DM8168 PCIE is support DMA memory read according to the sprugs6d.pdf(2.9.3.2 Memory Read Transfer).

When I use EDMA, I find the value of DMA memory read from pcie is zero!!!

but  use EDMA transfer data from ddr to ddr  is ok.

Is PCIE DMA memory read special ? Or  My operation is wrong?

the following is the kernel print information :

ti81xx_pcie: Invoking PCI BIOS...
ti81xx_pcie: Setting up Host Controller...
ti81xx_pcie: Register base mapped @0xd0820000
ti81xx_pcie: Starting PCI scan...
PCI: bus0: Fast back to back transfers disabled
PCI: bus1: Fast back to back transfers disabled
ti81xx_pcie: PCI scan done.
pci 0000:00:00.0: BAR 9: assigned [mem 0x20000000-0x21ffffff pref]
pci 0000:01:00.0: BAR 0: assigned [mem 0x20000000-0x20ffffff pref]
pci 0000:01:00.0: BAR 0: set to [mem 0x20000000-0x20ffffff pref] (PCI address [0x20000000-0x20ffffff])
pci 0000:01:00.0: BAR 1: assigned [mem 0x21000000-0x21ffffff pref]
pci 0000:01:00.0: BAR 1: set to [mem 0x21000000-0x21ffffff pref] (PCI address [0x21000000-0x21ffffff])
pci 0000:00:00.0: PCI bridge to [bus 01-01]
pci 0000:00:00.0: bridge window [io disabled]
pci 0000:00:00.0: bridge window [mem disabled]
pci 0000:00:00.0: bridge window [mem 0x20000000-0x21ffffff pref]
PCI: enabling device 0000:00:00.0 (0140 -> 0143)

My test code is :


edma3_memtomemcpytest_dma(128,2,1,0,0);


int edma3_memtomemcpytest_dma (int acnt, int bcnt, int ccnt, int sync_mode, int event_queue)
{
int result = 0;
int i;
int count = 0;
unsigned int Istestpassed = 0u;
unsigned int numenabled = 0;
unsigned int BRCnt = 0;
int srcbidx = 0;
int desbidx = 0;
int srccidx = 0;
int descidx = 0;
struct edmacc_param param_set;

#define STATIC_SHIFT 3
#define TCINTEN_SHIFT 20
#define ITCINTEN_SHIFT 21
#define TCCHEN_SHIFT 22
#define ITCCHEN_SHIFT 23

dmabufsrc1 = 0xd5000000;
dmaphyssrc1 = 0x21000000;

if(dmabufdest1 == NULL){
dmabufdest1 = dma_alloc_coherent (NULL, 2048,
&dmaphysdest1, 0);
}

printk( "\nSRC1: dmabufdest1=0x%x;\ndmaphysdest1=%x \n",dmabufdest1, dmaphysdest1);
if (!dmaphysdest1) {
printk ("dma_alloc_coherent failed for dmaphyssrc1\n");
return -ENOMEM;
}

if (dmaphyssrc1==NULL) {
printk("dmabufdest1 ERR get dma page error\n");
return NULL;
}

/* Set B count reload as B count. */
BRCnt = 0;//bcnt;

/* Setting up the SRC/DES Index */
if(bcnt == 1){
srcbidx = 0;
desbidx = 0;
}else{
srcbidx = acnt;
desbidx = acnt;
}

/* A Sync Transfer Mode */
srccidx = 0;
descidx = 0;
if(dma_ch == -1){
result = edma_alloc_channel (EDMA_CHANNEL_ANY, callback1, NULL, event_queue);
if (result < 0) {
printk ("\nedma3_memtomemcpytest_dma::edma_alloc_channel failed for dma_ch, error:%d\n", result);
return result;
}
dma_ch = result;//result;
}

edma_set_src (dma_ch, (unsigned long)(dmaphyssrc1), INCR, W8BIT);
edma_set_dest (dma_ch, (unsigned long)(dmaphysdest1), INCR, W8BIT);
edma_set_src_index (dma_ch, srcbidx, srccidx);
edma_set_dest_index (dma_ch, desbidx, descidx);
/* A Sync Transfer Mode */
edma_set_transfer_params(dma_ch, acnt, bcnt, ccnt, BRCnt, ABSYNC);

/* Enable the Interrupts on Channel 1 */
edma_read_slot (dma_ch, &param_set);
//param_set.opt |= (1 << ITCINTEN_SHIFT);
param_set.opt |= (1 << TCINTEN_SHIFT);
param_set.opt |= EDMA_TCC(EDMA_CHAN_SLOT(dma_ch));
edma_write_slot (dma_ch, &param_set);

{
irqraised1 = 0;
/*
* Now enable the transfer as many times as calculated above.
*/
printk("edma_start before\n");
result = edma_start(dma_ch);
printk("after edma_start:%x\n",result);
if (result != 0) {
printk ("edma3_memtomemcpytest_dma: davinci_start_dma failed \n");
//break;
}
printk ("edma3_memtomemcpytest_dma: result=%x \n",result);
i = 0;
/* Wait for the Completion ISR. */
while (irqraised1 == 0u){
printk("Wait for the Completion ISR. i=%d\n",i);;
if(i++ > 3000)
break;
}

/* Check the status of the completed transfer */
if (irqraised1 < 0) {
/* Some error occured, break from the FOR loop. */
printk ("edma3_memtomemcpytest_dma: Event Miss Occured!!!\n");
}

for (i = 0; i < 10; i++)
{
printk ("\n edma: dest *%x=%x\n",dmabufdest1 + i,dmabufdest1[i]);
printk ("\n edma: src *%x=%x\n",dmabufsrc1 + i,dmabufsrc1[i]);
}
if (Istestpassed == 1u) {
printk ("\nedma3_memtomemcpytest_dma: EDMA Data Transfer Successfull \n");
} else {
printk ("\nedma3_memtomemcpytest_dma: EDMA Data Transfer Failed \n");
}
return result;
}