Sat Apr 11 13:44:14 2015 UTC ()
Don't make the frame buffer BUS_DMA_COHERENT, but instead
do a bus_dmamap_sync() on end-of-frame interrupts.
This effectively cause the frame buffer to be mapped cached,
giving a very noticeable performance boost.


(bouyer)
diff -r1.3 -r1.4 src/sys/arch/arm/omap/tifb.c

cvs diff -r1.3 -r1.4 src/sys/arch/arm/omap/Attic/tifb.c (expand / switch to unified diff)

--- src/sys/arch/arm/omap/Attic/tifb.c 2014/08/22 20:01:16 1.3
+++ src/sys/arch/arm/omap/Attic/tifb.c 2015/04/11 13:44:14 1.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tifb.c,v 1.3 2014/08/22 20:01:16 jakllsch Exp $ */ 1/* $NetBSD: tifb.c,v 1.4 2015/04/11 13:44:14 bouyer Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2010 Michael Lorenz 4 * Copyright (c) 2010 Michael Lorenz
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -47,27 +47,27 @@ @@ -47,27 +47,27 @@
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE. 51 * SUCH DAMAGE.
52 */ 52 */
53 53
54/* 54/*
55 * A framebuffer driver for TI 35xx built-in video controller 55 * A framebuffer driver for TI 35xx built-in video controller
56 * tested on beaglebone 56 * tested on beaglebone
57 */ 57 */
58 58
59#include <sys/cdefs.h> 59#include <sys/cdefs.h>
60__KERNEL_RCSID(0, "$NetBSD: tifb.c,v 1.3 2014/08/22 20:01:16 jakllsch Exp $"); 60__KERNEL_RCSID(0, "$NetBSD: tifb.c,v 1.4 2015/04/11 13:44:14 bouyer Exp $");
61 61
62#include "opt_omap.h" 62#include "opt_omap.h"
63 63
64#include <sys/param.h> 64#include <sys/param.h>
65#include <sys/systm.h> 65#include <sys/systm.h>
66#include <sys/kernel.h> 66#include <sys/kernel.h>
67#include <sys/device.h> 67#include <sys/device.h>
68#include <sys/malloc.h> 68#include <sys/malloc.h>
69#include <sys/lwp.h> 69#include <sys/lwp.h>
70#include <sys/kauth.h> 70#include <sys/kauth.h>
71 71
72#include <uvm/uvm_extern.h> 72#include <uvm/uvm_extern.h>
73 73
@@ -216,26 +216,27 @@ struct wsdisplay_accessops tifb_accessop @@ -216,26 +216,27 @@ struct wsdisplay_accessops tifb_accessop
216 NULL, /* load_font */ 216 NULL, /* load_font */
217 NULL, /* pollc */ 217 NULL, /* pollc */
218 NULL /* scroll */ 218 NULL /* scroll */
219}; 219};
220 220
221extern const u_char rasops_cmap[768]; 221extern const u_char rasops_cmap[768];
222 222
223static struct evcnt ev_sync_lost; 223static struct evcnt ev_sync_lost;
224static struct evcnt ev_palette; 224static struct evcnt ev_palette;
225static struct evcnt ev_eof0; 225static struct evcnt ev_eof0;
226static struct evcnt ev_eof1; 226static struct evcnt ev_eof1;
227static struct evcnt ev_fifo_underflow; 227static struct evcnt ev_fifo_underflow;
228static struct evcnt ev_ac_bias; 228static struct evcnt ev_ac_bias;
 229static struct evcnt ev_frame_done;
229static struct evcnt ev_others; 230static struct evcnt ev_others;
230 231
231 232
232static uint32_t 233static uint32_t
233am335x_lcd_calc_divisor(uint32_t reference, uint32_t freq) 234am335x_lcd_calc_divisor(uint32_t reference, uint32_t freq)
234{ 235{
235 uint32_t div; 236 uint32_t div;
236 /* Raster mode case: divisors are in range from 2 to 255 */ 237 /* Raster mode case: divisors are in range from 2 to 255 */
237 for (div = 2; div < 255; div++) 238 for (div = 2; div < 255; div++)
238 if (reference/div <= freq) 239 if (reference/div <= freq)
239 return (div); 240 return (div);
240 241
241 return (255); 242 return (255);
@@ -309,26 +310,28 @@ tifb_attach(device_t parent, device_t se @@ -309,26 +310,28 @@ tifb_attach(device_t parent, device_t se
309 310
310 evcnt_attach_dynamic(&ev_sync_lost, EVCNT_TYPE_MISC, NULL, 311 evcnt_attach_dynamic(&ev_sync_lost, EVCNT_TYPE_MISC, NULL,
311 "lcd", "sync lost"); 312 "lcd", "sync lost");
312 evcnt_attach_dynamic(&ev_palette, EVCNT_TYPE_MISC, NULL, 313 evcnt_attach_dynamic(&ev_palette, EVCNT_TYPE_MISC, NULL,
313 "lcd", "palette loaded"); 314 "lcd", "palette loaded");
314 evcnt_attach_dynamic(&ev_eof0, EVCNT_TYPE_MISC, NULL, 315 evcnt_attach_dynamic(&ev_eof0, EVCNT_TYPE_MISC, NULL,
315 "lcd", "eof0"); 316 "lcd", "eof0");
316 evcnt_attach_dynamic(&ev_eof1, EVCNT_TYPE_MISC, NULL, 317 evcnt_attach_dynamic(&ev_eof1, EVCNT_TYPE_MISC, NULL,
317 "lcd", "eof1"); 318 "lcd", "eof1");
318 evcnt_attach_dynamic(&ev_fifo_underflow, EVCNT_TYPE_MISC, NULL, 319 evcnt_attach_dynamic(&ev_fifo_underflow, EVCNT_TYPE_MISC, NULL,
319 "lcd", "fifo underflow"); 320 "lcd", "fifo underflow");
320 evcnt_attach_dynamic(&ev_ac_bias, EVCNT_TYPE_MISC, NULL, 321 evcnt_attach_dynamic(&ev_ac_bias, EVCNT_TYPE_MISC, NULL,
321 "lcd", "ac bias"); 322 "lcd", "ac bias");
 323 evcnt_attach_dynamic(&ev_frame_done, EVCNT_TYPE_MISC, NULL,
 324 "lcd", "frame_done");
322 evcnt_attach_dynamic(&ev_others, EVCNT_TYPE_MISC, NULL, 325 evcnt_attach_dynamic(&ev_others, EVCNT_TYPE_MISC, NULL,
323 "lcd", "others"); 326 "lcd", "others");
324 327
325 sc->sc_iot = obio->obio_iot; 328 sc->sc_iot = obio->obio_iot;
326 sc->sc_dev = self; 329 sc->sc_dev = self;
327 sc->sc_dmat = obio->obio_dmat; 330 sc->sc_dmat = obio->obio_dmat;
328 331
329 if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size, 0, 332 if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size, 0,
330 &sc->sc_regh)) { 333 &sc->sc_regh)) {
331 aprint_error(": couldn't map register space\n"); 334 aprint_error(": couldn't map register space\n");
332 return; 335 return;
333 } 336 }
334 337
@@ -390,27 +393,27 @@ tifb_attach(device_t parent, device_t se @@ -390,27 +393,27 @@ tifb_attach(device_t parent, device_t se
390 } 393 }
391 394
392 sc->sc_vramsize = sc->sc_palettesize + 395 sc->sc_vramsize = sc->sc_palettesize +
393 sc->sc_stride * sc->sc_panel->panel_height; 396 sc->sc_stride * sc->sc_panel->panel_height;
394 397
395 if (bus_dmamem_alloc(sc->sc_dmat, sc->sc_vramsize, 0, 0, 398 if (bus_dmamem_alloc(sc->sc_dmat, sc->sc_vramsize, 0, 0,
396 sc->sc_dmamem, 1, &segs, BUS_DMA_NOWAIT) != 0) { 399 sc->sc_dmamem, 1, &segs, BUS_DMA_NOWAIT) != 0) {
397 aprint_error_dev(sc->sc_dev, 400 aprint_error_dev(sc->sc_dev,
398 "failed to allocate video memory\n"); 401 "failed to allocate video memory\n");
399 return; 402 return;
400 } 403 }
401 404
402 if (bus_dmamem_map(sc->sc_dmat, sc->sc_dmamem, 1, sc->sc_vramsize, 405 if (bus_dmamem_map(sc->sc_dmat, sc->sc_dmamem, 1, sc->sc_vramsize,
403 &sc->sc_vramaddr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT) != 0) { 406 &sc->sc_vramaddr, BUS_DMA_NOWAIT) != 0) {
404 aprint_error_dev(sc->sc_dev, "failed to map video RAM\n"); 407 aprint_error_dev(sc->sc_dev, "failed to map video RAM\n");
405 return; 408 return;
406 } 409 }
407 sc->sc_fbaddr = (uint8_t *)sc->sc_vramaddr + sc->sc_palettesize; 410 sc->sc_fbaddr = (uint8_t *)sc->sc_vramaddr + sc->sc_palettesize;
408 sc->sc_palette = sc->sc_vramaddr; 411 sc->sc_palette = sc->sc_vramaddr;
409 412
410 if (bus_dmamap_create(sc->sc_dmat, sc->sc_vramsize, 1, sc->sc_vramsize, 413 if (bus_dmamap_create(sc->sc_dmat, sc->sc_vramsize, 1, sc->sc_vramsize,
411 0, BUS_DMA_NOWAIT, &sc->sc_dmamap) != 0) { 414 0, BUS_DMA_NOWAIT, &sc->sc_dmamap) != 0) {
412 aprint_error_dev(sc->sc_dev, "failed to create DMA map\n"); 415 aprint_error_dev(sc->sc_dev, "failed to create DMA map\n");
413 return; 416 return;
414 } 417 }
415 418
416 if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_vramaddr, 419 if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_vramaddr,
@@ -673,26 +676,37 @@ tifb_intr(void *v) @@ -673,26 +676,37 @@ tifb_intr(void *v)
673 676
674 if (reg & IRQ_PL) { 677 if (reg & IRQ_PL) {
675 ev_palette.ev_count ++; 678 ev_palette.ev_count ++;
676 reg = TIFB_READ(sc, LCD_RASTER_CTRL); 679 reg = TIFB_READ(sc, LCD_RASTER_CTRL);
677 reg &= ~RASTER_CTRL_LCDEN; 680 reg &= ~RASTER_CTRL_LCDEN;
678 TIFB_WRITE(sc, LCD_RASTER_CTRL, reg); 681 TIFB_WRITE(sc, LCD_RASTER_CTRL, reg);
679 682
680 reg = TIFB_READ(sc, LCD_RASTER_CTRL); 683 reg = TIFB_READ(sc, LCD_RASTER_CTRL);
681 reg |= RASTER_CTRL_LCDEN; 684 reg |= RASTER_CTRL_LCDEN;
682 TIFB_WRITE(sc, LCD_RASTER_CTRL, reg); 685 TIFB_WRITE(sc, LCD_RASTER_CTRL, reg);
683 return 0; 686 return 0;
684 } 687 }
685 688
 689 if (reg & (IRQ_FRAME_DONE|IRQ_EOF0|IRQ_EOF1)) {
 690 /* flush the write-back cache */
 691 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
 692 0, sc->sc_vramsize, BUS_DMASYNC_PREWRITE);
 693 }
 694
 695 if (reg & IRQ_FRAME_DONE) {
 696 ev_frame_done.ev_count ++;
 697 reg &= ~IRQ_FRAME_DONE;
 698 }
 699
686 if (reg & IRQ_EOF0) { 700 if (reg & IRQ_EOF0) {
687 ev_eof0.ev_count ++; 701 ev_eof0.ev_count ++;
688 TIFB_WRITE(sc, LCD_LCDDMA_FB0_BASE, sc->sc_dmamem->ds_addr); 702 TIFB_WRITE(sc, LCD_LCDDMA_FB0_BASE, sc->sc_dmamem->ds_addr);
689 TIFB_WRITE(sc, LCD_LCDDMA_FB0_CEILING, 703 TIFB_WRITE(sc, LCD_LCDDMA_FB0_CEILING,
690 sc->sc_dmamem->ds_addr + sc->sc_vramsize - 1); 704 sc->sc_dmamem->ds_addr + sc->sc_vramsize - 1);
691 reg &= ~IRQ_EOF0; 705 reg &= ~IRQ_EOF0;
692 } 706 }
693 707
694 if (reg & IRQ_EOF1) { 708 if (reg & IRQ_EOF1) {
695 ev_eof1.ev_count ++; 709 ev_eof1.ev_count ++;
696 TIFB_WRITE(sc, LCD_LCDDMA_FB1_BASE, sc->sc_dmamem->ds_addr); 710 TIFB_WRITE(sc, LCD_LCDDMA_FB1_BASE, sc->sc_dmamem->ds_addr);
697 TIFB_WRITE(sc, LCD_LCDDMA_FB1_CEILING, 711 TIFB_WRITE(sc, LCD_LCDDMA_FB1_CEILING,
698 sc->sc_dmamem->ds_addr + sc->sc_vramsize - 1); 712 sc->sc_dmamem->ds_addr + sc->sc_vramsize - 1);