DMA engine of MPC8349E issues incorrect PCI read command

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

DMA engine of MPC8349E issues incorrect PCI read command

1,648 Views
dimm
Contributor I
Hello!

We are trying to use the MPC8349E DMA engine to transfer data from a PCI memory and have faced the following problem: regardless of the "PRC" (PCI read command) field in the  DMAMR0 (DMA Mode) register commands of type "Memory read line" (code 0b1110) are issued on the bus.

We expected that DMA engine issues burst transfer using "Memory read" command (code 0b0110) when DMAMR0 bits 10 and 11 are cleared. But ChipScope on the target PCI device shows that "Memory read line" commands (code 0b1110) are issued instead of the burst transfer. Please, refer to the code below.

Any suggestions are welcome!


Regards,

Dmitry Vasilchenko,
RINA ltd.

/* ========================== cut here ================================ */

#define DMA_OFFSET 0x8000

#define DMASR0 0x104
#define DMASAR0 0x110
#define DMADAR0 0x118
#define DMABCR0 0x120
#define DMAMR0 0x100

/* Direct mode snoop enable */
#define DMAMR_SEN (1 << 20)

/* PCI Read Line Command */
#define DMAMR_PCI_READ_LINE (1 << 10)
/* PCI Read Multiple Command */
#define DMAMR_PCI_READ_MULT (1 << 11)

/* Channel Transfer Mode */
#define DMAMR_CTM (1 << 2)

/* Channel start */
#define DMAMR_CS 1

void __iomem *DMA_BASE = ioremap(get_immrbase() + DMA_OFFSET, 0x300);

void __iomem *DMA_SR = DMA_BASE + DMASR0;
void __iomem *DMA_MR = DMA_BASE + DMAMR0;
void __iomem *DMA_SAR = DMA_BASE + DMASAR0;
void __iomem *DMA_DAR = DMA_BASE + DMADAR0;
void __iomem *DMA_BCR = DMA_BASE + DMABCR0;

/* Source Address */
out_le32(DMA_SAR, src);
/* Destination Address */
out_le32(DMA_DAR, dst);
/* Counter */
out_le32(DMA_BCR, size);

/* DMA mode */
reg = DMAMR_CTM | DMAMR_SEN;
out_le32(DMA_MR, reg);

printk("Going to start transfer: 0x%08lx->0x%08lx(0x%08lx) mode=0x%08lx\n",
    in_le32(DMA_SAR), in_le32(DMA_DAR), in_le32(DMA_BCR), in_le32(DMA_MR));

/* Start transfer */
reg |= DMAMR_CS;
out_le32(DMA_MR, reg);

/* Check status */
reg = in_le32(DMA_SR);
while (reg & DMASR_CB) {
    reg = in_le32(DMA_SR);
}
printk("Done! DMA Status=0x%08lx\n", reg);

/* ========================== cut here ================================ */
0 Kudos
3 Replies

485 Views
Joxean
Contributor I

I'm trying your code in a MPC8313ERDB.

What i want is to read data from the memory of a PCI slave only device.

The address i'm setting for the source parameter is "pci:resource_start(dev, MMIO_INDX)", the DMA operation finishes with a OK status, but i see that the PCI device is not readed.

How should i set the source addr??

 

Thanks in advance

0 Kudos

485 Views
huangxianguo
Contributor I

It's the same issue for me. Take MPC8313ERDB as the PCI host, and want to read from one PCI device with the DMA master mode.

0 Kudos

485 Views
huangxianguo
Contributor I

Aha, smileytongue:

0 Kudos