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