Current-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: PXA2x0 DMAC alignment check
Hi! Tsutsui-san,
From: Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost>
Date: Sun, 31 Jul 2011 19:20:34 +0900
> kiyohara@ wrote:
>
> > 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.
>
> Looks okay, but have a few comments:
I remake newer patch.
Thanks,
--
kiyohara
Index: 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
--- pxa2x0_dmac.c 1 Jul 2011 20:32:51 -0000 1.8
+++ pxa2x0_dmac.c 10 Aug 2011 05:47:14 -0000
@@ -765,24 +765,39 @@
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);
- for (i = 0, size = 0; i < xd->xd_nsegs; i++) {
- if (xd->xd_dma_segs[i].ds_addr & 0x7) {
+ periph_end = CPU_IS_PXA270 ? PXA270_PERIPH_END : PXA250_PERIPH_END;
+ for (i = 0, size = 0; i < nsegs; i++) {
+ if (dma_segs[i].ds_addr >= PXA2X0_PERIPH_START &&
+ dma_segs[i].ds_addr + dma_segs[i].ds_len < periph_end)
+ /* Internal Peripherals. */
+ align = 0x03;
+ else /* Companion-Chip/External Peripherals/External Memory. */
+ align = 0x07;
+ /*
+ * XXXX:
+ * Also PXA27x has more constraints by pairs Source/Target.
+ */
+
+ 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