Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
20 years ago

Setting up a DMA Transaction in a driver

Hello everyone,

i currently working on driver, where i need to do some dma-transaction.

I can do DMA and PIO directly on the Nios 2 System, without Linux ( withot an running system Linux Kernel).

But now i want to run the whole system under Linux, so i started writing adriver. Everything works fine, including PIO, but i have problems with DMA.

I read the chapter about setting up the dma in "Linux device drivers" by Corbet & Rubini. But simply it doesn't work:

1) request_dma(...) fails... for example

2) I wanted some uncached memory (:=alt_uncached_malloc)

therefore i tried:

3) dma_pool_create(...): -> unresolved symbol error;

4) dma_alloc_coherent(...) -> Kernel bug

i'm not sure, if the function are dedicated to pci.

well maybe someone has an hint and can teach howto do?

Best Regards.

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Helmchen,

    > request_dma(...) fails... for example

    Check the name of your dma controller in SOPCBuilder ... I believe it needs to be

    "dma_0" ... and "dma_1" if you have a second controller. Otherwise, the dma

    channel table won't have anything in it (since the address and irq macros won't

    be defined). See arch/nios2nommu/kernel/dma.c

    Regards,

    --Scott
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Scott,

    thanks you for answer.

    According to your suggestion

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    Check the name of your dma controller in SOPCBuilder ...[/b]

    --- Quote End ---

    i checked it:

    - the name of the DMA controller in the SoPC Builder is correct: dma_0

    - in the nios2_system.h file of my Kernel Build, there is na_dma_0

    - in the kernel i have enabled DMA Support

    - in the proc filesystem i have an dma entry, if i use

    cat dma

    its empty.

    it seems there is still something wrong. For a little in my driver code i used

    i=get_dma_residue((unsigned int)0);

    it returns -1,

    according to the driver code in arch/nios2nommu/kernel/dma.c

    nt get_dma_residue(unsigned int dmanr)
    {
        int result =-1;
        if (dmanr < MAX_DMA_CHANNELS) {
      result = inl(dma_channels.addr+REG_DMA_LENGTH);
        }
        return result;
    }

    this means MAX_DMA_CHANNELS is at least 0, since dmanr is 0,

    so something is wrong in

    #define MAX_DMA_CHANNELS    sizeof(dma_channels)/sizeof(struct dma_channel)

    but this again depends on the definition on the the table, as you have written in your post.

    Any idea?

    Thanks.

    Helmar

    -- according to the kernel bug. the function i used isn&#39;t implemented
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Helmar,

    > get_dma_residue((unsigned int)0);

    >

    > it returns -1,

    <<snip>>

    > this means MAX_DMA_CHANNELS is at least 0

    Indeed! Check your dma.o with objdump ... each entry in dma_channels should account

    for 0x38 bytes (which I confirmed in my own kernel build -- it&#39;s ok). Although I haven&#39;t

    actually used the dma in the kernel yet -- sorry.

    If your table is in fact length zero, you might want to touch your nios2_system.h

    (or dma.c).

    Regards,

    --Scott
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hello Scott,

    thank you for sharing your thoughts.

    ---

    another way to check if the dma included correctly in the kernel is to look for an registered dma interrupt in "interrupts" in proc dir of the kernel, but objdump will show the proof. It is just another way to see it didn&#39;t work.

    But its actually no problem, I can access (inl,outl) the dma register and like i did without Linux.

    It is essential to get some uncached memory. I can try to "make" some handmade DMAable Memory. Since I use an Nios/f core i can try to do the 31-bit-uncache trick and flush the data cache.

    However I will think about it and try some ideas, and check if did something wrong.