Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

PXA2x0 DMAC alignment check



Hi! all,


My pxa255 machine happens error when start write DMA to MMC.
Error message is

pxamci0: couldn't start dma xfer. (error=14)

This reason is fault alignment on pxadmac.  It checks alignment
to 8bytes boundary always.  But PXA255/270 datasheets describing
4byte allowed, if internal peripherals.

However pxa2x0 DMAC has more constraints for alignment.
We need more check?

This patch tested only on NETBOOK PRO(hpcarm. coming soon:).

Thanks,
--
kiyohara

Index: arch/arm/xscale/pxa2x0_dmac.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/xscale/pxa2x0_dmac.c,v
retrieving revision 1.8
diff -u -r1.8 pxa2x0_dmac.c
--- arch/arm/xscale/pxa2x0_dmac.c       1 Jul 2011 20:32:51 -0000       1.8
+++ arch/arm/xscale/pxa2x0_dmac.c       31 Jul 2011 02:41:43 -0000
@@ -765,24 +765,33 @@
 dmac_validate_desc(struct dmac_xfer_desc *xd, size_t *psize,
     bool *misaligned_flag)
 {
+       bus_dma_segment_t *dma_segs = xd->xd_dma_segs;
+       bus_addr_t periph_end;
+       bus_size_t align;
        size_t size;
-       int i;
+       int i, nsegs = xd->xd_nsegs;
 
        /*
         * Make sure the transfer parameters are acceptable.
         */
 
        if (xd->xd_addr_hold &&
-           (xd->xd_nsegs != 1 || xd->xd_dma_segs[0].ds_len == 0))
+           (nsegs != 1 || dma_segs[0].ds_len == 0))
                return (EINVAL);
 
+       periph_end = CPU_IS_PXA270 ? PXA270_PERIPH_END : PXA250_PERIPH_END;
        for (i = 0, size = 0; i < xd->xd_nsegs; i++) {
-               if (xd->xd_dma_segs[i].ds_addr & 0x7) {
+               if (dma_segs[i].ds_addr >= PXA2X0_PERIPH_START &&
+                   dma_segs[i].ds_addr + dma_segs[i].ds_len < periph_end)
+                       align = 0x03;
+               else
+                       align = 0x07;
+               if (dma_segs[i].ds_addr & align) {
                        if (!CPU_IS_PXA270)
                                return (EFAULT);
                        *misaligned_flag = true;
                }
-               size += xd->xd_dma_segs[i].ds_len;
+               size += dma_segs[i].ds_len;
        }
 
        *psize = size;


Home | Main Index | Thread Index | Old Index