DMA engine of MPC8349E issues incorrect PCI read command

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

DMA engine of MPC8349E issues incorrect PCI read command

2,977 次查看
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 项奖励
回复
3 回复数

1,814 次查看
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 项奖励
回复

1,814 次查看
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 项奖励
回复

1,814 次查看
huangxianguo
Contributor I

Aha, smileytongue:

0 项奖励
回复