Module Name:    src
Committed By:   macallan
Date:           Sun Jan  4 18:18:20 UTC 2015

Modified Files:
        src/sys/dev/sbus: files.sbus mgx.c mgxreg.h

Log Message:
support hardware acceleration, adapted from OpenBSD
TODO: figure out how to do host blits so we can get away without mapping the
      framebuffer


To generate a diff of this commit:
cvs rdiff -u -r1.40 -r1.41 src/sys/dev/sbus/files.sbus
cvs rdiff -u -r1.1 -r1.2 src/sys/dev/sbus/mgx.c src/sys/dev/sbus/mgxreg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/sbus/files.sbus
diff -u src/sys/dev/sbus/files.sbus:1.40 src/sys/dev/sbus/files.sbus:1.41
--- src/sys/dev/sbus/files.sbus:1.40	Tue Dec 16 21:01:34 2014
+++ src/sys/dev/sbus/files.sbus	Sun Jan  4 18:18:20 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: files.sbus,v 1.40 2014/12/16 21:01:34 macallan Exp $
+#	$NetBSD: files.sbus,v 1.41 2015/01/04 18:18:20 macallan Exp $
 #
 # Config file and device description for machine-independent SBUS code.
 # Included by ports that need it.
@@ -157,6 +157,6 @@ file	dev/sbus/cgtwelve.c		cgtwelve
 
 # SSB MGX
 defflag opt_mgx.h	MGX_DEBUG
-device	mgx: fb, rasops8, wsemuldisplaydev, vcons
+device	mgx: fb, rasops8, wsemuldisplaydev, vcons, glyphcache
 attach	mgx at sbus
 file	dev/sbus/mgx.c			mgx

Index: src/sys/dev/sbus/mgx.c
diff -u src/sys/dev/sbus/mgx.c:1.1 src/sys/dev/sbus/mgx.c:1.2
--- src/sys/dev/sbus/mgx.c:1.1	Tue Dec 16 21:01:34 2014
+++ src/sys/dev/sbus/mgx.c	Sun Jan  4 18:18:20 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: mgx.c,v 1.1 2014/12/16 21:01:34 macallan Exp $ */
+/*	$NetBSD: mgx.c,v 1.2 2015/01/04 18:18:20 macallan Exp $ */
 
 /*-
  * Copyright (c) 2014 Michael Lorenz
@@ -29,7 +29,7 @@
 /* a console driver for the SSB 4096V-MGX graphics card */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mgx.c,v 1.1 2014/12/16 21:01:34 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mgx.c,v 1.2 2015/01/04 18:18:20 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -52,6 +52,7 @@ __KERNEL_RCSID(0, "$NetBSD: mgx.c,v 1.1 
 #include <dev/rasops/rasops.h>
 
 #include <dev/wscons/wsdisplay_vconsvar.h>
+#include <dev/wscons/wsdisplay_glyphcachevar.h>
 
 #include <dev/ic/vgareg.h>
 #include <dev/sbus/mgxreg.h>
@@ -71,14 +72,17 @@ struct mgx_softc {
 	int		sc_stride;
 	int		sc_fbsize;
 	int		sc_mode;
+	uint32_t	sc_dec;
 	u_char		sc_cmap_red[256];
 	u_char		sc_cmap_green[256];
 	u_char		sc_cmap_blue[256];
+	void (*sc_putchar)(void *, int, int, u_int, long);
 	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;
+	glyphcache 	sc_gc;
 };
 
 static int	mgx_match(device_t, cfdata_t, void *);
@@ -91,6 +95,18 @@ static void	mgx_init_screen(void *, stru
 static void	mgx_write_dac(struct mgx_softc *, int, int, int, int);
 static void	mgx_setup(struct mgx_softc *, int);
 static void	mgx_init_palette(struct mgx_softc *);
+static int	mgx_wait_engine(struct mgx_softc *);
+static int	mgx_wait_fifo(struct mgx_softc *, unsigned int);
+
+static void	mgx_bitblt(void *, int, int, int, int, int, int, int);
+static void 	mgx_rectfill(void *, int, int, int, int, long);
+
+static void	mgx_putchar(void *, int, int, u_int, long);
+static void	mgx_cursor(void *, int, int, int);
+static void	mgx_copycols(void *, int, int, int, int);
+static void	mgx_erasecols(void *, int, int, int, long);
+static void	mgx_copyrows(void *, int, int, int);
+static void	mgx_eraserows(void *, int, int, long);
 
 CFATTACH_DECL_NEW(mgx, sizeof(struct mgx_softc),
     mgx_match, mgx_attach, NULL, NULL);
@@ -143,13 +159,14 @@ mgx_attach(device_t parent, device_t sel
 	sc->sc_height = prom_getpropint(sa->sa_node, "height", 900);
 	sc->sc_stride = prom_getpropint(sa->sa_node, "linebytes", 900);
 	sc->sc_fbsize = sc->sc_height * sc->sc_stride;
-	sc->sc_fbaddr = NULL; //(void *)(unsigned long)prom_getpropint(sa->sa_node, "address", 0);
+	sc->sc_fbaddr = NULL;
 	if (sc->sc_fbaddr == NULL) {
 		if (sbus_bus_map(sa->sa_bustag,
 			 sa->sa_slot,
 			 sa->sa_reg[8].oa_base,
 			 sc->sc_fbsize,
-			 BUS_SPACE_MAP_LINEAR, &bh) != 0) {
+			 BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
+			 &bh) != 0) {
 			aprint_error_dev(self, "cannot map framebuffer\n");
 			return;
 		}
@@ -169,8 +186,8 @@ mgx_attach(device_t parent, device_t sel
 
 	if (sbus_bus_map(sa->sa_bustag,
 			 sa->sa_slot,
-			 sa->sa_reg[5].oa_base, 0x1000, 0, 
-			 &sc->sc_blith) != 0) {
+			 sa->sa_reg[5].oa_base + MGX_REG_ATREG_OFFSET, 0x1000,
+			 0, &sc->sc_blith) != 0) {
 		aprint_error("%s: couldn't map blitter registers\n", 
 		    device_xname(sc->sc_dev));
 		return;
@@ -207,10 +224,24 @@ mgx_attach(device_t parent, device_t sel
 	sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
 	sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
 
+	sc->sc_gc.gc_bitblt = mgx_bitblt;
+	sc->sc_gc.gc_rectfill = mgx_rectfill;
+	sc->sc_gc.gc_blitcookie = sc;
+	sc->sc_gc.gc_rop = ROP_SRC;
+
+	glyphcache_init(&sc->sc_gc,
+	    sc->sc_height + 5,
+	    (0x400000 / sc->sc_stride) - sc->sc_height - 5,
+	    sc->sc_width,
+	    ri->ri_font->fontwidth,
+	    ri->ri_font->fontheight,
+	    defattr);
+
 	mgx_init_palette(sc);
 
 	if(isconsole) {
-		wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, defattr);
+		wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
+		    defattr);
 		vcons_replay_msgbuf(&sc->sc_console_screen);
 	}
 
@@ -222,12 +253,31 @@ mgx_attach(device_t parent, device_t sel
 	config_found(self, &aa, wsemuldisplaydevprint);
 }
 
-static void
+static inline void
 mgx_write_vga(struct mgx_softc *sc, uint32_t reg, uint8_t val)
 {
 	bus_space_write_1(sc->sc_tag, sc->sc_vgah, reg ^ 3, val);
 }
 
+static inline void
+mgx_write_1(struct mgx_softc *sc, uint32_t reg, uint8_t val)
+{
+	bus_space_write_1(sc->sc_tag, sc->sc_blith, reg ^ 3, val);
+}
+
+static inline uint8_t
+mgx_read_1(struct mgx_softc *sc, uint32_t reg)
+{
+	return bus_space_read_1(sc->sc_tag, sc->sc_blith, reg ^ 3);
+}
+
+static inline void
+mgx_write_4(struct mgx_softc *sc, uint32_t reg, uint32_t val)
+{
+	bus_space_write_4(sc->sc_tag, sc->sc_blith, reg, val);
+}
+
+
 static void
 mgx_write_dac(struct mgx_softc *sc, int idx, int r, int g, int b)
 {
@@ -254,9 +304,278 @@ mgx_init_palette(struct mgx_softc *sc)
 	}
 }
 
+static int
+mgx_wait_engine(struct mgx_softc *sc)
+{
+	unsigned int i;
+	uint8_t stat;
+
+	for (i = 100000; i != 0; i--) {
+		stat = mgx_read_1(sc, ATR_BLT_STATUS);
+		if ((stat & (BLT_HOST_BUSY | BLT_ENGINE_BUSY)) == 0)
+			break;
+	}
+
+	return i;
+}
+
+static int
+mgx_wait_fifo(struct mgx_softc *sc, unsigned int nfifo)
+{
+	unsigned int i;
+	uint8_t stat;
+
+	for (i = 100000; i != 0; i--) {
+		stat = mgx_read_1(sc, ATR_FIFO_STATUS);
+		stat = (stat & FIFO_MASK) >> FIFO_SHIFT;
+		if (stat >= nfifo)
+			break;
+		mgx_write_1(sc, ATR_FIFO_STATUS, 0);
+	}
+
+	return i;
+}
+
 static void
 mgx_setup(struct mgx_softc *sc, int depth)
 {
+	/* wait for everything to go idle */
+	if (mgx_wait_engine(sc) == 0)
+		return;
+	if (mgx_wait_fifo(sc, FIFO_AT24) == 0)
+		return;
+	/*
+	 * Compute the invariant bits of the DEC register.
+	 */
+
+	switch (depth) {
+		case 8:
+			sc->sc_dec = DEC_DEPTH_8 << DEC_DEPTH_SHIFT;
+			break;
+		case 15:
+		case 16:
+			sc->sc_dec = DEC_DEPTH_16 << DEC_DEPTH_SHIFT;
+			break;
+		case 32:
+			sc->sc_dec = DEC_DEPTH_32 << DEC_DEPTH_SHIFT;
+			break;
+		default:
+			return; /* not supported */
+	}
+
+	switch (sc->sc_stride) {
+		case 640:
+			sc->sc_dec |= DEC_WIDTH_640 << DEC_WIDTH_SHIFT;
+			break;
+		case 800:
+			sc->sc_dec |= DEC_WIDTH_800 << DEC_WIDTH_SHIFT;
+			break;
+		case 1024:
+			sc->sc_dec |= DEC_WIDTH_1024 << DEC_WIDTH_SHIFT;
+			break;
+		case 1152:
+			sc->sc_dec |= DEC_WIDTH_1152 << DEC_WIDTH_SHIFT;
+			break;
+		case 1280:
+			sc->sc_dec |= DEC_WIDTH_1280 << DEC_WIDTH_SHIFT;
+			break;
+		case 1600:
+			sc->sc_dec |= DEC_WIDTH_1600 << DEC_WIDTH_SHIFT;
+			break;
+		default:
+			return; /* not supported */
+	}
+	mgx_write_1(sc, ATR_CLIP_CONTROL, 0);
+	mgx_write_1(sc, ATR_BYTEMASK, 0xff);
+}
+
+static void
+mgx_bitblt(void *cookie, int xs, int ys, int xd, int yd, int wi, int he,
+             int rop)
+{
+	struct mgx_softc *sc = cookie;
+	uint32_t dec = sc->sc_dec;
+
+        dec |= (DEC_COMMAND_BLT << DEC_COMMAND_SHIFT) |
+	       (DEC_START_DIMX << DEC_START_SHIFT);
+	if (xs < xd) {
+		xs += wi - 1;
+		xd += wi - 1;
+		dec |= DEC_DIR_X_REVERSE;
+	}
+	if (ys < yd) {
+		ys += he - 1;
+		yd += he - 1;
+		dec |= DEC_DIR_Y_REVERSE;
+	}
+	mgx_wait_fifo(sc, 5);
+	mgx_write_1(sc, ATR_ROP, rop);
+	mgx_write_4(sc, ATR_DEC, dec);
+	mgx_write_4(sc, ATR_SRC_XY, (ys << 16) | xs);
+	mgx_write_4(sc, ATR_DST_XY, (yd << 16) | xd);
+	mgx_write_4(sc, ATR_WH, (he << 16) | wi);
+}
+	
+static void
+mgx_rectfill(void *cookie, int x, int y, int wi, int he, long fg)
+{
+	struct mgx_softc *sc = cookie;
+	struct vcons_screen *scr = sc->vd.active;
+	uint32_t dec = sc->sc_dec;
+	uint32_t col;
+
+	if (scr == NULL)
+		return;
+	col = scr->scr_ri.ri_devcmap[fg];
+
+	dec = sc->sc_dec;
+	dec |= (DEC_COMMAND_RECT << DEC_COMMAND_SHIFT) |
+	       (DEC_START_DIMX << DEC_START_SHIFT);
+	mgx_wait_fifo(sc, 5);
+	mgx_write_1(sc, ATR_ROP, ROP_SRC);
+	mgx_write_4(sc, ATR_FG, col);
+	mgx_write_4(sc, ATR_DEC, dec);
+	mgx_write_4(sc, ATR_DST_XY, (y << 16) | x);
+	mgx_write_4(sc, ATR_WH, (he << 16) | wi);
+}
+
+static void
+mgx_putchar(void *cookie, int row, int col, u_int c, long attr)
+{
+	struct rasops_info *ri = cookie;
+	struct wsdisplay_font *font = PICK_FONT(ri, c);
+	struct vcons_screen *scr = ri->ri_hw;
+	struct mgx_softc *sc = scr->scr_cookie;
+	uint32_t fg, bg;
+	int x, y, wi, he, rv;
+
+	wi = font->fontwidth;
+	he = font->fontheight;
+
+	bg = (attr >> 16) & 0xf;
+	fg = (attr >> 24) & 0xf;
+
+	x = ri->ri_xorigin + col * wi;
+	y = ri->ri_yorigin + row * he;
+
+	if (c == 0x20) {
+		mgx_rectfill(sc, x, y, wi, he, bg);
+		if (attr & 1)
+			mgx_rectfill(sc, x, y + he - 2, wi, 1, fg);
+		return;
+	}
+	rv = glyphcache_try(&sc->sc_gc, c, x, y, attr);
+	if (rv == GC_OK)
+		return;
+	mgx_wait_engine(sc);
+	sc->sc_putchar(cookie, row, col, c, attr & ~1);
+
+	if (rv == GC_ADD) {
+		glyphcache_add(&sc->sc_gc, c, x, y);
+	} else {
+		if (attr & 1)
+			mgx_rectfill(sc, x, y + he - 2, wi, 1, fg);
+	}
+}
+
+static void
+mgx_cursor(void *cookie, int on, int row, int col)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct mgx_softc *sc = scr->scr_cookie;
+	int x, y, wi,he;
+
+	wi = ri->ri_font->fontwidth;
+	he = ri->ri_font->fontheight;
+
+	if (ri->ri_flg & RI_CURSOR) {
+		x = ri->ri_ccol * wi + ri->ri_xorigin;
+		y = ri->ri_crow * he + ri->ri_yorigin;
+		mgx_bitblt(sc, x, y, x, y, wi, he, ROP_INV);
+		ri->ri_flg &= ~RI_CURSOR;
+	}
+
+	ri->ri_crow = row;
+	ri->ri_ccol = col;
+
+	if (on)
+	{
+		x = ri->ri_ccol * wi + ri->ri_xorigin;
+		y = ri->ri_crow * he + ri->ri_yorigin;
+		mgx_bitblt(sc, x, y, x, y, wi, he, ROP_INV);
+		ri->ri_flg |= RI_CURSOR;
+	}
+}
+
+static void
+mgx_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct mgx_softc *sc = scr->scr_cookie;
+	int32_t xs, xd, y, width, height;
+
+	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;
+	mgx_bitblt(sc, xs, y, xd, y, width, height, ROP_SRC);
+}
+
+static void
+mgx_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct mgx_softc *sc = scr->scr_cookie;
+	int32_t x, y, width, height, bg;
+
+	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;
+	bg = (fillattr >> 16) & 0xff;
+	mgx_rectfill(sc, x, y, width, height, bg);
+}
+
+static void
+mgx_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct mgx_softc *sc = scr->scr_cookie;
+	int32_t x, ys, yd, width, height;
+
+	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;
+	mgx_bitblt(sc, x, ys, x, yd, width, height, ROP_SRC);
+}
+
+static void
+mgx_eraserows(void *cookie, int row, int nrows, long fillattr)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct mgx_softc *sc = scr->scr_cookie;
+	int32_t x, y, width, height, bg;
+
+	if ((row == 0) && (nrows == ri->ri_rows)) {
+		x = y = 0;
+		width = ri->ri_width;
+		height = ri->ri_height;
+	} else {
+		x = ri->ri_xorigin;
+		y = ri->ri_yorigin + ri->ri_font->fontheight * row;
+		width = ri->ri_emuwidth;
+		height = ri->ri_font->fontheight * nrows;
+	}
+	bg = (fillattr >> 16) & 0xff;
+	mgx_rectfill(sc, x, y, width, height, bg);
 }
 
 static void
@@ -284,14 +603,22 @@ mgx_init_screen(void *cookie, struct vco
 #endif
 
 	ri->ri_bits = sc->sc_fbaddr;
-	scr->scr_flags |= VCONS_DONT_READ;
 
 	rasops_init(ri, 0, 0);
+	sc->sc_putchar = ri->ri_ops.putchar;
 
 	ri->ri_caps = WSSCREEN_REVERSE | WSSCREEN_WSCOLORS;
 
 	rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight,
 		    ri->ri_width / ri->ri_font->fontwidth);
+
+	ri->ri_hw = scr;
+	ri->ri_ops.putchar   = mgx_putchar;
+	ri->ri_ops.cursor    = mgx_cursor;
+	ri->ri_ops.copyrows  = mgx_copyrows;
+	ri->ri_ops.eraserows = mgx_eraserows;
+	ri->ri_ops.copycols  = mgx_copycols;
+	ri->ri_ops.erasecols = mgx_erasecols;
 }
 
 static int
Index: src/sys/dev/sbus/mgxreg.h
diff -u src/sys/dev/sbus/mgxreg.h:1.1 src/sys/dev/sbus/mgxreg.h:1.2
--- src/sys/dev/sbus/mgxreg.h:1.1	Tue Dec 16 21:01:34 2014
+++ src/sys/dev/sbus/mgxreg.h	Sun Jan  4 18:18:20 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: mgxreg.h,v 1.1 2014/12/16 21:01:34 macallan Exp $ */
+/*	$NetBSD: mgxreg.h,v 1.2 2015/01/04 18:18:20 macallan Exp $ */
 
 /*-
  * Copyright (c) 2014 Michael Lorenz
@@ -31,4 +31,208 @@
 
 #define VGA_BASE 0x3c0
 
-#endif /* MGX_REG_H */
\ No newline at end of file
+/* register definitions based on OpenBSD's atxxreg.h: */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Alliance Promotion AP6422, AT24 and AT3D extended register set definitions.
+ *
+ * This has been reconstructed from XFree86 ``apm'' driver, whose authors
+ * apparently do not believe in meaningful constants for numbers. See
+ * apm_regs.h for more madness.
+ */
+
+/*
+ * Clipping Control
+ */
+
+#define ATR_CLIP_CONTROL                0x0030  /* byte access */
+#define ATR_CLIP_LEFT                   0x0038
+#define ATR_CLIP_TOP                    0x003a
+#define ATR_CLIP_LEFTTOP                0x0038
+#define ATR_CLIP_RIGHT                  0x003c
+#define ATR_CLIP_BOTTOM                 0x003e
+#define ATR_CLIP_RIGHTBOTTOM            0x003c
+
+/*
+ * Drawing Engine
+ */
+
+#define ATR_DEC                         0x0040
+#define ATR_ROP                         0x0046
+#define ATR_BYTEMASK                    0x0047
+#define ATR_PATTERN1                    0x0048
+#define ATR_PATTERN2                    0x004c
+#define ATR_SRC_X                       0x0050
+#define ATR_SRC_Y                       0x0052
+#define ATR_SRC_XY                      0x0050
+#define ATR_DST_X                       0x0054
+#define ATR_DST_Y                       0x0056
+#define ATR_DST_XY                      0x0054
+#define ATR_W                           0x0058
+#define ATR_H                           0x005a
+#define ATR_WH                          0x0058
+#define ATR_OFFSET                      0x005c
+#define ATR_SRC_OFFSET                  0x005e
+#define ATR_FG                          0x0060
+#define ATR_BG                          0x0064
+
+/* DEC layout */
+#define DEC_COMMAND_MASK                0x0000003f
+#define DEC_COMMAND_SHIFT               0
+#define DEC_DIR_X_REVERSE               0x00000040
+#define DEC_DIR_Y_REVERSE               0x00000080
+#define DEC_DIR_Y_MAJOR                 0x00000100
+#define DEC_SRC_LINEAR                  0x00000200
+#define DEC_SRC_CONTIGUOUS              0x00000800
+#define DEC_MONOCHROME                  0x00001000
+#define DEC_SRC_TRANSPARENT             0x00002000
+#define DEC_DEPTH_MASK                  0x0001c000
+#define DEC_DEPTH_SHIFT                 14
+#define DEC_DST_LINEAR                  0x00040000
+#define DEC_DST_CONTIGUOUS              0x00080000
+#define DEC_DST_TRANSPARENT             0x00100000
+#define DEC_DST_TRANSPARENT_POLARITY    0x00200000
+#define DEC_PATTERN_MASK                0x00c00000
+#define DEC_PATTERN_SHIFT               22
+#define DEC_WIDTH_MASK                  0x07000000
+#define DEC_WIDTH_SHIFT                 24
+#define DEC_UPDATE_MASK                 0x18000000
+#define DEC_UPDATE_SHIFT                27
+#define DEC_START_MASK                  0x60000000
+#define DEC_START_SHIFT                 29
+#define DEC_START                       0x80000000
+
+/* DEC commands */
+#define DEC_COMMAND_NOP                 0x00
+#define DEC_COMMAND_BLT                 0x01    /* screen to screen blt */
+#define DEC_COMMAND_RECT                0x02    /* rectangle fill */
+#define DEC_COMMAND_BLT_STRETCH         0x03    /* blt and stretch */
+#define DEC_COMMAND_STRIP               0x04    /* strip pattern */
+#define DEC_COMMAND_HOST_BLT            0x08    /* host to screen blt */
+#define DEC_COMMAND_SCREEN_BLT          0x09    /* screen to host blt */
+#define DEC_COMMAND_VECT_ENDP           0x0c    /* vector with end point */
+#define DEC_COMMAND_VECT_NO_ENDP        0x0d    /* vector without end point */
+
+/* depth */
+#define DEC_DEPTH_8                     0x01
+#define DEC_DEPTH_16                    0x02
+#define DEC_DEPTH_32                    0x03
+#define DEC_DEPTH_24                    0x04
+
+/* width */
+#define DEC_WIDTH_LINEAR                0x00
+#define DEC_WIDTH_640                   0x01
+#define DEC_WIDTH_800                   0x02
+#define DEC_WIDTH_1024                  0x04
+#define DEC_WIDTH_1152                  0x05
+#define DEC_WIDTH_1280                  0x06
+#define DEC_WIDTH_1600                  0x07
+
+/* update mode */
+#define DEC_UPDATE_NONE                 0x00
+#define DEC_UPDATE_TOP_RIGHT            0x01
+#define DEC_UPDATE_BOTTOM_LEFT          0x02
+#define DEC_UPDATE_LASTPIX              0x03
+
+/* quickstart mode - operation starts as soon as given register is written to */
+#define DEC_START_DIMX                  0x01
+#define DEC_START_SRC                   0x02
+#define DEC_START_DST                   0x03
+
+/* ROP */
+#define ROP_DST                         0x66
+#define ROP_SRC                         0xcc
+#define ROP_INV                         0x33
+#define ROP_PATTERN                     0xf0
+
+/*
+ * Configuration Registers
+ */
+
+#define ATR_PIXEL                       0x0080  /* byte access */
+#define PIXEL_DEPTH_MASK                0x0f
+#define PIXEL_DEPTH_SHIFT               0
+
+/* pixel depth */
+#define PIXEL_4                         0x01
+#define PIXEL_8                         0x02
+#define PIXEL_15                        0x0c
+#define PIXEL_16                        0x0d
+#define PIXEL_24                        0x0e
+#define PIXEL_32                        0x0f
+
+#define ATR_APERTURE                    0x00c0  /* short access */
+
+/*
+ * DPMS Control
+ */
+
+#define ATR_DPMS                        0x00d0  /* byte access */
+#define DPMS_HSYNC_DISABLE              0x01
+#define DPMS_VSYNC_DISABLE              0x02
+
+/*
+ * RAMDAC
+ */
+
+#define ATR_COLOR_CORRECTION            0x00e0
+#define ATR_MCLK                        0x00e8
+#define ATR_PCLK                        0x00ec
+
+/*
+ * Hardware Cursor
+ *
+ * The position can not become negative; the offset register, encoded as
+ * (signed y delta << 8) | signed x delta, allow the cursor image to
+ * cross the upper-left corner.
+ */
+
+#define ATR_CURSOR_ENABLE               0x0140
+#define ATR_CURSOR_FG                   0x0141  /* 3:3:2 */
+#define ATR_CURSOR_BG                   0x0142  /* 3:3:2 */
+#define ATR_CURSOR_ADDRESS              0x0144  /* in KB from vram */
+#define ATR_CURSOR_POSITION             0x0148
+#define ATR_CURSOR_OFFSET               0x014c  /* short access */
+
+/*
+ * Identification Register
+ */
+
+#define ATR_ID                          0x0182
+#define ID_AP6422                       0x6422
+#define ID_AT24                         0x6424
+#define ID_AT3D                         0x643d
+
+/*
+ * Status Registers
+ */
+
+#define ATR_FIFO_STATUS                 0x01fc
+#define ATR_BLT_STATUS                  0x01fd
+#define FIFO_MASK                       0x0f
+#define FIFO_SHIFT                      0
+#define FIFO_AP6422             4
+#define FIFO_AT24               8
+
+#define BLT_HOST_BUSY                   0x01
+#define BLT_ENGINE_BUSY                 0x04
+
+#define MGX_REG_ATREG_OFFSET		0x000b0000
+
+#endif /* MGX_REG_H */

Reply via email to