Annotation of sys/dev/pci/tga.c, Revision 1.1.1.1
1.1 nbrk 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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, ul;
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, &ul);
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 (ul) {
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
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
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
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
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
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
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
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
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
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
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 *
1685: tga_getmonitor(dc)
1686: struct tga_devconfig *dc;
1687: {
1688: return &decmonitors[(~TGARREG(dc, TGA_REG_GREV) >> 16) & 0x0f];
1689: }
1690:
1691: unsigned
1692: tga_getdotclock(dc)
1693: struct tga_devconfig *dc;
1694: {
1695: return tga_getmonitor(dc)->dotclock;
1696: }
CVSweb