195b296d0Smrg/*
295b296d0Smrg * Copyright 1992-2003 by Alan Hourihane, North Wales, UK.
395b296d0Smrg *
495b296d0Smrg * Permission to use, copy, modify, distribute, and sell this software and its
595b296d0Smrg * documentation for any purpose is hereby granted without fee, provided that
695b296d0Smrg * the above copyright notice appear in all copies and that both that
795b296d0Smrg * copyright notice and this permission notice appear in supporting
895b296d0Smrg * documentation, and that the name of Alan Hourihane not be used in
995b296d0Smrg * advertising or publicity pertaining to distribution of the software without
1095b296d0Smrg * specific, written prior permission.  Alan Hourihane makes no representations
1195b296d0Smrg * about the suitability of this software for any purpose.  It is provided
1295b296d0Smrg * "as is" without express or implied warranty.
1395b296d0Smrg *
1495b296d0Smrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1595b296d0Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1695b296d0Smrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1795b296d0Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1895b296d0Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1995b296d0Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2095b296d0Smrg * PERFORMANCE OF THIS SOFTWARE.
2195b296d0Smrg *
2295b296d0Smrg * Author:  Alan Hourihane, alanh@fairlite.demon.co.uk
230b7217d9Smrg *          Re-written for XFree86 v4.0
2495b296d0Smrg *
2595b296d0Smrg * Previous driver (pre-XFree86 v4.0) by
260b7217d9Smrg *          Alan Hourihane, alanh@fairlite.demon.co.uk
270b7217d9Smrg *          David Wexelblat (major contributor)
280b7217d9Smrg *          Massimiliano Ghilardi, max@Linuz.sns.it, some fixes to the
290b7217d9Smrg *                                 clockchip programming code.
3095b296d0Smrg */
3195b296d0Smrg
3295b296d0Smrg#ifdef HAVE_CONFIG_H
3395b296d0Smrg#include "config.h"
3495b296d0Smrg#endif
3595b296d0Smrg
3695b296d0Smrg#include "fb.h"
3795b296d0Smrg
382378475aSmrg#ifdef HAVE_ISA
3995b296d0Smrg#include "mibank.h"
402378475aSmrg#endif
4195b296d0Smrg#include "micmap.h"
4295b296d0Smrg#include "xf86.h"
4395b296d0Smrg#include "xf86_OSproc.h"
44e6f085baSmrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
4595b296d0Smrg#include "xf86Resources.h"
46e6f085baSmrg#include "xf86RAC.h"
47e6f085baSmrg#endif
4895b296d0Smrg#include "xf86Pci.h"
4995b296d0Smrg#include "xf86cmap.h"
5095b296d0Smrg#include "vgaHW.h"
51e6f085baSmrg
5295b296d0Smrg#include "vbe.h"
5395b296d0Smrg#include "dixstruct.h"
5495b296d0Smrg#include "compiler.h"
5595b296d0Smrg
5695b296d0Smrg#include "mipointer.h"
5795b296d0Smrg
5895b296d0Smrg#include "shadow.h"
5995b296d0Smrg#include "trident.h"
6095b296d0Smrg#include "trident_regs.h"
6195b296d0Smrg
6295b296d0Smrg#ifdef XFreeXDGA
6395b296d0Smrg#define _XF86DGA_SERVER_
6414330f12Smrg#include <X11/extensions/xf86dgaproto.h>
6595b296d0Smrg#endif
6695b296d0Smrg
6795b296d0Smrg#include "globals.h"
68e6f085baSmrg#ifdef HAVE_XEXTPROTO_71
69e6f085baSmrg#include <X11/extensions/dpmsconst.h>
70e6f085baSmrg#else
7195b296d0Smrg#define DPMS_SERVER
7295b296d0Smrg#include <X11/extensions/dpms.h>
73e6f085baSmrg#endif
74e6f085baSmrg
7595b296d0Smrg#include "xf86xv.h"
7695b296d0Smrg
7795b296d0Smrgstatic const OptionInfoRec * TRIDENTAvailableOptions(int chipid, int busid);
780b7217d9Smrgstatic void     TRIDENTIdentify(int flags);
790b7217d9Smrgstatic Bool     TRIDENTProbe(DriverPtr drv, int flags);
800b7217d9Smrgstatic Bool     TRIDENTPreInit(ScrnInfoPtr pScrn, int flags);
810b7217d9Smrgstatic Bool     TRIDENTScreenInit(SCREEN_INIT_ARGS_DECL);
8295b296d0Smrg
8395b296d0Smrg/*
8495b296d0Smrg * This is intentionally screen-independent.  It indicates the binding
8595b296d0Smrg * choice made in the first PreInit.
8695b296d0Smrg */
8795b296d0Smrgstatic int pix24bpp = 0;
880b7217d9Smrg
8995b296d0Smrg#define TRIDENT_VERSION 4000
9095b296d0Smrg#define TRIDENT_NAME "TRIDENT"
9195b296d0Smrg#define TRIDENT_DRIVER_NAME "trident"
92ff89ac2bSmrg#define TRIDENT_MAJOR_VERSION PACKAGE_VERSION_MAJOR
93ff89ac2bSmrg#define TRIDENT_MINOR_VERSION PACKAGE_VERSION_MINOR
94ff89ac2bSmrg#define TRIDENT_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL
9595b296d0Smrg
9695b296d0Smrg/*
9795b296d0Smrg * This contains the functions needed by the server after loading the driver
9895b296d0Smrg * module.  It must be supplied, and gets passed back by the SetupProc
9995b296d0Smrg * function in the dynamic case.  In the static case, a reference to this
10095b296d0Smrg * is compiled in, and this requires that the name of this DriverRec be
10195b296d0Smrg * an upper-case version of the driver name.
10295b296d0Smrg */
10395b296d0Smrg
10495b296d0Smrg_X_EXPORT DriverRec TRIDENT = {
10595b296d0Smrg    TRIDENT_VERSION,
10695b296d0Smrg    TRIDENT_DRIVER_NAME,
10795b296d0Smrg    TRIDENTIdentify,
10895b296d0Smrg    TRIDENTProbe,
10995b296d0Smrg    TRIDENTAvailableOptions,
11095b296d0Smrg    NULL,
11195b296d0Smrg    0
11295b296d0Smrg};
11395b296d0Smrg
11495b296d0Smrgstatic SymTabRec TRIDENTChipsets[] = {
1150b7217d9Smrg    { TVGA9000,         "tvga9000" },
1160b7217d9Smrg    { TVGA9000i,        "tvga9000i" },
1170b7217d9Smrg    { TVGA8900C,        "tvga8900c" },
1180b7217d9Smrg    { TVGA8900D,        "tvga8900d" },
1190b7217d9Smrg    { TVGA9200CXr,      "tvga9200cxr" },
1200b7217d9Smrg    { TGUI9400CXi,      "tgui9400cxi" },
1210b7217d9Smrg    { CYBER9320,        "cyber9320" },
1220b7217d9Smrg    { CYBER9388,        "cyber9388" },
1230b7217d9Smrg    { CYBER9397,        "cyber9397" },
1240b7217d9Smrg    { CYBER9397DVD,     "cyber9397dvd" },
1250b7217d9Smrg    { CYBER9520,        "cyber9520" },
1260b7217d9Smrg    { CYBER9525DVD,     "cyber9525dvd" },
1270b7217d9Smrg    { CYBERBLADEE4,     "cyberblade/e4" },
1280b7217d9Smrg    { TGUI9420DGi,      "tgui9420dgi" },
1290b7217d9Smrg    { TGUI9440AGi,      "tgui9440agi" },
1300b7217d9Smrg    { TGUI9660,         "tgui9660" },
1310b7217d9Smrg    { TGUI9680,         "tgui9680" },
1320b7217d9Smrg    { PROVIDIA9682,     "providia9682" },
1330b7217d9Smrg    { PROVIDIA9685,     "providia9685" },
1340b7217d9Smrg    { CYBER9382,        "cyber9382" },
1350b7217d9Smrg    { CYBER9385,        "cyber9385" },
1360b7217d9Smrg    { IMAGE975,         "3dimage975" },
1370b7217d9Smrg    { IMAGE985,         "3dimage985" },
1380b7217d9Smrg    { BLADE3D,          "blade3d" },
1390b7217d9Smrg    { CYBERBLADEI7,     "cyberbladei7" },
1400b7217d9Smrg    { CYBERBLADEI7D,    "cyberbladei7d" },
1410b7217d9Smrg    { CYBERBLADEI1,     "cyberbladei1" },
1420b7217d9Smrg    { CYBERBLADEI1D,    "cyberbladei1d" },
1430b7217d9Smrg    { CYBERBLADEAI1,    "cyberbladeAi1" },
1440b7217d9Smrg    { CYBERBLADEAI1D,   "cyberbladeAi1d" },
1450b7217d9Smrg    { BLADEXP,          "bladeXP" },
1460b7217d9Smrg    { CYBERBLADEXPAI1,  "cyberbladeXPAi1" },
1470b7217d9Smrg    { CYBERBLADEXP4,    "cyberbladeXP4" },
1480b7217d9Smrg    { XP5,              "XP5" },
1490b7217d9Smrg    { -1,               NULL }
15095b296d0Smrg};
15195b296d0Smrg
152ff89ac2bSmrg#ifdef HAVE_ISA
15395b296d0Smrgstatic IsaChipsets TRIDENTISAchipsets[] = {
1540b7217d9Smrg    { TVGA9000,         RES_EXCLUSIVE_VGA },
1550b7217d9Smrg    { TVGA9000i,        RES_EXCLUSIVE_VGA },
1560b7217d9Smrg    { TVGA8900C,        RES_EXCLUSIVE_VGA },
1570b7217d9Smrg    { TVGA8900D,        RES_EXCLUSIVE_VGA },
1580b7217d9Smrg    { TVGA9200CXr,      RES_EXCLUSIVE_VGA },
1590b7217d9Smrg    { TGUI9400CXi,      RES_EXCLUSIVE_VGA },
1600b7217d9Smrg    { CYBER9320,        RES_EXCLUSIVE_VGA },
1610b7217d9Smrg    { TGUI9440AGi,      RES_EXCLUSIVE_VGA },
1620b7217d9Smrg    { -1,               RES_UNDEFINED }
16395b296d0Smrg};
164ff89ac2bSmrg#endif
16595b296d0Smrg
16695b296d0Smrgstatic PciChipsets TRIDENTPciChipsets[] = {
1670b7217d9Smrg    { CYBER9320,        PCI_CHIP_9320,  RES_SHARED_VGA },
1680b7217d9Smrg    { CYBER9388,        PCI_CHIP_9388,  RES_SHARED_VGA },
1690b7217d9Smrg    { CYBER9397,        PCI_CHIP_9397,  RES_SHARED_VGA },
1700b7217d9Smrg    { CYBER9397DVD,     PCI_CHIP_939A,  RES_SHARED_VGA },
1710b7217d9Smrg    { CYBER9520,        PCI_CHIP_9520,  RES_SHARED_VGA },
1720b7217d9Smrg    { CYBER9525DVD,     PCI_CHIP_9525,  RES_SHARED_VGA },
1730b7217d9Smrg    { CYBERBLADEE4,     PCI_CHIP_9540,  RES_SHARED_VGA },
1740b7217d9Smrg    { TGUI9420DGi,      PCI_CHIP_9420,  RES_SHARED_VGA },
1750b7217d9Smrg    { TGUI9440AGi,      PCI_CHIP_9440,  RES_SHARED_VGA },
1760b7217d9Smrg    { TGUI9660,         PCI_CHIP_9660,  RES_SHARED_VGA },
1770b7217d9Smrg    { TGUI9680,         PCI_CHIP_9660,  RES_SHARED_VGA },
1780b7217d9Smrg    { PROVIDIA9682,     PCI_CHIP_9660,  RES_SHARED_VGA },
1790b7217d9Smrg    { PROVIDIA9685,     PCI_CHIP_9660,  RES_SHARED_VGA },
1800b7217d9Smrg    { CYBER9382,        PCI_CHIP_9660,  RES_SHARED_VGA },
1810b7217d9Smrg    { CYBER9385,        PCI_CHIP_9660,  RES_SHARED_VGA },
1820b7217d9Smrg    { IMAGE975,         PCI_CHIP_9750,  RES_SHARED_VGA },
1830b7217d9Smrg    { IMAGE985,         PCI_CHIP_9850,  RES_SHARED_VGA },
1840b7217d9Smrg    { BLADE3D,          PCI_CHIP_9880,  RES_SHARED_VGA },
1850b7217d9Smrg    { CYBERBLADEI7,     PCI_CHIP_8400,  RES_SHARED_VGA },
1860b7217d9Smrg    { CYBERBLADEI7D,    PCI_CHIP_8420,  RES_SHARED_VGA },
1870b7217d9Smrg    { CYBERBLADEI1,     PCI_CHIP_8500,  RES_SHARED_VGA },
1880b7217d9Smrg    { CYBERBLADEI1D,    PCI_CHIP_8520,  RES_SHARED_VGA },
1890b7217d9Smrg    { CYBERBLADEAI1,    PCI_CHIP_8600,  RES_SHARED_VGA },
1900b7217d9Smrg    { CYBERBLADEAI1D,   PCI_CHIP_8620,  RES_SHARED_VGA },
1910b7217d9Smrg    { BLADEXP,          PCI_CHIP_9910,  RES_SHARED_VGA },
1920b7217d9Smrg    { CYBERBLADEXPAI1,  PCI_CHIP_8820,  RES_SHARED_VGA },
1930b7217d9Smrg    { CYBERBLADEXP4,    PCI_CHIP_2100,  RES_SHARED_VGA },
1940b7217d9Smrg    { XP5,              PCI_CHIP_2200,  RES_SHARED_VGA },
1950b7217d9Smrg    { -1,               -1,             RES_UNDEFINED }
19695b296d0Smrg};
1970b7217d9Smrg
19895b296d0Smrgtypedef enum {
19995b296d0Smrg    OPTION_ACCELMETHOD,
20095b296d0Smrg    OPTION_SW_CURSOR,
20195b296d0Smrg    OPTION_PCI_RETRY,
20295b296d0Smrg    OPTION_RGB_BITS,
20395b296d0Smrg    OPTION_NOACCEL,
20495b296d0Smrg    OPTION_SETMCLK,
20595b296d0Smrg    OPTION_MUX_THRESHOLD,
20695b296d0Smrg    OPTION_SHADOW_FB,
20795b296d0Smrg    OPTION_ROTATE,
20895b296d0Smrg    OPTION_MMIO_ONLY,
20995b296d0Smrg    OPTION_VIDEO_KEY,
21095b296d0Smrg    OPTION_NOMMIO,
21195b296d0Smrg    OPTION_NOPCIBURST,
21295b296d0Smrg    OPTION_CYBER_SHADOW,
21395b296d0Smrg    OPTION_CYBER_STRETCH,
21495b296d0Smrg    OPTION_XV_HSYNC,
21595b296d0Smrg    OPTION_XV_VSYNC,
21695b296d0Smrg    OPTION_XV_BSKEW,
21795b296d0Smrg    OPTION_XV_RSKEW,
21895b296d0Smrg    OPTION_FP_DELAY,
21995b296d0Smrg    OPTION_1400_DISPLAY,
22095b296d0Smrg    OPTION_DISPLAY,
22195b296d0Smrg    OPTION_GB,
22295b296d0Smrg    OPTION_TV_CHIPSET,
22395b296d0Smrg    OPTION_TV_SIGNALMODE
22495b296d0Smrg} TRIDENTOpts;
22595b296d0Smrg
22695b296d0Smrgstatic const OptionInfoRec TRIDENTOptions[] = {
2270b7217d9Smrg    { OPTION_ACCELMETHOD,       "AccelMethod",      OPTV_ANYSTR,    {0}, FALSE },
2280b7217d9Smrg    { OPTION_SW_CURSOR,         "SWcursor",         OPTV_BOOLEAN,   {0}, FALSE },
2290b7217d9Smrg    { OPTION_PCI_RETRY,         "PciRetry",         OPTV_BOOLEAN,   {0}, FALSE },
2300b7217d9Smrg    { OPTION_NOACCEL,           "NoAccel",          OPTV_BOOLEAN,   {0}, FALSE },
2310b7217d9Smrg    { OPTION_SETMCLK,           "SetMClk",          OPTV_FREQ,      {0}, FALSE },
2320b7217d9Smrg    { OPTION_MUX_THRESHOLD,     "MUXThreshold",     OPTV_INTEGER,   {0}, FALSE },
2330b7217d9Smrg    { OPTION_SHADOW_FB,         "ShadowFB",         OPTV_BOOLEAN,   {0}, FALSE },
2340b7217d9Smrg    { OPTION_ROTATE,            "Rotate",           OPTV_ANYSTR,    {0}, FALSE },
2350b7217d9Smrg    { OPTION_VIDEO_KEY,         "VideoKey",         OPTV_INTEGER,   {0}, FALSE },
2360b7217d9Smrg    { OPTION_NOMMIO,            "NoMMIO",           OPTV_BOOLEAN,   {0}, FALSE },
2370b7217d9Smrg    { OPTION_NOPCIBURST,        "NoPciBurst",       OPTV_BOOLEAN,   {0}, FALSE },
2380b7217d9Smrg    { OPTION_MMIO_ONLY,         "MMIOonly",         OPTV_BOOLEAN,   {0}, FALSE },
2390b7217d9Smrg    { OPTION_CYBER_SHADOW,      "CyberShadow",      OPTV_BOOLEAN,   {0}, FALSE },
2400b7217d9Smrg    { OPTION_CYBER_STRETCH,     "CyberStretch",     OPTV_BOOLEAN,   {0}, FALSE },
2410b7217d9Smrg    { OPTION_XV_HSYNC,          "XvHsync",          OPTV_INTEGER,   {0}, FALSE },
2420b7217d9Smrg    { OPTION_XV_VSYNC,          "XvVsync",          OPTV_INTEGER,   {0}, FALSE },
2430b7217d9Smrg    { OPTION_XV_BSKEW,          "XvBskew",          OPTV_INTEGER,   {0}, FALSE },
2440b7217d9Smrg    { OPTION_XV_RSKEW,          "XvRskew",          OPTV_INTEGER,   {0}, FALSE },
2450b7217d9Smrg    { OPTION_FP_DELAY,          "FpDelay",          OPTV_INTEGER,   {0}, FALSE },
2460b7217d9Smrg    { OPTION_1400_DISPLAY,      "Display1400",      OPTV_BOOLEAN,   {0}, FALSE },
2470b7217d9Smrg    { OPTION_DISPLAY,           "Display",          OPTV_ANYSTR,    {0}, FALSE },
2480b7217d9Smrg    { OPTION_GB,                "GammaBrightness",  OPTV_ANYSTR,    {0}, FALSE },
2490b7217d9Smrg    { OPTION_TV_CHIPSET,        "TVChipset",        OPTV_ANYSTR,    {0}, FALSE },
2500b7217d9Smrg    { OPTION_TV_SIGNALMODE,     "TVSignal",         OPTV_INTEGER,   {0}, FALSE },
2510b7217d9Smrg    { -1,                       NULL,               OPTV_NONE,      {0}, FALSE }
25295b296d0Smrg};
25395b296d0Smrg
25495b296d0Smrg/* Clock Limits */
25595b296d0Smrgstatic int ClockLimit[] = {
2560b7217d9Smrg    80000,
2570b7217d9Smrg    80000,
2580b7217d9Smrg    80000,
2590b7217d9Smrg    80000,
2600b7217d9Smrg    80000,
2610b7217d9Smrg    80000,
2620b7217d9Smrg    80000,
2630b7217d9Smrg    80000,
2640b7217d9Smrg    80000,
2650b7217d9Smrg    80000,
2660b7217d9Smrg    80000,
2670b7217d9Smrg    80000,
2680b7217d9Smrg    80000,
2690b7217d9Smrg    80000,
2700b7217d9Smrg    90000,
2710b7217d9Smrg    90000,
2720b7217d9Smrg    135000,
2730b7217d9Smrg    135000,
2740b7217d9Smrg    170000,
2750b7217d9Smrg    170000,
2760b7217d9Smrg    170000,
2770b7217d9Smrg    170000,
2780b7217d9Smrg    170000,
2790b7217d9Smrg    170000,
2800b7217d9Smrg    170000,
2810b7217d9Smrg    230000,
2820b7217d9Smrg    230000,
2830b7217d9Smrg    230000,
2840b7217d9Smrg    230000,
2850b7217d9Smrg    230000,
2860b7217d9Smrg    230000,
2870b7217d9Smrg    230000,
2880b7217d9Smrg    230000,
2890b7217d9Smrg    230000,
2900b7217d9Smrg    230000,
2910b7217d9Smrg    230000,
2920b7217d9Smrg    230000,
2930b7217d9Smrg    230000,
2940b7217d9Smrg    230000,
2950b7217d9Smrg    230000,
2960b7217d9Smrg    230000,
29795b296d0Smrg};
29895b296d0Smrg
29995b296d0Smrgstatic int ClockLimit16bpp[] = {
3000b7217d9Smrg    40000,
3010b7217d9Smrg    40000,
3020b7217d9Smrg    40000,
3030b7217d9Smrg    40000,
3040b7217d9Smrg    40000,
3050b7217d9Smrg    40000,
3060b7217d9Smrg    40000,
3070b7217d9Smrg    40000,
3080b7217d9Smrg    40000,
3090b7217d9Smrg    40000,
3100b7217d9Smrg    40000,
3110b7217d9Smrg    40000,
3120b7217d9Smrg    40000,
3130b7217d9Smrg    40000,
3140b7217d9Smrg    45000,
3150b7217d9Smrg    45000,
3160b7217d9Smrg    90000,
3170b7217d9Smrg    90000,
3180b7217d9Smrg    135000,
3190b7217d9Smrg    135000,
3200b7217d9Smrg    170000,
3210b7217d9Smrg    170000,
3220b7217d9Smrg    170000,
3230b7217d9Smrg    170000,
3240b7217d9Smrg    170000,
3250b7217d9Smrg    230000,
3260b7217d9Smrg    230000,
3270b7217d9Smrg    230000,
3280b7217d9Smrg    230000,
3290b7217d9Smrg    230000,
3300b7217d9Smrg    230000,
3310b7217d9Smrg    230000,
3320b7217d9Smrg    230000,
3330b7217d9Smrg    230000,
3340b7217d9Smrg    230000,
3350b7217d9Smrg    230000,
3360b7217d9Smrg    230000,
3370b7217d9Smrg    230000,
3380b7217d9Smrg    230000,
3390b7217d9Smrg    230000,
3400b7217d9Smrg    230000,
34195b296d0Smrg};
34295b296d0Smrg
34395b296d0Smrgstatic int ClockLimit24bpp[] = {
3440b7217d9Smrg    25180,
3450b7217d9Smrg    25180,
3460b7217d9Smrg    25180,
3470b7217d9Smrg    25180,
3480b7217d9Smrg    25180,
3490b7217d9Smrg    25180,
3500b7217d9Smrg    25180,
3510b7217d9Smrg    25180,
3520b7217d9Smrg    25180,
3530b7217d9Smrg    25180,
3540b7217d9Smrg    25180,
3550b7217d9Smrg    25180,
3560b7217d9Smrg    25180,
3570b7217d9Smrg    25180,
3580b7217d9Smrg    25180,
3590b7217d9Smrg    25180,
3600b7217d9Smrg    40000,
3610b7217d9Smrg    40000,
3620b7217d9Smrg    70000,
3630b7217d9Smrg    70000,
3640b7217d9Smrg    70000,
3650b7217d9Smrg    115000,
3660b7217d9Smrg    115000,
3670b7217d9Smrg    115000,
3680b7217d9Smrg    115000,
3690b7217d9Smrg    115000,
3700b7217d9Smrg    115000,
3710b7217d9Smrg    115000,
3720b7217d9Smrg    115000,
3730b7217d9Smrg    115000,
3740b7217d9Smrg    115000,
3750b7217d9Smrg    115000,
3760b7217d9Smrg    115000,
3770b7217d9Smrg    115000,
3780b7217d9Smrg    115000,
3790b7217d9Smrg    115000,
3800b7217d9Smrg    115000,
3810b7217d9Smrg    115000,
3820b7217d9Smrg    115000,
3830b7217d9Smrg    115000,
3840b7217d9Smrg    115000,
38595b296d0Smrg};
38695b296d0Smrg
38795b296d0Smrgstatic int ClockLimit32bpp[] = {
3880b7217d9Smrg    25180,
3890b7217d9Smrg    25180,
3900b7217d9Smrg    25180,
3910b7217d9Smrg    25180,
3920b7217d9Smrg    25180,
3930b7217d9Smrg    25180,
3940b7217d9Smrg    25180,
3950b7217d9Smrg    25180,
3960b7217d9Smrg    25180,
3970b7217d9Smrg    25180,
3980b7217d9Smrg    25180,
3990b7217d9Smrg    25180,
4000b7217d9Smrg    25180,
4010b7217d9Smrg    25180,
4020b7217d9Smrg    25180,
4030b7217d9Smrg    25180,
4040b7217d9Smrg    40000,
4050b7217d9Smrg    40000,
4060b7217d9Smrg    70000,
4070b7217d9Smrg    70000,
4080b7217d9Smrg    70000,
4090b7217d9Smrg    115000,
4100b7217d9Smrg    115000,
4110b7217d9Smrg    115000,
4120b7217d9Smrg    115000,
4130b7217d9Smrg    115000,
4140b7217d9Smrg    115000,
4150b7217d9Smrg    115000,
4160b7217d9Smrg    115000,
4170b7217d9Smrg    115000,
4180b7217d9Smrg    115000,
4190b7217d9Smrg    115000,
4200b7217d9Smrg    115000,
4210b7217d9Smrg    115000,
4220b7217d9Smrg    115000,
4230b7217d9Smrg    115000,
4240b7217d9Smrg    115000,
4250b7217d9Smrg    115000,
4260b7217d9Smrg    115000,
4270b7217d9Smrg    115000,
4280b7217d9Smrg    115000,
4290b7217d9Smrg    115000,
43095b296d0Smrg};
43195b296d0Smrg
43295b296d0Smrg/*
43395b296d0Smrg * These are fixed modelines for all physical display dimensions the
43495b296d0Smrg *  chipsets supports on FPs. Most of them are not tested yet.
43595b296d0Smrg */
43695b296d0Smrg#if 0
43795b296d0SmrgtridentLCD LCD[] = {   /* 0    3    4    5   6    7    10   11  16 */
43895b296d0Smrg    { 0,"640x480",25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08},
43995b296d0Smrg    { 1,"800x600",40000,0x7f,0x99,0x69,0x99,0x72,0xf0,0x59,0x2d,0x5e,0x08},
44095b296d0Smrg    { 2,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08},
44195b296d0Smrg    { 3,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, /*0x96*/
44295b296d0Smrg    { 4,"1280x1024",108000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08},
44395b296d0Smrg    { 5,"1024x600",50500 ,0xa3,0x6,0x8f,0xa0,0xb,0x3e,0xea,0x8c,0xb,0x08},
44495b296d0Smrg    { 0xff,"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
44595b296d0Smrg};
44695b296d0Smrg#else
44795b296d0Smrg#if 0
44895b296d0SmrgtridentLCD LCD[] = {
44995b296d0Smrg    { 1,640,480,25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08},
45095b296d0Smrg    { 3,800,600,40000,0x7f,0x82,0x6b,0x1b,0x72,0xf8,0x58,0x8c,0x72,0x08},
45195b296d0Smrg    { 2,1024,768,65000,0xa3,/*0x6*/0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x24,0x0a,0x08},
45295b296d0Smrg    { 0,1280,1024,108000,0xce,0x81,0xa6,0x9a,0x27,0x50,0x00,0x03,0x26,0xa8},
45395b296d0Smrg    { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
45495b296d0Smrg};
45595b296d0Smrg#else
45695b296d0SmrgtridentLCD LCD[] = {
45795b296d0Smrg    { 1,640,480,25200,0x5f,0x80,0x52,0x1e,0xb,0x3e,0xea,0x0c,0xb,0x08},
45895b296d0Smrg    { 3,800,600,40000,0x7f,0x00,0x69,0x7f,0x72,0xf0,0x59,0x0d,0x00,0x08},
45995b296d0Smrg    { 2,1024,768,65000,0xa3,0x00,0x84,0x94,0x24,0xf5,0x03,0x09,0x24,0x08},
46095b296d0Smrg    { 0,1280,1024,108000,0xce,0x91,0xa6,0x14,0x28,0x5a,0x01,0x04,0x28,0xa8},
46195b296d0Smrg    { 4,1400,1050,122000,0xe6,0x8d,0xba,0x1d,0x38,0x00,0x1c,0x28,0x28,0xf8},
46295b296d0Smrg    { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
46395b296d0Smrg};
46495b296d0Smrg#endif
46595b296d0Smrg#endif
46695b296d0Smrg
46795b296d0Smrg#ifdef XFree86LOADER
46895b296d0Smrg
46995b296d0Smrgstatic MODULESETUPPROTO(tridentSetup);
47095b296d0Smrg
47195b296d0Smrgstatic XF86ModuleVersionInfo tridentVersRec =
47295b296d0Smrg{
4730b7217d9Smrg    "trident",
4740b7217d9Smrg    MODULEVENDORSTRING,
4750b7217d9Smrg    MODINFOSTRING1,
4760b7217d9Smrg    MODINFOSTRING2,
4770b7217d9Smrg    XORG_VERSION_CURRENT,
4780b7217d9Smrg    TRIDENT_MAJOR_VERSION, TRIDENT_MINOR_VERSION, TRIDENT_PATCHLEVEL,
4790b7217d9Smrg    ABI_CLASS_VIDEODRV,			/* This is a video driver */
4800b7217d9Smrg    ABI_VIDEODRV_VERSION,
4810b7217d9Smrg    MOD_CLASS_VIDEODRV,
4820b7217d9Smrg    {0,0,0,0}
48395b296d0Smrg};
48495b296d0Smrg
48595b296d0Smrg_X_EXPORT XF86ModuleData tridentModuleData = {
4860b7217d9Smrg    &tridentVersRec,
4870b7217d9Smrg    tridentSetup,
4880b7217d9Smrg    NULL
48995b296d0Smrg};
49095b296d0Smrg
49195b296d0Smrgpointer
49295b296d0SmrgtridentSetup(pointer module, pointer opts, int *errmaj, int *errmin)
49395b296d0Smrg{
49495b296d0Smrg    static Bool setupDone = FALSE;
49595b296d0Smrg
49695b296d0Smrg    if (!setupDone) {
4970b7217d9Smrg        setupDone = TRUE;
4980b7217d9Smrg        xf86AddDriver(&TRIDENT, module, 0);
4990b7217d9Smrg        return (pointer)TRUE;
50095b296d0Smrg    }
50195b296d0Smrg
50295b296d0Smrg    if (errmaj) *errmaj = LDR_ONCEONLY;
50395b296d0Smrg    return NULL;
50495b296d0Smrg}
50595b296d0Smrg
50695b296d0Smrg#endif /* XFree86LOADER */
50795b296d0Smrg
5080b7217d9Smrgstatic void
5090b7217d9SmrgTRIDENTEnableMMIO(ScrnInfoPtr pScrn)
51095b296d0Smrg{
5110b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
5120b7217d9Smrg    unsigned long vgaIOBase = pTrident->PIOBase + VGAHWPTR(pScrn)->IOBase;
5130b7217d9Smrg    CARD8 temp = 0, protect = 0;
5140b7217d9Smrg
51595b296d0Smrg    /*
5160b7217d9Smrg     * Skip MMIO Enable in PC-9821 PCI Trident Card!!
5170b7217d9Smrg     * Because of lack of non PCI VGA port
51895b296d0Smrg     */
5190b7217d9Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
5200b7217d9Smrg    if (IsPciCard && xf86IsPc98())
5210b7217d9Smrg        return;
5220b7217d9Smrg#endif
52395b296d0Smrg
5240b7217d9Smrg    /* Goto New Mode */
5250b7217d9Smrg    outb(pTrident->PIOBase + 0x3C4, 0x0B);
5260b7217d9Smrg    inb(pTrident->PIOBase + 0x3C5);
52795b296d0Smrg
5280b7217d9Smrg    /* Unprotect registers */
5290b7217d9Smrg    if (pTrident->Chipset > PROVIDIA9685) {
5300b7217d9Smrg        outb(pTrident->PIOBase + 0x3C4, Protection);
5310b7217d9Smrg        protect = inb(pTrident->PIOBase + 0x3C5);
5320b7217d9Smrg        outb(pTrident->PIOBase + 0x3C5, 0x92);
5330b7217d9Smrg    }
5340b7217d9Smrg    outb(pTrident->PIOBase + 0x3C4, NewMode1);
5350b7217d9Smrg    temp = inb(pTrident->PIOBase + 0x3C5);
5360b7217d9Smrg    outb(pTrident->PIOBase + 0x3C5, 0x80);
53795b296d0Smrg
5380b7217d9Smrg    /* Enable MMIO */
5390b7217d9Smrg    outb(vgaIOBase + 4, PCIReg);
5400b7217d9Smrg    pTrident->REGPCIReg = inb(vgaIOBase + 5);
5410b7217d9Smrg    outb(vgaIOBase + 5, pTrident->REGPCIReg | 0x01); /* Enable it */
5420b7217d9Smrg
5430b7217d9Smrg    /* Protect registers */
5440b7217d9Smrg    if (pTrident->Chipset > PROVIDIA9685) {
5450b7217d9Smrg        OUTB(0x3C4, Protection);
5460b7217d9Smrg        OUTB(0x3C5, protect);
5470b7217d9Smrg    }
5480b7217d9Smrg    OUTB(0x3C4, NewMode1);
5490b7217d9Smrg    OUTB(0x3C5, temp);
55095b296d0Smrg}
55195b296d0Smrg
5520b7217d9Smrgstatic void
5530b7217d9SmrgTRIDENTDisableMMIO(ScrnInfoPtr pScrn)
55495b296d0Smrg{
5550b7217d9Smrg    int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
5560b7217d9Smrg    CARD8 temp = 0, protect = 0;
55795b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
55895b296d0Smrg
5590b7217d9Smrg    /*
5600b7217d9Smrg     * Skip MMIO Disable in PC-9821 PCI Trident Card!!
5610b7217d9Smrg     * Because of lack of non PCI VGA port
5620b7217d9Smrg     */
5630b7217d9Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
5640b7217d9Smrg    if (IsPciCard && xf86IsPc98())
5650b7217d9Smrg        return;
5660b7217d9Smrg#endif
56795b296d0Smrg
5680b7217d9Smrg    /* Goto New Mode */
5690b7217d9Smrg    OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
5700b7217d9Smrg
5710b7217d9Smrg    /* Unprotect registers */
5720b7217d9Smrg    OUTB(0x3C4, NewMode1); temp = INB(0x3C5);
5730b7217d9Smrg    OUTB(0x3C5, 0x80);
5740b7217d9Smrg    if (pTrident->Chipset > PROVIDIA9685) {
5750b7217d9Smrg        OUTB(0x3C4, Protection);
5760b7217d9Smrg        protect = INB(0x3C5);
5770b7217d9Smrg        OUTB(0x3C5, 0x92);
57895b296d0Smrg    }
5790b7217d9Smrg
5800b7217d9Smrg    /* Disable MMIO access */
5810b7217d9Smrg    OUTB(vgaIOBase + 4, PCIReg);
5820b7217d9Smrg    pTrident->REGPCIReg = INB(vgaIOBase + 5);
5830b7217d9Smrg    OUTB(vgaIOBase + 5, pTrident->REGPCIReg & 0xFE);
5840b7217d9Smrg
5850b7217d9Smrg    /* Protect registers */
5860b7217d9Smrg    if (pTrident->Chipset > PROVIDIA9685) {
5870b7217d9Smrg        outb(pTrident->PIOBase + 0x3C4, Protection);
5880b7217d9Smrg        outb(pTrident->PIOBase + 0x3C5, protect);
5890b7217d9Smrg    }
5900b7217d9Smrg    outb(pTrident->PIOBase + 0x3C4, NewMode1);
5910b7217d9Smrg    outb(pTrident->PIOBase + 0x3C5, temp);
59295b296d0Smrg}
59395b296d0Smrg
5940b7217d9Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
5950b7217d9Smrg/* Initialize VGA Block for Cyber9385 on PC-98x1 */
59695b296d0Smrgstatic void
5970b7217d9SmrgPC98TRIDENT9385Init(ScrnInfoPtr pScrn)
598eca46af7Smrg{
5990b7217d9Smrg    /* Nothing to initialize */
6000b7217d9Smrg}
60195b296d0Smrg
6020b7217d9Smrgstatic void
6030b7217d9SmrgPC98TRIDENT9385Enable(ScrnInfoPtr pScrn)
60495b296d0Smrg{
6050b7217d9Smrg    outb(0xFAC, 0x02);
60695b296d0Smrg}
60795b296d0Smrg
60895b296d0Smrgstatic void
6090b7217d9SmrgPC98TRIDENT9385Disable(ScrnInfoPtr pScrn)
61095b296d0Smrg{
6110b7217d9Smrg    outb(0xFAC, 0x00);
61295b296d0Smrg}
61395b296d0Smrg
6140b7217d9Smrg/* Initialize VGA Block for Trident96xx on PC-98x1 */
6150b7217d9Smrgstatic void
6160b7217d9SmrgPC98TRIDENT96xxInit(ScrnInfoPtr pScrn)
61795b296d0Smrg{
61895b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
6190b7217d9Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
6200b7217d9Smrg    CARD8 temp = 0;
62195b296d0Smrg
6220b7217d9Smrg    vgaHWProtect(pScrn, TRUE);
6230b7217d9Smrg
6240b7217d9Smrg    /* Video SusSystem Enable */
6250b7217d9Smrg    temp = INB(0x3CC);
6260b7217d9Smrg    OUTB(0x3C2, temp | 0xC3);
6270b7217d9Smrg    /* Switch Old */
6280b7217d9Smrg    OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
6290b7217d9Smrg    OUTW(0x3C4, 0x0B | (temp << 8));
6300b7217d9Smrg    /* Select Configuration Port 1 */
6310b7217d9Smrg    OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
6320b7217d9Smrg    OUTW(0x3C4, 0x0E | ((temp | 0x20) << 8));
6330b7217d9Smrg
6340b7217d9Smrg    OUTB(0x3C4, 0x0c);
6350b7217d9Smrg    if((INB(0x3C5) & 0x10) == 0x10)
6360b7217d9Smrg    {
6370b7217d9Smrg        OUTB(0x3C4, 0x0E | (temp << 8));
6380b7217d9Smrg        OUTB(0x94,  0x00);
6390b7217d9Smrg        OUTB(0x102, 0x01);
6400b7217d9Smrg        OUTB(0x94,  0x20);
6410b7217d9Smrg        temp = INB(0x3C3);
6420b7217d9Smrg        OUTB(0x3C3, temp | 0x01);
6430b7217d9Smrg    } else {
6440b7217d9Smrg        OUTB(0x3C4, 0x0E | (temp << 8));
6450b7217d9Smrg        OUTB(0x46E8, 0x10);
6460b7217d9Smrg        OUTB(0x102,  0x01);
6470b7217d9Smrg        OUTB(0x46E8, 0x08);
64895b296d0Smrg    }
64995b296d0Smrg
6500b7217d9Smrg    INB(0x3DA);
6510b7217d9Smrg    OUTB(0x3C0,0x10);
6520b7217d9Smrg    OUTB(0x3C0,0x41);
65395b296d0Smrg
6540b7217d9Smrg    /* Register Unlock */
6550b7217d9Smrg    vgaHWUnlock(hwp);
6560b7217d9Smrg    OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */
6570b7217d9Smrg    OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
6580b7217d9Smrg    OUTW(0x3C4, 0x0E | ((temp | 0x80) << 8));
65995b296d0Smrg
6600b7217d9Smrg    /* For Speed Up [Facoor 2 at Xengine] */
6610b7217d9Smrg    OUTW(0x3D4, 0x3820); /* Command FIFO Register */
6620b7217d9Smrg    OUTW(0x3D4, 0x2020); /* Command FIFO Register */
6630b7217d9Smrg    /* Latency Control Registers 0x30 - 0x32 */
6640b7217d9Smrg    /* Parameter Range 0x00 - 0x0F */
6650b7217d9Smrg    /* Tune these parameter to avoid GE Timeout */
6660b7217d9Smrg    OUTW(0x3D4, 0x0E30); /* Display Queue Latency Control */
6670b7217d9Smrg    /* 8bpp GE No Timeout Parameter 0x0D - 0x0F for PC-9821Xa7 TGUi9680 */
6680b7217d9Smrg    OUTW(0x3D4, 0x0031); /* Frame Buffer Latency Control */
6690b7217d9Smrg    OUTW(0x3D4, 0x0032); /* Display & Frame Buffer Latency Control */
6700b7217d9Smrg    OUTW(0x3D4, 0x213B); /* Clock and Tuning */
67195b296d0Smrg
6720b7217d9Smrg    /* MCLK Init */
6730b7217d9Smrg    OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */
6740b7217d9Smrg#if 0
6750b7217d9Smrg    /* Sample MCLKs */
6760b7217d9Smrg    OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */
6770b7217d9Smrg    OUTB(0x43C6, 0xA7); OUTB(0x43C7, 0x00); /* 77.0MHz */
6780b7217d9Smrg    OUTB(0x43C6, 0x8E); OUTB(0x43C7, 0x00); /* 75.0MHz */
6790b7217d9Smrg    OUTB(0x43C6, 0x86); OUTB(0x43C7, 0x00); /* 72.0MHz */
6800b7217d9Smrg    OUTB(0x43C6, 0x8F); OUTB(0x43C7, 0x00); /* 67.2MHz */
6810b7217d9Smrg    OUTB(0x43C6, 0xD5); OUTB(0x43C7, 0x02); /* 61.6MHz */
682ff89ac2bSmrg#endif
68395b296d0Smrg
6840b7217d9Smrg    /* Register Lock */
6850b7217d9Smrg    OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */
6860b7217d9Smrg    OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
6870b7217d9Smrg    OUTW(0x3C4, 0x0E | ((temp & 0x7F) << 8));
6880b7217d9Smrg    vgaHWLock(hwp);
6890b7217d9Smrg
6900b7217d9Smrg    vgaHWProtect(pScrn, FALSE);
6910b7217d9Smrg}
69295b296d0Smrg
6930b7217d9Smrgstatic void
6940b7217d9SmrgPC98TRIDENT96xxEnable(ScrnInfoPtr pScrn)
69595b296d0Smrg{
6960b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
6970b7217d9Smrg    CARD8 temp = 0;
69895b296d0Smrg
6990b7217d9Smrg    outb(0x68, 0x0E);
7000b7217d9Smrg    outb(0x6A, 0x07);
7010b7217d9Smrg    outb(0x6A, 0x8F);
7020b7217d9Smrg    outb(0x6A, 0x06);
70395b296d0Smrg
7040b7217d9Smrg    vgaHWProtect(pScrn, TRUE);
70595b296d0Smrg
7060b7217d9Smrg    OUTB(0x3D4, 0x23); temp = INB(0x3D5);
7070b7217d9Smrg    OUTW(0x3D4, 0x23 | ((temp & 0xDF) << 8));
70895b296d0Smrg
7090b7217d9Smrg    OUTB(0x3D4, 0x29); temp = INB(0x3D5);
7100b7217d9Smrg    OUTW(0x3D4, 0x29 | ((temp | 0x04) << 8));
71195b296d0Smrg
7120b7217d9Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
7130b7217d9Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x06));
714ff89ac2bSmrg
7150b7217d9Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
7160b7217d9Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x08));
7170b7217d9Smrg
7180b7217d9Smrg    OUTB(0x3CE, 0x23); temp = INB(0x3CF);
7190b7217d9Smrg    OUTW(0x3CE, 0x23 | ((temp & 0xFC) << 8));
7200b7217d9Smrg
7210b7217d9Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
7220b7217d9Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x01));
7230b7217d9Smrg
7240b7217d9Smrg    OUTB(0x3C4, 0x01); temp = INB(0x3C5);
7250b7217d9Smrg    OUTW(0x3C4, 0x01 | ((temp & 0xEF) << 8));
7260b7217d9Smrg
7270b7217d9Smrg    vgaHWProtect(pScrn, FALSE);
7280b7217d9Smrg
7290b7217d9Smrg    outb(0xFAC, 0x02);
73095b296d0Smrg}
7310b7217d9Smrg
7320b7217d9Smrgstatic void
7330b7217d9SmrgPC98TRIDENT96xxDisable(ScrnInfoPtr pScrn)
73495b296d0Smrg{
73595b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
7360b7217d9Smrg    CARD8 temp = 0;
73795b296d0Smrg
7380b7217d9Smrg    outb(0xFAC, 0x00);
73995b296d0Smrg
7400b7217d9Smrg    vgaHWProtect(pScrn, TRUE);
7410b7217d9Smrg
7420b7217d9Smrg    OUTB(0x3C4, 0x01); temp = INB(0x3C5);
7430b7217d9Smrg    OUTW(0x3C4, 0x01 | ((temp | 0x10) << 8));
7440b7217d9Smrg
7450b7217d9Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
7460b7217d9Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFE));
7470b7217d9Smrg
7480b7217d9Smrg    OUTB(0x3CE, 0x23); temp = INB(0x3CF);
7490b7217d9Smrg    OUTW(0x3CE, 0x23 | (((temp & 0xFC) | 0x01) << 8));
7500b7217d9Smrg
7510b7217d9Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
7520b7217d9Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFD));
7530b7217d9Smrg
7540b7217d9Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
7550b7217d9Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xCF));
7560b7217d9Smrg
7570b7217d9Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
7580b7217d9Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xF7));
7590b7217d9Smrg
7600b7217d9Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
7610b7217d9Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFB));
7620b7217d9Smrg
7630b7217d9Smrg    OUTB(0x3D4, 0x29); temp = INB(0x3D5);
7640b7217d9Smrg    OUTW(0x3D4, 0x29 | ((temp & 0xFB) << 8));
7650b7217d9Smrg
7660b7217d9Smrg    OUTB(0x3D4, 0x23); temp = INB(0x3D5);
7670b7217d9Smrg    OUTW(0x3D4, 0x23 | ((temp | 0x20) << 8));
7680b7217d9Smrg
7690b7217d9Smrg    vgaHWProtect(pScrn, FALSE);
7700b7217d9Smrg
7710b7217d9Smrg    outb(0x6A, 0x07);
7720b7217d9Smrg    outb(0x6A, 0x8E);
7730b7217d9Smrg    outb(0x6A, 0x06);
7740b7217d9Smrg    outb(0x68, 0x0F);
77595b296d0Smrg}
77695b296d0Smrg
7770b7217d9Smrg/* Initialize VGA Block for Trident Chip on PC-98x1 */
77895b296d0Smrgstatic void
7790b7217d9SmrgPC98TRIDENTInit(ScrnInfoPtr pScrn)
78095b296d0Smrg{
7810b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
7820b7217d9Smrg    switch (pTrident->Chipset) {
7830b7217d9Smrg    case TGUI9660:
7840b7217d9Smrg    case TGUI9680:
7850b7217d9Smrg    case PROVIDIA9682:
7860b7217d9Smrg        PC98TRIDENT96xxInit(pScrn);
7870b7217d9Smrg        break;
7880b7217d9Smrg    case CYBER9320:
7890b7217d9Smrg    case CYBER9385:
7900b7217d9Smrg        PC98TRIDENT9385Init(pScrn);
7910b7217d9Smrg        break;
7920b7217d9Smrg    default: /* Run 96xx code as default */
7930b7217d9Smrg        PC98TRIDENT96xxInit(pScrn);
7940b7217d9Smrg        break;
79595b296d0Smrg    }
79695b296d0Smrg}
79795b296d0Smrg
798eca46af7Smrgstatic void
7990b7217d9SmrgPC98TRIDENTEnable(ScrnInfoPtr pScrn)
800eca46af7Smrg{
8010b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
8020b7217d9Smrg    switch (pTrident->Chipset) {
8030b7217d9Smrg    case TGUI9660:
8040b7217d9Smrg    case TGUI9680:
8050b7217d9Smrg    case PROVIDIA9682:
8060b7217d9Smrg        PC98TRIDENT96xxEnable(pScrn);
8070b7217d9Smrg        break;
8080b7217d9Smrg    case CYBER9320:
8090b7217d9Smrg    case CYBER9385:
8100b7217d9Smrg        PC98TRIDENT9385Enable(pScrn);
8110b7217d9Smrg        break;
8120b7217d9Smrg    default: /* Run 96xx code as default */
8130b7217d9Smrg        PC98TRIDENT96xxEnable(pScrn);
8140b7217d9Smrg        break;
8150b7217d9Smrg    }
816eca46af7Smrg}
817eca46af7Smrg
818eca46af7Smrgstatic void
8190b7217d9SmrgPC98TRIDENTDisable(ScrnInfoPtr pScrn)
820eca46af7Smrg{
8210b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
8220b7217d9Smrg    switch (pTrident->Chipset) {
8230b7217d9Smrg    case TGUI9660:
8240b7217d9Smrg    case TGUI9680:
8250b7217d9Smrg    case PROVIDIA9682:
8260b7217d9Smrg        PC98TRIDENT96xxDisable(pScrn);
8270b7217d9Smrg        break;
8280b7217d9Smrg    case CYBER9320:
8290b7217d9Smrg    case CYBER9385:
8300b7217d9Smrg        PC98TRIDENT9385Disable(pScrn);
8310b7217d9Smrg        break;
8320b7217d9Smrg    default: /* Run 96xx code as default */
8330b7217d9Smrg        PC98TRIDENT96xxDisable(pScrn);
8340b7217d9Smrg        break;
8350b7217d9Smrg    }
836eca46af7Smrg}
8370b7217d9Smrg#endif
838eca46af7Smrg
8390b7217d9Smrg/*
8400b7217d9Smrg * This is a terrible hack! If we are on a notebook in a stretched
8410b7217d9Smrg * mode and don't want full screen we use the BIOS to set an unstreched
8420b7217d9Smrg * mode.
8430b7217d9Smrg */
8440b7217d9Smrgvoid
8450b7217d9SmrgtridentSetModeBIOS(ScrnInfoPtr pScrn, DisplayModePtr mode)
84695b296d0Smrg{
8470b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
84895b296d0Smrg
84995b296d0Smrg
8500b7217d9Smrg#ifdef VBE_INFO
8510b7217d9Smrg    if (pTrident->vbeModes) {
8520b7217d9Smrg        vbeSaveRestoreRec vbesr;
8530b7217d9Smrg        vbesr.stateMode = VBECalcVbeModeIndex(pTrident->vbeModes,
8540b7217d9Smrg                mode, pScrn->bitsPerPixel);
8550b7217d9Smrg        vbesr.pstate = NULL;
8560b7217d9Smrg        if (vbesr.stateMode) {
8570b7217d9Smrg            if (IsPciCard && UseMMIO)
8580b7217d9Smrg                TRIDENTDisableMMIO(pScrn);
8590b7217d9Smrg            VBEVesaSaveRestore(pTrident->pVbe,&vbesr,MODE_RESTORE);
8600b7217d9Smrg            if (IsPciCard && UseMMIO)
8610b7217d9Smrg                TRIDENTEnableMMIO(pScrn);
8620b7217d9Smrg            return;
8630b7217d9Smrg        } else
8640b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"No BIOS Mode matches "
8650b7217d9Smrg                    "%ix%I@%ibpp\n",mode->HDisplay,mode->VDisplay,
8660b7217d9Smrg                    pScrn->bitsPerPixel);
86795b296d0Smrg    }
8680b7217d9Smrg#endif
8690b7217d9Smrg    /* This function is only for LCD screens, and also when we have
8700b7217d9Smrg     * int10 available */
87195b296d0Smrg
8720b7217d9Smrg    if (pTrident->IsCyber && pTrident->lcdMode && pTrident->Int10) {
8730b7217d9Smrg        int i = pTrident->lcdMode;
8740b7217d9Smrg        if ((pScrn->currentMode->HDisplay != LCD[i].display_x) /* !fullsize? */
8750b7217d9Smrg                || (pScrn->currentMode->VDisplay != LCD[i].display_y)) {
8760b7217d9Smrg            if (pTrident->lcdActive)  { /* LCD Active ?*/
8770b7217d9Smrg                int h_str, v_str;
8780b7217d9Smrg
8790b7217d9Smrg                OUTB(0x3CE,HorStretch);  h_str = INB(0x3CF) & 0x01;
8800b7217d9Smrg                OUTB(0x3CE,VertStretch); v_str = INB(0x3CF) & 0x01;
8810b7217d9Smrg                if (h_str || v_str) {
8820b7217d9Smrg                    OUTB(0x3C4, 0x11); OUTB(0x3C5, 0x92);
8830b7217d9Smrg                    OUTW(0x3CE, BiosReg );
8840b7217d9Smrg                    pTrident->Int10->ax = 0x3;
8850b7217d9Smrg                    pTrident->Int10->num = 0x10;
8860b7217d9Smrg                    if (IsPciCard && UseMMIO)
8870b7217d9Smrg                        TRIDENTDisableMMIO(pScrn);
8880b7217d9Smrg                    xf86ExecX86int10(pTrident->Int10);
8890b7217d9Smrg                    if (IsPciCard && UseMMIO)
8900b7217d9Smrg                        TRIDENTEnableMMIO(pScrn);
8910b7217d9Smrg                }
8920b7217d9Smrg            }
8930b7217d9Smrg        }
89495b296d0Smrg    }
8950b7217d9Smrg}
89695b296d0Smrg
8970b7217d9Smrg/* Currently we only test for 1400 */
8980b7217d9Smrgstatic int
8990b7217d9SmrgTRIDENTLcdDisplaySize (xf86MonPtr pMon)
9000b7217d9Smrg{
9010b7217d9Smrg    if (pMon) {
9020b7217d9Smrg        int i,j;
90395b296d0Smrg
9040b7217d9Smrg        for (i = 0; i < STD_TIMINGS; i++) {
9050b7217d9Smrg            if (pMon->timings2[i].hsize == 1400) {
9060b7217d9Smrg                return 1400;
9070b7217d9Smrg            }
9080b7217d9Smrg        }
9090b7217d9Smrg        /*
9100b7217d9Smrg         * If not explicitly set try to find out if the display supports
9110b7217d9Smrg         * the 1400 mode. For sanity check if DDC comes from a digital
9120b7217d9Smrg         * display.
9130b7217d9Smrg         */
9140b7217d9Smrg        if (DIGITAL(pMon->features.input_type)) {
9150b7217d9Smrg            for (i = 0; i < DET_TIMINGS; i++) {
9160b7217d9Smrg                if (pMon->det_mon[i].type == DS_STD_TIMINGS) {
9170b7217d9Smrg                    for (j = 0; j < 5; j++) {
9180b7217d9Smrg                        if (pMon->det_mon[i].section.std_t[j].hsize == 1400) {
9190b7217d9Smrg                            return 1400;
9200b7217d9Smrg                        }
9210b7217d9Smrg                    }
9220b7217d9Smrg                } else if (pMon->det_mon[i].type == DT) {
9230b7217d9Smrg                    if (pMon->det_mon[i].section.d_timings.h_active == 1400) {
9240b7217d9Smrg                        return 1400;
9250b7217d9Smrg                    }
9260b7217d9Smrg                }
9270b7217d9Smrg            }
9280b7217d9Smrg        }
92995b296d0Smrg    }
9300b7217d9Smrg    return 0;
9310b7217d9Smrg}
93295b296d0Smrg
9330b7217d9Smrg/*
9340b7217d9Smrg * Initialise a new mode.  This is currently still using the old
9350b7217d9Smrg * "initialise struct, restore/write struct to HW" model.  That could
9360b7217d9Smrg * be changed.
9370b7217d9Smrg */
93895b296d0Smrg
9390b7217d9Smrgstatic Bool
9400b7217d9SmrgTRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
9410b7217d9Smrg{
9420b7217d9Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
9430b7217d9Smrg    vgaRegPtr vgaReg;
9440b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
9450b7217d9Smrg    TRIDENTRegPtr tridentReg;
94614330f12Smrg
94714330f12Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
9480b7217d9Smrg    if (!xf86IsPc98())
949e6f085baSmrg#endif
9500b7217d9Smrg        WAITFORVSYNC;
95195b296d0Smrg
9520b7217d9Smrg    TridentFindClock(pScrn,mode->Clock);
95395b296d0Smrg
9540b7217d9Smrg    switch (pTrident->Chipset) {
9550b7217d9Smrg    case TGUI9660:
9560b7217d9Smrg    case TGUI9680:
9570b7217d9Smrg    case PROVIDIA9682:
9580b7217d9Smrg    case PROVIDIA9685:
9590b7217d9Smrg    case IMAGE975:
9600b7217d9Smrg    case IMAGE985:
9610b7217d9Smrg    case BLADE3D:
9620b7217d9Smrg    case CYBERBLADEI7:
9630b7217d9Smrg    case CYBERBLADEI7D:
9640b7217d9Smrg    case CYBERBLADEI1:
9650b7217d9Smrg    case CYBERBLADEI1D:
9660b7217d9Smrg    case CYBERBLADEAI1:
9670b7217d9Smrg    case CYBERBLADEAI1D:
9680b7217d9Smrg    case CYBER9520:
9690b7217d9Smrg    case CYBER9525DVD:
9700b7217d9Smrg    case CYBERBLADEE4:
9710b7217d9Smrg    case CYBER9397:
9720b7217d9Smrg    case CYBER9397DVD:
9730b7217d9Smrg    case BLADEXP:
9740b7217d9Smrg    case CYBERBLADEXPAI1:
9750b7217d9Smrg    case CYBERBLADEXP4:
9760b7217d9Smrg    case XP5:
9770b7217d9Smrg        /* Get ready for MUX mode */
9780b7217d9Smrg        if (pTrident->MUX &&
9790b7217d9Smrg                pScrn->bitsPerPixel == 8 &&
9800b7217d9Smrg                !mode->CrtcHAdjusted) {
9810b7217d9Smrg            ErrorF("BARF\n");
9820b7217d9Smrg            mode->CrtcHDisplay >>= 1;
9830b7217d9Smrg            mode->CrtcHSyncStart >>= 1;
9840b7217d9Smrg            mode->CrtcHSyncEnd >>= 1;
9850b7217d9Smrg            mode->CrtcHBlankStart >>= 1;
9860b7217d9Smrg            mode->CrtcHBlankEnd >>= 1;
9870b7217d9Smrg            mode->CrtcHTotal >>= 1;
9880b7217d9Smrg            mode->CrtcHAdjusted = TRUE;
9890b7217d9Smrg        }
9900b7217d9Smrg        break;
9910b7217d9Smrg    default:
9920b7217d9Smrg        if (pScrn->videoRam < 1024 &&
9930b7217d9Smrg                !mode->CrtcHAdjusted) {
9940b7217d9Smrg            mode->CrtcHDisplay <<= 1;
9950b7217d9Smrg            mode->CrtcHSyncStart <<= 1;
9960b7217d9Smrg            mode->CrtcHSyncEnd <<= 1;
9970b7217d9Smrg            mode->CrtcHBlankStart <<= 1;
9980b7217d9Smrg            mode->CrtcHBlankEnd <<= 1;
9990b7217d9Smrg            mode->CrtcHTotal <<= 1;
10000b7217d9Smrg            mode->CrtcHAdjusted = TRUE;
100195b296d0Smrg        }
10020b7217d9Smrg        break;
100395b296d0Smrg    }
100495b296d0Smrg
10050b7217d9Smrg    vgaHWUnlock(hwp);
10060b7217d9Smrg    /* Initialise the ModeReg values */
10070b7217d9Smrg    if (!vgaHWInit(pScrn, mode))
10080b7217d9Smrg        return FALSE;
100995b296d0Smrg
10100b7217d9Smrg    pScrn->vtSema = TRUE;
101195b296d0Smrg    /*
10120b7217d9Smrg     * We used to do this at a later time.
10130b7217d9Smrg     * Now since READOUT isn't defined any more
10140b7217d9Smrg     * we do it here.
10150b7217d9Smrg     * The original NOTE read:
10160b7217d9Smrg     * TridentInit() has to modify registers
10170b7217d9Smrg     * that have already been set by vgaHWRestore().
10180b7217d9Smrg     * So we call it _after_ vgaHWRestore() has
10190b7217d9Smrg     * programmed these registers.
10200b7217d9Smrg     */
10210b7217d9Smrg    if (pScrn->progClock) {
10220b7217d9Smrg        if (!TridentInit(pScrn, mode))
10230b7217d9Smrg            return FALSE;
10240b7217d9Smrg    } else {
10250b7217d9Smrg        if (!TVGAInit(pScrn, mode))
10260b7217d9Smrg            return FALSE;
102795b296d0Smrg    }
102895b296d0Smrg
10290b7217d9Smrg    /* Program the registers */
10300b7217d9Smrg    vgaHWProtect(pScrn, TRUE);
10310b7217d9Smrg    vgaReg = &hwp->ModeReg;
10320b7217d9Smrg    tridentReg = &pTrident->ModeReg;
103395b296d0Smrg
10340b7217d9Smrg    vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
10350b7217d9Smrg    if (pScrn->progClock)
10360b7217d9Smrg        TridentRestore(pScrn, tridentReg);
10370b7217d9Smrg    else
10380b7217d9Smrg        TVGARestore(pScrn, tridentReg);
103995b296d0Smrg
10400b7217d9Smrg    vgaHWProtect(pScrn, FALSE);
10410b7217d9Smrg
10420b7217d9Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
10430b7217d9Smrg    if (xf86IsPc98())
10440b7217d9Smrg        PC98TRIDENTEnable(pScrn);
104595b296d0Smrg#endif
104695b296d0Smrg
10470b7217d9Smrg    if (pTrident->TVChipset != 0)
10480b7217d9Smrg        VIA_TVInit(pScrn);
104995b296d0Smrg
10500b7217d9Smrg    return TRUE;
10510b7217d9Smrg}
105295b296d0Smrg
10530b7217d9Smrgstatic Bool
10540b7217d9SmrgTRIDENTGetRec(ScrnInfoPtr pScrn)
10550b7217d9Smrg{
10560b7217d9Smrg    /*
10570b7217d9Smrg     * Allocate an TRIDENTRec, and hook it into pScrn->driverPrivate.
10580b7217d9Smrg     * pScrn->driverPrivate is initialised to NULL, so we can check if
10590b7217d9Smrg     * the allocation has already been done.
10600b7217d9Smrg     */
10610b7217d9Smrg    if (pScrn->driverPrivate != NULL)
10620b7217d9Smrg        return TRUE;
106395b296d0Smrg
10640b7217d9Smrg    pScrn->driverPrivate = xnfcalloc(sizeof(TRIDENTRec), 1);
10650b7217d9Smrg    /* Initialise it */
106695b296d0Smrg
10670b7217d9Smrg    return TRUE;
10680b7217d9Smrg}
106995b296d0Smrg
10700b7217d9Smrgstatic void
10710b7217d9SmrgTRIDENTFreeRec(ScrnInfoPtr pScrn)
10720b7217d9Smrg{
10730b7217d9Smrg    if (pScrn->driverPrivate == NULL)
10740b7217d9Smrg        return;
10750b7217d9Smrg    free(pScrn->driverPrivate);
10760b7217d9Smrg    pScrn->driverPrivate = NULL;
10770b7217d9Smrg}
107895b296d0Smrg
107995b296d0Smrg
10800b7217d9Smrg/*
10810b7217d9Smrg * This function saves the video state.
10820b7217d9Smrg */
10830b7217d9Smrgstatic void
10840b7217d9SmrgTRIDENTSave(ScrnInfoPtr pScrn)
10850b7217d9Smrg{
10860b7217d9Smrg    TRIDENTPtr pTrident;
10870b7217d9Smrg    vgaRegPtr vgaReg;
10880b7217d9Smrg    TRIDENTRegPtr tridentReg;
108995b296d0Smrg
10900b7217d9Smrg    pTrident = TRIDENTPTR(pScrn);
10910b7217d9Smrg    vgaReg = &VGAHWPTR(pScrn)->SavedReg;
10920b7217d9Smrg    tridentReg = &pTrident->SavedReg;
109395b296d0Smrg
10940b7217d9Smrg    vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP |
10950b7217d9Smrg            (IsPrimaryCard ? VGA_SR_FONTS : 0));
109695b296d0Smrg
10970b7217d9Smrg    if (pScrn->progClock)
10980b7217d9Smrg        TridentSave(pScrn, tridentReg);
10990b7217d9Smrg    else
11000b7217d9Smrg        TVGASave(pScrn, tridentReg);
110195b296d0Smrg
11020b7217d9Smrg    if (pTrident->TVChipset != 0)
11030b7217d9Smrg        VIA_SaveTVDepentVGAReg(pScrn);
11040b7217d9Smrg}
110595b296d0Smrg
110695b296d0Smrg
11070b7217d9Smrg/*
11080b7217d9Smrg * Restore the initial (text) mode.
11090b7217d9Smrg */
11100b7217d9Smrgstatic void
11110b7217d9SmrgTRIDENTRestore(ScrnInfoPtr pScrn)
11120b7217d9Smrg{
11130b7217d9Smrg    vgaHWPtr hwp;
11140b7217d9Smrg    vgaRegPtr vgaReg;
11150b7217d9Smrg    TRIDENTPtr pTrident;
11160b7217d9Smrg    TRIDENTRegPtr tridentReg;
111795b296d0Smrg
11180b7217d9Smrg    hwp = VGAHWPTR(pScrn);
11190b7217d9Smrg    pTrident = TRIDENTPTR(pScrn);
11200b7217d9Smrg    vgaReg = &hwp->SavedReg;
11210b7217d9Smrg    tridentReg = &pTrident->SavedReg;
112295b296d0Smrg
11230b7217d9Smrg    vgaHWProtect(pScrn, TRUE);
112495b296d0Smrg
11250b7217d9Smrg    if (pScrn->progClock)
11260b7217d9Smrg        TridentRestore(pScrn, tridentReg);
11270b7217d9Smrg    else
11280b7217d9Smrg        TVGARestore(pScrn, tridentReg);
112995b296d0Smrg
11300b7217d9Smrg    vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP |
11310b7217d9Smrg            (IsPrimaryCard ? VGA_SR_FONTS : 0));
113295b296d0Smrg
11330b7217d9Smrg    if (pTrident->TVChipset != 0)
11340b7217d9Smrg        VIA_RestoreTVDependVGAReg(pScrn);
113595b296d0Smrg
11360b7217d9Smrg    vgaHWProtect(pScrn, FALSE);
11370b7217d9Smrg}
113895b296d0Smrg
11390b7217d9Smrg/* Usually mandatory */
11400b7217d9SmrgBool
11410b7217d9SmrgTRIDENTSwitchMode(SWITCH_MODE_ARGS_DECL)
11420b7217d9Smrg{
11430b7217d9Smrg    SCRN_INFO_PTR(arg);
11440b7217d9Smrg    return TRIDENTModeInit(pScrn, mode);
11450b7217d9Smrg}
114695b296d0Smrg
114795b296d0Smrg
11480b7217d9Smrg/*
11490b7217d9Smrg * This function is used to initialize the Start Address - the first
11500b7217d9Smrg * displayed location in the video memory.
11510b7217d9Smrg */
11520b7217d9Smrg/* Usually mandatory */
11530b7217d9Smrgvoid
11540b7217d9SmrgTRIDENTAdjustFrame(ADJUST_FRAME_ARGS_DECL)
11550b7217d9Smrg{
11560b7217d9Smrg    SCRN_INFO_PTR(arg);
11570b7217d9Smrg    TRIDENTPtr pTrident;
11580b7217d9Smrg    int base = y * pScrn->displayWidth + x;
11590b7217d9Smrg    int vgaIOBase;
11600b7217d9Smrg    CARD8 temp;
11610b7217d9Smrg
11620b7217d9Smrg    pTrident = TRIDENTPTR(pScrn);
11630b7217d9Smrg    vgaIOBase = VGAHWPTR(pScrn)->IOBase;
11640b7217d9Smrg
11650b7217d9Smrg    switch (pScrn->bitsPerPixel) {
11660b7217d9Smrg    case 8:
11670b7217d9Smrg        if (pScrn->progClock)
11680b7217d9Smrg            base = (base & 0xFFFFFFF8) >> 2;
11690b7217d9Smrg        else
11700b7217d9Smrg            base = (base & 0xFFFFFFF8) >> 3;
11710b7217d9Smrg        break;
11720b7217d9Smrg    case 16:
11730b7217d9Smrg        base >>= 1;
11740b7217d9Smrg        break;
11750b7217d9Smrg    case 24:
11760b7217d9Smrg        base = (((base + 1) & ~0x03) * 3) >> 2;
11770b7217d9Smrg        break;
11780b7217d9Smrg    case 32:
11790b7217d9Smrg        break;
118095b296d0Smrg    }
118195b296d0Smrg
11820b7217d9Smrg    /* CRT bits 0-15 */
11830b7217d9Smrg    OUTW(vgaIOBase + 4, (base & 0x00FF00) | 0x0C);
11840b7217d9Smrg    OUTW(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D);
11850b7217d9Smrg    /* CRT bit 16 */
11860b7217d9Smrg    OUTB(vgaIOBase + 4, CRTCModuleTest); temp = INB(vgaIOBase + 5) & 0xDF;
11870b7217d9Smrg    OUTB(vgaIOBase + 5, temp | ((base & 0x10000) >> 11));
11880b7217d9Smrg    /* CRT bit 17-19 */
11890b7217d9Smrg    OUTB(vgaIOBase + 4, CRTHiOrd); temp = INB(vgaIOBase + 5) & 0xF8;
11900b7217d9Smrg    OUTB(vgaIOBase + 5, temp | ((base & 0xE0000) >> 17));
11910b7217d9Smrg}
119295b296d0Smrg
119395b296d0Smrg
11940b7217d9Smrg/*
11950b7217d9Smrg * This is called when VT switching back to the X server.  Its job is
11960b7217d9Smrg * to reinitialise the video mode.
11970b7217d9Smrg */
119895b296d0Smrg
11990b7217d9Smrg/* Mandatory */
12000b7217d9Smrgstatic Bool
12010b7217d9SmrgTRIDENTEnterVT(VT_FUNC_ARGS_DECL)
12020b7217d9Smrg{
12030b7217d9Smrg    SCRN_INFO_PTR(arg);
12040b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
120595b296d0Smrg
12060b7217d9Smrg    if (IsPciCard && UseMMIO) TRIDENTEnableMMIO(pScrn);
120795b296d0Smrg
12080b7217d9Smrg    /* Should we re-save the text mode on each VT enter? */
12090b7217d9Smrg    if (!TRIDENTModeInit(pScrn, pScrn->currentMode))
12100b7217d9Smrg        return FALSE;
121195b296d0Smrg
12120b7217d9Smrg    if (pTrident->InitializeAccelerator)
12130b7217d9Smrg        pTrident->InitializeAccelerator(pScrn);
121495b296d0Smrg
12150b7217d9Smrg    return TRUE;
12160b7217d9Smrg}
12170b7217d9Smrg
12180b7217d9Smrg
12190b7217d9Smrg/*
12200b7217d9Smrg * This is called when VT switching away from the X server.  Its job is
12210b7217d9Smrg * to restore the previous (text) mode.
12220b7217d9Smrg *
12230b7217d9Smrg * We may wish to remap video/MMIO memory too.
12240b7217d9Smrg */
12250b7217d9Smrg
12260b7217d9Smrg/* Mandatory */
12270b7217d9Smrgstatic void
12280b7217d9SmrgTRIDENTLeaveVT(VT_FUNC_ARGS_DECL)
12290b7217d9Smrg{
12300b7217d9Smrg    SCRN_INFO_PTR(arg);
12310b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
12320b7217d9Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
12330b7217d9Smrg
12340b7217d9Smrg#ifdef HAVE_XAA_H
12350b7217d9Smrg    if (!pTrident->NoAccel && !pTrident->useEXA)
12360b7217d9Smrg        pTrident->AccelInfoRec->Sync(pScrn);
12370b7217d9Smrg    else
12380b7217d9Smrg#endif
12390b7217d9Smrg        if (!pTrident->NoAccel && pTrident->useEXA)
12400b7217d9Smrg            pTrident->EXADriverPtr->WaitMarker(pScrn->pScreen, 0);
12410b7217d9Smrg
12420b7217d9Smrg    TRIDENTRestore(pScrn);
12430b7217d9Smrg    vgaHWLock(hwp);
12440b7217d9Smrg
12450b7217d9Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
12460b7217d9Smrg    if (xf86IsPc98())
12470b7217d9Smrg        PC98TRIDENTDisable(pScrn);
12480b7217d9Smrg#endif
12490b7217d9Smrg
12500b7217d9Smrg    if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn);
12510b7217d9Smrg}
12520b7217d9Smrg
12530b7217d9Smrg
12540b7217d9Smrg/* Free up any per-generation data structures */
12550b7217d9Smrg
12560b7217d9Smrg/* Optional */
12570b7217d9Smrgstatic void
12580b7217d9SmrgTRIDENTFreeScreen(FREE_SCREEN_ARGS_DECL)
12590b7217d9Smrg{
12600b7217d9Smrg    SCRN_INFO_PTR(arg);
12610b7217d9Smrg    if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
12620b7217d9Smrg        vgaHWFreeHWRec(pScrn);
12630b7217d9Smrg    TRIDENTFreeRec(pScrn);
12640b7217d9Smrg}
126595b296d0Smrg
126695b296d0Smrg
12670b7217d9Smrg/* Checks if a mode is suitable for the selected chipset. */
126895b296d0Smrg
12690b7217d9Smrg/* Optional */
12700b7217d9Smrgstatic ModeStatus
12710b7217d9SmrgTRIDENTValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
12720b7217d9Smrg{
12730b7217d9Smrg    SCRN_INFO_PTR(arg);
12740b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
127595b296d0Smrg
12760b7217d9Smrg    if (pTrident->lcdActive && (pTrident->lcdMode != 0xff)){
12770b7217d9Smrg        if (((mode->HDisplay > LCD[pTrident->lcdMode].display_x)
12780b7217d9Smrg                || (mode->VDisplay > LCD[pTrident->lcdMode].display_y))) {
12790b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Removing mode (%dx%d) "
12800b7217d9Smrg                    "larger than the LCD panel (%dx%d)\n",
12810b7217d9Smrg                    mode->HDisplay,
12820b7217d9Smrg                    mode->VDisplay,
12830b7217d9Smrg                    LCD[pTrident->lcdMode].display_x,
12840b7217d9Smrg                    LCD[pTrident->lcdMode].display_y);
12850b7217d9Smrg            return(MODE_BAD);
12860b7217d9Smrg        }
12870b7217d9Smrg        if (((float)mode->HDisplay/(float)mode->VDisplay) > 2.0) {
12880b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Removing mode (%dx%d) "
12890b7217d9Smrg                    "unusual aspect ratio\n",
12900b7217d9Smrg                    mode->HDisplay,
12910b7217d9Smrg                    mode->VDisplay);
12920b7217d9Smrg            return(MODE_BAD);
12930b7217d9Smrg        }
129495b296d0Smrg    }
12950b7217d9Smrg    return (MODE_OK);
12960b7217d9Smrg}
129795b296d0Smrg
12980b7217d9Smrgstatic void
12990b7217d9SmrgTRIDENTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
13000b7217d9Smrg{
13010b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
13020b7217d9Smrg    CARD8 DPMSCont, PMCont, temp;
130395b296d0Smrg
13040b7217d9Smrg    if (!pScrn->vtSema)
13050b7217d9Smrg        return;
130695b296d0Smrg
13070b7217d9Smrg    OUTB(0x3C4, 0x0E);
13080b7217d9Smrg    temp = INB(0x3C5);
13090b7217d9Smrg    OUTB(0x3C5, 0xC2);
13100b7217d9Smrg    OUTB(0x83C8, 0x04); /* Read DPMS Control */
13110b7217d9Smrg    PMCont = INB(0x83C6) & 0xFC;
13120b7217d9Smrg    OUTB(0x3CE, 0x23);
13130b7217d9Smrg    DPMSCont = INB(0x3CF) & 0xFC;
13140b7217d9Smrg    switch (PowerManagementMode)
13150b7217d9Smrg    {
13160b7217d9Smrg    case DPMSModeOn:
13170b7217d9Smrg        /* Screen: On, HSync: On, VSync: On */
13180b7217d9Smrg        PMCont |= 0x03;
13190b7217d9Smrg        DPMSCont |= 0x00;
13200b7217d9Smrg        break;
13210b7217d9Smrg    case DPMSModeStandby:
13220b7217d9Smrg        /* Screen: Off, HSync: Off, VSync: On */
13230b7217d9Smrg        PMCont |= 0x02;
13240b7217d9Smrg        DPMSCont |= 0x01;
13250b7217d9Smrg        break;
13260b7217d9Smrg    case DPMSModeSuspend:
13270b7217d9Smrg        /* Screen: Off, HSync: On, VSync: Off */
13280b7217d9Smrg        PMCont |= 0x02;
13290b7217d9Smrg        DPMSCont |= 0x02;
13300b7217d9Smrg        break;
13310b7217d9Smrg    case DPMSModeOff:
13320b7217d9Smrg        /* Screen: Off, HSync: Off, VSync: Off */
13330b7217d9Smrg        PMCont |= 0x00;
13340b7217d9Smrg        DPMSCont |= 0x03;
13350b7217d9Smrg        break;
13360b7217d9Smrg    }
13370b7217d9Smrg    OUTB(0x3CF, DPMSCont);
13380b7217d9Smrg    OUTB(0x83C8, 0x04);
13390b7217d9Smrg    OUTB(0x83C6, PMCont);
13400b7217d9Smrg    OUTW(0x3C4, (temp<<8) | 0x0E);
13410b7217d9Smrg}
134295b296d0Smrg
13430b7217d9Smrgstatic void
13440b7217d9SmrgTRIDENTBlockHandler (BLOCKHANDLER_ARGS_DECL)
13450b7217d9Smrg{
13460b7217d9Smrg    SCREEN_PTR(arg);
13470b7217d9Smrg    ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
13480b7217d9Smrg    TRIDENTPtr     pTrident = TRIDENTPTR(pScrn);
134995b296d0Smrg
13500b7217d9Smrg    pScreen->BlockHandler = pTrident->BlockHandler;
13510b7217d9Smrg    (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
13520b7217d9Smrg    pScreen->BlockHandler = TRIDENTBlockHandler;
135395b296d0Smrg
13540b7217d9Smrg    if(pTrident->VideoTimerCallback) {
13550b7217d9Smrg        UpdateCurrentTime();
13560b7217d9Smrg        (*pTrident->VideoTimerCallback)(pScrn, currentTime.milliseconds);
135795b296d0Smrg    }
13580b7217d9Smrg}
135995b296d0Smrg
13600b7217d9Smrgstatic const OptionInfoRec *
13610b7217d9SmrgTRIDENTAvailableOptions(int chipid, int busid)
13620b7217d9Smrg{
13630b7217d9Smrg    return TRIDENTOptions;
13640b7217d9Smrg}
136595b296d0Smrg
13660b7217d9Smrg/* Mandatory */
13670b7217d9Smrgstatic void
13680b7217d9SmrgTRIDENTIdentify(int flags)
13690b7217d9Smrg{
13700b7217d9Smrg    xf86PrintChipsets(TRIDENT_NAME, "driver for Trident chipsets", TRIDENTChipsets);
13710b7217d9Smrg}
137295b296d0Smrg
13730b7217d9SmrgBool
13740b7217d9SmrgTRIDENTClockSelect(ScrnInfoPtr pScrn, int no)
13750b7217d9Smrg{
13760b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
13770b7217d9Smrg    unsigned char temp;
137895b296d0Smrg
13790b7217d9Smrg    /*
13800b7217d9Smrg     * CS0 and CS1 are in MiscOutReg
13810b7217d9Smrg     *
13820b7217d9Smrg     * For 8900B, 8900C, 8900CL and 9000, CS2 is bit 0 of
13830b7217d9Smrg     * New Mode Control Register 2.
13840b7217d9Smrg     *
13850b7217d9Smrg     * For 8900CL, CS3 is bit 4 of Old Mode Control Register 1.
13860b7217d9Smrg     *
13870b7217d9Smrg     * For 9000, CS3 is bit 6 of New Mode Control Register 2.
13880b7217d9Smrg     *
13890b7217d9Smrg     * For TGUI, we don't use the ClockSelect function at all.
13900b7217d9Smrg     */
13910b7217d9Smrg    switch(no) {
13920b7217d9Smrg    case CLK_REG_SAVE:
13930b7217d9Smrg        pTrident->SaveClock1 = INB(0x3CC);
13940b7217d9Smrg        if (pTrident->Chipset != TVGA8800CS) {
13950b7217d9Smrg            if ( (pScrn->numClocks == 16) &&
13960b7217d9Smrg                    (pTrident->Chipset != TVGA9000) &&
13970b7217d9Smrg                    (pTrident->Chipset != TVGA9000i) )
13980b7217d9Smrg            {
13990b7217d9Smrg                OUTW(0x3C4, 0x000B);	/* Switch to Old Mode */
14000b7217d9Smrg                OUTB(0x3C4, 0x0E); pTrident->SaveClock3 = INB(0x3C5);
14010b7217d9Smrg            }
14020b7217d9Smrg            OUTB(0x3C4, 0x0B);
14030b7217d9Smrg            INB(0x3C5);		/* Now to New Mode */
14040b7217d9Smrg            OUTB(0x3C4, 0x0D); pTrident->SaveClock2 = INB(0x3C5);
14050b7217d9Smrg        }
14060b7217d9Smrg        break;
14070b7217d9Smrg    case CLK_REG_RESTORE:
14080b7217d9Smrg        OUTB(0x3C2, pTrident->SaveClock1);
14090b7217d9Smrg        if (pTrident->Chipset != TVGA8800CS) {
14100b7217d9Smrg            if ( (pScrn->numClocks == 16) &&
14110b7217d9Smrg                    (pTrident->Chipset != TVGA9000) &&
14120b7217d9Smrg                    (pTrident->Chipset != TVGA9000i) )
14130b7217d9Smrg            {
14140b7217d9Smrg                OUTW(0x3C4, 0x000B);	/* Switch to Old Mode */
14150b7217d9Smrg                OUTW(0x3C4, (pTrident->SaveClock3 << 8) | 0x0E);
14160b7217d9Smrg            }
14170b7217d9Smrg            OUTB(0x3C4, 0x0B);
14180b7217d9Smrg            INB(0x3C5);		/* Now to New Mode */
14190b7217d9Smrg            OUTW(0x3C4, (pTrident->SaveClock2 << 8) | 0x0D);
14200b7217d9Smrg        }
14210b7217d9Smrg        break;
14220b7217d9Smrg    default:
14230b7217d9Smrg        /*
14240b7217d9Smrg         * Do CS0 and CS1
14250b7217d9Smrg         */
14260b7217d9Smrg        temp = INB(0x3CC);
14270b7217d9Smrg        OUTB(0x3C2, (temp & 0xF3) | ((no << 2) & 0x0C));
14280b7217d9Smrg        if (pTrident->Chipset != TVGA8800CS) {
14290b7217d9Smrg            if ( (pScrn->numClocks == 16) &&
14300b7217d9Smrg                    (pTrident->Chipset != TVGA9000) &&
14310b7217d9Smrg                    (pTrident->Chipset != TVGA9000i) )
14320b7217d9Smrg            {
14330b7217d9Smrg                /*
14340b7217d9Smrg                 * Go to Old Mode for CS3.
14350b7217d9Smrg                 */
14360b7217d9Smrg                OUTW(0x3C4, 0x000B);	/* Switch to Old Mode */
14370b7217d9Smrg                OUTB(0x3C4, 0x0E);
14380b7217d9Smrg                temp = INB(0x3C5) & 0xEF;
14390b7217d9Smrg                temp |= (no & 0x08) << 1;
14400b7217d9Smrg                OUTB(0x3C5, temp);
14410b7217d9Smrg            }
14420b7217d9Smrg            /*
14430b7217d9Smrg             * Go to New Mode for CS2 and TVGA9000 CS3.
14440b7217d9Smrg             */
14450b7217d9Smrg            OUTB(0x3C4, 0x0B);
14460b7217d9Smrg            INB(0x3C5);		/* Now to New Mode */
14470b7217d9Smrg            OUTB(0x3C4, 0x0D);
14480b7217d9Smrg            /*
14490b7217d9Smrg             * Bits 1 & 2 are dividers - set to 0 to get no
14500b7217d9Smrg             * clock division.
14510b7217d9Smrg             */
14520b7217d9Smrg            temp = INB(0x3C5) & 0xF8;
14530b7217d9Smrg            temp |= (no & 0x04) >> 2;
14540b7217d9Smrg            if ( (pTrident->Chipset == TVGA9000) ||
14550b7217d9Smrg                    (pTrident->Chipset == TVGA9000i) )
14560b7217d9Smrg            {
14570b7217d9Smrg                temp &= ~0x40;
14580b7217d9Smrg                temp |= (no & 0x08) << 3;
14590b7217d9Smrg            }
14600b7217d9Smrg            OUTB(0x3C5, temp);
14610b7217d9Smrg        }
146214330f12Smrg    }
14630b7217d9Smrg    return(TRUE);
14640b7217d9Smrg}
146514330f12Smrg
14660b7217d9Smrg#ifdef HAVE_ISA
14670b7217d9Smrgstatic int
14680b7217d9SmrgTridentFindIsaDevice(GDevPtr dev)
14690b7217d9Smrg{
14700b7217d9Smrg    int found = -1;
14710b7217d9Smrg    unsigned char temp, origVal, newVal;
147295b296d0Smrg
14730b7217d9Smrg    /*
14740b7217d9Smrg     * Check first that we have a Trident card.
14750b7217d9Smrg     */
14760b7217d9Smrg    outb(0x3C4, 0x0B);
14770b7217d9Smrg    temp = inb(0x3C5);	/* Save old value */
14780b7217d9Smrg    outb(0x3C4, 0x0B);	/* Switch to Old Mode */
14790b7217d9Smrg    outb(0x3C5, 0x00);
14800b7217d9Smrg    inb(0x3C5);		/* Now to New Mode */
14810b7217d9Smrg    outb(0x3C4, 0x0E);
14820b7217d9Smrg    origVal = inb(0x3C5);
14830b7217d9Smrg    outb(0x3C5, 0x00);
14840b7217d9Smrg    newVal = inb(0x3C5) & 0x0F;
14850b7217d9Smrg    outb(0x3C5, (origVal ^ 0x02));
148695b296d0Smrg
14870b7217d9Smrg    /*
14880b7217d9Smrg     * Is it a Trident card ??
14890b7217d9Smrg     */
14900b7217d9Smrg    if (newVal != 2) {
14910b7217d9Smrg        /*
14920b7217d9Smrg         * Nope, so quit
14930b7217d9Smrg         */
14940b7217d9Smrg        outb(0x3C4, 0x0B);	/* Restore value of 0x0B */
14950b7217d9Smrg        outb(0x3C5, temp);
14960b7217d9Smrg        outb(0x3C4, 0x0E);
14970b7217d9Smrg        outb(0x3C5, origVal);
14980b7217d9Smrg        return found;
149995b296d0Smrg    }
150095b296d0Smrg
15010b7217d9Smrg    outb(0x3C4, 0x0B);
15020b7217d9Smrg    temp = inb(0x3C5);
15030b7217d9Smrg    switch (temp) {
15040b7217d9Smrg    case 0x01:
15050b7217d9Smrg        found = TVGA8800BR;
15060b7217d9Smrg        break;
15070b7217d9Smrg    case 0x02:
15080b7217d9Smrg        found = TVGA8800CS;
15090b7217d9Smrg        break;
15100b7217d9Smrg    case 0x03:
15110b7217d9Smrg        found = TVGA8900B;
15120b7217d9Smrg        break;
15130b7217d9Smrg    case 0x04:
15140b7217d9Smrg    case 0x13:
15150b7217d9Smrg        found = TVGA8900C;
15160b7217d9Smrg        break;
15170b7217d9Smrg    case 0x23:
15180b7217d9Smrg        found = TVGA9000;
15190b7217d9Smrg        break;
15200b7217d9Smrg    case 0x33:
15210b7217d9Smrg        found = TVGA8900D;
15220b7217d9Smrg        break;
15230b7217d9Smrg    case 0x43:
15240b7217d9Smrg        found = TVGA9000i;
15250b7217d9Smrg        break;
15260b7217d9Smrg    case 0x53:
15270b7217d9Smrg        found = TVGA9200CXr;
15280b7217d9Smrg        break;
15290b7217d9Smrg    case 0x63:
15300b7217d9Smrg        found = TVGA9100B;
15310b7217d9Smrg        break;
15320b7217d9Smrg    case 0x73:
15330b7217d9Smrg    case 0xC3:
15340b7217d9Smrg        found = TGUI9420DGi;
15350b7217d9Smrg        break;
15360b7217d9Smrg    case 0x83:
15370b7217d9Smrg        found = TVGA8200LX;
15380b7217d9Smrg        break;
15390b7217d9Smrg    case 0x93:
15400b7217d9Smrg        found = TGUI9400CXi;
15410b7217d9Smrg        break;
15420b7217d9Smrg    case 0xA3:
15430b7217d9Smrg        found = CYBER9320;
15440b7217d9Smrg        break;
15450b7217d9Smrg    case 0xD3:
15460b7217d9Smrg        found = TGUI9660;
15470b7217d9Smrg        break;
15480b7217d9Smrg    case 0xE3:
15490b7217d9Smrg        found = TGUI9440AGi;
15500b7217d9Smrg        break;
15510b7217d9Smrg    case 0xF3:
15520b7217d9Smrg        found = TGUI9430DGi;
15530b7217d9Smrg        break;
15540b7217d9Smrg    }
15550b7217d9Smrg    return found;
155695b296d0Smrg}
15570b7217d9Smrg#endif
155895b296d0Smrg
155995b296d0Smrg/*
156095b296d0Smrg * Map the framebuffer and MMIO memory.
156195b296d0Smrg */
156295b296d0Smrg
156395b296d0Smrgstatic Bool
156495b296d0SmrgTRIDENTMapMem(ScrnInfoPtr pScrn)
156595b296d0Smrg{
156695b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
156795b296d0Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
156895b296d0Smrg    int mapsize = 0x10000;
156995b296d0Smrg
157095b296d0Smrg    if (Is3Dchip) mapsize = 0x20000;
157195b296d0Smrg
157295b296d0Smrg    if (IsPciCard && UseMMIO)
1573ff89ac2bSmrg#ifndef XSERVER_LIBPCIACCESS
15740b7217d9Smrg        pTrident->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
15750b7217d9Smrg                pTrident->PciTag, pTrident->IOAddress, mapsize);
1576ff89ac2bSmrg#else
15770b7217d9Smrg    {
15780b7217d9Smrg        void **result = (void **)&pTrident->IOBase;
15790b7217d9Smrg        int err = pci_device_map_range(pTrident->PciInfo,
15800b7217d9Smrg                pTrident->IOAddress,
15810b7217d9Smrg                mapsize,
15820b7217d9Smrg                PCI_DEV_MAP_FLAG_WRITABLE,
15830b7217d9Smrg                result);
15840b7217d9Smrg        if (err) {
15850b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
15860b7217d9Smrg                    "Unable to map IO aperture. %s (%d)\n",
15870b7217d9Smrg                    strerror(err), err);
15880b7217d9Smrg        }
15890b7217d9Smrg    }
1590ff89ac2bSmrg#endif
159195b296d0Smrg    else {
1592ff89ac2bSmrg#ifndef XSERVER_LIBPCIACCESS
15930b7217d9Smrg        pTrident->IOBase = xf86MapDomainMemory(pScrn->scrnIndex, VIDMEM_MMIO,
15940b7217d9Smrg                pTrident->PciTag, pTrident->IOAddress, 0x1000);
15950b7217d9Smrg        pTrident->IOBase += 0xF00;
1596ff89ac2bSmrg#else
15970b7217d9Smrg        return FALSE;
1598ff89ac2bSmrg#endif
159995b296d0Smrg    }
160095b296d0Smrg
160195b296d0Smrg    if (pTrident->IOBase == NULL)
16020b7217d9Smrg        return FALSE;
160395b296d0Smrg
16042378475aSmrg    if (LINEAR()) {
160595b296d0Smrg        if (pTrident->FbMapSize != 0) {
1606ff89ac2bSmrg#ifndef XSERVER_LIBPCIACCESS
16070b7217d9Smrg            pTrident->FbBase = xf86MapPciMem(pScrn->scrnIndex,
16080b7217d9Smrg                    VIDMEM_FRAMEBUFFER,
16090b7217d9Smrg                    pTrident->PciTag,
16100b7217d9Smrg                    (unsigned long)pTrident->FbAddress,
16110b7217d9Smrg                    pTrident->FbMapSize);
1612ff89ac2bSmrg#else
16130b7217d9Smrg            {
16140b7217d9Smrg                void **result = (void **)&pTrident->FbBase;
16150b7217d9Smrg                int err = pci_device_map_range(pTrident->PciInfo,
16160b7217d9Smrg                        pTrident->FbAddress,
16170b7217d9Smrg                        pTrident->FbMapSize,
16180b7217d9Smrg                        PCI_DEV_MAP_FLAG_WRITABLE |
16190b7217d9Smrg                        PCI_DEV_MAP_FLAG_WRITE_COMBINE,
16200b7217d9Smrg                        result);
16210b7217d9Smrg                if (err) {
16220b7217d9Smrg                    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
16230b7217d9Smrg                            "Unable to map VRAM aperture. %s (%d)\n",
16240b7217d9Smrg                            strerror(err), err);
16250b7217d9Smrg                }
16260b7217d9Smrg            }
1627ff89ac2bSmrg#endif
16280b7217d9Smrg            if (pTrident->FbBase == NULL)
16290b7217d9Smrg                return FALSE;
16300b7217d9Smrg        }
163195b296d0Smrg    }
163295b296d0Smrg    else
16330b7217d9Smrg        pTrident->FbBase = hwp->Base;
163495b296d0Smrg
163595b296d0Smrg    return TRUE;
163695b296d0Smrg}
163795b296d0Smrg
163895b296d0Smrg/*
163995b296d0Smrg * Unmap the framebuffer and MMIO memory.
164095b296d0Smrg */
164195b296d0Smrg
164295b296d0Smrgstatic Bool
164395b296d0SmrgTRIDENTUnmapMem(ScrnInfoPtr pScrn)
164495b296d0Smrg{
164595b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
164695b296d0Smrg    int mapsize = 0x10000;
164795b296d0Smrg
164895b296d0Smrg    if (Is3Dchip) mapsize = 0x20000;
164995b296d0Smrg
165095b296d0Smrg    /*
165195b296d0Smrg     * Unmap IO registers to virtual address space
16520b7217d9Smrg     */
1653ff89ac2bSmrg#ifdef XSERVER_LIBPCIACCESS
1654ff89ac2bSmrg    pci_device_unmap_range(pTrident->PciInfo, (pointer)pTrident->IOBase, mapsize);
1655ff89ac2bSmrg#else
1656ff89ac2bSmrg    if (IsPciCard && UseMMIO) {
16570b7217d9Smrg        xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, mapsize);
1658ff89ac2bSmrg    } else {
16590b7217d9Smrg        pTrident->IOBase -= 0xF00;
16600b7217d9Smrg        xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, 0x1000);
166195b296d0Smrg    }
1662ff89ac2bSmrg#endif
166395b296d0Smrg    pTrident->IOBase = NULL;
166495b296d0Smrg
16652378475aSmrg    if (LINEAR()) {
16660b7217d9Smrg        if (pTrident->FbMapSize != 0) {
1667ff89ac2bSmrg#ifdef XSERVER_LIBPCIACCESS
16680b7217d9Smrg            pci_device_unmap_range(pTrident->PciInfo, (pointer)pTrident->FbBase, pTrident->FbMapSize);
1669ff89ac2bSmrg#else
16700b7217d9Smrg            xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->FbBase,
16710b7217d9Smrg                    pTrident->FbMapSize);
1672ff89ac2bSmrg#endif
16730b7217d9Smrg            pTrident->FbBase = NULL;
167495b296d0Smrg        }
167595b296d0Smrg    }
167695b296d0Smrg
167795b296d0Smrg    return TRUE;
167895b296d0Smrg}
167995b296d0Smrg
168095b296d0Smrg/*
16810b7217d9Smrg * GetAccelPitchValues -
16820b7217d9Smrg *
16830b7217d9Smrg * This function returns a list of display width (pitch) values that can
16840b7217d9Smrg * be used in accelerated mode.
168595b296d0Smrg */
16860b7217d9Smrgstatic int *
16870b7217d9SmrgGetAccelPitchValues(ScrnInfoPtr pScrn)
168895b296d0Smrg{
16890b7217d9Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
16900b7217d9Smrg    int *linePitches = NULL;
16910b7217d9Smrg    int lines[4] = { 512, 1024, 2048, 4096 }; /* 9440AGi */
16920b7217d9Smrg    int i, n = 0;
169395b296d0Smrg
16940b7217d9Smrg    if (pTrident->Chipset >= BLADEXP) {
16950b7217d9Smrg        lines[0] = 1024;
16960b7217d9Smrg        lines[1] = 2048;
16970b7217d9Smrg        lines[2] = 4096;
16980b7217d9Smrg        lines[3] = 8192;
16990b7217d9Smrg    }
170095b296d0Smrg
17010b7217d9Smrg    for (i = 0; i < 4; i++) {
17020b7217d9Smrg        n++;
17030b7217d9Smrg        linePitches = xnfrealloc(linePitches, n * sizeof(int));
17040b7217d9Smrg        linePitches[n - 1] = lines[i];
17050b7217d9Smrg    }
170695b296d0Smrg
17070b7217d9Smrg    /* Mark the end of the list */
17080b7217d9Smrg    if (n > 0) {
17090b7217d9Smrg        linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
17100b7217d9Smrg        linePitches[n] = 0;
17110b7217d9Smrg    }
17120b7217d9Smrg    return linePitches;
17130b7217d9Smrg}
171495b296d0Smrg
17150b7217d9Smrgstatic void
17160b7217d9SmrgTRIDENTProbeDDC(ScrnInfoPtr pScrn, int index)
17170b7217d9Smrg{
17180b7217d9Smrg    vbeInfoPtr pVbe;
17190b7217d9Smrg    if (xf86LoadSubModule(pScrn, "vbe")) {
17200b7217d9Smrg        pVbe = VBEInit(NULL,index);
17210b7217d9Smrg        ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
17220b7217d9Smrg        vbeFree(pVbe);
17230b7217d9Smrg    }
172495b296d0Smrg}
172595b296d0Smrg
17260b7217d9Smrgstatic void
17270b7217d9SmrgTRIDENTProtect(ScrnInfoPtr pScrn, Bool on)
17280b7217d9Smrg{
17290b7217d9Smrg    vgaHWProtect(pScrn, on);
17300b7217d9Smrg}
173195b296d0Smrg
17320b7217d9Smrgstatic void
17330b7217d9SmrgTRIDENTBlankScreen(ScrnInfoPtr pScrn, Bool on)
17340b7217d9Smrg{
17350b7217d9Smrg    vgaHWBlankScreen(pScrn, on);
17360b7217d9Smrg}
173795b296d0Smrg
17380b7217d9Smrg/* Mandatory */
173995b296d0Smrgstatic Bool
17400b7217d9SmrgTRIDENTProbe(DriverPtr drv, int flags)
174195b296d0Smrg{
17420b7217d9Smrg    int i;
17430b7217d9Smrg    GDevPtr *devSections;
17440b7217d9Smrg    int *usedChips = NULL;
17450b7217d9Smrg    int numDevSections;
17460b7217d9Smrg    int numUsed;
17470b7217d9Smrg    Bool foundScreen = FALSE;
174895b296d0Smrg
17490b7217d9Smrg    if ((numDevSections = xf86MatchDevice(TRIDENT_DRIVER_NAME,
17500b7217d9Smrg            &devSections)) <= 0) {
17510b7217d9Smrg        /*
17520b7217d9Smrg         * There's no matching device section in the config file, so quit
17530b7217d9Smrg         * now.
17540b7217d9Smrg         */
17550b7217d9Smrg        return FALSE;
175695b296d0Smrg    }
175795b296d0Smrg
17580b7217d9Smrg    /*
17590b7217d9Smrg     * While we're VGA-dependent, can really only have one such instance, but
17600b7217d9Smrg     * we'll ignore that.
17610b7217d9Smrg     */
176295b296d0Smrg
176395b296d0Smrg    /*
17640b7217d9Smrg     * We need to probe the hardware first.  We then need to see how this
17650b7217d9Smrg     * fits in with what is given in the config file, and allow the config
17660b7217d9Smrg     * file info to override any contradictions.
17670b7217d9Smrg     */
17680b7217d9Smrg
17690b7217d9Smrg    /*
17700b7217d9Smrg     * All of the cards this driver supports are PCI, so the "probing" just
17710b7217d9Smrg     * amounts to checking the PCI data that the server has already collected.
177295b296d0Smrg     */
17730b7217d9Smrg#ifndef XSERVER_LIBPCIACCESS
17740b7217d9Smrg    if (xf86GetPciVideoInfo()== NULL) {
17750b7217d9Smrg        return FALSE;
17760b7217d9Smrg    }
17770b7217d9Smrg#endif
17780b7217d9Smrg    {
17790b7217d9Smrg        numUsed = xf86MatchPciInstances(TRIDENT_NAME, PCI_VENDOR_TRIDENT,
17800b7217d9Smrg                TRIDENTChipsets, TRIDENTPciChipsets, devSections,
17810b7217d9Smrg                numDevSections, drv, &usedChips);
17820b7217d9Smrg
17830b7217d9Smrg        if (numUsed > 0) {
17840b7217d9Smrg            if (flags & PROBE_DETECT)
17850b7217d9Smrg                foundScreen = TRUE;
17860b7217d9Smrg            else for (i = 0; i < numUsed; i++) {
17870b7217d9Smrg                ScrnInfoPtr pScrn = NULL;
17880b7217d9Smrg
17890b7217d9Smrg                if ((pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i],
17900b7217d9Smrg                        TRIDENTPciChipsets, NULL,
17910b7217d9Smrg                        NULL, NULL, NULL, NULL))) {
17920b7217d9Smrg                    /* Fill in what we can of the ScrnInfoRec */
17930b7217d9Smrg                    pScrn->driverVersion = TRIDENT_VERSION;
17940b7217d9Smrg                    pScrn->driverName	 = TRIDENT_DRIVER_NAME;
17950b7217d9Smrg                    pScrn->name		 = TRIDENT_NAME;
17960b7217d9Smrg                    pScrn->Probe	 = TRIDENTProbe;
17970b7217d9Smrg                    pScrn->PreInit	 = TRIDENTPreInit;
17980b7217d9Smrg                    pScrn->ScreenInit	 = TRIDENTScreenInit;
17990b7217d9Smrg                    pScrn->SwitchMode	 = TRIDENTSwitchMode;
18000b7217d9Smrg                    pScrn->AdjustFrame	 = TRIDENTAdjustFrame;
18010b7217d9Smrg                    pScrn->EnterVT	 = TRIDENTEnterVT;
18020b7217d9Smrg                    pScrn->LeaveVT	 = TRIDENTLeaveVT;
18030b7217d9Smrg                    pScrn->FreeScreen	 = TRIDENTFreeScreen;
18040b7217d9Smrg                    pScrn->ValidMode	 = TRIDENTValidMode;
18050b7217d9Smrg                    foundScreen = TRUE;
18060b7217d9Smrg                }
18070b7217d9Smrg            }
18080b7217d9Smrg            free(usedChips);
18090b7217d9Smrg        }
181095b296d0Smrg    }
181195b296d0Smrg
18120b7217d9Smrg#ifdef HAVE_ISA
18130b7217d9Smrg    /* Isa Bus */
18140b7217d9Smrg    numUsed = xf86MatchIsaInstances(TRIDENT_NAME,TRIDENTChipsets,
18150b7217d9Smrg            TRIDENTISAchipsets,
18160b7217d9Smrg            drv,TridentFindIsaDevice,devSections,
18170b7217d9Smrg            numDevSections,&usedChips);
18180b7217d9Smrg    if (numUsed > 0) {
18190b7217d9Smrg        if (flags & PROBE_DETECT)
18200b7217d9Smrg            foundScreen = TRUE;
18210b7217d9Smrg        else 	for (i = 0; i < numUsed; i++) {
18220b7217d9Smrg            ScrnInfoPtr pScrn = NULL;
18230b7217d9Smrg            if ((pScrn = xf86ConfigIsaEntity(pScrn,0,usedChips[i],
18240b7217d9Smrg                    TRIDENTISAchipsets,NULL,
18250b7217d9Smrg                    NULL,NULL,NULL,NULL))) {
18260b7217d9Smrg                pScrn->driverVersion = TRIDENT_VERSION;
18270b7217d9Smrg                pScrn->driverName    = TRIDENT_DRIVER_NAME;
18280b7217d9Smrg                pScrn->name          = TRIDENT_NAME;
18290b7217d9Smrg                pScrn->Probe         = TRIDENTProbe;
18300b7217d9Smrg                pScrn->PreInit       = TRIDENTPreInit;
18310b7217d9Smrg                pScrn->ScreenInit    = TRIDENTScreenInit;
18320b7217d9Smrg                pScrn->SwitchMode    = TRIDENTSwitchMode;
18330b7217d9Smrg                pScrn->AdjustFrame   = TRIDENTAdjustFrame;
18340b7217d9Smrg                pScrn->EnterVT       = TRIDENTEnterVT;
18350b7217d9Smrg                pScrn->LeaveVT       = TRIDENTLeaveVT;
18360b7217d9Smrg                pScrn->FreeScreen    = TRIDENTFreeScreen;
18370b7217d9Smrg                pScrn->ValidMode     = TRIDENTValidMode;
18380b7217d9Smrg                foundScreen = TRUE;
18390b7217d9Smrg            }
18400b7217d9Smrg        }
18410b7217d9Smrg        free(usedChips);
18420b7217d9Smrg    }
184314330f12Smrg#endif
184495b296d0Smrg
18450b7217d9Smrg    free(devSections);
18460b7217d9Smrg    return foundScreen;
184795b296d0Smrg}
184895b296d0Smrg
18490b7217d9Smrg/* Mandatory */
18500b7217d9Smrgstatic Bool
18510b7217d9SmrgTRIDENTPreInit(ScrnInfoPtr pScrn, int flags)
185295b296d0Smrg{
185395b296d0Smrg    TRIDENTPtr pTrident;
18540b7217d9Smrg    vgaHWPtr hwp;
18550b7217d9Smrg    MessageType from;
18560b7217d9Smrg    CARD8 videoram, videorammask;
18570b7217d9Smrg    const char *ramtype = NULL, *chipset = NULL;
18580b7217d9Smrg    Bool Support24bpp;
18590b7217d9Smrg    int vgaIOBase;
18600b7217d9Smrg    float mclk;
18610b7217d9Smrg    double real;
18620b7217d9Smrg    int i, NoClocks = 16;
18630b7217d9Smrg    CARD8 revision;
18640b7217d9Smrg    ClockRangePtr clockRanges;
18650b7217d9Smrg    Bool ddcLoaded = FALSE;
18660b7217d9Smrg    xf86MonPtr pMon = NULL;
18670b7217d9Smrg    const char *s;
18680b7217d9Smrg    Bool tmp_bool;
186995b296d0Smrg
18700b7217d9Smrg    /* Allocate the TRIDENTRec driverPrivate */
18710b7217d9Smrg    if (!TRIDENTGetRec(pScrn)) {
18720b7217d9Smrg        return FALSE;
18730b7217d9Smrg    }
187495b296d0Smrg    pTrident = TRIDENTPTR(pScrn);
18750b7217d9Smrg    pTrident->pScrn = pScrn;
187695b296d0Smrg
18770b7217d9Smrg    if (pScrn->numEntities > 1)
18780b7217d9Smrg        return FALSE;
18790b7217d9Smrg    /* This is the general case */
18800b7217d9Smrg    for (i = 0; i<pScrn->numEntities; i++) {
18810b7217d9Smrg        pTrident->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
18820b7217d9Smrg#ifndef XSERVER_LIBPCIACCESS
18830b7217d9Smrg        if (pTrident->pEnt->resources) return FALSE;
18840b7217d9Smrg#endif
18850b7217d9Smrg        pTrident->Chipset = pTrident->pEnt->chipset;
18860b7217d9Smrg        pScrn->chipset = (char *)xf86TokenToString(TRIDENTChipsets,
18870b7217d9Smrg                pTrident->pEnt->chipset);
18880b7217d9Smrg        /* This driver can handle ISA and PCI buses */
18890b7217d9Smrg        if (pTrident->pEnt->location.type == BUS_PCI) {
18900b7217d9Smrg            pTrident->PciInfo = xf86GetPciInfoForEntity(pTrident->pEnt->index);
18910b7217d9Smrg#ifndef XSERVER_LIBPCIACCESS
18920b7217d9Smrg            pTrident->PciTag = PCI_DEV_TAG(pTrident->PciInfo);
18930b7217d9Smrg#endif
18940b7217d9Smrg            pTrident->Linear = TRUE;
18950b7217d9Smrg        } else {
18960b7217d9Smrg            pTrident->Linear = FALSE;
18970b7217d9Smrg        }
18980b7217d9Smrg    }
189995b296d0Smrg
19000b7217d9Smrg    if (flags & PROBE_DETECT) {
19010b7217d9Smrg        TRIDENTProbeDDC(pScrn, pTrident->pEnt->index);
19020b7217d9Smrg        return TRUE;
19030b7217d9Smrg    }
190495b296d0Smrg
19050b7217d9Smrg    /* Set pScrn->monitor */
19060b7217d9Smrg    pScrn->monitor = pScrn->confScreen->monitor;
190795b296d0Smrg
19080b7217d9Smrg    /*
19090b7217d9Smrg     * The first thing we should figure out is the depth, bpp, etc.
19100b7217d9Smrg     * Our preference for depth 24 is 24bpp, so tell it that too.
19110b7217d9Smrg     */
19120b7217d9Smrg    if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb |
19130b7217d9Smrg            SupportConvert32to24 /*| PreferConvert32to24*/)) {
19140b7217d9Smrg        return FALSE;
19150b7217d9Smrg    } else {
19160b7217d9Smrg        /* Check that the returned depth is one we support */
19170b7217d9Smrg        switch (pScrn->depth) {
19180b7217d9Smrg        case 8:
19190b7217d9Smrg            if (pScrn->bitsPerPixel != pScrn->depth) {
19200b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
19210b7217d9Smrg                        "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
19220b7217d9Smrg                        pScrn->depth, pScrn->bitsPerPixel);
19230b7217d9Smrg                return FALSE;
19240b7217d9Smrg            }
19250b7217d9Smrg            break;
19260b7217d9Smrg        case 15:
19270b7217d9Smrg        case 16:
19280b7217d9Smrg            if (pScrn->bitsPerPixel != 16) {
19290b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
19300b7217d9Smrg                        "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
19310b7217d9Smrg                        pScrn->depth, pScrn->bitsPerPixel);
19320b7217d9Smrg                return FALSE;
19330b7217d9Smrg            }
19340b7217d9Smrg            break;
19350b7217d9Smrg        case 24:
19360b7217d9Smrg            if ((pScrn->bitsPerPixel != 24) && (pScrn->bitsPerPixel != 32)) {
19370b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
19380b7217d9Smrg                        "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
19390b7217d9Smrg                        pScrn->depth, pScrn->bitsPerPixel);
19400b7217d9Smrg                return FALSE;
19410b7217d9Smrg            }
19420b7217d9Smrg            /* OK */
19430b7217d9Smrg            break;
19440b7217d9Smrg        default:
19450b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
19460b7217d9Smrg                    "Given depth (%d) is not supported by this driver\n",
19470b7217d9Smrg                    pScrn->depth);
19480b7217d9Smrg            return FALSE;
19490b7217d9Smrg        }
19500b7217d9Smrg    }
195195b296d0Smrg
19520b7217d9Smrg    xf86PrintDepthBpp(pScrn);
195395b296d0Smrg
19540b7217d9Smrg    /* Get the depth24 pixmap format */
19550b7217d9Smrg    if (pScrn->depth == 24 && pix24bpp == 0)
19560b7217d9Smrg        pix24bpp = xf86GetBppFromDepth(pScrn, 24);
1957eca46af7Smrg
19580b7217d9Smrg    /* The vgahw module should be loaded here when needed */
19590b7217d9Smrg    if (!xf86LoadSubModule(pScrn, "vgahw"))
19600b7217d9Smrg        return FALSE;
1961eca46af7Smrg
19620b7217d9Smrg    /*
19630b7217d9Smrg     * Allocate a vgaHWRec
19640b7217d9Smrg     */
19650b7217d9Smrg    if (!vgaHWGetHWRec(pScrn))
19660b7217d9Smrg        return FALSE;
1967eca46af7Smrg
19680b7217d9Smrg    hwp = VGAHWPTR(pScrn);
19690b7217d9Smrg    vgaHWSetStdFuncs(hwp);
19700b7217d9Smrg    vgaHWGetIOBase(hwp);
19710b7217d9Smrg    vgaIOBase = hwp->IOBase;
197295b296d0Smrg
19730b7217d9Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
19740b7217d9Smrg    pTrident->PIOBase = hwp->PIOOffset;
19750b7217d9Smrg#else
19760b7217d9Smrg    pTrident->PIOBase = 0;
19770b7217d9Smrg#endif
197895b296d0Smrg
19790b7217d9Smrg#ifndef XSERVER_LIBPCIACCESS
19800b7217d9Smrg    xf86SetOperatingState(resVga, pTrident->pEnt->index, ResUnusedOpr);
19810b7217d9Smrg#endif
198295b296d0Smrg
19830b7217d9Smrg    /* The ramdac module should be loaded here when needed */
19840b7217d9Smrg    if (!xf86LoadSubModule(pScrn, "ramdac"))
19850b7217d9Smrg        return FALSE;
198695b296d0Smrg
19870b7217d9Smrg    /*
19880b7217d9Smrg     * This must happen after pScrn->display has been set because
19890b7217d9Smrg     * xf86SetWeight references it.
199095b296d0Smrg     */
19910b7217d9Smrg    if (pScrn->depth > 8) {
19920b7217d9Smrg        /* The defaults are OK for us */
19930b7217d9Smrg        rgb zeros = {0, 0, 0};
199495b296d0Smrg
19950b7217d9Smrg        if (!xf86SetWeight(pScrn, zeros, zeros)) {
19960b7217d9Smrg            return FALSE;
19970b7217d9Smrg        } else {
19980b7217d9Smrg            /* XXX check that weight returned is supported */
19990b7217d9Smrg            ;
20000b7217d9Smrg        }
200195b296d0Smrg    }
200295b296d0Smrg
20030b7217d9Smrg    if (!xf86SetDefaultVisual(pScrn, -1)) {
20040b7217d9Smrg        return FALSE;
20050b7217d9Smrg    } else {
20060b7217d9Smrg        /* We don't currently support DirectColor at > 8bpp */
20070b7217d9Smrg        if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
20080b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
20090b7217d9Smrg                    " (%s) is not supported at depth %d\n",
20100b7217d9Smrg                    xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
20110b7217d9Smrg            return FALSE;
20120b7217d9Smrg        }
20130b7217d9Smrg    }
20140b7217d9Smrg
20150b7217d9Smrg    /*
20160b7217d9Smrg     * The new cmap layer needs this to be initialised.
20170b7217d9Smrg     */
201895b296d0Smrg
201914330f12Smrg    {
20200b7217d9Smrg        Gamma zeros = {0.0, 0.0, 0.0};
20210b7217d9Smrg
20220b7217d9Smrg        if (!xf86SetGamma(pScrn, zeros)) {
20230b7217d9Smrg            return FALSE;
20240b7217d9Smrg        }
202595b296d0Smrg    }
202614330f12Smrg
20270b7217d9Smrg    /* Collect all of the relevant option flags (fill in pScrn->options) */
20280b7217d9Smrg    xf86CollectOptions(pScrn, NULL);
202995b296d0Smrg
20300b7217d9Smrg    /* Process the options */
20310b7217d9Smrg    if (!(pTrident->Options = malloc(sizeof(TRIDENTOptions))))
20320b7217d9Smrg        return FALSE;
20330b7217d9Smrg    memcpy(pTrident->Options, TRIDENTOptions, sizeof(TRIDENTOptions));
20340b7217d9Smrg    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTrident->Options);
203595b296d0Smrg
20360b7217d9Smrg    /* Set the bits per RGB for 8bpp mode */
20370b7217d9Smrg    if (pScrn->depth == 8) {
20380b7217d9Smrg        /* XXX This is here just to test options. */
20390b7217d9Smrg        /* Default to 8 */
20400b7217d9Smrg        pScrn->rgbBits = 6;
20410b7217d9Smrg#if 0
20420b7217d9Smrg        if (xf86GetOptValInteger(pTrident->Options, OPTION_RGB_BITS,
20430b7217d9Smrg                &pScrn->rgbBits)) {
20440b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
20450b7217d9Smrg                    pScrn->rgbBits);
20460b7217d9Smrg        }
20470b7217d9Smrg#endif
204895b296d0Smrg    }
20490b7217d9Smrg    from = X_DEFAULT;
205095b296d0Smrg
20510b7217d9Smrg    pTrident->useEXA = FALSE;
20520b7217d9Smrg    if ((s = (char *)xf86GetOptValString(pTrident->Options,
20530b7217d9Smrg            OPTION_ACCELMETHOD))) {
20540b7217d9Smrg        if (!xf86NameCmp(s, "EXA")) {
20550b7217d9Smrg            pTrident->useEXA = TRUE;
20560b7217d9Smrg            from = X_CONFIG;
20570b7217d9Smrg        }
20580b7217d9Smrg        else if (!xf86NameCmp(s, "XAA")) {
20590b7217d9Smrg            pTrident->useEXA = FALSE;
20600b7217d9Smrg            from = X_CONFIG;
20610b7217d9Smrg        }
20620b7217d9Smrg    }
20630b7217d9Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n",
20640b7217d9Smrg            pTrident->useEXA ? "EXA" : "XAA");
206595b296d0Smrg
20660b7217d9Smrg    pTrident->HWCursor = TRUE;
20670b7217d9Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_SW_CURSOR, FALSE)) {
20680b7217d9Smrg        from = X_CONFIG;
20690b7217d9Smrg        pTrident->HWCursor = FALSE;
20700b7217d9Smrg    }
20710b7217d9Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOACCEL, FALSE)) {
20720b7217d9Smrg        pTrident->NoAccel = TRUE;
20730b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
20740b7217d9Smrg    }
20750b7217d9Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_PCI_RETRY, FALSE)) {
20760b7217d9Smrg        pTrident->UsePCIRetry = TRUE;
20770b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
20780b7217d9Smrg    }
20790b7217d9Smrg    pTrident->UsePCIBurst = TRUE;
20800b7217d9Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOPCIBURST, FALSE)) {
20810b7217d9Smrg        pTrident->UsePCIBurst = FALSE;
20820b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI Burst disabled\n");
20830b7217d9Smrg    }
20840b7217d9Smrg    /* Display Size override moved to DDC section */
20850b7217d9Smrg    if(xf86GetOptValInteger(pTrident->Options, OPTION_VIDEO_KEY,
20860b7217d9Smrg            &(pTrident->videoKey))) {
20870b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
20880b7217d9Smrg                pTrident->videoKey);
20890b7217d9Smrg    } else {
20900b7217d9Smrg        pTrident->videoKey =  (1 << pScrn->offset.red) |
20910b7217d9Smrg                (1 << pScrn->offset.green) |
20920b7217d9Smrg                (((pScrn->mask.blue >> pScrn->offset.blue) - 1)
20930b7217d9Smrg                        << pScrn->offset.blue);
20940b7217d9Smrg    }
20950b7217d9Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOMMIO, FALSE)) {
20960b7217d9Smrg        pTrident->NoMMIO = TRUE;
20970b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO Disabled\n");
20980b7217d9Smrg    }
20990b7217d9Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_MMIO_ONLY, FALSE)) {
21000b7217d9Smrg        if (pTrident->NoMMIO)
21010b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MMIO only cannot be set"
21020b7217d9Smrg                    " with NoMMIO\n");
21030b7217d9Smrg        else {
21040b7217d9Smrg            pTrident->MMIOonly = TRUE;
21050b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO only enabled\n");
21060b7217d9Smrg        }
21070b7217d9Smrg    }
210895b296d0Smrg
21090b7217d9Smrg    pTrident->dspOverride = 0;
21100b7217d9Smrg    if ((s = xf86GetOptValString(pTrident->Options, OPTION_DISPLAY))) {
21110b7217d9Smrg        if(!xf86NameCmp(s, "CRT")) {
21120b7217d9Smrg            pTrident->dspOverride = CRT_ACTIVE;
21130b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD off CRT on\n");
21140b7217d9Smrg        } else if (!xf86NameCmp(s, "LCD")) {
21150b7217d9Smrg            pTrident->dspOverride = LCD_ACTIVE;
21160b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT off\n");
21170b7217d9Smrg        } else if (!xf86NameCmp(s, "Dual")) {
21180b7217d9Smrg            pTrident->dspOverride = LCD_ACTIVE | CRT_ACTIVE;
21190b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT on\n");
21200b7217d9Smrg        } else
21210b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex,X_ERROR,
21220b7217d9Smrg                    "%s is an unknown display option\n",s);
21230b7217d9Smrg    }
21240b7217d9Smrg    if ((s = xf86GetOptValString(pTrident->Options, OPTION_GB))) {
21250b7217d9Smrg        int brightness = -1;
21260b7217d9Smrg        double gamma = -1.0;
21270b7217d9Smrg        Bool error = FALSE;
21280b7217d9Smrg        int i;
21290b7217d9Smrg
21300b7217d9Smrg        i = sscanf(s,"%lf %i",&gamma,&brightness);
21310b7217d9Smrg
21320b7217d9Smrg        if (i != 2 || brightness == -1 || gamma == -1.0) {
21330b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
21340b7217d9Smrg                    "Invalid Gamma/Brightness argument: %s\n",s);
21350b7217d9Smrg            error = TRUE;
21360b7217d9Smrg        } else {
21370b7217d9Smrg            if (brightness < 0 || brightness > 128) {
21380b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
21390b7217d9Smrg                        "brightness out of range [0,128]: %i\n",brightness);
21400b7217d9Smrg                error = TRUE;
21410b7217d9Smrg            }
21420b7217d9Smrg            if (gamma <= 0.0 || gamma > 10.0) {
21430b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
21440b7217d9Smrg                        "gamma out of range (0,10.0]: %f\n",gamma);
21450b7217d9Smrg                error = TRUE;
21460b7217d9Smrg            }
21470b7217d9Smrg        }
214895b296d0Smrg
21490b7217d9Smrg        if (!error) {
21500b7217d9Smrg            pTrident->GammaBrightnessOn = TRUE;
21510b7217d9Smrg            pTrident->gamma = gamma;
21520b7217d9Smrg            pTrident->brightness = brightness;
21530b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Gamma: %f Brightness: %i\n",
21540b7217d9Smrg                    gamma,brightness);
21550b7217d9Smrg        }
21560b7217d9Smrg    }
21570b7217d9Smrg
21580b7217d9Smrg    /* The following is a temporary hack */
21590b7217d9Smrg    pTrident->FPDelay = 7; /* invalid value */
21600b7217d9Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_FP_DELAY,
21610b7217d9Smrg            &pTrident->FPDelay)) {
21620b7217d9Smrg        if (pTrident->FPDelay < -2 || pTrident->FPDelay > 5) {
21630b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "FPDelay %i out if range "
21640b7217d9Smrg                    "(-2 < FPDelay < 5)\n",pTrident->FPDelay);
21650b7217d9Smrg            pTrident->FPDelay = 7;
21660b7217d9Smrg        } else
21670b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "FP Delay set to %i\n",
21680b7217d9Smrg                    pTrident->FPDelay);
21690b7217d9Smrg    }
21700b7217d9Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_SHADOW, FALSE)) {
21710b7217d9Smrg        pTrident->CyberShadow = TRUE;
21720b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Shadow enabled\n");
21730b7217d9Smrg    }
21740b7217d9Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_STRETCH, FALSE)) {
21750b7217d9Smrg        pTrident->CyberStretch = TRUE;
21760b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Stretch enabled\n");
21770b7217d9Smrg    }
21780b7217d9Smrg
21790b7217d9Smrg    pTrident->MUXThreshold = 90000; /* 90MHz */
21800b7217d9Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_MUX_THRESHOLD,
21810b7217d9Smrg            &pTrident->MUXThreshold)) {
21820b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MUX Threshold set to %d\n",
21830b7217d9Smrg                pTrident->MUXThreshold);
21840b7217d9Smrg    }
21850b7217d9Smrg    pTrident->OverrideHsync = 0;
21860b7217d9Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC,
21870b7217d9Smrg            &pTrident->OverrideHsync)) {
21880b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n",
21890b7217d9Smrg                pTrident->OverrideHsync);
21900b7217d9Smrg    }
21910b7217d9Smrg    pTrident->OverrideVsync = 0;
21920b7217d9Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC,
21930b7217d9Smrg            &pTrident->OverrideVsync)) {
21940b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n",
21950b7217d9Smrg                pTrident->OverrideVsync);
21960b7217d9Smrg    }
21970b7217d9Smrg    pTrident->OverrideHsync = 0;
21980b7217d9Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC,
21990b7217d9Smrg            &pTrident->OverrideHsync)) {
22000b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n",
22010b7217d9Smrg                pTrident->OverrideHsync);
22020b7217d9Smrg    }
22030b7217d9Smrg    pTrident->OverrideVsync = 0;
22040b7217d9Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC,
22050b7217d9Smrg            &pTrident->OverrideVsync)) {
22060b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n",
22070b7217d9Smrg                pTrident->OverrideVsync);
22080b7217d9Smrg    }
22090b7217d9Smrg    pTrident->OverrideRskew = 0;
22100b7217d9Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_RSKEW,
22110b7217d9Smrg            &pTrident->OverrideRskew)) {
22120b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Rskew set to %d\n",
22130b7217d9Smrg                pTrident->OverrideRskew);
22140b7217d9Smrg    }
22150b7217d9Smrg    pTrident->OverrideBskew = 0;
22160b7217d9Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_BSKEW,
22170b7217d9Smrg            &pTrident->OverrideBskew)) {
22180b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Bskew set to %d\n",
22190b7217d9Smrg                pTrident->OverrideBskew);
22200b7217d9Smrg    }
22210b7217d9Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_SHADOW_FB, FALSE)) {
22220b7217d9Smrg        if (!LINEAR())
22230b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option SHADOW_FB"
22240b7217d9Smrg                    " in non-Linear Mode\n");
22250b7217d9Smrg        else {
22260b7217d9Smrg            pTrident->ShadowFB = TRUE;
22270b7217d9Smrg            pTrident->NoAccel = TRUE;
22280b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
22290b7217d9Smrg                    "Using \"Shadow Framebuffer\" - acceleration disabled\n");
22300b7217d9Smrg        }
22310b7217d9Smrg    }
22320b7217d9Smrg    pTrident->Rotate = 0;
22330b7217d9Smrg    if ((s = xf86GetOptValString(pTrident->Options, OPTION_ROTATE))) {
22340b7217d9Smrg        if (!LINEAR())
22350b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option ROTATE "
22360b7217d9Smrg                    "in non-Linear Mode\n");
22370b7217d9Smrg        else {
22380b7217d9Smrg            if(!xf86NameCmp(s, "CW")) {
22390b7217d9Smrg                /* accel is disabled below for shadowFB */
22400b7217d9Smrg                pTrident->ShadowFB = TRUE;
22410b7217d9Smrg                pTrident->NoAccel = TRUE;
22420b7217d9Smrg                pTrident->HWCursor = FALSE;
22430b7217d9Smrg                pTrident->Rotate = 1;
22440b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
22450b7217d9Smrg                        "Rotating screen clockwise - acceleration disabled\n");
22460b7217d9Smrg            } else if(!xf86NameCmp(s, "CCW")) {
22470b7217d9Smrg                pTrident->ShadowFB = TRUE;
22480b7217d9Smrg                pTrident->NoAccel = TRUE;
22490b7217d9Smrg                pTrident->HWCursor = FALSE;
22500b7217d9Smrg                pTrident->Rotate = -1;
22510b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,  "Rotating screen"
22520b7217d9Smrg                        "counter clockwise - acceleration disabled\n");
22530b7217d9Smrg            } else {
22540b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
22550b7217d9Smrg                        "value for Option \"Rotate\"\n", s);
22560b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
22570b7217d9Smrg                        "Valid options are \"CW\" or \"CCW\"\n");
22580b7217d9Smrg            }
22590b7217d9Smrg        }
22600b7217d9Smrg    }
226195b296d0Smrg
22620b7217d9Smrg    pTrident->TVChipset = 0;
22630b7217d9Smrg    if ((s = xf86GetOptValString(pTrident->Options, OPTION_TV_CHIPSET))) {
22640b7217d9Smrg        if(!xf86NameCmp(s, "VT1621")) {
22650b7217d9Smrg            pTrident->TVChipset = 1;
22660b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Using VIA VT1621 TV chip\n");
22670b7217d9Smrg        } else if (!xf86NameCmp(s, "CH7005")) {
22680b7217d9Smrg            pTrident->TVChipset = 2;
22690b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Using Chrontel CH7005 TV chip\n");
22700b7217d9Smrg        } else
22710b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex,X_ERROR,
22720b7217d9Smrg                    "%s is an unknown TV chipset option\n",s);
22730b7217d9Smrg    }
22740b7217d9Smrg    /* Default : NTSC */
22750b7217d9Smrg    pTrident->TVSignalMode=0;
22760b7217d9Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_TV_SIGNALMODE,
22770b7217d9Smrg            &pTrident->TVSignalMode)) {
22780b7217d9Smrg        ErrorF("TV SignalMode set to %d\n",pTrident->TVSignalMode);
22790b7217d9Smrg    }
228095b296d0Smrg
22810b7217d9Smrg    /* FIXME ACCELERATION */
22820b7217d9Smrg    if (!UseMMIO) pTrident->NoAccel = TRUE;
228395b296d0Smrg
22840b7217d9Smrg    if (LINEAR()) {
22850b7217d9Smrg        if (pTrident->pEnt->device->MemBase != 0) {
22860b7217d9Smrg            /*
22870b7217d9Smrg             * XXX Should check that the config file value matches one of the
22880b7217d9Smrg             * PCI base address values.
22890b7217d9Smrg             */
22900b7217d9Smrg            pTrident->FbAddress = pTrident->pEnt->device->MemBase;
22910b7217d9Smrg            from = X_CONFIG;
22920b7217d9Smrg        } else {
22930b7217d9Smrg            if (IsPciCard)
22940b7217d9Smrg                pTrident->FbAddress = PCI_REGION_BASE(pTrident->PciInfo, 0, REGION_MEM) & 0xFFFFFFF0;
22950b7217d9Smrg            else
22960b7217d9Smrg                pTrident->FbAddress = 0xA0000;
22970b7217d9Smrg        }
229895b296d0Smrg
22990b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
23000b7217d9Smrg                (unsigned long)pTrident->FbAddress);
230195b296d0Smrg    }
230295b296d0Smrg
23030b7217d9Smrg    if (UseMMIO) {
23040b7217d9Smrg        if (pTrident->pEnt->device->IOBase != 0) {
23050b7217d9Smrg            /*
23060b7217d9Smrg             * XXX Should check that the config file value matches one of the
23070b7217d9Smrg             * PCI base address values.
23080b7217d9Smrg             */
23090b7217d9Smrg            pTrident->IOAddress = pTrident->pEnt->device->IOBase;
23100b7217d9Smrg            from = X_CONFIG;
23110b7217d9Smrg        } else {
23120b7217d9Smrg            if (IsPciCard)
23130b7217d9Smrg                pTrident->IOAddress = PCI_REGION_BASE(pTrident->PciInfo, 1, REGION_MEM) & 0xFFFFC000;
23140b7217d9Smrg            else
23150b7217d9Smrg                /* FIXME - Multihead UNAWARE */
23160b7217d9Smrg                pTrident->IOAddress = 0xBF000;
23170b7217d9Smrg        }
231895b296d0Smrg
23190b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex,X_PROBED,"IO registers at 0x%lX\n",
23200b7217d9Smrg                (unsigned long)pTrident->IOAddress);
232195b296d0Smrg    }
232295b296d0Smrg
23230b7217d9Smrg#ifndef XSERVER_LIBPCIACCESS
23240b7217d9Smrg    /* Register the PCI-assigned resources. */
23250b7217d9Smrg    if (xf86RegisterResources(pTrident->pEnt->index, NULL, ResExclusive)) {
23260b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
23270b7217d9Smrg                "xf86RegisterResources() found resource conflicts\n");
23280b7217d9Smrg        return FALSE;
232995b296d0Smrg    }
23300b7217d9Smrg#endif
23310b7217d9Smrg    /* Initialize VBE if possible
23320b7217d9Smrg     * Don't move this past MMIO enable!!
23330b7217d9Smrg     * PIO access will be blocked
23340b7217d9Smrg     * when MMIO is turned on!
233595b296d0Smrg     */
233695b296d0Smrg
23370b7217d9Smrg    if (xf86LoadSubModule(pScrn, "vbe")) {
23380b7217d9Smrg        vbeInfoPtr pVbe;
233995b296d0Smrg
23400b7217d9Smrg        pVbe =  VBEInit(NULL,pTrident->pEnt->index);
23410b7217d9Smrg        pMon = vbeDoEDID(pVbe, NULL);
23420b7217d9Smrg#ifdef VBE_INFO
23430b7217d9Smrg        {
23440b7217d9Smrg            VbeInfoBlock* vbeInfoBlockPtr;
23450b7217d9Smrg            if ((vbeInfoBlockPtr = VBEGetVBEInfo(pVbe))) {
23460b7217d9Smrg                pTrident->vbeModes = VBEBuildVbeModeList(pVbe,vbeInfoBlockPtr);
23470b7217d9Smrg                VBEFreeVBEInfo(vbeInfoBlockPtr);
23480b7217d9Smrg            }
23490b7217d9Smrg        }
23500b7217d9Smrg#endif
23510b7217d9Smrg        vbeFree(pVbe);
23520b7217d9Smrg        if (pMon) {
23530b7217d9Smrg            if (!xf86LoadSubModule(pScrn, "ddc")) {
23540b7217d9Smrg                TRIDENTFreeRec(pScrn);
23550b7217d9Smrg                return FALSE;
23560b7217d9Smrg            } else {
23570b7217d9Smrg                xf86SetDDCproperties(pScrn,xf86PrintEDID(pMon));
23580b7217d9Smrg                ddcLoaded = TRUE;
23590b7217d9Smrg            }
23600b7217d9Smrg        }
236195b296d0Smrg
23620b7217d9Smrg    }
236395b296d0Smrg
23640b7217d9Smrg    if (xf86GetOptValBool(pTrident->Options, OPTION_1400_DISPLAY, &tmp_bool)) {
23650b7217d9Smrg        if (tmp_bool)
23660b7217d9Smrg            pTrident->displaySize = 1400;
23670b7217d9Smrg    } else
23680b7217d9Smrg        pTrident->displaySize = TRIDENTLcdDisplaySize(pMon);
236995b296d0Smrg
23700b7217d9Smrg    if (IsPciCard && UseMMIO) {
23710b7217d9Smrg        if (!TRIDENTMapMem(pScrn))
23720b7217d9Smrg            return FALSE;
237395b296d0Smrg
23740b7217d9Smrg        TRIDENTEnableMMIO(pScrn);
237595b296d0Smrg    }
237695b296d0Smrg
23770b7217d9Smrg    OUTB(0x3C4, RevisionID); revision = INB(0x3C5);
23780b7217d9Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Revision is %d\n",revision);
237995b296d0Smrg
23800b7217d9Smrg    pScrn->progClock = TRUE;
23810b7217d9Smrg    pTrident->EngineOperation = 0x00;
23820b7217d9Smrg    pTrident->IsCyber = FALSE;
23830b7217d9Smrg    pTrident->HasSGRAM = FALSE;
23840b7217d9Smrg    pTrident->NewClockCode = FALSE;
23850b7217d9Smrg    pTrident->MUX = FALSE;
23860b7217d9Smrg    Support24bpp = FALSE;
238795b296d0Smrg
23880b7217d9Smrg    OUTB(vgaIOBase + 4, InterfaceSel);
238995b296d0Smrg
23900b7217d9Smrg    switch (pTrident->Chipset) {
23910b7217d9Smrg    case TVGA9000:
23920b7217d9Smrg    case TVGA9000i:
23930b7217d9Smrg        pScrn->progClock = FALSE;
23940b7217d9Smrg        NoClocks = 16;
23950b7217d9Smrg        pTrident->NoMMIO = TRUE;
23960b7217d9Smrg        pTrident->NoAccel = TRUE;
23970b7217d9Smrg        pTrident->HWCursor = FALSE;
23980b7217d9Smrg        chipset = "TVGA9000/9000i";
23990b7217d9Smrg        ramtype = "Standard DRAM";
24000b7217d9Smrg        if (pTrident->UsePCIRetry)
24010b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
24020b7217d9Smrg        pTrident->UsePCIRetry = FALSE; /* Not Supported */
24030b7217d9Smrg        pTrident->frequency = NTSC;
24040b7217d9Smrg        break;
24050b7217d9Smrg    case TVGA9100B:
24060b7217d9Smrg        pScrn->progClock = FALSE;
24070b7217d9Smrg        NoClocks = 8;
24080b7217d9Smrg        pTrident->NoMMIO = TRUE;
24090b7217d9Smrg        pTrident->NoAccel = TRUE;
24100b7217d9Smrg        pTrident->HWCursor = FALSE;
24110b7217d9Smrg        chipset = "TVGA9100B";
24120b7217d9Smrg        ramtype = "Standard DRAM";
24130b7217d9Smrg        if (pTrident->UsePCIRetry)
24140b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
24150b7217d9Smrg        pTrident->UsePCIRetry = FALSE; /* Not Supported */
24160b7217d9Smrg        pTrident->frequency = NTSC;
24170b7217d9Smrg        break;
24180b7217d9Smrg    case TVGA8900B:
24190b7217d9Smrg        pScrn->progClock = FALSE;
24200b7217d9Smrg        NoClocks = 8;
24210b7217d9Smrg        pTrident->NoMMIO = TRUE;
24220b7217d9Smrg        pTrident->NoAccel = TRUE;
24230b7217d9Smrg        pTrident->HWCursor = FALSE;
24240b7217d9Smrg        chipset = "TVGA8900B";
24250b7217d9Smrg        ramtype = "Standard DRAM";
24260b7217d9Smrg        if (pTrident->UsePCIRetry)
24270b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
24280b7217d9Smrg        pTrident->UsePCIRetry = FALSE; /* Not Supported */
24290b7217d9Smrg        pTrident->frequency = NTSC;
24300b7217d9Smrg        break;
24310b7217d9Smrg    case TVGA8900C:
24320b7217d9Smrg        pScrn->progClock = FALSE;
24330b7217d9Smrg        NoClocks = 16;
24340b7217d9Smrg        pTrident->NoMMIO = TRUE;
24350b7217d9Smrg        pTrident->NoAccel = TRUE;
24360b7217d9Smrg        pTrident->HWCursor = FALSE;
24370b7217d9Smrg        chipset = "TVGA8900C";
24380b7217d9Smrg        ramtype = "Standard DRAM";
24390b7217d9Smrg        if (pTrident->UsePCIRetry)
24400b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
24410b7217d9Smrg        pTrident->UsePCIRetry = FALSE; /* Not Supported */
24420b7217d9Smrg        pTrident->frequency = NTSC;
24430b7217d9Smrg        break;
24440b7217d9Smrg    case TVGA8900D:
24450b7217d9Smrg        pScrn->progClock = FALSE;
24460b7217d9Smrg        NoClocks = 16;
24470b7217d9Smrg        pTrident->NoMMIO = TRUE;
24480b7217d9Smrg        pTrident->NoAccel = TRUE;
24490b7217d9Smrg        pTrident->HWCursor = FALSE;
24500b7217d9Smrg        chipset = "TVGA8900D";
24510b7217d9Smrg        ramtype = "Standard DRAM";
24520b7217d9Smrg        if (pTrident->UsePCIRetry)
24530b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
24540b7217d9Smrg        pTrident->UsePCIRetry = FALSE; /* Not Supported */
24550b7217d9Smrg        pTrident->frequency = NTSC;
24560b7217d9Smrg        break;
24570b7217d9Smrg    case TVGA9200CXr:
24580b7217d9Smrg        pScrn->progClock = FALSE;
24590b7217d9Smrg        NoClocks = 16;
24600b7217d9Smrg        pTrident->NoMMIO = TRUE;
24610b7217d9Smrg        pTrident->NoAccel = TRUE;
24620b7217d9Smrg        pTrident->HWCursor = FALSE;
24630b7217d9Smrg        chipset = "TVGA9200CXr";
24640b7217d9Smrg        ramtype = "Standard DRAM";
24650b7217d9Smrg        if (pTrident->UsePCIRetry)
24660b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
24670b7217d9Smrg        pTrident->UsePCIRetry = FALSE; /* Not Supported */
24680b7217d9Smrg        pTrident->frequency = NTSC;
24690b7217d9Smrg        break;
24700b7217d9Smrg    case TGUI9400CXi:
24710b7217d9Smrg        pScrn->progClock = FALSE;
24720b7217d9Smrg        NoClocks = 16;
24730b7217d9Smrg        pTrident->NoMMIO = TRUE;
24740b7217d9Smrg        pTrident->NoAccel = TRUE;
24750b7217d9Smrg        pTrident->HWCursor = FALSE;
24760b7217d9Smrg        chipset = "TVGA9200CXr";
24770b7217d9Smrg        ramtype = "Standard DRAM";
24780b7217d9Smrg        if (pTrident->UsePCIRetry)
24790b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
24800b7217d9Smrg        pTrident->UsePCIRetry = FALSE; /* Not Supported */
24810b7217d9Smrg        pTrident->frequency = NTSC;
24820b7217d9Smrg        break;
24830b7217d9Smrg    case TGUI9440AGi:
24840b7217d9Smrg        pTrident->ddc1Read = Tridentddc1Read;
24850b7217d9Smrg        pTrident->HWCursor = FALSE;
24860b7217d9Smrg        chipset = "TGUI9440AGi";
24870b7217d9Smrg        ramtype = "Standard DRAM";
24880b7217d9Smrg        if (pTrident->UsePCIRetry)
24890b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
24900b7217d9Smrg        pTrident->UsePCIRetry = FALSE; /* Not Supported */
24910b7217d9Smrg        pTrident->frequency = NTSC;
24920b7217d9Smrg        break;
24930b7217d9Smrg    case CYBER9320:
24940b7217d9Smrg        pTrident->ddc1Read = Tridentddc1Read;
24950b7217d9Smrg        chipset = "Cyber9320";
24960b7217d9Smrg        ramtype = "Standard DRAM";
24970b7217d9Smrg        if (pTrident->UsePCIRetry)
24980b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
24990b7217d9Smrg        pTrident->UsePCIRetry = FALSE; /* Not Supported */
25000b7217d9Smrg        break;
25010b7217d9Smrg        /* Trident didn't update the PCI ID's and so we have to determine
25020b7217d9Smrg         * which chips are right ! Then override pTrident->Chipset to
25030b7217d9Smrg         * correct values */
25040b7217d9Smrg    case TGUI9660:
25050b7217d9Smrg        pTrident->ddc1Read = Tridentddc1Read;
25060b7217d9Smrg        if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
25070b7217d9Smrg            ramtype = "EDO Ram";
25080b7217d9Smrg        if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C)
25090b7217d9Smrg            ramtype = "Standard DRAM";
25100b7217d9Smrg        switch (revision) {
25110b7217d9Smrg        case 0x00:
25120b7217d9Smrg            chipset = "TGUI9660";
25130b7217d9Smrg            pTrident->Chipset = TGUI9660;
25140b7217d9Smrg            if (pTrident->UsePCIRetry)
25150b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
25160b7217d9Smrg            pTrident->UsePCIRetry = FALSE; /* Not Supported */
25170b7217d9Smrg            break;
25180b7217d9Smrg        case 0x01:
25190b7217d9Smrg            chipset = "TGUI9680";
25200b7217d9Smrg            pTrident->Chipset = TGUI9680;
25210b7217d9Smrg            if (pTrident->UsePCIRetry)
25220b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
25230b7217d9Smrg            pTrident->UsePCIRetry = FALSE; /* Not Supported */
25240b7217d9Smrg            break;
25250b7217d9Smrg        case 0x10:
25260b7217d9Smrg            chipset = "ProVidia 9682";
25270b7217d9Smrg            Support24bpp = TRUE;
25280b7217d9Smrg            pTrident->Chipset = PROVIDIA9682;
25290b7217d9Smrg            break;
25300b7217d9Smrg        case 0x21:
25310b7217d9Smrg            chipset = "ProVidia 9685";
25320b7217d9Smrg            Support24bpp = TRUE;
25330b7217d9Smrg            pTrident->NewClockCode = TRUE;
25340b7217d9Smrg            pTrident->Chipset = PROVIDIA9685;
25350b7217d9Smrg            break;
25360b7217d9Smrg        case 0x22:
25370b7217d9Smrg        case 0x23:
25380b7217d9Smrg            chipset = "Cyber 9397";
25390b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
25400b7217d9Smrg                ramtype = "EDO Ram";
25410b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
25420b7217d9Smrg                ramtype = "SDRAM";
25430b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
25440b7217d9Smrg                pTrident->HasSGRAM = TRUE;
25450b7217d9Smrg                ramtype = "SGRAM";
25460b7217d9Smrg            }
25470b7217d9Smrg            pTrident->NewClockCode = TRUE;
25480b7217d9Smrg            pTrident->Chipset = CYBER9397;
25490b7217d9Smrg            pTrident->IsCyber = TRUE;
25500b7217d9Smrg            break;
25510b7217d9Smrg        case 0x2a:
25520b7217d9Smrg            chipset = "Cyber 9397/DVD";
25530b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
25540b7217d9Smrg                ramtype = "EDO Ram";
25550b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
25560b7217d9Smrg                ramtype = "SDRAM";
25570b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
25580b7217d9Smrg                pTrident->HasSGRAM = TRUE;
25590b7217d9Smrg                ramtype = "SGRAM";
25600b7217d9Smrg            }
25610b7217d9Smrg            pTrident->NewClockCode = TRUE;
25620b7217d9Smrg            pTrident->Chipset = CYBER9397DVD;
25630b7217d9Smrg            pTrident->IsCyber = TRUE;
25640b7217d9Smrg            break;
25650b7217d9Smrg        case 0x30:
25660b7217d9Smrg        case 0x33:
25670b7217d9Smrg        case 0x34:
25680b7217d9Smrg        case 0x35:
25690b7217d9Smrg        case 0xB3:
25700b7217d9Smrg            chipset = "Cyber 9385";
25710b7217d9Smrg            pTrident->NewClockCode = TRUE;
25720b7217d9Smrg            pTrident->Chipset = CYBER9385;
25730b7217d9Smrg            pTrident->IsCyber = TRUE;
25740b7217d9Smrg            break;
25750b7217d9Smrg        case 0x38:
25760b7217d9Smrg        case 0x3A:
25770b7217d9Smrg            chipset = "Cyber 9385-1";
25780b7217d9Smrg            pTrident->NewClockCode = TRUE;
25790b7217d9Smrg            pTrident->Chipset = CYBER9385;
25800b7217d9Smrg            pTrident->IsCyber = TRUE;
25810b7217d9Smrg            break;
25820b7217d9Smrg        case 0x40:
25830b7217d9Smrg        case 0x41:
25840b7217d9Smrg        case 0x42:
25850b7217d9Smrg        case 0x43:
25860b7217d9Smrg            chipset = "Cyber 9382";
25870b7217d9Smrg            pTrident->NewClockCode = TRUE;
25880b7217d9Smrg            pTrident->Chipset = CYBER9382;
25890b7217d9Smrg            pTrident->IsCyber = TRUE;
25900b7217d9Smrg            break;
25910b7217d9Smrg        case 0x4A:
25920b7217d9Smrg            chipset = "Cyber 9388";
25930b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
25940b7217d9Smrg                ramtype = "EDO Ram";
25950b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
25960b7217d9Smrg                ramtype = "SDRAM";
25970b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
25980b7217d9Smrg                pTrident->HasSGRAM = TRUE;
25990b7217d9Smrg                ramtype = "SGRAM";
26000b7217d9Smrg            }
26010b7217d9Smrg            pTrident->NewClockCode = TRUE;
26020b7217d9Smrg            pTrident->Chipset = CYBER9388;
26030b7217d9Smrg            pTrident->IsCyber = TRUE;
26040b7217d9Smrg            break;
26050b7217d9Smrg        default:
26060b7217d9Smrg            chipset = "Unknown";
26070b7217d9Smrg            pTrident->Chipset = TGUI9660;
26080b7217d9Smrg            break;
26090b7217d9Smrg        }
26100b7217d9Smrg        break;
26110b7217d9Smrg        case CYBER9388:
26120b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
26130b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
26140b7217d9Smrg                ramtype = "EDO Ram";
26150b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
26160b7217d9Smrg                ramtype = "SDRAM";
26170b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
26180b7217d9Smrg                pTrident->HasSGRAM = TRUE;
26190b7217d9Smrg                ramtype = "SGRAM";
26200b7217d9Smrg            }
26210b7217d9Smrg            pTrident->IsCyber = TRUE;
26220b7217d9Smrg            Support24bpp = TRUE;
26230b7217d9Smrg            chipset = "Cyber 9388";
26240b7217d9Smrg            pTrident->NewClockCode = TRUE;
26250b7217d9Smrg            break;
26260b7217d9Smrg        case CYBER9397:
26270b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
26280b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
26290b7217d9Smrg                ramtype = "EDO Ram";
26300b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
26310b7217d9Smrg                ramtype = "SDRAM";
26320b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
26330b7217d9Smrg                pTrident->HasSGRAM = TRUE;
26340b7217d9Smrg                ramtype = "SGRAM";
26350b7217d9Smrg            }
26360b7217d9Smrg            pTrident->IsCyber = TRUE;
26370b7217d9Smrg            Support24bpp = TRUE;
26380b7217d9Smrg            chipset = "Cyber 9397";
26390b7217d9Smrg            pTrident->NewClockCode = TRUE;
26400b7217d9Smrg            break;
26410b7217d9Smrg        case CYBER9397DVD:
26420b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
26430b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
26440b7217d9Smrg                ramtype = "EDO Ram";
26450b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
26460b7217d9Smrg                ramtype = "SDRAM";
26470b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
26480b7217d9Smrg                pTrident->HasSGRAM = TRUE;
26490b7217d9Smrg                ramtype = "SGRAM";
26500b7217d9Smrg            }
26510b7217d9Smrg            pTrident->IsCyber = TRUE;
26520b7217d9Smrg            Support24bpp = TRUE;
26530b7217d9Smrg            chipset = "Cyber 9397/DVD";
26540b7217d9Smrg            pTrident->NewClockCode = TRUE;
26550b7217d9Smrg            break;
26560b7217d9Smrg        case CYBER9520:
26570b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
26580b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
26590b7217d9Smrg                ramtype = "EDO Ram";
26600b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
26610b7217d9Smrg                ramtype = "SDRAM";
26620b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
26630b7217d9Smrg                pTrident->HasSGRAM = TRUE;
26640b7217d9Smrg                ramtype = "SGRAM";
26650b7217d9Smrg            }
26660b7217d9Smrg            pTrident->IsCyber = TRUE;
26670b7217d9Smrg            Support24bpp = TRUE;
26680b7217d9Smrg            chipset = "Cyber 9520";
26690b7217d9Smrg            pTrident->NewClockCode = TRUE;
26700b7217d9Smrg            break;
26710b7217d9Smrg        case CYBER9525DVD:
26720b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
26730b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
26740b7217d9Smrg                ramtype = "EDO Ram";
26750b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
26760b7217d9Smrg                ramtype = "SDRAM";
26770b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
26780b7217d9Smrg                pTrident->HasSGRAM = TRUE;
26790b7217d9Smrg                ramtype = "SGRAM";
26800b7217d9Smrg            }
26810b7217d9Smrg            pTrident->IsCyber = TRUE;
26820b7217d9Smrg            Support24bpp = TRUE;
26830b7217d9Smrg            chipset = "Cyber 9525/DVD";
26840b7217d9Smrg            pTrident->NewClockCode = TRUE;
26850b7217d9Smrg            break;
26860b7217d9Smrg        case CYBERBLADEE4:
26870b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
26880b7217d9Smrg            ramtype = "SDRAM";
26890b7217d9Smrg            pTrident->IsCyber = TRUE;
26900b7217d9Smrg            Support24bpp = TRUE;
26910b7217d9Smrg            chipset = "CyberBlade e4/128";
26920b7217d9Smrg            pTrident->NewClockCode = TRUE;
26930b7217d9Smrg            break;
26940b7217d9Smrg        case IMAGE975:
26950b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
26960b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
26970b7217d9Smrg                ramtype = "EDO Ram";
26980b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
26990b7217d9Smrg                ramtype = "SDRAM";
27000b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
27010b7217d9Smrg                pTrident->HasSGRAM = TRUE;
27020b7217d9Smrg                ramtype = "SGRAM";
27030b7217d9Smrg            }
27040b7217d9Smrg            Support24bpp = TRUE;
27050b7217d9Smrg            chipset = "3DImage975";
27060b7217d9Smrg            pTrident->NewClockCode = TRUE;
27070b7217d9Smrg            break;
27080b7217d9Smrg        case IMAGE985:
27090b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
27100b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
27110b7217d9Smrg                ramtype = "EDO Ram";
27120b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
27130b7217d9Smrg                ramtype = "SDRAM";
27140b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
27150b7217d9Smrg                pTrident->HasSGRAM = TRUE;
27160b7217d9Smrg                ramtype = "SGRAM";
27170b7217d9Smrg            }
27180b7217d9Smrg            Support24bpp = TRUE;
27190b7217d9Smrg            chipset = "3DImage985";
27200b7217d9Smrg            pTrident->NewClockCode = TRUE;
27210b7217d9Smrg            break;
27220b7217d9Smrg        case BLADE3D:
27230b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
27240b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
27250b7217d9Smrg                ramtype = "SDRAM";
27260b7217d9Smrg            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
27270b7217d9Smrg                pTrident->HasSGRAM = TRUE;
27280b7217d9Smrg                ramtype = "SGRAM";
27290b7217d9Smrg            }
27300b7217d9Smrg            Support24bpp = TRUE;
27310b7217d9Smrg            chipset = "Blade3D";
27320b7217d9Smrg            pTrident->NewClockCode = TRUE;
27330b7217d9Smrg            pTrident->frequency = NTSC;
27340b7217d9Smrg            pTrident->UsePCIRetry = TRUE; /* To avoid lockups */
27350b7217d9Smrg            break;
27360b7217d9Smrg        case CYBERBLADEI7:
27370b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
27380b7217d9Smrg            ramtype = "SDRAM";
27390b7217d9Smrg            /* pTrident->IsCyber = TRUE; VIA MVP4 integrated Desktop version */
27400b7217d9Smrg            Support24bpp = TRUE;
27410b7217d9Smrg            chipset = "CyberBlade/i7/VIA MVP4";
27420b7217d9Smrg            pTrident->NewClockCode = TRUE;
27430b7217d9Smrg            pTrident->frequency = NTSC;
27440b7217d9Smrg            break;
27450b7217d9Smrg        case CYBERBLADEI7D:
27460b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
27470b7217d9Smrg            ramtype = "SDRAM";
27480b7217d9Smrg            pTrident->IsCyber = TRUE;
27490b7217d9Smrg            Support24bpp = TRUE;
27500b7217d9Smrg            chipset = "CyberBlade/DSTN/i7";
27510b7217d9Smrg            pTrident->NewClockCode = TRUE;
27520b7217d9Smrg            pTrident->frequency = NTSC;
27530b7217d9Smrg            break;
27540b7217d9Smrg        case CYBERBLADEI1:
27550b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
27560b7217d9Smrg            ramtype = "SDRAM";
27570b7217d9Smrg            pTrident->IsCyber = TRUE;
27580b7217d9Smrg            Support24bpp = TRUE;
27590b7217d9Smrg            chipset = "CyberBlade/i1";
27600b7217d9Smrg            pTrident->NewClockCode = TRUE;
27610b7217d9Smrg            pTrident->frequency = NTSC;
27620b7217d9Smrg            break;
27630b7217d9Smrg        case CYBERBLADEI1D:
27640b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
27650b7217d9Smrg            ramtype = "SDRAM";
27660b7217d9Smrg            pTrident->IsCyber = TRUE;
27670b7217d9Smrg            Support24bpp = TRUE;
27680b7217d9Smrg            chipset = "CyberBlade/DSTN/i1";
27690b7217d9Smrg            pTrident->NewClockCode = TRUE;
27700b7217d9Smrg            pTrident->frequency = NTSC;
27710b7217d9Smrg            break;
27720b7217d9Smrg        case CYBERBLADEAI1:
27730b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
27740b7217d9Smrg            ramtype = "SDRAM";
27750b7217d9Smrg            pTrident->IsCyber = TRUE;
27760b7217d9Smrg            Support24bpp = TRUE;
27770b7217d9Smrg            chipset = "CyberBlade/Ai1";
27780b7217d9Smrg            pTrident->NewClockCode = TRUE;
27790b7217d9Smrg            pTrident->frequency = NTSC;
27800b7217d9Smrg            break;
27810b7217d9Smrg        case CYBERBLADEAI1D:
27820b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
27830b7217d9Smrg            ramtype = "SDRAM";
27840b7217d9Smrg            pTrident->IsCyber = TRUE;
27850b7217d9Smrg            Support24bpp = TRUE;
27860b7217d9Smrg            chipset = "CyberBlade/DSTN/Ai1";
27870b7217d9Smrg            pTrident->NewClockCode = TRUE;
27880b7217d9Smrg            pTrident->frequency = NTSC;
27890b7217d9Smrg            break;
27900b7217d9Smrg        case BLADEXP: /* 0x9910 */
27910b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
27920b7217d9Smrg            ramtype = "SGRAM";
27930b7217d9Smrg            pTrident->HasSGRAM = TRUE;
27940b7217d9Smrg            Support24bpp = TRUE;
27950b7217d9Smrg            pTrident->NewClockCode = TRUE;
27960b7217d9Smrg            pTrident->frequency = NTSC;
27970b7217d9Smrg            OUTB(0x3C4, 0x5D);
27980b7217d9Smrg            if (PCI_SUB_VENDOR_ID(pTrident->PciInfo) != 0x1023) {
27990b7217d9Smrg                chipset = "CyberBladeXP";
28000b7217d9Smrg                pTrident->IsCyber = TRUE;
28010b7217d9Smrg            } else
28020b7217d9Smrg                if (!(INB(0x3C5) & 0x01)) {
28030b7217d9Smrg                    chipset = "BladeXP";
28040b7217d9Smrg                } else {
28050b7217d9Smrg                    CARD8 mem1, mem2;
28060b7217d9Smrg                    OUTB(vgaIOBase + 0x04, SPR);
28070b7217d9Smrg                    mem1 = INB(vgaIOBase + 5);
28080b7217d9Smrg                    OUTB(vgaIOBase + 0x04, 0xC1);
28090b7217d9Smrg                    mem2 = INB(vgaIOBase + 5);
28100b7217d9Smrg                    if ((mem1 & 0x0e) && (mem2 == 0x11)) {
28110b7217d9Smrg                        chipset = "BladeT64";
28120b7217d9Smrg                    } else {
28130b7217d9Smrg                        chipset = "BladeT16";
28140b7217d9Smrg                    }
28150b7217d9Smrg                }
28160b7217d9Smrg            break;
28170b7217d9Smrg        case CYBERBLADEXPAI1:
28180b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
28190b7217d9Smrg            ramtype = "SGRAM";
28200b7217d9Smrg            pTrident->HasSGRAM = TRUE;
28210b7217d9Smrg            pTrident->IsCyber = TRUE;
28220b7217d9Smrg            pTrident->shadowNew = TRUE;
28230b7217d9Smrg            Support24bpp = TRUE;
28240b7217d9Smrg            chipset = "CyberBladeXPAi1";
28250b7217d9Smrg            pTrident->NewClockCode = TRUE;
28260b7217d9Smrg            pTrident->frequency = NTSC;
28270b7217d9Smrg            break;
28280b7217d9Smrg        case CYBERBLADEXP4:
28290b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
28300b7217d9Smrg            ramtype = "SGRAM";
28310b7217d9Smrg            pTrident->HasSGRAM = TRUE;
28320b7217d9Smrg            pTrident->IsCyber = TRUE;
28330b7217d9Smrg            pTrident->shadowNew = TRUE;
28340b7217d9Smrg            Support24bpp = TRUE;
28350b7217d9Smrg            chipset = "CyberBladeXP4";
28360b7217d9Smrg            pTrident->NewClockCode = TRUE;
28370b7217d9Smrg            pTrident->frequency = NTSC;
28380b7217d9Smrg            break;
28390b7217d9Smrg        case XP5:
28400b7217d9Smrg            pTrident->ddc1Read = Tridentddc1Read;
28410b7217d9Smrg            ramtype = "SGRAM";
28420b7217d9Smrg            pTrident->HasSGRAM = TRUE;
28430b7217d9Smrg            pTrident->IsCyber = TRUE;
28440b7217d9Smrg            pTrident->shadowNew = TRUE;
28450b7217d9Smrg            Support24bpp = TRUE;
28460b7217d9Smrg            chipset = "XP5";
28470b7217d9Smrg            pTrident->NewClockCode = TRUE;
28480b7217d9Smrg            pTrident->frequency = NTSC;
28490b7217d9Smrg            break;
28500b7217d9Smrg    }
285195b296d0Smrg
28520b7217d9Smrg    if (!pScrn->progClock) {
28530b7217d9Smrg        pScrn->numClocks = NoClocks;
28540b7217d9Smrg        xf86GetClocks(pScrn, NoClocks, TRIDENTClockSelect,
28550b7217d9Smrg                TRIDENTProtect, TRIDENTBlankScreen,
28560b7217d9Smrg                vgaIOBase + 0x0A, 0x08, 1, 28322);
28570b7217d9Smrg        from = X_PROBED;
28580b7217d9Smrg        xf86ShowClocks(pScrn, from);
28590b7217d9Smrg    }
286095b296d0Smrg
28610b7217d9Smrg    if (!chipset) {
28620b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No support for \"%s\"\n",
28630b7217d9Smrg                pScrn->chipset);
28640b7217d9Smrg        if (IsPciCard && UseMMIO) {
28650b7217d9Smrg            TRIDENTDisableMMIO(pScrn);
28660b7217d9Smrg            TRIDENTUnmapMem(pScrn);
28670b7217d9Smrg        }
28680b7217d9Smrg        return FALSE;
286995b296d0Smrg    }
28700b7217d9Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Found %s chip\n", chipset);
28710b7217d9Smrg    if (ramtype)
28720b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RAM type is %s\n", ramtype);
287395b296d0Smrg
28740b7217d9Smrg    if (pScrn->bitsPerPixel == 24 && !Support24bpp) {
28750b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No support for 24bpp on this chipset, use -pixmap32.\n");
28760b7217d9Smrg        if (IsPciCard && UseMMIO) {
28770b7217d9Smrg            TRIDENTDisableMMIO(pScrn);
28780b7217d9Smrg            TRIDENTUnmapMem(pScrn);
28790b7217d9Smrg        }
28800b7217d9Smrg        return FALSE;
288195b296d0Smrg    }
288295b296d0Smrg
28830b7217d9Smrg    /* HW bpp matches reported bpp */
28840b7217d9Smrg    pTrident->HwBpp = pScrn->bitsPerPixel;
288595b296d0Smrg
28860b7217d9Smrg    /* Due to bugs in the chip, turn it off */
28870b7217d9Smrg    if (pTrident->Chipset >= CYBERBLADEI7 && pTrident->Chipset <= CYBERBLADEAI1D)
28880b7217d9Smrg        pTrident->HWCursor = FALSE;
288995b296d0Smrg
28900b7217d9Smrg    from = X_PROBED;
28910b7217d9Smrg    if (pTrident->pEnt->device->videoRam != 0) {
28920b7217d9Smrg        pScrn->videoRam = pTrident->pEnt->device->videoRam;
28930b7217d9Smrg        from = X_CONFIG;
28940b7217d9Smrg    } else {
28950b7217d9Smrg        if (pTrident->Chipset == XP5) {
28960b7217d9Smrg            OUTB(vgaIOBase + 4, 0x60);
28970b7217d9Smrg            videoram = INB(vgaIOBase + 5);
28980b7217d9Smrg            switch (videoram & 0x7) {
28990b7217d9Smrg            case 0x00:
29000b7217d9Smrg                pScrn->videoRam = 65536 /* 131072 */;
29010b7217d9Smrg                break;
29020b7217d9Smrg            case 0x01:
29030b7217d9Smrg                pScrn->videoRam = 65536;
29040b7217d9Smrg                break;
29050b7217d9Smrg            case 0x02:
29060b7217d9Smrg                pScrn->videoRam = 32768;
29070b7217d9Smrg                break;
29080b7217d9Smrg            case 0x03:
29090b7217d9Smrg                pScrn->videoRam = 16384;
29100b7217d9Smrg                break;
29110b7217d9Smrg            case 0x04:
29120b7217d9Smrg                pScrn->videoRam = 8192;
29130b7217d9Smrg                break;
29140b7217d9Smrg            }
29150b7217d9Smrg        } else
29160b7217d9Smrg            if (pTrident->Chipset == CYBER9525DVD) {
29170b7217d9Smrg                pScrn->videoRam = 2560;
29180b7217d9Smrg            } else
29190b7217d9Smrg            {
29200b7217d9Smrg                OUTB(vgaIOBase + 4, SPR);
29210b7217d9Smrg                videoram = INB(vgaIOBase + 5);
29220b7217d9Smrg                if (pTrident->Chipset < TGUI9440AGi)
29230b7217d9Smrg                    videorammask = 0x07;
29240b7217d9Smrg                else
29250b7217d9Smrg                    videorammask = 0x0F;
29260b7217d9Smrg                switch (videoram & videorammask) {
29270b7217d9Smrg                case 0x01:
29280b7217d9Smrg                    pScrn->videoRam = 512;
29290b7217d9Smrg                    break;
29300b7217d9Smrg                case 0x02: /* XP */
29310b7217d9Smrg                    pScrn->videoRam = 6144;
29320b7217d9Smrg                    break;
29330b7217d9Smrg                case 0x03:
29340b7217d9Smrg                    pScrn->videoRam = 1024;
29350b7217d9Smrg                    break;
29360b7217d9Smrg                case 0x04:
29370b7217d9Smrg                    pScrn->videoRam = 8192;
29380b7217d9Smrg                    break;
29390b7217d9Smrg                case 0x06: /* XP */
29400b7217d9Smrg                    pScrn->videoRam = 10240;
29410b7217d9Smrg                    break;
29420b7217d9Smrg                case 0x07:
29430b7217d9Smrg                    pScrn->videoRam = 2048;
29440b7217d9Smrg                    break;
29450b7217d9Smrg                case 0x08: /* XP */
29460b7217d9Smrg                    pScrn->videoRam = 12288;
29470b7217d9Smrg                    break;
29480b7217d9Smrg                case 0x0A: /* XP */
29490b7217d9Smrg                    pScrn->videoRam = 14336;
29500b7217d9Smrg                    break;
29510b7217d9Smrg                case 0x0C: /* XP */
29520b7217d9Smrg                    pScrn->videoRam = 16384;
29530b7217d9Smrg                    break;
29540b7217d9Smrg                case 0x0E: /* XP */
29550b7217d9Smrg                    OUTB(vgaIOBase + 4, 0xC1);
29560b7217d9Smrg                    switch (INB(vgaIOBase + 5) & 0x11) {
29570b7217d9Smrg                    case 0x00:
29580b7217d9Smrg                        pScrn->videoRam = 20480;
29590b7217d9Smrg                        break;
29600b7217d9Smrg                    case 0x01:
29610b7217d9Smrg                        pScrn->videoRam = 24576;
29620b7217d9Smrg                        break;
29630b7217d9Smrg                    case 0x10:
29640b7217d9Smrg                        pScrn->videoRam = 28672;
29650b7217d9Smrg                        break;
29660b7217d9Smrg                    case 0x11:
29670b7217d9Smrg                        pScrn->videoRam = 32768;
29680b7217d9Smrg                        break;
29690b7217d9Smrg                    }
29700b7217d9Smrg                    break;
29710b7217d9Smrg                    case 0x0F:
29720b7217d9Smrg                        pScrn->videoRam = 4096;
29730b7217d9Smrg                        break;
29740b7217d9Smrg                    default:
29750b7217d9Smrg                        pScrn->videoRam = 1024;
29760b7217d9Smrg                        xf86DrvMsg(pScrn->scrnIndex, from,
29770b7217d9Smrg                                "Unable to determine VideoRam, defaulting to 1MB\n");
29780b7217d9Smrg                        break;
29790b7217d9Smrg                }
29800b7217d9Smrg            }
298195b296d0Smrg    }
298295b296d0Smrg
29830b7217d9Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
29840b7217d9Smrg            pTrident->HWCursor ? "HW" : "SW");
29850b7217d9Smrg
29860b7217d9Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
29870b7217d9Smrg            pScrn->videoRam);
29880b7217d9Smrg
29890b7217d9Smrg    if (pTrident->IsCyber) {
29900b7217d9Smrg        unsigned char mod, dsp, dsp1;
29910b7217d9Smrg
29920b7217d9Smrg        pTrident->lcdMode = 0xff;
29930b7217d9Smrg
29940b7217d9Smrg        OUTB(0x3CE,0x42);
29950b7217d9Smrg        dsp = INB(0x3CF);
29960b7217d9Smrg        OUTB(0x3CE,0x43);
29970b7217d9Smrg        dsp1 = INB(0x3CF);
29980b7217d9Smrg        OUTB(0x3CE,0x52);
29990b7217d9Smrg        mod = INB(0x3CF);
30000b7217d9Smrg        /*
30010b7217d9Smrg         * Only allow display size override if 1280x1024 is detected
30020b7217d9Smrg         * Currently 1400x1050 is supported - which is detected as
30030b7217d9Smrg         * 1280x1024
30040b7217d9Smrg         */
30050b7217d9Smrg        if (pTrident->displaySize) {
30060b7217d9Smrg            if (((mod >> 4) & 3) == 0) {
30070b7217d9Smrg                for (i = 0; LCD[i].mode != 0xff; i++) {
30080b7217d9Smrg                    if (pTrident->displaySize == LCD[i].display_x)
30090b7217d9Smrg                        pTrident->lcdMode = LCD[i].mode;
30100b7217d9Smrg                }
30110b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex,
30120b7217d9Smrg                        X_INFO,"%s Panel %ix%i found\n",
30130b7217d9Smrg                        (dsp & 0x80) ? "TFT" :
30140b7217d9Smrg                                ((dsp1 & 0x20) ? "DSTN" : "STN"),
30150b7217d9Smrg                                LCD[i].display_x,LCD[i].display_y);
30160b7217d9Smrg            } else {
30170b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex,X_WARNING,
30180b7217d9Smrg                        "Display size override only for 1280x1024\n");
30190b7217d9Smrg                pTrident->displaySize = 0;
30200b7217d9Smrg            }
30210b7217d9Smrg        }
30220b7217d9Smrg
30230b7217d9Smrg        if (!pTrident->displaySize) {
30240b7217d9Smrg            for (i = 0; LCD[i].mode != 0xff; i++) {
30250b7217d9Smrg                if (LCD[i].mode == ((mod >> 4) & 3)) {
30260b7217d9Smrg                    pTrident->lcdMode = i;
30270b7217d9Smrg                    xf86DrvMsg(pScrn->scrnIndex,
30280b7217d9Smrg                            X_PROBED,"%s Panel %ix%i found\n",
30290b7217d9Smrg                            (dsp & 0x80) ? "TFT" :
30300b7217d9Smrg                                    ((dsp1 & 0x20) ? "DSTN" : "STN"),
30310b7217d9Smrg                                    LCD[i].display_x,LCD[i].display_y);
30320b7217d9Smrg                }
30330b7217d9Smrg            }
30340b7217d9Smrg        }
30350b7217d9Smrg        if (pTrident->dspOverride) {
30360b7217d9Smrg            if (pTrident->dspOverride & LCD_ACTIVE)
30370b7217d9Smrg                pTrident->lcdActive = TRUE;
30380b7217d9Smrg            else
30390b7217d9Smrg                pTrident->lcdActive = FALSE;
30400b7217d9Smrg        } else {
30410b7217d9Smrg            OUTB(0x3CE, FPConfig);
30420b7217d9Smrg            pTrident->lcdActive = (INB(0x3CF) & 0x10);
30430b7217d9Smrg        }
304495b296d0Smrg    }
30450b7217d9Smrg
30460b7217d9Smrg    pTrident->MCLK = 0;
30470b7217d9Smrg    mclk = CalculateMCLK(pScrn);
30480b7217d9Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory Clock is %3.2f MHz\n", mclk);
30490b7217d9Smrg    if (xf86GetOptValFreq(pTrident->Options, OPTION_SETMCLK, OPTUNITS_MHZ,
30500b7217d9Smrg            &real)) {
30510b7217d9Smrg        pTrident->MCLK = (int)(real * 1000.0);
30520b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Setting new Memory Clock to %3.2f MHz\n",
30530b7217d9Smrg                (float)(pTrident->MCLK / 1000));
305495b296d0Smrg    }
305595b296d0Smrg
30560b7217d9Smrg    /* Set the min pixel clock */
30570b7217d9Smrg    pTrident->MinClock = 12000;	/* XXX Guess, need to check this */
30580b7217d9Smrg    xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
30590b7217d9Smrg            pTrident->MinClock / 1000);
306095b296d0Smrg
30610b7217d9Smrg    /*
30620b7217d9Smrg     * If the user has specified ramdac speed in the XF86Config
30630b7217d9Smrg     * file, we respect that setting.
30640b7217d9Smrg     */
30650b7217d9Smrg    if (pTrident->pEnt->device->dacSpeeds[0]) {
30660b7217d9Smrg        int speed = 0;
30670b7217d9Smrg
30680b7217d9Smrg        switch (pScrn->bitsPerPixel) {
30690b7217d9Smrg        case 8:
30700b7217d9Smrg            speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP8];
30710b7217d9Smrg            break;
30720b7217d9Smrg        case 16:
30730b7217d9Smrg            speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP16];
30740b7217d9Smrg            break;
30750b7217d9Smrg        case 24:
30760b7217d9Smrg            speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP24];
30770b7217d9Smrg            break;
30780b7217d9Smrg        case 32:
30790b7217d9Smrg            speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP32];
30800b7217d9Smrg            break;
30810b7217d9Smrg        }
30820b7217d9Smrg        if (speed == 0)
30830b7217d9Smrg            pTrident->MaxClock = pTrident->pEnt->device->dacSpeeds[0];
30840b7217d9Smrg        else
30850b7217d9Smrg            pTrident->MaxClock = speed;
30860b7217d9Smrg        from = X_CONFIG;
30870b7217d9Smrg    } else {
30880b7217d9Smrg        switch (pScrn->bitsPerPixel) {
30890b7217d9Smrg        case 16:
30900b7217d9Smrg            pTrident->MaxClock = ClockLimit16bpp[pTrident->Chipset];
30910b7217d9Smrg            break;
30920b7217d9Smrg        case 24:
30930b7217d9Smrg            pTrident->MaxClock = ClockLimit24bpp[pTrident->Chipset];
30940b7217d9Smrg            break;
30950b7217d9Smrg        case 32:
30960b7217d9Smrg            pTrident->MaxClock = ClockLimit32bpp[pTrident->Chipset];
30970b7217d9Smrg            break;
30980b7217d9Smrg        default:
30990b7217d9Smrg            pTrident->MaxClock = ClockLimit[pTrident->Chipset];
31000b7217d9Smrg            break;
31010b7217d9Smrg        }
31020b7217d9Smrg    }
31030b7217d9Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
31040b7217d9Smrg            pTrident->MaxClock / 1000);
310595b296d0Smrg
31060b7217d9Smrg    /*
31070b7217d9Smrg     * Setup the ClockRanges, which describe what clock ranges are available,
31080b7217d9Smrg     * and what sort of modes they can be used for.
31090b7217d9Smrg     */
31100b7217d9Smrg    clockRanges = xnfcalloc(sizeof(ClockRange), 1);
31110b7217d9Smrg    clockRanges->next = NULL;
31120b7217d9Smrg    if (!pScrn->progClock) {
31130b7217d9Smrg        if (pScrn->videoRam < 1024)
31140b7217d9Smrg            clockRanges->ClockMulFactor = 2;
31150b7217d9Smrg        if (pScrn->bitsPerPixel == 16)
31160b7217d9Smrg            clockRanges->ClockMulFactor = 2;
31170b7217d9Smrg    }
31180b7217d9Smrg    clockRanges->minClock = pTrident->MinClock;
31190b7217d9Smrg    clockRanges->maxClock = pTrident->MaxClock;
31200b7217d9Smrg    clockRanges->clockIndex = -1;		/* programmable */
31210b7217d9Smrg    clockRanges->interlaceAllowed = TRUE;
31220b7217d9Smrg    clockRanges->doubleScanAllowed = TRUE;
312395b296d0Smrg
31240b7217d9Smrg    /*
31250b7217d9Smrg     * xf86ValidateModes will check that the mode HTotal and VTotal values
31260b7217d9Smrg     * don't exceed the chipset's limit if pScrn->maxHValue and
31270b7217d9Smrg     * pScrn->maxVValue are set.  Since our TRIDENTValidMode() already takes
31280b7217d9Smrg     * care of this, we don't worry about setting them here.
31290b7217d9Smrg     */
313095b296d0Smrg
31310b7217d9Smrg    if (pScrn->bitsPerPixel == 24) {
31320b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
31330b7217d9Smrg                "Disabling Engine due to 24bpp.\n");
31340b7217d9Smrg        pTrident->NoAccel = TRUE;
313595b296d0Smrg    }
313695b296d0Smrg
31370b7217d9Smrg    /* Select valid modes from those available */
31380b7217d9Smrg    if (pTrident->NoAccel || Is3Dchip) {
31390b7217d9Smrg        /*
31400b7217d9Smrg         * XXX Assuming min pitch 256, max 4096
31410b7217d9Smrg         * XXX Assuming min height 128, max 4096
31420b7217d9Smrg         */
31430b7217d9Smrg        i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
31440b7217d9Smrg                pScrn->display->modes, clockRanges,
31450b7217d9Smrg                NULL, 256, 4096,
31460b7217d9Smrg                pScrn->bitsPerPixel, 128, 4096,
31470b7217d9Smrg                pScrn->display->virtualX,
31480b7217d9Smrg                pScrn->display->virtualY,
31490b7217d9Smrg                pTrident->FbMapSize,
31500b7217d9Smrg                LOOKUP_BEST_REFRESH);
31510b7217d9Smrg    } else {
31520b7217d9Smrg        /*
31530b7217d9Smrg         * XXX Assuming min height 128, max 2048
31540b7217d9Smrg         */
31550b7217d9Smrg        i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
31560b7217d9Smrg                pScrn->display->modes, clockRanges,
31570b7217d9Smrg                GetAccelPitchValues(pScrn), 0, 0,
31580b7217d9Smrg                pScrn->bitsPerPixel, 128, 2048,
31590b7217d9Smrg                pScrn->display->virtualX,
31600b7217d9Smrg                pScrn->display->virtualY,
31610b7217d9Smrg                pTrident->FbMapSize,
31620b7217d9Smrg                LOOKUP_BEST_REFRESH);
31630b7217d9Smrg    }
316495b296d0Smrg
31650b7217d9Smrg    if (i == -1) {
31660b7217d9Smrg        if (IsPciCard && UseMMIO) {
31670b7217d9Smrg            TRIDENTDisableMMIO(pScrn);
31680b7217d9Smrg            TRIDENTUnmapMem(pScrn);
31690b7217d9Smrg        }
31700b7217d9Smrg        TRIDENTFreeRec(pScrn);
31710b7217d9Smrg        return FALSE;
31720b7217d9Smrg    }
317395b296d0Smrg
31740b7217d9Smrg    /* Prune the modes marked as invalid */
31750b7217d9Smrg    xf86PruneDriverModes(pScrn);
317695b296d0Smrg
31770b7217d9Smrg    if (i == 0 || pScrn->modes == NULL) {
31780b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
31790b7217d9Smrg        if (IsPciCard && UseMMIO) {
31800b7217d9Smrg            TRIDENTDisableMMIO(pScrn);
31810b7217d9Smrg            TRIDENTUnmapMem(pScrn);
31820b7217d9Smrg        }
31830b7217d9Smrg        TRIDENTFreeRec(pScrn);
31840b7217d9Smrg        return FALSE;
31850b7217d9Smrg    }
318695b296d0Smrg
31870b7217d9Smrg    xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
318895b296d0Smrg
31890b7217d9Smrg    /* Set the current mode to the first in the list */
31900b7217d9Smrg    pScrn->currentMode = pScrn->modes;
319195b296d0Smrg
31920b7217d9Smrg    /* Print the list of modes being used */
31930b7217d9Smrg    xf86PrintModes(pScrn);
31940b7217d9Smrg
31950b7217d9Smrg    /* Set display resolution */
31960b7217d9Smrg    xf86SetDpi(pScrn, 0, 0);
319795b296d0Smrg
31980b7217d9Smrg    /* Load bpp-specific modules */
319995b296d0Smrg    switch (pScrn->bitsPerPixel) {
32000b7217d9Smrg    case 8:
32010b7217d9Smrg        pTrident->EngineOperation |= 0x00;
32020b7217d9Smrg        break;
32030b7217d9Smrg    case 16:
32040b7217d9Smrg        pTrident->EngineOperation |= 0x01;
32050b7217d9Smrg        break;
32060b7217d9Smrg    case 24:
32070b7217d9Smrg        pTrident->EngineOperation |= 0x03;
32080b7217d9Smrg        break;
32090b7217d9Smrg    case 32:
32100b7217d9Smrg        pTrident->EngineOperation |= 0x02;
32110b7217d9Smrg        break;
321295b296d0Smrg    }
321395b296d0Smrg
32140b7217d9Smrg    if (xf86LoadSubModule(pScrn, "fb") == NULL) {
32150b7217d9Smrg        if (IsPciCard && UseMMIO) {
32160b7217d9Smrg            TRIDENTDisableMMIO(pScrn);
32170b7217d9Smrg            TRIDENTUnmapMem(pScrn);
32180b7217d9Smrg        }
32190b7217d9Smrg        TRIDENTFreeRec(pScrn);
32200b7217d9Smrg        return FALSE;
32210b7217d9Smrg    }
322295b296d0Smrg
32230b7217d9Smrg    if (!xf86LoadSubModule(pScrn, "i2c")) {
32240b7217d9Smrg        if (IsPciCard && UseMMIO) {
32250b7217d9Smrg            TRIDENTDisableMMIO(pScrn);
32260b7217d9Smrg            TRIDENTUnmapMem(pScrn);
32270b7217d9Smrg        }
32280b7217d9Smrg        TRIDENTFreeRec(pScrn);
32290b7217d9Smrg        return FALSE;
32300b7217d9Smrg    }
323195b296d0Smrg
32320b7217d9Smrg    /* Load XAA if needed */
32330b7217d9Smrg    if (!pTrident->NoAccel) {
32340b7217d9Smrg        if (!pTrident->useEXA) {
32350b7217d9Smrg            if (!xf86LoadSubModule(pScrn, "xaa")) {
32360b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
32370b7217d9Smrg                        "Falling back to shadowfb\n");
32380b7217d9Smrg                pTrident->NoAccel = 1;
32390b7217d9Smrg                pTrident->ShadowFB = 1;
32400b7217d9Smrg            }
32410b7217d9Smrg        }
324295b296d0Smrg
32430b7217d9Smrg        if (pTrident->useEXA) {
32440b7217d9Smrg            XF86ModReqInfo req;
32450b7217d9Smrg            int errmaj, errmin;
324695b296d0Smrg
32470b7217d9Smrg            memset(&req, 0, sizeof(req));
324895b296d0Smrg
32490b7217d9Smrg            req.majorversion = 2;
32500b7217d9Smrg            if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
32510b7217d9Smrg                    &errmaj, &errmin))
32520b7217d9Smrg            {
32530b7217d9Smrg                LoaderErrorMsg(NULL, "exa", errmaj, errmin);
32540b7217d9Smrg                if (IsPciCard && UseMMIO) {
32550b7217d9Smrg                    TRIDENTDisableMMIO(pScrn);
32560b7217d9Smrg                    TRIDENTUnmapMem(pScrn);
32570b7217d9Smrg                }
32580b7217d9Smrg                TRIDENTFreeRec(pScrn);
32590b7217d9Smrg                return FALSE;
32600b7217d9Smrg            }
32610b7217d9Smrg        }
326295b296d0Smrg
32630b7217d9Smrg        switch (pScrn->displayWidth * pScrn->bitsPerPixel / 8) {
32640b7217d9Smrg        case 512:
32650b7217d9Smrg        case 8192:
32660b7217d9Smrg            pTrident->EngineOperation |= 0x00;
32670b7217d9Smrg            break;
32680b7217d9Smrg        case 1024:
32690b7217d9Smrg            pTrident->EngineOperation |= 0x04;
32700b7217d9Smrg            break;
32710b7217d9Smrg        case 2048:
32720b7217d9Smrg            pTrident->EngineOperation |= 0x08;
32730b7217d9Smrg            break;
32740b7217d9Smrg        case 4096:
32750b7217d9Smrg            pTrident->EngineOperation |= 0x0C;
32760b7217d9Smrg            break;
32770b7217d9Smrg        }
32780b7217d9Smrg    }
327995b296d0Smrg
32800b7217d9Smrg    /* Load shadow if needed */
32810b7217d9Smrg    if (pTrident->ShadowFB) {
32820b7217d9Smrg        if (!xf86LoadSubModule(pScrn, "shadow")) {
32830b7217d9Smrg            TRIDENTFreeRec(pScrn);
32840b7217d9Smrg            return FALSE;
32850b7217d9Smrg        }
32860b7217d9Smrg    }
328795b296d0Smrg
32880b7217d9Smrg    /* Load DDC if needed */
32890b7217d9Smrg    /* This gives us DDC1 - we should be able to get DDC2B using i2c */
329095b296d0Smrg
32910b7217d9Smrg    if (! ddcLoaded)
32920b7217d9Smrg        if (!xf86LoadSubModule(pScrn, "ddc")) {
32930b7217d9Smrg            if (IsPciCard && UseMMIO) {
32940b7217d9Smrg                TRIDENTDisableMMIO(pScrn);
32950b7217d9Smrg                TRIDENTUnmapMem(pScrn);
32960b7217d9Smrg            }
32970b7217d9Smrg            TRIDENTFreeRec(pScrn);
32980b7217d9Smrg            return FALSE;
32990b7217d9Smrg        }
330095b296d0Smrg
33010b7217d9Smrg    if (IsPciCard && UseMMIO) {
33020b7217d9Smrg        TRIDENTDisableMMIO(pScrn);
33030b7217d9Smrg        TRIDENTUnmapMem(pScrn);
33040b7217d9Smrg    }
330595b296d0Smrg
33060b7217d9Smrg#ifndef XSERVER_LIBPCIACCESS
33070b7217d9Smrg    pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
33080b7217d9Smrg
33090b7217d9Smrg    if (pTrident->IsCyber && pTrident->MMIOonly)
33100b7217d9Smrg        pScrn->racIoFlags = 0;
33110b7217d9Smrg    else
33120b7217d9Smrg        pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
331314330f12Smrg#endif
33140b7217d9Smrg    pTrident->FbMapSize = pScrn->videoRam * 1024;
331595b296d0Smrg
33160b7217d9Smrg    return TRUE;
331795b296d0Smrg}
331895b296d0Smrg
331995b296d0Smrg
332095b296d0Smrg/*
332195b296d0Smrg * This is called at the end of each server generation.  It restores the
332295b296d0Smrg * original (text) mode.  It should really also unmap the video memory too.
332395b296d0Smrg */
332495b296d0Smrg
332595b296d0Smrg/* Mandatory */
332695b296d0Smrgstatic Bool
3327eca46af7SmrgTRIDENTCloseScreen(CLOSE_SCREEN_ARGS_DECL)
332895b296d0Smrg{
3329eca46af7Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
333095b296d0Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
333195b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
333295b296d0Smrg
333395b296d0Smrg    if (pScrn->vtSema) {
3334eca46af7Smrg#ifdef HAVE_XAA_H
33350b7217d9Smrg        if (!pTrident->NoAccel && !pTrident->useEXA)
33360b7217d9Smrg            pTrident->AccelInfoRec->Sync(pScrn);
33370b7217d9Smrg        else
3338eca46af7Smrg#endif
33390b7217d9Smrg            if (!pTrident->NoAccel && pTrident->useEXA)
33400b7217d9Smrg                pTrident->EXADriverPtr->WaitMarker(pScreen, 0);
334114330f12Smrg
334214330f12Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
33430b7217d9Smrg        if (xf86IsPc98())
33440b7217d9Smrg            PC98TRIDENTDisable(pScrn);
334514330f12Smrg#endif
334695b296d0Smrg
33470b7217d9Smrg        TRIDENTRestore(pScrn);
33480b7217d9Smrg        vgaHWLock(hwp);
33490b7217d9Smrg        if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn);
33500b7217d9Smrg        TRIDENTUnmapMem(pScrn);
335195b296d0Smrg    }
335214330f12Smrg
3353eca46af7Smrg#ifdef HAVE_XAA_H
335495b296d0Smrg    if (pTrident->AccelInfoRec)
33550b7217d9Smrg        XAADestroyInfoRec(pTrident->AccelInfoRec);
3356eca46af7Smrg#endif
335795b296d0Smrg    if (pTrident->EXADriverPtr) {
33580b7217d9Smrg        exaDriverFini(pScreen);
33590b7217d9Smrg        free(pTrident->EXADriverPtr);
33600b7217d9Smrg        pTrident->EXADriverPtr = NULL;
33610b7217d9Smrg    }
336295b296d0Smrg    if (pTrident->CursorInfoRec)
33630b7217d9Smrg        xf86DestroyCursorInfoRec(pTrident->CursorInfoRec);
3364eca46af7Smrg    if (pTrident->ShadowPtr) {
33650b7217d9Smrg        shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen));
33660b7217d9Smrg        free(pTrident->ShadowPtr);
33670b7217d9Smrg        pScreen->CreateScreenResources = pTrident->CreateScreenResources;
3368eca46af7Smrg    }
336995b296d0Smrg    if (pTrident->DGAModes)
33700b7217d9Smrg        free(pTrident->DGAModes);
337195b296d0Smrg    pScrn->vtSema = FALSE;
337295b296d0Smrg
337395b296d0Smrg    if(pTrident->BlockHandler)
33740b7217d9Smrg        pScreen->BlockHandler = pTrident->BlockHandler;
33750b7217d9Smrg
337695b296d0Smrg    if (pTrident->pVbe)
33770b7217d9Smrg        vbeFree(pTrident->pVbe);
337895b296d0Smrg    else
33790b7217d9Smrg        xf86FreeInt10(pTrident->Int10);
338095b296d0Smrg    pScreen->CloseScreen = pTrident->CloseScreen;
3381eca46af7Smrg    return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
338295b296d0Smrg}
338395b296d0Smrg
338495b296d0Smrg/* Do screen blanking */
338595b296d0Smrg
338695b296d0Smrg/* Mandatory */
338795b296d0Smrgstatic Bool
338895b296d0SmrgTRIDENTSaveScreen(ScreenPtr pScreen, int mode)
338995b296d0Smrg{
339095b296d0Smrg    return vgaHWSaveScreen(pScreen, mode);
339195b296d0Smrg}
339295b296d0Smrg
339395b296d0Smrg
33940b7217d9Smrgstatic Bool
33950b7217d9SmrgTRIDENTCreateScreenResources(ScreenPtr pScreen)
339695b296d0Smrg{
33970b7217d9Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
339895b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
33990b7217d9Smrg    Bool ret;
340095b296d0Smrg
34010b7217d9Smrg    pScreen->CreateScreenResources = pTrident->CreateScreenResources;
34020b7217d9Smrg    ret = pScreen->CreateScreenResources(pScreen);
34030b7217d9Smrg    pTrident->CreateScreenResources = pScreen->CreateScreenResources;
34040b7217d9Smrg    pScreen->CreateScreenResources = TRIDENTCreateScreenResources;
340595b296d0Smrg
34060b7217d9Smrg    if (ret)
34070b7217d9Smrg        ret = shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen),
34080b7217d9Smrg                TRIDENTShadowUpdate, NULL, 0, 0);
340995b296d0Smrg
34100b7217d9Smrg    return ret;
341195b296d0Smrg}
341295b296d0Smrg
34130b7217d9Smrg/* Mandatory */
341495b296d0Smrg
34150b7217d9Smrg/* This gets called at the start of each server generation */
341695b296d0Smrg
34170b7217d9Smrgstatic Bool
34180b7217d9SmrgTRIDENTScreenInit(SCREEN_INIT_ARGS_DECL)
341995b296d0Smrg{
34200b7217d9Smrg    /* The vgaHW references will disappear one day */
34210b7217d9Smrg    ScrnInfoPtr pScrn;
34220b7217d9Smrg    vgaHWPtr hwp;
34230b7217d9Smrg    TRIDENTPtr pTrident;
34240b7217d9Smrg    int ret;
34250b7217d9Smrg    VisualPtr visual;
34260b7217d9Smrg    unsigned char *FBStart;
34270b7217d9Smrg    int width, height, displayWidth;
342895b296d0Smrg
34290b7217d9Smrg    /*
34300b7217d9Smrg     * First get the ScrnInfoRec
34310b7217d9Smrg     */
34320b7217d9Smrg    pScrn = xf86ScreenToScrn(pScreen);
34330b7217d9Smrg    pTrident = TRIDENTPTR(pScrn);
343495b296d0Smrg
34350b7217d9Smrg    if (IsPrimaryCard) {
34360b7217d9Smrg        if (!vgaHWMapMem(pScrn))
34370b7217d9Smrg            return FALSE;
34380b7217d9Smrg    }
343995b296d0Smrg
34400b7217d9Smrg    /* Map the TRIDENT memory and MMIO areas */
34410b7217d9Smrg    if (!TRIDENTMapMem(pScrn))
34420b7217d9Smrg        return FALSE;
344395b296d0Smrg
34440b7217d9Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
34450b7217d9Smrg    if (!xf86IsPc98())
34460b7217d9Smrg#endif
344795b296d0Smrg    {
34480b7217d9Smrg#ifdef VBE_INFO
34490b7217d9Smrg        if (pTrident->vbeModes) {
34500b7217d9Smrg            pTrident->pVbe = VBEInit(NULL,pTrident->pEnt->index);
34510b7217d9Smrg            pTrident->Int10 = pTrident->pVbe->pInt10;
34520b7217d9Smrg        } else
34530b7217d9Smrg#endif
34540b7217d9Smrg        {
34550b7217d9Smrg            if (xf86LoadSubModule(pScrn, "int10")) {
34560b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Initializing int10\n");
34570b7217d9Smrg                pTrident->Int10 = xf86InitInt10(pTrident->pEnt->index);
34580b7217d9Smrg            }
34590b7217d9Smrg        }
346095b296d0Smrg    }
346195b296d0Smrg
34620b7217d9Smrg    hwp = VGAHWPTR(pScrn);
346395b296d0Smrg
34640b7217d9Smrg    if (IsPciCard && UseMMIO) {
34650b7217d9Smrg        TRIDENTEnableMMIO(pScrn);
346695b296d0Smrg
34670b7217d9Smrg        /* Initialize the MMIO vgahw functions */
34680b7217d9Smrg        vgaHWSetMmioFuncs(hwp, pTrident->IOBase, 0);
34690b7217d9Smrg    }
34700b7217d9Smrg
34710b7217d9Smrg    /* Save the current state */
34720b7217d9Smrg    TRIDENTSave(pScrn);
34730b7217d9Smrg
34740b7217d9Smrg    /*
34750b7217d9Smrg     * Some Trident chip on PC-9821 needs setup,
34760b7217d9Smrg     * because VGA chip is not initialized by VGA BIOS.
34770b7217d9Smrg     */
34780b7217d9Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
34790b7217d9Smrg    if (IsPciCard && xf86IsPc98()) {
34800b7217d9Smrg        PC98TRIDENTInit(pScrn);
34810b7217d9Smrg    } else
348295b296d0Smrg#endif
34830b7217d9Smrg        tridentSetModeBIOS(pScrn,pScrn->currentMode);
348495b296d0Smrg
34850b7217d9Smrg    /* Initialise the first mode */
34860b7217d9Smrg    if (!TRIDENTModeInit(pScrn, pScrn->currentMode))
34870b7217d9Smrg        return FALSE;
348895b296d0Smrg
34890b7217d9Smrg    /* Darken the screen for aesthetic reasons and set the viewport */
34900b7217d9Smrg    TRIDENTSaveScreen(pScreen, SCREEN_SAVER_ON);
34910b7217d9Smrg    TRIDENTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
349295b296d0Smrg
34930b7217d9Smrg    /*
34940b7217d9Smrg     * The next step is to setup the screen's visuals, and initialise the
34950b7217d9Smrg     * framebuffer code.  In cases where the framebuffer's default
34960b7217d9Smrg     * choices for things like visual layouts and bits per RGB are OK,
34970b7217d9Smrg     * this may be as simple as calling the framebuffer's ScreenInit()
34980b7217d9Smrg     * function.  If not, the visuals will need to be setup before calling
34990b7217d9Smrg     * a fb ScreenInit() function and fixed up after.
35000b7217d9Smrg     *
35010b7217d9Smrg     * For most PC hardware at depths >= 8, the defaults that fb uses
35020b7217d9Smrg     * are not appropriate.  In this driver, we fixup the visuals after.
35030b7217d9Smrg     */
350495b296d0Smrg
35050b7217d9Smrg    /*
35060b7217d9Smrg     * Reset visual list.
35070b7217d9Smrg     */
35080b7217d9Smrg    miClearVisualTypes();
350995b296d0Smrg
35100b7217d9Smrg    /* Setup the visuals we support. */
351195b296d0Smrg
35120b7217d9Smrg    if (!miSetVisualTypes(pScrn->depth,
35130b7217d9Smrg            miGetDefaultVisualMask(pScrn->depth),
35140b7217d9Smrg            pScrn->rgbBits, pScrn->defaultVisual)) {
35150b7217d9Smrg        if (pTrident->pVbe)
35160b7217d9Smrg            vbeFree(pTrident->pVbe);
35170b7217d9Smrg        else
35180b7217d9Smrg            xf86FreeInt10(pTrident->Int10);
35190b7217d9Smrg        return FALSE;
35200b7217d9Smrg    }
352195b296d0Smrg
35220b7217d9Smrg    miSetPixmapDepths ();
352395b296d0Smrg
35240b7217d9Smrg    /* FIXME - we don't do shadowfb for < 4 */
35250b7217d9Smrg    displayWidth = pScrn->displayWidth;
35260b7217d9Smrg    if (pTrident->Rotate) {
35270b7217d9Smrg        height = pScrn->virtualX;
35280b7217d9Smrg        width = pScrn->virtualY;
35290b7217d9Smrg    } else {
35300b7217d9Smrg        width = pScrn->virtualX;
35310b7217d9Smrg        height = pScrn->virtualY;
35320b7217d9Smrg    }
353395b296d0Smrg
35340b7217d9Smrg    if(pTrident->ShadowFB) {
35350b7217d9Smrg        pTrident->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
35360b7217d9Smrg        pTrident->ShadowPtr = malloc(pTrident->ShadowPitch * height);
35370b7217d9Smrg        displayWidth = pTrident->ShadowPitch / (pScrn->bitsPerPixel >> 3);
35380b7217d9Smrg        FBStart = pTrident->ShadowPtr;
35390b7217d9Smrg    } else {
35400b7217d9Smrg        pTrident->ShadowFB = FALSE;
35410b7217d9Smrg        pTrident->ShadowPtr = NULL;
35420b7217d9Smrg        FBStart = pTrident->FbBase;
35430b7217d9Smrg    }
354495b296d0Smrg
35450b7217d9Smrg    /*
35460b7217d9Smrg     * Call the framebuffer layer's ScreenInit function, and fill in other
35470b7217d9Smrg     * pScreen fields.
35480b7217d9Smrg     */
354995b296d0Smrg
35500b7217d9Smrg    switch (pScrn->bitsPerPixel) {
35510b7217d9Smrg    case 8:
35520b7217d9Smrg    case 16:
35530b7217d9Smrg    case 24:
35540b7217d9Smrg    case 32:
35550b7217d9Smrg        ret = fbScreenInit(pScreen, FBStart, width,
35560b7217d9Smrg                height, pScrn->xDpi, pScrn->yDpi,
35570b7217d9Smrg                displayWidth, pScrn->bitsPerPixel);
355895b296d0Smrg
35590b7217d9Smrg        break;
35600b7217d9Smrg    default:
35610b7217d9Smrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
35620b7217d9Smrg                "Internal error: invalid bpp (%d) in TRIDENTScrnInit\n",
35630b7217d9Smrg                pScrn->bitsPerPixel);
35640b7217d9Smrg        ret = FALSE;
35650b7217d9Smrg        break;
35660b7217d9Smrg    }
35670b7217d9Smrg    if (!ret) {
35680b7217d9Smrg        if (pTrident->pVbe)
35690b7217d9Smrg            vbeFree(pTrident->pVbe);
35700b7217d9Smrg        else
35710b7217d9Smrg            xf86FreeInt10(pTrident->Int10);
35720b7217d9Smrg        return FALSE;
35730b7217d9Smrg    }
35740b7217d9Smrg    if (pScrn->bitsPerPixel > 8) {
35750b7217d9Smrg        /* Fixup RGB ordering */
35760b7217d9Smrg        visual = pScreen->visuals + pScreen->numVisuals;
35770b7217d9Smrg        while (--visual >= pScreen->visuals) {
35780b7217d9Smrg            if ((visual->class | DynamicClass) == DirectColor) {
35790b7217d9Smrg                visual->offsetRed = pScrn->offset.red;
35800b7217d9Smrg                visual->offsetGreen = pScrn->offset.green;
35810b7217d9Smrg                visual->offsetBlue = pScrn->offset.blue;
35820b7217d9Smrg                visual->redMask = pScrn->mask.red;
35830b7217d9Smrg                visual->greenMask = pScrn->mask.green;
35840b7217d9Smrg                visual->blueMask = pScrn->mask.blue;
35850b7217d9Smrg            }
35860b7217d9Smrg        }
35870b7217d9Smrg    }
358895b296d0Smrg
35890b7217d9Smrg    /* must be after RGB ordering fixed */
35900b7217d9Smrg    fbPictureInit (pScreen, 0, 0);
359195b296d0Smrg
35920b7217d9Smrg    xf86SetBlackWhitePixels(pScreen);
359395b296d0Smrg
35940b7217d9Smrg    pTrident->BlockHandler = pScreen->BlockHandler;
35950b7217d9Smrg    pScreen->BlockHandler = TRIDENTBlockHandler;
359695b296d0Smrg
35970b7217d9Smrg    if (!pTrident->ShadowFB)
35980b7217d9Smrg        TRIDENTDGAInit(pScreen);
359995b296d0Smrg
36000b7217d9Smrg#ifdef HAVE_ISA
36010b7217d9Smrg    if (!LINEAR()) {
36020b7217d9Smrg        miBankInfoPtr pBankInfo;
36030b7217d9Smrg
36040b7217d9Smrg        /* Setup the vga banking variables */
36050b7217d9Smrg        pBankInfo = xnfcalloc(sizeof(miBankInfoRec),1);
36060b7217d9Smrg        if (pBankInfo == NULL) {
36070b7217d9Smrg            if (pTrident->pVbe)
36080b7217d9Smrg                vbeFree(pTrident->pVbe);
36090b7217d9Smrg            else
36100b7217d9Smrg                xf86FreeInt10(pTrident->Int10);
36110b7217d9Smrg            return FALSE;
36120b7217d9Smrg        }
36130b7217d9Smrg        pBankInfo->pBankA = pTrident->FbBase;
36140b7217d9Smrg        pBankInfo->pBankB = pTrident->FbBase;
36150b7217d9Smrg        pBankInfo->BankSize = 0x10000;
36160b7217d9Smrg        pBankInfo->nBankDepth = (pScrn->depth == 4) ? 1 : pScrn->depth;
36170b7217d9Smrg
36180b7217d9Smrg        pBankInfo->SetSourceBank =
36190b7217d9Smrg                (miBankProcPtr)TVGA8900SetRead;
36200b7217d9Smrg        pBankInfo->SetDestinationBank =
36210b7217d9Smrg                (miBankProcPtr)TVGA8900SetWrite;
36220b7217d9Smrg        pBankInfo->SetSourceAndDestinationBanks =
36230b7217d9Smrg                (miBankProcPtr)TVGA8900SetReadWrite;
36240b7217d9Smrg        if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
36250b7217d9Smrg                pScrn->displayWidth, pBankInfo)) {
36260b7217d9Smrg            free(pBankInfo);
36270b7217d9Smrg            pBankInfo = NULL;
36280b7217d9Smrg            if (pTrident->pVbe)
36290b7217d9Smrg                vbeFree(pTrident->pVbe);
36300b7217d9Smrg            else
36310b7217d9Smrg                xf86FreeInt10(pTrident->Int10);
36320b7217d9Smrg            return FALSE;
36330b7217d9Smrg        }
36340b7217d9Smrg    }
36350b7217d9Smrg#endif
363695b296d0Smrg
36370b7217d9Smrg    {
36380b7217d9Smrg        BoxRec AvailFBArea;
363995b296d0Smrg
36400b7217d9Smrg        AvailFBArea.x1 = 0;
36410b7217d9Smrg        AvailFBArea.y1 = 0;
36420b7217d9Smrg        AvailFBArea.x2 = pScrn->displayWidth;
36430b7217d9Smrg        AvailFBArea.y2 = pTrident->FbMapSize / (pScrn->displayWidth *
36440b7217d9Smrg                pScrn->bitsPerPixel / 8);
364595b296d0Smrg
36460b7217d9Smrg        if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047;
364795b296d0Smrg
36480b7217d9Smrg        if (xf86InitFBManager(pScreen, &AvailFBArea)) {
36490b7217d9Smrg            int cpp = pScrn->bitsPerPixel / 8;
36500b7217d9Smrg            int area = AvailFBArea.y2 * pScrn->displayWidth;
36510b7217d9Smrg            int areaoffset = area * cpp;
365295b296d0Smrg
36530b7217d9Smrg            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
36540b7217d9Smrg                    "Using %i scanlines of offscreen memory for area's \n",
36550b7217d9Smrg                    AvailFBArea.y2 - pScrn->virtualY);
365695b296d0Smrg
36570b7217d9Smrg            if (xf86InitFBManagerLinear(pScreen, area, ((pTrident->FbMapSize/cpp) - area))) {
36580b7217d9Smrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
36590b7217d9Smrg                        "Using %ld bytes of offscreen memory for linear (offset=0x%x)\n", (pTrident->FbMapSize - areaoffset), areaoffset);
36600b7217d9Smrg            }
36610b7217d9Smrg        }
36620b7217d9Smrg    }
366395b296d0Smrg
36640b7217d9Smrg    if (Is3Dchip) {
36650b7217d9Smrg        if ((pTrident->Chipset == CYBERBLADEI7) ||
36660b7217d9Smrg                (pTrident->Chipset == CYBERBLADEI7D) ||
36670b7217d9Smrg                (pTrident->Chipset == CYBERBLADEI1) ||
36680b7217d9Smrg                (pTrident->Chipset == CYBERBLADEI1D) ||
36690b7217d9Smrg                (pTrident->Chipset == CYBERBLADEAI1) ||
36700b7217d9Smrg                (pTrident->Chipset == CYBERBLADEAI1D) ||
36710b7217d9Smrg                (pTrident->Chipset == CYBERBLADEE4) ||
36720b7217d9Smrg                (pTrident->Chipset == BLADE3D)) {
36730b7217d9Smrg            if (pTrident->useEXA)
36740b7217d9Smrg                BladeExaInit(pScreen);
36750b7217d9Smrg            else
36760b7217d9Smrg                BladeXaaInit(pScreen);
36770b7217d9Smrg        } else
36780b7217d9Smrg            if ((pTrident->Chipset == CYBERBLADEXP4) ||
36790b7217d9Smrg                    (pTrident->Chipset == XP5)) {
36800b7217d9Smrg                if (pTrident->useEXA)
36810b7217d9Smrg                    XP4ExaInit(pScreen);
36820b7217d9Smrg                else
36830b7217d9Smrg                    XP4XaaInit(pScreen);
36840b7217d9Smrg            } else
36850b7217d9Smrg                if ((pTrident->Chipset == BLADEXP) ||
36860b7217d9Smrg                        (pTrident->Chipset == CYBERBLADEXPAI1)) {
36870b7217d9Smrg                    XPAccelInit(pScreen);
36880b7217d9Smrg                } else {
36890b7217d9Smrg                    ImageAccelInit(pScreen);
36900b7217d9Smrg                }
36910b7217d9Smrg    } else {
36920b7217d9Smrg        TridentAccelInit(pScreen);
36930b7217d9Smrg    }
369495b296d0Smrg
36950b7217d9Smrg    xf86SetBackingStore(pScreen);
369695b296d0Smrg
36970b7217d9Smrg    /* Initialise cursor functions */
36980b7217d9Smrg    miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
369995b296d0Smrg
37000b7217d9Smrg    if (pTrident->HWCursor) {
37010b7217d9Smrg        xf86SetSilkenMouse(pScreen);
37020b7217d9Smrg        TridentHWCursorInit(pScreen);
37030b7217d9Smrg    }
370495b296d0Smrg
37050b7217d9Smrg    /* Initialise default colourmap */
37060b7217d9Smrg    if (!miCreateDefColormap(pScreen)) {
37070b7217d9Smrg        if (pTrident->pVbe)
37080b7217d9Smrg            vbeFree(pTrident->pVbe);
37090b7217d9Smrg        else
37100b7217d9Smrg            xf86FreeInt10(pTrident->Int10);
37110b7217d9Smrg        return FALSE;
37120b7217d9Smrg    }
37130b7217d9Smrg    if(!xf86HandleColormaps(pScreen, 256, 6, TridentLoadPalette,
37140b7217d9Smrg            TridentSetOverscan, CMAP_RELOAD_ON_MODE_SWITCH|CMAP_PALETTED_TRUECOLOR)) {
37150b7217d9Smrg        if (pTrident->pVbe)
37160b7217d9Smrg            vbeFree(pTrident->pVbe);
37170b7217d9Smrg        else
37180b7217d9Smrg            xf86FreeInt10(pTrident->Int10);
37190b7217d9Smrg        return FALSE;
37200b7217d9Smrg    }
37210b7217d9Smrg    if(pTrident->ShadowFB) {
37220b7217d9Smrg        if(pTrident->Rotate) {
37230b7217d9Smrg            if (!pTrident->PointerMoved) {
37240b7217d9Smrg                pTrident->PointerMoved = pScrn->PointerMoved;
37250b7217d9Smrg                pScrn->PointerMoved = TRIDENTPointerMoved;
37260b7217d9Smrg            }
37270b7217d9Smrg            switch (pScrn->bitsPerPixel) {
37280b7217d9Smrg            case 8:    pTrident->RefreshArea = TRIDENTRefreshArea8; break;
37290b7217d9Smrg            case 16:   pTrident->RefreshArea = TRIDENTRefreshArea16; break;
37300b7217d9Smrg            case 24:   pTrident->RefreshArea = TRIDENTRefreshArea24; break;
37310b7217d9Smrg            case 32:   pTrident->RefreshArea = TRIDENTRefreshArea32; break;
37320b7217d9Smrg            }
37330b7217d9Smrg        } else {
37340b7217d9Smrg            pTrident->RefreshArea = TRIDENTRefreshArea;
37350b7217d9Smrg        }
37360b7217d9Smrg        if (!shadowSetup(pScreen))
37370b7217d9Smrg            return FALSE;
37380b7217d9Smrg        pTrident->CreateScreenResources = pScreen->CreateScreenResources;
37390b7217d9Smrg        pScreen->CreateScreenResources = TRIDENTCreateScreenResources;
37400b7217d9Smrg    }
374195b296d0Smrg
37420b7217d9Smrg    xf86DPMSInit(pScreen, (DPMSSetProcPtr)TRIDENTDisplayPowerManagementSet, 0);
374395b296d0Smrg
37440b7217d9Smrg    pScrn->memPhysBase = pTrident->FbAddress;
37450b7217d9Smrg    pScrn->fbOffset = 0;
374695b296d0Smrg
37470b7217d9Smrg    if (pTrident->Chipset >= TGUI9660)
37480b7217d9Smrg        TRIDENTInitVideo(pScreen);
374995b296d0Smrg
37500b7217d9Smrg    pTrident->CloseScreen = pScreen->CloseScreen;
37510b7217d9Smrg    pScreen->CloseScreen = TRIDENTCloseScreen;
37520b7217d9Smrg    pScreen->SaveScreen = TRIDENTSaveScreen;
375395b296d0Smrg
37540b7217d9Smrg    /* Report any unused options (only for the first generation) */
37550b7217d9Smrg    if (serverGeneration == 1) {
37560b7217d9Smrg        xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
375795b296d0Smrg    }
37580b7217d9Smrg
37590b7217d9Smrg#if 0
37600b7217d9Smrg    TRIDENTI2CInit(pScreen);
37610b7217d9Smrg
37620b7217d9Smrg    xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,pTrident->DDC));
37630b7217d9Smrg#endif
37640b7217d9Smrg
37650b7217d9Smrg    return TRUE;
376695b296d0Smrg}
376795b296d0Smrg
3768