Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  * Copyright 1992-2003 by Alan Hourihane, North Wales, UK.
      3  *
      4  * Permission to use, copy, modify, distribute, and sell this software and its
      5  * documentation for any purpose is hereby granted without fee, provided that
      6  * the above copyright notice appear in all copies and that both that
      7  * copyright notice and this permission notice appear in supporting
      8  * documentation, and that the name of Alan Hourihane not be used in
      9  * advertising or publicity pertaining to distribution of the software without
     10  * specific, written prior permission.  Alan Hourihane makes no representations
     11  * about the suitability of this software for any purpose.  It is provided
     12  * "as is" without express or implied warranty.
     13  *
     14  * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     16  * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     20  * PERFORMANCE OF THIS SOFTWARE.
     21  *
     22  * Author:  Alan Hourihane, alanh (at) fairlite.demon.co.uk
     23  *          Re-written for XFree86 v4.0
     24  *
     25  * Previous driver (pre-XFree86 v4.0) by
     26  *          Alan Hourihane, alanh (at) fairlite.demon.co.uk
     27  *          David Wexelblat (major contributor)
     28  *          Massimiliano Ghilardi, max (at) Linuz.sns.it, some fixes to the
     29  *                                 clockchip programming code.
     30  */
     31 
     32 #ifdef HAVE_CONFIG_H
     33 #include "config.h"
     34 #endif
     35 
     36 #include "fb.h"
     37 
     38 #ifdef HAVE_ISA
     39 #include "mibank.h"
     40 #endif
     41 #include "micmap.h"
     42 #include "xf86.h"
     43 #include "xf86_OSproc.h"
     44 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
     45 #include "xf86Resources.h"
     46 #include "xf86RAC.h"
     47 #endif
     48 #include "xf86Pci.h"
     49 #include "xf86cmap.h"
     50 #include "vgaHW.h"
     51 
     52 #include "vbe.h"
     53 #include "dixstruct.h"
     54 #include "compiler.h"
     55 
     56 #include "mipointer.h"
     57 
     58 #include "shadow.h"
     59 #include "trident.h"
     60 #include "trident_regs.h"
     61 
     62 #ifdef XFreeXDGA
     63 #define _XF86DGA_SERVER_
     64 #include <X11/extensions/xf86dgaproto.h>
     65 #endif
     66 
     67 #include "globals.h"
     68 #ifdef HAVE_XEXTPROTO_71
     69 #include <X11/extensions/dpmsconst.h>
     70 #else
     71 #define DPMS_SERVER
     72 #include <X11/extensions/dpms.h>
     73 #endif
     74 
     75 #include "xf86xv.h"
     76 
     77 static const OptionInfoRec * TRIDENTAvailableOptions(int chipid, int busid);
     78 static void     TRIDENTIdentify(int flags);
     79 static Bool     TRIDENTProbe(DriverPtr drv, int flags);
     80 static Bool     TRIDENTPreInit(ScrnInfoPtr pScrn, int flags);
     81 static Bool     TRIDENTScreenInit(SCREEN_INIT_ARGS_DECL);
     82 
     83 /*
     84  * This is intentionally screen-independent.  It indicates the binding
     85  * choice made in the first PreInit.
     86  */
     87 static int pix24bpp = 0;
     88 
     89 #define TRIDENT_VERSION 4000
     90 #define TRIDENT_NAME "TRIDENT"
     91 #define TRIDENT_DRIVER_NAME "trident"
     92 #define TRIDENT_MAJOR_VERSION PACKAGE_VERSION_MAJOR
     93 #define TRIDENT_MINOR_VERSION PACKAGE_VERSION_MINOR
     94 #define TRIDENT_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL
     95 
     96 /*
     97  * This contains the functions needed by the server after loading the driver
     98  * module.  It must be supplied, and gets passed back by the SetupProc
     99  * function in the dynamic case.  In the static case, a reference to this
    100  * is compiled in, and this requires that the name of this DriverRec be
    101  * an upper-case version of the driver name.
    102  */
    103 
    104 _X_EXPORT DriverRec TRIDENT = {
    105     TRIDENT_VERSION,
    106     TRIDENT_DRIVER_NAME,
    107     TRIDENTIdentify,
    108     TRIDENTProbe,
    109     TRIDENTAvailableOptions,
    110     NULL,
    111     0
    112 };
    113 
    114 static SymTabRec TRIDENTChipsets[] = {
    115     { TVGA9000,         "tvga9000" },
    116     { TVGA9000i,        "tvga9000i" },
    117     { TVGA8900C,        "tvga8900c" },
    118     { TVGA8900D,        "tvga8900d" },
    119     { TVGA9200CXr,      "tvga9200cxr" },
    120     { TGUI9400CXi,      "tgui9400cxi" },
    121     { CYBER9320,        "cyber9320" },
    122     { CYBER9388,        "cyber9388" },
    123     { CYBER9397,        "cyber9397" },
    124     { CYBER9397DVD,     "cyber9397dvd" },
    125     { CYBER9520,        "cyber9520" },
    126     { CYBER9525DVD,     "cyber9525dvd" },
    127     { CYBERBLADEE4,     "cyberblade/e4" },
    128     { TGUI9420DGi,      "tgui9420dgi" },
    129     { TGUI9440AGi,      "tgui9440agi" },
    130     { TGUI9660,         "tgui9660" },
    131     { TGUI9680,         "tgui9680" },
    132     { PROVIDIA9682,     "providia9682" },
    133     { PROVIDIA9685,     "providia9685" },
    134     { CYBER9382,        "cyber9382" },
    135     { CYBER9385,        "cyber9385" },
    136     { IMAGE975,         "3dimage975" },
    137     { IMAGE985,         "3dimage985" },
    138     { BLADE3D,          "blade3d" },
    139     { CYBERBLADEI7,     "cyberbladei7" },
    140     { CYBERBLADEI7D,    "cyberbladei7d" },
    141     { CYBERBLADEI1,     "cyberbladei1" },
    142     { CYBERBLADEI1D,    "cyberbladei1d" },
    143     { CYBERBLADEAI1,    "cyberbladeAi1" },
    144     { CYBERBLADEAI1D,   "cyberbladeAi1d" },
    145     { BLADEXP,          "bladeXP" },
    146     { CYBERBLADEXPAI1,  "cyberbladeXPAi1" },
    147     { CYBERBLADEXP4,    "cyberbladeXP4" },
    148     { XP5,              "XP5" },
    149     { -1,               NULL }
    150 };
    151 
    152 #ifdef HAVE_ISA
    153 static IsaChipsets TRIDENTISAchipsets[] = {
    154     { TVGA9000,         RES_EXCLUSIVE_VGA },
    155     { TVGA9000i,        RES_EXCLUSIVE_VGA },
    156     { TVGA8900C,        RES_EXCLUSIVE_VGA },
    157     { TVGA8900D,        RES_EXCLUSIVE_VGA },
    158     { TVGA9200CXr,      RES_EXCLUSIVE_VGA },
    159     { TGUI9400CXi,      RES_EXCLUSIVE_VGA },
    160     { CYBER9320,        RES_EXCLUSIVE_VGA },
    161     { TGUI9440AGi,      RES_EXCLUSIVE_VGA },
    162     { -1,               RES_UNDEFINED }
    163 };
    164 #endif
    165 
    166 static PciChipsets TRIDENTPciChipsets[] = {
    167     { CYBER9320,        PCI_CHIP_9320,  RES_SHARED_VGA },
    168     { CYBER9388,        PCI_CHIP_9388,  RES_SHARED_VGA },
    169     { CYBER9397,        PCI_CHIP_9397,  RES_SHARED_VGA },
    170     { CYBER9397DVD,     PCI_CHIP_939A,  RES_SHARED_VGA },
    171     { CYBER9520,        PCI_CHIP_9520,  RES_SHARED_VGA },
    172     { CYBER9525DVD,     PCI_CHIP_9525,  RES_SHARED_VGA },
    173     { CYBERBLADEE4,     PCI_CHIP_9540,  RES_SHARED_VGA },
    174     { TGUI9420DGi,      PCI_CHIP_9420,  RES_SHARED_VGA },
    175     { TGUI9440AGi,      PCI_CHIP_9440,  RES_SHARED_VGA },
    176     { TGUI9660,         PCI_CHIP_9660,  RES_SHARED_VGA },
    177     { TGUI9680,         PCI_CHIP_9660,  RES_SHARED_VGA },
    178     { PROVIDIA9682,     PCI_CHIP_9660,  RES_SHARED_VGA },
    179     { PROVIDIA9685,     PCI_CHIP_9660,  RES_SHARED_VGA },
    180     { CYBER9382,        PCI_CHIP_9660,  RES_SHARED_VGA },
    181     { CYBER9385,        PCI_CHIP_9660,  RES_SHARED_VGA },
    182     { IMAGE975,         PCI_CHIP_9750,  RES_SHARED_VGA },
    183     { IMAGE985,         PCI_CHIP_9850,  RES_SHARED_VGA },
    184     { BLADE3D,          PCI_CHIP_9880,  RES_SHARED_VGA },
    185     { CYBERBLADEI7,     PCI_CHIP_8400,  RES_SHARED_VGA },
    186     { CYBERBLADEI7D,    PCI_CHIP_8420,  RES_SHARED_VGA },
    187     { CYBERBLADEI1,     PCI_CHIP_8500,  RES_SHARED_VGA },
    188     { CYBERBLADEI1D,    PCI_CHIP_8520,  RES_SHARED_VGA },
    189     { CYBERBLADEAI1,    PCI_CHIP_8600,  RES_SHARED_VGA },
    190     { CYBERBLADEAI1D,   PCI_CHIP_8620,  RES_SHARED_VGA },
    191     { BLADEXP,          PCI_CHIP_9910,  RES_SHARED_VGA },
    192     { CYBERBLADEXPAI1,  PCI_CHIP_8820,  RES_SHARED_VGA },
    193     { CYBERBLADEXP4,    PCI_CHIP_2100,  RES_SHARED_VGA },
    194     { XP5,              PCI_CHIP_2200,  RES_SHARED_VGA },
    195     { -1,               -1,             RES_UNDEFINED }
    196 };
    197 
    198 typedef enum {
    199     OPTION_ACCELMETHOD,
    200     OPTION_SW_CURSOR,
    201     OPTION_PCI_RETRY,
    202     OPTION_RGB_BITS,
    203     OPTION_NOACCEL,
    204     OPTION_SETMCLK,
    205     OPTION_MUX_THRESHOLD,
    206     OPTION_SHADOW_FB,
    207     OPTION_ROTATE,
    208     OPTION_MMIO_ONLY,
    209     OPTION_VIDEO_KEY,
    210     OPTION_NOMMIO,
    211     OPTION_NOPCIBURST,
    212     OPTION_CYBER_SHADOW,
    213     OPTION_CYBER_STRETCH,
    214     OPTION_XV_HSYNC,
    215     OPTION_XV_VSYNC,
    216     OPTION_XV_BSKEW,
    217     OPTION_XV_RSKEW,
    218     OPTION_FP_DELAY,
    219     OPTION_1400_DISPLAY,
    220     OPTION_DISPLAY,
    221     OPTION_GB,
    222     OPTION_TV_CHIPSET,
    223     OPTION_TV_SIGNALMODE
    224 } TRIDENTOpts;
    225 
    226 static const OptionInfoRec TRIDENTOptions[] = {
    227     { OPTION_ACCELMETHOD,       "AccelMethod",      OPTV_ANYSTR,    {0}, FALSE },
    228     { OPTION_SW_CURSOR,         "SWcursor",         OPTV_BOOLEAN,   {0}, FALSE },
    229     { OPTION_PCI_RETRY,         "PciRetry",         OPTV_BOOLEAN,   {0}, FALSE },
    230     { OPTION_NOACCEL,           "NoAccel",          OPTV_BOOLEAN,   {0}, FALSE },
    231     { OPTION_SETMCLK,           "SetMClk",          OPTV_FREQ,      {0}, FALSE },
    232     { OPTION_MUX_THRESHOLD,     "MUXThreshold",     OPTV_INTEGER,   {0}, FALSE },
    233     { OPTION_SHADOW_FB,         "ShadowFB",         OPTV_BOOLEAN,   {0}, FALSE },
    234     { OPTION_ROTATE,            "Rotate",           OPTV_ANYSTR,    {0}, FALSE },
    235     { OPTION_VIDEO_KEY,         "VideoKey",         OPTV_INTEGER,   {0}, FALSE },
    236     { OPTION_NOMMIO,            "NoMMIO",           OPTV_BOOLEAN,   {0}, FALSE },
    237     { OPTION_NOPCIBURST,        "NoPciBurst",       OPTV_BOOLEAN,   {0}, FALSE },
    238     { OPTION_MMIO_ONLY,         "MMIOonly",         OPTV_BOOLEAN,   {0}, FALSE },
    239     { OPTION_CYBER_SHADOW,      "CyberShadow",      OPTV_BOOLEAN,   {0}, FALSE },
    240     { OPTION_CYBER_STRETCH,     "CyberStretch",     OPTV_BOOLEAN,   {0}, FALSE },
    241     { OPTION_XV_HSYNC,          "XvHsync",          OPTV_INTEGER,   {0}, FALSE },
    242     { OPTION_XV_VSYNC,          "XvVsync",          OPTV_INTEGER,   {0}, FALSE },
    243     { OPTION_XV_BSKEW,          "XvBskew",          OPTV_INTEGER,   {0}, FALSE },
    244     { OPTION_XV_RSKEW,          "XvRskew",          OPTV_INTEGER,   {0}, FALSE },
    245     { OPTION_FP_DELAY,          "FpDelay",          OPTV_INTEGER,   {0}, FALSE },
    246     { OPTION_1400_DISPLAY,      "Display1400",      OPTV_BOOLEAN,   {0}, FALSE },
    247     { OPTION_DISPLAY,           "Display",          OPTV_ANYSTR,    {0}, FALSE },
    248     { OPTION_GB,                "GammaBrightness",  OPTV_ANYSTR,    {0}, FALSE },
    249     { OPTION_TV_CHIPSET,        "TVChipset",        OPTV_ANYSTR,    {0}, FALSE },
    250     { OPTION_TV_SIGNALMODE,     "TVSignal",         OPTV_INTEGER,   {0}, FALSE },
    251     { -1,                       NULL,               OPTV_NONE,      {0}, FALSE }
    252 };
    253 
    254 /* Clock Limits */
    255 static int ClockLimit[] = {
    256     80000,
    257     80000,
    258     80000,
    259     80000,
    260     80000,
    261     80000,
    262     80000,
    263     80000,
    264     80000,
    265     80000,
    266     80000,
    267     80000,
    268     80000,
    269     80000,
    270     90000,
    271     90000,
    272     135000,
    273     135000,
    274     170000,
    275     170000,
    276     170000,
    277     170000,
    278     170000,
    279     170000,
    280     170000,
    281     230000,
    282     230000,
    283     230000,
    284     230000,
    285     230000,
    286     230000,
    287     230000,
    288     230000,
    289     230000,
    290     230000,
    291     230000,
    292     230000,
    293     230000,
    294     230000,
    295     230000,
    296     230000,
    297 };
    298 
    299 static int ClockLimit16bpp[] = {
    300     40000,
    301     40000,
    302     40000,
    303     40000,
    304     40000,
    305     40000,
    306     40000,
    307     40000,
    308     40000,
    309     40000,
    310     40000,
    311     40000,
    312     40000,
    313     40000,
    314     45000,
    315     45000,
    316     90000,
    317     90000,
    318     135000,
    319     135000,
    320     170000,
    321     170000,
    322     170000,
    323     170000,
    324     170000,
    325     230000,
    326     230000,
    327     230000,
    328     230000,
    329     230000,
    330     230000,
    331     230000,
    332     230000,
    333     230000,
    334     230000,
    335     230000,
    336     230000,
    337     230000,
    338     230000,
    339     230000,
    340     230000,
    341 };
    342 
    343 static int ClockLimit24bpp[] = {
    344     25180,
    345     25180,
    346     25180,
    347     25180,
    348     25180,
    349     25180,
    350     25180,
    351     25180,
    352     25180,
    353     25180,
    354     25180,
    355     25180,
    356     25180,
    357     25180,
    358     25180,
    359     25180,
    360     40000,
    361     40000,
    362     70000,
    363     70000,
    364     70000,
    365     115000,
    366     115000,
    367     115000,
    368     115000,
    369     115000,
    370     115000,
    371     115000,
    372     115000,
    373     115000,
    374     115000,
    375     115000,
    376     115000,
    377     115000,
    378     115000,
    379     115000,
    380     115000,
    381     115000,
    382     115000,
    383     115000,
    384     115000,
    385 };
    386 
    387 static int ClockLimit32bpp[] = {
    388     25180,
    389     25180,
    390     25180,
    391     25180,
    392     25180,
    393     25180,
    394     25180,
    395     25180,
    396     25180,
    397     25180,
    398     25180,
    399     25180,
    400     25180,
    401     25180,
    402     25180,
    403     25180,
    404     40000,
    405     40000,
    406     70000,
    407     70000,
    408     70000,
    409     115000,
    410     115000,
    411     115000,
    412     115000,
    413     115000,
    414     115000,
    415     115000,
    416     115000,
    417     115000,
    418     115000,
    419     115000,
    420     115000,
    421     115000,
    422     115000,
    423     115000,
    424     115000,
    425     115000,
    426     115000,
    427     115000,
    428     115000,
    429     115000,
    430 };
    431 
    432 /*
    433  * These are fixed modelines for all physical display dimensions the
    434  *  chipsets supports on FPs. Most of them are not tested yet.
    435  */
    436 #if 0
    437 tridentLCD LCD[] = {   /* 0    3    4    5   6    7    10   11  16 */
    438     { 0,"640x480",25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08},
    439     { 1,"800x600",40000,0x7f,0x99,0x69,0x99,0x72,0xf0,0x59,0x2d,0x5e,0x08},
    440     { 2,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08},
    441     { 3,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, /*0x96*/
    442     { 4,"1280x1024",108000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08},
    443     { 5,"1024x600",50500 ,0xa3,0x6,0x8f,0xa0,0xb,0x3e,0xea,0x8c,0xb,0x08},
    444     { 0xff,"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
    445 };
    446 #else
    447 #if 0
    448 tridentLCD LCD[] = {
    449     { 1,640,480,25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08},
    450     { 3,800,600,40000,0x7f,0x82,0x6b,0x1b,0x72,0xf8,0x58,0x8c,0x72,0x08},
    451     { 2,1024,768,65000,0xa3,/*0x6*/0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x24,0x0a,0x08},
    452     { 0,1280,1024,108000,0xce,0x81,0xa6,0x9a,0x27,0x50,0x00,0x03,0x26,0xa8},
    453     { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
    454 };
    455 #else
    456 tridentLCD LCD[] = {
    457     { 1,640,480,25200,0x5f,0x80,0x52,0x1e,0xb,0x3e,0xea,0x0c,0xb,0x08},
    458     { 3,800,600,40000,0x7f,0x00,0x69,0x7f,0x72,0xf0,0x59,0x0d,0x00,0x08},
    459     { 2,1024,768,65000,0xa3,0x00,0x84,0x94,0x24,0xf5,0x03,0x09,0x24,0x08},
    460     { 0,1280,1024,108000,0xce,0x91,0xa6,0x14,0x28,0x5a,0x01,0x04,0x28,0xa8},
    461     { 4,1400,1050,122000,0xe6,0x8d,0xba,0x1d,0x38,0x00,0x1c,0x28,0x28,0xf8},
    462     { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
    463 };
    464 #endif
    465 #endif
    466 
    467 #ifdef XFree86LOADER
    468 
    469 static MODULESETUPPROTO(tridentSetup);
    470 
    471 static XF86ModuleVersionInfo tridentVersRec =
    472 {
    473     "trident",
    474     MODULEVENDORSTRING,
    475     MODINFOSTRING1,
    476     MODINFOSTRING2,
    477     XORG_VERSION_CURRENT,
    478     TRIDENT_MAJOR_VERSION, TRIDENT_MINOR_VERSION, TRIDENT_PATCHLEVEL,
    479     ABI_CLASS_VIDEODRV,			/* This is a video driver */
    480     ABI_VIDEODRV_VERSION,
    481     MOD_CLASS_VIDEODRV,
    482     {0,0,0,0}
    483 };
    484 
    485 _X_EXPORT XF86ModuleData tridentModuleData = {
    486     &tridentVersRec,
    487     tridentSetup,
    488     NULL
    489 };
    490 
    491 pointer
    492 tridentSetup(pointer module, pointer opts, int *errmaj, int *errmin)
    493 {
    494     static Bool setupDone = FALSE;
    495 
    496     if (!setupDone) {
    497         setupDone = TRUE;
    498         xf86AddDriver(&TRIDENT, module, 0);
    499         return (pointer)TRUE;
    500     }
    501 
    502     if (errmaj) *errmaj = LDR_ONCEONLY;
    503     return NULL;
    504 }
    505 
    506 #endif /* XFree86LOADER */
    507 
    508 static void
    509 TRIDENTEnableMMIO(ScrnInfoPtr pScrn)
    510 {
    511     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    512     unsigned long vgaIOBase = pTrident->PIOBase + VGAHWPTR(pScrn)->IOBase;
    513     CARD8 temp = 0, protect = 0;
    514 
    515     /*
    516      * Skip MMIO Enable in PC-9821 PCI Trident Card!!
    517      * Because of lack of non PCI VGA port
    518      */
    519 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
    520     if (IsPciCard && xf86IsPc98())
    521         return;
    522 #endif
    523 
    524     /* Goto New Mode */
    525     outb(pTrident->PIOBase + 0x3C4, 0x0B);
    526     inb(pTrident->PIOBase + 0x3C5);
    527 
    528     /* Unprotect registers */
    529     if (pTrident->Chipset > PROVIDIA9685) {
    530         outb(pTrident->PIOBase + 0x3C4, Protection);
    531         protect = inb(pTrident->PIOBase + 0x3C5);
    532         outb(pTrident->PIOBase + 0x3C5, 0x92);
    533     }
    534     outb(pTrident->PIOBase + 0x3C4, NewMode1);
    535     temp = inb(pTrident->PIOBase + 0x3C5);
    536     outb(pTrident->PIOBase + 0x3C5, 0x80);
    537 
    538     /* Enable MMIO */
    539     outb(vgaIOBase + 4, PCIReg);
    540     pTrident->REGPCIReg = inb(vgaIOBase + 5);
    541     outb(vgaIOBase + 5, pTrident->REGPCIReg | 0x01); /* Enable it */
    542 
    543     /* Protect registers */
    544     if (pTrident->Chipset > PROVIDIA9685) {
    545         OUTB(0x3C4, Protection);
    546         OUTB(0x3C5, protect);
    547     }
    548     OUTB(0x3C4, NewMode1);
    549     OUTB(0x3C5, temp);
    550 }
    551 
    552 static void
    553 TRIDENTDisableMMIO(ScrnInfoPtr pScrn)
    554 {
    555     int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
    556     CARD8 temp = 0, protect = 0;
    557     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    558 
    559     /*
    560      * Skip MMIO Disable in PC-9821 PCI Trident Card!!
    561      * Because of lack of non PCI VGA port
    562      */
    563 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
    564     if (IsPciCard && xf86IsPc98())
    565         return;
    566 #endif
    567 
    568     /* Goto New Mode */
    569     OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
    570 
    571     /* Unprotect registers */
    572     OUTB(0x3C4, NewMode1); temp = INB(0x3C5);
    573     OUTB(0x3C5, 0x80);
    574     if (pTrident->Chipset > PROVIDIA9685) {
    575         OUTB(0x3C4, Protection);
    576         protect = INB(0x3C5);
    577         OUTB(0x3C5, 0x92);
    578     }
    579 
    580     /* Disable MMIO access */
    581     OUTB(vgaIOBase + 4, PCIReg);
    582     pTrident->REGPCIReg = INB(vgaIOBase + 5);
    583     OUTB(vgaIOBase + 5, pTrident->REGPCIReg & 0xFE);
    584 
    585     /* Protect registers */
    586     if (pTrident->Chipset > PROVIDIA9685) {
    587         outb(pTrident->PIOBase + 0x3C4, Protection);
    588         outb(pTrident->PIOBase + 0x3C5, protect);
    589     }
    590     outb(pTrident->PIOBase + 0x3C4, NewMode1);
    591     outb(pTrident->PIOBase + 0x3C5, temp);
    592 }
    593 
    594 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
    595 /* Initialize VGA Block for Cyber9385 on PC-98x1 */
    596 static void
    597 PC98TRIDENT9385Init(ScrnInfoPtr pScrn)
    598 {
    599     /* Nothing to initialize */
    600 }
    601 
    602 static void
    603 PC98TRIDENT9385Enable(ScrnInfoPtr pScrn)
    604 {
    605     outb(0xFAC, 0x02);
    606 }
    607 
    608 static void
    609 PC98TRIDENT9385Disable(ScrnInfoPtr pScrn)
    610 {
    611     outb(0xFAC, 0x00);
    612 }
    613 
    614 /* Initialize VGA Block for Trident96xx on PC-98x1 */
    615 static void
    616 PC98TRIDENT96xxInit(ScrnInfoPtr pScrn)
    617 {
    618     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    619     vgaHWPtr hwp = VGAHWPTR(pScrn);
    620     CARD8 temp = 0;
    621 
    622     vgaHWProtect(pScrn, TRUE);
    623 
    624     /* Video SusSystem Enable */
    625     temp = INB(0x3CC);
    626     OUTB(0x3C2, temp | 0xC3);
    627     /* Switch Old */
    628     OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
    629     OUTW(0x3C4, 0x0B | (temp << 8));
    630     /* Select Configuration Port 1 */
    631     OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
    632     OUTW(0x3C4, 0x0E | ((temp | 0x20) << 8));
    633 
    634     OUTB(0x3C4, 0x0c);
    635     if((INB(0x3C5) & 0x10) == 0x10)
    636     {
    637         OUTB(0x3C4, 0x0E | (temp << 8));
    638         OUTB(0x94,  0x00);
    639         OUTB(0x102, 0x01);
    640         OUTB(0x94,  0x20);
    641         temp = INB(0x3C3);
    642         OUTB(0x3C3, temp | 0x01);
    643     } else {
    644         OUTB(0x3C4, 0x0E | (temp << 8));
    645         OUTB(0x46E8, 0x10);
    646         OUTB(0x102,  0x01);
    647         OUTB(0x46E8, 0x08);
    648     }
    649 
    650     INB(0x3DA);
    651     OUTB(0x3C0,0x10);
    652     OUTB(0x3C0,0x41);
    653 
    654     /* Register Unlock */
    655     vgaHWUnlock(hwp);
    656     OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */
    657     OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
    658     OUTW(0x3C4, 0x0E | ((temp | 0x80) << 8));
    659 
    660     /* For Speed Up [Facoor 2 at Xengine] */
    661     OUTW(0x3D4, 0x3820); /* Command FIFO Register */
    662     OUTW(0x3D4, 0x2020); /* Command FIFO Register */
    663     /* Latency Control Registers 0x30 - 0x32 */
    664     /* Parameter Range 0x00 - 0x0F */
    665     /* Tune these parameter to avoid GE Timeout */
    666     OUTW(0x3D4, 0x0E30); /* Display Queue Latency Control */
    667     /* 8bpp GE No Timeout Parameter 0x0D - 0x0F for PC-9821Xa7 TGUi9680 */
    668     OUTW(0x3D4, 0x0031); /* Frame Buffer Latency Control */
    669     OUTW(0x3D4, 0x0032); /* Display & Frame Buffer Latency Control */
    670     OUTW(0x3D4, 0x213B); /* Clock and Tuning */
    671 
    672     /* MCLK Init */
    673     OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */
    674 #if 0
    675     /* Sample MCLKs */
    676     OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */
    677     OUTB(0x43C6, 0xA7); OUTB(0x43C7, 0x00); /* 77.0MHz */
    678     OUTB(0x43C6, 0x8E); OUTB(0x43C7, 0x00); /* 75.0MHz */
    679     OUTB(0x43C6, 0x86); OUTB(0x43C7, 0x00); /* 72.0MHz */
    680     OUTB(0x43C6, 0x8F); OUTB(0x43C7, 0x00); /* 67.2MHz */
    681     OUTB(0x43C6, 0xD5); OUTB(0x43C7, 0x02); /* 61.6MHz */
    682 #endif
    683 
    684     /* Register Lock */
    685     OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */
    686     OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
    687     OUTW(0x3C4, 0x0E | ((temp & 0x7F) << 8));
    688     vgaHWLock(hwp);
    689 
    690     vgaHWProtect(pScrn, FALSE);
    691 }
    692 
    693 static void
    694 PC98TRIDENT96xxEnable(ScrnInfoPtr pScrn)
    695 {
    696     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    697     CARD8 temp = 0;
    698 
    699     outb(0x68, 0x0E);
    700     outb(0x6A, 0x07);
    701     outb(0x6A, 0x8F);
    702     outb(0x6A, 0x06);
    703 
    704     vgaHWProtect(pScrn, TRUE);
    705 
    706     OUTB(0x3D4, 0x23); temp = INB(0x3D5);
    707     OUTW(0x3D4, 0x23 | ((temp & 0xDF) << 8));
    708 
    709     OUTB(0x3D4, 0x29); temp = INB(0x3D5);
    710     OUTW(0x3D4, 0x29 | ((temp | 0x04) << 8));
    711 
    712     OUTB(0x83C8, 0x04); temp = INB(0x83c6);
    713     OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x06));
    714 
    715     OUTB(0x83C8, 0x04); temp = INB(0x83c6);
    716     OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x08));
    717 
    718     OUTB(0x3CE, 0x23); temp = INB(0x3CF);
    719     OUTW(0x3CE, 0x23 | ((temp & 0xFC) << 8));
    720 
    721     OUTB(0x83C8, 0x04); temp = INB(0x83c6);
    722     OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x01));
    723 
    724     OUTB(0x3C4, 0x01); temp = INB(0x3C5);
    725     OUTW(0x3C4, 0x01 | ((temp & 0xEF) << 8));
    726 
    727     vgaHWProtect(pScrn, FALSE);
    728 
    729     outb(0xFAC, 0x02);
    730 }
    731 
    732 static void
    733 PC98TRIDENT96xxDisable(ScrnInfoPtr pScrn)
    734 {
    735     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    736     CARD8 temp = 0;
    737 
    738     outb(0xFAC, 0x00);
    739 
    740     vgaHWProtect(pScrn, TRUE);
    741 
    742     OUTB(0x3C4, 0x01); temp = INB(0x3C5);
    743     OUTW(0x3C4, 0x01 | ((temp | 0x10) << 8));
    744 
    745     OUTB(0x83C8, 0x04); temp = INB(0x83c6);
    746     OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFE));
    747 
    748     OUTB(0x3CE, 0x23); temp = INB(0x3CF);
    749     OUTW(0x3CE, 0x23 | (((temp & 0xFC) | 0x01) << 8));
    750 
    751     OUTB(0x83C8, 0x04); temp = INB(0x83c6);
    752     OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFD));
    753 
    754     OUTB(0x83C8, 0x04); temp = INB(0x83c6);
    755     OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xCF));
    756 
    757     OUTB(0x83C8, 0x04); temp = INB(0x83c6);
    758     OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xF7));
    759 
    760     OUTB(0x83C8, 0x04); temp = INB(0x83c6);
    761     OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFB));
    762 
    763     OUTB(0x3D4, 0x29); temp = INB(0x3D5);
    764     OUTW(0x3D4, 0x29 | ((temp & 0xFB) << 8));
    765 
    766     OUTB(0x3D4, 0x23); temp = INB(0x3D5);
    767     OUTW(0x3D4, 0x23 | ((temp | 0x20) << 8));
    768 
    769     vgaHWProtect(pScrn, FALSE);
    770 
    771     outb(0x6A, 0x07);
    772     outb(0x6A, 0x8E);
    773     outb(0x6A, 0x06);
    774     outb(0x68, 0x0F);
    775 }
    776 
    777 /* Initialize VGA Block for Trident Chip on PC-98x1 */
    778 static void
    779 PC98TRIDENTInit(ScrnInfoPtr pScrn)
    780 {
    781     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    782     switch (pTrident->Chipset) {
    783     case TGUI9660:
    784     case TGUI9680:
    785     case PROVIDIA9682:
    786         PC98TRIDENT96xxInit(pScrn);
    787         break;
    788     case CYBER9320:
    789     case CYBER9385:
    790         PC98TRIDENT9385Init(pScrn);
    791         break;
    792     default: /* Run 96xx code as default */
    793         PC98TRIDENT96xxInit(pScrn);
    794         break;
    795     }
    796 }
    797 
    798 static void
    799 PC98TRIDENTEnable(ScrnInfoPtr pScrn)
    800 {
    801     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    802     switch (pTrident->Chipset) {
    803     case TGUI9660:
    804     case TGUI9680:
    805     case PROVIDIA9682:
    806         PC98TRIDENT96xxEnable(pScrn);
    807         break;
    808     case CYBER9320:
    809     case CYBER9385:
    810         PC98TRIDENT9385Enable(pScrn);
    811         break;
    812     default: /* Run 96xx code as default */
    813         PC98TRIDENT96xxEnable(pScrn);
    814         break;
    815     }
    816 }
    817 
    818 static void
    819 PC98TRIDENTDisable(ScrnInfoPtr pScrn)
    820 {
    821     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    822     switch (pTrident->Chipset) {
    823     case TGUI9660:
    824     case TGUI9680:
    825     case PROVIDIA9682:
    826         PC98TRIDENT96xxDisable(pScrn);
    827         break;
    828     case CYBER9320:
    829     case CYBER9385:
    830         PC98TRIDENT9385Disable(pScrn);
    831         break;
    832     default: /* Run 96xx code as default */
    833         PC98TRIDENT96xxDisable(pScrn);
    834         break;
    835     }
    836 }
    837 #endif
    838 
    839 /*
    840  * This is a terrible hack! If we are on a notebook in a stretched
    841  * mode and don't want full screen we use the BIOS to set an unstreched
    842  * mode.
    843  */
    844 void
    845 tridentSetModeBIOS(ScrnInfoPtr pScrn, DisplayModePtr mode)
    846 {
    847     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    848 
    849 
    850 #ifdef VBE_INFO
    851     if (pTrident->vbeModes) {
    852         vbeSaveRestoreRec vbesr;
    853         vbesr.stateMode = VBECalcVbeModeIndex(pTrident->vbeModes,
    854                 mode, pScrn->bitsPerPixel);
    855         vbesr.pstate = NULL;
    856         if (vbesr.stateMode) {
    857             if (IsPciCard && UseMMIO)
    858                 TRIDENTDisableMMIO(pScrn);
    859             VBEVesaSaveRestore(pTrident->pVbe,&vbesr,MODE_RESTORE);
    860             if (IsPciCard && UseMMIO)
    861                 TRIDENTEnableMMIO(pScrn);
    862             return;
    863         } else
    864             xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"No BIOS Mode matches "
    865                     "%ix%I@%ibpp\n",mode->HDisplay,mode->VDisplay,
    866                     pScrn->bitsPerPixel);
    867     }
    868 #endif
    869     /* This function is only for LCD screens, and also when we have
    870      * int10 available */
    871 
    872     if (pTrident->IsCyber && pTrident->lcdMode && pTrident->Int10) {
    873         int i = pTrident->lcdMode;
    874         if ((pScrn->currentMode->HDisplay != LCD[i].display_x) /* !fullsize? */
    875                 || (pScrn->currentMode->VDisplay != LCD[i].display_y)) {
    876             if (pTrident->lcdActive)  { /* LCD Active ?*/
    877                 int h_str, v_str;
    878 
    879                 OUTB(0x3CE,HorStretch);  h_str = INB(0x3CF) & 0x01;
    880                 OUTB(0x3CE,VertStretch); v_str = INB(0x3CF) & 0x01;
    881                 if (h_str || v_str) {
    882                     OUTB(0x3C4, 0x11); OUTB(0x3C5, 0x92);
    883                     OUTW(0x3CE, BiosReg );
    884                     pTrident->Int10->ax = 0x3;
    885                     pTrident->Int10->num = 0x10;
    886                     if (IsPciCard && UseMMIO)
    887                         TRIDENTDisableMMIO(pScrn);
    888                     xf86ExecX86int10(pTrident->Int10);
    889                     if (IsPciCard && UseMMIO)
    890                         TRIDENTEnableMMIO(pScrn);
    891                 }
    892             }
    893         }
    894     }
    895 }
    896 
    897 /* Currently we only test for 1400 */
    898 static int
    899 TRIDENTLcdDisplaySize (xf86MonPtr pMon)
    900 {
    901     if (pMon) {
    902         int i,j;
    903 
    904         for (i = 0; i < STD_TIMINGS; i++) {
    905             if (pMon->timings2[i].hsize == 1400) {
    906                 return 1400;
    907             }
    908         }
    909         /*
    910          * If not explicitly set try to find out if the display supports
    911          * the 1400 mode. For sanity check if DDC comes from a digital
    912          * display.
    913          */
    914         if (DIGITAL(pMon->features.input_type)) {
    915             for (i = 0; i < DET_TIMINGS; i++) {
    916                 if (pMon->det_mon[i].type == DS_STD_TIMINGS) {
    917                     for (j = 0; j < 5; j++) {
    918                         if (pMon->det_mon[i].section.std_t[j].hsize == 1400) {
    919                             return 1400;
    920                         }
    921                     }
    922                 } else if (pMon->det_mon[i].type == DT) {
    923                     if (pMon->det_mon[i].section.d_timings.h_active == 1400) {
    924                         return 1400;
    925                     }
    926                 }
    927             }
    928         }
    929     }
    930     return 0;
    931 }
    932 
    933 /*
    934  * Initialise a new mode.  This is currently still using the old
    935  * "initialise struct, restore/write struct to HW" model.  That could
    936  * be changed.
    937  */
    938 
    939 static Bool
    940 TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
    941 {
    942     vgaHWPtr hwp = VGAHWPTR(pScrn);
    943     vgaRegPtr vgaReg;
    944     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
    945     TRIDENTRegPtr tridentReg;
    946 
    947 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
    948     if (!xf86IsPc98())
    949 #endif
    950         WAITFORVSYNC;
    951 
    952     TridentFindClock(pScrn,mode->Clock);
    953 
    954     switch (pTrident->Chipset) {
    955     case TGUI9660:
    956     case TGUI9680:
    957     case PROVIDIA9682:
    958     case PROVIDIA9685:
    959     case IMAGE975:
    960     case IMAGE985:
    961     case BLADE3D:
    962     case CYBERBLADEI7:
    963     case CYBERBLADEI7D:
    964     case CYBERBLADEI1:
    965     case CYBERBLADEI1D:
    966     case CYBERBLADEAI1:
    967     case CYBERBLADEAI1D:
    968     case CYBER9520:
    969     case CYBER9525DVD:
    970     case CYBERBLADEE4:
    971     case CYBER9397:
    972     case CYBER9397DVD:
    973     case BLADEXP:
    974     case CYBERBLADEXPAI1:
    975     case CYBERBLADEXP4:
    976     case XP5:
    977         /* Get ready for MUX mode */
    978         if (pTrident->MUX &&
    979                 pScrn->bitsPerPixel == 8 &&
    980                 !mode->CrtcHAdjusted) {
    981             ErrorF("BARF\n");
    982             mode->CrtcHDisplay >>= 1;
    983             mode->CrtcHSyncStart >>= 1;
    984             mode->CrtcHSyncEnd >>= 1;
    985             mode->CrtcHBlankStart >>= 1;
    986             mode->CrtcHBlankEnd >>= 1;
    987             mode->CrtcHTotal >>= 1;
    988             mode->CrtcHAdjusted = TRUE;
    989         }
    990         break;
    991     default:
    992         if (pScrn->videoRam < 1024 &&
    993                 !mode->CrtcHAdjusted) {
    994             mode->CrtcHDisplay <<= 1;
    995             mode->CrtcHSyncStart <<= 1;
    996             mode->CrtcHSyncEnd <<= 1;
    997             mode->CrtcHBlankStart <<= 1;
    998             mode->CrtcHBlankEnd <<= 1;
    999             mode->CrtcHTotal <<= 1;
   1000             mode->CrtcHAdjusted = TRUE;
   1001         }
   1002         break;
   1003     }
   1004 
   1005     vgaHWUnlock(hwp);
   1006     /* Initialise the ModeReg values */
   1007     if (!vgaHWInit(pScrn, mode))
   1008         return FALSE;
   1009 
   1010     pScrn->vtSema = TRUE;
   1011     /*
   1012      * We used to do this at a later time.
   1013      * Now since READOUT isn't defined any more
   1014      * we do it here.
   1015      * The original NOTE read:
   1016      * TridentInit() has to modify registers
   1017      * that have already been set by vgaHWRestore().
   1018      * So we call it _after_ vgaHWRestore() has
   1019      * programmed these registers.
   1020      */
   1021     if (pScrn->progClock) {
   1022         if (!TridentInit(pScrn, mode))
   1023             return FALSE;
   1024     } else {
   1025         if (!TVGAInit(pScrn, mode))
   1026             return FALSE;
   1027     }
   1028 
   1029     /* Program the registers */
   1030     vgaHWProtect(pScrn, TRUE);
   1031     vgaReg = &hwp->ModeReg;
   1032     tridentReg = &pTrident->ModeReg;
   1033 
   1034     vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
   1035     if (pScrn->progClock)
   1036         TridentRestore(pScrn, tridentReg);
   1037     else
   1038         TVGARestore(pScrn, tridentReg);
   1039 
   1040     vgaHWProtect(pScrn, FALSE);
   1041 
   1042 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
   1043     if (xf86IsPc98())
   1044         PC98TRIDENTEnable(pScrn);
   1045 #endif
   1046 
   1047     if (pTrident->TVChipset != 0)
   1048         VIA_TVInit(pScrn);
   1049 
   1050     return TRUE;
   1051 }
   1052 
   1053 static Bool
   1054 TRIDENTGetRec(ScrnInfoPtr pScrn)
   1055 {
   1056     /*
   1057      * Allocate an TRIDENTRec, and hook it into pScrn->driverPrivate.
   1058      * pScrn->driverPrivate is initialised to NULL, so we can check if
   1059      * the allocation has already been done.
   1060      */
   1061     if (pScrn->driverPrivate != NULL)
   1062         return TRUE;
   1063 
   1064     pScrn->driverPrivate = xnfcalloc(sizeof(TRIDENTRec), 1);
   1065     /* Initialise it */
   1066 
   1067     return TRUE;
   1068 }
   1069 
   1070 static void
   1071 TRIDENTFreeRec(ScrnInfoPtr pScrn)
   1072 {
   1073     if (pScrn->driverPrivate == NULL)
   1074         return;
   1075     free(pScrn->driverPrivate);
   1076     pScrn->driverPrivate = NULL;
   1077 }
   1078 
   1079 
   1080 /*
   1081  * This function saves the video state.
   1082  */
   1083 static void
   1084 TRIDENTSave(ScrnInfoPtr pScrn)
   1085 {
   1086     TRIDENTPtr pTrident;
   1087     vgaRegPtr vgaReg;
   1088     TRIDENTRegPtr tridentReg;
   1089 
   1090     pTrident = TRIDENTPTR(pScrn);
   1091     vgaReg = &VGAHWPTR(pScrn)->SavedReg;
   1092     tridentReg = &pTrident->SavedReg;
   1093 
   1094     vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP |
   1095             (IsPrimaryCard ? VGA_SR_FONTS : 0));
   1096 
   1097     if (pScrn->progClock)
   1098         TridentSave(pScrn, tridentReg);
   1099     else
   1100         TVGASave(pScrn, tridentReg);
   1101 
   1102     if (pTrident->TVChipset != 0)
   1103         VIA_SaveTVDepentVGAReg(pScrn);
   1104 }
   1105 
   1106 
   1107 /*
   1108  * Restore the initial (text) mode.
   1109  */
   1110 static void
   1111 TRIDENTRestore(ScrnInfoPtr pScrn)
   1112 {
   1113     vgaHWPtr hwp;
   1114     vgaRegPtr vgaReg;
   1115     TRIDENTPtr pTrident;
   1116     TRIDENTRegPtr tridentReg;
   1117 
   1118     hwp = VGAHWPTR(pScrn);
   1119     pTrident = TRIDENTPTR(pScrn);
   1120     vgaReg = &hwp->SavedReg;
   1121     tridentReg = &pTrident->SavedReg;
   1122 
   1123     vgaHWProtect(pScrn, TRUE);
   1124 
   1125     if (pScrn->progClock)
   1126         TridentRestore(pScrn, tridentReg);
   1127     else
   1128         TVGARestore(pScrn, tridentReg);
   1129 
   1130     vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP |
   1131             (IsPrimaryCard ? VGA_SR_FONTS : 0));
   1132 
   1133     if (pTrident->TVChipset != 0)
   1134         VIA_RestoreTVDependVGAReg(pScrn);
   1135 
   1136     vgaHWProtect(pScrn, FALSE);
   1137 }
   1138 
   1139 /* Usually mandatory */
   1140 Bool
   1141 TRIDENTSwitchMode(SWITCH_MODE_ARGS_DECL)
   1142 {
   1143     SCRN_INFO_PTR(arg);
   1144     return TRIDENTModeInit(pScrn, mode);
   1145 }
   1146 
   1147 
   1148 /*
   1149  * This function is used to initialize the Start Address - the first
   1150  * displayed location in the video memory.
   1151  */
   1152 /* Usually mandatory */
   1153 void
   1154 TRIDENTAdjustFrame(ADJUST_FRAME_ARGS_DECL)
   1155 {
   1156     SCRN_INFO_PTR(arg);
   1157     TRIDENTPtr pTrident;
   1158     int base = y * pScrn->displayWidth + x;
   1159     int vgaIOBase;
   1160     CARD8 temp;
   1161 
   1162     pTrident = TRIDENTPTR(pScrn);
   1163     vgaIOBase = VGAHWPTR(pScrn)->IOBase;
   1164 
   1165     switch (pScrn->bitsPerPixel) {
   1166     case 8:
   1167         if (pScrn->progClock)
   1168             base = (base & 0xFFFFFFF8) >> 2;
   1169         else
   1170             base = (base & 0xFFFFFFF8) >> 3;
   1171         break;
   1172     case 16:
   1173         base >>= 1;
   1174         break;
   1175     case 24:
   1176         base = (((base + 1) & ~0x03) * 3) >> 2;
   1177         break;
   1178     case 32:
   1179         break;
   1180     }
   1181 
   1182     /* CRT bits 0-15 */
   1183     OUTW(vgaIOBase + 4, (base & 0x00FF00) | 0x0C);
   1184     OUTW(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D);
   1185     /* CRT bit 16 */
   1186     OUTB(vgaIOBase + 4, CRTCModuleTest); temp = INB(vgaIOBase + 5) & 0xDF;
   1187     OUTB(vgaIOBase + 5, temp | ((base & 0x10000) >> 11));
   1188     /* CRT bit 17-19 */
   1189     OUTB(vgaIOBase + 4, CRTHiOrd); temp = INB(vgaIOBase + 5) & 0xF8;
   1190     OUTB(vgaIOBase + 5, temp | ((base & 0xE0000) >> 17));
   1191 }
   1192 
   1193 
   1194 /*
   1195  * This is called when VT switching back to the X server.  Its job is
   1196  * to reinitialise the video mode.
   1197  */
   1198 
   1199 /* Mandatory */
   1200 static Bool
   1201 TRIDENTEnterVT(VT_FUNC_ARGS_DECL)
   1202 {
   1203     SCRN_INFO_PTR(arg);
   1204     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
   1205 
   1206     if (IsPciCard && UseMMIO) TRIDENTEnableMMIO(pScrn);
   1207 
   1208     /* Should we re-save the text mode on each VT enter? */
   1209     if (!TRIDENTModeInit(pScrn, pScrn->currentMode))
   1210         return FALSE;
   1211 
   1212     if (pTrident->InitializeAccelerator)
   1213         pTrident->InitializeAccelerator(pScrn);
   1214 
   1215     return TRUE;
   1216 }
   1217 
   1218 
   1219 /*
   1220  * This is called when VT switching away from the X server.  Its job is
   1221  * to restore the previous (text) mode.
   1222  *
   1223  * We may wish to remap video/MMIO memory too.
   1224  */
   1225 
   1226 /* Mandatory */
   1227 static void
   1228 TRIDENTLeaveVT(VT_FUNC_ARGS_DECL)
   1229 {
   1230     SCRN_INFO_PTR(arg);
   1231     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
   1232     vgaHWPtr hwp = VGAHWPTR(pScrn);
   1233 
   1234 #ifdef HAVE_XAA_H
   1235     if (!pTrident->NoAccel && !pTrident->useEXA)
   1236         pTrident->AccelInfoRec->Sync(pScrn);
   1237     else
   1238 #endif
   1239         if (!pTrident->NoAccel && pTrident->useEXA)
   1240             pTrident->EXADriverPtr->WaitMarker(pScrn->pScreen, 0);
   1241 
   1242     TRIDENTRestore(pScrn);
   1243     vgaHWLock(hwp);
   1244 
   1245 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
   1246     if (xf86IsPc98())
   1247         PC98TRIDENTDisable(pScrn);
   1248 #endif
   1249 
   1250     if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn);
   1251 }
   1252 
   1253 
   1254 /* Free up any per-generation data structures */
   1255 
   1256 /* Optional */
   1257 static void
   1258 TRIDENTFreeScreen(FREE_SCREEN_ARGS_DECL)
   1259 {
   1260     SCRN_INFO_PTR(arg);
   1261     if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
   1262         vgaHWFreeHWRec(pScrn);
   1263     TRIDENTFreeRec(pScrn);
   1264 }
   1265 
   1266 
   1267 /* Checks if a mode is suitable for the selected chipset. */
   1268 
   1269 /* Optional */
   1270 static ModeStatus
   1271 TRIDENTValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
   1272 {
   1273     SCRN_INFO_PTR(arg);
   1274     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
   1275 
   1276     if (pTrident->lcdActive && (pTrident->lcdMode != 0xff)){
   1277         if (((mode->HDisplay > LCD[pTrident->lcdMode].display_x)
   1278                 || (mode->VDisplay > LCD[pTrident->lcdMode].display_y))) {
   1279             xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Removing mode (%dx%d) "
   1280                     "larger than the LCD panel (%dx%d)\n",
   1281                     mode->HDisplay,
   1282                     mode->VDisplay,
   1283                     LCD[pTrident->lcdMode].display_x,
   1284                     LCD[pTrident->lcdMode].display_y);
   1285             return(MODE_BAD);
   1286         }
   1287         if (((float)mode->HDisplay/(float)mode->VDisplay) > 2.0) {
   1288             xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Removing mode (%dx%d) "
   1289                     "unusual aspect ratio\n",
   1290                     mode->HDisplay,
   1291                     mode->VDisplay);
   1292             return(MODE_BAD);
   1293         }
   1294     }
   1295     return (MODE_OK);
   1296 }
   1297 
   1298 static void
   1299 TRIDENTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
   1300 {
   1301     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
   1302     CARD8 DPMSCont, PMCont, temp;
   1303 
   1304     if (!pScrn->vtSema)
   1305         return;
   1306 
   1307     OUTB(0x3C4, 0x0E);
   1308     temp = INB(0x3C5);
   1309     OUTB(0x3C5, 0xC2);
   1310     OUTB(0x83C8, 0x04); /* Read DPMS Control */
   1311     PMCont = INB(0x83C6) & 0xFC;
   1312     OUTB(0x3CE, 0x23);
   1313     DPMSCont = INB(0x3CF) & 0xFC;
   1314     switch (PowerManagementMode)
   1315     {
   1316     case DPMSModeOn:
   1317         /* Screen: On, HSync: On, VSync: On */
   1318         PMCont |= 0x03;
   1319         DPMSCont |= 0x00;
   1320         break;
   1321     case DPMSModeStandby:
   1322         /* Screen: Off, HSync: Off, VSync: On */
   1323         PMCont |= 0x02;
   1324         DPMSCont |= 0x01;
   1325         break;
   1326     case DPMSModeSuspend:
   1327         /* Screen: Off, HSync: On, VSync: Off */
   1328         PMCont |= 0x02;
   1329         DPMSCont |= 0x02;
   1330         break;
   1331     case DPMSModeOff:
   1332         /* Screen: Off, HSync: Off, VSync: Off */
   1333         PMCont |= 0x00;
   1334         DPMSCont |= 0x03;
   1335         break;
   1336     }
   1337     OUTB(0x3CF, DPMSCont);
   1338     OUTB(0x83C8, 0x04);
   1339     OUTB(0x83C6, PMCont);
   1340     OUTW(0x3C4, (temp<<8) | 0x0E);
   1341 }
   1342 
   1343 static void
   1344 TRIDENTBlockHandler (BLOCKHANDLER_ARGS_DECL)
   1345 {
   1346     SCREEN_PTR(arg);
   1347     ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
   1348     TRIDENTPtr     pTrident = TRIDENTPTR(pScrn);
   1349 
   1350     pScreen->BlockHandler = pTrident->BlockHandler;
   1351     (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
   1352     pScreen->BlockHandler = TRIDENTBlockHandler;
   1353 
   1354     if(pTrident->VideoTimerCallback) {
   1355         UpdateCurrentTime();
   1356         (*pTrident->VideoTimerCallback)(pScrn, currentTime.milliseconds);
   1357     }
   1358 }
   1359 
   1360 static const OptionInfoRec *
   1361 TRIDENTAvailableOptions(int chipid, int busid)
   1362 {
   1363     return TRIDENTOptions;
   1364 }
   1365 
   1366 /* Mandatory */
   1367 static void
   1368 TRIDENTIdentify(int flags)
   1369 {
   1370     xf86PrintChipsets(TRIDENT_NAME, "driver for Trident chipsets", TRIDENTChipsets);
   1371 }
   1372 
   1373 Bool
   1374 TRIDENTClockSelect(ScrnInfoPtr pScrn, int no)
   1375 {
   1376     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
   1377     unsigned char temp;
   1378 
   1379     /*
   1380      * CS0 and CS1 are in MiscOutReg
   1381      *
   1382      * For 8900B, 8900C, 8900CL and 9000, CS2 is bit 0 of
   1383      * New Mode Control Register 2.
   1384      *
   1385      * For 8900CL, CS3 is bit 4 of Old Mode Control Register 1.
   1386      *
   1387      * For 9000, CS3 is bit 6 of New Mode Control Register 2.
   1388      *
   1389      * For TGUI, we don't use the ClockSelect function at all.
   1390      */
   1391     switch(no) {
   1392     case CLK_REG_SAVE:
   1393         pTrident->SaveClock1 = INB(0x3CC);
   1394         if (pTrident->Chipset != TVGA8800CS) {
   1395             if ( (pScrn->numClocks == 16) &&
   1396                     (pTrident->Chipset != TVGA9000) &&
   1397                     (pTrident->Chipset != TVGA9000i) )
   1398             {
   1399                 OUTW(0x3C4, 0x000B);	/* Switch to Old Mode */
   1400                 OUTB(0x3C4, 0x0E); pTrident->SaveClock3 = INB(0x3C5);
   1401             }
   1402             OUTB(0x3C4, 0x0B);
   1403             INB(0x3C5);		/* Now to New Mode */
   1404             OUTB(0x3C4, 0x0D); pTrident->SaveClock2 = INB(0x3C5);
   1405         }
   1406         break;
   1407     case CLK_REG_RESTORE:
   1408         OUTB(0x3C2, pTrident->SaveClock1);
   1409         if (pTrident->Chipset != TVGA8800CS) {
   1410             if ( (pScrn->numClocks == 16) &&
   1411                     (pTrident->Chipset != TVGA9000) &&
   1412                     (pTrident->Chipset != TVGA9000i) )
   1413             {
   1414                 OUTW(0x3C4, 0x000B);	/* Switch to Old Mode */
   1415                 OUTW(0x3C4, (pTrident->SaveClock3 << 8) | 0x0E);
   1416             }
   1417             OUTB(0x3C4, 0x0B);
   1418             INB(0x3C5);		/* Now to New Mode */
   1419             OUTW(0x3C4, (pTrident->SaveClock2 << 8) | 0x0D);
   1420         }
   1421         break;
   1422     default:
   1423         /*
   1424          * Do CS0 and CS1
   1425          */
   1426         temp = INB(0x3CC);
   1427         OUTB(0x3C2, (temp & 0xF3) | ((no << 2) & 0x0C));
   1428         if (pTrident->Chipset != TVGA8800CS) {
   1429             if ( (pScrn->numClocks == 16) &&
   1430                     (pTrident->Chipset != TVGA9000) &&
   1431                     (pTrident->Chipset != TVGA9000i) )
   1432             {
   1433                 /*
   1434                  * Go to Old Mode for CS3.
   1435                  */
   1436                 OUTW(0x3C4, 0x000B);	/* Switch to Old Mode */
   1437                 OUTB(0x3C4, 0x0E);
   1438                 temp = INB(0x3C5) & 0xEF;
   1439                 temp |= (no & 0x08) << 1;
   1440                 OUTB(0x3C5, temp);
   1441             }
   1442             /*
   1443              * Go to New Mode for CS2 and TVGA9000 CS3.
   1444              */
   1445             OUTB(0x3C4, 0x0B);
   1446             INB(0x3C5);		/* Now to New Mode */
   1447             OUTB(0x3C4, 0x0D);
   1448             /*
   1449              * Bits 1 & 2 are dividers - set to 0 to get no
   1450              * clock division.
   1451              */
   1452             temp = INB(0x3C5) & 0xF8;
   1453             temp |= (no & 0x04) >> 2;
   1454             if ( (pTrident->Chipset == TVGA9000) ||
   1455                     (pTrident->Chipset == TVGA9000i) )
   1456             {
   1457                 temp &= ~0x40;
   1458                 temp |= (no & 0x08) << 3;
   1459             }
   1460             OUTB(0x3C5, temp);
   1461         }
   1462     }
   1463     return(TRUE);
   1464 }
   1465 
   1466 #ifdef HAVE_ISA
   1467 static int
   1468 TridentFindIsaDevice(GDevPtr dev)
   1469 {
   1470     int found = -1;
   1471     unsigned char temp, origVal, newVal;
   1472 
   1473     /*
   1474      * Check first that we have a Trident card.
   1475      */
   1476     outb(0x3C4, 0x0B);
   1477     temp = inb(0x3C5);	/* Save old value */
   1478     outb(0x3C4, 0x0B);	/* Switch to Old Mode */
   1479     outb(0x3C5, 0x00);
   1480     inb(0x3C5);		/* Now to New Mode */
   1481     outb(0x3C4, 0x0E);
   1482     origVal = inb(0x3C5);
   1483     outb(0x3C5, 0x00);
   1484     newVal = inb(0x3C5) & 0x0F;
   1485     outb(0x3C5, (origVal ^ 0x02));
   1486 
   1487     /*
   1488      * Is it a Trident card ??
   1489      */
   1490     if (newVal != 2) {
   1491         /*
   1492          * Nope, so quit
   1493          */
   1494         outb(0x3C4, 0x0B);	/* Restore value of 0x0B */
   1495         outb(0x3C5, temp);
   1496         outb(0x3C4, 0x0E);
   1497         outb(0x3C5, origVal);
   1498         return found;
   1499     }
   1500 
   1501     outb(0x3C4, 0x0B);
   1502     temp = inb(0x3C5);
   1503     switch (temp) {
   1504     case 0x01:
   1505         found = TVGA8800BR;
   1506         break;
   1507     case 0x02:
   1508         found = TVGA8800CS;
   1509         break;
   1510     case 0x03:
   1511         found = TVGA8900B;
   1512         break;
   1513     case 0x04:
   1514     case 0x13:
   1515         found = TVGA8900C;
   1516         break;
   1517     case 0x23:
   1518         found = TVGA9000;
   1519         break;
   1520     case 0x33:
   1521         found = TVGA8900D;
   1522         break;
   1523     case 0x43:
   1524         found = TVGA9000i;
   1525         break;
   1526     case 0x53:
   1527         found = TVGA9200CXr;
   1528         break;
   1529     case 0x63:
   1530         found = TVGA9100B;
   1531         break;
   1532     case 0x73:
   1533     case 0xC3:
   1534         found = TGUI9420DGi;
   1535         break;
   1536     case 0x83:
   1537         found = TVGA8200LX;
   1538         break;
   1539     case 0x93:
   1540         found = TGUI9400CXi;
   1541         break;
   1542     case 0xA3:
   1543         found = CYBER9320;
   1544         break;
   1545     case 0xD3:
   1546         found = TGUI9660;
   1547         break;
   1548     case 0xE3:
   1549         found = TGUI9440AGi;
   1550         break;
   1551     case 0xF3:
   1552         found = TGUI9430DGi;
   1553         break;
   1554     }
   1555     return found;
   1556 }
   1557 #endif
   1558 
   1559 /*
   1560  * Map the framebuffer and MMIO memory.
   1561  */
   1562 
   1563 static Bool
   1564 TRIDENTMapMem(ScrnInfoPtr pScrn)
   1565 {
   1566     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
   1567     vgaHWPtr hwp = VGAHWPTR(pScrn);
   1568     int mapsize = 0x10000;
   1569 
   1570     if (Is3Dchip) mapsize = 0x20000;
   1571 
   1572     if (IsPciCard && UseMMIO)
   1573 #ifndef XSERVER_LIBPCIACCESS
   1574         pTrident->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
   1575                 pTrident->PciTag, pTrident->IOAddress, mapsize);
   1576 #else
   1577     {
   1578         void **result = (void **)&pTrident->IOBase;
   1579         int err = pci_device_map_range(pTrident->PciInfo,
   1580                 pTrident->IOAddress,
   1581                 mapsize,
   1582                 PCI_DEV_MAP_FLAG_WRITABLE,
   1583                 result);
   1584         if (err) {
   1585             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1586                     "Unable to map IO aperture. %s (%d)\n",
   1587                     strerror(err), err);
   1588         }
   1589     }
   1590 #endif
   1591     else {
   1592 #ifndef XSERVER_LIBPCIACCESS
   1593         pTrident->IOBase = xf86MapDomainMemory(pScrn->scrnIndex, VIDMEM_MMIO,
   1594                 pTrident->PciTag, pTrident->IOAddress, 0x1000);
   1595         pTrident->IOBase += 0xF00;
   1596 #else
   1597         return FALSE;
   1598 #endif
   1599     }
   1600 
   1601     if (pTrident->IOBase == NULL)
   1602         return FALSE;
   1603 
   1604     if (LINEAR()) {
   1605         if (pTrident->FbMapSize != 0) {
   1606 #ifndef XSERVER_LIBPCIACCESS
   1607             pTrident->FbBase = xf86MapPciMem(pScrn->scrnIndex,
   1608                     VIDMEM_FRAMEBUFFER,
   1609                     pTrident->PciTag,
   1610                     (unsigned long)pTrident->FbAddress,
   1611                     pTrident->FbMapSize);
   1612 #else
   1613             {
   1614                 void **result = (void **)&pTrident->FbBase;
   1615                 int err = pci_device_map_range(pTrident->PciInfo,
   1616                         pTrident->FbAddress,
   1617                         pTrident->FbMapSize,
   1618                         PCI_DEV_MAP_FLAG_WRITABLE |
   1619                         PCI_DEV_MAP_FLAG_WRITE_COMBINE,
   1620                         result);
   1621                 if (err) {
   1622                     xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1623                             "Unable to map VRAM aperture. %s (%d)\n",
   1624                             strerror(err), err);
   1625                 }
   1626             }
   1627 #endif
   1628             if (pTrident->FbBase == NULL)
   1629                 return FALSE;
   1630         }
   1631     }
   1632     else
   1633         pTrident->FbBase = hwp->Base;
   1634 
   1635     return TRUE;
   1636 }
   1637 
   1638 /*
   1639  * Unmap the framebuffer and MMIO memory.
   1640  */
   1641 
   1642 static Bool
   1643 TRIDENTUnmapMem(ScrnInfoPtr pScrn)
   1644 {
   1645     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
   1646     int mapsize = 0x10000;
   1647 
   1648     if (Is3Dchip) mapsize = 0x20000;
   1649 
   1650     /*
   1651      * Unmap IO registers to virtual address space
   1652      */
   1653 #ifdef XSERVER_LIBPCIACCESS
   1654     pci_device_unmap_range(pTrident->PciInfo, (pointer)pTrident->IOBase, mapsize);
   1655 #else
   1656     if (IsPciCard && UseMMIO) {
   1657         xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, mapsize);
   1658     } else {
   1659         pTrident->IOBase -= 0xF00;
   1660         xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, 0x1000);
   1661     }
   1662 #endif
   1663     pTrident->IOBase = NULL;
   1664 
   1665     if (LINEAR()) {
   1666         if (pTrident->FbMapSize != 0) {
   1667 #ifdef XSERVER_LIBPCIACCESS
   1668             pci_device_unmap_range(pTrident->PciInfo, (pointer)pTrident->FbBase, pTrident->FbMapSize);
   1669 #else
   1670             xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->FbBase,
   1671                     pTrident->FbMapSize);
   1672 #endif
   1673             pTrident->FbBase = NULL;
   1674         }
   1675     }
   1676 
   1677     return TRUE;
   1678 }
   1679 
   1680 /*
   1681  * GetAccelPitchValues -
   1682  *
   1683  * This function returns a list of display width (pitch) values that can
   1684  * be used in accelerated mode.
   1685  */
   1686 static int *
   1687 GetAccelPitchValues(ScrnInfoPtr pScrn)
   1688 {
   1689     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
   1690     int *linePitches = NULL;
   1691     int lines[4] = { 512, 1024, 2048, 4096 }; /* 9440AGi */
   1692     int i, n = 0;
   1693 
   1694     if (pTrident->Chipset >= BLADEXP) {
   1695         lines[0] = 1024;
   1696         lines[1] = 2048;
   1697         lines[2] = 4096;
   1698         lines[3] = 8192;
   1699     }
   1700 
   1701     for (i = 0; i < 4; i++) {
   1702         n++;
   1703         linePitches = xnfrealloc(linePitches, n * sizeof(int));
   1704         linePitches[n - 1] = lines[i];
   1705     }
   1706 
   1707     /* Mark the end of the list */
   1708     if (n > 0) {
   1709         linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
   1710         linePitches[n] = 0;
   1711     }
   1712     return linePitches;
   1713 }
   1714 
   1715 static void
   1716 TRIDENTProbeDDC(ScrnInfoPtr pScrn, int index)
   1717 {
   1718     vbeInfoPtr pVbe;
   1719     if (xf86LoadSubModule(pScrn, "vbe")) {
   1720         pVbe = VBEInit(NULL,index);
   1721         ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
   1722         vbeFree(pVbe);
   1723     }
   1724 }
   1725 
   1726 static void
   1727 TRIDENTProtect(ScrnInfoPtr pScrn, Bool on)
   1728 {
   1729     vgaHWProtect(pScrn, on);
   1730 }
   1731 
   1732 static void
   1733 TRIDENTBlankScreen(ScrnInfoPtr pScrn, Bool on)
   1734 {
   1735     vgaHWBlankScreen(pScrn, on);
   1736 }
   1737 
   1738 /* Mandatory */
   1739 static Bool
   1740 TRIDENTProbe(DriverPtr drv, int flags)
   1741 {
   1742     int i;
   1743     GDevPtr *devSections;
   1744     int *usedChips = NULL;
   1745     int numDevSections;
   1746     int numUsed;
   1747     Bool foundScreen = FALSE;
   1748 
   1749     if ((numDevSections = xf86MatchDevice(TRIDENT_DRIVER_NAME,
   1750             &devSections)) <= 0) {
   1751         /*
   1752          * There's no matching device section in the config file, so quit
   1753          * now.
   1754          */
   1755         return FALSE;
   1756     }
   1757 
   1758     /*
   1759      * While we're VGA-dependent, can really only have one such instance, but
   1760      * we'll ignore that.
   1761      */
   1762 
   1763     /*
   1764      * We need to probe the hardware first.  We then need to see how this
   1765      * fits in with what is given in the config file, and allow the config
   1766      * file info to override any contradictions.
   1767      */
   1768 
   1769     /*
   1770      * All of the cards this driver supports are PCI, so the "probing" just
   1771      * amounts to checking the PCI data that the server has already collected.
   1772      */
   1773 #ifndef XSERVER_LIBPCIACCESS
   1774     if (xf86GetPciVideoInfo()== NULL) {
   1775         return FALSE;
   1776     }
   1777 #endif
   1778     {
   1779         numUsed = xf86MatchPciInstances(TRIDENT_NAME, PCI_VENDOR_TRIDENT,
   1780                 TRIDENTChipsets, TRIDENTPciChipsets, devSections,
   1781                 numDevSections, drv, &usedChips);
   1782 
   1783         if (numUsed > 0) {
   1784             if (flags & PROBE_DETECT)
   1785                 foundScreen = TRUE;
   1786             else for (i = 0; i < numUsed; i++) {
   1787                 ScrnInfoPtr pScrn = NULL;
   1788 
   1789                 if ((pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i],
   1790                         TRIDENTPciChipsets, NULL,
   1791                         NULL, NULL, NULL, NULL))) {
   1792                     /* Fill in what we can of the ScrnInfoRec */
   1793                     pScrn->driverVersion = TRIDENT_VERSION;
   1794                     pScrn->driverName	 = TRIDENT_DRIVER_NAME;
   1795                     pScrn->name		 = TRIDENT_NAME;
   1796                     pScrn->Probe	 = TRIDENTProbe;
   1797                     pScrn->PreInit	 = TRIDENTPreInit;
   1798                     pScrn->ScreenInit	 = TRIDENTScreenInit;
   1799                     pScrn->SwitchMode	 = TRIDENTSwitchMode;
   1800                     pScrn->AdjustFrame	 = TRIDENTAdjustFrame;
   1801                     pScrn->EnterVT	 = TRIDENTEnterVT;
   1802                     pScrn->LeaveVT	 = TRIDENTLeaveVT;
   1803                     pScrn->FreeScreen	 = TRIDENTFreeScreen;
   1804                     pScrn->ValidMode	 = TRIDENTValidMode;
   1805                     foundScreen = TRUE;
   1806                 }
   1807             }
   1808             free(usedChips);
   1809         }
   1810     }
   1811 
   1812 #ifdef HAVE_ISA
   1813     /* Isa Bus */
   1814     numUsed = xf86MatchIsaInstances(TRIDENT_NAME,TRIDENTChipsets,
   1815             TRIDENTISAchipsets,
   1816             drv,TridentFindIsaDevice,devSections,
   1817             numDevSections,&usedChips);
   1818     if (numUsed > 0) {
   1819         if (flags & PROBE_DETECT)
   1820             foundScreen = TRUE;
   1821         else 	for (i = 0; i < numUsed; i++) {
   1822             ScrnInfoPtr pScrn = NULL;
   1823             if ((pScrn = xf86ConfigIsaEntity(pScrn,0,usedChips[i],
   1824                     TRIDENTISAchipsets,NULL,
   1825                     NULL,NULL,NULL,NULL))) {
   1826                 pScrn->driverVersion = TRIDENT_VERSION;
   1827                 pScrn->driverName    = TRIDENT_DRIVER_NAME;
   1828                 pScrn->name          = TRIDENT_NAME;
   1829                 pScrn->Probe         = TRIDENTProbe;
   1830                 pScrn->PreInit       = TRIDENTPreInit;
   1831                 pScrn->ScreenInit    = TRIDENTScreenInit;
   1832                 pScrn->SwitchMode    = TRIDENTSwitchMode;
   1833                 pScrn->AdjustFrame   = TRIDENTAdjustFrame;
   1834                 pScrn->EnterVT       = TRIDENTEnterVT;
   1835                 pScrn->LeaveVT       = TRIDENTLeaveVT;
   1836                 pScrn->FreeScreen    = TRIDENTFreeScreen;
   1837                 pScrn->ValidMode     = TRIDENTValidMode;
   1838                 foundScreen = TRUE;
   1839             }
   1840         }
   1841         free(usedChips);
   1842     }
   1843 #endif
   1844 
   1845     free(devSections);
   1846     return foundScreen;
   1847 }
   1848 
   1849 /* Mandatory */
   1850 static Bool
   1851 TRIDENTPreInit(ScrnInfoPtr pScrn, int flags)
   1852 {
   1853     TRIDENTPtr pTrident;
   1854     vgaHWPtr hwp;
   1855     MessageType from;
   1856     CARD8 videoram, videorammask;
   1857     const char *ramtype = NULL, *chipset = NULL;
   1858     Bool Support24bpp;
   1859     int vgaIOBase;
   1860     float mclk;
   1861     double real;
   1862     int i, NoClocks = 16;
   1863     CARD8 revision;
   1864     ClockRangePtr clockRanges;
   1865     Bool ddcLoaded = FALSE;
   1866     xf86MonPtr pMon = NULL;
   1867     const char *s;
   1868     Bool tmp_bool;
   1869 
   1870     /* Allocate the TRIDENTRec driverPrivate */
   1871     if (!TRIDENTGetRec(pScrn)) {
   1872         return FALSE;
   1873     }
   1874     pTrident = TRIDENTPTR(pScrn);
   1875     pTrident->pScrn = pScrn;
   1876 
   1877     if (pScrn->numEntities > 1)
   1878         return FALSE;
   1879     /* This is the general case */
   1880     for (i = 0; i<pScrn->numEntities; i++) {
   1881         pTrident->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
   1882 #ifndef XSERVER_LIBPCIACCESS
   1883         if (pTrident->pEnt->resources) return FALSE;
   1884 #endif
   1885         pTrident->Chipset = pTrident->pEnt->chipset;
   1886         pScrn->chipset = (char *)xf86TokenToString(TRIDENTChipsets,
   1887                 pTrident->pEnt->chipset);
   1888         /* This driver can handle ISA and PCI buses */
   1889         if (pTrident->pEnt->location.type == BUS_PCI) {
   1890             pTrident->PciInfo = xf86GetPciInfoForEntity(pTrident->pEnt->index);
   1891 #ifndef XSERVER_LIBPCIACCESS
   1892             pTrident->PciTag = PCI_DEV_TAG(pTrident->PciInfo);
   1893 #endif
   1894             pTrident->Linear = TRUE;
   1895         } else {
   1896             pTrident->Linear = FALSE;
   1897         }
   1898     }
   1899 
   1900     if (flags & PROBE_DETECT) {
   1901         TRIDENTProbeDDC(pScrn, pTrident->pEnt->index);
   1902         return TRUE;
   1903     }
   1904 
   1905     /* Set pScrn->monitor */
   1906     pScrn->monitor = pScrn->confScreen->monitor;
   1907 
   1908     /*
   1909      * The first thing we should figure out is the depth, bpp, etc.
   1910      * Our preference for depth 24 is 24bpp, so tell it that too.
   1911      */
   1912     if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb |
   1913             SupportConvert32to24 /*| PreferConvert32to24*/)) {
   1914         return FALSE;
   1915     } else {
   1916         /* Check that the returned depth is one we support */
   1917         switch (pScrn->depth) {
   1918         case 8:
   1919             if (pScrn->bitsPerPixel != pScrn->depth) {
   1920                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1921                         "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
   1922                         pScrn->depth, pScrn->bitsPerPixel);
   1923                 return FALSE;
   1924             }
   1925             break;
   1926         case 15:
   1927         case 16:
   1928             if (pScrn->bitsPerPixel != 16) {
   1929                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1930                         "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
   1931                         pScrn->depth, pScrn->bitsPerPixel);
   1932                 return FALSE;
   1933             }
   1934             break;
   1935         case 24:
   1936             if ((pScrn->bitsPerPixel != 24) && (pScrn->bitsPerPixel != 32)) {
   1937                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1938                         "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
   1939                         pScrn->depth, pScrn->bitsPerPixel);
   1940                 return FALSE;
   1941             }
   1942             /* OK */
   1943             break;
   1944         default:
   1945             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1946                     "Given depth (%d) is not supported by this driver\n",
   1947                     pScrn->depth);
   1948             return FALSE;
   1949         }
   1950     }
   1951 
   1952     xf86PrintDepthBpp(pScrn);
   1953 
   1954     /* Get the depth24 pixmap format */
   1955     if (pScrn->depth == 24 && pix24bpp == 0)
   1956         pix24bpp = xf86GetBppFromDepth(pScrn, 24);
   1957 
   1958     /* The vgahw module should be loaded here when needed */
   1959     if (!xf86LoadSubModule(pScrn, "vgahw"))
   1960         return FALSE;
   1961 
   1962     /*
   1963      * Allocate a vgaHWRec
   1964      */
   1965     if (!vgaHWGetHWRec(pScrn))
   1966         return FALSE;
   1967 
   1968     hwp = VGAHWPTR(pScrn);
   1969     vgaHWSetStdFuncs(hwp);
   1970     vgaHWGetIOBase(hwp);
   1971     vgaIOBase = hwp->IOBase;
   1972 
   1973 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
   1974     pTrident->PIOBase = hwp->PIOOffset;
   1975 #else
   1976     pTrident->PIOBase = 0;
   1977 #endif
   1978 
   1979 #ifndef XSERVER_LIBPCIACCESS
   1980     xf86SetOperatingState(resVga, pTrident->pEnt->index, ResUnusedOpr);
   1981 #endif
   1982 
   1983     /* The ramdac module should be loaded here when needed */
   1984     if (!xf86LoadSubModule(pScrn, "ramdac"))
   1985         return FALSE;
   1986 
   1987     /*
   1988      * This must happen after pScrn->display has been set because
   1989      * xf86SetWeight references it.
   1990      */
   1991     if (pScrn->depth > 8) {
   1992         /* The defaults are OK for us */
   1993         rgb zeros = {0, 0, 0};
   1994 
   1995         if (!xf86SetWeight(pScrn, zeros, zeros)) {
   1996             return FALSE;
   1997         } else {
   1998             /* XXX check that weight returned is supported */
   1999             ;
   2000         }
   2001     }
   2002 
   2003     if (!xf86SetDefaultVisual(pScrn, -1)) {
   2004         return FALSE;
   2005     } else {
   2006         /* We don't currently support DirectColor at > 8bpp */
   2007         if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
   2008             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
   2009                     " (%s) is not supported at depth %d\n",
   2010                     xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
   2011             return FALSE;
   2012         }
   2013     }
   2014 
   2015     /*
   2016      * The new cmap layer needs this to be initialised.
   2017      */
   2018 
   2019     {
   2020         Gamma zeros = {0.0, 0.0, 0.0};
   2021 
   2022         if (!xf86SetGamma(pScrn, zeros)) {
   2023             return FALSE;
   2024         }
   2025     }
   2026 
   2027     /* Collect all of the relevant option flags (fill in pScrn->options) */
   2028     xf86CollectOptions(pScrn, NULL);
   2029 
   2030     /* Process the options */
   2031     if (!(pTrident->Options = malloc(sizeof(TRIDENTOptions))))
   2032         return FALSE;
   2033     memcpy(pTrident->Options, TRIDENTOptions, sizeof(TRIDENTOptions));
   2034     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTrident->Options);
   2035 
   2036     /* Set the bits per RGB for 8bpp mode */
   2037     if (pScrn->depth == 8) {
   2038         /* XXX This is here just to test options. */
   2039         /* Default to 8 */
   2040         pScrn->rgbBits = 6;
   2041 #if 0
   2042         if (xf86GetOptValInteger(pTrident->Options, OPTION_RGB_BITS,
   2043                 &pScrn->rgbBits)) {
   2044             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
   2045                     pScrn->rgbBits);
   2046         }
   2047 #endif
   2048     }
   2049     from = X_DEFAULT;
   2050 
   2051     pTrident->useEXA = FALSE;
   2052     if ((s = (char *)xf86GetOptValString(pTrident->Options,
   2053             OPTION_ACCELMETHOD))) {
   2054         if (!xf86NameCmp(s, "EXA")) {
   2055             pTrident->useEXA = TRUE;
   2056             from = X_CONFIG;
   2057         }
   2058         else if (!xf86NameCmp(s, "XAA")) {
   2059             pTrident->useEXA = FALSE;
   2060             from = X_CONFIG;
   2061         }
   2062     }
   2063     xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n",
   2064             pTrident->useEXA ? "EXA" : "XAA");
   2065 
   2066     pTrident->HWCursor = TRUE;
   2067     if (xf86ReturnOptValBool(pTrident->Options, OPTION_SW_CURSOR, FALSE)) {
   2068         from = X_CONFIG;
   2069         pTrident->HWCursor = FALSE;
   2070     }
   2071     if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOACCEL, FALSE)) {
   2072         pTrident->NoAccel = TRUE;
   2073         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
   2074     }
   2075     if (xf86ReturnOptValBool(pTrident->Options, OPTION_PCI_RETRY, FALSE)) {
   2076         pTrident->UsePCIRetry = TRUE;
   2077         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
   2078     }
   2079     pTrident->UsePCIBurst = TRUE;
   2080     if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOPCIBURST, FALSE)) {
   2081         pTrident->UsePCIBurst = FALSE;
   2082         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI Burst disabled\n");
   2083     }
   2084     /* Display Size override moved to DDC section */
   2085     if(xf86GetOptValInteger(pTrident->Options, OPTION_VIDEO_KEY,
   2086             &(pTrident->videoKey))) {
   2087         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
   2088                 pTrident->videoKey);
   2089     } else {
   2090         pTrident->videoKey =  (1 << pScrn->offset.red) |
   2091                 (1 << pScrn->offset.green) |
   2092                 (((pScrn->mask.blue >> pScrn->offset.blue) - 1)
   2093                         << pScrn->offset.blue);
   2094     }
   2095     if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOMMIO, FALSE)) {
   2096         pTrident->NoMMIO = TRUE;
   2097         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO Disabled\n");
   2098     }
   2099     if (xf86ReturnOptValBool(pTrident->Options, OPTION_MMIO_ONLY, FALSE)) {
   2100         if (pTrident->NoMMIO)
   2101             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MMIO only cannot be set"
   2102                     " with NoMMIO\n");
   2103         else {
   2104             pTrident->MMIOonly = TRUE;
   2105             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO only enabled\n");
   2106         }
   2107     }
   2108 
   2109     pTrident->dspOverride = 0;
   2110     if ((s = xf86GetOptValString(pTrident->Options, OPTION_DISPLAY))) {
   2111         if(!xf86NameCmp(s, "CRT")) {
   2112             pTrident->dspOverride = CRT_ACTIVE;
   2113             xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD off CRT on\n");
   2114         } else if (!xf86NameCmp(s, "LCD")) {
   2115             pTrident->dspOverride = LCD_ACTIVE;
   2116             xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT off\n");
   2117         } else if (!xf86NameCmp(s, "Dual")) {
   2118             pTrident->dspOverride = LCD_ACTIVE | CRT_ACTIVE;
   2119             xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT on\n");
   2120         } else
   2121             xf86DrvMsg(pScrn->scrnIndex,X_ERROR,
   2122                     "%s is an unknown display option\n",s);
   2123     }
   2124     if ((s = xf86GetOptValString(pTrident->Options, OPTION_GB))) {
   2125         int brightness = -1;
   2126         double gamma = -1.0;
   2127         Bool error = FALSE;
   2128         int i;
   2129 
   2130         i = sscanf(s,"%lf %i",&gamma,&brightness);
   2131 
   2132         if (i != 2 || brightness == -1 || gamma == -1.0) {
   2133             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   2134                     "Invalid Gamma/Brightness argument: %s\n",s);
   2135             error = TRUE;
   2136         } else {
   2137             if (brightness < 0 || brightness > 128) {
   2138                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   2139                         "brightness out of range [0,128]: %i\n",brightness);
   2140                 error = TRUE;
   2141             }
   2142             if (gamma <= 0.0 || gamma > 10.0) {
   2143                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   2144                         "gamma out of range (0,10.0]: %f\n",gamma);
   2145                 error = TRUE;
   2146             }
   2147         }
   2148 
   2149         if (!error) {
   2150             pTrident->GammaBrightnessOn = TRUE;
   2151             pTrident->gamma = gamma;
   2152             pTrident->brightness = brightness;
   2153             xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Gamma: %f Brightness: %i\n",
   2154                     gamma,brightness);
   2155         }
   2156     }
   2157 
   2158     /* The following is a temporary hack */
   2159     pTrident->FPDelay = 7; /* invalid value */
   2160     if (xf86GetOptValInteger(pTrident->Options, OPTION_FP_DELAY,
   2161             &pTrident->FPDelay)) {
   2162         if (pTrident->FPDelay < -2 || pTrident->FPDelay > 5) {
   2163             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "FPDelay %i out if range "
   2164                     "(-2 < FPDelay < 5)\n",pTrident->FPDelay);
   2165             pTrident->FPDelay = 7;
   2166         } else
   2167             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "FP Delay set to %i\n",
   2168                     pTrident->FPDelay);
   2169     }
   2170     if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_SHADOW, FALSE)) {
   2171         pTrident->CyberShadow = TRUE;
   2172         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Shadow enabled\n");
   2173     }
   2174     if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_STRETCH, FALSE)) {
   2175         pTrident->CyberStretch = TRUE;
   2176         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Stretch enabled\n");
   2177     }
   2178 
   2179     pTrident->MUXThreshold = 90000; /* 90MHz */
   2180     if (xf86GetOptValInteger(pTrident->Options, OPTION_MUX_THRESHOLD,
   2181             &pTrident->MUXThreshold)) {
   2182         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MUX Threshold set to %d\n",
   2183                 pTrident->MUXThreshold);
   2184     }
   2185     pTrident->OverrideHsync = 0;
   2186     if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC,
   2187             &pTrident->OverrideHsync)) {
   2188         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n",
   2189                 pTrident->OverrideHsync);
   2190     }
   2191     pTrident->OverrideVsync = 0;
   2192     if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC,
   2193             &pTrident->OverrideVsync)) {
   2194         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n",
   2195                 pTrident->OverrideVsync);
   2196     }
   2197     pTrident->OverrideHsync = 0;
   2198     if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC,
   2199             &pTrident->OverrideHsync)) {
   2200         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n",
   2201                 pTrident->OverrideHsync);
   2202     }
   2203     pTrident->OverrideVsync = 0;
   2204     if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC,
   2205             &pTrident->OverrideVsync)) {
   2206         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n",
   2207                 pTrident->OverrideVsync);
   2208     }
   2209     pTrident->OverrideRskew = 0;
   2210     if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_RSKEW,
   2211             &pTrident->OverrideRskew)) {
   2212         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Rskew set to %d\n",
   2213                 pTrident->OverrideRskew);
   2214     }
   2215     pTrident->OverrideBskew = 0;
   2216     if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_BSKEW,
   2217             &pTrident->OverrideBskew)) {
   2218         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Bskew set to %d\n",
   2219                 pTrident->OverrideBskew);
   2220     }
   2221     if (xf86ReturnOptValBool(pTrident->Options, OPTION_SHADOW_FB, FALSE)) {
   2222         if (!LINEAR())
   2223             xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option SHADOW_FB"
   2224                     " in non-Linear Mode\n");
   2225         else {
   2226             pTrident->ShadowFB = TRUE;
   2227             pTrident->NoAccel = TRUE;
   2228             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
   2229                     "Using \"Shadow Framebuffer\" - acceleration disabled\n");
   2230         }
   2231     }
   2232     pTrident->Rotate = 0;
   2233     if ((s = xf86GetOptValString(pTrident->Options, OPTION_ROTATE))) {
   2234         if (!LINEAR())
   2235             xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option ROTATE "
   2236                     "in non-Linear Mode\n");
   2237         else {
   2238             if(!xf86NameCmp(s, "CW")) {
   2239                 /* accel is disabled below for shadowFB */
   2240                 pTrident->ShadowFB = TRUE;
   2241                 pTrident->NoAccel = TRUE;
   2242                 pTrident->HWCursor = FALSE;
   2243                 pTrident->Rotate = 1;
   2244                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
   2245                         "Rotating screen clockwise - acceleration disabled\n");
   2246             } else if(!xf86NameCmp(s, "CCW")) {
   2247                 pTrident->ShadowFB = TRUE;
   2248                 pTrident->NoAccel = TRUE;
   2249                 pTrident->HWCursor = FALSE;
   2250                 pTrident->Rotate = -1;
   2251                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,  "Rotating screen"
   2252                         "counter clockwise - acceleration disabled\n");
   2253             } else {
   2254                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
   2255                         "value for Option \"Rotate\"\n", s);
   2256                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2257                         "Valid options are \"CW\" or \"CCW\"\n");
   2258             }
   2259         }
   2260     }
   2261 
   2262     pTrident->TVChipset = 0;
   2263     if ((s = xf86GetOptValString(pTrident->Options, OPTION_TV_CHIPSET))) {
   2264         if(!xf86NameCmp(s, "VT1621")) {
   2265             pTrident->TVChipset = 1;
   2266             xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Using VIA VT1621 TV chip\n");
   2267         } else if (!xf86NameCmp(s, "CH7005")) {
   2268             pTrident->TVChipset = 2;
   2269             xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Using Chrontel CH7005 TV chip\n");
   2270         } else
   2271             xf86DrvMsg(pScrn->scrnIndex,X_ERROR,
   2272                     "%s is an unknown TV chipset option\n",s);
   2273     }
   2274     /* Default : NTSC */
   2275     pTrident->TVSignalMode=0;
   2276     if (xf86GetOptValInteger(pTrident->Options, OPTION_TV_SIGNALMODE,
   2277             &pTrident->TVSignalMode)) {
   2278         ErrorF("TV SignalMode set to %d\n",pTrident->TVSignalMode);
   2279     }
   2280 
   2281     /* FIXME ACCELERATION */
   2282     if (!UseMMIO) pTrident->NoAccel = TRUE;
   2283 
   2284     if (LINEAR()) {
   2285         if (pTrident->pEnt->device->MemBase != 0) {
   2286             /*
   2287              * XXX Should check that the config file value matches one of the
   2288              * PCI base address values.
   2289              */
   2290             pTrident->FbAddress = pTrident->pEnt->device->MemBase;
   2291             from = X_CONFIG;
   2292         } else {
   2293             if (IsPciCard)
   2294                 pTrident->FbAddress = PCI_REGION_BASE(pTrident->PciInfo, 0, REGION_MEM) & 0xFFFFFFF0;
   2295             else
   2296                 pTrident->FbAddress = 0xA0000;
   2297         }
   2298 
   2299         xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
   2300                 (unsigned long)pTrident->FbAddress);
   2301     }
   2302 
   2303     if (UseMMIO) {
   2304         if (pTrident->pEnt->device->IOBase != 0) {
   2305             /*
   2306              * XXX Should check that the config file value matches one of the
   2307              * PCI base address values.
   2308              */
   2309             pTrident->IOAddress = pTrident->pEnt->device->IOBase;
   2310             from = X_CONFIG;
   2311         } else {
   2312             if (IsPciCard)
   2313                 pTrident->IOAddress = PCI_REGION_BASE(pTrident->PciInfo, 1, REGION_MEM) & 0xFFFFC000;
   2314             else
   2315                 /* FIXME - Multihead UNAWARE */
   2316                 pTrident->IOAddress = 0xBF000;
   2317         }
   2318 
   2319         xf86DrvMsg(pScrn->scrnIndex,X_PROBED,"IO registers at 0x%lX\n",
   2320                 (unsigned long)pTrident->IOAddress);
   2321     }
   2322 
   2323 #ifndef XSERVER_LIBPCIACCESS
   2324     /* Register the PCI-assigned resources. */
   2325     if (xf86RegisterResources(pTrident->pEnt->index, NULL, ResExclusive)) {
   2326         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   2327                 "xf86RegisterResources() found resource conflicts\n");
   2328         return FALSE;
   2329     }
   2330 #endif
   2331     /* Initialize VBE if possible
   2332      * Don't move this past MMIO enable!!
   2333      * PIO access will be blocked
   2334      * when MMIO is turned on!
   2335      */
   2336 
   2337     if (xf86LoadSubModule(pScrn, "vbe")) {
   2338         vbeInfoPtr pVbe;
   2339 
   2340         pVbe =  VBEInit(NULL,pTrident->pEnt->index);
   2341         pMon = vbeDoEDID(pVbe, NULL);
   2342 #ifdef VBE_INFO
   2343         {
   2344             VbeInfoBlock* vbeInfoBlockPtr;
   2345             if ((vbeInfoBlockPtr = VBEGetVBEInfo(pVbe))) {
   2346                 pTrident->vbeModes = VBEBuildVbeModeList(pVbe,vbeInfoBlockPtr);
   2347                 VBEFreeVBEInfo(vbeInfoBlockPtr);
   2348             }
   2349         }
   2350 #endif
   2351         vbeFree(pVbe);
   2352         if (pMon) {
   2353             if (!xf86LoadSubModule(pScrn, "ddc")) {
   2354                 TRIDENTFreeRec(pScrn);
   2355                 return FALSE;
   2356             } else {
   2357                 xf86SetDDCproperties(pScrn,xf86PrintEDID(pMon));
   2358                 ddcLoaded = TRUE;
   2359             }
   2360         }
   2361 
   2362     }
   2363 
   2364     if (xf86GetOptValBool(pTrident->Options, OPTION_1400_DISPLAY, &tmp_bool)) {
   2365         if (tmp_bool)
   2366             pTrident->displaySize = 1400;
   2367     } else
   2368         pTrident->displaySize = TRIDENTLcdDisplaySize(pMon);
   2369 
   2370     if (IsPciCard && UseMMIO) {
   2371         if (!TRIDENTMapMem(pScrn))
   2372             return FALSE;
   2373 
   2374         TRIDENTEnableMMIO(pScrn);
   2375     }
   2376 
   2377     OUTB(0x3C4, RevisionID); revision = INB(0x3C5);
   2378     xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Revision is %d\n",revision);
   2379 
   2380     pScrn->progClock = TRUE;
   2381     pTrident->EngineOperation = 0x00;
   2382     pTrident->IsCyber = FALSE;
   2383     pTrident->HasSGRAM = FALSE;
   2384     pTrident->NewClockCode = FALSE;
   2385     pTrident->MUX = FALSE;
   2386     Support24bpp = FALSE;
   2387 
   2388     OUTB(vgaIOBase + 4, InterfaceSel);
   2389 
   2390     switch (pTrident->Chipset) {
   2391     case TVGA9000:
   2392     case TVGA9000i:
   2393         pScrn->progClock = FALSE;
   2394         NoClocks = 16;
   2395         pTrident->NoMMIO = TRUE;
   2396         pTrident->NoAccel = TRUE;
   2397         pTrident->HWCursor = FALSE;
   2398         chipset = "TVGA9000/9000i";
   2399         ramtype = "Standard DRAM";
   2400         if (pTrident->UsePCIRetry)
   2401             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
   2402         pTrident->UsePCIRetry = FALSE; /* Not Supported */
   2403         pTrident->frequency = NTSC;
   2404         break;
   2405     case TVGA9100B:
   2406         pScrn->progClock = FALSE;
   2407         NoClocks = 8;
   2408         pTrident->NoMMIO = TRUE;
   2409         pTrident->NoAccel = TRUE;
   2410         pTrident->HWCursor = FALSE;
   2411         chipset = "TVGA9100B";
   2412         ramtype = "Standard DRAM";
   2413         if (pTrident->UsePCIRetry)
   2414             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
   2415         pTrident->UsePCIRetry = FALSE; /* Not Supported */
   2416         pTrident->frequency = NTSC;
   2417         break;
   2418     case TVGA8900B:
   2419         pScrn->progClock = FALSE;
   2420         NoClocks = 8;
   2421         pTrident->NoMMIO = TRUE;
   2422         pTrident->NoAccel = TRUE;
   2423         pTrident->HWCursor = FALSE;
   2424         chipset = "TVGA8900B";
   2425         ramtype = "Standard DRAM";
   2426         if (pTrident->UsePCIRetry)
   2427             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
   2428         pTrident->UsePCIRetry = FALSE; /* Not Supported */
   2429         pTrident->frequency = NTSC;
   2430         break;
   2431     case TVGA8900C:
   2432         pScrn->progClock = FALSE;
   2433         NoClocks = 16;
   2434         pTrident->NoMMIO = TRUE;
   2435         pTrident->NoAccel = TRUE;
   2436         pTrident->HWCursor = FALSE;
   2437         chipset = "TVGA8900C";
   2438         ramtype = "Standard DRAM";
   2439         if (pTrident->UsePCIRetry)
   2440             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
   2441         pTrident->UsePCIRetry = FALSE; /* Not Supported */
   2442         pTrident->frequency = NTSC;
   2443         break;
   2444     case TVGA8900D:
   2445         pScrn->progClock = FALSE;
   2446         NoClocks = 16;
   2447         pTrident->NoMMIO = TRUE;
   2448         pTrident->NoAccel = TRUE;
   2449         pTrident->HWCursor = FALSE;
   2450         chipset = "TVGA8900D";
   2451         ramtype = "Standard DRAM";
   2452         if (pTrident->UsePCIRetry)
   2453             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
   2454         pTrident->UsePCIRetry = FALSE; /* Not Supported */
   2455         pTrident->frequency = NTSC;
   2456         break;
   2457     case TVGA9200CXr:
   2458         pScrn->progClock = FALSE;
   2459         NoClocks = 16;
   2460         pTrident->NoMMIO = TRUE;
   2461         pTrident->NoAccel = TRUE;
   2462         pTrident->HWCursor = FALSE;
   2463         chipset = "TVGA9200CXr";
   2464         ramtype = "Standard DRAM";
   2465         if (pTrident->UsePCIRetry)
   2466             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
   2467         pTrident->UsePCIRetry = FALSE; /* Not Supported */
   2468         pTrident->frequency = NTSC;
   2469         break;
   2470     case TGUI9400CXi:
   2471         pScrn->progClock = FALSE;
   2472         NoClocks = 16;
   2473         pTrident->NoMMIO = TRUE;
   2474         pTrident->NoAccel = TRUE;
   2475         pTrident->HWCursor = FALSE;
   2476         chipset = "TVGA9200CXr";
   2477         ramtype = "Standard DRAM";
   2478         if (pTrident->UsePCIRetry)
   2479             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
   2480         pTrident->UsePCIRetry = FALSE; /* Not Supported */
   2481         pTrident->frequency = NTSC;
   2482         break;
   2483     case TGUI9440AGi:
   2484         pTrident->ddc1Read = Tridentddc1Read;
   2485         pTrident->HWCursor = FALSE;
   2486         chipset = "TGUI9440AGi";
   2487         ramtype = "Standard DRAM";
   2488         if (pTrident->UsePCIRetry)
   2489             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
   2490         pTrident->UsePCIRetry = FALSE; /* Not Supported */
   2491         pTrident->frequency = NTSC;
   2492         break;
   2493     case CYBER9320:
   2494         pTrident->ddc1Read = Tridentddc1Read;
   2495         chipset = "Cyber9320";
   2496         ramtype = "Standard DRAM";
   2497         if (pTrident->UsePCIRetry)
   2498             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
   2499         pTrident->UsePCIRetry = FALSE; /* Not Supported */
   2500         break;
   2501         /* Trident didn't update the PCI ID's and so we have to determine
   2502          * which chips are right ! Then override pTrident->Chipset to
   2503          * correct values */
   2504     case TGUI9660:
   2505         pTrident->ddc1Read = Tridentddc1Read;
   2506         if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
   2507             ramtype = "EDO Ram";
   2508         if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C)
   2509             ramtype = "Standard DRAM";
   2510         switch (revision) {
   2511         case 0x00:
   2512             chipset = "TGUI9660";
   2513             pTrident->Chipset = TGUI9660;
   2514             if (pTrident->UsePCIRetry)
   2515                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
   2516             pTrident->UsePCIRetry = FALSE; /* Not Supported */
   2517             break;
   2518         case 0x01:
   2519             chipset = "TGUI9680";
   2520             pTrident->Chipset = TGUI9680;
   2521             if (pTrident->UsePCIRetry)
   2522                 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
   2523             pTrident->UsePCIRetry = FALSE; /* Not Supported */
   2524             break;
   2525         case 0x10:
   2526             chipset = "ProVidia 9682";
   2527             Support24bpp = TRUE;
   2528             pTrident->Chipset = PROVIDIA9682;
   2529             break;
   2530         case 0x21:
   2531             chipset = "ProVidia 9685";
   2532             Support24bpp = TRUE;
   2533             pTrident->NewClockCode = TRUE;
   2534             pTrident->Chipset = PROVIDIA9685;
   2535             break;
   2536         case 0x22:
   2537         case 0x23:
   2538             chipset = "Cyber 9397";
   2539             if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
   2540                 ramtype = "EDO Ram";
   2541             if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
   2542                 ramtype = "SDRAM";
   2543             if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
   2544                 pTrident->HasSGRAM = TRUE;
   2545                 ramtype = "SGRAM";
   2546             }
   2547             pTrident->NewClockCode = TRUE;
   2548             pTrident->Chipset = CYBER9397;
   2549             pTrident->IsCyber = TRUE;
   2550             break;
   2551         case 0x2a:
   2552             chipset = "Cyber 9397/DVD";
   2553             if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
   2554                 ramtype = "EDO Ram";
   2555             if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
   2556                 ramtype = "SDRAM";
   2557             if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
   2558                 pTrident->HasSGRAM = TRUE;
   2559                 ramtype = "SGRAM";
   2560             }
   2561             pTrident->NewClockCode = TRUE;
   2562             pTrident->Chipset = CYBER9397DVD;
   2563             pTrident->IsCyber = TRUE;
   2564             break;
   2565         case 0x30:
   2566         case 0x33:
   2567         case 0x34:
   2568         case 0x35:
   2569         case 0xB3:
   2570             chipset = "Cyber 9385";
   2571             pTrident->NewClockCode = TRUE;
   2572             pTrident->Chipset = CYBER9385;
   2573             pTrident->IsCyber = TRUE;
   2574             break;
   2575         case 0x38:
   2576         case 0x3A:
   2577             chipset = "Cyber 9385-1";
   2578             pTrident->NewClockCode = TRUE;
   2579             pTrident->Chipset = CYBER9385;
   2580             pTrident->IsCyber = TRUE;
   2581             break;
   2582         case 0x40:
   2583         case 0x41:
   2584         case 0x42:
   2585         case 0x43:
   2586             chipset = "Cyber 9382";
   2587             pTrident->NewClockCode = TRUE;
   2588             pTrident->Chipset = CYBER9382;
   2589             pTrident->IsCyber = TRUE;
   2590             break;
   2591         case 0x4A:
   2592             chipset = "Cyber 9388";
   2593             if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
   2594                 ramtype = "EDO Ram";
   2595             if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
   2596                 ramtype = "SDRAM";
   2597             if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
   2598                 pTrident->HasSGRAM = TRUE;
   2599                 ramtype = "SGRAM";
   2600             }
   2601             pTrident->NewClockCode = TRUE;
   2602             pTrident->Chipset = CYBER9388;
   2603             pTrident->IsCyber = TRUE;
   2604             break;
   2605         default:
   2606             chipset = "Unknown";
   2607             pTrident->Chipset = TGUI9660;
   2608             break;
   2609         }
   2610         break;
   2611         case CYBER9388:
   2612             pTrident->ddc1Read = Tridentddc1Read;
   2613             if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
   2614                 ramtype = "EDO Ram";
   2615             if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
   2616                 ramtype = "SDRAM";
   2617             if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
   2618                 pTrident->HasSGRAM = TRUE;
   2619                 ramtype = "SGRAM";
   2620             }
   2621             pTrident->IsCyber = TRUE;
   2622             Support24bpp = TRUE;
   2623             chipset = "Cyber 9388";
   2624             pTrident->NewClockCode = TRUE;
   2625             break;
   2626         case CYBER9397:
   2627             pTrident->ddc1Read = Tridentddc1Read;
   2628             if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
   2629                 ramtype = "EDO Ram";
   2630             if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
   2631                 ramtype = "SDRAM";
   2632             if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
   2633                 pTrident->HasSGRAM = TRUE;
   2634                 ramtype = "SGRAM";
   2635             }
   2636             pTrident->IsCyber = TRUE;
   2637             Support24bpp = TRUE;
   2638             chipset = "Cyber 9397";
   2639             pTrident->NewClockCode = TRUE;
   2640             break;
   2641         case CYBER9397DVD:
   2642             pTrident->ddc1Read = Tridentddc1Read;
   2643             if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
   2644                 ramtype = "EDO Ram";
   2645             if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
   2646                 ramtype = "SDRAM";
   2647             if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
   2648                 pTrident->HasSGRAM = TRUE;
   2649                 ramtype = "SGRAM";
   2650             }
   2651             pTrident->IsCyber = TRUE;
   2652             Support24bpp = TRUE;
   2653             chipset = "Cyber 9397/DVD";
   2654             pTrident->NewClockCode = TRUE;
   2655             break;
   2656         case CYBER9520:
   2657             pTrident->ddc1Read = Tridentddc1Read;
   2658             if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
   2659                 ramtype = "EDO Ram";
   2660             if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
   2661                 ramtype = "SDRAM";
   2662             if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
   2663                 pTrident->HasSGRAM = TRUE;
   2664                 ramtype = "SGRAM";
   2665             }
   2666             pTrident->IsCyber = TRUE;
   2667             Support24bpp = TRUE;
   2668             chipset = "Cyber 9520";
   2669             pTrident->NewClockCode = TRUE;
   2670             break;
   2671         case CYBER9525DVD:
   2672             pTrident->ddc1Read = Tridentddc1Read;
   2673             if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
   2674                 ramtype = "EDO Ram";
   2675             if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
   2676                 ramtype = "SDRAM";
   2677             if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
   2678                 pTrident->HasSGRAM = TRUE;
   2679                 ramtype = "SGRAM";
   2680             }
   2681             pTrident->IsCyber = TRUE;
   2682             Support24bpp = TRUE;
   2683             chipset = "Cyber 9525/DVD";
   2684             pTrident->NewClockCode = TRUE;
   2685             break;
   2686         case CYBERBLADEE4:
   2687             pTrident->ddc1Read = Tridentddc1Read;
   2688             ramtype = "SDRAM";
   2689             pTrident->IsCyber = TRUE;
   2690             Support24bpp = TRUE;
   2691             chipset = "CyberBlade e4/128";
   2692             pTrident->NewClockCode = TRUE;
   2693             break;
   2694         case IMAGE975:
   2695             pTrident->ddc1Read = Tridentddc1Read;
   2696             if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
   2697                 ramtype = "EDO Ram";
   2698             if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
   2699                 ramtype = "SDRAM";
   2700             if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
   2701                 pTrident->HasSGRAM = TRUE;
   2702                 ramtype = "SGRAM";
   2703             }
   2704             Support24bpp = TRUE;
   2705             chipset = "3DImage975";
   2706             pTrident->NewClockCode = TRUE;
   2707             break;
   2708         case IMAGE985:
   2709             pTrident->ddc1Read = Tridentddc1Read;
   2710             if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
   2711                 ramtype = "EDO Ram";
   2712             if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
   2713                 ramtype = "SDRAM";
   2714             if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
   2715                 pTrident->HasSGRAM = TRUE;
   2716                 ramtype = "SGRAM";
   2717             }
   2718             Support24bpp = TRUE;
   2719             chipset = "3DImage985";
   2720             pTrident->NewClockCode = TRUE;
   2721             break;
   2722         case BLADE3D:
   2723             pTrident->ddc1Read = Tridentddc1Read;
   2724             if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
   2725                 ramtype = "SDRAM";
   2726             if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
   2727                 pTrident->HasSGRAM = TRUE;
   2728                 ramtype = "SGRAM";
   2729             }
   2730             Support24bpp = TRUE;
   2731             chipset = "Blade3D";
   2732             pTrident->NewClockCode = TRUE;
   2733             pTrident->frequency = NTSC;
   2734             pTrident->UsePCIRetry = TRUE; /* To avoid lockups */
   2735             break;
   2736         case CYBERBLADEI7:
   2737             pTrident->ddc1Read = Tridentddc1Read;
   2738             ramtype = "SDRAM";
   2739             /* pTrident->IsCyber = TRUE; VIA MVP4 integrated Desktop version */
   2740             Support24bpp = TRUE;
   2741             chipset = "CyberBlade/i7/VIA MVP4";
   2742             pTrident->NewClockCode = TRUE;
   2743             pTrident->frequency = NTSC;
   2744             break;
   2745         case CYBERBLADEI7D:
   2746             pTrident->ddc1Read = Tridentddc1Read;
   2747             ramtype = "SDRAM";
   2748             pTrident->IsCyber = TRUE;
   2749             Support24bpp = TRUE;
   2750             chipset = "CyberBlade/DSTN/i7";
   2751             pTrident->NewClockCode = TRUE;
   2752             pTrident->frequency = NTSC;
   2753             break;
   2754         case CYBERBLADEI1:
   2755             pTrident->ddc1Read = Tridentddc1Read;
   2756             ramtype = "SDRAM";
   2757             pTrident->IsCyber = TRUE;
   2758             Support24bpp = TRUE;
   2759             chipset = "CyberBlade/i1";
   2760             pTrident->NewClockCode = TRUE;
   2761             pTrident->frequency = NTSC;
   2762             break;
   2763         case CYBERBLADEI1D:
   2764             pTrident->ddc1Read = Tridentddc1Read;
   2765             ramtype = "SDRAM";
   2766             pTrident->IsCyber = TRUE;
   2767             Support24bpp = TRUE;
   2768             chipset = "CyberBlade/DSTN/i1";
   2769             pTrident->NewClockCode = TRUE;
   2770             pTrident->frequency = NTSC;
   2771             break;
   2772         case CYBERBLADEAI1:
   2773             pTrident->ddc1Read = Tridentddc1Read;
   2774             ramtype = "SDRAM";
   2775             pTrident->IsCyber = TRUE;
   2776             Support24bpp = TRUE;
   2777             chipset = "CyberBlade/Ai1";
   2778             pTrident->NewClockCode = TRUE;
   2779             pTrident->frequency = NTSC;
   2780             break;
   2781         case CYBERBLADEAI1D:
   2782             pTrident->ddc1Read = Tridentddc1Read;
   2783             ramtype = "SDRAM";
   2784             pTrident->IsCyber = TRUE;
   2785             Support24bpp = TRUE;
   2786             chipset = "CyberBlade/DSTN/Ai1";
   2787             pTrident->NewClockCode = TRUE;
   2788             pTrident->frequency = NTSC;
   2789             break;
   2790         case BLADEXP: /* 0x9910 */
   2791             pTrident->ddc1Read = Tridentddc1Read;
   2792             ramtype = "SGRAM";
   2793             pTrident->HasSGRAM = TRUE;
   2794             Support24bpp = TRUE;
   2795             pTrident->NewClockCode = TRUE;
   2796             pTrident->frequency = NTSC;
   2797             OUTB(0x3C4, 0x5D);
   2798             if (PCI_SUB_VENDOR_ID(pTrident->PciInfo) != 0x1023) {
   2799                 chipset = "CyberBladeXP";
   2800                 pTrident->IsCyber = TRUE;
   2801             } else
   2802                 if (!(INB(0x3C5) & 0x01)) {
   2803                     chipset = "BladeXP";
   2804                 } else {
   2805                     CARD8 mem1, mem2;
   2806                     OUTB(vgaIOBase + 0x04, SPR);
   2807                     mem1 = INB(vgaIOBase + 5);
   2808                     OUTB(vgaIOBase + 0x04, 0xC1);
   2809                     mem2 = INB(vgaIOBase + 5);
   2810                     if ((mem1 & 0x0e) && (mem2 == 0x11)) {
   2811                         chipset = "BladeT64";
   2812                     } else {
   2813                         chipset = "BladeT16";
   2814                     }
   2815                 }
   2816             break;
   2817         case CYBERBLADEXPAI1:
   2818             pTrident->ddc1Read = Tridentddc1Read;
   2819             ramtype = "SGRAM";
   2820             pTrident->HasSGRAM = TRUE;
   2821             pTrident->IsCyber = TRUE;
   2822             pTrident->shadowNew = TRUE;
   2823             Support24bpp = TRUE;
   2824             chipset = "CyberBladeXPAi1";
   2825             pTrident->NewClockCode = TRUE;
   2826             pTrident->frequency = NTSC;
   2827             break;
   2828         case CYBERBLADEXP4:
   2829             pTrident->ddc1Read = Tridentddc1Read;
   2830             ramtype = "SGRAM";
   2831             pTrident->HasSGRAM = TRUE;
   2832             pTrident->IsCyber = TRUE;
   2833             pTrident->shadowNew = TRUE;
   2834             Support24bpp = TRUE;
   2835             chipset = "CyberBladeXP4";
   2836             pTrident->NewClockCode = TRUE;
   2837             pTrident->frequency = NTSC;
   2838             break;
   2839         case XP5:
   2840             pTrident->ddc1Read = Tridentddc1Read;
   2841             ramtype = "SGRAM";
   2842             pTrident->HasSGRAM = TRUE;
   2843             pTrident->IsCyber = TRUE;
   2844             pTrident->shadowNew = TRUE;
   2845             Support24bpp = TRUE;
   2846             chipset = "XP5";
   2847             pTrident->NewClockCode = TRUE;
   2848             pTrident->frequency = NTSC;
   2849             break;
   2850     }
   2851 
   2852     if (!pScrn->progClock) {
   2853         pScrn->numClocks = NoClocks;
   2854         xf86GetClocks(pScrn, NoClocks, TRIDENTClockSelect,
   2855                 TRIDENTProtect, TRIDENTBlankScreen,
   2856                 vgaIOBase + 0x0A, 0x08, 1, 28322);
   2857         from = X_PROBED;
   2858         xf86ShowClocks(pScrn, from);
   2859     }
   2860 
   2861     if (!chipset) {
   2862         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No support for \"%s\"\n",
   2863                 pScrn->chipset);
   2864         if (IsPciCard && UseMMIO) {
   2865             TRIDENTDisableMMIO(pScrn);
   2866             TRIDENTUnmapMem(pScrn);
   2867         }
   2868         return FALSE;
   2869     }
   2870     xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Found %s chip\n", chipset);
   2871     if (ramtype)
   2872         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RAM type is %s\n", ramtype);
   2873 
   2874     if (pScrn->bitsPerPixel == 24 && !Support24bpp) {
   2875         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No support for 24bpp on this chipset, use -pixmap32.\n");
   2876         if (IsPciCard && UseMMIO) {
   2877             TRIDENTDisableMMIO(pScrn);
   2878             TRIDENTUnmapMem(pScrn);
   2879         }
   2880         return FALSE;
   2881     }
   2882 
   2883     /* HW bpp matches reported bpp */
   2884     pTrident->HwBpp = pScrn->bitsPerPixel;
   2885 
   2886     /* Due to bugs in the chip, turn it off */
   2887     if (pTrident->Chipset >= CYBERBLADEI7 && pTrident->Chipset <= CYBERBLADEAI1D)
   2888         pTrident->HWCursor = FALSE;
   2889 
   2890     from = X_PROBED;
   2891     if (pTrident->pEnt->device->videoRam != 0) {
   2892         pScrn->videoRam = pTrident->pEnt->device->videoRam;
   2893         from = X_CONFIG;
   2894     } else {
   2895         if (pTrident->Chipset == XP5) {
   2896             OUTB(vgaIOBase + 4, 0x60);
   2897             videoram = INB(vgaIOBase + 5);
   2898             switch (videoram & 0x7) {
   2899             case 0x00:
   2900                 pScrn->videoRam = 65536 /* 131072 */;
   2901                 break;
   2902             case 0x01:
   2903                 pScrn->videoRam = 65536;
   2904                 break;
   2905             case 0x02:
   2906                 pScrn->videoRam = 32768;
   2907                 break;
   2908             case 0x03:
   2909                 pScrn->videoRam = 16384;
   2910                 break;
   2911             case 0x04:
   2912                 pScrn->videoRam = 8192;
   2913                 break;
   2914             }
   2915         } else
   2916             if (pTrident->Chipset == CYBER9525DVD) {
   2917                 pScrn->videoRam = 2560;
   2918             } else
   2919             {
   2920                 OUTB(vgaIOBase + 4, SPR);
   2921                 videoram = INB(vgaIOBase + 5);
   2922                 if (pTrident->Chipset < TGUI9440AGi)
   2923                     videorammask = 0x07;
   2924                 else
   2925                     videorammask = 0x0F;
   2926                 switch (videoram & videorammask) {
   2927                 case 0x01:
   2928                     pScrn->videoRam = 512;
   2929                     break;
   2930                 case 0x02: /* XP */
   2931                     pScrn->videoRam = 6144;
   2932                     break;
   2933                 case 0x03:
   2934                     pScrn->videoRam = 1024;
   2935                     break;
   2936                 case 0x04:
   2937                     pScrn->videoRam = 8192;
   2938                     break;
   2939                 case 0x06: /* XP */
   2940                     pScrn->videoRam = 10240;
   2941                     break;
   2942                 case 0x07:
   2943                     pScrn->videoRam = 2048;
   2944                     break;
   2945                 case 0x08: /* XP */
   2946                     pScrn->videoRam = 12288;
   2947                     break;
   2948                 case 0x0A: /* XP */
   2949                     pScrn->videoRam = 14336;
   2950                     break;
   2951                 case 0x0C: /* XP */
   2952                     pScrn->videoRam = 16384;
   2953                     break;
   2954                 case 0x0E: /* XP */
   2955                     OUTB(vgaIOBase + 4, 0xC1);
   2956                     switch (INB(vgaIOBase + 5) & 0x11) {
   2957                     case 0x00:
   2958                         pScrn->videoRam = 20480;
   2959                         break;
   2960                     case 0x01:
   2961                         pScrn->videoRam = 24576;
   2962                         break;
   2963                     case 0x10:
   2964                         pScrn->videoRam = 28672;
   2965                         break;
   2966                     case 0x11:
   2967                         pScrn->videoRam = 32768;
   2968                         break;
   2969                     }
   2970                     break;
   2971                     case 0x0F:
   2972                         pScrn->videoRam = 4096;
   2973                         break;
   2974                     default:
   2975                         pScrn->videoRam = 1024;
   2976                         xf86DrvMsg(pScrn->scrnIndex, from,
   2977                                 "Unable to determine VideoRam, defaulting to 1MB\n");
   2978                         break;
   2979                 }
   2980             }
   2981     }
   2982 
   2983     xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
   2984             pTrident->HWCursor ? "HW" : "SW");
   2985 
   2986     xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
   2987             pScrn->videoRam);
   2988 
   2989     if (pTrident->IsCyber) {
   2990         unsigned char mod, dsp, dsp1;
   2991 
   2992         pTrident->lcdMode = 0xff;
   2993 
   2994         OUTB(0x3CE,0x42);
   2995         dsp = INB(0x3CF);
   2996         OUTB(0x3CE,0x43);
   2997         dsp1 = INB(0x3CF);
   2998         OUTB(0x3CE,0x52);
   2999         mod = INB(0x3CF);
   3000         /*
   3001          * Only allow display size override if 1280x1024 is detected
   3002          * Currently 1400x1050 is supported - which is detected as
   3003          * 1280x1024
   3004          */
   3005         if (pTrident->displaySize) {
   3006             if (((mod >> 4) & 3) == 0) {
   3007                 for (i = 0; LCD[i].mode != 0xff; i++) {
   3008                     if (pTrident->displaySize == LCD[i].display_x)
   3009                         pTrident->lcdMode = LCD[i].mode;
   3010                 }
   3011                 xf86DrvMsg(pScrn->scrnIndex,
   3012                         X_INFO,"%s Panel %ix%i found\n",
   3013                         (dsp & 0x80) ? "TFT" :
   3014                                 ((dsp1 & 0x20) ? "DSTN" : "STN"),
   3015                                 LCD[i].display_x,LCD[i].display_y);
   3016             } else {
   3017                 xf86DrvMsg(pScrn->scrnIndex,X_WARNING,
   3018                         "Display size override only for 1280x1024\n");
   3019                 pTrident->displaySize = 0;
   3020             }
   3021         }
   3022 
   3023         if (!pTrident->displaySize) {
   3024             for (i = 0; LCD[i].mode != 0xff; i++) {
   3025                 if (LCD[i].mode == ((mod >> 4) & 3)) {
   3026                     pTrident->lcdMode = i;
   3027                     xf86DrvMsg(pScrn->scrnIndex,
   3028                             X_PROBED,"%s Panel %ix%i found\n",
   3029                             (dsp & 0x80) ? "TFT" :
   3030                                     ((dsp1 & 0x20) ? "DSTN" : "STN"),
   3031                                     LCD[i].display_x,LCD[i].display_y);
   3032                 }
   3033             }
   3034         }
   3035         if (pTrident->dspOverride) {
   3036             if (pTrident->dspOverride & LCD_ACTIVE)
   3037                 pTrident->lcdActive = TRUE;
   3038             else
   3039                 pTrident->lcdActive = FALSE;
   3040         } else {
   3041             OUTB(0x3CE, FPConfig);
   3042             pTrident->lcdActive = (INB(0x3CF) & 0x10);
   3043         }
   3044     }
   3045 
   3046     pTrident->MCLK = 0;
   3047     mclk = CalculateMCLK(pScrn);
   3048     xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory Clock is %3.2f MHz\n", mclk);
   3049     if (xf86GetOptValFreq(pTrident->Options, OPTION_SETMCLK, OPTUNITS_MHZ,
   3050             &real)) {
   3051         pTrident->MCLK = (int)(real * 1000.0);
   3052         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Setting new Memory Clock to %3.2f MHz\n",
   3053                 (float)(pTrident->MCLK / 1000));
   3054     }
   3055 
   3056     /* Set the min pixel clock */
   3057     pTrident->MinClock = 12000;	/* XXX Guess, need to check this */
   3058     xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
   3059             pTrident->MinClock / 1000);
   3060 
   3061     /*
   3062      * If the user has specified ramdac speed in the XF86Config
   3063      * file, we respect that setting.
   3064      */
   3065     if (pTrident->pEnt->device->dacSpeeds[0]) {
   3066         int speed = 0;
   3067 
   3068         switch (pScrn->bitsPerPixel) {
   3069         case 8:
   3070             speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP8];
   3071             break;
   3072         case 16:
   3073             speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP16];
   3074             break;
   3075         case 24:
   3076             speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP24];
   3077             break;
   3078         case 32:
   3079             speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP32];
   3080             break;
   3081         }
   3082         if (speed == 0)
   3083             pTrident->MaxClock = pTrident->pEnt->device->dacSpeeds[0];
   3084         else
   3085             pTrident->MaxClock = speed;
   3086         from = X_CONFIG;
   3087     } else {
   3088         switch (pScrn->bitsPerPixel) {
   3089         case 16:
   3090             pTrident->MaxClock = ClockLimit16bpp[pTrident->Chipset];
   3091             break;
   3092         case 24:
   3093             pTrident->MaxClock = ClockLimit24bpp[pTrident->Chipset];
   3094             break;
   3095         case 32:
   3096             pTrident->MaxClock = ClockLimit32bpp[pTrident->Chipset];
   3097             break;
   3098         default:
   3099             pTrident->MaxClock = ClockLimit[pTrident->Chipset];
   3100             break;
   3101         }
   3102     }
   3103     xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
   3104             pTrident->MaxClock / 1000);
   3105 
   3106     /*
   3107      * Setup the ClockRanges, which describe what clock ranges are available,
   3108      * and what sort of modes they can be used for.
   3109      */
   3110     clockRanges = xnfcalloc(sizeof(ClockRange), 1);
   3111     clockRanges->next = NULL;
   3112     if (!pScrn->progClock) {
   3113         if (pScrn->videoRam < 1024)
   3114             clockRanges->ClockMulFactor = 2;
   3115         if (pScrn->bitsPerPixel == 16)
   3116             clockRanges->ClockMulFactor = 2;
   3117     }
   3118     clockRanges->minClock = pTrident->MinClock;
   3119     clockRanges->maxClock = pTrident->MaxClock;
   3120     clockRanges->clockIndex = -1;		/* programmable */
   3121     clockRanges->interlaceAllowed = TRUE;
   3122     clockRanges->doubleScanAllowed = TRUE;
   3123 
   3124     /*
   3125      * xf86ValidateModes will check that the mode HTotal and VTotal values
   3126      * don't exceed the chipset's limit if pScrn->maxHValue and
   3127      * pScrn->maxVValue are set.  Since our TRIDENTValidMode() already takes
   3128      * care of this, we don't worry about setting them here.
   3129      */
   3130 
   3131     if (pScrn->bitsPerPixel == 24) {
   3132         xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
   3133                 "Disabling Engine due to 24bpp.\n");
   3134         pTrident->NoAccel = TRUE;
   3135     }
   3136 
   3137     /* Select valid modes from those available */
   3138     if (pTrident->NoAccel || Is3Dchip) {
   3139         /*
   3140          * XXX Assuming min pitch 256, max 4096
   3141          * XXX Assuming min height 128, max 4096
   3142          */
   3143         i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
   3144                 pScrn->display->modes, clockRanges,
   3145                 NULL, 256, 4096,
   3146                 pScrn->bitsPerPixel, 128, 4096,
   3147                 pScrn->display->virtualX,
   3148                 pScrn->display->virtualY,
   3149                 pTrident->FbMapSize,
   3150                 LOOKUP_BEST_REFRESH);
   3151     } else {
   3152         /*
   3153          * XXX Assuming min height 128, max 2048
   3154          */
   3155         i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
   3156                 pScrn->display->modes, clockRanges,
   3157                 GetAccelPitchValues(pScrn), 0, 0,
   3158                 pScrn->bitsPerPixel, 128, 2048,
   3159                 pScrn->display->virtualX,
   3160                 pScrn->display->virtualY,
   3161                 pTrident->FbMapSize,
   3162                 LOOKUP_BEST_REFRESH);
   3163     }
   3164 
   3165     if (i == -1) {
   3166         if (IsPciCard && UseMMIO) {
   3167             TRIDENTDisableMMIO(pScrn);
   3168             TRIDENTUnmapMem(pScrn);
   3169         }
   3170         TRIDENTFreeRec(pScrn);
   3171         return FALSE;
   3172     }
   3173 
   3174     /* Prune the modes marked as invalid */
   3175     xf86PruneDriverModes(pScrn);
   3176 
   3177     if (i == 0 || pScrn->modes == NULL) {
   3178         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
   3179         if (IsPciCard && UseMMIO) {
   3180             TRIDENTDisableMMIO(pScrn);
   3181             TRIDENTUnmapMem(pScrn);
   3182         }
   3183         TRIDENTFreeRec(pScrn);
   3184         return FALSE;
   3185     }
   3186 
   3187     xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
   3188 
   3189     /* Set the current mode to the first in the list */
   3190     pScrn->currentMode = pScrn->modes;
   3191 
   3192     /* Print the list of modes being used */
   3193     xf86PrintModes(pScrn);
   3194 
   3195     /* Set display resolution */
   3196     xf86SetDpi(pScrn, 0, 0);
   3197 
   3198     /* Load bpp-specific modules */
   3199     switch (pScrn->bitsPerPixel) {
   3200     case 8:
   3201         pTrident->EngineOperation |= 0x00;
   3202         break;
   3203     case 16:
   3204         pTrident->EngineOperation |= 0x01;
   3205         break;
   3206     case 24:
   3207         pTrident->EngineOperation |= 0x03;
   3208         break;
   3209     case 32:
   3210         pTrident->EngineOperation |= 0x02;
   3211         break;
   3212     }
   3213 
   3214     if (xf86LoadSubModule(pScrn, "fb") == NULL) {
   3215         if (IsPciCard && UseMMIO) {
   3216             TRIDENTDisableMMIO(pScrn);
   3217             TRIDENTUnmapMem(pScrn);
   3218         }
   3219         TRIDENTFreeRec(pScrn);
   3220         return FALSE;
   3221     }
   3222 
   3223     if (!xf86LoadSubModule(pScrn, "i2c")) {
   3224         if (IsPciCard && UseMMIO) {
   3225             TRIDENTDisableMMIO(pScrn);
   3226             TRIDENTUnmapMem(pScrn);
   3227         }
   3228         TRIDENTFreeRec(pScrn);
   3229         return FALSE;
   3230     }
   3231 
   3232     /* Load XAA if needed */
   3233     if (!pTrident->NoAccel) {
   3234         if (!pTrident->useEXA) {
   3235             if (!xf86LoadSubModule(pScrn, "xaa")) {
   3236                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   3237                         "Falling back to shadowfb\n");
   3238                 pTrident->NoAccel = 1;
   3239                 pTrident->ShadowFB = 1;
   3240             }
   3241         }
   3242 
   3243         if (pTrident->useEXA) {
   3244             XF86ModReqInfo req;
   3245             int errmaj, errmin;
   3246 
   3247             memset(&req, 0, sizeof(req));
   3248 
   3249             req.majorversion = 2;
   3250             if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
   3251                     &errmaj, &errmin))
   3252             {
   3253                 LoaderErrorMsg(NULL, "exa", errmaj, errmin);
   3254                 if (IsPciCard && UseMMIO) {
   3255                     TRIDENTDisableMMIO(pScrn);
   3256                     TRIDENTUnmapMem(pScrn);
   3257                 }
   3258                 TRIDENTFreeRec(pScrn);
   3259                 return FALSE;
   3260             }
   3261         }
   3262 
   3263         switch (pScrn->displayWidth * pScrn->bitsPerPixel / 8) {
   3264         case 512:
   3265         case 8192:
   3266             pTrident->EngineOperation |= 0x00;
   3267             break;
   3268         case 1024:
   3269             pTrident->EngineOperation |= 0x04;
   3270             break;
   3271         case 2048:
   3272             pTrident->EngineOperation |= 0x08;
   3273             break;
   3274         case 4096:
   3275             pTrident->EngineOperation |= 0x0C;
   3276             break;
   3277         }
   3278     }
   3279 
   3280     /* Load shadow if needed */
   3281     if (pTrident->ShadowFB) {
   3282         if (!xf86LoadSubModule(pScrn, "shadow")) {
   3283             TRIDENTFreeRec(pScrn);
   3284             return FALSE;
   3285         }
   3286     }
   3287 
   3288     /* Load DDC if needed */
   3289     /* This gives us DDC1 - we should be able to get DDC2B using i2c */
   3290 
   3291     if (! ddcLoaded)
   3292         if (!xf86LoadSubModule(pScrn, "ddc")) {
   3293             if (IsPciCard && UseMMIO) {
   3294                 TRIDENTDisableMMIO(pScrn);
   3295                 TRIDENTUnmapMem(pScrn);
   3296             }
   3297             TRIDENTFreeRec(pScrn);
   3298             return FALSE;
   3299         }
   3300 
   3301     if (IsPciCard && UseMMIO) {
   3302         TRIDENTDisableMMIO(pScrn);
   3303         TRIDENTUnmapMem(pScrn);
   3304     }
   3305 
   3306 #ifndef XSERVER_LIBPCIACCESS
   3307     pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
   3308 
   3309     if (pTrident->IsCyber && pTrident->MMIOonly)
   3310         pScrn->racIoFlags = 0;
   3311     else
   3312         pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
   3313 #endif
   3314     pTrident->FbMapSize = pScrn->videoRam * 1024;
   3315 
   3316     return TRUE;
   3317 }
   3318 
   3319 
   3320 /*
   3321  * This is called at the end of each server generation.  It restores the
   3322  * original (text) mode.  It should really also unmap the video memory too.
   3323  */
   3324 
   3325 /* Mandatory */
   3326 static Bool
   3327 TRIDENTCloseScreen(CLOSE_SCREEN_ARGS_DECL)
   3328 {
   3329     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
   3330     vgaHWPtr hwp = VGAHWPTR(pScrn);
   3331     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
   3332 
   3333     if (pScrn->vtSema) {
   3334 #ifdef HAVE_XAA_H
   3335         if (!pTrident->NoAccel && !pTrident->useEXA)
   3336             pTrident->AccelInfoRec->Sync(pScrn);
   3337         else
   3338 #endif
   3339             if (!pTrident->NoAccel && pTrident->useEXA)
   3340                 pTrident->EXADriverPtr->WaitMarker(pScreen, 0);
   3341 
   3342 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
   3343         if (xf86IsPc98())
   3344             PC98TRIDENTDisable(pScrn);
   3345 #endif
   3346 
   3347         TRIDENTRestore(pScrn);
   3348         vgaHWLock(hwp);
   3349         if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn);
   3350         TRIDENTUnmapMem(pScrn);
   3351     }
   3352 
   3353 #ifdef HAVE_XAA_H
   3354     if (pTrident->AccelInfoRec)
   3355         XAADestroyInfoRec(pTrident->AccelInfoRec);
   3356 #endif
   3357     if (pTrident->EXADriverPtr) {
   3358         exaDriverFini(pScreen);
   3359         free(pTrident->EXADriverPtr);
   3360         pTrident->EXADriverPtr = NULL;
   3361     }
   3362     if (pTrident->CursorInfoRec)
   3363         xf86DestroyCursorInfoRec(pTrident->CursorInfoRec);
   3364     if (pTrident->ShadowPtr) {
   3365         shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen));
   3366         free(pTrident->ShadowPtr);
   3367         pScreen->CreateScreenResources = pTrident->CreateScreenResources;
   3368     }
   3369     if (pTrident->DGAModes)
   3370         free(pTrident->DGAModes);
   3371     pScrn->vtSema = FALSE;
   3372 
   3373     if(pTrident->BlockHandler)
   3374         pScreen->BlockHandler = pTrident->BlockHandler;
   3375 
   3376     if (pTrident->pVbe)
   3377         vbeFree(pTrident->pVbe);
   3378     else
   3379         xf86FreeInt10(pTrident->Int10);
   3380     pScreen->CloseScreen = pTrident->CloseScreen;
   3381     return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
   3382 }
   3383 
   3384 /* Do screen blanking */
   3385 
   3386 /* Mandatory */
   3387 static Bool
   3388 TRIDENTSaveScreen(ScreenPtr pScreen, int mode)
   3389 {
   3390     return vgaHWSaveScreen(pScreen, mode);
   3391 }
   3392 
   3393 
   3394 static Bool
   3395 TRIDENTCreateScreenResources(ScreenPtr pScreen)
   3396 {
   3397     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
   3398     TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
   3399     Bool ret;
   3400 
   3401     pScreen->CreateScreenResources = pTrident->CreateScreenResources;
   3402     ret = pScreen->CreateScreenResources(pScreen);
   3403     pTrident->CreateScreenResources = pScreen->CreateScreenResources;
   3404     pScreen->CreateScreenResources = TRIDENTCreateScreenResources;
   3405 
   3406     if (ret)
   3407         ret = shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen),
   3408                 TRIDENTShadowUpdate, NULL, 0, 0);
   3409 
   3410     return ret;
   3411 }
   3412 
   3413 /* Mandatory */
   3414 
   3415 /* This gets called at the start of each server generation */
   3416 
   3417 static Bool
   3418 TRIDENTScreenInit(SCREEN_INIT_ARGS_DECL)
   3419 {
   3420     /* The vgaHW references will disappear one day */
   3421     ScrnInfoPtr pScrn;
   3422     vgaHWPtr hwp;
   3423     TRIDENTPtr pTrident;
   3424     int ret;
   3425     VisualPtr visual;
   3426     unsigned char *FBStart;
   3427     int width, height, displayWidth;
   3428 
   3429     /*
   3430      * First get the ScrnInfoRec
   3431      */
   3432     pScrn = xf86ScreenToScrn(pScreen);
   3433     pTrident = TRIDENTPTR(pScrn);
   3434 
   3435     if (IsPrimaryCard) {
   3436         if (!vgaHWMapMem(pScrn))
   3437             return FALSE;
   3438     }
   3439 
   3440     /* Map the TRIDENT memory and MMIO areas */
   3441     if (!TRIDENTMapMem(pScrn))
   3442         return FALSE;
   3443 
   3444 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
   3445     if (!xf86IsPc98())
   3446 #endif
   3447     {
   3448 #ifdef VBE_INFO
   3449         if (pTrident->vbeModes) {
   3450             pTrident->pVbe = VBEInit(NULL,pTrident->pEnt->index);
   3451             pTrident->Int10 = pTrident->pVbe->pInt10;
   3452         } else
   3453 #endif
   3454         {
   3455             if (xf86LoadSubModule(pScrn, "int10")) {
   3456                 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Initializing int10\n");
   3457                 pTrident->Int10 = xf86InitInt10(pTrident->pEnt->index);
   3458             }
   3459         }
   3460     }
   3461 
   3462     hwp = VGAHWPTR(pScrn);
   3463 
   3464     if (IsPciCard && UseMMIO) {
   3465         TRIDENTEnableMMIO(pScrn);
   3466 
   3467         /* Initialize the MMIO vgahw functions */
   3468         vgaHWSetMmioFuncs(hwp, pTrident->IOBase, 0);
   3469     }
   3470 
   3471     /* Save the current state */
   3472     TRIDENTSave(pScrn);
   3473 
   3474     /*
   3475      * Some Trident chip on PC-9821 needs setup,
   3476      * because VGA chip is not initialized by VGA BIOS.
   3477      */
   3478 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
   3479     if (IsPciCard && xf86IsPc98()) {
   3480         PC98TRIDENTInit(pScrn);
   3481     } else
   3482 #endif
   3483         tridentSetModeBIOS(pScrn,pScrn->currentMode);
   3484 
   3485     /* Initialise the first mode */
   3486     if (!TRIDENTModeInit(pScrn, pScrn->currentMode))
   3487         return FALSE;
   3488 
   3489     /* Darken the screen for aesthetic reasons and set the viewport */
   3490     TRIDENTSaveScreen(pScreen, SCREEN_SAVER_ON);
   3491     TRIDENTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
   3492 
   3493     /*
   3494      * The next step is to setup the screen's visuals, and initialise the
   3495      * framebuffer code.  In cases where the framebuffer's default
   3496      * choices for things like visual layouts and bits per RGB are OK,
   3497      * this may be as simple as calling the framebuffer's ScreenInit()
   3498      * function.  If not, the visuals will need to be setup before calling
   3499      * a fb ScreenInit() function and fixed up after.
   3500      *
   3501      * For most PC hardware at depths >= 8, the defaults that fb uses
   3502      * are not appropriate.  In this driver, we fixup the visuals after.
   3503      */
   3504 
   3505     /*
   3506      * Reset visual list.
   3507      */
   3508     miClearVisualTypes();
   3509 
   3510     /* Setup the visuals we support. */
   3511 
   3512     if (!miSetVisualTypes(pScrn->depth,
   3513             miGetDefaultVisualMask(pScrn->depth),
   3514             pScrn->rgbBits, pScrn->defaultVisual)) {
   3515         if (pTrident->pVbe)
   3516             vbeFree(pTrident->pVbe);
   3517         else
   3518             xf86FreeInt10(pTrident->Int10);
   3519         return FALSE;
   3520     }
   3521 
   3522     miSetPixmapDepths ();
   3523 
   3524     /* FIXME - we don't do shadowfb for < 4 */
   3525     displayWidth = pScrn->displayWidth;
   3526     if (pTrident->Rotate) {
   3527         height = pScrn->virtualX;
   3528         width = pScrn->virtualY;
   3529     } else {
   3530         width = pScrn->virtualX;
   3531         height = pScrn->virtualY;
   3532     }
   3533 
   3534     if(pTrident->ShadowFB) {
   3535         pTrident->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
   3536         pTrident->ShadowPtr = malloc(pTrident->ShadowPitch * height);
   3537         displayWidth = pTrident->ShadowPitch / (pScrn->bitsPerPixel >> 3);
   3538         FBStart = pTrident->ShadowPtr;
   3539     } else {
   3540         pTrident->ShadowFB = FALSE;
   3541         pTrident->ShadowPtr = NULL;
   3542         FBStart = pTrident->FbBase;
   3543     }
   3544 
   3545     /*
   3546      * Call the framebuffer layer's ScreenInit function, and fill in other
   3547      * pScreen fields.
   3548      */
   3549 
   3550     switch (pScrn->bitsPerPixel) {
   3551     case 8:
   3552     case 16:
   3553     case 24:
   3554     case 32:
   3555         ret = fbScreenInit(pScreen, FBStart, width,
   3556                 height, pScrn->xDpi, pScrn->yDpi,
   3557                 displayWidth, pScrn->bitsPerPixel);
   3558 
   3559         break;
   3560     default:
   3561         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   3562                 "Internal error: invalid bpp (%d) in TRIDENTScrnInit\n",
   3563                 pScrn->bitsPerPixel);
   3564         ret = FALSE;
   3565         break;
   3566     }
   3567     if (!ret) {
   3568         if (pTrident->pVbe)
   3569             vbeFree(pTrident->pVbe);
   3570         else
   3571             xf86FreeInt10(pTrident->Int10);
   3572         return FALSE;
   3573     }
   3574     if (pScrn->bitsPerPixel > 8) {
   3575         /* Fixup RGB ordering */
   3576         visual = pScreen->visuals + pScreen->numVisuals;
   3577         while (--visual >= pScreen->visuals) {
   3578             if ((visual->class | DynamicClass) == DirectColor) {
   3579                 visual->offsetRed = pScrn->offset.red;
   3580                 visual->offsetGreen = pScrn->offset.green;
   3581                 visual->offsetBlue = pScrn->offset.blue;
   3582                 visual->redMask = pScrn->mask.red;
   3583                 visual->greenMask = pScrn->mask.green;
   3584                 visual->blueMask = pScrn->mask.blue;
   3585             }
   3586         }
   3587     }
   3588 
   3589     /* must be after RGB ordering fixed */
   3590     fbPictureInit (pScreen, 0, 0);
   3591 
   3592     xf86SetBlackWhitePixels(pScreen);
   3593 
   3594     pTrident->BlockHandler = pScreen->BlockHandler;
   3595     pScreen->BlockHandler = TRIDENTBlockHandler;
   3596 
   3597     if (!pTrident->ShadowFB)
   3598         TRIDENTDGAInit(pScreen);
   3599 
   3600 #ifdef HAVE_ISA
   3601     if (!LINEAR()) {
   3602         miBankInfoPtr pBankInfo;
   3603 
   3604         /* Setup the vga banking variables */
   3605         pBankInfo = xnfcalloc(sizeof(miBankInfoRec),1);
   3606         if (pBankInfo == NULL) {
   3607             if (pTrident->pVbe)
   3608                 vbeFree(pTrident->pVbe);
   3609             else
   3610                 xf86FreeInt10(pTrident->Int10);
   3611             return FALSE;
   3612         }
   3613         pBankInfo->pBankA = pTrident->FbBase;
   3614         pBankInfo->pBankB = pTrident->FbBase;
   3615         pBankInfo->BankSize = 0x10000;
   3616         pBankInfo->nBankDepth = (pScrn->depth == 4) ? 1 : pScrn->depth;
   3617 
   3618         pBankInfo->SetSourceBank =
   3619                 (miBankProcPtr)TVGA8900SetRead;
   3620         pBankInfo->SetDestinationBank =
   3621                 (miBankProcPtr)TVGA8900SetWrite;
   3622         pBankInfo->SetSourceAndDestinationBanks =
   3623                 (miBankProcPtr)TVGA8900SetReadWrite;
   3624         if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
   3625                 pScrn->displayWidth, pBankInfo)) {
   3626             free(pBankInfo);
   3627             pBankInfo = NULL;
   3628             if (pTrident->pVbe)
   3629                 vbeFree(pTrident->pVbe);
   3630             else
   3631                 xf86FreeInt10(pTrident->Int10);
   3632             return FALSE;
   3633         }
   3634     }
   3635 #endif
   3636 
   3637     {
   3638         BoxRec AvailFBArea;
   3639 
   3640         AvailFBArea.x1 = 0;
   3641         AvailFBArea.y1 = 0;
   3642         AvailFBArea.x2 = pScrn->displayWidth;
   3643         AvailFBArea.y2 = pTrident->FbMapSize / (pScrn->displayWidth *
   3644                 pScrn->bitsPerPixel / 8);
   3645 
   3646         if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047;
   3647 
   3648         if (xf86InitFBManager(pScreen, &AvailFBArea)) {
   3649             int cpp = pScrn->bitsPerPixel / 8;
   3650             int area = AvailFBArea.y2 * pScrn->displayWidth;
   3651             int areaoffset = area * cpp;
   3652 
   3653             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   3654                     "Using %i scanlines of offscreen memory for area's \n",
   3655                     AvailFBArea.y2 - pScrn->virtualY);
   3656 
   3657             if (xf86InitFBManagerLinear(pScreen, area, ((pTrident->FbMapSize/cpp) - area))) {
   3658                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   3659                         "Using %ld bytes of offscreen memory for linear (offset=0x%x)\n", (pTrident->FbMapSize - areaoffset), areaoffset);
   3660             }
   3661         }
   3662     }
   3663 
   3664     if (Is3Dchip) {
   3665         if ((pTrident->Chipset == CYBERBLADEI7) ||
   3666                 (pTrident->Chipset == CYBERBLADEI7D) ||
   3667                 (pTrident->Chipset == CYBERBLADEI1) ||
   3668                 (pTrident->Chipset == CYBERBLADEI1D) ||
   3669                 (pTrident->Chipset == CYBERBLADEAI1) ||
   3670                 (pTrident->Chipset == CYBERBLADEAI1D) ||
   3671                 (pTrident->Chipset == CYBERBLADEE4) ||
   3672                 (pTrident->Chipset == BLADE3D)) {
   3673             if (pTrident->useEXA)
   3674                 BladeExaInit(pScreen);
   3675             else
   3676                 BladeXaaInit(pScreen);
   3677         } else
   3678             if ((pTrident->Chipset == CYBERBLADEXP4) ||
   3679                     (pTrident->Chipset == XP5)) {
   3680                 if (pTrident->useEXA)
   3681                     XP4ExaInit(pScreen);
   3682                 else
   3683                     XP4XaaInit(pScreen);
   3684             } else
   3685                 if ((pTrident->Chipset == BLADEXP) ||
   3686                         (pTrident->Chipset == CYBERBLADEXPAI1)) {
   3687                     XPAccelInit(pScreen);
   3688                 } else {
   3689                     ImageAccelInit(pScreen);
   3690                 }
   3691     } else {
   3692         TridentAccelInit(pScreen);
   3693     }
   3694 
   3695     xf86SetBackingStore(pScreen);
   3696 
   3697     /* Initialise cursor functions */
   3698     miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
   3699 
   3700     if (pTrident->HWCursor) {
   3701         xf86SetSilkenMouse(pScreen);
   3702         TridentHWCursorInit(pScreen);
   3703     }
   3704 
   3705     /* Initialise default colourmap */
   3706     if (!miCreateDefColormap(pScreen)) {
   3707         if (pTrident->pVbe)
   3708             vbeFree(pTrident->pVbe);
   3709         else
   3710             xf86FreeInt10(pTrident->Int10);
   3711         return FALSE;
   3712     }
   3713     if(!xf86HandleColormaps(pScreen, 256, 6, TridentLoadPalette,
   3714             TridentSetOverscan, CMAP_RELOAD_ON_MODE_SWITCH|CMAP_PALETTED_TRUECOLOR)) {
   3715         if (pTrident->pVbe)
   3716             vbeFree(pTrident->pVbe);
   3717         else
   3718             xf86FreeInt10(pTrident->Int10);
   3719         return FALSE;
   3720     }
   3721     if(pTrident->ShadowFB) {
   3722         if(pTrident->Rotate) {
   3723             if (!pTrident->PointerMoved) {
   3724                 pTrident->PointerMoved = pScrn->PointerMoved;
   3725                 pScrn->PointerMoved = TRIDENTPointerMoved;
   3726             }
   3727             switch (pScrn->bitsPerPixel) {
   3728             case 8:    pTrident->RefreshArea = TRIDENTRefreshArea8; break;
   3729             case 16:   pTrident->RefreshArea = TRIDENTRefreshArea16; break;
   3730             case 24:   pTrident->RefreshArea = TRIDENTRefreshArea24; break;
   3731             case 32:   pTrident->RefreshArea = TRIDENTRefreshArea32; break;
   3732             }
   3733         } else {
   3734             pTrident->RefreshArea = TRIDENTRefreshArea;
   3735         }
   3736         if (!shadowSetup(pScreen))
   3737             return FALSE;
   3738         pTrident->CreateScreenResources = pScreen->CreateScreenResources;
   3739         pScreen->CreateScreenResources = TRIDENTCreateScreenResources;
   3740     }
   3741 
   3742     xf86DPMSInit(pScreen, (DPMSSetProcPtr)TRIDENTDisplayPowerManagementSet, 0);
   3743 
   3744     pScrn->memPhysBase = pTrident->FbAddress;
   3745     pScrn->fbOffset = 0;
   3746 
   3747     if (pTrident->Chipset >= TGUI9660)
   3748         TRIDENTInitVideo(pScreen);
   3749 
   3750     pTrident->CloseScreen = pScreen->CloseScreen;
   3751     pScreen->CloseScreen = TRIDENTCloseScreen;
   3752     pScreen->SaveScreen = TRIDENTSaveScreen;
   3753 
   3754     /* Report any unused options (only for the first generation) */
   3755     if (serverGeneration == 1) {
   3756         xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
   3757     }
   3758 
   3759 #if 0
   3760     TRIDENTI2CInit(pScreen);
   3761 
   3762     xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,pTrident->DDC));
   3763 #endif
   3764 
   3765     return TRUE;
   3766 }
   3767 
   3768