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/pc/vgamga4xx.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 /*
    3  * Matrox G200, G400 and G450.
    4  * Written by Philippe Anel <xigh@free.fr>
    5  *
    6  *  2006-08-07 : Minor fix to allow the G200 cards to work fine. YDSTORG is now initialized.
    7  *             : Also support for 16 and 24 bit modes is added.
    8  *             : by Leonardo Valencia <leoval@anixcorp.com>
    9  */
   10 
   11 #include "u.h"
   12 #include "../port/lib.h"
   13 #include "mem.h"
   14 #include "dat.h"
   15 #include "fns.h"
   16 #include "io.h"
   17 #include "../port/error.h"
   18 
   19 #define Image IMAGE
   20 #include <draw.h>
   21 #include <memdraw.h>
   22 #include <cursor.h>
   23 #include "screen.h"
   24 
   25 enum {
   26         MATROX                  = 0x102B,
   27         MGA550                  = 0x2527,
   28         MGA4xx                  = 0x0525,
   29         MGA200                  = 0x0521,
   30 
   31         FCOL                    = 0x1c24,
   32         FXRIGHT                 = 0x1cac,       
   33         FXLEFT                  = 0x1ca8,
   34         YDST                    = 0x1c90,
   35         YLEN                    = 0x1c5c,
   36         DWGCTL                  = 0x1c00,
   37                 DWG_TRAP                = 0x04,
   38                 DWG_BITBLT              = 0x08,
   39                 DWG_ILOAD               = 0x09,
   40                 DWG_LINEAR              = 0x0080,
   41                 DWG_SOLID               = 0x0800,
   42                 DWG_ARZERO              = 0x1000,
   43                 DWG_SGNZERO             = 0x2000,
   44                 DWG_SHIFTZERO   = 0x4000,
   45                 DWG_REPLACE             = 0x000C0000,
   46                 DWG_BFCOL               = 0x04000000,
   47         SRCORG                  = 0x2cb4,
   48         PITCH                   = 0x1c8c,
   49         DSTORG                  = 0x2cb8,
   50         YDSTORG                 = 0x1c94,
   51         PLNWRT                  = 0x1c1c,
   52         ZORG                    = 0x1c0c,
   53         MACCESS                 = 0x1c04,
   54         STATUS                  = 0x1e14,
   55         FXBNDRY                 = 0x1C84,
   56         CXBNDRY                 = 0x1C80,
   57         YTOP                    = 0x1C98,
   58         YBOT                    = 0x1C9C,
   59         YDSTLEN                 = 0x1C88,
   60         AR0                             = 0x1C60,
   61         AR1                             = 0x1C64,
   62         AR2                             = 0x1C68,
   63         AR3                             = 0x1C6C,
   64         AR4                             = 0x1C70,
   65         AR5                             = 0x1C74,
   66         SGN                             = 0x1C58,
   67                 SGN_LEFT                = 1,
   68                 SGN_UP                  = 4,
   69 
   70         GO                              = 0x0100,
   71         FIFOSTATUS              = 0x1E10,
   72         CACHEFLUSH              = 0x1FFF,
   73 
   74         CRTCEXTIDX              = 0x1FDE,               /* CRTC Extension Index */
   75         CRTCEXTDATA             = 0x1FDF,               /* CRTC Extension Data */
   76 
   77         FILL_OPERAND    = 0x800c7804,
   78 };
   79 
   80 static Pcidev *
   81 mgapcimatch(void)
   82 {
   83         Pcidev *p;
   84         
   85         p = pcimatch(nil, MATROX, MGA4xx);
   86         if(p == nil)
   87                 p = pcimatch(nil, MATROX, MGA550);
   88         if(p == nil)
   89                 p = pcimatch(nil, MATROX, MGA200);
   90         return p;
   91 }
   92 
   93 
   94 static void
   95 mgawrite8(VGAscr *scr, int index, uchar val)
   96 {
   97         ((uchar*)scr->mmio)[index] = val;
   98 }
   99 
  100 static uchar
  101 mgaread8(VGAscr *scr, int index)
  102 {
  103         return ((uchar*)scr->mmio)[index];
  104 }
  105 
  106 static uchar
  107 crtcextset(VGAscr *scr, int index, uchar set, uchar clr)
  108 {
  109         uchar tmp;
  110 
  111         mgawrite8(scr, CRTCEXTIDX, index);
  112         tmp = mgaread8(scr, CRTCEXTDATA);
  113         mgawrite8(scr, CRTCEXTIDX, index);
  114         mgawrite8(scr, CRTCEXTDATA, (tmp & ~clr) | set);
  115 
  116         return tmp;
  117 }
  118 
  119 static void
  120 mga4xxenable(VGAscr* scr)
  121 {
  122         Pcidev *pci;
  123         int size;
  124         int i, n, k;
  125         uchar *p;
  126         uchar x[16];
  127         uchar crtcext3;
  128 
  129         if(scr->mmio)
  130                 return;
  131 
  132         pci = mgapcimatch();
  133         if(pci == nil)
  134                 return;
  135 
  136         scr->mmio = vmap(pci->mem[1].bar&~0x0F, 16*1024);
  137         if(scr->mmio == nil)
  138                 return;
  139         
  140         addvgaseg("mga4xxmmio", pci->mem[1].bar&~0x0F, pci->mem[1].size);
  141 
  142         /* need to map frame buffer here too, so vga can find memory size */
  143         if(pci->did == MGA4xx || pci->did == MGA550)
  144                 size = 32*MB;
  145         else
  146                 size = 8*MB;
  147         vgalinearaddr(scr, pci->mem[0].bar&~0x0F, size);
  148 
  149         if(scr->paddr){
  150 
  151                 /* Find out how much memory is here, some multiple of 2 MB */
  152 
  153                 /* First Set MGA Mode ... */
  154                 crtcext3 = crtcextset(scr, 3, 0x80, 0x00);
  155 
  156                 p = scr->vaddr;
  157                 n = (size / MB) / 2;
  158                 for(i = 0; i < n; i++){
  159                         k = (2*i+1)*MB;
  160                         p[k] = 0;
  161                         p[k] = i+1;
  162                         *((uchar*)scr->mmio + CACHEFLUSH) = 0;
  163                         x[i] = p[k];
  164                 }
  165                 for(i = 1; i < n; i++)
  166                         if(x[i] != i+1)
  167                                 break;
  168                 scr->apsize = 2*i*MB;   /* sketchy */
  169                 addvgaseg("mga4xxscreen", scr->paddr, scr->apsize);
  170                 crtcextset(scr, 3, crtcext3, 0xff);
  171         }
  172 }
  173 
  174 enum{
  175         Index           = 0x00,         /* Index */
  176         Data                    = 0x0A,         /* Data */
  177 
  178         Cxlsb           = 0x0C,         /* Cursor X LSB */
  179         Cxmsb           = 0x0D,         /* Cursor X MSB */
  180         Cylsb           = 0x0E,         /* Cursor Y LSB */
  181         Cymsb           = 0x0F,         /* Cursor Y MSB */
  182 
  183         Icuradrl                = 0x04,         /* Cursor Base Address Low */   
  184         Icuradrh                = 0x05,         /* Cursor Base Address High */
  185         Icctl                   = 0x06,         /* Indirect Cursor Control */
  186 };
  187 
  188 static void
  189 dac4xxdisable(VGAscr *scr)
  190 {
  191         uchar *dac4xx;
  192         
  193         if(scr->mmio == 0)
  194                 return;
  195 
  196         dac4xx = (uchar*)scr->mmio+0x3C00;
  197         
  198         *(dac4xx+Index) = Icctl;
  199         *(dac4xx+Data) = 0x00;
  200 }
  201 
  202 static void
  203 dac4xxload(VGAscr *scr, Cursor *curs)
  204 {
  205         int y;
  206         uchar *p;
  207         uchar *dac4xx;
  208 
  209         if(scr->mmio == 0)
  210                 return;
  211 
  212         dac4xx = (uchar*)scr->mmio+0x3C00;
  213         
  214         dac4xxdisable(scr);
  215 
  216         p = (uchar*)scr->storage;
  217         for(y = 0; y < 64; y++){
  218                 *p++ = 0; *p++ = 0; *p++ = 0;
  219                 *p++ = 0; *p++ = 0; *p++ = 0;
  220                 if(y < 16){
  221                         *p++ = curs->set[1+y*2];
  222                         *p++ = curs->set[y*2];
  223                 } else{
  224                         *p++ = 0; *p++ = 0;
  225                 }
  226 
  227                 *p++ = 0; *p++ = 0; *p++ = 0;
  228                 *p++ = 0; *p++ = 0; *p++ = 0;
  229                 if(y < 16){
  230                         *p++ = curs->set[1+y*2]|curs->clr[1+2*y];
  231                         *p++ = curs->set[y*2]|curs->clr[2*y];
  232                 } else{
  233                         *p++ = 0; *p++ = 0;
  234                 }
  235         }
  236         scr->offset.x = 64 + curs->offset.x;
  237         scr->offset.y = 64 + curs->offset.y;
  238 
  239         *(dac4xx+Index) = Icctl;
  240         *(dac4xx+Data) = 0x03;
  241 }
  242 
  243 static int
  244 dac4xxmove(VGAscr *scr, Point p)
  245 {
  246         int x, y;
  247         uchar *dac4xx;
  248 
  249         if(scr->mmio == 0)
  250                 return 1;
  251 
  252         dac4xx = (uchar*)scr->mmio + 0x3C00;
  253 
  254         x = p.x + scr->offset.x;
  255         y = p.y + scr->offset.y;
  256 
  257         *(dac4xx+Cxlsb) = x & 0xFF;
  258         *(dac4xx+Cxmsb) = (x>>8) & 0x0F;
  259 
  260         *(dac4xx+Cylsb) = y & 0xFF;
  261         *(dac4xx+Cymsb) = (y>>8) & 0x0F;
  262 
  263         return 0;
  264 }
  265 
  266 static void
  267 dac4xxenable(VGAscr *scr)
  268 {
  269         uchar *dac4xx;
  270         ulong storage;
  271         
  272         if(scr->mmio == 0)
  273                 return;
  274         dac4xx = (uchar*)scr->mmio+0x3C00;
  275 
  276         dac4xxdisable(scr);
  277 
  278         storage = (scr->apsize-4096)&~0x3ff;
  279 
  280         *(dac4xx+Index) = Icuradrl;
  281         *(dac4xx+Data) = 0xff & (storage >> 10);
  282         *(dac4xx+Index) = Icuradrh;
  283         *(dac4xx+Data) = 0xff & (storage >> 18);                
  284 
  285         scr->storage = (ulong)scr->vaddr + storage;
  286 
  287         /* Show X11-Like Cursor */
  288         *(dac4xx+Index) = Icctl;
  289         *(dac4xx+Data) = 0x03;
  290 
  291         /* Cursor Color 0 : White */
  292         *(dac4xx+Index) = 0x08;
  293         *(dac4xx+Data)  = 0xff;
  294         *(dac4xx+Index) = 0x09;
  295         *(dac4xx+Data)  = 0xff;
  296         *(dac4xx+Index) = 0x0a;
  297         *(dac4xx+Data)  = 0xff;
  298 
  299         /* Cursor Color 1 : Black */
  300         *(dac4xx+Index) = 0x0c;
  301         *(dac4xx+Data)  = 0x00;
  302         *(dac4xx+Index) = 0x0d;
  303         *(dac4xx+Data)  = 0x00;
  304         *(dac4xx+Index) = 0x0e;
  305         *(dac4xx+Data)  = 0x00;
  306 
  307         /* Cursor Color 2 : Red */
  308         *(dac4xx+Index) = 0x10;
  309         *(dac4xx+Data)  = 0xff;
  310         *(dac4xx+Index) = 0x11;
  311         *(dac4xx+Data)  = 0x00;
  312         *(dac4xx+Index) = 0x12;
  313         *(dac4xx+Data)  = 0x00;
  314 
  315         /*
  316          * Load, locate and enable the
  317          * 64x64 cursor in X11 mode.
  318          */
  319         dac4xxload(scr, &arrow);
  320         dac4xxmove(scr, ZP);
  321 }
  322 
  323 static void
  324 mga4xxblank(VGAscr *scr, int blank)
  325 {
  326         char *cp;
  327         uchar *mga;
  328         uchar seq1, crtcext1;
  329         
  330         /* blank = 0 -> turn screen on */
  331         /* blank = 1 -> turn screen off */
  332 
  333         if(scr->mmio == 0)
  334                 return;
  335         mga = (uchar*)scr->mmio;        
  336 
  337         if(blank == 0){
  338                 seq1 = 0x00;
  339                 crtcext1 = 0x00;
  340         } else {
  341                 seq1 = 0x20;
  342                 crtcext1 = 0x10;                        /* Default value ... : standby */
  343                 cp = getconf("*dpms");
  344                 if(cp){
  345                         if(cistrcmp(cp, "standby") == 0)
  346                                 crtcext1 = 0x10;
  347                         else if(cistrcmp(cp, "suspend") == 0)
  348                                 crtcext1 = 0x20;
  349                         else if(cistrcmp(cp, "off") == 0)
  350                                 crtcext1 = 0x30;
  351                 }
  352         }
  353 
  354         *(mga + 0x1fc4) = 1;
  355         seq1 |= *(mga + 0x1fc5) & ~0x20;
  356         *(mga + 0x1fc5) = seq1;
  357 
  358         *(mga + 0x1fde) = 1;
  359         crtcext1 |= *(mga + 0x1fdf) & ~0x30;
  360         *(mga + 0x1fdf) = crtcext1;
  361 }
  362 
  363 static void
  364 mgawrite32(uchar *mga, ulong reg, ulong val)
  365 {
  366         *((ulong*)(&mga[reg])) = val;
  367 }
  368 
  369 static ulong
  370 mgaread32(uchar *mga, ulong reg)
  371 {
  372         return *((ulong*)(&mga[reg]));
  373 }
  374 
  375 static void
  376 mga_fifo(uchar *mga, uchar n)
  377 {
  378         ulong t;
  379 
  380 #define Timeout 100
  381         for (t = 0; t < Timeout; t++)
  382                 if ((mgaread32(mga, FIFOSTATUS) & 0xff) >= n)
  383                         break;
  384         if (t >= Timeout)
  385                 print("mga4xx: fifo timeout");
  386 }
  387 
  388 static int
  389 mga4xxfill(VGAscr *scr, Rectangle r, ulong color)
  390 {
  391         uchar *mga;
  392 
  393         if(scr->mmio == 0)
  394                 return 0;
  395         mga = (uchar*)scr->mmio;
  396 
  397         mga_fifo(mga, 7);
  398         mgawrite32(mga, DWGCTL, 0);
  399         mgawrite32(mga, FCOL, color);
  400         mgawrite32(mga, FXLEFT, r.min.x);
  401         mgawrite32(mga, FXRIGHT, r.max.x);
  402         mgawrite32(mga, YDST, r.min.y);
  403         mgawrite32(mga, YLEN, Dy(r));
  404         mgawrite32(mga, DWGCTL + GO, FILL_OPERAND);
  405 
  406         while(mgaread32(mga, STATUS) & 0x00010000)
  407                 ;
  408 
  409         return 1;
  410 }
  411 
  412 static int
  413 mga4xxscroll(VGAscr *scr, Rectangle dr, Rectangle sr)
  414 {
  415         uchar * mga;
  416         int pitch;
  417         int width, height;
  418         ulong start, end, sgn;
  419         Point sp, dp;
  420  
  421         if(scr->mmio == 0)
  422                 return 0;
  423         mga = (uchar*)scr->mmio;
  424 
  425         assert(Dx(sr) == Dx(dr) && Dy(sr) == Dy(dr));
  426 
  427         sp = sr.min;
  428         dp = dr.min;
  429         if(eqpt(sp, dp))
  430                 return 1;
  431 
  432         pitch = Dx(scr->gscreen->r);
  433         width = Dx(sr);
  434         height = Dy(sr);
  435         sgn = 0;
  436 
  437         if(dp.y > sp.y && dp.y < sp.y + height){
  438                 sp.y += height - 1;
  439                 dp.y += height - 1;
  440                 sgn |= SGN_UP;
  441         }
  442 
  443         width--;
  444         start = end = sp.x + (sp.y * pitch);
  445 
  446         if(dp.x > sp.x && dp.x < sp.x + width){
  447                 start += width;
  448                 sgn |= SGN_LEFT;
  449         }
  450         else
  451                 end += width;
  452 
  453         mga_fifo(mga, 8);
  454         mgawrite32(mga, DWGCTL, 0);
  455         mgawrite32(mga, SGN, sgn);
  456         mgawrite32(mga, AR5, sgn & SGN_UP ? -pitch : pitch);
  457         mgawrite32(mga, AR0, end);
  458         mgawrite32(mga, AR3, start);
  459         mgawrite32(mga, FXBNDRY, ((dp.x + width) << 16) | dp.x);
  460         mgawrite32(mga, YDSTLEN, (dp.y << 16) | height);
  461         mgawrite32(mga, DWGCTL + GO, DWG_BITBLT | DWG_SHIFTZERO | DWG_BFCOL | DWG_REPLACE);
  462 
  463         while(mgaread32(mga, STATUS) & 0x00010000)
  464                 ;
  465 
  466         return 1;
  467 }
  468 
  469 static void
  470 mga4xxdrawinit(VGAscr *scr)
  471 {
  472         uchar *mga;
  473 
  474         if(scr->mmio == 0)
  475                 return;
  476 
  477         mga = (uchar*)scr->mmio;
  478 
  479         mgawrite32(mga, SRCORG, 0);
  480         mgawrite32(mga, DSTORG, 0);
  481         mgawrite32(mga, YDSTORG, 0);
  482         mgawrite32(mga, ZORG, 0);
  483         mgawrite32(mga, PLNWRT, ~0);
  484         mgawrite32(mga, FCOL, 0xffff0000);
  485         mgawrite32(mga, CXBNDRY, 0xFFFF0000);
  486         mgawrite32(mga, YTOP, 0);
  487         mgawrite32(mga, YBOT, 0x01FFFFFF);
  488         mgawrite32(mga, PITCH, Dx(scr->gscreen->r) & ((1 << 13) - 1));
  489         switch(scr->gscreen->depth){
  490         case 8:
  491                 mgawrite32(mga, MACCESS, 0);
  492                 break;
  493         case 16:
  494                 mgawrite32(mga, MACCESS, 1);
  495                 break;
  496         case 24:
  497                 mgawrite32(mga, MACCESS, 3);
  498                 break;
  499         case 32:
  500                 mgawrite32(mga, MACCESS, 2);
  501                 break;
  502         default:
  503                 return;         /* depth not supported ! */
  504         }
  505         scr->fill = mga4xxfill;
  506         scr->scroll = mga4xxscroll;
  507         scr->blank = mga4xxblank;
  508 }
  509 
  510 VGAdev vgamga4xxdev = {
  511         "mga4xx",
  512         mga4xxenable,           /* enable */
  513         0,                                      /* disable */
  514         0,                                      /* page */
  515         0,                                      /* linear */
  516         mga4xxdrawinit,
  517 };
  518 
  519 VGAcur vgamga4xxcur = {
  520         "mga4xxhwgc",
  521         dac4xxenable,
  522         dac4xxdisable,
  523         dac4xxload,
  524         dac4xxmove,
  525 };

Cache object: 2395aa54ef613aac7d5369b2379e49c1


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