]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/fb/tga.c
This commit was generated by cvs2svn to compensate for changes in r100616,
[FreeBSD/FreeBSD.git] / sys / dev / fb / tga.c
1 /*-
2  * Copyright (c) 2000, 2001 Andrew Miklic, Andrew Gallatin, Peter Jeremy,
3  * and Thomas V. Crimi
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
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.
14  *
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
25  * SUCH DAMAGE.
26  */
27 /*
28  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
29  * All rights reserved.
30  *
31  * Author: Chris G. Demetriou
32  * 
33  * Permission to use, copy, modify and distribute this software and
34  * its documentation is hereby granted, provided that both the copyright
35  * notice and this permission notice appear in all copies of the
36  * software, derivative works or modified versions, and any portions
37  * thereof, and that both notices appear in supporting documentation.
38  * 
39  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
40  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
41  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
42  * 
43  * Carnegie Mellon requests users of this software to return to
44  *
45  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
46  *  School of Computer Science
47  *  Carnegie Mellon University
48  *  Pittsburgh PA 15213-3890
49  *
50  * any improvements or extensions that they make and grant Carnegie the
51  * rights to redistribute these changes.
52  */
53
54 #include <sys/cdefs.h>
55 __FBSDID("$FreeBSD$");
56
57 #include <machine/stdarg.h>
58
59 #include <sys/param.h>
60 #include <sys/systm.h>
61 #include <sys/kernel.h>
62 #include <sys/conf.h>
63 #include <sys/proc.h>
64 #include <sys/fcntl.h>
65 #include <sys/malloc.h>
66 #include <sys/fbio.h>
67 #include <sys/consio.h>
68
69 #include <isa/isareg.h>
70 #include <dev/fb/vgareg.h>
71
72 #include <vm/vm.h>
73 #include <vm/vm_param.h>
74 #include <vm/pmap.h>
75
76 #include <machine/md_var.h>
77 #include <machine/pc/bios.h>
78 #include <machine/clock.h>
79 #include <machine/bus_memio.h>
80 #include <machine/bus.h>
81 #include <machine/pc/vesa.h>
82 #include <machine/resource.h>
83 #include <machine/rpb.h>
84
85 #include <sys/bus.h>
86 #include <sys/rman.h>
87
88 #include <pci/pcireg.h>
89 #include <pci/pcivar.h>
90
91 #include <dev/fb/fbreg.h>
92 #include <dev/syscons/syscons.h>
93 #include <dev/fb/gfb.h>
94 #include <dev/gfb/gfb_pci.h>
95 #include <dev/fb/tga.h>
96 #include <dev/tga/tga_pci.h>
97
98 #include "opt_fb.h"
99
100 /* TGA-specific FB video driver function declarations */
101 static int tga_error(void);
102 static vi_init_t tga_init;
103 static void tga2_init(struct gfb_softc *, int);
104
105 /* TGA-specific functionality. */
106 static gfb_builtin_save_palette_t tga_builtin_save_palette;
107 static gfb_builtin_load_palette_t tga_builtin_load_palette;
108 #ifdef TGA2
109 static gfb_builtin_save_palette_t tga2_builtin_save_palette;
110 static gfb_builtin_load_palette_t tga2_builtin_load_palette;
111 static gfb_builtin_save_cursor_palette_t tga2_builtin_save_cursor_palette;
112 static gfb_builtin_load_cursor_palette_t tga2_builtin_load_cursor_palette;
113 #endif 
114 static gfb_builtin_read_hw_cursor_t tga_builtin_read_hw_cursor;
115 static gfb_builtin_set_hw_cursor_t tga_builtin_set_hw_cursor;
116 static gfb_builtin_set_hw_cursor_shape_t tga_builtin_set_hw_cursor_shape;
117 static void bt463_load_palette_intr(struct gfb_softc *);
118 static void bt463_load_cursor_palette_intr(struct gfb_softc *);
119 static int tga_schedule_intr(struct gfb_softc *, void (*)(struct gfb_softc *));
120
121 /* RAMDAC interface functions */
122 static gfb_ramdac_wr_t tga_bt485_wr;
123 static gfb_ramdac_rd_t tga_bt485_rd;
124 static gfb_ramdac_wr_t tga_bt463_wr;
125 static gfb_ramdac_rd_t tga_bt463_rd;
126 static gfb_ramdac_wr_t tga2_ibm561_wr;
127 static gfb_ramdac_rd_t tga2_ibm561_rd;
128 static void tga2_ics9110_wr(struct gfb_softc *, int);
129
130 /* RAMDAC-specific functions */
131 static gfb_ramdac_init_t bt463_init;
132 static void bt463_update_window_type(struct gfb_softc *);
133 #if 0
134 static gfb_ramdac_save_palette_t bt463_save_palette;
135 static gfb_ramdac_load_palette_t bt463_load_palette;
136 #endif 
137 static gfb_ramdac_save_cursor_palette_t bt463_save_cursor_palette;
138 static gfb_ramdac_load_cursor_palette_t bt463_load_cursor_palette;
139 static gfb_ramdac_init_t bt485_init;
140 static gfb_ramdac_save_palette_t bt485_save_palette;
141 static gfb_ramdac_load_palette_t bt485_load_palette;
142 static gfb_ramdac_save_cursor_palette_t bt485_save_cursor_palette;
143 static gfb_ramdac_load_cursor_palette_t bt485_load_cursor_palette;
144 static gfb_ramdac_read_hw_cursor_t bt485_read_hw_cursor;
145 static gfb_ramdac_set_hw_cursor_t bt485_set_hw_cursor;
146 static gfb_ramdac_set_hw_cursor_shape_t bt485_set_hw_cursor_shape;
147 static gfb_ramdac_init_t ibm561_init;
148 static gfb_ramdac_save_palette_t ibm561_save_palette;
149 static gfb_ramdac_load_palette_t ibm561_load_palette;
150 static gfb_ramdac_save_cursor_palette_t ibm561_save_cursor_palette;
151 static gfb_ramdac_load_cursor_palette_t ibm561_load_cursor_palette;
152
153 /* Video Driver-generic functions */
154 static vi_query_mode_t tga_query_mode;
155 static vi_set_mode_t tga_set_mode;
156 static vi_blank_display_t tga_blank_display;
157 #if 0
158 static vi_ioctl_t tga_ioctl;
159 #endif
160 static vi_set_border_t tga_set_border;
161 static vi_set_win_org_t tga_set_win_org;
162 static vi_fill_rect_t tga_fill_rect;
163 static vi_bitblt_t tga_bitblt;
164 static vi_clear_t tga_clear;
165 static vi_putc_t tga_putc;
166 static vi_puts_t tga_puts;
167 static vi_putm_t tga_putm;
168
169 static video_switch_t tgavidsw = {
170         gfb_probe,
171         tga_init,
172         gfb_get_info,
173         tga_query_mode,
174         tga_set_mode,
175         gfb_save_font,
176         gfb_load_font,
177         gfb_show_font,
178         gfb_save_palette,
179         gfb_load_palette,
180         tga_set_border,
181         gfb_save_state,
182         gfb_load_state,
183         tga_set_win_org,
184         gfb_read_hw_cursor,
185         gfb_set_hw_cursor,
186         gfb_set_hw_cursor_shape,
187         tga_blank_display,
188         gfb_mmap,
189         gfb_ioctl,
190         tga_clear,
191         tga_fill_rect,
192         tga_bitblt,
193         tga_error,
194         tga_error,
195         gfb_diag,
196         gfb_save_cursor_palette,
197         gfb_load_cursor_palette,
198         gfb_copy,
199         gfb_putp,
200         tga_putc,
201         tga_puts,
202         tga_putm,
203 };
204
205 VIDEO_DRIVER(tga, tgavidsw, NULL);
206
207 extern sc_rndr_sw_t txtrndrsw;
208 RENDERER(tga, 0, txtrndrsw, gfb_set);
209
210 #ifdef SC_PIXEL_MODE
211 extern sc_rndr_sw_t gfbrndrsw;
212 RENDERER(tga, PIXEL_MODE, gfbrndrsw, gfb_set);
213 #endif /* SC_PIXEL_MODE */
214
215 #ifndef SC_NO_MODE_CHANGE
216 extern sc_rndr_sw_t grrndrsw;
217 RENDERER(tga, GRAPHICS_MODE, grrndrsw, gfb_set);
218 #endif /* SC_NO_MODE_CHANGE */
219
220 RENDERER_MODULE(tga, gfb_set);
221
222 #define MHz     * 1000000
223 #define KHz     * 1000
224
225 extern struct gfb_softc *gfb_device_softcs[2][MAX_NUM_GFB_CARDS];
226
227 /*
228    The following 3 variables exist only because we need statically
229    allocated structures very early in boot to support tga_configure()...
230 */
231 extern struct gfb_softc console;
232 extern video_adapter_t console_adp;
233 extern struct gfb_conf console_gfbc;
234 extern u_char console_palette_red[256];
235 extern u_char console_palette_green[256];
236 extern u_char console_palette_blue[256];
237 extern u_char console_cursor_palette_red[3];
238 extern u_char console_cursor_palette_green[3];
239 extern u_char console_cursor_palette_blue[3];
240
241 static struct monitor decmonitors[] = {
242         /* 0x0: 1280 x 1024 @ 72Hz */
243         { 1280, 32,     160,    232,
244           1024, 3,      3,      33,
245           130808 KHz },
246
247         /* 0x1: 1280 x 1024 @ 66Hz */
248         { 1280, 32,     160,    232,
249           1024, 3,      3,      33,
250           119840 KHz },
251
252         /* 0x2: 1280 x 1024 @ 60Hz */
253         { 1280, 44,     184,    200,
254           1024, 3,      3,      26,
255           108180 KHz },
256
257         /* 0x3: 1152 x  900 @ 72Hz */
258         { 1152, 64,     112,    176,
259           900,  6,      10,     44,
260           103994 KHz },
261
262         /* 0x4: 1600 x 1200 @ 65Hz */
263         { 1600, 32,     192,    336,
264           1200, 1,      3,      46,
265           175 MHz },
266
267         /* 0x5: 1024 x  768 @ 70Hz */
268         { 1024, 24,     136,    144,
269           768,  3,      6,      29,
270           75 MHz },
271
272         /* 0x6: 1024 x  768 @ 72Hz */
273         { 1024, 16,     128,    128,
274           768,  1,      6,      22,
275           74 MHz },
276
277         /* 0x7: 1024 x  864 @ 60Hz */
278         { 1024, 12,     128,    116,
279           864,  0,      3,      34,
280           69 MHz },
281
282         /* 0x8: 1024 x  768 @ 60Hz */
283         { 1024, 56,     64,     200,
284           768,  7,      9,      26,
285           65 MHz },
286
287         /* 0x9:  800 x  600 @ 72Hz */
288         { 800,  56,     120,    64,
289           600,  37,     6,      23,
290           50 MHz },
291
292         /* 0xa:  800 x  600 @ 60Hz */
293         { 800,  40,     128,    88,
294           600,  1,      4,      23,
295           40 MHz },
296
297         /* 0xb:  640 x  480 @ 72Hz */
298         { 640,  24,     40,     128,
299           480,  9,      3,      28,
300           31500 KHz },
301
302         /* 0xc:  640 x  480 @ 60Hz */
303         { 640,  16,     96,     48,
304           480,  10,     2,      33,
305           25175 KHz },
306
307         /* 0xd: 1280 x 1024 @ 75Hz */
308         { 1280, 16,     144,    248,
309           1024, 1,      3,      38,
310           135 MHz  },
311
312         /* 0xe: 1280 x 1024 @ 60Hz */
313         { 1280, 19,     163,    234,
314           1024, 6,      7,      44,
315           110 MHz },
316
317         /* 0xf: 1600 x 1200 @ 75Hz */
318         /* XXX -- this one's weird.  rcd */
319         { 1600, 32,     192,    336,
320           1200, 1,      3,      46,
321           202500 KHz }
322 };
323
324 #undef MHz
325 #undef KHz
326
327 #undef KB
328 #define KB      * 1024
329 #undef MB
330 #define MB      * 1024 * 1024
331
332 /*
333  * These are the 16 default VGA colors--these are replicated 16 times as the
334  * initial (default) color-map.  The text rendering functions use entries
335  * 0..15 for normal foreground/background colors.  The entries 128..255 are
336  * used for blinking entries--when "on," they contain the foreground color
337  * entries; when "off," they contain the background color entries...
338  */
339 static const struct cmap {
340         u_char red;
341         u_char green;
342         u_char blue;
343 } default_cmap[16] = {
344         {0x00, 0x00, 0x00},     /* Black */
345         {0x00, 0x00, 0xff},     /* Blue */
346         {0x00, 0xff, 0x00},     /* Green */
347         {0x00, 0xc0, 0xc0},     /* Cyan */
348         {0xff, 0x00, 0x00},     /* Red */
349         {0xc0, 0x00, 0xc0},     /* Magenta */
350         {0xc0, 0xc0, 0x00},     /* Brown */
351         {0xc0, 0xc0, 0xc0},     /* Light Grey */
352         {0x80, 0x80, 0x80},     /* Dark Grey */
353         {0x80, 0x80, 0xff},     /* Light Blue */
354         {0x80, 0xff, 0x80},     /* Light Green */
355         {0x80, 0xff, 0xff},     /* Light Cyan */
356         {0xff, 0x80, 0x80},     /* Light Red */
357         {0xff, 0x80, 0xff},     /* Light Magenta */
358         {0xff, 0xff, 0x80},     /* Yellow */
359         {0xff, 0xff, 0xff}      /* White */
360 };
361
362 extern struct gfb_font bold8x16;
363
364 /*****************************************************************************
365  *
366  * FB-generic functions
367  *
368  ****************************************************************************/
369
370 static int
371 tga_init(int unit, video_adapter_t *adp, int flags)
372 {
373         struct gfb_softc *sc;
374         struct gfb_conf *gfbc;
375         unsigned int monitor;
376         int card_type;
377         int gder;
378         int deep;
379         int addrmask;
380         int cs;
381         int error;
382         gfb_reg_t ccbr;
383
384         /* Assume the best... */
385         error = 0;
386
387         sc = gfb_device_softcs[adp->va_model][unit];
388         gfbc = sc->gfbc;
389
390         /* Initialize palette counts... */
391         gfbc->palette.count = 256;
392         gfbc->cursor_palette.count = 3;
393
394         /* Initialize the adapter... */
395         gder = BASIC_READ_TGA_REGISTER(adp, TGA_REG_GDER);
396         addrmask = (gder & GDER_ADDR_MASK) >> GDER_ADDR_SHIFT;
397         deep = (gder & GDER_DEEP) != 0;
398         cs = (gder & GDER_CS) == 0;
399         card_type = TGA_TYPE_UNKNOWN;
400         adp->va_little_bitian = 1;
401         adp->va_little_endian = 0;
402         adp->va_initial_mode = 0;
403         adp->va_initial_bios_mode = 0;
404         adp->va_mode = 0;
405         adp->va_info.vi_mem_model = V_INFO_MM_TEXT;
406         adp->va_info.vi_mode = M_VGA_M80x30;
407         adp->va_info.vi_flags = V_INFO_COLOR;
408         adp->va_buffer = adp->va_mem_base;
409         adp->va_buffer_size = 4 MB * (1 + addrmask);
410         adp->va_registers = adp->va_buffer + TGA_REG_SPACE_OFFSET;
411         adp->va_registers_size = 2 KB;
412         adp->va_window = adp->va_buffer + (adp->va_buffer_size / 2);
413         adp->va_info.vi_window = vtophys(adp->va_window);
414         adp->va_window_size = (deep ? 4 MB : 2 MB);
415         adp->va_info.vi_window_size = adp->va_window_size;
416         adp->va_window_gran = adp->va_window_size;
417         adp->va_info.vi_window_gran = adp->va_window_gran;
418         adp->va_info.vi_buffer = vtophys(adp->va_buffer);
419         adp->va_info.vi_buffer_size = adp->va_buffer_size;
420         adp->va_disp_start.x = 0;
421         adp->va_disp_start.y = 0;
422         adp->va_info.vi_depth = (deep ? 32 : 8);
423         adp->va_info.vi_planes = adp->va_info.vi_depth / 8;
424         adp->va_info.vi_width = (READ_GFB_REGISTER(adp, TGA_REG_VHCR) &
425                                    VHCR_ACTIVE_MASK);
426         adp->va_info.vi_width |= (READ_GFB_REGISTER(adp, TGA_REG_VHCR) &
427                                    0x30000000) >> 19;
428         switch(adp->va_info.vi_width) {
429         case 0:
430                 adp->va_info.vi_width = 8192;
431                 break;
432         case 1:
433                 adp->va_info.vi_width = 8196;
434                 break;
435         default:
436                 adp->va_info.vi_width *= 4;
437                 break;
438         }
439         adp->va_info.vi_height = (READ_GFB_REGISTER(adp, TGA_REG_VVCR) &
440                                    VVCR_ACTIVE_MASK);
441         adp->va_line_width = adp->va_info.vi_width * adp->va_info.vi_depth / 8;
442         if(READ_GFB_REGISTER(adp, TGA_REG_VHCR) & VHCR_ODD)
443                 adp->va_info.vi_width -= 4;
444
445         /*
446            Set the video base address and the cursor base address to
447            something known such that the video base address is at
448            least 1 KB past the cursor base address (the cursor is 1 KB
449            in size, so leave room for it)...we pick 4 KB  and 0 KB,
450            respectively, since they begin at the top of the framebuffer
451            for minimal fragmentation of the address space, and this will
452            always leave enough room for the cursor for all implementations...
453         */
454
455         /* Set the video base address... */     
456         tga_set_win_org(sc->adp, 4 KB);
457
458         /* Set the cursor base address... */    
459         ccbr = READ_GFB_REGISTER(sc->adp, TGA_REG_CCBR);
460         ccbr = (ccbr & 0xfffffc0f) | (0 << 4);
461         WRITE_GFB_REGISTER(sc->adp, TGA_REG_CCBR, ccbr);
462
463         /* Type the card... */
464         if(adp->va_type == KD_TGA) {
465                 if(!deep) {
466
467                         /* 8bpp frame buffer */
468                         gfbc->ramdac_name = "BT485";
469                         gfbc->ramdac_init = bt485_init;
470                         gfbc->ramdac_rd = tga_bt485_rd;
471                         gfbc->ramdac_wr = tga_bt485_wr;
472                         gfbc->ramdac_save_palette = bt485_save_palette;
473                         gfbc->ramdac_load_palette = bt485_load_palette;
474                         gfbc->ramdac_save_cursor_palette =
475                             bt485_save_cursor_palette;
476                         gfbc->ramdac_load_cursor_palette =
477                             bt485_load_cursor_palette;
478                         gfbc->ramdac_read_hw_cursor = bt485_read_hw_cursor;
479                         gfbc->ramdac_set_hw_cursor = bt485_set_hw_cursor;
480                         gfbc->ramdac_set_hw_cursor_shape =
481                             bt485_set_hw_cursor_shape;
482
483                         if(addrmask == GDER_ADDR_4MB) {
484
485                                 /* 4MB core map; T8-01 or T8-02 */
486                                 if(!cs) {
487                                         card_type = TGA_TYPE_T8_01;
488                                         gfbc->name = "T8-01";
489                                 } else {
490                                         card_type = TGA_TYPE_T8_02;
491                                         gfbc->name = "T8-02";
492                                 }
493                         } else if(addrmask == GDER_ADDR_8MB) {
494
495                                 /* 8MB core map; T8-22 */
496                                 if(cs) {/* sanity */
497                                         card_type = TGA_TYPE_T8_22;
498                                         gfbc->name = "T8-22";
499                                 }
500                         } else if(addrmask == GDER_ADDR_16MB) {
501
502                                 /* 16MB core map; T8-44 */
503                                 if(cs) {/* sanity */
504                                         card_type = TGA_TYPE_T8_44;
505                                         gfbc->name = "T8-44";
506                                 }
507                         } else if(addrmask == GDER_ADDR_32MB) {
508
509                                 /* 32MB core map; ??? */
510                                 card_type = TGA_TYPE_UNKNOWN;
511                         }
512                 } else {
513
514                         /* 32bpp frame buffer */
515                         gfbc->ramdac_name = "BT463";
516                         gfbc->ramdac_init = bt463_init;
517                         gfbc->ramdac_rd = tga_bt463_rd;
518                         gfbc->ramdac_wr = tga_bt463_wr;
519                         gfbc->builtin_save_palette = tga_builtin_save_palette;
520                         gfbc->builtin_load_palette = tga_builtin_load_palette;
521                         gfbc->ramdac_save_cursor_palette =
522                             bt463_save_cursor_palette;
523                         gfbc->ramdac_load_cursor_palette =
524                             bt463_load_cursor_palette;
525                         gfbc->builtin_read_hw_cursor =
526                             tga_builtin_read_hw_cursor;
527                         gfbc->builtin_set_hw_cursor = tga_builtin_set_hw_cursor;
528                         gfbc->builtin_set_hw_cursor_shape =
529                             tga_builtin_set_hw_cursor_shape;
530
531                         /* 32bpp frame buffer */
532                         if(addrmask == GDER_ADDR_4MB) {
533
534                                 /* 4MB core map; ??? */
535                                 card_type = TGA_TYPE_UNKNOWN;
536                         } else if(addrmask == GDER_ADDR_8MB) {
537
538                                 /* 8MB core map; ??? */
539                                 card_type = TGA_TYPE_UNKNOWN;
540                         } else if(addrmask == GDER_ADDR_16MB) {
541
542                                 /* 16MB core map; T32-04 or T32-08 */
543                                 if(!cs) {
544                                         card_type = TGA_TYPE_T32_04;
545                                         gfbc->name = "T32-04";
546                                 } else {
547                                         card_type = TGA_TYPE_T32_08;
548                                         gfbc->name = "T32-08";
549                                 }
550                         } else if(addrmask == GDER_ADDR_32MB) {
551
552                                 /* 32MB core map; T32-88 */
553                                 if(cs) {/* sanity */
554                                         card_type = TGA_TYPE_T32_88;
555                                         gfbc->name = "T32-88";
556                                 }
557                         }
558                 }
559         }
560         else if(adp->va_type == KD_TGA2) {
561                 gfbc->ramdac_name = "IBM561";
562                 gfbc->ramdac_init = ibm561_init;
563                 gfbc->ramdac_rd = tga2_ibm561_rd;
564                 gfbc->ramdac_wr = tga2_ibm561_wr;
565                 gfbc->ramdac_save_palette = ibm561_save_palette;
566                 gfbc->ramdac_load_palette = ibm561_load_palette;
567                 gfbc->ramdac_save_cursor_palette = ibm561_save_cursor_palette;
568                 gfbc->ramdac_load_cursor_palette = ibm561_load_cursor_palette;
569                 gfbc->builtin_read_hw_cursor = tga_builtin_read_hw_cursor;
570                 gfbc->builtin_set_hw_cursor = tga_builtin_set_hw_cursor;
571                 gfbc->builtin_set_hw_cursor_shape =
572                     tga_builtin_set_hw_cursor_shape;
573
574                 /* 4MB core map */
575                 if(addrmask == GDER_ADDR_4MB)
576                         card_type = TGA_TYPE_UNKNOWN;
577
578                 /* 8MB core map */
579                 else if(addrmask == GDER_ADDR_8MB) {
580                         card_type = TGA2_TYPE_3D30;
581                         gfbc->name = "3D30";
582                 }
583
584                 /* 16MB core map */
585                 else if(addrmask == GDER_ADDR_16MB) {
586                         card_type = TGA2_TYPE_4D20;
587                         gfbc->name = "4D20";
588                 }
589                 else if(addrmask == GDER_ADDR_32MB)
590                         card_type = TGA_TYPE_UNKNOWN;
591         }
592
593         /*
594           For now, just return for TGA2 cards (i.e.,
595           allow syscons to treat this device as a normal
596           VGA device, and don't do anything TGA2-specific,
597           e.g., only use the TGA2 card in VGA mode for now
598           as opposed to 2DA mode...
599         */
600         if(adp->va_type == KD_TGA2)
601                 return(error);
602
603         /* If we couldn't identify the card, err-out... */
604         if(card_type == TGA_TYPE_UNKNOWN) {
605                 printf("tga%d: Unknown TGA type\n", unit);
606                 error = ENODEV;
607                 goto done;
608         } 
609
610         /* Clear and disable interrupts... */
611         WRITE_GFB_REGISTER(adp, TGA_REG_SISR, 0x00000001);
612
613         /* Perform TGA2-specific initialization, if necessary... */
614         if(adp->va_type == KD_TGA2) {
615                 monitor = (~READ_GFB_REGISTER(adp, TGA_REG_GREV) >> 16 ) & 0x0f;
616                 tga2_init(sc, monitor);
617         }
618 done:
619         return(error);
620 }
621
622 static void
623 tga2_init(sc, monitor)
624         struct gfb_softc *sc;
625         int monitor;
626 {
627         return;
628         tga2_ics9110_wr(sc, decmonitors[monitor].dotclock);
629         WRITE_GFB_REGISTER(sc->adp, TGA_REG_VHCR,
630             ((decmonitors[monitor].hbp / 4) << VHCR_BPORCH_SHIFT) |
631             ((decmonitors[monitor].hsync / 4) << VHCR_HSYNC_SHIFT) |
632             (((decmonitors[monitor].hfp) / 4) << VHCR_FPORCH_SHIFT) |
633             ((decmonitors[monitor].cols) / 4));
634         WRITE_GFB_REGISTER(sc->adp, TGA_REG_VVCR,
635             (decmonitors[monitor].vbp << VVCR_BPORCH_SHIFT) |
636             (decmonitors[monitor].vsync << VVCR_VSYNC_SHIFT) |
637             (decmonitors[monitor].vfp << VVCR_FPORCH_SHIFT) |
638             (decmonitors[monitor].rows));
639         WRITE_GFB_REGISTER(sc->adp, TGA_REG_VVBR, 1);
640         GFB_REGISTER_READWRITE_BARRIER(sc, TGA_REG_VHCR, 3);
641         WRITE_GFB_REGISTER(sc->adp, TGA_REG_VVVR,
642             READ_GFB_REGISTER(sc->adp, TGA_REG_VVVR) | 1);
643         GFB_REGISTER_READWRITE_BARRIER(sc, TGA_REG_VVVR, 1);
644         WRITE_GFB_REGISTER(sc->adp, TGA_REG_GPMR, 0xffffffff);
645         GFB_REGISTER_READWRITE_BARRIER(sc, TGA_REG_GPMR, 1);
646 }
647
648 static int
649 tga_query_mode(video_adapter_t *adp, video_info_t *info)
650 {
651         int error;
652
653         /* Assume the best... */
654         error = 0;
655
656         /* Verify that this mode is supported on this adapter... */
657         if(adp->va_type == KD_TGA2) {
658                 if((info->vi_mode != TGA2_2DA_MODE) &&
659                     (info->vi_mode != TGA2_VGA_MODE))
660                         error = ENODEV;
661         }
662         else {
663                 if(info->vi_mode != 0)
664                         error = ENODEV;
665         }
666         return(error);
667 }
668
669 static int
670 tga_set_mode(video_adapter_t *adp, int mode)
671 {
672         int error;
673         gfb_reg_t gder;
674         gfb_reg_t vgae_mask;
675
676         /* Assume the best... */
677         error = 0;
678         
679         gder = READ_GFB_REGISTER(adp, TGA_REG_GDER);
680
681         /*
682            Determine the adapter type first
683            so we know which modes are valid for it...
684         */
685         switch(adp->va_type) {
686         case KD_TGA2:
687
688                 /*
689                    Verify that this mode is supported
690                    on this adapter...
691                 */
692                 switch(mode) {
693                 case TGA2_2DA_MODE:
694                         vgae_mask = ~0x00400000;
695                         WRITE_GFB_REGISTER(adp, TGA_REG_GDER,
696                             gder & vgae_mask);
697                         adp->va_mode = mode;
698                         break;
699                 case TGA2_VGA_MODE:
700                         vgae_mask = 0x00400000;
701                         WRITE_GFB_REGISTER(adp, TGA_REG_GDER,
702                             gder | vgae_mask);
703                         adp->va_mode = mode;
704                         break;
705                 default:
706                         error = ENODEV;
707                 }
708                 break;
709         case KD_TGA:
710
711                 /*
712                    Verify that this mode is supported
713                    on this adapter...
714                 */
715                 switch(mode) {
716                 case 0:
717                         break;
718                 default:
719                         error = ENXIO;
720                 }
721                 break;
722         default:
723                 error = ENODEV;
724         }
725         return(error);
726 }
727
728 static int
729 tga_blank_display(video_adapter_t *adp, int mode)
730 {
731         gfb_reg_t blanked;
732         int error;
733
734         /* Assume the best... */
735         error = 0;
736
737         blanked = READ_GFB_REGISTER(adp, TGA_REG_VVVR) &
738             (VVR_BLANK | VVR_VIDEOVALID | VVR_CURSOR);
739
740         /* If we're not already blanked, then blank...*/
741         switch(mode) {
742         case V_DISPLAY_BLANK:
743                 if(blanked != (VVR_VIDEOVALID | VVR_BLANK)) {
744                         blanked = VVR_VIDEOVALID | VVR_BLANK;
745                         WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, blanked);
746                 }
747                 break;
748         case V_DISPLAY_STAND_BY:
749                 if(blanked != VVR_BLANK) {
750                         blanked = VVR_BLANK;
751                         WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, blanked);
752                 }
753                 break;
754         case V_DISPLAY_ON:
755                 if(blanked != (VVR_VIDEOVALID | VVR_CURSOR)) {
756                         blanked = VVR_VIDEOVALID | VVR_CURSOR;
757                         WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, blanked);
758                 }
759                 break;
760         default:
761                 break;
762         }
763         return(0);
764 }
765
766 #if 0
767
768 static int
769 tga_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
770 {
771         struct gfb_softc *sc;
772         int error;
773
774         error = 0;
775         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
776         switch (cmd) {
777         case FBIOPUTCMAP:
778 #if 0
779                 tga_schedule_intr(sc, bt463_load_palette_intr);
780                 break;
781 #endif
782         case FBIO_GETWINORG:
783         case FBIO_SETWINORG:
784         case FBIO_SETDISPSTART:
785         case FBIO_SETLINEWIDTH:
786         case FBIO_GETPALETTE:
787         case FBIOGTYPE:
788         case FBIOGETCMAP:
789         default:
790                 error = fb_commonioctl(adp, cmd, arg); 
791         }
792         return(error);
793 }
794
795 #endif /* 0 */
796
797 static int
798 tga_set_border(video_adapter_t *adp, int color) {
799         return(ENODEV);
800 }
801
802 static int
803 tga_set_win_org(video_adapter_t *adp, off_t offset) {
804         gfb_reg_t vvbr;
805         u_int16_t window_orig;
806         int gder;
807         int deep;
808         int cs;
809
810         /* Get the adapter's parameters... */
811         gder = BASIC_READ_TGA_REGISTER(adp, TGA_REG_GDER);
812         deep = (gder & 0x1) != 0;
813         cs = (gder & 0x200) == 0;
814
815         /*
816            Set the window (framebuffer) origin according to the video
817            base address...
818         */
819         window_orig = offset / ((1 + cs) * (1 + deep) * (1 + deep) * 2 KB);
820         adp->va_window_orig = window_orig * ((1 + cs) * (1 + deep) *
821             (1 + deep) * 2 KB);
822
823         /* Set the video base address... */
824         vvbr = READ_GFB_REGISTER(adp, TGA_REG_VVBR);
825         vvbr = (vvbr & 0xfffffe00) | window_orig;
826         WRITE_GFB_REGISTER(adp, TGA_REG_VVBR, vvbr);
827         return(0);
828 }
829
830 static int
831 tga_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) {
832         int off;
833         gfb_reg_t gpxr;
834         gfb_reg_t gmor;
835         gfb_reg_t gbcr0;
836         gfb_reg_t gbcr1;
837         gfb_reg_t color;
838
839         /* Save the pixel mode... */
840         gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
841
842         /* Save the pixel mask... */
843         gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
844
845         /* Save the block-color... */
846         gbcr0 = READ_GFB_REGISTER(adp, TGA_REG_GBCR0);
847         gbcr1 = READ_GFB_REGISTER(adp, TGA_REG_GBCR1);
848
849         /* Set the pixel mode (block-fill)... */
850         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
851                            (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_BLK_FILL);
852
853         /* Set the pixel mask (enable writes to all pixels)... */
854         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, 0xffffffff);
855
856         color = ((val & 0xff00) << 24) || ((val & 0xff00) << 16) ||
857             ((val & 0xff00) << 8) || ((val & 0xff00) << 0);
858
859         /* Set the color for the block-fill... */
860         WRITE_GFB_REGISTER(adp, TGA_REG_GBCR0, color);
861         WRITE_GFB_REGISTER(adp, TGA_REG_GBCR1, color);
862
863         /*
864            Just traverse the buffer, one 2K-pixel span at a time, setting
865            each pixel to the bolck-color...
866         */
867         for(off = (x * y); off < ((x + cx) * (y + cy)); off += (2 KB))
868                 WRITE_GFB_BUFFER(adp, off >> 2L, 0x000007ff);
869
870         /* Restore the pixel mode... */
871         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
872
873         /* Restore the pixel mask... */
874         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
875
876         /* Restore the block-color... */
877         WRITE_GFB_REGISTER(adp, TGA_REG_GBCR0, gbcr0);
878         WRITE_GFB_REGISTER(adp, TGA_REG_GBCR1, gbcr1);
879
880         return(0);
881 }
882
883 static int
884 tga_bitblt(video_adapter_t *adp, ...) {
885         va_list args;
886         int i, count;
887         gfb_reg_t gmor;
888         gfb_reg_t gopr;
889         vm_offset_t src, dst;
890
891         va_start(args, adp);
892
893         /* Save the pixel mode... */
894         gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
895
896         /* Save the raster op... */
897         gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
898
899         /* Set the pixel mode (copy)... */
900         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
901             (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_COPY);
902
903         /* Set the raster op (src)... */
904         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x3);
905
906         src = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
907             0x0000000000fffff8;
908         dst = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
909             0x0000000000fffff8;
910         count = va_arg(args, int);
911         for(i = 0; i < count; i+= 64, src += 64, dst += 64) {
912                 WRITE_GFB_REGISTER(adp, TGA_REG_GCSR, src);
913                 WRITE_GFB_REGISTER(adp, TGA_REG_GCDR, dst);
914         }
915
916         /* Restore the raster op... */
917         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
918
919         /* Restore the pixel mode... */
920         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
921
922         va_end(args);
923         return(0);
924 }
925
926 static int
927 #if 0
928 tga_clear(video_adapter_t *adp, int n)
929 #else
930 tga_clear(video_adapter_t *adp)
931 #endif
932 {
933         int off;
934         gfb_reg_t gpxr;
935         gfb_reg_t gmor;
936         gfb_reg_t gopr;
937
938 #if 0
939         if(n == 0) return(0);
940 #endif
941
942         /* Save the pixel mode... */
943         gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
944
945         /* Save the pixel mask... */
946         gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
947
948         /* Save the raster op... */
949         gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
950
951         /* Set the pixel mode (opaque-fill)... */
952         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
953                            (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_OPQ_FILL);
954
955         /* Set the pixel mask (enable writes to all pixels)... */
956         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, 0xffffffff);
957
958         /* Set the raster op (clear)... */
959         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x00);
960
961         /*
962            Just traverse the buffer, one 2K-pixel span at a time, clearing
963            each pixel...
964         */
965 #if 0
966         for(off = 0; off < (n * adp->va_line_width); off += (2 KB))
967 #endif
968         for(off = 0; off < adp->va_window_size; off += (2 KB))
969                 WRITE_GFB_BUFFER(adp, off >> 2L, 0x000007ff);
970
971         /* Restore the pixel mask... */
972         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
973
974         /* Restore the raster op... */
975         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
976
977         /* Restore the pixel mode... */
978         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
979
980         return(0);
981 }
982
983 int
984 tga_putc(video_adapter_t *adp, vm_offset_t off, u_int8_t c, u_int8_t a)
985 {
986         int i;
987         gfb_reg_t gpxr;
988         gfb_reg_t gmor;
989         gfb_reg_t gopr;
990         gfb_reg_t gbgr;
991         gfb_reg_t gfgr;
992         gfb_reg_t mask;
993         int row, col;
994         u_int8_t *pixel;
995         vm_offset_t poff;
996         struct gfb_softc *sc;
997         int pixel_size;
998
999         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1000         pixel_size = adp->va_info.vi_depth / 8;
1001
1002         /* Save the pixel mode... */
1003         gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
1004
1005         /* Save the pixel mask... */
1006         gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
1007
1008         /* Save the raster op... */
1009         gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
1010
1011         /* Save the background color... */
1012         gbgr = READ_GFB_REGISTER(adp, TGA_REG_GBGR);
1013
1014         /* Save the foreground color... */
1015         gfgr = READ_GFB_REGISTER(adp, TGA_REG_GFGR);
1016
1017         /* Set the pixel mode (opaque-stipple)... */
1018         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
1019             (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_OPQ_STPL);
1020
1021         /* Set the pixel mask (enable writes to the first cwidth pixels)... */
1022         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P,
1023             (1 << adp->va_info.vi_cwidth) - 1);
1024
1025         /* Set the raster op (src)... */
1026         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x3);
1027
1028         /* Set the foreground color mask from the attribute byte... */
1029         mask = (a & 0x80) ? a : (a & 0x0f);
1030
1031         /* Propagate the 8-bit mask across the full 32 bits... */
1032         mask |= (mask << 24) | (mask << 16) | (mask << 8);
1033
1034         /* Set the foreground color... */
1035         WRITE_GFB_REGISTER(adp, TGA_REG_GFGR, mask);
1036
1037         /* Set the background color mask from the attribute byte... */
1038         mask = (a >> 4) & 0x07;
1039
1040         /* Propagate the 8-bit mask across the full 32 bits... */
1041         mask |= (mask << 24) | (mask << 16) | (mask << 8);
1042
1043         /* Set the background color... */
1044         WRITE_GFB_REGISTER(adp, TGA_REG_GBGR, mask);
1045
1046         /* Get the start of the array of pixels rows for this character... */
1047         pixel = sc->gfbc->font + (c * adp->va_info.vi_cheight);
1048
1049         /* Calculate the new cursor position... */
1050         row = off / adp->va_info.vi_width;
1051         col = off % adp->va_info.vi_width;
1052
1053         /* Iterate over all the pixel rows for this character... */
1054         for(i = 0; i < adp->va_info.vi_cheight; i++) {
1055
1056                 /* Get the address of the character's pixel-row... */
1057                 poff = ((col * adp->va_info.vi_cwidth * pixel_size) +
1058                     (((row * adp->va_info.vi_cheight) + i) *
1059                     adp->va_line_width)) / sizeof(gfb_reg_t);
1060
1061                 /* Now display the current pixel row... */
1062                 WRITE_GFB_BUFFER(adp, poff, pixel[i]);
1063         }
1064
1065         /* Restore the foreground color... */
1066         WRITE_GFB_REGISTER(adp, TGA_REG_GFGR, gfgr);
1067
1068         /* Restore the background color... */
1069         WRITE_GFB_REGISTER(adp, TGA_REG_GBGR, gbgr);
1070
1071         /* Restore the pixel mode... */
1072         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
1073
1074         /* Restore the pixel mask... */
1075         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
1076
1077         /* Restore the raster op... */
1078         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
1079
1080         return(0);
1081 }
1082
1083 int
1084 tga_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
1085 {
1086         int i, j, k;
1087         gfb_reg_t gpxr;
1088         gfb_reg_t gmor;
1089         gfb_reg_t gopr;
1090         gfb_reg_t row, col;
1091         u_int8_t *pixel;
1092         u_int8_t c;
1093         u_int8_t a;
1094         gfb_reg_t p;
1095         vm_offset_t poff;
1096         struct gfb_softc *sc;
1097         int pixel_size;
1098
1099         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1100         pixel_size = adp->va_info.vi_depth / 8;
1101
1102         /* If the string in empty, just return now... */
1103         if(len == 0) return(0);
1104
1105         for(i = 0; i < len; i++)
1106                 tga_putc(adp, off + i, s[i] & 0x00ff, (s[i] & 0xff00) >> 8);
1107         return(0);
1108
1109         /* Save the pixel mode... */
1110         gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
1111
1112         /* Save the pixel mask... */
1113         gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
1114
1115         /* Save the raster op... */
1116         gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
1117
1118         /* Set the pixel mode (simple)... */
1119         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, (gmor & 0xffffffc0) | 0x00);
1120
1121         /* Set the pixel mask (enable writes to all 32 pixels)... */
1122         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, (gpxr & 0xfffffff0) | 0xf);
1123
1124         /* Set the raster op (src)... */
1125         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x03);
1126
1127         /*
1128            First, do as many characters-rows at a time as possible (as exist)...
1129         */
1130         for(i = 0; (len - i) > adp->va_info.vi_width;
1131             i += adp->va_info.vi_width) {
1132
1133                 /*
1134                    Iterate over all the pixels for each character in the
1135                    character-row, doing a scan-line at-a-time, rather than
1136                    a character at-a-time (like tga_putc())...
1137                 */
1138                 for(j = 0; j < adp->va_info.vi_cheight; j++) {
1139                         p = 0;
1140                         for(k = 0; k < adp->va_info.vi_width; k++) {
1141
1142                                 /*
1143                                    Get this character...
1144                                 */
1145                                 c = s[i + k] & 0x00ff;
1146
1147                                 /*
1148                                    Get the attribute for this character...
1149                                 */
1150                                 a = (s[i + k] & 0xff00) >> 8;
1151
1152                                 /*
1153                                    Get the start of the array of pixels rows for
1154                                    this character...
1155                                 */
1156                                 pixel = sc->gfbc->font +
1157                                         (c * adp->va_info.vi_cheight);
1158
1159                                 /* Shift the other pre-existing pixel rows... */
1160                                 p <<= 8;
1161
1162                                 /*
1163                                    Get the first pixel row for
1164                                    this character...
1165                                 */
1166                                 p |= pixel[j];
1167
1168                                 if (((k + 1) % sizeof(gfb_reg_t)) == 0) {
1169
1170                                         /*
1171                                            Calculate the new cursor
1172                                            position...
1173                                         */
1174                                         row = (off + i + (k -
1175                                             (sizeof(gfb_reg_t) - 1))) /
1176                                             adp->va_info.vi_width;
1177                                         col = (off + i + (k -
1178                                             (sizeof(gfb_reg_t) - 1))) %
1179                                             adp->va_info.vi_width;
1180
1181                                         /*
1182                                            Get the address of the current
1183                                            character's pixel-row...
1184                                         */
1185                                         poff = ((col * adp->va_info.vi_cwidth * 
1186                                             pixel_size) + (((row *
1187                                             adp->va_info.vi_cheight) + j) *
1188                                             adp->va_line_width)) /
1189                                             sizeof(gfb_reg_t);
1190
1191                                         /*
1192                                            Now display the current
1193                                            pixel row...
1194                                         */
1195                                         (*vidsw[adp->va_index]->putp)(adp, poff,
1196                                             p, a, sizeof(gfb_reg_t),
1197                                             adp->va_info.vi_depth, 1, 0);
1198
1199                                         /* Reset (clear) p... */
1200                                         p = 0;
1201                                 }
1202                         }
1203                 }
1204         }
1205
1206         /*
1207            Next, do as many character-sets at a time as possible (as exist)...
1208         */
1209         for(; (len - i) > sizeof(gfb_reg_t); i += sizeof(gfb_reg_t)) {
1210
1211                 /*
1212                    Iterate over all the pixels for each character in the
1213                    character-row, doing a scan-line at-a-time, rather than
1214                    a character at-a-time (like tga_putc())...
1215                 */
1216                 for(j = 0; j < adp->va_info.vi_cheight; j++) {
1217                         p = 0;
1218                         for(k = 0; k < sizeof(gfb_reg_t); k++) {
1219
1220                                 /*
1221                                    Get this character...
1222                                 */
1223                                 c = s[i + k] & 0x00ff;
1224
1225                                 /*
1226                                    Get the attribute for this character...
1227                                 */
1228                                 a = (s[i + k] & 0xff00) >> 8;
1229
1230                                 /*
1231                                    Get the start of the array of pixels rows for
1232                                    this character...
1233                                 */
1234                                 pixel = sc->gfbc->font +
1235                                     (c * adp->va_info.vi_cheight);
1236
1237                                 /* Shift the other pre-existing pixel rows... */
1238                                 p <<= 8;
1239
1240                                 /*
1241                                    Get the first pixel row for
1242                                    this character...
1243                                 */
1244                                 p |= pixel[j];
1245
1246                                 if (((k + 1) % sizeof(gfb_reg_t)) == 0) {
1247
1248                                         /*
1249                                            Calculate the new cursor
1250                                            position...
1251                                         */
1252                                         row = (off + i) / adp->va_info.vi_width;
1253                                         col = (off + i) % adp->va_info.vi_width;
1254
1255                                         /*
1256                                            Get the address of the current
1257                                            character's pixel-row...
1258                                         */
1259                                         poff = ((col * adp->va_info.vi_cwidth * 
1260                                             pixel_size) + (((row *
1261                                             adp->va_info.vi_cheight) + j) *
1262                                             adp->va_line_width)) /
1263                                             sizeof(gfb_reg_t);
1264
1265                                         /*
1266                                            Now display the current
1267                                            pixel row...
1268                                         */
1269                                         (*vidsw[adp->va_index]->putp)(adp, poff,
1270                                             p, a, sizeof(gfb_reg_t),
1271                                             adp->va_info.vi_depth, 1, 0);
1272
1273                                         /* Reset (clear) p... */
1274                                         p = 0;
1275                                 }
1276                         }
1277                 }
1278         }
1279
1280         /* Restore the pixel mode... */
1281         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
1282
1283         /* Restore the pixel mask... */
1284         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
1285
1286         /* Restore the raster op... */
1287         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
1288
1289         /* Finally, do the remaining characters a character at-a-time... */
1290         for(; i < len; i++) {
1291                 /*
1292                    Get this character...
1293                 */
1294                 c = s[i] & 0x00ff;
1295
1296                 /*
1297                    Get the attribute for this character...
1298                 */
1299                 a = (s[i] & 0xff00) >> 8;
1300
1301                 /*
1302                    Display this character...
1303                 */
1304                 tga_putc(adp, off + i, c, a);
1305         }
1306         return(0);
1307 }
1308
1309 int
1310 tga_putm(video_adapter_t *adp, int x, int y, u_int8_t *pixel_image,
1311             gfb_reg_t pixel_mask, int size)
1312 {
1313         gfb_reg_t gpxr;
1314         gfb_reg_t gmor;
1315         gfb_reg_t gopr;
1316         int i, pixel_size;
1317         vm_offset_t poff;
1318
1319         pixel_size = adp->va_info.vi_depth / 8;
1320
1321         /* Save the pixel mode... */
1322         gmor = READ_GFB_REGISTER(adp, TGA_REG_GMOR);
1323
1324         /* Save the pixel mask... */
1325         gpxr = READ_GFB_REGISTER(adp, TGA_REG_GPXR_P);
1326
1327         /* Save the raster op... */
1328         gopr = READ_GFB_REGISTER(adp, TGA_REG_GOPR);
1329
1330         /* Set the pixel mode (simple)... */
1331         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR,
1332             (gmor & ~GMOR_MODE_MASK) | GMOR_MODE_SIMPLE);
1333
1334         /* Set the pixel mask (enable writes to the first 8 pixels)... */
1335         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, (gpxr & 0xfffffff0) | 0xf);
1336
1337         /* Set the raster op (src)... */
1338         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, (gopr & 0xfffffff0) | 0x3);
1339
1340         /* Iterate over all the pixel rows for the mouse pointer... */
1341         for(i = 0; i < size; i++) {
1342
1343                 /* Get the address of the mouse pointer's pixel-row... */
1344                 poff = ((x * pixel_size) + ((y + i) * adp->va_line_width)) /
1345                     sizeof(gfb_reg_t);
1346
1347                 /* Now display the current pixel-row... */
1348                 (*vidsw[adp->va_index]->putp)(adp, poff, pixel_image[i],
1349                     pixel_mask, sizeof(u_int8_t), adp->va_info.vi_depth, 1, 0);
1350         }
1351
1352         /* Restore the pixel mode... */
1353         WRITE_GFB_REGISTER(adp, TGA_REG_GPXR_P, gpxr);
1354
1355         /* Restore the pixel mask... */
1356         WRITE_GFB_REGISTER(adp, TGA_REG_GMOR, gmor);
1357
1358         /* Restore the raster op... */
1359         WRITE_GFB_REGISTER(adp, TGA_REG_GOPR, gopr);
1360
1361         return(0);
1362 }
1363
1364 static int
1365 tga_error(void)
1366 {
1367         return(0);
1368 }
1369
1370 /*****************************************************************************
1371  *
1372  * TGA-specific functions
1373  *
1374  ****************************************************************************/
1375
1376 static int
1377 tga_builtin_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
1378 {
1379         int i;
1380         int error;
1381         struct gfb_softc *sc;
1382
1383         error = 0;
1384         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1385
1386         /*
1387          * We store 8 bit values in the palette buffer, while the standard
1388          * VGA has 6 bit DAC .
1389          */
1390         outb(PALRADR, 0x00);
1391         for(i = 0; i < palette->count; ++i) {
1392                 palette->red[i] = inb(PALDATA) << 2;
1393                 palette->green[i] = inb(PALDATA) << 2;
1394                 palette->blue[i] = inb(PALDATA) << 2;
1395         }
1396         return(error);
1397 }
1398
1399 static int
1400 tga_builtin_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
1401 {
1402         int i;
1403         int error;
1404         struct gfb_softc *sc;
1405
1406         error = 0;
1407         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1408
1409         /*
1410          * We store 8 bit values in the palette buffer, while the standard
1411          * VGA has 6 bit DAC .
1412         */
1413         outb(PIXMASK, 0xff);
1414         outb(PALWADR, 0x00);
1415         for(i = 0; i < palette->count; ++i) {
1416                 outb(PALDATA, palette->red[i] >> 2);
1417                 outb(PALDATA, palette->green[i] >> 2);
1418                 outb(PALDATA, palette->blue[i] >> 2);
1419         }
1420         return(error);
1421 }
1422
1423 #ifdef TGA2
1424 static int
1425 tga2_builtin_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
1426 {
1427         int i;
1428         int error;
1429         struct gfb_softc *sc;
1430
1431         error = 0;
1432         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1433
1434         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1435             BT463_IREG_CPALETTE_RAM & 0xff);
1436         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1437             (BT463_IREG_CPALETTE_RAM >> 8) & 0xff);
1438
1439         /* spit out the colormap data */
1440         for(i = 0; i < palette->count; i++) {
1441                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA,
1442                     palette->red[i]);
1443                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, 
1444                     palette->green[i]);
1445                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, 
1446                     palette->blue[i]);
1447         }
1448         return(error);
1449 }
1450
1451 static int
1452 tga2_builtin_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
1453 {
1454         int i;
1455         int error;
1456         struct gfb_softc *sc;
1457
1458         error = 0;
1459         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1460
1461         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1462             BT463_IREG_CPALETTE_RAM & 0xff);
1463         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1464             (BT463_IREG_CPALETTE_RAM >> 8) & 0xff);
1465
1466         /* spit out the colormap data */
1467         for(i = 0; i < palette->count; i++) {
1468                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA,
1469                     palette->red[i]);
1470                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, 
1471                     palette->green[i]);
1472                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, 
1473                     palette->blue[i]);
1474         }
1475         return(error);
1476 }
1477
1478 static int
1479 tga2_builtin_save_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
1480 {
1481         int i;
1482         int error;
1483         struct gfb_softc *sc;
1484
1485         error = 0;
1486         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1487
1488         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1489             BT463_IREG_CURSOR_COLOR_0 & 0xff);
1490         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1491             (BT463_IREG_CURSOR_COLOR_0 >> 8) & 0xff);
1492
1493         /* spit out the cursor data */
1494         for(i = 0; i < palette->count; i++) {
1495                 BTWNREG(sc, palette->red[i]);
1496                 BTWNREG(sc, palette->green[i]);
1497                 BTWNREG(sc, palette->blue[i]);
1498         }
1499         return(error);
1500 }
1501
1502 static int
1503 tga2_builtin_load_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
1504 {
1505         int i;
1506         int error;
1507         struct gfb_softc *sc;
1508
1509         error = 0;
1510         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1511
1512         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1513             BT463_IREG_CURSOR_COLOR_0 & 0xff);
1514         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1515             (BT463_IREG_CURSOR_COLOR_0 >> 8) & 0xff);
1516
1517         /* spit out the cursor data */
1518         for(i = 0; i < palette->count; i++) {
1519                 BTWNREG(sc, palette->red[i]);
1520                 BTWNREG(sc, palette->green[i]);
1521                 BTWNREG(sc, palette->blue[i]);
1522         }
1523         return(error);
1524 }
1525
1526 #endif /* TGA2 */
1527
1528 static int
1529 tga_builtin_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
1530 {
1531         gfb_reg_t cxyr;
1532         int error;
1533
1534         /* Assume the best... */
1535         error = 0;
1536
1537         cxyr = READ_GFB_REGISTER(adp, TGA_REG_CXYR) | 0x00ffffff;
1538         *col = (cxyr & 0x00000fff) / adp->va_info.vi_cwidth;
1539         *row = ((cxyr & 0x00fff000) >> 12) / adp->va_info.vi_cheight;
1540         return(error);
1541 }
1542
1543 static int
1544 tga_builtin_set_hw_cursor(video_adapter_t *adp, int col, int row)
1545 {
1546         int error;
1547         gfb_reg_t cxyr;
1548         gfb_reg_t vvvr;
1549
1550         /* Assume the best... */
1551         error = 0;
1552
1553         vvvr = READ_GFB_REGISTER(adp, TGA_REG_VVVR);
1554
1555         /*
1556            Make sure the parameters are in range for the screen
1557            size...
1558         */
1559         if((row > adp->va_info.vi_height) ||
1560             (col > adp->va_info.vi_width))
1561                 error = EINVAL;
1562         else if(((row * adp->va_info.vi_cheight) > 0x0fff) ||
1563             ((col * adp->va_info.vi_cwidth) > 0x0fff))
1564                 error = EINVAL;
1565         /*
1566            If either of the parameters is less than 0,
1567            then hide the cursor...
1568         */
1569         else if((row < 0) || (col < 0)) {
1570                 if((vvvr & 0x00000004) != 0) {
1571                         vvvr &= 0xfffffffb;
1572                         WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, vvvr);
1573                 }
1574         }
1575                 
1576         /* Otherwise, just move the cursor as requested... */
1577         else {
1578                 cxyr = READ_GFB_REGISTER(adp, TGA_REG_CXYR) & 0xff000000;
1579                 cxyr |= ((row * adp->va_info.vi_cheight) << 12);
1580                 cxyr |= (col * adp->va_info.vi_cwidth);
1581                 WRITE_GFB_REGISTER(adp, TGA_REG_CXYR, cxyr);
1582                 if((vvvr & 0x00000004) == 0) {
1583                         vvvr |= 0x00000004;
1584                 WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, vvvr);
1585                 }
1586         }
1587         return(error);
1588 }
1589
1590 static int
1591 tga_builtin_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
1592             int cellsize, int blink)
1593 {
1594         int i, j;
1595         vm_offset_t cba;
1596         gfb_reg_t window_orig;
1597         gfb_reg_t ccbr;
1598         gfb_reg_t vvvr;
1599         int error;
1600
1601         /* Assume the best... */
1602         error = 0;
1603
1604         vvvr = READ_GFB_REGISTER(adp, TGA_REG_VVVR);
1605
1606         /*
1607            Make sure the parameters are in range for the cursor
1608            (it's a 64x64 cursor)...
1609         */
1610         if(height > 64)
1611                 error = EINVAL;
1612
1613         /* If height is less than or equal to 0, then hide the cursor... */
1614         else if(height <= 0) {
1615                 if((vvvr & 0x00000004) != 0) {
1616                         vvvr &= 0xfffffffb;
1617                         WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, vvvr);
1618                 }
1619         }
1620
1621         /* Otherwise, just resize the cursor as requested... */
1622         else {
1623                 ccbr = READ_GFB_REGISTER(adp, TGA_REG_CCBR);
1624                 ccbr &= 0xffff03ff;
1625                 ccbr |= ((height - 1) << 10);
1626                 WRITE_GFB_REGISTER(adp, TGA_REG_CCBR, ccbr);
1627                 if((vvvr & 0x00000004) == 0) {
1628                         vvvr |= 0x00000004;
1629                         WRITE_GFB_REGISTER(adp, TGA_REG_VVVR, vvvr);
1630                 }
1631
1632                 /* Save the window origin... */
1633                 window_orig = adp->va_window_orig;
1634
1635                 /*
1636                    Fill in the cursor image (64 rows of 64 pixels per cursor
1637                    row at 2 bits-per-pixel, so 64 rows of 16 bytes each)--we
1638                    set va_window_orig to the cursor base address temporarily
1639                    so that we can write to the cursor image...
1640                 */
1641                 cba = (READ_GFB_REGISTER(adp, TGA_REG_CCBR) & 0xfffffc0f) >> 4;
1642                 adp->va_window_orig = cba;
1643                 for(i = 0; i < (64 - height); i++) {
1644                         WRITE_GFB_BUFFER(adp, cba++, 0x00000000);
1645                         WRITE_GFB_BUFFER(adp, cba++, 0x00000000);
1646                 }
1647                 for(; i < 64; i++) {
1648                         for(j = 0; j < (((64 - cellsize) / 8) /
1649                             sizeof(gfb_reg_t)); j++)
1650                                 WRITE_GFB_BUFFER(adp, cba++, 0x00000000);
1651                         for(; j < ((64 / 8) / sizeof(gfb_reg_t)); j++)
1652                                 WRITE_GFB_BUFFER(adp, cba++, 0xffffffff);
1653                 }
1654
1655                 /* Restore the window origin... */
1656                 adp->va_window_orig = window_orig;
1657
1658         }
1659         return(error);
1660 }
1661
1662 static void
1663 bt463_load_palette_intr(struct gfb_softc *sc)
1664 {
1665         sc->gfbc->ramdac_save_palette(sc->adp, &sc->gfbc->palette);
1666 }
1667
1668 static void
1669 bt463_load_cursor_palette_intr(struct gfb_softc *sc)
1670 {
1671         sc->gfbc->ramdac_load_cursor_palette(sc->adp, &sc->gfbc->cursor_palette);
1672 }
1673
1674 static int
1675 tga_schedule_intr(struct gfb_softc *sc, void (*f)(struct gfb_softc *))
1676 {
1677         /* Busy-wait for the previous interrupt to complete... */
1678         while((READ_GFB_REGISTER(sc->adp, TGA_REG_SISR) & 0x00000001) != 0);
1679
1680         /* Arrange for f to be called at the next end-of-frame interrupt... */
1681         sc->gfbc->ramdac_intr = f;
1682
1683         /* Enable the interrupt... */
1684         WRITE_GFB_REGISTER(sc->adp, TGA_REG_SISR, 0x00010000);
1685         return(0);
1686 }
1687
1688 static u_int8_t
1689 tga_bt485_rd(struct gfb_softc *sc, u_int btreg)
1690 {
1691         gfb_reg_t rdval;
1692
1693         if(btreg > BT485_REG_MAX)
1694                 panic("tga_ramdac_rd: reg %d out of range\n", btreg);
1695         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPSR, (btreg << 1) | 0x1);
1696         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPSR, 1);
1697         rdval = READ_GFB_REGISTER(sc->adp, TGA_REG_EPDR);
1698         return((rdval >> 16) & 0xff);
1699 }
1700
1701 static void
1702 tga_bt485_wr(struct gfb_softc *sc, u_int btreg, u_int8_t val)
1703 {
1704         if(btreg > BT485_REG_MAX)
1705                 panic("tga_ramdac_wr: reg %d out of range\n", btreg);
1706         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPDR,
1707             (btreg << 9) | (0 << 8 ) | val);
1708         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPDR, 1);
1709 }
1710
1711 static u_int8_t
1712 tga2_ibm561_rd(struct gfb_softc *sc, u_int btreg)
1713 {
1714         bus_space_handle_t ramdac;
1715         u_int8_t retval;
1716
1717         if(btreg > BT485_REG_MAX)
1718                 panic("tga_ramdac_rd: reg %d out of range\n", btreg);
1719         ramdac = sc->bhandle + TGA2_MEM_RAMDAC + (0xe << 12) + (btreg << 8);
1720         retval = bus_space_read_4(sc->btag, ramdac, 0) & 0xff;
1721         bus_space_barrier(sc->btag, ramdac, 0, 4, BUS_SPACE_BARRIER_READ);
1722         return(retval);
1723 }
1724
1725 static void
1726 tga2_ibm561_wr(struct gfb_softc *sc, u_int btreg, u_int8_t val)
1727 {
1728         bus_space_handle_t ramdac;
1729
1730         if(btreg > BT485_REG_MAX)
1731                 panic("tga_ramdac_wr: reg %d out of range\n", btreg);
1732         ramdac = sc->bhandle + TGA2_MEM_RAMDAC + (0xe << 12) + (btreg << 8);
1733         bus_space_write_4(sc->btag, ramdac, 0, val & 0xff);
1734         bus_space_barrier(sc->btag, ramdac, 0, 4, BUS_SPACE_BARRIER_WRITE);
1735 }
1736
1737 static u_int8_t
1738 tga_bt463_rd(struct gfb_softc *sc, u_int btreg)
1739 {
1740         gfb_reg_t rdval;
1741
1742         /* 
1743          * Strobe CE# (high->low->high) since status and data are latched on 
1744          * the falling and rising edges (repsectively) of this active-low
1745          * signal.
1746          */
1747         
1748         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPSR, 1);
1749         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
1750         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPSR, 1);
1751         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPSR, (btreg << 2) | 2 | 0);
1752         GFB_REGISTER_READ_BARRIER(sc, TGA_REG_EPSR, 1);
1753         rdval = READ_GFB_REGISTER(sc->adp, TGA_REG_EPDR);
1754         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPSR, 1);
1755         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPSR, (btreg << 2) | 2 | 1);
1756         return((rdval >> 16) & 0xff);
1757 }
1758
1759 static void
1760 tga_bt463_wr(struct gfb_softc *sc, u_int btreg, u_int8_t val)
1761 {
1762         /* 
1763          * In spite of the 21030 documentation, to set the MPU bus bits for
1764          * a write, you set them in the upper bits of EPDR, not EPSR.
1765          */
1766         
1767         /* 
1768          * Strobe CE# (high->low->high) since status and data are latched on
1769          * the falling and rising edges of this active-low signal.
1770          */
1771
1772         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPDR, 1);
1773         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
1774         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPDR, 1);
1775         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPDR, (btreg << 10) | 0x000 | val);
1776         GFB_REGISTER_WRITE_BARRIER(sc, TGA_REG_EPDR, 1);
1777         WRITE_GFB_REGISTER(sc->adp, TGA_REG_EPDR, (btreg << 10) | 0x100 | val);
1778 }
1779
1780 static void
1781 tga2_ics9110_wr(struct gfb_softc *sc, int dotclock)
1782 {
1783         bus_space_handle_t clock;
1784         gfb_reg_t valU;
1785         int N, M, R, V, X;
1786         int i;
1787
1788         switch(dotclock) {
1789         case 130808000:
1790                 N = 0x40; M = 0x7; V = 0x0; X = 0x1; R = 0x1; break;
1791         case 119840000:
1792                 N = 0x2d; M = 0x2b; V = 0x1; X = 0x1; R = 0x1; break;
1793         case 108180000:
1794                 N = 0x11; M = 0x9; V = 0x1; X = 0x1; R = 0x2; break;
1795         case 103994000:
1796                 N = 0x6d; M = 0xf; V = 0x0; X = 0x1; R = 0x1; break;
1797         case 175000000:
1798                 N = 0x5F; M = 0x3E; V = 0x1; X = 0x1; R = 0x1; break;
1799         case  75000000:
1800                 N = 0x6e; M = 0x15; V = 0x0; X = 0x1; R = 0x1; break;
1801         case  74000000:
1802                 N = 0x2a; M = 0x41; V = 0x1; X = 0x1; R = 0x1; break;
1803         case  69000000:
1804                 N = 0x35; M = 0xb; V = 0x0; X = 0x1; R = 0x1; break;
1805         case  65000000:
1806                 N = 0x6d; M = 0x0c; V = 0x0; X = 0x1; R = 0x2; break;
1807         case  50000000:
1808                 N = 0x37; M = 0x3f; V = 0x1; X = 0x1; R = 0x2; break;
1809         case  40000000:
1810                 N = 0x5f; M = 0x11; V = 0x0; X = 0x1; R = 0x2; break;
1811         case  31500000:
1812                 N = 0x16; M = 0x05; V = 0x0; X = 0x1; R = 0x2; break;
1813         case  25175000:
1814                 N = 0x66; M = 0x1d; V = 0x0; X = 0x1; R = 0x2; break;
1815         case 135000000:
1816                 N = 0x42; M = 0x07; V = 0x0; X = 0x1; R = 0x1; break;
1817         case 110000000:
1818                 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
1819         case 202500000:
1820                 N = 0x60; M = 0x32; V = 0x1; X = 0x1; R = 0x2; break;
1821         default:
1822                 panic("unrecognized clock rate %d\n", dotclock);
1823         }
1824
1825         /* XXX -- hard coded, bad */
1826         valU  = N | ( M << 7 ) | (V << 14);
1827         valU |= (X << 15) | (R << 17);
1828         valU |= 0x17 << 19;
1829         clock = sc->bhandle + TGA2_MEM_EXTDEV + TGA2_MEM_CLOCK + (0xe << 12);
1830         for(i = 24; i > 0; i--) {
1831                 gfb_reg_t       writeval;
1832                 
1833                 writeval = valU & 0x1;
1834                 if (i == 1)  
1835                         writeval |= 0x2; 
1836                 valU >>= 1;
1837                 bus_space_write_4(sc->btag, clock, 0, writeval);
1838                 bus_space_barrier(sc->btag, clock, 0, 4,
1839                     BUS_SPACE_BARRIER_WRITE);
1840         }       
1841         clock = sc->bhandle + TGA2_MEM_EXTDEV + TGA2_MEM_CLOCK + (0xe << 12) +
1842             (0x1 << 11) + (0x1 << 11);
1843         bus_space_write_4(sc->btag, clock, 0, 0x0);
1844         bus_space_barrier(sc->btag, clock, 0, 0, BUS_SPACE_BARRIER_WRITE);
1845 }
1846
1847 /*****************************************************************************
1848  *
1849  * BrookTree RAMDAC-specific functions
1850  *
1851  ****************************************************************************/
1852
1853 static void
1854 bt463_init(struct gfb_softc *sc)
1855 {
1856         int i;
1857
1858         return;
1859
1860         /*
1861          * Init the BT463 for normal operation.
1862          */
1863
1864         /*
1865          * Setup:
1866          * reg 0: 4:1 multiplexing, 25/75 blink.
1867          * reg 1: Overlay mapping: mapped to common palette, 
1868          *        14 window type entries, 24-plane configuration mode,
1869          *        4 overlay planes, underlays disabled, no cursor. 
1870          * reg 2: sync-on-green enabled, pedestal enabled.
1871          */
1872
1873         BTWREG(sc, BT463_IREG_COMMAND_0, 0x40);
1874         BTWREG(sc, BT463_IREG_COMMAND_1, 0x48);
1875         BTWREG(sc, BT463_IREG_COMMAND_2, 0xC0);
1876
1877         /*
1878          * Initialize the read mask.
1879          */
1880         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1881             BT463_IREG_READ_MASK_P0_P7 & 0xff);
1882         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1883             (BT463_IREG_READ_MASK_P0_P7 >> 8) & 0xff);
1884         for(i = 0; i < 4; i++)
1885                 BTWNREG(sc, 0xff);
1886
1887         /*
1888          * Initialize the blink mask.
1889          */
1890         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1891             BT463_IREG_READ_MASK_P0_P7 & 0xff);
1892         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1893             (BT463_IREG_READ_MASK_P0_P7 >> 8) & 0xff);
1894         for(i = 0; i < 4; i++)
1895                 BTWNREG(sc, 0);
1896
1897         /*
1898          * Clear test register
1899          */
1900         BTWREG(sc, BT463_IREG_TEST, 0);
1901
1902         /*
1903          * Initalize the RAMDAC info struct to hold all of our
1904          * data, and fill it in.
1905          */
1906
1907         /* Initialize the window type table:
1908          *
1909          * Entry 0: 24-plane truecolor, overlays enabled, bypassed.
1910          *
1911          *  Lookup table bypass:      yes (    1 << 23 & 0x800000)  800000
1912          *  Colormap address:       0x000 (0x000 << 17 & 0x7e0000)       0 
1913          *  Overlay mask:             0xf (  0xf << 13 & 0x01e000)   1e000
1914          *  Overlay location:    P<27:24> (    0 << 12 & 0x001000)       0
1915          *  Display mode:       Truecolor (    0 <<  9 & 0x000e00)     000
1916          *  Number of planes:           8 (    8 <<  5 & 0x0001e0)     100
1917          *  Plane shift:                0 (    0 <<  0 & 0x00001f)       0
1918          *                                                        --------
1919          *                                                        0x81e100
1920          */       
1921 #if 0
1922         data->window_type[0] = 0x81e100;
1923 #endif
1924
1925         /* Entry 1: 8-plane pseudocolor in the bottom 8 bits, 
1926          *          overlays enabled, colormap starting at 0. 
1927          *
1928          *  Lookup table bypass:       no (    0 << 23 & 0x800000)       0
1929          *  Colormap address:       0x000 (0x000 << 17 & 0x7e0000)       0 
1930          *  Overlay mask:             0xf (  0xf << 13 & 0x01e000) 0x1e000
1931          *  Overlay location:    P<27:24> (    0 << 12 & 0x001000)       0
1932          *  Display mode:     Pseudocolor (    1 <<  9 & 0x000e00)   0x200
1933          *  Number of planes:           8 (    8 <<  5 & 0x0001e0)   0x100
1934          *  Plane shift:               16 ( 0x10 <<  0 & 0x00001f)      10
1935          *                                                        --------
1936          *                                                        0x01e310
1937          */       
1938 #if 0
1939         data->window_type[1] = 0x01e310;
1940 #endif
1941         /* The colormap interface to the world only supports one colormap, 
1942          * so having an entry for the 'alternate' colormap in the bt463 
1943          * probably isn't useful.
1944          */
1945
1946         /* Fill the remaining table entries with clones of entry 0 until we 
1947          * figure out a better use for them.
1948          */
1949 #if 0
1950         for(i = 2; i < BT463_NWTYPE_ENTRIES; i++) {
1951                 data->window_type[i] = 0x81e100;
1952         }
1953 #endif
1954
1955         tga_schedule_intr(sc, bt463_update_window_type);
1956         tga_schedule_intr(sc, bt463_load_cursor_palette_intr);
1957         tga_schedule_intr(sc, bt463_load_palette_intr);
1958 }
1959
1960 static void
1961 bt463_update_window_type(struct gfb_softc *sc)
1962 {
1963         int i;
1964
1965         /* The Bt463 won't accept window type data except during a blanking
1966          * interval, so we do this early in the interrupt.
1967          * Blanking the screen might also be a good idea, but it can cause 
1968          * unpleasant flashing and is hard to do from this side of the
1969          * ramdac interface.
1970          */
1971         /* spit out the window type data */
1972         for(i = 0; i < BT463_NWTYPE_ENTRIES; i++) {
1973 #if 0
1974                 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1975                     (BT463_IREG_WINDOW_TYPE_TABLE + i) & 0xff);
1976                 sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1977                     ((BT463_IREG_WINDOW_TYPE_TABLE + i) >> 8) & 0xff);
1978                 BTWNREG(sc, (data->window_type[i]) & 0xff);
1979                 BTWNREG(sc, (data->window_type[i] >> 8) & 0xff);
1980                 BTWNREG(sc, (data->window_type[i] >> 16) & 0xff);
1981 #endif
1982         }
1983 }
1984
1985 #if 0
1986 static int
1987 bt463_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
1988 {
1989         struct gfb_softc *sc;
1990         int error, i;
1991
1992         error = 0;
1993         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
1994
1995         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
1996             BT463_IREG_CPALETTE_RAM & 0xff);
1997         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
1998             (BT463_IREG_CPALETTE_RAM >> 8) & 0xff);
1999
2000         /* get the colormap data */
2001         for(i = 0; i < palette->count; i++) {
2002                 palette->red[i] = sc->gfbc->ramdac_rd(sc, BT463_REG_CMAP_DATA);
2003                 palette->green[i] = sc->gfbc->ramdac_rd(sc,
2004                     BT463_REG_CMAP_DATA);
2005                 palette->blue[i] = sc->gfbc->ramdac_rd(sc, BT463_REG_CMAP_DATA);
2006         }
2007         return(error);
2008 }
2009
2010 static int
2011 bt463_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
2012 {
2013         struct gfb_softc *sc;
2014         int error, i;
2015
2016         error = 0;
2017         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2018
2019         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
2020             BT463_IREG_CPALETTE_RAM & 0xff);
2021         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
2022             (BT463_IREG_CPALETTE_RAM >> 8) & 0xff);
2023
2024         /* spit out the colormap data */
2025         for(i = 0; i < palette->count; i++) {
2026                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, palette->red[i]);
2027                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, palette->green[i]);
2028                 sc->gfbc->ramdac_wr(sc, BT463_REG_CMAP_DATA, palette->blue[i]);
2029         }
2030         return(error);
2031 }
2032
2033 #endif /* 0 */
2034
2035 static int
2036 bt463_save_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2037 {
2038         struct gfb_softc *sc;
2039         int error, i;
2040
2041         error = 0;
2042         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2043
2044         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
2045             BT463_IREG_CURSOR_COLOR_0 & 0xff);
2046         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
2047             (BT463_IREG_CURSOR_COLOR_0 >> 8) & 0xff);
2048
2049         /* spit out the cursor data */
2050         for(i = 0; i < palette->count; i++) {
2051                 palette->red[i] = BTRNREG(sc);
2052                 palette->green[i] = BTRNREG(sc);
2053                 palette->blue[i] = BTRNREG(sc);
2054         }
2055         return(error);
2056 }
2057
2058 static int
2059 bt463_load_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2060 {
2061         struct gfb_softc *sc;
2062         int error, i;
2063
2064         error = 0;
2065         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2066
2067         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_LOW,
2068             BT463_IREG_CURSOR_COLOR_0 & 0xff);
2069         sc->gfbc->ramdac_wr(sc, BT463_REG_ADDR_HIGH,
2070             (BT463_IREG_CURSOR_COLOR_0 >> 8) & 0xff);
2071
2072         /* spit out the cursor data */
2073         for(i = 0; i < palette->count; i++) {
2074                 BTWNREG(sc, palette->red[i]);
2075                 BTWNREG(sc, palette->green[i]);
2076                 BTWNREG(sc, palette->blue[i]);
2077         }
2078         return(error);
2079 }
2080
2081 static void
2082 bt485_init(struct gfb_softc *sc)
2083 {
2084         int i, j, num_cmap_entries;
2085         u_int8_t regval;
2086
2087         regval = sc->gfbc->ramdac_rd(sc, BT485_REG_COMMAND_0);
2088
2089         /*
2090          * Set the RAMDAC to 8 bit resolution, rather than 6 bit
2091          * resolution.
2092          */
2093         regval |= 0x02;
2094
2095         /*
2096          * Set the RAMDAC to sync-on-green.
2097          */
2098         regval |= 0x08;
2099         sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_0, regval);
2100
2101 #if 0
2102         /* Set the RAMDAC to 8BPP (no interesting options). */
2103         sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_1, 0x40);
2104
2105         /* Disable the cursor (for now) */
2106         regval = sc->gfbc->ramdac_rd(sc, BT485_REG_COMMAND_2);
2107         regval &= ~0x03;
2108         regval |= 0x24;
2109         sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_2, regval);
2110
2111         /* Use a 64x64x2 cursor */
2112         sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, BT485_IREG_COMMAND_3);
2113         regval = sc->gfbc->ramdac_rd(sc, BT485_REG_EXTENDED);
2114         regval |= 0x04;
2115         regval |= 0x08;
2116         sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, BT485_IREG_COMMAND_3);
2117         sc->gfbc->ramdac_wr(sc, BT485_REG_EXTENDED, regval);
2118
2119         /* Set the Pixel Mask to something useful */
2120         sc->gfbc->ramdac_wr(sc, BT485_REG_PIXMASK, 0xff);
2121 #endif
2122
2123         /* Generate the cursor color map (Light-Grey)... */
2124         for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
2125                 sc->gfbc->cursor_palette.red[i] = default_cmap[7].red;
2126                 sc->gfbc->cursor_palette.green[i] = default_cmap[7].green;
2127                 sc->gfbc->cursor_palette.blue[i] = default_cmap[7].blue;
2128         }
2129
2130 #if 0
2131         /* Enable cursor... */
2132         regval = sc->gfbc->ramdac_rd(sc, BT485_REG_COMMAND_2);
2133         if(!(regval & 0x01)) {
2134                 regval |= 0x01;
2135                 sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_2, regval);
2136         }
2137         else if(regval & 0x03) {
2138                 regval &= ~0x03;
2139                 sc->gfbc->ramdac_wr(sc, BT485_REG_COMMAND_2, regval);
2140         }
2141 #endif
2142
2143         /* Generate the screen color map... */
2144         num_cmap_entries = sizeof(default_cmap) / sizeof(struct cmap);
2145         for(i = 0; i < sc->gfbc->palette.count / num_cmap_entries; i++)
2146                 for(j = 0; j < num_cmap_entries; j++) {
2147                         sc->gfbc->palette.red[(num_cmap_entries * i) + j] =
2148                             default_cmap[j].red;
2149                         sc->gfbc->palette.green[(num_cmap_entries * i) + j] =
2150                             default_cmap[j].green;
2151                         sc->gfbc->palette.blue[(num_cmap_entries * i) + j] =
2152                             default_cmap[j].blue;
2153                 }
2154 }
2155
2156 static int
2157 bt485_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
2158 {
2159         struct gfb_softc *sc;
2160         int error, i;
2161
2162         error = 0;
2163         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2164
2165         /* addr[9:0] assumed to be 0 */
2166         /* set addr[7:0] to 0 */
2167         sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, 0x00);
2168
2169         /* spit out the color data */
2170         for(i = 0; i < palette->count; i++) {
2171                 palette->red[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_PALETTE);
2172                 palette->green[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_PALETTE);
2173                 palette->blue[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_PALETTE);
2174         }
2175         return(error);
2176 }
2177
2178 static int
2179 bt485_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
2180 {
2181         struct gfb_softc *sc;
2182         int error, i;
2183
2184         error = 0;
2185         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2186
2187         /* addr[9:0] assumed to be 0 */
2188         /* set addr[7:0] to 0 */
2189         sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, 0x00);
2190
2191         /* spit out the color data */
2192         for(i = 0; i < palette->count; i++) {
2193                 sc->gfbc->ramdac_wr(sc, BT485_REG_PALETTE, palette->red[i]);
2194                 sc->gfbc->ramdac_wr(sc, BT485_REG_PALETTE, palette->green[i]);
2195                 sc->gfbc->ramdac_wr(sc, BT485_REG_PALETTE, palette->blue[i]);
2196         }
2197         return(error);
2198 }
2199
2200 static int
2201 bt485_save_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2202 {
2203         struct gfb_softc *sc;
2204         int error, i;
2205
2206         error = 0;
2207         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2208
2209         /* addr[9:0] assumed to be 0 */
2210         /* set addr[7:0] to 1 */
2211         sc->gfbc->ramdac_wr(sc, BT485_REG_COC_WRADDR, 0x01);
2212
2213         /* spit out the cursor color data */
2214         for(i = 0; i < palette->count; i++) {
2215                 palette->red[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_COCDATA);
2216                 palette->green[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_COCDATA);
2217                 palette->blue[i] = sc->gfbc->ramdac_rd(sc, BT485_REG_COCDATA);
2218         }
2219         return(error);
2220 }
2221
2222 static int
2223 bt485_load_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2224 {
2225         struct gfb_softc *sc;
2226         int error, i;
2227
2228         error = 0;
2229         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2230
2231         /* addr[9:0] assumed to be 0 */
2232         /* set addr[7:0] to 1 */
2233         sc->gfbc->ramdac_wr(sc, BT485_REG_COC_WRADDR, 0x01);
2234
2235         /* spit out the cursor color data */
2236         for(i = 0; i < palette->count; i++) {
2237                 sc->gfbc->ramdac_wr(sc, BT485_REG_COCDATA, palette->red[i]);
2238                 sc->gfbc->ramdac_wr(sc, BT485_REG_COCDATA, palette->green[i]);
2239                 sc->gfbc->ramdac_wr(sc, BT485_REG_COCDATA, palette->blue[i]);
2240         }
2241         return(error);
2242 }
2243
2244 static int
2245 bt485_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
2246 {
2247         struct gfb_softc *sc;
2248         int error, s;
2249
2250         error = 0;
2251         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2252         s = spltty();
2253         *col = (sc->gfbc->ramdac_rd(sc, BT485_REG_CURSOR_X_HIGH) & 0x0f) << 8;
2254         *col |= sc->gfbc->ramdac_rd(sc, BT485_REG_CURSOR_X_LOW) & 0xff;
2255         *col /= adp->va_info.vi_cwidth;
2256         *col -= 8;
2257         *row = (sc->gfbc->ramdac_rd(sc, BT485_REG_CURSOR_Y_HIGH) & 0x0f) << 8;
2258         *row |= sc->gfbc->ramdac_rd(sc, BT485_REG_CURSOR_Y_LOW) & 0xff;
2259         *row /= adp->va_info.vi_cheight;
2260         *row -= 4;
2261         splx(s);
2262         return(error);
2263 }
2264
2265 static int
2266 bt485_set_hw_cursor(video_adapter_t *adp, int col, int row)
2267 {
2268         struct gfb_softc *sc;
2269         int error, s;
2270
2271         error = 0;
2272
2273         /* Make sure the parameters are in range for the screen
2274            size... */
2275         if((row > adp->va_info.vi_height) || (col > adp->va_info.vi_width))
2276                 error = EINVAL;
2277         else if(((row * adp->va_info.vi_cheight) > 0x0fff) ||
2278             ((col * adp->va_info.vi_cwidth) > 0x0fff))
2279                 error = EINVAL;
2280         else if((row < 0) || (col < 0)) {
2281                 /* If either of the parameters is less than 0, then hide the
2282                    cursor... */
2283                 col = -8;
2284                 row = -4;
2285         } else {
2286                 /* Otherwise, just move the cursor as requested... */
2287                 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2288                 s = spltty();
2289                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_X_LOW,
2290                     ((col + 8) * adp->va_info.vi_cwidth) & 0xff);
2291                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_X_HIGH,
2292                     (((col + 8) * adp->va_info.vi_cwidth) >> 8) & 0x0f);
2293                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_Y_LOW,
2294                     ((row + 4) * adp->va_info.vi_cheight) & 0xff);
2295                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_Y_HIGH,
2296                     (((row + 4) * adp->va_info.vi_cheight) >> 8) & 0x0f);
2297                 splx(s);
2298         }
2299         return(error);
2300 }
2301
2302 static int
2303 bt485_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
2304     int cellsize, int blink)
2305 {
2306         struct gfb_softc *sc;
2307         int error, cell_count, count, i, j;
2308         u_int8_t regval;
2309
2310         error = 0;
2311         cellsize /= 2;
2312         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
2313
2314         /*
2315            Make sure the parameters are in range for the cursor
2316            (it's a 64x64 cursor)...
2317         */
2318         if(height > 64)
2319                 error = EINVAL;
2320         else if(height <= 0) {
2321                 /* If height is less than or equal to 0, then hide the
2322                    cursor... */
2323         } else {
2324                 /* Otherwise, just resize the cursor as requested... */
2325
2326                 /* 64 pixels per cursor-row, 2 bits-per-pixel, so counts in
2327                    bytes... */
2328                 cell_count = cellsize / 8;
2329                 count = 64 / 8;
2330         
2331                  /* 
2332                   * Write the cursor image data:
2333                   *     set addr[9:8] to 0,
2334                   *     set addr[7:0] to 0,
2335                   *     spit it all out.
2336                   */
2337                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2338                     BT485_IREG_COMMAND_3);
2339                 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_EXTENDED);
2340                 regval &= ~0x03;
2341                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2342                     BT485_IREG_COMMAND_3);
2343                 sc->gfbc->ramdac_wr(sc, BT485_REG_EXTENDED, regval);
2344                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, 0);
2345
2346                 /* Fill-in the desired pixels in the specified pixel-rows... */
2347                 for(i = 0; i < height; i++) {
2348                         for(j = 0; j < cell_count; j++)
2349                                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2350                                     0xff);
2351                         for(j = 0; j < count - cell_count; j++)
2352                                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2353                                     0x00);
2354                 }
2355
2356                 /* Clear the remaining pixel rows... */
2357                 for(; i < 64; i++)
2358                         for(j = 0; j < count; j++)
2359                                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2360                                     0x00);
2361
2362                 /*
2363                  * Write the cursor mask data:
2364                  *      set addr[9:8] to 2,
2365                  *      set addr[7:0] to 0,
2366                  *      spit it all out.
2367                  */
2368                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2369                     BT485_IREG_COMMAND_3);
2370                 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_EXTENDED);
2371                 regval &= ~0x03; regval |= 0x02;
2372                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2373                     BT485_IREG_COMMAND_3);
2374                 sc->gfbc->ramdac_wr(sc, BT485_REG_EXTENDED, regval);
2375                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR, 0);
2376
2377                 /* Fill-in the desired pixels in the specified pixel-rows... */
2378                 for(i = 0; i < height; i++) {
2379                         for(j = 0; j < cell_count; j++)
2380                                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2381                                     0xff);
2382                         for(j = 0; j < count - cell_count; j++)
2383                                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2384                                     0x00);
2385                 }
2386
2387                 /* Clear the remaining pixel rows... */
2388                 for(; i < 64; i++)
2389                         for(j = 0; j < count; j++)
2390                                 sc->gfbc->ramdac_wr(sc, BT485_REG_CURSOR_RAM,
2391                                     0x00);
2392
2393                 /* set addr[9:0] back to 0 */
2394                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2395                     BT485_IREG_COMMAND_3);
2396                 regval = sc->gfbc->ramdac_rd(sc, BT485_REG_EXTENDED);
2397                 regval &= ~0x03;
2398                 sc->gfbc->ramdac_wr(sc, BT485_REG_PCRAM_WRADDR,
2399                     BT485_IREG_COMMAND_3);
2400                 sc->gfbc->ramdac_wr(sc, BT485_REG_EXTENDED, regval);
2401         }
2402         return(error);
2403 }
2404
2405 static void
2406 ibm561_init(struct gfb_softc *sc)
2407 {
2408 }
2409
2410 static int
2411 ibm561_save_palette(video_adapter_t *adp, video_color_palette_t *palette)
2412 {
2413         int error;
2414
2415         error = 0;
2416         return(error);
2417 }
2418
2419 static int
2420 ibm561_load_palette(video_adapter_t *adp, video_color_palette_t *palette)
2421 {
2422         int error;
2423
2424         error = 0;
2425         return(error);
2426 }
2427
2428 static int
2429 ibm561_save_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2430 {
2431         int error;
2432
2433         error = 0;
2434         return(error);
2435 }
2436
2437 static int
2438 ibm561_load_cursor_palette(video_adapter_t *adp, struct fbcmap *palette)
2439 {
2440         int error;
2441
2442         error = 0;
2443         return(error);
2444 }
2445
2446 #undef MB
2447 #undef KB