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.

DMA parameters

Hello!

I have read SPRUEE4A.pdf and I can't understand how can I select DMA parametrs, e.g. A or AB-synchronized transfer mode.

Can you help me?

Thank you and excuse me for my bad english.

  • please see arch/arm/...davinci/mcbsp.c file .

    Its actually , the implementation of the A_SYNC ,non - bursting example given in the pdf.

    You will easily get the compel picture of EDMA , how to use it through LINUX :)

     

  • Thank you for your reply!

    I see this file and try to use it in our network driver, please see https://community.ti.com/forums/t/12239.aspx, but with no success.

  • Just to clear up some confusion, the location of the DMA driver is

    ...lsp/ti-davinci/arch/arm/mach-davinci/dma.c

    but as Digant pointed out, an example of how a software component uses DMA driver can be found at

       arch/arm/...davinci/mcbsp.c

     

  • Ok, I have found in mcbsp.c next code:

    int davinci_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
    {
    ....................................................
    davinci_set_dma_transfer_params(mcbsp[id].dma_rx_lch, 2, length / 2, 1, 0, ASYNC);
    .....................................................
    davinci_set_dma_src_index(mcbsp[id].dma_rx_lch, 0, 0);
    davinci_set_dma_dest_index(mcbsp[id].dma_rx_lch, 2, 0);
    davinci_start_dma(mcbsp[id].dma_rx_lch);
    .....................................................
    }

    What do I need to know to choose DMA-parameters (ACNT, BCNT, CCNT) correctly?

    Thank you.

  • ACNT, BCNT , and CCNT are used to define the area in memory your want to copy.  This can be very useful when re-arranging video pixel data as it allows for great felxibility (e.g. copy first 10 pixels of every other line into a destination buffer).  Of course, you may not always need to do such a complex transfer, you may just be copying x number of bytes from source buffer to destination buffer (or port), in which case, ACNT may be enough and you would not use BCNT or CNT for added flexibility. 

    Figure 2-4 in spruee4a.pdf gives you a good visual of how ACNT, BCNT and CCNT can be used to define complex transfers.. If you still have questions, perhaps you can describe the type of data movement you are trying to do in more detail and we can help you identify the proper values...

  • Tnank you, Juan!

    I continue try modify DM9000 driver for work via DMA, copy from DDR2 to DDR2 working.

    My source:
    static void dm9000_outblk_8bit(void __iomem *reg, void *data, int count)
    {
    int res, i;
    for (i = 12; i < 14; i++) {
    res = davinci_request_dma(i,"dm9000_dma_tx",dm9000_dmaHandler,dmaData,&lch,&tcc,0);
    if (!res)
    {
    printk(KERN_INFO "allocated dma channel %d\n",lch);
    break;
    }
    }
    davinci_set_dma_transfer_params(lch, count, 0, 0, 0, ASYNC);
    davinci_set_dma_dest_params(lch, (unsigned long)reg, 0, 0);
    davinci_set_dma_src_params(lch, (unsigned long)data, 0, 0);
    davinci_set_dma_src_index(lch, 0, 0);
    davinci_set_dma_dest_index(lch, 0, 0);
    res = davinci_start_dma(lch);
    if (res)
    printk("dm9000 dma start error\n");
    }

    void dm9000_dmaHandler(int lch, unsigned short ch_status,void *data)
    {
    davinci_stop_dma(lch);
    davinci_free_dma(lch);
    ch_status = ch_status;
    data = data;

    I successufuly get DMA channell, but driver don't send right packets.

     

  • please note that ACNT, BCNT and CCNT must be 1 or greater.  Also, in your davinci_set_dma_dest_params and davinci_set_dma_src_params, you need to put in a valid value for the last two parameters

    I am not sure if you have had a chance to go over the DMA User Guide yet?  If not, I would recommend you do this.  Finally, I would recommend you print out the param settings after you set them just to verify everything was set appropriately

    davinci_get_dma_params(dma->channel, &dma->paramentry);
    printk(KERN_INFO "PaRAM(%d): OPT - 0x%.8x\n", dma->channel, dma->paramentry.opt);
    printk(KERN_INFO "PaRAM(%d): SRC - 0x%.8x\n", dma->channel, dma->paramentry.src);
    printk(KERN_INFO "PaRAM(%d): BCNT - 0x%.4x, ACNT - 0x%.4x\n", dma->channel, dma->paramentry.a_b_cnt >> 16, dma->paramentry.a_b_cnt & 0xffff);
    printk(KERN_INFO "PaRAM(%d): DST - 0x%.8x\n", dma->channel, dma->paramentry.dst);
    printk(KERN_INFO "PaRAM(%d): CCNT - 0x%.8x\n", dma->channel, dma->paramentry.ccnt);

    the param settings control the type of transfer you are requesting and having a look at what was actually set may help determine if the transaction is valid or not...

     

     

  • Juan Gonzales said:

    I am not sure if you have had a chance to go over the DMA User Guide yet?  If not, I would recommend you do this.  

    Thank you, Juan!

    Where can I find DMA User Guide?

    My changed source:

    static void dm9000_outblk_8bit(void __iomem *reg, void *data, int count)
    {
    ........................................................
    davinci_set_dma_transfer_params(lch, count, 1, 1, 0, ASYNC);
    davinci_set_dma_dest_params(lch, (unsigned long)reg, 0, 0);
    davinci_set_dma_src_params(lch, (unsigned long)data, 0, 0);
    davinci_set_dma_src_index(lch, 0, 0);
    davinci_set_dma_dest_index(lch, 0, 0);
    .........................................................
    struct {
    int channel;
    edmacc_paramentry_regs paramentry;
    } _dma,*dma;
    dma = &_dma;
    dma->channel = lch;

    davinci_get_dma_params(dma->channel, &dma->paramentry);
    printk(KERN_INFO "PaRAM(%d): OPT - 0x%.8x\n", dma->channel, dma->paramentry.opt);
    printk(KERN_INFO "PaRAM(%d): SRC - 0x%.8x\n", dma->channel, dma->paramentry.src);
    printk(KERN_INFO "PaRAM(%d): BCNT - 0x%.4x, ACNT - 0x%.4x\n", dma->channel, 
    dma->paramentry.a_b_cnt >> 16, dma->paramentry.a_b_cnt & 0xffff);
    printk(KERN_INFO "PaRAM(%d): DST - 0x%.8x\n", dma->channel, dma->paramentry.dst);
    printk(KERN_INFO "PaRAM(%d): CCNT - 0x%.8x\n", dma->channel, dma->paramentry.ccnt);

    Result:

    start dm9000_outblk_8bit, data = c6be1002,count = 70, channel = 12,tcc = 12,reg = 0xC7064002
    requesting dma channel
    allocated dma channel 12
    PaRAM(12): OPT - 0x0010c000
    PaRAM(12): SRC - 0xc6be1002
    PaRAM(12): BCNT - 0x0001, ACNT - 0x0046
    PaRAM(12): DST - 0xc7064002
    PaRAM(12): CCNT - 0x00000001
    end dm9000_outblk_8bit
    eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
    start dm9000_outblk_8bit, data = c6a7ec82,count = 42, channel = 12,tcc = 12,reg = 0xC7064002
    requesting dma channel
    allocated dma channel 12
    PaRAM(12): OPT - 0x0010c000
    PaRAM(12): SRC - 0xc6a7ec82
    PaRAM(12): BCNT - 0x0001, ACNT - 0x002a
    PaRAM(12): DST - 0xc7064002
    PaRAM(12): CCNT - 0x00000001
    end dm9000_outblk_8bit
    start dm9000_outblk_8bit, data = c6a7ec82,count = 42, channel = 12,tcc = 12,reg = 0xC7064002
    requesting dma channel
    allocated dma channel 12
    PaRAM(12): OPT - 0x0010c000
    PaRAM(12): SRC - 0xc6a7ec82
    PaRAM(12): BCNT - 0x0001, ACNT - 0x002a
    PaRAM(12): DST - 0xc7064002
    PaRAM(12): CCNT - 0x00000001
    end dm9000_outblk_8bit

    Thank you.

  • The DMA User Guide is the doc you referred to on your first post (link http://focus.ti.com/general/docs/litabsmultiplefilelist.tsp?literatureNumber=spruee4a).  It describes each of the PaRAM elements in detail and has Figures which show you how ACNT, BCNT and CCNT may help define your memory region.

  • Thank your, Juan!

    But I don't understand how can I select SRC/DST B and C index, can you help me?

    I can try with B-index packet = size + 10 and C-index = 0, but not success.

    start dm9000_outblk_8bit, data = c6732b82,count = 42, channel = 12,tcc = 12,reg = 0xC7064002
    requesting dma channel
    allocated dma channel 12
    PaRAM(12): OPT - 0x0010c000
    PaRAM(12): SRC - 0x86732b82
    PaRAM(12): BCNT - 0x0001, ACNT - 0x002a
    PaRAM(12): DST - 0xc7064002
    PaRAM(12): DSTBIDX - 0x0034, SRCBIDX - 0x0034 //count + 10
    PaRAM(12): CCNT - 0x00000001
    PaRAM(12): DSTCIDX - 0x0000, SRCCIDX - 0x0000
    end dm9000_outblk_8bit

    Thank your.

  • Kirill,

    1) In order for me to help you choose the appropriate parameters settings, I need to understand the type of transaction you are trying to accomplish (e.g. pass every other 16 bytes of data from DDR2 starting at address src-xxxxx to FIFO at address dest-xxxx ).  Without knowing this, I can tell you if that your configuration is a valid one, but it is impossible for me to say if it is correct one for the goal you have in mind.  This is why I asked you to describe the transaction you are trying to accompish in an earlier post.  Since I got source code instead, I gave you feedback on restrictions (ACNT, BCNT, CCNT must be greater than 1).  The indexes could be any value you want, but depending on what your goal is, it may or may not be right.

    2) My goal is for you to understand how DMA hardware works rather give you a one time set of parameters.  This is why I keep referring you to the DMA User Guide; if you do not understand a particular description in the document or need clarification, I would be happy to help clear things up.  However, it is not feasible for me to explain how the entire thing works; this is why we have manuals.  When I help clear up some confusion in our docs, other readers of the post can benefit and my time is well spent; if I give you a one time costum configuration, not many others can benefit hence I have less incentive to spend my time in this sort of effort.  Therefore, if something is not clear in the document, please let me know which section or sentence and I can help add some clarity.  Thank you for your understanding.

     

  • I understand you Juan.

    I have to modify DM9000 driver to work via DMA. I have found that source packet come from 0xc67ca6c2 virtual address, 0x807d2a82 physical address via vir_to_phys function, and destination is 0xc7064002 virtual, constant 0x87064002 physical address. Destination physical address is in DDR EMIF (SPRS463, p. 7) and I think that it must be in the ASYNC EMIF memory region.

    I think my problem is that destination region is wrong.