Module Name:    src
Committed By:   tsutsui
Date:           Sun Aug  8 11:24:52 UTC 2010

Modified Files:
        src/sys/arch/arm/xscale: pxa2x0_lcd.c

Log Message:
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)?


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/sys/arch/arm/xscale/pxa2x0_lcd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/xscale/pxa2x0_lcd.c
diff -u src/sys/arch/arm/xscale/pxa2x0_lcd.c:1.29 src/sys/arch/arm/xscale/pxa2x0_lcd.c:1.30
--- src/sys/arch/arm/xscale/pxa2x0_lcd.c:1.29	Sun Aug  8 09:33:35 2010
+++ src/sys/arch/arm/xscale/pxa2x0_lcd.c	Sun Aug  8 11:24:52 2010
@@ -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));
 }
 
 

Reply via email to