2 * Copyright (c) 2000, 2001 Andrew Miklic, Andrew Gallatin, Peter Jeremy,
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
32 * All rights reserved.
34 * Author: Chris G. Demetriou
36 * Permission to use, copy, modify and distribute this software and
37 * its documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
44 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie the
54 * rights to redistribute these changes.
57 #include <sys/cdefs.h>
58 __FBSDID("$FreeBSD$");
60 #include <machine/stdarg.h>
62 #include <sys/param.h>
63 #include <sys/systm.h>
64 #include <sys/kernel.h>
67 #include <sys/fcntl.h>
68 #include <sys/malloc.h>
70 #include <sys/consio.h>
72 #include <isa/isareg.h>
73 #include <dev/fb/vgareg.h>
76 #include <vm/vm_param.h>
79 #include <machine/md_var.h>
80 #include <machine/pc/bios.h>
81 #include <machine/clock.h>
82 #include <machine/bus_memio.h>
83 #include <machine/bus.h>
84 #include <machine/pc/vesa.h>
85 #include <machine/resource.h>
86 #include <machine/rpb.h>
91 #include <dev/pci/pcireg.h>
92 #include <dev/pci/pcivar.h>
94 #include <dev/fb/fbreg.h>
95 #include <dev/syscons/syscons.h>
96 #include <dev/fb/gfb.h>
97 #include <dev/gfb/gfb_pci.h>
98 #include <dev/fb/tga.h>
99 #include <dev/tga/tga_pci.h>
103 /* TGA-specific FB video driver function declarations */
104 static int tga_error(void);
105 static vi_init_t tga_init;
106 static void tga2_init(struct gfb_softc *, int);
108 /* TGA-specific functionality. */
109 static gfb_builtin_save_palette_t tga_builtin_save_palette;
110 static gfb_builtin_load_palette_t tga_builtin_load_palette;
112 static gfb_builtin_save_palette_t tga2_builtin_save_palette;
113 static gfb_builtin_load_palette_t tga2_builtin_load_palette;
114 static gfb_builtin_save_cursor_palette_t tga2_builtin_save_cursor_palette;
115 static gfb_builtin_load_cursor_palette_t tga2_builtin_load_cursor_palette;
117 static gfb_builtin_read_hw_cursor_t tga_builtin_read_hw_cursor;
118 static gfb_builtin_set_hw_cursor_t tga_builtin_set_hw_cursor;
119 static gfb_builtin_set_hw_cursor_shape_t tga_builtin_set_hw_cursor_shape;
120 static void bt463_load_palette_intr(struct gfb_softc *);
121 static void bt463_load_cursor_palette_intr(struct gfb_softc *);
122 static int tga_schedule_intr(struct gfb_softc *, void (*)(struct gfb_softc *));
124 /* RAMDAC interface functions */
125 static gfb_ramdac_wr_t tga_bt485_wr;
126 static gfb_ramdac_rd_t tga_bt485_rd;
127 static gfb_ramdac_wr_t tga_bt463_wr;
128 static gfb_ramdac_rd_t tga_bt463_rd;
129 static gfb_ramdac_wr_t tga2_ibm561_wr;
130 static gfb_ramdac_rd_t tga2_ibm561_rd;
131 static void tga2_ics9110_wr(struct gfb_softc *, int);
133 /* RAMDAC-specific functions */
134 static gfb_ramdac_init_t bt463_init;
135 static void bt463_update_window_type(struct gfb_softc *);
137 static gfb_ramdac_save_palette_t bt463_save_palette;
138 static gfb_ramdac_load_palette_t bt463_load_palette;
140 static gfb_ramdac_save_cursor_palette_t bt463_save_cursor_palette;
141 static gfb_ramdac_load_cursor_palette_t bt463_load_cursor_palette;
142 static gfb_ramdac_init_t bt485_init;
143 static gfb_ramdac_save_palette_t bt485_save_palette;
144 static gfb_ramdac_load_palette_t bt485_load_palette;
145 static gfb_ramdac_save_cursor_palette_t bt485_save_cursor_palette;
146 static gfb_ramdac_load_cursor_palette_t bt485_load_cursor_palette;
147 static gfb_ramdac_read_hw_cursor_t bt485_read_hw_cursor;
148 static gfb_ramdac_set_hw_cursor_t bt485_set_hw_cursor;
149 static gfb_ramdac_set_hw_cursor_shape_t bt485_set_hw_cursor_shape;
150 static gfb_ramdac_init_t ibm561_init;
151 static gfb_ramdac_save_palette_t ibm561_save_palette;
152 static gfb_ramdac_load_palette_t ibm561_load_palette;
153 static gfb_ramdac_save_cursor_palette_t ibm561_save_cursor_palette;
154 static gfb_ramdac_load_cursor_palette_t ibm561_load_cursor_palette;
156 /* Video Driver-generic functions */
157 static vi_query_mode_t tga_query_mode;
158 static vi_set_mode_t tga_set_mode;
159 static vi_blank_display_t tga_blank_display;
161 static vi_ioctl_t tga_ioctl;
163 static vi_set_border_t tga_set_border;
164 static vi_set_win_org_t tga_set_win_org;
165 static vi_fill_rect_t tga_fill_rect;
166 static vi_bitblt_t tga_bitblt;
167 static vi_clear_t tga_clear;
168 static vi_putc_t tga_putc;
169 static vi_puts_t tga_puts;
170 static vi_putm_t tga_putm;
172 static video_switch_t tgavidsw = {
189 gfb_set_hw_cursor_shape,
199 gfb_save_cursor_palette,
200 gfb_load_cursor_palette,
208 VIDEO_DRIVER(tga, tgavidsw, NULL);
210 extern sc_rndr_sw_t txtrndrsw;
211 RENDERER(tga, 0, txtrndrsw, gfb_set);
214 extern sc_rndr_sw_t gfbrndrsw;
215 RENDERER(tga, PIXEL_MODE, gfbrndrsw, gfb_set);
216 #endif /* SC_PIXEL_MODE */
218 #ifndef SC_NO_MODE_CHANGE
219 extern sc_rndr_sw_t grrndrsw;
220 RENDERER(tga, GRAPHICS_MODE, grrndrsw, gfb_set);
221 #endif /* SC_NO_MODE_CHANGE */
223 RENDERER_MODULE(tga, gfb_set);
225 #define MHz * 1000000
228 extern struct gfb_softc *gfb_device_softcs[2][MAX_NUM_GFB_CARDS];
231 The following 3 variables exist only because we need statically
232 allocated structures very early in boot to support tga_configure()...
234 extern struct gfb_softc console;
235 extern video_adapter_t console_adp;
236 extern struct gfb_conf console_gfbc;
237 extern u_char console_palette_red[256];
238 extern u_char console_palette_green[256];
239 extern u_char console_palette_blue[256];
240 extern u_char console_cursor_palette_red[3];
241 extern u_char console_cursor_palette_green[3];
242 extern u_char console_cursor_palette_blue[3];
244 static struct monitor decmonitors[] = {
245 /* 0x0: 1280 x 1024 @ 72Hz */
246 { 1280, 32, 160, 232,
250 /* 0x1: 1280 x 1024 @ 66Hz */
251 { 1280, 32, 160, 232,
255 /* 0x2: 1280 x 1024 @ 60Hz */
256 { 1280, 44, 184, 200,
260 /* 0x3: 1152 x 900 @ 72Hz */
261 { 1152, 64, 112, 176,
265 /* 0x4: 1600 x 1200 @ 65Hz */
266 { 1600, 32, 192, 336,
270 /* 0x5: 1024 x 768 @ 70Hz */
271 { 1024, 24, 136, 144,
275 /* 0x6: 1024 x 768 @ 72Hz */
276 { 1024, 16, 128, 128,
280 /* 0x7: 1024 x 864 @ 60Hz */
281 { 1024, 12, 128, 116,
285 /* 0x8: 1024 x 768 @ 60Hz */
290 /* 0x9: 800 x 600 @ 72Hz */
295 /* 0xa: 800 x 600 @ 60Hz */
300 /* 0xb: 640 x 480 @ 72Hz */
305 /* 0xc: 640 x 480 @ 60Hz */
310 /* 0xd: 1280 x 1024 @ 75Hz */
311 { 1280, 16, 144, 248,
315 /* 0xe: 1280 x 1024 @ 60Hz */
316 { 1280, 19, 163, 234,
320 /* 0xf: 1600 x 1200 @ 75Hz */
321 /* XXX -- this one's weird. rcd */
322 { 1600, 32, 192, 336,
333 #define MB * 1024 * 1024
336 * These are the 16 default VGA colors--these are replicated 16 times as the
337 * initial (default) color-map. The text rendering functions use entries
338 * 0..15 for normal foreground/background colors. The entries 128..255 are
339 * used for blinking entries--when "on," they contain the foreground color
340 * entries; when "off," they contain the background color entries...
342 static const struct cmap {
346 } default_cmap[16] = {
347 {0x00, 0x00, 0x00}, /* Black */
348 {0x00, 0x00, 0xff}, /* Blue */
349 {0x00, 0xff, 0x00}, /* Green */
350 {0x00, 0xc0, 0xc0}, /* Cyan */
351 {0xff, 0x00, 0x00}, /* Red */
352 {0xc0, 0x00, 0xc0}, /* Magenta */
353 {0xc0, 0xc0, 0x00}, /* Brown */
354 {0xc0, 0xc0, 0xc0}, /* Light Grey */
355 {0x80, 0x80, 0x80}, /* Dark Grey */
356 {0x80, 0x80, 0xff}, /* Light Blue */
357 {0x80, 0xff, 0x80}, /* Light Green */
358 {0x80, 0xff, 0xff}, /* Light Cyan */
359 {0xff, 0x80, 0x80}, /* Light Red */
360 {0xff, 0x80, 0xff}, /* Light Magenta */
361 {0xff, 0xff, 0x80}, /* Yellow */
362 {0xff, 0xff, 0xff} /* White */
365 extern struct gfb_font bold8x16;
367 /*****************************************************************************
369 * FB-generic functions
371 ****************************************************************************/
374 tga_init(int unit, video_adapter_t *adp, int flags)
376 struct gfb_softc *sc;
377 struct gfb_conf *gfbc;
378 unsigned int monitor;
387 /* Assume the best... */
390 sc = gfb_device_softcs[adp->va_model][unit];
393 /* Initialize palette counts... */
394 gfbc->palette.count = 256;
395 gfbc->cursor_palette.count = 3;
397 /* Initialize the adapter... */
398 gder = BASIC_READ_TGA_REGISTER(adp, TGA_REG_GDER);
399 addrmask = (gder & GDER_ADDR_MASK) >> GDER_ADDR_SHIFT;
400 deep = (gder & GDER_DEEP) != 0;
401 cs = (gder & GDER_CS) == 0;
402 card_type = TGA_TYPE_UNKNOWN;
403 adp->va_little_bitian = 1;
404 adp->va_little_endian = 0;
405 adp->va_initial_mode = 0;
406 adp->va_initial_bios_mode = 0;
408 adp->va_info.vi_mem_model = V_INFO_MM_TEXT;
409 adp->va_info.vi_mode = M_VGA_M80x30;
410 adp->va_info.vi_flags = V_INFO_COLOR;
411 adp->va_buffer = adp->va_mem_base;
412 adp->va_buffer_size = 4 MB * (1 + addrmask);
413 adp->va_registers = adp->va_buffer + TGA_REG_SPACE_OFFSET;
414 adp->va_registers_size = 2 KB;
415 adp->va_window = adp->va_buffer + (adp->va_buffer_size / 2);
416 adp->va_info.vi_window = vtophys(adp->va_window);
417 adp->va_window_size = (deep ? 4 MB : 2 MB);
418 adp->va_info.vi_window_size = adp->va_window_size;
419 adp->va_window_gran = adp->va_window_size;
420 adp->va_info.vi_window_gran = adp->va_window_gran;
421 adp->va_info.vi_buffer = vtophys(adp->va_buffer);
422 adp->va_info.vi_buffer_size = adp->va_buffer_size;
423 adp->va_disp_start.x = 0;
424 adp->va_disp_start.y = 0;
425 adp->va_info.vi_depth = (deep ? 32 : 8);
426 adp->va_info.vi_planes = adp->va_info.vi_depth / 8;
427 adp->va_info.vi_width = (READ_GFB_REGISTER(adp, TGA_REG_VHCR) &
429 adp->va_info.vi_width |= (READ_GFB_REGISTER(adp, TGA_REG_VHCR) &
431 switch(adp->va_info.vi_width) {
433 adp->va_info.vi_width = 8192;
436 adp->va_info.vi_width = 8196;
439 adp->va_info.vi_width *= 4;
442 adp->va_info.vi_height = (READ_GFB_REGISTER(adp, TGA_REG_VVCR) &
444 adp->va_line_width = adp->va_info.vi_width * adp->va_info.vi_depth / 8;
445 if(READ_GFB_REGISTER(adp, TGA_REG_VHCR) & VHCR_ODD)
446 adp->va_info.vi_width -= 4;
449 Set the video base address and the cursor base address to
450 something known such that the video base address is at
451 least 1 KB past the cursor base address (the cursor is 1 KB
452 in size, so leave room for it)...we pick 4 KB and 0 KB,
453 respectively, since they begin at the top of the framebuffer
454 for minimal fragmentation of the address space, and this will
455 always leave enough room for the cursor for all implementations...
458 /* Set the video base address... */
459 tga_set_win_org(sc->adp, 4 KB);
461 /* Set the cursor base address... */
462 ccbr = READ_GFB_REGISTER(sc->adp, TGA_REG_CCBR);
463 ccbr = (ccbr & 0xfffffc0f) | (0 << 4);
464 WRITE_GFB_REGISTER(sc->adp, TGA_REG_CCBR, ccbr);
466 /* Type the card... */
467 if(adp->va_type == KD_TGA) {
470 /* 8bpp frame buffer */
471 gfbc->ramdac_name = "BT485";
472 gfbc->ramdac_init = bt485_init;
473 gfbc->ramdac_rd = tga_bt485_rd;
474 gfbc->ramdac_wr = tga_bt485_wr;
475 gfbc->ramdac_save_palette = bt485_save_palette;
476 gfbc->ramdac_load_palette = bt485_load_palette;
477 gfbc->ramdac_save_cursor_palette =
478 bt485_save_cursor_palette;
479 gfbc->ramdac_load_cursor_palette =
480 bt485_load_cursor_palette;
481 gfbc->ramdac_read_hw_cursor = bt485_read_hw_cursor;
482 gfbc->ramdac_set_hw_cursor = bt485_set_hw_cursor;
483 gfbc->ramdac_set_hw_cursor_shape =
484 bt485_set_hw_cursor_shape;
486 if(addrmask == GDER_ADDR_4MB) {
488 /* 4MB core map; T8-01 or T8-02 */
490 card_type = TGA_TYPE_T8_01;
491 gfbc->name = "T8-01";
493 card_type = TGA_TYPE_T8_02;
494 gfbc->name = "T8-02";
496 } else if(addrmask == GDER_ADDR_8MB) {
498 /* 8MB core map; T8-22 */
500 card_type = TGA_TYPE_T8_22;
501 gfbc->name = "T8-22";
503 } else if(addrmask == GDER_ADDR_16MB) {
505 /* 16MB core map; T8-44 */
507 card_type = TGA_TYPE_T8_44;
508 gfbc->name = "T8-44";
510 } else if(addrmask == GDER_ADDR_32MB) {
512 /* 32MB core map; ??? */
513 card_type = TGA_TYPE_UNKNOWN;
517 /* 32bpp frame buffer */
518 gfbc->ramdac_name = "BT463";
519 gfbc->ramdac_init = bt463_init;
520 gfbc->ramdac_rd = tga_bt463_rd;
521 gfbc->ramdac_wr = tga_bt463_wr;
522 gfbc->builtin_save_palette = tga_builtin_save_palette;
523 gfbc->builtin_load_palette = tga_builtin_load_palette;
524 gfbc->ramdac_save_cursor_palette =
525 bt463_save_cursor_palette;
526 gfbc->ramdac_load_cursor_palette =
527 bt463_load_cursor_palette;
528 gfbc->builtin_read_hw_cursor =
529 tga_builtin_read_hw_cursor;
530 gfbc->builtin_set_hw_cursor = tga_builtin_set_hw_cursor;
531 gfbc->builtin_set_hw_cursor_shape =
532 tga_builtin_set_hw_cursor_shape;
534 /* 32bpp frame buffer */
535 if(addrmask == GDER_ADDR_4MB) {
537 /* 4MB core map; ??? */
538 card_type = TGA_TYPE_UNKNOWN;
539 } else if(addrmask == GDER_ADDR_8MB) {
541 /* 8MB core map; ??? */
542 card_type = TGA_TYPE_UNKNOWN;
543 } else if(addrmask == GDER_ADDR_16MB) {
545 /* 16MB core map; T32-04 or T32-08 */
547 card_type = TGA_TYPE_T32_04;
548 gfbc->name = "T32-04";
550 card_type = TGA_TYPE_T32_08;
551 gfbc->name = "T32-08";
553 } else if(addrmask == GDER_ADDR_32MB) {
555 /* 32MB core map; T32-88 */
557 card_type = TGA_TYPE_T32_88;
558 gfbc->name = "T32-88";
563 else if(adp->va_type == KD_TGA2) {
564 gfbc->ramdac_name = "IBM561";
565 gfbc->ramdac_init = ibm561_init;
566 gfbc->ramdac_rd = tga2_ibm561_rd;
567 gfbc->ramdac_wr = tga2_ibm561_wr;
568 gfbc->ramdac_save_palette = ibm561_save_palette;
569 gfbc->ramdac_load_palette = ibm561_load_palette;
570 gfbc->ramdac_save_cursor_palette = ibm561_save_cursor_palette;
571 gfbc->ramdac_load_cursor_palette = ibm561_load_cursor_palette;
572 gfbc->builtin_read_hw_cursor = tga_builtin_read_hw_cursor;
573 gfbc->builtin_set_hw_cursor = tga_builtin_set_hw_cursor;
574 gfbc->builtin_set_hw_cursor_shape =
575 tga_builtin_set_hw_cursor_shape;
578 if(addrmask == GDER_ADDR_4MB)
579 card_type = TGA_TYPE_UNKNOWN;
582 else if(addrmask == GDER_ADDR_8MB) {
583 card_type = TGA2_TYPE_3D30;
588 else if(addrmask == GDER_ADDR_16MB) {
589 card_type = TGA2_TYPE_4D20;
592 else if(addrmask == GDER_ADDR_32MB)
593 card_type = TGA_TYPE_UNKNOWN;
597 For now, just return for TGA2 cards (i.e.,
598 allow syscons to treat this device as a normal
599 VGA device, and don't do anything TGA2-specific,
600 e.g., only use the TGA2 card in VGA mode for now
601 as opposed to 2DA mode...
603 if(adp->va_type == KD_TGA2)
606 /* If we couldn't identify the card, err-out... */
607 if(card_type == TGA_TYPE_UNKNOWN) {
608 printf("tga%d: Unknown TGA type\n", unit);
613 /* Clear and disable interrupts... */
614 WRITE_GFB_REGISTER(adp, TGA_REG_SISR, 0x00000001);
616 /* Perform TGA2-specific initialization, if necessary... */
617 if(adp->va_type == KD_TGA2) {
618 monitor = (~READ_GFB_REGISTER(adp, TGA_REG_GREV) >> 16 ) & 0x0f;
619 tga2_init(sc, monitor);
626 tga2_init(sc, monitor)
627 struct gfb_softc *sc;
631 tga2_ics9110_wr(sc, decmonitors[monitor].dotclock);
632 WRITE_GFB_REGISTER(sc->adp, TGA_REG_VHCR,
633 ((decmonitors[monitor].hbp / 4) << VHCR_BPORCH_SHIFT) |
634 ((decmonitors[monitor].hsync / 4) << VHCR_HSYNC_SHIFT) |
635 (((decmonitors[monitor].hfp) / 4) << VHCR_FPORCH_SHIFT) |
636 ((decmonitors[monitor].cols) / 4));
637 WRITE_GFB_REGISTER(sc->adp, TGA_REG_VVCR,
638 (decmonitors[monitor].vbp << VVCR_BPORCH_SHIFT) |
639 (decmonitors[monitor].vsync << VVCR_VSYNC_SHIFT) |
640 (decmonitors[monitor].vfp << VVCR_FPORCH_SHIFT) |
641 (decmonitors[monitor].rows));
642 WRITE_GFB_REGISTER(sc->adp, TGA_REG_VVBR, 1);
643 GFB_REGISTER_READWRITE_BARRIER(sc, TGA_REG_VHCR, 3);
644 WRITE_GFB_REGISTER(sc->adp, TGA_REG_VVVR,
645 READ_GFB_REGISTER(sc->adp, TGA_REG_VVVR) | 1);
646 GFB_REGISTER_READWRITE_BARRIER(sc, TGA_REG_VVVR, 1);
647 WRITE_GFB_REGISTER(sc->adp, TGA_REG_GPMR, 0xffffffff);
648 GFB_REGISTER_READWRITE_BARRIER(sc, TGA_REG_GPMR, 1);
652 tga_query_mode(video_adapter_t *adp, video_info_t *info)
656 /* Assume the best... */
659 /* Verify that this mode is supported on this adapter... */
660 if(adp->va_type == KD_TGA2) {
661 if((info->vi_mode != TGA2_2DA_MODE) &&
662 (info->vi_mode != TGA2_VGA_MODE))
666 if(info->vi_mode != 0)
673 tga_set_mode(video_adapter_t *adp, int mode)
679 /* Assume the best... */
682 gder = READ_GFB_REGISTER(adp, TGA_REG_GDER);
685 Determine the adapter type first
686 so we know which modes are valid for it...
688 switch(adp->va_type) {
692 Verify that this mode is supported
697 vgae_mask = ~0x00400000;
698 WRITE_GFB_REGISTER(adp, TGA_REG_GDER,
703 vgae_mask = 0x00400000;
704 WRITE_GFB_REGISTER(adp, TGA_REG_GDER,
715 Verify that this mode is supported
732 tga_blank_display(video_adapter_t *adp, int mode)
737 /* Assume the best... */
740 blanked = READ_GFB_REGISTER(adp, TGA_REG_VVVR) &
741 (VVR_BLANK | VVR_VIDEOVALID | VVR_CURSOR);
743 /* If we're not already blanked, then blank...*/
745 case V_DISPLAY_BLANK:
746 if(blanked != (VVR_VIDEOVALID | VVR_BLANK)) {
747 blanked = VVR_VIDEOVALID | VVR_BLANK;
748 WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, blanked);
751 case V_DISPLAY_STAND_BY:
752 if(blanked != VVR_BLANK) {
754 WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, blanked);
758 if(blanked != (VVR_VIDEOVALID | VVR_CURSOR)) {
759 blanked = VVR_VIDEOVALID | VVR_CURSOR;
760 WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, blanked);
772 tga_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
774 struct gfb_softc *sc;
778 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
782 tga_schedule_intr(sc, bt463_load_palette_intr);
787 case FBIO_SETDISPSTART:
788 case FBIO_SETLINEWIDTH:
789 case FBIO_GETPALETTE:
793 error = fb_commonioctl(adp, cmd, arg);
801 tga_set_border(video_adapter_t *adp, int color) {
806 tga_set_win_org(video_adapter_t *adp, off_t offset) {
808 u_int16_t window_orig;
813 /* Get the adapter's parameters... */
814 gder = BASIC_READ_TGA_REGISTER(adp, TGA_REG_GDER);
815 deep = (gder & 0x1) != 0;
816 cs = (gder & 0x200) == 0;
819 Set the window (framebuffer) origin according to the video
822 window_orig = offset / ((1 + cs) * (1 + deep) * (1 + deep) * 2 KB);
823 adp->va_window_orig = window_orig * ((1 + cs) * (1 + deep) *
826 /* Set the video base address... */
827 vvbr = READ_GFB_REGISTER(adp, TGA_REG_VVBR);
828 vvbr = (vvbr & 0xfffffe00) | window_orig;
829 WRITE_GFB_REGISTER(adp, TGA_REG_VVBR, vvbr);
834 tga_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) {
842 /* Save the pixel mode... */
843 gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
845 /* Save the pixel mask... */
846 gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
848 /* Save the block-color... */
849 gbcr0 = READ_GFB_REGISTER(adp, TGA_REG_GBCR0);
850 gbcr1 = READ_GFB_REGISTER(adp, TGA_REG_GBCR1);
852 /* Set the pixel mode (block-fill)... */
853 WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
854 (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_BLK_FILL);
856 /* Set the pixel mask (enable writes to all pixels)... */
857 WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, 0xffffffff);
859 color = ((val & 0xff00) << 24) || ((val & 0xff00) << 16) ||
860 ((val & 0xff00) << 8) || ((val & 0xff00) << 0);
862 /* Set the color for the block-fill... */
863 WRITE_GFB_REGISTER(adp, TGA_REG_GBCR0, color);
864 WRITE_GFB_REGISTER(adp, TGA_REG_GBCR1, color);
867 Just traverse the buffer, one 2K-pixel span at a time, setting
868 each pixel to the bolck-color...
870 for(off = (x * y); off < ((x + cx) * (y + cy)); off += (2 KB))
871 WRITE_GFB_BUFFER(adp, off >> 2L, 0x000007ff);
873 /* Restore the pixel mode... */
874 WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
876 /* Restore the pixel mask... */
877 WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
879 /* Restore the block-color... */
880 WRITE_GFB_REGISTER(adp, TGA_REG_GBCR0, gbcr0);
881 WRITE_GFB_REGISTER(adp, TGA_REG_GBCR1, gbcr1);
887 tga_bitblt(video_adapter_t *adp, ...) {
892 vm_offset_t src, dst;
896 /* Save the pixel mode... */
897 gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
899 /* Save the raster op... */
900 gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
902 /* Set the pixel mode (copy)... */
903 WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
904 (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_COPY);
906 /* Set the raster op (src)... */
907 WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x3);
909 src = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
911 dst = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
913 count = va_arg(args, int);
914 for(i = 0; i < count; i+= 64, src += 64, dst += 64) {
915 WRITE_GFB_REGISTER(adp, TGA_REG_GCSR, src);
916 WRITE_GFB_REGISTER(adp, TGA_REG_GCDR, dst);
919 /* Restore the raster op... */
920 WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
922 /* Restore the pixel mode... */
923 WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
931 tga_clear(video_adapter_t *adp, int n)
933 tga_clear(video_adapter_t *adp)
942 if(n == 0) return(0);
945 /* Save the pixel mode... */
946 gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
948 /* Save the pixel mask... */
949 gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
951 /* Save the raster op... */
952 gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
954 /* Set the pixel mode (opaque-fill)... */
955 WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
956 (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_OPQ_FILL);
958 /* Set the pixel mask (enable writes to all pixels)... */
959 WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, 0xffffffff);
961 /* Set the raster op (clear)... */
962 WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x00);
965 Just traverse the buffer, one 2K-pixel span at a time, clearing
969 for(off = 0; off < (n * adp->va_line_width); off += (2 KB))
971 for(off = 0; off < adp->va_window_size; off += (2 KB))
972 WRITE_GFB_BUFFER(adp, off >> 2L, 0x000007ff);
974 /* Restore the pixel mask... */
975 WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
977 /* Restore the raster op... */
978 WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
980 /* Restore the pixel mode... */
981 WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
987 tga_putc(video_adapter_t *adp, vm_offset_t off, u_int8_t c, u_int8_t a)
999 struct gfb_softc *sc;
1002 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1003 pixel_size = adp->va_info.vi_depth / 8;
1005 /* Save the pixel mode... */
1006 gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
1008 /* Save the pixel mask... */
1009 gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
1011 /* Save the raster op... */
1012 gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
1014 /* Save the background color... */
1015 gbgr = READ_GFB_REGISTER(adp, TGA_REG_GBGR);
1017 /* Save the foreground color... */
1018 gfgr = READ_GFB_REGISTER(adp, TGA_REG_GFGR);
1020 /* Set the pixel mode (opaque-stipple)... */
1021 WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
1022 (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_OPQ_STPL);
1024 /* Set the pixel mask (enable writes to the first cwidth pixels)... */
1025 WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P,
1026 (1 << adp->va_info.vi_cwidth) - 1);
1028 /* Set the raster op (src)... */
1029 WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x3);
1031 /* Set the foreground color mask from the attribute byte... */
1032 mask = (a & 0x80) ? a : (a & 0x0f);
1034 /* Propagate the 8-bit mask across the full 32 bits... */
1035 mask |= (mask << 24) | (mask << 16) | (mask << 8);
1037 /* Set the foreground color... */
1038 WRITE_GFB_REGISTER(adp, TGA_REG_GFGR, mask);
1040 /* Set the background color mask from the attribute byte... */
1041 mask = (a >> 4) & 0x07;
1043 /* Propagate the 8-bit mask across the full 32 bits... */
1044 mask |= (mask << 24) | (mask << 16) | (mask << 8);
1046 /* Set the background color... */
1047 WRITE_GFB_REGISTER(adp, TGA_REG_GBGR, mask);
1049 /* Get the start of the array of pixels rows for this character... */
1050 pixel = sc->gfbc->font + (c * adp->va_info.vi_cheight);
1052 /* Calculate the new cursor position... */
1053 row = off / adp->va_info.vi_width;
1054 col = off % adp->va_info.vi_width;
1056 /* Iterate over all the pixel rows for this character... */
1057 for(i = 0; i < adp->va_info.vi_cheight; i++) {
1059 /* Get the address of the character's pixel-row... */
1060 poff = ((col * adp->va_info.vi_cwidth * pixel_size) +
1061 (((row * adp->va_info.vi_cheight) + i) *
1062 adp->va_line_width)) / sizeof(gfb_reg_t);
1064 /* Now display the current pixel row... */
1065 WRITE_GFB_BUFFER(adp, poff, pixel[i]);
1068 /* Restore the foreground color... */
1069 WRITE_GFB_REGISTER(adp, TGA_REG_GFGR, gfgr);
1071 /* Restore the background color... */
1072 WRITE_GFB_REGISTER(adp, TGA_REG_GBGR, gbgr);
1074 /* Restore the pixel mode... */
1075 WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
1077 /* Restore the pixel mask... */
1078 WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
1080 /* Restore the raster op... */
1081 WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
1087 tga_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
1099 struct gfb_softc *sc;
1102 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1103 pixel_size = adp->va_info.vi_depth / 8;
1105 /* If the string in empty, just return now... */
1106 if(len == 0) return(0);
1108 for(i = 0; i < len; i++)
1109 tga_putc(adp, off + i, s[i] & 0x00ff, (s[i] & 0xff00) >> 8);
1112 /* Save the pixel mode... */
1113 gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
1115 /* Save the pixel mask... */
1116 gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
1118 /* Save the raster op... */
1119 gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
1121 /* Set the pixel mode (simple)... */
1122 WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, (gmor & 0xffffffc0) | 0x00);
1124 /* Set the pixel mask (enable writes to all 32 pixels)... */
1125 WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, (gpxr & 0xfffffff0) | 0xf);
1127 /* Set the raster op (src)... */
1128 WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x03);
1131 First, do as many characters-rows at a time as possible (as exist)...
1133 for(i = 0; (len - i) > adp->va_info.vi_width;
1134 i += adp->va_info.vi_width) {
1137 Iterate over all the pixels for each character in the
1138 character-row, doing a scan-line at-a-time, rather than
1139 a character at-a-time (like tga_putc())...
1141 for(j = 0; j < adp->va_info.vi_cheight; j++) {
1143 for(k = 0; k < adp->va_info.vi_width; k++) {
1146 Get this character...
1148 c = s[i + k] & 0x00ff;
1151 Get the attribute for this character...
1153 a = (s[i + k] & 0xff00) >> 8;
1156 Get the start of the array of pixels rows for
1159 pixel = sc->gfbc->font +
1160 (c * adp->va_info.vi_cheight);
1162 /* Shift the other pre-existing pixel rows... */
1166 Get the first pixel row for
1171 if (((k + 1) % sizeof(gfb_reg_t)) == 0) {
1174 Calculate the new cursor
1177 row = (off + i + (k -
1178 (sizeof(gfb_reg_t) - 1))) /
1179 adp->va_info.vi_width;
1180 col = (off + i + (k -
1181 (sizeof(gfb_reg_t) - 1))) %
1182 adp->va_info.vi_width;
1185 Get the address of the current
1186 character's pixel-row...
1188 poff = ((col * adp->va_info.vi_cwidth *
1189 pixel_size) + (((row *
1190 adp->va_info.vi_cheight) + j) *
1191 adp->va_line_width)) /
1195 Now display the current
1198 (*vidsw[adp->va_index]->putp)(adp, poff,
1199 p, a, sizeof(gfb_reg_t),
1200 adp->va_info.vi_depth, 1, 0);
1202 /* Reset (clear) p... */
1210 Next, do as many character-sets at a time as possible (as exist)...
1212 for(; (len - i) > sizeof(gfb_reg_t); i += sizeof(gfb_reg_t)) {
1215 Iterate over all the pixels for each character in the
1216 character-row, doing a scan-line at-a-time, rather than
1217 a character at-a-time (like tga_putc())...
1219 for(j = 0; j < adp->va_info.vi_cheight; j++) {
1221 for(k = 0; k < sizeof(gfb_reg_t); k++) {
1224 Get this character...
1226 c = s[i + k] & 0x00ff;
1229 Get the attribute for this character...
1231 a = (s[i + k] & 0xff00) >> 8;
1234 Get the start of the array of pixels rows for
1237 pixel = sc->gfbc->font +
1238 (c * adp->va_info.vi_cheight);
1240 /* Shift the other pre-existing pixel rows... */
1244 Get the first pixel row for
1249 if (((k + 1) % sizeof(gfb_reg_t)) == 0) {
1252 Calculate the new cursor
1255 row = (off + i) / adp->va_info.vi_width;
1256 col = (off + i) % adp->va_info.vi_width;
1259 Get the address of the current
1260 character's pixel-row...
1262 poff = ((col * adp->va_info.vi_cwidth *
1263 pixel_size) + (((row *
1264 adp->va_info.vi_cheight) + j) *
1265 adp->va_line_width)) /
1269 Now display the current
1272 (*vidsw[adp->va_index]->putp)(adp, poff,
1273 p, a, sizeof(gfb_reg_t),
1274 adp->va_info.vi_depth, 1, 0);
1276 /* Reset (clear) p... */
1283 /* Restore the pixel mode... */
1284 WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
1286 /* Restore the pixel mask... */
1287 WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
1289 /* Restore the raster op... */
1290 WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
1292 /* Finally, do the remaining characters a character at-a-time... */
1293 for(; i < len; i++) {
1295 Get this character...
1300 Get the attribute for this character...
1302 a = (s[i] & 0xff00) >> 8;
1305 Display this character...
1307 tga_putc(adp, off + i, c, a);
1313 tga_putm(video_adapter_t *adp, int x, int y, u_int8_t *pixel_image,
1314 gfb_reg_t pixel_mask, int size)
1322 pixel_size = adp->va_info.vi_depth / 8;
1324 /* Save the pixel mode... */
1325 gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
1327 /* Save the pixel mask... */
1328 gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
1330 /* Save the raster op... */
1331 gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
1333 /* Set the pixel mode (simple)... */
1334 WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
1335 (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_SIMPLE);
1337 /* Set the pixel mask (enable writes to the first 8 pixels)... */
1338 WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, (gpxr & 0xfffffff0) | 0xf);
1340 /* Set the raster op (src)... */
1341 WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x3);
1343 /* Iterate over all the pixel rows for the mouse pointer... */
1344 for(i = 0; i < size; i++) {
1346 /* Get the address of the mouse pointer's pixel-row... */
1347 poff = ((x * pixel_size) + ((y + i) * adp->va_line_width)) /
1350 /* Now display the current pixel-row... */
1351 (*vidsw[adp->va_index]->putp)(adp, poff, pixel_image[i],
1352 pixel_mask, sizeof(u_int8_t), adp->va_info.vi_depth, 1, 0);
1355 /* Restore the pixel mode... */
1356 WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
1358 /* Restore the pixel mask... */
1359 WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
1361 /* Restore the raster op... */
1362 WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
1373 /*****************************************************************************
1375 * TGA-specific functions
1377 ****************************************************************************/
1380 tga_builtin_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
1384 struct gfb_softc *sc;
1387 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1390 * We store 8 bit values in the palette buffer, while the standard
1391 * VGA has 6 bit DAC .
1393 outb(PALRADR, 0x00);
1394 for(i = 0; i < palette->count; ++i) {
1395 palette->red[i] = inb(PALDATA) << 2;
1396 palette->green[i] = inb(PALDATA) << 2;
1397 palette->blue[i] = inb(PALDATA) << 2;
1403 tga_builtin_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
1407 struct gfb_softc *sc;
1410 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1413 * We store 8 bit values in the palette buffer, while the standard
1414 * VGA has 6 bit DAC .
1416 outb(PIXMASK, 0xff);
1417 outb(PALWADR, 0x00);
1418 for(i = 0; i < palette->count; ++i) {
1419 outb(PALDATA, palette->red[i] >> 2);
1420 outb(PALDATA, palette->green[i] >> 2);
1421 outb(PALDATA, palette->blue[i] >> 2);
1428 tga2_builtin_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
1432 struct gfb_softc *sc;
1435 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1437 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1438 BT463_IREG_CPALETTE_RAM & 0xff);
1439 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1440 (BT463_IREG_CPALETTE_RAM >> 8) & 0xff);
1442 /* spit out the colormap data */
1443 for(i = 0; i < palette->count; i++) {
1444 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA,
1446 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA,
1448 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA,
1455 tga2_builtin_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
1459 struct gfb_softc *sc;
1462 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1464 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1465 BT463_IREG_CPALETTE_RAM & 0xff);
1466 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1467 (BT463_IREG_CPALETTE_RAM >> 8) & 0xff);
1469 /* spit out the colormap data */
1470 for(i = 0; i < palette->count; i++) {
1471 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA,
1473 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA,
1475 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA,
1482 tga2_builtin_save_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
1486 struct gfb_softc *sc;
1489 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1491 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1492 BT463_IREG_CURSOR_COLOR_0 & 0xff);
1493 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1494 (BT463_IREG_CURSOR_COLOR_0 >> 8) & 0xff);
1496 /* spit out the cursor data */
1497 for(i = 0; i < palette->count; i++) {
1498 BTWNREG(sc, palette->red[i]);
1499 BTWNREG(sc, palette->green[i]);
1500 BTWNREG(sc, palette->blue[i]);
1506 tga2_builtin_load_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
1510 struct gfb_softc *sc;
1513 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1515 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1516 BT463_IREG_CURSOR_COLOR_0 & 0xff);
1517 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1518 (BT463_IREG_CURSOR_COLOR_0 >> 8) & 0xff);
1520 /* spit out the cursor data */
1521 for(i = 0; i < palette->count; i++) {
1522 BTWNREG(sc, palette->red[i]);
1523 BTWNREG(sc, palette->green[i]);
1524 BTWNREG(sc, palette->blue[i]);
1532 tga_builtin_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
1537 /* Assume the best... */
1540 cxyr = READ_GFB_REGISTER(adp, TGA_REG_CXYR) | 0x00ffffff;
1541 *col = (cxyr & 0x00000fff) / adp->va_info.vi_cwidth;
1542 *row = ((cxyr & 0x00fff000) >> 12) / adp->va_info.vi_cheight;
1547 tga_builtin_set_hw_cursor(video_adapter_t *adp, int col, int row)
1553 /* Assume the best... */
1556 vvvr = READ_GFB_REGISTER(adp, TGA_REG_VVVR);
1559 Make sure the parameters are in range for the screen
1562 if((row > adp->va_info.vi_height) ||
1563 (col > adp->va_info.vi_width))
1565 else if(((row * adp->va_info.vi_cheight) > 0x0fff) ||
1566 ((col * adp->va_info.vi_cwidth) > 0x0fff))
1569 If either of the parameters is less than 0,
1570 then hide the cursor...
1572 else if((row < 0) || (col < 0)) {
1573 if((vvvr & 0x00000004) != 0) {
1575 WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, vvvr);
1579 /* Otherwise, just move the cursor as requested... */
1581 cxyr = READ_GFB_REGISTER(adp, TGA_REG_CXYR) & 0xff000000;
1582 cxyr |= ((row * adp->va_info.vi_cheight) << 12);
1583 cxyr |= (col * adp->va_info.vi_cwidth);
1584 WRITE_GFB_REGISTER(adp, TGA_REG_CXYR, cxyr);
1585 if((vvvr & 0x00000004) == 0) {
1587 WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, vvvr);
1594 tga_builtin_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
1595 int cellsize, int blink)
1599 gfb_reg_t window_orig;
1604 /* Assume the best... */
1607 vvvr = READ_GFB_REGISTER(adp, TGA_REG_VVVR);
1610 Make sure the parameters are in range for the cursor
1611 (it's a 64x64 cursor)...
1616 /* If height is less than or equal to 0, then hide the cursor... */
1617 else if(height <= 0) {
1618 if((vvvr & 0x00000004) != 0) {
1620 WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, vvvr);
1624 /* Otherwise, just resize the cursor as requested... */
1626 ccbr = READ_GFB_REGISTER(adp, TGA_REG_CCBR);
1628 ccbr |= ((height - 1) << 10);
1629 WRITE_GFB_REGISTER(adp, TGA_REG_CCBR, ccbr);
1630 if((vvvr & 0x00000004) == 0) {
1632 WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, vvvr);
1635 /* Save the window origin... */
1636 window_orig = adp->va_window_orig;
1639 Fill in the cursor image (64 rows of 64 pixels per cursor
1640 row at 2 bits-per-pixel, so 64 rows of 16 bytes each)--we
1641 set va_window_orig to the cursor base address temporarily
1642 so that we can write to the cursor image...
1644 cba = (READ_GFB_REGISTER(adp, TGA_REG_CCBR) & 0xfffffc0f) >> 4;
1645 adp->va_window_orig = cba;
1646 for(i = 0; i < (64 - height); i++) {
1647 WRITE_GFB_BUFFER(adp, cba++, 0x00000000);
1648 WRITE_GFB_BUFFER(adp, cba++, 0x00000000);
1650 for(; i < 64; i++) {
1651 for(j = 0; j < (((64 - cellsize) / 8) /
1652 sizeof(gfb_reg_t)); j++)
1653 WRITE_GFB_BUFFER(adp, cba++, 0x00000000);
1654 for(; j < ((64 / 8) / sizeof(gfb_reg_t)); j++)
1655 WRITE_GFB_BUFFER(adp, cba++, 0xffffffff);
1658 /* Restore the window origin... */
1659 adp->va_window_orig = window_orig;
1666 bt463_load_palette_intr(struct gfb_softc *sc)
1668 sc->gfbc->ramdac_save_palette(sc->adp, &sc->gfbc->palette);
1672 bt463_load_cursor_palette_intr(struct gfb_softc *sc)
1674 sc->gfbc->ramdac_load_cursor_palette(sc->adp, &sc->gfbc->cursor_palette);
1678 tga_schedule_intr(struct gfb_softc *sc, void (*f)(struct gfb_softc *))
1680 /* Busy-wait for the previous interrupt to complete... */
1681 while((READ_GFB_REGISTER(sc->adp, TGA_REG_SISR) & 0x00000001) != 0);
1683 /* Arrange for f to be called at the next end-of-frame interrupt... */
1684 sc->gfbc->ramdac_intr = f;
1686 /* Enable the interrupt... */
1687 WRITE_GFB_REGISTER(sc->adp, TGA_REG_SISR, 0x00010000);
1692 tga_bt485_rd(struct gfb_softc *sc, u_int btreg)
1696 if(btreg > BT485_REG_MAX)
1697 panic("tga_ramdac_rd: reg %d out of range\n", btreg);
1698 WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPSR, (btreg << 1) | 0x1);
1699 GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPSR, 1);
1700 rdval = READ_GFB_REGISTER(sc->adp, TGA_REG_EPDR);
1701 return((rdval >> 16) & 0xff);
1705 tga_bt485_wr(struct gfb_softc *sc, u_int btreg, u_int8_t val)
1707 if(btreg > BT485_REG_MAX)
1708 panic("tga_ramdac_wr: reg %d out of range\n", btreg);
1709 WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPDR,
1710 (btreg << 9) | (0 << 8 ) | val);
1711 GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPDR, 1);
1715 tga2_ibm561_rd(struct gfb_softc *sc, u_int btreg)
1717 bus_space_handle_t ramdac;
1720 if(btreg > BT485_REG_MAX)
1721 panic("tga_ramdac_rd: reg %d out of range\n", btreg);
1722 ramdac = sc->bhandle + TGA2_MEM_RAMDAC + (0xe << 12) + (btreg << 8);
1723 retval = bus_space_read_4(sc->btag, ramdac, 0) & 0xff;
1724 bus_space_barrier(sc->btag, ramdac, 0, 4, BUS_SPACE_BARRIER_READ);
1729 tga2_ibm561_wr(struct gfb_softc *sc, u_int btreg, u_int8_t val)
1731 bus_space_handle_t ramdac;
1733 if(btreg > BT485_REG_MAX)
1734 panic("tga_ramdac_wr: reg %d out of range\n", btreg);
1735 ramdac = sc->bhandle + TGA2_MEM_RAMDAC + (0xe << 12) + (btreg << 8);
1736 bus_space_write_4(sc->btag, ramdac, 0, val & 0xff);
1737 bus_space_barrier(sc->btag, ramdac, 0, 4, BUS_SPACE_BARRIER_WRITE);
1741 tga_bt463_rd(struct gfb_softc *sc, u_int btreg)
1746 * Strobe CE# (high->low->high) since status and data are latched on
1747 * the falling and rising edges (repsectively) of this active-low
1751 GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPSR, 1);
1752 WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
1753 GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPSR, 1);
1754 WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPSR, (btreg << 2) | 2 | 0);
1755 GFB_REGISTER_READ_BARRIER(sc, TGA_REG_EPSR, 1);
1756 rdval = READ_GFB_REGISTER(sc->adp, TGA_REG_EPDR);
1757 GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPSR, 1);
1758 WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
1759 return((rdval >> 16) & 0xff);
1763 tga_bt463_wr(struct gfb_softc *sc, u_int btreg, u_int8_t val)
1766 * In spite of the 21030 documentation, to set the MPU bus bits for
1767 * a write, you set them in the upper bits of EPDR, not EPSR.
1771 * Strobe CE# (high->low->high) since status and data are latched on
1772 * the falling and rising edges of this active-low signal.
1775 GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPDR, 1);
1776 WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
1777 GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPDR, 1);
1778 WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPDR, (btreg << 10) | 0x000 | val);
1779 GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPDR, 1);
1780 WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
1784 tga2_ics9110_wr(struct gfb_softc *sc, int dotclock)
1786 bus_space_handle_t clock;
1793 N = 0x40; M = 0x7; V = 0x0; X = 0x1; R = 0x1; break;
1795 N = 0x2d; M = 0x2b; V = 0x1; X = 0x1; R = 0x1; break;
1797 N = 0x11; M = 0x9; V = 0x1; X = 0x1; R = 0x2; break;
1799 N = 0x6d; M = 0xf; V = 0x0; X = 0x1; R = 0x1; break;
1801 N = 0x5F; M = 0x3E; V = 0x1; X = 0x1; R = 0x1; break;
1803 N = 0x6e; M = 0x15; V = 0x0; X = 0x1; R = 0x1; break;
1805 N = 0x2a; M = 0x41; V = 0x1; X = 0x1; R = 0x1; break;
1807 N = 0x35; M = 0xb; V = 0x0; X = 0x1; R = 0x1; break;
1809 N = 0x6d; M = 0x0c; V = 0x0; X = 0x1; R = 0x2; break;
1811 N = 0x37; M = 0x3f; V = 0x1; X = 0x1; R = 0x2; break;
1813 N = 0x5f; M = 0x11; V = 0x0; X = 0x1; R = 0x2; break;
1815 N = 0x16; M = 0x05; V = 0x0; X = 0x1; R = 0x2; break;
1817 N = 0x66; M = 0x1d; V = 0x0; X = 0x1; R = 0x2; break;
1819 N = 0x42; M = 0x07; V = 0x0; X = 0x1; R = 0x1; break;
1821 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
1823 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
1825 panic("unrecognized clock rate %d\n", dotclock);
1828 /* XXX -- hard coded, bad */
1829 valU = N | ( M << 7 ) | (V << 14);
1830 valU |= (X << 15) | (R << 17);
1832 clock = sc->bhandle + TGA2_MEM_EXTDEV + TGA2_MEM_CLOCK + (0xe << 12);
1833 for(i = 24; i > 0; i--) {
1836 writeval = valU & 0x1;
1840 bus_space_write_4(sc->btag, clock, 0, writeval);
1841 bus_space_barrier(sc->btag, clock, 0, 4,
1842 BUS_SPACE_BARRIER_WRITE);
1844 clock = sc->bhandle + TGA2_MEM_EXTDEV + TGA2_MEM_CLOCK + (0xe << 12) +
1845 (0x1 << 11) + (0x1 << 11);
1846 bus_space_write_4(sc->btag, clock, 0, 0x0);
1847 bus_space_barrier(sc->btag, clock, 0, 0, BUS_SPACE_BARRIER_WRITE);
1850 /*****************************************************************************
1852 * BrookTree RAMDAC-specific functions
1854 ****************************************************************************/
1857 bt463_init(struct gfb_softc *sc)
1864 * Init the BT463 for normal operation.
1869 * reg 0: 4:1 multiplexing, 25/75 blink.
1870 * reg 1: Overlay mapping: mapped to common palette,
1871 * 14 window type entries, 24-plane configuration mode,
1872 * 4 overlay planes, underlays disabled, no cursor.
1873 * reg 2: sync-on-green enabled, pedestal enabled.
1876 BTWREG(sc, BT463_IREG_COMMAND_0, 0x40);
1877 BTWREG(sc, BT463_IREG_COMMAND_1, 0x48);
1878 BTWREG(sc, BT463_IREG_COMMAND_2, 0xC0);
1881 * Initialize the read mask.
1883 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1884 BT463_IREG_READ_MASK_P0_P7 & 0xff);
1885 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1886 (BT463_IREG_READ_MASK_P0_P7 >> 8) & 0xff);
1887 for(i = 0; i < 4; i++)
1891 * Initialize the blink mask.
1893 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1894 BT463_IREG_READ_MASK_P0_P7 & 0xff);
1895 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1896 (BT463_IREG_READ_MASK_P0_P7 >> 8) & 0xff);
1897 for(i = 0; i < 4; i++)
1901 * Clear test register
1903 BTWREG(sc, BT463_IREG_TEST, 0);
1906 * Initalize the RAMDAC info struct to hold all of our
1907 * data, and fill it in.
1910 /* Initialize the window type table:
1912 * Entry 0: 24-plane truecolor, overlays enabled, bypassed.
1914 * Lookup table bypass: yes ( 1 << 23 & 0x800000) 800000
1915 * Colormap address: 0x000 (0x000 << 17 & 0x7e0000) 0
1916 * Overlay mask: 0xf ( 0xf << 13 & 0x01e000) 1e000
1917 * Overlay location: P<27:24> ( 0 << 12 & 0x001000) 0
1918 * Display mode: Truecolor ( 0 << 9 & 0x000e00) 000
1919 * Number of planes: 8 ( 8 << 5 & 0x0001e0) 100
1920 * Plane shift: 0 ( 0 << 0 & 0x00001f) 0
1925 data->window_type[0] = 0x81e100;
1928 /* Entry 1: 8-plane pseudocolor in the bottom 8 bits,
1929 * overlays enabled, colormap starting at 0.
1931 * Lookup table bypass: no ( 0 << 23 & 0x800000) 0
1932 * Colormap address: 0x000 (0x000 << 17 & 0x7e0000) 0
1933 * Overlay mask: 0xf ( 0xf << 13 & 0x01e000) 0x1e000
1934 * Overlay location: P<27:24> ( 0 << 12 & 0x001000) 0
1935 * Display mode: Pseudocolor ( 1 << 9 & 0x000e00) 0x200
1936 * Number of planes: 8 ( 8 << 5 & 0x0001e0) 0x100
1937 * Plane shift: 16 ( 0x10 << 0 & 0x00001f) 10
1942 data->window_type[1] = 0x01e310;
1944 /* The colormap interface to the world only supports one colormap,
1945 * so having an entry for the 'alternate' colormap in the bt463
1946 * probably isn't useful.
1949 /* Fill the remaining table entries with clones of entry 0 until we
1950 * figure out a better use for them.
1953 for(i = 2; i < BT463_NWTYPE_ENTRIES; i++) {
1954 data->window_type[i] = 0x81e100;
1958 tga_schedule_intr(sc, bt463_update_window_type);
1959 tga_schedule_intr(sc, bt463_load_cursor_palette_intr);
1960 tga_schedule_intr(sc, bt463_load_palette_intr);
1964 bt463_update_window_type(struct gfb_softc *sc)
1968 /* The Bt463 won't accept window type data except during a blanking
1969 * interval, so we do this early in the interrupt.
1970 * Blanking the screen might also be a good idea, but it can cause
1971 * unpleasant flashing and is hard to do from this side of the
1974 /* spit out the window type data */
1975 for(i = 0; i < BT463_NWTYPE_ENTRIES; i++) {
1977 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1978 (BT463_IREG_WINDOW_TYPE_TABLE + i) & 0xff);
1979 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1980 ((BT463_IREG_WINDOW_TYPE_TABLE + i) >> 8) & 0xff);
1981 BTWNREG(sc, (data->window_type[i]) & 0xff);
1982 BTWNREG(sc, (data->window_type[i] >> 8) & 0xff);
1983 BTWNREG(sc, (data->window_type[i] >> 16) & 0xff);
1990 bt463_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
1992 struct gfb_softc *sc;
1996 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1998 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1999 BT463_IREG_CPALETTE_RAM & 0xff);
2000 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
2001 (BT463_IREG_CPALETTE_RAM >> 8) & 0xff);
2003 /* get the colormap data */
2004 for(i = 0; i < palette->count; i++) {
2005 palette->red[i] = sc->gfbc->ramdac_rd(sc, BT463_REG_CMAP_DATA);
2006 palette->green[i] = sc->gfbc->ramdac_rd(sc,
2007 BT463_REG_CMAP_DATA);
2008 palette->blue[i] = sc->gfbc->ramdac_rd(sc, BT463_REG_CMAP_DATA);
2014 bt463_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
2016 struct gfb_softc *sc;
2020 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2022 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
2023 BT463_IREG_CPALETTE_RAM & 0xff);
2024 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
2025 (BT463_IREG_CPALETTE_RAM >> 8) & 0xff);
2027 /* spit out the colormap data */
2028 for(i = 0; i < palette->count; i++) {
2029 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, palette->red[i]);
2030 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, palette->green[i]);
2031 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, palette->blue[i]);
2039 bt463_save_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2041 struct gfb_softc *sc;
2045 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2047 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
2048 BT463_IREG_CURSOR_COLOR_0 & 0xff);
2049 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
2050 (BT463_IREG_CURSOR_COLOR_0 >> 8) & 0xff);
2052 /* spit out the cursor data */
2053 for(i = 0; i < palette->count; i++) {
2054 palette->red[i] = BTRNREG(sc);
2055 palette->green[i] = BTRNREG(sc);
2056 palette->blue[i] = BTRNREG(sc);
2062 bt463_load_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2064 struct gfb_softc *sc;
2068 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2070 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
2071 BT463_IREG_CURSOR_COLOR_0 & 0xff);
2072 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
2073 (BT463_IREG_CURSOR_COLOR_0 >> 8) & 0xff);
2075 /* spit out the cursor data */
2076 for(i = 0; i < palette->count; i++) {
2077 BTWNREG(sc, palette->red[i]);
2078 BTWNREG(sc, palette->green[i]);
2079 BTWNREG(sc, palette->blue[i]);
2085 bt485_init(struct gfb_softc *sc)
2087 int i, j, num_cmap_entries;
2090 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_COMMAND_0);
2093 * Set the RAMDAC to 8 bit resolution, rather than 6 bit
2099 * Set the RAMDAC to sync-on-green.
2102 sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_0, regval);
2105 /* Set the RAMDAC to 8BPP (no interesting options). */
2106 sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_1, 0x40);
2108 /* Disable the cursor (for now) */
2109 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_COMMAND_2);
2112 sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_2, regval);
2114 /* Use a 64x64x2 cursor */
2115 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, BT485_IREG_COMMAND_3);
2116 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_EXTENDED);
2119 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, BT485_IREG_COMMAND_3);
2120 sc->gfbc->ramdac_wr(sc, BT485_REG_EXTENDED, regval);
2122 /* Set the Pixel Mask to something useful */
2123 sc->gfbc->ramdac_wr(sc, BT485_REG_PIXMASK, 0xff);
2126 /* Generate the cursor color map (Light-Grey)... */
2127 for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
2128 sc->gfbc->cursor_palette.red[i] = default_cmap[7].red;
2129 sc->gfbc->cursor_palette.green[i] = default_cmap[7].green;
2130 sc->gfbc->cursor_palette.blue[i] = default_cmap[7].blue;
2134 /* Enable cursor... */
2135 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_COMMAND_2);
2136 if(!(regval & 0x01)) {
2138 sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_2, regval);
2140 else if(regval & 0x03) {
2142 sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_2, regval);
2146 /* Generate the screen color map... */
2147 num_cmap_entries = sizeof(default_cmap) / sizeof(struct cmap);
2148 for(i = 0; i < sc->gfbc->palette.count / num_cmap_entries; i++)
2149 for(j = 0; j < num_cmap_entries; j++) {
2150 sc->gfbc->palette.red[(num_cmap_entries * i) + j] =
2151 default_cmap[j].red;
2152 sc->gfbc->palette.green[(num_cmap_entries * i) + j] =
2153 default_cmap[j].green;
2154 sc->gfbc->palette.blue[(num_cmap_entries * i) + j] =
2155 default_cmap[j].blue;
2160 bt485_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
2162 struct gfb_softc *sc;
2166 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2168 /* addr[9:0] assumed to be 0 */
2169 /* set addr[7:0] to 0 */
2170 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, 0x00);
2172 /* spit out the color data */
2173 for(i = 0; i < palette->count; i++) {
2174 palette->red[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_PALETTE);
2175 palette->green[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_PALETTE);
2176 palette->blue[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_PALETTE);
2182 bt485_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
2184 struct gfb_softc *sc;
2188 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2190 /* addr[9:0] assumed to be 0 */
2191 /* set addr[7:0] to 0 */
2192 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, 0x00);
2194 /* spit out the color data */
2195 for(i = 0; i < palette->count; i++) {
2196 sc->gfbc->ramdac_wr(sc, BT485_REG_PALETTE, palette->red[i]);
2197 sc->gfbc->ramdac_wr(sc, BT485_REG_PALETTE, palette->green[i]);
2198 sc->gfbc->ramdac_wr(sc, BT485_REG_PALETTE, palette->blue[i]);
2204 bt485_save_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2206 struct gfb_softc *sc;
2210 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2212 /* addr[9:0] assumed to be 0 */
2213 /* set addr[7:0] to 1 */
2214 sc->gfbc->ramdac_wr(sc, BT485_REG_COC_WRADDR, 0x01);
2216 /* spit out the cursor color data */
2217 for(i = 0; i < palette->count; i++) {
2218 palette->red[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_COCDATA);
2219 palette->green[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_COCDATA);
2220 palette->blue[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_COCDATA);
2226 bt485_load_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2228 struct gfb_softc *sc;
2232 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2234 /* addr[9:0] assumed to be 0 */
2235 /* set addr[7:0] to 1 */
2236 sc->gfbc->ramdac_wr(sc, BT485_REG_COC_WRADDR, 0x01);
2238 /* spit out the cursor color data */
2239 for(i = 0; i < palette->count; i++) {
2240 sc->gfbc->ramdac_wr(sc, BT485_REG_COCDATA, palette->red[i]);
2241 sc->gfbc->ramdac_wr(sc, BT485_REG_COCDATA, palette->green[i]);
2242 sc->gfbc->ramdac_wr(sc, BT485_REG_COCDATA, palette->blue[i]);
2248 bt485_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
2250 struct gfb_softc *sc;
2254 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2256 *col = (sc->gfbc->ramdac_rd(sc, BT485_REG_CURSOR_X_HIGH) & 0x0f) << 8;
2257 *col |= sc->gfbc->ramdac_rd(sc, BT485_REG_CURSOR_X_LOW) & 0xff;
2258 *col /= adp->va_info.vi_cwidth;
2260 *row = (sc->gfbc->ramdac_rd(sc, BT485_REG_CURSOR_Y_HIGH) & 0x0f) << 8;
2261 *row |= sc->gfbc->ramdac_rd(sc, BT485_REG_CURSOR_Y_LOW) & 0xff;
2262 *row /= adp->va_info.vi_cheight;
2269 bt485_set_hw_cursor(video_adapter_t *adp, int col, int row)
2271 struct gfb_softc *sc;
2276 /* Make sure the parameters are in range for the screen
2278 if((row > adp->va_info.vi_height) || (col > adp->va_info.vi_width))
2280 else if(((row * adp->va_info.vi_cheight) > 0x0fff) ||
2281 ((col * adp->va_info.vi_cwidth) > 0x0fff))
2283 else if((row < 0) || (col < 0)) {
2284 /* If either of the parameters is less than 0, then hide the
2289 /* Otherwise, just move the cursor as requested... */
2290 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2292 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_X_LOW,
2293 ((col + 8) * adp->va_info.vi_cwidth) & 0xff);
2294 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_X_HIGH,
2295 (((col + 8) * adp->va_info.vi_cwidth) >> 8) & 0x0f);
2296 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_Y_LOW,
2297 ((row + 4) * adp->va_info.vi_cheight) & 0xff);
2298 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_Y_HIGH,
2299 (((row + 4) * adp->va_info.vi_cheight) >> 8) & 0x0f);
2306 bt485_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
2307 int cellsize, int blink)
2309 struct gfb_softc *sc;
2310 int error, cell_count, count, i, j;
2315 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2318 Make sure the parameters are in range for the cursor
2319 (it's a 64x64 cursor)...
2323 else if(height <= 0) {
2324 /* If height is less than or equal to 0, then hide the
2327 /* Otherwise, just resize the cursor as requested... */
2329 /* 64 pixels per cursor-row, 2 bits-per-pixel, so counts in
2331 cell_count = cellsize / 8;
2335 * Write the cursor image data:
2336 * set addr[9:8] to 0,
2337 * set addr[7:0] to 0,
2340 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2341 BT485_IREG_COMMAND_3);
2342 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_EXTENDED);
2344 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2345 BT485_IREG_COMMAND_3);
2346 sc->gfbc->ramdac_wr(sc, BT485_REG_EXTENDED, regval);
2347 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, 0);
2349 /* Fill-in the desired pixels in the specified pixel-rows... */
2350 for(i = 0; i < height; i++) {
2351 for(j = 0; j < cell_count; j++)
2352 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2354 for(j = 0; j < count - cell_count; j++)
2355 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2359 /* Clear the remaining pixel rows... */
2361 for(j = 0; j < count; j++)
2362 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2366 * Write the cursor mask data:
2367 * set addr[9:8] to 2,
2368 * set addr[7:0] to 0,
2371 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2372 BT485_IREG_COMMAND_3);
2373 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_EXTENDED);
2374 regval &= ~0x03; regval |= 0x02;
2375 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2376 BT485_IREG_COMMAND_3);
2377 sc->gfbc->ramdac_wr(sc, BT485_REG_EXTENDED, regval);
2378 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, 0);
2380 /* Fill-in the desired pixels in the specified pixel-rows... */
2381 for(i = 0; i < height; i++) {
2382 for(j = 0; j < cell_count; j++)
2383 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2385 for(j = 0; j < count - cell_count; j++)
2386 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2390 /* Clear the remaining pixel rows... */
2392 for(j = 0; j < count; j++)
2393 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2396 /* set addr[9:0] back to 0 */
2397 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2398 BT485_IREG_COMMAND_3);
2399 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_EXTENDED);
2401 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2402 BT485_IREG_COMMAND_3);
2403 sc->gfbc->ramdac_wr(sc, BT485_REG_EXTENDED, regval);
2409 ibm561_init(struct gfb_softc *sc)
2414 ibm561_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
2423 ibm561_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
2432 ibm561_save_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2441 ibm561_load_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)