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