1 /* $NetBSD: tga.c,v 1.76 2009/05/16 13:04:26 tsutsui Exp $ */
4 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
7 * Author: Chris G. Demetriou
9 * Permission to use, copy, modify and distribute this software and
10 * its documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation.
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 * Carnegie Mellon requests users of this software to return to
21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22 * School of Computer Science
23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: tga.c,v 1.76 2009/05/16 13:04:26 tsutsui Exp $");
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/device.h>
38 #include <sys/malloc.h>
40 #include <sys/ioctl.h>
45 #include <dev/pci/pcireg.h>
46 #include <dev/pci/pcivar.h>
47 #include <dev/pci/pcidevs.h>
48 #include <dev/pci/pciio.h>
49 #include <dev/pci/tgareg.h>
50 #include <dev/pci/tgavar.h>
51 #include <dev/ic/bt485reg.h>
52 #include <dev/ic/bt485var.h>
53 #include <dev/ic/bt463reg.h>
54 #include <dev/ic/bt463var.h>
55 #include <dev/ic/ibm561var.h>
57 #include <dev/wscons/wsconsio.h>
58 #include <dev/wscons/wscons_raster.h>
59 #include <dev/rasops/rasops.h>
60 #include <dev/wsfont/wsfont.h>
61 #include <uvm/uvm_extern.h>
63 int tgamatch(device_t
, cfdata_t
, void *);
64 void tgaattach(device_t
, device_t
, void *);
65 int tgaprint(void *, const char *);
67 CFATTACH_DECL_NEW(tga
, sizeof(struct tga_softc
),
68 tgamatch
, tgaattach
, NULL
, NULL
);
70 static void tga_init(bus_space_tag_t memt
, pci_chipset_tag_t pc
,
71 pcitag_t tag
, struct tga_devconfig
*dc
);
73 static int tga_matchcommon(bus_space_tag_t
, pci_chipset_tag_t
, pcitag_t
);
74 static void tga_mapaddrs(bus_space_tag_t memt
, pci_chipset_tag_t pc
,
75 pcitag_t
, bus_size_t
*pcisize
, struct tga_devconfig
*dc
);
76 unsigned int tga_getdotclock(struct tga_devconfig
*dc
);
78 int tga_ioctl(void *, void *, u_long
, void *, int, struct lwp
*);
79 paddr_t
tga_mmap(void *, void *, off_t
, int);
80 static void tga_copyrows(void *, int, int, int);
81 static void tga_copycols(void *, int, int, int, int);
82 static int tga_alloc_screen(void *, const struct wsscreen_descr
*,
83 void **, int *, int *, long *);
84 static void tga_free_screen(void *, void *);
85 static int tga_show_screen(void *, void *, int,
86 void (*) (void *, int, int), void *);
87 static int tga_rop(struct rasops_info
*, int, int, int, int, int,
88 struct rasops_info
*, int, int);
89 static int tga_rop_vtov(struct rasops_info
*, int, int, int, int,
90 int, struct rasops_info
*, int, int);
91 static void tga_putchar(void *c
, int row
, int col
, u_int uc
, long attr
);
92 static void tga_eraserows(void *, int, int, long);
93 static void tga_erasecols(void *, int, int, int, long);
94 void tga2_init(struct tga_devconfig
*);
96 static void tga_config_interrupts(device_t
);
98 /* RAMDAC interface functions */
99 static int tga_sched_update(void *, void (*)(void *));
100 static void tga_ramdac_wr(void *, u_int
, uint8_t);
101 static uint8_t tga_ramdac_rd(void *, u_int
);
102 static void tga_bt463_wr(void *, u_int
, uint8_t);
103 static uint8_t tga_bt463_rd(void *, u_int
);
104 static void tga2_ramdac_wr(void *, u_int
, uint8_t);
105 static uint8_t tga2_ramdac_rd(void *, u_int
);
107 /* Interrupt handler */
108 static int tga_intr(void *);
110 struct tga_devconfig tga_console_dc
;
112 /* The NULL entries will get filled in by rasops_init().
113 * XXX and the non-NULL ones will be overwritten; reset after calling it.
115 struct wsdisplay_emulops tga_emulops
= {
127 struct wsscreen_descr tga_stdscreen
= {
129 0, 0, /* will be filled in -- XXX shouldn't, it's global */
136 const struct wsscreen_descr
*_tga_scrlist
[] = {
138 /* XXX other formats, graphics screen? */
141 struct wsscreen_list tga_screenlist
= {
142 sizeof(_tga_scrlist
) / sizeof(struct wsscreen_descr
*), _tga_scrlist
145 struct wsdisplay_accessops tga_accessops
= {
151 NULL
, /* load_font */
156 static void tga_blank(struct tga_devconfig
*);
157 static void tga_unblank(struct tga_devconfig
*);
160 tga_cnmatch(bus_space_tag_t iot
, bus_space_tag_t memt
,
161 pci_chipset_tag_t pc
, pcitag_t tag
)
164 return tga_matchcommon(memt
, pc
, tag
);
168 tgamatch(device_t parent
, cfdata_t match
, void *aux
)
170 struct pci_attach_args
*pa
= aux
;
172 if (PCI_VENDOR(pa
->pa_id
) != PCI_VENDOR_DEC
)
175 switch (PCI_PRODUCT(pa
->pa_id
)) {
176 case PCI_PRODUCT_DEC_21030
:
177 case PCI_PRODUCT_DEC_PBXGB
:
183 #if defined(__alpha__) || defined(arc)
184 /* short-circuit the following test, as we
185 * already have the memory mapped and hence
186 * cannot perform it---and we are the console
189 if (pa
->pa_tag
== tga_console_dc
.dc_pcitag
)
192 return tga_matchcommon(pa
->pa_memt
, pa
->pa_pc
, pa
->pa_tag
);
196 tga_matchcommon(bus_space_tag_t memt
, pci_chipset_tag_t pc
, pcitag_t tag
)
198 struct tga_devconfig tmp_dc
;
199 struct tga_devconfig
*dc
= &tmp_dc
;
202 tga_mapaddrs(memt
, pc
, tag
, &pcisize
, dc
);
203 dc
->dc_tga_type
= tga_identify(dc
);
205 dc
->dc_tgaconf
= tga_getconf(dc
->dc_tga_type
);
206 bus_space_unmap(memt
, dc
->dc_memh
, pcisize
);
213 tga_mapaddrs(bus_space_tag_t memt
, pci_chipset_tag_t pc
, pcitag_t tag
,
214 bus_size_t
*pcisize
, struct tga_devconfig
*dc
)
219 dc
->dc_tgaconf
= NULL
;
221 /* XXX magic number */
222 if (pci_mapreg_info(pc
, tag
, 0x10,
223 PCI_MAPREG_TYPE_MEM
| PCI_MAPREG_MEM_TYPE_32BIT
,
224 &dc
->dc_pcipaddr
, pcisize
, &flags
))
225 panic("tga_mapaddrs: pci_mapreg_info() failed");
226 if ((flags
& BUS_SPACE_MAP_PREFETCHABLE
) == 0) /* XXX */
227 panic("tga memory not prefetchable");
229 if (bus_space_map(memt
, dc
->dc_pcipaddr
, *pcisize
,
230 BUS_SPACE_MAP_PREFETCHABLE
| BUS_SPACE_MAP_LINEAR
, &dc
->dc_memh
))
231 panic("tga_mapaddrs: could not map TGA address space");
232 dc
->dc_vaddr
= (vaddr_t
)bus_space_vaddr(memt
, dc
->dc_memh
);
234 bus_space_subregion(dc
->dc_memt
, dc
->dc_memh
,
235 TGA_MEM_CREGS
, TGA_CREGS_SIZE
, &dc
->dc_regs
);
239 tga_init(bus_space_tag_t memt
, pci_chipset_tag_t pc
, pcitag_t tag
,
240 struct tga_devconfig
*dc
)
242 const struct tga_conf
*tgac
;
243 struct rasops_info
*rip
;
250 tga_mapaddrs(memt
, pc
, tag
, &pcisize
, dc
);
251 dc
->dc_tga_type
= tga_identify(dc
);
252 tgac
= dc
->dc_tgaconf
= tga_getconf(dc
->dc_tga_type
);
254 /* XXX on the Alpha, pcisize = 4 * cspace_size. */
255 if (tgac
->tgac_cspace_size
!= pcisize
) /* sanity */
256 panic("tga_init: memory size mismatch?");
259 switch (TGARREG(dc
, TGA_REG_GREV
) & 0xff) {
272 panic("tga_init: TGA Revision not recognized");
278 switch (TGARREG(dc
, TGA_REG_VHCR
) & 0x1ff) { /* XXX */
288 dc
->dc_wid
= (TGARREG(dc
, TGA_REG_VHCR
) & 0x1ff) * 4; /* XXX */
293 * XXX XXX Turning off "odd" shouldn't be necessary,
294 * XXX XXX but I can't make X work with the weird size.
296 if ((TGARREG(dc
, TGA_REG_VHCR
) & 0x00000001) != 0 && /* XXX */
297 (TGARREG(dc
, TGA_REG_VHCR
) & 0x80000000) != 0) { /* XXX */
298 TGAWREG(dc
, TGA_REG_VHCR
,
299 (TGARREG(dc
, TGA_REG_VHCR
) & ~0x80000001));
303 dc
->dc_rowbytes
= dc
->dc_wid
* (dc
->dc_tgaconf
->tgac_phys_depth
/ 8);
304 dc
->dc_ht
= (TGARREG(dc
, TGA_REG_VVCR
) & 0x7ff); /* XXX */
306 /* XXX this seems to be what DEC does */
307 TGAWREG(dc
, TGA_REG_CCBR
, 0);
308 TGAWREG(dc
, TGA_REG_VVBR
, 1);
309 dc
->dc_videobase
= dc
->dc_vaddr
+ tgac
->tgac_dbuf
[0] +
310 1 * tgac
->tgac_vvbr_units
;
315 * Set all bits in the pixel mask, to enable writes to all pixels.
316 * It seems that the console firmware clears some of them
317 * under some circumstances, which causes cute vertical stripes.
319 TGAWREG(dc
, TGA_REG_GPXR_P
, 0xffffffff);
321 /* clear the screen */
322 for (i
= 0; i
< dc
->dc_ht
* dc
->dc_rowbytes
; i
+= sizeof(uint32_t))
323 *(uint32_t *)(dc
->dc_videobase
+ i
) = 0;
325 /* Initialize rasops descriptor */
327 rip
->ri_flg
= RI_CENTER
;
328 rip
->ri_depth
= tgac
->tgac_phys_depth
;
329 rip
->ri_bits
= (void *)dc
->dc_videobase
;
330 rip
->ri_width
= dc
->dc_wid
;
331 rip
->ri_height
= dc
->dc_ht
;
332 rip
->ri_stride
= dc
->dc_rowbytes
;
335 if (tgac
->tgac_phys_depth
== 32) {
345 /* prefer 8 pixel wide font */
346 cookie
= wsfont_find(NULL
, 8, 0, 0, WSDISPLAY_FONTORDER_R2L
,
347 WSDISPLAY_FONTORDER_L2R
);
349 cookie
= wsfont_find(NULL
, 0, 0, 0, WSDISPLAY_FONTORDER_R2L
,
350 WSDISPLAY_FONTORDER_L2R
);
352 printf("tga: no appropriate fonts.\n");
356 /* the accelerated tga_putchar() needs LSbit left */
357 if (wsfont_lock(cookie
, &dc
->dc_rinfo
.ri_font
)) {
358 printf("tga: couldn't lock font\n");
361 dc
->dc_rinfo
.ri_wsfcookie
= cookie
;
363 rasops_init(rip
, 34, 80);
365 /* add our accelerated functions */
366 /* XXX shouldn't have to do this; rasops should leave non-NULL
369 dc
->dc_rinfo
.ri_ops
.copyrows
= tga_copyrows
;
370 dc
->dc_rinfo
.ri_ops
.eraserows
= tga_eraserows
;
371 dc
->dc_rinfo
.ri_ops
.erasecols
= tga_erasecols
;
372 dc
->dc_rinfo
.ri_ops
.copycols
= tga_copycols
;
373 dc
->dc_rinfo
.ri_ops
.putchar
= tga_putchar
;
375 tga_stdscreen
.nrows
= dc
->dc_rinfo
.ri_rows
;
376 tga_stdscreen
.ncols
= dc
->dc_rinfo
.ri_cols
;
377 tga_stdscreen
.textops
= &dc
->dc_rinfo
.ri_ops
;
378 tga_stdscreen
.capabilities
= dc
->dc_rinfo
.ri_caps
;
381 dc
->dc_intrenabled
= 0;
385 tgaattach(device_t parent
, device_t self
, void *aux
)
387 struct pci_attach_args
*pa
= aux
;
388 struct tga_softc
*sc
= device_private(self
);
389 struct tga_devconfig
*dc
;
390 struct wsemuldisplaydev_attach_args aa
;
391 pci_intr_handle_t intrh
;
398 #if defined(__alpha__) || defined(arc)
399 console
= (pa
->pa_tag
== tga_console_dc
.dc_pcitag
);
404 sc
->sc_dc
= &tga_console_dc
;
407 sc
->sc_dc
= malloc(sizeof(struct tga_devconfig
), M_DEVBUF
,
409 tga_init(pa
->pa_memt
, pa
->pa_pc
, pa
->pa_tag
, sc
->sc_dc
);
411 if (sc
->sc_dc
->dc_vaddr
== 0) {
412 aprint_error(": couldn't map memory space; punt!\n");
416 /* XXX say what's going on. */
418 if (pci_intr_map(pa
, &intrh
)) {
419 aprint_error(": couldn't map interrupt");
422 intrstr
= pci_intr_string(pa
->pa_pc
, intrh
);
423 sc
->sc_intr
= pci_intr_establish(pa
->pa_pc
, intrh
, IPL_TTY
, tga_intr
,
425 if (sc
->sc_intr
== NULL
) {
426 aprint_error(": couldn't establish interrupt");
428 aprint_error("at %s", intrstr
);
433 rev
= PCI_REVISION(pa
->pa_class
);
438 aprint_normal(": DC21030 step %c", 'A' + rev
- 1);
441 aprint_normal(": TGA2 abstract software model");
445 aprint_normal(": TGA2 pass %d", rev
- 0x20);
449 aprint_normal("unknown stepping (0x%x)", rev
);
455 * Get RAMDAC function vectors and call the RAMDAC functions
456 * to allocate its private storage and pass that back to us.
460 dc
->dc_ramdac_funcs
= dc
->dc_tgaconf
->ramdac_funcs();
462 if (dc
->dc_tgaconf
->ramdac_funcs
== bt485_funcs
)
463 dc
->dc_ramdac_cookie
=
464 dc
->dc_ramdac_funcs
->ramdac_register(dc
,
465 tga_sched_update
, tga_ramdac_wr
, tga_ramdac_rd
);
467 dc
->dc_ramdac_cookie
=
468 dc
->dc_ramdac_funcs
->ramdac_register(dc
,
469 tga_sched_update
, tga_bt463_wr
, tga_bt463_rd
);
471 dc
->dc_ramdac_cookie
= dc
->dc_ramdac_funcs
->ramdac_register(dc
,
472 tga_sched_update
, tga2_ramdac_wr
, tga2_ramdac_rd
);
474 /* XXX this is a bit of a hack, setting the dotclock here */
475 if (dc
->dc_tgaconf
->ramdac_funcs
!= bt485_funcs
)
476 (*dc
->dc_ramdac_funcs
->ramdac_set_dotclock
)
477 (dc
->dc_ramdac_cookie
, tga_getdotclock(dc
));
481 * Initialize the RAMDAC. Initialization includes disabling
482 * cursor, setting a sane colormap, etc. We presume that we've
483 * filled in the necessary dot clock for PowerStorm 4d20.
485 (*dc
->dc_ramdac_funcs
->ramdac_init
)(dc
->dc_ramdac_cookie
);
486 TGAWREG(dc
, TGA_REG_SISR
, 0x00000001); /* XXX */
488 if (dc
->dc_tgaconf
== NULL
) {
489 aprint_error("unknown board configuration\n");
492 aprint_normal("board type %s\n", dc
->dc_tgaconf
->tgac_name
);
493 aprint_normal_dev(self
, "%d x %d, %dbpp, %s RAMDAC\n",
494 dc
->dc_wid
, dc
->dc_ht
,
495 dc
->dc_tgaconf
->tgac_phys_depth
,
496 dc
->dc_ramdac_funcs
->ramdac_name
);
499 aprint_normal_dev(self
, "interrupting at %s\n",
502 aa
.console
= console
;
503 aa
.scrdata
= &tga_screenlist
;
504 aa
.accessops
= &tga_accessops
;
505 aa
.accesscookie
= sc
;
507 config_found(self
, &aa
, wsemuldisplaydevprint
);
509 config_interrupts(self
, tga_config_interrupts
);
513 tga_config_interrupts(device_t self
)
515 struct tga_softc
*sc
;
517 sc
= device_private(self
);
518 sc
->sc_dc
->dc_intrenabled
= 1;
522 tga_ioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
524 struct tga_softc
*sc
= v
;
525 struct tga_devconfig
*dc
= sc
->sc_dc
;
526 struct ramdac_funcs
*dcrf
= dc
->dc_ramdac_funcs
;
527 struct ramdac_cookie
*dcrc
= dc
->dc_ramdac_cookie
;
530 case WSDISPLAYIO_GTYPE
:
531 *(u_int
*)data
= WSDISPLAY_TYPE_TGA
;
534 case WSDISPLAYIO_GINFO
:
535 #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
536 wsd_fbip
->height
= sc
->sc_dc
->dc_ht
;
537 wsd_fbip
->width
= sc
->sc_dc
->dc_wid
;
538 wsd_fbip
->depth
= sc
->sc_dc
->dc_tgaconf
->tgac_phys_depth
;
540 wsd_fbip
->cmsize
= 256; /* XXX ??? */
542 wsd_fbip
->cmsize
= 1024; /* XXX ??? */
547 case WSDISPLAYIO_GETCMAP
:
548 return (*dcrf
->ramdac_get_cmap
)(dcrc
,
549 (struct wsdisplay_cmap
*)data
);
551 case WSDISPLAYIO_PUTCMAP
:
552 return (*dcrf
->ramdac_set_cmap
)(dcrc
,
553 (struct wsdisplay_cmap
*)data
);
555 case WSDISPLAYIO_SVIDEO
:
556 if (*(u_int
*)data
== WSDISPLAYIO_VIDEO_OFF
)
557 tga_blank(sc
->sc_dc
);
559 tga_unblank(sc
->sc_dc
);
562 case WSDISPLAYIO_GVIDEO
:
563 *(u_int
*)data
= dc
->dc_blanked
?
564 WSDISPLAYIO_VIDEO_OFF
: WSDISPLAYIO_VIDEO_ON
;
567 case WSDISPLAYIO_GCURPOS
:
568 return (*dcrf
->ramdac_get_curpos
)(dcrc
,
569 (struct wsdisplay_curpos
*)data
);
571 case WSDISPLAYIO_SCURPOS
:
572 return (*dcrf
->ramdac_set_curpos
)(dcrc
,
573 (struct wsdisplay_curpos
*)data
);
575 case WSDISPLAYIO_GCURMAX
:
576 return (*dcrf
->ramdac_get_curmax
)(dcrc
,
577 (struct wsdisplay_curpos
*)data
);
579 case WSDISPLAYIO_GCURSOR
:
580 return (*dcrf
->ramdac_get_cursor
)(dcrc
,
581 (struct wsdisplay_cursor
*)data
);
583 case WSDISPLAYIO_SCURSOR
:
584 return (*dcrf
->ramdac_set_cursor
)(dcrc
,
585 (struct wsdisplay_cursor
*)data
);
587 case WSDISPLAYIO_LINEBYTES
:
588 *(u_int
*)data
= dc
->dc_rowbytes
;
591 /* PCI config read/write passthrough. */
592 case PCI_IOC_CFGREAD
:
593 case PCI_IOC_CFGWRITE
:
594 return pci_devioctl(dc
->dc_pc
, dc
->dc_pcitag
,
601 tga_sched_update(void *v
, void (*f
)(void *))
603 struct tga_devconfig
*dc
= v
;
605 if (dc
->dc_intrenabled
) {
607 * Arrange for f to be called at the next end-of-frame
610 dc
->dc_ramdac_intr
= f
;
611 TGAWREG(dc
, TGA_REG_SISR
, 0x00010000);
613 /* Spin until the end-of-frame, then call f */
614 TGAWREG(dc
, TGA_REG_SISR
, 0x00010001);
615 TGAREGWB(dc
, TGA_REG_SISR
, 1);
616 while ((TGARREG(dc
, TGA_REG_SISR
) & 0x00000001) == 0)
618 f(dc
->dc_ramdac_cookie
);
619 TGAWREG(dc
, TGA_REG_SISR
, 0x00000001);
620 TGAREGWB(dc
, TGA_REG_SISR
, 1);
629 struct tga_devconfig
*dc
= v
;
630 struct ramdac_cookie
*dcrc
= dc
->dc_ramdac_cookie
;
634 reg
= TGARREG(dc
, TGA_REG_SISR
);
635 if (( reg
& 0x00010001) != 0x00010001) {
636 /* Odd. We never set any of the other interrupt enables. */
637 if ((reg
& 0x1f) != 0) {
638 /* Clear the mysterious pending interrupts. */
639 TGAWREG(dc
, TGA_REG_SISR
, (reg
& 0x1f));
640 TGAREGWB(dc
, TGA_REG_SISR
, 1);
642 * This was our interrupt, even if we're puzzled
643 * as to why we got it. Don't make the interrupt
644 * handler think it was a stray.
651 /* if we have something to do, do it */
652 if (dc
->dc_ramdac_intr
) {
653 dc
->dc_ramdac_intr(dcrc
);
654 dc
->dc_ramdac_intr
= NULL
;
656 TGAWREG(dc
, TGA_REG_SISR
, 0x00000001);
657 TGAREGWB(dc
, TGA_REG_SISR
, 1);
662 tga_mmap(void *v
, void *vs
, off_t offset
, int prot
)
664 struct tga_softc
*sc
= v
;
666 if (offset
>= sc
->sc_dc
->dc_tgaconf
->tgac_cspace_size
|| offset
< 0)
669 return bus_space_mmap(sc
->sc_dc
->dc_memt
, sc
->sc_dc
->dc_pcipaddr
,
670 offset
, prot
, BUS_SPACE_MAP_LINEAR
);
674 tga_alloc_screen(void *v
, const struct wsscreen_descr
*type
, void **cookiep
,
675 int *curxp
, int *curyp
, long *attrp
)
677 struct tga_softc
*sc
= v
;
680 if (sc
->nscreens
> 0)
683 *cookiep
= &sc
->sc_dc
->dc_rinfo
; /* one and only for now */
686 sc
->sc_dc
->dc_rinfo
.ri_ops
.allocattr(&sc
->sc_dc
->dc_rinfo
,
694 tga_free_screen(void *v
, void *cookie
)
696 struct tga_softc
*sc
= v
;
698 if (sc
->sc_dc
== &tga_console_dc
)
699 panic("tga_free_screen: console");
705 tga_show_screen(void *v
, void *cookie
, int waitok
,
706 void (*cb
)(void *, int, int), void *cbarg
)
713 tga_cnattach(bus_space_tag_t iot
, bus_space_tag_t memt
,
714 pci_chipset_tag_t pc
, int bus
, int device
, int function
)
716 struct tga_devconfig
*dcp
= &tga_console_dc
;
719 tga_init(memt
, pc
, pci_make_tag(pc
, bus
, device
, function
), dcp
);
722 if (dcp
->dc_vaddr
== 0)
723 panic("tga_console(%d, %d): couldn't map memory space",
725 if (dcp
->dc_tgaconf
== NULL
)
726 panic("tga_console(%d, %d): unknown board configuration",
730 * Initialize the RAMDAC but DO NOT allocate any private storage.
731 * Initialization includes disabling cursor, setting a sane
732 * colormap, etc. It will be reinitialized in tgaattach().
735 if (dcp
->dc_tgaconf
->ramdac_funcs
== bt485_funcs
)
736 bt485_cninit(dcp
, tga_sched_update
, tga2_ramdac_wr
,
739 ibm561_cninit(dcp
, tga_sched_update
, tga2_ramdac_wr
,
740 tga2_ramdac_rd
, tga_getdotclock(dcp
));
742 if (dcp
->dc_tgaconf
->ramdac_funcs
== bt485_funcs
)
743 bt485_cninit(dcp
, tga_sched_update
, tga_ramdac_wr
,
746 bt463_cninit(dcp
, tga_sched_update
, tga_bt463_wr
,
750 dcp
->dc_rinfo
.ri_ops
.allocattr(&dcp
->dc_rinfo
, 0, 0, 0, &defattr
);
751 wsdisplay_cnattach(&tga_stdscreen
, &dcp
->dc_rinfo
, 0, 0, defattr
);
757 * Functions to blank and unblank the display.
760 tga_blank(struct tga_devconfig
*dc
)
763 if (!dc
->dc_blanked
) {
766 TGAWREG(dc
, TGA_REG_VVVR
,
767 TGARREG(dc
, TGA_REG_VVVR
) | VVR_BLANK
);
772 tga_unblank(struct tga_devconfig
*dc
)
775 if (dc
->dc_blanked
) {
778 TGAWREG(dc
, TGA_REG_VVVR
,
779 TGARREG(dc
, TGA_REG_VVVR
) & ~VVR_BLANK
);
784 * Functions to manipulate the built-in cursor handing hardware.
787 tga_builtin_set_cursor(struct tga_devconfig
*dc
,
788 struct wsdisplay_cursor
*cursorp
)
790 struct ramdac_funcs
*dcrf
= dc
->dc_ramdac_funcs
;
791 struct ramdac_cookie
*dcrc
= dc
->dc_ramdac_cookie
;
797 if (v
& WSDISPLAY_CURSOR_DOCMAP
) {
798 error
= dcrf
->ramdac_check_curcmap(dcrc
, cursorp
);
802 if (v
& WSDISPLAY_CURSOR_DOSHAPE
) {
803 if ((u_int
)cursorp
->size
.x
!= 64 ||
804 (u_int
)cursorp
->size
.y
> 64)
806 /* The cursor is 2 bits deep, and there is no mask */
807 count
= (cursorp
->size
.y
* 64 * 2) / NBBY
;
808 error
= copyin(cursorp
->image
, image
, count
);
812 if (v
& WSDISPLAY_CURSOR_DOHOT
) /* not supported */
815 /* parameters are OK; do it */
816 if (v
& WSDISPLAY_CURSOR_DOCUR
) {
819 TGAWREG(dc
, TGA_REG_VVVR
,
820 TGARREG(dc
, TGA_REG_VVVR
) | 0x04);
823 TGAWREG(dc
, TGA_REG_VVVR
,
824 TGARREG(dc
, TGA_REG_VVVR
) & ~0x04);
826 if (v
& WSDISPLAY_CURSOR_DOPOS
) {
827 TGAWREG(dc
, TGA_REG_CXYR
, ((cursorp
->pos
.y
& 0xfff) << 12) |
828 (cursorp
->pos
.x
& 0xfff));
830 if (v
& WSDISPLAY_CURSOR_DOCMAP
) {
831 dcrf
->ramdac_set_curcmap(dcrc
, cursorp
);
833 if (v
& WSDISPLAY_CURSOR_DOSHAPE
) {
834 count
= ((64 * 2) / NBBY
) * cursorp
->size
.y
;
835 TGAWREG(dc
, TGA_REG_CCBR
,
836 (TGARREG(dc
, TGA_REG_CCBR
) & ~0xfc00) |
837 (cursorp
->size
.y
<< 10));
838 memcpy((void *)(dc
->dc_vaddr
+
839 (TGARREG(dc
, TGA_REG_CCBR
) & 0x3ff)),
846 tga_builtin_get_cursor(struct tga_devconfig
*dc
,
847 struct wsdisplay_cursor
*cursorp
)
849 struct ramdac_funcs
*dcrf
= dc
->dc_ramdac_funcs
;
850 struct ramdac_cookie
*dcrc
= dc
->dc_ramdac_cookie
;
853 cursorp
->which
= WSDISPLAY_CURSOR_DOALL
&
854 ~(WSDISPLAY_CURSOR_DOHOT
| WSDISPLAY_CURSOR_DOCMAP
);
855 cursorp
->enable
= (TGARREG(dc
, TGA_REG_VVVR
) & 0x04) != 0;
856 cursorp
->pos
.x
= TGARREG(dc
, TGA_REG_CXYR
) & 0xfff;
857 cursorp
->pos
.y
= (TGARREG(dc
, TGA_REG_CXYR
) >> 12) & 0xfff;
858 cursorp
->size
.x
= 64;
859 cursorp
->size
.y
= (TGARREG(dc
, TGA_REG_CCBR
) >> 10) & 0x3f;
861 if (cursorp
->image
!= NULL
) {
862 count
= (cursorp
->size
.y
* 64 * 2) / NBBY
;
863 error
= copyout((char *)(dc
->dc_vaddr
+
864 (TGARREG(dc
, TGA_REG_CCBR
) & 0x3ff)),
865 cursorp
->image
, count
);
870 error
= dcrf
->ramdac_get_curcmap(dcrc
, cursorp
);
875 tga_builtin_set_curpos(struct tga_devconfig
*dc
,
876 struct wsdisplay_curpos
*curposp
)
879 TGAWREG(dc
, TGA_REG_CXYR
,
880 ((curposp
->y
& 0xfff) << 12) | (curposp
->x
& 0xfff));
885 tga_builtin_get_curpos(struct tga_devconfig
*dc
,
886 struct wsdisplay_curpos
*curposp
)
889 curposp
->x
= TGARREG(dc
, TGA_REG_CXYR
) & 0xfff;
890 curposp
->y
= (TGARREG(dc
, TGA_REG_CXYR
) >> 12) & 0xfff;
895 tga_builtin_get_curmax(struct tga_devconfig
*dc
,
896 struct wsdisplay_curpos
*curposp
)
899 curposp
->x
= curposp
->y
= 64;
904 * Copy columns (characters) in a row (line).
907 tga_copycols(void *id
, int row
, int srccol
, int dstcol
, int ncols
)
909 struct rasops_info
*ri
= id
;
910 int y
, srcx
, dstx
, nx
;
912 y
= ri
->ri_font
->fontheight
* row
;
913 srcx
= ri
->ri_font
->fontwidth
* srccol
;
914 dstx
= ri
->ri_font
->fontwidth
* dstcol
;
915 nx
= ri
->ri_font
->fontwidth
* ncols
;
918 nx
, ri
->ri_font
->fontheight
, RAS_SRC
,
926 tga_copyrows(void *id
, int srcrow
, int dstrow
, int nrows
)
928 struct rasops_info
*ri
= id
;
931 srcy
= ri
->ri_font
->fontheight
* srcrow
;
932 dsty
= ri
->ri_font
->fontheight
* dstrow
;
933 ny
= ri
->ri_font
->fontheight
* nrows
;
936 ri
->ri_emuwidth
, ny
, RAS_SRC
,
940 /* Do we need the src? */
941 static const int needsrc
[16] =
942 { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0 };
944 /* A mapping between our API and the TGA card */
945 static const int map_rop
[16] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6,
946 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
950 * Generic TGA raster op.
951 * This covers all possible raster ops, and
952 * clips the sizes and all of that.
955 tga_rop(struct rasops_info
*dst
, int dx
, int dy
, int w
, int h
, int rop
,
956 struct rasops_info
*src
, int sx
, int sy
)
961 if (needsrc
[RAS_GETOP(rop
)]) {
963 return -1; /* We want a src */
964 /* Clip against src */
973 if (sx
+ w
> src
->ri_emuwidth
)
974 w
= src
->ri_emuwidth
- sx
;
975 if (sy
+ h
> src
->ri_emuheight
)
976 h
= src
->ri_emuheight
- sy
;
979 return -1; /* We need no src */
981 /* Clip against dst. We modify src regardless of using it,
982 * since it really doesn't matter.
994 if (dx
+ w
> dst
->ri_emuwidth
)
995 w
= dst
->ri_emuwidth
- dx
;
996 if (dy
+ h
> dst
->ri_emuheight
)
997 h
= dst
->ri_emuheight
- dy
;
998 if (w
<= 0 || h
<= 0)
999 return 0; /* Vacuously true; */
1004 return tga_rop_vtov(dst
, dx
, dy
, w
, h
, rop
, src
, sx
, sy
);
1010 * Video to Video raster ops.
1011 * This function deals with all raster ops that have a src and dst
1012 * that are on the card.
1015 tga_rop_vtov(struct rasops_info
*dst
, int dx
, int dy
, int w
, int h
, int rop
,
1016 struct rasops_info
*src
, int sx
, int sy
)
1018 struct tga_devconfig
*dc
= dst
->ri_hw
;
1019 int srcb
, dstb
, tga_srcb
, tga_dstb
;
1021 int xstart
, xend
, xdir
;
1022 int ystart
, yend
, ydir
, yinc
;
1023 int xleft
, lastx
, lastleft
;
1024 int offset
= 1 * dc
->dc_tgaconf
->tgac_vvbr_units
;
1027 * I don't yet want to deal with unaligned guys, really. And we don't
1028 * deal with copies from one card to another.
1030 if (dx
% 8 != 0 || sx
% 8 != 0 || src
!= dst
) {
1032 /* XXX should never happen, since it's only being used to
1033 * XXX copy 8-pixel-wide characters.
1038 srcb
= sy
* src
->ri_stride
+ sx
* (src
->ri_depth
/ 8);
1039 dstb
= dy
* dst
->ri_stride
+ dx
* (dst
->ri_depth
/ 8);
1040 tga_srcb
= offset
+ (sy
+ src
->ri_yorigin
) * src
->ri_stride
+
1041 (sx
+ src
->ri_xorigin
) * (src
->ri_depth
/ 8);
1042 tga_dstb
= offset
+ (dy
+ dst
->ri_yorigin
) * dst
->ri_stride
+
1043 (dx
+ dst
->ri_xorigin
) * (dst
->ri_depth
/ 8);
1047 yend
= (h
- 1) * dst
->ri_stride
;
1050 ystart
= (h
- 1) * dst
->ri_stride
;
1054 yinc
= ydir
* dst
->ri_stride
;
1056 wb
= w
* (dst
->ri_depth
/ 8);
1057 if (sx
>= dx
|| (sx
+ w
) <= dx
) { /* copy forwards */
1061 } else { /* copy backwards */
1067 TGAWALREG(dc
, TGA_REG_GMOR
, 3, 0x0007); /* Copy mode */
1068 TGAWALREG(dc
, TGA_REG_GOPR
, 3, map_rop
[rop
]); /* Set up the op */
1069 TGAWALREG(dc
, TGA_REG_GPSR
, 3, 0); /* No shift */
1072 * we have 3 sizes of pixels to move in X direction:
1073 * 4 * 64 (unrolled TGA ops)
1074 * 64 (single TGA op)
1075 * 4 (CPU, using long word)
1078 if (xdir
== 1) { /* move to the left */
1081 for (y
= ystart
; (ydir
* y
) <= (ydir
* yend
); y
+= yinc
) {
1082 /* 4 * 64 byte chunks */
1083 for (xleft
= wb
, x
= xstart
; xleft
>= 4 * 64;
1084 x
+= 4 * 64, xleft
-= 4 * 64) {
1087 * XXX XXX Eight writes to different addresses
1088 * XXX XXX should fill up the write buffers on
1089 * XXX XXX 21064 and 21164 chips, but later
1090 * XXX XXX CPUs might have larger write buffers
1091 * XXX XXX which require further unrolling of
1092 * XXX XXX this loop, or the insertion of
1093 * XXX XXX memory barriers.
1095 TGAWALREG(dc
, TGA_REG_GCSR
, 0,
1096 tga_srcb
+ y
+ x
+ 0 * 64);
1097 TGAWALREG(dc
, TGA_REG_GCDR
, 0,
1098 tga_dstb
+ y
+ x
+ 0 * 64);
1099 TGAWALREG(dc
, TGA_REG_GCSR
, 1,
1100 tga_srcb
+ y
+ x
+ 1 * 64);
1101 TGAWALREG(dc
, TGA_REG_GCDR
, 1,
1102 tga_dstb
+ y
+ x
+ 1 * 64);
1103 TGAWALREG(dc
, TGA_REG_GCSR
, 2,
1104 tga_srcb
+ y
+ x
+ 2 * 64);
1105 TGAWALREG(dc
, TGA_REG_GCDR
, 2,
1106 tga_dstb
+ y
+ x
+ 2 * 64);
1107 TGAWALREG(dc
, TGA_REG_GCSR
, 3,
1108 tga_srcb
+ y
+ x
+ 3 * 64);
1109 TGAWALREG(dc
, TGA_REG_GCDR
, 3,
1110 tga_dstb
+ y
+ x
+ 3 * 64);
1113 /* 64 byte chunks */
1114 for (; xleft
>= 64; x
+= 64, xleft
-= 64) {
1115 TGAWALREG(dc
, TGA_REG_GCSR
, 0,
1116 tga_srcb
+ y
+ x
+ 0 * 64);
1117 TGAWALREG(dc
, TGA_REG_GCDR
, 0,
1118 tga_dstb
+ y
+ x
+ 0 * 64);
1122 TGAWALREG(dc
, TGA_REG_GOPR
, 0, 0x0003); /* op -> dst = src */
1123 TGAWALREG(dc
, TGA_REG_GMOR
, 0, 0x0000); /* Simple mode */
1127 lastx
= xstart
+ (wb
& ~63);
1128 for (y
= ystart
; (ydir
* y
) <= (ydir
* yend
);
1130 /* 4 byte granularity */
1131 for (x
= lastx
, xleft
= lastleft
; xleft
>= 4;
1132 x
+= 4, xleft
-= 4) {
1133 *(uint32_t *)(dst
->ri_bits
+ dstb
+
1135 *(uint32_t *)(dst
->ri_bits
+ srcb
+
1140 } else { /* above move to the left, below move to the right */
1143 for (y
= ystart
; (ydir
* y
) <= (ydir
* yend
); y
+= yinc
) {
1144 /* 4 * 64 byte chunks */
1145 for (xleft
= wb
, x
= xstart
; xleft
>= 4 * 64;
1146 x
-= 4 * 64, xleft
-= 4 * 64) {
1149 * XXX XXX Eight writes to different addresses
1150 * XXX XXX should fill up the write buffers on
1151 * XXX XXX 21064 and 21164 chips, but later
1152 * XXX XXX CPUs might have larger write buffers
1153 * XXX XXX which require further unrolling of
1154 * XXX XXX this loop, or the insertion of
1155 * XXX XXX memory barriers.
1157 TGAWALREG(dc
, TGA_REG_GCSR
, 0,
1158 tga_srcb
+ y
+ x
- 1 * 64);
1159 TGAWALREG(dc
, TGA_REG_GCDR
, 0,
1160 tga_dstb
+ y
+ x
- 1 * 64);
1161 TGAWALREG(dc
, TGA_REG_GCSR
, 1,
1162 tga_srcb
+ y
+ x
- 2 * 64);
1163 TGAWALREG(dc
, TGA_REG_GCDR
, 1,
1164 tga_dstb
+ y
+ x
- 2 * 64);
1165 TGAWALREG(dc
, TGA_REG_GCSR
, 2,
1166 tga_srcb
+ y
+ x
- 3 * 64);
1167 TGAWALREG(dc
, TGA_REG_GCDR
, 2,
1168 tga_dstb
+ y
+ x
- 3 * 64);
1169 TGAWALREG(dc
, TGA_REG_GCSR
, 3,
1170 tga_srcb
+ y
+ x
- 4 * 64);
1171 TGAWALREG(dc
, TGA_REG_GCDR
, 3,
1172 tga_dstb
+ y
+ x
- 4 * 64);
1175 /* 64 byte chunks */
1176 for (; xleft
>= 64; x
-= 64, xleft
-= 64) {
1177 TGAWALREG(dc
, TGA_REG_GCSR
, 0,
1178 tga_srcb
+ y
+ x
- 1 * 64);
1179 TGAWALREG(dc
, TGA_REG_GCDR
, 0,
1180 tga_dstb
+ y
+ x
- 1 * 64);
1184 TGAWALREG(dc
, TGA_REG_GOPR
, 0, 0x0003); /* op -> dst = src */
1185 TGAWALREG(dc
, TGA_REG_GMOR
, 0, 0x0000); /* Simple mode */
1189 lastx
= xstart
- (wb
& ~63);
1190 for (y
= ystart
; (ydir
* y
) <= (ydir
* yend
);
1192 /* 4 byte granularity */
1193 for (x
= lastx
, xleft
= lastleft
; xleft
>= 4;
1194 x
-= 4, xleft
-= 4) {
1195 *(uint32_t *)(dst
->ri_bits
+ dstb
+
1197 *(uint32_t *)(dst
->ri_bits
+ srcb
+
1207 void tga_putchar(void *c
, int row
, int col
, u_int uc
, long attr
)
1209 struct rasops_info
*ri
= c
;
1210 struct tga_devconfig
*dc
= ri
->ri_hw
;
1211 int fs
, height
, width
;
1215 rp
= (int32_t *)(ri
->ri_bits
+
1216 row
* ri
->ri_yscale
+ col
* ri
->ri_xscale
);
1218 height
= ri
->ri_font
->fontheight
;
1219 width
= ri
->ri_font
->fontwidth
;
1221 uc
-= ri
->ri_font
->firstchar
;
1222 fr
= (uint8_t *)ri
->ri_font
->data
+ uc
* ri
->ri_fontscale
;
1223 fs
= ri
->ri_font
->stride
;
1225 /* Set foreground and background color. XXX memoize this somehow?
1226 * The rasops code has already expanded the color entry to 32 bits
1227 * for us, even for 8-bit displays, so we don't have to do anything.
1229 TGAWREG(dc
, TGA_REG_GFGR
, ri
->ri_devcmap
[(attr
>> 24) & 15]);
1230 TGAWREG(dc
, TGA_REG_GBGR
, ri
->ri_devcmap
[(attr
>> 16) & 15]);
1232 /* Set raster operation to "copy"... */
1233 if (ri
->ri_depth
== 8)
1234 TGAWREG(dc
, TGA_REG_GOPR
, 0x3);
1235 else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
1236 TGAWREG(dc
, TGA_REG_GOPR
, 0x3 | (0x3 << 8));
1238 /* Set which pixels we're drawing (of a possible 32). */
1239 TGAWREG(dc
, TGA_REG_GPXR_P
, (1 << width
) - 1);
1241 /* Set drawing mode to opaque stipple. */
1242 TGAWREG(dc
, TGA_REG_GMOR
, 0x1);
1244 /* Insert write barrier before actually sending data */
1245 /* XXX Abuses the fact that there is only one write barrier on Alphas */
1246 TGAREGWB(dc
, TGA_REG_GMOR
, 1);
1249 /* The actual stipple write */
1250 *rp
= fr
[0] | (fr
[1] << 8) | (fr
[2] << 16) | (fr
[3] << 24);
1253 rp
= (int32_t *)((uint8_t *)rp
+ ri
->ri_stride
);
1257 if ((attr
& 1) != 0) {
1258 rp
= (int32_t *)((uint8_t *)rp
- (ri
->ri_stride
<< 1));
1262 /* Set grapics mode back to normal. */
1263 TGAWREG(dc
, TGA_REG_GMOR
, 0);
1264 TGAWREG(dc
, TGA_REG_GPXR_P
, 0xffffffff);
1268 tga_eraserows(void *c
, int row
, int num
, long attr
)
1270 struct rasops_info
*ri
= c
;
1271 struct tga_devconfig
*dc
= ri
->ri_hw
;
1272 int32_t color
, lines
, pixels
;
1275 color
= ri
->ri_devcmap
[(attr
>> 16) & 15];
1276 rp
= (int32_t *)(ri
->ri_bits
+ row
*ri
->ri_yscale
);
1277 lines
= num
* ri
->ri_font
->fontheight
;
1278 pixels
= ri
->ri_emuwidth
- 1;
1280 /* Set fill color in block-color registers */
1281 TGAWREG(dc
, TGA_REG_GBCR0
, color
);
1282 TGAWREG(dc
, TGA_REG_GBCR1
, color
);
1283 if (ri
->ri_depth
!= 8) {
1284 TGAWREG(dc
, TGA_REG_GBCR2
, color
);
1285 TGAWREG(dc
, TGA_REG_GBCR3
, color
);
1286 TGAWREG(dc
, TGA_REG_GBCR4
, color
);
1287 TGAWREG(dc
, TGA_REG_GBCR5
, color
);
1288 TGAWREG(dc
, TGA_REG_GBCR6
, color
);
1289 TGAWREG(dc
, TGA_REG_GBCR7
, color
);
1292 /* Set raster operation to "copy"... */
1293 if (ri
->ri_depth
== 8)
1294 TGAWREG(dc
, TGA_REG_GOPR
, 0x3);
1295 else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
1296 TGAWREG(dc
, TGA_REG_GOPR
, 0x3 | (0x3 << 8));
1298 /* Set which pixels we're drawing (of a possible 32). */
1299 TGAWREG(dc
, TGA_REG_GDAR
, 0xffffffff);
1301 /* Set drawing mode to block fill. */
1302 TGAWREG(dc
, TGA_REG_GMOR
, 0x2d);
1304 /* Insert write barrier before actually sending data */
1305 /* XXX Abuses the fact that there is only one write barrier on Alphas */
1306 TGAREGWB(dc
, TGA_REG_GMOR
, 1);
1310 rp
= (int32_t *)((uint8_t *)rp
+ ri
->ri_stride
);
1313 /* Set grapics mode back to normal. */
1314 TGAWREG(dc
, TGA_REG_GMOR
, 0);
1318 tga_erasecols (void *c
, int row
, int col
, int num
, long attr
)
1320 struct rasops_info
*ri
= c
;
1321 struct tga_devconfig
*dc
= ri
->ri_hw
;
1322 int32_t color
, lines
, pixels
;
1325 color
= ri
->ri_devcmap
[(attr
>> 16) & 15];
1326 rp
= (int32_t *)(ri
->ri_bits
+ row
*ri
->ri_yscale
+ col
*ri
->ri_xscale
);
1327 lines
= ri
->ri_font
->fontheight
;
1328 pixels
= (num
* ri
->ri_font
->fontwidth
) - 1;
1330 /* Set fill color in block-color registers */
1331 TGAWREG(dc
, TGA_REG_GBCR0
, color
);
1332 TGAWREG(dc
, TGA_REG_GBCR1
, color
);
1333 if (ri
->ri_depth
!= 8) {
1334 TGAWREG(dc
, TGA_REG_GBCR2
, color
);
1335 TGAWREG(dc
, TGA_REG_GBCR3
, color
);
1336 TGAWREG(dc
, TGA_REG_GBCR4
, color
);
1337 TGAWREG(dc
, TGA_REG_GBCR5
, color
);
1338 TGAWREG(dc
, TGA_REG_GBCR6
, color
);
1339 TGAWREG(dc
, TGA_REG_GBCR7
, color
);
1342 /* Set raster operation to "copy"... */
1343 if (ri
->ri_depth
== 8)
1344 TGAWREG(dc
, TGA_REG_GOPR
, 0x3);
1345 else /* ... and in 24-bit mode, set the destination bitmap to 24-bit. */
1346 TGAWREG(dc
, TGA_REG_GOPR
, 0x3 | (0x3 << 8));
1348 /* Set which pixels we're drawing (of a possible 32). */
1349 TGAWREG(dc
, TGA_REG_GDAR
, 0xffffffff);
1351 /* Set drawing mode to block fill. */
1352 TGAWREG(dc
, TGA_REG_GMOR
, 0x2d);
1354 /* Insert write barrier before actually sending data */
1355 /* XXX Abuses the fact that there is only one write barrier on Alphas */
1356 TGAREGWB(dc
, TGA_REG_GMOR
, 1);
1360 rp
= (int32_t *)((uint8_t *)rp
+ ri
->ri_stride
);
1363 /* Set grapics mode back to normal. */
1364 TGAWREG(dc
, TGA_REG_GMOR
, 0);
1369 tga_ramdac_wr(void *v
, u_int btreg
, uint8_t val
)
1371 struct tga_devconfig
*dc
= v
;
1373 if (btreg
> BT485_REG_MAX
)
1374 panic("tga_ramdac_wr: reg %d out of range", btreg
);
1376 TGAWREG(dc
, TGA_REG_EPDR
, (btreg
<< 9) | (0 << 8 ) | val
); /* XXX */
1377 TGAREGWB(dc
, TGA_REG_EPDR
, 1);
1381 tga2_ramdac_wr(void *v
, u_int btreg
, uint8_t val
)
1383 struct tga_devconfig
*dc
= v
;
1384 bus_space_handle_t ramdac
;
1386 if (btreg
> BT485_REG_MAX
)
1387 panic("tga_ramdac_wr: reg %d out of range", btreg
);
1389 bus_space_subregion(dc
->dc_memt
, dc
->dc_memh
,
1390 TGA2_MEM_RAMDAC
+ (0xe << 12) + (btreg
<< 8), 4, &ramdac
);
1391 bus_space_write_4(dc
->dc_memt
, ramdac
, 0, val
& 0xff);
1392 bus_space_barrier(dc
->dc_memt
, ramdac
, 0, 4, BUS_SPACE_BARRIER_WRITE
);
1396 tga_bt463_rd(void *v
, u_int btreg
)
1398 struct tga_devconfig
*dc
= v
;
1402 * Strobe CE# (high->low->high) since status and data are latched on
1403 * the falling and rising edges (repsectively) of this active-low
1407 TGAREGWB(dc
, TGA_REG_EPSR
, 1);
1408 TGAWREG(dc
, TGA_REG_EPSR
, (btreg
<< 2) | 2 | 1);
1409 TGAREGWB(dc
, TGA_REG_EPSR
, 1);
1410 TGAWREG(dc
, TGA_REG_EPSR
, (btreg
<< 2) | 2 | 0);
1412 TGAREGRB(dc
, TGA_REG_EPSR
, 1);
1414 rdval
= TGARREG(dc
, TGA_REG_EPDR
);
1415 TGAREGWB(dc
, TGA_REG_EPSR
, 1);
1416 TGAWREG(dc
, TGA_REG_EPSR
, (btreg
<< 2) | 2 | 1);
1418 return (rdval
>> 16) & 0xff;
1422 tga_bt463_wr(void *v
, u_int btreg
, uint8_t val
)
1424 struct tga_devconfig
*dc
= v
;
1427 * In spite of the 21030 documentation, to set the MPU bus bits for
1428 * a write, you set them in the upper bits of EPDR, not EPSR.
1432 * Strobe CE# (high->low->high) since status and data are latched on
1433 * the falling and rising edges of this active-low signal.
1436 TGAREGWB(dc
, TGA_REG_EPDR
, 1);
1437 TGAWREG(dc
, TGA_REG_EPDR
, (btreg
<< 10) | 0x100 | val
);
1438 TGAREGWB(dc
, TGA_REG_EPDR
, 1);
1439 TGAWREG(dc
, TGA_REG_EPDR
, (btreg
<< 10) | 0x000 | val
);
1440 TGAREGWB(dc
, TGA_REG_EPDR
, 1);
1441 TGAWREG(dc
, TGA_REG_EPDR
, (btreg
<< 10) | 0x100 | val
);
1445 tga_ramdac_rd(void *v
, u_int btreg
)
1447 struct tga_devconfig
*dc
= v
;
1450 if (btreg
> BT485_REG_MAX
)
1451 panic("tga_ramdac_rd: reg %d out of range", btreg
);
1453 TGAWREG(dc
, TGA_REG_EPSR
, (btreg
<< 1) | 0x1); /* XXX */
1454 TGAREGWB(dc
, TGA_REG_EPSR
, 1);
1456 rdval
= TGARREG(dc
, TGA_REG_EPDR
);
1457 return (rdval
>> 16) & 0xff; /* XXX */
1461 tga2_ramdac_rd(void *v
, u_int btreg
)
1463 struct tga_devconfig
*dc
= v
;
1464 bus_space_handle_t ramdac
;
1467 if (btreg
> BT485_REG_MAX
)
1468 panic("tga_ramdac_rd: reg %d out of range", btreg
);
1470 bus_space_subregion(dc
->dc_memt
, dc
->dc_memh
,
1471 TGA2_MEM_RAMDAC
+ (0xe << 12) + (btreg
<< 8), 4, &ramdac
);
1472 retval
= bus_space_read_4(dc
->dc_memt
, ramdac
, 0) & 0xff;
1473 bus_space_barrier(dc
->dc_memt
, ramdac
, 0, 4, BUS_SPACE_BARRIER_READ
);
1477 #include <dev/ic/decmonitors.c>
1478 void tga2_ics9110_wr(struct tga_devconfig
*dc
, int dotclock
);
1480 struct monitor
*tga_getmonitor(struct tga_devconfig
*dc
);
1483 tga2_init(struct tga_devconfig
*dc
)
1485 struct monitor
*m
= tga_getmonitor(dc
);
1487 /* Deal with the dot clocks.
1489 if (dc
->dc_tga_type
== TGA_TYPE_POWERSTORM_4D20
) {
1491 * Set this up as a reference clock for the
1494 tga2_ics9110_wr(dc
, 14300000);
1496 * XXX Can't set up the dotclock properly, until such time
1497 * as the RAMDAC is configured.
1500 /* otherwise the ics9110 is our clock. */
1501 tga2_ics9110_wr(dc
, m
->dotclock
);
1504 TGAWREG(dc
, TGA_REG_VHCR
,
1505 ((m
->hbp
/ 4) << 21) |
1506 ((m
->hsync
/ 4) << 14) |
1507 (((m
->hfp
- 4) / 4) << 9) |
1508 ((m
->cols
+ 4) / 4));
1510 TGAWREG(dc
, TGA_REG_VHCR
,
1511 ((m
->hbp
/ 4) << 21) |
1512 ((m
->hsync
/ 4) << 14) |
1513 (((m
->hfp
) / 4) << 9) |
1516 TGAWREG(dc
, TGA_REG_VVCR
,
1521 TGAWREG(dc
, TGA_REG_VVBR
, 1);
1522 TGAREGRWB(dc
, TGA_REG_VHCR
, 3);
1523 TGAWREG(dc
, TGA_REG_VVVR
, TGARREG(dc
, TGA_REG_VVVR
) | 1);
1524 TGAREGRWB(dc
, TGA_REG_VVVR
, 1);
1525 TGAWREG(dc
, TGA_REG_GPMR
, 0xffffffff);
1526 TGAREGRWB(dc
, TGA_REG_GPMR
, 1);
1530 tga2_ics9110_wr(struct tga_devconfig
*dc
, int dotclock
)
1532 bus_space_handle_t clock
;
1539 N
= 0x40; M
= 0x7; V
= 0x0; X
= 0x1; R
= 0x1; break;
1541 N
= 0x2d; M
= 0x2b; V
= 0x1; X
= 0x1; R
= 0x1; break;
1543 N
= 0x11; M
= 0x9; V
= 0x1; X
= 0x1; R
= 0x2; break;
1545 N
= 0x6d; M
= 0xf; V
= 0x0; X
= 0x1; R
= 0x1; break;
1547 N
= 0x5F; M
= 0x3E; V
= 0x1; X
= 0x1; R
= 0x1; break;
1549 N
= 0x6e; M
= 0x15; V
= 0x0; X
= 0x1; R
= 0x1; break;
1551 N
= 0x2a; M
= 0x41; V
= 0x1; X
= 0x1; R
= 0x1; break;
1553 N
= 0x35; M
= 0xb; V
= 0x0; X
= 0x1; R
= 0x1; break;
1555 N
= 0x6d; M
= 0x0c; V
= 0x0; X
= 0x1; R
= 0x2; break;
1557 N
= 0x37; M
= 0x3f; V
= 0x1; X
= 0x1; R
= 0x2; break;
1559 N
= 0x5f; M
= 0x11; V
= 0x0; X
= 0x1; R
= 0x2; break;
1561 N
= 0x16; M
= 0x05; V
= 0x0; X
= 0x1; R
= 0x2; break;
1563 N
= 0x66; M
= 0x1d; V
= 0x0; X
= 0x1; R
= 0x2; break;
1565 N
= 0x42; M
= 0x07; V
= 0x0; X
= 0x1; R
= 0x1; break;
1567 N
= 0x60; M
= 0x32; V
= 0x1; X
= 0x1; R
= 0x2; break;
1569 N
= 0x60; M
= 0x32; V
= 0x1; X
= 0x1; R
= 0x2; break;
1570 case 14300000: /* this one is just a ref clock */
1571 N
= 0x03; M
= 0x03; V
= 0x1; X
= 0x1; R
= 0x3; break;
1573 panic("unrecognized clock rate %d", dotclock
);
1576 /* XXX -- hard coded, bad */
1577 valU
= N
| ( M
<< 7 ) | (V
<< 14);
1578 valU
|= (X
<< 15) | (R
<< 17);
1581 bus_space_subregion(dc
->dc_memt
, dc
->dc_memh
, TGA2_MEM_EXTDEV
+
1582 TGA2_MEM_CLOCK
+ (0xe << 12), 4, &clock
); /* XXX */
1584 for (i
= 24; i
> 0; i
--) {
1587 writeval
= valU
& 0x1;
1591 bus_space_write_4(dc
->dc_memt
, clock
, 0, writeval
);
1592 bus_space_barrier(dc
->dc_memt
, clock
, 0, 4,
1593 BUS_SPACE_BARRIER_WRITE
);
1595 bus_space_subregion(dc
->dc_memt
, dc
->dc_memh
, TGA2_MEM_EXTDEV
+
1596 TGA2_MEM_CLOCK
+ (0xe << 12) + (0x1 << 11) + (0x1 << 11), 4,
1598 bus_space_write_4(dc
->dc_memt
, clock
, 0, 0x0);
1599 bus_space_barrier(dc
->dc_memt
, clock
, 0, 0, BUS_SPACE_BARRIER_WRITE
);
1603 tga_getmonitor(struct tga_devconfig
*dc
)
1606 return &decmonitors
[(~TGARREG(dc
, TGA_REG_GREV
) >> 16) & 0x0f];
1610 tga_getdotclock(struct tga_devconfig
*dc
)
1613 return tga_getmonitor(dc
)->dotclock
;