Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/arm/xscale Allow pxa2x0_lcd driver mapping screen b...



details:   https://anonhg.NetBSD.org/src/rev/4d1177264855
branches:  trunk
changeset: 756942:4d1177264855
user:      tsutsui <tsutsui%NetBSD.org@localhost>
date:      Sun Aug 08 11:24:52 2010 +0000

description:
Allow pxa2x0_lcd driver mapping screen buffer memory cachable with
write-through map (i.e. map it without BUS_DMA_COHERENT) since
currently all DMA data transfers are memory to device only.

Disabled by default, but enabled by "options PXA2X0_LCD_WRITETHROUGH"
or setting pxa2x0_lcd_writethrough = 1 in a kernel binary.

Tested on WS003SH by me and on WS011SH by jun@, and console output speed
is improved ~three times faster than coherent (uncached) mapping.

XXX: should we have a flag like BUS_DMA_WRITETHROUGH in MI bus_dma(9)?

diffstat:

 sys/arch/arm/xscale/pxa2x0_lcd.c |  39 +++++++++++++++++++++++++++++++++++----
 1 files changed, 35 insertions(+), 4 deletions(-)

diffs (84 lines):

diff -r 1ac1179a8636 -r 4d1177264855 sys/arch/arm/xscale/pxa2x0_lcd.c
--- a/sys/arch/arm/xscale/pxa2x0_lcd.c  Sun Aug 08 09:33:35 2010 +0000
+++ b/sys/arch/arm/xscale/pxa2x0_lcd.c  Sun Aug 08 11:24:52 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pxa2x0_lcd.c,v 1.29 2010/08/08 09:33:35 kiyohara Exp $ */
+/* $NetBSD: pxa2x0_lcd.c,v 1.30 2010/08/08 11:24:52 tsutsui Exp $ */
 
 /*
  * Copyright (c) 2002  Genetec Corporation.  All rights reserved.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pxa2x0_lcd.c,v 1.29 2010/08/08 09:33:35 kiyohara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pxa2x0_lcd.c,v 1.30 2010/08/08 11:24:52 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -78,6 +78,12 @@
        const struct lcd_panel_geometry *geom;
 } pxa2x0_lcd_console;
 
+#ifdef PXA2X0_LCD_WRITETHROUGH
+int pxa2x0_lcd_writethrough = 1;       /* patchable */
+#else
+int pxa2x0_lcd_writethrough = 0;
+#endif
+
 int            lcdintr(void *);
 
 static void    pxa2x0_lcd_initialize(struct pxa2x0_lcd_softc *, 
@@ -333,6 +339,9 @@
        iot = sc->iot;
        ioh = sc->ioh;
 
+       bus_dmamap_sync(sc->dma_tag, scr->dma, 0, scr->buf_size,
+           BUS_DMASYNC_PREWRITE);
+
        save = disable_interrupts(I32_bit);
 
        switch (scr->depth) {
@@ -536,10 +545,31 @@
        }
 
        error = bus_dmamem_map(dma_tag, scr->segs, scr->nsegs, size,
-           (void **)&scr->buf_va, busdma_flag | BUS_DMA_COHERENT);
+           (void **)&scr->buf_va,
+           busdma_flag | (pxa2x0_lcd_writethrough ? 0 : BUS_DMA_COHERENT));
        if (error)
                goto bad;
 
+       /* XXX: should we have BUS_DMA_WRITETHROUGH in MI bus_dma(9) API? */
+       if (pxa2x0_lcd_writethrough) {
+               pt_entry_t *ptep;
+               vaddr_t va, eva;
+
+               va = (vaddr_t)scr->buf_va;
+               eva = va + size;
+               while (va < eva) {
+                       /* taken from arm/arm32/bus_dma.c:_bus_dmamem_map() */
+                       cpu_dcache_wbinv_range(va, PAGE_SIZE);
+                       cpu_drain_writebuf();
+                       ptep = vtopte(va);
+                       *ptep &= ~L2_S_CACHE_MASK;
+                       *ptep |= L2_C;
+                       PTE_SYNC(ptep);
+                       tlb_flush();
+                       va += PAGE_SIZE;
+               }
+       }
+
        memset(scr->buf_va, 0, scr->buf_size);
 
        /* map memory for DMA */
@@ -899,7 +929,8 @@
                return -1;
 
        return bus_dmamem_mmap(sc->dma_tag, scr->segs, scr->nsegs,
-           offset, prot, BUS_DMA_WAITOK|BUS_DMA_COHERENT);
+           offset, prot,
+           BUS_DMA_WAITOK | (pxa2x0_lcd_writethrough ? 0 : BUS_DMA_COHERENT));
 }
 
 



Home | Main Index | Thread Index | Old Index