tga.c revision 1.19 1 /* $NetBSD: tga.c,v 1.19 2000/03/05 07:57:52 elric Exp $ */
2
3 /*
4 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
5 * All rights reserved.
6 *
7 * Author: Chris G. Demetriou
8 *
9 * Permission to use, copy, modify and distribute this software and
10 * its documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation.
14 *
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 *
19 * Carnegie Mellon requests users of this software to return to
20 *
21 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
22 * School of Computer Science
23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890
25 *
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
28 */
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/device.h>
34 #include <sys/conf.h>
35 #include <sys/malloc.h>
36 #include <sys/buf.h>
37 #include <sys/ioctl.h>
38
39 #include <vm/vm.h>
40
41 #include <machine/bus.h>
42 #include <machine/intr.h>
43
44 #include <dev/pci/pcireg.h>
45 #include <dev/pci/pcivar.h>
46 #include <dev/pci/pcidevs.h>
47 #include <dev/pci/tgareg.h>
48 #include <dev/pci/tgavar.h>
49 #include <dev/ic/bt485reg.h>
50 #include <dev/ic/bt485var.h>
51
52 #include <dev/rcons/raster.h>
53 #include <dev/wscons/wsconsio.h>
54 #include <dev/wscons/wscons_raster.h>
55 #include <dev/wscons/wsdisplayvar.h>
56
57 #ifdef __alpha__
58 #include <machine/pte.h>
59 #endif
60
61 int tgamatch __P((struct device *, struct cfdata *, void *));
62 void tgaattach __P((struct device *, struct device *, void *));
63 int tgaprint __P((void *, const char *));
64
65 struct cfattach tga_ca = {
66 sizeof(struct tga_softc), tgamatch, tgaattach,
67 };
68
69 int tga_identify __P((tga_reg_t *));
70 const struct tga_conf *tga_getconf __P((int));
71 void tga_getdevconfig __P((bus_space_tag_t memt, pci_chipset_tag_t pc,
72 pcitag_t tag, struct tga_devconfig *dc));
73
74 struct tga_devconfig tga_console_dc;
75
76 int tga_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
77 int tga_mmap __P((void *, off_t, int));
78 static void tga_copyrows __P((void *, int, int, int));
79 static void tga_copycols __P((void *, int, int, int, int));
80 static int tga_alloc_screen __P((void *, const struct wsscreen_descr *,
81 void **, int *, int *, long *));
82 static void tga_free_screen __P((void *, void *));
83 static int tga_show_screen __P((void *, void *, int,
84 void (*) (void *, int, int), void *));
85 static int tga_rop __P((struct raster *, int, int, int, int, int,
86 struct raster *, int, int));
87 static int tga_rop_nosrc __P((struct raster *, int, int, int, int, int));
88 static int tga_rop_htov __P((struct raster *, int, int, int, int,
89 int, struct raster *, int, int ));
90 static int tga_rop_vtov __P((struct raster *, int, int, int, int,
91 int, struct raster *, int, int ));
92 void tga2_init __P((struct tga_devconfig *, int));
93
94 /* RAMDAC interface functions */
95 int tga_sched_update __P((void *, void (*)(void *)));
96 void tga_ramdac_wr __P((void *, u_int, u_int8_t));
97 u_int8_t tga_ramdac_rd __P((void *, u_int));
98 void tga2_ramdac_wr __P((void *, u_int, u_int8_t));
99 u_int8_t tga2_ramdac_rd __P((void *, u_int));
100
101 /* Interrupt handler */
102 int tga_intr __P((void *));
103
104 struct wsdisplay_emulops tga_emulops = {
105 rcons_cursor, /* could use hardware cursor; punt */
106 rcons_mapchar,
107 rcons_putchar,
108 tga_copycols,
109 rcons_erasecols,
110 tga_copyrows,
111 rcons_eraserows,
112 rcons_alloc_attr
113 };
114
115 struct wsscreen_descr tga_stdscreen = {
116 "std",
117 0, 0, /* will be filled in -- XXX shouldn't, it's global */
118 &tga_emulops,
119 0, 0,
120 WSSCREEN_REVERSE
121 };
122
123 const struct wsscreen_descr *_tga_scrlist[] = {
124 &tga_stdscreen,
125 /* XXX other formats, graphics screen? */
126 };
127
128 struct wsscreen_list tga_screenlist = {
129 sizeof(_tga_scrlist) / sizeof(struct wsscreen_descr *), _tga_scrlist
130 };
131
132 struct wsdisplay_accessops tga_accessops = {
133 tga_ioctl,
134 tga_mmap,
135 tga_alloc_screen,
136 tga_free_screen,
137 tga_show_screen,
138 0 /* load_font */
139 };
140
141 void tga_blank __P((struct tga_devconfig *));
142 void tga_unblank __P((struct tga_devconfig *));
143
144 int
145 tgamatch(parent, match, aux)
146 struct device *parent;
147 struct cfdata *match;
148 void *aux;
149 {
150 struct pci_attach_args *pa = aux;
151
152 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_DEC)
153 return (0);
154
155 switch (PCI_PRODUCT(pa->pa_id)) {
156 case PCI_PRODUCT_DEC_21030:
157 case PCI_PRODUCT_DEC_PBXGB:
158 return 10;
159 default:
160 return 0;
161 }
162 return (0);
163 }
164
165 void
166 tga_getdevconfig(memt, pc, tag, dc)
167 bus_space_tag_t memt;
168 pci_chipset_tag_t pc;
169 pcitag_t tag;
170 struct tga_devconfig *dc;
171 {
172 const struct tga_conf *tgac;
173 struct raster *rap;
174 struct rcons *rcp;
175 bus_size_t pcisize;
176 int i, flags;
177
178 dc->dc_memt = memt;
179 dc->dc_pc = pc;
180
181 dc->dc_pcitag = tag;
182
183 /* XXX magic number */
184 if (pci_mapreg_info(pc, tag, 0x10,
185 PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
186 &dc->dc_pcipaddr, &pcisize, &flags))
187 return;
188 if ((flags & BUS_SPACE_MAP_PREFETCHABLE) == 0) /* XXX */
189 panic("tga memory not prefetchable");
190
191 if (bus_space_map(memt, dc->dc_pcipaddr, pcisize,
192 BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR, &dc->dc_vaddr))
193 return;
194 #ifdef __alpha__
195 dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr); /* XXX */
196 #endif
197
198 dc->dc_regs = (tga_reg_t *)(dc->dc_vaddr + TGA_MEM_CREGS);
199 dc->dc_tga_type = tga_identify(dc->dc_regs);
200
201 tgac = dc->dc_tgaconf = tga_getconf(dc->dc_tga_type);
202 if (tgac == NULL)
203 return;
204
205 #if 0
206 /* XXX on the Alpha, pcisize = 4 * cspace_size. */
207 if (tgac->tgac_cspace_size != pcisize) /* sanity */
208 panic("tga_getdevconfig: memory size mismatch?");
209 #endif
210
211 switch (dc->dc_regs[TGA_REG_GREV] & 0xff) {
212 case 0x01:
213 case 0x02:
214 case 0x03:
215 case 0x04:
216 dc->dc_tga2 = 0;
217 break;
218 case 0x20:
219 case 0x21:
220 case 0x22:
221 dc->dc_tga2 = 1;
222 break;
223 default:
224 panic("tga_getdevconfig: TGA Revision not recognized");
225 }
226
227 if (dc->dc_tga2) {
228 int monitor;
229
230 monitor = (~dc->dc_regs[TGA_REG_GREV] >> 16) & 0x0f;
231 tga2_init(dc, monitor);
232 }
233
234 switch (dc->dc_regs[TGA_REG_VHCR] & 0x1ff) { /* XXX */
235 case 0:
236 dc->dc_wid = 8192;
237 break;
238
239 case 1:
240 dc->dc_wid = 8196;
241 break;
242
243 default:
244 dc->dc_wid = (dc->dc_regs[TGA_REG_VHCR] & 0x1ff) * 4; /* XXX */
245 break;
246 }
247
248 dc->dc_rowbytes = dc->dc_wid * (dc->dc_tgaconf->tgac_phys_depth / 8);
249
250 if ((dc->dc_regs[TGA_REG_VHCR] & 0x00000001) != 0 && /* XXX */
251 (dc->dc_regs[TGA_REG_VHCR] & 0x80000000) != 0) { /* XXX */
252 dc->dc_wid -= 4;
253 /*
254 * XXX XXX turning off 'odd' shouldn't be necesssary,
255 * XXX XXX but i can't make X work with the weird size.
256 */
257 dc->dc_regs[TGA_REG_VHCR] &= ~0x80000001;
258 dc->dc_rowbytes =
259 dc->dc_wid * (dc->dc_tgaconf->tgac_phys_depth / 8);
260 }
261
262 dc->dc_ht = (dc->dc_regs[TGA_REG_VVCR] & 0x7ff); /* XXX */
263
264 /* XXX this seems to be what DEC does */
265 dc->dc_regs[TGA_REG_CCBR] = 0;
266 dc->dc_regs[TGA_REG_VVBR] = 1;
267 dc->dc_videobase = dc->dc_vaddr + tgac->tgac_dbuf[0] +
268 1 * tgac->tgac_vvbr_units;
269 dc->dc_blanked = 1;
270 tga_unblank(dc);
271
272 /*
273 * Set all bits in the pixel mask, to enable writes to all pixels.
274 * It seems that the console firmware clears some of them
275 * under some circumstances, which causes cute vertical stripes.
276 */
277 dc->dc_regs[TGA_REG_GPXR_P] = 0xffffffff;
278
279 /* clear the screen */
280 for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t))
281 *(u_int32_t *)(dc->dc_videobase + i) = 0;
282
283 /* initialize the raster */
284 rap = &dc->dc_raster;
285 rap->width = dc->dc_wid;
286 rap->height = dc->dc_ht;
287 rap->depth = tgac->tgac_phys_depth;
288 rap->linelongs = dc->dc_rowbytes / sizeof(u_int32_t);
289 rap->pixels = (u_int32_t *)dc->dc_videobase;
290 rap->data = (caddr_t)dc;
291
292 /* initialize the raster console blitter */
293 rcp = &dc->dc_rcons;
294 rcp->rc_sp = rap;
295 rcp->rc_crow = rcp->rc_ccol = -1;
296 rcp->rc_crowp = &rcp->rc_crow;
297 rcp->rc_ccolp = &rcp->rc_ccol;
298 rcons_init(rcp, 34, 80);
299
300 tga_stdscreen.nrows = dc->dc_rcons.rc_maxrow;
301 tga_stdscreen.ncols = dc->dc_rcons.rc_maxcol;
302 }
303
304 void
305 tgaattach(parent, self, aux)
306 struct device *parent, *self;
307 void *aux;
308 {
309 struct pci_attach_args *pa = aux;
310 struct tga_softc *sc = (struct tga_softc *)self;
311 struct wsemuldisplaydev_attach_args aa;
312 pci_intr_handle_t intrh;
313 const char *intrstr;
314 u_int8_t rev;
315 int console;
316
317 #ifdef __alpha__
318 console = (pa->pa_tag == tga_console_dc.dc_pcitag);
319 #else
320 console = 0;
321 #endif
322 if (console) {
323 sc->sc_dc = &tga_console_dc;
324 sc->nscreens = 1;
325 } else {
326 sc->sc_dc = (struct tga_devconfig *)
327 malloc(sizeof(struct tga_devconfig), M_DEVBUF, M_WAITOK);
328 bzero(sc->sc_dc, sizeof(struct tga_devconfig));
329 tga_getdevconfig(pa->pa_memt, pa->pa_pc, pa->pa_tag,
330 sc->sc_dc);
331 }
332 if (sc->sc_dc->dc_vaddr == NULL) {
333 printf(": couldn't map memory space; punt!\n");
334 return;
335 }
336
337 /* XXX say what's going on. */
338 intrstr = NULL;
339 if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
340 pa->pa_intrline, &intrh)) {
341 printf(": couldn't map interrupt");
342 return;
343 }
344 intrstr = pci_intr_string(pa->pa_pc, intrh);
345 sc->sc_intr = pci_intr_establish(pa->pa_pc, intrh, IPL_TTY, tga_intr,
346 sc->sc_dc);
347 if (sc->sc_intr == NULL) {
348 printf(": couldn't establish interrupt");
349 if (intrstr != NULL)
350 printf("at %s", intrstr);
351 printf("\n");
352 return;
353 }
354
355 rev = PCI_REVISION(pa->pa_class);
356 switch (rev) {
357 case 0x1:
358 case 0x2:
359 case 0x3:
360 printf(": DC21030 step %c", 'A' + rev - 1);
361 break;
362 case 0x20:
363 printf(": TGA2 abstract software model");
364 break;
365 case 0x21:
366 case 0x22:
367 printf(": TGA2 pass %d", rev - 0x20);
368 break;
369
370 default:
371 printf("unknown stepping (0x%x)", rev);
372 break;
373 }
374 printf(", ");
375
376 /*
377 * Get RAMDAC function vectors and call the RAMDAC functions
378 * to allocate its private storage and pass that back to us.
379 */
380 sc->sc_dc->dc_ramdac_funcs = bt485_funcs();
381 if (!sc->sc_dc->dc_tga2) {
382 sc->sc_dc->dc_ramdac_cookie = bt485_register(
383 sc->sc_dc, tga_sched_update, tga_ramdac_wr,
384 tga_ramdac_rd);
385 } else {
386 sc->sc_dc->dc_ramdac_cookie = bt485_register(
387 sc->sc_dc, tga_sched_update, tga2_ramdac_wr,
388 tga2_ramdac_rd);
389 }
390
391 /*
392 * Initialize the RAMDAC. Initialization includes disabling
393 * cursor, setting a sane colormap, etc.
394 */
395 (*sc->sc_dc->dc_ramdac_funcs->ramdac_init)(sc->sc_dc->dc_ramdac_cookie);
396 sc->sc_dc->dc_regs[TGA_REG_SISR] = 0x00000001; /* XXX */
397
398 if (sc->sc_dc->dc_tgaconf == NULL) {
399 printf("unknown board configuration\n");
400 return;
401 }
402 printf("board type %s\n", sc->sc_dc->dc_tgaconf->tgac_name);
403 printf("%s: %d x %d, %dbpp, %s RAMDAC\n", sc->sc_dev.dv_xname,
404 sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
405 sc->sc_dc->dc_tgaconf->tgac_phys_depth,
406 sc->sc_dc->dc_ramdac_funcs->ramdac_name);
407
408 if (intrstr != NULL)
409 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname,
410 intrstr);
411
412 aa.console = console;
413 aa.scrdata = &tga_screenlist;
414 aa.accessops = &tga_accessops;
415 aa.accesscookie = sc;
416
417 config_found(self, &aa, wsemuldisplaydevprint);
418 }
419
420 int
421 tga_ioctl(v, cmd, data, flag, p)
422 void *v;
423 u_long cmd;
424 caddr_t data;
425 int flag;
426 struct proc *p;
427 {
428 struct tga_softc *sc = v;
429 struct tga_devconfig *dc = sc->sc_dc;
430 struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
431 struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
432
433 switch (cmd) {
434 case WSDISPLAYIO_GTYPE:
435 *(u_int *)data = WSDISPLAY_TYPE_TGA;
436 return (0);
437
438 case WSDISPLAYIO_GINFO:
439 #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
440 wsd_fbip->height = sc->sc_dc->dc_ht;
441 wsd_fbip->width = sc->sc_dc->dc_wid;
442 wsd_fbip->depth = sc->sc_dc->dc_tgaconf->tgac_phys_depth;
443 wsd_fbip->cmsize = 256; /* XXX ??? */
444 #undef wsd_fbip
445 return (0);
446
447 case WSDISPLAYIO_GETCMAP:
448 return (*dcrf->ramdac_get_cmap)(dcrc,
449 (struct wsdisplay_cmap *)data);
450
451 case WSDISPLAYIO_PUTCMAP:
452 return (*dcrf->ramdac_set_cmap)(dcrc,
453 (struct wsdisplay_cmap *)data);
454
455 case WSDISPLAYIO_SVIDEO:
456 if (*(u_int *)data == WSDISPLAYIO_VIDEO_OFF)
457 tga_blank(sc->sc_dc);
458 else
459 tga_unblank(sc->sc_dc);
460 return (0);
461
462 case WSDISPLAYIO_GVIDEO:
463 *(u_int *)data = dc->dc_blanked ?
464 WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON;
465 return (0);
466
467 case WSDISPLAYIO_GCURPOS:
468 return (*dcrf->ramdac_get_curpos)(dcrc,
469 (struct wsdisplay_curpos *)data);
470
471 case WSDISPLAYIO_SCURPOS:
472 return (*dcrf->ramdac_set_curpos)(dcrc,
473 (struct wsdisplay_curpos *)data);
474
475 case WSDISPLAYIO_GCURMAX:
476 return (*dcrf->ramdac_get_curmax)(dcrc,
477 (struct wsdisplay_curpos *)data);
478
479 case WSDISPLAYIO_GCURSOR:
480 return (*dcrf->ramdac_get_cursor)(dcrc,
481 (struct wsdisplay_cursor *)data);
482
483 case WSDISPLAYIO_SCURSOR:
484 return (*dcrf->ramdac_set_cursor)(dcrc,
485 (struct wsdisplay_cursor *)data);
486 }
487 return (-1);
488 }
489
490 int
491 tga_sched_update(v, f)
492 void *v;
493 void (*f) __P((void *));
494 {
495 struct tga_devconfig *dc = v;
496
497 dc->dc_regs[TGA_REG_SISR] = 0x00010000;
498 dc->dc_ramdac_intr = f;
499 return 0;
500 }
501
502 int
503 tga_intr(v)
504 void *v;
505 {
506 struct tga_devconfig *dc = v;
507 struct ramdac_cookie *dcrc= dc->dc_ramdac_cookie;
508
509 if ((dc->dc_regs[TGA_REG_SISR] & 0x00010001) != 0x00010001)
510 return 0;
511 dc->dc_ramdac_intr(dcrc);
512 dc->dc_ramdac_intr = NULL;
513 dc->dc_regs[TGA_REG_SISR] = 0x00000001;
514 return (1);
515 }
516
517 int
518 tga_mmap(v, offset, prot)
519 void *v;
520 off_t offset;
521 int prot;
522 {
523
524 /* XXX NEW MAPPING CODE... */
525
526 #ifdef __alpha__
527 struct tga_softc *sc = v;
528
529 if (offset >= sc->sc_dc->dc_tgaconf->tgac_cspace_size || offset < 0)
530 return -1;
531 return alpha_btop(sc->sc_dc->dc_paddr + offset);
532 #else
533 return (-1);
534 #endif
535 }
536
537 int
538 tga_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
539 void *v;
540 const struct wsscreen_descr *type;
541 void **cookiep;
542 int *curxp, *curyp;
543 long *attrp;
544 {
545 struct tga_softc *sc = v;
546 long defattr;
547
548 if (sc->nscreens > 0)
549 return (ENOMEM);
550
551 *cookiep = &sc->sc_dc->dc_rcons; /* one and only for now */
552 *curxp = 0;
553 *curyp = 0;
554 rcons_alloc_attr(&sc->sc_dc->dc_rcons, 0, 0, 0, &defattr);
555 *attrp = defattr;
556 sc->nscreens++;
557 return (0);
558 }
559
560 void
561 tga_free_screen(v, cookie)
562 void *v;
563 void *cookie;
564 {
565 struct tga_softc *sc = v;
566
567 if (sc->sc_dc == &tga_console_dc)
568 panic("tga_free_screen: console");
569
570 sc->nscreens--;
571 }
572
573 int
574 tga_show_screen(v, cookie, waitok, cb, cbarg)
575 void *v;
576 void *cookie;
577 int waitok;
578 void (*cb) __P((void *, int, int));
579 void *cbarg;
580 {
581
582 return (0);
583 }
584
585 int
586 tga_cnattach(iot, memt, pc, bus, device, function)
587 bus_space_tag_t iot, memt;
588 pci_chipset_tag_t pc;
589 int bus, device, function;
590 {
591 struct tga_devconfig *dcp = &tga_console_dc;
592 long defattr;
593
594 tga_getdevconfig(memt, pc,
595 pci_make_tag(pc, bus, device, function), dcp);
596
597 /* sanity checks */
598 if (dcp->dc_vaddr == NULL)
599 panic("tga_console(%d, %d): couldn't map memory space",
600 device, function);
601 if (dcp->dc_tgaconf == NULL)
602 panic("tga_console(%d, %d): unknown board configuration",
603 device, function);
604
605 /*
606 * Initialize the RAMDAC but DO NOT allocate any private storage.
607 * Initialization includes disabling cursor, setting a sane
608 * colormap, etc. It will be reinitialized in tgaattach().
609 */
610
611 /* XXX -- this only works for bt485, but then we only support that,
612 * currently.
613 */
614 if (dcp->dc_tga2)
615 bt485_cninit(dcp, tga_sched_update, tga2_ramdac_wr,
616 tga2_ramdac_rd);
617 else
618 bt485_cninit(dcp, tga_sched_update, tga_ramdac_wr,
619 tga_ramdac_rd);
620
621 rcons_alloc_attr(&dcp->dc_rcons, 0, 0, 0, &defattr);
622
623 wsdisplay_cnattach(&tga_stdscreen, &dcp->dc_rcons,
624 0, 0, defattr);
625
626 return(0);
627 }
628
629 /*
630 * Functions to blank and unblank the display.
631 */
632 void
633 tga_blank(dc)
634 struct tga_devconfig *dc;
635 {
636
637 if (!dc->dc_blanked) {
638 dc->dc_blanked = 1;
639 dc->dc_regs[TGA_REG_VVVR] |= VVR_BLANK; /* XXX */
640 }
641 }
642
643 void
644 tga_unblank(dc)
645 struct tga_devconfig *dc;
646 {
647
648 if (dc->dc_blanked) {
649 dc->dc_blanked = 0;
650 dc->dc_regs[TGA_REG_VVVR] &= ~VVR_BLANK; /* XXX */
651 }
652 }
653
654 /*
655 * Functions to manipulate the built-in cursor handing hardware.
656 */
657 int
658 tga_builtin_set_cursor(dc, cursorp)
659 struct tga_devconfig *dc;
660 struct wsdisplay_cursor *cursorp;
661 {
662 struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
663 struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
664 int count, error, v;
665
666 v = cursorp->which;
667 if (v & WSDISPLAY_CURSOR_DOCMAP) {
668 error = dcrf->ramdac_check_curcmap(dcrc, cursorp);
669 if (error)
670 return (error);
671 }
672 if (v & WSDISPLAY_CURSOR_DOSHAPE) {
673 if ((u_int)cursorp->size.x != 64 ||
674 (u_int)cursorp->size.y > 64)
675 return (EINVAL);
676 /* The cursor is 2 bits deep, and there is no mask */
677 count = (cursorp->size.y * 64 * 2) / NBBY;
678 if (!uvm_useracc(cursorp->image, count, B_READ))
679 return (EFAULT);
680 }
681 if (v & WSDISPLAY_CURSOR_DOHOT) /* not supported */
682 return EINVAL;
683
684 /* parameters are OK; do it */
685 if (v & WSDISPLAY_CURSOR_DOCUR) {
686 if (cursorp->enable)
687 dc->dc_regs[TGA_REG_VVVR] |= 0x04; /* XXX */
688 else
689 dc->dc_regs[TGA_REG_VVVR] &= ~0x04; /* XXX */
690 }
691 if (v & WSDISPLAY_CURSOR_DOPOS) {
692 dc->dc_regs[TGA_REG_CXYR] = ((cursorp->pos.y & 0xfff) << 12) |
693 (cursorp->pos.x & 0xfff);
694 }
695 if (v & WSDISPLAY_CURSOR_DOCMAP) {
696 /* can't fail. */
697 dcrf->ramdac_set_curcmap(dcrc, cursorp);
698 }
699 if (v & WSDISPLAY_CURSOR_DOSHAPE) {
700 count = ((64 * 2) / NBBY) * cursorp->size.y;
701 dc->dc_regs[TGA_REG_CCBR] =
702 (dc->dc_regs[TGA_REG_CCBR] & ~0xfc00) |
703 (cursorp->size.y << 10);
704 copyin(cursorp->image, (char *)(dc->dc_vaddr +
705 (dc->dc_regs[TGA_REG_CCBR] & 0x3ff)),
706 count); /* can't fail. */
707 }
708 return (0);
709 }
710
711 int
712 tga_builtin_get_cursor(dc, cursorp)
713 struct tga_devconfig *dc;
714 struct wsdisplay_cursor *cursorp;
715 {
716 struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
717 struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
718 int count, error;
719
720 cursorp->which = WSDISPLAY_CURSOR_DOALL &
721 ~(WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCMAP);
722 cursorp->enable = (dc->dc_regs[TGA_REG_VVVR] & 0x04) != 0;
723 cursorp->pos.x = dc->dc_regs[TGA_REG_CXYR] & 0xfff;
724 cursorp->pos.y = (dc->dc_regs[TGA_REG_CXYR] >> 12) & 0xfff;
725 cursorp->size.x = 64;
726 cursorp->size.y = (dc->dc_regs[TGA_REG_CCBR] >> 10) & 0x3f;
727
728 if (cursorp->image != NULL) {
729 count = (cursorp->size.y * 64 * 2) / NBBY;
730 error = copyout((char *)(dc->dc_vaddr +
731 (dc->dc_regs[TGA_REG_CCBR] & 0x3ff)),
732 cursorp->image, count);
733 if (error)
734 return (error);
735 /* No mask */
736 }
737 error = dcrf->ramdac_get_curcmap(dcrc, cursorp);
738 return (error);
739 }
740
741 int
742 tga_builtin_set_curpos(dc, curposp)
743 struct tga_devconfig *dc;
744 struct wsdisplay_curpos *curposp;
745 {
746
747 dc->dc_regs[TGA_REG_CXYR] =
748 ((curposp->y & 0xfff) << 12) | (curposp->x & 0xfff);
749 return (0);
750 }
751
752 int
753 tga_builtin_get_curpos(dc, curposp)
754 struct tga_devconfig *dc;
755 struct wsdisplay_curpos *curposp;
756 {
757
758 curposp->x = dc->dc_regs[TGA_REG_CXYR] & 0xfff;
759 curposp->y = (dc->dc_regs[TGA_REG_CXYR] >> 12) & 0xfff;
760 return (0);
761 }
762
763 int
764 tga_builtin_get_curmax(dc, curposp)
765 struct tga_devconfig *dc;
766 struct wsdisplay_curpos *curposp;
767 {
768
769 curposp->x = curposp->y = 64;
770 return (0);
771 }
772
773 /*
774 * Copy columns (characters) in a row (line).
775 */
776 void
777 tga_copycols(id, row, srccol, dstcol, ncols)
778 void *id;
779 int row, srccol, dstcol, ncols;
780 {
781 struct rcons *rc = id;
782 int y, srcx, dstx, nx;
783
784 y = rc->rc_yorigin + rc->rc_font->height * row;
785 srcx = rc->rc_xorigin + rc->rc_font->width * srccol;
786 dstx = rc->rc_xorigin + rc->rc_font->width * dstcol;
787 nx = rc->rc_font->width * ncols;
788
789 tga_rop(rc->rc_sp, dstx, y,
790 nx, rc->rc_font->height, RAS_SRC,
791 rc->rc_sp, srcx, y);
792 }
793
794 /*
795 * Copy rows (lines).
796 */
797 void
798 tga_copyrows(id, srcrow, dstrow, nrows)
799 void *id;
800 int srcrow, dstrow, nrows;
801 {
802 struct rcons *rc = id;
803 int srcy, dsty, ny;
804
805 srcy = rc->rc_yorigin + rc->rc_font->height * srcrow;
806 dsty = rc->rc_yorigin + rc->rc_font->height * dstrow;
807 ny = rc->rc_font->height * nrows;
808
809 tga_rop(rc->rc_sp, rc->rc_xorigin, dsty,
810 rc->rc_raswidth, ny, RAS_SRC,
811 rc->rc_sp, rc->rc_xorigin, srcy);
812 }
813
814 /* Do we need the src? */
815 static int needsrc[16] = { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0 };
816
817 /* A mapping between our API and the TGA card */
818 static int map_rop[16] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6,
819 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
820 };
821
822 /*
823 * Generic TGA raster op.
824 * This covers all possible raster ops, and
825 * clips the sizes and all of that.
826 */
827 static int
828 tga_rop(dst, dx, dy, w, h, rop, src, sx, sy)
829 struct raster *dst;
830 int dx, dy, w, h, rop;
831 struct raster *src;
832 int sx, sy;
833 {
834 if (!dst)
835 return -1;
836 if (dst->data == NULL)
837 return -1; /* we should be writing to a screen */
838 if (needsrc[RAS_GETOP(rop)]) {
839 if (src == (struct raster *) 0)
840 return -1; /* We want a src */
841 /* Clip against src */
842 if (sx < 0) {
843 w += sx;
844 sx = 0;
845 }
846 if (sy < 0) {
847 h += sy;
848 sy = 0;
849 }
850 if (sx + w > src->width)
851 w = src->width - sx;
852 if (sy + h > src->height)
853 h = src->height - sy;
854 } else {
855 if (src != (struct raster *) 0)
856 return -1; /* We need no src */
857 }
858 /* Clip against dst. We modify src regardless of using it,
859 * since it really doesn't matter.
860 */
861 if (dx < 0) {
862 w += dx;
863 sx -= dx;
864 dx = 0;
865 }
866 if (dy < 0) {
867 h += dy;
868 sy -= dy;
869 dy = 0;
870 }
871 if (dx + w > dst->width)
872 w = dst->width - dx;
873 if (dy + h > dst->height)
874 h = dst->height - dy;
875 if (w <= 0 || h <= 0)
876 return 0; /* Vacuously true; */
877 if (!src)
878 return tga_rop_nosrc(dst, dx, dy, w, h, rop);
879 if (src->data == NULL)
880 return tga_rop_htov(dst, dx, dy, w, h, rop, src, sx, sy);
881 else
882 return tga_rop_vtov(dst, dx, dy, w, h, rop, src, sx, sy);
883 }
884
885 /*
886 * No source raster ops.
887 * This function deals with all raster ops that don't require a src.
888 */
889 static int
890 tga_rop_nosrc(dst, dx, dy, w, h, rop)
891 struct raster *dst;
892 int dx, dy, w, h, rop;
893 {
894 return raster_op(dst, dx, dy, w, h, rop, NULL, 0, 0);
895 }
896
897 /*
898 * Host to Video raster ops.
899 * This function deals with all raster ops that have a src that is host memory.
900 */
901 static int
902 tga_rop_htov(dst, dx, dy, w, h, rop, src, sx, sy)
903 struct raster *dst;
904 int dx, dy, w, h, rop;
905 struct raster *src;
906 int sx, sy;
907 {
908 return raster_op(dst, dx, dy, w, h, rop, src, sx, sy);
909 }
910
911 /*
912 * Video to Video raster ops.
913 * This function deals with all raster ops that have a src and dst
914 * that are on the card.
915 */
916 static int
917 tga_rop_vtov(dst, dx, dy, w, h, rop, src, sx, sy)
918 struct raster *dst;
919 int dx, dy, w, h, rop;
920 struct raster *src;
921 int sx, sy;
922 {
923 struct tga_devconfig *dc = (struct tga_devconfig *)dst->data;
924 tga_reg_t *regs0 = dc->dc_regs;
925 tga_reg_t *regs1 = regs0 + 16 * 1024; /* register alias 1 */
926 tga_reg_t *regs2 = regs1 + 16 * 1024; /* register alias 2 */
927 tga_reg_t *regs3 = regs2 + 16 * 1024; /* register alias 3 */
928 int srcb, dstb;
929 int x, y;
930 int xstart, xend, xdir, xinc;
931 int ystart, yend, ydir, yinc;
932 int offset = 1 * dc->dc_tgaconf->tgac_vvbr_units;
933
934 /*
935 * I don't yet want to deal with unaligned guys, really. And we don't
936 * deal with copies from one card to another.
937 */
938 if (dx % 8 != 0 || sx % 8 != 0 || src != dst)
939 return raster_op(dst, dx, dy, w, h, rop, src, sx, sy);
940
941 if (sy >= dy) {
942 ystart = 0;
943 yend = h;
944 ydir = 1;
945 } else {
946 ystart = h;
947 yend = 0;
948 ydir = -1;
949 }
950 if (sx >= dx) {
951 xstart = 0;
952 xend = w * (dst->depth / 8);
953 xdir = 1;
954 } else {
955 xstart = w * (dst->depth / 8);
956 xend = 0;
957 xdir = -1;
958 }
959 xinc = xdir * 4 * 64;
960 yinc = ydir * dst->linelongs * 4;
961 ystart *= dst->linelongs * 4;
962 yend *= dst->linelongs * 4;
963 srcb = offset + sy * src->linelongs * 4 + sx;
964 dstb = offset + dy * dst->linelongs * 4 + dx;
965 regs3[TGA_REG_GMOR] = 0x0007; /* Copy mode */
966 regs3[TGA_REG_GOPR] = map_rop[rop]; /* Set up the op */
967 for (y = ystart; (ydir * y) < (ydir * yend); y += yinc) {
968 for (x = xstart; (xdir * x) < (xdir * xend); x += xinc) {
969 regs0[TGA_REG_GCSR] = srcb + y + x + 3 * 64;
970 regs0[TGA_REG_GCDR] = dstb + y + x + 3 * 64;
971 regs1[TGA_REG_GCSR] = srcb + y + x + 2 * 64;
972 regs1[TGA_REG_GCDR] = dstb + y + x + 2 * 64;
973 regs2[TGA_REG_GCSR] = srcb + y + x + 1 * 64;
974 regs2[TGA_REG_GCDR] = dstb + y + x + 1 * 64;
975 regs3[TGA_REG_GCSR] = srcb + y + x + 0 * 64;
976 regs3[TGA_REG_GCDR] = dstb + y + x + 0 * 64;
977 }
978 }
979 regs0[TGA_REG_GOPR] = 0x0003; /* op -> dst = src */
980 regs0[TGA_REG_GMOR] = 0x0000; /* Simple mode */
981 return 0;
982 }
983
984 void
985 tga_ramdac_wr(v, btreg, val)
986 void *v;
987 u_int btreg;
988 u_int8_t val;
989 {
990 struct tga_devconfig *dc = v;
991 volatile tga_reg_t *tgaregs = dc->dc_regs;
992
993 if (btreg > BT485_REG_MAX)
994 panic("tga_ramdac_wr: reg %d out of range\n", btreg);
995
996 tgaregs[TGA_REG_EPDR] = (btreg << 9) | (0 << 8 ) | val; /* XXX */
997 #ifdef __alpha__
998 alpha_mb();
999 #endif
1000 }
1001
1002 void
1003 tga2_ramdac_wr(v, btreg, val)
1004 void *v;
1005 u_int btreg;
1006 u_int8_t val;
1007 {
1008 struct tga_devconfig *dc = v;
1009 volatile tga_reg_t *ramdac;
1010
1011 if (btreg > BT485_REG_MAX)
1012 panic("tga_ramdac_wr: reg %d out of range\n", btreg);
1013
1014 ramdac = (tga_reg_t *)(dc->dc_vaddr + TGA2_MEM_RAMDAC +
1015 (0xe << 12) + (btreg << 8));
1016 *ramdac = val & 0xff;
1017 #ifdef __alpha__
1018 alpha_mb();
1019 #endif
1020 }
1021
1022 u_int8_t
1023 tga_ramdac_rd(v, btreg)
1024 void *v;
1025 u_int btreg;
1026 {
1027 struct tga_devconfig *dc = v;
1028 volatile tga_reg_t *tgaregs = dc->dc_regs;
1029 tga_reg_t rdval;
1030
1031 if (btreg > BT485_REG_MAX)
1032 panic("tga_ramdac_rd: reg %d out of range\n", btreg);
1033
1034 tgaregs[TGA_REG_EPSR] = (btreg << 1) | 0x1; /* XXX */
1035 #ifdef __alpha__
1036 alpha_mb();
1037 #endif
1038
1039 rdval = tgaregs[TGA_REG_EPDR];
1040 return (rdval >> 16) & 0xff; /* XXX */
1041 }
1042
1043 u_int8_t
1044 tga2_ramdac_rd(v, btreg)
1045 void *v;
1046 u_int btreg;
1047 {
1048 struct tga_devconfig *dc = v;
1049 volatile tga_reg_t *ramdac;
1050 u_int8_t retval;
1051
1052 if (btreg > BT485_REG_MAX)
1053 panic("tga_ramdac_rd: reg %d out of range\n", btreg);
1054
1055 ramdac = (tga_reg_t *)(dc->dc_vaddr + TGA2_MEM_RAMDAC +
1056 (0xe << 12) + (btreg << 8));
1057 retval = (u_int8_t)(*ramdac & 0xff);
1058 #ifdef __alpha__
1059 alpha_mb();
1060 #endif
1061 return retval;
1062 }
1063
1064 #include <dev/ic/decmonitors.c>
1065 void tga2_ics9110_wr __P((
1066 struct tga_devconfig *dc,
1067 int dotclock
1068 ));
1069
1070 void
1071 tga2_init(dc, m)
1072 struct tga_devconfig *dc;
1073 int m;
1074 {
1075
1076 tga2_ics9110_wr(dc, decmonitors[m].dotclock);
1077 dc->dc_regs[TGA_REG_VHCR] =
1078 ((decmonitors[m].hbp / 4) << 21) |
1079 ((decmonitors[m].hsync / 4) << 14) |
1080 #if 0
1081 (((decmonitors[m].hfp - 4) / 4) << 9) |
1082 ((decmonitors[m].cols + 4) / 4);
1083 #else
1084 (((decmonitors[m].hfp) / 4) << 9) |
1085 ((decmonitors[m].cols) / 4);
1086 #endif
1087 dc->dc_regs[TGA_REG_VVCR] =
1088 (decmonitors[m].vbp << 22) |
1089 (decmonitors[m].vsync << 16) |
1090 (decmonitors[m].vfp << 11) |
1091 (decmonitors[m].rows);
1092 dc->dc_regs[TGA_REG_VVBR] = 1; alpha_mb();
1093 dc->dc_regs[TGA_REG_VVVR] |= 1; alpha_mb();
1094 dc->dc_regs[TGA_REG_GPMR] = 0xffffffff; alpha_mb();
1095 }
1096
1097 void
1098 tga2_ics9110_wr(dc, dotclock)
1099 struct tga_devconfig *dc;
1100 int dotclock;
1101 {
1102 volatile tga_reg_t *clock;
1103 u_int32_t valU;
1104 int N, M, R, V, X;
1105 int i;
1106
1107 switch (dotclock) {
1108 case 130808000:
1109 N = 0x40; M = 0x7; V = 0x0; X = 0x1; R = 0x1; break;
1110 case 119840000:
1111 N = 0x2d; M = 0x2b; V = 0x1; X = 0x1; R = 0x1; break;
1112 case 108180000:
1113 N = 0x11; M = 0x9; V = 0x1; X = 0x1; R = 0x2; break;
1114 case 103994000:
1115 N = 0x6d; M = 0xf; V = 0x0; X = 0x1; R = 0x1; break;
1116 case 175000000:
1117 N = 0x5F; M = 0x3E; V = 0x1; X = 0x1; R = 0x1; break;
1118 case 75000000:
1119 N = 0x6e; M = 0x15; V = 0x0; X = 0x1; R = 0x1; break;
1120 case 74000000:
1121 N = 0x2a; M = 0x41; V = 0x1; X = 0x1; R = 0x1; break;
1122 case 69000000:
1123 N = 0x35; M = 0xb; V = 0x0; X = 0x1; R = 0x1; break;
1124 case 65000000:
1125 N = 0x6d; M = 0x0c; V = 0x0; X = 0x1; R = 0x2; break;
1126 case 50000000:
1127 N = 0x37; M = 0x3f; V = 0x1; X = 0x1; R = 0x2; break;
1128 case 40000000:
1129 N = 0x5f; M = 0x11; V = 0x0; X = 0x1; R = 0x2; break;
1130 case 31500000:
1131 N = 0x16; M = 0x05; V = 0x0; X = 0x1; R = 0x2; break;
1132 case 25175000:
1133 N = 0x66; M = 0x1d; V = 0x0; X = 0x1; R = 0x2; break;
1134 case 135000000:
1135 N = 0x42; M = 0x07; V = 0x0; X = 0x1; R = 0x1; break;
1136 case 110000000:
1137 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
1138 case 202500000:
1139 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
1140 default:
1141 panic("unrecognized clock rate %d\n", dotclock);
1142 }
1143
1144 /* XXX -- hard coded, bad */
1145 valU = N | ( M << 7 ) | (V << 14);
1146 valU |= (X << 15) | (R << 17);
1147 valU |= 0x17 << 19;
1148
1149
1150 clock = (tga_reg_t *)(dc->dc_vaddr + TGA2_MEM_EXTDEV +
1151 TGA2_MEM_CLOCK + (0xe << 12)); /* XXX */
1152
1153 for (i=24; i>0; i--) {
1154 u_int32_t writeval;
1155
1156 writeval = valU & 0x1;
1157 if (i == 1)
1158 writeval |= 0x2;
1159 valU >>= 1;
1160 *clock = writeval;
1161 #ifdef __alpha__
1162 alpha_mb();
1163 #endif
1164 }
1165 clock = (tga_reg_t *)(dc->dc_vaddr + TGA2_MEM_EXTDEV +
1166 TGA2_MEM_CLOCK + (0xe << 12) + (0x1 << 11)); /* XXX */
1167 clock += 0x1 << 9;
1168 *clock = 0x0;
1169 #ifdef __alpha__
1170 alpha_mb();
1171 #endif
1172 }
1173