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