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.

PCIe EP and EDMA transfers



All-

We're currently seeing an issue with inbound EDMA transfers via PCIe, and are wondering if anyone has seen similar results.  Details are as follows:

  • DM814x on custom PCI expansion card.
  • DM814x sits behind PEX8112 PCIe bridge (in reverse-bridging mode), and acts as a PCIe endpoint.
  • Custom driver for PCIe endpoint operations on DM814x, based on TI sample code and making use of TI's EDMA infrastructure.
  • Transfers (inbound to DM814x and outbound from DM814x) are handled via EDMA, and are sent to/from host memory via an 8 MiB PCIe outbound mapping + offset @ 0x20000000.  All transfers are page (4 KiB) aligned and 1 page in size on both the DM814x and x86 host.
  • Outbound transfers (from DM814x SDRAM to x86 WinXP host SDRAM) are 100% reliable - we've validated multi-GiB transfers of both test data and encoded bitstreams.
  • Inbound transfers (from host x86 WinXP host SDRAM to DM814x SDRAM) are occasionally corrupt; we see 64 bytes of (aligned) zeros somewhere in the middle of the page on the DM814x once the DMA operation completes.
    • No EDMA error is reported.
    • Re-trying the EDMA does not result in a successful transfer.
    • Re-trying the transfer as a simple PIO (i.e. *dest++ = *src++) through the existing mapping is 100% successful.
    • A full flush of the cache via flush_cache_all() both before and after the EDMA does not help.

I've included a small snippet of the relevant code below.  mdl->pa_buf is the physical address of the buffer on the host system, and ti81xx_edma_dma_rx() is as per the PCIe Express EP Driver User's Guide.

Any tips would be appreciated.

Thanks.

-Cory

/* Map the host memory into PCIe outbound region 0. */
write_application_register(OB_OFFSET_INDEX(0), ((mdl->pa_buf & 0xFF800000) | 1));
write_application_register(OB_OFFSET_HI(0), 0);

/* EDMA transactions _must_ be 16-byte aligned, and on 16-byte
 * boundaries.
 *
 * TMS320DM814x DaVinci(TM) Digital Media Processors
 * Silicon Revision 2.1 Errata (SPRZ343A.pdf)
 *
 * Advisory 2.1.6
 */
dma_addr_src = (dma_addr_t)(0x20000000 | (mdl->pa_buf & 0x007FFFFF));
BUG_ON(dma_addr_src & 0xF);
dma_addr_dest = dma_map_single(c->device, dma_buffer, HDUAC_PAGE_SIZE, DMA_FROM_DEVICE);
BUG_ON(dma_addr_dest & 0xF);

//flush_cache_all();
err_dma = ti81xx_edma_dma_rx(dma_addr_src, dma_addr_dest, 1, 4096, 1, ABSYNC);
if (err_dma)
    pr_err(KBUILD_MODNAME ": ti81xx_edma_dma_rx() failed!\n");

dma_unmap_single(c->device, dma_addr_dest, HDUAC_PAGE_SIZE, DMA_FROM_DEVICE);
//flush_cache_all();