Module Name: src Committed By: jmcneill Date: Thu Oct 31 17:08:54 UTC 2019
Modified Files: src/sys/arch/arm/ti: files.ti src/sys/arch/evbarm/conf: GENERIC Added Files: src/sys/arch/arm/ti: omap3_dss.c omap3_dssreg.h Log Message: Add omapfb to FDT-ized TI port. To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 src/sys/arch/arm/ti/files.ti cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/ti/omap3_dss.c \ src/sys/arch/arm/ti/omap3_dssreg.h cvs rdiff -u -r1.63 -r1.64 src/sys/arch/evbarm/conf/GENERIC 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/ti/files.ti diff -u src/sys/arch/arm/ti/files.ti:1.17 src/sys/arch/arm/ti/files.ti:1.18 --- src/sys/arch/arm/ti/files.ti:1.17 Wed Oct 30 21:41:40 2019 +++ src/sys/arch/arm/ti/files.ti Thu Oct 31 17:08:54 2019 @@ -1,4 +1,4 @@ -# $NetBSD: files.ti,v 1.17 2019/10/30 21:41:40 jmcneill Exp $ +# $NetBSD: files.ti,v 1.18 2019/10/31 17:08:54 jmcneill Exp $ # file arch/arm/ti/ti_cpufreq.c soc_ti @@ -107,6 +107,11 @@ device tirng attach tirng at fdt with ti_rng file arch/arm/ti/ti_rng.c ti_rng +# Display adapter +device omapfb: rasops16, rasops8, wsemuldisplaydev, vcons, edid +attach omapfb at fdt with omap3_dss +file arch/arm/ti/omap3_dss.c omap3_dss + # SOC parameters defflag opt_soc.h SOC_TI defflag opt_soc.h SOC_AM33XX: SOC_TI Index: src/sys/arch/evbarm/conf/GENERIC diff -u src/sys/arch/evbarm/conf/GENERIC:1.63 src/sys/arch/evbarm/conf/GENERIC:1.64 --- src/sys/arch/evbarm/conf/GENERIC:1.63 Wed Oct 30 21:42:41 2019 +++ src/sys/arch/evbarm/conf/GENERIC Thu Oct 31 17:08:54 2019 @@ -1,5 +1,5 @@ # -# $NetBSD: GENERIC,v 1.63 2019/10/30 21:42:41 jmcneill Exp $ +# $NetBSD: GENERIC,v 1.64 2019/10/31 17:08:54 jmcneill Exp $ # # GENERIC ARM (aarch32) kernel # @@ -662,6 +662,7 @@ hdmicec* at hdmicecbus? #tegrafb* at tegrafbbus? genfb* at fdt? # Simple Framebuffer mesonfb* at fdt? # Amlogic Meson Framebuffer +omapfb* at fdt? # TI OMAP3 Framebuffer wsdisplay* at wsemuldisplaydev? sunxidebe* at fdt? pass 4 # Display Backend genfb* at sunxidebe? Added files: Index: src/sys/arch/arm/ti/omap3_dss.c diff -u /dev/null src/sys/arch/arm/ti/omap3_dss.c:1.1 --- /dev/null Thu Oct 31 17:08:54 2019 +++ src/sys/arch/arm/ti/omap3_dss.c Thu Oct 31 17:08:54 2019 @@ -0,0 +1,1260 @@ +/* $NetBSD: omap3_dss.c,v 1.1 2019/10/31 17:08:54 jmcneill Exp $ */ + +/* + * Copyright (c) 2010 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * A console driver for OMAP 3530's built-in video controller + * tested on beagleboard only so far + */ + +#include "opt_wsdisplay_compat.h" + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: omap3_dss.c,v 1.1 2019/10/31 17:08:54 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/malloc.h> +#include <sys/lwp.h> +#include <sys/kauth.h> +#include <sys/bus.h> + +#include <uvm/uvm_extern.h> + +#include <dev/videomode/videomode.h> +#include <dev/videomode/edidvar.h> + +#include <dev/fdt/fdtvar.h> + +#include <arm/ti/omap3_dssreg.h> + +#include <dev/wscons/wsdisplayvar.h> +#include <dev/wscons/wsconsio.h> +#include <dev/wsfont/wsfont.h> +#include <dev/rasops/rasops.h> +#include <dev/wscons/wsdisplay_vconsvar.h> + +struct omapfb_softc { + device_t sc_dev; + + bus_space_tag_t sc_iot; + bus_dma_tag_t sc_dmat; + bus_space_handle_t sc_regh; + bus_dmamap_t sc_dmamap; + bus_dma_segment_t sc_dmamem[1]; + size_t sc_vramsize; + + int sc_width, sc_height, sc_depth, sc_stride; + int sc_locked; + void *sc_fbaddr, *sc_vramaddr; + + int sc_cursor_offset; + uint32_t *sc_cursor_img; + int sc_cursor_x, sc_cursor_y; + int sc_hot_x, sc_hot_y; + uint8_t sc_cursor_bitmap[8 * 64]; + uint8_t sc_cursor_mask[8 * 64]; + uint32_t sc_cursor_cmap[4]; + + bus_addr_t sc_fbhwaddr; + uint32_t *sc_clut; + uint32_t sc_dispc_config; + int sc_video_is_on; + struct vcons_screen sc_console_screen; + struct wsscreen_descr sc_defaultscreen_descr; + const struct wsscreen_descr *sc_screens[1]; + struct wsscreen_list sc_screenlist; + struct vcons_data vd; + int sc_mode; + uint8_t sc_cmap_red[256], sc_cmap_green[256], sc_cmap_blue[256]; + void (*sc_putchar)(void *, int, int, u_int, long); + + uint8_t sc_edid_data[1024]; + size_t sc_edid_size; +}; + +static int omapfb_match(device_t, cfdata_t, void *); +static void omapfb_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(omap3_dss, sizeof(struct omapfb_softc), + omapfb_match, omapfb_attach, NULL, NULL); + +static int omapfb_ioctl(void *, void *, u_long, void *, int, + struct lwp *); +static paddr_t omapfb_mmap(void *, void *, off_t, int); +static void omapfb_init_screen(void *, struct vcons_screen *, int, long *); + +static int omapfb_putcmap(struct omapfb_softc *, struct wsdisplay_cmap *); +static int omapfb_getcmap(struct omapfb_softc *, struct wsdisplay_cmap *); +static void omapfb_restore_palette(struct omapfb_softc *); +static void omapfb_putpalreg(struct omapfb_softc *, int, uint8_t, + uint8_t, uint8_t); + +static int omapfb_set_depth(struct omapfb_softc *, int); +static void omapfb_set_video(struct omapfb_softc *, int); + +static void omapfb_move_cursor(struct omapfb_softc *, int, int); +static int omapfb_do_cursor(struct omapfb_softc *, + struct wsdisplay_cursor *); + +#if NOMAPDMA > 0 +static void omapfb_init(struct omapfb_softc *); +static void omapfb_wait_idle(struct omapfb_softc *); +static void omapfb_rectfill(struct omapfb_softc *, int, int, int, int, + uint32_t); +static void omapfb_bitblt(struct omapfb_softc *, int, int, int, int, int, + int, int); + +static void omapfb_cursor(void *, int, int, int); +static void omapfb_putchar(void *, int, int, u_int, long); +static void omapfb_copycols(void *, int, int, int, int); +static void omapfb_erasecols(void *, int, int, int, long); +static void omapfb_copyrows(void *, int, int, int); +static void omapfb_eraserows(void *, int, int, long); +#endif /* NOMAPDMA > 0 */ + +struct wsdisplay_accessops omapfb_accessops = { + omapfb_ioctl, + omapfb_mmap, + NULL, /* alloc_screen */ + NULL, /* free_screen */ + NULL, /* show_screen */ + NULL, /* load_font */ + NULL, /* pollc */ + NULL /* scroll */ +}; + +uint32_t venc_mode_ntsc[] = { + 0x00000000, 0x00000001, 0x00008040, 0x00000359, + 0x0000020c, 0x00000000, 0x043f2631, 0x00000000, + 0x00000102, 0x0000016c, 0x0000012f, 0x00000043, + 0x00000038, 0x00000007, 0x00000001, 0x00000038, + 0x21f07c1f, 0x00000000, 0x01310011, 0x0000f003, + 0x00000000, 0x069300f4, 0x0016020c, 0x00060107, + 0x008e0350, 0x000f0359, 0x01a00000, 0x020701a0, + 0x01ac0024, 0x020d01ac, 0x00000006, 0x03480078, + 0x02060024, 0x0001008a, 0x01ac0106, 0x01060006, + 0x00140001, 0x00010001, 0x00f90000, 0x0000000d, + 0x00000000}; + +extern const u_char rasops_cmap[768]; + +static const char * const compatible[] = { + "ti,omap3-dss", + NULL +}; + +static int omapfb_console_phandle = -1; + +static int +omapfb_match(device_t parent, cfdata_t match, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +omapfb_attach(device_t parent, device_t self, void *aux) +{ + struct omapfb_softc *sc = device_private(self); + struct fdt_attach_args *faa = aux; + const int phandle = faa->faa_phandle; + struct rasops_info *ri; + struct wsemuldisplaydev_attach_args aa; + prop_dictionary_t dict; + prop_data_t edid_data; + unsigned long defattr; +#ifdef WSDISPLAY_MULTICONS + bool is_console = true; +#else + bool is_console = phandle == omapfb_console_phandle; +#endif + uint32_t sz, reg; + int segs, i, j; + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + sc->sc_dev = self; + sc->sc_iot = faa->faa_bst; + sc->sc_dmat = faa->faa_dmat; + + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_regh) != 0) { + aprint_error(": couldn't map registers\n"); + return; + } + + aprint_naive("\n"); + aprint_normal(": OMAP onboard video\n"); + + sc->sc_video_is_on = 1; + + /* + * XXX + * different u-boot versions initialize the graphics controller in + * different ways, so we look for the display resolution in a few + * different places... + */ + sz = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_SIZE); + if (sz == 0) { + sz = bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_SIZE_LCD); + } + if (sz == 0) { + sz = bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_SIZE_DIG); + } + + /* ... and make sure it ends up where we need it */ + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_SIZE, sz); + + sc->sc_width = (sz & 0xfff) + 1; + sc->sc_height = ((sz & 0x0fff0000 ) >> 16) + 1; + sc->sc_depth = 16; + sc->sc_stride = sc->sc_width << 1; + + if (sc->sc_width == 1 || sc->sc_height == 1) { + aprint_error_dev(self, "bogus display size, not attaching\n"); + return; + } + + printf("%s: firmware set up %d x %d\n", device_xname(self), + sc->sc_width, sc->sc_height); +#if 0 + printf("DSS revision: %08x\n", + bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_REVISION)); +#endif + dict = device_properties(self); + edid_data = prop_dictionary_get(dict, "EDID"); + + if (edid_data != NULL) { + struct edid_info ei; + + sc->sc_edid_size = uimin(prop_data_size(edid_data), 1024); + memset(sc->sc_edid_data, 0, sizeof(sc->sc_edid_data)); + memcpy(sc->sc_edid_data, prop_data_data_nocopy(edid_data), + sc->sc_edid_size); + + edid_parse(sc->sc_edid_data, &ei); + edid_print(&ei); + } + + /* setup video DMA */ + sc->sc_vramsize = (12 << 20) + PAGE_SIZE; /* 12MB + CLUT */ + + if (bus_dmamem_alloc(sc->sc_dmat, sc->sc_vramsize, 0, 0, + sc->sc_dmamem, 1, &segs, BUS_DMA_NOWAIT) != 0) { + panic("boo!\n"); + aprint_error_dev(sc->sc_dev, + "failed to allocate video memory\n"); + return; + } + + if (bus_dmamem_map(sc->sc_dmat, sc->sc_dmamem, 1, sc->sc_vramsize, + &sc->sc_vramaddr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT) != 0) { + aprint_error_dev(sc->sc_dev, "failed to map video RAM\n"); + return; + } + sc->sc_fbaddr = (uint8_t *)sc->sc_vramaddr + PAGE_SIZE; + sc->sc_clut = sc->sc_vramaddr; + + if (bus_dmamap_create(sc->sc_dmat, sc->sc_vramsize, 1, sc->sc_vramsize, + 0, BUS_DMA_NOWAIT, &sc->sc_dmamap) != 0) { + aprint_error_dev(sc->sc_dev, "failed to create DMA map\n"); + return; + } + + if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_vramaddr, + sc->sc_vramsize, NULL, BUS_DMA_NOWAIT) != 0) { + aprint_error_dev(sc->sc_dev, "failed to load DMA map\n"); + return; + } + + if (sc->sc_depth == 8) { + j = 0; + for (i = 0; i < 256; i++) { + sc->sc_cmap_red[i] = rasops_cmap[j]; + sc->sc_cmap_green[i] = rasops_cmap[j + 1]; + sc->sc_cmap_blue[i] = rasops_cmap[j + 2]; + j += 3; + } + } else { + for (i = 0; i < 256; i++) { + sc->sc_cmap_red[i] = i; + sc->sc_cmap_green[i] = i; + sc->sc_cmap_blue[i] = i; + } + } + omapfb_restore_palette(sc); + + /* now that we have video memory, stick it to the video controller */ + + reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_SYSCONFIG); + reg &= ~(OMAP_DISPC_SYSC_STANDBY_MASK | OMAP_DISPC_SYSC_IDLE_MASK); + reg |= OMAP_DISPC_SYSC_SMART_STANDBY | OMAP_DISPC_SYSC_SMART_IDLE | + OMAP_DISPC_SYSC_WAKEUP_ENABLE | OMAP_SYSCONF_AUTOIDLE; + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_SYSCONFIG, reg); + + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_SYSCONFIG, + OMAP_SYSCONF_AUTOIDLE); + + reg = OMAP_DISPC_CFG_TV_ALPHA_EN | OMAP_DISPC_CFG_LCD_ALPHA_EN; + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONFIG, reg); + sc->sc_dispc_config = reg; + + /* we use overlay 1 for the console and X */ + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GLOBAL_ALPHA, + 0x00ff00ff); + sc->sc_fbhwaddr = sc->sc_dmamem->ds_addr + PAGE_SIZE; + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_VID1_BASE_0, + sc->sc_fbhwaddr); + bus_space_write_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_VID1_POSITION, 0); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_VID1_SIZE, + ((sc->sc_height - 1) << 16) | (sc->sc_width - 1)); + bus_space_write_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_VID1_PICTURE_SIZE, + ((sc->sc_height - 1) << 16) | (sc->sc_width - 1)); + bus_space_write_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_VID1_ROW_INC, 1); + bus_space_write_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_VID1_PIXEL_INC, 1); + bus_space_write_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_VID1_PRELOAD, 0x60); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_VID1_ATTRIBUTES, + OMAP_VID_ATTR_ENABLE | + OMAP_VID_ATTR_BURST_16x32 | + OMAP_VID_ATTR_RGB16 | + OMAP_VID_ATTR_REPLICATION); + + /* turn off overlay 2 */ + bus_space_write_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_VID2_ATTRIBUTES, 0); + + /* initialize the gfx layer for use as hardware cursor */ + sc->sc_cursor_cmap[0] = 0; + sc->sc_cursor_offset = (12 << 20) - (64 * 64 * 4); + sc->sc_cursor_img = + (uint32_t *)((uint8_t *)sc->sc_fbaddr + sc->sc_cursor_offset); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_BASE_0, + sc->sc_fbhwaddr + sc->sc_cursor_offset); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_TABLE_BASE, + sc->sc_dmamem->ds_addr); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_SIZE, + 0x003f003f); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_POSITION, + 0x00100010); + bus_space_write_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_GFX_PRELOAD, 0x60); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_ATTRIBUTES, + /*OMAP_DISPC_ATTR_ENABLE |*/ + OMAP_DISPC_ATTR_BURST_16x32 | + OMAP_DISPC_ATTR_ARGB32 | + OMAP_DISPC_ATTR_REPLICATION); + +#if 0 + printf("dss_control: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DSS_CONTROL)); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DSS_CONTROL, + /*OMAP_DSSCTRL_DISPC_CLK_SWITCH |*/ + OMAP_DSSCTRL_CLOCK_MODE | + OMAP_DSSCTRL_VENC_CLOCK_4X | + OMAP_DSSCTRL_DAC_DEMEN); +#endif + +#if 0 + /* VENC to NTSC mode */ + int adr = OMAPFB_VENC_F_CONTROL; + for (i = 0; i < __arraycount(venc_mode_ntsc); i++) { + bus_space_write_4(sc->sc_iot, sc->sc_regh, adr, + venc_mode_ntsc[i]); + adr += 4; + } + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_VENC_F_CONTROL, + venc_mode_ntsc[0]); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_VENC_SYNC_CTRL, + venc_mode_ntsc[2]); + + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_DEFAULT_COLOR_1, + 0x00ff0000); +#endif + + /* now we make sure the video output is actually running */ + reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL, + reg | OMAP_DISPC_CTRL_GO_LCD | OMAP_DISPC_CTRL_GO_DIGITAL); + +#ifdef OMAPFB_DEBUG + printf("attr: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_GFX_ATTRIBUTES)); + printf("preload: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_GFX_PRELOAD)); + printf("config: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_CONFIG)); + printf("control: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_CONTROL)); + printf("dss_control: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DSS_CONTROL)); + printf("threshold: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_GFX_FIFO_THRESH)); + printf("GFX size: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_GFX_SIZE)); + printf("row inc: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_GFX_ROW_INC)); + printf("pixel inc: %08x\n", bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_GFX_PIXEL_INC)); +#endif + + sc->sc_defaultscreen_descr = (struct wsscreen_descr){ + "default", + 0, 0, + NULL, + 8, 16, + WSSCREEN_WSCOLORS | WSSCREEN_HILIT, + NULL + }; + sc->sc_screens[0] = &sc->sc_defaultscreen_descr; + sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens}; + sc->sc_mode = WSDISPLAYIO_MODE_EMUL; + sc->sc_locked = 0; + + vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, + &omapfb_accessops); + sc->vd.init_screen = omapfb_init_screen; + + /* init engine here */ +#if NOMAPDMA > 0 + omapfb_init(sc); +#endif + + ri = &sc->sc_console_screen.scr_ri; + vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, &defattr); + sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; +#if NOMAPDMA > 0 + omapfb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, + ri->ri_devcmap[(defattr >> 16) & 0xff]); +#endif + sc->sc_defaultscreen_descr.textops = &ri->ri_ops; + sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; + sc->sc_defaultscreen_descr.nrows = ri->ri_rows; + sc->sc_defaultscreen_descr.ncols = ri->ri_cols; + + if (is_console) + wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, + defattr); + + vcons_replay_msgbuf(&sc->sc_console_screen); + + aa.console = is_console; + aa.scrdata = &sc->sc_screenlist; + aa.accessops = &omapfb_accessops; + aa.accesscookie = &sc->vd; + + config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); +#ifdef OMAPFB_DEBUG +#if NOMAPDMA > 0 + omapfb_rectfill(sc, 100, 100, 100, 100, 0xe000); + omapfb_rectfill(sc, 100, 200, 100, 100, 0x01f8); + omapfb_rectfill(sc, 200, 100, 100, 100, 0x01f8); + omapfb_rectfill(sc, 200, 200, 100, 100, 0xe000); + omapfb_bitblt(sc, 100, 100, 400, 100, 200, 200, 0); + /* let's see if we can draw something */ + printf("OMAPDMAC_CDAC: %08x\n", omapdma_read_ch_reg(0, OMAPDMAC_CDAC)); + printf("OMAPDMAC_CSR: %08x\n", omapdma_read_ch_reg(0, OMAPDMAC_CSR)); + printf("OMAPDMAC_CCR: %08x\n", omapdma_read_ch_reg(0, OMAPDMAC_CCR)); +#endif +#endif +} + +static int +omapfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, + struct lwp *l) +{ + struct vcons_data *vd = v; + struct omapfb_softc *sc = vd->cookie; + struct wsdisplay_fbinfo *wdf; + struct vcons_screen *ms = vd->active; + + switch (cmd) { + + case WSDISPLAYIO_GTYPE: + *(u_int *)data = WSDISPLAY_TYPE_OMAP3; + return 0; + + case WSDISPLAYIO_GET_BUSID: + { + struct wsdisplayio_bus_id *busid; + + busid = data; + busid->bus_type = WSDISPLAYIO_BUS_SOC; + return 0; + } + + case WSDISPLAYIO_GINFO: + if (ms == NULL) + return ENODEV; + wdf = (void *)data; + wdf->height = ms->scr_ri.ri_height; + wdf->width = ms->scr_ri.ri_width; + wdf->depth = 32; + wdf->cmsize = 256; + return 0; + + case WSDISPLAYIO_GETCMAP: + return omapfb_getcmap(sc, + (struct wsdisplay_cmap *)data); + + case WSDISPLAYIO_PUTCMAP: + return omapfb_putcmap(sc, + (struct wsdisplay_cmap *)data); + + case WSDISPLAYIO_LINEBYTES: + *(u_int *)data = sc->sc_width * 4; + return 0; + + case WSDISPLAYIO_SMODE: + { + int new_mode = *(int*)data; + + if (new_mode != sc->sc_mode) { + sc->sc_mode = new_mode; + if (new_mode == WSDISPLAYIO_MODE_EMUL) { + omapfb_set_depth(sc, 16); + vcons_redraw_screen(ms); + } else { + omapfb_set_depth(sc, 32); + } + } + } + return 0; + + case WSDISPLAYIO_GET_FBINFO: + { + struct wsdisplayio_fbinfo *fbi = data; + + fbi->fbi_width = sc->sc_width; + fbi->fbi_height = sc->sc_height; + fbi->fbi_stride = sc->sc_width << 2; + fbi->fbi_bitsperpixel = 32; + fbi->fbi_pixeltype = WSFB_RGB; + fbi->fbi_subtype.fbi_rgbmasks.red_offset = 16; + fbi->fbi_subtype.fbi_rgbmasks.red_size = 8; + fbi->fbi_subtype.fbi_rgbmasks.green_offset = 8; + fbi->fbi_subtype.fbi_rgbmasks.green_size = 8; + fbi->fbi_subtype.fbi_rgbmasks.blue_offset = 0; + fbi->fbi_subtype.fbi_rgbmasks.blue_size = 8; + fbi->fbi_subtype.fbi_rgbmasks.alpha_offset = 0; + fbi->fbi_subtype.fbi_rgbmasks.alpha_size = 0; + fbi->fbi_flags = 0; + fbi->fbi_fbsize = sc->sc_vramsize; + fbi->fbi_fboffset = 0; + fbi->fbi_flags = WSFB_VRAM_IS_RAM; + + } + return 0; + + case WSDISPLAYIO_GVIDEO: + { + int *on = data; + *on = sc->sc_video_is_on; + } + return 0; + + case WSDISPLAYIO_SVIDEO: + { + int *on = data; + omapfb_set_video(sc, *on); + } + return 0; + + case WSDISPLAYIO_GCURPOS: + { + struct wsdisplay_curpos *cp = (void *)data; + + cp->x = sc->sc_cursor_x; + cp->y = sc->sc_cursor_y; + } + return 0; + case WSDISPLAYIO_SCURPOS: + { + struct wsdisplay_curpos *cp = (void *)data; + + omapfb_move_cursor(sc, cp->x, cp->y); + } + return 0; + case WSDISPLAYIO_GCURMAX: + { + struct wsdisplay_curpos *cp = (void *)data; + + cp->x = 64; + cp->y = 64; + } + return 0; + case WSDISPLAYIO_SCURSOR: + { + struct wsdisplay_cursor *cursor = (void *)data; + + return omapfb_do_cursor(sc, cursor); + } + } + return EPASSTHROUGH; +} + +static paddr_t +omapfb_mmap(void *v, void *vs, off_t offset, int prot) +{ + paddr_t pa = -1; + struct vcons_data *vd = v; + struct omapfb_softc *sc = vd->cookie; + + /* 'regular' framebuffer mmap()ing */ + if (offset < sc->sc_vramsize) { + pa = bus_dmamem_mmap(sc->sc_dmat, sc->sc_dmamem, 1, + offset + PAGE_SIZE, prot, BUS_DMA_PREFETCHABLE); + return pa; + } + return pa; +} + +static void +omapfb_init_screen(void *cookie, struct vcons_screen *scr, + int existing, long *defattr) +{ + struct omapfb_softc *sc = cookie; + struct rasops_info *ri = &scr->scr_ri; + + ri->ri_depth = sc->sc_depth; + ri->ri_width = sc->sc_width; + ri->ri_height = sc->sc_height; + ri->ri_stride = sc->sc_stride; + ri->ri_flg = RI_CENTER | RI_FULLCLEAR; + + ri->ri_bits = (char *)sc->sc_fbaddr; + +#if NOMAPDMA < 1 + scr->scr_flags |= VCONS_DONT_READ; +#endif + + if (existing) { + ri->ri_flg |= RI_CLEAR; + } + + rasops_init(ri, sc->sc_height / 8, sc->sc_width / 8); + ri->ri_caps = WSSCREEN_WSCOLORS; + + rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, + sc->sc_width / ri->ri_font->fontwidth); + + ri->ri_hw = scr; + +#if NOMAPDMA > 0 + ri->ri_ops.copyrows = omapfb_copyrows; + ri->ri_ops.copycols = omapfb_copycols; + ri->ri_ops.eraserows = omapfb_eraserows; + ri->ri_ops.erasecols = omapfb_erasecols; + ri->ri_ops.cursor = omapfb_cursor; + sc->sc_putchar = ri->ri_ops.putchar; + ri->ri_ops.putchar = omapfb_putchar; +#endif +} + +static int +omapfb_putcmap(struct omapfb_softc *sc, struct wsdisplay_cmap *cm) +{ + u_char *r, *g, *b; + u_int index = cm->index; + u_int count = cm->count; + int i, error; + u_char rbuf[256], gbuf[256], bbuf[256]; + + if (cm->index >= 256 || cm->count > 256 || + (cm->index + cm->count) > 256) + return EINVAL; + error = copyin(cm->red, &rbuf[index], count); + if (error) + return error; + error = copyin(cm->green, &gbuf[index], count); + if (error) + return error; + error = copyin(cm->blue, &bbuf[index], count); + if (error) + return error; + + memcpy(&sc->sc_cmap_red[index], &rbuf[index], count); + memcpy(&sc->sc_cmap_green[index], &gbuf[index], count); + memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count); + + r = &sc->sc_cmap_red[index]; + g = &sc->sc_cmap_green[index]; + b = &sc->sc_cmap_blue[index]; + + for (i = 0; i < count; i++) { + omapfb_putpalreg(sc, index, *r, *g, *b); + index++; + r++, g++, b++; + } + return 0; +} + +static int +omapfb_getcmap(struct omapfb_softc *sc, struct wsdisplay_cmap *cm) +{ + u_int index = cm->index; + u_int count = cm->count; + int error; + + if (index >= 255 || count > 256 || index + count > 256) + return EINVAL; + + error = copyout(&sc->sc_cmap_red[index], cm->red, count); + if (error) + return error; + error = copyout(&sc->sc_cmap_green[index], cm->green, count); + if (error) + return error; + error = copyout(&sc->sc_cmap_blue[index], cm->blue, count); + if (error) + return error; + + return 0; +} + +static void +omapfb_restore_palette(struct omapfb_softc *sc) +{ + int i; + + for (i = 0; i < 256; i++) { + omapfb_putpalreg(sc, i, sc->sc_cmap_red[i], + sc->sc_cmap_green[i], sc->sc_cmap_blue[i]); + } +} + +static void +omapfb_putpalreg(struct omapfb_softc *sc, int idx, uint8_t r, uint8_t g, + uint8_t b) +{ + uint32_t reg; + + if ((idx < 0) || (idx > 255)) + return; + /* whack the DAC */ + reg = (r << 16) | (g << 8) | b; + sc->sc_clut[idx] = reg; +} + +static int +omapfb_set_depth(struct omapfb_softc *sc, int d) +{ + uint32_t reg; + + reg = OMAP_VID_ATTR_ENABLE | + OMAP_VID_ATTR_BURST_16x32 | + OMAP_VID_ATTR_REPLICATION; + switch (d) { + case 16: + reg |= OMAP_VID_ATTR_RGB16; + break; + case 32: + reg |= OMAP_VID_ATTR_RGB24; + break; + default: + aprint_error_dev(sc->sc_dev, + "unsupported depth (%d)\n", d); + return EINVAL; + } + + bus_space_write_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_VID1_ATTRIBUTES, reg); + + /* + * now tell the video controller that we're done mucking around and + * actually update its settings + */ + reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL, + reg | OMAP_DISPC_CTRL_GO_LCD | OMAP_DISPC_CTRL_GO_DIGITAL); + + sc->sc_depth = d; + sc->sc_stride = sc->sc_width * (sc->sc_depth >> 3); + + /* clear the screen here */ +#if NOMAPDMA > 0 + omapfb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, 0); +#else + memset(sc->sc_fbaddr, 0, sc->sc_stride * sc->sc_height); +#endif + return 0; +} + +static void +omapfb_set_video(struct omapfb_softc *sc, int on) +{ + uint32_t reg; + + if (on == sc->sc_video_is_on) + return; + if (on) { + bus_space_write_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_CONFIG, sc->sc_dispc_config); + on = 1; + } else { + bus_space_write_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_CONFIG, sc->sc_dispc_config | + OMAP_DISPC_CFG_VSYNC_GATED | OMAP_DISPC_CFG_HSYNC_GATED | + OMAP_DISPC_CFG_PIXELCLK_GATED | + OMAP_DISPC_CFG_PIXELDATA_GATED); + } + + /* + * now tell the video controller that we're done mucking around and + * actually update its settings + */ + reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL, + reg | OMAP_DISPC_CTRL_GO_LCD | OMAP_DISPC_CTRL_GO_DIGITAL); + + aprint_debug_dev(sc->sc_dev, "%s %08x\n", __func__, + bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONFIG)); + sc->sc_video_is_on = on; +} + +#if NOMAPDMA > 0 +static void +omapfb_init(struct omapfb_softc *sc) +{ + omapdma_write_ch_reg(0, OMAPDMAC_CLNK_CTRL, 0); + omapdma_write_ch_reg(0, OMAPDMAC_CICRI, 0); + omapdma_write_ch_reg(0, OMAPDMAC_CSDPI, + CSDPI_SRC_BURST_64 | CSDPI_DST_BURST_64 | + CSDPI_WRITE_POSTED | CSDPI_DATA_TYPE_16); +} + +static void +omapfb_wait_idle(struct omapfb_softc *sc) +{ + while ((omapdma_read_ch_reg(0, OMAPDMAC_CCR) & CCR_WR_ACTIVE) != 0); +} + +static void +omapfb_rectfill(struct omapfb_softc *sc, int x, int y, int wi, int he, + uint32_t colour) +{ + int bpp = sc->sc_depth >> 3; /* bytes per pixel */ + int width_in_bytes = wi * bpp; + uint32_t daddr; + + daddr = sc->sc_fbhwaddr + sc->sc_stride * y + x * bpp; + omapfb_wait_idle(sc); + + /* + * stupid hardware + * in 32bit mode the DMA controller always writes 0 into the upper + * byte, so we can use this mode only if we actually want that + */ + if (((colour & 0xff00) == 0) && + (((daddr | width_in_bytes) & 3) == 0)) { + /* + * everything is properly aligned so we can copy stuff in + * 32bit chunks instead of pixel by pixel + */ + wi = wi >> 1; + + /* just in case */ + colour |= colour << 16; + + omapdma_write_ch_reg(0, OMAPDMAC_CSDPI, + CSDPI_SRC_BURST_64 | CSDPI_DST_BURST_64 | + CSDPI_DST_PACKED | CSDPI_WRITE_POSTED_EXCEPT_LAST | + CSDPI_DATA_TYPE_32); + } else { + omapdma_write_ch_reg(0, OMAPDMAC_CSDPI, + CSDPI_SRC_BURST_64 | CSDPI_DST_BURST_64 | + CSDPI_DST_PACKED | CSDPI_WRITE_POSTED_EXCEPT_LAST | + CSDPI_DATA_TYPE_16); + } + + omapdma_write_ch_reg(0, OMAPDMAC_CEN, wi); + omapdma_write_ch_reg(0, OMAPDMAC_CFN, he); + omapdma_write_ch_reg(0, OMAPDMAC_CDSA, daddr); + omapdma_write_ch_reg(0, OMAPDMAC_CCR, + CCR_CONST_FILL_ENABLE | CCR_DST_AMODE_DOUBLE_INDEX | + CCR_SRC_AMODE_CONST_ADDR); + omapdma_write_ch_reg(0, OMAPDMAC_CDEI, 1); + omapdma_write_ch_reg(0, OMAPDMAC_CDFI, + (sc->sc_stride - width_in_bytes) + 1); + omapdma_write_ch_reg(0, OMAPDMAC_COLOR, colour); + omapdma_write_ch_reg(0, OMAPDMAC_CCR, + CCR_CONST_FILL_ENABLE | CCR_DST_AMODE_DOUBLE_INDEX | + CCR_SRC_AMODE_CONST_ADDR | CCR_ENABLE); +} + +static void +omapfb_bitblt(struct omapfb_softc *sc, int xs, int ys, int xd, int yd, + int wi, int he, int rop) +{ + int bpp = sc->sc_depth >> 3; /* bytes per pixel */ + int width_in_bytes = wi * bpp; + + int hstep, vstep; + uint32_t saddr, daddr; + + saddr = sc->sc_fbhwaddr + sc->sc_stride * ys + xs * bpp; + daddr = sc->sc_fbhwaddr + sc->sc_stride * yd + xd * bpp; + + if (ys < yd) { + /* need to go vertically backwards */ + vstep = 1 - (sc->sc_stride + width_in_bytes); + saddr += sc->sc_stride * (he - 1); + daddr += sc->sc_stride * (he - 1); + } else + vstep = (sc->sc_stride - width_in_bytes) + 1; + if ((xs < xd) && (ys == yd)) { + /* + * need to go horizontally backwards, only needed if source + * and destination pixels are on the same line + */ + hstep = 1 - (sc->sc_depth >> 2); + vstep = sc->sc_stride + bpp * (wi - 1) + 1; + saddr += bpp * (wi - 1); + daddr += bpp * (wi - 1); + } else + hstep = 1; + + omapfb_wait_idle(sc); + if (((saddr | daddr | width_in_bytes) & 3) == 0) { + /* + * everything is properly aligned so we can copy stuff in + * 32bit chunks instead of pixel by pixel + */ + wi = wi >> 1; + omapdma_write_ch_reg(0, OMAPDMAC_CSDPI, + CSDPI_SRC_BURST_64 | CSDPI_DST_BURST_64 | + CSDPI_DST_PACKED | CSDPI_WRITE_POSTED_EXCEPT_LAST | + CSDPI_DATA_TYPE_32); + } else { + omapdma_write_ch_reg(0, OMAPDMAC_CSDPI, + CSDPI_SRC_BURST_64 | CSDPI_DST_BURST_64 | + CSDPI_DST_PACKED | CSDPI_WRITE_POSTED_EXCEPT_LAST | + CSDPI_DATA_TYPE_16); + } + + omapdma_write_ch_reg(0, OMAPDMAC_CEN, wi); + omapdma_write_ch_reg(0, OMAPDMAC_CFN, he); + omapdma_write_ch_reg(0, OMAPDMAC_CSSA, saddr); + omapdma_write_ch_reg(0, OMAPDMAC_CDSA, daddr); + omapdma_write_ch_reg(0, OMAPDMAC_CCR, + CCR_DST_AMODE_DOUBLE_INDEX | + CCR_SRC_AMODE_DOUBLE_INDEX); + omapdma_write_ch_reg(0, OMAPDMAC_CSEI, hstep); + omapdma_write_ch_reg(0, OMAPDMAC_CSFI, vstep); + omapdma_write_ch_reg(0, OMAPDMAC_CDEI, hstep); + omapdma_write_ch_reg(0, OMAPDMAC_CDFI, vstep); + omapdma_write_ch_reg(0, OMAPDMAC_CCR, + CCR_DST_AMODE_DOUBLE_INDEX | + CCR_SRC_AMODE_DOUBLE_INDEX | CCR_ENABLE); +} + +static void +omapfb_cursor(void *cookie, int on, int row, int col) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct omapfb_softc *sc = scr->scr_cookie; + int pos; + + pos = col + row * ri->ri_cols; +#ifdef WSDISPLAY_SCROLLSUPPORT + pos += scr->scr_offset_to_zero; +#endif + if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { + if (ri->ri_flg & RI_CURSOR) { + omapfb_putchar(cookie, row, col, scr->scr_chars[pos], + scr->scr_attrs[pos]); + ri->ri_flg &= ~RI_CURSOR; + } + ri->ri_crow = row; + ri->ri_ccol = col; + if (on) { + omapfb_putchar(cookie, row, col, scr->scr_chars[pos], + scr->scr_attrs[pos] ^ 0x0f0f0000); + ri->ri_flg |= RI_CURSOR; + } + } else { + scr->scr_ri.ri_crow = row; + scr->scr_ri.ri_ccol = col; + scr->scr_ri.ri_flg &= ~RI_CURSOR; + } +} + +static void +omapfb_putchar(void *cookie, int row, int col, u_int c, long attr) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct omapfb_softc *sc = scr->scr_cookie; + + if (c == 0x20) { + uint32_t fg, bg, ul; + rasops_unpack_attr(attr, &fg, &bg, &ul); + omapfb_rectfill(sc, + ri->ri_xorigin + ri->ri_font->fontwidth * col, + ri->ri_yorigin + ri->ri_font->fontheight * row, + ri->ri_font->fontwidth, + ri->ri_font->fontheight, + ri->ri_devcmap[bg]); + return; + } + omapfb_wait_idle(sc); + sc->sc_putchar(cookie, row, col, c, attr); +} + +static void +omapfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct omapfb_softc *sc = scr->scr_cookie; + int32_t xs, xd, y, width, height; + + if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { + xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; + xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; + y = ri->ri_yorigin + ri->ri_font->fontheight * row; + width = ri->ri_font->fontwidth * ncols; + height = ri->ri_font->fontheight; + omapfb_bitblt(sc, xs, y, xd, y, width, height, 12); + } +} + +static void +omapfb_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct omapfb_softc *sc = scr->scr_cookie; + int32_t x, y, width, height, fg, bg, ul; + + if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { + x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; + y = ri->ri_yorigin + ri->ri_font->fontheight * row; + width = ri->ri_font->fontwidth * ncols; + height = ri->ri_font->fontheight; + rasops_unpack_attr(fillattr, &fg, &bg, &ul); + + omapfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); + } +} + +static void +omapfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct omapfb_softc *sc = scr->scr_cookie; + int32_t x, ys, yd, width, height; + + if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { + x = ri->ri_xorigin; + ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; + yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; + width = ri->ri_emuwidth; + height = ri->ri_font->fontheight * nrows; + omapfb_bitblt(sc, x, ys, x, yd, width, height, 12); + } +} + +static void +omapfb_eraserows(void *cookie, int row, int nrows, long fillattr) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct omapfb_softc *sc = scr->scr_cookie; + int32_t x, y, width, height, fg, bg, ul; + + if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { + x = ri->ri_xorigin; + y = ri->ri_yorigin + ri->ri_font->fontheight * row; + width = ri->ri_emuwidth; + height = ri->ri_font->fontheight * nrows; + rasops_unpack_attr(fillattr, &fg, &bg, &ul); + + omapfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); + } +} +#endif /* NOMAPDMA > 0 */ + +static void +omapfb_move_cursor(struct omapfb_softc *sc, int x, int y) +{ + uint32_t pos, reg, addr; + int xx, yy, wi = 64, he = 64; + + /* + * we need to special case anything and everything where the cursor + * may be partially off screen + */ + + addr = sc->sc_fbhwaddr + sc->sc_cursor_offset; + xx = x - sc->sc_hot_x; + yy = y - sc->sc_hot_y; + + /* + * if we're off to the top or left we need to shif the start address + * and shrink the gfx layer size + */ + if (xx < 0) { + wi += xx; + addr -= xx * 4; + xx = 0; + } + if (yy < 0) { + he += yy; + addr -= yy * 64 * 4; + yy = 0; + } + if (xx > (sc->sc_width - 64)) { + wi -= (xx + 64 - sc->sc_width); + } + if (yy > (sc->sc_height - 64)) { + he -= (yy + 64 - sc->sc_height); + } + pos = (yy << 16) | xx; + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_BASE_0, + addr); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_POSITION, + pos); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_SIZE, + ((he - 1) << 16) | (wi - 1)); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_GFX_ROW_INC, + (64 - wi) * 4 + 1); + /* + * now tell the video controller that we're done mucking around and + * actually update its settings + */ + reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL, + reg | OMAP_DISPC_CTRL_GO_LCD | OMAP_DISPC_CTRL_GO_DIGITAL); +} + +static int +omapfb_do_cursor(struct omapfb_softc * sc, + struct wsdisplay_cursor *cur) +{ + int whack = 0; + int shape = 0; + + if (cur->which & WSDISPLAY_CURSOR_DOCUR) { + uint32_t attr = OMAP_DISPC_ATTR_BURST_16x32 | + OMAP_DISPC_ATTR_ARGB32 | + OMAP_DISPC_ATTR_REPLICATION; + + if (cur->enable) attr |= OMAP_DISPC_ATTR_ENABLE; + bus_space_write_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_GFX_ATTRIBUTES, attr); + whack = 1; + } + if (cur->which & WSDISPLAY_CURSOR_DOHOT) { + + sc->sc_hot_x = cur->hot.x; + sc->sc_hot_y = cur->hot.y; + cur->which |= WSDISPLAY_CURSOR_DOPOS; + } + if (cur->which & WSDISPLAY_CURSOR_DOPOS) { + + omapfb_move_cursor(sc, cur->pos.x, cur->pos.y); + } + if (cur->which & WSDISPLAY_CURSOR_DOCMAP) { + int i; + uint32_t val; + + for (i = 0; i < uimin(cur->cmap.count, 3); i++) { + val = (cur->cmap.red[i] << 16 ) | + (cur->cmap.green[i] << 8) | + (cur->cmap.blue[i] ) | + 0xff000000; + sc->sc_cursor_cmap[i + cur->cmap.index + 2] = val; + } + shape = 1; + } + if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) { + + copyin(cur->mask, sc->sc_cursor_mask, 64 * 8); + copyin(cur->image, sc->sc_cursor_bitmap, 64 * 8); + shape = 1; + } + if (shape) { + int i, j, idx; + uint8_t mask; + + for (i = 0; i < 64 * 8; i++) { + mask = 0x01; + for (j = 0; j < 8; j++) { + idx = ((sc->sc_cursor_mask[i] & mask) ? 2 : 0) | + ((sc->sc_cursor_bitmap[i] & mask) ? 1 : 0); + sc->sc_cursor_img[i * 8 + j] = + sc->sc_cursor_cmap[idx]; + mask = mask << 1; + } + } + } + if (whack) { + uint32_t reg; + + reg = bus_space_read_4(sc->sc_iot, sc->sc_regh, + OMAPFB_DISPC_CONTROL); + bus_space_write_4(sc->sc_iot, sc->sc_regh, OMAPFB_DISPC_CONTROL, + reg | OMAP_DISPC_CTRL_GO_LCD | OMAP_DISPC_CTRL_GO_DIGITAL); + } + return 0; + +} + +static int +omapfb_console_match(int phandle) +{ + return of_match_compatible(phandle, compatible); +} + +static void +omapfb_console_consinit(struct fdt_attach_args *faa, u_int uart_freq) +{ + omapfb_console_phandle = faa->faa_phandle; +} + +static const struct fdt_console omapfb_fdt_console = { + .match = omapfb_console_match, + .consinit = omapfb_console_consinit, +}; + +FDT_CONSOLE(omapfb, &omapfb_fdt_console); Index: src/sys/arch/arm/ti/omap3_dssreg.h diff -u /dev/null src/sys/arch/arm/ti/omap3_dssreg.h:1.1 --- /dev/null Thu Oct 31 17:08:54 2019 +++ src/sys/arch/arm/ti/omap3_dssreg.h Thu Oct 31 17:08:54 2019 @@ -0,0 +1,373 @@ +/* $NetBSD: omap3_dssreg.h,v 1.1 2019/10/31 17:08:54 jmcneill Exp $ */ + +/*- + * Copyright (c) 2010 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: omap3_dssreg.h,v 1.1 2019/10/31 17:08:54 jmcneill Exp $"); + +#ifndef OMAP3_DSSREG_H +#define OMAP3_DSSREG_H + +#define OMAPFB_DSS_REVISION 0x0000 +#define OMAPFB_DSS_SYSCONFIG 0x0010 +#define OMAPFB_DSS_SYSSTATUS 0x0014 +#define OMAPFB_DSS_IRQSTATUS 0x0018 +#define OMAPFB_DSS_CONTROL 0x0040 +#define OMAPFB_DSS_SDI_CONTROL 0x0044 +#define OMAPFB_DSS_PLL_CONTROL 0x0048 +#define OMAPFB_DSS_SDI_STATUS 0x005c + +/* display controller */ +#define OMAPFB_DISPC_REVISION 0x0400 +#define OMAPFB_DISPC_SYSCONFIG 0x0410 +#define OMAPFB_DISPC_SYSSTATUS 0x0414 +#define OMAPFB_DISPC_IRQSTATUS 0x0418 +#define OMAPFB_DISPC_IRQENABLE 0x041c +#define OMAPFB_DISPC_CONTROL 0x0440 +#define OMAPFB_DISPC_CONFIG 0x0444 +#define OMAPFB_DISPC_DEFAULT_COLOR_0 0x044c +#define OMAPFB_DISPC_DEFAULT_COLOR_1 0x0450 +#define OMAPFB_DISPC_TRANS_COLOR_0 0x0454 +#define OMAPFB_DISPC_TRANS_COLOR_1 0x0458 +#define OMAPFB_DISPC_LINE_STATUS 0x045c +#define OMAPFB_DISPC_LINE_NUMBER 0x0460 +#define OMAPFB_DISPC_TIMING_H 0x0464 +#define OMAPFB_DISPC_TIMING_V 0x0468 +#define OMAPFB_DISPC_POL_FREQ 0x046c +#define OMAPFB_DISPC_DIVISOR 0x0470 +#define OMAPFB_DISPC_GLOBAL_ALPHA 0x0474 +#define OMAPFB_DISPC_SIZE_DIG 0x0478 +#define OMAPFB_DISPC_SIZE_LCD 0x047c +#define OMAPFB_DISPC_GFX_BASE_0 0x0480 +#define OMAPFB_DISPC_GFX_BASE_1 0x0484 +#define OMAPFB_DISPC_GFX_POSITION 0x0488 +#define OMAPFB_DISPC_GFX_SIZE 0x048c +#define OMAPFB_DISPC_GFX_ATTRIBUTES 0x04a0 +#define OMAPFB_DISPC_GFX_FIFO_THRESH 0x04a4 +#define OMAPFB_DISPC_GFX_FIFO_SZ_STATUS 0x04a8 +#define OMAPFB_DISPC_GFX_ROW_INC 0x04ac +#define OMAPFB_DISPC_GFX_PIXEL_INC 0x04b0 +#define OMAPFB_DISPC_GFX_WINDOW_SKIP 0x04b4 +#define OMAPFB_DISPC_GFX_TABLE_BASE 0x04b8 +#define OMAPFB_DISPC_DATA_CYCLE_0 0x05d4 +#define OMAPFB_DISPC_DATA_CYCLE_1 0x05d8 +#define OMAPFB_DISPC_DATA_CYCLE_2 0x05dc +#define OMAPFB_DISPC_CPR_COEFF_R 0x0620 +#define OMAPFB_DISPC_CPR_COEFF_G 0x0624 +#define OMAPFB_DISPC_CPR_COEFF_B 0x0628 +#define OMAPFB_DISPC_GFX_PRELOAD 0x062c + +/* VID1 */ +#define OMAPFB_DISPC_VID1_BASE_0 0x04bc +#define OMAPFB_DISPC_VID1_BASE_1 0x04c0 +#define OMAPFB_DISPC_VID1_POSITION 0x04c4 +#define OMAPFB_DISPC_VID1_SIZE 0x04c8 /* displayed size */ +#define OMAPFB_DISPC_VID1_ATTRIBUTES 0x04cc +#define OMAPFB_DISPC_VID1_FIFO_THRESH 0x04d0 +#define OMAPFB_DISPC_VID1_FIFO_SZ_STAT 0x04d4 +#define OMAPFB_DISPC_VID1_ROW_INC 0x04d8 +#define OMAPFB_DISPC_VID1_PIXEL_INC 0x04dc +#define OMAPFB_DISPC_VID1_FIR 0x04e0 +#define OMAPFB_DISPC_VID1_PICTURE_SIZE 0x04e4 /* original size */ +#define OMAPFB_DISPC_VID1_ACCU_0 0x04e8 +#define OMAPFB_DISPC_VID1_ACCU_1 0x04ec +#define OMAPFB_DISPC_VID1_COEFF_H_0 0x04d0 +#define OMAPFB_DISPC_VID1_COEFF_HV_0 0x04d4 +#define OMAPFB_DISPC_VID1_COEFF_H_1 0x04d8 +#define OMAPFB_DISPC_VID1_COEFF_HV_1 0x04dc +#define OMAPFB_DISPC_VID1_COEFF_H_2 0x04e0 +#define OMAPFB_DISPC_VID1_COEFF_HV_2 0x04e4 +#define OMAPFB_DISPC_VID1_COEFF_H_3 0x04e8 +#define OMAPFB_DISPC_VID1_COEFF_HV_3 0x04ec +#define OMAPFB_DISPC_VID1_COEFF_H_4 0x04f0 +#define OMAPFB_DISPC_VID1_COEFF_HV_4 0x04f4 +#define OMAPFB_DISPC_VID1_COEFF_H_5 0x04f8 +#define OMAPFB_DISPC_VID1_COEFF_HV_5 0x04fc +#define OMAPFB_DISPC_VID1_COEFF_H_6 0x0500 +#define OMAPFB_DISPC_VID1_COEFF_HV_6 0x0504 +#define OMAPFB_DISPC_VID1_COEFF_H_7 0x0508 +#define OMAPFB_DISPC_VID1_COEFF_HV_7 0x050c +#define OMAPFB_DISPC_VID1_CONV_COEFF_0 0x0530 +#define OMAPFB_DISPC_VID1_CONV_COEFF_1 0x0534 +#define OMAPFB_DISPC_VID1_CONV_COEFF_2 0x0538 +#define OMAPFB_DISPC_VID1_CONV_COEFF_3 0x053c +#define OMAPFB_DISPC_VID1_CONV_COEFF_4 0x0540 +#define OMAPFB_DISPC_VID1_FIR_COEFF_V0 0x05e0 +#define OMAPFB_DISPC_VID1_FIR_COEFF_V1 0x05e4 +#define OMAPFB_DISPC_VID1_FIR_COEFF_V2 0x05e8 +#define OMAPFB_DISPC_VID1_FIR_COEFF_V3 0x05ec +#define OMAPFB_DISPC_VID1_FIR_COEFF_V4 0x05f0 +#define OMAPFB_DISPC_VID1_FIR_COEFF_V5 0x05f4 +#define OMAPFB_DISPC_VID1_FIR_COEFF_V6 0x05f8 +#define OMAPFB_DISPC_VID1_FIR_COEFF_V7 0x05fc +#define OMAPFB_DISPC_VID1_PRELOAD 0x0630 + +/* VID2 */ +#define OMAPFB_DISPC_VID2_BASE_0 0x054c +#define OMAPFB_DISPC_VID2_BASE_1 0x0550 +#define OMAPFB_DISPC_VID2_POSITION 0x0554 +#define OMAPFB_DISPC_VID2_SIZE 0x0558 +#define OMAPFB_DISPC_VID2_ATTRIBUTES 0x055c +#define OMAPFB_DISPC_VID2_FIFO_THRESH 0x0560 +#define OMAPFB_DISPC_VID2_FIFO_SZ_STAT 0x0564 +#define OMAPFB_DISPC_VID2_ROW_INC 0x0568 +#define OMAPFB_DISPC_VID2_PIXEL_INC 0x056c +#define OMAPFB_DISPC_VID2_FIR 0x0570 +#define OMAPFB_DISPC_VID2_PICTURE_SIZE 0x0574 +#define OMAPFB_DISPC_VID2_ACCU_0 0x0578 +#define OMAPFB_DISPC_VID2_ACCU_1 0x057c +#define OMAPFB_DISPC_VID2_COEFF_H_0 0x0580 +#define OMAPFB_DISPC_VID2_COEFF_HV_0 0x0584 +#define OMAPFB_DISPC_VID2_COEFF_H_1 0x0588 +#define OMAPFB_DISPC_VID2_COEFF_HV_1 0x058c +#define OMAPFB_DISPC_VID2_COEFF_H_2 0x0590 +#define OMAPFB_DISPC_VID2_COEFF_HV_2 0x0594 +#define OMAPFB_DISPC_VID2_COEFF_H_3 0x0598 +#define OMAPFB_DISPC_VID2_COEFF_HV_3 0x059c +#define OMAPFB_DISPC_VID2_COEFF_H_4 0x05a0 +#define OMAPFB_DISPC_VID2_COEFF_HV_4 0x05a4 +#define OMAPFB_DISPC_VID2_COEFF_H_5 0x05a8 +#define OMAPFB_DISPC_VID2_COEFF_HV_5 0x05ac +#define OMAPFB_DISPC_VID2_COEFF_H_6 0x05b0 +#define OMAPFB_DISPC_VID2_COEFF_HV_6 0x05b4 +#define OMAPFB_DISPC_VID2_COEFF_H_7 0x05b8 +#define OMAPFB_DISPC_VID2_COEFF_HV_7 0x05bc +#define OMAPFB_DISPC_VID2_CONV_COEFF_0 0x05c0 +#define OMAPFB_DISPC_VID2_CONV_COEFF_1 0x05c4 +#define OMAPFB_DISPC_VID2_CONV_COEFF_2 0x05c8 +#define OMAPFB_DISPC_VID2_CONV_COEFF_3 0x05cc +#define OMAPFB_DISPC_VID2_CONV_COEFF_4 0x05d0 +#define OMAPFB_DISPC_VID2_FIR_COEFF_V0 0x0670 +#define OMAPFB_DISPC_VID2_FIR_COEFF_V1 0x0674 +#define OMAPFB_DISPC_VID2_FIR_COEFF_V2 0x0678 +#define OMAPFB_DISPC_VID2_FIR_COEFF_V3 0x067c +#define OMAPFB_DISPC_VID2_FIR_COEFF_V4 0x0680 +#define OMAPFB_DISPC_VID2_FIR_COEFF_V5 0x0684 +#define OMAPFB_DISPC_VID2_FIR_COEFF_V6 0x0688 +#define OMAPFB_DISPC_VID2_FIR_COEFF_V7 0x068c +#define OMAPFB_DISPC_VID2_PRELOAD 0x0634 + +/* video encoder */ +#define OMAPFB_VENC_REV_ID 0x0c00 +#define OMAPFB_VENC_STATUS 0x0c04 +#define OMAPFB_VENC_F_CONTROL 0x0c08 +#define OMAPFB_VENC_VIDOUT_CTRL 0x0c10 +#define OMAPFB_VENC_SYNC_CTRL 0x0c14 +#define OMAPFB_VENC_LLEN 0x0c1c +#define OMAPFB_VENC_FLENS 0x0c20 +#define OMAPFB_VENC_HFLTR_CTRL 0x0c24 +#define OMAPFB_VENC_CC_CARR_WSS_CARR 0x0c28 +#define OMAPFB_VENC_C_PHASE 0x0c2c +#define OMAPFB_VENC_GAIN_U 0x0c30 +#define OMAPFB_VENC_GAIN_V 0x0c34 +#define OMAPFB_VENC_GAIN_Y 0x0c38 +#define OMAPFB_VENC_BLACK_LEVEL 0x0c3c +#define OMAPFB_VENC_BLANK_LEVEL 0x0c40 +#define OMAPFB_VENC_X_COLOR 0x0c44 +#define OMAPFB_VENC_M_CONTROL 0x0c48 +#define OMAPFB_VENC_BSTAMP_WSS_DATA 0x0c4c +#define OMAPFB_VENC_S_CARR 0x0c50 +#define OMAPFB_VENC_LINE21 0x0c54 +#define OMAPFB_VENC_LN_SEL 0x0c58 +#define OMAPFB_VENC_L21_WC_CTL 0x0c5c +#define OMAPFB_VENC_HTRIGGER_VTRIGGER 0x0c60 +#define OMAPFB_VENC_SAVID_EAVID 0x0c64 +#define OMAPFB_VENC_FLEN_FAL 0x0c68 +#define OMAPFB_VENC_LAL_PHASE_RESET 0x0c6c +#define OMAPFB_VENC_HS_INT_START_STOP_X 0x0c70 +#define OMAPFB_VENC_HS_EXT_START_STOP_X 0x0c74 +#define OMAPFB_VENC_VS_INT_START 0x0c78 +#define OMAPFB_VENC_VS_INT_STOP_X_VS_INT_START_Y 0x0c7c +#define OMAPFB_VENC_VS_INT_STOP_Y_VS_EXT_START_X 0x0c80 +#define OMAPFB_VENC_VS_EXT_STOP_X_VS_EXT_START_Y 0x0c84 +#define OMAPFB_VENC_VS_EXT_STOP_Y 0x0c88 +#define OMAPFB_VENC_AVID_START_STOP_X 0x0c90 +#define OMAPFB_VENC_AVID_START_STOP_Y 0x0c94 +#define OMAPFB_VENC_FID_START_X_FID_START_Y 0x0ca0 +#define OMAPFB_VENC_FID_INT_OFFSET_Y_FID_EXT_START_X 0x0ca4 +#define OMAPFB_VENC_FID_EXT_START_Y_FID_EXT_OFFSET_Y 0x0ca8 +#define OMAPFB_VENC_TVDETGP_INT_START_STOP_X 0x0cb0 +#define OMAPFB_VENC_TVDETGP_INT_START_STOP_Y 0x0cb4 +#define OMAPFB_VENC_GEN_CTRL 0x0cb8 +#define OMAPFB_VENC_OUTPUT_CONTROL 0x0cc4 +#define OMAPFB_VENC_OUTPUT_TEST 0x0cc8 + +/* revision registers */ +#define OMAP_REVISION_MINOR_MASK 0x0000000f +#define OMAP_REVISION_MAJOR_MASK 0x000000f0 + +/* sysconfig registers */ +#define OMAP_SYSCONF_AUTOIDLE 0x00000001 +#define OMAP_SYSCONF_SOFTRESET 0x00000002 + +/* sysstatus registers */ +#define OMAP_SYSSTAT_RESET_DONE 0x00000001 + +/* OMAPFB_DSS_IRQSTATUS */ +#define OMAP_DSSIRQ_DISPC 0x00000001 +#define OMAP_DSSIRQ_DSI 0x00000002 + +/* OMAPFB_DSS_CONTROL */ +#define OMAP_DSSCTRL_VENC_SVIDEO 0x00000040 /* composite otherwise */ +#define OMAP_DSSCTRL_POWERDN_BGZ 0x00000020 /* power-down band gap up */ +#define OMAP_DSSCTRL_DAC_DEMEN 0x00000010 /* dynamic element match */ +#define OMAP_DSSCTRL_VENC_CLOCK_4X 0x00000008 +#define OMAP_DSSCTRL_CLOCK_MODE 0x00000004 +#define OMAP_DSSCTRL_DSI_CLK_SWITCH 0x00000002 /* use DSI PLL */ +#define OMAP_DSSCTRL_DISPC_CLK_SWITCH 0x00000001 /* use DSI PLL */ + +/* additional bits in OMAPFB_DISPC_SYSCONFIG */ +#define OMAP_DISPC_SYSC_FORCE_STANDBY 0x00000000 +#define OMAP_DISPC_SYSC_NO_STANDBY 0x00001000 +#define OMAP_DISPC_SYSC_SMART_STANDBY 0x00002000 +#define OMAP_DISPC_SYSC_STANDBY_MASK 0x00003000 +#define OMAP_DISPC_SYSC_CLOCKS_OFF 0x00000000 +#define OMAP_DISPC_SYSC_FCLOCK_OFF 0x00000100 +#define OMAP_DISPC_SYSC_ICLOCK_OFF 0x00000200 +#define OMAP_DISPC_SYSC_CLOCK_ON 0x00000300 +#define OMAP_DISPC_SYSC_CLOCK_MASK 0x00000300 +#define OMAP_DISPC_SYSC_FORCE_IDLE 0x00000000 +#define OMAP_DISPC_SYSC_NO_IDLE 0x00000008 +#define OMAP_DISPC_SYSC_SMART_IDLE 0x00000010 +#define OMAP_DISPC_SYSC_IDLE_MASK 0x00000018 +#define OMAP_DISPC_SYSC_WAKEUP_ENABLE 0x00000004 + +/* OMAPFB_DISPC_GFX_ATTRIBUTES */ +#define OMAP_DISPC_ATTR_REFRESH_FIFO 0x00008000 /* refresh from FIFO only */ +#define OMAP_DISPC_ATTR_PRIORITY_HIGH 0x00004000 +#define OMAP_DISPC_ATTR_ROT_NONE 0x00000000 +#define OMAP_DISPC_ATTR_ROT_90 0x00001000 /* for 24bit packed only */ +#define OMAP_DISPC_ATTR_ROT_180 0x00002000 +#define OMAP_DISPC_ATTR_ROT_270 0x00003000 +#define OMAP_DISPC_ATTR_FIFO_PRELOAD 0x00000800 /* use threshold for FIFO */ +#define OMAP_DISPC_ATTR_BIG_ENDIAN 0x00000400 /* little endian otherwise */ +#define OMAP_DISPC_ATTR_NIBBLE 0x00000200 /* for < 8 bit only */ +#define OMAP_DISPC_ATTR_24BIT_OUT 0x00000100 /* LCD otherwise */ +#define OMAP_DISPC_ATTR_BURST_4x32 0x00000000 +#define OMAP_DISPC_ATTR_BURST_8x32 0x00000040 +#define OMAP_DISPC_ATTR_BURST_16x32 0x00000080 +#define OMAP_DISPC_ATTR_REPLICATION 0x00000020 +#define OMAP_DISPC_ATTR_8BIT 0x00000006 +#define OMAP_DISPC_ATTR_RGB12 0x00000008 +#define OMAP_DISPC_ATTR_ARGB16 0x0000000a +#define OMAP_DISPC_ATTR_RGB16 0x0000000c +#define OMAP_DISPC_ATTR_RGB24 0x00000010 /* 32bit pixels */ +#define OMAP_DISPC_ATTR_RGB24P 0x00000012 /* 24bit packed */ +#define OMAP_DISPC_ATTR_ARGB32 0x00000018 +#define OMAP_DISPC_ATTR_RGBA32 0x0000001a +#define OMAP_DISPC_ATTR_RGBX 0x0000001c +#define OMAP_DISPC_ATTR_ENABLE 0x00000001 + +/* OMAPFB_DISPC_CONTROL */ +#define OMAP_DISPC_CTRL_LCD_ACTIVE_HIGH 0x20000000 +#define OMAP_DISPC_CTRL_LCD_SIGNAL 0x10000000 +#define OMAP_DISPC_CTRL_PIXEL_CLOCK 0x08000000 +#define OMAP_DISPC_CTRL_GO_DIGITAL 0x00000040 +#define OMAP_DISPC_CTRL_GO_LCD 0x00000020 +#define OMAP_DISPC_CTRL_MONO_8_BYTE 0x00000010 /* 4 otherwise */ +#define OMAP_DISPC_CTRL_ACTIVE_MTRX 0x00000008 /* disable STN dither */ +#define OMAP_DISPC_CTRL_MONO 0x00000004 +#define OMAP_DISPC_CTRL_DIGITAL_ENABLE 0x00000002 +#define OMAP_DISPC_CTRL_LCD_ENABLE 0x00000001 + +/* OMAPFB_VENC_F_CONTROL */ +#define OMAP_VENCFCTL_RESET 0x00000100 +#define OMAP_VENCFCTL_VID_EXTERNAL 0x00000000 +#define OMAP_VENCFCTL_VID_COLOR_BAR 0x00000040 +#define OMAP_VENCFCTL_VID_BACKGROUND 0x00000080 +#define OMAP_VENCFCTL_RGBF 0x00000020 +#define OMAP_VENCFCTL_BG_COLOR_MASK 0x0000001c +#define OMAP_VENCFCTL_FMT_444RGB 0x00000000 +#define OMAP_VENCFCTL_FMT_444 0x00000001 +#define OMAP_VENCFCTL_FMT_422 0x00000002 +#define OMAP_VENCFCTL_FMT_ITU_422 0x00000003 + +/* OMAPFB_DISPC_CONFIG */ +#define OMAP_DISPC_CFG_TV_ALPHA_EN 0x00080000 +#define OMAP_DISPC_CFG_LCD_ALPHA_EN 0x00040000 +#define OMAP_DISPC_CFG_FIFO_FILL_ALL 0x00020000 /* fill all FIFOs if at least one is low */ +#define OMAP_DISPC_CFG_FIFOHANDCHECK 0x00010000 +#define OMAP_DISPC_CFG_CPR 0x00008000 /* color phase rotation */ +#define OMAP_DISPC_CFG_FIFOMERGE 0x00004000 +#define OMAP_DISPC_CFG_TCKDIGSELECTION 0x00002000 /* transp. color key */ +#define OMAP_DISPC_CFG_TCKDIGENABLE 0x00001000 +#define OMAP_DISPC_CFG_TCKLCDSELECTION 0x00000800 /* transp. color key */ +#define OMAP_DISPC_CFG_TCKLCDENABLE 0x00000400 +#define OMAP_DISPC_CFG_FUNCGATED 0x00000200 /* functional clocks */ +#define OMAP_DISPC_CFG_ACBIAS_GATED 0x00000100 +#define OMAP_DISPC_CFG_VSYNC_GATED 0x00000080 +#define OMAP_DISPC_CFG_HSYNC_GATED 0x00000040 +#define OMAP_DISPC_CFG_PIXELCLK_GATED 0x00000020 +#define OMAP_DISPC_CFG_PIXELDATA_GATED 0x00000010 +#define OMAP_DISPC_CFG_PALGAMMATABLE 0x00000008 /* use LUT as gamma in >8bit */ +#define OMAP_DISPC_CFG_LUT_LOAD_ALWAYS 0x00000000 +#define OMAP_DISPC_CFG_LUT_LOAD 0x00000002 +#define OMAP_DISPC_CFG_LUT_LOAD_F_ONLY 0x00000004 /* only frame data */ +#define OMAP_DISPC_CFG_LUT_LOAD_ONCE 0x00000006 /* load once, then 4 */ +#define OMAP_DISPC_CFG_PIXEL_GATED 0x00000001 /* active matrix only */ + +/* OMAPFB_DISPC_VIDn_ATTRIBUTES */ +#define OMAP_VID_ATTR_SELFREFRESH 0x01000000 /* no DMA, display from FIFO only */ +#define OMAP_VID_ATTR_HIGH_PRIORITY 0x00800000 +#define OMAP_VID_ATTR_BUFFER_SPLIT 0x00400000 +#define OMAP_VID_ATTR_TAP_5 0x00200000 /* resize, 3 taps otherwise */ +#define OMAP_VID_ATTR_DMA_OPT 0x00100000 /* for rotation */ +#define OMAP_VID_ATTR_FIFO_PRELOAD 0x00080000 /* use high threshold reg */ +#define OMAP_VID_ATTR_ROWREPEAT 0x00040000 /* for YUV */ +#define OMAP_VID_ATTR_BIG_ENDIAN 0x00020000 +#define OMAP_VID_ATTR_CHANNEL_24BIT 0x00010000 /* LCD otherwise */ +#define OMAP_VID_ATTR_BURST_4x32 0x00000000 +#define OMAP_VID_ATTR_BURST_8x32 0x00004000 +#define OMAP_VID_ATTR_BURST_16x32 0x00008000 +#define OMAP_VID_ATTR_BURST_MASK 0x0000c000 +#define OMAP_VID_ATTR_ROT_NONE 0x00000000 +#define OMAP_VID_ATTR_ROT_90 0x00001000 +#define OMAP_VID_ATTR_ROT_180 0x00002000 +#define OMAP_VID_ATTR_ROT_270 0x00003000 +#define OMAP_VID_ATTR_ROT_MASK 0x00003000 +#define OMAP_VID_ATTR_FULLRANGE 0x00000800 /* YUV */ +#define OMAP_VID_ATTR_REPLICATION 0x00000400 /* 16bit -> 24bit */ +#define OMAP_VID_ATTR_COLORSPACE_CONV 0x00000200 /* CbYCr -> RGB */ +#define OMAP_VID_ATTR_VRESIZE_UP 0x00000100 /* down otherwise */ +#define OMAP_VID_ATTR_HRESIZE_UP 0x00000080 +#define OMAP_VID_ATTR_VRESIZE_ENABLE 0x00000040 +#define OMAP_VID_ATTR_HRESIZE_ENABLE 0x00000020 +/* VID1 doesn't support any alpha formats */ +#define OMAP_VID_ATTR_RGB12 0x00000008 +#define OMAP_VID_ATTR_ARGB16 0x0000000a +#define OMAP_VID_ATTR_RGB16 0x0000000c +#define OMAP_VID_ATTR_RGB24 0x00000010 /* 32bit pixels */ +#define OMAP_VID_ATTR_RGB24P 0x00000012 /* 24bit packed */ +#define OMAP_VID_ATTR_YUV2 0x00000014 +#define OMAP_VID_ATTR_UYVY 0x00000016 +#define OMAP_VID_ATTR_ARGB32 0x00000018 +#define OMAP_VID_ATTR_RGBA32 0x0000001a +#define OMAP_VID_ATTR_RGBX 0x0000001c + +#define OMAP_VID_ATTR_ENABLE 0x00000001 + +#endif /* OMAP3_DSSREG_H */