Index: arch/shark/conf/files.shark
===================================================================
RCS file: /cvsroot/src/sys/arch/shark/conf/files.shark,v
retrieving revision 1.17
diff -u -r1.17 files.shark
--- arch/shark/conf/files.shark	20 Feb 2008 21:43:35 -0000	1.17
+++ arch/shark/conf/files.shark	18 May 2008 16:46:55 -0000
@@ -122,6 +122,10 @@
 attach	vga at ofbus with vga_ofbus
 file	arch/shark/ofw/vga_ofbus.c		vga_ofbus	needs-flag
 
+# ofbus Chips & Technologies
+attach	chipsfb at ofbus with chipsfb_ofbus
+file	arch/shark/ofw/chipsfb_ofbus.c		chipsfb_ofbus needs-flag
+
 # ofbus CyberPro
 attach	igsfb at ofbus with igsfb_ofbus
 file	arch/shark/ofw/igsfb_ofbus.c		igsfb_ofbus needs-flag
Index: conf/files
===================================================================
RCS file: /cvsroot/src/sys/conf/files,v
retrieving revision 1.905
diff -u -r1.905 files
--- conf/files	5 May 2008 13:42:15 -0000	1.905
+++ conf/files	18 May 2008 16:46:55 -0000
@@ -1037,6 +1037,13 @@
 file	dev/ic/vga_raster.c	vga_rasterconsole		needs-flag
 file	dev/ic/vga_subr.c	vga | vga_rasterconsole
 file	dev/ic/vga_common.c	vga | vga_rasterconsole
+
+# Chips & Technologies 655x0 framebuffers (linear non-VGA mode)
+#
+device	chipsfb: wsemuldisplaydev, wsrasteremulops, rasops8, vcons, videomode
+file	dev/ic/chipsfb.c		chipsfb			needs-flag
+defflag opt_chipsfb.h	CHIPSFB_DEBUG CHIPSFB_WAIT
+
 # Integraphics Systems IGA168x and CyberPro framebuffers (linear non-VGA mode)
 #
 device	igsfb: wsemuldisplaydev, wsrasteremulops, rasops8, vcons
Index: dev/pci/files.pci
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/files.pci,v
retrieving revision 1.303
diff -u -r1.303 files.pci
--- dev/pci/files.pci	29 Mar 2008 00:16:26 -0000	1.303
+++ dev/pci/files.pci	18 May 2008 16:49:02 -0000
@@ -805,11 +805,8 @@
 file	dev/pci/cxgb_osdep.c		cxgbc | cxgb
 
 # Chips & Technologies 65550 framebuffer console driver
-device	chipsfb: wsemuldisplaydev, rasops8, vcons, videomode
-attach	chipsfb at pci
-file	dev/pci/chipsfb.c		chipsfb
-defflag	opt_chipsfb.h	CHIPSFB_DEBUG
-defflag	opt_chipsfb.h	CHIPSFB_WAIT
+attach	chipsfb at pci with chipsfb_pci
+file	dev/pci/chipsfb_pci.c		chipsfb_pci
 
 # 3Com 3c990
 device	txp: ether, ifnet, arp
--- /dev/null	2008-05-18 21:24:23.000000000 +0900
+++ arch/shark/ofw/chipsfb_ofbus.c	2007-09-20 01:15:21.000000000 +0900
@@ -0,0 +1,122 @@
+/*	$NetBSD$	*/
+
+/*
+ * Copyright (c) 2006 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+/*
+ * ofbus attachment for Chips & Technologies 65550 graphics controllers
+ * found on some DNARD compatibles
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+#include <machine/ofw.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>
+
+#include <dev/ofw/openfirm.h>
+
+#include <dev/isa/isavar.h>
+
+#include <dev/ic/chipsfbreg.h>
+#include <dev/ic/chipsfbvar.h>
+
+#define CHIPSFB_BASE	0x06800000
+#define CHIPSFB_SIZE	(2 * 1024 * 1024)
+
+static int	chipsfb_ofbus_match(struct device *, struct cfdata *, void *);
+static void	chipsfb_ofbus_attach(struct device *, struct device *, void *);
+
+CFATTACH_DECL(chipsfb_ofbus, sizeof(struct chipsfb_softc),
+    chipsfb_ofbus_match, chipsfb_ofbus_attach, NULL, NULL);
+
+static const char const *compat_strings[] = { "CHPS,ct65550", NULL };
+
+vaddr_t chipsfb_mem_vaddr = 0;
+vaddr_t chipsfb_mem_paddr;
+struct bus_space chipsfb_memt;
+
+static int
+chipsfb_ofbus_match(struct device *parent, struct cfdata *match, void *aux)
+{
+	struct ofbus_attach_args *oba = (void *)aux;
+
+	if (of_compatible(oba->oba_phandle, compat_strings) < 0)
+		return 0;
+
+	return 10;	/* beat vga etc. */
+}
+
+static void
+chipsfb_ofbus_attach(struct device *parent, struct device *self, void *aux)
+{
+	struct chipsfb_softc *sc = (void *)self;
+	struct ofbus_attach_args *oba = aux;
+	int chipsfb_node;
+	uint32_t regs[6];
+
+	chipsfb_node = oba->oba_phandle;
+
+	if (OF_getprop(chipsfb_node, "reg", regs, sizeof(regs)) <= 0) {
+		printf(": can't get properties\n");
+		return;
+	}
+
+	sc->sc_memt = &isa_mem_bs_tag;	/* XXX */
+	sc->sc_iot  = &isa_io_bs_tag;	/* XXX */
+
+	/* the framebuffer */
+	chipsfb_mem_paddr = CHIPSFB_BASE;
+	chipsfb_mem_vaddr = ofw_map(chipsfb_mem_paddr, CHIPSFB_SIZE, 0);
+	memcpy(&chipsfb_memt, sc->sc_memt, sizeof (struct bus_space));
+	chipsfb_memt.bs_cookie = (void *)chipsfb_mem_vaddr;
+
+	sc->sc_fbt = &chipsfb_memt;
+	sc->sc_fb = 0;
+	sc->sc_fbsize = CHIPSFB_SIZE;
+
+	/* IO-mapped registers */
+	if (bus_space_map(sc->sc_iot, CT_VGAREG_OFF, CT_VGAREG_SIZE,
+	    0, &sc->sc_ioregh) != 0) {
+		aprint_error("%s: failed to map IO registers.\n",
+		    sc->sc_dev.dv_xname);
+	}
+
+	chipsfb_attach(sc);
+}
--- /dev/null	2008-05-18 21:24:23.000000000 +0900
+++ dev/ic/chipsfb.c	2007-09-20 00:40:06.000000000 +0900
@@ -0,0 +1,910 @@
+/*	$NetBSD$	*/
+
+/*
+ * Copyright (c) 2006 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+/*
+ * MI part of Chips & Technologies 65550 graphics controller driver
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: chipsfb.c,v 1.12 2007/08/19 15:57:24 he Exp $");
+
+#include "opt_wsemul.h"
+#include "opt_chipsfb.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/callout.h>
+#include <sys/lwp.h>
+#include <sys/kauth.h>
+#include <sys/proc.h>
+
+#include <machine/bus.h>
+
+#include <dev/videomode/videomode.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>
+
+#include <dev/i2c/i2cvar.h>
+
+#include <dev/ic/chipsfbreg.h>
+#include <dev/ic/chipsfbvar.h>
+
+static struct vcons_screen chipsfb_console_screen;
+
+extern const u_char rasops_cmap[768];
+
+static void 	chipsfb_init(struct chipsfb_softc *);
+
+static void	chipsfb_cursor(void *, int, int, int);
+static void	chipsfb_copycols(void *, int, int, int, int);
+static void	chipsfb_erasecols(void *, int, int, int, long);
+static void	chipsfb_copyrows(void *, int, int, int);
+static void	chipsfb_eraserows(void *, int, int, long);
+
+#if 0
+static int	chipsfb_allocattr(void *, int, int, int, long *);
+static void	chipsfb_scroll(void *, void *, int);
+static int	chipsfb_load_font(void *, void *, struct wsdisplay_font *);
+#endif
+
+static int	chipsfb_putcmap(struct chipsfb_softc *,
+			    struct wsdisplay_cmap *);
+static int 	chipsfb_getcmap(struct chipsfb_softc *,
+			    struct wsdisplay_cmap *);
+static int 	chipsfb_putpalreg(struct chipsfb_softc *, uint8_t, uint8_t,
+			    uint8_t, uint8_t);
+
+static void	chipsfb_bitblt(struct chipsfb_softc *, int, int, int, int,
+			    int, int, uint8_t);
+static void	chipsfb_rectfill(struct chipsfb_softc *, int, int, int, int,
+			    int);
+static void	chipsfb_putchar(void *, int, int, u_int, long);
+static void	chipsfb_setup_mono(struct chipsfb_softc *, int, int, int,
+			    int, uint32_t, uint32_t);
+static void	chipsfb_feed(struct chipsfb_softc *, int, uint8_t *);
+
+#if 0
+static void	chipsfb_showpal(struct chipsfb_softc *);
+#endif
+static void	chipsfb_restore_palette(struct chipsfb_softc *);
+
+static void	chipsfb_wait_idle(struct chipsfb_softc *);
+
+static uint32_t chipsfb_probe_vram(struct chipsfb_softc *);
+
+static int	chipsfb_ioctl(void *, void *, u_long, void *, int,
+		    struct lwp *);
+static paddr_t	chipsfb_mmap(void *, void *, off_t, int);
+static void	chipsfb_clearscreen(struct chipsfb_softc *);
+static void	chipsfb_init_screen(void *, struct vcons_screen *, int, long *);
+
+struct wsscreen_descr chipsfb_defaultscreen = {
+	"default",
+	0, 0,
+	NULL,
+	8, 16,
+	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
+};
+
+const struct wsscreen_descr *_chipsfb_scrlist[] = {
+	&chipsfb_defaultscreen,
+	/* XXX other formats, graphics screen? */
+};
+
+struct wsscreen_list chipsfb_screenlist = {
+	sizeof(_chipsfb_scrlist) / sizeof(struct wsscreen_descr *),
+	    _chipsfb_scrlist
+};
+
+
+struct wsdisplay_accessops chipsfb_accessops = {
+	chipsfb_ioctl,
+	chipsfb_mmap,
+	NULL,	/* load_font */
+	NULL,	/* polls */
+	NULL,	/* scroll */
+};
+
+/*
+ * Inline functions for getting access to register aperture.
+ */
+static inline void
+chipsfb_write32(struct chipsfb_softc *sc, uint32_t reg, uint32_t val)
+{
+
+	bus_space_write_4(sc->sc_fbt, sc->sc_fbh, reg, val);
+}
+
+static inline uint32_t
+chipsfb_read32(struct chipsfb_softc *sc, uint32_t reg)
+{
+
+	return bus_space_read_4(sc->sc_fbt, sc->sc_fbh, reg);
+}
+
+static inline void
+chipsfb_write_vga(struct chipsfb_softc *sc, uint32_t reg,  uint8_t val)
+{
+
+	bus_space_write_1(sc->sc_iot, sc->sc_ioregh, reg, val);
+}
+
+static inline uint8_t
+chipsfb_read_vga(struct chipsfb_softc *sc, uint32_t reg)
+{
+
+	return bus_space_read_1(sc->sc_iot, sc->sc_ioregh, reg);
+}
+
+static inline uint8_t
+chipsfb_read_indexed(struct chipsfb_softc *sc, uint32_t reg, uint8_t index)
+{
+
+	chipsfb_write_vga(sc, reg & 0xfffe, index);
+	return chipsfb_read_vga(sc, reg | 0x0001);
+}
+
+static inline void
+chipsfb_write_indexed(struct chipsfb_softc *sc, uint32_t reg, uint8_t index,
+    uint8_t val)
+{
+
+	chipsfb_write_vga(sc, reg & 0xfffe, index);
+	chipsfb_write_vga(sc, reg | 0x0001, val);
+}
+
+static void
+chipsfb_wait_idle(struct chipsfb_softc *sc)
+{
+
+#ifdef CHIPSFB_DEBUG
+	chipsfb_write32(sc, CT_OFF_FB + (800 * 598) - 4, 0);
+#endif
+
+	/* spin until the blitter is idle */
+	while ((chipsfb_read32(sc, CT_BLT_CONTROL) & BLT_IS_BUSY) != 0) {
+	}
+
+#ifdef CHIPSFB_DEBUG
+	chipsfb_write32(sc, CT_OFF_FB + (800 * 598) - 4, 0xffffffff);
+#endif
+}
+
+void
+chipsfb_attach(struct chipsfb_softc *sc)
+{
+	struct wsemuldisplaydev_attach_args aa;
+	struct rasops_info *ri;
+	prop_dictionary_t dict;
+	ulong defattr;
+	bool console = false;
+	int width, height, i, j;
+	uint32_t bg, fg, ul;
+
+	dict = device_properties(&sc->sc_dev);
+	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
+	sc->sc_dacw = -1;
+
+#ifdef CHIPSFB_DEBUG
+	printf(prop_dictionary_externalize(dict));
+#endif
+
+	sc->memsize = chipsfb_probe_vram(sc);
+	chipsfb_init(sc);
+
+	/* we should read these from the chip instead of depending on OF */
+	width = height = -1;
+
+	/* detect panel size */
+	width = chipsfb_read_indexed(sc, CT_FP_INDEX, FP_HSIZE_LSB);
+	width |= (chipsfb_read_indexed(sc, CT_FP_INDEX, FP_HORZ_OVERFLOW_1)
+	    & 0x0f) << 8;
+	width = (width + 1) * 8;
+	height = chipsfb_read_indexed(sc, CT_FP_INDEX, FP_VSIZE_LSB);
+	height |= (chipsfb_read_indexed(sc, CT_FP_INDEX, FP_VERT_OVERFLOW_1)
+	    & 0x0f) << 8;
+	height++;
+	aprint_verbose("Panel size: %d x %d\n", width, height);
+
+	if (!prop_dictionary_get_uint32(dict, "width", &sc->width))
+		sc->width = width;
+	if (!prop_dictionary_get_uint32(dict, "height", &sc->height))
+		sc->height = height;
+	if (!prop_dictionary_get_uint32(dict, "depth", &sc->bits_per_pixel))
+		sc->bits_per_pixel = 8;
+	if (!prop_dictionary_get_uint32(dict, "linebytes", &sc->linebytes))
+		sc->linebytes = (sc->width * sc->bits_per_pixel) >> 3;
+
+	prop_dictionary_get_bool(dict, "is_console", &console);
+
+#ifdef notyet
+	/* XXX this should at least be configurable via kernel config */
+	chipsfb_set_videomode(sc, &videomode_list[16]);
+#endif
+
+	vcons_init(&sc->vd, sc, &chipsfb_defaultscreen, &chipsfb_accessops);
+	sc->vd.init_screen = chipsfb_init_screen;
+
+	ri = &chipsfb_console_screen.scr_ri;
+	if (console) {
+		vcons_init_screen(&sc->vd, &chipsfb_console_screen, 1,
+		    &defattr);
+		chipsfb_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
+
+		chipsfb_defaultscreen.textops = &ri->ri_ops;
+		chipsfb_defaultscreen.capabilities = ri->ri_caps;
+		chipsfb_defaultscreen.nrows = ri->ri_rows;
+		chipsfb_defaultscreen.ncols = ri->ri_cols;
+		wsdisplay_cnattach(&chipsfb_defaultscreen, ri, 0, 0, defattr);
+	} else {
+		/*
+		 * since we're not the console we can postpone the rest
+		 * until someone actually allocates a screen for us
+		 */
+#ifdef notyet
+		chipsfb_set_videomode(sc, &videomode_list[0]);
+#endif
+	}
+
+	rasops_unpack_attr(defattr, &fg, &bg, &ul);
+	sc->sc_bg = ri->ri_devcmap[bg];
+	chipsfb_clearscreen(sc);
+
+	aprint_normal("%s: %d MB aperture, %d MB VRAM at 0x%08x\n",
+	    sc->sc_dev.dv_xname, (u_int)(sc->sc_fbsize >> 20),
+	    (u_int)sc->memsize >> 20, (u_int)sc->sc_fb);
+#ifdef CHIPSFB_DEBUG
+	aprint_debug("fb: %08lx\n", (ulong)ri->ri_bits);
+#endif
+
+	j = 0;
+	for (i = 0; i < 256; i++) {
+		chipsfb_putpalreg(sc, i, rasops_cmap[j], rasops_cmap[j + 1],
+		    rasops_cmap[j + 2]);
+		j += 3;
+	}
+
+	aa.console = console;
+	aa.scrdata = &chipsfb_screenlist;
+	aa.accessops = &chipsfb_accessops;
+	aa.accesscookie = &sc->vd;
+
+	config_found(&sc->sc_dev, &aa, wsemuldisplaydevprint);
+}
+
+static int
+chipsfb_putpalreg(struct chipsfb_softc *sc, uint8_t index, uint8_t r,
+    uint8_t g, uint8_t b)
+{
+
+	sc->sc_cmap_red[index] = r;
+	sc->sc_cmap_green[index] = g;
+	sc->sc_cmap_blue[index] = b;
+
+	chipsfb_write_vga(sc, CT_DACMASK, 0xff);
+	chipsfb_write_vga(sc, CT_WRITEINDEX, index);
+	chipsfb_write_vga(sc, CT_DACDATA, r);
+	chipsfb_write_vga(sc, CT_DACDATA, g);
+	chipsfb_write_vga(sc, CT_DACDATA, b);
+
+	return 0;
+}
+
+static int
+chipsfb_putcmap(struct chipsfb_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];
+
+#ifdef CHIPSFB_DEBUG
+	aprint_debug("putcmap: %d %d\n",index, count);
+#endif
+	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++) {
+		chipsfb_putpalreg(sc, index, *r, *g, *b);
+		index++;
+		r++, g++, b++;
+	}
+	return 0;
+}
+
+static int
+chipsfb_getcmap(struct chipsfb_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
+chipsfb_clearscreen(struct chipsfb_softc *sc)
+{
+	chipsfb_rectfill(sc, 0, 0, sc->width, sc->height, sc->sc_bg);
+}
+
+/*
+ * wsdisplay_emulops
+ */
+
+static void
+chipsfb_cursor(void *cookie, int on, int row, int col)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct chipsfb_softc *sc = scr->scr_cookie;
+	int x, y, wi, he;
+
+	wi = ri->ri_font->fontwidth;
+	he = ri->ri_font->fontheight;
+
+	if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
+		x = ri->ri_ccol * wi + ri->ri_xorigin;
+		y = ri->ri_crow * he + ri->ri_yorigin;
+		if (ri->ri_flg & RI_CURSOR) {
+			chipsfb_bitblt(sc, x, y, x, y, wi, he, ROP_NOT_DST);
+			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;
+			chipsfb_bitblt(sc, x, y, x, y, wi, he, ROP_NOT_DST);
+			ri->ri_flg |= RI_CURSOR;
+		}
+	} else {
+		ri->ri_flg &= ~RI_CURSOR;
+		ri->ri_crow = row;
+		ri->ri_ccol = col;
+	}
+}
+
+#if 0
+int
+chipsfb_mapchar(void *cookie, int uni, u_int *index)
+{
+	return 0;
+}
+#endif
+
+static void
+chipsfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct chipsfb_softc *sc = scr->scr_cookie;
+	int32_t xs, xd, y, width, height;
+
+	if (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;
+		chipsfb_bitblt(sc, xs, y, xd, y, width, height, ROP_COPY);
+	}
+}
+
+static void
+chipsfb_erasecols(void *cookie, int row, int startcol, int ncols,
+    long fillattr)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct chipsfb_softc *sc = scr->scr_cookie;
+	int32_t x, y, width, height, fg, bg, ul;
+
+	if (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);
+
+		chipsfb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]);
+	}
+}
+
+static void
+chipsfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct chipsfb_softc *sc = scr->scr_cookie;
+	int32_t x, ys, yd, width, height;
+
+	if (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;
+		chipsfb_bitblt(sc, x, ys, x, yd, width, height, ROP_COPY);
+	}
+}
+
+static void
+chipsfb_eraserows(void *cookie, int row, int nrows, long fillattr)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct chipsfb_softc *sc = scr->scr_cookie;
+	int32_t x, y, width, height, fg, bg, ul;
+
+	if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
+		rasops_unpack_attr(fillattr, &fg, &bg, &ul);
+		if ((row == 0) && (nrows == ri->ri_rows)) {
+			/* clear the whole screen */
+			chipsfb_rectfill(sc, 0, 0, ri->ri_width,
+			    ri->ri_height, ri->ri_devcmap[bg]);
+		} else {
+			x = ri->ri_xorigin;
+			y = ri->ri_yorigin + ri->ri_font->fontheight * row;
+			width = ri->ri_emuwidth;
+			height = ri->ri_font->fontheight * nrows;
+			chipsfb_rectfill(sc, x, y, width, height,
+			    ri->ri_devcmap[bg]);
+		}
+	}
+}
+
+static void
+chipsfb_bitblt(struct chipsfb_softc *sc, int xs, int ys, int xd, int yd,
+    int width, int height, uint8_t rop)
+{
+	uint32_t src, dst, cmd = rop, stride, size;
+
+	cmd |= BLT_PAT_IS_SOLID;
+
+	/* we assume 8 bit for now */
+	src = xs + ys * sc->linebytes;
+	dst = xd + yd * sc->linebytes;
+
+	if (xs < xd) {
+		/* right-to-left operation */
+		cmd |= BLT_START_RIGHT;
+		src += width - 1;
+		dst += width - 1;
+	}
+
+	if (ys < yd) {
+		/* bottom-to-top operation */
+		cmd |= BLT_START_BOTTOM;
+		src += (height - 1) * sc->linebytes;
+		dst += (height - 1) * sc->linebytes;
+	}
+
+	stride = (sc->linebytes << 16) | sc->linebytes;
+	size = (height << 16) | width;
+
+	chipsfb_wait_idle(sc);
+	chipsfb_write32(sc, CT_BLT_STRIDE, stride);
+	chipsfb_write32(sc, CT_BLT_SRCADDR, src);
+	chipsfb_write32(sc, CT_BLT_DSTADDR, dst);
+	chipsfb_write32(sc, CT_BLT_CONTROL, cmd);
+	chipsfb_write32(sc, CT_BLT_SIZE, size);
+#ifdef CHIPSFB_WAIT
+	chipsfb_wait_idle(sc);
+#endif
+}
+
+static void
+chipsfb_rectfill(struct chipsfb_softc *sc, int x, int y, int width,
+    int height, int colour)
+{
+	uint32_t dst, cmd, stride, size;
+
+	cmd = BLT_PAT_IS_SOLID | BLT_PAT_IS_MONO | ROP_PAT;
+
+	/* we assume 8 bit for now */
+	dst = x + y * sc->linebytes;
+
+	stride = (sc->linebytes << 16) | sc->linebytes;
+	size = (height << 16) | width;
+
+	chipsfb_wait_idle(sc);
+	chipsfb_write32(sc, CT_BLT_STRIDE, stride);
+	chipsfb_write32(sc, CT_BLT_SRCADDR, dst);
+	chipsfb_write32(sc, CT_BLT_DSTADDR, dst);
+	chipsfb_write32(sc, CT_BLT_CONTROL, cmd);
+	chipsfb_write32(sc, CT_BLT_BG, colour);
+	chipsfb_write32(sc, CT_BLT_FG, colour);
+	chipsfb_write32(sc, CT_BLT_SIZE, size);
+#ifdef CHIPSFB_WAIT
+	chipsfb_wait_idle(sc);
+#endif
+}
+
+static void
+chipsfb_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 chipsfb_softc *sc = scr->scr_cookie;
+
+	if (__predict_false((unsigned int)row > ri->ri_rows ||
+	    (unsigned int)col > ri->ri_cols))
+		return;
+
+	if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
+		uint8_t *data;
+		int fg, bg, uc;
+		int x, y, wi, he;
+
+		wi = ri->ri_font->fontwidth;
+		he = ri->ri_font->fontheight;
+
+		if (!CHAR_IN_FONT(c, ri->ri_font))
+			return;
+		bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf];
+		fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf];
+		x = ri->ri_xorigin + col * wi;
+		y = ri->ri_yorigin + row * he;
+		if (c == 0x20) {
+			chipsfb_rectfill(sc, x, y, wi, he, bg);
+		} else {
+			uc = c-ri->ri_font->firstchar;
+			data = (uint8_t *)ri->ri_font->data + uc *
+			    ri->ri_fontscale;
+			chipsfb_setup_mono(sc, x, y, wi, he, fg, bg);
+			chipsfb_feed(sc, ri->ri_font->stride * he, data);
+		}
+	}
+}
+
+static void
+chipsfb_setup_mono(struct chipsfb_softc *sc, int xd, int yd, int width,
+    int height, uint32_t fg, uint32_t bg)
+{
+	uint32_t dst, cmd, stride, size;
+
+	cmd = BLT_PAT_IS_SOLID | BLT_SRC_IS_CPU | BLT_SRC_IS_MONO | ROP_COPY;
+
+	/* we assume 8 bit for now */
+	dst = xd + yd * sc->linebytes;
+
+	stride = (sc->linebytes << 16);
+	size = (height << 16) | width;
+
+	chipsfb_wait_idle(sc);
+	chipsfb_write32(sc, CT_BLT_STRIDE, stride);
+	chipsfb_write32(sc, CT_BLT_EXPCTL, MONO_SRC_ALIGN_BYTE);
+	chipsfb_write32(sc, CT_BLT_DSTADDR, dst);
+	chipsfb_write32(sc, CT_BLT_SRCADDR, 0);
+	chipsfb_write32(sc, CT_BLT_CONTROL, cmd);
+	chipsfb_write32(sc, CT_BLT_BG, bg);
+	chipsfb_write32(sc, CT_BLT_FG, fg);
+	chipsfb_write32(sc, CT_BLT_SIZE, size);
+}
+
+static void
+chipsfb_feed(struct chipsfb_softc *sc, int count, uint8_t *data)
+{
+	int i;
+	uint32_t latch = 0, bork;
+	int shift = 0;
+
+	for (i = 0; i < count; i++) {
+		bork = data[i];
+		latch |= (bork << shift);
+		if (shift == 24) {
+			chipsfb_write32(sc, CT_OFF_DATA, latch);
+			latch = 0;
+			shift = 0;
+		} else
+			shift += 8;
+	}
+
+	if (shift != 0) {
+		chipsfb_write32(sc, CT_OFF_DATA, latch);
+	}
+
+	/* apparently the chip wants 64bit-aligned data or it won't go idle */
+	if ((count + 3) & 0x04) {
+		chipsfb_write32(sc, CT_OFF_DATA, 0);
+	}
+#ifdef CHIPSFB_WAIT
+	chipsfb_wait_idle(sc);
+#endif
+}
+
+#if 0
+static void
+chipsfb_showpal(struct chipsfb_softc *sc)
+{
+	int i, x = 0;
+
+	for (i = 0; i < 16; i++) {
+		chipsfb_rectfill(sc, x, 0, 64, 64, i);
+		x += 64;
+	}
+}
+#endif
+
+#if 0
+static int
+chipsfb_allocattr(void *cookie, int fg, int bg, int flags, long *attrp)
+{
+
+	return 0;
+}
+#endif
+
+static void
+chipsfb_restore_palette(struct chipsfb_softc *sc)
+{
+	int i;
+
+	for (i = 0; i < 256; i++) {
+		chipsfb_putpalreg(sc,
+		   i,
+		   sc->sc_cmap_red[i],
+		   sc->sc_cmap_green[i],
+		   sc->sc_cmap_blue[i]);
+	}
+}
+
+/*
+ * wsdisplay_accessops
+ */
+
+static int
+chipsfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
+	struct lwp *l)
+{
+	struct vcons_data *vd = v;
+	struct chipsfb_softc *sc = vd->cookie;
+	struct wsdisplay_fbinfo *wdf;
+	struct vcons_screen *ms = vd->active;
+
+	switch (cmd) {
+		case WSDISPLAYIO_GTYPE:
+			*(u_int *)data = WSDISPLAY_TYPE_PCIMISC;
+			return 0;
+
+		case WSDISPLAYIO_GINFO:
+			wdf = (void *)data;
+			wdf->height = ms->scr_ri.ri_height;
+			wdf->width = ms->scr_ri.ri_width;
+			wdf->depth = ms->scr_ri.ri_depth;
+			wdf->cmsize = 256;
+			return 0;
+
+		case WSDISPLAYIO_GETCMAP:
+			return chipsfb_getcmap(sc,
+			    (struct wsdisplay_cmap *)data);
+
+		case WSDISPLAYIO_PUTCMAP:
+			return chipsfb_putcmap(sc,
+			    (struct wsdisplay_cmap *)data);
+
+#if 0
+		/* PCI config read/write passthrough. */
+		case PCI_IOC_CFGREAD:
+		case PCI_IOC_CFGWRITE:
+			return (pci_devioctl(sc->sc_pc, sc->sc_pcitag,
+			    cmd, data, flag, l));
+#endif
+
+		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) {
+						chipsfb_restore_palette(sc);
+						vcons_redraw_screen(ms);
+					}
+				}
+			}
+			return 0;
+	}
+	return EPASSTHROUGH;
+}
+
+static paddr_t
+chipsfb_mmap(void *v, void *vs, off_t offset, int prot)
+{
+	struct vcons_data *vd = v;
+	struct chipsfb_softc *sc = vd->cookie;
+	struct lwp *me;
+	paddr_t pa;
+
+	/* 'regular' framebuffer mmap()ing */
+	if (offset < sc->memsize) {
+		pa = bus_space_mmap(sc->sc_fbt, offset, 0, prot,
+		    BUS_SPACE_MAP_LINEAR);
+		return pa;
+	}
+
+	/*
+	 * restrict all other mappings to processes with superuser privileges
+	 * or the kernel itself
+	 */
+	me = curlwp;
+	if (me != NULL) {
+		if (kauth_authorize_generic(me->l_cred, KAUTH_GENERIC_ISSUSER,
+		    NULL) != 0) {
+			aprint_normal("%s: mmap() rejected.\n", sc->sc_dev.dv_xname);
+			return -1;
+		}
+	}
+
+	if ((offset >= sc->sc_fb) && (offset < (sc->sc_fb + sc->sc_fbsize))) {
+		pa = bus_space_mmap(sc->sc_memt, offset, 0, prot,
+		    BUS_SPACE_MAP_LINEAR);
+		return pa;
+	}
+
+#ifdef macppc
+	/* allow mapping of IO space */
+	if ((offset >= 0xf2000000) && (offset < 0xf2800000)) {
+		pa = bus_space_mmap(sc->sc_iot, offset - 0xf2000000, 0, prot,
+		    BUS_SPACE_MAP_LINEAR);
+		return pa;
+	}
+#endif
+
+#ifdef OFB_ALLOW_OTHERS
+	if (offset >= 0x80000000) {
+		pa = bus_space_mmap(sc->sc_memt, offset, 0, prot,
+		    BUS_SPACE_MAP_LINEAR);
+		return pa;
+	}
+#endif
+	return -1;
+}
+
+static void
+chipsfb_init_screen(void *cookie, struct vcons_screen *scr,
+    int existing, long *defattr)
+{
+	struct chipsfb_softc *sc = cookie;
+	struct rasops_info *ri = &scr->scr_ri;
+
+	ri->ri_depth = sc->bits_per_pixel;
+	ri->ri_width = sc->width;
+	ri->ri_height = sc->height;
+	ri->ri_stride = sc->width;
+	ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
+
+	ri->ri_bits = bus_space_vaddr(sc->sc_fbt, sc->sc_fbh);
+
+#ifdef CHIPSFB_DEBUG
+	aprint_debug("addr: %08lx\n", (ulong)ri->ri_bits);
+#endif
+	if (existing) {
+		ri->ri_flg |= RI_CLEAR;
+	}
+
+	rasops_init(ri, sc->height/8, sc->width/8);
+	ri->ri_caps = WSSCREEN_WSCOLORS;
+
+	rasops_reconfig(ri, sc->height / ri->ri_font->fontheight,
+		    sc->width / ri->ri_font->fontwidth);
+
+	ri->ri_hw = scr;
+	ri->ri_ops.copyrows = chipsfb_copyrows;
+	ri->ri_ops.copycols = chipsfb_copycols;
+	ri->ri_ops.eraserows = chipsfb_eraserows;
+	ri->ri_ops.erasecols = chipsfb_erasecols;
+	ri->ri_ops.cursor = chipsfb_cursor;
+	ri->ri_ops.putchar = chipsfb_putchar;
+}
+
+#if 0
+int
+chipsfb_load_font(void *v, void *cookie, struct wsdisplay_font *data)
+{
+
+	return 0;
+}
+#endif
+
+static void
+chipsfb_init(struct chipsfb_softc *sc)
+{
+
+	chipsfb_wait_idle(sc);
+
+	chipsfb_write_indexed(sc, CT_CONF_INDEX, XR_IO_CONTROL,
+	    ENABLE_CRTC_EXT | ENABLE_ATTR_EXT);
+	chipsfb_write_indexed(sc, CT_CONF_INDEX, XR_ADDR_MAPPING,
+	    ENABLE_LINEAR);
+
+	/* setup the blitter */
+}
+
+static uint32_t
+chipsfb_probe_vram(struct chipsfb_softc *sc)
+{
+	uint32_t ofs = 0x00080000;	/* 512kB */
+
+	/*
+	 * advance in 0.5MB steps, see if we can read back what we wrote and
+	 * if what we wrote to 0 is left untouched. Max. fb size is 4MB so
+	 * we voluntarily stop there.
+	 */
+	chipsfb_write32(sc, 0, 0xf0f0f0f0);
+	chipsfb_write32(sc, ofs, 0x0f0f0f0f);
+	while ((chipsfb_read32(sc, 0) == 0xf0f0f0f0) &&
+	    (chipsfb_read32(sc, ofs) == 0x0f0f0f0f) &&
+	    (ofs < 0x00400000)) {
+
+		ofs += 0x00080000;
+		chipsfb_write32(sc, ofs, 0x0f0f0f0f);
+	}
+
+	return ofs;
+}
--- /dev/null	2008-05-18 21:24:23.000000000 +0900
+++ dev/ic/chipsfbreg.h	2007-09-20 00:25:07.000000000 +0900
@@ -0,0 +1,436 @@
+/*	$NetBSD: chipsfbreg.h,v 1.2 2006/09/27 05:19:23 macallan Exp $	*/
+
+/*
+ * Copyright 2006 by Michael Lorenz.
+ *
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *
+*/
+
+#ifndef CHIPSFB_H
+#define CHIPSFB_H
+
+#define CT_VGAREG_OFF	0x3c0
+#define CT_VGAREG_SIZE	0x20
+
+/* VGA */
+#define CRTC_INDEX	0x14
+#define CRTC_DATA	0x15
+#define SEQ_INDEX	0x04
+#define SEQ_DATA	0x05
+#define MISC_W		0x02
+#define GRA_INDEX	0x0e
+#define GRA_DATA	0x0f
+#define ATT_IW		0x00
+
+/* palette */
+#define CT_DACMASK	0x06
+#define CT_DACSTATE	0x07	/* read only */
+#define CT_READINDEX	0x07	/* write only */
+#define CT_WRITEINDEX	0x08
+#define CT_DACDATA	0x09
+
+/* extended VGA */
+#define CT_FP_INDEX	0x10
+#define CT_FP_DATA	0x11
+#define CT_MM_INDEX	0x12
+#define CT_MM_DATA	0x13
+#define CT_CONF_INDEX	0x16
+#define CT_CONF_DATA	0x17
+
+/* offsets in aperture */
+#define CT_OFF_FB	0x00000000
+#define CT_OFF_BITBLT	0x00400000
+#define CT_OFF_DRAW	0x00400040
+#define CT_OFF_DATA	0x00410000
+
+#define CT_OFF_BE	0x00800000
+
+/* blitter registers */
+#define CT_BLT_STRIDE	CT_OFF_BITBLT
+	/* 
+	 * upper 16 bit are destination stride in bytes
+	 * lower 16 bit are source stride in bytes
+	 */
+	 
+#define CT_BLT_BG	CT_OFF_BITBLT + 0x04
+#define CT_BLT_FG	CT_OFF_BITBLT + 0x08
+#define CT_BLT_EXPCTL	CT_OFF_BITBLT + 0x0c	/* expansion control */
+	#define LEFT_CLIPPING_MSK	0x0000003f
+	#define MONO_RIGHT_CLIPPING_MSK	0x00003f00
+	#define MONO_INITIAL_DISCARD	0x003f0000
+	#define MONO_SRC_ALIGN_MASK	0x07000000
+	#define MONO_SRC_ALIGN_BIT	0x01000000
+	#define MONO_SRC_ALIGN_BYTE	0x02000000
+	#define MONO_SRC_ALIGN_WORD	0x03000000
+	#define MONO_SRC_ALIGN_LONG	0x04000000
+	#define MONO_SRC_ALIGN_LONGLONG	0x05000000
+	#define MONO_SELECT_ALT_FG_BG	0x08000000 /* use CT_SRC_EXP_* */
+	
+#define CT_BLT_CONTROL	CT_OFF_BITBLT + 0x10
+	#define BLT_ROP_MASK		0x000000ff
+	#define BLT_START_RIGHT		0x00000100 /* 0 for start left */
+	#define BLT_START_BOTTOM	0x00000200 /* 0 for start top */
+	#define BLT_SRC_IS_CPU		0x00000400 /* 0 for vram source */
+	#define BLT_SRC_IS_MONO		0x00001000
+	#define BLT_MONO_TRANSPARENCY	0x00002000
+	#define BLT_COLOR_COMPARE_MASK	0x0001c000 /* 0 for no color keying */
+	#define BLT_PAT_TRANSPARENCY	0x00020000 /* pattern is transparent */
+	#define BLT_PAT_IS_MONO		0x00040000
+	#define BLT_PAT_IS_SOLID	0x00080000 /* ignore pattern */
+	#define BLT_PAT_VERT_ALIGN_MASK	0x00700000
+	#define BLT_IS_BUSY		0x80000000
+
+#define ROP_COPY	0xcc
+#define ROP_NOT_SRC	0x33
+#define ROP_NOT_DST	0x55
+#define ROP_PAT		0xf0
+
+#define CT_BLT_PATTERN	CT_OFF_BITBLT + 0x14 /* address in vram */
+#define CT_BLT_SRCADDR	CT_OFF_BITBLT + 0x18
+#define CT_BLT_DSTADDR	CT_OFF_BITBLT + 0x1c
+
+#define CT_BLT_SIZE	CT_OFF_BITBLT + 0x20	/* width and height */
+/*
+ * upper 16 bit are destination height
+ * lower 16 bit are destination width in bytes
+ */
+
+#define CT_SRC_EXP_BG	CT_OFF_BITBLT + 0x24
+#define CT_SRC_EXP_FG	CT_OFF_BITBLT + 0x28
+
+/* extension registers ( via CT_CONF */
+#define XR_VENDOR_LO		0x00
+#define XR_VENDOR_HI		0x01
+#define XR_DEVICE_LO		0x02
+#define XR_DEVICE_HI		0x03
+#define XR_REVISION		0x04
+#define XR_LINEAR_BASE_LO	0x05
+#define XR_LINEAR_BASE_HI	0x06
+
+#define XR_CONFIGURATION	0x08
+	#define BUS_PCI		0x01
+	#define BUS_VL		0x00
+	#define ENABLE_PCI	0x02
+
+#define XR_IO_CONTROL		0x09
+	#define ENABLE_CRTC_EXT	0x01
+	#define ENABLE_ATTR_EXT	0x02
+	
+#define XR_ADDR_MAPPING		0x0a
+	#define ENABLE_MAPPING	0x01	/* in VGA window */
+	#define ENABLE_LINEAR	0x02
+	#define ENABLE_PACKED	0x04
+	#define FB_SWAP_NONE	0x00
+	#define FB_SWAP_16	0x10
+	#define FB_SWAP_32	0x20
+
+#define XR_BURST_WRITE_MODE	0x0b
+
+#define XR_PAGE_SELECT		0x0e
+
+#define XR_BITBLT_CONTROL0	0x20
+	#define BLITTER_BUSY	0x01
+	#define BLITTER_RESET	0x02
+	#define BLITTER_8BIT	0x00
+	#define BLITTER_16BIT	0x10
+	#define BLITTER_24BIT	0x20
+	#define BLITTER_32BIT	0x30	/* reserved */
+	
+#define XR_DRAM_ACCESS_CONTROL	0x40
+	#define	ENABLE_64BIT	0x01
+	#define DISABLE_WRAP	0x02	/* otherwise only 256kB */
+	#define EXTENDED_TEXT	0x10
+	
+#define XR_DRAM_TYPE		0x41
+	#define DRAM_FASTPAGE	0x00
+	#define DRAM_EDO	0x01
+	
+#define XR_DRAM_CONFIG		0x42
+	#define DRAM_8BIT_COL	0x00
+	#define DRAM_9BIT_COL	0x01
+	
+#define XR_DRAM_INTERFACE	0x43
+#define XR_DRAM_TIMING		0x44
+
+#define XR_VIDEO_PIN_CONTROL	0x60
+#define XR_DDC_SYNC_SELECT	0x61
+	#define DDC_HSYNC_DATA	0x01
+	#define DDC_HSYNC_OUT	0x02	/* hsync is controlled by above */
+	#define DDC_VSYNC_DATA	0x04
+	#define DDC_VSYNC_OUT	0x08	/* vsync is controlled by above */
+	#define DDC_HV_POWERDOWN 0x10
+	#define DDC_ENABLE_HSYNC 0x20
+	#define DDC_ENABLE_VSYNC 0x40
+	
+/*
+ * upper 6 bit define if corresponding bits in DATA are input or output 
+ * 1 selects output
+ */
+#define XR_GPIO_CONTROL		0x62	
+#define XR_GPIO_DATA		0x63
+
+#define XR_PIN_TRISTATE_CONTROL	0x67
+
+#define XR_CONFIG_PINS_0	0x70
+#define XR_CONFIG_PINS_1	0x71
+
+#define XR_PIXEL_PIPELINE_CTL_0	0x80
+	#define ENABLE_EXTENDED_PALETTE	0x01
+	#define ENABLE_CRT_OVERSCAN	0x02
+	#define ENABLE_PANEL_OVERSCAN	0x04
+	#define ENABLE_EXTENDED_STATUS	0x08
+	#define ENABLE_CURSOR_1		0x10
+	#define ENABLE_PIXEL_AVERAGING	0x20
+	#define SELECT_PIXEL_STREAM	0x40	/* 1 for P1 */
+	#define ENABLE_8BIT_DAC		0x80	/* 6 bit otherwise */
+	
+#define XR_PIXEL_PIPELINE_CTL_1	0x81
+	#define COLOR_VGA		0x00
+	#define COLOR_8BIT_EXTENDED	0x02
+	#define COLOR_15BIT		0x04
+	#define COLOR_16BIT		0x05
+	#define COLOR_24BIT		0x06
+	#define COLOR_32BIT		0x07
+	
+#define XR_PIXEL_PIPELINE_CTL_2	0x82
+	#define ENABLE_BLANK_PEDESTAL	0x01
+	#define ENABLE_SYNY_ON_GREEN	0x02
+	#define ENABLE_VIDEO_GAMMA	0x04
+	#define ENABLE_GRAPHICS_GAMMA	0x08
+	
+#define XR_CURSOR_1_CTL		0xa0
+#define XR_CURSOR_1_VERT_EXT	0xa1
+#define XR_CURSOR_1_BASEADDR_LO	0xa2
+#define XR_CURSOR_1_BASEADDR_HI	0xa3
+#define XR_CURSOR_1_X_LO	0xa4
+#define XR_CURSOR_1_X_HI	0xa5
+#define XR_CURSOR_1_Y_LO	0xa6
+#define XR_CURSOR_1_Y_HI	0xa7
+
+#define XR_CURSOR_2_CTL		0xa8
+#define XR_CURSOR_2_VERT_EXT	0xa9
+#define XR_CURSOR_2_BASEADDR_LO	0xaa
+#define XR_CURSOR_2_BASEADDR_HI	0xab
+#define XR_CURSOR_2_X_LO	0xac
+#define XR_CURSOR_2_X_HI	0xad
+#define XR_CURSOR_2_Y_LO	0xae
+#define XR_CURSOR_2_Y_HI	0xaf
+
+#define XR_VCLOCK_0_M		0xc0
+#define XR_VCLOCK_0_N		0xc1
+#define XR_VCLOCK_0_MN_MSBS	0xc2
+#define XR_VCLOCK_0_DIV_SELECT	0xc3
+
+#define XR_VCLOCK_1_M		0xc4
+#define XR_VCLOCK_1_N		0xc5
+#define XR_VCLOCK_1_MN_MSBS	0xc6
+#define XR_VCLOCK_1_DIV_SELECT	0xc7
+
+#define XR_VCLOCK_2_M		0xc8
+#define XR_VCLOCK_2_N		0xc9
+#define XR_VCLOCK_2_MN_MSBS	0xca
+#define XR_VCLOCK_2_DIV_SELECT	0xcb
+
+#define XR_MEMCLOCK_M		0xcc
+#define XR_MEMCLOCK_N		0xcd
+#define XR_MEMCLOCK_DIV_SELECT	0xce
+#define XR_CLOCK_CONFIG		0xcf
+
+#define XR_MODULE_POWER_DOWN	0xd0
+#define XR_DOWN_COUNTER		0xd2
+
+#define XR_SOFTWARE_FLAG_0	0xe0
+#define XR_SOFTWARE_FLAG_1	0xe1
+#define XR_SOFTWARE_FLAG_2	0xe2
+#define XR_SOFTWARE_FLAG_3	0xe3
+#define XR_SOFTWARE_FLAG_4	0xe4
+#define XR_SOFTWARE_FLAG_5	0xe5
+#define XR_SOFTWARE_FLAG_6	0xe6
+#define XR_SOFTWARE_FLAG_7	0xe7
+
+#define XR_TEST_BLOCK_SELECT	0xf8
+#define XR_TEST_CONTROL_PORT	0xf9
+#define XR_TEST_DATA_PORT	0xfa
+#define XR_SCAN_TEST_CONTROL_0	0xfb
+#define XR_SCAN_TEST_CONTROL_1	0xfc
+
+/* flat panel control registers, via CT_FP_* */
+#define FP_FEATURE		0x00
+	#define PANEL_EXISTS	0x01
+	#define POPUP_EXISTS	0x04
+	
+#define FP_CRT_FP_CONTROL	0x01
+	#define ENABLE_CRT	0x01
+	#define ENABLE_PANEL	0x02
+	
+#define FP_MODE_CONTROL		0x02
+#define FP_DOT_CLOCK_SOURCE	0x03
+	#define FP_CLOCK_0	0x00
+	#define FP_CLOCK_1	0x04
+	#define FP_CLOCK_2	0x08
+	#define USE_VIDEO_CLOCK	0x00
+	#define USE_MEM_CLOCK	0x10
+	
+#define FP_POWER_SEQ_DELAY	0x04
+/*
+ * upper 4 bits select power up delay in 3.4ms increments
+ * lower 4 bits select power down delay in 29ms increments
+ */
+
+#define FP_POWER_DOWN_CTL_1	0x05
+/* the lower 3 bits select how many refresh cycles per scanline are preformed */
+	#define PANEL_POWER_OFF	0x08
+	#define HOST_STANDBY	0x10
+	#define PANEL_TRISTATE	0x20
+	#define NO_SEFL_REFRESH	0x40
+	#define PANEL_INACTIVE	0x80
+
+/* these bits are effective when the panel is powered down */
+#define FP_POWER_DOWN_CTL_0	0x06
+	#define FP_VGA_PALETTE_POWERDOWN	0x01
+	#define FP_VGA_PALETTE_ENABLE		0x02
+	#define FP_ENABLE_SYNC			0x04
+	
+#define FP_PIN_POLARITY		0x08
+	#define FP_DISPLAY_NEGATIVE	0x02
+	#define FP_HSYNC_NEGATIVE	0x04
+	#define FP_VSYNC_NEGATIVE	0x08
+	#define FP_TEXT_VIDEO_INVERT	0x10
+	#define FP_GRAPHICS_INVERT	0x20
+	#define CRT_HSYNC_NEGATIVE	0x40
+	#define CRT_VSYNC_NEGATIVE	0x80
+	
+#define FP_OUTPUT_DRIVE		0x0a
+	#define VL_THRESHOLD_5V		0x02	/* 3.3v otherwise */
+	#define FP_DRIVE_HIGH		0x04	/* req. with 3.3v */
+	#define BUS_INTERFACE_LOW	0x08	/* req. with 3.3v */
+	#define MEM_DRIVE_HIGHER	0x10
+	#define MEM_C_DRIVE_HIGHER	0x20
+	#define SYNC_DRIVE_HIGHER	0x40
+	
+#define FP_PIN_CONTROL_1	0x0b
+	#define DISPLAY_ENABLE_ON_69	0x01	/* M signal otherwise */
+	#define DISPLAY_ENABLE_ON_68	0x02	/* FP Hsync otherwise */
+	#define COMPOSITE_SYNC_ON_65	0x04	/* separate otherwise */
+	#define BACKLIGHT_ON_61		0x08	/* on 54 otherwise */
+	#define GPIO_ON_154		0x10
+	#define SIMPLE_COMPOSITE_SYNC	0x20
+	#define MEM_C_TRISTATE		0x80
+	
+#define FP_PIN_CONTROL_2	0x0c
+	#define ACTI_ON_53		0x00
+	#define COMPOSITE_SYNC_ON_53	0x08
+	#define GPIO_IN_ON_53		0x10
+	#define GPIO_OUT_ON_53		0x18
+	#define ENABKL_ON_54		0x00
+	#define COMPOSITE_SYNC_ON_54	0x40
+	#define GPIO_IN_ON_54		0x80
+	#define GPIO_OUT_ON_54		0xc0
+	
+#define FP_ACTIVITY_CONTROL	0x0f
+/* the lower 5 bits select a timeout in 28.1s increments */
+	#define PANEL_OFF_ON_TIMEOUT	0x40 /* backlight off otherwise */
+	#define ENABLE_ACTIVITY_TIMER	0x80
+	
+#define FP_PANEL_FORMAT_0	0x10
+	#define SINGLE_PANEL_SINGLE_DRIVE	0x00
+	#define DUAL_PANEL_DUAL_DRIVE		0x03
+	#define MONO_NTSC			0x00
+	#define MONO_EQUIV_WEIGHT		0x04
+	#define MONO_GREEN_ONLY			0x08
+	#define COLOUR_PANEL			0x0c
+	#define SHIFT_CLOCK_DIVIDER_MASK	0x70
+	
+#define FP_PANEL_FORMAT_1	0x11
+	
+#define FP_PANEL_FORMAT_2	0x12
+#define FP_PANEL_FORMAT_3	0x13
+
+#define FP_FRC_OPTION_SELECT	0x16
+#define FP_POLYNOMIAL_FRC_CTL	0x17
+
+#define FP_TEXTMODE_CONTROL	0x18
+#define FP_BLINK_RATE_CONTROL	0x19
+#define FP_FB_CONTROL		0x1a
+
+#define FP_ACDCLK_CONTROL	0x1e
+#define FP_DIAGNOSTIC		0x1f
+
+#define FP_HSIZE_LSB		0x20 /* panel size - 1 */
+#define FP_HSYNC_START		0x21 /* value - 1 */
+#define FP_HSYNC_END		0x22
+#define FP_HTOTAL_LSB		0x23 /* value - 5 */
+#define FP_HSYNC_DELAY_LSB	0x24
+#define FP_HORZ_OVERFLOW_1	0x25
+/*
+ * upper 4 bits are upper 4 bits of FP_HSYNC_START
+ * lower 4 bits are upper 4 bits of FP_HSIZE_LSB
+ */
+ 
+#define FP_HORZ_OVERFLOW_2	0x26
+/*
+ * upper 4 bits are upper 4 bits of FP_HSYNC_DELAY_LSB
+ * lower 4 bits are upper 4 bits of FP_HTOTAL_LSB
+ */
+ 
+#define FP_HSYNC_WIDTH_DISABLE	0x27
+/* lower 7 bits are HSYNC width - 1 */
+	#define DELAY_DISABLE	0x80
+	
+#define FP_VSIZE_LSB		0x30 /* panel size - 1 */
+#define FP_VSYNC_START		0x31 /* value - 1 */
+#define FP_VSYNC_END		0x32 /* value - 1 */
+#define FP_VTOTAL_LSB		0x33 /* value - 2 */
+#define FP_VSYNC_DELAY_LSB	0x34 /* value - 1 */
+#define FP_VERT_OVERFLOW_1	0x35
+/*
+ * upper 4 bits are upper 4 bits of FP_VSYNC_START
+ * lower 4 bits are upper 4 bits of FP_VSIZE_LSB
+ */
+ 
+#define FP_VERT_OVERFLOW_2	0x36
+/*
+ * upper 4 bits are upper 4 bits of FP_VSYNC_DELAY_LSB
+ * lower 4 bits are upper 4 bits of FP_VTOTAL_LSB
+ */
+
+#define FP_VSYNC_DISABLE	0x37
+	#define FP_VSYNC_WIDTH_MASK	0x38 /* value - 1 */
+	#define FP_VSYNC_IS_CRT_VSYNC	0x40
+	#define FP_VSYNC_DELAY_DISABLE	0x80
+	
+#define FP_HORZ_COMPENSATION	0x40
+#define FP_VERT_COMPENSATION	0x41
+#define FP_VERT_COMPENSATION2	0x48
+
+#define FP_TEXT_VSTRETCH_0_MSB	0x49
+#define FP_TEXT_VSTRETCH_0_LSB	0x4a
+#define FP_TEXT_VSTRETCH_1_MSB	0x4b
+#define FP_TEXT_VSTRETCH_1_LSB	0x4c
+#define FP_TEXT_LINE_REPL	0x4d
+#define FP_SEL_VSTRETCH_DISABLE	0x4e
+
+
+
+#endif
--- /dev/null	2008-05-18 21:24:23.000000000 +0900
+++ dev/ic/chipsfbvar.h	2007-09-19 23:45:26.000000000 +0900
@@ -0,0 +1,72 @@
+/*	$NetBSD$	*/
+
+/*
+ * Copyright (c) 2006 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+#include <dev/i2c/i2cvar.h>
+
+struct chipsfb_softc {
+	struct device sc_dev;
+
+	bus_space_tag_t sc_memt;
+	bus_space_tag_t sc_iot;
+	bus_space_handle_t sc_memh;
+
+	bus_space_tag_t sc_fbt;
+	bus_space_tag_t sc_ioregt;
+	bus_space_handle_t sc_fbh;
+	bus_space_handle_t sc_ioregh;
+	bus_addr_t sc_fb, sc_ioreg;
+	bus_size_t sc_fbsize, sc_ioregsize;
+
+	void *sc_ih;
+
+	size_t memsize;
+
+	int bits_per_pixel;
+	int width, height, linebytes;
+
+	int sc_mode;
+	uint32_t sc_bg;
+
+	u_char sc_cmap_red[256];
+	u_char sc_cmap_green[256];
+	u_char sc_cmap_blue[256];
+	int sc_dacw;
+
+	/*
+	 * I2C stuff
+	 * DDC2 clock is on GPIO1, data on GPIO0
+	 */
+	struct i2c_controller sc_i2c;
+	uint8_t sc_edid[1024];
+	int sc_edidbytes;	/* number of bytes read from the monitor */
+
+	struct vcons_data vd;
+};
+
+void	chipsfb_attach(struct chipsfb_softc *);
--- /dev/null	2008-05-18 21:24:23.000000000 +0900
+++ dev/pci/chipsfb_pci.c	2007-09-20 00:25:16.000000000 +0900
@@ -0,0 +1,133 @@
+/*	$NetBSD$	*/
+
+/*
+ * Copyright (c) 2006 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+/*
+ * PCI attachment for Chips & Technologies 65550 graphics controllers
+ * found on macppc
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include "opt_wsemul.h"
+#include "opt_chipsfb.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.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>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pciio.h>
+
+#include <dev/i2c/i2cvar.h>
+
+#include <dev/ic/chipsfbreg.h>
+#include <dev/ic/chipsfbvar.h>
+
+struct chipsfb_pci_softc {
+	struct chipsfb_softc sc_chipsfb;
+
+	pci_chipset_tag_t sc_pc;
+	pcitag_t sc_pcitag;
+};
+
+static int	chipsfb_pci_match(struct device *, struct cfdata *, void *);
+static void	chipsfb_pci_attach(struct device *, struct device *, void *);
+
+CFATTACH_DECL(chipsfb_pci, sizeof(struct chipsfb_pci_softc), chipsfb_pci_match,
+    chipsfb_pci_attach, NULL, NULL);
+
+static int
+chipsfb_pci_match(struct device *parent, struct cfdata *match, void *aux)
+{
+	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
+
+	if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY ||
+	    PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
+		return 0;
+	if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CHIPS) &&
+	    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CHIPS_65550))
+		return 100;
+	if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CHIPS) &&
+	    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CHIPS_65554))
+		return 100;
+	return 0;
+}
+
+static void
+chipsfb_pci_attach(struct device *parent, struct device *self, void *aux)
+{
+	struct chipsfb_pci_softc *psc = (void *)self;
+	struct chipsfb_softc *sc = &psc->sc_chipsfb;
+	struct pci_attach_args *pa = aux;
+	char devinfo[256];
+	pcireg_t screg;
+
+	psc->sc_pc = pa->pa_pc;
+	psc->sc_pcitag = pa->pa_tag;
+
+	screg = pci_conf_read(psc->sc_pc, psc->sc_pcitag,
+	    PCI_COMMAND_STATUS_REG);
+	screg |= PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
+	pci_conf_write(psc->sc_pc, psc->sc_pcitag,
+	    PCI_COMMAND_STATUS_REG, screg);
+
+	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
+	aprint_normal(": %s (rev. 0x%02x)\n", devinfo,
+	    PCI_REVISION(pa->pa_class));
+
+	sc->sc_memt = pa->pa_memt;
+	sc->sc_iot = pa->pa_iot;
+
+	/* the framebuffer */
+	if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_MEM,
+	    BUS_SPACE_MAP_LINEAR,
+	    &sc->sc_fbt, &sc->sc_fbh, &sc->sc_fb, &sc->sc_fbsize)) {
+		aprint_error("%s: failed to map the frame buffer.\n",
+		    sc->sc_dev.dv_xname);
+	}
+
+	/* IO-mapped registers */
+	if (bus_space_map(sc->sc_iot, CT_VGAREG_OFF, CT_VGAREG_SIZE,
+	    0, &sc->sc_ioregh) != 0) {
+		aprint_error("%s: failed to map IO registers.\n",
+		    sc->sc_dev.dv_xname);
+	}
+
+	chipsfb_attach(sc);
+}