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