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