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/vgasavage.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 #include "u.h"
    2 #include "../port/lib.h"
    3 #include "mem.h"
    4 #include "dat.h"
    5 #include "fns.h"
    6 #include "io.h"
    7 #include "../port/error.h"
    8 
    9 #define Image   IMAGE
   10 #include <draw.h>
   11 #include <memdraw.h>
   12 #include <cursor.h>
   13 #include "screen.h"
   14 
   15 enum {
   16         PCIS3           = 0x5333,               /* PCI VID */
   17 
   18         SAVAGE3D        = 0x8A20,       /* PCI DID */
   19         SAVAGE3DMV      = 0x8A21,
   20         SAVAGE4         = 0x8A22,
   21         PROSAVAGEP      = 0x8A25,
   22         PROSAVAGEK      = 0x8A26,
   23         PROSAVAGE8      = 0x8D04,
   24         SAVAGEMXMV      = 0x8C10,
   25         SAVAGEMX        = 0x8C11,
   26         SAVAGEIXMV      = 0x8C12,
   27         SAVAGEIX        = 0x8C13,
   28         SUPERSAVAGEIXC16 = 0x8C2E,
   29         SAVAGE2000      = 0x9102,
   30 
   31         VIRGE           = 0x5631,
   32         VIRGEGX2        = 0x8A10,
   33         VIRGEDXGX       = 0x8A01,
   34         VIRGEVX         = 0x883D,
   35         VIRGEMX         = 0x8C01,
   36         VIRGEMXP        = 0x8C03,
   37 
   38         AURORA64VPLUS   = 0x8812,
   39 };
   40 
   41 /*
   42  * Savage4 et al. acceleration.
   43  *
   44  * This is based only on the Savage4 documentation.
   45  * It is expected to work on other Savage cards as well,
   46  * but has not been tried.
   47  * 
   48  * There are five ways to access the 2D graphics engine registers:
   49  *      - Old MMIO non-packed format
   50  *      - Old MMIO packed format
   51  *      - New MMIO non-packed format
   52  *      - New MMIO packed format
   53  *      - Burst Command Interface (BCI)
   54  *
   55  * Of these, the manual hints that the first three are deprecated,
   56  * and it does not document any of those three well enough to use.
   57  * 
   58  * I have tried for many hours with no success to understand the BCI
   59  * interface well enough to use it.  It is not well documented, and the
   60  * XFree86 driver seems to completely contradict what little documentation
   61  * there is.
   62  *
   63  * This leaves the packed new MMIO.
   64  * The manual contradicts itself here, claming that the registers
   65  * start at 0x2008100 as well as at 0x0008100 from the base of the 
   66  * mmio segment.  Since the segment is only 512k, we assume that
   67  * the latter is the correct offset.
   68  *
   69  * According to the manual, only 16-bit reads of the 2D registers
   70  * are supported: 32-bit reads will return garbage in the upper word.
   71  * 32-bit writes must be enabled explicitly.
   72  * 
   73  * 32-bit reads of the status registers seem just fine.
   74  */
   75 
   76 /* 2D graphics engine registers for Savage4; others appear to be mostly the same */
   77 enum {
   78         SubsystemStatus = 0x8504,       /* Subsystem Status: read only */
   79           /* read only: whether we get interrupts on various events */
   80           VsyncInt              = 1<<0,         /* vertical sync */
   81           GeBusyInt             = 1<<1,         /* 2D graphics engine busy */
   82           BfifoFullInt  = 1<<2,         /* BIU FIFO full */
   83           BfifoEmptyInt = 1<<3,         /* BIU FIFO empty */
   84           CfifoFullInt  = 1<<4,         /* command FIFO full */
   85           CfifoEmptyInt = 1<<5,         /* command FIFO empty */
   86           BciInt                = 1<<6,         /* BCI */
   87           LpbInt                = 1<<7,         /* LPB */
   88           CbHiInt               = 1<<16,        /* COB upper threshold */
   89           CbLoInt               = 1<<17,        /* COB lower threshold */
   90 
   91         SubsystemCtl    = 0x8504,       /* Subsystem Control: write only */
   92           /* clear interrupts for various events */
   93           VsyncClr              = 1<<0,
   94           GeBusyClr             = 1<<1,
   95           BfifoFullClr  = 1<<2,
   96           BfifoEmptyClr = 1<<3,
   97           CfifoFullClr  = 1<<4,
   98           CfifoEmptyClr = 1<<5,
   99           BciClr                = 1<<6,
  100           LpbClr                = 1<<7,
  101           CbHiClr               = 1<<16,
  102           CbLoClr               = 1<<17,
  103 
  104           /* enable interrupts for various events */
  105           VsyncEna              = 1<<8,
  106           Busy2DEna             = 1<<9,
  107           BfifoFullEna  = 1<<10,
  108           BfifoEmptyEna = 1<<11,
  109           CfifoFullEna  = 1<<12,
  110           CfifoEmptyEna = 1<<13,
  111           SubsysBciEna  = 1<<14,
  112           CbHiEna               = 1<<24,
  113           CbLoEna               = 1<<25,
  114 
  115           /* 2D graphics engine software reset */
  116           GeSoftReset   = 1<<15,
  117 
  118         FifoStatus              = 0x8508,       /* FIFO status: read only */
  119           CwbEmpty              = 1<<0,         /* command write buffer empty */
  120           CrbEmpty              = 1<<1,         /* command read buffer empty */
  121           CobEmpty              = 1<<2,         /* command overflow buffer empty */
  122           CfifoEmpty    = 1<<3,         /* command FIFO empty */
  123           CwbFull               = 1<<8,         /* command write buffer full */
  124           CrbFull               = 1<<9,         /* command read buffer full */
  125           CobFull               = 1<<10,        /* command overflow buffer full */
  126           CfifoFull             = 1<<11,        /* command FIFO full */
  127 
  128         AdvFunCtl               = 0x850C,       /* Advanced Function Control: read/write */
  129           GeEna                 = 1<<0, /* enable 2D/3D engine */
  130           /*
  131            * according to the manual, BigPixel should be
  132            * set when bpp >= 8 (bpp != 4), and then CR50_5-4 are
  133            * used to figure out bpp example.  however, it does bad things
  134            * to the screen in 8bpp mode.
  135            */
  136           BigPixel              = 1<<2,         /* 8 or more bpp enhanced mode */
  137           LaEna                 = 1<<3,         /* linear addressing ena: or'ed with CR58_4 */
  138           Mclk_2                = 0<<8,         /* 2D engine clock divide: MCLK/2 */
  139           Mclk_4                = 1<<8,         /* " MCLK/4 */
  140           Mclk                  = 2<<8,         /* " MCLK */
  141         /* Mclk                 = 3<<8,         /* " MCLK */
  142           Ic33mhz               = 1<<16,        /* Internal clock 33 MHz (instead of 66) */
  143 
  144         WakeupReg               = 0x8510,       /* Wakeup: read/write */
  145           WakeupBit             = 1<<0, /* wake up: or'ed with 3C3_0 */
  146 
  147         SourceY                 = 0x8100,       /* UL corner of bitblt source */
  148         SourceX                 = 0x8102,       /* " */
  149         RectY                   = 0x8100,       /* UL corner of rectangle fill */
  150         RectX                   = 0x8102,       /* " */
  151         DestY                   = 0x8108,       /* UL corner of bitblt dest */
  152         DestX                   = 0x810A,       /* " */
  153         Height                  = 0x8148,       /* bitblt, image xfer rectangle height */
  154         Width                   = 0x814A,       /* bitblt, image xfer rectangle width */
  155 
  156         StartY                  = 0x8100,       /* Line draw: first point*/
  157         StartX                  = 0x8102,       /* " */
  158         /*
  159          * For line draws, the following must be programmed:
  160          * axial step constant = 2*min(|dx|,|dy|)
  161          * diagonal step constant = 2*[min(|dx|,|dy|) - max(|dx|,|dy|)]
  162          * error term = 2*min(|dx|,|dy|) - max(|dx|,|dy| - 1
  163          *      [sic] when start X < end X
  164          * error term = 2*min(|dx|,|dy|) - max(|dx|,|dy|
  165          *  [sic] when start X >= end X
  166          */
  167         AxialStep               = 0x8108,
  168         DiagonalStep    = 0x810A,
  169         LineError               = 0x8110,
  170         MinorLength             = 0x8148,       /* pixel count along minor axis */
  171         MajorLength             = 0x814A,       /* pixel count along major axis */
  172 
  173         DrawCmd                 = 0x8118,       /* Drawing Command: write only */
  174           CmdMagic              = 0<<1,
  175           AcrossPlane   = 1<<1,         /* across the plane mode */
  176           LastPixelOff  = 1<<2,         /* last pixel of line or vector draw not drawn */
  177           Radial                = 1<<3,         /* enable radial direction (else axial) */
  178           DoDraw                = 1<<4,         /* draw pixels (else only move current pos) */
  179 
  180           DrawRight             = 1<<5,         /* axial drawing direction: left to right */
  181           /* DrawLeft           = 0<<5, */
  182           MajorY                = 1<<6,
  183           /* MajorX             = 0<<6, */
  184           DrawDown              = 1<<7,
  185           /* DrawUp             = 0<<7, */
  186           Degree0               = 0<<5,         /* drawing direction when Radial */
  187           Degree45              = 1<<5,
  188                 /* ... */
  189           Degree315             = 7<<5,
  190 
  191           UseCPUData    = 1<<8,
  192 
  193           /* image write bus transfer width */
  194           Bus8                  = 0<<9,
  195           Bus16                 = 1<<9,
  196           /*
  197            * in Bus32 mode, doubleword bits beyond the image rect width are
  198            * discarded.  each line starts on a new doubleword.
  199            * Bus32AP is intended for across-the-plane mode and
  200            * rounds to byte boundaries instead.
  201            */
  202           Bus32                 = 2<<9,
  203           Bus32AP               = 3<<9,
  204 
  205           CmdNop                = 0<<13,        /* nop */
  206           CmdLine               = 1<<13,        /* draw line */
  207           CmdFill               = 2<<13,        /* fill rectangle */
  208           CmdBitblt             = 6<<13,        /* bitblt */
  209           CmdPatblt             = 7<<13,        /* 8x8 pattern blt */
  210 
  211           SrcGBD                = 0<<16,
  212           SrcPBD                = 1<<16,
  213           SrcSBD                = 2<<16,
  214 
  215           DstGBD                = 0<<18,
  216           DstPBD                = 1<<18,
  217           DstSBD                = 2<<18,
  218 
  219         /* color sources, controls */
  220         BgColor                 = 0x8120,       /* Background Color: read/write */
  221         FgColor                 = 0x8124,       /* Foreground Color: read/write */
  222         BitplaneWmask   = 0x8128,       /* Bitplane Write Mask: read/write */
  223         BitplaneRmask   = 0x812C,       /* Bitplane Read Mask: read/write */
  224         CmpColor                = 0x8130,       /* Color Compare: read/write */
  225         BgMix                   = 0x8134,
  226         FgMix                   = 0x8136,
  227           MixNew                = 7,
  228           SrcBg                 = 0<<5,
  229           SrcFg                 = 1<<5,
  230           SrcCPU                = 2<<5,
  231           SrcDisp               = 3<<5,
  232 
  233         /* clipping rectangle */
  234         TopScissors             = 0x8138,       /* Top Scissors: write only */
  235         LeftScissors    = 0x813A,       /* Left Scissors: write only */
  236         BottomScissors  = 0x813C,       /* Bottom Scissors: write only */
  237         RightScissors   = 0x813E,       /* Right Scissors: write only */
  238 
  239         /*
  240          * Registers with Magic were indirectly accessed in older modes.
  241          * It is not clear whether the Magic is necessary.
  242          * In the older modes, writes to these registers were pipelined,
  243          * so that you had to issue an engine command and wait for engine
  244          * idle before reading a write back.  It is not clear if this is
  245          * still the case either.
  246          */
  247         PixCtl                  = 0x8140,       /* Pixel Control: write only */
  248           PixMagic              = 0xA<<12,
  249           PixMixFg              = 0<<6,         /* foreground mix register always */
  250           PixMixCPU             = 2<<6,         /* CPU data determines mix register */
  251           PixMixDisp    = 3<<6,         /* display data determines mix register */
  252 
  253         MfMisc2Ctl              = 0x8142,       /* Multifunction Control Misc. 2: write only */
  254           MfMisc2Magic  = 0xD<<12,
  255           DstShift              = 0,            /* 3 bits: destination base address in MB */
  256           SrcShift              = 4,            /* 3 bits: source base address in MB */
  257           WaitFifoEmpty = 2<<8,         /* wait for write FIFO empty between draws */
  258 
  259         MfMiscCtl               = 0x8144,       /* Multifunction Control Misc: write only */
  260           MfMiscMagic   = 0xE<<12,
  261           UseHighBits   = 1<<4,         /* select upper 16 bits for 32-bit reg access */
  262           ClipInvert    = 1<<5,         /* only touch pixels outside clip rectangle */
  263           SkipSame              = 0<<6,         /* ignore pixels with color CmpColor */
  264           SkipDifferent = 1<<7,         /* ignore pixels not color CmpColor */
  265           CmpEna                = 1<<8,         /* enable color compare */
  266           W32Ena                = 1<<9,         /* enable 32-bit register write */
  267           ClipDis               = 1<<11,        /* disable clipping */
  268 
  269         /*
  270          * The bitmap descriptor 1 registers contain the starting
  271          * address of the bitmap (in bytes).
  272          * The bitmap descriptor 2 registesr contain stride (in pixels)
  273          * in the lower 16 bits, depth (in bits) in the next 8 bits,
  274          * and whether block write is disabled.
  275          */
  276         GBD1                    = 0x8168,       /* Global Bitmap Descriptor 1: read/write */
  277         GBD2                    = 0x816C,       /* Global Bitmap Descriptor 2: read/write */
  278           /* GBD2-only bits */
  279           BDS64                 = 1<<0,         /* bitmap descriptor size 64 bits */
  280           GBDBciEna             = 1<<3,         /* BCI enable */
  281           /* generic BD2 bits */
  282           BlockWriteDis = 1<<28,
  283           StrideShift   = 0,
  284           DepthShift    = 16,
  285 
  286         PBD1                    = 0x8170,       /* Primary Bitmap Descriptor: read/write */
  287         PBD2                    = 0x8174,
  288         SBD1                    = 0x8178,       /* Secondary Bitmap Descriptor: read/write */
  289         SBD2                    = 0x817C,
  290 };
  291 
  292 /* mastered data transfer registers */
  293 
  294 /* configuration/status registers */
  295 enum {
  296         XStatus0                        = 0x48C00,      /* Status Word 0: read only */
  297           /* rev. A silicon differs from rev. B; use AltStatus0 */
  298           CBEMaskA              = 0x1FFFF,      /* filled command buffer entries */
  299           CBEShiftA             = 0,
  300           BciIdleA              = 1<<17,        /* BCI idle */
  301           Ge3IdleA              = 1<<18,        /* 3D engine idle */
  302           Ge2IdleA              = 1<<19,        /* 2D engine idle */
  303           McpIdleA              = 1<<20,        /* motion compensation processor idle */
  304           MeIdleA               = 1<<22,        /* master engine idle */
  305           PfPendA               = 1<<23,        /* page flip pending */
  306 
  307           CBEMaskB              = 0x1FFFFF,
  308           CBEShiftB             = 0,
  309           BciIdleB              = 1<<25,
  310           Ge3IdleB              = 1<<26,
  311           Ge2IdleB              = 1<<27,
  312           McpIdleB              = 1<<28,
  313           MeIdleB               = 1<<30,
  314           PfPendB               = 1<<31,
  315 
  316         AltStatus0              = 0x48C60,      /* Alternate Status Word 0: read only */
  317           CBEMask               = 0x1FFFF,
  318           CBEShift              = 0,
  319           /* the Savage4 manual says bits 17..23 for these, like Status0 */
  320           /* empirically, they are bits 21..26 */
  321           BciIdle               = 1<<21,
  322           Ge3Idle               = 1<<22,
  323           Ge2Idle               = 1<<23,
  324           McpIdle               = 1<<24,
  325           MeIdle                = 1<<25,
  326           PfPend                = 1<<26,
  327 
  328         XStatus1                        = 0x48C04,      /* Status Word 1: read only */
  329           /* contains event tag 1, event tag 0, both 16 bits */
  330 
  331         XStatus2                        = 0x48C08,      /* Status Word 2: read only */
  332           ScanMask              = 0x3FF,        /* current scan line */
  333           ScanShift             = 0,
  334           VRTMask               = 0x7F100,      /* vert retrace count */
  335           VRTShift              = 11,
  336 
  337         CbThresh                = 0x48C10,      /* Command Buffer Thresholds: read/write */
  338         CobOff                  = 0x48C14,      /* Command Overflow Buffer: read/write */
  339 
  340         CobPtr                  = 0x48C18,      /* Command Overflow Buffer Pointers: read/write */
  341           CobEna                = 1<<2,         /* command overflow buffer enable */
  342           CobBciEna             = 1<<3,         /* BCI function enable */
  343           CbeMask               = 0xFFFF8000,   /* no. of entries in command buffer */
  344           CbeShift              = 15,
  345 
  346         AltStatus1              = 0x48C64,      /* Alternate Status Word 1: read onnly */
  347           /* contains current texture surface tag, vertex buffer tag */
  348 
  349 };
  350 
  351 struct {
  352         ulong idletimeout;
  353         ulong tostatw[16];
  354 } savagestats;
  355 
  356 enum {
  357         Maxloop = 1<<20
  358 };
  359 
  360 static void
  361 savagewaitidle(VGAscr *scr)
  362 {
  363         long x;
  364         ulong *statw, mask, goal;
  365 
  366         switch(scr->id){
  367         case SAVAGE4:
  368         case PROSAVAGEP:
  369         case PROSAVAGEK:
  370         case PROSAVAGE8:
  371                 /* wait for engine idle and FIFO empty */
  372                 statw = (ulong*)((uchar*)scr->mmio+AltStatus0);
  373                 mask = CBEMask | Ge2Idle;
  374                 goal = Ge2Idle;
  375                 break;
  376         /* case SAVAGEMXMV: ? */
  377         /* case SAVAGEMX: ? */
  378         /* case SAVAGEIX: ? */
  379         case SUPERSAVAGEIXC16:
  380         case SAVAGEIXMV:
  381         case SAVAGEMXMV:
  382                 /* wait for engine idle and FIFO empty */
  383                 statw = (ulong*)((uchar*)scr->mmio+XStatus0);
  384                 mask = CBEMaskA | Ge2IdleA;
  385                 goal = Ge2IdleA;
  386                 break;
  387         default:
  388                 /* 
  389                  * best we can do: can't print or we'll call ourselves.
  390                  * savageinit is supposed to not let this happen.
  391                  */     
  392                 return;
  393         }
  394 
  395         for(x=0; x<Maxloop; x++)
  396                 if((*statw & mask) == goal)
  397                         return;
  398 
  399         savagestats.tostatw[savagestats.idletimeout++&15] = *statw;
  400         savagestats.tostatw[savagestats.idletimeout++&15] = (ulong)statw;
  401 }
  402 
  403 static int
  404 savagefill(VGAscr *scr, Rectangle r, ulong sval)
  405 {
  406         uchar *mmio;
  407 
  408         mmio = (uchar*)scr->mmio;
  409 
  410         *(ulong*)(mmio+FgColor) = sval;
  411         *(ulong*)(mmio+BgColor) = sval;
  412         *(ulong*)(mmio+BgMix) = SrcFg|MixNew;
  413         *(ulong*)(mmio+FgMix) = SrcFg|MixNew;
  414         *(ushort*)(mmio+RectY) = r.min.y;
  415         *(ushort*)(mmio+RectX) = r.min.x;
  416         *(ushort*)(mmio+Width) = Dx(r)-1;
  417         *(ushort*)(mmio+Height) = Dy(r)-1;
  418         *(ulong*)(mmio+DrawCmd) = CmdMagic | DoDraw | CmdFill | DrawRight | DrawDown;
  419         savagewaitidle(scr);
  420         return 1;
  421 }
  422 
  423 static int
  424 savagescroll(VGAscr *scr, Rectangle r, Rectangle sr)
  425 {
  426         uchar *mmio;
  427         ulong cmd;
  428         Point dp, sp;
  429 
  430         cmd = CmdMagic | DoDraw | CmdBitblt | SrcPBD | DstGBD;
  431 
  432         if(r.min.x <= sr.min.x){
  433                 cmd |= DrawRight;
  434                 dp.x = r.min.x;
  435                 sp.x = sr.min.x;
  436         }else{
  437                 dp.x = r.max.x-1;
  438                 sp.x = sr.max.x-1;
  439         }
  440 
  441         if(r.min.y <= sr.min.y){
  442                 cmd |= DrawDown;
  443                 dp.y = r.min.y;
  444                 sp.y = sr.min.y;
  445         }else{
  446                 dp.y = r.max.y-1;
  447                 sp.y = sr.max.y-1;
  448         }
  449 
  450         mmio = (uchar*)scr->mmio;
  451 
  452         *(ushort*)(mmio+SourceX) = sp.x;
  453         *(ushort*)(mmio+SourceY) = sp.y;
  454         *(ushort*)(mmio+DestX) = dp.x;
  455         *(ushort*)(mmio+DestY) = dp.y;
  456         *(ushort*)(mmio+Width) = Dx(r)-1;
  457         *(ushort*)(mmio+Height) = Dy(r)-1;
  458         *(ulong*)(mmio+BgMix) = SrcDisp|MixNew;
  459         *(ulong*)(mmio+FgMix) = SrcDisp|MixNew;
  460         *(ulong*)(mmio+DrawCmd) = cmd;
  461         savagewaitidle(scr);
  462         return 1;
  463 }
  464 
  465 static void
  466 savageblank(VGAscr*, int blank)
  467 {
  468         uchar seqD;
  469 
  470         /*
  471          * Will handle DPMS to monitor
  472          */
  473         vgaxo(Seqx, 8, vgaxi(Seqx,8)|0x06);
  474         seqD = vgaxi(Seqx, 0xD);
  475         seqD &= 0x03;
  476         if(blank)
  477                 seqD |= 0x50;
  478         vgaxo(Seqx, 0xD, seqD);
  479 
  480         /*
  481          * Will handle LCD
  482          */
  483         if(blank)
  484                 vgaxo(Seqx, 0x31, vgaxi(Seqx, 0x31) & ~0x10);
  485         else
  486                 vgaxo(Seqx, 0x31, vgaxi(Seqx, 0x31) | 0x10);
  487 }
  488 
  489 
  490 void
  491 savageinit(VGAscr *scr)
  492 {
  493         uchar *mmio;
  494         ulong bd;
  495 
  496         /* if you add chip IDs here be sure to update savagewaitidle */
  497         switch(scr->id){
  498         case SAVAGE4:
  499         case PROSAVAGEP:
  500         case PROSAVAGEK:
  501         case PROSAVAGE8:
  502         case SAVAGEIXMV:
  503         case SUPERSAVAGEIXC16:
  504         case SAVAGEMXMV:
  505                 break;
  506         default:
  507                 print("unknown savage %.4lux\n", scr->id);
  508                 return;
  509         }
  510 
  511         mmio = (uchar*)scr->mmio;
  512         if(mmio == nil) {
  513                 print("savageinit: no mmio\n");
  514                 return;
  515         }
  516 
  517         /* 2D graphics engine software reset */
  518         *(ushort*)(mmio+SubsystemCtl) = GeSoftReset;
  519         delay(2);
  520         *(ushort*)(mmio+SubsystemCtl) = 0;
  521         savagewaitidle(scr);
  522 
  523         /* disable BCI as much as possible */
  524         *(ushort*)(mmio+CobPtr) &= ~CobBciEna;
  525         *(ushort*)(mmio+GBD2) &= ~GBDBciEna;
  526         savagewaitidle(scr);
  527 
  528         /* enable 32-bit writes, disable clipping */
  529         *(ushort*)(mmio+MfMiscCtl) = MfMiscMagic|W32Ena|ClipDis;
  530         savagewaitidle(scr);
  531 
  532         /* enable all read, write planes */
  533         *(ulong*)(mmio+BitplaneRmask) = ~0;
  534         *(ulong*)(mmio+BitplaneWmask) = ~0;
  535         savagewaitidle(scr);
  536 
  537         /* turn on linear access, 2D engine */
  538         *(ulong*)(mmio+AdvFunCtl) |= GeEna|LaEna;
  539         savagewaitidle(scr);
  540 
  541         /* set bitmap descriptors */
  542         bd = (scr->gscreen->depth<<DepthShift) |
  543                 (Dx(scr->gscreen->r)<<StrideShift) | BlockWriteDis
  544                 | BDS64;
  545 
  546         *(ulong*)(mmio+GBD1) = 0;
  547         *(ulong*)(mmio+GBD2) = bd;
  548 
  549         *(ulong*)(mmio+PBD1) = 0;
  550         *(ulong*)(mmio+PBD2) = bd;
  551 
  552         *(ulong*)(mmio+SBD1) = 0;
  553         *(ulong*)(mmio+SBD2) = bd;
  554 
  555         /*
  556          * For some reason, the GBD needs to get programmed twice,
  557          * once before the PBD, SBD, and once after.
  558          * This empirically makes it get set right.
  559          * I would like to better understand the ugliness
  560          * going on here.
  561          */
  562         *(ulong*)(mmio+GBD1) = 0;
  563         *(ulong*)(mmio+GBD2) = bd;
  564         *(ushort*)(mmio+GBD2+2) = bd>>16;
  565         savagewaitidle(scr);
  566 
  567         scr->fill = savagefill;
  568         scr->scroll = savagescroll;
  569         scr->blank = savageblank;
  570         hwblank = 0;
  571 }

Cache object: 935824bf7cb6de008e2fe05626bec368


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