Module Name:    src
Committed By:   macallan
Date:           Tue May  4 05:07:14 UTC 2010

Modified Files:
        src/sys/dev/pci: machfb.c

Log Message:
this has been sitting in my tree too long:
- device_t-ify
- sanitize debugging #ifdefs
- deal with firmwares setting up modes using other clocks than #0
- get rid of sparc and macppc-specific code, use device properties instead
- while there, use alternate box drawing font if needed


To generate a diff of this commit:
cvs rdiff -u -r1.58 -r1.59 src/sys/dev/pci/machfb.c

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

Modified files:

Index: src/sys/dev/pci/machfb.c
diff -u src/sys/dev/pci/machfb.c:1.58 src/sys/dev/pci/machfb.c:1.59
--- src/sys/dev/pci/machfb.c:1.58	Thu Mar 11 04:00:36 2010
+++ src/sys/dev/pci/machfb.c	Tue May  4 05:07:14 2010
@@ -1,7 +1,8 @@
-/*	$NetBSD: machfb.c,v 1.58 2010/03/11 04:00:36 mrg Exp $	*/
+/*	$NetBSD: machfb.c,v 1.59 2010/05/04 05:07:14 macallan Exp $	*/
 
 /*
  * Copyright (c) 2002 Bang Jun-Young
+ * Copyright (c) 2005, 2006, 2007 Michael Lorenz
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,7 +34,7 @@
 
 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, 
-	"$NetBSD: machfb.c,v 1.58 2010/03/11 04:00:36 mrg Exp $");
+	"$NetBSD: machfb.c,v 1.59 2010/05/04 05:07:14 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -41,18 +42,11 @@
 #include <sys/device.h>
 #include <sys/malloc.h>
 #include <sys/callout.h>
+#include <sys/lwp.h>
 #include <sys/kauth.h>
 
-#ifdef __sparc__
-#include <machine/promlib.h>
-#endif
-
-#ifdef __powerpc__
-#include <dev/ofw/openfirm.h>
-#include <dev/ofw/ofw_pci.h>
-#endif
-
 #include <dev/videomode/videomode.h>
+#include <dev/videomode/edidvar.h>
 
 #include <dev/pci/pcivar.h>
 #include <dev/pci/pcireg.h>
@@ -74,6 +68,9 @@
 
 #include <dev/wscons/wsdisplay_vconsvar.h>
 
+#include "opt_wsemul.h"
+#include "opt_machfb.h"
+
 #define MACH64_REG_SIZE		1024
 #define MACH64_REG_OFF		0x7ffc00
 
@@ -88,7 +85,7 @@
 };
 
 struct mach64_softc {
-	struct device sc_dev;
+	device_t sc_dev;
 #ifdef __sparc__
 	struct fbdevice sc_fb;
 #endif
@@ -111,6 +108,7 @@
 
 	bus_space_tag_t sc_regt;
 	bus_space_tag_t sc_memt;
+	bus_space_tag_t sc_iot;
 	bus_space_handle_t sc_regh;
 	bus_space_handle_t sc_memh;
 	void *sc_aperture;		/* mapped aperture vaddr */
@@ -142,8 +140,12 @@
 	int vclk_fb_div;
 	int mclk_post_div;
 	int mclk_fb_div;
+	int sc_clock;	/* which clock to use */
 
 	struct videomode *sc_my_mode;
+	int sc_edid_size;
+	uint8_t sc_edid_data[1024];
+
 	u_char sc_cmap_red[256];
 	u_char sc_cmap_green[256];
 	u_char sc_cmap_blue[256];
@@ -174,6 +176,7 @@
 	{ PCI_PRODUCT_ATI_RAGE_PRO_PCI_P, 230000 },
 	{ PCI_PRODUCT_ATI_RAGE_PRO_PCI_L, 230000 },
 	{ PCI_PRODUCT_ATI_RAGE_XL_PCI, 230000 },
+	{ PCI_PRODUCT_ATI_RAGE_XL_PCI66, 230000 },
 	{ PCI_PRODUCT_ATI_RAGE_II, 135000 },
 	{ PCI_PRODUCT_ATI_RAGE_IIP, 200000 },
 	{ PCI_PRODUCT_ATI_RAGE_IIC_PCI, 230000 },
@@ -183,11 +186,12 @@
 	{ PCI_PRODUCT_ATI_RAGE_LT_PRO_AGP, 230000 },
 	{ PCI_PRODUCT_ATI_RAGE_MOB_M3_PCI, 230000 },
 	{ PCI_PRODUCT_ATI_RAGE_MOB_M3_AGP, 230000 },
-	{ PCI_PRODUCT_ATI_RAGE_LT, 230000 },
-	{ PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI, 230000 },
 	{ PCI_PRODUCT_ATI_RAGE_MOBILITY, 230000 },
 	{ PCI_PRODUCT_ATI_RAGE_LT_PRO, 230000 },
 #endif
+	{ PCI_PRODUCT_ATI_RAGE_LT_PRO, 230000 },
+	{ PCI_PRODUCT_ATI_RAGE_LT, 230000 },
+	{ PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI, 230000 },
 	{ PCI_PRODUCT_ATI_MACH64_VT, 170000 },
 	{ PCI_PRODUCT_ATI_MACH64_VTB, 200000 },
 	{ PCI_PRODUCT_ATI_MACH64_VT4, 230000 }
@@ -224,7 +228,7 @@
 static int	mach64_match(device_t, cfdata_t, void *);
 static void	mach64_attach(device_t, device_t, void *);
 
-CFATTACH_DECL(machfb, sizeof(struct mach64_softc), mach64_match, mach64_attach,
+CFATTACH_DECL_NEW(machfb, sizeof(struct mach64_softc), mach64_match, mach64_attach,
     NULL, NULL);
 
 static void	mach64_init(struct mach64_softc *);
@@ -254,7 +258,7 @@
 static void	mach64_init_screen(void *, struct vcons_screen *, int, long *);
 static int 	mach64_set_screentype(struct mach64_softc *,
 				      const struct wsscreen_descr *);
-static int	mach64_is_console(struct pci_attach_args *);
+static int	mach64_is_console(struct mach64_softc *);
 
 static void	mach64_cursor(void *, int, int, int);
 #if 0
@@ -265,7 +269,6 @@
 static void	mach64_erasecols(void *, int, int, int, long);
 static void	mach64_copyrows(void *, int, int, int);
 static void	mach64_eraserows(void *, int, int, long);
-static int	mach64_allocattr(void *, int, int, int, long *);
 static void 	mach64_clearscreen(struct mach64_softc *);
 
 static int	mach64_putcmap(struct mach64_softc *, struct wsdisplay_cmap *);
@@ -284,19 +287,7 @@
 
 static void	set_address(struct rasops_info *, void *);
 static void	machfb_blank(struct mach64_softc *, int);
-
-#if 0
-static const struct wsdisplay_emulops mach64_emulops = {
-	mach64_cursor,
-	mach64_mapchar,
-	mach64_putchar,
-	mach64_copycols,
-	mach64_erasecols,
-	mach64_copyrows,
-	mach64_eraserows,
-	mach64_allocattr,
-};
-#endif
+static int	machfb_drm_print(void *, const char *);
 
 static struct wsscreen_descr mach64_defaultscreen = {
 	"default",
@@ -449,9 +440,26 @@
 static inline void
 regwb_pll(struct mach64_softc *sc, uint32_t index, uint8_t data)
 {
-	regwb(sc, CLOCK_CNTL + 1, (index << 2) | PLL_WR_EN);
-	regwb(sc, CLOCK_CNTL + 2, data);
-	regwb(sc, CLOCK_CNTL + 1, (index << 2) & ~PLL_WR_EN);
+	uint32_t reg;
+
+	reg = regr(sc, CLOCK_CNTL);
+	reg |= PLL_WR_EN;
+	regw(sc, CLOCK_CNTL, reg);
+	reg &= ~(PLL_ADDR | PLL_DATA);
+	reg |= (index & 0x3f) << PLL_ADDR_SHIFT;
+	reg |= data << PLL_DATA_SHIFT;
+	reg |= CLOCK_STROBE;
+	regw(sc, CLOCK_CNTL, reg);
+	reg &= ~PLL_WR_EN;
+	regw(sc, CLOCK_CNTL, reg);
+}
+
+static inline uint8_t
+regrb_pll(struct mach64_softc *sc, uint32_t index)
+{
+
+	regwb(sc, CLOCK_CNTL + 1, index << 2);
+	return regrb(sc, CLOCK_CNTL + 2);
 }
 
 static inline void
@@ -495,13 +503,17 @@
 	struct mach64_softc *sc = device_private(self);
 	struct pci_attach_args *pa = aux;
 	struct rasops_info *ri;
+	prop_data_t edid_data;
+	const struct videomode *mode = NULL;
 	char devinfo[256];
-	int bar, reg, id;
+	int bar, id;
 	struct wsemuldisplaydev_attach_args aa;
 	long defattr;
-	int setmode;
+	int setmode, width, height;
 	pcireg_t screg;
+	uint32_t reg;
 
+	sc->sc_dev = self;
 	sc->sc_pc = pa->pa_pc;
 	sc->sc_pcitag = pa->pa_tag;
 	sc->sc_dacw = -1;
@@ -510,16 +522,24 @@
 	sc->sc_ndev = pa->pa_device;
 	sc->sc_nfunc = pa->pa_function;
 	sc->sc_locked = 0;
+	sc->sc_iot = pa->pa_iot;
 
 	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));
+	aprint_normal(": %s (rev. 0x%02x)\n", devinfo, 
+	    PCI_REVISION(pa->pa_class));
 	aprint_naive(": Graphics processor\n");
+#ifdef DEBUG
+	printf(prop_dictionary_externalize(device_properties(self)));
+#endif
 	
-	/* enable memory and IO access */
+	/* enable memory and disable IO access */
 	screg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
-	screg |= PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
-	pci_conf_write(sc->sc_pc, sc->sc_pcitag,PCI_COMMAND_STATUS_REG,screg);
-
+	if ((screg & PCI_FLAGS_MEM_ENABLED) == 0) {
+		screg |= PCI_FLAGS_IO_ENABLED;
+		screg |= PCI_FLAGS_MEM_ENABLED;
+		pci_conf_write(sc->sc_pc, sc->sc_pcitag,
+		    PCI_COMMAND_STATUS_REG, screg);
+	}
 	for (bar = 0; bar < NBARS; bar++) {
 		reg = PCI_MAPREG_START + (bar * 4);
 		sc->sc_bars[bar].vb_type = pci_mapreg_type(sc->sc_pc,
@@ -528,18 +548,65 @@
 		    sc->sc_bars[bar].vb_type, &sc->sc_bars[bar].vb_base,
 		    &sc->sc_bars[bar].vb_size, &sc->sc_bars[bar].vb_flags);
 		sc->sc_bars[bar].vb_busaddr = pci_conf_read(sc->sc_pc,
-		    sc->sc_pcitag, reg)&0xfffffff0;
+		    sc->sc_pcitag, reg) & 0xfffffff0;
 	}
+	printf("%s: aperture size %08x\n", device_xname(sc->sc_dev), 
+	    (uint32_t)sc->sc_apersize);
+
+	sc->sc_rom.vb_type = PCI_MAPREG_TYPE_ROM;	
+	pci_mapreg_info(sc->sc_pc, sc->sc_pcitag, PCI_MAPREG_ROM,
+		    sc->sc_rom.vb_type, &sc->sc_rom.vb_base,
+		    &sc->sc_rom.vb_size, &sc->sc_rom.vb_flags);
 	sc->sc_memt = pa->pa_memt;
 
+	if (bus_space_map(sc->sc_memt, sc->sc_aperbase, sc->sc_apersize,
+		BUS_SPACE_MAP_LINEAR, &sc->sc_memh)) {
+		panic("%s: failed to map aperture", device_xname(sc->sc_dev));
+	}
+	sc->sc_aperture = (void *)bus_space_vaddr(sc->sc_memt, sc->sc_memh);
+
+	sc->sc_regt = sc->sc_memt;
+	bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF,
+	    sc->sc_regsize, &sc->sc_regh);
+	sc->sc_registers = (char *)sc->sc_aperture + 0x7ffc00;
+
 	mach64_init(sc);
 
-	aprint_normal_dev(&sc->sc_dev,
+	aprint_normal_dev(sc->sc_dev,
 	    "%d MB aperture at 0x%08x, %d KB registers at 0x%08x\n",
 	    (u_int)(sc->sc_apersize / (1024 * 1024)),
 	    (u_int)sc->sc_aperphys, (u_int)(sc->sc_regsize / 1024),
 	    (u_int)sc->sc_regphys);
 
+	printf("%s: %d KB ROM at 0x%08x\n", device_xname(sc->sc_dev),
+	    (int)sc->sc_rom.vb_size >> 10, (uint32_t)sc->sc_rom.vb_base);
+
+	prop_dictionary_get_uint32(device_properties(self), "width", &width);
+	prop_dictionary_get_uint32(device_properties(self), "height", &height);
+
+	if ((edid_data = prop_dictionary_get(device_properties(self), "EDIDDD"))
+	    != NULL) {
+	    	struct edid_info ei;
+
+		sc->sc_edid_size = min(1024, prop_data_size(edid_data));
+		memset(sc->sc_edid_data, 0, sizeof(sc->sc_edid_data));
+		memcpy(sc->sc_edid_data, prop_data_data_nocopy(edid_data),
+		    sc->sc_edid_size);
+
+		edid_parse(sc->sc_edid_data, &ei);
+
+#ifdef DEBUG
+		edid_print(&ei);
+#endif
+		if (ei.edid_have_range) {
+
+			/* ei has dotclock in MHz, struct videomode in kHz */
+			mode = pick_mode_by_dotclock(width, height,
+			    ei.edid_range.er_max_clock * 1000);
+			if (mode != NULL)
+				printf("mode: %s\n", mode->name);
+		}
+	}
 	if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_CT ||
 	    ((mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II) &&
@@ -559,21 +626,26 @@
 	if ((mach64_chip_id == PCI_PRODUCT_ATI_RAGE_XL_PCI) ||
 	    ((mach64_chip_id >= PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI) &&
 	    (mach64_chip_id <= PCI_PRODUCT_ATI_RAGE_LT_PRO))) {
-		aprint_normal_dev(&sc->sc_dev, "ref_freq=29.498MHz\n");
+		aprint_normal_dev(sc->sc_dev, "ref_freq=29.498MHz\n");
 		sc->ref_freq = 29498;
 	} else
 		sc->ref_freq = 14318;
 
-	regwb(sc, CLOCK_CNTL + 1, PLL_REF_DIV << 2);
-	sc->ref_div = regrb(sc, CLOCK_CNTL + 2);
-	regwb(sc, CLOCK_CNTL + 1, MCLK_FB_DIV << 2);
-	sc->mclk_fb_div = regrb(sc, CLOCK_CNTL + 2);
+	reg = regr(sc, CLOCK_CNTL);
+	printf("CLOCK_CNTL: %08x\n", reg);
+	sc->sc_clock = reg & 3;
+	printf("using clock %d\n", sc->sc_clock);
+
+	sc->ref_div = regrb_pll(sc, PLL_REF_DIV);
+	printf("ref_div: %d\n", sc->ref_div);
+	sc->mclk_fb_div = regrb_pll(sc, MCLK_FB_DIV);
+	printf("mclk_fb_div: %d\n", sc->mclk_fb_div);
 	sc->mem_freq = (2 * sc->ref_freq * sc->mclk_fb_div) /
 	    (sc->ref_div * 2);
 	sc->mclk_post_div = (sc->mclk_fb_div * 2 * sc->ref_freq) /
 	    (sc->mem_freq * sc->ref_div);
 	sc->ramdac_freq = mach64_get_max_ramdac(sc);
-	aprint_normal_dev(&sc->sc_dev,
+	aprint_normal_dev(sc->sc_dev,
 	    "%ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz\n",
 	    (u_long)sc->memsize,
 	    mach64_memtype_names[sc->memtype],
@@ -582,19 +654,24 @@
 
 	id = regr(sc, CONFIG_CHIP_ID) & 0xffff;
 	if (id != mach64_chip_id) {
-		aprint_error_dev(&sc->sc_dev,
+		aprint_error_dev(sc->sc_dev,
 		    "chip ID mismatch, 0x%x != 0x%x\n", id, mach64_chip_id);
 		return;
 	}
 
-	sc->sc_console = mach64_is_console(pa);
+	sc->sc_console = mach64_is_console(sc);
 #ifdef DIAGNOSTIC
 	aprint_normal("gen_cntl: %08x\n", regr(sc, CRTC_GEN_CNTL));
 #endif
 #if defined(__sparc__) || defined(__powerpc__)
 	if (sc->sc_console) {
-		mach64_get_mode(sc, &default_mode);
-		setmode = 0;
+		if (mode != NULL) {
+			memcpy(&default_mode, mode, sizeof(struct videomode));
+			setmode = 1;
+		} else {
+			mach64_get_mode(sc, &default_mode);
+			setmode = 0;
+		}
 		sc->sc_my_mode = &default_mode;
 	} else {
 		/* fill in default_mode if it's empty */
@@ -625,13 +702,16 @@
 	sc->color_depth = CRTC_PIX_WIDTH_8BPP;
 
 	mach64_init_engine(sc);
+
+	if (setmode)
+		mach64_modeswitch(sc, sc->sc_my_mode);
 #if 0
 	mach64_adjust_frame(0, 0);
 	if (sc->bits_per_pixel == 8)
 		mach64_init_lut(sc);
 #endif
 
-	aprint_normal_dev(&sc->sc_dev,
+	aprint_normal_dev(sc->sc_dev,
 	    "initial resolution %dx%d at %d bpp\n",
 	    sc->sc_my_mode->hdisplay, sc->sc_my_mode->vdisplay,
 	    sc->bits_per_pixel);
@@ -646,6 +726,10 @@
 	vcons_init(&sc->vd, sc, &mach64_defaultscreen, &mach64_accessops);
 	sc->vd.init_screen = mach64_init_screen;
 
+	mach64_init_lut(sc);
+	mach64_clearscreen(sc);
+	machfb_blank(sc, 0);	/* unblank the screen */
+
 	if (sc->sc_console) {
 		vcons_init_screen(&sc->vd, &mach64_console_screen, 1,
 		    &defattr);
@@ -657,6 +741,7 @@
 		mach64_defaultscreen.nrows = ri->ri_rows;
 		mach64_defaultscreen.ncols = ri->ri_cols;
 		wsdisplay_cnattach(&mach64_defaultscreen, ri, 0, 0, defattr);	
+		vcons_replay_msgbuf(&mach64_console_screen);
 	} else {
 		/*
 		 * since we're not the console we can postpone the rest
@@ -664,17 +749,23 @@
 		 */
 		mach64_modeswitch(sc, sc->sc_my_mode);		 
 	}
-	
-	mach64_init_lut(sc);
-	mach64_clearscreen(sc);
-	machfb_blank(sc, 0);	/* unblank the screen */
-	
+		
 	aa.console = sc->sc_console;
 	aa.scrdata = &mach64_screenlist;
 	aa.accessops = &mach64_accessops;
 	aa.accesscookie = &sc->vd;
 
 	config_found(self, &aa, wsemuldisplaydevprint);
+
+	config_found_ia(self, "drm", aux, machfb_drm_print);
+}
+
+static int
+machfb_drm_print(void *aux, const char *pnp)
+{
+	if (pnp)
+		aprint_normal("direct rendering for %s", pnp);
+	return (UNSUPP);
 }
 
 static void
@@ -698,12 +789,12 @@
 		ri->ri_flg |= RI_CLEAR;
 		if (setmode && mach64_set_screentype(sc, scr->scr_type)) {
 			panic("%s: failed to switch video mode",
-			    device_xname(&sc->sc_dev));
+			    device_xname(sc->sc_dev));
 		}
 	}
 	
-	rasops_init(ri, sc->sc_my_mode->vdisplay/8,
-	    sc->sc_my_mode->hdisplay/8);
+	rasops_init(ri, sc->sc_my_mode->vdisplay / 8,
+	    sc->sc_my_mode->hdisplay / 8);
 	ri->ri_caps = WSSCREEN_WSCOLORS;
 
 	rasops_reconfig(ri, sc->sc_my_mode->vdisplay / ri->ri_font->fontheight,
@@ -717,7 +808,6 @@
 	ri->ri_ops.erasecols = mach64_erasecols;
 	ri->ri_ops.cursor = mach64_cursor;
 	ri->ri_ops.putchar = mach64_putchar;
-	ri->ri_ops.allocattr = mach64_allocattr;
 }
 
 static void
@@ -727,17 +817,6 @@
 	uint8_t *p;
 	int need_swap;
 
-	if (bus_space_map(sc->sc_memt, sc->sc_aperbase, sc->sc_apersize,
-		BUS_SPACE_MAP_LINEAR, &sc->sc_memh)) {
-		panic("%s: failed to map aperture", device_xname(&sc->sc_dev));
-	}
-	sc->sc_aperture = (void *)bus_space_vaddr(sc->sc_memt, sc->sc_memh);
-
-	sc->sc_regt = sc->sc_memt;
-	bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF,
-	    sc->sc_regsize, &sc->sc_regh);
-	sc->sc_registers = (char *)sc->sc_aperture + 0x7ffc00;
-
 	/*
 	 * Test wether the aperture is byte swapped or not
 	 */
@@ -751,8 +830,11 @@
 		need_swap = 1;
 	if (need_swap) {
 		sc->sc_aperture = (char *)sc->sc_aperture + 0x800000;
+#if 0
+		/* what the fsck is this for? */
 		sc->sc_aperbase += 0x800000;
 		sc->sc_apersize -= 0x800000;
+#endif
 	}
 	*p32 = saved_value;
 	
@@ -768,7 +850,7 @@
 	};
 	tmp = regr(sc, MEM_CNTL);
 #ifdef DIAGNOSTIC
-	aprint_debug_dev(&sc->sc_dev, "memctl %08x\n", tmp);
+	aprint_debug_dev(sc->sc_dev, "memctl %08x\n", tmp);
 #endif
 	if (sc->has_dsp) {
 		tmp &= 0x0000000f;
@@ -890,7 +972,7 @@
 
 	if (sc->has_dsp)
 		mach64_set_dsp(sc);
-
+#if 1
 	regw(sc, CRTC_H_TOTAL_DISP, crtc->h_total_disp);
 	regw(sc, CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
 	regw(sc, CRTC_V_TOTAL_DISP, crtc->v_total_disp);
@@ -906,6 +988,7 @@
 	    CRTC_CSYNC_EN |
 #endif
 	    CRTC_EXT_DISP_EN | CRTC_EXT_EN);
+#endif
 }
 
 static int
@@ -917,7 +1000,12 @@
 
 	if (mach64_calc_crtcregs(sc, &crtc, mode))
 		return 1;
-
+	aprint_debug("crtc dot clock: %d\n", crtc.dot_clock);
+	if (crtc.dot_clock == 0) {
+		aprint_error("%s: preposterous dot clock (%d)\n", 
+		    device_xname(sc->sc_dev), crtc.dot_clock);
+		return 1;
+	}
 	mach64_set_crtcregs(sc, &crtc);
 	return 0;
 }
@@ -1006,13 +1094,11 @@
 		/* We want 8 bit per channel */
 		regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
 		break;
-#if 0
 	case 32:
 		regw(sc, DP_PIX_WIDTH, HOST_32BPP | SRC_32BPP | DST_32BPP);
 		regw(sc, DP_CHAIN_MASK, DP_CHAIN_32BPP);
 		regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
 		break;
-#endif
 	}
 
 	wait_for_fifo(sc, 5);
@@ -1043,7 +1129,8 @@
 	uint32_t xclks_per_qw, y;
 	uint32_t fifo_off, fifo_on;
 
-	aprint_normal_dev(&sc->sc_dev, "initializing the DSP\n");
+	aprint_normal_dev(sc->sc_dev, "initializing the DSP\n");
+
 	if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II ||
 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIP ||
@@ -1108,7 +1195,7 @@
 	dsp_on = fifo_on >> dsp_precision;
 	dsp_off = fifo_off >> dsp_precision;
 
-#ifdef DEBUG_MACHFB
+#ifdef MACHFB_DEBUG
 	printf("dsp_xclks_per_qw = %d, dsp_on = %d, dsp_off = %d,\n"
 	    "dsp_precision = %d, dsp_loop_latency = %d,\n"
 	    "mclk_fb_div = %d, vclk_fb_div = %d,\n"
@@ -1127,10 +1214,12 @@
 static void
 mach64_set_pll(struct mach64_softc *sc, int clock)
 {
-	int q;
+	uint32_t q, clockreg;
+	int clockshift = sc->sc_clock << 1;
+	uint8_t reg, vclk_ctl;
 
 	q = (clock * sc->ref_div * 100) / (2 * sc->ref_freq);
-#ifdef DEBUG_MACHFB
+#ifdef MACHFB_DEBUG
 	printf("q = %d\n", q);
 #endif
 	if (q > 25500) {
@@ -1156,10 +1245,27 @@
 		sc->log2_vclk_post_div = 3;
 	}
 	sc->vclk_fb_div = q * sc->vclk_post_div / 100;
+	printf("post_div: %d log2_post_div: %d mclk_div: %d\n", sc->vclk_post_div, sc->log2_vclk_post_div, sc->mclk_fb_div);
 
+	vclk_ctl = regrb_pll(sc, PLL_VCLK_CNTL);
+	printf("vclk_ctl: %02x\n", vclk_ctl);
+	vclk_ctl |= PLL_VCLK_RESET;
+	regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl);
+	
 	regwb_pll(sc, MCLK_FB_DIV, sc->mclk_fb_div);
-	regwb_pll(sc, VCLK_POST_DIV, sc->log2_vclk_post_div);
-	regwb_pll(sc, VCLK0_FB_DIV, sc->vclk_fb_div);
+	reg = regrb_pll(sc, VCLK_POST_DIV);
+	reg &= ~(3 << clockshift);
+	reg |= (sc->log2_vclk_post_div << clockshift);
+	regwb_pll(sc, VCLK_POST_DIV, reg);
+	regwb_pll(sc, VCLK0_FB_DIV + sc->sc_clock, sc->vclk_fb_div);
+
+	vclk_ctl &= ~PLL_VCLK_RESET;
+	regwb_pll(sc, PLL_VCLK_CNTL, vclk_ctl);
+
+	clockreg = regr(sc, CLOCK_CNTL);
+	clockreg &= ~CLOCK_SEL;
+	clockreg |= sc->sc_clock | CLOCK_STROBE;
+	regw(sc, CLOCK_CNTL, clockreg);
 }
 
 static void
@@ -1273,28 +1379,13 @@
 }
 
 static int
-mach64_is_console(struct pci_attach_args *pa)
+mach64_is_console(struct mach64_softc *sc)
 {
-#ifdef __sparc__
-	int node;
-
-	node = PCITAG_NODE(pa->pa_tag);
-	if (node == -1)
-		return 0;
+	bool console = 0;
 
-	return (node == prom_instance_to_package(prom_stdout()));
-#elif defined(__powerpc__)
-	/* check if we're the /chosen console device */
-	int chosen, stdout, node, us;
-
-	us = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag);
-	chosen = OF_finddevice("/chosen");
-	OF_getprop(chosen, "stdout", &stdout, 4);
-	node = OF_instance_to_package(stdout);
-	return (us == node);
-#else
-	return 1;
-#endif
+	prop_dictionary_get_bool(device_properties(sc->sc_dev),
+	    "is_console", &console);
+	return console;
 }
 
 /*
@@ -1348,6 +1439,7 @@
 mach64_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 mach64_softc *sc = scr->scr_cookie;
 	
@@ -1355,20 +1447,20 @@
 		int fg, bg, uc;
 		uint8_t *data;
 		int x, y, wi, he;
-		wi = ri->ri_font->fontwidth;
-		he = ri->ri_font->fontheight;
+		wi = font->fontwidth;
+		he = font->fontheight;
 
-		if (!CHAR_IN_FONT(c, ri->ri_font))
+		if (!CHAR_IN_FONT(c, font))
 			return;
-		bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf];
-		fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf];
+		bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0x0f];
+		fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0x0f];
 		x = ri->ri_xorigin + col * wi;
 		y = ri->ri_yorigin + row * he;
 		if (c == 0x20) {
 			mach64_rectfill(sc, x, y, wi, he, bg);
 		} else {
-			uc = c-ri->ri_font->firstchar;
-			data = (uint8_t *)ri->ri_font->data + uc * 
+			uc = c - font->firstchar;
+			data = (uint8_t *)font->data + uc * 
 			    ri->ri_fontscale;
 
 			mach64_setup_mono(sc, x, y, wi, he, fg, bg);
@@ -1573,18 +1665,6 @@
 }
 #endif
 
-static int
-mach64_allocattr(void *cookie, int fg, int bg, int flags, long *attrp)
-{
-	if ((fg == 0) && (bg == 0))
-	{
-		fg = WS_DEFAULT_FG;
-		bg = WS_DEFAULT_BG;
-	}
-	*attrp = (fg & 0xf) << 24 | (bg & 0xf) << 16 | (flags & 0xff) << 8;
-	return 0;
-}
-
 /*
  * wsdisplay_accessops
  */
@@ -1640,6 +1720,11 @@
 					if ((new_mode == WSDISPLAYIO_MODE_EMUL)
 					    && (ms != NULL))
 					{
+						/* restore initial video mode */
+						mach64_init(sc);
+						mach64_init_engine(sc);
+						mach64_init_lut(sc);
+						mach64_modeswitch(sc, sc->sc_my_mode);
 						vcons_redraw_screen(ms);
 					}
 				}
@@ -1679,9 +1764,6 @@
 	 */
 	if (kauth_authorize_generic(kauth_cred_get(), KAUTH_GENERIC_ISSUSER,
 	    NULL) != 0) {
-#if 0
-		printf("%s: mmap() rejected.\n", device_xname(&sc->sc_dev));
-#endif
 		return -1;
 	}
 
@@ -1689,7 +1771,7 @@
 	if (reg != sc->sc_regphys) {
 #ifdef DIAGNOSTIC
 		printf("%s: BAR 0x18 changed! (%x %x)\n", 
-		    device_xname(&sc->sc_dev), (uint32_t)sc->sc_regphys, 
+		    device_xname(sc->sc_dev), (uint32_t)sc->sc_regphys, 
 		    (uint32_t)reg);
 #endif
 		sc->sc_regphys = reg;
@@ -1699,35 +1781,41 @@
 	if (reg != sc->sc_aperphys) {
 #ifdef DIAGNOSTIC
 		printf("%s: BAR 0x10 changed! (%x %x)\n", 
-		    device_xname(&sc->sc_dev), (uint32_t)sc->sc_aperphys, 
+		    device_xname(sc->sc_dev), (uint32_t)sc->sc_aperphys, 
 		    (uint32_t)reg);
 #endif
 		sc->sc_aperphys = reg;
 	}
 
-#if 0
-	/* evil hack to allow mmap()ing other devices as well */
-	if ((offset > 0x80000000) && (offset <= 0xffffffff)) {
+	if ((offset >= sc->sc_aperphys) && 
+	    (offset < (sc->sc_aperphys + sc->sc_apersize))) {
 		pa = bus_space_mmap(sc->sc_memt, offset, 0, prot, 
 		    BUS_SPACE_MAP_LINEAR);
 		return pa;
 	}
-#endif
 
-	if ((offset >= sc->sc_aperphys) && 
-	    (offset < (sc->sc_aperphys + sc->sc_apersize))) {
+	if ((offset >= sc->sc_regphys) && 
+	    (offset < (sc->sc_regphys + sc->sc_regsize))) {
 		pa = bus_space_mmap(sc->sc_memt, offset, 0, prot, 
 		    BUS_SPACE_MAP_LINEAR);
 		return pa;
 	}
 
-	if ((offset >= sc->sc_regphys) && 
-	    (offset < (sc->sc_regphys + sc->sc_regsize))) {
+	if ((offset >= sc->sc_rom.vb_base) && 
+	    (offset < (sc->sc_rom.vb_base + sc->sc_rom.vb_size))) {
 		pa = bus_space_mmap(sc->sc_memt, offset, 0, prot, 
 		    BUS_SPACE_MAP_LINEAR);
 		return pa;
 	}
 
+#ifdef PCI_MAGIC_IO_RANGE
+	if ((offset >= PCI_MAGIC_IO_RANGE) &&
+	    (offset <= PCI_MAGIC_IO_RANGE + 0x10000)) {
+	    	return bus_space_mmap(sc->sc_iot, offset - PCI_MAGIC_IO_RANGE,
+	    	   0, prot, BUS_SPACE_MAP_LINEAR);
+	}
+#endif
+
 	return -1;
 }
 
@@ -1791,14 +1879,14 @@
 {
 	struct fbdevice *fb = &sc->sc_fb;
 	
-	fb->fb_device = &sc->sc_dev;
+	fb->fb_device = sc->sc_dev;
 	fb->fb_driver = &machfb_fbdriver;
 
 	fb->fb_type.fb_cmsize = 256;
 	fb->fb_type.fb_size = sc->memsize;
 	
 	fb->fb_type.fb_type = FBTYPE_GENERIC_PCI;
-	fb->fb_flags = sc->sc_dev.dv_cfdata->cf_flags & FB_USERMASK;
+	fb->fb_flags = sc->sc_dev->dv_cfdata->cf_flags & FB_USERMASK;
 	fb->fb_type.fb_depth = sc->bits_per_pixel;
 	fb->fb_type.fb_width = sc->virt_x;
 	fb->fb_type.fb_height = sc->virt_y;
@@ -1817,7 +1905,7 @@
 		return ENXIO;
 	sc->sc_locked = 1;
 	
-#ifdef DEBUG_MACHFB	
+#ifdef MACHFB_DEBUG
 	printf("machfb_fbopen(%d)\n", minor(dev));
 #endif
 	return 0;
@@ -1828,7 +1916,7 @@
 {
 	struct mach64_softc *sc = device_lookup_private(&machfb_cd, minor(dev));
 
-#ifdef DEBUG_MACHFB
+#ifdef MACHFB_DEBUG
 	printf("machfb_fbclose()\n");
 #endif
 	mach64_init_engine(sc);
@@ -1842,7 +1930,7 @@
 {
 	struct mach64_softc *sc = device_lookup_private(&machfb_cd, minor(dev));
 
-#ifdef DEBUG_MACHFB
+#ifdef MACHFB_DEBUG
 	printf("machfb_fbioctl(%d, %lx)\n", minor(dev), cmd);
 #endif
 	switch (cmd) {
@@ -1919,19 +2007,19 @@
 			ret = pci_devioctl(sc->sc_pc, sc->sc_pcitag,
 			    cmd, data, flags, l);
 			
-#ifdef DEBUG_MACHFB
+#ifdef MACHFB_DEBUG
 			printf("pci_devioctl: %d\n", ret);
 #endif
 			return ret;
 		}
 		default:
-#ifdef DEBUG_MACHFB
+#ifdef MACHFB_DEBUG
 			log(LOG_NOTICE, "machfb_fbioctl(0x%lx) (%s[%d])\n", cmd,
 			    p->p_comm, p->p_pid);
 #endif
 			return ENOTTY;
 	}
-#ifdef DEBUG_MACHFB
+#ifdef MACHFB_DEBUG
 	printf("machfb_fbioctl done\n");
 #endif
 	return 0;

Reply via email to