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