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