Home | History | Annotate | Line # | Download | only in tc
sfbplus.c revision 1.6
      1 /* $NetBSD: sfbplus.c,v 1.6 2000/09/09 06:15:17 nisimura Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1999 Tohru Nishimura.  All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. All advertising materials mentioning features or use of this software
     15  *    must display the following acknowledgement:
     16  *      This product includes software developed by Tohru Nishimura
     17  *	for the NetBSD Project.
     18  * 4. The name of the author may not be used to endorse or promote products
     19  *    derived from this software without specific prior written permission
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
     34 
     35 __KERNEL_RCSID(0, "$NetBSD: sfbplus.c,v 1.6 2000/09/09 06:15:17 nisimura 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/buf.h>
     43 #include <sys/ioctl.h>
     44 
     45 #include <machine/bus.h>
     46 #include <machine/intr.h>
     47 
     48 #include <dev/wscons/wsconsio.h>
     49 #include <dev/wscons/wsdisplayvar.h>
     50 
     51 #include <dev/rasops/rasops.h>
     52 #include <dev/wsfont/wsfont.h>
     53 
     54 #include <dev/tc/tcvar.h>
     55 #include <dev/ic/bt459reg.h>
     56 #include <dev/ic/bt463reg.h>
     57 #include <dev/tc/sfbreg.h>
     58 #include <dev/pci/tgareg.h>
     59 
     60 #include <uvm/uvm_extern.h>
     61 
     62 #if defined(pmax)
     63 #define	machine_btop(x) mips_btop(x)
     64 #define	MACHINE_KSEG0_TO_PHYS(x) MIPS_KSEG1_TO_PHYS(x)
     65 #endif
     66 
     67 #if defined(__alpha__) || defined(alpha)
     68 #define machine_btop(x) alpha_btop(x)
     69 #define MACHINE_KSEG0_TO_PHYS(x) ALPHA_K0SEG_TO_PHYS(x)
     70 #endif
     71 
     72 /* Bt459/Bt463 hardware registers */
     73 #define bt_lo	0
     74 #define bt_hi	1
     75 #define bt_reg	2
     76 #define bt_cmap 3
     77 
     78 #define REG(base, index)	*((u_int32_t *)(base) + (index))
     79 #define SELECT(vdac, regno) do {			\
     80 	REG(vdac, bt_lo) = ((regno) & 0x00ff);		\
     81 	REG(vdac, bt_hi) = ((regno) & 0x0f00) >> 8;	\
     82 	tc_wmb();					\
     83    } while (0)
     84 
     85 struct fb_devconfig {
     86 	vaddr_t dc_vaddr;		/* memory space virtual base address */
     87 	paddr_t dc_paddr;		/* memory space physical base address */
     88 	vsize_t dc_size;		/* size of slot memory */
     89 	int	dc_wid;			/* width of frame buffer */
     90 	int	dc_ht;			/* height of frame buffer */
     91 	int	dc_depth;		/* depth, bits per pixel */
     92 	int	dc_rowbytes;		/* bytes in a FB scan line */
     93 	vaddr_t	dc_videobase;		/* base of flat frame buffer */
     94 	int	dc_blanked;		/* currently has video disabled */
     95 
     96 	struct rasops_info rinfo;
     97 };
     98 
     99 struct hwcmap256 {
    100 #define	CMAP_SIZE	256	/* 256 R/G/B entries */
    101 	u_int8_t r[CMAP_SIZE];
    102 	u_int8_t g[CMAP_SIZE];
    103 	u_int8_t b[CMAP_SIZE];
    104 };
    105 
    106 struct hwcursor64 {
    107 	struct wsdisplay_curpos cc_pos;
    108 	struct wsdisplay_curpos cc_hot;
    109 	struct wsdisplay_curpos cc_size;
    110 	struct wsdisplay_curpos cc_magic;
    111 #define	CURSOR_MAX_SIZE	64
    112 	u_int8_t cc_color[6];
    113 	u_int64_t cc_image[64 + 64];
    114 };
    115 
    116 struct hwops {
    117 	void (*setlut) __P((void *, struct hwcmap256 *));
    118 	void (*getlut) __P((void *, struct hwcmap256 *));
    119 	void (*visible) __P((void *, int));
    120 	void (*locate) __P((void *, int, int));
    121 	void (*shape) __P((void *, struct wsdisplay_curpos *, u_int64_t *));
    122 	void (*color) __P((void *, u_int8_t *));
    123 };
    124 
    125 struct sfb_softc {
    126 	struct device sc_dev;
    127 	struct fb_devconfig *sc_dc;	/* device configuration */
    128 	struct hwcmap256 sc_cmap;	/* software copy of colormap */
    129 	struct hwcursor64 sc_cursor;	/* software copy of cursor */
    130 	int sc_curenb;			/* cursor sprite enabled */
    131 	int sc_changed;			/* need update of colormap */
    132 #define	DATA_ENB_CHANGED	0x01	/* cursor enable changed */
    133 #define	DATA_CURCMAP_CHANGED	0x02	/* cursor colormap changed */
    134 #define	DATA_CURSHAPE_CHANGED	0x04	/* cursor size, image, mask changed */
    135 #define	DATA_CMAP_CHANGED	0x08	/* colormap changed */
    136 #define	DATA_ALL_CHANGED	0x0f
    137 	int nscreens;
    138 	struct hwops sc_hwops;
    139 	void *sc_hw0, *sc_hw1;
    140 };
    141 
    142 #define	HX_MAGIC_X 368
    143 #define	HX_MAGIC_Y 38
    144 
    145 static int  sfbpmatch __P((struct device *, struct cfdata *, void *));
    146 static void sfbpattach __P((struct device *, struct device *, void *));
    147 
    148 struct cfattach sfbp_ca = {
    149 	sizeof(struct sfb_softc), sfbpmatch, sfbpattach,
    150 };
    151 
    152 static void sfbp_getdevconfig __P((tc_addr_t, struct fb_devconfig *));
    153 static struct fb_devconfig sfbp_console_dc;
    154 static tc_addr_t sfbp_consaddr;
    155 
    156 extern const struct wsdisplay_emulops sfbp_emulops, sfbp_emulops32;
    157 
    158 static struct wsscreen_descr sfb_stdscreen = {
    159 	"std", 0, 0,
    160 	NULL, /* textops */
    161 	0, 0,
    162 	WSSCREEN_REVERSE
    163 };
    164 
    165 static const struct wsscreen_descr *_sfb_scrlist[] = {
    166 	&sfb_stdscreen,
    167 };
    168 
    169 static const struct wsscreen_list sfb_screenlist = {
    170 	sizeof(_sfb_scrlist) / sizeof(struct wsscreen_descr *), _sfb_scrlist
    171 };
    172 
    173 static int	sfbioctl __P((void *, u_long, caddr_t, int, struct proc *));
    174 static paddr_t	sfbmmap __P((void *, off_t, int));
    175 
    176 static int	sfb_alloc_screen __P((void *, const struct wsscreen_descr *,
    177 				      void **, int *, int *, long *));
    178 static void	sfb_free_screen __P((void *, void *));
    179 static int	sfb_show_screen __P((void *, void *, int,
    180 				     void (*) (void *, int, int), void *));
    181 /* EXPORT */ int  sfb_alloc_attr __P((void *, int, int, int, long *));
    182 
    183 static const struct wsdisplay_accessops sfb_accessops = {
    184 	sfbioctl,
    185 	sfbmmap,
    186 	sfb_alloc_screen,
    187 	sfb_free_screen,
    188 	sfb_show_screen,
    189 	0 /* load_font */
    190 };
    191 
    192 static void bt459visible __P((void *, int));
    193 static void bt459locate __P((void *, int, int));
    194 static void bt459shape __P((void *, struct wsdisplay_curpos *, u_int64_t *));
    195 static void bt459color __P((void *, u_int8_t *));
    196 static void bt459setlut __P((void *, struct hwcmap256 *));
    197 
    198 static void sfbpvisible __P((void *, int));
    199 static void sfbplocate __P((void *, int, int));
    200 static void sfbpshape __P((void *, struct wsdisplay_curpos *, u_int64_t *));
    201 static void bt463color __P((void *, u_int8_t *));
    202 static void noplut __P((void *, struct hwcmap256 *));
    203 
    204 
    205 /* EXPORT */ int sfbp_cnattach __P((tc_addr_t));
    206 static int  sfbpintr __P((void *));
    207 static void sfbpinit __P((struct fb_devconfig *));
    208 
    209 static int  get_cmap __P((struct sfb_softc *, struct wsdisplay_cmap *));
    210 static int  set_cmap __P((struct sfb_softc *, struct wsdisplay_cmap *));
    211 static int  set_cursor __P((struct sfb_softc *, struct wsdisplay_cursor *));
    212 static int  get_cursor __P((struct sfb_softc *, struct wsdisplay_cursor *));
    213 
    214 
    215 /*
    216  * Compose 2 bit/pixel cursor image.  Bit order will be reversed.
    217  *   M M M M I I I I		M I M I M I M I
    218  *	[ before ]		   [ after ]
    219  *   3 2 1 0 3 2 1 0		0 0 1 1 2 2 3 3
    220  *   7 6 5 4 7 6 5 4		4 4 5 5 6 6 7 7
    221  */
    222 static const u_int8_t shuffle[256] = {
    223 	0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
    224 	0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55,
    225 	0x80, 0xc0, 0x90, 0xd0, 0x84, 0xc4, 0x94, 0xd4,
    226 	0x81, 0xc1, 0x91, 0xd1, 0x85, 0xc5, 0x95, 0xd5,
    227 	0x20, 0x60, 0x30, 0x70, 0x24, 0x64, 0x34, 0x74,
    228 	0x21, 0x61, 0x31, 0x71, 0x25, 0x65, 0x35, 0x75,
    229 	0xa0, 0xe0, 0xb0, 0xf0, 0xa4, 0xe4, 0xb4, 0xf4,
    230 	0xa1, 0xe1, 0xb1, 0xf1, 0xa5, 0xe5, 0xb5, 0xf5,
    231 	0x08, 0x48, 0x18, 0x58, 0x0c, 0x4c, 0x1c, 0x5c,
    232 	0x09, 0x49, 0x19, 0x59, 0x0d, 0x4d, 0x1d, 0x5d,
    233 	0x88, 0xc8, 0x98, 0xd8, 0x8c, 0xcc, 0x9c, 0xdc,
    234 	0x89, 0xc9, 0x99, 0xd9, 0x8d, 0xcd, 0x9d, 0xdd,
    235 	0x28, 0x68, 0x38, 0x78, 0x2c, 0x6c, 0x3c, 0x7c,
    236 	0x29, 0x69, 0x39, 0x79, 0x2d, 0x6d, 0x3d, 0x7d,
    237 	0xa8, 0xe8, 0xb8, 0xf8, 0xac, 0xec, 0xbc, 0xfc,
    238 	0xa9, 0xe9, 0xb9, 0xf9, 0xad, 0xed, 0xbd, 0xfd,
    239 	0x02, 0x42, 0x12, 0x52, 0x06, 0x46, 0x16, 0x56,
    240 	0x03, 0x43, 0x13, 0x53, 0x07, 0x47, 0x17, 0x57,
    241 	0x82, 0xc2, 0x92, 0xd2, 0x86, 0xc6, 0x96, 0xd6,
    242 	0x83, 0xc3, 0x93, 0xd3, 0x87, 0xc7, 0x97, 0xd7,
    243 	0x22, 0x62, 0x32, 0x72, 0x26, 0x66, 0x36, 0x76,
    244 	0x23, 0x63, 0x33, 0x73, 0x27, 0x67, 0x37, 0x77,
    245 	0xa2, 0xe2, 0xb2, 0xf2, 0xa6, 0xe6, 0xb6, 0xf6,
    246 	0xa3, 0xe3, 0xb3, 0xf3, 0xa7, 0xe7, 0xb7, 0xf7,
    247 	0x0a, 0x4a, 0x1a, 0x5a, 0x0e, 0x4e, 0x1e, 0x5e,
    248 	0x0b, 0x4b, 0x1b, 0x5b, 0x0f, 0x4f, 0x1f, 0x5f,
    249 	0x8a, 0xca, 0x9a, 0xda, 0x8e, 0xce, 0x9e, 0xde,
    250 	0x8b, 0xcb, 0x9b, 0xdb, 0x8f, 0xcf, 0x9f, 0xdf,
    251 	0x2a, 0x6a, 0x3a, 0x7a, 0x2e, 0x6e, 0x3e, 0x7e,
    252 	0x2b, 0x6b, 0x3b, 0x7b, 0x2f, 0x6f, 0x3f, 0x7f,
    253 	0xaa, 0xea, 0xba, 0xfa, 0xae, 0xee, 0xbe, 0xfe,
    254 	0xab, 0xeb, 0xbb, 0xfb, 0xaf, 0xef, 0xbf, 0xff,
    255 };
    256 
    257 static int
    258 sfbpmatch(parent, match, aux)
    259 	struct device *parent;
    260 	struct cfdata *match;
    261 	void *aux;
    262 {
    263 	struct tc_attach_args *ta = aux;
    264 
    265 	if (strncmp("PMAGD", ta->ta_modname, 5) != 0)
    266 		return (0);
    267 
    268 	return (1);
    269 }
    270 
    271 static void
    272 sfbp_getdevconfig(dense_addr, dc)
    273 	tc_addr_t dense_addr;
    274 	struct fb_devconfig *dc;
    275 {
    276 	caddr_t sfbasic;
    277 	int i, hsetup, vsetup, vbase, cookie;
    278 
    279 	dc->dc_vaddr = dense_addr;
    280 	dc->dc_paddr = MACHINE_KSEG0_TO_PHYS(dc->dc_vaddr);
    281 
    282 	sfbasic = (caddr_t)(dc->dc_vaddr + SFB_ASIC_OFFSET);
    283 	hsetup = *(u_int32_t *)(sfbasic + SFB_ASIC_VIDEO_HSETUP);
    284 	vsetup = *(u_int32_t *)(sfbasic + SFB_ASIC_VIDEO_VSETUP);
    285 	i = *(u_int32_t *)(sfbasic + SFB_ASIC_DEEP);
    286 	*(u_int32_t *)(sfbasic + SFB_ASIC_VIDEO_BASE) = vbase = 1;
    287 
    288 	dc->dc_wid = (hsetup & 0x1ff) << 2;
    289 	dc->dc_ht = (vsetup & 0x7ff);
    290 	dc->dc_depth = (i & 1) ? 32 : 8;
    291 	dc->dc_rowbytes = dc->dc_wid * (dc->dc_depth / 8);
    292 	dc->dc_videobase = dc->dc_vaddr + 0x800000 + vbase * 4096; /* XXX */
    293 	dc->dc_blanked = 0;
    294 
    295 	/* initialize colormap and cursor resource */
    296 	sfbpinit(dc);
    297 
    298 	/* clear the screen */
    299 	for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t))
    300 		*(u_int32_t *)(dc->dc_videobase + i) = 0x0;
    301 
    302 	dc->rinfo.ri_flg = RI_CENTER;
    303 	dc->rinfo.ri_depth = dc->dc_depth;
    304 	dc->rinfo.ri_bits = (void *)dc->dc_videobase;
    305 	dc->rinfo.ri_width = dc->dc_wid;
    306 	dc->rinfo.ri_height = dc->dc_ht;
    307 	dc->rinfo.ri_stride = dc->dc_rowbytes;
    308 	dc->rinfo.ri_hw = sfbasic;
    309 
    310 	wsfont_init();
    311 	/* prefer 8 pixel wide font */
    312 	if ((cookie = wsfont_find(NULL, 8, 0, 0)) <= 0)
    313 		cookie = wsfont_find(NULL, 0, 0, 0);
    314 	if (cookie <= 0) {
    315 		printf("sfb: font table is empty\n");
    316 		return;
    317 	}
    318 
    319 	/* the accelerated sfb_putchar() needs LSbit left */
    320 	if (wsfont_lock(cookie, &dc->rinfo.ri_font,
    321 	    WSDISPLAY_FONTORDER_R2L, WSDISPLAY_FONTORDER_L2R) <= 0) {
    322 		printf("sfb: couldn't lock font\n");
    323 		return;
    324 	}
    325 	dc->rinfo.ri_wsfcookie = cookie;
    326 
    327 	rasops_init(&dc->rinfo, 34, 80);
    328 
    329 	/* XXX shouldn't be global */
    330 	sfb_stdscreen.nrows = dc->rinfo.ri_rows;
    331 	sfb_stdscreen.ncols = dc->rinfo.ri_cols;
    332 	sfb_stdscreen.textops
    333 	    = (dc->dc_depth == 8) ? &sfbp_emulops : &sfbp_emulops32;
    334 	sfb_stdscreen.capabilities = dc->rinfo.ri_caps;
    335 	/* our accelerated putchar can't underline */
    336 	sfb_stdscreen.capabilities &= ~WSSCREEN_UNDERLINE;
    337 }
    338 
    339 static void
    340 sfbpattach(parent, self, aux)
    341 	struct device *parent, *self;
    342 	void *aux;
    343 {
    344 	struct sfb_softc *sc = (struct sfb_softc *)self;
    345 	struct tc_attach_args *ta = aux;
    346 	struct wsemuldisplaydev_attach_args waa;
    347 	struct hwcmap256 *cm;
    348 	caddr_t sfbasic;
    349 	int console;
    350 
    351 	console = (ta->ta_addr == sfbp_consaddr);
    352 	if (console) {
    353 		sc->sc_dc = &sfbp_console_dc;
    354 		sc->nscreens = 1;
    355 	}
    356 	else {
    357 		sc->sc_dc = (struct fb_devconfig *)
    358 		    malloc(sizeof(struct fb_devconfig), M_DEVBUF, M_WAITOK);
    359 		sfbp_getdevconfig(ta->ta_addr, sc->sc_dc);
    360 	}
    361 	printf(": %d x %d, %dbpp\n", sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
    362 	    sc->sc_dc->dc_depth);
    363 
    364 	cm = &sc->sc_cmap;
    365 	memset(cm, 255, sizeof(struct hwcmap256));	/* XXX */
    366 	cm->r[0] = cm->g[0] = cm->b[0] = 0;		/* XXX */
    367 
    368 	sc->sc_cursor.cc_magic.x = HX_MAGIC_X;
    369 	sc->sc_cursor.cc_magic.y = HX_MAGIC_Y;
    370 
    371 	if (sc->sc_dc->dc_depth == 8) {
    372 		sc->sc_hw0 = (caddr_t)ta->ta_addr + SFB_RAMDAC_OFFSET;
    373 		sc->sc_hw1 = sc->sc_hw0;
    374 		sc->sc_hwops.visible = bt459visible;
    375 		sc->sc_hwops.locate = bt459locate;
    376 		sc->sc_hwops.shape = bt459shape;
    377 		sc->sc_hwops.color = bt459color;
    378 		sc->sc_hwops.setlut = bt459setlut;
    379 		sc->sc_hwops.getlut = noplut;
    380 	}
    381 	else {
    382 		sc->sc_hw0 = (caddr_t)ta->ta_addr + SFB_ASIC_OFFSET;
    383 		sc->sc_hw1 = (caddr_t)ta->ta_addr + SFB_RAMDAC_OFFSET;
    384 		sc->sc_hwops.visible = sfbpvisible;
    385 		sc->sc_hwops.locate = sfbplocate;
    386 		sc->sc_hwops.shape = sfbpshape;
    387 		sc->sc_hwops.color = bt463color;
    388 		sc->sc_hwops.setlut = noplut;
    389 		sc->sc_hwops.getlut = noplut;
    390 	}
    391 
    392         tc_intr_establish(parent, ta->ta_cookie, IPL_TTY, sfbpintr, sc);
    393 
    394 	sfbasic = (caddr_t)(sc->sc_dc->dc_vaddr + SFB_ASIC_OFFSET);
    395 	*(u_int32_t *)(sfbasic + SFB_ASIC_CLEAR_INTR) = 0;	tc_wmb();
    396 	*(u_int32_t *)(sfbasic + SFB_ASIC_ENABLE_INTR) = 1;	tc_wmb();
    397 
    398 	waa.console = console;
    399 	waa.scrdata = &sfb_screenlist;
    400 	waa.accessops = &sfb_accessops;
    401 	waa.accesscookie = sc;
    402 
    403 	config_found(self, &waa, wsemuldisplaydevprint);
    404 }
    405 
    406 static int
    407 sfbioctl(v, cmd, data, flag, p)
    408 	void *v;
    409 	u_long cmd;
    410 	caddr_t data;
    411 	int flag;
    412 	struct proc *p;
    413 {
    414 	struct sfb_softc *sc = v;
    415 	struct fb_devconfig *dc = sc->sc_dc;
    416 	int turnoff;
    417 
    418 	switch (cmd) {
    419 	case WSDISPLAYIO_GTYPE:
    420 		*(u_int *)data = WSDISPLAY_TYPE_SFB; /* XXX SFBP XXX */
    421 		return (0);
    422 
    423 	case WSDISPLAYIO_GINFO:
    424 #define	wsd_fbip ((struct wsdisplay_fbinfo *)data)
    425 		wsd_fbip->height = sc->sc_dc->dc_ht;
    426 		wsd_fbip->width = sc->sc_dc->dc_wid;
    427 		wsd_fbip->depth = sc->sc_dc->dc_depth;
    428 		wsd_fbip->cmsize = CMAP_SIZE;
    429 #undef fbt
    430 		return (0);
    431 
    432 	case WSDISPLAYIO_GETCMAP:
    433 		return get_cmap(sc, (struct wsdisplay_cmap *)data);
    434 
    435 	case WSDISPLAYIO_PUTCMAP:
    436 		return set_cmap(sc, (struct wsdisplay_cmap *)data);
    437 
    438 	case WSDISPLAYIO_SVIDEO:
    439 		turnoff = *(int *)data == WSDISPLAYIO_VIDEO_OFF;
    440 		if ((dc->dc_blanked == 0) ^ turnoff) {
    441 			dc->dc_blanked = turnoff;
    442 #if 0 /* XXX later XXX */
    443 	Low order 3bit control visibilities of screen and builtin cursor.
    444 #endif	/* XXX XXX XXX */
    445 		}
    446 		return (0);
    447 
    448 	case WSDISPLAYIO_GVIDEO:
    449 		*(u_int *)data = dc->dc_blanked ?
    450 		    WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON;
    451 		return (0);
    452 
    453 	case WSDISPLAYIO_GCURPOS:
    454 		*(struct wsdisplay_curpos *)data = sc->sc_cursor.cc_pos;
    455 		return (0);
    456 
    457 	case WSDISPLAYIO_SCURPOS: {
    458 		struct wsdisplay_curpos *pos = (void *)data;
    459 		int x, y;
    460 
    461 		x = pos->x;
    462 		y = pos->y;
    463 		if (y < 0)
    464 			y = 0;
    465 		else if (y > dc->dc_ht)
    466 			y = dc->dc_ht;
    467 		if (x < 0)
    468 			x = 0;
    469 		else if (x > dc->dc_wid)
    470 			x = dc->dc_wid;
    471 		sc->sc_cursor.cc_pos.x = x;
    472 		sc->sc_cursor.cc_pos.y = y;
    473 		x -= sc->sc_cursor.cc_hot.x;
    474 		y -= sc->sc_cursor.cc_hot.y;
    475 		x += sc->sc_cursor.cc_magic.x;
    476 		y += sc->sc_cursor.cc_magic.y;
    477 		(*sc->sc_hwops.locate)(sc->sc_hw0, x, y);
    478 		return (0);
    479 		}
    480 
    481 	case WSDISPLAYIO_GCURMAX:
    482 		((struct wsdisplay_curpos *)data)->x =
    483 		((struct wsdisplay_curpos *)data)->y = CURSOR_MAX_SIZE;
    484 		return (0);
    485 
    486 	case WSDISPLAYIO_GCURSOR:
    487 		return get_cursor(sc, (struct wsdisplay_cursor *)data);
    488 
    489 	case WSDISPLAYIO_SCURSOR:
    490 		return set_cursor(sc, (struct wsdisplay_cursor *)data);
    491 	}
    492 	return ENOTTY;
    493 }
    494 
    495 paddr_t
    496 sfbmmap(v, offset, prot)
    497 	void *v;
    498 	off_t offset;
    499 	int prot;
    500 {
    501 	struct sfb_softc *sc = v;
    502 
    503 	if (offset >= 0x1000000 || offset < 0) /* XXX 16MB XXX */
    504 		return (-1);
    505 	return machine_btop(sc->sc_dc->dc_paddr + offset);
    506 }
    507 
    508 static int
    509 sfb_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
    510 	void *v;
    511 	const struct wsscreen_descr *type;
    512 	void **cookiep;
    513 	int *curxp, *curyp;
    514 	long *attrp;
    515 {
    516 	struct sfb_softc *sc = v;
    517 	long defattr;
    518 
    519 	if (sc->nscreens > 0)
    520 		return (ENOMEM);
    521 
    522 	*cookiep = &sc->sc_dc->rinfo; /* one and only for now */
    523 	*curxp = 0;
    524 	*curyp = 0;
    525 	(*sc->sc_dc->rinfo.ri_ops.alloc_attr)(&sc->sc_dc->rinfo, 0, 0, 0, &defattr);
    526 	*attrp = defattr;
    527 	sc->nscreens++;
    528 	return (0);
    529 }
    530 
    531 void
    532 sfb_free_screen(v, cookie)
    533 	void *v;
    534 	void *cookie;
    535 {
    536 	struct sfb_softc *sc = v;
    537 
    538 	if (sc->sc_dc == &sfbp_console_dc)
    539 		panic("sfb_free_screen: console");
    540 
    541 	sc->nscreens--;
    542 }
    543 
    544 static int
    545 sfb_show_screen(v, cookie, waitok, cb, cbarg)
    546 	void *v;
    547 	void *cookie;
    548 	int waitok;
    549 	void (*cb) __P((void *, int, int));
    550 	void *cbarg;
    551 {
    552 
    553 	return (0);
    554 }
    555 
    556 int
    557 sfbp_cnattach(addr)
    558 	tc_addr_t addr;
    559 {
    560 	struct fb_devconfig *dcp = &sfbp_console_dc;
    561 	long defattr;
    562 
    563 	sfbp_getdevconfig(addr, dcp);
    564 
    565 	(*dcp->rinfo.ri_ops.alloc_attr)(&dcp->rinfo, 0, 0, 0, &defattr);
    566 
    567 	wsdisplay_cnattach(&sfb_stdscreen, &dcp->rinfo, 0, 0, defattr);
    568 	sfbp_consaddr = addr;
    569 	return(0);
    570 }
    571 
    572 static int
    573 sfbpintr(arg)
    574 	void *arg;
    575 {
    576 	struct sfb_softc *sc = arg;
    577 	caddr_t sfbasic = (caddr_t)sc->sc_dc->dc_vaddr + SFB_ASIC_OFFSET;
    578 	int v;
    579 	u_int32_t sisr;
    580 
    581 #define	cc (&sc->sc_cursor)
    582 	sisr = *((u_int32_t *)sfbasic + TGA_REG_SISR);
    583 
    584 	*(u_int32_t *)(sfbasic + SFB_ASIC_CLEAR_INTR) = 0;
    585 
    586 	if (sc->sc_changed == 0)
    587 		goto finish;
    588 
    589 	v = sc->sc_changed;
    590 	sc->sc_changed = 0;
    591 
    592 	if (v & DATA_ENB_CHANGED)
    593 		(*sc->sc_hwops.visible)(sc->sc_hw0, sc->sc_curenb);
    594 	if (v & DATA_CURCMAP_CHANGED)
    595 		(*sc->sc_hwops.color)(sc->sc_hw1, cc->cc_color);
    596 	if (v & DATA_CURSHAPE_CHANGED)
    597 		(*sc->sc_hwops.shape)(sc->sc_hw0, &cc->cc_size, cc->cc_image);
    598 	if (v & DATA_CMAP_CHANGED)
    599 		(*sc->sc_hwops.setlut)(sc->sc_hw1, &sc->sc_cmap);
    600 
    601 finish:
    602 	*((u_int32_t *)sfbasic + TGA_REG_SISR) = sisr = 0x00000001; tc_wmb();
    603 	return (1);
    604 #undef cc
    605 }
    606 
    607 static void
    608 sfbpinit(dc)
    609 	struct fb_devconfig *dc;
    610 {
    611 	caddr_t sfbasic = (caddr_t)(dc->dc_vaddr + SFB_ASIC_OFFSET);
    612 	caddr_t vdac = (caddr_t)(dc->dc_vaddr + SFB_RAMDAC_OFFSET);
    613 	int i;
    614 
    615 	*(u_int32_t *)(sfbasic + SFB_ASIC_PLANEMASK) = ~0;
    616 	*(u_int32_t *)(sfbasic + SFB_ASIC_PIXELMASK) = ~0;
    617 	*(u_int32_t *)(sfbasic + SFB_ASIC_MODE) = 0; /* MODE_SIMPLE */
    618 	*(u_int32_t *)(sfbasic + SFB_ASIC_ROP) = 3;  /* ROP_COPY */
    619 
    620     if (dc->dc_depth == 8) {
    621 	*(u_int32_t *)(sfbasic + 0x180000) = 0; /* Bt459 reset */
    622 
    623 	SELECT(vdac, BT459_IREG_COMMAND_0);
    624 	REG(vdac, bt_reg) = 0x40; /* CMD0 */	tc_wmb();
    625 	REG(vdac, bt_reg) = 0x0;  /* CMD1 */	tc_wmb();
    626 	REG(vdac, bt_reg) = 0xc0; /* CMD2 */	tc_wmb();
    627 	REG(vdac, bt_reg) = 0xff; /* PRM */	tc_wmb();
    628 	REG(vdac, bt_reg) = 0;    /* 205 */	tc_wmb();
    629 	REG(vdac, bt_reg) = 0x0;  /* PBM */	tc_wmb();
    630 	REG(vdac, bt_reg) = 0;    /* 207 */	tc_wmb();
    631 	REG(vdac, bt_reg) = 0x0;  /* ORM */	tc_wmb();
    632 	REG(vdac, bt_reg) = 0x0;  /* OBM */	tc_wmb();
    633 	REG(vdac, bt_reg) = 0x0;  /* ILV */	tc_wmb();
    634 	REG(vdac, bt_reg) = 0x0;  /* TEST */	tc_wmb();
    635 
    636 	SELECT(vdac, BT459_IREG_CCR);
    637 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    638 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    639 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    640 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    641 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    642 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    643 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    644 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    645 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    646 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    647 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    648 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    649 	REG(vdac, bt_reg) = 0x0;	tc_wmb();
    650 
    651 	/* build sane colormap */
    652 	SELECT(vdac, 0);
    653 	REG(vdac, bt_cmap) = 0;	tc_wmb();
    654 	REG(vdac, bt_cmap) = 0;	tc_wmb();
    655 	REG(vdac, bt_cmap) = 0;	tc_wmb();
    656 	for (i = 1; i < CMAP_SIZE; i++) {
    657 		REG(vdac, bt_cmap) = 0xff;	tc_wmb();
    658 		REG(vdac, bt_cmap) = 0xff;	tc_wmb();
    659 		REG(vdac, bt_cmap) = 0xff;	tc_wmb();
    660 	}
    661 
    662 	/* clear out cursor image */
    663 	SELECT(vdac, BT459_IREG_CRAM_BASE);
    664 	for (i = 0; i < 1024; i++)
    665 		REG(vdac, bt_reg) = 0xff;	tc_wmb();
    666 
    667 	/*
    668 	 * 2 bit/pixel cursor.  Assign MSB for cursor mask and LSB for
    669 	 * cursor image.  CCOLOR_2 for mask color, while CCOLOR_3 for
    670 	 * image color.  CCOLOR_1 will be never used.
    671 	 */
    672 	SELECT(vdac, BT459_IREG_CCOLOR_1);
    673 	REG(vdac, bt_reg) = 0xff;	tc_wmb();
    674 	REG(vdac, bt_reg) = 0xff;	tc_wmb();
    675 	REG(vdac, bt_reg) = 0xff;	tc_wmb();
    676 
    677 	REG(vdac, bt_reg) = 0;		tc_wmb();
    678 	REG(vdac, bt_reg) = 0;		tc_wmb();
    679 	REG(vdac, bt_reg) = 0;		tc_wmb();
    680 
    681 	REG(vdac, bt_reg) = 0xff;	tc_wmb();
    682 	REG(vdac, bt_reg) = 0xff;	tc_wmb();
    683 	REG(vdac, bt_reg) = 0xff;	tc_wmb();
    684     } else {
    685 	SELECT(vdac, BT463_IREG_COMMAND_0);
    686 	REG(vdac, bt_reg) = 0x40;	tc_wmb();	/* CMD 0 */
    687 	REG(vdac, bt_reg) = 0x46;	tc_wmb();	/* CMD 1 */
    688 	REG(vdac, bt_reg) = 0xc0;	tc_wmb();	/* CMD 2 */
    689 	REG(vdac, bt_reg) = 0;		tc_wmb();	/* !? 204 !? */
    690 	REG(vdac, bt_reg) = 0xff;	tc_wmb();	/* plane  0:7  */
    691 	REG(vdac, bt_reg) = 0xff;	tc_wmb();	/* plane  8:15 */
    692 	REG(vdac, bt_reg) = 0xff;	tc_wmb();	/* plane 16:23 */
    693 	REG(vdac, bt_reg) = 0xff;	tc_wmb();	/* plane 24:27 */
    694 	REG(vdac, bt_reg) = 0x00;	tc_wmb();	/* blink  0:7  */
    695 	REG(vdac, bt_reg) = 0x00;	tc_wmb();	/* blink  8:15 */
    696 	REG(vdac, bt_reg) = 0x00;	tc_wmb();	/* blink 16:23 */
    697 	REG(vdac, bt_reg) = 0x00;	tc_wmb();	/* blink 24:27 */
    698 	REG(vdac, bt_reg) = 0x00;	tc_wmb();
    699 
    700 #if 0 /* XXX ULTRIX does initialize 16 entry window type here XXX */
    701   {
    702 	static u_int32_t windowtype[BT463_IREG_WINDOW_TYPE_TABLE] = {
    703 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    704 	};
    705 
    706 	SELECT(vdac, BT463_IREG_WINDOW_TYPE_TABLE);
    707 	for (i = 0; i < BT463_NWTYPE_ENTRIES; i++) {
    708 		REG(vdac, bt_reg) = windowtype[i];	  /*   0:7  */
    709 		REG(vdac, bt_reg) = windowtype[i] >> 8;  /*   8:15 */
    710 		REG(vdac, bt_reg) = windowtype[i] >> 16; /*  16:23 */
    711 	}
    712   }
    713 #endif
    714 
    715 	SELECT(vdac, BT463_IREG_CPALETTE_RAM);
    716 	REG(vdac, bt_cmap) = 0;		tc_wmb();
    717 	REG(vdac, bt_cmap) = 0;		tc_wmb();
    718 	REG(vdac, bt_cmap) = 0;		tc_wmb();
    719 	for (i = 1; i < 256; i++) {
    720 		REG(vdac, bt_cmap) = 0xff;	tc_wmb();
    721 		REG(vdac, bt_cmap) = 0xff;	tc_wmb();
    722 		REG(vdac, bt_cmap) = 0xff;	tc_wmb();
    723 	}
    724 
    725 	/* !? Eeeh !? */
    726 	SELECT(vdac, 0x0100 /* BT463_IREG_CURSOR_COLOR_0 */);
    727 	for (i = 0; i < 256; i++) {
    728 		REG(vdac, bt_cmap) = i;	tc_wmb();
    729 		REG(vdac, bt_cmap) = i;	tc_wmb();
    730 		REG(vdac, bt_cmap) = i;	tc_wmb();
    731 	}
    732     }
    733 }
    734 
    735 static int
    736 get_cmap(sc, p)
    737 	struct sfb_softc *sc;
    738 	struct wsdisplay_cmap *p;
    739 {
    740 	u_int index = p->index, count = p->count;
    741 
    742 	if (index >= CMAP_SIZE || (index + count) > CMAP_SIZE)
    743 		return (EINVAL);
    744 
    745 	if (!uvm_useracc(p->red, count, B_WRITE) ||
    746 	    !uvm_useracc(p->green, count, B_WRITE) ||
    747 	    !uvm_useracc(p->blue, count, B_WRITE))
    748 		return (EFAULT);
    749 
    750 	copyout(&sc->sc_cmap.r[index], p->red, count);
    751 	copyout(&sc->sc_cmap.g[index], p->green, count);
    752 	copyout(&sc->sc_cmap.b[index], p->blue, count);
    753 
    754 	return (0);
    755 }
    756 
    757 static int
    758 set_cmap(sc, p)
    759 	struct sfb_softc *sc;
    760 	struct wsdisplay_cmap *p;
    761 {
    762 	u_int index = p->index, count = p->count;
    763 
    764 	if (index >= CMAP_SIZE || (index + count) > CMAP_SIZE)
    765 		return (EINVAL);
    766 
    767 	if (!uvm_useracc(p->red, count, B_READ) ||
    768 	    !uvm_useracc(p->green, count, B_READ) ||
    769 	    !uvm_useracc(p->blue, count, B_READ))
    770 		return (EFAULT);
    771 
    772 	copyin(p->red, &sc->sc_cmap.r[index], count);
    773 	copyin(p->green, &sc->sc_cmap.g[index], count);
    774 	copyin(p->blue, &sc->sc_cmap.b[index], count);
    775 
    776 	sc->sc_changed |= DATA_CMAP_CHANGED;
    777 
    778 	return (0);
    779 }
    780 
    781 
    782 static int
    783 set_cursor(sc, p)
    784 	struct sfb_softc *sc;
    785 	struct wsdisplay_cursor *p;
    786 {
    787 #define	cc (&sc->sc_cursor)
    788 	int v, index, count, icount, x, y;
    789 
    790 	v = p->which;
    791 	if (v & WSDISPLAY_CURSOR_DOCMAP) {
    792 		index = p->cmap.index;
    793 		count = p->cmap.count;
    794 		if (index >= 2 || (index + count) > 2)
    795 			return (EINVAL);
    796 		if (!uvm_useracc(p->cmap.red, count, B_READ) ||
    797 		    !uvm_useracc(p->cmap.green, count, B_READ) ||
    798 		    !uvm_useracc(p->cmap.blue, count, B_READ))
    799 			return (EFAULT);
    800 	}
    801 	if (v & WSDISPLAY_CURSOR_DOSHAPE) {
    802 		if (p->size.x > CURSOR_MAX_SIZE || p->size.y > CURSOR_MAX_SIZE)
    803 			return (EINVAL);
    804 		icount = ((p->size.x < 33) ? 4 : 8) * p->size.y;
    805 		if (!uvm_useracc(p->image, icount, B_READ) ||
    806 		    !uvm_useracc(p->mask, icount, B_READ))
    807 			return (EFAULT);
    808 	}
    809 	if (v & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOCUR)) {
    810 		if (v & WSDISPLAY_CURSOR_DOCUR)
    811 			cc->cc_hot = p->hot;
    812 		if (v & WSDISPLAY_CURSOR_DOPOS) {
    813 			struct fb_devconfig *dc = sc->sc_dc;
    814 
    815 			x = p->pos.x;
    816 			y = p->pos.y;
    817 			if (y < 0)
    818 				y = 0;
    819 			else if (y > dc->dc_ht)
    820 				y = dc->dc_ht;
    821 			if (x < 0)
    822 				x = 0;
    823 			else if (x > dc->dc_wid)
    824 				x = dc->dc_wid;
    825 			sc->sc_cursor.cc_pos.x = x;
    826 			sc->sc_cursor.cc_pos.y = y;
    827 		}
    828 		x = sc->sc_cursor.cc_pos.x - sc->sc_cursor.cc_hot.x;
    829 		y = sc->sc_cursor.cc_pos.y - sc->sc_cursor.cc_hot.y;
    830 		x += sc->sc_cursor.cc_magic.x;
    831 		y += sc->sc_cursor.cc_magic.y;
    832 		(*sc->sc_hwops.locate)(sc->sc_hw0, x, y);
    833 	}
    834 
    835 	sc->sc_changed = 0;
    836 	if (v & WSDISPLAY_CURSOR_DOCUR) {
    837 		sc->sc_curenb = p->enable;
    838 		sc->sc_changed |= DATA_ENB_CHANGED;
    839 	}
    840 	if (v & WSDISPLAY_CURSOR_DOCMAP) {
    841 		copyin(p->cmap.red, &cc->cc_color[index], count);
    842 		copyin(p->cmap.green, &cc->cc_color[index + 2], count);
    843 		copyin(p->cmap.blue, &cc->cc_color[index + 4], count);
    844 		sc->sc_changed |= DATA_CURCMAP_CHANGED;
    845 	}
    846 	if (v & WSDISPLAY_CURSOR_DOSHAPE) {
    847 		cc->cc_size = p->size;
    848 		memset(cc->cc_image, 0, sizeof cc->cc_image);
    849 		copyin(p->image, cc->cc_image, icount);
    850 		copyin(p->mask, cc->cc_image+CURSOR_MAX_SIZE, icount);
    851 		sc->sc_changed |= DATA_CURSHAPE_CHANGED;
    852 	}
    853 
    854 	return (0);
    855 #undef cc
    856 }
    857 
    858 static int
    859 get_cursor(sc, p)
    860 	struct sfb_softc *sc;
    861 	struct wsdisplay_cursor *p;
    862 {
    863 	return (ENOTTY); /* XXX */
    864 }
    865 
    866 int
    867 sfb_alloc_attr(id, fg, bg, flags, attrp)
    868 	void *id;
    869 	int fg, bg, flags;
    870 	long *attrp;
    871 {
    872 	if (flags & (WSATTR_HILIT | WSATTR_BLINK |
    873 		     WSATTR_UNDERLINE | WSATTR_WSCOLORS))
    874 		return (EINVAL);
    875 	if (flags & WSATTR_REVERSE)
    876 		*attrp = 1;
    877 	else
    878 		*attrp = 0;
    879 	return (0);
    880 }
    881 
    882 static void
    883 bt459visible(hw, on)
    884 	void *hw;
    885 	int on;
    886 {
    887 	SELECT(hw, BT459_IREG_CCR);
    888 	REG(hw, bt_reg) = (on) ? 0xc0 : 0x00;
    889 	tc_wmb();
    890 }
    891 
    892 static void
    893 sfbpvisible(hw, on)
    894 	void *hw;
    895 	int on;
    896 {
    897 }
    898 
    899 static void
    900 bt459locate(hw, x, y)
    901 	void *hw;
    902 	int x, y;
    903 {
    904 	int s;
    905 
    906 	s = spltty();
    907 	SELECT(hw, BT459_IREG_CURSOR_X_LOW);
    908 	REG(hw, bt_reg) = x;		tc_wmb();
    909 	REG(hw, bt_reg) = x >> 8;	tc_wmb();
    910 	REG(hw, bt_reg) = y;		tc_wmb();
    911 	REG(hw, bt_reg) = y >> 8;	tc_wmb();
    912 	splx(s);
    913 }
    914 
    915 static void
    916 sfbplocate(hw, x, y)
    917 	void *hw;
    918 	int x, y;
    919 {
    920 	*((u_int32_t *)hw + TGA_REG_CXYR) = ((y & 0xfff) << 12) | (x & 0xfff);
    921 	tc_wmb();
    922 }
    923 
    924 static void
    925 bt459color(hw, cp)
    926 	void *hw;
    927 	u_int8_t *cp;
    928 {
    929 	SELECT(hw, BT459_IREG_CCOLOR_2);
    930 	REG(hw, bt_reg) = cp[1]; tc_wmb();
    931 	REG(hw, bt_reg) = cp[3]; tc_wmb();
    932 	REG(hw, bt_reg) = cp[5]; tc_wmb();
    933 
    934 	REG(hw, bt_reg) = cp[0]; tc_wmb();
    935 	REG(hw, bt_reg) = cp[2]; tc_wmb();
    936 	REG(hw, bt_reg) = cp[4]; tc_wmb();
    937 }
    938 
    939 static void
    940 bt463color(hw, cp)
    941 	void *hw;
    942 	u_int8_t *cp;
    943 {
    944 }
    945 
    946 static void
    947 bt459shape(hw, size, image)
    948 	void *hw;
    949 	struct wsdisplay_curpos *size;
    950 	u_int64_t *image;
    951 {
    952 	u_int8_t *ip, *mp, img, msk;
    953 	u_int8_t u;
    954 	int bcnt;
    955 
    956 	ip = (u_int8_t *)image;
    957 	mp = (u_int8_t *)(image + CURSOR_MAX_SIZE);
    958 
    959 	bcnt = 0;
    960 	SELECT(hw, BT459_IREG_CRAM_BASE+0);
    961 	/* 64 pixel scan line is consisted with 16 byte cursor ram */
    962 	while (bcnt < size->y * 16) {
    963 		/* pad right half 32 pixel when smaller than 33 */
    964 		if ((bcnt & 0x8) && size->x < 33) {
    965 			REG(hw, bt_reg) = 0; tc_wmb();
    966 			REG(hw, bt_reg) = 0; tc_wmb();
    967 		}
    968 		else {
    969 			img = *ip++;
    970 			msk = *mp++;
    971 			img &= msk;	/* cookie off image */
    972 			u = (msk & 0x0f) << 4 | (img & 0x0f);
    973 			REG(hw, bt_reg) = shuffle[u];	tc_wmb();
    974 			u = (msk & 0xf0) | (img & 0xf0) >> 4;
    975 			REG(hw, bt_reg) = shuffle[u];	tc_wmb();
    976 		}
    977 		bcnt += 2;
    978 	}
    979 	/* pad unoccupied scan lines */
    980 	while (bcnt < CURSOR_MAX_SIZE * 16) {
    981 		REG(hw, bt_reg) = 0; tc_wmb();
    982 		REG(hw, bt_reg) = 0; tc_wmb();
    983 		bcnt += 2;
    984 	}
    985 }
    986 
    987 static void
    988 sfbpshape(hw, size, image)
    989 	void *hw;
    990 	struct wsdisplay_curpos *size;
    991 	u_int64_t *image;
    992 {
    993 }
    994 
    995 static void
    996 bt459setlut(hw, cm)
    997 	void *hw;
    998 	struct hwcmap256 *cm;
    999 {
   1000 	int index;
   1001 
   1002 	SELECT(hw, 0);
   1003 	for (index = 0; index < CMAP_SIZE; index++) {
   1004 		REG(hw, bt_cmap) = cm->r[index];	tc_wmb();
   1005 		REG(hw, bt_cmap) = cm->g[index];	tc_wmb();
   1006 		REG(hw, bt_cmap) = cm->b[index];	tc_wmb();
   1007 	}
   1008 }
   1009 
   1010 static void
   1011 noplut(hw, cm)
   1012 	void *hw;
   1013 	struct hwcmap256 *cm;
   1014 {
   1015 }
   1016