Home | History | Annotate | Line # | Download | only in dev
      1 /*	$NetBSD: grfabs_et.c,v 1.37 2023/01/06 10:28:28 tsutsui Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1996 Leo Weppelman.
      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  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 /*
     29  * Most of the lower-level et4000 stuff was derived from:
     30  *	.../amiga/dev/grf_et.c
     31  *
     32  * Which was copyrighted by:
     33  *	Copyright (c) 1996 Tobias Abt
     34  *	Copyright (c) 1995 Ezra Story
     35  *	Copyright (c) 1995 Kari Mettinen
     36  *	Copyright (c) 1994 Markus Wild
     37  *	Copyright (c) 1994 Lutz Vieweg
     38  *
     39  * Thanks guys!
     40  *
     41  */
     42 
     43 #include <sys/cdefs.h>
     44 __KERNEL_RCSID(0, "$NetBSD: grfabs_et.c,v 1.37 2023/01/06 10:28:28 tsutsui Exp $");
     45 
     46 #include <sys/param.h>
     47 #include <sys/queue.h>
     48 #include <sys/malloc.h>
     49 #include <sys/device.h>
     50 #include <sys/systm.h>
     51 
     52 #include <uvm/uvm_extern.h>
     53 
     54 /*
     55  * For PCI probing...
     56  */
     57 #include <dev/pci/pcireg.h>
     58 #include <dev/pci/pcivar.h>
     59 #include <dev/pci/pcidevs.h>
     60 
     61 #include <machine/iomap.h>
     62 #include <machine/video.h>
     63 #include <machine/mfp.h>
     64 #include <machine/cpu.h>
     65 #include <atari/atari/device.h>
     66 #include <atari/dev/grfioctl.h>
     67 #include <atari/dev/grfabs_reg.h>
     68 #include <atari/dev/grfabs_et.h>
     69 #include <atari/dev/grf_etreg.h>
     70 
     71 #define	SAVEBUF_SIZE	(32*1024 + sizeof(save_area_t))
     72 
     73 /*
     74  * Allow a 16Kb io-region and a 4MB frame buffer to be mapped. This
     75  * is more or less required by the XFree server.
     76  */
     77 #define	REG_MAPPABLE	(16 * 1024)
     78 #define	FRAME_MAPPABLE	(4 * 1024 * 1024)
     79 #define VGA_MAPPABLE	(128 * 1024)
     80 #define VGA_BASE	0xa0000
     81 
     82 /*
     83  * Linear memory base, near the end of the pci area
     84  */
     85 #define PCI_LINMEMBASE  0x0e000000
     86 
     87 /*
     88  * Function decls
     89  */
     90 static void       init_view(view_t *, bmap_t *, dmode_t *, box_t *);
     91 static colormap_t *alloc_colormap(dmode_t *);
     92 static void	  et_display_view(view_t *);
     93 static view_t	  *et_alloc_view(dmode_t *, dimen_t *, u_char);
     94 static void	  et_free_view(view_t *);
     95 static void	  et_loadmode(struct grfvideo_mode *, et_sv_reg_t *);
     96 static void	  et_remove_view(view_t *);
     97 static void	  et_save_view(view_t *);
     98 static int	  et_use_colormap(view_t *, colormap_t *);
     99 
    100 /*
    101  * Our function switch table
    102  */
    103 struct grfabs_sw et_vid_sw = {
    104 	et_display_view,
    105 	et_alloc_view,
    106 	et_free_view,
    107 	et_remove_view,
    108 	et_save_view,
    109 	et_use_colormap
    110 };
    111 
    112 static struct grfvideo_mode hw_modes[] = {
    113     {
    114 	0, "", 22450000,		/* num, descr, pix-clock	*/
    115 	640, 400, 4,			/* width, height, depth		*/
    116 	632/8, 672/8, 688/8, 808/8, 768/8,/* HBS, HBE, HSS, HSE, HT	*/
    117 	399, 450, 408, 413, 449		/* VBS, VBE, VSS, VSE, VT	*/
    118     },
    119     {
    120 	0, "", 25175000,		/* num, descr, pix-clock	*/
    121 	640, 480, 4,			/* width, height, depth		*/
    122 	632/8, 672/8, 688/8, 752/8, 752/8,/* HBS, HBE, HSS, HSE, HT	*/
    123 	481, 522, 490, 498, 522		/* VBS, VBE, VSS, VSE, VT	*/
    124     }
    125 };
    126 
    127 static dmode_t vid_modes[] = {
    128     { { NULL, NULL },
    129 	"640x400", { 640, 400 }, 1, (void*)&hw_modes[0], &et_vid_sw },
    130     { { NULL, NULL },
    131 	"640x480", { 640, 480 }, 1, (void*)&hw_modes[1], &et_vid_sw },
    132     { { NULL, NULL }, NULL,  }
    133 };
    134 
    135 #define	ET_NUMCLOCKS	32
    136 
    137 static u_int et_clockfreqs[ET_NUMCLOCKS] = {
    138 	 6293750,  7080500,  7875000,  8125000,
    139 	 9000000,  9375000, 10000000, 11225000,
    140 	12587500, 14161000, 15750000, 16250000,
    141 	18000000, 18750000, 20000000, 22450000,
    142 	25175000, 28322000, 31500000, 32500000,
    143 	36000000, 37500000, 40000000, 44900000,
    144 	50350000, 56644000, 63000000, 65000000,
    145 	72000000, 75000000, 80000000, 89800000
    146 };
    147 
    148 static bmap_t	con_bm; /* XXX */
    149 
    150 struct grfabs_et_priv {
    151 	pcitag_t		pci_tag;
    152 	void			*regkva;
    153 	void			*memkva;
    154 	u_int			linbase;
    155 	int			regsz;
    156 	int			memsz;
    157 	int			board_type;
    158 } et_priv;
    159 
    160 /*
    161  * Board types:
    162  */
    163 #define	BT_ET4000		1
    164 #define	BT_ET6000		2
    165 
    166 /*
    167  * XXX: called from ite console init routine.
    168  * Initialize list of possible video modes.
    169  */
    170 void
    171 et_probe_video(MODES *modelp)
    172 {
    173 	dmode_t	*dm;
    174 	int	i;
    175 
    176 	for (i = 0; (dm = &vid_modes[i])->name != NULL; i++) {
    177 		LIST_INSERT_HEAD(modelp, dm, link);
    178 	}
    179 }
    180 
    181 static void
    182 et_display_view(view_t *v)
    183 {
    184 	dmode_t		*dm = v->mode;
    185 	bmap_t		*bm = v->bitmap;
    186 	int		sv_size;
    187 	u_short		*src, *dst;
    188 	save_area_t	*sa;
    189 
    190 	if (dm->current_view && (dm->current_view != v)) {
    191 		/*
    192 		 * Mark current view for this mode as no longer displayed
    193 		 */
    194 		dm->current_view->flags &= ~VF_DISPLAY;
    195 	}
    196 	dm->current_view = v;
    197 	v->flags |= VF_DISPLAY;
    198 
    199 	if ((sa = (save_area_t*)v->save_area) == NULL)
    200 		return; /* XXX: Can't happen.... */
    201 
    202 	/*
    203 	 * Restore register settings and turn the plane pointer
    204 	 * to the card-memory
    205 	 */
    206 	et_hwrest(&sa->sv_regs);
    207 	bm->plane = et_priv.memkva;
    208 
    209 	et_use_colormap(v, v->colormap);
    210 
    211 	/*
    212 	 * Copy the backing store to card-memory
    213 	 */
    214 	sv_size = sa->fb_size;
    215 	src     = sa->sv_fb;
    216 	dst     = (u_short *)bm->plane;
    217 	while (sv_size--)
    218 		*dst++ = *src++;
    219 }
    220 
    221 void
    222 et_remove_view(view_t *v)
    223 {
    224 	dmode_t *mode = v->mode;
    225 
    226 	if (mode->current_view == v) {
    227 #if 0
    228 		if (v->flags & VF_DISPLAY)
    229 			panic("Cannot shutdown display"); /* XXX */
    230 #endif
    231 		mode->current_view = NULL;
    232 	}
    233 	v->flags &= ~VF_DISPLAY;
    234 }
    235 
    236 void
    237 et_save_view(view_t *v)
    238 {
    239 	bmap_t		*bm = v->bitmap;
    240 	u_char		font_height;
    241 	int		sv_size;
    242 	u_short		*src, *dst;
    243 	save_area_t	*sa;
    244 	volatile u_char *ba;
    245 
    246 	if (!atari_realconfig)
    247 		return;
    248 
    249 	ba = et_priv.regkva;
    250 
    251 	if (RGfx(ba, GCT_ID_MISC) & 1) {
    252 #if 0 /* XXX: Can't use printf here.... */
    253 		printf("et_save_view: Don't know how to save"
    254 			" a graphics mode\n");
    255 #endif
    256 		return;
    257 	}
    258 	if (v->save_area == NULL)
    259 		v->save_area = malloc(SAVEBUF_SIZE, M_DEVBUF, M_NOWAIT);
    260 
    261 	/*
    262 	 * Calculate the size of the copy
    263 	 */
    264 	font_height = RCrt(ba, CRT_ID_MAX_ROW_ADDRESS) & 0x1f;
    265 	sv_size = bm->bytes_per_row * (bm->rows / (font_height + 1));
    266 	sv_size = uimin(SAVEBUF_SIZE, sv_size);
    267 
    268 	/*
    269 	 * Save all we need to know....
    270 	 */
    271 	sa  = (save_area_t *)v->save_area;
    272 	et_hwsave(&sa->sv_regs);
    273 	sa->fb_size = sv_size;
    274 	src = (u_short *)bm->plane;
    275 	dst = sa->sv_fb;
    276 	while (sv_size--)
    277 		*dst++ = *src++;
    278 	bm->plane = (u_char *)sa->sv_fb;
    279 }
    280 
    281 void
    282 et_free_view(view_t *v)
    283 {
    284 
    285 	if (v) {
    286 		et_remove_view(v);
    287 		if (v->colormap != &gra_con_cmap)
    288 			free(v->colormap, M_DEVBUF);
    289 		if (v->save_area != NULL)
    290 			free(v->save_area, M_DEVBUF);
    291 		if (v != &gra_con_view) {
    292 			free(v->bitmap, M_DEVBUF);
    293 			free(v, M_DEVBUF);
    294 		}
    295 	}
    296 }
    297 
    298 static int
    299 et_use_colormap(view_t *v, colormap_t *cm)
    300 {
    301 	return (0); /* XXX: Nothing here for now... */
    302 }
    303 
    304 static view_t *
    305 et_alloc_view(dmode_t *mode, dimen_t *dim, u_char depth)
    306 {
    307 	view_t		*v;
    308 	bmap_t		*bm;
    309 	box_t		box;
    310 	save_area_t	*sa;
    311 
    312 	if (!atari_realconfig) {
    313 		v  = &gra_con_view;
    314 		bm = &con_bm;
    315 	} else {
    316 		v  = malloc(sizeof(*v), M_DEVBUF, M_WAITOK);
    317 		bm = malloc(sizeof(*bm), M_DEVBUF, M_WAITOK);
    318 	}
    319 	v->bitmap = bm;
    320 
    321 	/*
    322 	 * Initialize the bitmap
    323 	 */
    324 	bm->plane         = et_priv.memkva;
    325 	bm->vga_address   = (void *)kvtop(et_priv.memkva);
    326 	bm->vga_base      = VGA_BASE;
    327 	bm->hw_address    = (void *)(PCI_MEM_PHYS | et_priv.linbase);
    328 	bm->lin_base      = et_priv.linbase;
    329 	bm->regs          = et_priv.regkva;
    330 	bm->hw_regs       = (void *)kvtop(et_priv.regkva);
    331 	bm->reg_size      = REG_MAPPABLE;
    332 	bm->phys_mappable = FRAME_MAPPABLE;
    333 	bm->vga_mappable  = VGA_MAPPABLE;
    334 
    335 	bm->bytes_per_row = (mode->size.width * depth) / NBBY;
    336 	bm->rows          = mode->size.height;
    337 	bm->depth         = depth;
    338 
    339 	/*
    340 	 * Allocate a save_area.
    341 	 * Note: If atari_realconfig is false, no save area is (can be)
    342 	 * allocated. This means that the plane is the video memory,
    343 	 * which is what's wanted in this case.
    344 	 */
    345 	if (atari_realconfig) {
    346 		v->save_area = malloc(SAVEBUF_SIZE, M_DEVBUF, M_WAITOK);
    347 		sa           = (save_area_t*)v->save_area;
    348 		sa->fb_size  = 0;
    349 		bm->plane    = (u_char *)sa->sv_fb;
    350 		et_loadmode(mode->data, &sa->sv_regs);
    351 	} else
    352 		v->save_area = NULL;
    353 
    354 	v->colormap = alloc_colormap(mode);
    355 	if (v->colormap) {
    356 		INIT_BOX(&box,0,0,mode->size.width,mode->size.height);
    357 		init_view(v, bm, mode, &box);
    358 		return (v);
    359 	}
    360 	if (v != &gra_con_view) {
    361 		free(v, M_DEVBUF);
    362 		free(bm, M_DEVBUF);
    363 	}
    364 	return (NULL);
    365 }
    366 
    367 static void
    368 init_view(view_t *v, bmap_t *bm, dmode_t *mode, box_t *dbox)
    369 {
    370 	v->bitmap    = bm;
    371 	v->mode      = mode;
    372 	v->flags     = 0;
    373 	memcpy(&v->display, dbox, sizeof(box_t));
    374 }
    375 
    376 /* XXX: No more than a stub... */
    377 static colormap_t *
    378 alloc_colormap(dmode_t *dm)
    379 {
    380 	colormap_t	*cm;
    381 	int		i;
    382 
    383 	cm = &gra_con_cmap;
    384 	cm->entry = gra_con_colors;
    385 
    386 	cm->first = 0;
    387 	cm->size  = 2;
    388 
    389 	for (i = 0; i < 2; i++)
    390 		cm->entry[i] = gra_def_color16[i % 16];
    391 	return (cm);
    392 }
    393 
    394 /*
    395  * Go look for a VGA card on the PCI-bus. This search is a
    396  * stripped down version of the PCI-probe. It only looks on
    397  * bus0 for et4000/et6000 cards. The first card found is used.
    398  */
    399 int
    400 et_probe_card(void)
    401 {
    402 	pci_chipset_tag_t	pc = NULL; /* XXX */
    403 	pcitag_t		tag;
    404 	int			device, found, id, maxndevs;
    405 
    406 	found    = 0;
    407 	tag      = 0;
    408 	id       = 0;
    409 	maxndevs = pci_bus_maxdevs(pc, 0);
    410 
    411 	for (device = 0; !found && (device < maxndevs); device++) {
    412 
    413 		tag = pci_make_tag(pc, 0, device, 0);
    414 		id  = pci_conf_read(pc, tag, PCI_ID_REG);
    415 		if (id == 0 || id == 0xffffffff)
    416 			continue;
    417 		switch (PCI_PRODUCT(id)) {
    418 			case PCI_PRODUCT_TSENG_ET6000:
    419 			case PCI_PRODUCT_TSENG_ET4000_W32P_A:
    420 			case PCI_PRODUCT_TSENG_ET4000_W32P_B:
    421 			case PCI_PRODUCT_TSENG_ET4000_W32P_C:
    422 			case PCI_PRODUCT_TSENG_ET4000_W32P_D:
    423 				found = 1;
    424 				break;
    425 			default:
    426 				break;
    427 		}
    428 	}
    429 	if (!found)
    430 		return (0);
    431 
    432 	if (PCI_PRODUCT(id) ==  PCI_PRODUCT_TSENG_ET6000)
    433 		et_priv.board_type = BT_ET6000;
    434 	else {
    435 #ifdef ET4000_HAS_2MB_MEM
    436 		volatile u_char *ba;
    437 #endif
    438 
    439 		et_priv.board_type = BT_ET4000;
    440 
    441 #ifdef ET4000_HAS_2MB_MEM
    442 		/* set KEY to access the tseng private registers */
    443 		ba = (volatile void *)pci_io_addr;
    444 		vgaw(ba, GREG_HERCULESCOMPAT, 0x03);
    445 		vgaw(ba, GREG_DISPMODECONTROL, 0xa0);
    446 
    447 		/* enable memory interleave */
    448 		WCrt(ba, CRT_ID_RASCAS_CONFIG, 0xa0);
    449 		WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x89);
    450 #endif
    451 	}
    452 
    453 	et_priv.pci_tag = tag;
    454 
    455 	/*
    456 	 * The things below are setup in atari_init.c
    457 	 */
    458 	et_priv.regkva  = (void *)pci_io_addr;
    459 	et_priv.memkva  = (void *)pci_mem_addr;
    460 	et_priv.linbase = PCI_LINMEMBASE; /* XXX pci_conf_read??? */
    461 	et_priv.memsz   = PCI_VGA_SIZE;
    462 	et_priv.regsz   = PCI_IO_SIZE;
    463 
    464 	if (!atari_realconfig) {
    465 		et_loadmode(&hw_modes[0], NULL);
    466 		return (1);
    467 	}
    468 
    469 	return (1);
    470 }
    471 
    472 static void
    473 et_loadmode(struct grfvideo_mode *mode, et_sv_reg_t *regs)
    474 {
    475 	unsigned short	HDE, VDE;
    476 	int		lace, dblscan;
    477 	int		uplim, lowlim;
    478 	int		i;
    479 	unsigned char	clock, tmp;
    480 	volatile u_char	*ba;
    481 	et_sv_reg_t	loc_regs;
    482 
    483 	if (regs == NULL)
    484 		regs = &loc_regs;
    485 
    486 	ba  = et_priv.regkva;
    487 	HDE = mode->disp_width / 8 - 1;
    488 	VDE = mode->disp_height - 1;
    489 
    490 	/* figure out whether lace or dblscan is needed */
    491 
    492 	uplim   = mode->disp_height + (mode->disp_height / 4);
    493 	lowlim  = mode->disp_height - (mode->disp_height / 4);
    494 	lace    = (((mode->vtotal * 2) > lowlim)
    495 		   && ((mode->vtotal * 2) < uplim)) ? 1 : 0;
    496 	dblscan = (((mode->vtotal / 2) > lowlim)
    497 		   && ((mode->vtotal / 2) < uplim)) ? 1 : 0;
    498 
    499 	/* adjustments */
    500 	if (lace)
    501 		VDE /= 2;
    502 
    503 	regs->misc_output = 0x23; /* Page 0, Color mode */
    504 	regs->seg_sel     = 0x00;
    505 	regs->state_ctl   = 0x00;
    506 
    507 	regs->seq[SEQ_ID_RESET]           = 0x03; /* reset off		*/
    508 	regs->seq[SEQ_ID_CLOCKING_MODE]   = 0x21; /* Turn off screen	*/
    509 	regs->seq[SEQ_ID_MAP_MASK]        = 0xff; /* CPU writes all planes*/
    510 	regs->seq[SEQ_ID_CHAR_MAP_SELECT] = 0x00; /* Char. generator 0	*/
    511 	regs->seq[SEQ_ID_MEMORY_MODE]     = 0x0e; /* Seq. Memory mode	*/
    512 
    513 	/*
    514 	 * Set the clock...
    515 	 */
    516 	for (clock = ET_NUMCLOCKS-1; clock > 0; clock--) {
    517 		if (et_clockfreqs[clock] <= mode->pixel_clock)
    518 			break;
    519 	}
    520 	regs->misc_output |= (clock & 3) << 2;
    521 	regs->aux_mode     = 0xb4 | ((clock & 8) << 3);
    522 	regs->compat_6845  = (clock & 4) ? 0x0a : 0x08;
    523 
    524 	/*
    525 	 * The display parameters...
    526 	 */
    527 	regs->crt[CRT_ID_HOR_TOTAL]        =  mode->htotal;
    528 	regs->crt[CRT_ID_HOR_DISP_ENA_END] = ((HDE >= mode->hblank_start)
    529 						? mode->hblank_stop - 1
    530 						: HDE);
    531 	regs->crt[CRT_ID_START_HOR_BLANK]  = mode->hblank_start;
    532 	regs->crt[CRT_ID_END_HOR_BLANK]    = (mode->hblank_stop & 0x1f) | 0x80;
    533 	regs->crt[CRT_ID_START_HOR_RETR]   = mode->hsync_start;
    534 	regs->crt[CRT_ID_END_HOR_RETR]     = (mode->hsync_stop & 0x1f)
    535 						| ((mode->hblank_stop & 0x20)
    536 							? 0x80 : 0x00);
    537 	regs->crt[CRT_ID_VER_TOTAL]        = mode->vtotal;
    538 	regs->crt[CRT_ID_START_VER_RETR]   = mode->vsync_start;
    539 	regs->crt[CRT_ID_END_VER_RETR]     = (mode->vsync_stop & 0x0f) | 0x30;
    540 	regs->crt[CRT_ID_VER_DISP_ENA_END] = VDE;
    541 	regs->crt[CRT_ID_START_VER_BLANK]  = mode->vblank_start;
    542 	regs->crt[CRT_ID_END_VER_BLANK]    = mode->vblank_stop;
    543 	regs->crt[CRT_ID_MODE_CONTROL]     = 0xab;
    544 	regs->crt[CRT_ID_START_ADDR_HIGH]  = 0x00;
    545 	regs->crt[CRT_ID_START_ADDR_LOW]   = 0x00;
    546 	regs->crt[CRT_ID_LINE_COMPARE]     = 0xff;
    547 	regs->crt[CRT_ID_UNDERLINE_LOC]    = 0x00;
    548 	regs->crt[CRT_ID_PRESET_ROW_SCAN]  = 0x00;
    549 	regs->crt[CRT_ID_OFFSET]           = mode->disp_width/16;
    550 	regs->crt[CRT_ID_MAX_ROW_ADDRESS]  =
    551 		0x40 |
    552 		(dblscan ? 0x80 : 0x00) |
    553 		((mode->vblank_start & 0x200) ? 0x20 : 0x00);
    554 	regs->crt[CRT_ID_OVERFLOW] =
    555 		0x10 |
    556 		((mode->vtotal       & 0x100) ? 0x01 : 0x00) |
    557 		((VDE                & 0x100) ? 0x02 : 0x00) |
    558 		((mode->vsync_start  & 0x100) ? 0x04 : 0x00) |
    559 		((mode->vblank_start & 0x100) ? 0x08 : 0x00) |
    560 		((mode->vtotal       & 0x200) ? 0x20 : 0x00) |
    561 		((VDE                & 0x200) ? 0x40 : 0x00) |
    562 		((mode->vsync_start  & 0x200) ? 0x80 : 0x00);
    563 	regs->overfl_high =
    564 		0x10 |
    565 		((mode->vblank_start & 0x400) ? 0x01 : 0x00) |
    566 		((mode->vtotal       & 0x400) ? 0x02 : 0x00) |
    567 		((VDE                & 0x400) ? 0x04 : 0x00) |
    568 		((mode->vsync_start  & 0x400) ? 0x08 : 0x00) |
    569 		(lace ? 0x80 : 0x00);
    570 	regs->hor_overfl =
    571 		((mode->htotal       & 0x100) ? 0x01 : 0x00) |
    572 		((mode->hblank_start & 0x100) ? 0x04 : 0x00) |
    573 		((mode->hsync_start  & 0x100) ? 0x10 : 0x00);
    574 
    575 	regs->grf[GCT_ID_SET_RESET]        = 0x00;
    576 	regs->grf[GCT_ID_ENABLE_SET_RESET] = 0x00;
    577 	regs->grf[GCT_ID_COLOR_COMPARE]    = 0x00;
    578 	regs->grf[GCT_ID_DATA_ROTATE]      = 0x00;
    579 	regs->grf[GCT_ID_READ_MAP_SELECT]  = 0x00;
    580 	regs->grf[GCT_ID_GRAPHICS_MODE]    = mode->depth == 1 ? 0x00: 0x40;
    581 	regs->grf[GCT_ID_MISC]             = 0x01;
    582 	regs->grf[GCT_ID_COLOR_XCARE]      = 0x0f;
    583 	regs->grf[GCT_ID_BITMASK]          = 0xff;
    584 
    585 	for (i = 0; i < 0x10; i++)
    586 		regs->attr[i] = i;
    587 	regs->attr[ACT_ID_ATTR_MODE_CNTL]  = 0x01;
    588 	regs->attr[ACT_ID_OVERSCAN_COLOR]  = 0x00;
    589 	regs->attr[ACT_ID_COLOR_PLANE_ENA] = 0x0f;
    590 	regs->attr[ACT_ID_HOR_PEL_PANNING] = 0x00;
    591 	regs->attr[ACT_ID_COLOR_SELECT]    = 0x00;
    592 	regs->attr[ACT_ID_MISCELLANEOUS]   = 0x00;
    593 
    594 	/*
    595 	 * XXX: This works for depth == 4. I need some better docs
    596 	 * to fix the other modes....
    597 	 */
    598 	/*
    599 	 * What we need would be probe functions for RAMDAC/clock chip
    600 	 */
    601 	vgar(ba, VDAC_ADDRESS);		/* clear old state */
    602 	vgar(ba, VDAC_MASK);
    603 	vgar(ba, VDAC_MASK);
    604 	vgar(ba, VDAC_MASK);
    605 	vgar(ba, VDAC_MASK);
    606 
    607 	vgaw(ba, VDAC_MASK, 0);		/* set to palette */
    608 	vgar(ba, VDAC_ADDRESS);		/* clear state */
    609 
    610 	vgaw(ba, VDAC_MASK, 0xff);
    611 	/*
    612 	 * End of depth stuff
    613 	 */
    614 
    615 	/*
    616 	 * Compute Hsync & Vsync polarity
    617 	 * Note: This seems to be some kind of a black art :-(
    618 	 */
    619 	tmp = regs->misc_output & 0x3f;
    620 #if 1 /* This is according to my BW monitor & Xfree... */
    621 	if (VDE < 400)
    622 		tmp |= 0x40;	/* -hsync +vsync */
    623 	else if (VDE < 480)
    624 		tmp |= 0xc0;	/* -hsync -vsync */
    625 #else /* This is according to my color monitor.... */
    626 	if (VDE < 400)
    627 		tmp |= 0x00;	/* +hsync +vsync */
    628 	else if (VDE < 480)
    629 		tmp |= 0x80;	/* +hsync -vsync */
    630 #endif
    631 	/* I'm unable to try the rest.... */
    632 	regs->misc_output = tmp;
    633 
    634 	if (regs == &loc_regs)
    635 		et_hwrest(regs);
    636 }
    637 
    638 void
    639 et_hwsave(et_sv_reg_t *et_regs)
    640 {
    641 	volatile u_char *ba;
    642 	int		i, s;
    643 
    644 	ba = et_priv.regkva;
    645 
    646 	s = splhigh();
    647 
    648 	/*
    649 	 * General VGA registers
    650 	 */
    651 	et_regs->misc_output = vgar(ba, GREG_MISC_OUTPUT_R);
    652 	for (i = 0; i < 25; i++)
    653 		et_regs->crt[i]  = RCrt(ba, i);
    654 	for (i = 0; i < 21; i++)
    655 		et_regs->attr[i] = RAttr(ba, i | 0x20);
    656 	for (i = 0; i < 9; i++)
    657 		et_regs->grf[i]  = RGfx(ba, i);
    658 	for (i = 0; i < 5; i++)
    659 		et_regs->seq[i]  = RSeq(ba, i);
    660 
    661 	/*
    662 	 * ET4000 extensions
    663 	 */
    664 	et_regs->ext_start   = RCrt(ba, CTR_ID_EXT_START);
    665 	et_regs->compat_6845 = RCrt(ba, CRT_ID_6845_COMPAT);
    666 	et_regs->overfl_high = RCrt(ba, CRT_ID_OVERFLOW_HIGH);
    667 	et_regs->hor_overfl  = RCrt(ba, CRT_ID_HOR_OVERFLOW);
    668 	et_regs->state_ctl   = RSeq(ba, SEQ_ID_STATE_CONTROL);
    669 	et_regs->aux_mode    = RSeq(ba, SEQ_ID_AUXILIARY_MODE);
    670 	et_regs->seg_sel     = vgar(ba, GREG_SEGMENTSELECT);
    671 
    672 	splx(s);
    673 }
    674 
    675 void
    676 et_hwrest(et_sv_reg_t *et_regs)
    677 {
    678 	volatile u_char *ba;
    679 	int		i, s;
    680 
    681 	ba = et_priv.regkva;
    682 
    683 	s = splhigh();
    684 
    685 	vgaw(ba, GREG_SEGMENTSELECT, 0);
    686 	vgaw(ba, GREG_MISC_OUTPUT_W, et_regs->misc_output);
    687 
    688 	/*
    689 	 * General VGA registers
    690 	 */
    691 	WSeq(ba, SEQ_ID_RESET, 0x01);
    692 	for (i = 1; i < 5; i++)
    693 		WSeq(ba, i, et_regs->seq[i]);
    694 	WSeq(ba, SEQ_ID_RESET, 0x03);
    695 
    696 	/*
    697 	 * Make sure we're allowed to write all crt-registers
    698 	 */
    699 	WCrt(ba, CRT_ID_END_VER_RETR,
    700 		et_regs->crt[CRT_ID_END_VER_RETR] & 0x7f);
    701 	for (i = 0; i < 25; i++)
    702 		WCrt(ba, i, et_regs->crt[i]);
    703 	for (i = 0; i < 9; i++)
    704 		WGfx(ba, i, et_regs->grf[i]);
    705 	for (i = 0; i < 21; i++)
    706 		WAttr(ba, i | 0x20, et_regs->attr[i]);
    707 
    708 	/*
    709 	 * ET4000 extensions
    710 	 */
    711 	WSeq(ba, SEQ_ID_STATE_CONTROL, et_regs->state_ctl);
    712 	WSeq(ba, SEQ_ID_AUXILIARY_MODE, et_regs->aux_mode);
    713 	WCrt(ba, CTR_ID_EXT_START, et_regs->ext_start);
    714 	WCrt(ba, CRT_ID_6845_COMPAT, et_regs->compat_6845);
    715 	WCrt(ba, CRT_ID_OVERFLOW_HIGH, et_regs->overfl_high);
    716 	WCrt(ba, CRT_ID_HOR_OVERFLOW, et_regs->hor_overfl);
    717 	vgaw(ba, GREG_SEGMENTSELECT, et_regs->seg_sel);
    718 
    719 	i = et_regs->seq[SEQ_ID_CLOCKING_MODE] & ~0x20;
    720 	WSeq(ba, SEQ_ID_CLOCKING_MODE, i);
    721 
    722 	splx(s);
    723 }
    724