Home | History | Annotate | Line # | Download | only in pci
machfb.c revision 1.14.2.5
      1 /*	$NetBSD: machfb.c,v 1.14.2.5 2005/01/17 19:31:25 skrll Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2002 Bang Jun-Young
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. The name of the author may not be used to endorse or promote products
     16  *    derived from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 /*
     31  * Some code is derived from ATI Rage Pro and Derivatives Programmer's Guide.
     32  */
     33 
     34 #include <sys/cdefs.h>
     35 __KERNEL_RCSID(0, "$NetBSD: machfb.c,v 1.14.2.5 2005/01/17 19:31:25 skrll Exp $");
     36 
     37 #include <sys/param.h>
     38 #include <sys/systm.h>
     39 #include <sys/kernel.h>
     40 #include <sys/device.h>
     41 #include <sys/malloc.h>
     42 #include <sys/callout.h>
     43 
     44 #ifdef __sparc__
     45 #include <machine/promlib.h>
     46 #endif
     47 
     48 #include <dev/ic/videomode.h>
     49 
     50 #include <dev/pci/pcivar.h>
     51 #include <dev/pci/pcireg.h>
     52 #include <dev/pci/pcidevs.h>
     53 #include <dev/pci/pciio.h>
     54 #include <dev/pci/machfbreg.h>
     55 
     56 #include <dev/wscons/wsdisplayvar.h>
     57 #include <dev/wscons/wsconsio.h>
     58 #include <dev/wsfont/wsfont.h>
     59 #include <dev/rasops/rasops.h>
     60 
     61 #include "opt_wsemul.h"
     62 
     63 #define MACH64_REG_SIZE		1024
     64 #define MACH64_REG_OFF		0x7ffc00
     65 
     66 #define	NBARS		3	/* number of Mach64 PCI BARs */
     67 
     68 struct vga_bar {
     69 	bus_addr_t vb_base;
     70 	bus_size_t vb_size;
     71 	pcireg_t vb_type;
     72 	int vb_flags;
     73 };
     74 
     75 struct mach64_softc {
     76 	struct device sc_dev;
     77 	pci_chipset_tag_t sc_pc;
     78 	pcitag_t sc_pcitag;
     79 
     80 	struct vga_bar sc_bars[NBARS];
     81 	struct vga_bar sc_rom;
     82 
     83 #define sc_aperbase 	sc_bars[0].vb_base
     84 #define sc_apersize	sc_bars[0].vb_size
     85 
     86 #define sc_iobase	sc_bars[1].vb_base
     87 #define sc_iosize	sc_bars[1].vb_size
     88 
     89 #define sc_regbase	sc_bars[2].vb_base
     90 #define sc_regsize	sc_bars[2].vb_size
     91 
     92 	bus_space_tag_t sc_regt;
     93 	bus_space_tag_t sc_memt;
     94 	bus_space_handle_t sc_regh;
     95 	bus_space_handle_t sc_memh;
     96 
     97 	size_t memsize;
     98 	int memtype;
     99 
    100 	int has_dsp;
    101 	int bits_per_pixel;
    102 	int max_x, max_y;
    103 	int virt_x, virt_y;
    104 	int color_depth;
    105 
    106 	int mem_freq;
    107 	int ramdac_freq;
    108 	int ref_freq;
    109 
    110 	int ref_div;
    111 	int log2_vclk_post_div;
    112 	int vclk_post_div;
    113 	int vclk_fb_div;
    114 	int mclk_post_div;
    115 	int mclk_fb_div;
    116 
    117 	struct mach64screen *wanted;
    118 	struct mach64screen *active;
    119 	void (*switchcb)(void *, int, int);
    120 	void *switchcbarg;
    121 	struct callout switch_callout;
    122 	LIST_HEAD(, mach64screen) screens;
    123 	const struct wsscreen_descr *currenttype;
    124 	u_char sc_cmap_red[256];
    125 	u_char sc_cmap_green[256];
    126 	u_char sc_cmap_blue[256];
    127 	int sc_dacw;
    128 };
    129 
    130 struct mach64screen {
    131 	struct rasops_info ri;
    132 	LIST_ENTRY(mach64screen) next;
    133 	struct mach64_softc *sc;
    134 	const struct wsscreen_descr *type;
    135 	int active;
    136 	u_int16_t *mem;
    137 	int dispoffset;
    138 	int mindispoffset;
    139 	int maxdispoffset;
    140 
    141 	int cursoron;
    142 	int cursorcol;
    143 	int cursorrow;
    144 	u_int16_t cursortmp;
    145 };
    146 
    147 struct mach64_crtcregs {
    148 	u_int32_t h_total_disp;
    149 	u_int32_t h_sync_strt_wid;
    150 	u_int32_t v_total_disp;
    151 	u_int32_t v_sync_strt_wid;
    152 	u_int32_t gen_cntl;
    153 	u_int32_t clock_cntl;
    154 	u_int32_t color_depth;
    155 	u_int32_t dot_clock;
    156 };
    157 
    158 struct {
    159 	u_int16_t chip_id;
    160 	u_int32_t ramdac_freq;
    161 } mach64_info[] = {
    162 	{ PCI_PRODUCT_ATI_MACH64_CT, 135000 },
    163 	{ PCI_PRODUCT_ATI_RAGE_PRO_AGP, 230000 },
    164 	{ PCI_PRODUCT_ATI_RAGE_PRO_AGP1X, 230000 },
    165 	{ PCI_PRODUCT_ATI_RAGE_PRO_PCI_B, 230000 },
    166 	{ PCI_PRODUCT_ATI_RAGE_XL_AGP, 230000 },
    167 	{ PCI_PRODUCT_ATI_RAGE_PRO_PCI_P, 230000 },
    168 	{ PCI_PRODUCT_ATI_RAGE_PRO_PCI_L, 230000 },
    169 	{ PCI_PRODUCT_ATI_RAGE_XL_PCI, 230000 },
    170 	{ PCI_PRODUCT_ATI_RAGE_II, 135000 },
    171 	{ PCI_PRODUCT_ATI_RAGE_IIP, 200000 },
    172 	{ PCI_PRODUCT_ATI_RAGE_IIC_PCI, 230000 },
    173 	{ PCI_PRODUCT_ATI_RAGE_IIC_AGP_B, 230000 },
    174 	{ PCI_PRODUCT_ATI_RAGE_IIC_AGP_P, 230000 },
    175 	{ PCI_PRODUCT_ATI_RAGE_LT_PRO_AGP, 230000 },
    176 	{ PCI_PRODUCT_ATI_RAGE_MOB_M3_PCI, 230000 },
    177 	{ PCI_PRODUCT_ATI_RAGE_MOB_M3_AGP, 230000 },
    178 	{ PCI_PRODUCT_ATI_RAGE_LT, 230000 },
    179 	{ PCI_PRODUCT_ATI_RAGE_LT_PRO_PCI, 230000 },
    180 	{ PCI_PRODUCT_ATI_RAGE_MOBILITY, 230000 },
    181 	{ PCI_PRODUCT_ATI_RAGE_LT_PRO, 230000 },
    182 	{ PCI_PRODUCT_ATI_MACH64_VT, 170000 },
    183 	{ PCI_PRODUCT_ATI_MACH64_VTB, 200000 },
    184 	{ PCI_PRODUCT_ATI_MACH64_VT4, 230000 }
    185 };
    186 
    187 static int mach64_chip_id, mach64_chip_rev;
    188 static struct videomode default_mode;
    189 static struct mach64screen mach64_console_screen;
    190 
    191 static char *mach64_memtype_names[] = {
    192 	"(N/A)", "DRAM", "EDO DRAM", "EDO DRAM", "SDRAM", "SGRAM", "WRAM",
    193 	"(unknown type)"
    194 };
    195 
    196 struct videomode mach64_modes[] = {
    197 	/* 640x400 @ 70 Hz, 31.5 kHz */
    198 	{ 25175, 640, 664, 760, 800, 400, 409, 411, 450, 0 },
    199 	/* 640x480 @ 72 Hz, 36.5 kHz */
    200 	{ 25175, 640, 664, 760, 800, 480, 491, 493, 525, 0 },
    201 	/* 800x600 @ 72 Hz, 48.0 kHz */
    202 	{ 50000, 800, 856, 976, 1040, 600, 637, 643, 666,
    203 	  VID_PHSYNC | VID_PVSYNC },
    204 	/* 1024x768 @ 70 Hz, 56.5 kHz */
    205 	{ 75000, 1024, 1048, 1184, 1328, 768, 771, 777, 806,
    206 	  VID_NHSYNC | VID_NVSYNC },
    207 	/* 1152x864 @ 70 Hz, 62.4 kHz */
    208 	{ 92000, 1152, 1208, 1368, 1474, 864, 865, 875, 895, 0 },
    209 	/* 1280x1024 @ 70 Hz, 74.59 kHz */
    210 	{ 126500, 1280, 1312, 1472, 1696, 1024, 1032, 1040, 1068,
    211 	  VID_NHSYNC | VID_NVSYNC }
    212 };
    213 
    214 /* Macallan: let the terminal emulator program the palette, it should be in the softc anyway */
    215 #if 1
    216 /* FIXME values are wrong! */
    217 const u_char mach64_cmap[16 * 3] = {
    218 	0x00, 0x00, 0x00, /* black */
    219 	0x7f, 0x00, 0x00, /* red */
    220 	0x00, 0x7f, 0x00, /* green */
    221 	0x7f, 0x7f, 0x00, /* brown */
    222 	0x00, 0x00, 0x7f, /* blue */
    223 	0x7f, 0x00, 0x7f, /* magenta */
    224 	0x00, 0x7f, 0x7f, /* cyan */
    225 	0xc8, 0xc8, 0xc8, /* white */
    226 
    227 	0x7f, 0x7f, 0x7f, /* black */
    228 	0xff, 0x00, 0x00, /* red */
    229 	0x00, 0xff, 0x00, /* green */
    230 	0xff, 0xff, 0x00, /* brown */
    231 	0x00, 0x00, 0xff, /* blue */
    232 	0xff, 0x00, 0xff, /* magenta */
    233 	0x00, 0xff, 0xff, /* cyan */
    234 	0xff, 0xff, 0xff, /* white */
    235 };
    236 #endif
    237 
    238 #ifdef WSEMUL_VT100
    239 extern const u_char rasops_cmap[768];
    240 #endif
    241 
    242 int	mach64_match(struct device *, struct cfdata *, void *);
    243 void	mach64_attach(struct device *, struct device *, void *);
    244 
    245 CFATTACH_DECL(machfb, sizeof(struct mach64_softc), mach64_match, mach64_attach,
    246     NULL, NULL);
    247 
    248 void	mach64_init(struct mach64_softc *);
    249 int	mach64_get_memsize(struct mach64_softc *);
    250 int	mach64_get_max_ramdac(struct mach64_softc *);
    251 void	mach64_get_mode(struct mach64_softc *, struct videomode *);
    252 int	mach64_calc_crtcregs(struct mach64_softc *, struct mach64_crtcregs *,
    253 	    struct videomode *);
    254 void	mach64_set_crtcregs(struct mach64_softc *, struct mach64_crtcregs *);
    255 int	mach64_modeswitch(struct mach64_softc *, struct videomode *);
    256 void	mach64_set_dsp(struct mach64_softc *);
    257 void	mach64_set_pll(struct mach64_softc *, int);
    258 void	mach64_reset_engine(struct mach64_softc *);
    259 void	mach64_init_engine(struct mach64_softc *);
    260 void	mach64_adjust_frame(struct mach64_softc *, int, int);
    261 void	mach64_init_lut(struct mach64_softc *);
    262 void	mach64_switch_screen(struct mach64_softc *);
    263 void	mach64_init_screen(struct mach64_softc *, struct mach64screen *,
    264 	    const struct wsscreen_descr *, int, long *, int);
    265 void	mach64_restore_screen(struct mach64screen *,
    266 	    const struct wsscreen_descr *, u_int16_t *);
    267 int 	mach64_set_screentype(struct mach64_softc *,
    268 	    const struct wsscreen_descr *);
    269 int	mach64_is_console(struct pci_attach_args *);
    270 
    271 void	mach64_cursor(void *, int, int, int);
    272 int	mach64_mapchar(void *, int, u_int *);
    273 void	mach64_putchar(void *, int, int, u_int, long);
    274 void	mach64_copycols(void *, int, int, int, int);
    275 void	mach64_erasecols(void *, int, int, int, long);
    276 void	mach64_copyrows(void *, int, int, int);
    277 void	mach64_eraserows(void *, int, int, long);
    278 int	mach64_allocattr(void *, int, int, int, long *);
    279 
    280 void	mach64_scroll(void *, void *, int);
    281 
    282 int mach64_putcmap(struct mach64_softc *, struct wsdisplay_cmap *);
    283 int mach64_getcmap(struct mach64_softc *, struct wsdisplay_cmap *);
    284 int mach64_putpalreg(struct mach64_softc *, uint8_t, uint8_t, uint8_t, uint8_t);
    285 void mach64_bitblt(struct mach64_softc *, int, int, int, int, int, int, int, int) ;
    286 void mach64_rectfill(struct mach64_softc *, int, int, int, int, int);
    287 void mach64_showpal(struct mach64_softc *);
    288 
    289 #if 0
    290 const struct wsdisplay_emulops mach64_emulops = {
    291 	mach64_cursor,
    292 	mach64_mapchar,
    293 	mach64_putchar,
    294 	mach64_copycols,
    295 	mach64_erasecols,
    296 	mach64_copyrows,
    297 	mach64_eraserows,
    298 	mach64_allocattr,
    299 };
    300 #endif
    301 
    302 struct wsscreen_descr mach64_defaultscreen = {
    303 	"default",
    304 	0, 0,
    305 	&mach64_console_screen.ri.ri_ops,
    306 	8, 16,
    307 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    308 	&default_mode
    309 }, mach64_80x25_screen = {
    310 	"80x25", 80, 25,
    311 	&mach64_console_screen.ri.ri_ops,
    312 	8, 16,
    313 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    314 	&mach64_modes[0]
    315 }, mach64_80x30_screen = {
    316 	"80x30", 80, 30,
    317 	&mach64_console_screen.ri.ri_ops,
    318 	8, 16,
    319 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    320 	&mach64_modes[1]
    321 }, mach64_80x40_screen = {
    322 	"80x40", 80, 40,
    323 	&mach64_console_screen.ri.ri_ops,
    324 	8, 10,
    325 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    326 	&mach64_modes[0]
    327 }, mach64_80x50_screen = {
    328 	"80x50", 80, 50,
    329 	&mach64_console_screen.ri.ri_ops,
    330 	8, 8,
    331 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    332 	&mach64_modes[0]
    333 }, mach64_100x37_screen = {
    334 	"100x37", 100, 37,
    335 	&mach64_console_screen.ri.ri_ops,
    336 	8, 16,
    337 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    338 	&mach64_modes[2]
    339 }, mach64_128x48_screen = {
    340 	"128x48", 128, 48,
    341 	&mach64_console_screen.ri.ri_ops,
    342 	8, 16,
    343 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    344 	&mach64_modes[3]
    345 }, mach64_144x54_screen = {
    346 	"144x54", 144, 54,
    347 	&mach64_console_screen.ri.ri_ops,
    348 	8, 16,
    349 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    350 	&mach64_modes[4]
    351 }, mach64_160x64_screen = {
    352 	"160x54", 160, 64,
    353 	&mach64_console_screen.ri.ri_ops,
    354 	8, 16,
    355 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
    356 	&mach64_modes[5]
    357 };
    358 
    359 const struct wsscreen_descr *_mach64_scrlist[] = {
    360 	&mach64_defaultscreen,
    361 	&mach64_80x25_screen,
    362 	&mach64_80x30_screen,
    363 	&mach64_80x40_screen,
    364 	&mach64_80x50_screen,
    365 	&mach64_100x37_screen,
    366 	&mach64_128x48_screen,
    367 	&mach64_144x54_screen,
    368 	&mach64_160x64_screen
    369 };
    370 
    371 struct wsscreen_list mach64_screenlist = {
    372 	sizeof(_mach64_scrlist) / sizeof(struct wsscreen_descr *),
    373 	_mach64_scrlist
    374 };
    375 
    376 int	mach64_ioctl(void *, u_long, caddr_t, int, struct lwp *);
    377 paddr_t	mach64_mmap(void *, off_t, int);
    378 int	mach64_alloc_screen(void *, const struct wsscreen_descr *, void **,
    379 	    int *, int *, long *);
    380 void	mach64_free_screen(void *, void *);
    381 int	mach64_show_screen(void *, void *, int, void (*)(void *, int, int),
    382 	    void *);
    383 int	mach64_load_font(void *, void *, struct wsdisplay_font *);
    384 
    385 struct wsdisplay_accessops mach64_accessops = {
    386 	mach64_ioctl,
    387 	mach64_mmap,
    388 	mach64_alloc_screen,
    389 	mach64_free_screen,
    390 	mach64_show_screen,
    391 	NULL,	/* load_font */
    392 	NULL,	/* polls */
    393 	NULL,	/* getwschar */
    394 	NULL,	/* putwschar */
    395 	NULL,	/* scroll */
    396 	NULL,	/* getborder */
    397 	NULL	/* setborder */
    398 };
    399 
    400 /*
    401  * Inline functions for getting access to register aperture.
    402  */
    403 static inline u_int32_t regr(struct mach64_softc *, u_int32_t);
    404 static inline u_int8_t regrb(struct mach64_softc *, u_int32_t);
    405 static inline void regw(struct mach64_softc *, u_int32_t, u_int32_t);
    406 static inline void regwb(struct mach64_softc *, u_int32_t, u_int8_t);
    407 static inline void regwb_pll(struct mach64_softc *, u_int32_t, u_int8_t);
    408 
    409 static inline u_int32_t
    410 regr(struct mach64_softc *sc, u_int32_t index)
    411 {
    412 
    413 	return bus_space_read_4(sc->sc_regt, sc->sc_regh, index);
    414 }
    415 
    416 static inline u_int8_t
    417 regrb(struct mach64_softc *sc, u_int32_t index)
    418 {
    419 
    420 	return bus_space_read_1(sc->sc_regt, sc->sc_regh, index);
    421 }
    422 
    423 static inline void
    424 regw(struct mach64_softc *sc, u_int32_t index, u_int32_t data)
    425 {
    426 
    427 	bus_space_write_4(sc->sc_regt, sc->sc_regh, index, data);
    428 	bus_space_barrier(sc->sc_regt, sc->sc_regh, index, 4, BUS_SPACE_BARRIER_WRITE);
    429 }
    430 
    431 static inline void
    432 regwb(struct mach64_softc *sc, u_int32_t index, u_int8_t data)
    433 {
    434 
    435 	bus_space_write_1(sc->sc_regt, sc->sc_regh, index, data);
    436 	bus_space_barrier(sc->sc_regt, sc->sc_regh, index, 1, BUS_SPACE_BARRIER_WRITE);
    437 }
    438 
    439 static inline void
    440 regwb_pll(struct mach64_softc *sc, u_int32_t index, u_int8_t data)
    441 {
    442 
    443 	regwb(sc, CLOCK_CNTL + 1, (index << 2) | PLL_WR_EN);
    444 	regwb(sc, CLOCK_CNTL + 2, data);
    445 	regwb(sc, CLOCK_CNTL + 1, (index << 2) & ~PLL_WR_EN);
    446 }
    447 
    448 static inline void
    449 wait_for_fifo(struct mach64_softc *sc, u_int8_t v)
    450 {
    451 
    452 	while ((regr(sc, FIFO_STAT) & 0xffff) > (0x8000 >> v))
    453 		;
    454 }
    455 
    456 static inline void
    457 wait_for_idle(struct mach64_softc *sc)
    458 {
    459 
    460 	wait_for_fifo(sc, 16);
    461 	while ((regr(sc, GUI_STAT) & 1) != 0)
    462 		;
    463 }
    464 
    465 int
    466 mach64_match(struct device *parent, struct cfdata *match, void *aux)
    467 {
    468 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
    469 	int i;
    470 
    471 	if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY ||
    472 	    PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
    473 		return 0;
    474 
    475 	for (i = 0; i < sizeof(mach64_info) / sizeof(mach64_info[0]); i++)
    476 		if (PCI_PRODUCT(pa->pa_id) == mach64_info[i].chip_id) {
    477 			mach64_chip_id = PCI_PRODUCT(pa->pa_id);
    478 			mach64_chip_rev = PCI_REVISION(pa->pa_class);
    479 			return 1;
    480 		}
    481 
    482 	return 0;
    483 }
    484 
    485 void
    486 mach64_attach(struct device *parent, struct device *self, void *aux)
    487 {
    488 	struct mach64_softc *sc = (void *)self;
    489 	struct pci_attach_args *pa = aux;
    490 	char devinfo[256];
    491 	int bar, reg, id;
    492 	struct wsemuldisplaydev_attach_args aa;
    493 	long defattr;
    494 	int setmode, console;
    495 
    496 	sc->sc_pc = pa->pa_pc;
    497 	sc->sc_pcitag = pa->pa_tag;
    498 	sc->sc_dacw=-1;
    499 	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
    500 	printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class));
    501 
    502 	for (bar = 0; bar < NBARS; bar++) {
    503 		reg = PCI_MAPREG_START + (bar * 4);
    504 		sc->sc_bars[bar].vb_type = pci_mapreg_type(sc->sc_pc,
    505 		    sc->sc_pcitag, reg);
    506 		(void)pci_mapreg_info(sc->sc_pc, sc->sc_pcitag, reg,
    507 		    sc->sc_bars[bar].vb_type, &sc->sc_bars[bar].vb_base,
    508 		    &sc->sc_bars[bar].vb_size, &sc->sc_bars[bar].vb_flags);
    509 	}
    510 	sc->sc_memt = pa->pa_memt;
    511 
    512 	mach64_init(sc);
    513 
    514 	printf("%s: %d MB aperture at 0x%08x, %d KB registers at 0x%08x\n",
    515 	    sc->sc_dev.dv_xname, (u_int)(sc->sc_apersize / (1024 * 1024)),
    516 	    (u_int)sc->sc_aperbase, (u_int)(sc->sc_regsize / 1024),
    517 	    (u_int)sc->sc_regbase);
    518 
    519 	if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_CT ||
    520 	    ((mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
    521 	      mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II) &&
    522 	      (mach64_chip_rev & 0x07) == 0))
    523 		sc->has_dsp = 0;
    524 	else
    525 		sc->has_dsp = 1;
    526 
    527 	sc->memsize = mach64_get_memsize(sc);
    528 	if (sc->memsize == 8192)
    529 		/* The last page is used as register aperture. */
    530 		sc->memsize -= 4;
    531 	sc->memtype = regr(sc, CONFIG_STAT0) & 0x07;
    532 
    533 	/* XXX is there any way to calculate reference frequency from
    534 	   known values? */
    535 	if (mach64_chip_id == PCI_PRODUCT_ATI_RAGE_XL_PCI)
    536 		sc->ref_freq = 29498;
    537 	else
    538 		sc->ref_freq = 14318;
    539 
    540 	regwb(sc, CLOCK_CNTL + 1, PLL_REF_DIV << 2);
    541 	sc->ref_div = regrb(sc, CLOCK_CNTL + 2);
    542 	regwb(sc, CLOCK_CNTL + 1, MCLK_FB_DIV << 2);
    543 	sc->mclk_fb_div = regrb(sc, CLOCK_CNTL + 2);
    544 	sc->mem_freq = (2 * sc->ref_freq * sc->mclk_fb_div) /
    545 	    (sc->ref_div * 2);
    546 	sc->mclk_post_div = (sc->mclk_fb_div * 2 * sc->ref_freq) /
    547 	    (sc->mem_freq * sc->ref_div);
    548 	sc->ramdac_freq = mach64_get_max_ramdac(sc);
    549 	printf("%s: %ld KB %s %d.%d MHz, maximum RAMDAC clock %d MHz\n",
    550 	    sc->sc_dev.dv_xname, (u_long)sc->memsize,
    551 	    mach64_memtype_names[sc->memtype],
    552 	    sc->mem_freq / 1000, sc->mem_freq % 1000,
    553 	    sc->ramdac_freq / 1000);
    554 
    555 	id = regr(sc, CONFIG_CHIP_ID) & 0xffff;
    556 	if (id != mach64_chip_id) {
    557 		printf("%s: chip ID mismatch, 0x%x != 0x%x\n",
    558 		    sc->sc_dev.dv_xname, id, mach64_chip_id);
    559 		return;
    560 	}
    561 
    562 	console = mach64_is_console(pa);
    563 
    564 #ifdef __sparc__
    565 	if (console) {
    566 		mach64_get_mode(sc, &default_mode);
    567 		setmode = 0;
    568 	} else {
    569 		memcpy(&default_mode, &mach64_modes[4], sizeof(struct videomode));
    570 		setmode = 1;
    571 	}
    572 #else
    573 	memcpy(&default_mode, &mach64_modes[0], sizeof(struct videomode));
    574 	setmode = 1;
    575 #endif
    576 
    577 	sc->bits_per_pixel = 8;
    578 	sc->virt_x = default_mode.hdisplay;
    579 	sc->virt_y = default_mode.vdisplay;
    580 	sc->max_x = sc->virt_x - 1;
    581 	sc->max_y = (sc->memsize * 1024) /
    582 	    (sc->virt_x * (sc->bits_per_pixel / 8)) - 1;
    583 
    584 	sc->color_depth = CRTC_PIX_WIDTH_8BPP;
    585 
    586 	mach64_init_engine(sc);
    587 #if 0
    588 	mach64_adjust_frame(0, 0);
    589 	if (sc->bits_per_pixel == 8)
    590 		mach64_init_lut(sc);
    591 #endif
    592 
    593 	printf("%s: initial resolution %dx%d at %d bpp\n", sc->sc_dev.dv_xname,
    594 	    default_mode.hdisplay, default_mode.vdisplay,
    595 	    sc->bits_per_pixel);
    596 
    597 	mach64_console_screen.ri.ri_hw = sc;
    598 	mach64_console_screen.ri.ri_depth = sc->bits_per_pixel;
    599 	mach64_console_screen.ri.ri_bits = (void*)(u_long)sc->sc_aperbase;
    600 	mach64_console_screen.ri.ri_width = default_mode.hdisplay;
    601 	mach64_console_screen.ri.ri_height = default_mode.vdisplay;
    602 	mach64_console_screen.ri.ri_stride = mach64_console_screen.ri.ri_width;
    603 
    604 	mach64_console_screen.ri.ri_flg = RI_CLEAR|RI_CENTER;
    605 
    606 #ifdef WSEMUL_SUN
    607 	mach64_console_screen.ri.ri_flg = RI_CLEAR|RI_CENTER|RI_FORCEMONO;
    608 #endif
    609 
    610 	rasops_init(&mach64_console_screen.ri, mach64_console_screen.ri.ri_height / 16,
    611 	    mach64_console_screen.ri.ri_width / 8);	/* XXX width/height are nonsense */
    612 
    613 	/* enable acceleration */
    614 	mach64_console_screen.ri.ri_ops.copyrows=mach64_copyrows;
    615 	mach64_console_screen.ri.ri_ops.eraserows=mach64_eraserows;
    616 	mach64_console_screen.ri.ri_ops.copycols=mach64_copycols;
    617 	mach64_console_screen.ri.ri_ops.erasecols=mach64_erasecols;
    618 
    619 	mach64_defaultscreen.nrows = mach64_console_screen.ri.ri_rows;
    620 	mach64_defaultscreen.ncols = mach64_console_screen.ri.ri_cols;
    621 
    622 	mach64_console_screen.ri.ri_ops.allocattr(&mach64_console_screen.ri, 0, 0, 0,
    623 	    &defattr);
    624 
    625 	/* really necessary? */
    626 	mach64_defaultscreen.capabilities=mach64_console_screen.ri.ri_caps;
    627 	mach64_defaultscreen.textops=&mach64_console_screen.ri.ri_ops;
    628 
    629 	/* Initialize fonts */
    630 	/* XXX Macallan: shouldn't that happen /before/ we call rasops_init()? */
    631 	wsfont_init();
    632 
    633 	if (console) {
    634 		mach64_init_screen(sc, &mach64_console_screen,
    635 		    &mach64_defaultscreen, 1, &defattr, setmode);
    636 		wsdisplay_cnattach(&mach64_defaultscreen, &mach64_console_screen.ri,
    637 		    0, 0, defattr);
    638 	}
    639 
    640 	mach64_init_lut(sc);
    641 
    642 #ifdef DEBUG
    643 	mach64_showpal(sc);
    644 	delay(4000000);
    645 #endif
    646 	aa.console = console;
    647 	aa.scrdata = &mach64_screenlist;
    648 	aa.accessops = &mach64_accessops;
    649 	aa.accesscookie = sc;
    650 
    651 	config_found(self, &aa, wsemuldisplaydevprint);
    652 }
    653 
    654 void
    655 mach64_init_screen(struct mach64_softc *sc, struct mach64screen *scr,
    656     const struct wsscreen_descr *type, int existing, long *attrp, int setmode)
    657 {
    658 
    659 	scr->sc = sc;
    660 	scr->type = type;
    661 	scr->mindispoffset = 0;
    662 	scr->maxdispoffset = sc->memsize * 1024;
    663 	scr->dispoffset = 0;
    664 	scr->cursorcol = 0;
    665 	scr->cursorrow = 0;
    666 
    667 	scr->mem = (u_int16_t *)malloc(type->nrows * type->ncols * 2,
    668 	    M_DEVBUF, M_WAITOK);
    669 	if (existing) {
    670 		scr->active = 1;
    671 
    672 		if (setmode && mach64_set_screentype(sc, type)) {
    673 			panic("%s: failed to switch video mode",
    674 			    sc->sc_dev.dv_xname);
    675 		}
    676 	} else {
    677 		scr->active = 0;
    678 	}
    679 
    680 	LIST_INSERT_HEAD(&sc->screens, scr, next);
    681 }
    682 
    683 void
    684 mach64_init(struct mach64_softc *sc)
    685 {
    686 	u_int32_t *p32, saved_value;
    687 	u_int8_t *p;
    688 	int need_swap;
    689 
    690 	if (bus_space_map(sc->sc_memt, sc->sc_aperbase, sc->sc_apersize,
    691 		BUS_SPACE_MAP_LINEAR, &sc->sc_memh)) {
    692 		panic("%s: failed to map aperture", sc->sc_dev.dv_xname);
    693 	}
    694 	sc->sc_aperbase = (vaddr_t)bus_space_vaddr(sc->sc_memt, sc->sc_memh);
    695 
    696 	sc->sc_regt = sc->sc_memt;
    697 	bus_space_subregion(sc->sc_regt, sc->sc_memh, MACH64_REG_OFF,
    698 	    sc->sc_regsize, &sc->sc_regh);
    699 	sc->sc_regbase = sc->sc_aperbase + 0x7ffc00;
    700 
    701 	/*
    702 	 * Test wether the aperture is byte swapped or not
    703 	 */
    704 	p32 = (u_int32_t*)(u_long)sc->sc_aperbase;
    705 	saved_value = *p32;
    706 	p = (u_int8_t*)(u_long)sc->sc_aperbase;
    707 	*p32 = 0x12345678;
    708 	if (p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78)
    709 		need_swap = 0;
    710 	else
    711 		need_swap = 1;
    712 	if (need_swap) {
    713 		sc->sc_aperbase += 0x800000;
    714 		sc->sc_apersize -= 0x800000;
    715 	}
    716 	*p32 = saved_value;
    717 
    718 	LIST_INIT(&sc->screens);
    719 	sc->active = NULL;
    720 	sc->currenttype = &mach64_defaultscreen;
    721 	callout_init(&sc->switch_callout);
    722 }
    723 
    724 int
    725 mach64_get_memsize(struct mach64_softc *sc)
    726 {
    727 	int tmp, memsize;
    728 	int mem_tab[] = {
    729 		512, 1024, 2048, 4096, 6144, 8192, 12288, 16384
    730 	};
    731 
    732 	tmp = regr(sc, MEM_CNTL);
    733 	if (sc->has_dsp) {
    734 		tmp &= 0x0000000f;
    735 		if (tmp < 8)
    736 			memsize = (tmp + 1) * 512;
    737 		else if (tmp < 12)
    738 			memsize = (tmp - 3) * 1024;
    739 		else
    740 			memsize = (tmp - 7) * 2048;
    741 	} else {
    742 		memsize = mem_tab[tmp & 0x07];
    743 	}
    744 
    745 	return memsize;
    746 }
    747 
    748 int
    749 mach64_get_max_ramdac(struct mach64_softc *sc)
    750 {
    751 	int i;
    752 
    753 	if ((mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
    754 	     mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II) &&
    755 	     (mach64_chip_rev & 0x07))
    756 		return 170000;
    757 
    758 	for (i = 0; i < sizeof(mach64_info) / sizeof(mach64_info[0]); i++)
    759 		if (mach64_chip_id == mach64_info[i].chip_id)
    760 			return mach64_info[i].ramdac_freq;
    761 
    762 	if (sc->bits_per_pixel == 8)
    763 		return 135000;
    764 	else
    765 		return 80000;
    766 }
    767 
    768 void
    769 mach64_get_mode(struct mach64_softc *sc, struct videomode *mode)
    770 {
    771 	struct mach64_crtcregs crtc;
    772 
    773 	crtc.h_total_disp = regr(sc, CRTC_H_TOTAL_DISP);
    774 	crtc.h_sync_strt_wid = regr(sc, CRTC_H_SYNC_STRT_WID);
    775 	crtc.v_total_disp = regr(sc, CRTC_V_TOTAL_DISP);
    776 	crtc.v_sync_strt_wid = regr(sc, CRTC_V_SYNC_STRT_WID);
    777 
    778 	mode->htotal = ((crtc.h_total_disp & 0xffff) + 1) << 3;
    779 	mode->hdisplay = ((crtc.h_total_disp >> 16) + 1) << 3;
    780 	mode->hsync_start = ((crtc.h_sync_strt_wid & 0xffff) + 1) << 3;
    781 	mode->hsync_end = ((crtc.h_sync_strt_wid >> 16) << 3) +
    782 	    mode->hsync_start;
    783 	mode->vtotal = (crtc.v_total_disp & 0xffff) + 1;
    784 	mode->vdisplay = (crtc.v_total_disp >> 16) + 1;
    785 	mode->vsync_start = (crtc.v_sync_strt_wid & 0xffff) + 1;
    786 	mode->vsync_end = (crtc.v_sync_strt_wid >> 16) + mode->vsync_start;
    787 
    788 #ifdef MACH64_DEBUG
    789 	printf("mach64_get_mode: %d %d %d %d %d %d %d %d\n",
    790 	    mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
    791 	    mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal);
    792 #endif
    793 }
    794 
    795 int
    796 mach64_calc_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc,
    797     struct videomode *mode)
    798 {
    799 
    800 	if (mode->dot_clock > sc->ramdac_freq)
    801 		/* Clock too high. */
    802 		return 1;
    803 
    804 	crtc->h_total_disp = (((mode->hdisplay >> 3) - 1) << 16) |
    805 	    ((mode->htotal >> 3) - 1);
    806 	crtc->h_sync_strt_wid =
    807 	    (((mode->hsync_end - mode->hsync_start) >> 3) << 16) |
    808 	    ((mode->hsync_start >> 3) - 1);
    809 
    810 	crtc->v_total_disp = ((mode->vdisplay - 1) << 16) |
    811 	    (mode->vtotal - 1);
    812 	crtc->v_sync_strt_wid =
    813 	    ((mode->vsync_end - mode->vsync_start) << 16) |
    814 	    (mode->vsync_start - 1);
    815 
    816 	if (mode->flags & VID_NVSYNC)
    817 		crtc->v_sync_strt_wid |= CRTC_VSYNC_NEG;
    818 
    819 	switch (sc->bits_per_pixel) {
    820 	case 8:
    821 		crtc->color_depth = CRTC_PIX_WIDTH_8BPP;
    822 		break;
    823 	case 16:
    824 		crtc->color_depth = CRTC_PIX_WIDTH_16BPP;
    825 		break;
    826 	case 32:
    827 		crtc->color_depth = CRTC_PIX_WIDTH_32BPP;
    828 		break;
    829 	}
    830 
    831 	crtc->gen_cntl = 0;
    832 	if (mode->flags & VID_INTERLACE)
    833 		crtc->gen_cntl |= CRTC_INTERLACE_EN;
    834 	if (mode->flags & VID_CSYNC)
    835 		crtc->gen_cntl |= CRTC_CSYNC_EN;
    836 
    837 	crtc->dot_clock = mode->dot_clock;
    838 
    839 	return 0;
    840 }
    841 
    842 void
    843 mach64_set_crtcregs(struct mach64_softc *sc, struct mach64_crtcregs *crtc)
    844 {
    845 
    846 	mach64_set_pll(sc, crtc->dot_clock);
    847 
    848 	if (sc->has_dsp)
    849 		mach64_set_dsp(sc);
    850 
    851 	regw(sc, CRTC_H_TOTAL_DISP, crtc->h_total_disp);
    852 	regw(sc, CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
    853 	regw(sc, CRTC_V_TOTAL_DISP, crtc->v_total_disp);
    854 	regw(sc, CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid);
    855 
    856 	regw(sc, CRTC_VLINE_CRNT_VLINE, 0);
    857 
    858 	regw(sc, CRTC_OFF_PITCH, (sc->virt_x >> 3) << 22);
    859 
    860 	regw(sc, CRTC_GEN_CNTL, crtc->gen_cntl | crtc->color_depth |
    861 	    CRTC_EXT_DISP_EN | CRTC_EXT_EN);
    862 }
    863 
    864 int
    865 mach64_modeswitch(struct mach64_softc *sc, struct videomode *mode)
    866 {
    867 	struct mach64_crtcregs crtc;
    868 
    869 	if (mach64_calc_crtcregs(sc, &crtc, mode))
    870 		return 1;
    871 
    872 	mach64_set_crtcregs(sc, &crtc);
    873 	return 0;
    874 }
    875 
    876 void
    877 mach64_reset_engine(struct mach64_softc *sc)
    878 {
    879 
    880 	/* Reset engine.*/
    881 	regw(sc, GEN_TEST_CNTL, regr(sc, GEN_TEST_CNTL) & ~GUI_ENGINE_ENABLE);
    882 
    883 	/* Enable engine. */
    884 	regw(sc, GEN_TEST_CNTL, regr(sc, GEN_TEST_CNTL) | GUI_ENGINE_ENABLE);
    885 
    886 	/* Ensure engine is not locked up by clearing any FIFO or
    887 	   host errors. */
    888 	regw(sc, BUS_CNTL, regr(sc, BUS_CNTL) | BUS_HOST_ERR_ACK |
    889 	    BUS_FIFO_ERR_ACK);
    890 }
    891 
    892 void
    893 mach64_init_engine(struct mach64_softc *sc)
    894 {
    895 	u_int32_t pitch_value;
    896 
    897 	pitch_value = sc->virt_x;
    898 
    899 	if (sc->bits_per_pixel == 24)
    900 		pitch_value *= 3;
    901 
    902 	mach64_reset_engine(sc);
    903 
    904 	wait_for_fifo(sc, 14);
    905 
    906 	regw(sc, CONTEXT_MASK, 0xffffffff);
    907 
    908 	regw(sc, DST_OFF_PITCH, (pitch_value / 8) << 22);
    909 
    910 	regw(sc, DST_Y_X, 0);
    911 	regw(sc, DST_HEIGHT, 0);
    912 	regw(sc, DST_BRES_ERR, 0);
    913 	regw(sc, DST_BRES_INC, 0);
    914 	regw(sc, DST_BRES_DEC, 0);
    915 
    916 	regw(sc, DST_CNTL, DST_LAST_PEL | DST_X_LEFT_TO_RIGHT |
    917 	    DST_Y_TOP_TO_BOTTOM);
    918 
    919 	regw(sc, SRC_OFF_PITCH, (pitch_value / 8) << 22);
    920 
    921 	regw(sc, SRC_Y_X, 0);
    922 	regw(sc, SRC_HEIGHT1_WIDTH1, 1);
    923 	regw(sc, SRC_Y_X_START, 0);
    924 	regw(sc, SRC_HEIGHT2_WIDTH2, 1);
    925 
    926 	regw(sc, SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT);
    927 
    928 	wait_for_fifo(sc, 13);
    929 	regw(sc, HOST_CNTL, 0);
    930 
    931 	regw(sc, PAT_REG0, 0);
    932 	regw(sc, PAT_REG1, 0);
    933 	regw(sc, PAT_CNTL, 0);
    934 
    935 	regw(sc, SC_LEFT, 0);
    936 	regw(sc, SC_TOP, 0);
    937 	regw(sc, SC_BOTTOM, default_mode.vdisplay - 1);
    938 	regw(sc, SC_RIGHT, pitch_value - 1);
    939 
    940 	regw(sc, DP_BKGD_CLR, 0);
    941 	regw(sc, DP_FRGD_CLR, 0xffffffff);
    942 	regw(sc, DP_WRITE_MASK, 0xffffffff);
    943 	regw(sc, DP_MIX, (MIX_SRC << 16) | MIX_DST);
    944 
    945 	regw(sc, DP_SRC, FRGD_SRC_FRGD_CLR);
    946 
    947 	wait_for_fifo(sc, 3);
    948 	regw(sc, CLR_CMP_CLR, 0);
    949 	regw(sc, CLR_CMP_MASK, 0xffffffff);
    950 	regw(sc, CLR_CMP_CNTL, 0);
    951 
    952 	wait_for_fifo(sc, 2);
    953 	switch (sc->bits_per_pixel) {
    954 	case 8:
    955 		regw(sc, DP_PIX_WIDTH, HOST_8BPP | SRC_8BPP | DST_8BPP);
    956 		regw(sc, DP_CHAIN_MASK, DP_CHAIN_8BPP);
    957 		/* XXX Macallan: huh? We /want/ an 8 bit per channel palette! */
    958 		/*regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) & ~DAC_8BIT_EN);*/
    959 		regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
    960 		break;
    961 #if 0
    962 	case 32:
    963 		regw(sc, DP_PIX_WIDTH, HOST_32BPP | SRC_32BPP | DST_32BPP);
    964 		regw(sc, DP_CHAIN_MASK, DP_CHAIN_32BPP);
    965 		regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN);
    966 		break;
    967 #endif
    968 	}
    969 
    970 	wait_for_fifo(sc, 5);
    971 	regw(sc, CRTC_INT_CNTL, regr(sc, CRTC_INT_CNTL) & ~0x20);
    972 	regw(sc, GUI_TRAJ_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
    973 
    974 	wait_for_idle(sc);
    975 }
    976 
    977 void
    978 mach64_adjust_frame(struct mach64_softc *sc, int x, int y)
    979 {
    980 	int offset;
    981 
    982 	offset = ((x + y * sc->virt_x) * (sc->bits_per_pixel >> 3)) >> 3;
    983 
    984 	regw(sc, CRTC_OFF_PITCH, (regr(sc, CRTC_OFF_PITCH) & 0xfff00000) |
    985 	     offset);
    986 }
    987 
    988 void
    989 mach64_set_dsp(struct mach64_softc *sc)
    990 {
    991 	u_int32_t fifo_depth, page_size, dsp_precision, dsp_loop_latency;
    992 	u_int32_t dsp_off, dsp_on, dsp_xclks_per_qw;
    993 	u_int32_t xclks_per_qw, y;
    994 	u_int32_t fifo_off, fifo_on;
    995 
    996 	if (mach64_chip_id == PCI_PRODUCT_ATI_MACH64_VT ||
    997 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_II ||
    998 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIP ||
    999 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIC_PCI ||
   1000 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIC_AGP_B ||
   1001 	    mach64_chip_id == PCI_PRODUCT_ATI_RAGE_IIC_AGP_P) {
   1002 		dsp_loop_latency = 0;
   1003 		fifo_depth = 24;
   1004 	} else {
   1005 		dsp_loop_latency = 2;
   1006 		fifo_depth = 32;
   1007 	}
   1008 
   1009 	dsp_precision = 0;
   1010 	xclks_per_qw = (sc->mclk_fb_div * sc->vclk_post_div * 64 << 11) /
   1011 	    (sc->vclk_fb_div * sc->mclk_post_div * sc->bits_per_pixel);
   1012 	y = (xclks_per_qw * fifo_depth) >> 11;
   1013 	while (y) {
   1014 		y >>= 1;
   1015 		dsp_precision++;
   1016 	}
   1017 	dsp_precision -= 5;
   1018 	fifo_off = ((xclks_per_qw * (fifo_depth - 1)) >> 5) + (3 << 6);
   1019 
   1020 	switch (sc->memtype) {
   1021 	case DRAM:
   1022 	case EDO_DRAM:
   1023 	case PSEUDO_EDO:
   1024 		if (sc->memsize > 1024) {
   1025 			page_size = 9;
   1026 			dsp_loop_latency += 6;
   1027 		} else {
   1028 			page_size = 10;
   1029 			if (sc->memtype == DRAM)
   1030 				dsp_loop_latency += 8;
   1031 			else
   1032 				dsp_loop_latency += 7;
   1033 		}
   1034 		break;
   1035 	case SDRAM:
   1036 	case SGRAM:
   1037 		if (sc->memsize > 1024) {
   1038 			page_size = 8;
   1039 			dsp_loop_latency += 8;
   1040 		} else {
   1041 			page_size = 10;
   1042 			dsp_loop_latency += 9;
   1043 		}
   1044 		break;
   1045 	default:
   1046 		page_size = 10;
   1047 		dsp_loop_latency += 9;
   1048 		break;
   1049 	}
   1050 
   1051 	if (xclks_per_qw >= (page_size << 11))
   1052 		fifo_on = ((2 * page_size + 1) << 6) + (xclks_per_qw >> 5);
   1053 	else
   1054 		fifo_on = (3 * page_size + 2) << 6;
   1055 
   1056 	dsp_xclks_per_qw = xclks_per_qw >> dsp_precision;
   1057 	dsp_on = fifo_on >> dsp_precision;
   1058 	dsp_off = fifo_off >> dsp_precision;
   1059 
   1060 #ifdef MACH64_DEBUG
   1061 	printf("dsp_xclks_per_qw = %d, dsp_on = %d, dsp_off = %d,\n"
   1062 	    "dsp_precision = %d, dsp_loop_latency = %d,\n"
   1063 	    "mclk_fb_div = %d, vclk_fb_div = %d,\n"
   1064 	    "mclk_post_div = %d, vclk_post_div = %d\n",
   1065 	    dsp_xclks_per_qw, dsp_on, dsp_off, dsp_precision, dsp_loop_latency,
   1066 	    sc->mclk_fb_div, sc->vclk_fb_div,
   1067 	    sc->mclk_post_div, sc->vclk_post_div);
   1068 #endif
   1069 
   1070 	regw(sc, DSP_ON_OFF, ((dsp_on << 16) & DSP_ON) | (dsp_off & DSP_OFF));
   1071 	regw(sc, DSP_CONFIG, ((dsp_precision << 20) & DSP_PRECISION) |
   1072 	    ((dsp_loop_latency << 16) & DSP_LOOP_LATENCY) |
   1073 	    (dsp_xclks_per_qw & DSP_XCLKS_PER_QW));
   1074 }
   1075 
   1076 void
   1077 mach64_set_pll(struct mach64_softc *sc, int clock)
   1078 {
   1079 	int q;
   1080 
   1081 	q = (clock * sc->ref_div * 100) / (2 * sc->ref_freq);
   1082 #ifdef MACH64_DEBUG
   1083 	printf("q = %d\n", q);
   1084 #endif
   1085 	if (q > 25500) {
   1086 		printf("Warning: q > 25500\n");
   1087 		q = 25500;
   1088 		sc->vclk_post_div = 1;
   1089 		sc->log2_vclk_post_div = 0;
   1090 	} else if (q > 12750) {
   1091 		sc->vclk_post_div = 1;
   1092 		sc->log2_vclk_post_div = 0;
   1093 	} else if (q > 6350) {
   1094 		sc->vclk_post_div = 2;
   1095 		sc->log2_vclk_post_div = 1;
   1096 	} else if (q > 3150) {
   1097 		sc->vclk_post_div = 4;
   1098 		sc->log2_vclk_post_div = 2;
   1099 	} else if (q >= 1600) {
   1100 		sc->vclk_post_div = 8;
   1101 		sc->log2_vclk_post_div = 3;
   1102 	} else {
   1103 		printf("Warning: q < 1600\n");
   1104 		sc->vclk_post_div = 8;
   1105 		sc->log2_vclk_post_div = 3;
   1106 	}
   1107 	sc->vclk_fb_div = q * sc->vclk_post_div / 100;
   1108 
   1109 	regwb_pll(sc, MCLK_FB_DIV, sc->mclk_fb_div);
   1110 	regwb_pll(sc, VCLK_POST_DIV, sc->log2_vclk_post_div);
   1111 	regwb_pll(sc, VCLK0_FB_DIV, sc->vclk_fb_div);
   1112 }
   1113 
   1114 void
   1115 mach64_init_lut(struct mach64_softc *sc)
   1116 {
   1117 	/* XXX this is pretty dodgy since it's perfectly possible that
   1118 	   both terminal emulations are compiled into the kernel, in this
   1119 	   case we'd install the VT100 colour map which may be wrong */
   1120 #ifdef WSEMUL_SUN
   1121 	mach64_putpalreg(sc,0,255,255,255);
   1122 	mach64_putpalreg(sc,1,0,0,0);
   1123 	mach64_putpalreg(sc,255,0,0,0);
   1124 #endif
   1125 #ifdef WSEMUL_VT100
   1126 	{
   1127 		int i,idx;
   1128 		idx=0;
   1129 		for(i=0;i<256;i++) {
   1130 			mach64_putpalreg(sc,i,rasops_cmap[idx],rasops_cmap[idx+1],rasops_cmap[idx+2]);
   1131 			idx+=3;
   1132 		}
   1133 	}
   1134 #endif
   1135 }
   1136 
   1137 int mach64_putpalreg(struct mach64_softc *sc, uint8_t index, uint8_t r, uint8_t g, uint8_t b)
   1138 {
   1139 	sc->sc_cmap_red[index]=r;
   1140 	sc->sc_cmap_green[index]=g;
   1141 	sc->sc_cmap_blue[index]=b;
   1142 	/* writing the dac index takes a while, in theory we can poll some register
   1143 	   to see when it's ready - but we better avoid writing it unnecessarily */
   1144 	if(index!=sc->sc_dacw)
   1145 	{
   1146 		regwb(sc, DAC_MASK, 0xff);
   1147 		regwb(sc, DAC_WINDEX, index);
   1148 	}
   1149 	sc->sc_dacw=index+1;
   1150 	regwb(sc, DAC_DATA, r);
   1151 	regwb(sc, DAC_DATA, g);
   1152 	regwb(sc, DAC_DATA, b);
   1153 	return 0;
   1154 }
   1155 
   1156 int mach64_putcmap(struct mach64_softc *sc, struct wsdisplay_cmap *cm)
   1157 {
   1158 	u_int index = cm->index;
   1159 	u_int count = cm->count;
   1160 	int i, error;
   1161 	u_char rbuf[256], gbuf[256], bbuf[256];
   1162 	u_char *r, *g, *b;
   1163 
   1164 	printf("putcmap: %d %d\n",index, count);
   1165 	if (cm->index >= 256 || cm->count > 256 ||
   1166 	    (cm->index + cm->count) > 256)
   1167 		return EINVAL;
   1168 	error = copyin(cm->red, &rbuf[index], count);
   1169 	if (error)
   1170 		return error;
   1171 	error = copyin(cm->green, &gbuf[index], count);
   1172 	if (error)
   1173 		return error;
   1174 	error = copyin(cm->blue, &bbuf[index], count);
   1175 	if (error)
   1176 		return error;
   1177 
   1178 	memcpy(&sc->sc_cmap_red[index], &rbuf[index], count);
   1179 	memcpy(&sc->sc_cmap_green[index], &gbuf[index], count);
   1180 	memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count);
   1181 
   1182 	r = &sc->sc_cmap_red[index];
   1183 	g = &sc->sc_cmap_green[index];
   1184 	b = &sc->sc_cmap_blue[index];
   1185 
   1186 	for (i = 0; i < count; i++) {
   1187 		mach64_putpalreg(sc,index,*r, *g, *b);
   1188 		index++;
   1189 		r++, g++, b++;
   1190 	}
   1191 	return 0;
   1192 }
   1193 
   1194 int mach64_getcmap(struct mach64_softc *sc, struct wsdisplay_cmap *cm)
   1195 {
   1196 	u_int index = cm->index;
   1197 	u_int count = cm->count;
   1198 	int error;
   1199 
   1200 	if (index >= 255 || count > 256 || index + count > 256)
   1201 		return EINVAL;
   1202 
   1203 	error = copyout(&sc->sc_cmap_red[index],   cm->red,   count);
   1204 	if (error)
   1205 		return error;
   1206 	error = copyout(&sc->sc_cmap_green[index], cm->green, count);
   1207 	if (error)
   1208 		return error;
   1209 	error = copyout(&sc->sc_cmap_blue[index],  cm->blue,  count);
   1210 	if (error)
   1211 		return error;
   1212 
   1213 	return 0;
   1214 }
   1215 
   1216 void
   1217 mach64_switch_screen(struct mach64_softc *sc)
   1218 {
   1219 	struct mach64screen *scr, *oldscr;
   1220 	const struct wsscreen_descr *type;
   1221 
   1222 	scr = sc->wanted;
   1223 	if (!scr) {
   1224 		printf("mach64_switch_screen: disappeared\n");
   1225 		(*sc->switchcb)(sc->switchcbarg, EIO, 0);
   1226 		return;
   1227 	}
   1228 	type = scr->type;
   1229 	oldscr = sc->active; /* can be NULL! */
   1230 #ifdef DIAGNOSTIC
   1231 	if (oldscr) {
   1232 		if (!oldscr->active)
   1233 			panic("mach64_switch_screen: not active");
   1234 		if (oldscr->type != sc->currenttype)
   1235 			panic("mach64_switch_screen: bad type");
   1236 	}
   1237 #endif
   1238 	if (scr == oldscr)
   1239 		return;
   1240 
   1241 #ifdef DIAGNOSTIC
   1242 /* XXX Macallan: this one bites us at reboot */
   1243 /*	if (scr->active)
   1244 		panic("mach64_switch_screen: active");*/
   1245 #endif
   1246 
   1247 	if (oldscr)
   1248 		oldscr->active = 0;
   1249 
   1250 	if (sc->currenttype != type) {
   1251 		mach64_set_screentype(sc, type);
   1252 		sc->currenttype = type;
   1253 	}
   1254 
   1255 	scr->dispoffset = scr->mindispoffset;
   1256 
   1257 	if (!oldscr || (scr->dispoffset != oldscr->dispoffset)) {
   1258 
   1259 	}
   1260 
   1261 	/* Clear the entire screen. */
   1262 
   1263 	scr->active = 1;
   1264 	mach64_restore_screen(scr, type, scr->mem);
   1265 
   1266 	sc->active = scr;
   1267 
   1268 	mach64_cursor(scr, scr->cursoron, scr->cursorrow, scr->cursorcol);
   1269 
   1270 	sc->wanted = 0;
   1271 	if (sc->switchcb)
   1272 		(*sc->switchcb)(sc->switchcbarg, 0, 0);
   1273 }
   1274 
   1275 void
   1276 mach64_restore_screen(struct mach64screen *scr,
   1277     const struct wsscreen_descr *type, u_int16_t *mem)
   1278 {
   1279 
   1280 }
   1281 
   1282 int
   1283 mach64_set_screentype(struct mach64_softc *sc, const struct wsscreen_descr *des)
   1284 {
   1285 	struct mach64_crtcregs regs;
   1286 
   1287 	if (mach64_calc_crtcregs(sc, &regs,
   1288 	    (struct videomode *)des->modecookie))
   1289 		return 1;
   1290 
   1291 	mach64_set_crtcregs(sc, &regs);
   1292 	return 0;
   1293 }
   1294 
   1295 int
   1296 mach64_is_console(struct pci_attach_args *pa)
   1297 {
   1298 #ifdef __sparc__
   1299 	int node;
   1300 
   1301 	node = PCITAG_NODE(pa->pa_tag);
   1302 	if (node == -1)
   1303 		return 0;
   1304 
   1305 	return (node == prom_instance_to_package(prom_stdout()));
   1306 #else
   1307 	return 1;
   1308 #endif
   1309 }
   1310 
   1311 /*
   1312  * wsdisplay_emulops
   1313  */
   1314 
   1315 void
   1316 mach64_cursor(void *cookie, int on, int row, int col)
   1317 {
   1318 
   1319 }
   1320 
   1321 #if 0
   1322 int
   1323 mach64_mapchar(void *cookie, int uni, u_int *index)
   1324 {
   1325 
   1326 	return 0;
   1327 }
   1328 
   1329 void
   1330 mach64_putchar(void *cookie, int row, int col, u_int c, long attr)
   1331 {
   1332 
   1333 }
   1334 #endif
   1335 
   1336 void
   1337 mach64_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
   1338 {
   1339 	struct rasops_info *ri=cookie;
   1340 	struct mach64_softc *sc=ri->ri_hw;
   1341 	int32_t xs,xd,y,width,height;
   1342 
   1343 	xs=ri->ri_xorigin+ri->ri_font->fontwidth*srccol;
   1344 	xd=ri->ri_xorigin+ri->ri_font->fontwidth*dstcol;
   1345 	y=ri->ri_yorigin+ri->ri_font->fontheight*row;
   1346 	width=ri->ri_font->fontwidth*ncols;
   1347 	height=ri->ri_font->fontheight;
   1348 	mach64_bitblt(sc,xs,y,xd,y,width,height,MIX_SRC,0xff);
   1349 }
   1350 
   1351 void
   1352 mach64_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
   1353 {
   1354 	struct rasops_info *ri=cookie;
   1355 	struct mach64_softc *sc=ri->ri_hw;
   1356 	int32_t x,y,width,height,fg,bg,ul;;
   1357 
   1358 	x=ri->ri_xorigin+ri->ri_font->fontwidth*startcol;
   1359 	y=ri->ri_yorigin+ri->ri_font->fontheight*row;
   1360 	width=ri->ri_font->fontwidth*ncols;
   1361 	height=ri->ri_font->fontheight;
   1362 	rasops_unpack_attr(fillattr,&fg,&bg,&ul);
   1363 
   1364 	mach64_rectfill(sc,x,y,width,height,bg);
   1365 
   1366 }
   1367 
   1368 void
   1369 mach64_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
   1370 {
   1371 	struct rasops_info *ri=cookie;
   1372 	struct mach64_softc *sc=ri->ri_hw;
   1373 	int32_t x,ys,yd,width,height;
   1374 
   1375 	x=ri->ri_xorigin;
   1376 	ys=ri->ri_yorigin+ri->ri_font->fontheight*srcrow;
   1377 	yd=ri->ri_yorigin+ri->ri_font->fontheight*dstrow;
   1378 	width=ri->ri_emuwidth;
   1379 	height=ri->ri_font->fontheight*nrows;
   1380 	mach64_bitblt(sc,x,ys,x,yd,width,height,MIX_SRC,0xff);
   1381 }
   1382 
   1383 void mach64_bitblt(struct mach64_softc *sc, int xs, int ys, int xd, int yd, int width, int height, int rop,
   1384 int mask)
   1385 {
   1386 	uint32_t dest_ctl=0;
   1387 	wait_for_idle(sc);
   1388 	regw(sc,DP_WRITE_MASK,mask);	/* XXX only good for 8 bit */
   1389 	regw(sc,DP_PIX_WIDTH,DST_8BPP|SRC_8BPP|HOST_8BPP);
   1390 	regw(sc,DP_SRC,FRGD_SRC_BLIT);
   1391 	regw(sc,DP_MIX,(rop&0xffff)<<16);
   1392 	regw(sc,CLR_CMP_CNTL,0);	/* no transparency */
   1393 	if(yd<ys) {
   1394 		dest_ctl=DST_Y_TOP_TO_BOTTOM;
   1395 	} else {
   1396 		ys+=height-1;
   1397 		yd+=height-1;
   1398 		dest_ctl=DST_Y_BOTTOM_TO_TOP;
   1399 	}
   1400 	if(xd<xs) {
   1401 		dest_ctl|=DST_X_LEFT_TO_RIGHT;
   1402 		regw(sc,SRC_CNTL,SRC_LINE_X_LEFT_TO_RIGHT);
   1403 	} else {
   1404 		dest_ctl|=DST_X_RIGHT_TO_LEFT;
   1405 		xs+=width-1;
   1406 		xd+=width-1;
   1407 		regw(sc,SRC_CNTL,SRC_LINE_X_RIGHT_TO_LEFT);
   1408 	}
   1409 	regw(sc,DST_CNTL,dest_ctl);
   1410 
   1411 	regw(sc,SRC_Y_X,(xs<<16)|ys);
   1412 	regw(sc,SRC_WIDTH1,width);
   1413 	regw(sc,DST_Y_X,(xd<<16)|yd);
   1414 	regw(sc,DST_HEIGHT_WIDTH,(width<<16)|height);
   1415 	/* as long as the other rasops* functions aren't aware of the blitter we must wait here
   1416 	   or the blitter might not be done when someone else draws the next line */
   1417 	wait_for_idle(sc);
   1418 }
   1419 
   1420 void mach64_rectfill(struct mach64_softc *sc, int x, int y, int width, int height, int colour)
   1421 {
   1422 	wait_for_idle(sc);
   1423 	regw(sc,DP_WRITE_MASK,0xff);
   1424 	regw(sc,DP_FRGD_CLR,colour);
   1425 	regw(sc,DP_PIX_WIDTH,DST_8BPP|SRC_8BPP|HOST_8BPP);
   1426 	regw(sc,DP_SRC,FRGD_SRC_FRGD_CLR);
   1427 	regw(sc,DP_MIX,(MIX_SRC)<<16);
   1428 	regw(sc,CLR_CMP_CNTL,0);	/* no transparency */
   1429 	regw(sc,SRC_CNTL,SRC_LINE_X_LEFT_TO_RIGHT);
   1430 	regw(sc,DST_CNTL,DST_X_LEFT_TO_RIGHT|DST_Y_TOP_TO_BOTTOM);
   1431 
   1432 	regw(sc,SRC_Y_X,(x<<16)|y);
   1433 	regw(sc,SRC_WIDTH1,width);
   1434 	regw(sc,DST_Y_X,(x<<16)|y);
   1435 	regw(sc,DST_HEIGHT_WIDTH,(width<<16)|height);
   1436 	wait_for_idle(sc);
   1437 }
   1438 
   1439 void mach64_showpal(struct mach64_softc *sc)
   1440 {
   1441 	int i,x=0;
   1442 	for (i=0;i<16;i++) {
   1443 		mach64_rectfill(sc,x,0,64,64,i);
   1444 		x+=64;
   1445 	}
   1446 }
   1447 
   1448 int
   1449 mach64_allocattr(void *cookie, int fg, int bg, int flags, long *attrp)
   1450 {
   1451 
   1452 	return 0;
   1453 }
   1454 
   1455 void
   1456 mach64_eraserows(void *cookie, int row, int nrows, long fillattr)
   1457 {
   1458 	struct rasops_info *ri=cookie;
   1459 	struct mach64_softc *sc=ri->ri_hw;
   1460 	int32_t x,y,width,height,fg,bg,ul;
   1461 
   1462 	x=ri->ri_xorigin;
   1463 	y=ri->ri_yorigin+ri->ri_font->fontheight*row;
   1464 	width=ri->ri_emuwidth;
   1465 	height=ri->ri_font->fontheight*nrows;
   1466 	rasops_unpack_attr(fillattr,&fg,&bg,&ul);
   1467 
   1468 	mach64_rectfill(sc,x,y,width,height,bg);
   1469 }
   1470 
   1471 /*
   1472  * wsdisplay_accessops
   1473  */
   1474 
   1475 int
   1476 mach64_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct lwp *l)
   1477 {
   1478 	/* we'll probably need to add more stuff here */
   1479 	struct mach64_softc *sc = v;
   1480 	struct wsdisplay_fbinfo *wdf;
   1481 	struct mach64screen *ms=sc->active;
   1482 	switch (cmd) {
   1483 		case WSDISPLAYIO_GTYPE:
   1484 			*(u_int *)data = WSDISPLAY_TYPE_PCIMISC;	/* XXX ? */
   1485 			return 0;
   1486 
   1487 		case WSDISPLAYIO_GINFO:
   1488 			wdf = (void *)data;
   1489 			wdf->height = ms->ri.ri_height;
   1490 			wdf->width = ms->ri.ri_width;
   1491 			wdf->depth = ms->ri.ri_depth;
   1492 			wdf->cmsize = 256;
   1493 			return 0;
   1494 		case WSDISPLAYIO_GETCMAP:
   1495 			return mach64_getcmap(sc, (struct wsdisplay_cmap *)data);
   1496 
   1497 		case WSDISPLAYIO_PUTCMAP:
   1498 			return mach64_putcmap(sc, (struct wsdisplay_cmap *)data);
   1499 		/* PCI config read/write passthrough. */
   1500 		case PCI_IOC_CFGREAD:
   1501 		case PCI_IOC_CFGWRITE:
   1502 			return (pci_devioctl(sc->sc_pc, sc->sc_pcitag,
   1503 			    cmd, data, flag, p));
   1504 #ifdef notyet
   1505 		case WSDISPLAYIO_SMODE:
   1506 			{
   1507 				int new_mode=*(int*)data;
   1508 				if(new_mode!=sc->sc_mode)
   1509 				{
   1510 					sc->sc_mode=new_mode;
   1511 					if(new_mode==WSDISPLAYIO_MODE_EMUL)
   1512 					{
   1513 						/* we'll probably want to reset the console into a known state here
   1514 						   just in case the Xserver crashed or didn't properly clean up after
   1515 						   itself for whetever reason */
   1516 					}
   1517 				}
   1518 			}
   1519 #endif
   1520 	}
   1521 	return EPASSTHROUGH;
   1522 }
   1523 
   1524 paddr_t
   1525 mach64_mmap(void *v, off_t offset, int prot)
   1526 {
   1527 	struct mach64_softc *sc = v;
   1528 	paddr_t pa;
   1529 	/* 'regular' framebuffer mmap()ing */
   1530 	if(offset<sc->sc_apersize) {
   1531 		pa = bus_space_mmap(sc->sc_memt,sc->sc_aperbase+offset,0,prot,BUS_SPACE_MAP_LINEAR);
   1532 		return pa;
   1533 	}
   1534 	/* allow XFree86 to mmap() PCI space as if the BARs contain physical addresses */
   1535 	if((offset>0x80000000) && (offset<=0xffffffff)) {
   1536 		pa = bus_space_mmap(sc->sc_memt,offset,0,prot,BUS_SPACE_MAP_LINEAR);
   1537 		return pa;
   1538 	}
   1539 	return -1;
   1540 }
   1541 
   1542 int
   1543 mach64_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
   1544     int *curxp, int *curyp, long *defattrp)
   1545 {
   1546 	struct mach64_softc *sc = v;
   1547 	struct mach64screen *scr;
   1548 
   1549 	scr = malloc(sizeof(struct mach64screen), M_DEVBUF, M_WAITOK|M_ZERO);
   1550 	mach64_init_screen(sc, scr, type, 0, defattrp, sc->active == NULL);
   1551 	rasops_init(&scr->ri, mach64_console_screen.ri.ri_height / 16,
   1552 	    mach64_console_screen.ri.ri_width / 8);
   1553 
   1554 	scr->mem = malloc(type->ncols * type->nrows * 2, M_DEVBUF,
   1555 	     M_WAITOK);
   1556 	mach64_eraserows(sc, 0, type->nrows, *defattrp);
   1557 	if (sc->active == NULL) {
   1558 		scr->active = 1;
   1559 		sc->active = scr;
   1560 		sc->currenttype = type;
   1561 	}
   1562 
   1563 	*cookiep = scr;
   1564 	*curxp = scr->cursorcol;
   1565 	*curyp = scr->cursorrow;
   1566 
   1567 	return 0;
   1568 }
   1569 
   1570 void
   1571 mach64_free_screen(void *v, void *cookie)
   1572 {
   1573 	struct mach64_softc *sc = v;
   1574 	struct mach64screen *scr = cookie;
   1575 
   1576 	LIST_REMOVE(scr, next);
   1577 	if (scr != &mach64_console_screen)
   1578 		free(scr, M_DEVBUF);
   1579 	else
   1580 		panic("mach64_free_screen: console");
   1581 
   1582 	if (sc->active == scr)
   1583 		sc->active = 0;
   1584 }
   1585 
   1586 int
   1587 mach64_show_screen(void *v, void *cookie, int waitok,
   1588     void (*cb)(void *, int, int), void *cbarg)
   1589 {
   1590 	struct mach64_softc *sc = v;
   1591 	struct mach64screen *scr, *oldscr;
   1592 
   1593 	scr = cookie;
   1594 	oldscr = sc->active;
   1595 	if (scr == oldscr)
   1596 		return 0;
   1597 
   1598 	sc->wanted = scr;
   1599 	sc->switchcb = cb;
   1600 	sc->switchcbarg = cbarg;
   1601 	if (cb) {
   1602 		callout_reset(&sc->switch_callout, 0,
   1603 		    (void(*)(void *))mach64_switch_screen, sc);
   1604 		return EAGAIN;
   1605 	}
   1606 
   1607 	mach64_switch_screen(sc);
   1608 
   1609 	return 0;
   1610 }
   1611 
   1612 #if 0
   1613 int
   1614 mach64_load_font(void *v, void *cookie, struct wsdisplay_font *data)
   1615 {
   1616 
   1617 	return 0;
   1618 }
   1619 #endif
   1620