1 /* $OpenBSD: tga.c,v 1.29 2006/12/17 22:18:16 miod Exp $ */
2 /* $NetBSD: tga.c,v 1.40 2002/03/13 15:05:18 ad Exp $ */
3
4 /*
5 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
6 * All rights reserved.
7 *
8 * Author: Chris G. Demetriou
9 *
10 * Permission to use, copy, modify and distribute this software and
11 * its documentation is hereby granted, provided that both the copyright
12 * notice and this permission notice appear in all copies of the
13 * software, derivative works or modified versions, and any portions
14 * thereof, and that both notices appear in supporting documentation.
15 *
16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 *
20 * Carnegie Mellon requests users of this software to return to
21 *
22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23 * School of Computer Science
24 * Carnegie Mellon University
25 * Pittsburgh PA 15213-3890
26 *
27 * any improvements or extensions that they make and grant Carnegie the
28 * rights to redistribute these changes.
29 */
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/device.h>
35 #include <sys/conf.h>
36 #include <sys/malloc.h>
37 #include <sys/buf.h>
38 #include <sys/ioctl.h>
39
40 #include <machine/bus.h>
41 #include <machine/intr.h>
42
43 #include <dev/pci/pcireg.h>
44 #include <dev/pci/pcivar.h>
45 #include <dev/pci/pcidevs.h>
46 #include <dev/pci/tgareg.h>
47 #include <dev/pci/tgavar.h>
48 #include <dev/ic/bt485reg.h>
49 #include <dev/ic/bt485var.h>
50 #include <dev/ic/bt463reg.h>
51 #include <dev/ic/bt463var.h>
52 #include <dev/ic/ibm561var.h>
53
54 #include <dev/wscons/wsconsio.h>
55 #include <dev/rasops/rasops.h>
56 #include <dev/wsfont/wsfont.h>
57
58 #if defined(__alpha__) || defined(__mips__)
59 #include <uvm/uvm_extern.h>
60 #endif
61
62 #ifdef __alpha__
63 #include <machine/pte.h>
64 #endif
65 #ifdef __mips__
66 #include <mips/pte.h>
67 #endif
68
69 int tgamatch(struct device *, struct cfdata *, void *);
70 void tgaattach(struct device *, struct device *, void *);
71 int tgaprint(void *, const char *);
72
73 struct cfdriver tga_cd = {
74 NULL, "tga", DV_DULL
75 };
76
77 struct cfattach tga_ca = {
78 sizeof(struct tga_softc), (cfmatch_t)tgamatch, tgaattach,
79 };
80
81 int tga_identify(struct tga_devconfig *);
82 const struct tga_conf *tga_getconf(int);
83 void tga_getdevconfig(bus_space_tag_t memt, pci_chipset_tag_t pc,
84 pcitag_t tag, struct tga_devconfig *dc);
85 unsigned tga_getdotclock(struct tga_devconfig *dc);
86
87 struct tga_devconfig tga_console_dc;
88
89 int tga_ioctl(void *, u_long, caddr_t, int, struct proc *);
90 paddr_t tga_mmap(void *, off_t, int);
91 void tga_copyrows(void *, int, int, int);
92 void tga_copycols(void *, int, int, int, int);
93 int tga_alloc_screen(void *, const struct wsscreen_descr *,
94 void **, int *, int *, long *);
95 void tga_free_screen(void *, void *);
96 int tga_show_screen(void *, void *, int,
97 void (*) (void *, int, int), void *);
98 void tga_burner(void *, u_int, u_int);
99 int tga_rop(struct rasops_info *, int, int, int, int,
100 struct rasops_info *, int, int);
101 int tga_rop_vtov(struct rasops_info *, int, int, int,
102 int, struct rasops_info *, int, int );
103 void tga_putchar(void *c, int row, int col, u_int uc, long attr);
104 void tga_eraserows(void *, int, int, long);
105 void tga_erasecols(void *, int, int, int, long);
106 void tga2_init(struct tga_devconfig *);
107
108 void tga_config_interrupts(struct device *);
109
110 /* RAMDAC interface functions */
111 int tga_sched_update(void *, void (*)(void *));
112 void tga_ramdac_wr(void *, u_int, u_int8_t);
113 u_int8_t tga_ramdac_rd(void *, u_int);
114 void tga_bt463_wr(void *, u_int, u_int8_t);
115 u_int8_t tga_bt463_rd(void *, u_int);
116 void tga2_ramdac_wr(void *, u_int, u_int8_t);
117 u_int8_t tga2_ramdac_rd(void *, u_int);
118
119 /* Interrupt handler */
120 int tga_intr(void *);
121
122 /* The NULL entries will get filled in by rasops_init().
123 * XXX and the non-NULL ones will be overwritten; reset after calling it.
124 */
125 struct wsdisplay_emulops tga_emulops = {
126 NULL,
127 NULL,
128 tga_putchar,
129 tga_copycols,
130 tga_erasecols,
131 tga_copyrows,
132 tga_eraserows,
133 NULL,
134 NULL
135 };
136
137 struct wsscreen_descr tga_stdscreen = {
138 "std",
139 0, 0, /* will be filled in -- XXX shouldn't, it's global */
140 &tga_emulops,
141 0, 0,
142 WSSCREEN_UNDERLINE | WSSCREEN_HILIT |
143 WSSCREEN_WSCOLORS | WSSCREEN_REVERSE
144 };
145
146 const struct wsscreen_descr *_tga_scrlist[] = {
147 &tga_stdscreen,
148 /* XXX other formats, graphics screen? */
149 };
150
151 struct wsscreen_list tga_screenlist = {
152 sizeof(_tga_scrlist) / sizeof(struct wsscreen_descr *), _tga_scrlist
153 };
154
155 struct wsdisplay_accessops tga_accessops = {
156 tga_ioctl,
157 tga_mmap,
158 tga_alloc_screen,
159 tga_free_screen,
160 tga_show_screen,
161 NULL, /* load_font */
162 NULL, /* scrollback */
163 NULL, /* getchar */
164 tga_burner,
165 };
166
167 void tga_blank(struct tga_devconfig *);
168 void tga_unblank(struct tga_devconfig *);
169
170 #ifdef TGA_DEBUG
171 #define DPRINTF(...) printf (__VA_ARGS__)
172 #define DPRINTFN(n, ...) if (tgadebug > (n)) printf (__VA_ARGS__)
173 int tgadebug = 0;
174 #else
175 #define DPRINTF(...)
176 #define DPRINTFN(n,...)
177 #endif
178
179 const struct pci_matchid tga_devices[] = {
180 { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21030 },
181 { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_PBXGB },
182 };
183
184 int
tgamatch(parent,match,aux)185 tgamatch(parent, match, aux)
186 struct device *parent;
187 struct cfdata *match;
188 void *aux;
189 {
190 if (pci_matchbyid((struct pci_attach_args *)aux, tga_devices,
191 sizeof(tga_devices) / sizeof(tga_devices[0])))
192 return (10); /* need to return more than vga_pci here! */
193
194 return (0);
195 }
196
197 void
tga_getdevconfig(memt,pc,tag,dc)198 tga_getdevconfig(memt, pc, tag, dc)
199 bus_space_tag_t memt;
200 pci_chipset_tag_t pc;
201 pcitag_t tag;
202 struct tga_devconfig *dc;
203 {
204 const struct tga_conf *tgac;
205 struct rasops_info *rip;
206 int cookie;
207 bus_size_t pcisize;
208 int i;
209
210 dc->dc_memt = memt;
211
212 dc->dc_pcitag = tag;
213
214 DPRINTF("tga_getdevconfig: Getting map info\n");
215 /* XXX magic number */
216 if (pci_mapreg_info(pc, tag, 0x10,
217 PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
218 &dc->dc_pcipaddr, &pcisize, NULL))
219 return;
220
221 DPRINTF("tga_getdevconfig: preparing to map\n");
222 #ifdef __OpenBSD__
223 if (bus_space_map(memt, dc->dc_pcipaddr, pcisize, 1, &dc->dc_memh))
224 return;
225 dc->dc_vaddr = dc->dc_memh;
226 #else
227 if (bus_space_map(memt, dc->dc_pcipaddr, pcisize,
228 BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR, &dc->dc_memh))
229 return;
230 dc->dc_vaddr = (vaddr_t) bus_space_vaddr(memt, dc->dc_memh);
231 #endif
232 DPRINTF("tga_getdevconfig: mapped\n");
233
234 #ifdef __alpha__
235 dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr); /* XXX */
236 #endif
237 #ifdef arc
238 bus_space_paddr(memt, dc->dc_memh, &dc->dc_paddr);
239 #endif
240 DPRINTF("tga_getdevconfig: allocating subregion\n");
241 bus_space_subregion(dc->dc_memt, dc->dc_memh,
242 TGA_MEM_CREGS, TGA_CREGS_SIZE,
243 &dc->dc_regs);
244
245 DPRINTF("tga_getdevconfig: going to identify\n");
246 dc->dc_tga_type = tga_identify(dc);
247
248 DPRINTF("tga_getdevconfig: preparing to get config\n");
249 tgac = dc->dc_tgaconf = tga_getconf(dc->dc_tga_type);
250 if (tgac == NULL)
251 return;
252
253 #if 0
254 /* XXX on the Alpha, pcisize = 4 * cspace_size. */
255 if (tgac->tgac_cspace_size != pcisize) /* sanity */
256 panic("tga_getdevconfig: memory size mismatch?");
257 #endif
258
259 DPRINTF("tga_getdevconfig: get revno\n");
260 switch (TGARREG(dc, TGA_REG_GREV) & 0xff) {
261 case 0x01:
262 case 0x02:
263 case 0x03:
264 case 0x04:
265 dc->dc_tga2 = 0;
266 break;
267 case 0x20:
268 case 0x21:
269 case 0x22:
270 dc->dc_tga2 = 1;
271 break;
272 default:
273 panic("tga_getdevconfig: TGA Revision not recognized");
274 }
275
276 if (dc->dc_tga2) {
277 tga2_init(dc);
278 }
279
280 i = TGARREG(dc, TGA_REG_VHCR) & 0x1ff;
281 DPRINTF("tga_getdevconfig: TGA_REG_VHCR & 0x1ff = %d\n", i);
282 switch (i) { /* XXX */
283 case 0:
284 dc->dc_wid = 8192;
285 break;
286
287 case 1:
288 dc->dc_wid = 8196;
289 break;
290
291 default:
292 dc->dc_wid = (TGARREG(dc, TGA_REG_VHCR) & 0x1ff) * 4; /* XXX */
293 break;
294 }
295
296 DPRINTF("tga_getdevconfig: dc->dc_wid = %d\n", dc->dc_wid);
297 /*
298 * XXX XXX Turning off "odd" shouldn't be necessary,
299 * XXX XXX but I can't make X work with the weird size.
300 */
301 DPRINTF("tga_getdevconfig: beginning magic incantation\n");
302 if ((TGARREG(dc, TGA_REG_VHCR) & 0x00000001) != 0 && /* XXX */
303 (TGARREG(dc, TGA_REG_VHCR) & 0x80000000) != 0) { /* XXX */
304 TGAWREG(dc, TGA_REG_VHCR,
305 (TGARREG(dc, TGA_REG_VHCR) & ~0x80000001));
306 dc->dc_wid -= 4;
307 }
308
309 dc->dc_rowbytes = dc->dc_wid * (dc->dc_tgaconf->tgac_phys_depth / 8);
310 dc->dc_ht = (TGARREG(dc, TGA_REG_VVCR) & 0x7ff); /* XXX */
311 DPRINTF("tga_getdevconfig: rowbytes = %d, tgac_phys_depth = %d\n"
312 " dc_wid = %d, dc_ht = %d\n",
313 dc->dc_rowbytes, dc->dc_tgaconf->tgac_phys_depth,
314 dc->dc_wid, dc->dc_ht);
315
316 /* XXX this seems to be what DEC does */
317 DPRINTF("tga_getdevconfig: more magic\n");
318 TGAWREG(dc, TGA_REG_CCBR, 0);
319 TGAWREG(dc, TGA_REG_VVBR, 1);
320 dc->dc_videobase = dc->dc_vaddr + tgac->tgac_dbuf[0] +
321 1 * tgac->tgac_vvbr_units;
322 dc->dc_blanked = 1;
323 tga_unblank(dc);
324
325 DPRINTF("tga_getdevconfig: dc_videobase = 0x%016llx\n"
326 " dc_vaddr = 0x%016llx\n"
327 " tgac_dbuf[0] = %d\n"
328 " tgac_vvbr_units = %d\n",
329 dc->dc_videobase, dc->dc_vaddr, tgac->tgac_dbuf[0],
330 tgac->tgac_vvbr_units);
331
332 /*
333 * Set all bits in the pixel mask, to enable writes to all pixels.
334 * It seems that the console firmware clears some of them
335 * under some circumstances, which causes cute vertical stripes.
336 */
337 DPRINTF("tga_getdevconfig: set pixel mask\n");
338 TGAWREG(dc, TGA_REG_GPXR_P, 0xffffffff);
339
340 /* clear the screen */
341 DPRINTF("tga_getdevconfig: clear screen\n");
342 for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t))
343 *(u_int32_t *)(dc->dc_videobase + i) = 0;
344
345 DPRINTF("tga_getdevconfig: raster ops\n");
346 /* Initialize rasops descriptor */
347 rip = &dc->dc_rinfo;
348 rip->ri_flg = RI_CENTER;
349 rip->ri_depth = tgac->tgac_phys_depth;
350 rip->ri_bits = (void *)dc->dc_videobase;
351 rip->ri_width = dc->dc_wid;
352 rip->ri_height = dc->dc_ht;
353 rip->ri_stride = dc->dc_rowbytes;
354 rip->ri_hw = dc;
355
356 if (tgac->tgac_phys_depth == 32) {
357 rip->ri_rnum = 8;
358 rip->ri_gnum = 8;
359 rip->ri_bnum = 8;
360 rip->ri_rpos = 16;
361 rip->ri_gpos = 8;
362 rip->ri_bpos = 0;
363 }
364
365 DPRINTF("tga_getdevconfig: wsfont_init\n");
366 wsfont_init();
367 if (rip->ri_width > 80*12)
368 /* High res screen, choose a big font */
369 cookie = wsfont_find(NULL, 12, 0, 0);
370 else
371 /* lower res, choose a 8 pixel wide font */
372 cookie = wsfont_find(NULL, 8, 0, 0);
373 if (cookie <= 0)
374 cookie = wsfont_find(NULL, 0, 0, 0);
375 if (cookie <= 0) {
376 printf("tga: no appropriate fonts.\n");
377 return;
378 }
379
380 /* the accelerated tga_putchar() needs LSbit left */
381 if (wsfont_lock(cookie, &rip->ri_font,
382 WSDISPLAY_FONTORDER_R2L, WSDISPLAY_FONTORDER_L2R) <= 0) {
383 printf("tga: couldn't lock font\n");
384 return;
385 }
386 rip->ri_wsfcookie = cookie;
387 /* fill screen size */
388 rasops_init(rip, rip->ri_height / rip->ri_font->fontheight,
389 rip->ri_width / rip->ri_font->fontwidth);
390
391 /* add our accelerated functions */
392 /* XXX shouldn't have to do this; rasops should leave non-NULL
393 * XXX entries alone.
394 */
395 rip->ri_ops.copyrows = tga_copyrows;
396 rip->ri_ops.eraserows = tga_eraserows;
397 rip->ri_ops.erasecols = tga_erasecols;
398 rip->ri_ops.copycols = tga_copycols;
399 rip->ri_ops.putchar = tga_putchar;
400
401 tga_stdscreen.nrows = rip->ri_rows;
402 tga_stdscreen.ncols = rip->ri_cols;
403 tga_stdscreen.textops = &rip->ri_ops;
404 tga_stdscreen.capabilities = rip->ri_caps;
405
406 dc->dc_intrenabled = 0;
407 }
408
409 void
tgaattach(parent,self,aux)410 tgaattach(parent, self, aux)
411 struct device *parent, *self;
412 void *aux;
413 {
414 struct pci_attach_args *pa = aux;
415 struct tga_softc *sc = (struct tga_softc *)self;
416 struct wsemuldisplaydev_attach_args aa;
417 pci_intr_handle_t intrh;
418 const char *intrstr;
419 u_int8_t rev;
420 int console;
421
422 #if defined(__alpha__) || defined(arc)
423 console = (pa->pa_tag == tga_console_dc.dc_pcitag);
424 #else
425 console = 0;
426 #endif
427 if (console) {
428 sc->sc_dc = &tga_console_dc;
429 sc->nscreens = 1;
430 } else {
431 sc->sc_dc = (struct tga_devconfig *)
432 malloc(sizeof(struct tga_devconfig), M_DEVBUF, M_NOWAIT);
433 if (sc->sc_dc == NULL)
434 return;
435 bzero(sc->sc_dc, sizeof(struct tga_devconfig));
436 tga_getdevconfig(pa->pa_memt, pa->pa_pc, pa->pa_tag,
437 sc->sc_dc);
438 }
439 if (sc->sc_dc->dc_vaddr == NULL) {
440 printf(": couldn't map memory space; punt!\n");
441 return;
442 }
443
444 /* XXX say what's going on. */
445 intrstr = NULL;
446 if (pci_intr_map(pa, &intrh)) {
447 printf(": couldn't map interrupt");
448 return;
449 }
450 intrstr = pci_intr_string(pa->pa_pc, intrh);
451 sc->sc_intr = pci_intr_establish(pa->pa_pc, intrh, IPL_TTY, tga_intr,
452 sc->sc_dc, sc->sc_dev.dv_xname);
453 if (sc->sc_intr == NULL) {
454 printf(": couldn't establish interrupt");
455 if (intrstr != NULL)
456 printf("at %s", intrstr);
457 printf("\n");
458 return;
459 }
460
461 rev = PCI_REVISION(pa->pa_class);
462 switch (rev) {
463 case 0x1:
464 case 0x2:
465 case 0x3:
466 printf(": DC21030 step %c", 'A' + rev - 1);
467 break;
468 case 0x20:
469 printf(": TGA2 abstract software model");
470 break;
471 case 0x21:
472 case 0x22:
473 printf(": TGA2 pass %d", rev - 0x20);
474 break;
475
476 default:
477 printf("unknown stepping (0x%x)", rev);
478 break;
479 }
480 printf(", ");
481
482 /*
483 * Get RAMDAC function vectors and call the RAMDAC functions
484 * to allocate its private storage and pass that back to us.
485 */
486
487 DPRINTF("tgaattach: Get RAMDAC functions\n");
488 sc->sc_dc->dc_ramdac_funcs = sc->sc_dc->dc_tgaconf->ramdac_funcs();
489 if (!sc->sc_dc->dc_tga2) {
490 DPRINTF("tgaattach: !sc->sc_dc->dc_tga2\n");
491 DPRINTF("tgaattach: sc->sc_dc->dc_tgaconf->ramdac_funcs %s "
492 "bt485_funcs\n",
493 (sc->sc_dc->dc_tgaconf->ramdac_funcs == bt485_funcs)
494 ? "==" : "!=");
495 if (sc->sc_dc->dc_tgaconf->ramdac_funcs == bt485_funcs)
496 sc->sc_dc->dc_ramdac_cookie =
497 sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc,
498 tga_sched_update, tga_ramdac_wr, tga_ramdac_rd);
499 else
500 sc->sc_dc->dc_ramdac_cookie =
501 sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc,
502 tga_sched_update, tga_bt463_wr, tga_bt463_rd);
503 } else {
504 DPRINTF("tgaattach: sc->sc_dc->dc_tga2\n");
505 sc->sc_dc->dc_ramdac_cookie =
506 sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc,
507 tga_sched_update, tga2_ramdac_wr, tga2_ramdac_rd);
508
509 /* XXX this is a bit of a hack, setting the dotclock here */
510 if (sc->sc_dc->dc_tgaconf->ramdac_funcs != bt485_funcs)
511 (*sc->sc_dc->dc_ramdac_funcs->ramdac_set_dotclock)
512 (sc->sc_dc->dc_ramdac_cookie,
513 tga_getdotclock(sc->sc_dc));
514 }
515 DPRINTF("tgaattach: sc->sc_dc->dc_ramdac_cookie = 0x%016llx\n",
516 sc->sc_dc->dc_ramdac_cookie);
517 /*
518 * Initialize the RAMDAC. Initialization includes disabling
519 * cursor, setting a sane colormap, etc.
520 */
521 DPRINTF("tgaattach: Initializing RAMDAC.\n");
522 (*sc->sc_dc->dc_ramdac_funcs->ramdac_init)(sc->sc_dc->dc_ramdac_cookie);
523 TGAWREG(sc->sc_dc, TGA_REG_SISR, 0x00000001); /* XXX */
524
525 if (sc->sc_dc->dc_tgaconf == NULL) {
526 printf("unknown board configuration\n");
527 return;
528 }
529 printf("board type %s\n", sc->sc_dc->dc_tgaconf->tgac_name);
530 printf("%s: %d x %d, %dbpp, %s RAMDAC\n", sc->sc_dev.dv_xname,
531 sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
532 sc->sc_dc->dc_tgaconf->tgac_phys_depth,
533 sc->sc_dc->dc_ramdac_funcs->ramdac_name);
534
535 if (intrstr != NULL)
536 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname,
537 intrstr);
538
539 aa.console = console;
540 aa.scrdata = &tga_screenlist;
541 aa.accessops = &tga_accessops;
542 aa.accesscookie = sc;
543 aa.defaultscreens = 0;
544
545 config_found(self, &aa, wsemuldisplaydevprint);
546
547 #ifdef __NetBSD__
548 config_interrupts(self, tga_config_interrupts);
549 #else
550 tga_config_interrupts(self);
551 #endif
552 }
553
554 void
tga_config_interrupts(d)555 tga_config_interrupts (d)
556 struct device *d;
557 {
558 struct tga_softc *sc = (struct tga_softc *)d;
559 sc->sc_dc->dc_intrenabled = 1;
560 }
561
562
563 int
tga_ioctl(v,cmd,data,flag,p)564 tga_ioctl(v, cmd, data, flag, p)
565 void *v;
566 u_long cmd;
567 caddr_t data;
568 int flag;
569 struct proc *p;
570 {
571 struct tga_softc *sc = v;
572 struct tga_devconfig *dc = sc->sc_dc;
573 struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
574 struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
575
576 switch (cmd) {
577 case WSDISPLAYIO_GTYPE:
578 *(u_int *)data = WSDISPLAY_TYPE_TGA;
579 break;
580
581 case WSDISPLAYIO_SMODE:
582 sc->sc_mode = *(u_int *)data;
583 switch (sc->sc_mode) {
584 case WSDISPLAYIO_MODE_DUMBFB:
585 /* in dump fb mode start the framebuffer at 0 */
586 TGAWREG(dc, TGA_REG_VVBR, 0);
587 break;
588 default:
589 /* XXX it this useful, except for not breaking Xtga? */
590 TGAWREG(dc, TGA_REG_VVBR, 1);
591 break;
592 }
593 break;
594
595 case WSDISPLAYIO_GINFO:
596 #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
597 wsd_fbip->height = sc->sc_dc->dc_ht;
598 wsd_fbip->width = sc->sc_dc->dc_wid;
599 wsd_fbip->depth = sc->sc_dc->dc_tgaconf->tgac_phys_depth;
600 wsd_fbip->cmsize = 1024; /* XXX ??? */
601 #undef wsd_fbip
602 break;
603
604 case WSDISPLAYIO_LINEBYTES:
605 *(u_int *)data = sc->sc_dc->dc_rowbytes;
606 break;
607
608 case WSDISPLAYIO_GETCMAP:
609 return (*dcrf->ramdac_get_cmap)(dcrc,
610 (struct wsdisplay_cmap *)data);
611 case WSDISPLAYIO_PUTCMAP:
612 return (*dcrf->ramdac_set_cmap)(dcrc,
613 (struct wsdisplay_cmap *)data);
614
615 case WSDISPLAYIO_SVIDEO:
616 case WSDISPLAYIO_GVIDEO:
617 break;
618
619 case WSDISPLAYIO_GCURPOS:
620 return (*dcrf->ramdac_get_curpos)(dcrc,
621 (struct wsdisplay_curpos *)data);
622
623 case WSDISPLAYIO_SCURPOS:
624 return (*dcrf->ramdac_set_curpos)(dcrc,
625 (struct wsdisplay_curpos *)data);
626
627 case WSDISPLAYIO_GCURMAX:
628 return (*dcrf->ramdac_get_curmax)(dcrc,
629 (struct wsdisplay_curpos *)data);
630
631 case WSDISPLAYIO_GCURSOR:
632 return (*dcrf->ramdac_get_cursor)(dcrc,
633 (struct wsdisplay_cursor *)data);
634
635 case WSDISPLAYIO_SCURSOR:
636 return (*dcrf->ramdac_set_cursor)(dcrc,
637 (struct wsdisplay_cursor *)data);
638
639 default:
640 return (-1);
641 }
642
643 return (0);
644 }
645
646 int
tga_sched_update(v,f)647 tga_sched_update(v, f)
648 void *v;
649 void (*f)(void *);
650 {
651 struct tga_devconfig *dc = v;
652
653 if (dc->dc_intrenabled) {
654 /* Arrange for f to be called at the next end-of-frame interrupt */
655 dc->dc_ramdac_intr = f;
656 TGAWREG(dc, TGA_REG_SISR, 0x00010000);
657 } else {
658 /* Spin until the end-of-frame, then call f */
659 TGAWREG(dc, TGA_REG_SISR, 0x00010001);
660 TGAREGWB(dc, TGA_REG_SISR, 1);
661 while ((TGARREG(dc, TGA_REG_SISR) & 0x00000001) == 0)
662 ;
663 f(dc->dc_ramdac_cookie);
664 TGAWREG(dc, TGA_REG_SISR, 0x00000001);
665 TGAREGWB(dc, TGA_REG_SISR, 1);
666 }
667
668 return 0;
669 }
670
671 int
tga_intr(v)672 tga_intr(v)
673 void *v;
674 {
675 struct tga_devconfig *dc = v;
676 struct ramdac_cookie *dcrc= dc->dc_ramdac_cookie;
677
678 u_int32_t reg;
679
680 reg = TGARREG(dc, TGA_REG_SISR);
681 if (( reg & 0x00010001) != 0x00010001) {
682 /* Odd. We never set any of the other interrupt enables. */
683 if ((reg & 0x1f) != 0) {
684 /* Clear the mysterious pending interrupts. */
685 TGAWREG(dc, TGA_REG_SISR, (reg & 0x1f));
686 TGAREGWB(dc, TGA_REG_SISR, 1);
687 /* This was our interrupt, even if we're puzzled as to why
688 * we got it. Don't make the interrupt handler think it
689 * was a stray.
690 */
691 return -1;
692 } else {
693 return 0;
694 }
695 }
696 /* if we have something to do, do it */
697 if (dc->dc_ramdac_intr) {
698 dc->dc_ramdac_intr(dcrc);
699 dc->dc_ramdac_intr = NULL;
700 }
701 TGAWREG(dc, TGA_REG_SISR, 0x00000001);
702 TGAREGWB(dc, TGA_REG_SISR, 1);
703 return (1);
704 }
705
706 paddr_t
tga_mmap(v,offset,prot)707 tga_mmap(v, offset, prot)
708 void *v;
709 off_t offset;
710 int prot;
711 {
712 struct tga_softc *sc = v;
713 struct tga_devconfig *dc = sc->sc_dc;
714
715 if (offset >= dc->dc_tgaconf->tgac_cspace_size || offset < 0)
716 return -1;
717
718 if (sc->sc_mode == WSDISPLAYIO_MODE_DUMBFB) {
719 /*
720 * The framebuffer starts at the upper half of tga mem
721 */
722 offset += dc->dc_tgaconf->tgac_cspace_size / 2;
723 }
724 #if defined(__alpha__) || defined(__mips__)
725 return atop(sc->sc_dc->dc_paddr + offset);
726 #else
727 return (-1);
728 #endif
729 }
730
731 int
tga_alloc_screen(v,type,cookiep,curxp,curyp,attrp)732 tga_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
733 void *v;
734 const struct wsscreen_descr *type;
735 void **cookiep;
736 int *curxp, *curyp;
737 long *attrp;
738 {
739 struct tga_softc *sc = v;
740 long defattr;
741
742 if (sc->nscreens > 0)
743 return (ENOMEM);
744
745 *cookiep = &sc->sc_dc->dc_rinfo; /* one and only for now */
746 *curxp = 0;
747 *curyp = 0;
748 sc->sc_dc->dc_rinfo.ri_ops.alloc_attr(&sc->sc_dc->dc_rinfo,
749 0, 0, 0, &defattr);
750 *attrp = defattr;
751 sc->nscreens++;
752 return (0);
753 }
754
755 void
tga_free_screen(v,cookie)756 tga_free_screen(v, cookie)
757 void *v;
758 void *cookie;
759 {
760 struct tga_softc *sc = v;
761
762 if (sc->sc_dc == &tga_console_dc)
763 panic("tga_free_screen: console");
764
765 sc->nscreens--;
766 }
767
768 int
tga_show_screen(v,cookie,waitok,cb,cbarg)769 tga_show_screen(v, cookie, waitok, cb, cbarg)
770 void *v;
771 void *cookie;
772 int waitok;
773 void (*cb)(void *, int, int);
774 void *cbarg;
775 {
776
777 return (0);
778 }
779
780 int
tga_cnattach(iot,memt,pc,bus,device,function)781 tga_cnattach(iot, memt, pc, bus, device, function)
782 bus_space_tag_t iot, memt;
783 pci_chipset_tag_t pc;
784 int bus, device, function;
785 {
786 struct tga_devconfig *dcp = &tga_console_dc;
787 long defattr;
788
789 tga_getdevconfig(memt, pc,
790 pci_make_tag(pc, bus, device, function), dcp);
791
792 /* sanity checks */
793 if (dcp->dc_vaddr == NULL)
794 panic("tga_console(%d, %d): couldn't map memory space",
795 device, function);
796 if (dcp->dc_tgaconf == NULL)
797 panic("tga_console(%d, %d): unknown board configuration",
798 device, function);
799
800 /*
801 * Initialize the RAMDAC but DO NOT allocate any private storage.
802 * Initialization includes disabling cursor, setting a sane
803 * colormap, etc. It will be reinitialized in tgaattach().
804 */
805 if (dcp->dc_tga2) {
806 if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs)
807 bt485_cninit(dcp, tga_sched_update, tga2_ramdac_wr,
808 tga2_ramdac_rd);
809 else
810 ibm561_cninit(dcp, tga_sched_update, tga2_ramdac_wr,
811 tga2_ramdac_rd, tga_getdotclock(dcp));
812 } else {
813 if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs)
814 bt485_cninit(dcp, tga_sched_update, tga_ramdac_wr,
815 tga_ramdac_rd);
816 else {
817 bt463_cninit(dcp, tga_sched_update, tga_bt463_wr,
818 tga_bt463_rd);
819 }
820 }
821 dcp->dc_rinfo.ri_ops.alloc_attr(&dcp->dc_rinfo, 0, 0, 0, &defattr);
822 wsdisplay_cnattach(&tga_stdscreen, &dcp->dc_rinfo, 0, 0, defattr);
823
824 return(0);
825 }
826
827 /*
828 * Functions to blank and unblank the display.
829 */
830 void
tga_burner(v,on,flags)831 tga_burner(v, on, flags)
832 void *v;
833 u_int on, flags;
834 {
835 struct tga_softc *sc = v;
836
837 if (on) {
838 tga_unblank(sc->sc_dc);
839 } else {
840 tga_blank(sc->sc_dc);
841 }
842 }
843
844 void
tga_blank(dc)845 tga_blank(dc)
846 struct tga_devconfig *dc;
847 {
848
849 if (!dc->dc_blanked) {
850 dc->dc_blanked = 1;
851 /* XXX */
852 TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | VVR_BLANK);
853 }
854 }
855
856 void
tga_unblank(dc)857 tga_unblank(dc)
858 struct tga_devconfig *dc;
859 {
860
861 if (dc->dc_blanked) {
862 dc->dc_blanked = 0;
863 /* XXX */
864 TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) & ~VVR_BLANK);
865 }
866 }
867
868 /*
869 * Functions to manipulate the built-in cursor handing hardware.
870 */
871 int
tga_builtin_set_cursor(dc,cursorp)872 tga_builtin_set_cursor(dc, cursorp)
873 struct tga_devconfig *dc;
874 struct wsdisplay_cursor *cursorp;
875 {
876 struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
877 struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
878 u_int count, v;
879 int error;
880
881 v = cursorp->which;
882 if (v & WSDISPLAY_CURSOR_DOCMAP) {
883 error = dcrf->ramdac_check_curcmap(dcrc, cursorp);
884 if (error)
885 return (error);
886 }
887 if (v & WSDISPLAY_CURSOR_DOSHAPE) {
888 if ((u_int)cursorp->size.x != 64 ||
889 (u_int)cursorp->size.y > 64)
890 return (EINVAL);
891 }
892 if (v & WSDISPLAY_CURSOR_DOHOT) /* not supported */
893 return EINVAL;
894
895 /* parameters are OK; do it */
896 if (v & WSDISPLAY_CURSOR_DOCUR) {
897 if (cursorp->enable)
898 /* XXX */
899 TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 0x04);
900 else
901 /* XXX */
902 TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) & ~0x04);
903 }
904 if (v & WSDISPLAY_CURSOR_DOPOS) {
905 TGAWREG(dc, TGA_REG_CXYR,
906 ((cursorp->pos.y & 0xfff) << 12) | (cursorp->pos.x & 0xfff));
907 }
908 if (v & WSDISPLAY_CURSOR_DOCMAP) {
909 /* can't fail. */
910 dcrf->ramdac_set_curcmap(dcrc, cursorp);
911 }
912 if (v & WSDISPLAY_CURSOR_DOSHAPE) {
913 /* The cursor is 2 bits deep, and there is no mask */
914 count = (cursorp->size.y * 64 * 2) / NBBY;
915 TGAWREG(dc, TGA_REG_CCBR,
916 (TGARREG(dc, TGA_REG_CCBR) & ~0xfc00) | (cursorp->size.y << 10));
917 if ((error = copyin(cursorp->image,(char *)(dc->dc_vaddr +
918 (TGARREG(dc, TGA_REG_CCBR) & 0x3ff)), count)) != 0)
919 return (error);
920 }
921 return (0);
922 }
923
924 int
tga_builtin_get_cursor(dc,cursorp)925 tga_builtin_get_cursor(dc, cursorp)
926 struct tga_devconfig *dc;
927 struct wsdisplay_cursor *cursorp;
928 {
929 struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
930 struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
931 int error;
932 u_int count;
933
934 cursorp->which = WSDISPLAY_CURSOR_DOALL &
935 ~(WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCMAP);
936 cursorp->enable = (TGARREG(dc, TGA_REG_VVVR) & 0x04) != 0;
937 cursorp->pos.x = TGARREG(dc, TGA_REG_CXYR) & 0xfff;
938 cursorp->pos.y = (TGARREG(dc, TGA_REG_CXYR) >> 12) & 0xfff;
939 cursorp->size.x = 64;
940 cursorp->size.y = (TGARREG(dc, TGA_REG_CCBR) >> 10) & 0x3f;
941
942 if (cursorp->image != NULL) {
943 count = (cursorp->size.y * 64 * 2) / NBBY;
944 error = copyout((char *)(dc->dc_vaddr +
945 (TGARREG(dc, TGA_REG_CCBR) & 0x3ff)),
946 cursorp->image, count);
947 if (error)
948 return (error);
949 /* No mask */
950 }
951 error = dcrf->ramdac_get_curcmap(dcrc, cursorp);
952 return (error);
953 }
954
955 int
tga_builtin_set_curpos(dc,curposp)956 tga_builtin_set_curpos(dc, curposp)
957 struct tga_devconfig *dc;
958 struct wsdisplay_curpos *curposp;
959 {
960
961 TGAWREG(dc, TGA_REG_CXYR,
962 ((curposp->y & 0xfff) << 12) | (curposp->x & 0xfff));
963 return (0);
964 }
965
966 int
tga_builtin_get_curpos(dc,curposp)967 tga_builtin_get_curpos(dc, curposp)
968 struct tga_devconfig *dc;
969 struct wsdisplay_curpos *curposp;
970 {
971
972 curposp->x = TGARREG(dc, TGA_REG_CXYR) & 0xfff;
973 curposp->y = (TGARREG(dc, TGA_REG_CXYR) >> 12) & 0xfff;
974 return (0);
975 }
976
977 int
tga_builtin_get_curmax(dc,curposp)978 tga_builtin_get_curmax(dc, curposp)
979 struct tga_devconfig *dc;
980 struct wsdisplay_curpos *curposp;
981 {
982
983 curposp->x = curposp->y = 64;
984 return (0);
985 }
986
987 /*
988 * Copy columns (characters) in a row (line).
989 */
990 void
tga_copycols(id,row,srccol,dstcol,ncols)991 tga_copycols(id, row, srccol, dstcol, ncols)
992 void *id;
993 int row, srccol, dstcol, ncols;
994 {
995 struct rasops_info *ri = id;
996 int y, srcx, dstx, nx;
997
998 y = ri->ri_font->fontheight * row;
999 srcx = ri->ri_font->fontwidth * srccol;
1000 dstx = ri->ri_font->fontwidth * dstcol;
1001 nx = ri->ri_font->fontwidth * ncols;
1002
1003 tga_rop(ri, dstx, y, nx, ri->ri_font->fontheight, ri, srcx, y);
1004 }
1005
1006 /*
1007 * Copy rows (lines).
1008 */
1009 void
tga_copyrows(id,srcrow,dstrow,nrows)1010 tga_copyrows(id, srcrow, dstrow, nrows)
1011 void *id;
1012 int srcrow, dstrow, nrows;
1013 {
1014 struct rasops_info *ri = id;
1015 int srcy, dsty, ny;
1016
1017 srcy = ri->ri_font->fontheight * srcrow;
1018 dsty = ri->ri_font->fontheight * dstrow;
1019 ny = ri->ri_font->fontheight * nrows;
1020
1021 tga_rop(ri, 0, dsty, ri->ri_emuwidth, ny, ri, 0, srcy);
1022 }
1023
1024 /*
1025 * Generic TGA raster op.
1026 * This covers all possible raster ops, and
1027 * clips the sizes and all of that.
1028 */
1029 int
tga_rop(dst,dx,dy,w,h,src,sx,sy)1030 tga_rop(dst, dx, dy, w, h, src, sx, sy)
1031 struct rasops_info *dst;
1032 int dx, dy, w, h;
1033 struct rasops_info *src;
1034 int sx, sy;
1035 {
1036 if (dst == NULL || src == NULL)
1037 return -1;
1038
1039 /* Clip against src */
1040 if (sx < 0) {
1041 w += sx;
1042 sx = 0;
1043 }
1044 if (sy < 0) {
1045 h += sy;
1046 sy = 0;
1047 }
1048 if (sx + w > src->ri_emuwidth)
1049 w = src->ri_emuwidth - sx;
1050 if (sy + h > src->ri_emuheight)
1051 h = src->ri_emuheight - sy;
1052
1053 /* Clip against dst. We modify src regardless of using it,
1054 * since it really doesn't matter.
1055 */
1056 if (dx < 0) {
1057 w += dx;
1058 sx -= dx;
1059 dx = 0;
1060 }
1061 if (dy < 0) {
1062 h += dy;
1063 sy -= dy;
1064 dy = 0;
1065 }
1066 if (dx + w > dst->ri_emuwidth)
1067 w = dst->ri_emuwidth - dx;
1068 if (dy + h > dst->ri_emuheight)
1069 h = dst->ri_emuheight - dy;
1070 if (w <= 0 || h <= 0)
1071 return 0; /* Vacuously true; */
1072
1073 return tga_rop_vtov(dst, dx, dy, w, h, src, sx, sy);
1074 }
1075
1076
1077
1078 /*
1079 * Video to Video raster ops.
1080 * This function deals with all raster ops that have a src and dst
1081 * that are on the card.
1082 */
1083 int
tga_rop_vtov(dst,dx,dy,w,h,src,sx,sy)1084 tga_rop_vtov(dst, dx, dy, w, h, src, sx, sy)
1085 struct rasops_info *dst;
1086 int dx, dy, w, h;
1087 struct rasops_info *src;
1088 int sx, sy;
1089 {
1090 struct tga_devconfig *dc = (struct tga_devconfig *)dst->ri_hw;
1091 int srcb, dstb, tga_srcb, tga_dstb;
1092 int x, y, wb;
1093 int xstart, xend, xdir;
1094 int ystart, yend, ydir, yinc;
1095 int xleft, lastx, lastleft;
1096 int offset = 1 * dc->dc_tgaconf->tgac_vvbr_units;
1097
1098 /*
1099 * I don't yet want to deal with unaligned guys, really. And we don't
1100 * deal with copies from one card to another.
1101 */
1102 if (dx % 8 != 0 || sx % 8 != 0 || src != dst) {
1103 /* XXX Punt! */
1104 /* XXX should never happen, since it's only being used to
1105 * XXX copy 8-pixel-wide characters.
1106 */
1107 return -1;
1108 }
1109
1110 wb = w * (dst->ri_depth / 8);
1111 if (sy >= dy) {
1112 ystart = 0;
1113 yend = h;
1114 ydir = 1;
1115 } else {
1116 ystart = h;
1117 yend = 0;
1118 ydir = -1;
1119 }
1120 if (sx >= dx) { /* moving to the left */
1121 xstart = 0;
1122 xend = w * (dst->ri_depth / 8) - 4;
1123 xdir = 1;
1124 } else { /* moving to the right */
1125 xstart = wb - ( wb >= 4*64 ? 4*64 : wb >= 64 ? 64 : 4 );
1126 xend = 0;
1127 xdir = -1;
1128 }
1129 #define XINC4 4
1130 #define XINC64 64
1131 #define XINC256 (64*4)
1132 yinc = ydir * dst->ri_stride;
1133 ystart *= dst->ri_stride;
1134 yend *= dst->ri_stride;
1135
1136 srcb = sy * src->ri_stride + sx * (src->ri_depth/8);
1137 dstb = dy * dst->ri_stride + dx * (dst->ri_depth/8);
1138 tga_srcb = offset + (sy + src->ri_yorigin) * src->ri_stride +
1139 (sx + src->ri_xorigin) * (src->ri_depth/8);
1140 tga_dstb = offset + (dy + dst->ri_yorigin) * dst->ri_stride +
1141 (dx + dst->ri_xorigin) * (dst->ri_depth/8);
1142
1143 TGAWALREG(dc, TGA_REG_GMOR, 3, 0x0007); /* Copy mode */
1144 TGAWALREG(dc, TGA_REG_GOPR, 3, 0x0003); /* SRC */
1145
1146 /*
1147 * we have 3 sizes of pixels to move in X direction:
1148 * 4 * 64 (unrolled TGA ops)
1149 * 64 (single TGA op)
1150 * 4 (CPU, using long word)
1151 */
1152
1153 if (xdir == 1) { /* move to the left */
1154
1155 for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
1156
1157 /* 4*64 byte chunks */
1158 for (xleft = wb, x = xstart;
1159 x <= xend && xleft >= 4*64;
1160 x += XINC256, xleft -= XINC256) {
1161
1162 /* XXX XXX Eight writes to different addresses should fill
1163 * XXX XXX up the write buffers on 21064 and 21164 chips,
1164 * XXX XXX but later CPUs might have larger write buffers which
1165 * XXX XXX require further unrolling of this loop, or the
1166 * XXX XXX insertion of memory barriers.
1167 */
1168 TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
1169 TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
1170 TGAWALREG(dc, TGA_REG_GCSR, 1, tga_srcb + y + x + 1 * 64);
1171 TGAWALREG(dc, TGA_REG_GCDR, 1, tga_dstb + y + x + 1 * 64);
1172 TGAWALREG(dc, TGA_REG_GCSR, 2, tga_srcb + y + x + 2 * 64);
1173 TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 2 * 64);
1174 TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 3 * 64);
1175 TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 3 * 64);
1176 }
1177
1178 /* 64 byte chunks */
1179 for ( ; x <= xend && xleft >= 64;
1180 x += XINC64, xleft -= XINC64) {
1181 TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
1182 TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
1183 }
1184 lastx = x; lastleft = xleft; /* remember for CPU loop */
1185
1186 }
1187 TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */
1188 TGAWALREG(dc, TGA_REG_GMOR, 0, 0x0000); /* Simple mode */
1189
1190 for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
1191 /* 4 byte granularity */
1192 for (x = lastx, xleft = lastleft;
1193 x <= xend && xleft >= 4;
1194 x += XINC4, xleft -= XINC4) {
1195 *(uint32_t *)(dst->ri_bits + dstb + y + x) =
1196 *(uint32_t *)(dst->ri_bits + srcb + y + x);
1197 }
1198 }
1199 }
1200 else { /* above move to the left, below move to the right */
1201
1202 for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
1203
1204 /* 4*64 byte chunks */
1205 for (xleft = wb, x = xstart;
1206 x >= xend && xleft >= 4*64;
1207 x -= XINC256, xleft -= XINC256) {
1208
1209 /* XXX XXX Eight writes to different addresses should fill
1210 * XXX XXX up the write buffers on 21064 and 21164 chips,
1211 * XXX XXX but later CPUs might have larger write buffers which
1212 * XXX XXX require further unrolling of this loop, or the
1213 * XXX XXX insertion of memory barriers.
1214 */
1215 TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 3 * 64);
1216 TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 3 * 64);
1217 TGAWALREG(dc, TGA_REG_GCSR, 1, tga_srcb + y + x + 2 * 64);
1218 TGAWALREG(dc, TGA_REG_GCDR, 1, tga_dstb + y + x + 2 * 64);
1219 TGAWALREG(dc, TGA_REG_GCSR, 2, tga_srcb + y + x + 1 * 64);
1220 TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 1 * 64);
1221 TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 0 * 64);
1222 TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 0 * 64);
1223 }
1224
1225 if (xleft) x += XINC256 - XINC64;
1226
1227 /* 64 byte chunks */
1228 for ( ; x >= xend && xleft >= 64;
1229 x -= XINC64, xleft -= XINC64) {
1230 TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
1231 TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
1232 }
1233 if (xleft) x += XINC64 - XINC4;
1234 lastx = x; lastleft = xleft; /* remember for CPU loop */
1235 }
1236 TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */
1237 TGAWALREG(dc, TGA_REG_GMOR, 0, 0x0000); /* Simple mode */
1238
1239 for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
1240 /* 4 byte granularity */
1241 for (x = lastx, xleft = lastleft;
1242 x >= xend && xleft >= 4;
1243 x -= XINC4, xleft -= XINC4) {
1244 *(uint32_t *)(dst->ri_bits + dstb + y + x) =
1245 *(uint32_t *)(dst->ri_bits + srcb + y + x);
1246 }
1247 }
1248 }
1249 return 0;
1250 }
1251
1252
1253 void
tga_putchar(c,row,col,uc,attr)1254 tga_putchar(c, row, col, uc, attr)
1255 void *c;
1256 int row, col;
1257 u_int uc;
1258 long attr;
1259 {
1260 struct rasops_info *ri = c;
1261 struct tga_devconfig *dc = ri->ri_hw;
1262 int fs, height, width;
1263 int fg, bg, ulflag;
1264 u_char *fr;
1265 int32_t *rp;
1266
1267 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
1268
1269 height = ri->ri_font->fontheight;
1270 width = ri->ri_font->fontwidth;
1271
1272 uc -= ri->ri_font->firstchar;
1273 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
1274 fs = ri->ri_font->stride;
1275
1276 /* Set foreground and background color. XXX memoize this somehow?
1277 * The rasops code has already expanded the color entry to 32 bits
1278 * for us, even for 8-bit displays, so we don't have to do anything.
1279 */
1280 ri->ri_ops.unpack_attr(c, attr, &fg, &bg, &ulflag);
1281 TGAWREG(dc, TGA_REG_GFGR, ri->ri_devcmap[fg]);
1282 TGAWREG(dc, TGA_REG_GBGR, ri->ri_devcmap[bg]);
1283
1284 /* Set raster operation to "copy"... */
1285 if (ri->ri_depth == 8)
1286 TGAWREG(dc, TGA_REG_GOPR, 0x3);
1287 else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
1288 TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8));
1289
1290 /* Set which pixels we're drawing (of a possible 32). */
1291 TGAWREG(dc, TGA_REG_GPXR_P, (1 << width) - 1);
1292
1293 /* Set drawing mode to opaque stipple. */
1294 TGAWREG(dc, TGA_REG_GMOR, 0x1);
1295
1296 /* Insert write barrier before actually sending data */
1297 /* XXX Abuses the fact that there is only one write barrier on Alphas */
1298 TGAREGWB(dc, TGA_REG_GMOR, 1);
1299
1300 while (height--) {
1301 /* The actual stipple write */
1302 *rp = fr[0] | (fr[1] << 8) | (fr[2] << 16) | (fr[3] << 24);
1303
1304 fr += fs;
1305 rp = (int32_t *)((caddr_t)rp + ri->ri_stride);
1306 }
1307
1308 /* Do underline */
1309 if (ulflag & WSATTR_UNDERLINE) {
1310 rp = (int32_t *)((caddr_t)rp - (ri->ri_stride << 1));
1311 *rp = 0xffffffff;
1312 }
1313
1314 /* Set grapics mode back to normal. */
1315 TGAWREG(dc, TGA_REG_GMOR, 0);
1316 TGAWREG(dc, TGA_REG_GPXR_P, 0xffffffff);
1317 }
1318
1319 void
tga_eraserows(c,row,num,attr)1320 tga_eraserows(c, row, num, attr)
1321 void *c;
1322 int row, num;
1323 long attr;
1324 {
1325 struct rasops_info *ri = c;
1326 struct tga_devconfig *dc = ri->ri_hw;
1327 int32_t color, lines, pixels;
1328 int fg, bg;
1329 int32_t *rp;
1330
1331 ri->ri_ops.unpack_attr(c, attr, &fg, &bg, NULL);
1332 color = ri->ri_devcmap[bg];
1333 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale);
1334 lines = num * ri->ri_font->fontheight;
1335 pixels = ri->ri_emuwidth - 1;
1336
1337 /* Set fill color in block-color registers */
1338 TGAWREG(dc, TGA_REG_GBCR0, color);
1339 TGAWREG(dc, TGA_REG_GBCR1, color);
1340 if (ri->ri_depth != 8) {
1341 TGAWREG(dc, TGA_REG_GBCR2, color);
1342 TGAWREG(dc, TGA_REG_GBCR3, color);
1343 TGAWREG(dc, TGA_REG_GBCR4, color);
1344 TGAWREG(dc, TGA_REG_GBCR5, color);
1345 TGAWREG(dc, TGA_REG_GBCR6, color);
1346 TGAWREG(dc, TGA_REG_GBCR7, color);
1347 }
1348
1349 /* Set raster operation to "copy"... */
1350 if (ri->ri_depth == 8)
1351 TGAWREG(dc, TGA_REG_GOPR, 0x3);
1352 else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
1353 TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8));
1354
1355 /* Set which pixels we're drawing (of a possible 32). */
1356 TGAWREG(dc, TGA_REG_GDAR, 0xffffffff);
1357
1358 /* Set drawing mode to block fill. */
1359 TGAWREG(dc, TGA_REG_GMOR, 0x2d);
1360
1361 /* Insert write barrier before actually sending data */
1362 /* XXX Abuses the fact that there is only one write barrier on Alphas */
1363 TGAREGWB(dc, TGA_REG_GMOR, 1);
1364
1365 while (lines--) {
1366 *rp = pixels;
1367 rp = (int32_t *)((caddr_t)rp + ri->ri_stride);
1368 }
1369
1370 /* Set grapics mode back to normal. */
1371 TGAWREG(dc, TGA_REG_GMOR, 0);
1372
1373 }
1374
1375 void
tga_erasecols(c,row,col,num,attr)1376 tga_erasecols (c, row, col, num, attr)
1377 void *c;
1378 int row, col, num;
1379 long attr;
1380 {
1381 struct rasops_info *ri = c;
1382 struct tga_devconfig *dc = ri->ri_hw;
1383 int32_t color, lines, pixels;
1384 int fg, bg;
1385 int32_t *rp;
1386
1387 ri->ri_ops.unpack_attr(c, attr, &fg, &bg, NULL);
1388 color = ri->ri_devcmap[bg];
1389 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
1390 lines = ri->ri_font->fontheight;
1391 pixels = (num * ri->ri_font->fontwidth) - 1;
1392
1393 /* Set fill color in block-color registers */
1394 TGAWREG(dc, TGA_REG_GBCR0, color);
1395 TGAWREG(dc, TGA_REG_GBCR1, color);
1396 if (ri->ri_depth != 8) {
1397 TGAWREG(dc, TGA_REG_GBCR2, color);
1398 TGAWREG(dc, TGA_REG_GBCR3, color);
1399 TGAWREG(dc, TGA_REG_GBCR4, color);
1400 TGAWREG(dc, TGA_REG_GBCR5, color);
1401 TGAWREG(dc, TGA_REG_GBCR6, color);
1402 TGAWREG(dc, TGA_REG_GBCR7, color);
1403 }
1404
1405 /* Set raster operation to "copy"... */
1406 if (ri->ri_depth == 8)
1407 TGAWREG(dc, TGA_REG_GOPR, 0x3);
1408 else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
1409 TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8));
1410
1411 /* Set which pixels we're drawing (of a possible 32). */
1412 TGAWREG(dc, TGA_REG_GDAR, 0xffffffff);
1413
1414 /* Set drawing mode to block fill. */
1415 TGAWREG(dc, TGA_REG_GMOR, 0x2d);
1416
1417 /* Insert write barrier before actually sending data */
1418 /* XXX Abuses the fact that there is only one write barrier on Alphas */
1419 TGAREGWB(dc, TGA_REG_GMOR, 1);
1420
1421 while (lines--) {
1422 *rp = pixels;
1423 rp = (int32_t *)((caddr_t)rp + ri->ri_stride);
1424 }
1425
1426 /* Set grapics mode back to normal. */
1427 TGAWREG(dc, TGA_REG_GMOR, 0);
1428 }
1429
1430
1431 void
tga_ramdac_wr(v,btreg,val)1432 tga_ramdac_wr(v, btreg, val)
1433 void *v;
1434 u_int btreg;
1435 u_int8_t val;
1436 {
1437 struct tga_devconfig *dc = v;
1438
1439 if (btreg > BT485_REG_MAX)
1440 panic("tga_ramdac_wr: reg %d out of range", btreg);
1441
1442 TGAWREG(dc, TGA_REG_EPDR, (btreg << 9) | (0 << 8 ) | val); /* XXX */
1443 TGAREGWB(dc, TGA_REG_EPDR, 1);
1444 }
1445
1446 void
tga2_ramdac_wr(v,btreg,val)1447 tga2_ramdac_wr(v, btreg, val)
1448 void *v;
1449 u_int btreg;
1450 u_int8_t val;
1451 {
1452 struct tga_devconfig *dc = v;
1453 bus_space_handle_t ramdac;
1454
1455 if (btreg > BT485_REG_MAX)
1456 panic("tga_ramdac_wr: reg %d out of range", btreg);
1457
1458 bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_RAMDAC +
1459 (0xe << 12) + (btreg << 8), 4, &ramdac);
1460 bus_space_write_4(dc->dc_memt, ramdac, 0, val & 0xff);
1461 bus_space_barrier(dc->dc_memt, ramdac, 0, 4, BUS_SPACE_BARRIER_WRITE);
1462 }
1463
1464 u_int8_t
tga_bt463_rd(v,btreg)1465 tga_bt463_rd(v, btreg)
1466 void *v;
1467 u_int btreg;
1468 {
1469 struct tga_devconfig *dc = v;
1470 tga_reg_t rdval;
1471
1472 /*
1473 * Strobe CE# (high->low->high) since status and data are latched on
1474 * the falling and rising edges (repsectively) of this active-low signal.
1475 */
1476
1477 TGAREGWB(dc, TGA_REG_EPSR, 1);
1478 TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
1479 TGAREGWB(dc, TGA_REG_EPSR, 1);
1480 TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 0);
1481
1482 TGAREGRB(dc, TGA_REG_EPSR, 1);
1483
1484 rdval = TGARREG(dc, TGA_REG_EPDR);
1485 TGAREGWB(dc, TGA_REG_EPSR, 1);
1486 TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
1487
1488 return (rdval >> 16) & 0xff;
1489 }
1490
1491 void
tga_bt463_wr(v,btreg,val)1492 tga_bt463_wr(v, btreg, val)
1493 void *v;
1494 u_int btreg;
1495 u_int8_t val;
1496 {
1497 struct tga_devconfig *dc = v;
1498
1499 /*
1500 * In spite of the 21030 documentation, to set the MPU bus bits for
1501 * a write, you set them in the upper bits of EPDR, not EPSR.
1502 */
1503
1504 /*
1505 * Strobe CE# (high->low->high) since status and data are latched on
1506 * the falling and rising edges of this active-low signal.
1507 */
1508
1509 TGAREGWB(dc, TGA_REG_EPDR, 1);
1510 TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
1511 TGAREGWB(dc, TGA_REG_EPDR, 1);
1512 TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x000 | val);
1513 TGAREGWB(dc, TGA_REG_EPDR, 1);
1514 TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
1515
1516 }
1517
1518 u_int8_t
tga_ramdac_rd(v,btreg)1519 tga_ramdac_rd(v, btreg)
1520 void *v;
1521 u_int btreg;
1522 {
1523 struct tga_devconfig *dc = v;
1524 tga_reg_t rdval;
1525
1526 if (btreg > BT485_REG_MAX)
1527 panic("tga_ramdac_rd: reg %d out of range", btreg);
1528
1529 TGAWREG(dc, TGA_REG_EPSR, (btreg << 1) | 0x1); /* XXX */
1530 TGAREGWB(dc, TGA_REG_EPSR, 1);
1531
1532 rdval = TGARREG(dc, TGA_REG_EPDR);
1533 return (rdval >> 16) & 0xff; /* XXX */
1534 }
1535
1536 u_int8_t
tga2_ramdac_rd(v,btreg)1537 tga2_ramdac_rd(v, btreg)
1538 void *v;
1539 u_int btreg;
1540 {
1541 struct tga_devconfig *dc = v;
1542 bus_space_handle_t ramdac;
1543 u_int8_t retval;
1544
1545 if (btreg > BT485_REG_MAX)
1546 panic("tga_ramdac_rd: reg %d out of range", btreg);
1547
1548 bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_RAMDAC +
1549 (0xe << 12) + (btreg << 8), 4, &ramdac);
1550 retval = bus_space_read_4(dc->dc_memt, ramdac, 0) & 0xff;
1551 bus_space_barrier(dc->dc_memt, ramdac, 0, 4, BUS_SPACE_BARRIER_READ);
1552 return retval;
1553 }
1554
1555 #include <dev/ic/decmonitors.c>
1556 void tga2_ics9110_wr(
1557 struct tga_devconfig *dc,
1558 int dotclock
1559 );
1560
1561 struct monitor *tga_getmonitor(struct tga_devconfig *dc);
1562
1563 void
tga2_init(dc)1564 tga2_init(dc)
1565 struct tga_devconfig *dc;
1566 {
1567 struct monitor *m = tga_getmonitor(dc);
1568
1569
1570 /* Deal with the dot clocks.
1571 */
1572 if (dc->dc_tga_type == TGA_TYPE_POWERSTORM_4D20) {
1573 /* Set this up as a reference clock for the
1574 * ibm561's PLL.
1575 */
1576 tga2_ics9110_wr(dc, 14300000);
1577 /* XXX Can't set up the dotclock properly, until such time
1578 * as the RAMDAC is configured.
1579 */
1580 } else {
1581 /* otherwise the ics9110 is our clock. */
1582 tga2_ics9110_wr(dc, m->dotclock);
1583 }
1584 #if 0
1585 TGAWREG(dc, TGA_REG_VHCR,
1586 ((m->hbp / 4) << 21) |
1587 ((m->hsync / 4) << 14) |
1588 (((m->hfp - 4) / 4) << 9) |
1589 ((m->cols + 4) / 4));
1590 #else
1591 TGAWREG(dc, TGA_REG_VHCR,
1592 ((m->hbp / 4) << 21) |
1593 ((m->hsync / 4) << 14) |
1594 (((m->hfp) / 4) << 9) |
1595 ((m->cols) / 4));
1596 #endif
1597 TGAWREG(dc, TGA_REG_VVCR,
1598 (m->vbp << 22) |
1599 (m->vsync << 16) |
1600 (m->vfp << 11) |
1601 (m->rows));
1602 TGAWREG(dc, TGA_REG_VVBR, 1);
1603 TGAREGRWB(dc, TGA_REG_VHCR, 3);
1604 TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 1);
1605 TGAREGRWB(dc, TGA_REG_VVVR, 1);
1606 TGAWREG(dc, TGA_REG_GPMR, 0xffffffff);
1607 TGAREGRWB(dc, TGA_REG_GPMR, 1);
1608 }
1609
1610 void
tga2_ics9110_wr(dc,dotclock)1611 tga2_ics9110_wr(dc, dotclock)
1612 struct tga_devconfig *dc;
1613 int dotclock;
1614 {
1615 bus_space_handle_t clock;
1616 u_int32_t valU;
1617 int N, M, R, V, X;
1618 int i;
1619
1620 switch (dotclock) {
1621 case 130808000:
1622 N = 0x40; M = 0x7; V = 0x0; X = 0x1; R = 0x1; break;
1623 case 119840000:
1624 N = 0x2d; M = 0x2b; V = 0x1; X = 0x1; R = 0x1; break;
1625 case 108180000:
1626 N = 0x11; M = 0x9; V = 0x1; X = 0x1; R = 0x2; break;
1627 case 103994000:
1628 N = 0x6d; M = 0xf; V = 0x0; X = 0x1; R = 0x1; break;
1629 case 175000000:
1630 N = 0x5F; M = 0x3E; V = 0x1; X = 0x1; R = 0x1; break;
1631 case 75000000:
1632 N = 0x6e; M = 0x15; V = 0x0; X = 0x1; R = 0x1; break;
1633 case 74000000:
1634 N = 0x2a; M = 0x41; V = 0x1; X = 0x1; R = 0x1; break;
1635 case 69000000:
1636 N = 0x35; M = 0xb; V = 0x0; X = 0x1; R = 0x1; break;
1637 case 65000000:
1638 N = 0x6d; M = 0x0c; V = 0x0; X = 0x1; R = 0x2; break;
1639 case 50000000:
1640 N = 0x37; M = 0x3f; V = 0x1; X = 0x1; R = 0x2; break;
1641 case 40000000:
1642 N = 0x5f; M = 0x11; V = 0x0; X = 0x1; R = 0x2; break;
1643 case 31500000:
1644 N = 0x16; M = 0x05; V = 0x0; X = 0x1; R = 0x2; break;
1645 case 25175000:
1646 N = 0x66; M = 0x1d; V = 0x0; X = 0x1; R = 0x2; break;
1647 case 135000000:
1648 N = 0x42; M = 0x07; V = 0x0; X = 0x1; R = 0x1; break;
1649 case 110000000:
1650 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
1651 case 202500000:
1652 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
1653 case 14300000: /* this one is just a ref clock */
1654 N = 0x03; M = 0x03; V = 0x1; X = 0x1; R = 0x3; break;
1655 default:
1656 panic("unrecognized clock rate %d", dotclock);
1657 }
1658
1659 /* XXX -- hard coded, bad */
1660 valU = N | ( M << 7 ) | (V << 14);
1661 valU |= (X << 15) | (R << 17);
1662 valU |= 0x17 << 19;
1663
1664 bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_EXTDEV +
1665 TGA2_MEM_CLOCK + (0xe << 12), 4, &clock); /* XXX */
1666
1667 for (i = 24; i > 0; i--) {
1668 u_int32_t writeval;
1669
1670 writeval = valU & 0x1;
1671 if (i == 1)
1672 writeval |= 0x2;
1673 valU >>= 1;
1674 bus_space_write_4(dc->dc_memt, clock, 0, writeval);
1675 bus_space_barrier(dc->dc_memt, clock, 0, 4, BUS_SPACE_BARRIER_WRITE);
1676 }
1677 bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_EXTDEV +
1678 TGA2_MEM_CLOCK + (0xe << 12) + (0x1 << 11) + (0x1 << 11), 4,
1679 &clock); /* XXX */
1680 bus_space_write_4(dc->dc_memt, clock, 0, 0x0);
1681 bus_space_barrier(dc->dc_memt, clock, 0, 0, BUS_SPACE_BARRIER_WRITE);
1682 }
1683
1684 struct monitor *
tga_getmonitor(dc)1685 tga_getmonitor(dc)
1686 struct tga_devconfig *dc;
1687 {
1688 return &decmonitors[(~TGARREG(dc, TGA_REG_GREV) >> 16) & 0x0f];
1689 }
1690
1691 unsigned
tga_getdotclock(dc)1692 tga_getdotclock(dc)
1693 struct tga_devconfig *dc;
1694 {
1695 return tga_getmonitor(dc)->dotclock;
1696 }
1697