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.

AM5728: DSP EDMA issue

Part Number: AM5728

Hello,

we are using the AM5728. On the A15 cores runs Linux, on both DSP's are running highly optimized bare metal real time applications (motion control).

The DSP1 is in need to transfer data from peripherals to its memory by DMA. The EDMA is used for this.
Because of some problems with the EDMA transfer I reduced the desired functionality to a very simple one dimensional manual tiggered memory to memory EDMA example with completion polling to demonstrate my problem.

First I used the system level EDMA to transfer the data. Please note the section .dma_mem is located at the OCMC_RAM1. It works as expected.

//#define EDMA_CC_BASE  SOC_DSP1_EDMA_CC_BASE
#define EDMA_CC_BASE SOC_EDMA_TPCC_BASE_VIRT

#pragma DATA_SECTION(".dma_mem")
char  srcBuff[16] = "Hello~world~123";

#pragma DATA_SECTION(".dma_mem")
char  dstBuff[16];

dma_test( 5, 5, 0 );

void dma_test( uint32_t ch_num, uint32_t tcc_num, uint32_t evtq_num )
{
  EDMAsetRegion( 0 );
  EDMA3Init( EDMA_CC_BASE, EVT_QUEUE_NUM );
  if( EDMA3RequestChannel( EDMA_CC_BASE, EDMA3_CHANNEL_TYPE_DMA, ch_num, tcc_num, evtq_num ) == 0 )
  {
    TRACE( true, (TRACE_ERR, "EDMA channel request failed") );
  }

  EDMA3CCPaRAMEntry Param =
  {
    .srcAddr  = (uint32_t)srcBuff,
    .destAddr = (uint32_t)dstBuff,
    .aCnt     = ARRAYSIZE(srcBuff),
    .bCnt     = 1,
    .cCnt     = 1,
    .srcBIdx  = 1,
    .destBIdx = 1,
    .srcCIdx  = 1,
    .destCIdx = 1,
    .linkAddr = 0xFFFFU,
    .opt      = (EDMA3_OPT_TCINTEN_MASK | EDMA3_OPT_ITCINTEN_MASK | ((tcc_num << EDMA3_OPT_TCC_SHIFT) & EDMA3_OPT_TCC_MASK))
  };

  EDMA3SetPaRAM( EDMA_CC_BASE, ch_num, &Param );
  EDMA3EnableTransfer( EDMA_CC_BASE, ch_num, EDMA3_TRIG_MODE_MANUAL );

  // poll on complete
  if(tcc_num < 32)
  {
    while( (EDMA3GetIntrStatus(EDMA_CC_BASE) & (0x1 << tcc_num)) != (0x1 << tcc_num) ) ;
  }
  else
  {
    while( (EDMA3IntrStatusHighGet(EDMA_CC_BASE) & (0x1 << (tcc_num - 32))) != (0x1 << (tcc_num - 32)) ) ;
  }
}

Now I want to to ensure the Linux EDMA usage and the DSP1 EDMA usage will not conflict. Therefore DSP1 shall not use the system EDMA but the DSP1 EDMA.
But when changing EDMA_CC_BASE to SOC_DSP1_EDMA_CC_BASE something gets wrong.
It compiles, it runs, it generates no error, also the transfer seems to work because the transfer completion will be set shortly after the transmission has been start, but the destination memory is not filled with the data as this happens with the system EDMA.

What has to be considered when using DSP1 EDMA instead of system EDMA?
I read the TRM carefully but find not the reason for this malfunction.

Thank you very much.

Regards Dirk

  • Hi Dirk,

    Have you checked the CSL EDMA example for AM57x C66?

    Please see <PDK>\pdk_am57xx_1_0_16\packages\ti\csl\example\edma.

    To build (on Windows):

    > cd <PDK>\packages
    > pdksetupenv.bat
    > gmake csl_apps LIMIT_SOCS="am572x" LIMIT_BOARDS="idkAM572x"

    Regards,
    Frank

  • Hi Frank,

    thank you very much for your fast reply.

    >> Have you checked the CSL EDMA example for AM57x C66? Please see <PDK>\pdk_am57xx_1_0_16\packages\ti\csl\example\edma.
    Yes I did.
    And my code printed above is a nearly exact copy of \pdk_am57xx_1_0_14\packages\ti\csl\example\edma\edma_test\dma_polled.c
    This simple example (memory to memory copy with polling) is build for the AM572x.
    At the first glance it seems this example is using the DSP_EDMA:
       line 76 main.c:
       #if defined (SOC_AM574x) || defined (SOC_AM572x) || defined (SOC_AM571x)
       #define EDMA_U_BASE CSL_DSP_EDMA_CC_REGS
       #else

    but when you dig deeper, it turns out that CSL_DSP_EDMA_CC_REGS is not the address of the DSP_EDMA (even it sounds like this) but of the system EDMA.

    CSL_DSP_EDMA_CC_REGS is defined at cslr_soc_dsp_baseaddress.h line 297 as
    #define CSL_DSP_EDMA_CC_REGS                                                    (0x3300000U)

    When looking at the TRM of the AM572X it becomes visible this is the system EDMA (red mark), because the DSP_EDMA is mapped at 0x01D10000 (green mark).



    However, as described above when I start the original demo its work when running stand alone.
    But when started via remote_proc with Linux running on the A15 core it does not work.
    The reason is, that Linux itself used the system EDMA too and kills the EDMA configuration done by the DSP (due to EDMA resource conflict).
    I worked actually around this by changing the DSP event queue to 1, because Linux seems actually to use queue 0 only.
    But this is not a real solution and not safe.
    The real solution would be that the DSP uses the DSP_EDMA and Linux the system EDMA as described at my first post.
    But when changing the EDMA instance address from
    #define EDMA_U_BASE CSL_DSP_EDMA_CC_REGS      /* 0x3300000U */
    to
    #define EDMA_U_BASE CSL_DSP_DSP_EDMA_CC_REGS  /* 0x1d10000U */
    things do not work any longer.

    So still I have my question:
    What has to be considered when using DSP1 EDMA instead of system EDMA?
    I read the TRM carefully but find not the reason for this malfunction.

    Regards    Dirk

  • Hallo,

    anybody out there who actually used the DSP EDMA (EDMA_U_BASE CSL_DSP_DSP_EDMA_CC_REGS) not the system EDMA (EDMA_U_BASE CSL_DSP_EDMA_CC_REGS) ?

    I have still the problem that a simple copy works with the system EDMA but not with the DSP1 EDMA.

    Thank You.

  • Hi Dirk,

    Sorry for the delay on this. I'm now checking on this internally.

    Regards,
    Frank

  • Hi Dirk,

    What type of failure to you observe when you attempt to use DSP EDMA? For example: interrupt status not set, DMA not triggered, or DMA completion interrupt is not being serviced, other..?

    Regards,
    Frank

  • Hi,

    The PDK example is written and tested only for the system edma.
    You may update it for the dsp edma.
    let us know what type of failure you are seeing as asked by Frank to assist on this further.

    There is another driver package for edma, named edma3lld.
    which supports and tested for both the system edma and dsp edma.

    Also from your initial post, the sharing of the system edma between linux running on one core and RTOS running on dsp is possible.
    You need to make sure to use different dma channels, and different edma regions to program.

    Regards,
    Prasad

  • Hello Frank,

    First I run the simple memory-to-memory DMA copy demo on the system EDMA (CSL_DSP_EDMA_CC_REGS = 0x3300000U) and the result was as expected.
    Second I want to use the DSP1_EDMA instead of the system EDMA and changed the EDMA base address to CSL_DSP_DSP_EDMA_CC_REGS = 0x1d10000U.
    Now the program is simply crashing with mmu fault:

    [  229.768029] remoteproc remoteproc3: remote processor 40800000.dsp is now up
    [  229.880772] omap-iommu 40d02000.mmu: iommu fault: da 0x4082a300 flags 0x0
    [  229.887595] remoteproc remoteproc3: crash detected in 40800000.dsp: type mmufault
    [  229.895120] omap-iommu 40d02000.mmu: 40d02000.mmu: errs:0x00000002 da:0x4082a300 pgd:0xedb71020 *pgd:px00000000
    [  229.905294] remoteproc remoteproc3: handling crash #30 in 40800000.dsp

    In consequence to your posts I did more analysis.
    The answer to my question (What has to be considered when using DSP1 EDMA instead of system EDMA?) is at the end simple.

    When changing from system EDMA to DSP1_EDMA you need not only to change the base address of the EDMA controller.
    Furthermore - and that was my missing link I was asking for - you need also to change the the given address of the source and destination buffer, even they are still on the same location and address!

    Lets say it in simple words.
    When you use the system EDMA (even from DSP1) source and destination buffer must be given in "system view" address.
    When you switch over to DSP1_EDMA both buffers must be given in "local view" address.

    So an offset of 0x40000000 makes the difference.

    And it is working...

    Thank you.

    Regards Dirk

  • Hi Dirk,

    Thanks much for sharing the final solution! My understanding is we currently don't have any examples in PDK which use DSP EDMA. I'll see if we can address this gap moving forward.

    Regards,
    Frank