| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: omapfb.c,v 1.14 2013/01/21 14:17:39 macallan Exp $ */ | | 1 | /* $NetBSD: omapfb.c,v 1.15 2013/01/21 16:08:30 macallan 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. |
| @@ -21,27 +21,27 @@ | | | @@ -21,27 +21,27 @@ |
21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | | 26 | */ |
27 | | | 27 | |
28 | /* | | 28 | /* |
29 | * A console driver for OMAP 3530's built-in video controller | | 29 | * A console driver for OMAP 3530's built-in video controller |
30 | * tested on beagleboard only so far | | 30 | * tested on beagleboard only so far |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <sys/cdefs.h> | | 33 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: omapfb.c,v 1.14 2013/01/21 14:17:39 macallan Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: omapfb.c,v 1.15 2013/01/21 16:08:30 macallan Exp $"); |
35 | | | 35 | |
36 | #include <sys/param.h> | | 36 | #include <sys/param.h> |
37 | #include <sys/systm.h> | | 37 | #include <sys/systm.h> |
38 | #include <sys/kernel.h> | | 38 | #include <sys/kernel.h> |
39 | #include <sys/device.h> | | 39 | #include <sys/device.h> |
40 | #include <sys/malloc.h> | | 40 | #include <sys/malloc.h> |
41 | #include <sys/lwp.h> | | 41 | #include <sys/lwp.h> |
42 | #include <sys/kauth.h> | | 42 | #include <sys/kauth.h> |
43 | | | 43 | |
44 | #include <uvm/uvm_extern.h> | | 44 | #include <uvm/uvm_extern.h> |
45 | | | 45 | |
46 | #include <dev/videomode/videomode.h> | | 46 | #include <dev/videomode/videomode.h> |
47 | | | 47 | |
| @@ -97,26 +97,28 @@ CFATTACH_DECL_NEW(omapfb, sizeof(struct | | | @@ -97,26 +97,28 @@ CFATTACH_DECL_NEW(omapfb, sizeof(struct |
97 | omapfb_match, omapfb_attach, NULL, NULL); | | 97 | omapfb_match, omapfb_attach, NULL, NULL); |
98 | | | 98 | |
99 | static int omapfb_ioctl(void *, void *, u_long, void *, int, | | 99 | static int omapfb_ioctl(void *, void *, u_long, void *, int, |
100 | struct lwp *); | | 100 | struct lwp *); |
101 | static paddr_t omapfb_mmap(void *, void *, off_t, int); | | 101 | static paddr_t omapfb_mmap(void *, void *, off_t, int); |
102 | static void omapfb_init_screen(void *, struct vcons_screen *, int, long *); | | 102 | static void omapfb_init_screen(void *, struct vcons_screen *, int, long *); |
103 | | | 103 | |
104 | static int omapfb_putcmap(struct omapfb_softc *, struct wsdisplay_cmap *); | | 104 | static int omapfb_putcmap(struct omapfb_softc *, struct wsdisplay_cmap *); |
105 | static int omapfb_getcmap(struct omapfb_softc *, struct wsdisplay_cmap *); | | 105 | static int omapfb_getcmap(struct omapfb_softc *, struct wsdisplay_cmap *); |
106 | static void omapfb_restore_palette(struct omapfb_softc *); | | 106 | static void omapfb_restore_palette(struct omapfb_softc *); |
107 | static void omapfb_putpalreg(struct omapfb_softc *, int, uint8_t, | | 107 | static void omapfb_putpalreg(struct omapfb_softc *, int, uint8_t, |
108 | uint8_t, uint8_t); | | 108 | uint8_t, uint8_t); |
109 | | | 109 | |
| | | 110 | static int omapfb_set_depth(struct omapfb_softc *, int); |
| | | 111 | |
110 | #if NOMAPDMA > 0 | | 112 | #if NOMAPDMA > 0 |
111 | static void omapfb_init(struct omapfb_softc *); | | 113 | static void omapfb_init(struct omapfb_softc *); |
112 | static void omapfb_wait_idle(struct omapfb_softc *); | | 114 | static void omapfb_wait_idle(struct omapfb_softc *); |
113 | static void omapfb_rectfill(struct omapfb_softc *, int, int, int, int, | | 115 | static void omapfb_rectfill(struct omapfb_softc *, int, int, int, int, |
114 | uint32_t); | | 116 | uint32_t); |
115 | static void omapfb_bitblt(struct omapfb_softc *, int, int, int, int, int, | | 117 | static void omapfb_bitblt(struct omapfb_softc *, int, int, int, int, int, |
116 | int, int); | | 118 | int, int); |
117 | | | 119 | |
118 | static void omapfb_cursor(void *, int, int, int); | | 120 | static void omapfb_cursor(void *, int, int, int); |
119 | static void omapfb_putchar(void *, int, int, u_int, long); | | 121 | static void omapfb_putchar(void *, int, int, u_int, long); |
120 | static void omapfb_copycols(void *, int, int, int, int); | | 122 | static void omapfb_copycols(void *, int, int, int, int); |
121 | static void omapfb_erasecols(void *, int, int, int, long); | | 123 | static void omapfb_erasecols(void *, int, int, int, long); |
122 | static void omapfb_copyrows(void *, int, int, int); | | 124 | static void omapfb_copyrows(void *, int, int, int); |
| @@ -443,52 +445,54 @@ omapfb_ioctl(void *v, void *vs, u_long c | | | @@ -443,52 +445,54 @@ omapfb_ioctl(void *v, void *vs, u_long c |
443 | struct wsdisplayio_bus_id *busid; | | 445 | struct wsdisplayio_bus_id *busid; |
444 | | | 446 | |
445 | busid = data; | | 447 | busid = data; |
446 | busid->bus_type = WSDISPLAYIO_BUS_SOC; | | 448 | busid->bus_type = WSDISPLAYIO_BUS_SOC; |
447 | return 0; | | 449 | return 0; |
448 | } | | 450 | } |
449 | | | 451 | |
450 | case WSDISPLAYIO_GINFO: | | 452 | case WSDISPLAYIO_GINFO: |
451 | if (ms == NULL) | | 453 | if (ms == NULL) |
452 | return ENODEV; | | 454 | return ENODEV; |
453 | wdf = (void *)data; | | 455 | wdf = (void *)data; |
454 | wdf->height = ms->scr_ri.ri_height; | | 456 | wdf->height = ms->scr_ri.ri_height; |
455 | wdf->width = ms->scr_ri.ri_width; | | 457 | wdf->width = ms->scr_ri.ri_width; |
456 | wdf->depth = ms->scr_ri.ri_depth; | | 458 | wdf->depth = 32; |
457 | wdf->cmsize = 256; | | 459 | wdf->cmsize = 256; |
458 | return 0; | | 460 | return 0; |
459 | | | 461 | |
460 | case WSDISPLAYIO_GETCMAP: | | 462 | case WSDISPLAYIO_GETCMAP: |
461 | return omapfb_getcmap(sc, | | 463 | return omapfb_getcmap(sc, |
462 | (struct wsdisplay_cmap *)data); | | 464 | (struct wsdisplay_cmap *)data); |
463 | | | 465 | |
464 | case WSDISPLAYIO_PUTCMAP: | | 466 | case WSDISPLAYIO_PUTCMAP: |
465 | return omapfb_putcmap(sc, | | 467 | return omapfb_putcmap(sc, |
466 | (struct wsdisplay_cmap *)data); | | 468 | (struct wsdisplay_cmap *)data); |
467 | | | 469 | |
468 | case WSDISPLAYIO_LINEBYTES: | | 470 | case WSDISPLAYIO_LINEBYTES: |
469 | *(u_int *)data = sc->sc_stride; | | 471 | *(u_int *)data = sc->sc_width * 4; |
470 | return 0; | | 472 | return 0; |
471 | | | 473 | |
472 | case WSDISPLAYIO_SMODE: | | 474 | case WSDISPLAYIO_SMODE: |
473 | { | | 475 | { |
474 | int new_mode = *(int*)data; | | 476 | int new_mode = *(int*)data; |
475 | | | 477 | |
476 | /* notify the bus backend */ | | | |
477 | if (new_mode != sc->sc_mode) { | | 478 | if (new_mode != sc->sc_mode) { |
478 | sc->sc_mode = new_mode; | | 479 | sc->sc_mode = new_mode; |
479 | if(new_mode == WSDISPLAYIO_MODE_EMUL) { | | 480 | if (new_mode == WSDISPLAYIO_MODE_EMUL) { |
| | | 481 | omapfb_set_depth(sc, 16); |
480 | vcons_redraw_screen(ms); | | 482 | vcons_redraw_screen(ms); |
481 | } | | 483 | } else { |
| | | 484 | omapfb_set_depth(sc, 32); |
| | | 485 | } |
482 | } | | 486 | } |
483 | } | | 487 | } |
484 | return 0; | | 488 | return 0; |
485 | } | | 489 | } |
486 | return EPASSTHROUGH; | | 490 | return EPASSTHROUGH; |
487 | } | | 491 | } |
488 | | | 492 | |
489 | static paddr_t | | 493 | static paddr_t |
490 | omapfb_mmap(void *v, void *vs, off_t offset, int prot) | | 494 | omapfb_mmap(void *v, void *vs, off_t offset, int prot) |
491 | { | | 495 | { |
492 | paddr_t pa = -1; | | 496 | paddr_t pa = -1; |
493 | struct vcons_data *vd = v; | | 497 | struct vcons_data *vd = v; |
494 | struct omapfb_softc *sc = vd->cookie; | | 498 | struct omapfb_softc *sc = vd->cookie; |
| @@ -620,26 +624,69 @@ static void | | | @@ -620,26 +624,69 @@ static void |
620 | omapfb_putpalreg(struct omapfb_softc *sc, int idx, uint8_t r, uint8_t g, | | 624 | omapfb_putpalreg(struct omapfb_softc *sc, int idx, uint8_t r, uint8_t g, |
621 | uint8_t b) | | 625 | uint8_t b) |
622 | { | | 626 | { |
623 | uint32_t reg; | | 627 | uint32_t reg; |
624 | | | 628 | |
625 | if ((idx < 0) || (idx > 255)) | | 629 | if ((idx < 0) || (idx > 255)) |
626 | return; | | 630 | return; |
627 | /* whack the DAC */ | | 631 | /* whack the DAC */ |
628 | reg = (r << 16) | (g << 8) | b; | | 632 | reg = (r << 16) | (g << 8) | b; |
629 | sc->sc_clut[idx] = reg; | | 633 | sc->sc_clut[idx] = reg; |
630 | | | 634 | |
631 | } | | 635 | } |
632 | | | 636 | |
| | | 637 | static int |
| | | 638 | omapfb_set_depth(struct omapfb_softc *sc, int d) |
| | | 639 | { |
| | | 640 | uint32_t reg; |
| | | 641 | |
| | | 642 | reg = OMAP_DISPC_ATTR_ENABLE | |
| | | 643 | OMAP_DISPC_ATTR_BURST_16x32 | |
| | | 644 | OMAP_DISPC_ATTR_REPLICATION; |
| | | 645 | switch (d) { |
| | | 646 | case 16: |
| | | 647 | reg |= OMAP_DISPC_ATTR_RGB16; |
| | | 648 | break; |
| | | 649 | case 32: |
| | | 650 | reg |= OMAP_DISPC_ATTR_RGB24; |
| | | 651 | break; |
| | | 652 | default: |
| | | 653 | aprint_error_dev(sc->sc_dev, "unsupported depth (%d)\n", d); |
| | | 654 | return EINVAL; |
| | | 655 | } |
| | | 656 | |
| | | 657 | bus_space_write_4(sc->sc_iot, sc->sc_regh, |
| | | 658 | OMAPFB_DISPC_GFX_ATTRIBUTES, reg); |
| | | 659 | |
| | | 660 | /* |
| | | 661 | * now tell the video controller that we're done mucking around and |
| | | 662 | * actually update its settings |
| | | 663 | */ |
| | | 664 | reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL); |
| | | 665 | bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL, |
| | | 666 | reg | OMAP_DISPC_CTRL_GO_LCD | OMAP_DISPC_CTRL_GO_DIGITAL); |
| | | 667 | |
| | | 668 | sc->sc_depth = d; |
| | | 669 | sc->sc_stride = sc->sc_width * (sc->sc_depth >> 3); |
| | | 670 | |
| | | 671 | /* clear the screen here */ |
| | | 672 | #if NOMAPDMA > 0 |
| | | 673 | omapfb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, 0); |
| | | 674 | #else |
| | | 675 | memset(sc->sc_fbaddr, 0, sc->sc_stride * sc->sc_height); |
| | | 676 | #endif |
| | | 677 | return 0; |
| | | 678 | } |
| | | 679 | |
633 | #if NOMAPDMA > 0 | | 680 | #if NOMAPDMA > 0 |
634 | static void | | 681 | static void |
635 | omapfb_init(struct omapfb_softc *sc) | | 682 | omapfb_init(struct omapfb_softc *sc) |
636 | { | | 683 | { |
637 | omapdma_write_ch_reg(0, OMAPDMAC_CLNK_CTRL, 0); | | 684 | omapdma_write_ch_reg(0, OMAPDMAC_CLNK_CTRL, 0); |
638 | omapdma_write_ch_reg(0, OMAPDMAC_CICRI, 0); | | 685 | omapdma_write_ch_reg(0, OMAPDMAC_CICRI, 0); |
639 | omapdma_write_ch_reg(0, OMAPDMAC_CSDPI, | | 686 | omapdma_write_ch_reg(0, OMAPDMAC_CSDPI, |
640 | CSDPI_SRC_BURST_64 | CSDPI_DST_BURST_64 | | | 687 | CSDPI_SRC_BURST_64 | CSDPI_DST_BURST_64 | |
641 | CSDPI_WRITE_POSTED | CSDPI_DATA_TYPE_16); | | 688 | CSDPI_WRITE_POSTED | CSDPI_DATA_TYPE_16); |
642 | } | | 689 | } |
643 | | | 690 | |
644 | static void | | 691 | static void |
645 | omapfb_wait_idle(struct omapfb_softc *sc) | | 692 | omapfb_wait_idle(struct omapfb_softc *sc) |