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