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