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 */

Reply via email to