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

Cache object: 26b58a1359ed9dc4f14edb0c28669882


[ 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.