MPC831e + DMA

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MPC831e + DMA

1,542 Views
medina
Contributor III

Hello,

            We are facing some issues when trying to use the MPC8313e  DMA peripheral. When we start a DMA transaction our system freezes so we must reset it. We are trying several buffer configurations (dynamical and static) and various transfer sizes but the same problem keeps on happening, the systems stops responding. There is also an important thing that may help you to find the cause. Sometimes the system freezes at the first transaction, but sometimes it happens later.

 

Below you can find the piece of code that fails. This code works without DMA (using a write loop). Could you please help us identifying the wrong part?

 

Thanks in advance.

 

DMA:  memory to PCI (4byte, direct mode, snooping).

            Memory buffer from kmalloc

            1000 bytes

 

 

// pointer to the kmalloc'd area, rounded up to a page boundary

static char *buffer_area;

// original pointer for kmalloc'd area as returned by kmalloc

static void *buffer_ptr;

 

 

initmodule

{

....

// Allocate a memory area with kmalloc. Will be rounded up to a page boundary

       buffer_ptr = kmalloc((NPAGES + 2) * PAGE_SIZE, GFP_KERNEL);

       if ( buffer_ptr == NULL)

       {

             printk ( KERN_ALERT "\n\tERROR: kmalloc\n");

             return -ENOMEM;

       }

// round it up to the page bondary

       buffer_area = (int *)((((unsigned long)buffer_ptr) + PAGE_SIZE - 1) & PAGE_MASK);

       printk ("\n\tkmalloc buffer (0x%.8x@%lu)...", buffer_area,(NPAGES + 2) * PAGE_SIZE);

.....

}

 

fileoperation_write(buff,count_c)

{

 

       int *buffer=(int *)buffer_area;

 

       printk("pci_write:smileyvery-happy:MA buffer  %.8x v - %.8x p - %.8x b\n",

             buffer, virt_to_phys(buffer), virt_to_bus(buffer));

 

       copy_from_user((void *)buffer,(void *)buf,count_c);

 

       *dmadar1=swapbyte(PCI_ADDR);                   //Dest Address

       *dmasar1=swapbyte(virt_to_phys (buffer));      //Source Address

....

 

       *dmabcr1=swapbyte(wr);                         //Byte count

 

 

       *dmamr1=DMAMR_WR;                       //Config Mode

       printk("DMA_WR: Before START\n");

       print_config_DMA();

       *dmamr1=DMAMR_WR_S;                     //Start DMA

       printk("DMA_WR: After START\n");

       print_config_DMA();

....

}

 

 

Console output:

 

(init)

kmalloc buffer (0xc0998000@28672)...

 

(fo_write)

pci_write:smileyvery-happy:MA buffer  c7fb0000 v - 07fb0000 p - 07fb0000 b

DMA_WR: Before START

        Config DMA

     MODE       STATUS     DESC ACT   SOURCE     DEST       COUNT      NEXT DESC

(1) 04801200   00000000   00000000   00009c00   004000e3   e8030000   00000000

DMA_WR: After START

        Config DMA

     MODE       STATUS     DESC ACT   SOURCE     DEST       COUNT      NEXT DESC

(1)  Here is where the system stops. There should be written the same as in the previous example

 

 

Thanks,

Medina

0 Kudos
2 Replies

522 Views
Chansun
Contributor I
Hi medina,
 
I must confess that don't know much about your problem. I've seen below statement from Chip Errata document (MPC8360ECE.pdf).
 
Devices:
MPC8360E, MPC8358E
Description:
There can be corruption of the DMA data under the following conditions:
• DMAMR[DAHE] = 1 (destination address hold)
• DMAMR[DAHTS] = 10 (4 bytes) or 11 (8 bytes)
• DMA source address is not aligned to the transaction size specified by DAHTS
• The source port width is smaller than the destination transaction size OR the source port returns
valid read data only in the valid byte lanes
Example of error condition:
• DAHTS is 8 bytes and the source port is a 32-bit PCI bus
• The source memory space is on the PCI bus and is not prefetchable
Projected Impact:
Corrupted data written to the destination peripheral or memory.
Work Arounds:
• Use a source address aligned to the destination transaction size
or
• Do not access any DMA registers while this type of DMA transfer is active
Projected Solution:
Will not be fixed.
DMA2 Data corruption by DMA when destination address hold (DAHE) bit is
used
 
Hope this help,
Chansun
0 Kudos

522 Views
medina
Contributor III
Hi chansun,

Thanks for your reply. I don't use address hold, it allow use the pci-burst. I use 4 byte in source and destination address. I'm implementing the IRQ for DMA to avoid access to dma register while DMA transfer is active.

In my system there isn't data corrupted. When I start a DMA transaction to/from dynamic memory buffer my system freezes.

Thanks for your help,
Medina
0 Kudos