xref: /openbsd-src/sys/dev/pci/tga.c (revision 2b0358df1d88d06ef4139321dd05bd5e05d91eaf)
1 /* $OpenBSD: tga.c,v 1.31 2009/03/29 21:53:52 sthen 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 = malloc(sizeof(struct tga_devconfig), M_DEVBUF,
432 		    M_NOWAIT | M_ZERO);
433 		if (sc->sc_dc == NULL)
434 			return;
435 		tga_getdevconfig(pa->pa_memt, pa->pa_pc, pa->pa_tag,
436 		    sc->sc_dc);
437 	}
438 	if (sc->sc_dc->dc_vaddr == NULL) {
439 		printf(": can't map mem space\n");
440 		return;
441 	}
442 
443 	/* XXX say what's going on. */
444 	intrstr = NULL;
445 	if (pci_intr_map(pa, &intrh)) {
446 		printf(": can't map interrupt");
447 		return;
448 	}
449 	intrstr = pci_intr_string(pa->pa_pc, intrh);
450 	sc->sc_intr = pci_intr_establish(pa->pa_pc, intrh, IPL_TTY, tga_intr,
451 	    sc->sc_dc, sc->sc_dev.dv_xname);
452 	if (sc->sc_intr == NULL) {
453 		printf(": can't establish interrupt");
454 		if (intrstr != NULL)
455 			printf("at %s", intrstr);
456 		printf("\n");
457 		return;
458 	}
459 
460 	rev = PCI_REVISION(pa->pa_class);
461 	switch (rev) {
462 	case 0x1:
463 	case 0x2:
464 	case 0x3:
465 		printf(": DC21030 step %c", 'A' + rev - 1);
466 		break;
467 	case 0x20:
468 		printf(": TGA2 abstract software model");
469 		break;
470 	case 0x21:
471 	case 0x22:
472 		printf(": TGA2 pass %d", rev - 0x20);
473 		break;
474 
475 	default:
476 		printf("unknown stepping (0x%x)", rev);
477 		break;
478 	}
479 	printf(", ");
480 
481 	/*
482 	 * Get RAMDAC function vectors and call the RAMDAC functions
483 	 * to allocate its private storage and pass that back to us.
484 	 */
485 
486 	DPRINTF("tgaattach: Get RAMDAC functions\n");
487 	sc->sc_dc->dc_ramdac_funcs = sc->sc_dc->dc_tgaconf->ramdac_funcs();
488 	if (!sc->sc_dc->dc_tga2) {
489 	    DPRINTF("tgaattach: !sc->sc_dc->dc_tga2\n");
490 	    DPRINTF("tgaattach: sc->sc_dc->dc_tgaconf->ramdac_funcs %s "
491 		    "bt485_funcs\n",
492 		    (sc->sc_dc->dc_tgaconf->ramdac_funcs == bt485_funcs)
493 		    ? "==" : "!=");
494 	    if (sc->sc_dc->dc_tgaconf->ramdac_funcs == bt485_funcs)
495 		  sc->sc_dc->dc_ramdac_cookie =
496 			sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc,
497 		    tga_sched_update, tga_ramdac_wr, tga_ramdac_rd);
498 		else
499 		  sc->sc_dc->dc_ramdac_cookie =
500 			sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc,
501 		    tga_sched_update, tga_bt463_wr, tga_bt463_rd);
502 	} else {
503 	        DPRINTF("tgaattach: sc->sc_dc->dc_tga2\n");
504 		sc->sc_dc->dc_ramdac_cookie =
505 			sc->sc_dc->dc_ramdac_funcs->ramdac_register(sc->sc_dc,
506 			tga_sched_update, tga2_ramdac_wr, tga2_ramdac_rd);
507 
508 		/* XXX this is a bit of a hack, setting the dotclock here */
509 		if (sc->sc_dc->dc_tgaconf->ramdac_funcs != bt485_funcs)
510 			(*sc->sc_dc->dc_ramdac_funcs->ramdac_set_dotclock)
511 				(sc->sc_dc->dc_ramdac_cookie,
512 				 tga_getdotclock(sc->sc_dc));
513 	}
514 	DPRINTF("tgaattach: sc->sc_dc->dc_ramdac_cookie = 0x%016llx\n",
515 		sc->sc_dc->dc_ramdac_cookie);
516 	/*
517 	 * Initialize the RAMDAC.  Initialization includes disabling
518 	 * cursor, setting a sane colormap, etc.
519 	 */
520 	DPRINTF("tgaattach: Initializing RAMDAC.\n");
521 	(*sc->sc_dc->dc_ramdac_funcs->ramdac_init)(sc->sc_dc->dc_ramdac_cookie);
522 	TGAWREG(sc->sc_dc, TGA_REG_SISR, 0x00000001); /* XXX */
523 
524 	if (sc->sc_dc->dc_tgaconf == NULL) {
525 		printf("unknown board configuration\n");
526 		return;
527 	}
528 	printf("board type %s\n", sc->sc_dc->dc_tgaconf->tgac_name);
529 	printf("%s: %d x %d, %dbpp, %s RAMDAC\n", sc->sc_dev.dv_xname,
530 	    sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
531 	    sc->sc_dc->dc_tgaconf->tgac_phys_depth,
532 	    sc->sc_dc->dc_ramdac_funcs->ramdac_name);
533 
534 	if (intrstr != NULL)
535 		printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname,
536 		    intrstr);
537 
538 	aa.console = console;
539 	aa.scrdata = &tga_screenlist;
540 	aa.accessops = &tga_accessops;
541 	aa.accesscookie = sc;
542 	aa.defaultscreens = 0;
543 
544 	config_found(self, &aa, wsemuldisplaydevprint);
545 
546 #ifdef __NetBSD__
547 	config_interrupts(self, tga_config_interrupts);
548 #else
549 	tga_config_interrupts(self);
550 #endif
551 }
552 
553 void
554 tga_config_interrupts (d)
555 	struct device *d;
556 {
557 	struct tga_softc *sc = (struct tga_softc *)d;
558 	sc->sc_dc->dc_intrenabled = 1;
559 }
560 
561 
562 int
563 tga_ioctl(v, cmd, data, flag, p)
564 	void *v;
565 	u_long cmd;
566 	caddr_t data;
567 	int flag;
568 	struct proc *p;
569 {
570 	struct tga_softc *sc = v;
571 	struct tga_devconfig *dc = sc->sc_dc;
572 	struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
573 	struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
574 
575 	switch (cmd) {
576 	case WSDISPLAYIO_GTYPE:
577 		*(u_int *)data = WSDISPLAY_TYPE_TGA;
578 		break;
579 
580 	case WSDISPLAYIO_SMODE:
581 		sc->sc_mode = *(u_int *)data;
582 		switch (sc->sc_mode) {
583 		case WSDISPLAYIO_MODE_DUMBFB:
584 			/* in dump fb mode start the framebuffer at 0 */
585 			TGAWREG(dc, TGA_REG_VVBR, 0);
586 			break;
587 		default:
588 			/* XXX it this useful, except for not breaking Xtga? */
589 			TGAWREG(dc, TGA_REG_VVBR, 1);
590 			break;
591 		}
592 		break;
593 
594 	case WSDISPLAYIO_GINFO:
595 #define	wsd_fbip ((struct wsdisplay_fbinfo *)data)
596 		wsd_fbip->height = sc->sc_dc->dc_ht;
597 		wsd_fbip->width = sc->sc_dc->dc_wid;
598 		wsd_fbip->depth = sc->sc_dc->dc_tgaconf->tgac_phys_depth;
599 		wsd_fbip->cmsize = 1024;		/* XXX ??? */
600 #undef wsd_fbip
601 		break;
602 
603 	case WSDISPLAYIO_LINEBYTES:
604 		*(u_int *)data = sc->sc_dc->dc_rowbytes;
605 		break;
606 
607 	case WSDISPLAYIO_GETCMAP:
608 		return (*dcrf->ramdac_get_cmap)(dcrc,
609 		    (struct wsdisplay_cmap *)data);
610 	case WSDISPLAYIO_PUTCMAP:
611 		return (*dcrf->ramdac_set_cmap)(dcrc,
612 		    (struct wsdisplay_cmap *)data);
613 
614 	case WSDISPLAYIO_SVIDEO:
615 	case WSDISPLAYIO_GVIDEO:
616 		break;
617 
618 	case WSDISPLAYIO_GCURPOS:
619 		return (*dcrf->ramdac_get_curpos)(dcrc,
620 		    (struct wsdisplay_curpos *)data);
621 
622 	case WSDISPLAYIO_SCURPOS:
623 		return (*dcrf->ramdac_set_curpos)(dcrc,
624 		    (struct wsdisplay_curpos *)data);
625 
626 	case WSDISPLAYIO_GCURMAX:
627 		return (*dcrf->ramdac_get_curmax)(dcrc,
628 		    (struct wsdisplay_curpos *)data);
629 
630 	case WSDISPLAYIO_GCURSOR:
631 		return (*dcrf->ramdac_get_cursor)(dcrc,
632 		    (struct wsdisplay_cursor *)data);
633 
634 	case WSDISPLAYIO_SCURSOR:
635 		return (*dcrf->ramdac_set_cursor)(dcrc,
636 		    (struct wsdisplay_cursor *)data);
637 
638 	default:
639 		return (-1);
640 	}
641 
642 	return (0);
643 }
644 
645 int
646 tga_sched_update(v, f)
647 	void	*v;
648 	void	(*f)(void *);
649 {
650 	struct tga_devconfig *dc = v;
651 
652 	if (dc->dc_intrenabled) {
653 		/* Arrange for f to be called at the next end-of-frame interrupt */
654 		dc->dc_ramdac_intr = f;
655 		TGAWREG(dc, TGA_REG_SISR, 0x00010000);
656 	} else {
657 		/* Spin until the end-of-frame, then call f */
658 		TGAWREG(dc, TGA_REG_SISR, 0x00010001);
659 		TGAREGWB(dc, TGA_REG_SISR, 1);
660 		while ((TGARREG(dc, TGA_REG_SISR) & 0x00000001) == 0)
661 			;
662 		f(dc->dc_ramdac_cookie);
663 		TGAWREG(dc, TGA_REG_SISR, 0x00000001);
664 		TGAREGWB(dc, TGA_REG_SISR, 1);
665 	}
666 
667 	return 0;
668 }
669 
670 int
671 tga_intr(v)
672 	void *v;
673 {
674 	struct tga_devconfig *dc = v;
675 	struct ramdac_cookie *dcrc= dc->dc_ramdac_cookie;
676 
677 	u_int32_t reg;
678 
679 	reg = TGARREG(dc, TGA_REG_SISR);
680 	if (( reg & 0x00010001) != 0x00010001) {
681 		/* Odd. We never set any of the other interrupt enables. */
682 		if ((reg & 0x1f) != 0) {
683 			/* Clear the mysterious pending interrupts. */
684 			TGAWREG(dc, TGA_REG_SISR, (reg & 0x1f));
685 			TGAREGWB(dc, TGA_REG_SISR, 1);
686 			/* This was our interrupt, even if we're puzzled as to why
687 			 * we got it.  Don't make the interrupt handler think it
688 			 * was a stray.
689 			 */
690 			return -1;
691 		} else {
692 			return 0;
693 		}
694 	}
695 	/* if we have something to do, do it */
696 	if (dc->dc_ramdac_intr) {
697 		dc->dc_ramdac_intr(dcrc);
698 		dc->dc_ramdac_intr = NULL;
699 	}
700 	TGAWREG(dc, TGA_REG_SISR, 0x00000001);
701 	TGAREGWB(dc, TGA_REG_SISR, 1);
702 	return (1);
703 }
704 
705 paddr_t
706 tga_mmap(v, offset, prot)
707 	void *v;
708 	off_t offset;
709 	int prot;
710 {
711 	struct tga_softc *sc = v;
712 	struct tga_devconfig *dc = sc->sc_dc;
713 
714 	if (offset >= dc->dc_tgaconf->tgac_cspace_size || offset < 0)
715 		return -1;
716 
717 	if (sc->sc_mode == WSDISPLAYIO_MODE_DUMBFB) {
718 		/*
719 		 * The framebuffer starts at the upper half of tga mem
720 		 */
721 		offset += dc->dc_tgaconf->tgac_cspace_size / 2;
722 	}
723 #if defined(__alpha__) || defined(__mips__)
724 	return atop(sc->sc_dc->dc_paddr + offset);
725 #else
726 	return (-1);
727 #endif
728 }
729 
730 int
731 tga_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
732 	void *v;
733 	const struct wsscreen_descr *type;
734 	void **cookiep;
735 	int *curxp, *curyp;
736 	long *attrp;
737 {
738 	struct tga_softc *sc = v;
739 	long defattr;
740 
741 	if (sc->nscreens > 0)
742 		return (ENOMEM);
743 
744 	*cookiep = &sc->sc_dc->dc_rinfo; /* one and only for now */
745 	*curxp = 0;
746 	*curyp = 0;
747 	sc->sc_dc->dc_rinfo.ri_ops.alloc_attr(&sc->sc_dc->dc_rinfo,
748 		0, 0, 0, &defattr);
749 	*attrp = defattr;
750 	sc->nscreens++;
751 	return (0);
752 }
753 
754 void
755 tga_free_screen(v, cookie)
756 	void *v;
757 	void *cookie;
758 {
759 	struct tga_softc *sc = v;
760 
761 	if (sc->sc_dc == &tga_console_dc)
762 		panic("tga_free_screen: console");
763 
764 	sc->nscreens--;
765 }
766 
767 int
768 tga_show_screen(v, cookie, waitok, cb, cbarg)
769 	void *v;
770 	void *cookie;
771 	int waitok;
772 	void (*cb)(void *, int, int);
773 	void *cbarg;
774 {
775 
776 	return (0);
777 }
778 
779 int
780 tga_cnattach(iot, memt, pc, bus, device, function)
781 	bus_space_tag_t iot, memt;
782 	pci_chipset_tag_t pc;
783 	int bus, device, function;
784 {
785 	struct tga_devconfig *dcp = &tga_console_dc;
786 	long defattr;
787 
788 	tga_getdevconfig(memt, pc,
789 	    pci_make_tag(pc, bus, device, function), dcp);
790 
791 	/* sanity checks */
792 	if (dcp->dc_vaddr == NULL)
793 		panic("tga_console(%d, %d): can't map mem space",
794 		    device, function);
795 	if (dcp->dc_tgaconf == NULL)
796 		panic("tga_console(%d, %d): unknown board configuration",
797 		    device, function);
798 
799 	/*
800 	 * Initialize the RAMDAC but DO NOT allocate any private storage.
801 	 * Initialization includes disabling cursor, setting a sane
802 	 * colormap, etc.  It will be reinitialized in tgaattach().
803 	 */
804 	if (dcp->dc_tga2) {
805 		if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs)
806 			bt485_cninit(dcp, tga_sched_update, tga2_ramdac_wr,
807 				     tga2_ramdac_rd);
808 		else
809 			ibm561_cninit(dcp, tga_sched_update, tga2_ramdac_wr,
810 				      tga2_ramdac_rd, tga_getdotclock(dcp));
811 	} else {
812 		if (dcp->dc_tgaconf->ramdac_funcs == bt485_funcs)
813 			bt485_cninit(dcp, tga_sched_update, tga_ramdac_wr,
814 				tga_ramdac_rd);
815 		else {
816 			bt463_cninit(dcp, tga_sched_update, tga_bt463_wr,
817 				tga_bt463_rd);
818 		}
819 	}
820 	dcp->dc_rinfo.ri_ops.alloc_attr(&dcp->dc_rinfo, 0, 0, 0, &defattr);
821 	wsdisplay_cnattach(&tga_stdscreen, &dcp->dc_rinfo, 0, 0, defattr);
822 
823 	return(0);
824 }
825 
826 /*
827  * Functions to blank and unblank the display.
828  */
829 void
830 tga_burner(v, on, flags)
831 	void *v;
832 	u_int on, flags;
833 {
834 	struct tga_softc *sc = v;
835 
836 	if (on) {
837 		tga_unblank(sc->sc_dc);
838 	} else {
839 		tga_blank(sc->sc_dc);
840 	}
841 }
842 
843 void
844 tga_blank(dc)
845 	struct tga_devconfig *dc;
846 {
847 
848 	if (!dc->dc_blanked) {
849 		dc->dc_blanked = 1;
850 		/* XXX */
851 		TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | VVR_BLANK);
852 	}
853 }
854 
855 void
856 tga_unblank(dc)
857 	struct tga_devconfig *dc;
858 {
859 
860 	if (dc->dc_blanked) {
861 		dc->dc_blanked = 0;
862 		/* XXX */
863 		TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) & ~VVR_BLANK);
864 	}
865 }
866 
867 /*
868  * Functions to manipulate the built-in cursor handing hardware.
869  */
870 int
871 tga_builtin_set_cursor(dc, cursorp)
872 	struct tga_devconfig *dc;
873 	struct wsdisplay_cursor *cursorp;
874 {
875 	struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
876 	struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
877 	u_int count, v;
878 	int error;
879 
880 	v = cursorp->which;
881 	if (v & WSDISPLAY_CURSOR_DOCMAP) {
882 		error = dcrf->ramdac_check_curcmap(dcrc, cursorp);
883 		if (error)
884 			return (error);
885 	}
886 	if (v & WSDISPLAY_CURSOR_DOSHAPE) {
887 		if ((u_int)cursorp->size.x != 64 ||
888 		    (u_int)cursorp->size.y > 64)
889 			return (EINVAL);
890 	}
891 	if (v & WSDISPLAY_CURSOR_DOHOT)		/* not supported */
892 		return EINVAL;
893 
894 	/* parameters are OK; do it */
895 	if (v & WSDISPLAY_CURSOR_DOCUR) {
896 		if (cursorp->enable)
897 			/* XXX */
898 			TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 0x04);
899 		else
900 			/* XXX */
901 			TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) & ~0x04);
902 	}
903 	if (v & WSDISPLAY_CURSOR_DOPOS) {
904 		TGAWREG(dc, TGA_REG_CXYR,
905 		    ((cursorp->pos.y & 0xfff) << 12) | (cursorp->pos.x & 0xfff));
906 	}
907 	if (v & WSDISPLAY_CURSOR_DOCMAP) {
908 		/* can't fail. */
909 		dcrf->ramdac_set_curcmap(dcrc, cursorp);
910 	}
911 	if (v & WSDISPLAY_CURSOR_DOSHAPE) {
912 		/* The cursor is 2 bits deep, and there is no mask */
913 		count = (cursorp->size.y * 64 * 2) / NBBY;
914 		TGAWREG(dc, TGA_REG_CCBR,
915 		    (TGARREG(dc, TGA_REG_CCBR) & ~0xfc00) | (cursorp->size.y << 10));
916 		if ((error = copyin(cursorp->image,(char *)(dc->dc_vaddr +
917 		    (TGARREG(dc, TGA_REG_CCBR) & 0x3ff)), count)) != 0)
918 			return (error);
919 	}
920 	return (0);
921 }
922 
923 int
924 tga_builtin_get_cursor(dc, cursorp)
925 	struct tga_devconfig *dc;
926 	struct wsdisplay_cursor *cursorp;
927 {
928 	struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs;
929 	struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie;
930 	int error;
931 	u_int count;
932 
933 	cursorp->which = WSDISPLAY_CURSOR_DOALL &
934 	    ~(WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCMAP);
935 	cursorp->enable = (TGARREG(dc, TGA_REG_VVVR) & 0x04) != 0;
936 	cursorp->pos.x = TGARREG(dc, TGA_REG_CXYR) & 0xfff;
937 	cursorp->pos.y = (TGARREG(dc, TGA_REG_CXYR) >> 12) & 0xfff;
938 	cursorp->size.x = 64;
939 	cursorp->size.y = (TGARREG(dc, TGA_REG_CCBR) >> 10) & 0x3f;
940 
941 	if (cursorp->image != NULL) {
942 		count = (cursorp->size.y * 64 * 2) / NBBY;
943 		error = copyout((char *)(dc->dc_vaddr +
944 		      (TGARREG(dc, TGA_REG_CCBR) & 0x3ff)),
945 		    cursorp->image, count);
946 		if (error)
947 			return (error);
948 		/* No mask */
949 	}
950 	error = dcrf->ramdac_get_curcmap(dcrc, cursorp);
951 	return (error);
952 }
953 
954 int
955 tga_builtin_set_curpos(dc, curposp)
956 	struct tga_devconfig *dc;
957 	struct wsdisplay_curpos *curposp;
958 {
959 
960 	TGAWREG(dc, TGA_REG_CXYR,
961 	    ((curposp->y & 0xfff) << 12) | (curposp->x & 0xfff));
962 	return (0);
963 }
964 
965 int
966 tga_builtin_get_curpos(dc, curposp)
967 	struct tga_devconfig *dc;
968 	struct wsdisplay_curpos *curposp;
969 {
970 
971 	curposp->x = TGARREG(dc, TGA_REG_CXYR) & 0xfff;
972 	curposp->y = (TGARREG(dc, TGA_REG_CXYR) >> 12) & 0xfff;
973 	return (0);
974 }
975 
976 int
977 tga_builtin_get_curmax(dc, curposp)
978 	struct tga_devconfig *dc;
979 	struct wsdisplay_curpos *curposp;
980 {
981 
982 	curposp->x = curposp->y = 64;
983 	return (0);
984 }
985 
986 /*
987  * Copy columns (characters) in a row (line).
988  */
989 void
990 tga_copycols(id, row, srccol, dstcol, ncols)
991 	void *id;
992 	int row, srccol, dstcol, ncols;
993 {
994 	struct rasops_info *ri = id;
995 	int y, srcx, dstx, nx;
996 
997 	y = ri->ri_font->fontheight * row;
998 	srcx = ri->ri_font->fontwidth * srccol;
999 	dstx = ri->ri_font->fontwidth * dstcol;
1000 	nx = ri->ri_font->fontwidth * ncols;
1001 
1002 	tga_rop(ri, dstx, y, nx, ri->ri_font->fontheight, ri, srcx, y);
1003 }
1004 
1005 /*
1006  * Copy rows (lines).
1007  */
1008 void
1009 tga_copyrows(id, srcrow, dstrow, nrows)
1010 	void *id;
1011 	int srcrow, dstrow, nrows;
1012 {
1013 	struct rasops_info *ri = id;
1014 	int srcy, dsty, ny;
1015 
1016 	srcy = ri->ri_font->fontheight * srcrow;
1017 	dsty = ri->ri_font->fontheight * dstrow;
1018 	ny = ri->ri_font->fontheight * nrows;
1019 
1020 	tga_rop(ri, 0, dsty, ri->ri_emuwidth, ny, ri, 0, srcy);
1021 }
1022 
1023 /*
1024  *  Generic TGA raster op.
1025  *   This covers all possible raster ops, and
1026  *   clips the sizes and all of that.
1027  */
1028 int
1029 tga_rop(dst, dx, dy, w, h, src, sx, sy)
1030 	struct rasops_info *dst;
1031 	int dx, dy, w, h;
1032 	struct rasops_info *src;
1033 	int sx, sy;
1034 {
1035 	if (dst == NULL || src == NULL)
1036 		return -1;
1037 
1038 	/* Clip against src */
1039 	if (sx < 0) {
1040 		w += sx;
1041 		sx = 0;
1042 	}
1043 	if (sy < 0) {
1044 		h += sy;
1045 		sy = 0;
1046 	}
1047 	if (sx + w > src->ri_emuwidth)
1048 		w = src->ri_emuwidth - sx;
1049 	if (sy + h > src->ri_emuheight)
1050 		h = src->ri_emuheight - sy;
1051 
1052 	/* Clip against dst.  We modify src regardless of using it,
1053 	 * since it really doesn't matter.
1054 	 */
1055 	if (dx < 0) {
1056 		w += dx;
1057 		sx -= dx;
1058 		dx = 0;
1059 	}
1060 	if (dy < 0) {
1061 		h += dy;
1062 		sy -= dy;
1063 		dy = 0;
1064 	}
1065 	if (dx + w > dst->ri_emuwidth)
1066 		w = dst->ri_emuwidth - dx;
1067 	if (dy + h > dst->ri_emuheight)
1068 		h = dst->ri_emuheight - dy;
1069 	if (w <= 0 || h <= 0)
1070 		return 0;	/* Vacuously true; */
1071 
1072 	return tga_rop_vtov(dst, dx, dy, w, h, src, sx, sy);
1073 }
1074 
1075 
1076 
1077 /*
1078  * Video to Video raster ops.
1079  * This function deals with all raster ops that have a src and dst
1080  * that are on the card.
1081  */
1082 int
1083 tga_rop_vtov(dst, dx, dy, w, h, src, sx, sy)
1084 	struct rasops_info *dst;
1085 	int dx, dy, w, h;
1086 	struct rasops_info *src;
1087 	int sx, sy;
1088 {
1089 	struct tga_devconfig *dc = (struct tga_devconfig *)dst->ri_hw;
1090 	int srcb, dstb, tga_srcb, tga_dstb;
1091 	int x, y, wb;
1092 	int xstart, xend, xdir;
1093 	int ystart, yend, ydir, yinc;
1094 	int xleft, lastx, lastleft;
1095 	int offset = 1 * dc->dc_tgaconf->tgac_vvbr_units;
1096 
1097 	/*
1098 	 * I don't yet want to deal with unaligned guys, really.  And we don't
1099 	 * deal with copies from one card to another.
1100 	 */
1101 	if (dx % 8 != 0 || sx % 8 != 0 || src != dst) {
1102 		/* XXX Punt! */
1103 		/* XXX should never happen, since it's only being used to
1104 		 * XXX copy 8-pixel-wide characters.
1105 		 */
1106 		return -1;
1107 	}
1108 
1109         wb = w * (dst->ri_depth / 8);
1110 	if (sy >= dy) {
1111 		ystart = 0;
1112 		yend = h;
1113 		ydir = 1;
1114 	} else {
1115 		ystart = h;
1116 		yend = 0;
1117 		ydir = -1;
1118 	}
1119 	if (sx >= dx) {      /* moving to the left */
1120 		xstart = 0;
1121 		xend = w * (dst->ri_depth / 8) - 4;
1122 		xdir = 1;
1123 	} else {             /* moving to the right */
1124 		xstart = wb - ( wb >= 4*64 ? 4*64 : wb >= 64 ? 64 : 4 );
1125 		xend = 0;
1126 		xdir = -1;
1127 	}
1128 #define XINC4   4
1129 #define XINC64  64
1130 #define XINC256 (64*4)
1131 	yinc = ydir * dst->ri_stride;
1132 	ystart *= dst->ri_stride;
1133 	yend *= dst->ri_stride;
1134 
1135 	srcb = sy * src->ri_stride + sx * (src->ri_depth/8);
1136 	dstb = dy * dst->ri_stride + dx * (dst->ri_depth/8);
1137 	tga_srcb = offset + (sy + src->ri_yorigin) * src->ri_stride +
1138 		(sx + src->ri_xorigin) * (src->ri_depth/8);
1139 	tga_dstb = offset + (dy + dst->ri_yorigin) * dst->ri_stride +
1140 		(dx + dst->ri_xorigin) * (dst->ri_depth/8);
1141 
1142 	TGAWALREG(dc, TGA_REG_GMOR, 3, 0x0007); /* Copy mode */
1143 	TGAWALREG(dc, TGA_REG_GOPR, 3, 0x0003); /* SRC */
1144 
1145 	/*
1146 	 * we have 3 sizes of pixels to move in X direction:
1147 	 * 4 * 64   (unrolled TGA ops)
1148 	 *     64   (single TGA op)
1149 	 *      4   (CPU, using long word)
1150 	 */
1151 
1152 	if (xdir == 1) {   /* move to the left */
1153 
1154 		for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
1155 
1156 			/* 4*64 byte chunks */
1157 			for (xleft = wb, x = xstart;
1158 			     x <= xend && xleft >= 4*64;
1159 			     x += XINC256, xleft -= XINC256) {
1160 
1161 				/* XXX XXX Eight writes to different addresses should fill
1162 				 * XXX XXX up the write buffers on 21064 and 21164 chips,
1163 				 * XXX XXX but later CPUs might have larger write buffers which
1164 				 * XXX XXX require further unrolling of this loop, or the
1165 				 * XXX XXX insertion of memory barriers.
1166 				 */
1167 				TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
1168 				TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
1169 				TGAWALREG(dc, TGA_REG_GCSR, 1, tga_srcb + y + x + 1 * 64);
1170 				TGAWALREG(dc, TGA_REG_GCDR, 1, tga_dstb + y + x + 1 * 64);
1171 				TGAWALREG(dc, TGA_REG_GCSR, 2, tga_srcb + y + x + 2 * 64);
1172 				TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 2 * 64);
1173 				TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 3 * 64);
1174 				TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 3 * 64);
1175 			}
1176 
1177 			/* 64 byte chunks */
1178 			for ( ; x <= xend && xleft >= 64;
1179 			      x += XINC64, xleft -= XINC64) {
1180 				TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
1181 				TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
1182 			}
1183 			lastx = x; lastleft = xleft;  /* remember for CPU loop */
1184 
1185 		}
1186 		TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */
1187 		TGAWALREG(dc, TGA_REG_GMOR, 0, 0x0000); /* Simple mode */
1188 
1189 		for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
1190 			/* 4 byte granularity */
1191 			for (x = lastx, xleft = lastleft;
1192 			     x <= xend && xleft >= 4;
1193 			     x += XINC4, xleft -= XINC4) {
1194 				*(uint32_t *)(dst->ri_bits + dstb + y + x) =
1195 					*(uint32_t *)(dst->ri_bits + srcb + y + x);
1196 			}
1197 		}
1198 	}
1199 	else {    /* above move to the left, below move to the right */
1200 
1201 		for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
1202 
1203 			/* 4*64 byte chunks */
1204 			for (xleft = wb, x = xstart;
1205 			     x >= xend && xleft >= 4*64;
1206 			     x -= XINC256, xleft -= XINC256) {
1207 
1208 				/* XXX XXX Eight writes to different addresses should fill
1209 				 * XXX XXX up the write buffers on 21064 and 21164 chips,
1210 				 * XXX XXX but later CPUs might have larger write buffers which
1211 				 * XXX XXX require further unrolling of this loop, or the
1212 				 * XXX XXX insertion of memory barriers.
1213 				 */
1214 				TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 3 * 64);
1215 				TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 3 * 64);
1216 				TGAWALREG(dc, TGA_REG_GCSR, 1, tga_srcb + y + x + 2 * 64);
1217 				TGAWALREG(dc, TGA_REG_GCDR, 1, tga_dstb + y + x + 2 * 64);
1218 				TGAWALREG(dc, TGA_REG_GCSR, 2, tga_srcb + y + x + 1 * 64);
1219 				TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 1 * 64);
1220 				TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 0 * 64);
1221 				TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 0 * 64);
1222 			}
1223 
1224 			if (xleft) x += XINC256 - XINC64;
1225 
1226 			/* 64 byte chunks */
1227 			for ( ; x >= xend && xleft >= 64;
1228 			      x -= XINC64, xleft -= XINC64) {
1229 				TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
1230 				TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
1231 			}
1232 			if (xleft) x += XINC64 - XINC4;
1233 			lastx = x; lastleft = xleft;  /* remember for CPU loop */
1234 		}
1235 		TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */
1236 		TGAWALREG(dc, TGA_REG_GMOR, 0, 0x0000); /* Simple mode */
1237 
1238 		for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
1239 			/* 4 byte granularity */
1240 			for (x = lastx, xleft = lastleft;
1241 			     x >= xend && xleft >= 4;
1242 			     x -= XINC4, xleft -= XINC4) {
1243 				*(uint32_t *)(dst->ri_bits + dstb + y + x) =
1244 					*(uint32_t *)(dst->ri_bits + srcb + y + x);
1245 			}
1246 		}
1247 	}
1248 	return 0;
1249 }
1250 
1251 
1252 void
1253 tga_putchar(c, row, col, uc, attr)
1254 	void *c;
1255 	int row, col;
1256 	u_int uc;
1257 	long attr;
1258 {
1259 	struct rasops_info *ri = c;
1260 	struct tga_devconfig *dc = ri->ri_hw;
1261 	int fs, height, width;
1262 	int fg, bg, ul;
1263 	u_char *fr;
1264 	int32_t *rp;
1265 
1266 	rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
1267 
1268 	height = ri->ri_font->fontheight;
1269 	width = ri->ri_font->fontwidth;
1270 
1271 	uc -= ri->ri_font->firstchar;
1272 	fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
1273 	fs = ri->ri_font->stride;
1274 
1275 	/* Set foreground and background color. XXX memoize this somehow?
1276 	 * The rasops code has already expanded the color entry to 32 bits
1277 	 * for us, even for 8-bit displays, so we don't have to do anything.
1278 	 */
1279 	ri->ri_ops.unpack_attr(c, attr, &fg, &bg, &ul);
1280 	TGAWREG(dc, TGA_REG_GFGR, ri->ri_devcmap[fg]);
1281 	TGAWREG(dc, TGA_REG_GBGR, ri->ri_devcmap[bg]);
1282 
1283 	/* Set raster operation to "copy"... */
1284 	if (ri->ri_depth == 8)
1285 		TGAWREG(dc, TGA_REG_GOPR, 0x3);
1286 	else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
1287 		TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8));
1288 
1289 	/* Set which pixels we're drawing (of a possible 32). */
1290 	TGAWREG(dc, TGA_REG_GPXR_P, (1 << width) - 1);
1291 
1292 	/* Set drawing mode to opaque stipple. */
1293 	TGAWREG(dc, TGA_REG_GMOR, 0x1);
1294 
1295 	/* Insert write barrier before actually sending data */
1296 	/* XXX Abuses the fact that there is only one write barrier on Alphas */
1297 	TGAREGWB(dc, TGA_REG_GMOR, 1);
1298 
1299 	while (height--) {
1300 		/* The actual stipple write */
1301 		*rp = fr[0] | (fr[1] << 8) | (fr[2] << 16) | (fr[3] << 24);
1302 
1303 		fr += fs;
1304 		rp = (int32_t *)((caddr_t)rp + ri->ri_stride);
1305 	}
1306 
1307 	/* Do underline */
1308 	if (ul) {
1309 		rp = (int32_t *)((caddr_t)rp - (ri->ri_stride << 1));
1310 		*rp = 0xffffffff;
1311 	}
1312 
1313 	/* Set grapics mode back to normal. */
1314 	TGAWREG(dc, TGA_REG_GMOR, 0);
1315 	TGAWREG(dc, TGA_REG_GPXR_P, 0xffffffff);
1316 }
1317 
1318 void
1319 tga_eraserows(c, row, num, attr)
1320 	void *c;
1321 	int row, num;
1322 	long attr;
1323 {
1324 	struct rasops_info *ri = c;
1325 	struct tga_devconfig *dc = ri->ri_hw;
1326 	int32_t color, lines, pixels;
1327 	int fg, bg;
1328 	int32_t *rp;
1329 
1330 	ri->ri_ops.unpack_attr(c, attr, &fg, &bg, NULL);
1331 	color = ri->ri_devcmap[bg];
1332 	rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale);
1333 	lines = num * ri->ri_font->fontheight;
1334 	pixels = ri->ri_emuwidth - 1;
1335 
1336 	/* Set fill color in block-color registers */
1337 	TGAWREG(dc, TGA_REG_GBCR0, color);
1338 	TGAWREG(dc, TGA_REG_GBCR1, color);
1339 	if (ri->ri_depth != 8) {
1340 		TGAWREG(dc, TGA_REG_GBCR2, color);
1341 		TGAWREG(dc, TGA_REG_GBCR3, color);
1342 		TGAWREG(dc, TGA_REG_GBCR4, color);
1343 		TGAWREG(dc, TGA_REG_GBCR5, color);
1344 		TGAWREG(dc, TGA_REG_GBCR6, color);
1345 		TGAWREG(dc, TGA_REG_GBCR7, color);
1346 	}
1347 
1348 	/* Set raster operation to "copy"... */
1349 	if (ri->ri_depth == 8)
1350 		TGAWREG(dc, TGA_REG_GOPR, 0x3);
1351 	else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
1352 		TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8));
1353 
1354 	/* Set which pixels we're drawing (of a possible 32). */
1355 	TGAWREG(dc, TGA_REG_GDAR, 0xffffffff);
1356 
1357 	/* Set drawing mode to block fill. */
1358 	TGAWREG(dc, TGA_REG_GMOR, 0x2d);
1359 
1360 	/* Insert write barrier before actually sending data */
1361 	/* XXX Abuses the fact that there is only one write barrier on Alphas */
1362 	TGAREGWB(dc, TGA_REG_GMOR, 1);
1363 
1364 	while (lines--) {
1365 		*rp = pixels;
1366 		rp = (int32_t *)((caddr_t)rp + ri->ri_stride);
1367 	}
1368 
1369 	/* Set grapics mode back to normal. */
1370 	TGAWREG(dc, TGA_REG_GMOR, 0);
1371 
1372 }
1373 
1374 void
1375 tga_erasecols (c, row, col, num, attr)
1376 	void *c;
1377 	int row, col, num;
1378 	long attr;
1379 {
1380 	struct rasops_info *ri = c;
1381 	struct tga_devconfig *dc = ri->ri_hw;
1382 	int32_t color, lines, pixels;
1383 	int fg, bg;
1384 	int32_t *rp;
1385 
1386 	ri->ri_ops.unpack_attr(c, attr, &fg, &bg, NULL);
1387 	color = ri->ri_devcmap[bg];
1388 	rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
1389 	lines = ri->ri_font->fontheight;
1390 	pixels = (num * ri->ri_font->fontwidth) - 1;
1391 
1392 	/* Set fill color in block-color registers */
1393 	TGAWREG(dc, TGA_REG_GBCR0, color);
1394 	TGAWREG(dc, TGA_REG_GBCR1, color);
1395 	if (ri->ri_depth != 8) {
1396 		TGAWREG(dc, TGA_REG_GBCR2, color);
1397 		TGAWREG(dc, TGA_REG_GBCR3, color);
1398 		TGAWREG(dc, TGA_REG_GBCR4, color);
1399 		TGAWREG(dc, TGA_REG_GBCR5, color);
1400 		TGAWREG(dc, TGA_REG_GBCR6, color);
1401 		TGAWREG(dc, TGA_REG_GBCR7, color);
1402 	}
1403 
1404 	/* Set raster operation to "copy"... */
1405 	if (ri->ri_depth == 8)
1406 		TGAWREG(dc, TGA_REG_GOPR, 0x3);
1407 	else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
1408 		TGAWREG(dc, TGA_REG_GOPR, 0x3 | (0x3 << 8));
1409 
1410 	/* Set which pixels we're drawing (of a possible 32). */
1411 	TGAWREG(dc, TGA_REG_GDAR, 0xffffffff);
1412 
1413 	/* Set drawing mode to block fill. */
1414 	TGAWREG(dc, TGA_REG_GMOR, 0x2d);
1415 
1416 	/* Insert write barrier before actually sending data */
1417 	/* XXX Abuses the fact that there is only one write barrier on Alphas */
1418 	TGAREGWB(dc, TGA_REG_GMOR, 1);
1419 
1420 	while (lines--) {
1421 		*rp = pixels;
1422 		rp = (int32_t *)((caddr_t)rp + ri->ri_stride);
1423 	}
1424 
1425 	/* Set grapics mode back to normal. */
1426 	TGAWREG(dc, TGA_REG_GMOR, 0);
1427 }
1428 
1429 
1430 void
1431 tga_ramdac_wr(v, btreg, val)
1432 	void *v;
1433 	u_int btreg;
1434 	u_int8_t val;
1435 {
1436 	struct tga_devconfig *dc = v;
1437 
1438 	if (btreg > BT485_REG_MAX)
1439 		panic("tga_ramdac_wr: reg %d out of range", btreg);
1440 
1441 	TGAWREG(dc, TGA_REG_EPDR, (btreg << 9) | (0 << 8 ) | val); /* XXX */
1442 	TGAREGWB(dc, TGA_REG_EPDR, 1);
1443 }
1444 
1445 void
1446 tga2_ramdac_wr(v, btreg, val)
1447 	void *v;
1448 	u_int btreg;
1449 	u_int8_t val;
1450 {
1451 	struct tga_devconfig *dc = v;
1452 	bus_space_handle_t ramdac;
1453 
1454 	if (btreg > BT485_REG_MAX)
1455 		panic("tga_ramdac_wr: reg %d out of range", btreg);
1456 
1457 	bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_RAMDAC +
1458 		(0xe << 12) + (btreg << 8), 4, &ramdac);
1459 	bus_space_write_4(dc->dc_memt, ramdac, 0, val & 0xff);
1460 	bus_space_barrier(dc->dc_memt, ramdac, 0, 4, BUS_SPACE_BARRIER_WRITE);
1461 }
1462 
1463 u_int8_t
1464 tga_bt463_rd(v, btreg)
1465 	void *v;
1466 	u_int btreg;
1467 {
1468 	struct tga_devconfig *dc = v;
1469 	tga_reg_t rdval;
1470 
1471 	/*
1472 	 * Strobe CE# (high->low->high) since status and data are latched on
1473 	 * the falling and rising edges (repsectively) of this active-low signal.
1474 	 */
1475 
1476 	TGAREGWB(dc, TGA_REG_EPSR, 1);
1477 	TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
1478 	TGAREGWB(dc, TGA_REG_EPSR, 1);
1479 	TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 0);
1480 
1481 	TGAREGRB(dc, TGA_REG_EPSR, 1);
1482 
1483 	rdval = TGARREG(dc, TGA_REG_EPDR);
1484 	TGAREGWB(dc, TGA_REG_EPSR, 1);
1485 	TGAWREG(dc, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
1486 
1487 	return (rdval >> 16) & 0xff;
1488 }
1489 
1490 void
1491 tga_bt463_wr(v, btreg, val)
1492 	void *v;
1493 	u_int btreg;
1494 	u_int8_t val;
1495 {
1496 	struct tga_devconfig *dc = v;
1497 
1498 	/*
1499 	 * In spite of the 21030 documentation, to set the MPU bus bits for
1500 	 * a write, you set them in the upper bits of EPDR, not EPSR.
1501 	 */
1502 
1503 	/*
1504 	 * Strobe CE# (high->low->high) since status and data are latched on
1505 	 * the falling and rising edges of this active-low signal.
1506 	 */
1507 
1508 	TGAREGWB(dc, TGA_REG_EPDR, 1);
1509 	TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
1510 	TGAREGWB(dc, TGA_REG_EPDR, 1);
1511 	TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x000 | val);
1512 	TGAREGWB(dc, TGA_REG_EPDR, 1);
1513 	TGAWREG(dc, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
1514 
1515 }
1516 
1517 u_int8_t
1518 tga_ramdac_rd(v, btreg)
1519 	void *v;
1520 	u_int btreg;
1521 {
1522 	struct tga_devconfig *dc = v;
1523 	tga_reg_t rdval;
1524 
1525 	if (btreg > BT485_REG_MAX)
1526 		panic("tga_ramdac_rd: reg %d out of range", btreg);
1527 
1528 	TGAWREG(dc, TGA_REG_EPSR, (btreg << 1) | 0x1); /* XXX */
1529 	TGAREGWB(dc, TGA_REG_EPSR, 1);
1530 
1531 	rdval = TGARREG(dc, TGA_REG_EPDR);
1532 	return (rdval >> 16) & 0xff;				/* XXX */
1533 }
1534 
1535 u_int8_t
1536 tga2_ramdac_rd(v, btreg)
1537 	void *v;
1538 	u_int btreg;
1539 {
1540 	struct tga_devconfig *dc = v;
1541 	bus_space_handle_t ramdac;
1542 	u_int8_t retval;
1543 
1544 	if (btreg > BT485_REG_MAX)
1545 		panic("tga_ramdac_rd: reg %d out of range", btreg);
1546 
1547 	bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_RAMDAC +
1548 		(0xe << 12) + (btreg << 8), 4, &ramdac);
1549 	retval = bus_space_read_4(dc->dc_memt, ramdac, 0) & 0xff;
1550 	bus_space_barrier(dc->dc_memt, ramdac, 0, 4, BUS_SPACE_BARRIER_READ);
1551 	return retval;
1552 }
1553 
1554 #include <dev/ic/decmonitors.c>
1555 void tga2_ics9110_wr(
1556 	struct tga_devconfig *dc,
1557 	int dotclock
1558 );
1559 
1560 struct monitor *tga_getmonitor(struct tga_devconfig *dc);
1561 
1562 void
1563 tga2_init(dc)
1564 	struct tga_devconfig *dc;
1565 {
1566 	struct	monitor *m = tga_getmonitor(dc);
1567 
1568 
1569 	/* Deal with the dot clocks.
1570 	 */
1571 	if (dc->dc_tga_type == TGA_TYPE_POWERSTORM_4D20) {
1572 		/* Set this up as a reference clock for the
1573 		 * ibm561's PLL.
1574 		 */
1575 		tga2_ics9110_wr(dc, 14300000);
1576 		/* XXX Can't set up the dotclock properly, until such time
1577 		 * as the RAMDAC is configured.
1578 		 */
1579 	} else {
1580 		/* otherwise the ics9110 is our clock. */
1581 		tga2_ics9110_wr(dc, m->dotclock);
1582 	}
1583 #if 0
1584 	TGAWREG(dc, TGA_REG_VHCR,
1585 	     ((m->hbp / 4) << 21) |
1586 	     ((m->hsync / 4) << 14) |
1587 	    (((m->hfp - 4) / 4) << 9) |
1588 	     ((m->cols + 4) / 4));
1589 #else
1590 	TGAWREG(dc, TGA_REG_VHCR,
1591 	     ((m->hbp / 4) << 21) |
1592 	     ((m->hsync / 4) << 14) |
1593 	    (((m->hfp) / 4) << 9) |
1594 	     ((m->cols) / 4));
1595 #endif
1596 	TGAWREG(dc, TGA_REG_VVCR,
1597 	    (m->vbp << 22) |
1598 	    (m->vsync << 16) |
1599 	    (m->vfp << 11) |
1600 	    (m->rows));
1601 	TGAWREG(dc, TGA_REG_VVBR, 1);
1602 	TGAREGRWB(dc, TGA_REG_VHCR, 3);
1603 	TGAWREG(dc, TGA_REG_VVVR, TGARREG(dc, TGA_REG_VVVR) | 1);
1604 	TGAREGRWB(dc, TGA_REG_VVVR, 1);
1605 	TGAWREG(dc, TGA_REG_GPMR, 0xffffffff);
1606 	TGAREGRWB(dc, TGA_REG_GPMR, 1);
1607 }
1608 
1609 void
1610 tga2_ics9110_wr(dc, dotclock)
1611 	struct tga_devconfig *dc;
1612 	int dotclock;
1613 {
1614 	bus_space_handle_t clock;
1615 	u_int32_t valU;
1616 	int N, M, R, V, X;
1617 	int i;
1618 
1619 	switch (dotclock) {
1620 	case 130808000:
1621 		N = 0x40; M = 0x7; V = 0x0; X = 0x1; R = 0x1; break;
1622 	case 119840000:
1623 		N = 0x2d; M = 0x2b; V = 0x1; X = 0x1; R = 0x1; break;
1624 	case 108180000:
1625 		N = 0x11; M = 0x9; V = 0x1; X = 0x1; R = 0x2; break;
1626 	case 103994000:
1627 		N = 0x6d; M = 0xf; V = 0x0; X = 0x1; R = 0x1; break;
1628 	case 175000000:
1629 		N = 0x5F; M = 0x3E; V = 0x1; X = 0x1; R = 0x1; break;
1630 	case  75000000:
1631 		N = 0x6e; M = 0x15; V = 0x0; X = 0x1; R = 0x1; break;
1632 	case  74000000:
1633 		N = 0x2a; M = 0x41; V = 0x1; X = 0x1; R = 0x1; break;
1634 	case  69000000:
1635 		N = 0x35; M = 0xb; V = 0x0; X = 0x1; R = 0x1; break;
1636 	case  65000000:
1637 		N = 0x6d; M = 0x0c; V = 0x0; X = 0x1; R = 0x2; break;
1638 	case  50000000:
1639 		N = 0x37; M = 0x3f; V = 0x1; X = 0x1; R = 0x2; break;
1640 	case  40000000:
1641 		N = 0x5f; M = 0x11; V = 0x0; X = 0x1; R = 0x2; break;
1642 	case  31500000:
1643 		N = 0x16; M = 0x05; V = 0x0; X = 0x1; R = 0x2; break;
1644 	case  25175000:
1645 		N = 0x66; M = 0x1d; V = 0x0; X = 0x1; R = 0x2; break;
1646 	case 135000000:
1647 		N = 0x42; M = 0x07; V = 0x0; X = 0x1; R = 0x1; break;
1648 	case 110000000:
1649 		N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
1650 	case 202500000:
1651 		N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
1652        case  14300000:         /* this one is just a ref clock */
1653                N = 0x03; M = 0x03; V = 0x1; X = 0x1; R = 0x3; break;
1654 	default:
1655 		panic("unrecognized clock rate %d", dotclock);
1656 	}
1657 
1658 	/* XXX -- hard coded, bad */
1659 	valU  = N | ( M << 7 ) | (V << 14);
1660 	valU |= (X << 15) | (R << 17);
1661 	valU |= 0x17 << 19;
1662 
1663 	bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_EXTDEV +
1664 	    TGA2_MEM_CLOCK + (0xe << 12), 4, &clock); /* XXX */
1665 
1666 	for (i = 24; i > 0; i--) {
1667 		u_int32_t writeval;
1668 
1669 		writeval = valU & 0x1;
1670 		if (i == 1)
1671 			writeval |= 0x2;
1672 		valU >>= 1;
1673 		bus_space_write_4(dc->dc_memt, clock, 0, writeval);
1674 		bus_space_barrier(dc->dc_memt, clock, 0, 4, BUS_SPACE_BARRIER_WRITE);
1675         }
1676 	bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA2_MEM_EXTDEV +
1677 	    TGA2_MEM_CLOCK + (0xe << 12) + (0x1 << 11) + (0x1 << 11), 4,
1678 		&clock); /* XXX */
1679 	bus_space_write_4(dc->dc_memt, clock, 0, 0x0);
1680 	bus_space_barrier(dc->dc_memt, clock, 0, 0, BUS_SPACE_BARRIER_WRITE);
1681 }
1682 
1683 struct monitor *
1684 tga_getmonitor(dc)
1685        struct tga_devconfig *dc;
1686 {
1687        return &decmonitors[(~TGARREG(dc, TGA_REG_GREV) >> 16) & 0x0f];
1688 }
1689 
1690 unsigned
1691 tga_getdotclock(dc)
1692        struct tga_devconfig *dc;
1693 {
1694        return tga_getmonitor(dc)->dotclock;
1695 }
1696