NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/49518: I wrote Permedia3 3Dlabs Permedia 3 framebuffer console driver.(genfb driver doesn't work correct on Proformance 3)



>Number:         49518
>Category:       kern
>Synopsis:       I wrote Permedia3 3Dlabs Permedia 3 framebuffer console driver.(genfb driver doesn't work correct on Proformance 3)
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Dec 31 15:05:00 +0000 2014
>Originator:     Naruaki Etomi
>Release:        NetBSD 7.99.3
>Organization:
japan
>Environment:
NetBSD  7.99.3 NetBSD 7.99.3 (GENERIC-$Revision: 1.363 $) #3: Wed Dec 31 11:33:50 UTC 2014  naruaki@:/usr/obj.alpha/sys/arch/alpha/compile/GENERIC alpha and macppc
>Description:
Happy new year 2015!

Hello,

I wrote Permedia3 3Dlabs Permedia 3 / Oxygen VX1 / Proformance 3 
framebuffer console driver.
Proformance 3 is the fastest graphic card, especially for 
PCI Power Macintosh!

See:
OXYGEN VX1 for Alpha
https://twitter.com/nullnilaki/status/513417316487282688
https://twitter.com/nullnilaki/status/513417840326475776

ProFormance 3 16MB SGI TFT Module for Power Macintosh
https://twitter.com/nullnilaki/status/515853008387588096
https://twitter.com/nullnilaki/status/515853875169878017

The reason why I wrote driver is because 
genfb driver doesn't work correct on Proformance 3.
(The display gets corrupted.)

Some Power Mac G4 model could not initialize 
Proformance 3's memory control registers,
Power Mac G4 (Mirrored Drive Doors / AGP model?), for example.

See:
Open Firmware
https://twitter.com/nullnilaki/status/515855034790068225
https://twitter.com/nullnilaki/status/550281040644694016
genfb
https://twitter.com/nullnilaki/status/550281322426413057
https://twitter.com/nullnilaki/status/550281588982812672

Mac OS's driver deals with these problems.
See:
https://twitter.com/nullnilaki/status/515855482418774017
https://twitter.com/nullnilaki/status/516975393400557568

After applying my patch.

NetBSD/macppc
==========================================================================
dmesg:
-------------------------------
pchb1: Apple Computer UniNorth Host-PCI Bridge (rev. 0x00)
pm3fb0 at pci1 dev 21 function 0: 3D Labs GLINT Permedia 3 (rev. 0x01)
pm3fb0: 16 MB aperture at 0x84000000
pm3fb0: pm3 using 1280 x 1024 in 8 bit, stride 1280
wsdisplay0 at pm3fb0 kbdmux 1: console (default, vt100 emulation)
wsmux1: connecting to wsdisplay0 
-------------------------------
Screen shot:
https://twitter.com/nullnilaki/status/550287655032717312
https://twitter.com/nullnilaki/status/550288295574265856
https://twitter.com/nullnilaki/status/550288767601213440
-------------------------------
wsfb-driver:
https://twitter.com/nullnilaki/status/550289301603241984
-------------------------------
==========================================================================

NetBSD/alpha
==========================================================================
dmesg:
-------------------------------
usb0 at ohci0: USB revision 1.0
pm3fb0 at pci0 dev 11 function 0: vendor 3d3d product 000a (rev. 0x01)
pm3fb0: no width property
pm3fb0: no height property
pm3fb0: no depth property
pm3fb0: 16 MB aperture at 0x40000000
pm3fb0: pm3 using 1280 x 1024 in 8 bit, stride 1280
wsdisplay0 at pm3fb0 kbdmux 1: console (default, vt100 emulation)
wsmux1: connecting to wsdisplay0 
-------------------------------
Screen shot:
https://twitter.com/nullnilaki/status/550290949520097280
https://twitter.com/nullnilaki/status/550291070576099328
https://twitter.com/nullnilaki/status/550078066777538561
-------------------------------
wsfb-driver:
https://twitter.com/nullnilaki/status/550291225434021888
-------------------------------
==========================================================================

man pm3fb
==========================================================================
PM3FB(4)                   Kernel Interfaces Manual                   PM3FB(4)

NAME
     pm3fb -- 3Dlabs Permedia 3 / Oxygen VX1 / Proformance 3 framebuffer
     driver

SYNOPSIS
     pm3fb* at pci?
     wsdisplay* at pm3fb?

DESCRIPTION
     The pm3fb driver provides support for the 3Dlabs Permedia 3 / Oxygen VX1
     / Proformance 3 series of graphics cards and provides an interface for
     machine independent wscons(4) driver.

     Currently pm3fb does not support Anti-alias font rendering and OpenLDI
     video interface.  However, it is capable of changing the resolution and
     uses DDC2 to pick an appropriate video mode.

     A 2D graphics engine is used to accelerate scrolling, rectangle fills and
     Bitmap font rendering.

SEE ALSO
     pci(4), wscons(4), wsdisplay(4)

AUTHORS
     The pm3fb driver was written by Naruaki Etomi.
==========================================================================

Commentary1:
==========================================================================
+	/*
+	 * Permedia 3 always return 64MB fbsize
+	 * 16 MB should be enough -- more just wastes map entries
+	 */
+	if (sc->sc_fbsize != 0)
+	    sc->sc_fbsize = (16 << 20);

Permedia 3 always return 64MB frame buffer size.
The minimum frame buffer size is 16MB in Permedia 3 product lines.
I don't write frame buffer size check routine.
I think that's enough.
==========================================================================

Commentary2:
==========================================================================
+	/*
+	 * Some Power Mac G4 model could not initialize these registers,
+	 * Power Mac G4 (Mirrored Drive Doors), for example
+	 */
+#if defined(__powerpc__)
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LOCALMEMCAPS, 0x02e311B8);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LOCALMEMTIMINGS, 0x07424905);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LOCALMEMCONTROL, 0x0c000003);
+#endif

My Power Mac G4 Mirrored Drive Doors could not initialize these registers.
(Display gets corrupted.)
==========================================================================

Is there a problem?
Please point it out if there are any mistakes in my patch.
>How-To-Repeat:

>Fix:
diff -Naru src.orig/distrib/sets/lists/man/mi src/distrib/sets/lists/man/mi
--- src.orig/distrib/sets/lists/man/mi	2014-12-29 23:19:34.000000000 +0000
+++ src/distrib/sets/lists/man/mi	2014-12-31 11:18:25.000000000 +0000
@@ -1507,6 +1507,7 @@
 ./usr/share/man/cat4/piixpm.0			man-sys-catman		.cat
 ./usr/share/man/cat4/pim.0			man-sys-catman		.cat
 ./usr/share/man/cat4/plip.0			man-sys-catman		.cat
+./usr/share/man/cat4/pm3fb.0			man-sys-catman		.cat
 ./usr/share/man/cat4/pmax/asc.0			man-sys-catman		.cat
 ./usr/share/man/cat4/pmax/autoconf.0		man-sys-catman		.cat
 ./usr/share/man/cat4/pmax/dc.0			man-obsolete		obsolete
@@ -4510,6 +4511,7 @@
 ./usr/share/man/html4/piixpm.html		man-sys-htmlman		html
 ./usr/share/man/html4/pim.html			man-sys-htmlman		html
 ./usr/share/man/html4/plip.html			man-sys-htmlman		html
+./usr/share/man/html4/pm3fb.html		man-sys-htmlman		html
 ./usr/share/man/html4/pmax/asc.html		man-sys-htmlman		html
 ./usr/share/man/html4/pmax/autoconf.html	man-sys-htmlman		html
 ./usr/share/man/html4/pmax/ibus.html		man-sys-htmlman		html
@@ -7383,6 +7385,7 @@
 ./usr/share/man/man4/piixpm.4			man-sys-man		.man
 ./usr/share/man/man4/pim.4			man-sys-man		.man
 ./usr/share/man/man4/plip.4			man-sys-man		.man
+./usr/share/man/man4/pm3fb.4			man-sys-man		.man
 ./usr/share/man/man4/pmax/asc.4			man-sys-man		.man
 ./usr/share/man/man4/pmax/autoconf.4		man-sys-man		.man
 ./usr/share/man/man4/pmax/dc.4			man-obsolete		obsolete
diff -Naru src.orig/share/man/man4/Makefile src/share/man/man4/Makefile
--- src.orig/share/man/man4/Makefile	2014-12-29 23:24:51.000000000 +0000
+++ src/share/man/man4/Makefile	2014-12-31 11:02:09.000000000 +0000
@@ -46,7 +46,7 @@
 	oak.4 oosiop.4 opl.4 options.4 optiide.4 osiop.4 otus.4 \
 	pad.4 pas.4 pcdisplay.4 pcf8563rtc.4 pciide.4 pckbc.4 pckbd.4 pcn.4 \
 	pcppi.4 pcscp.4 pcweasel.4 pdcide.4 pdcsata.4 piixide.4 piixpcib.4 \
-	piixpm.4 pim.4 plip.4 pms.4 pmu.4 pnaphy.4 ppbus.4 ppp.4 pppoe.4 \
+	piixpm.4 pim.4 plip.4 pm3fb.4 pms.4 pmu.4 pnaphy.4 ppbus.4 ppp.4 pppoe.4 \
 	pseye.4 ptcd.4 ptm.4 pty.4 puc.4 pud.4 puffs.4 pwdog.4 px.4 pxg.4 \
 	qe.4 qec.4 qsphy.4 \
 	raid.4 ral.4 ray.4 rcons.4 rdcphy.4 re.4 rgephy.4 rlphy.4 \
diff -Naru src.orig/share/man/man4/pm3fb.4 src/share/man/man4/pm3fb.4
--- src.orig/share/man/man4/pm3fb.4	1970-01-01 00:00:00.000000000 +0000
+++ src/share/man/man4/pm3fb.4	2014-12-31 10:59:27.000000000 +0000
@@ -0,0 +1,59 @@
+.\" Copyright (c) 2015 Naruaki Etomi
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd January 1, 2015
+.Dt PM3FB 4
+.Os
+.Sh NAME
+.Nm pm3fb
+.Nd 3Dlabs Permedia 3 / Oxygen VX1 / Proformance 3 framebuffer driver
+.Sh SYNOPSIS
+.Cd "pm3fb* at pci?"
+.Cd "wsdisplay* at pm3fb?"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the 3Dlabs Permedia 3 / Oxygen VX1 / Proformance 3 series of
+graphics cards and provides an interface for machine independent
+.Xr wscons 4
+driver.
+.Pp
+Currently
+.Nm
+does not support Anti-alias font rendering and OpenLDI video interface.
+However, it is capable of changing the resolution and uses DDC2 to
+pick an appropriate video mode.
+.Pp
+A 2D graphics engine is used to accelerate scrolling, rectangle fills
+and Bitmap font rendering.
+.Sh SEE ALSO
+.Xr pci 4 ,
+.Xr wscons 4 ,
+.Xr wsdisplay 4
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Naruaki Etomi .
diff -Naru src.orig/sys/arch/alpha/conf/GENERIC src/sys/arch/alpha/conf/GENERIC
--- src.orig/sys/arch/alpha/conf/GENERIC	2014-12-29 23:25:02.000000000 +0000
+++ src/sys/arch/alpha/conf/GENERIC	2014-12-31 10:29:43.000000000 +0000
@@ -362,6 +362,7 @@
 pcn*	at	pci? dev ? function ?		# AMD PCnet-PCI Ethernet
 pcscp*	at	pci? dev ? function ?		# AMD Am53c974 PCscsi-PCI
 pm2fb*	at	pci? dev ? function ?		# 3Dlabs Permedia 2 Graphics
+pm3fb*	at	pci? dev ? function ?		# 3Dlabs Permedia 3 Graphics
 ppb*	at	pci? dev ? function ?		# PCI-PCI Bridges
 puc*	at 	pci? dev ? function ?		# PCI "universal" comm. cards
 radeonfb* at	pci? dev ? function ?		# ATI/AMD Radeon Graphics
@@ -709,6 +710,8 @@
 wsdisplay*	at	tfb?
 wsdisplay*	at	sfb?
 #wsdisplay*	at	sfbp?
+wsdisplay*	at	pm2fb?
+wsdisplay*	at	pm3fb?
 wsdisplay*	at	px?
 wsdisplay*	at	pxg?
 wsdisplay*	at	radeonfb?
diff -Naru src.orig/sys/arch/macppc/conf/GENERIC src/sys/arch/macppc/conf/GENERIC
--- src.orig/sys/arch/macppc/conf/GENERIC	2014-12-29 23:25:17.000000000 +0000
+++ src/sys/arch/macppc/conf/GENERIC	2014-12-31 10:35:41.000000000 +0000
@@ -291,6 +291,7 @@
 chipsfb*	at pci?	function ?	# C&T 65550
 gffb*		at pci?	function ?	# NVIDIA GeForce2 MX
 machfb*		at pci? function ?	# ATI Mach 64, Rage, Rage Pro
+pm3fb*		at pci? function ?	# 3Dlabs Permedia 3 Graphics
 tdvfb*		at pci? function ?	# 3Dfx Voodoo2
 r128fb*		at pci? function ?	# ATI Rage 128
 voodoofb*	at pci? function ?	# 3Dfx Voodoo3 
diff -Naru src.orig/sys/dev/pci/files.pci src/sys/dev/pci/files.pci
--- src.orig/sys/dev/pci/files.pci	2014-12-29 23:25:37.000000000 +0000
+++ src/sys/dev/pci/files.pci	2014-12-31 10:45:18.000000000 +0000
@@ -1063,6 +1063,11 @@
 file	dev/pci/pm2fb.c		pm2fb
 defflag	opt_pm2fb.h	PM2FB_DEBUG
 
+# Permedia 3 / Oxygen VX1 / Proformance 3  
+device  pm3fb: wsemuldisplaydev, rasops8, vcons, videomode, i2cbus, i2c_bitbang, ddc_read_edid, edid
+attach  pm3fb at pci
+file	dev/pci/pm3fb.c		pm3fb
+
 # 3Dlabs Wildcat / Sun XVR-500, 1200, Expert3D etc.
 device		wcfb: wsemuldisplaydev, rasops8, vcons
 attach		wcfb at pci
diff -Naru src.orig/sys/dev/pci/pm3fb.c src/sys/dev/pci/pm3fb.c
--- src.orig/sys/dev/pci/pm3fb.c	1970-01-01 00:00:00.000000000 +0000
+++ src/sys/dev/pci/pm3fb.c	2014-12-31 11:20:04.000000000 +0000
@@ -0,0 +1,1304 @@
+/*
+ * Copyright (c) 2015 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * A console driver for Permedia 3 graphics controllers
+ * most of the following was adapted from the xf86-video-glint driver's
+ * pm3_accel.c, pm3_dac.c and pm2fb framebuffer console driver
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/lwp.h>
+#include <sys/kauth.h>
+#include <sys/atomic.h>
+
+#include <dev/videomode/videomode.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pciio.h>
+#include <dev/pci/pm3reg.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/wsdisplay_pci.h>
+
+#include <dev/i2c/i2cvar.h>
+#include <dev/i2c/i2c_bitbang.h>
+#include <dev/i2c/ddcvar.h>
+#include <dev/videomode/videomode.h>
+#include <dev/videomode/edidvar.h>
+#include <dev/videomode/edidreg.h>
+
+struct pm3fb_softc {
+	device_t sc_dev;
+
+	pci_chipset_tag_t sc_pc;
+	pcitag_t sc_pcitag;
+
+	bus_space_tag_t sc_memt;
+	bus_space_tag_t sc_iot;
+
+	bus_space_handle_t sc_regh;
+	bus_addr_t sc_fb, sc_reg;
+	bus_size_t sc_fbsize, sc_regsize;
+
+	int sc_width, sc_height, sc_depth, sc_stride;
+	int sc_locked;
+	struct vcons_screen sc_console_screen;
+	struct wsscreen_descr sc_defaultscreen_descr;
+	const struct wsscreen_descr *sc_screens[1];
+	struct wsscreen_list sc_screenlist;
+	struct vcons_data vd;
+	int sc_mode;
+	u_char sc_cmap_red[256];
+	u_char sc_cmap_green[256];
+	u_char sc_cmap_blue[256];
+	/* i2c stuff */
+	struct i2c_controller sc_i2c;
+	uint8_t sc_edid_data[128];
+	struct edid_info sc_ei;
+	const struct videomode *sc_videomode;
+};
+
+static int	pm3fb_match(device_t, cfdata_t, void *);
+static void	pm3fb_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(pm3fb, sizeof(struct pm3fb_softc),
+    pm3fb_match, pm3fb_attach, NULL, NULL);
+
+extern const u_char rasops_cmap[768];
+
+static int	pm3fb_ioctl(void *, void *, u_long, void *, int, struct lwp *);
+static paddr_t	pm3fb_mmap(void *, void *, off_t, int);
+static void	pm3fb_init_screen(void *, struct vcons_screen *, int, long *);
+
+static int	pm3fb_putcmap(struct pm3fb_softc *, struct wsdisplay_cmap *);
+static int	pm3fb_getcmap(struct pm3fb_softc *, struct wsdisplay_cmap *);
+static void	pm3fb_init_palette(struct pm3fb_softc *);
+static int	pm3fb_putpalreg(struct pm3fb_softc *, uint8_t, uint8_t, uint8_t, uint8_t);
+
+static void	pm3fb_init(struct pm3fb_softc *);
+static inline void pm3fb_wait(struct pm3fb_softc *, int);
+static void	pm3fb_flush_engine(struct pm3fb_softc *);
+static void	pm3fb_rectfill(struct pm3fb_softc *, int, int, int, int, uint32_t);
+static void	pm3fb_bitblt(void *, int, int, int, int, int, int, int);
+
+static void	pm3fb_cursor(void *, int, int, int);
+static void	pm3fb_putchar(void *, int, int, u_int, long);
+static void	pm3fb_copycols(void *, int, int, int, int);
+static void	pm3fb_erasecols(void *, int, int, int, long);
+static void	pm3fb_copyrows(void *, int, int, int);
+static void	pm3fb_eraserows(void *, int, int, long);
+
+struct wsdisplay_accessops pm3fb_accessops = {
+	pm3fb_ioctl,
+	pm3fb_mmap,
+	NULL,    /* alloc_screen */
+	NULL,    /* free_screen */
+	NULL,    /* show_screen */
+	NULL,    /* load_font */
+	NULL,    /* pollc */
+	NULL     /* scroll */
+};
+
+/* I2C glue */
+static int pm3fb_i2c_acquire_bus(void *, int);
+static void pm3fb_i2c_release_bus(void *, int);
+static int pm3fb_i2c_send_start(void *, int);
+static int pm3fb_i2c_send_stop(void *, int);
+static int pm3fb_i2c_initiate_xfer(void *, i2c_addr_t, int);
+static int pm3fb_i2c_read_byte(void *, uint8_t *, int);
+static int pm3fb_i2c_write_byte(void *, uint8_t, int);
+
+/* I2C bitbang glue */
+static void pm3fb_i2cbb_set_bits(void *, uint32_t);
+static void pm3fb_i2cbb_set_dir(void *, uint32_t);
+static uint32_t pm3fb_i2cbb_read(void *);
+
+static void pm3_setup_i2c(struct pm3fb_softc *);
+
+static const struct i2c_bitbang_ops pm3fb_i2cbb_ops = {
+pm3fb_i2cbb_set_bits,
+	pm3fb_i2cbb_set_dir,
+	pm3fb_i2cbb_read,
+	{
+		PM3_DD_SDA_IN,
+		PM3_DD_SCL_IN,
+		0,
+		0
+	}
+};
+
+/* mode setting stuff */
+static int pm3fb_set_pll(struct pm3fb_softc *, int);
+static void pm3fb_write_dac(struct pm3fb_softc *, int, uint8_t);
+static void pm3fb_set_mode(struct pm3fb_softc *, const struct videomode *);
+
+static inline void
+pm3fb_wait(struct pm3fb_softc *sc, int slots)
+{
+    uint32_t reg;
+
+    do {
+		reg = bus_space_read_4(sc->sc_memt, sc->sc_regh,
+		    PM3_INPUT_FIFO_SPACE);
+	} while (reg <= slots);
+}
+
+static void
+pm3fb_flush_engine(struct pm3fb_softc *sc)
+{
+
+	pm3fb_wait(sc, 2);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FILTER_MODE, PM3_FM_PASS_SYNC);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SYNC, 0);
+
+	do {
+		while (bus_space_read_4(sc->sc_memt, sc->sc_regh, PM3_OUTPUT_FIFO_WORDS) == 0);
+	} while (bus_space_read_4(sc->sc_memt, sc->sc_regh, PM3_OUTPUT_FIFO) !=
+	    PM3_SYNC_TAG);
+}
+
+static int
+pm3fb_match(device_t parent, cfdata_t match, void *aux)
+{
+	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
+
+	if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
+		return 0;
+	if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_3DLABS)
+		return 0;
+
+	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3DLABS_PERMEDIA3)
+		return 100;
+	return (0);
+}
+
+static void
+pm3fb_attach(device_t parent, device_t self, void *aux)
+{
+	struct pm3fb_softc	*sc = device_private(self);
+	struct pci_attach_args	*pa = aux;
+	struct rasops_info	*ri;
+	struct wsemuldisplaydev_attach_args aa;
+	prop_dictionary_t	dict;
+	unsigned long		defattr;
+	bool			is_console;
+	uint32_t		flags;
+
+	sc->sc_pc = pa->pa_pc;
+	sc->sc_pcitag = pa->pa_tag;
+	sc->sc_memt = pa->pa_memt;
+	sc->sc_iot = pa->pa_iot;
+	sc->sc_dev = self;
+
+	pci_aprint_devinfo(pa, NULL);
+
+	/*
+	 * fill in parameters from properties
+	 * if we can't get a usable mode via DDC2 we'll use this to pick one,
+	 * which is why we fill them in with some conservative values that
+	 * hopefully work as a last resort
+	 */
+	dict = device_properties(self);
+	if (!prop_dictionary_get_uint32(dict, "width", &sc->sc_width)) {
+		aprint_error("%s: no width property\n", device_xname(self));
+		sc->sc_width = 1280;
+	}
+	if (!prop_dictionary_get_uint32(dict, "height", &sc->sc_height)) {
+		aprint_error("%s: no height property\n", device_xname(self));
+		sc->sc_height = 1024;
+	}
+	if (!prop_dictionary_get_uint32(dict, "depth", &sc->sc_depth)) {
+		aprint_error("%s: no depth property\n", device_xname(self));
+		sc->sc_depth = 8;
+	}
+
+	sc->sc_stride = sc->sc_width * (sc->sc_depth >> 3);
+
+	prop_dictionary_get_bool(dict, "is_console", &is_console);
+
+	pci_mapreg_info(pa->pa_pc, pa->pa_tag, 0x14, PCI_MAPREG_TYPE_MEM,
+	    &sc->sc_fb, &sc->sc_fbsize, &flags);
+
+	if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_MEM, 0,
+	    &sc->sc_memt, &sc->sc_regh, &sc->sc_reg, &sc->sc_regsize)) {
+		aprint_error("%s: failed to map registers.\n",
+		    device_xname(sc->sc_dev));
+	}
+
+	/*
+	 * Permedia 3 always return 64MB fbsize
+	 * 16 MB should be enough -- more just wastes map entries
+	 */
+	if (sc->sc_fbsize != 0)
+	    sc->sc_fbsize = (16 << 20);
+
+	/*
+	 * Some Power Mac G4 model could not initialize these registers,
+	 * Power Mac G4 (Mirrored Drive Doors), for example
+	 */
+#if defined(__powerpc__)
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LOCALMEMCAPS, 0x02e311B8);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LOCALMEMTIMINGS, 0x07424905);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LOCALMEMCONTROL, 0x0c000003);
+#endif
+
+	aprint_normal("%s: %d MB aperture at 0x%08x\n", device_xname(self),
+	    (int)(sc->sc_fbsize >> 20), (uint32_t)sc->sc_fb);
+
+	sc->sc_defaultscreen_descr = (struct wsscreen_descr){
+		"default",
+		0, 0,
+		NULL,
+		8, 16,
+		WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
+		NULL
+	};
+
+	sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
+	sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
+	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
+	sc->sc_locked = 0;
+
+	pm3_setup_i2c(sc);
+
+	vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
+	    &pm3fb_accessops);
+
+	sc->vd.init_screen = pm3fb_init_screen;
+
+	/* init engine here */
+	pm3fb_init(sc);
+
+	ri = &sc->sc_console_screen.scr_ri;
+
+	if (is_console) {
+		vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
+		    &defattr);
+		sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
+
+		pm3fb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height,
+		    ri->ri_devcmap[(defattr >> 16) & 0xff]);
+		sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
+		sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
+		sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
+		sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
+
+		wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
+		    defattr);
+		vcons_replay_msgbuf(&sc->sc_console_screen);
+	} else {
+		if (sc->sc_console_screen.scr_ri.ri_rows == 0) {
+			/* do some minimal setup to avoid weirdnesses later */
+			vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
+			   &defattr);
+		}
+	}
+
+	pm3fb_init_palette(sc);
+
+	aa.console = is_console;
+	aa.scrdata = &sc->sc_screenlist;
+	aa.accessops = &pm3fb_accessops;
+	aa.accesscookie = &sc->vd;
+
+	config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);
+}
+
+static int
+pm3fb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
+	struct lwp *l)
+{
+	struct vcons_data *vd = v;
+	struct pm3fb_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;
+
+	/* 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);
+
+	case WSDISPLAYIO_GET_BUSID:
+		return wsdisplayio_busid_pci(sc->sc_dev, sc->sc_pc,
+		    sc->sc_pcitag, data);
+
+	case WSDISPLAYIO_GINFO:
+		if (ms == NULL)
+			return ENODEV;
+		wdf = (void *)data;
+		wdf->height = ms->scr_ri.ri_height;
+		wdf->width = ms->scr_ri.ri_width;
+		wdf->depth = ms->scr_ri.ri_depth;
+		wdf->cmsize = 256;
+		return 0;
+
+	case WSDISPLAYIO_GETCMAP:
+		return pm3fb_getcmap(sc,
+		    (struct wsdisplay_cmap *)data);
+
+	case WSDISPLAYIO_PUTCMAP:
+		return pm3fb_putcmap(sc,
+		    (struct wsdisplay_cmap *)data);
+
+	case WSDISPLAYIO_LINEBYTES:
+		*(u_int *)data = sc->sc_stride;
+		return 0;
+
+	case WSDISPLAYIO_SMODE: {
+		int new_mode = *(int*)data;
+		if (new_mode != sc->sc_mode) {
+			sc->sc_mode = new_mode;
+			if(new_mode == WSDISPLAYIO_MODE_EMUL) {
+				/* first set the video mode */
+				if (sc->sc_videomode != NULL) {
+					pm3fb_set_mode(sc, sc->sc_videomode);
+				}
+				/* then initialize the drawing engine */
+				pm3fb_init(sc);
+				pm3fb_init_palette(sc);
+				vcons_redraw_screen(ms);
+			} else
+				pm3fb_flush_engine(sc);
+		}
+		}
+		return 0;
+	case WSDISPLAYIO_GET_EDID: {
+		struct wsdisplayio_edid_info *d = data;
+		d->data_size = 128;
+		if (d->buffer_size < 128)
+			return EAGAIN;
+		return copyout(sc->sc_edid_data, d->edid_data, 128);
+	}
+
+	case WSDISPLAYIO_GET_FBINFO: {
+		struct wsdisplayio_fbinfo *fbi = data;
+		return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi);
+	}
+	}
+	return EPASSTHROUGH;
+}
+
+static paddr_t
+pm3fb_mmap(void *v, void *vs, off_t offset, int prot)
+{
+	struct vcons_data *vd = v;
+	struct pm3fb_softc *sc = vd->cookie;
+	paddr_t pa;
+
+	/* 'regular' framebuffer mmap()ing */
+	if (offset < sc->sc_fbsize) {
+		pa = bus_space_mmap(sc->sc_memt, sc->sc_fb + offset, 0, prot,
+		    BUS_SPACE_MAP_LINEAR);
+		return pa;
+	}
+
+	/*
+	 * restrict all other mappings to processes with superuser privileges
+	 * or the kernel itself
+	 */
+	if (kauth_authorize_machdep(kauth_cred_get(),
+	    KAUTH_MACHDEP_UNMANAGEDMEM,
+	    NULL, NULL, NULL, NULL) != 0) {
+		aprint_normal("%s: mmap() rejected.\n",
+		    device_xname(sc->sc_dev));
+		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;
+	}
+
+	if ((offset >= sc->sc_reg) &&
+	    (offset < (sc->sc_reg + sc->sc_regsize))) {
+		pa = bus_space_mmap(sc->sc_memt, offset, 0, prot,
+		    BUS_SPACE_MAP_LINEAR);
+		return pa;
+	}
+
+#ifdef PCI_MAGIC_IO_RANGE
+	/* allow mapping of IO space */
+	if ((offset >= PCI_MAGIC_IO_RANGE) &&
+	    (offset < PCI_MAGIC_IO_RANGE + 0x10000)) {
+		pa = bus_space_mmap(sc->sc_iot, offset - PCI_MAGIC_IO_RANGE,
+		    0, prot, BUS_SPACE_MAP_LINEAR);
+		return pa;
+	}
+#endif
+	return -1;
+}
+
+static void
+pm3fb_init_screen(void *cookie, struct vcons_screen *scr,
+    int existing, long *defattr)
+{
+	struct pm3fb_softc *sc = cookie;
+	struct rasops_info *ri = &scr->scr_ri;
+
+	ri->ri_depth = sc->sc_depth;
+	ri->ri_width = sc->sc_width;
+	ri->ri_height = sc->sc_height;
+	ri->ri_stride = sc->sc_stride;
+	ri->ri_flg = RI_CENTER;
+	if (sc->sc_depth == 8)
+		ri->ri_flg |= RI_8BIT_IS_RGB;
+
+	rasops_init(ri, 0, 0);
+	ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_UNDERLINE;
+
+	rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
+		    sc->sc_width / ri->ri_font->fontwidth);
+
+	ri->ri_hw = scr;
+	ri->ri_ops.copyrows = pm3fb_copyrows;
+	ri->ri_ops.copycols = pm3fb_copycols;
+	ri->ri_ops.cursor = pm3fb_cursor;
+	ri->ri_ops.eraserows = pm3fb_eraserows;
+	ri->ri_ops.erasecols = pm3fb_erasecols;
+	ri->ri_ops.putchar = pm3fb_putchar;
+}
+
+static int
+pm3fb_putcmap(struct pm3fb_softc *sc, struct wsdisplay_cmap *cm)
+{
+	u_char *r, *g, *b;
+	u_int index = cm->index;
+	u_int count = cm->count;
+	int i, error;
+	u_char rbuf[256], gbuf[256], bbuf[256];
+
+	if (cm->index >= 256 || cm->count > 256 ||
+	    (cm->index + cm->count) > 256)
+		return EINVAL;
+	error = copyin(cm->red, &rbuf[index], count);
+	if (error)
+		return error;
+	error = copyin(cm->green, &gbuf[index], count);
+	if (error)
+		return error;
+	error = copyin(cm->blue, &bbuf[index], count);
+	if (error)
+		return error;
+
+	memcpy(&sc->sc_cmap_red[index], &rbuf[index], count);
+	memcpy(&sc->sc_cmap_green[index], &gbuf[index], count);
+	memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count);
+
+	r = &sc->sc_cmap_red[index];
+	g = &sc->sc_cmap_green[index];
+	b = &sc->sc_cmap_blue[index];
+
+	for (i = 0; i < count; i++) {
+		pm3fb_putpalreg(sc, index, *r, *g, *b);
+		index++;
+		r++, g++, b++;
+	}
+	return 0;
+}
+
+static int
+pm3fb_getcmap(struct pm3fb_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
+pm3fb_init_palette(struct pm3fb_softc *sc)
+{
+	struct rasops_info *ri = &sc->sc_console_screen.scr_ri;
+	int i, j = 0;
+	uint8_t cmap[768];
+
+	rasops_get_cmap(ri, cmap, sizeof(cmap));
+
+	for (i = 0; i < 256; i++) {
+		sc->sc_cmap_red[i] = cmap[j];
+		sc->sc_cmap_green[i] = cmap[j + 1];
+		sc->sc_cmap_blue[i] = cmap[j + 2];
+		pm3fb_putpalreg(sc, i, cmap[j], cmap[j + 1], cmap[j + 2]);
+		j += 3;
+	}
+}
+
+static int
+pm3fb_putpalreg(struct pm3fb_softc *sc, uint8_t idx, uint8_t r, uint8_t g, uint8_t b)
+{
+
+	pm3fb_wait(sc, 4);
+	bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_PAL_WRITE_IDX, idx);
+	bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_PAL_DATA, r);
+	bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_PAL_DATA, g);
+	bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_PAL_DATA, b);
+	return 0;
+}
+
+static void
+pm3fb_write_dac(struct pm3fb_softc *sc, int reg, uint8_t data)
+{
+
+	pm3fb_wait(sc, 3);
+	bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_INDEX_LOW, reg & 0xff);
+	bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_INDEX_HIGH, (reg >> 8) & 0xff);
+	bus_space_write_1(sc->sc_memt, sc->sc_regh, PM3_DAC_INDEX_DATA, data);
+}
+
+static void
+pm3fb_init(struct pm3fb_softc *sc)
+{
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LB_DESTREAD_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LB_DESTREAD_ENABLES, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LB_SOURCEREAD_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LB_WRITE_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FILTER_MODE, PM3_FM_PASS_SYNC);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STATISTIC_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DELTA_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RASTERIZER_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCISSOR_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LINESTIPPLE_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_AREASTIPPLE_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_GID_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DEPTH_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STENCIL_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STENCIL_DATA, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_COLORDDA_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREADDRESS_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREINDEX_MODE0, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREINDEX_MODE1, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREREAD_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXELLUT_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTUREFILTER_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITE_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOLOR_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITECOLOR_MODE1, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITEALPHA_MODE1, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITECOLOR_MODE0, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_TEXTURECOMPOSITEALPHA_MODE0, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FOG_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CHROMATEST_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ALPHATEST_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ANTIALIAS_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_YUV_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ALPHABLENDCOLOR_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ALPHABLENDALPHA_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DITHER_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_LOGICALOP_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_ROUTER_MODE, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_WINDOW, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CONFIG2D, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SPANCOLORMASK, 0xffffffff);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_XBIAS, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_YBIAS, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DELTACONTROL, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_BITMASKPATTERN, 0xffffffff);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBDESTREAD_ENABLE,
+	    PM3_FBDESTREAD_SET(0xff, 0xff, 0xff));
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBDESTREAD_BUFFERADDRESS0, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBDESTREAD_BUFFEROFFSET0, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBDESTREAD_BUFFERWIDTH0,
+	    PM3_FBDESTREAD_BUFFERWIDTH_WIDTH(sc->sc_stride));
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FB_DESTREAD_MODE,
+	    PM3_FBDRM_ENABLE | PM3_FBDRM_ENABLE0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_BUFFERADDRESS, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_BUFFEROFFSET, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_BUFFERWIDTH,
+	    PM3_FBSOURCEREAD_BUFFERWIDTH_WIDTH(sc->sc_stride));
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_MODE,
+	    PM3_FBSOURCEREAD_MODE_BLOCKING | PM3_FBSOURCEREAD_MODE_ENABLE);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_PIXEL_SIZE, PM3_PS_8BIT);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOFTWAREWRITEMASK, 0xffffffff);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBHARDWAREWRITEMASK, 0xffffffff);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBWRITE_MODE,
+	    PM3_FBWRITEMODE_WRITEENABLE | PM3_FBWRITEMODE_OPAQUESPAN | PM3_FBWRITEMODE_ENABLE0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBWRITEBUFFERADDRESS0, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBWRITEBUFFEROFFSET0, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBWRITEBUFFERWIDTH0,
+	    PM3_FBWRITEBUFFERWIDTH_WIDTH(sc->sc_stride));
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SIZEOF_FRAMEBUFFER, 4095);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DITHER_MODE, PM3_CF_TO_DIM_CF(4));
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DXDOM, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DXSUB, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DY, 1 << 16);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STARTXDOM, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STARTXSUB, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_STARTY, 0);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_COUNT, 0);
+}
+
+static void
+pm3fb_rectfill(struct pm3fb_softc *sc, int x, int y, int wi, int he,
+     uint32_t colour)
+{
+	pm3fb_wait(sc, 4);
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CONFIG2D,
+	    PM3_CONFIG2D_USECONSTANTSOURCE | PM3_CONFIG2D_FOREGROUNDROP_ENABLE | 
+	    (PM3_CONFIG2D_FOREGROUNDROP(0x3)) | PM3_CONFIG2D_FBWRITE_ENABLE);
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FOREGROUNDCOLOR, colour);
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RECTANGLEPOSITION,
+	    (((y) & 0xffff) << 16) | ((x) & 0xffff) );
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RENDER2D,
+	    PM3_RENDER2D_XPOSITIVE | PM3_RENDER2D_YPOSITIVE | 
+	    PM3_RENDER2D_OPERATION_NORMAL | PM3_RENDER2D_SPANOPERATION | 
+	    (((he) & 0x0fff) << 16) | ((wi) & 0x0fff));
+
+	pm3fb_flush_engine(sc);
+}
+
+static void
+pm3fb_bitblt(void *cookie, int srcx, int srcy, int dstx, int dsty,
+    int width, int height, int rop)
+{
+	struct pm3fb_softc *sc = cookie;
+	int x_align,  offset_x, offset_y; 
+	uint32_t dir = 0;
+
+	if (srcx > dstx) {
+		offset_x = srcx - dstx;
+	} else {
+		offset_x = dstx - srcx;
+	}
+
+	if (srcy > dsty) {
+		offset_y = srcy - dsty;
+	} else {
+		offset_y = dsty - srcy;
+	}
+
+	if (dsty <= srcy) {
+		dir |= PM3_RENDER2D_YPOSITIVE;
+	}
+
+	if (dstx <= srcx) {
+		dir |= PM3_RENDER2D_XPOSITIVE;
+	}
+
+	x_align = (srcx & 0x1f);
+
+	pm3fb_wait(sc, 6);
+
+	if (rop == 3){ 
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CONFIG2D,
+		    PM3_CONFIG2D_USERSCISSOR_ENABLE | PM3_CONFIG2D_FOREGROUNDROP_ENABLE | PM3_CONFIG2D_BLOCKING |
+		    PM3_CONFIG2D_FOREGROUNDROP(rop) | PM3_CONFIG2D_FBWRITE_ENABLE);
+	} else {
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CONFIG2D,
+		    PM3_CONFIG2D_USERSCISSOR_ENABLE | PM3_CONFIG2D_FOREGROUNDROP_ENABLE | PM3_CONFIG2D_BLOCKING |
+		    PM3_CONFIG2D_FOREGROUNDROP(rop) | PM3_CONFIG2D_FBWRITE_ENABLE | PM3_CONFIG2D_FBDESTREAD_ENABLE);
+	}
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCISSORMINXY,
+	    ((dsty & 0x0fff) << 16) | (dstx & 0x0fff));
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCISSORMAXXY,
+	    (((dsty + height) & 0x0fff) << 16) | ((dstx + width) & 0x0fff));
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FBSOURCEREAD_BUFFEROFFSET,
+	    (((offset_y) & 0xffff) << 16) | ((offset_x) & 0xffff));
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RECTANGLEPOSITION,
+	    (((dsty) & 0xffff) << 16) | ((dstx - x_align) & 0xffff));
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RENDER2D,
+	    dir |
+	    PM3_RENDER2D_OPERATION_NORMAL | PM3_RENDER2D_SPANOPERATION | PM3_RENDER2D_FBSOURCEREADENABLE |
+	    (((height) & 0x0fff) << 16) | ((width + x_align) & 0x0fff));
+
+	pm3fb_flush_engine(sc);
+}
+
+static void
+pm3fb_cursor(void *cookie, int on, int row, int col)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct pm3fb_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) {
+			pm3fb_bitblt(sc, x, y, x, y, wi, he, 12);
+			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;
+			pm3fb_bitblt(sc, x, y, x, y, wi, he, 12);
+			ri->ri_flg |= RI_CURSOR;
+		}
+	} else {
+		scr->scr_ri.ri_crow = row;
+		scr->scr_ri.ri_ccol = col;
+		scr->scr_ri.ri_flg &= ~RI_CURSOR;
+	}
+}
+
+static void
+pm3fb_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 pm3fb_softc *sc = scr->scr_cookie;
+	uint32_t mode;
+
+	if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
+		void *data;
+		uint32_t fg, bg;
+		int uc, i;
+		int x, y, wi, he;
+
+		wi = font->fontwidth;
+		he = font->fontheight;
+
+		if (!CHAR_IN_FONT(c, font))
+			return;
+
+		bg = ri->ri_devcmap[(attr >> 16) & 0xf];
+		fg = ri->ri_devcmap[(attr >> 24) & 0xf];
+		x = ri->ri_xorigin + col * wi;
+		y = ri->ri_yorigin + row * he;
+		if (c == 0x20) {
+			pm3fb_rectfill(sc, x, y, wi, he, bg);
+		} else {
+			uc = c - font->firstchar;
+			data = (uint8_t *)font->data + uc * ri->ri_fontscale;
+			mode = PM3_RM_MASK_MIRROR;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+			switch (ri->ri_font->stride) {
+			case 1:
+				mode |= 4 << 7; 
+				break;
+			case 2:
+				mode |= 3 << 7;
+				break;
+			}
+#else
+			switch (ri->ri_font->stride) {
+			case 1:
+				mode |= 3 << 7;
+				break;
+			case 2:
+				mode |= 2 << 7;
+				break;
+			}
+#endif
+			pm3fb_wait(sc, 8);
+			bus_space_write_4(sc->sc_memt, sc->sc_regh,
+			    PM3_FOREGROUNDCOLOR, fg);
+			bus_space_write_4(sc->sc_memt, sc->sc_regh,
+			    PM3_BACKGROUNDCOLOR, bg);
+
+			bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_RASTERIZER_MODE, mode); 
+
+			bus_space_write_4(sc->sc_memt, sc->sc_regh,
+			    PM3_CONFIG2D, 
+			    PM3_CONFIG2D_USERSCISSOR_ENABLE | 
+			    PM3_CONFIG2D_USECONSTANTSOURCE | 
+			    PM3_CONFIG2D_FOREGROUNDROP_ENABLE | 
+			    PM3_CONFIG2D_FOREGROUNDROP(0x03) | 
+			    PM3_CONFIG2D_OPAQUESPAN | 
+			    PM3_CONFIG2D_FBWRITE_ENABLE);
+
+			bus_space_write_4(sc->sc_memt, sc->sc_regh,
+			    PM3_SCISSORMINXY, ((y & 0x0fff) << 16) | (x & 0x0fff));
+
+			bus_space_write_4(sc->sc_memt, sc->sc_regh,
+			    PM3_SCISSORMAXXY, (((y + he) & 0x0fff) << 16) | ((x + wi) & 0x0fff));
+
+			bus_space_write_4(sc->sc_memt, sc->sc_regh,
+			    PM3_RECTANGLEPOSITION, (((y) & 0xffff)<<16) | ((x) & 0xffff));
+
+			bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+			    PM3_RENDER2D,
+			    PM3_RENDER2D_XPOSITIVE |
+			    PM3_RENDER2D_YPOSITIVE |
+			    PM3_RENDER2D_OPERATION_SYNCONBITMASK |
+			    PM3_RENDER2D_SPANOPERATION |
+			    ((wi) & 0x0fff) | (((he) & 0x0fff) << 16));
+
+			pm3fb_wait(sc, he);
+
+			switch (ri->ri_font->stride) {
+			case 1: {
+				uint8_t *data8 = data;
+				uint32_t reg;
+				for (i = 0; i < he; i++) {
+					reg = *data8;
+					bus_space_write_4(sc->sc_memt,
+					    sc->sc_regh,
+					    PM3_BITMASKPATTERN, reg);
+					data8++;
+				}
+				break;
+				}
+			case 2: {
+				uint16_t *data16 = data;
+				uint32_t reg;
+				for (i = 0; i < he; i++) {
+					reg = *data16;
+					bus_space_write_4(sc->sc_memt,
+					    sc->sc_regh,
+					    PM3_BITMASKPATTERN, reg);
+					data16++;
+				}
+				break;
+			}
+			}
+		}
+	}
+}
+
+static void
+pm3fb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct pm3fb_softc *sc = scr->scr_cookie;
+	int32_t xs, xd, y, width, height;
+
+	if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
+		xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol;
+		xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol;
+		y = ri->ri_yorigin + ri->ri_font->fontheight * row;
+		width = ri->ri_font->fontwidth * ncols;
+		height = ri->ri_font->fontheight;
+		pm3fb_bitblt(sc, xs, y, xd, y, width, height, 3);
+	}
+}
+
+static void
+pm3fb_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct pm3fb_softc *sc = scr->scr_cookie;
+	int32_t x, y, width, height, fg, bg, ul;
+
+	if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
+		x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol;
+		y = ri->ri_yorigin + ri->ri_font->fontheight * row;
+		width = ri->ri_font->fontwidth * ncols;
+		height = ri->ri_font->fontheight;
+		rasops_unpack_attr(fillattr, &fg, &bg, &ul);
+
+		pm3fb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]);
+	}
+}
+
+static void
+pm3fb_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct pm3fb_softc *sc = scr->scr_cookie;
+	int32_t x, ys, yd, width, height;
+
+	if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
+		x = ri->ri_xorigin;
+		ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow;
+		yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow;
+		width = ri->ri_emuwidth;
+		height = ri->ri_font->fontheight*nrows;
+		pm3fb_bitblt(sc, x, ys, x, yd, width, height, 3);
+	}
+}
+
+static void
+pm3fb_eraserows(void *cookie, int row, int nrows, long fillattr)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct pm3fb_softc *sc = scr->scr_cookie;
+	int32_t x, y, width, height, fg, bg, ul;
+
+	if ((sc->sc_locked == 0) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
+		x = ri->ri_xorigin;
+		y = ri->ri_yorigin + ri->ri_font->fontheight * row;
+		width = ri->ri_emuwidth;
+		height = ri->ri_font->fontheight * nrows;
+		rasops_unpack_attr(fillattr, &fg, &bg, &ul);
+
+		pm3fb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]);
+	}
+}
+
+/* should be enough */
+#define MODE_IS_VALID(m) (((m)->hdisplay < 2048))
+
+static void
+pm3_setup_i2c(struct pm3fb_softc *sc)
+{
+	int i;
+
+	/* Fill in the i2c tag */
+	sc->sc_i2c.ic_cookie = sc;
+	sc->sc_i2c.ic_acquire_bus = pm3fb_i2c_acquire_bus;
+	sc->sc_i2c.ic_release_bus = pm3fb_i2c_release_bus;
+	sc->sc_i2c.ic_send_start = pm3fb_i2c_send_start;
+	sc->sc_i2c.ic_send_stop = pm3fb_i2c_send_stop;
+	sc->sc_i2c.ic_initiate_xfer = pm3fb_i2c_initiate_xfer;
+	sc->sc_i2c.ic_read_byte = pm3fb_i2c_read_byte;
+	sc->sc_i2c.ic_write_byte = pm3fb_i2c_write_byte;
+	sc->sc_i2c.ic_exec = NULL;
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DISPLAY_DATA, 0);
+
+	/* zero out the EDID buffer */
+	memset(sc->sc_edid_data, 0, 128);
+
+	/* Some monitors don't respond first time */
+	i = 0;
+	while (sc->sc_edid_data[1] == 0 && i < 10) {
+		ddc_read_edid(&sc->sc_i2c, sc->sc_edid_data, 128);
+		i++;
+	}
+
+	if (edid_parse(&sc->sc_edid_data[0], &sc->sc_ei) != -1) {
+		/*
+		 * Now pick a mode.
+		 */
+		if ((sc->sc_ei.edid_preferred_mode != NULL)) {
+			struct videomode *m = sc->sc_ei.edid_preferred_mode;
+			if (MODE_IS_VALID(m)) {
+				sc->sc_videomode = m;
+			} else {
+				aprint_error_dev(sc->sc_dev,
+				    "unable to use preferred mode\n");
+			}
+		}
+		/*
+		 * if we can't use the preferred mode go look for the
+		 * best one we can support
+		 */
+		if (sc->sc_videomode == NULL) {
+			struct videomode *m = sc->sc_ei.edid_modes;
+
+			sort_modes(sc->sc_ei.edid_modes,
+			    &sc->sc_ei.edid_preferred_mode,
+			    sc->sc_ei.edid_nmodes);
+			if (sc->sc_videomode == NULL)
+				for (int n = 0; n < sc->sc_ei.edid_nmodes; n++)
+					if (MODE_IS_VALID(&m[n])) {
+						sc->sc_videomode = &m[n];
+						break;
+					}
+		}
+	}
+	if (sc->sc_videomode == NULL) {
+		/* no EDID data? */
+		sc->sc_videomode = pick_mode_by_ref(sc->sc_width,
+		    sc->sc_height, 60);
+	}
+	if (sc->sc_videomode != NULL) {
+		pm3fb_set_mode(sc, sc->sc_videomode);
+	}
+}
+
+/* I2C bitbanging */
+static void pm3fb_i2cbb_set_bits(void *cookie, uint32_t bits)
+{
+	struct pm3fb_softc *sc = cookie;
+	uint32_t out;
+
+	out = bits << 2;	/* bitmasks match the IN bits */
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_DISPLAY_DATA, out);
+	delay(100);
+}
+
+static void pm3fb_i2cbb_set_dir(void *cookie, uint32_t dir)
+{
+	/* Nothing to do */
+}
+
+static uint32_t pm3fb_i2cbb_read(void *cookie)
+{
+	struct pm3fb_softc *sc = cookie;
+	uint32_t bits;
+
+	bits = bus_space_read_4(sc->sc_memt, sc->sc_regh, PM3_DISPLAY_DATA);
+	return bits;
+}
+
+/* higher level I2C stuff */
+static int
+pm3fb_i2c_acquire_bus(void *cookie, int flags)
+{
+	/* private bus */
+	return (0);
+}
+
+static void
+pm3fb_i2c_release_bus(void *cookie, int flags)
+{
+	/* private bus */
+}
+
+static int
+pm3fb_i2c_send_start(void *cookie, int flags)
+{
+
+	return (i2c_bitbang_send_start(cookie, flags, &pm3fb_i2cbb_ops));
+}
+
+static int
+pm3fb_i2c_send_stop(void *cookie, int flags)
+{
+
+	return (i2c_bitbang_send_stop(cookie, flags, &pm3fb_i2cbb_ops));
+}
+
+static int
+pm3fb_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
+{
+
+	return (i2c_bitbang_initiate_xfer(cookie, addr, flags,
+	    &pm3fb_i2cbb_ops));
+}
+
+static int
+pm3fb_i2c_read_byte(void *cookie, uint8_t *valp, int flags)
+{
+
+	return (i2c_bitbang_read_byte(cookie, valp, flags, &pm3fb_i2cbb_ops));
+}
+
+static int
+pm3fb_i2c_write_byte(void *cookie, uint8_t val, int flags)
+{
+	return (i2c_bitbang_write_byte(cookie, val, flags, &pm3fb_i2cbb_ops));
+}
+
+static int
+pm3fb_set_pll(struct pm3fb_softc *sc, int freq)
+{
+	uint8_t bf = 0, bpre = 0, bpost = 0;
+	int count;
+	unsigned long feedback, prescale, postscale, IntRef, VCO, out_freq, diff,  VCOlow, VCOhigh, bdiff = 1000000;
+
+	freq *= 10; /* convert into 100Hz units */
+
+	for (postscale = 0; postscale <= 5; postscale++) {
+		/*
+		 * It is pointless going through the main loop if all values of
+		 * prescale produce an VCO outside the acceptable range
+		 */
+		prescale = 1;
+		feedback = (prescale * (1UL << postscale) * freq) / (2 * PM3_EXT_CLOCK_FREQ);
+		VCOlow = (2 * PM3_EXT_CLOCK_FREQ * feedback) / prescale;
+		if (VCOlow > PM3_VCO_FREQ_MAX)
+			continue;
+
+		prescale = 255;
+		feedback = (prescale * (1UL << postscale) * freq) / (2 * PM3_EXT_CLOCK_FREQ);
+		VCOhigh = (2 * PM3_EXT_CLOCK_FREQ * feedback) / prescale;
+		if (VCOhigh < PM3_VCO_FREQ_MIN)
+			continue;
+
+		for (prescale = 1; prescale <= 255; prescale++) {
+			IntRef = PM3_EXT_CLOCK_FREQ / prescale;
+			if (IntRef < PM3_INTREF_MIN || IntRef > PM3_INTREF_MAX) {
+				if (IntRef > PM3_INTREF_MAX) {
+				/*
+				 * Hopefully we will get into range as the prescale
+				 * value increases
+				 */
+					continue;
+				} else {
+					/*
+					 * already below minimum and it will only get worse
+					 * move to the next postscale value
+					 */
+					break;
+				}
+			}
+
+			feedback = (prescale * (1UL << postscale) * freq) / (2 * PM3_EXT_CLOCK_FREQ);
+
+			if (feedback > 255) {
+				/*
+				 * prescale, feedbackscale & postscale registers
+				 * are only 8 bits wide
+				 */
+				break;
+			} else if (feedback == 255) {
+				count = 1;
+			} else {
+				count = 2;
+			}
+
+			do {
+				VCO = (2 * PM3_EXT_CLOCK_FREQ * feedback) / prescale;
+				if (VCO >= PM3_VCO_FREQ_MIN && VCO <= PM3_VCO_FREQ_MAX) {
+					out_freq = VCO / (1UL << postscale);
+					diff = abs(out_freq - freq);
+					if (diff < bdiff) {
+						bdiff = diff;
+						bf = feedback;
+						bpre = prescale;
+						bpost = postscale;
+						if (diff == 0)
+							goto out;
+					}
+				}
+				feedback++;
+			} while (--count >= 0);
+		}
+	}
+out:
+	pm3fb_write_dac(sc, PM3_RAMDAC_CMD_CLOCK0_PRE_SCALE, bpre);
+	pm3fb_write_dac(sc, PM3_RAMDAC_CMD_CLOCK0_FEEDBACK_SCALE, bf);
+	pm3fb_write_dac(sc, PM3_RAMDAC_CMD_CLOCK0_POST_SCALE, bpost);
+	return 0;
+}
+
+static void
+pm3fb_set_mode(struct pm3fb_softc *sc, const struct videomode *mode)
+{
+	int t1, t2, t3, t4, stride;
+	uint32_t vclk, tmp1;
+	uint8_t sync = 0;
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_BYPASS_MASK, 0xffffffff);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_APERTURE1_CONTROL, 0x00000000);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_APERTURE2_CONTROL, 0x00000000);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FIFODISCONNECT, 0x00000007);
+
+	t1 = mode->hsync_start - mode->hdisplay;
+	t2 = mode->vsync_start - mode->vdisplay;
+	t3 = mode->hsync_end - mode->hsync_start;
+	t4 = mode->vsync_end - mode->vsync_start;
+        stride = (mode->hdisplay + 31) & ~31;
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_TOTAL,
+	    ((mode->htotal - 1) >> 4));
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_SYNC_END,
+	    (t1 + t3) >> 4);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_SYNC_START,
+	    (t1 >> 4));
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_BLANK_END,
+	    (mode->htotal - mode->hdisplay) >> 4);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_HORIZ_GATE_END,
+	    (mode->htotal - mode->hdisplay) >> 4);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCREEN_STRIDE,
+	    (stride >> 4));
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh,
+	    PM3_VERT_TOTAL, mode->vtotal - 1);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh,
+	    PM3_VERT_SYNC_END, t2 + t4 - 1);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh,
+	    PM3_VERT_SYNC_START, t2 - 1);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh,
+	    PM3_VERT_BLANK_END, mode->vtotal - mode->vdisplay);
+
+	/*8bpp*/
+	bus_space_write_4(sc->sc_memt, sc->sc_regh,
+	    PM3_BYAPERTURE1MODE, PM3_BYAPERTUREMODE_PIXELSIZE_8BIT);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh,
+	    PM3_BYAPERTURE2MODE, PM3_BYAPERTUREMODE_PIXELSIZE_8BIT);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_VIDEO_CONTROL,
+	    (PM3_VC_ENABLE | PM3_VC_HSC_ACTIVE_HIGH | PM3_VC_VSC_ACTIVE_HIGH | PM3_VC_PIXELSIZE_8BIT));
+
+	vclk = bus_space_read_4(sc->sc_memt, sc->sc_regh, PM3_V_CLOCK_CTL);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_V_CLOCK_CTL, (vclk & 0xFFFFFFFC));
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_SCREEN_BASE, 0x0);
+
+	tmp1 = bus_space_read_4(sc->sc_memt, sc->sc_regh, PM3_CHIP_CONFIG);
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_CHIP_CONFIG, tmp1 & 0xFFFFFFFD);
+
+	pm3fb_set_pll(sc, mode->dot_clock);
+
+	if (mode->flags & VID_PHSYNC)
+		sync |= PM3_SC_HSYNC_ACTIVE_HIGH;
+	if (mode->flags & VID_PVSYNC)
+		sync |= PM3_SC_VSYNC_ACTIVE_HIGH;
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh,
+	    PM3_RD_PM3_INDEX_CONTROL, PM3_INCREMENT_DISABLE);
+	pm3fb_write_dac(sc, PM3_RAMDAC_CMD_SYNC_CONTROL, sync);
+	pm3fb_write_dac(sc, PM3_RAMDAC_CMD_DAC_CONTROL, 0x00);
+
+	pm3fb_write_dac(sc, PM3_RAMDAC_CMD_PIXEL_SIZE, PM3_DACPS_8BIT);
+	pm3fb_write_dac(sc, PM3_RAMDAC_CMD_COLOR_FORMAT,
+	    (PM3_CF_ORDER_BGR | PM3_CF_VISUAL_256_COLOR));
+	pm3fb_write_dac(sc, PM3_RAMDAC_CMD_MISC_CONTROL, PM3_MC_DAC_SIZE_8BIT);
+
+	bus_space_write_4(sc->sc_memt, sc->sc_regh, PM3_FIFOCONTROL, 0x00000905);
+
+	sc->sc_width = mode->hdisplay;
+	sc->sc_height = mode->vdisplay;
+	sc->sc_depth = 8;
+	sc->sc_stride = stride;
+	aprint_normal_dev(sc->sc_dev, "pm3 using %d x %d in 8 bit, stride %d\n",
+	    sc->sc_width, sc->sc_height, sc->sc_width);
+}
diff -Naru src.orig/sys/dev/pci/pm3reg.h src/sys/dev/pci/pm3reg.h
--- src.orig/sys/dev/pci/pm3reg.h	1970-01-01 00:00:00.000000000 +0000
+++ src/sys/dev/pci/pm3reg.h	2014-12-31 11:21:37.000000000 +0000
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2015 Naruaki Etomi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * register definitions for Permedia 3 graphics controllers
+ */
+
+
+#ifndef PM3_REG_H
+#define PM3_REG_H
+
+#define PM3_EXT_CLOCK_FREQ 143180 /*in 100Hz units*/
+#define PM3_VCO_FREQ_MIN 2000000 /*in 100Hz units*/
+#define PM3_VCO_FREQ_MAX 6220000 /*in 100Hz units*/
+#define PM3_INTREF_MIN 10000 /*in 100Hz units*/
+#define PM3_INTREF_MAX 20000 /*in 100Hz units*/
+
+/*
+ * PM3 RAMDAC Indirect Commands
+ */
+
+#define PM3_RAMDAC_CMD_MISC_CONTROL            0x000
+#define PM3_RAMDAC_CMD_SYNC_CONTROL            0x001
+#define PM3_RAMDAC_CMD_DAC_CONTROL             0x002
+#define PM3_RAMDAC_CMD_PIXEL_SIZE              0x003
+#define PM3_RAMDAC_CMD_COLOR_FORMAT            0x004
+#define PM3_RAMDAC_CMD_CLOCK0_PRE_SCALE        0x201
+#define PM3_RAMDAC_CMD_CLOCK0_FEEDBACK_SCALE   0x202
+#define PM3_RAMDAC_CMD_CLOCK0_POST_SCALE       0x203
+
+/*
+ * PM3 RAMDAC Indirect Command SYNC_CONTROL
+ */
+
+#define PM3_SC_HSYNC_ACTIVE_LOW                0x000
+#define PM3_SC_HSYNC_ACTIVE_HIGH               0x001
+#define PM3_SC_HSYNC_FORCE_ACTIVE              0x003
+#define PM3_SC_HSYNC_FORCE_INACTIVE            0x004
+#define PM3_SC_VSYNC_ACTIVE_LOW                0x000
+#define PM3_SC_VSYNC_ACTIVE_HIGH               0x008
+#define PM3_SC_VSYNC_FORCE_ACTIVE              0x018
+#define PM3_SC_VSYNC_FORCE_INACTIVE            0x020
+
+/*
+ * PM3 RAMDAC Indirect Command DAC_CONTROL
+ */
+
+#define PM3_DC_NORMAL_POWER                    0x000
+#define PM3_DC_LOW_POWER                       0x001
+#define PM3_DC_SYNC_ON_GREEN_ENABLE            0x008
+#define PM3_DC_SYNC_ON_GREEN_DISABLE           0x000
+#define PM3_DC_BLANK_PEDESTAL_ENABLE           0x080
+#define PM3_DC_BLANK_PEDESTAL_DISABLE          0x000
+
+/*
+ * PM3 RAMDAC Indirect Command PIXEL_SIZE
+ */
+
+#define PM3_DACPS_8BIT                         0x000
+#define PM3_DACPS_16BIT                        0x001
+#define PM3_DACPS_32BIT                        0x002
+#define PM3_DACPS_24BIT                        0x004
+
+/*
+ * PM3 RAMDAC Indirect Command COLOR_FORMAT
+ */
+
+#define PM3_CF_VISUAL_256_COLOR                0x00e
+#define PM3_CF_VISUAL_HIGH_COLOR               0x010
+#define PM3_CF_VISUAL_TRUE_COLOR               0x000
+#define PM3_CF_ORDER_BGR                       0x020
+#define PM3_CF_ORDER_RGB                       0x000
+#define PM3_CF_LINEAR_COLOR_EXT_ENABLE         0x040
+#define PM3_CF_LINEAR_COLOR_EXT_DISABLE        0x000
+
+/*
+ * PM3 RAMDAC Indirect Command MISC_CONTROL
+ */
+
+#define PM3_MC_DAC_SIZE_8BIT                   0x001
+#define PM3_MC_DAC_SIZE_6BIT                   0x000
+#define PM3_MC_PIXEL_DOUBLE_ENABLE             0x002
+#define PM3_MC_PIXEL_DOUBLE_DISABLE            0x000
+#define PM3_MC_LAST_READ_ADDR_ENABLE           0x004
+#define PM3_MC_LAST_READ_ADDR_DISABLE          0x000
+#define PM3_MC_DIRECT_COLOR_ENABLE             0x008
+#define PM3_MC_DIRECT_COLOR_DISABLE            0x000
+#define PM3_MC_OVERLAY_ENABLE                  0x010
+#define PM3_MC_OVERLAY_DISABLE                 0x000
+#define PM3_MC_PIXEL_DB_ENABLE                 0x020
+#define PM3_MC_PIXEL_DB_DISABLE                0x000
+#define PM3_MC_STEREO_DB_ENABLE                0x040
+#define PM3_MC_STEREO_DB_DISABLE               0x000
+
+/*
+ * PM3 Registers
+ */
+
+#define PM3_INPUT_FIFO_SPACE                   0x00000018
+#define PM3_OUTPUT_FIFO_WORDS                  0x00000020
+#define PM3_V_CLOCK_CTL                        0x00000040
+#define PM3_APERTURE1_CONTROL                  0x00000050
+#define PM3_APERTURE2_CONTROL                  0x00000058
+#define              PM3_AP_MEMORY_BYTE_STANDARD                   0x00000000
+#define              PM3_AP_MEMORY_BYTE_SWAPPED                    0x00000001
+#define PM3_FIFODISCONNECT                     0x00000068
+#define PM3_CHIP_CONFIG                        0x00000070
+#define PM3_BYAPERTURE1MODE                    0x00000300
+#define PM3_BYAPERTURE2MODE                    0x00000328
+#define              PM3_BYAPERTUREMODE_PIXELSIZE_8BIT             0x00000000
+#define              PM3_BYAPERTUREMODE_PIXELSIZE_16BIT            0x00000020
+#define              PM3_BYAPERTUREMODE_PIXELSIZE_32BIT            0x00000040
+
+#define PM3_BYPASS_MASK                        0x00001008
+#define PM3_LOCALMEMCAPS                       0x00001018
+#define PM3_LOCALMEMTIMINGS                    0x00001020
+#define PM3_LOCALMEMCONTROL                    0x00001028
+
+#define PM3_OUTPUT_FIFO                        0x00002000
+
+#define PM3_SCREEN_BASE                        0x00003000
+#define PM3_SCREEN_STRIDE                      0x00003008
+#define PM3_HORIZ_TOTAL                        0x00003010
+#define PM3_HORIZ_GATE_END                     0x00003018
+#define PM3_HORIZ_BLANK_END                    0x00003020
+#define PM3_HORIZ_SYNC_START                   0x00003028
+#define PM3_HORIZ_SYNC_END                     0x00003030
+#define PM3_VERT_TOTAL                         0x00003038
+#define PM3_VERT_BLANK_END                     0x00003040
+#define PM3_VERT_SYNC_START                    0x00003048
+#define PM3_VERT_SYNC_END                      0x00003050
+#define PM3_VIDEO_CONTROL                      0x00003058
+#define              M3_VC_DISABLE                                 0x00000000
+#define              PM3_VC_ENABLE                                 0x00000001
+#define              PM3_VC_BL_ACTIVE_HIGH                         0x00000000
+#define              PM3_VC_BL_ACTIVE_LOW                          0x00000002
+#define              PM3_VC_LD_DISABLE                             0x00000000
+#define              PM3_VC_LD_ENABLE                              0x00000004
+#define              PM3_VC_HSC_FORCE_HIGH                         0x00000000
+#define              PM3_VC_HSC_ACTIVE_HIGH                        0x00000008
+#define              PM3_VC_HSC_FORCE_LOW                          0x00000010
+#define              PM3_VC_HSC_ACTIVE_LOW                         0x00000018
+#define              PM3_VC_VSC_FORCE_HIGH                         0x00000000
+#define              PM3_VC_VSC_ACTIVE_HIGH                        0x00000020
+#define              PM3_VC_VSC_FORCE_LOW                          0x00000040
+#define              PM3_VC_VSC_ACTIVE_LOW                         0x00000060
+#define              PM3_VC_PIXELSIZE_8BIT                         0x00000000
+#define              PM3_VC_PIXELSIZE_16BIT                        0x00080000
+#define              PM3_VC_PIXELSIZE_32BIT                        0x00B00000
+#define              PM3_VC_DISPLAY_ENABLE                         0x00010000
+#define              PM3_VC_DISPLAY_DISABLE                        0x00000000
+#define PM3_DISPLAY_DATA                       0x00003068
+#define              PM3_DD_SDA_IN                                 0x00000001
+#define              PM3_DD_SCL_IN                                 0x00000002
+#define PM3_FIFOCONTROL                        0x00003078
+#define PM3_RD_PM3_INDEX_CONTROL               0x00004038
+#define              PM3_INCREMENT_ENABLE                          0x00000001
+#define              PM3_INCREMENT_DISABLE                         0x00000000
+#define PM3_DAC_PAL_WRITE_IDX                  0x00004000
+#define PM3_DAC_PAL_DATA                       0x00004008
+#define PM3_DAC_INDEX_LOW                      0x00004020
+#define PM3_DAC_INDEX_HIGH                     0x00004028
+#define PM3_DAC_INDEX_DATA                     0x00004030
+#define PM3_DAC_INDEX_CONTROL                  0x00004038
+
+#define PM3_STARTXDOM                          0x00008000
+#define PM3_STARTXSUB                          0x00008010
+#define PM3_STARTY                             0x00008020
+#define PM3_COUNT                              0x00008030
+#define PM3_DXDOM                              0x00008008
+#define PM3_DXSUB                              0x00008018
+#define PM3_DY                                 0x00008028
+#define PM3_BITMASKPATTERN                     0x00008068
+#define PM3_RASTERIZER_MODE                    0x000080a0
+#define              PM3_RM_MASK_MIRROR                            0x00000001 /* mask is right-to-left */
+#define PM3_PIXEL_SIZE                         0x000080c0
+#define              PM3_PS_8BIT                                   0x00000002
+#define              PM3_PS_16BIT                                  0x00000001
+#define              PM3_PS_32BIT                                  0x00000000
+#define PM3_SPANCOLORMASK                      0x00008168
+#define PM3_SCISSOR_MODE                       0x00008180
+#define PM3_SCISSORMAXXY                       0x00008190
+#define PM3_SCISSORMINXY                       0x00008188
+#define PM3_AREASTIPPLE_MODE                   0x000081a0
+#define PM3_LINESTIPPLE_MODE                   0x000081a8
+#define PM3_TEXTUREADDRESS_MODE                0x00008380
+#define PM3_TEXTUREFILTER_MODE                 0x000084e0
+#define PM3_TEXTUREREAD_MODE                   0x00008670
+#define PM3_TEXTURECOLOR_MODE                  0x00008680
+#define PM3_FOG_MODE                           0x00008690
+#define PM3_COLORDDA_MODE                      0x000087e0
+#define PM3_ALPHATEST_MODE                     0x00008800
+#define PM3_ANTIALIAS_MODE                     0x00008808
+#define PM3_DITHER_MODE                        0x00008818
+#define              PM3_CF_TO_DIM_CF(_cf)                         ((((_cf) & 0x0f) << 2) | ( 1 << 10))
+#define PM3_FBSOFTWAREWRITEMASK                0x00008820
+#define PM3_LOGICALOP_MODE                     0x00008828
+#define PM3_ROUTER_MODE                        0x00008840
+#define PM3_LB_WRITE_MODE                      0x000088c0
+#define              PM3_LB_DISABLE                                0x00000000
+#define PM3_WINDOW                             0x00008980
+#define PM3_STENCIL_MODE                       0x00008988
+#define PM3_STENCIL_DATA                       0x00008990
+#define PM3_DEPTH_MODE                         0x000089a0
+#define PM3_FBWRITE_MODE                       0x00008ab8
+#define              PM3_FBWRITEMODE_WRITEENABLE                   0x00000001
+#define              PM3_FBWRITEMODE_OPAQUESPAN                    0x00000020
+#define              PM3_FBWRITEMODE_ENABLE0                       0x00001000
+#define PM3_FBHARDWAREWRITEMASK                0x00008ac0
+#define PM3_FILTER_MODE                        0x00008c00
+#define              PM3_FM_PASS_SYNC                              0x00000400
+#define PM3_STATISTIC_MODE                     0x00008c08
+#define PM3_SYNC                               0x00008c40
+#define              PM3_SYNC_TAG                                  0x188
+#define PM3_YUV_MODE                           0x00008f00
+#define PM3_CHROMATEST_MODE                    0x00008f18
+#define PM3_DELTA_MODE                         0x00009300
+#define PM3_DELTACONTROL                       0x00009350
+#define PM3_XBIAS                              0x00009480
+#define PM3_YBIAS                              0x00009488
+#define PM3_FBDESTREAD_BUFFERADDRESS0          0x0000ae80
+#define PM3_FBDESTREAD_BUFFEROFFSET0           0x0000aea0
+#define PM3_FBDESTREAD_BUFFERWIDTH0            0x0000aec0
+#define              PM3_FBDESTREAD_BUFFERWIDTH_WIDTH(_w)          ((_w) & 0x0fff)
+#define PM3_FB_DESTREAD_MODE                   0x0000aee0
+#define              PM3_FBDRM_ENABLE                              0x00000001
+#define              PM3_FBDRM_ENABLE0                             0x00000100
+#define PM3_FBDESTREAD_ENABLE                  0x0000aee8
+#define              PM3_FBDESTREAD_SET(_e, _r, _a)                (((_e) & 0xff) | (((_r) & 0xff) << 8) | (((_a) & 0xff) << 24))
+#define PM3_FBSOURCEREAD_MODE                  0x0000af00
+#define              PM3_FBSOURCEREAD_MODE_ENABLE                  0x00000001
+#define              PM3_FBSOURCEREAD_MODE_BLOCKING                0x00000800
+#define PM3_FBSOURCEREAD_BUFFERADDRESS         0x0000af08
+#define PM3_FBSOURCEREAD_BUFFEROFFSET          0x0000af10
+#define PM3_FBSOURCEREAD_BUFFERWIDTH           0x0000af18
+#define              PM3_FBSOURCEREAD_BUFFERWIDTH_WIDTH(_w)        ((_w) & 0x0fff)
+#define PM3_ALPHABLENDCOLOR_MODE               0x0000afa0
+#define PM3_ALPHABLENDALPHA_MODE               0x0000afa8
+#define PM3_FBWRITEBUFFERADDRESS0              0x0000b000
+#define PM3_FBWRITEBUFFEROFFSET0               0x0000b020
+#define PM3_FBWRITEBUFFERWIDTH0                0x0000b040
+#define              PM3_FBWRITEBUFFERWIDTH_WIDTH(_w)              ((_w) & 0x0fff)
+#define PM3_SIZEOF_FRAMEBUFFER                 0x0000b0a8
+#define PM3_FOREGROUNDCOLOR                    0x0000b0c0
+#define PM3_BACKGROUNDCOLOR                    0x0000b0c8
+#define PM3_TEXTURECOMPOSITE_MODE              0x0000b300
+#define PM3_TEXTURECOMPOSITECOLOR_MODE0        0x0000b308
+#define PM3_TEXTURECOMPOSITEALPHA_MODE0        0x0000b310
+#define PM3_TEXTURECOMPOSITECOLOR_MODE1        0x0000b318
+#define PM3_TEXTURECOMPOSITEALPHA_MODE1        0x0000b320
+#define PM3_TEXTUREINDEX_MODE0                 0x0000b338
+#define PM3_TEXTUREINDEX_MODE1                 0x0000b340
+#define PM3_TEXELLUT_MODE                      0x0000b378
+#define PM3_LB_DESTREAD_MODE                   0x0000b500
+#define PM3_LB_DESTREAD_ENABLES                0x0000b508
+#define PM3_LB_SOURCEREAD_MODE                 0x0000b520
+#define PM3_GID_MODE                           0x0000b538
+#define PM3_RECTANGLEPOSITION                  0x0000b600
+#define PM3_CONFIG2D                           0x0000b618
+#define              PM3_CONFIG2D_OPAQUESPAN                       0x00000001
+#define              PM3_CONFIG2D_MULTIRXBLIT                      0x00000002
+#define              PM3_CONFIG2D_USERSCISSOR_ENABLE               0x00000004
+#define              PM3_CONFIG2D_FBDESTREAD_ENABLE                0x00000008
+#define              PM3_CONFIG2D_ALPHABLEND_ENABLE                0x00000010
+#define              PM3_CONFIG2D_DITHER_ENABLE                    0x00000020
+#define              PM3_CONFIG2D_FOREGROUNDROP_ENABLE             0x00000040
+#define              PM3_CONFIG2D_FOREGROUNDROP(_rop)               (((_rop) & 0xF) << 7)
+#define              PM3_CONFIG2D_BACKGROUNDROP_ENABLE             0x00000800
+#define              PM3_CONFIG2D_BACKGROUNDROP(_rop)               (((_rop) & 0xF) << 12)
+#define              PM3_CONFIG2D_USECONSTANTSOURCE                0x00010000
+#define              PM3_CONFIG2D_FBWRITE_ENABLE                   0x00020000
+#define              PM3_CONFIG2D_BLOCKING                         0x00040000
+#define              PM3_CONFIG2D_EXTERNALSOURCEDATA               0x00080000
+#define              PM3_CONFIG2D_LUTMODE_ENABLE                   0x00100000
+#define PM3_RENDER2D                           0x0000b640
+#define              PM3_RENDER2D_OPERATION_NORMAL                 0x00000000
+#define              PM3_RENDER2D_OPERATION_SYNCONHOSTDATA         0x00001000
+#define              PM3_RENDER2D_OPERATION_SYNCONBITMASK          0x00002000
+#define              PM3_RENDER2D_OPERATION_PATCHORDERRENDERING    0x00003000
+#define              PM3_RENDER2D_FBSOURCEREADENABLE               0x00004000
+#define              PM3_RENDER2D_SPANOPERATION                    0x00008000
+#define              PM3_RENDER2D_XPOSITIVE                        0x10000000
+#define              PM3_RENDER2D_YPOSITIVE                        0x20000000
+#define              PM3_RENDER2D_AREASTIPPLEENABLE                0x40000000
+#define              PM3_RENDER2D_TEXTUREENABLE                    0x80000000
+
+#endif /* PM3_REG_H */



Home | Main Index | Thread Index | Old Index