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)); }