Home | History | Annotate | Line # | Download | only in dev
grfabs_et.c revision 1.12
      1 /*	$NetBSD: grfabs_et.c,v 1.12 1999/02/19 21:03:00 leo 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  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *      This product includes software developed by Leo Weppelman.
     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 /*
     34  * Most of the lower-level et4000 stuff was derived from:
     35  *	.../amiga/dev/grf_et.c
     36  *
     37  * Which was copyrighted by:
     38  *	Copyright (c) 1996 Tobias Abt
     39  *	Copyright (c) 1995 Ezra Story
     40  *	Copyright (c) 1995 Kari Mettinen
     41  *	Copyright (c) 1994 Markus Wild
     42  *	Copyright (c) 1994 Lutz Vieweg
     43  *
     44  * Thanks guys!
     45  *
     46  */
     47 #include <sys/param.h>
     48 #include <sys/queue.h>
     49 #include <sys/malloc.h>
     50 #include <sys/device.h>
     51 #include <sys/systm.h>
     52 
     53 #include <vm/vm.h>
     54 #include <vm/vm_kern.h>
     55 
     56 /*
     57  * For PCI probing...
     58  */
     59 #include <dev/pci/pcireg.h>
     60 #include <dev/pci/pcivar.h>
     61 #include <dev/pci/pcidevs.h>
     62 
     63 #include <machine/iomap.h>
     64 #include <machine/video.h>
     65 #include <machine/mfp.h>
     66 #include <machine/cpu.h>
     67 #include <atari/atari/device.h>
     68 #include <atari/dev/grfioctl.h>
     69 #include <atari/dev/grfabs_reg.h>
     70 #include <atari/dev/grfabs_et.h>
     71 #include <atari/dev/grf_etreg.h>
     72 
     73 #define	SAVEBUF_SIZE	(32*1024 + sizeof(save_area_t))
     74 
     75 /*
     76  * Allow a 16Kb io-region and a 4MB frame buffer to be mapped. This
     77  * is more or less required by the XFree server.
     78  */
     79 #define	REG_MAPPABLE	(16 * 1024)
     80 #define	FRAME_MAPPABLE	(4 * 1024 * 1024)
     81 #define VGA_MAPPABLE	(128 * 1024)
     82 #define VGA_BASE	0xa0000
     83 
     84 /*
     85  * Where we map the PCI registers in the io-space (et6000)
     86  * XXX: 0x400 would probably work too...
     87  */
     88 #define PCI_IOBASE	0x800
     89 /*
     90  * Linear memory base, near the end of the pci area
     91  */
     92 #define PCI_LINMEMBASE  0x0e000000
     93 
     94 /*
     95  * Function decls
     96  */
     97 static void       init_view __P((view_t *, bmap_t *, dmode_t *, box_t *));
     98 static colormap_t *alloc_colormap __P((dmode_t *));
     99 static void	  et6000_init __P((void));
    100 static void	  et_display_view __P((view_t *));
    101 static view_t	  *et_alloc_view __P((dmode_t *, dimen_t *, u_char));
    102 static void	  et_boardinit __P((void));
    103 static void	  et_free_view __P((view_t *));
    104 static void	  et_loadmode __P((struct grfvideo_mode *, et_sv_reg_t *));
    105 static void	  et_remove_view __P((view_t *));
    106 static void	  et_save_view __P((view_t *));
    107 static int	  et_use_colormap __P((view_t *, colormap_t *));
    108 
    109 /*
    110  * Our function switch table
    111  */
    112 struct grfabs_sw et_vid_sw = {
    113 	et_display_view,
    114 	et_alloc_view,
    115 	et_free_view,
    116 	et_remove_view,
    117 	et_save_view,
    118 	et_use_colormap
    119 };
    120 
    121 static struct grfvideo_mode hw_modes[] = {
    122     {
    123 	0, "", 25175000,		/* num, descr, pix-clock	*/
    124 	640, 400, 4,			/* width, height, depth		*/
    125 	632/8, 672/8, 688/8, 808/8, 768/8,/* HBS, HBE, HSS, HSE, HT	*/
    126 	399, 450, 408, 413, 449		/* VBS, VBE, VSS, VSE, VT	*/
    127     },
    128     {
    129 	0, "", 25175000,		/* num, descr, pix-clock	*/
    130 	640, 480, 4,			/* width, height, depth		*/
    131 	632/8, 672/8, 688/8, 752/8, 752/8,/* HBS, HBE, HSS, HSE, HT	*/
    132 	481, 522, 490, 498, 522		/* VBS, VBE, VSS, VSE, VT	*/
    133     }
    134 };
    135 
    136 static dmode_t vid_modes[] = {
    137     { { NULL, NULL },
    138 	"640x400", { 640, 400 }, 1, (void*)&hw_modes[0], &et_vid_sw },
    139     { { NULL, NULL },
    140 	"640x480", { 640, 480 }, 1, (void*)&hw_modes[1], &et_vid_sw },
    141     { { NULL, NULL }, NULL,  }
    142 };
    143 
    144 #define	ET_NUMCLOCKS	32
    145 
    146 static u_int et_clockfreqs[ET_NUMCLOCKS] = {
    147 	 6293750,  7080500,  7875000,  8125000,
    148 	 9000000,  9375000, 10000000, 11225000,
    149 	12587500, 14161000, 15750000, 16250000,
    150 	18000000, 18750000, 20000000, 22450000,
    151 	25175000, 28322000, 31500000, 32500000,
    152 	36000000, 37500000, 40000000, 44900000,
    153 	50350000, 56644000, 63000000, 65000000,
    154 	72000000, 75000000, 80000000, 89800000
    155 };
    156 
    157 static bmap_t	con_bm; /* XXX */
    158 
    159 struct grfabs_et_priv {
    160 	pcitag_t		pci_tag;
    161 	volatile caddr_t	regkva;
    162 	volatile caddr_t	memkva;
    163 	u_int			linbase;
    164 	int			regsz;
    165 	int			memsz;
    166 	int			board_type;
    167 } et_priv;
    168 
    169 /*
    170  * Board types:
    171  */
    172 #define	BT_ET4000		1
    173 #define	BT_ET6000		2
    174 
    175 /*
    176  * XXX: called from ite console init routine.
    177  * Initialize list of posible video modes.
    178  */
    179 void
    180 et_probe_video(modelp)
    181 MODES	*modelp;
    182 {
    183 	dmode_t	*dm;
    184 	int	i;
    185 
    186 	for (i = 0; (dm = &vid_modes[i])->name != NULL; i++) {
    187 		LIST_INSERT_HEAD(modelp, dm, link);
    188 	}
    189 }
    190 
    191 static void
    192 et_display_view(v)
    193 view_t *v;
    194 {
    195 	dmode_t		*dm = v->mode;
    196 	bmap_t		*bm = v->bitmap;
    197 	int		sv_size;
    198 	u_short		*src, *dst;
    199 	save_area_t	*sa;
    200 
    201 	if (dm->current_view && (dm->current_view != v)) {
    202 		/*
    203 		 * Mark current view for this mode as no longer displayed
    204 		 */
    205 		dm->current_view->flags &= ~VF_DISPLAY;
    206 	}
    207 	dm->current_view = v;
    208 	v->flags |= VF_DISPLAY;
    209 
    210 	if ((sa = (save_area_t*)v->save_area) == NULL)
    211 		return; /* XXX: Can't happen.... */
    212 
    213 	/*
    214 	 * Restore register settings and turn the plane pointer
    215 	 * to the card-memory
    216 	 */
    217 	et_hwrest(&sa->sv_regs);
    218 	bm->plane = et_priv.memkva;
    219 
    220 	et_use_colormap(v, v->colormap);
    221 
    222 	/*
    223 	 * Copy the backing store to card-memory
    224 	 */
    225 	sv_size = sa->fb_size;
    226 	src     = sa->sv_fb;
    227 	dst     = (u_short *)bm->plane;
    228 	while (sv_size--)
    229 		*dst++ = *src++;
    230 }
    231 
    232 void
    233 et_remove_view(v)
    234 view_t *v;
    235 {
    236 	dmode_t *mode = v->mode;
    237 
    238 	if (mode->current_view == v) {
    239 #if 0
    240 		if (v->flags & VF_DISPLAY)
    241 			panic("Cannot shutdown display\n"); /* XXX */
    242 #endif
    243 		mode->current_view = NULL;
    244 	}
    245 	v->flags &= ~VF_DISPLAY;
    246 }
    247 
    248 void
    249 et_save_view(v)
    250 view_t *v;
    251 {
    252 	bmap_t		*bm = v->bitmap;
    253 	u_char		font_height;
    254 	int		sv_size;
    255 	u_short		*src, *dst;
    256 	save_area_t	*sa;
    257 
    258 	if (!atari_realconfig)
    259 		return;
    260 
    261 	if (RGfx(et_priv.regkva, GCT_ID_MISC) & 1) {
    262 #if 0 /* XXX: Can't use printf here.... */
    263 		printf("et_save_view: Don't know how to save"
    264 			" a graphics mode\n");
    265 #endif
    266 		return;
    267 	}
    268 	if (v->save_area == NULL)
    269 		v->save_area = malloc(SAVEBUF_SIZE, M_DEVBUF, M_NOWAIT);
    270 
    271 	/*
    272 	 * Calculate the size of the copy
    273 	 */
    274 	font_height = RCrt(et_priv.regkva, CRT_ID_MAX_ROW_ADDRESS) & 0x1f;
    275 	sv_size = bm->bytes_per_row * (bm->rows / (font_height + 1));
    276 	sv_size = min(SAVEBUF_SIZE, sv_size);
    277 
    278 	/*
    279 	 * Save all we need to know....
    280 	 */
    281 	sa  = (save_area_t *)v->save_area;
    282 	et_hwsave(&sa->sv_regs);
    283 	sa->fb_size = sv_size;
    284 	src = (u_short *)bm->plane;
    285 	dst = sa->sv_fb;
    286 	while (sv_size--)
    287 		*dst++ = *src++;
    288 	bm->plane = (u_char *)sa->sv_fb;
    289 }
    290 
    291 void
    292 et_free_view(v)
    293 view_t *v;
    294 {
    295 	if(v) {
    296 		et_remove_view(v);
    297 		if (v->colormap != &gra_con_cmap)
    298 			free(v->colormap, M_DEVBUF);
    299 		if (v->save_area != NULL)
    300 			free(v->save_area, M_DEVBUF);
    301 		if (v != &gra_con_view) {
    302 			free(v->bitmap, M_DEVBUF);
    303 			free(v, M_DEVBUF);
    304 		}
    305 	}
    306 }
    307 
    308 static int
    309 et_use_colormap(v, cm)
    310 view_t		*v;
    311 colormap_t	*cm;
    312 {
    313 	return (0); /* XXX: Nothing here for now... */
    314 }
    315 
    316 static view_t *
    317 et_alloc_view(mode, dim, depth)
    318 dmode_t	*mode;
    319 dimen_t	*dim;
    320 u_char   depth;
    321 {
    322 	view_t		*v;
    323 	bmap_t		*bm;
    324 	box_t		box;
    325 	save_area_t	*sa;
    326 
    327 	if (!atari_realconfig) {
    328 		v  = &gra_con_view;
    329 		bm = &con_bm;
    330 	}
    331 	else {
    332 		v  = malloc(sizeof(*v), M_DEVBUF, M_WAITOK);
    333 		bm = malloc(sizeof(*bm), M_DEVBUF, M_WAITOK);
    334 	}
    335 	v->bitmap = bm;
    336 
    337 	/*
    338 	 * Initialize the bitmap
    339 	 */
    340 	bm->plane         = et_priv.memkva;
    341 	bm->vga_address   = (caddr_t)kvtop(et_priv.memkva);
    342 	bm->vga_base      = VGA_BASE;
    343 	bm->hw_address    = (caddr_t)(PCI_MEM_PHYS | et_priv.linbase);
    344 	bm->lin_base      = et_priv.linbase;
    345 	bm->regs          = et_priv.regkva;
    346 	bm->hw_regs       = (caddr_t)kvtop(et_priv.regkva);
    347 	bm->reg_size      = REG_MAPPABLE;
    348 	bm->phys_mappable = FRAME_MAPPABLE;
    349 	bm->vga_mappable  = VGA_MAPPABLE;
    350 
    351 	bm->bytes_per_row = (mode->size.width * depth) / NBBY;
    352 	bm->rows          = mode->size.height;
    353 	bm->depth         = depth;
    354 
    355 	/*
    356 	 * Allocate a save_area.
    357 	 * Note: If atari_realconfig is false, no save area is (can be)
    358 	 * allocated. This means that the plane is the video memory,
    359 	 * which is what's wanted in this case.
    360 	 */
    361 	if (atari_realconfig) {
    362 		v->save_area = malloc(SAVEBUF_SIZE, M_DEVBUF, M_WAITOK);
    363 		sa           = (save_area_t*)v->save_area;
    364 		sa->fb_size  = 0;
    365 		bm->plane    = (u_char *)sa->sv_fb;
    366 		et_loadmode(mode->data, &sa->sv_regs);
    367 	}
    368 	else v->save_area = NULL;
    369 
    370 	v->colormap = alloc_colormap(mode);
    371 	if (v->colormap) {
    372 		INIT_BOX(&box,0,0,mode->size.width,mode->size.height);
    373 		init_view(v, bm, mode, &box);
    374 		return (v);
    375 	}
    376 	if (v != &gra_con_view) {
    377 		free(v, M_DEVBUF);
    378 		free(bm, M_DEVBUF);
    379 	}
    380 	return (NULL);
    381 }
    382 
    383 static void
    384 init_view(v, bm, mode, dbox)
    385 view_t	*v;
    386 bmap_t	*bm;
    387 dmode_t	*mode;
    388 box_t	*dbox;
    389 {
    390 	v->bitmap    = bm;
    391 	v->mode      = mode;
    392 	v->flags     = 0;
    393 	bcopy(dbox, &v->display, sizeof(box_t));
    394 }
    395 
    396 /* XXX: No more than a stub... */
    397 static colormap_t *
    398 alloc_colormap(dm)
    399 dmode_t		*dm;
    400 {
    401 	colormap_t	*cm;
    402 	int		i;
    403 
    404 	cm = &gra_con_cmap;
    405 	cm->entry = gra_con_colors;
    406 
    407 	cm->first = 0;
    408 	cm->size  = 2;
    409 
    410 	for (i = 0; i < 2; i++)
    411 		cm->entry[i] = gra_def_color16[i % 16];
    412 	return (cm);
    413 }
    414 
    415 /*
    416  * Go look for a VGA card on the PCI-bus. This search is a
    417  * stripped down version of the PCI-probe. It only looks on
    418  * bus0 for et4000/et6000 cards. The first card found is used.
    419  */
    420 int
    421 et_probe_card()
    422 {
    423 	pci_chipset_tag_t	pc = NULL; /* XXX */
    424 	pcitag_t		tag, csr;
    425 	int			device, found, id, maxndevs;
    426 
    427 	found    = 0;
    428 	tag      = 0;
    429 	id       = 0;
    430 	maxndevs = pci_bus_maxdevs(pc, 0);
    431 
    432 	for (device = 0; !found && (device < maxndevs); device++) {
    433 
    434 		tag = pci_make_tag(pc, 0, device, 0);
    435 		id  = pci_conf_read(pc, tag, PCI_ID_REG);
    436 		if (id == 0 || id == 0xffffffff)
    437 			continue;
    438 		switch (PCI_PRODUCT(id)) {
    439 			case PCI_PRODUCT_TSENG_ET6000:
    440 			case PCI_PRODUCT_TSENG_ET4000_W32P_A:
    441 			case PCI_PRODUCT_TSENG_ET4000_W32P_B:
    442 			case PCI_PRODUCT_TSENG_ET4000_W32P_C:
    443 			case PCI_PRODUCT_TSENG_ET4000_W32P_D:
    444 				found = 1;
    445 				break;
    446 			default:
    447 				break;
    448 		}
    449 	}
    450 	if (!found)
    451 		return (0);
    452 
    453 	if (PCI_PRODUCT(id) ==  PCI_PRODUCT_TSENG_ET6000)
    454 		et_priv.board_type = BT_ET6000;
    455 	else et_priv.board_type = BT_ET4000;
    456 
    457 	/* Turn on the card */
    458 	pci_conf_write(pc, tag, PCI_MAPREG_START, PCI_LINMEMBASE);
    459 	if (et_priv.board_type == BT_ET6000)
    460 		pci_conf_write(pc, tag, PCI_MAPREG_START+4,
    461 					PCI_IOBASE | PCI_MAPREG_TYPE_IO);
    462 	csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
    463 	csr |= (PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_IO_ENABLE);
    464 	csr |= PCI_COMMAND_MASTER_ENABLE;
    465 	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr);
    466 
    467 	et_priv.pci_tag = tag;
    468 
    469 	/*
    470 	 * The things below are setup in atari_init.c
    471 	 */
    472 	et_priv.regkva  = (volatile caddr_t)pci_io_addr;
    473 	et_priv.memkva  = (volatile caddr_t)pci_mem_addr;
    474 	et_priv.linbase = PCI_LINMEMBASE;
    475 	et_priv.memsz   = PCI_VGA_SIZE;
    476 	et_priv.regsz   = PCI_IO_SIZE;
    477 
    478 	if (found && !atari_realconfig) {
    479 		et_boardinit();
    480 		et_loadmode(&hw_modes[0], NULL);
    481 		return (1);
    482 	}
    483 
    484 	return (1);
    485 }
    486 
    487 static void
    488 et_loadmode(mode, regs)
    489 struct grfvideo_mode	*mode;
    490 et_sv_reg_t		*regs;
    491 {
    492 	unsigned short	HDE, VDE;
    493 	int	    	lace, dblscan;
    494 	int     	uplim, lowlim;
    495 	int		i;
    496 	unsigned char	clock, tmp;
    497 	volatile u_char	*ba;
    498 	et_sv_reg_t	loc_regs;
    499 
    500 	if (regs == NULL)
    501 		regs = &loc_regs;
    502 
    503 	ba  = et_priv.regkva;
    504 	HDE = mode->disp_width / 8 - 1;
    505 	VDE = mode->disp_height - 1;
    506 
    507 	/* figure out whether lace or dblscan is needed */
    508 
    509 	uplim   = mode->disp_height + (mode->disp_height / 4);
    510 	lowlim  = mode->disp_height - (mode->disp_height / 4);
    511 	lace    = (((mode->vtotal * 2) > lowlim)
    512 		   && ((mode->vtotal * 2) < uplim)) ? 1 : 0;
    513 	dblscan = (((mode->vtotal / 2) > lowlim)
    514 		   && ((mode->vtotal / 2) < uplim)) ? 1 : 0;
    515 
    516 	/* adjustments */
    517 	if (lace)
    518 		VDE /= 2;
    519 
    520 	regs->misc_output = 0x23; /* Page 0, Color mode */
    521 	regs->seg_sel     = 0x00;
    522 	regs->state_ctl   = 0x00;
    523 
    524 	regs->seq[SEQ_ID_RESET]           = 0x03; /* reset off		*/
    525 	regs->seq[SEQ_ID_CLOCKING_MODE]   = 0x21; /* Turn off screen	*/
    526 	regs->seq[SEQ_ID_MAP_MASK]        = 0xff; /* Cpu writes all planes*/
    527 	regs->seq[SEQ_ID_CHAR_MAP_SELECT] = 0x00; /* Char. generator 0	*/
    528 	regs->seq[SEQ_ID_MEMORY_MODE]     = 0x0e; /* Seq. Memory mode	*/
    529 
    530 	/*
    531 	 * Set the clock...
    532 	 */
    533 	for(clock = ET_NUMCLOCKS-1; clock > 0; clock--) {
    534 		if (et_clockfreqs[clock] <= mode->pixel_clock)
    535 			break;
    536 	}
    537 	regs->misc_output |= (clock & 3) << 2;
    538 	regs->aux_mode     = 0xb4 | ((clock & 8) << 3);
    539 	regs->compat_6845  = (clock & 4) ? 0x0a : 0x08;
    540 
    541 	/*
    542 	 * The display parameters...
    543 	 */
    544 	regs->crt[CRT_ID_HOR_TOTAL]        =  mode->htotal;
    545 	regs->crt[CRT_ID_HOR_DISP_ENA_END] = ((HDE >= mode->hblank_start)
    546 						? mode->hblank_stop - 1
    547 						: HDE);
    548 	regs->crt[CRT_ID_START_HOR_BLANK]  = mode->hblank_start;
    549 	regs->crt[CRT_ID_END_HOR_BLANK]    = (mode->hblank_stop & 0x1f) | 0x80;
    550 	regs->crt[CRT_ID_START_HOR_RETR]   = mode->hsync_start;
    551 	regs->crt[CRT_ID_END_HOR_RETR]     = (mode->hsync_stop & 0x1f)
    552 						| ((mode->hblank_stop & 0x20)
    553 							? 0x80 : 0x00);
    554 	regs->crt[CRT_ID_VER_TOTAL]        = mode->vtotal;
    555 	regs->crt[CRT_ID_START_VER_RETR]   = mode->vsync_start;
    556 	regs->crt[CRT_ID_END_VER_RETR]     = (mode->vsync_stop & 0x0f) | 0x30;
    557 	regs->crt[CRT_ID_VER_DISP_ENA_END] = VDE;
    558 	regs->crt[CRT_ID_START_VER_BLANK]  = mode->vblank_start;
    559 	regs->crt[CRT_ID_END_VER_BLANK]    = mode->vblank_stop;
    560 	regs->crt[CRT_ID_MODE_CONTROL]     = 0xab;
    561 	regs->crt[CRT_ID_START_ADDR_HIGH]  = 0x00;
    562 	regs->crt[CRT_ID_START_ADDR_LOW]   = 0x00;
    563 	regs->crt[CRT_ID_LINE_COMPARE]     = 0xff;
    564 	regs->crt[CRT_ID_UNDERLINE_LOC]    = 0x00;
    565 	regs->crt[CRT_ID_OFFSET]           = mode->disp_width/16;
    566 	regs->crt[CRT_ID_MAX_ROW_ADDRESS]  =
    567 		0x40 |
    568 		(dblscan ? 0x80 : 0x00) |
    569 		((mode->vblank_start & 0x200) ? 0x20 : 0x00);
    570 	regs->crt[CRT_ID_OVERFLOW] =
    571 		0x10 |
    572 		((mode->vtotal       & 0x100) ? 0x01 : 0x00) |
    573 		((VDE                & 0x100) ? 0x02 : 0x00) |
    574 		((mode->vsync_start  & 0x100) ? 0x04 : 0x00) |
    575 		((mode->vblank_start & 0x100) ? 0x08 : 0x00) |
    576 		((mode->vtotal       & 0x200) ? 0x20 : 0x00) |
    577 		((VDE                & 0x200) ? 0x40 : 0x00) |
    578 		((mode->vsync_start  & 0x200) ? 0x80 : 0x00);
    579 	regs->overfl_high =
    580 		0x10 |
    581 		((mode->vblank_start & 0x400) ? 0x01 : 0x00) |
    582 		((mode->vtotal       & 0x400) ? 0x02 : 0x00) |
    583 		((VDE                & 0x400) ? 0x04 : 0x00) |
    584 		((mode->vsync_start  & 0x400) ? 0x08 : 0x00) |
    585 		(lace ? 0x80 : 0x00);
    586 	regs->hor_overfl =
    587 		((mode->htotal       & 0x100) ? 0x01 : 0x00) |
    588 		((mode->hblank_start & 0x100) ? 0x04 : 0x00) |
    589 		((mode->hsync_start  & 0x100) ? 0x10 : 0x00);
    590 
    591 	regs->grf[GCT_ID_SET_RESET]        = 0x00;
    592 	regs->grf[GCT_ID_ENABLE_SET_RESET] = 0x00;
    593 	regs->grf[GCT_ID_COLOR_COMPARE]    = 0x00;
    594 	regs->grf[GCT_ID_DATA_ROTATE]      = 0x00;
    595 	regs->grf[GCT_ID_READ_MAP_SELECT]  = 0x00;
    596 	regs->grf[GCT_ID_GRAPHICS_MODE]    = mode->depth == 1 ? 0x00: 0x40;
    597 	regs->grf[GCT_ID_MISC]             = 0x01;
    598 	regs->grf[GCT_ID_COLOR_XCARE]      = 0x0f;
    599 	regs->grf[GCT_ID_BITMASK]          = 0xff;
    600 
    601 	for (i = 0; i < 0x10; i++)
    602 		regs->attr[i] = i;
    603 	regs->attr[ACT_ID_ATTR_MODE_CNTL]  = 0x01;
    604 	regs->attr[ACT_ID_OVERSCAN_COLOR]  = 0x00;
    605 	regs->attr[ACT_ID_COLOR_PLANE_ENA] = 0x0f;
    606 	regs->attr[ACT_ID_HOR_PEL_PANNING] = 0x00;
    607 	regs->attr[ACT_ID_COLOR_SELECT]    = 0x00;
    608 	regs->attr[ACT_ID_MISCELLANEOUS]   = 0x00;
    609 
    610 	/*
    611 	 * XXX: This works for depth == 4. I need some better docs
    612 	 * to fix the other modes....
    613 	 */
    614 	/*
    615 	 * What we need would be probe functions for RAMDAC/clock chip
    616 	 */
    617 	vgar(ba, VDAC_ADDRESS);		/* clear old state */
    618 	vgar(ba, VDAC_MASK);
    619 	vgar(ba, VDAC_MASK);
    620 	vgar(ba, VDAC_MASK);
    621 	vgar(ba, VDAC_MASK);
    622 
    623 	vgaw(ba, VDAC_MASK, 0);		/* set to palette */
    624 	vgar(ba, VDAC_ADDRESS);		/* clear state */
    625 
    626 	vgaw(ba, VDAC_MASK, 0xff);
    627 	/*
    628 	 * End of depth stuff
    629 	 */
    630 
    631 	/*
    632 	 * Compute Hsync & Vsync polarity
    633 	 * Note: This seems to be some kind of a black art :-(
    634 	 */
    635 	tmp = regs->misc_output & 0x3f;
    636 #if 1 /* This is according to my BW monitor & Xfree... */
    637 	if (VDE < 400)
    638 		tmp |= 0x40;	/* -hsync +vsync */
    639 	else if (VDE < 480)
    640 		tmp |= 0xc0;	/* -hsync -vsync */
    641 #else /* This is according to my color monitor.... */
    642 	if (VDE < 400)
    643 		tmp |= 0x00;	/* +hsync +vsync */
    644 	else if (VDE < 480)
    645 		tmp |= 0x80;	/* +hsync -vsync */
    646 #endif
    647 	/* I'm unable to try the rest.... */
    648 	regs->misc_output = tmp;
    649 
    650 	if(regs == &loc_regs)
    651 		et_hwrest(regs);
    652 }
    653 
    654 static void
    655 et_boardinit()
    656 {
    657 	volatile u_char *ba;
    658 	int		i, j;
    659 
    660 	ba = et_priv.regkva;
    661 
    662 	vgaw(ba, GREG_HERCULESCOMPAT,     0x03);
    663 	vgaw(ba, GREG_DISPMODECONTROL,    0xa0);
    664 	vgaw(ba, GREG_MISC_OUTPUT_W,      0x23);
    665 
    666 	WSeq(ba, SEQ_ID_RESET,            0x03);
    667 	WSeq(ba, SEQ_ID_CLOCKING_MODE,    0x21);	/* 8 dot, Display off */
    668 	WSeq(ba, SEQ_ID_MAP_MASK,         0x0f);
    669 	WSeq(ba, SEQ_ID_CHAR_MAP_SELECT,  0x00);
    670 	WSeq(ba, SEQ_ID_MEMORY_MODE,      0x0e);
    671 	WSeq(ba, SEQ_ID_AUXILIARY_MODE,   0xf4);
    672 
    673 	WCrt(ba, CRT_ID_PRESET_ROW_SCAN,  0x00);
    674 	WCrt(ba, CRT_ID_CURSOR_START,     0x00);
    675 	WCrt(ba, CRT_ID_CURSOR_END,       0x08);
    676 	WCrt(ba, CRT_ID_START_ADDR_HIGH,  0x00);
    677 	WCrt(ba, CRT_ID_START_ADDR_LOW,   0x00);
    678 	WCrt(ba, CRT_ID_CURSOR_LOC_HIGH,  0x00);
    679 	WCrt(ba, CRT_ID_CURSOR_LOC_LOW,   0x00);
    680 
    681 	WCrt(ba, CRT_ID_UNDERLINE_LOC,    0x07);
    682 	WCrt(ba, CRT_ID_MODE_CONTROL,     0xa3);
    683 	WCrt(ba, CRT_ID_LINE_COMPARE,     0xff);
    684 	/*
    685 	 * ET4000 special
    686 	 */
    687 	WCrt(ba, CRT_ID_RASCAS_CONFIG,    0x28);
    688 	WCrt(ba, CTR_ID_EXT_START,        0x00);
    689 	WCrt(ba, CRT_ID_6845_COMPAT,      0x08);
    690 	if (et_priv.board_type == BT_ET6000)
    691 		et6000_init();
    692 	else {
    693 		WCrt(ba, CRT_ID_VIDEO_CONFIG1,    0x43);
    694 		WCrt(ba, CRT_ID_VIDEO_CONFIG2,    0x09);
    695 	}
    696 
    697 	WCrt(ba, CRT_ID_HOR_OVERFLOW,     0x00);
    698 
    699 	WGfx(ba, GCT_ID_SET_RESET,        0x00);
    700 	WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00);
    701 	WGfx(ba, GCT_ID_COLOR_COMPARE,    0x00);
    702 	WGfx(ba, GCT_ID_DATA_ROTATE,      0x00);
    703 	WGfx(ba, GCT_ID_READ_MAP_SELECT,  0x00);
    704 	WGfx(ba, GCT_ID_GRAPHICS_MODE,    0x40);
    705 	WGfx(ba, GCT_ID_MISC,             0x05);
    706 	WGfx(ba, GCT_ID_COLOR_XCARE,      0x0f);
    707 	WGfx(ba, GCT_ID_BITMASK,          0xff);
    708 
    709 	vgaw(ba, GREG_SEGMENTSELECT,      0x00);
    710 
    711 	for (i = 0; i < 0x10; i++)
    712 		WAttr(ba, i, i);
    713 	WAttr(ba, ACT_ID_ATTR_MODE_CNTL,  0x01);
    714 	WAttr(ba, ACT_ID_OVERSCAN_COLOR,  0x00);
    715 	WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f);
    716 	WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00);
    717 	WAttr(ba, ACT_ID_COLOR_SELECT,    0x00);
    718 	WAttr(ba, ACT_ID_MISCELLANEOUS,   0x00);
    719 
    720 	vgaw(ba, VDAC_MASK, 0xff);
    721 
    722 #if 0 /* XXX: We like to do this: */
    723 	delay(200000);
    724 #else /* But because we run before the delay is initialized: */
    725 	for(i = 0; i < 4000; i++)
    726 		for(j =  0; j < 400; j++);
    727 #endif
    728 
    729 	/*
    730 	 * colors initially set to greyscale
    731 	 */
    732 	vgaw(ba, VDAC_ADDRESS_W, 0);
    733 	for (i = 255; i >= 0; i--) {
    734 		vgaw(ba, VDAC_DATA, i);
    735 		vgaw(ba, VDAC_DATA, i);
    736 		vgaw(ba, VDAC_DATA, i);
    737 	}
    738 }
    739 
    740 /*
    741  * Initialize the et6000 specific (PCI) registers. Try to do it like the
    742  * video-bios would have done it, so things like Xservers get what they
    743  * expect. Most info was kindly provided by Koen Gadeyne.
    744  *
    745  * XXX: not fit for programming beauty contest...
    746  */
    747 static void
    748 et6000_init()
    749 {
    750 
    751 	volatile u_char *ba;
    752 	int		i;
    753 	u_char		dac_tab[] = { 0x7d,0x67, 0x5d,0x64, 0x56,0x63,
    754 				      0x28,0x22, 0x79,0x49, 0x6f,0x47,
    755 				      0x28,0x41, 0x6b,0x44, 0x00,0x00,
    756 				      0x00,0x00, 0x5d,0x25, 0x00,0x00,
    757 				      0x00,0x00, 0x00,0x96 };
    758 
    759 	ba = et_priv.regkva + PCI_IOBASE;
    760 
    761 
    762 	ba[0x40] = 0x06;	/* Use standard vga addressing		*/
    763 	ba[0x41] = 0x2a;	/* Performance control			*/
    764 	ba[0x43] = 0x02;	/* XCLK/SCLK config			*/
    765 	ba[0x44] = 0x11;	/* RAS/CAS config			*/
    766 	ba[0x46] = 0x00;	/* CRT display feature			*/
    767 	ba[0x47] = 0x10;
    768 	ba[0x58] = 0x00;	/* Video Control 1			*/
    769 	ba[0x59] = 0x04;	/* Video Control 2			*/
    770 
    771 	/*
    772 	 * Setup a 'standard' CLKDAC
    773 	 */
    774 	ba[0x42] = 0x00;	/* MCLK == CLK0 */
    775 	ba[0x67] = 0x00;	/* Start filling from dac-reg 0 and up... */
    776 	for (i = 0; i < 0x16; i++)
    777 		ba[0x69] = dac_tab[i];
    778 
    779 	if (ba[8] == 0x70) { /* et6100, right? */
    780 		volatile u_char *ma;
    781 		u_char	bv;
    782 
    783 		ma = et_priv.memkva;
    784 
    785 		/*
    786 		 * XXX Black magic to get the bloody MDRAM's to function...
    787                  * XXX _Only_ tested on my card! [leo]
    788 		 */
    789 		bv = ba[45];
    790 		ba[0x45] = bv | 0x40;	/* Reset MDRAM's		*/
    791 		ba[0x45] = bv | 0x70;	/* Program latency value	*/
    792 		ma[0x0] = 0;		/* Yeah, right :-(		*/
    793 		ba[0x45] = bv;		/* Back to normal		*/
    794 		ba[0x44] = 0x14;	/* RAS/CAS config		*/
    795 	}
    796 }
    797 
    798 void
    799 et_hwsave(et_regs)
    800 et_sv_reg_t	*et_regs;
    801 {
    802 	volatile u_char *ba;
    803 	int		i, s;
    804 
    805 	ba = et_priv.regkva;
    806 
    807 	s = splhigh();
    808 
    809 	/*
    810 	 * General VGA registers
    811 	 */
    812 	et_regs->misc_output = vgar(ba, GREG_MISC_OUTPUT_R);
    813 	for(i = 0; i < 25; i++)
    814 		et_regs->crt[i]  = RCrt(ba, i);
    815 	for(i = 0; i < 21; i++)
    816 		et_regs->attr[i] = RAttr(ba, i | 0x20);
    817 	for(i = 0; i < 9; i++)
    818 		et_regs->grf[i]  = RGfx(ba, i);
    819 	for(i = 0; i < 5; i++)
    820 		et_regs->seq[i]  = RSeq(ba, i);
    821 
    822 	/*
    823 	 * ET4000 extensions
    824 	 */
    825 	et_regs->ext_start   = RCrt(ba, CTR_ID_EXT_START);
    826 	et_regs->compat_6845 = RCrt(ba, CRT_ID_6845_COMPAT);
    827 	et_regs->overfl_high = RCrt(ba, CRT_ID_OVERFLOW_HIGH);
    828 	et_regs->hor_overfl  = RCrt(ba, CRT_ID_HOR_OVERFLOW);
    829 	et_regs->state_ctl   = RSeq(ba, SEQ_ID_STATE_CONTROL);
    830 	et_regs->aux_mode    = RSeq(ba, SEQ_ID_AUXILIARY_MODE);
    831 	et_regs->seg_sel     = vgar(ba, GREG_SEGMENTSELECT);
    832 
    833 	s = splx(s);
    834 }
    835 
    836 void
    837 et_hwrest(et_regs)
    838 et_sv_reg_t	*et_regs;
    839 {
    840 	volatile u_char *ba;
    841 	int		i, s;
    842 
    843 	ba = et_priv.regkva;
    844 
    845 	s = splhigh();
    846 
    847 	vgaw(ba, GREG_SEGMENTSELECT, 0);
    848 	vgaw(ba, GREG_MISC_OUTPUT_W, et_regs->misc_output);
    849 
    850 	/*
    851 	 * General VGA registers
    852 	 */
    853 	WSeq(ba, SEQ_ID_RESET, 0x01);
    854 	for(i = 1; i < 5; i++)
    855 		WSeq(ba, i, et_regs->seq[i]);
    856 	WSeq(ba, SEQ_ID_RESET, 0x03);
    857 
    858 	/*
    859 	 * Make sure we're allowed to write all crt-registers
    860 	 */
    861 	WCrt(ba, CRT_ID_END_VER_RETR,
    862 		et_regs->crt[CRT_ID_END_VER_RETR] & 0x7f);
    863 	for(i = 0; i < 25; i++)
    864 		WCrt(ba, i, et_regs->crt[i]);
    865 	for(i = 0; i < 9; i++)
    866 		WGfx(ba, i, et_regs->grf[i]);
    867 	for(i = 0; i < 21; i++)
    868 		WAttr(ba, i | 0x20, et_regs->attr[i]);
    869 
    870 	/*
    871 	 * ET4000 extensions
    872 	 */
    873 	WSeq(ba, SEQ_ID_STATE_CONTROL, et_regs->state_ctl);
    874 	WSeq(ba, SEQ_ID_AUXILIARY_MODE, et_regs->aux_mode);
    875 	WCrt(ba, CTR_ID_EXT_START, et_regs->ext_start);
    876 	WCrt(ba, CRT_ID_6845_COMPAT, et_regs->compat_6845);
    877 	WCrt(ba, CRT_ID_OVERFLOW_HIGH, et_regs->overfl_high);
    878 	WCrt(ba, CRT_ID_HOR_OVERFLOW, et_regs->hor_overfl);
    879 	vgaw(ba, GREG_SEGMENTSELECT, et_regs->seg_sel);
    880 
    881 	i = et_regs->seq[SEQ_ID_CLOCKING_MODE] & ~0x20;
    882 	WSeq(ba, SEQ_ID_CLOCKING_MODE, i);
    883 
    884 	s = splx(s);
    885 }
    886