The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/fb/tga.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: e350c6271607de239b2042d7ec6b824f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.