| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tifb.c,v 1.4 2015/04/11 13:44:14 bouyer Exp $ */ | | 1 | /* $NetBSD: tifb.c,v 1.5 2015/04/12 20:00:42 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,37 +47,38 @@ | | | @@ -47,37 +47,38 @@ |
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.4 2015/04/11 13:44:14 bouyer Exp $"); | | 60 | __KERNEL_RCSID(0, "$NetBSD: tifb.c,v 1.5 2015/04/12 20:00:42 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 | #include <sys/kmem.h> |
71 | | | 72 | |
72 | #include <uvm/uvm_extern.h> | | 73 | #include <uvm/uvm_extern.h> |
73 | | | 74 | |
74 | #include <dev/videomode/videomode.h> | | 75 | #include <dev/videomode/videomode.h> |
75 | | | 76 | |
76 | #include <sys/bus.h> | | 77 | #include <sys/bus.h> |
77 | #include <arm/omap/tifbreg.h> | | 78 | #include <arm/omap/tifbreg.h> |
78 | #include <arm/omap/omap_var.h> | | 79 | #include <arm/omap/omap_var.h> |
79 | #include <arm/omap/omap2_obiovar.h> | | 80 | #include <arm/omap/omap2_obiovar.h> |
80 | #include <arm/omap/omap2_obioreg.h> | | 81 | #include <arm/omap/omap2_obioreg.h> |
81 | #ifdef TI_AM335X | | 82 | #ifdef TI_AM335X |
82 | # include <arm/omap/am335x_prcm.h> | | 83 | # include <arm/omap/am335x_prcm.h> |
83 | # include <arm/omap/omap2_prcm.h> | | 84 | # include <arm/omap/omap2_prcm.h> |
| @@ -145,26 +146,27 @@ struct tifb_softc { | | | @@ -145,26 +146,27 @@ struct tifb_softc { |
145 | | | 146 | |
146 | void *sc_ih; | | 147 | void *sc_ih; |
147 | bus_space_tag_t sc_iot; | | 148 | bus_space_tag_t sc_iot; |
148 | bus_dma_tag_t sc_dmat; | | 149 | bus_dma_tag_t sc_dmat; |
149 | bus_space_handle_t sc_regh; | | 150 | bus_space_handle_t sc_regh; |
150 | bus_dmamap_t sc_dmamap; | | 151 | bus_dmamap_t sc_dmamap; |
151 | bus_dma_segment_t sc_dmamem[1]; | | 152 | bus_dma_segment_t sc_dmamem[1]; |
152 | size_t sc_vramsize; | | 153 | size_t sc_vramsize; |
153 | size_t sc_palettesize; | | 154 | size_t sc_palettesize; |
154 | | | 155 | |
155 | int sc_stride; | | 156 | int sc_stride; |
156 | int sc_locked; | | 157 | int sc_locked; |
157 | void *sc_fbaddr, *sc_vramaddr; | | 158 | void *sc_fbaddr, *sc_vramaddr; |
| | | 159 | void *sc_shadowfb; |
158 | | | 160 | |
159 | bus_addr_t sc_fbhwaddr; | | 161 | bus_addr_t sc_fbhwaddr; |
160 | uint16_t *sc_palette; | | 162 | uint16_t *sc_palette; |
161 | uint32_t sc_dispc_config; | | 163 | uint32_t sc_dispc_config; |
162 | struct vcons_screen sc_console_screen; | | 164 | struct vcons_screen sc_console_screen; |
163 | struct wsscreen_descr sc_defaultscreen_descr; | | 165 | struct wsscreen_descr sc_defaultscreen_descr; |
164 | const struct wsscreen_descr *sc_screens[1]; | | 166 | const struct wsscreen_descr *sc_screens[1]; |
165 | struct wsscreen_list sc_screenlist; | | 167 | struct wsscreen_list sc_screenlist; |
166 | struct vcons_data vd; | | 168 | struct vcons_data vd; |
167 | int sc_mode; | | 169 | int sc_mode; |
168 | uint8_t sc_cmap_red[256], sc_cmap_green[256], sc_cmap_blue[256]; | | 170 | uint8_t sc_cmap_red[256], sc_cmap_green[256], sc_cmap_blue[256]; |
169 | void (*sc_putchar)(void *, int, int, u_int, long); | | 171 | void (*sc_putchar)(void *, int, int, u_int, long); |
170 | | | 172 | |
| @@ -385,35 +387,41 @@ tifb_attach(device_t parent, device_t se | | | @@ -385,35 +387,41 @@ tifb_attach(device_t parent, device_t se |
385 | /* setup video DMA */ | | 387 | /* setup video DMA */ |
386 | switch(sc->sc_panel->bpp) { | | 388 | switch(sc->sc_panel->bpp) { |
387 | case 8: | | 389 | case 8: |
388 | sc->sc_palettesize = 512; | | 390 | sc->sc_palettesize = 512; |
389 | break; | | 391 | break; |
390 | default: | | 392 | default: |
391 | sc->sc_palettesize = 32; | | 393 | sc->sc_palettesize = 32; |
392 | break; | | 394 | break; |
393 | } | | 395 | } |
394 | | | 396 | |
395 | sc->sc_vramsize = sc->sc_palettesize + | | 397 | sc->sc_vramsize = sc->sc_palettesize + |
396 | sc->sc_stride * sc->sc_panel->panel_height; | | 398 | sc->sc_stride * sc->sc_panel->panel_height; |
397 | | | 399 | |
| | | 400 | sc->sc_shadowfb = kmem_alloc(sc->sc_vramsize - sc->sc_palettesize, |
| | | 401 | KM_NOSLEEP); |
| | | 402 | if (sc->sc_shadowfb == NULL) { |
| | | 403 | aprint_error_dev(sc->sc_dev, |
| | | 404 | "warning: failed to allocate shadow framebuffer\n"); |
| | | 405 | } |
398 | if (bus_dmamem_alloc(sc->sc_dmat, sc->sc_vramsize, 0, 0, | | 406 | if (bus_dmamem_alloc(sc->sc_dmat, sc->sc_vramsize, 0, 0, |
399 | sc->sc_dmamem, 1, &segs, BUS_DMA_NOWAIT) != 0) { | | 407 | sc->sc_dmamem, 1, &segs, BUS_DMA_NOWAIT) != 0) { |
400 | aprint_error_dev(sc->sc_dev, | | 408 | aprint_error_dev(sc->sc_dev, |
401 | "failed to allocate video memory\n"); | | 409 | "failed to allocate video memory\n"); |
402 | return; | | 410 | return; |
403 | } | | 411 | } |
404 | | | 412 | |
405 | if (bus_dmamem_map(sc->sc_dmat, sc->sc_dmamem, 1, sc->sc_vramsize, | | 413 | if (bus_dmamem_map(sc->sc_dmat, sc->sc_dmamem, 1, sc->sc_vramsize, |
406 | &sc->sc_vramaddr, BUS_DMA_NOWAIT) != 0) { | | 414 | &sc->sc_vramaddr, BUS_DMA_NOWAIT | BUS_DMA_PREFETCHABLE) != 0) { |
407 | aprint_error_dev(sc->sc_dev, "failed to map video RAM\n"); | | 415 | aprint_error_dev(sc->sc_dev, "failed to map video RAM\n"); |
408 | return; | | 416 | return; |
409 | } | | 417 | } |
410 | sc->sc_fbaddr = (uint8_t *)sc->sc_vramaddr + sc->sc_palettesize; | | 418 | sc->sc_fbaddr = (uint8_t *)sc->sc_vramaddr + sc->sc_palettesize; |
411 | sc->sc_palette = sc->sc_vramaddr; | | 419 | sc->sc_palette = sc->sc_vramaddr; |
412 | | | 420 | |
413 | if (bus_dmamap_create(sc->sc_dmat, sc->sc_vramsize, 1, sc->sc_vramsize, | | 421 | if (bus_dmamap_create(sc->sc_dmat, sc->sc_vramsize, 1, sc->sc_vramsize, |
414 | 0, BUS_DMA_NOWAIT, &sc->sc_dmamap) != 0) { | | 422 | 0, BUS_DMA_NOWAIT, &sc->sc_dmamap) != 0) { |
415 | aprint_error_dev(sc->sc_dev, "failed to create DMA map\n"); | | 423 | aprint_error_dev(sc->sc_dev, "failed to create DMA map\n"); |
416 | return; | | 424 | return; |
417 | } | | 425 | } |
418 | | | 426 | |
419 | if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_vramaddr, | | 427 | if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_vramaddr, |
| @@ -533,27 +541,27 @@ tifb_attach(device_t parent, device_t se | | | @@ -533,27 +541,27 @@ tifb_attach(device_t parent, device_t se |
533 | timing2 |= RASTER_TIMING_2_IPC; | | 541 | timing2 |= RASTER_TIMING_2_IPC; |
534 | | | 542 | |
535 | /* AC bias */ | | 543 | /* AC bias */ |
536 | timing2 |= (sc->sc_panel->ac_bias << RASTER_TIMING_2_ACB_SHIFT); | | 544 | timing2 |= (sc->sc_panel->ac_bias << RASTER_TIMING_2_ACB_SHIFT); |
537 | timing2 |= (sc->sc_panel->ac_bias_intrpt << RASTER_TIMING_2_ACBI_SHIFT); | | 545 | timing2 |= (sc->sc_panel->ac_bias_intrpt << RASTER_TIMING_2_ACBI_SHIFT); |
538 | | | 546 | |
539 | TIFB_WRITE(sc, LCD_RASTER_TIMING_0, timing0); | | 547 | TIFB_WRITE(sc, LCD_RASTER_TIMING_0, timing0); |
540 | TIFB_WRITE(sc, LCD_RASTER_TIMING_1, timing1); | | 548 | TIFB_WRITE(sc, LCD_RASTER_TIMING_1, timing1); |
541 | TIFB_WRITE(sc, LCD_RASTER_TIMING_2, timing2); | | 549 | TIFB_WRITE(sc, LCD_RASTER_TIMING_2, timing2); |
542 | aprint_debug_dev(self, ": timings 0x%x 0x%x 0x%x\n", | | 550 | aprint_debug_dev(self, ": timings 0x%x 0x%x 0x%x\n", |
543 | timing0, timing1, timing2); | | 551 | timing0, timing1, timing2); |
544 | | | 552 | |
545 | /* DMA settings */ | | 553 | /* DMA settings */ |
546 | reg = LCDDMA_CTRL_FB0_FB1; | | 554 | reg = 0; |
547 | /* Find power of 2 for current burst size */ | | 555 | /* Find power of 2 for current burst size */ |
548 | switch (sc->sc_panel->dma_burst_sz) { | | 556 | switch (sc->sc_panel->dma_burst_sz) { |
549 | case 1: | | 557 | case 1: |
550 | burst_log = 0; | | 558 | burst_log = 0; |
551 | break; | | 559 | break; |
552 | case 2: | | 560 | case 2: |
553 | burst_log = 1; | | 561 | burst_log = 1; |
554 | break; | | 562 | break; |
555 | case 4: | | 563 | case 4: |
556 | burst_log = 2; | | 564 | burst_log = 2; |
557 | break; | | 565 | break; |
558 | case 8: | | 566 | case 8: |
559 | burst_log = 3; | | 567 | burst_log = 3; |
| @@ -587,29 +595,27 @@ tifb_attach(device_t parent, device_t se | | | @@ -587,29 +595,27 @@ tifb_attach(device_t parent, device_t se |
587 | if (sc->sc_panel->bpp == 32) | | 595 | if (sc->sc_panel->bpp == 32) |
588 | reg |= RASTER_CTRL_TFT24_UNPACKED; | | 596 | reg |= RASTER_CTRL_TFT24_UNPACKED; |
589 | TIFB_WRITE(sc, LCD_RASTER_CTRL, reg); | | 597 | TIFB_WRITE(sc, LCD_RASTER_CTRL, reg); |
590 | aprint_debug_dev(self, ": LCD_RASTER_CTRL 0x%x\n", reg); | | 598 | aprint_debug_dev(self, ": LCD_RASTER_CTRL 0x%x\n", reg); |
591 | | | 599 | |
592 | TIFB_WRITE(sc, LCD_CLKC_ENABLE, | | 600 | TIFB_WRITE(sc, LCD_CLKC_ENABLE, |
593 | CLKC_ENABLE_DMA | CLKC_ENABLE_LDID | CLKC_ENABLE_CORE); | | 601 | CLKC_ENABLE_DMA | CLKC_ENABLE_LDID | CLKC_ENABLE_CORE); |
594 | | | 602 | |
595 | TIFB_WRITE(sc, LCD_CLKC_RESET, CLKC_RESET_MAIN); | | 603 | TIFB_WRITE(sc, LCD_CLKC_RESET, CLKC_RESET_MAIN); |
596 | DELAY(100); | | 604 | DELAY(100); |
597 | TIFB_WRITE(sc, LCD_CLKC_RESET, 0); | | 605 | TIFB_WRITE(sc, LCD_CLKC_RESET, 0); |
598 | aprint_debug_dev(self, ": LCD_CLKC_ENABLE 0x%x\n", TIFB_READ(sc, LCD_CLKC_ENABLE)); | | 606 | aprint_debug_dev(self, ": LCD_CLKC_ENABLE 0x%x\n", TIFB_READ(sc, LCD_CLKC_ENABLE)); |
599 | | | 607 | |
600 | reg = IRQ_EOF1 | IRQ_EOF0 | IRQ_FUF | IRQ_PL | | | 608 | reg = IRQ_FUF | IRQ_PL | IRQ_ACB | IRQ_SYNC_LOST; |
601 | IRQ_ACB | IRQ_SYNC_LOST | IRQ_RASTER_DONE | | | | |
602 | IRQ_FRAME_DONE; | | | |
603 | TIFB_WRITE(sc, LCD_IRQENABLE_SET, reg); | | 609 | TIFB_WRITE(sc, LCD_IRQENABLE_SET, reg); |
604 | | | 610 | |
605 | reg = TIFB_READ(sc, LCD_RASTER_CTRL); | | 611 | reg = TIFB_READ(sc, LCD_RASTER_CTRL); |
606 | reg |= RASTER_CTRL_LCDEN; | | 612 | reg |= RASTER_CTRL_LCDEN; |
607 | TIFB_WRITE(sc, LCD_RASTER_CTRL, reg); | | 613 | TIFB_WRITE(sc, LCD_RASTER_CTRL, reg); |
608 | aprint_debug_dev(self, ": LCD_RASTER_CTRL 0x%x\n", TIFB_READ(sc, LCD_RASTER_CTRL)); | | 614 | aprint_debug_dev(self, ": LCD_RASTER_CTRL 0x%x\n", TIFB_READ(sc, LCD_RASTER_CTRL)); |
609 | | | 615 | |
610 | TIFB_WRITE(sc, LCD_SYSCONFIG, | | 616 | TIFB_WRITE(sc, LCD_SYSCONFIG, |
611 | SYSCONFIG_STANDBY_SMART | SYSCONFIG_IDLE_SMART); | | 617 | SYSCONFIG_STANDBY_SMART | SYSCONFIG_IDLE_SMART); |
612 | aprint_debug_dev(self, ": LCD_SYSCONFIG 0x%x\n", TIFB_READ(sc, LCD_SYSCONFIG)); | | 618 | aprint_debug_dev(self, ": LCD_SYSCONFIG 0x%x\n", TIFB_READ(sc, LCD_SYSCONFIG)); |
613 | | | 619 | |
614 | /* attach wscons */ | | 620 | /* attach wscons */ |
615 | sc->sc_defaultscreen_descr = (struct wsscreen_descr){ | | 621 | sc->sc_defaultscreen_descr = (struct wsscreen_descr){ |
| @@ -643,26 +649,28 @@ tifb_attach(device_t parent, device_t se | | | @@ -643,26 +649,28 @@ tifb_attach(device_t parent, device_t se |
643 | wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, | | 649 | wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, |
644 | defattr); | | 650 | defattr); |
645 | vcons_replay_msgbuf(&sc->sc_console_screen); | | 651 | vcons_replay_msgbuf(&sc->sc_console_screen); |
646 | } | | 652 | } |
647 | | | 653 | |
648 | aa.console = is_console; | | 654 | aa.console = is_console; |
649 | aa.scrdata = &sc->sc_screenlist; | | 655 | aa.scrdata = &sc->sc_screenlist; |
650 | aa.accessops = &tifb_accessops; | | 656 | aa.accessops = &tifb_accessops; |
651 | aa.accesscookie = &sc->vd; | | 657 | aa.accesscookie = &sc->vd; |
652 | | | 658 | |
653 | config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); | | 659 | config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); |
654 | } | | 660 | } |
655 | | | 661 | |
| | | 662 | uint32_t tifb_intr_unh = 0; |
| | | 663 | |
656 | static int | | 664 | static int |
657 | tifb_intr(void *v) | | 665 | tifb_intr(void *v) |
658 | { | | 666 | { |
659 | struct tifb_softc *sc = v; | | 667 | struct tifb_softc *sc = v; |
660 | uint32_t reg; | | 668 | uint32_t reg; |
661 | | | 669 | |
662 | reg = TIFB_READ(sc, LCD_IRQSTATUS); | | 670 | reg = TIFB_READ(sc, LCD_IRQSTATUS); |
663 | TIFB_WRITE(sc, LCD_IRQSTATUS, reg); | | 671 | TIFB_WRITE(sc, LCD_IRQSTATUS, reg); |
664 | | | 672 | |
665 | if (reg & IRQ_SYNC_LOST) { | | 673 | if (reg & IRQ_SYNC_LOST) { |
666 | ev_sync_lost.ev_count ++; | | 674 | ev_sync_lost.ev_count ++; |
667 | reg = TIFB_READ(sc, LCD_RASTER_CTRL); | | 675 | reg = TIFB_READ(sc, LCD_RASTER_CTRL); |
668 | reg &= ~RASTER_CTRL_LCDEN; | | 676 | reg &= ~RASTER_CTRL_LCDEN; |
| @@ -676,32 +684,26 @@ tifb_intr(void *v) | | | @@ -676,32 +684,26 @@ tifb_intr(void *v) |
676 | | | 684 | |
677 | if (reg & IRQ_PL) { | | 685 | if (reg & IRQ_PL) { |
678 | ev_palette.ev_count ++; | | 686 | ev_palette.ev_count ++; |
679 | reg = TIFB_READ(sc, LCD_RASTER_CTRL); | | 687 | reg = TIFB_READ(sc, LCD_RASTER_CTRL); |
680 | reg &= ~RASTER_CTRL_LCDEN; | | 688 | reg &= ~RASTER_CTRL_LCDEN; |
681 | TIFB_WRITE(sc, LCD_RASTER_CTRL, reg); | | 689 | TIFB_WRITE(sc, LCD_RASTER_CTRL, reg); |
682 | | | 690 | |
683 | reg = TIFB_READ(sc, LCD_RASTER_CTRL); | | 691 | reg = TIFB_READ(sc, LCD_RASTER_CTRL); |
684 | reg |= RASTER_CTRL_LCDEN; | | 692 | reg |= RASTER_CTRL_LCDEN; |
685 | TIFB_WRITE(sc, LCD_RASTER_CTRL, reg); | | 693 | TIFB_WRITE(sc, LCD_RASTER_CTRL, reg); |
686 | return 0; | | 694 | return 0; |
687 | } | | 695 | } |
688 | | | 696 | |
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) { | | 697 | if (reg & IRQ_FRAME_DONE) { |
696 | ev_frame_done.ev_count ++; | | 698 | ev_frame_done.ev_count ++; |
697 | reg &= ~IRQ_FRAME_DONE; | | 699 | reg &= ~IRQ_FRAME_DONE; |
698 | } | | 700 | } |
699 | | | 701 | |
700 | if (reg & IRQ_EOF0) { | | 702 | if (reg & IRQ_EOF0) { |
701 | ev_eof0.ev_count ++; | | 703 | ev_eof0.ev_count ++; |
702 | TIFB_WRITE(sc, LCD_LCDDMA_FB0_BASE, sc->sc_dmamem->ds_addr); | | 704 | TIFB_WRITE(sc, LCD_LCDDMA_FB0_BASE, sc->sc_dmamem->ds_addr); |
703 | TIFB_WRITE(sc, LCD_LCDDMA_FB0_CEILING, | | 705 | TIFB_WRITE(sc, LCD_LCDDMA_FB0_CEILING, |
704 | sc->sc_dmamem->ds_addr + sc->sc_vramsize - 1); | | 706 | sc->sc_dmamem->ds_addr + sc->sc_vramsize - 1); |
705 | reg &= ~IRQ_EOF0; | | 707 | reg &= ~IRQ_EOF0; |
706 | } | | 708 | } |
707 | | | 709 | |
| @@ -714,28 +716,30 @@ tifb_intr(void *v) | | | @@ -714,28 +716,30 @@ tifb_intr(void *v) |
714 | } | | 716 | } |
715 | | | 717 | |
716 | if (reg & IRQ_FUF) { | | 718 | if (reg & IRQ_FUF) { |
717 | ev_fifo_underflow.ev_count ++; | | 719 | ev_fifo_underflow.ev_count ++; |
718 | /* TODO: Handle FUF */ | | 720 | /* TODO: Handle FUF */ |
719 | reg =~ IRQ_FUF; | | 721 | reg =~ IRQ_FUF; |
720 | } | | 722 | } |
721 | | | 723 | |
722 | if (reg & IRQ_ACB) { | | 724 | if (reg & IRQ_ACB) { |
723 | ev_ac_bias.ev_count ++; | | 725 | ev_ac_bias.ev_count ++; |
724 | /* TODO: Handle ACB */ | | 726 | /* TODO: Handle ACB */ |
725 | reg =~ IRQ_ACB; | | 727 | reg =~ IRQ_ACB; |
726 | } | | 728 | } |
727 | if (reg) | | 729 | if (reg) { |
728 | ev_others.ev_count ++; | | 730 | ev_others.ev_count ++; |
| | | 731 | tifb_intr_unh = reg; |
| | | 732 | } |
729 | return 0; | | 733 | return 0; |
730 | } | | 734 | } |
731 | | | 735 | |
732 | static int | | 736 | static int |
733 | tifb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, | | 737 | tifb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, |
734 | struct lwp *l) | | 738 | struct lwp *l) |
735 | { | | 739 | { |
736 | struct vcons_data *vd = v; | | 740 | struct vcons_data *vd = v; |
737 | struct tifb_softc *sc = vd->cookie; | | 741 | struct tifb_softc *sc = vd->cookie; |
738 | struct wsdisplay_fbinfo *wdf; | | 742 | struct wsdisplay_fbinfo *wdf; |
739 | struct vcons_screen *ms = vd->active; | | 743 | struct vcons_screen *ms = vd->active; |
740 | | | 744 | |
741 | switch (cmd) { | | 745 | switch (cmd) { |
| @@ -840,28 +844,34 @@ tifb_mmap(void *v, void *vs, off_t offse | | | @@ -840,28 +844,34 @@ tifb_mmap(void *v, void *vs, off_t offse |
840 | | | 844 | |
841 | static void | | 845 | static void |
842 | tifb_init_screen(void *cookie, struct vcons_screen *scr, | | 846 | tifb_init_screen(void *cookie, struct vcons_screen *scr, |
843 | int existing, long *defattr) | | 847 | int existing, long *defattr) |
844 | { | | 848 | { |
845 | struct tifb_softc *sc = cookie; | | 849 | struct tifb_softc *sc = cookie; |
846 | struct rasops_info *ri = &scr->scr_ri; | | 850 | struct rasops_info *ri = &scr->scr_ri; |
847 | | | 851 | |
848 | ri->ri_depth = sc->sc_panel->bpp; | | 852 | ri->ri_depth = sc->sc_panel->bpp; |
849 | ri->ri_width = sc->sc_panel->panel_width; | | 853 | ri->ri_width = sc->sc_panel->panel_width; |
850 | ri->ri_height = sc->sc_panel->panel_height; | | 854 | ri->ri_height = sc->sc_panel->panel_height; |
851 | ri->ri_stride = sc->sc_stride; | | 855 | ri->ri_stride = sc->sc_stride; |
852 | ri->ri_flg = RI_CENTER | RI_FULLCLEAR; | | 856 | ri->ri_flg = RI_CENTER | RI_FULLCLEAR; |
853 | | | 857 | |
854 | ri->ri_bits = (char *)sc->sc_fbaddr; | | 858 | if (sc->sc_shadowfb != NULL) { |
| | | 859 | ri->ri_bits = (char *)sc->sc_shadowfb; |
| | | 860 | ri->ri_hwbits = (char *)sc->sc_fbaddr; |
| | | 861 | } else { |
| | | 862 | ri->ri_bits = (char *)sc->sc_fbaddr; |
| | | 863 | ri->ri_hwbits = NULL; |
| | | 864 | } |
855 | | | 865 | |
856 | if (existing) { | | 866 | if (existing) { |
857 | ri->ri_flg |= RI_CLEAR; | | 867 | ri->ri_flg |= RI_CLEAR; |
858 | } | | 868 | } |
859 | | | 869 | |
860 | rasops_init(ri, sc->sc_panel->panel_height / 8, sc->sc_panel->panel_width / 8); | | 870 | rasops_init(ri, sc->sc_panel->panel_height / 8, sc->sc_panel->panel_width / 8); |
861 | ri->ri_caps = WSSCREEN_WSCOLORS; | | 871 | ri->ri_caps = WSSCREEN_WSCOLORS; |
862 | | | 872 | |
863 | rasops_reconfig(ri, sc->sc_panel->panel_height / ri->ri_font->fontheight, | | 873 | rasops_reconfig(ri, sc->sc_panel->panel_height / ri->ri_font->fontheight, |
864 | sc->sc_panel->panel_width / ri->ri_font->fontwidth); | | 874 | sc->sc_panel->panel_width / ri->ri_font->fontwidth); |
865 | | | 875 | |
866 | ri->ri_hw = scr; | | 876 | ri->ri_hw = scr; |
867 | } | | 877 | } |