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