trident_driver.c revision ff89ac2b
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
2395b296d0Smrg *	    Re-written for XFree86 v4.0
2495b296d0Smrg *
2595b296d0Smrg * Previous driver (pre-XFree86 v4.0) by
2695b296d0Smrg * 	    Alan Hourihane, alanh@fairlite.demon.co.uk
2795b296d0Smrg *	    David Wexelblat (major contributor)
2895b296d0Smrg *	    Massimiliano Ghilardi, max@Linuz.sns.it, some fixes to the
2995b296d0Smrg *				   clockchip programming code.
3095b296d0Smrg */
3195b296d0Smrg
3295b296d0Smrg#ifdef HAVE_CONFIG_H
3395b296d0Smrg#include "config.h"
3495b296d0Smrg#endif
3595b296d0Smrg
3695b296d0Smrg#include "fb.h"
3795b296d0Smrg
3895b296d0Smrg#include "mibank.h"
3995b296d0Smrg#include "micmap.h"
4095b296d0Smrg#include "xf86.h"
4195b296d0Smrg#include "xf86_OSproc.h"
4295b296d0Smrg#include "xf86Resources.h"
4395b296d0Smrg#include "xf86PciInfo.h"
4495b296d0Smrg#include "xf86Pci.h"
4595b296d0Smrg#include "xf86cmap.h"
4695b296d0Smrg#include "vgaHW.h"
4795b296d0Smrg#include "xf86RAC.h"
4895b296d0Smrg#include "vbe.h"
4995b296d0Smrg#include "dixstruct.h"
5095b296d0Smrg#include "compiler.h"
5195b296d0Smrg
5295b296d0Smrg#include "mipointer.h"
5395b296d0Smrg
5495b296d0Smrg#include "mibstore.h"
5595b296d0Smrg#include "shadow.h"
5695b296d0Smrg#include "trident.h"
5795b296d0Smrg#include "trident_regs.h"
5895b296d0Smrg
5995b296d0Smrg#ifdef XFreeXDGA
6095b296d0Smrg#define _XF86DGA_SERVER_
6195b296d0Smrg#include <X11/extensions/xf86dgastr.h>
6295b296d0Smrg#endif
6395b296d0Smrg
6495b296d0Smrg#include "globals.h"
6595b296d0Smrg#define DPMS_SERVER
6695b296d0Smrg#include <X11/extensions/dpms.h>
6795b296d0Smrg
6895b296d0Smrg#include "xf86xv.h"
6995b296d0Smrg
7095b296d0Smrgstatic const OptionInfoRec * TRIDENTAvailableOptions(int chipid, int busid);
7195b296d0Smrgstatic void	TRIDENTIdentify(int flags);
7295b296d0Smrgstatic Bool	TRIDENTProbe(DriverPtr drv, int flags);
7395b296d0Smrgstatic Bool	TRIDENTPreInit(ScrnInfoPtr pScrn, int flags);
7495b296d0Smrgstatic Bool	TRIDENTScreenInit(int Index, ScreenPtr pScreen, int argc,
7595b296d0Smrg			      char **argv);
7695b296d0Smrgstatic Bool	TRIDENTEnterVT(int scrnIndex, int flags);
7795b296d0Smrgstatic void	TRIDENTLeaveVT(int scrnIndex, int flags);
7895b296d0Smrgstatic Bool	TRIDENTCloseScreen(int scrnIndex, ScreenPtr pScreen);
7995b296d0Smrgstatic Bool	TRIDENTSaveScreen(ScreenPtr pScreen, int mode);
8095b296d0Smrg
8195b296d0Smrg/* Optional functions */
8295b296d0Smrgstatic void	TRIDENTFreeScreen(int scrnIndex, int flags);
8395b296d0Smrgstatic ModeStatus TRIDENTValidMode(int scrnIndex, DisplayModePtr mode,
8495b296d0Smrg				   Bool verbose, int flags);
8595b296d0Smrg
8695b296d0Smrg/* Internally used functions */
8795b296d0Smrgstatic Bool	TRIDENTMapMem(ScrnInfoPtr pScrn);
8895b296d0Smrgstatic Bool	TRIDENTUnmapMem(ScrnInfoPtr pScrn);
8995b296d0Smrgstatic void	TRIDENTSave(ScrnInfoPtr pScrn);
9095b296d0Smrgstatic void	TRIDENTRestore(ScrnInfoPtr pScrn);
9195b296d0Smrgstatic Bool	TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
9295b296d0Smrgstatic void 	TRIDENTBlockHandler(int, pointer, pointer, pointer);
9395b296d0Smrg
9495b296d0Smrgstatic void	TRIDENTEnableMMIO(ScrnInfoPtr pScrn);
9595b296d0Smrgstatic void	TRIDENTDisableMMIO(ScrnInfoPtr pScrn);
9695b296d0Smrgstatic void	PC98TRIDENTInit(ScrnInfoPtr pScrn);
9795b296d0Smrgstatic void	PC98TRIDENTEnable(ScrnInfoPtr pScrn);
9895b296d0Smrgstatic void	PC98TRIDENTDisable(ScrnInfoPtr pScrn);
9995b296d0Smrgstatic void	PC98TRIDENT96xxInit(ScrnInfoPtr pScrn);
10095b296d0Smrgstatic void	PC98TRIDENT96xxEnable(ScrnInfoPtr pScrn);
10195b296d0Smrgstatic void	PC98TRIDENT96xxDisable(ScrnInfoPtr pScrn);
10295b296d0Smrgstatic void	PC98TRIDENT9385Init(ScrnInfoPtr pScrn);
10395b296d0Smrgstatic void	PC98TRIDENT9385Enable(ScrnInfoPtr pScrn);
10495b296d0Smrgstatic void	PC98TRIDENT9385Disable(ScrnInfoPtr pScrn);
10595b296d0Smrgstatic int      TRIDENTLcdDisplaySize (xf86MonPtr pMon);
10695b296d0Smrg
10795b296d0Smrg/*
10895b296d0Smrg * This is intentionally screen-independent.  It indicates the binding
10995b296d0Smrg * choice made in the first PreInit.
11095b296d0Smrg */
11195b296d0Smrgstatic int pix24bpp = 0;
11295b296d0Smrg
11395b296d0Smrg#define TRIDENT_VERSION 4000
11495b296d0Smrg#define TRIDENT_NAME "TRIDENT"
11595b296d0Smrg#define TRIDENT_DRIVER_NAME "trident"
116ff89ac2bSmrg#define TRIDENT_MAJOR_VERSION PACKAGE_VERSION_MAJOR
117ff89ac2bSmrg#define TRIDENT_MINOR_VERSION PACKAGE_VERSION_MINOR
118ff89ac2bSmrg#define TRIDENT_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL
11995b296d0Smrg
12095b296d0Smrg/*
12195b296d0Smrg * This contains the functions needed by the server after loading the driver
12295b296d0Smrg * module.  It must be supplied, and gets passed back by the SetupProc
12395b296d0Smrg * function in the dynamic case.  In the static case, a reference to this
12495b296d0Smrg * is compiled in, and this requires that the name of this DriverRec be
12595b296d0Smrg * an upper-case version of the driver name.
12695b296d0Smrg */
12795b296d0Smrg
12895b296d0Smrg_X_EXPORT DriverRec TRIDENT = {
12995b296d0Smrg    TRIDENT_VERSION,
13095b296d0Smrg    TRIDENT_DRIVER_NAME,
13195b296d0Smrg    TRIDENTIdentify,
13295b296d0Smrg    TRIDENTProbe,
13395b296d0Smrg    TRIDENTAvailableOptions,
13495b296d0Smrg    NULL,
13595b296d0Smrg    0
13695b296d0Smrg};
13795b296d0Smrg
13895b296d0Smrgstatic SymTabRec TRIDENTChipsets[] = {
13995b296d0Smrg    { TVGA9000,			"tvga9000" },
14095b296d0Smrg    { TVGA9000i,		"tvga9000i" },
14195b296d0Smrg    { TVGA8900C,		"tvga8900c" },
14295b296d0Smrg    { TVGA8900D,		"tvga8900d" },
14395b296d0Smrg    { TVGA9200CXr,		"tvga9200cxr" },
14495b296d0Smrg    { TGUI9400CXi,		"tgui9400cxi" },
14595b296d0Smrg    { CYBER9320,		"cyber9320" },
14695b296d0Smrg    { CYBER9388,		"cyber9388" },
14795b296d0Smrg    { CYBER9397,		"cyber9397" },
14895b296d0Smrg    { CYBER9397DVD,		"cyber9397dvd" },
14995b296d0Smrg    { CYBER9520,		"cyber9520" },
15095b296d0Smrg    { CYBER9525DVD,		"cyber9525dvd" },
15195b296d0Smrg    { CYBERBLADEE4,		"cyberblade/e4" },
15295b296d0Smrg    { TGUI9420DGi,		"tgui9420dgi" },
15395b296d0Smrg    { TGUI9440AGi,		"tgui9440agi" },
15495b296d0Smrg    { TGUI9660,			"tgui9660" },
15595b296d0Smrg    { TGUI9680,			"tgui9680" },
15695b296d0Smrg    { PROVIDIA9682,		"providia9682" },
15795b296d0Smrg    { PROVIDIA9685,		"providia9685" },
15895b296d0Smrg    { CYBER9382,		"cyber9382" },
15995b296d0Smrg    { CYBER9385,		"cyber9385" },
16095b296d0Smrg    { IMAGE975,			"3dimage975" },
16195b296d0Smrg    { IMAGE985,			"3dimage985" },
16295b296d0Smrg    { BLADE3D,			"blade3d" },
16395b296d0Smrg    { CYBERBLADEI7,		"cyberbladei7" },
16495b296d0Smrg    { CYBERBLADEI7D,		"cyberbladei7d" },
16595b296d0Smrg    { CYBERBLADEI1,		"cyberbladei1" },
16695b296d0Smrg    { CYBERBLADEI1D,		"cyberbladei1d" },
16795b296d0Smrg    { CYBERBLADEAI1,		"cyberbladeAi1" },
16895b296d0Smrg    { CYBERBLADEAI1D,		"cyberbladeAi1d" },
16995b296d0Smrg    { BLADEXP,			"bladeXP" },
17095b296d0Smrg    { CYBERBLADEXPAI1,		"cyberbladeXPAi1" },
17195b296d0Smrg    { CYBERBLADEXP4,		"cyberbladeXP4" },
17295b296d0Smrg    { XP5,			"XP5" },
17395b296d0Smrg    { -1,				NULL }
17495b296d0Smrg};
17595b296d0Smrg
176ff89ac2bSmrg#ifdef HAVE_ISA
17795b296d0Smrgstatic IsaChipsets TRIDENTISAchipsets[] = {
17895b296d0Smrg    { TVGA9000,			RES_EXCLUSIVE_VGA },
17995b296d0Smrg    { TVGA9000i,		RES_EXCLUSIVE_VGA },
18095b296d0Smrg    { TVGA8900C,		RES_EXCLUSIVE_VGA },
18195b296d0Smrg    { TVGA8900D,		RES_EXCLUSIVE_VGA },
18295b296d0Smrg    { TVGA9200CXr,		RES_EXCLUSIVE_VGA },
18395b296d0Smrg    { TGUI9400CXi,		RES_EXCLUSIVE_VGA },
18495b296d0Smrg    { CYBER9320,		RES_EXCLUSIVE_VGA },
18595b296d0Smrg    { TGUI9440AGi,		RES_EXCLUSIVE_VGA },
18695b296d0Smrg    { -1,			RES_UNDEFINED }
18795b296d0Smrg};
188ff89ac2bSmrg#endif
18995b296d0Smrg
19095b296d0Smrgstatic PciChipsets TRIDENTPciChipsets[] = {
19195b296d0Smrg    { CYBER9320,	PCI_CHIP_9320,	RES_SHARED_VGA },
19295b296d0Smrg    { CYBER9388,	PCI_CHIP_9388,	RES_SHARED_VGA },
19395b296d0Smrg    { CYBER9397,	PCI_CHIP_9397,	RES_SHARED_VGA },
19495b296d0Smrg    { CYBER9397DVD,	PCI_CHIP_939A,	RES_SHARED_VGA },
19595b296d0Smrg    { CYBER9520,	PCI_CHIP_9520,	RES_SHARED_VGA },
19695b296d0Smrg    { CYBER9525DVD,	PCI_CHIP_9525,	RES_SHARED_VGA },
19795b296d0Smrg    { CYBERBLADEE4,	PCI_CHIP_9540,	RES_SHARED_VGA },
19895b296d0Smrg    { TGUI9420DGi,	PCI_CHIP_9420,	RES_SHARED_VGA },
19995b296d0Smrg    { TGUI9440AGi,	PCI_CHIP_9440,	RES_SHARED_VGA },
20095b296d0Smrg    { TGUI9660,		PCI_CHIP_9660,	RES_SHARED_VGA },
20195b296d0Smrg    { TGUI9680,		PCI_CHIP_9660,	RES_SHARED_VGA },
20295b296d0Smrg    { PROVIDIA9682,	PCI_CHIP_9660,	RES_SHARED_VGA },
20395b296d0Smrg    { PROVIDIA9685,	PCI_CHIP_9660,	RES_SHARED_VGA },
20495b296d0Smrg    { CYBER9382,	PCI_CHIP_9660,	RES_SHARED_VGA },
20595b296d0Smrg    { CYBER9385,	PCI_CHIP_9660,	RES_SHARED_VGA },
20695b296d0Smrg    { IMAGE975,		PCI_CHIP_9750,	RES_SHARED_VGA },
20795b296d0Smrg    { IMAGE985,		PCI_CHIP_9850,	RES_SHARED_VGA },
20895b296d0Smrg    { BLADE3D,		PCI_CHIP_9880,	RES_SHARED_VGA },
20995b296d0Smrg    { CYBERBLADEI7,	PCI_CHIP_8400,	RES_SHARED_VGA },
21095b296d0Smrg    { CYBERBLADEI7D,	PCI_CHIP_8420,	RES_SHARED_VGA },
21195b296d0Smrg    { CYBERBLADEI1,	PCI_CHIP_8500,	RES_SHARED_VGA },
21295b296d0Smrg    { CYBERBLADEI1D,	PCI_CHIP_8520,	RES_SHARED_VGA },
21395b296d0Smrg    { CYBERBLADEAI1,	PCI_CHIP_8600,	RES_SHARED_VGA },
21495b296d0Smrg    { CYBERBLADEAI1D,	PCI_CHIP_8620,	RES_SHARED_VGA },
21595b296d0Smrg    { BLADEXP,		PCI_CHIP_9910,	RES_SHARED_VGA },
21695b296d0Smrg    { CYBERBLADEXPAI1,	PCI_CHIP_8820,	RES_SHARED_VGA },
21795b296d0Smrg    { CYBERBLADEXP4,	PCI_CHIP_2100,	RES_SHARED_VGA },
21895b296d0Smrg    { XP5,		PCI_CHIP_2200,	RES_SHARED_VGA },
21995b296d0Smrg    { -1,		-1,		RES_UNDEFINED }
22095b296d0Smrg};
22195b296d0Smrg
22295b296d0Smrgtypedef enum {
22395b296d0Smrg    OPTION_ACCELMETHOD,
22495b296d0Smrg    OPTION_SW_CURSOR,
22595b296d0Smrg    OPTION_PCI_RETRY,
22695b296d0Smrg    OPTION_RGB_BITS,
22795b296d0Smrg    OPTION_NOACCEL,
22895b296d0Smrg    OPTION_SETMCLK,
22995b296d0Smrg    OPTION_MUX_THRESHOLD,
23095b296d0Smrg    OPTION_SHADOW_FB,
23195b296d0Smrg    OPTION_ROTATE,
23295b296d0Smrg    OPTION_MMIO_ONLY,
23395b296d0Smrg    OPTION_VIDEO_KEY,
23495b296d0Smrg    OPTION_NOMMIO,
23595b296d0Smrg    OPTION_NOPCIBURST,
23695b296d0Smrg    OPTION_CYBER_SHADOW,
23795b296d0Smrg    OPTION_CYBER_STRETCH,
23895b296d0Smrg    OPTION_XV_HSYNC,
23995b296d0Smrg    OPTION_XV_VSYNC,
24095b296d0Smrg    OPTION_XV_BSKEW,
24195b296d0Smrg    OPTION_XV_RSKEW,
24295b296d0Smrg    OPTION_FP_DELAY,
24395b296d0Smrg    OPTION_1400_DISPLAY,
24495b296d0Smrg    OPTION_DISPLAY,
24595b296d0Smrg    OPTION_GB,
24695b296d0Smrg    OPTION_TV_CHIPSET,
24795b296d0Smrg    OPTION_TV_SIGNALMODE
24895b296d0Smrg} TRIDENTOpts;
24995b296d0Smrg
25095b296d0Smrgstatic const OptionInfoRec TRIDENTOptions[] = {
25195b296d0Smrg    { OPTION_ACCELMETHOD,	"AccelMethod",	OPTV_ANYSTR,	{0}, FALSE },
25295b296d0Smrg    { OPTION_SW_CURSOR,		"SWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
25395b296d0Smrg    { OPTION_PCI_RETRY,		"PciRetry",	OPTV_BOOLEAN,	{0}, FALSE },
25495b296d0Smrg    { OPTION_NOACCEL,		"NoAccel",	OPTV_BOOLEAN,	{0}, FALSE },
25595b296d0Smrg    { OPTION_SETMCLK,		"SetMClk",	OPTV_FREQ,	{0}, FALSE },
25695b296d0Smrg    { OPTION_MUX_THRESHOLD,	"MUXThreshold",	OPTV_INTEGER,	{0}, FALSE },
25795b296d0Smrg    { OPTION_SHADOW_FB,		"ShadowFB",	OPTV_BOOLEAN,	{0}, FALSE },
25895b296d0Smrg    { OPTION_ROTATE,  	        "Rotate",	OPTV_ANYSTR,	{0}, FALSE },
25995b296d0Smrg    { OPTION_VIDEO_KEY,		"VideoKey",	OPTV_INTEGER,	{0}, FALSE },
26095b296d0Smrg    { OPTION_NOMMIO,		"NoMMIO",	OPTV_BOOLEAN,	{0}, FALSE },
26195b296d0Smrg    { OPTION_NOPCIBURST,	"NoPciBurst",	OPTV_BOOLEAN,	{0}, FALSE },
26295b296d0Smrg    { OPTION_MMIO_ONLY,		"MMIOonly",	OPTV_BOOLEAN,	{0}, FALSE },
26395b296d0Smrg    { OPTION_CYBER_SHADOW,	"CyberShadow",	OPTV_BOOLEAN,	{0}, FALSE },
26495b296d0Smrg    { OPTION_CYBER_STRETCH,	"CyberStretch",	OPTV_BOOLEAN,	{0}, FALSE },
26595b296d0Smrg    { OPTION_XV_HSYNC,          "XvHsync",      OPTV_INTEGER,   {0}, FALSE },
26695b296d0Smrg    { OPTION_XV_VSYNC,          "XvVsync",      OPTV_INTEGER,   {0}, FALSE },
26795b296d0Smrg    { OPTION_XV_BSKEW,          "XvBskew",      OPTV_INTEGER,   {0}, FALSE },
26895b296d0Smrg    { OPTION_XV_RSKEW,          "XvRskew",      OPTV_INTEGER,   {0}, FALSE },
26995b296d0Smrg    { OPTION_FP_DELAY,          "FpDelay",      OPTV_INTEGER,   {0}, FALSE },
27095b296d0Smrg    { OPTION_1400_DISPLAY,	"Display1400",	OPTV_BOOLEAN,	{0}, FALSE },
27195b296d0Smrg    { OPTION_DISPLAY,		"Display",	OPTV_ANYSTR,	{0}, FALSE },
27295b296d0Smrg    { OPTION_GB,		"GammaBrightness",	OPTV_ANYSTR,	{0}, FALSE },
27395b296d0Smrg    { OPTION_TV_CHIPSET,        "TVChipset",    OPTV_ANYSTR,    {0}, FALSE },
27495b296d0Smrg    { OPTION_TV_SIGNALMODE,     "TVSignal",     OPTV_INTEGER,   {0}, FALSE },
27595b296d0Smrg    { -1,			NULL,		OPTV_NONE,	{0}, FALSE }
27695b296d0Smrg};
27795b296d0Smrg
27895b296d0Smrg/* Clock Limits */
27995b296d0Smrgstatic int ClockLimit[] = {
28095b296d0Smrg	80000,
28195b296d0Smrg	80000,
28295b296d0Smrg	80000,
28395b296d0Smrg	80000,
28495b296d0Smrg	80000,
28595b296d0Smrg	80000,
28695b296d0Smrg	80000,
28795b296d0Smrg	80000,
28895b296d0Smrg	80000,
28995b296d0Smrg	80000,
29095b296d0Smrg	80000,
29195b296d0Smrg	80000,
29295b296d0Smrg	80000,
29395b296d0Smrg	80000,
29495b296d0Smrg	90000,
29595b296d0Smrg	90000,
29695b296d0Smrg	135000,
29795b296d0Smrg	135000,
29895b296d0Smrg	170000,
29995b296d0Smrg	170000,
30095b296d0Smrg	170000,
30195b296d0Smrg	170000,
30295b296d0Smrg	170000,
30395b296d0Smrg	170000,
30495b296d0Smrg	170000,
30595b296d0Smrg	230000,
30695b296d0Smrg	230000,
30795b296d0Smrg	230000,
30895b296d0Smrg	230000,
30995b296d0Smrg	230000,
31095b296d0Smrg	230000,
31195b296d0Smrg	230000,
31295b296d0Smrg	230000,
31395b296d0Smrg	230000,
31495b296d0Smrg	230000,
31595b296d0Smrg	230000,
31695b296d0Smrg	230000,
31795b296d0Smrg	230000,
31895b296d0Smrg	230000,
31995b296d0Smrg	230000,
32095b296d0Smrg	230000,
32195b296d0Smrg};
32295b296d0Smrg
32395b296d0Smrgstatic int ClockLimit16bpp[] = {
32495b296d0Smrg	40000,
32595b296d0Smrg	40000,
32695b296d0Smrg	40000,
32795b296d0Smrg	40000,
32895b296d0Smrg	40000,
32995b296d0Smrg	40000,
33095b296d0Smrg	40000,
33195b296d0Smrg	40000,
33295b296d0Smrg	40000,
33395b296d0Smrg	40000,
33495b296d0Smrg	40000,
33595b296d0Smrg	40000,
33695b296d0Smrg	40000,
33795b296d0Smrg	40000,
33895b296d0Smrg	45000,
33995b296d0Smrg	45000,
34095b296d0Smrg	90000,
34195b296d0Smrg	90000,
34295b296d0Smrg	135000,
34395b296d0Smrg	135000,
34495b296d0Smrg	170000,
34595b296d0Smrg	170000,
34695b296d0Smrg	170000,
34795b296d0Smrg	170000,
34895b296d0Smrg	170000,
34995b296d0Smrg	230000,
35095b296d0Smrg	230000,
35195b296d0Smrg	230000,
35295b296d0Smrg	230000,
35395b296d0Smrg	230000,
35495b296d0Smrg	230000,
35595b296d0Smrg	230000,
35695b296d0Smrg	230000,
35795b296d0Smrg	230000,
35895b296d0Smrg	230000,
35995b296d0Smrg	230000,
36095b296d0Smrg	230000,
36195b296d0Smrg	230000,
36295b296d0Smrg	230000,
36395b296d0Smrg	230000,
36495b296d0Smrg	230000,
36595b296d0Smrg};
36695b296d0Smrg
36795b296d0Smrgstatic int ClockLimit24bpp[] = {
36895b296d0Smrg	25180,
36995b296d0Smrg	25180,
37095b296d0Smrg	25180,
37195b296d0Smrg	25180,
37295b296d0Smrg	25180,
37395b296d0Smrg	25180,
37495b296d0Smrg	25180,
37595b296d0Smrg	25180,
37695b296d0Smrg	25180,
37795b296d0Smrg	25180,
37895b296d0Smrg	25180,
37995b296d0Smrg	25180,
38095b296d0Smrg	25180,
38195b296d0Smrg	25180,
38295b296d0Smrg	25180,
38395b296d0Smrg	25180,
38495b296d0Smrg	40000,
38595b296d0Smrg	40000,
38695b296d0Smrg	70000,
38795b296d0Smrg	70000,
38895b296d0Smrg	70000,
38995b296d0Smrg	115000,
39095b296d0Smrg	115000,
39195b296d0Smrg	115000,
39295b296d0Smrg	115000,
39395b296d0Smrg	115000,
39495b296d0Smrg	115000,
39595b296d0Smrg	115000,
39695b296d0Smrg	115000,
39795b296d0Smrg	115000,
39895b296d0Smrg	115000,
39995b296d0Smrg	115000,
40095b296d0Smrg	115000,
40195b296d0Smrg	115000,
40295b296d0Smrg	115000,
40395b296d0Smrg	115000,
40495b296d0Smrg	115000,
40595b296d0Smrg	115000,
40695b296d0Smrg	115000,
40795b296d0Smrg	115000,
40895b296d0Smrg	115000,
40995b296d0Smrg};
41095b296d0Smrg
41195b296d0Smrgstatic int ClockLimit32bpp[] = {
41295b296d0Smrg	25180,
41395b296d0Smrg	25180,
41495b296d0Smrg	25180,
41595b296d0Smrg	25180,
41695b296d0Smrg	25180,
41795b296d0Smrg	25180,
41895b296d0Smrg	25180,
41995b296d0Smrg	25180,
42095b296d0Smrg	25180,
42195b296d0Smrg	25180,
42295b296d0Smrg	25180,
42395b296d0Smrg	25180,
42495b296d0Smrg	25180,
42595b296d0Smrg	25180,
42695b296d0Smrg	25180,
42795b296d0Smrg	25180,
42895b296d0Smrg	40000,
42995b296d0Smrg	40000,
43095b296d0Smrg	70000,
43195b296d0Smrg	70000,
43295b296d0Smrg	70000,
43395b296d0Smrg	115000,
43495b296d0Smrg	115000,
43595b296d0Smrg	115000,
43695b296d0Smrg	115000,
43795b296d0Smrg	115000,
43895b296d0Smrg	115000,
43995b296d0Smrg	115000,
44095b296d0Smrg	115000,
44195b296d0Smrg	115000,
44295b296d0Smrg	115000,
44395b296d0Smrg	115000,
44495b296d0Smrg	115000,
44595b296d0Smrg	115000,
44695b296d0Smrg	115000,
44795b296d0Smrg	115000,
44895b296d0Smrg	115000,
44995b296d0Smrg	115000,
45095b296d0Smrg	115000,
45195b296d0Smrg	115000,
45295b296d0Smrg	115000,
45395b296d0Smrg	115000,
45495b296d0Smrg};
45595b296d0Smrg
45695b296d0Smrg/*
45795b296d0Smrg * These are fixed modelines for all physical display dimensions the
45895b296d0Smrg *  chipsets supports on FPs. Most of them are not tested yet.
45995b296d0Smrg */
46095b296d0Smrg#if 0
46195b296d0SmrgtridentLCD LCD[] = {   /* 0    3    4    5   6    7    10   11  16 */
46295b296d0Smrg    { 0,"640x480",25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08},
46395b296d0Smrg    { 1,"800x600",40000,0x7f,0x99,0x69,0x99,0x72,0xf0,0x59,0x2d,0x5e,0x08},
46495b296d0Smrg    { 2,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08},
46595b296d0Smrg    { 3,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, /*0x96*/
46695b296d0Smrg    { 4,"1280x1024",108000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08},
46795b296d0Smrg    { 5,"1024x600",50500 ,0xa3,0x6,0x8f,0xa0,0xb,0x3e,0xea,0x8c,0xb,0x08},
46895b296d0Smrg    { 0xff,"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
46995b296d0Smrg};
47095b296d0Smrg#else
47195b296d0Smrg#if 0
47295b296d0SmrgtridentLCD LCD[] = {
47395b296d0Smrg    { 1,640,480,25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08},
47495b296d0Smrg    { 3,800,600,40000,0x7f,0x82,0x6b,0x1b,0x72,0xf8,0x58,0x8c,0x72,0x08},
47595b296d0Smrg    { 2,1024,768,65000,0xa3,/*0x6*/0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x24,0x0a,0x08},
47695b296d0Smrg    { 0,1280,1024,108000,0xce,0x81,0xa6,0x9a,0x27,0x50,0x00,0x03,0x26,0xa8},
47795b296d0Smrg    { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
47895b296d0Smrg};
47995b296d0Smrg#else
48095b296d0SmrgtridentLCD LCD[] = {
48195b296d0Smrg    { 1,640,480,25200,0x5f,0x80,0x52,0x1e,0xb,0x3e,0xea,0x0c,0xb,0x08},
48295b296d0Smrg    { 3,800,600,40000,0x7f,0x00,0x69,0x7f,0x72,0xf0,0x59,0x0d,0x00,0x08},
48395b296d0Smrg    { 2,1024,768,65000,0xa3,0x00,0x84,0x94,0x24,0xf5,0x03,0x09,0x24,0x08},
48495b296d0Smrg    { 0,1280,1024,108000,0xce,0x91,0xa6,0x14,0x28,0x5a,0x01,0x04,0x28,0xa8},
48595b296d0Smrg    { 4,1400,1050,122000,0xe6,0x8d,0xba,0x1d,0x38,0x00,0x1c,0x28,0x28,0xf8},
48695b296d0Smrg    { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
48795b296d0Smrg};
48895b296d0Smrg#endif
48995b296d0Smrg#endif
49095b296d0Smrg
49195b296d0Smrgstatic const char *xaaSymbols[] = {
49295b296d0Smrg    "XAAGetCopyROP",
49395b296d0Smrg    "XAACreateInfoRec",
49495b296d0Smrg    "XAADestroyInfoRec",
49595b296d0Smrg    "XAAInit",
49695b296d0Smrg    "XAAGetPatternROP",
49795b296d0Smrg    NULL
49895b296d0Smrg};
49995b296d0Smrg
50095b296d0Smrgconst char *exaSymbols[] = {
50195b296d0Smrg    "exaDriverAlloc",
50295b296d0Smrg    "exaDriverInit",
50395b296d0Smrg    "exaDriverFini",
50495b296d0Smrg    "exaOffscreenAlloc",
50595b296d0Smrg    "exaOffscreenFree",
50695b296d0Smrg    NULL
50795b296d0Smrg};
50895b296d0Smrg
50995b296d0Smrgstatic const char *vgahwSymbols[] = {
51095b296d0Smrg    "vgaHWBlankScreenWeak",
51195b296d0Smrg    "vgaHWFreeHWRec",
51295b296d0Smrg    "vgaHWGetHWRec",
51395b296d0Smrg    "vgaHWGetIOBase",
51495b296d0Smrg    "vgaHWGetIndex",
51595b296d0Smrg    "vgaHWInit",
51695b296d0Smrg    "vgaHWLock",
51795b296d0Smrg    "vgaHWMapMem",
51895b296d0Smrg    "vgaHWProtectWeak",
51995b296d0Smrg    "vgaHWRestore",
52095b296d0Smrg    "vgaHWSave",
52195b296d0Smrg    "vgaHWSaveScreen",
52295b296d0Smrg    "vgaHWSetMmioFuncs",
52395b296d0Smrg    "vgaHWUnlock",
52495b296d0Smrg    NULL
52595b296d0Smrg};
52695b296d0Smrg
52795b296d0Smrgstatic const char *fbSymbols[] = {
52895b296d0Smrg    "fbPictureInit",
52995b296d0Smrg    "fbScreenInit",
53095b296d0Smrg    NULL
53195b296d0Smrg};
53295b296d0Smrg
53395b296d0Smrgstatic const char *ramdacSymbols[] = {
53495b296d0Smrg    "xf86CreateCursorInfoRec",
53595b296d0Smrg    "xf86DestroyCursorInfoRec",
53695b296d0Smrg    "xf86InitCursor",
53795b296d0Smrg    NULL
53895b296d0Smrg};
53995b296d0Smrg
54095b296d0Smrgstatic const char *ddcSymbols[] = {
54195b296d0Smrg    "xf86PrintEDID",
54295b296d0Smrg    "xf86SetDDCproperties",
54395b296d0Smrg    NULL
54495b296d0Smrg};
54595b296d0Smrg
54695b296d0Smrgstatic const char *i2cSymbols[] = {
54795b296d0Smrg    "xf86CreateI2CBusRec",
54895b296d0Smrg    "xf86I2CBusInit",
54995b296d0Smrg    NULL
55095b296d0Smrg};
55195b296d0Smrg
55295b296d0Smrgstatic const char *int10Symbols[] = {
55395b296d0Smrg    "xf86ExecX86int10",
55495b296d0Smrg    "xf86FreeInt10",
55595b296d0Smrg    "xf86InitInt10",
55695b296d0Smrg    NULL
55795b296d0Smrg};
55895b296d0Smrg
55995b296d0Smrgstatic const char *shadowSymbols[] = {
56095b296d0Smrg    "shadowInit",
56195b296d0Smrg    NULL
56295b296d0Smrg};
56395b296d0Smrg
56495b296d0Smrgstatic const char *vbeSymbols[] = {
56595b296d0Smrg    "VBEInit",
56695b296d0Smrg    "vbeDoEDID",
56795b296d0Smrg    "vbeFree",
56895b296d0Smrg    NULL
56995b296d0Smrg};
57095b296d0Smrg
57195b296d0Smrg#ifdef XFree86LOADER
57295b296d0Smrg
57395b296d0Smrgstatic MODULESETUPPROTO(tridentSetup);
57495b296d0Smrg
57595b296d0Smrgstatic XF86ModuleVersionInfo tridentVersRec =
57695b296d0Smrg{
57795b296d0Smrg	"trident",
57895b296d0Smrg	MODULEVENDORSTRING,
57995b296d0Smrg	MODINFOSTRING1,
58095b296d0Smrg	MODINFOSTRING2,
58195b296d0Smrg	XORG_VERSION_CURRENT,
58295b296d0Smrg	TRIDENT_MAJOR_VERSION, TRIDENT_MINOR_VERSION, TRIDENT_PATCHLEVEL,
58395b296d0Smrg	ABI_CLASS_VIDEODRV,			/* This is a video driver */
58495b296d0Smrg	ABI_VIDEODRV_VERSION,
58595b296d0Smrg	MOD_CLASS_VIDEODRV,
58695b296d0Smrg	{0,0,0,0}
58795b296d0Smrg};
58895b296d0Smrg
58995b296d0Smrg_X_EXPORT XF86ModuleData tridentModuleData = {
59095b296d0Smrg	&tridentVersRec,
59195b296d0Smrg	tridentSetup,
59295b296d0Smrg	NULL
59395b296d0Smrg};
59495b296d0Smrg
59595b296d0Smrgpointer
59695b296d0SmrgtridentSetup(pointer module, pointer opts, int *errmaj, int *errmin)
59795b296d0Smrg{
59895b296d0Smrg    static Bool setupDone = FALSE;
59995b296d0Smrg
60095b296d0Smrg    if (!setupDone) {
60195b296d0Smrg	setupDone = TRUE;
60295b296d0Smrg	xf86AddDriver(&TRIDENT, module, 0);
60395b296d0Smrg	LoaderRefSymLists(vgahwSymbols, fbSymbols, i2cSymbols, vbeSymbols,
60495b296d0Smrg			  ramdacSymbols, int10Symbols,
60595b296d0Smrg			  xaaSymbols, exaSymbols, shadowSymbols, NULL);
60695b296d0Smrg	return (pointer)TRUE;
60795b296d0Smrg    }
60895b296d0Smrg
60995b296d0Smrg    if (errmaj) *errmaj = LDR_ONCEONLY;
61095b296d0Smrg    return NULL;
61195b296d0Smrg}
61295b296d0Smrg
61395b296d0Smrg#endif /* XFree86LOADER */
61495b296d0Smrg
61595b296d0Smrgstatic Bool
61695b296d0SmrgTRIDENTGetRec(ScrnInfoPtr pScrn)
61795b296d0Smrg{
61895b296d0Smrg    /*
61995b296d0Smrg     * Allocate an TRIDENTRec, and hook it into pScrn->driverPrivate.
62095b296d0Smrg     * pScrn->driverPrivate is initialised to NULL, so we can check if
62195b296d0Smrg     * the allocation has already been done.
62295b296d0Smrg     */
62395b296d0Smrg    if (pScrn->driverPrivate != NULL)
62495b296d0Smrg	return TRUE;
62595b296d0Smrg
62695b296d0Smrg    pScrn->driverPrivate = xnfcalloc(sizeof(TRIDENTRec), 1);
62795b296d0Smrg    /* Initialise it */
62895b296d0Smrg
62995b296d0Smrg    return TRUE;
63095b296d0Smrg}
63195b296d0Smrg
63295b296d0Smrgstatic void
63395b296d0SmrgTRIDENTFreeRec(ScrnInfoPtr pScrn)
63495b296d0Smrg{
63595b296d0Smrg    if (pScrn->driverPrivate == NULL)
63695b296d0Smrg	return;
63795b296d0Smrg    xfree(pScrn->driverPrivate);
63895b296d0Smrg    pScrn->driverPrivate = NULL;
63995b296d0Smrg}
64095b296d0Smrg
64195b296d0Smrgstatic void
64295b296d0SmrgTRIDENTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
64395b296d0Smrg{
64495b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
64595b296d0Smrg    CARD8 DPMSCont, PMCont, temp;
64695b296d0Smrg
64795b296d0Smrg    if (!pScrn->vtSema)
64895b296d0Smrg	return;
64995b296d0Smrg
65095b296d0Smrg    OUTB(0x3C4, 0x0E);
65195b296d0Smrg    temp = INB(0x3C5);
65295b296d0Smrg    OUTB(0x3C5, 0xC2);
65395b296d0Smrg    OUTB(0x83C8, 0x04); /* Read DPMS Control */
65495b296d0Smrg    PMCont = INB(0x83C6) & 0xFC;
65595b296d0Smrg    OUTB(0x3CE, 0x23);
65695b296d0Smrg    DPMSCont = INB(0x3CF) & 0xFC;
65795b296d0Smrg    switch (PowerManagementMode)
65895b296d0Smrg    {
65995b296d0Smrg	case DPMSModeOn:
66095b296d0Smrg		/* Screen: On, HSync: On, VSync: On */
66195b296d0Smrg		PMCont |= 0x03;
66295b296d0Smrg		DPMSCont |= 0x00;
66395b296d0Smrg		break;
66495b296d0Smrg	case DPMSModeStandby:
66595b296d0Smrg		/* Screen: Off, HSync: Off, VSync: On */
66695b296d0Smrg		PMCont |= 0x02;
66795b296d0Smrg		DPMSCont |= 0x01;
66895b296d0Smrg		break;
66995b296d0Smrg	case DPMSModeSuspend:
67095b296d0Smrg		/* Screen: Off, HSync: On, VSync: Off */
67195b296d0Smrg		PMCont |= 0x02;
67295b296d0Smrg		DPMSCont |= 0x02;
67395b296d0Smrg		break;
67495b296d0Smrg	case DPMSModeOff:
67595b296d0Smrg		/* Screen: Off, HSync: Off, VSync: Off */
67695b296d0Smrg		PMCont |= 0x00;
67795b296d0Smrg		DPMSCont |= 0x03;
67895b296d0Smrg		break;
67995b296d0Smrg    }
68095b296d0Smrg    OUTB(0x3CF, DPMSCont);
68195b296d0Smrg    OUTB(0x83C8, 0x04);
68295b296d0Smrg    OUTB(0x83C6, PMCont);
68395b296d0Smrg    OUTW(0x3C4, (temp<<8) | 0x0E);
68495b296d0Smrg}
68595b296d0Smrg
68695b296d0Smrgstatic void
68795b296d0SmrgTRIDENTBlockHandler (
68895b296d0Smrg    int i,
68995b296d0Smrg    pointer     blockData,
69095b296d0Smrg    pointer     pTimeout,
69195b296d0Smrg    pointer     pReadmask
69295b296d0Smrg){
69395b296d0Smrg    ScreenPtr      pScreen = screenInfo.screens[i];
69495b296d0Smrg    ScrnInfoPtr    pScrn = xf86Screens[i];
69595b296d0Smrg    TRIDENTPtr     pTrident = TRIDENTPTR(pScrn);
69695b296d0Smrg
69795b296d0Smrg    pScreen->BlockHandler = pTrident->BlockHandler;
69895b296d0Smrg    (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
69995b296d0Smrg    pScreen->BlockHandler = TRIDENTBlockHandler;
70095b296d0Smrg
70195b296d0Smrg    if(pTrident->VideoTimerCallback) {
70295b296d0Smrg	UpdateCurrentTime();
70395b296d0Smrg	(*pTrident->VideoTimerCallback)(pScrn, currentTime.milliseconds);
70495b296d0Smrg    }
70595b296d0Smrg}
70695b296d0Smrg
70795b296d0Smrgstatic const OptionInfoRec *
70895b296d0SmrgTRIDENTAvailableOptions(int chipid, int busid)
70995b296d0Smrg{
71095b296d0Smrg    return TRIDENTOptions;
71195b296d0Smrg}
71295b296d0Smrg
71395b296d0Smrg/* Mandatory */
71495b296d0Smrgstatic void
71595b296d0SmrgTRIDENTIdentify(int flags)
71695b296d0Smrg{
71795b296d0Smrg    xf86PrintChipsets(TRIDENT_NAME, "driver for Trident chipsets", TRIDENTChipsets);
71895b296d0Smrg}
71995b296d0Smrg
72095b296d0SmrgBool
72195b296d0SmrgTRIDENTClockSelect(ScrnInfoPtr pScrn, int no)
72295b296d0Smrg{
72395b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
72495b296d0Smrg    unsigned char temp;
72595b296d0Smrg
72695b296d0Smrg    /*
72795b296d0Smrg     * CS0 and CS1 are in MiscOutReg
72895b296d0Smrg     *
72995b296d0Smrg     * For 8900B, 8900C, 8900CL and 9000, CS2 is bit 0 of
73095b296d0Smrg     * New Mode Control Register 2.
73195b296d0Smrg     *
73295b296d0Smrg     * For 8900CL, CS3 is bit 4 of Old Mode Control Register 1.
73395b296d0Smrg     *
73495b296d0Smrg     * For 9000, CS3 is bit 6 of New Mode Control Register 2.
73595b296d0Smrg     *
73695b296d0Smrg     * For TGUI, we don't use the ClockSelect function at all.
73795b296d0Smrg     */
73895b296d0Smrg     switch(no) {
73995b296d0Smrg	case CLK_REG_SAVE:
74095b296d0Smrg	    pTrident->SaveClock1 = INB(0x3CC);
74195b296d0Smrg	    if (pTrident->Chipset != TVGA8800CS) {
74295b296d0Smrg		if ( (pScrn->numClocks == 16) &&
74395b296d0Smrg		     (pTrident->Chipset != TVGA9000) &&
74495b296d0Smrg		     (pTrident->Chipset != TVGA9000i) )
74595b296d0Smrg		{
74695b296d0Smrg		    OUTW(0x3C4, 0x000B);	/* Switch to Old Mode */
74795b296d0Smrg		    OUTB(0x3C4, 0x0E); pTrident->SaveClock3 = INB(0x3C5);
74895b296d0Smrg		}
74995b296d0Smrg		OUTB(0x3C4, 0x0B);
75095b296d0Smrg		INB(0x3C5);		/* Now to New Mode */
75195b296d0Smrg		OUTB(0x3C4, 0x0D); pTrident->SaveClock2 = INB(0x3C5);
75295b296d0Smrg	    }
75395b296d0Smrg	    break;
75495b296d0Smrg	case CLK_REG_RESTORE:
75595b296d0Smrg	    OUTB(0x3C2, pTrident->SaveClock1);
75695b296d0Smrg	    if (pTrident->Chipset != TVGA8800CS) {
75795b296d0Smrg		if ( (pScrn->numClocks == 16) &&
75895b296d0Smrg		     (pTrident->Chipset != TVGA9000) &&
75995b296d0Smrg		     (pTrident->Chipset != TVGA9000i) )
76095b296d0Smrg		{
76195b296d0Smrg			OUTW(0x3C4, 0x000B);	/* Switch to Old Mode */
76295b296d0Smrg			OUTW(0x3C4, (pTrident->SaveClock3 << 8) | 0x0E);
76395b296d0Smrg		}
76495b296d0Smrg		OUTB(0x3C4, 0x0B);
76595b296d0Smrg		INB(0x3C5);		/* Now to New Mode */
76695b296d0Smrg		OUTW(0x3C4, (pTrident->SaveClock2 << 8) | 0x0D);
76795b296d0Smrg	    }
76895b296d0Smrg	    break;
76995b296d0Smrg	default:
77095b296d0Smrg	    /*
77195b296d0Smrg	     * Do CS0 and CS1
77295b296d0Smrg	     */
77395b296d0Smrg	    temp = INB(0x3CC);
77495b296d0Smrg	    OUTB(0x3C2, (temp & 0xF3) | ((no << 2) & 0x0C));
77595b296d0Smrg	    if (pTrident->Chipset != TVGA8800CS) {
77695b296d0Smrg		if ( (pScrn->numClocks == 16) &&
77795b296d0Smrg		     (pTrident->Chipset != TVGA9000) &&
77895b296d0Smrg		     (pTrident->Chipset != TVGA9000i) )
77995b296d0Smrg		{
78095b296d0Smrg			/*
78195b296d0Smrg			 * Go to Old Mode for CS3.
78295b296d0Smrg		 	 */
78395b296d0Smrg			OUTW(0x3C4, 0x000B);	/* Switch to Old Mode */
78495b296d0Smrg			OUTB(0x3C4, 0x0E);
78595b296d0Smrg			temp = INB(0x3C5) & 0xEF;
78695b296d0Smrg			temp |= (no & 0x08) << 1;
78795b296d0Smrg			OUTB(0x3C5, temp);
78895b296d0Smrg		}
78995b296d0Smrg		/*
79095b296d0Smrg	  	 * Go to New Mode for CS2 and TVGA9000 CS3.
79195b296d0Smrg	  	 */
79295b296d0Smrg		OUTB(0x3C4, 0x0B);
79395b296d0Smrg		INB(0x3C5);		/* Now to New Mode */
79495b296d0Smrg		OUTB(0x3C4, 0x0D);
79595b296d0Smrg		/*
79695b296d0Smrg		 * Bits 1 & 2 are dividers - set to 0 to get no
79795b296d0Smrg		 * clock division.
79895b296d0Smrg		 */
79995b296d0Smrg		temp = INB(0x3C5) & 0xF8;
80095b296d0Smrg		temp |= (no & 0x04) >> 2;
80195b296d0Smrg		if ( (pTrident->Chipset == TVGA9000) ||
80295b296d0Smrg		     (pTrident->Chipset == TVGA9000i) )
80395b296d0Smrg		{
80495b296d0Smrg			temp &= ~0x40;
80595b296d0Smrg			temp |= (no & 0x08) << 3;
80695b296d0Smrg		}
80795b296d0Smrg		OUTB(0x3C5, temp);
80895b296d0Smrg	}
80995b296d0Smrg    }
81095b296d0Smrg    return(TRUE);
81195b296d0Smrg}
81295b296d0Smrg
813ff89ac2bSmrg#ifdef HAVE_ISA
81495b296d0Smrgstatic int
81595b296d0SmrgTridentFindIsaDevice(GDevPtr dev)
81695b296d0Smrg{
81795b296d0Smrg    int found = -1;
81895b296d0Smrg    unsigned char temp, origVal, newVal;
81995b296d0Smrg
82095b296d0Smrg    /*
82195b296d0Smrg     * Check first that we have a Trident card.
82295b296d0Smrg     */
82395b296d0Smrg    outb(0x3C4, 0x0B);
82495b296d0Smrg    temp = inb(0x3C5);	/* Save old value */
82595b296d0Smrg    outb(0x3C4, 0x0B);	/* Switch to Old Mode */
82695b296d0Smrg    outb(0x3C5, 0x00);
82795b296d0Smrg    inb(0x3C5);		/* Now to New Mode */
82895b296d0Smrg    outb(0x3C4, 0x0E);
82995b296d0Smrg    origVal = inb(0x3C5);
83095b296d0Smrg    outb(0x3C5, 0x00);
83195b296d0Smrg    newVal = inb(0x3C5) & 0x0F;
83295b296d0Smrg    outb(0x3C5, (origVal ^ 0x02));
83395b296d0Smrg
83495b296d0Smrg    /*
83595b296d0Smrg     * Is it a Trident card ??
83695b296d0Smrg     */
83795b296d0Smrg    if (newVal != 2) {
83895b296d0Smrg	/*
83995b296d0Smrg	 * Nope, so quit
84095b296d0Smrg	 */
84195b296d0Smrg	outb(0x3C4, 0x0B);	/* Restore value of 0x0B */
84295b296d0Smrg	outb(0x3C5, temp);
84395b296d0Smrg	outb(0x3C4, 0x0E);
84495b296d0Smrg	outb(0x3C5, origVal);
84595b296d0Smrg	return found;
84695b296d0Smrg    }
84795b296d0Smrg
84895b296d0Smrg    outb(0x3C4, 0x0B);
84995b296d0Smrg    temp = inb(0x3C5);
85095b296d0Smrg    switch (temp) {
85195b296d0Smrg	case 0x01:
85295b296d0Smrg	    found = TVGA8800BR;
85395b296d0Smrg	    break;
85495b296d0Smrg	case 0x02:
85595b296d0Smrg	    found = TVGA8800CS;
85695b296d0Smrg	    break;
85795b296d0Smrg	case 0x03:
85895b296d0Smrg	    found = TVGA8900B;
85995b296d0Smrg	    break;
86095b296d0Smrg	case 0x04:
86195b296d0Smrg	case 0x13:
86295b296d0Smrg	    found = TVGA8900C;
86395b296d0Smrg	    break;
86495b296d0Smrg	case 0x23:
86595b296d0Smrg	    found = TVGA9000;
86695b296d0Smrg	    break;
86795b296d0Smrg	case 0x33:
86895b296d0Smrg	    found = TVGA8900D;
86995b296d0Smrg	    break;
87095b296d0Smrg	case 0x43:
87195b296d0Smrg	    found = TVGA9000i;
87295b296d0Smrg	    break;
87395b296d0Smrg	case 0x53:
87495b296d0Smrg	    found = TVGA9200CXr;
87595b296d0Smrg	    break;
87695b296d0Smrg	case 0x63:
87795b296d0Smrg	    found = TVGA9100B;
87895b296d0Smrg	    break;
87995b296d0Smrg	case 0x73:
88095b296d0Smrg	case 0xC3:
88195b296d0Smrg	    found = TGUI9420DGi;
88295b296d0Smrg	    break;
88395b296d0Smrg	case 0x83:
88495b296d0Smrg	    found = TVGA8200LX;
88595b296d0Smrg	    break;
88695b296d0Smrg	case 0x93:
88795b296d0Smrg	    found = TGUI9400CXi;
88895b296d0Smrg	    break;
88995b296d0Smrg	case 0xA3:
89095b296d0Smrg	    found = CYBER9320;
89195b296d0Smrg	    break;
89295b296d0Smrg	case 0xD3:
89395b296d0Smrg	    found = TGUI9660;
89495b296d0Smrg	    break;
89595b296d0Smrg	case 0xE3:
89695b296d0Smrg	    found = TGUI9440AGi;
89795b296d0Smrg	    break;
89895b296d0Smrg	case 0xF3:
89995b296d0Smrg	    found = TGUI9430DGi;
90095b296d0Smrg	    break;
90195b296d0Smrg    }
90295b296d0Smrg    return found;
90395b296d0Smrg}
904ff89ac2bSmrg#endif
90595b296d0Smrg
90695b296d0Smrg
90795b296d0Smrg/* Mandatory */
90895b296d0Smrgstatic Bool
90995b296d0SmrgTRIDENTProbe(DriverPtr drv, int flags)
91095b296d0Smrg{
91195b296d0Smrg    int i;
91295b296d0Smrg    GDevPtr *devSections;
91395b296d0Smrg    int *usedChips = NULL;
91495b296d0Smrg    int numDevSections;
91595b296d0Smrg    int numUsed;
91695b296d0Smrg    Bool foundScreen = FALSE;
91795b296d0Smrg
91895b296d0Smrg    if ((numDevSections = xf86MatchDevice(TRIDENT_DRIVER_NAME,
91995b296d0Smrg					  &devSections)) <= 0) {
92095b296d0Smrg	/*
92195b296d0Smrg	 * There's no matching device section in the config file, so quit
92295b296d0Smrg	 * now.
92395b296d0Smrg	 */
92495b296d0Smrg	return FALSE;
92595b296d0Smrg    }
92695b296d0Smrg
92795b296d0Smrg    /*
92895b296d0Smrg     * While we're VGA-dependent, can really only have one such instance, but
92995b296d0Smrg     * we'll ignore that.
93095b296d0Smrg     */
93195b296d0Smrg
93295b296d0Smrg    /*
93395b296d0Smrg     * We need to probe the hardware first.  We then need to see how this
93495b296d0Smrg     * fits in with what is given in the config file, and allow the config
93595b296d0Smrg     * file info to override any contradictions.
93695b296d0Smrg     */
93795b296d0Smrg
93895b296d0Smrg    /*
93995b296d0Smrg     * All of the cards this driver supports are PCI, so the "probing" just
94095b296d0Smrg     * amounts to checking the PCI data that the server has already collected.
94195b296d0Smrg     */
942ff89ac2bSmrg#ifndef XSERVER_LIBPCIACCESS
943ff89ac2bSmrg    if (xf86GetPciVideoInfo()== NULL) {
944ff89ac2bSmrg	return FALSE;
945ff89ac2bSmrg    }
946ff89ac2bSmrg#endif
947ff89ac2bSmrg    {
94895b296d0Smrg    	numUsed = xf86MatchPciInstances(TRIDENT_NAME, PCI_VENDOR_TRIDENT,
94995b296d0Smrg		   TRIDENTChipsets, TRIDENTPciChipsets, devSections,
95095b296d0Smrg		   numDevSections, drv, &usedChips);
95195b296d0Smrg
95295b296d0Smrg	if (numUsed > 0) {
95395b296d0Smrg	    if (flags & PROBE_DETECT)
95495b296d0Smrg		foundScreen = TRUE;
95595b296d0Smrg	    else for (i = 0; i < numUsed; i++) {
95695b296d0Smrg		ScrnInfoPtr pScrn = NULL;
95795b296d0Smrg
95895b296d0Smrg		if ((pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i],
95995b296d0Smrg						       TRIDENTPciChipsets, NULL,
96095b296d0Smrg						       NULL, NULL, NULL, NULL))) {
96195b296d0Smrg		    /* Fill in what we can of the ScrnInfoRec */
96295b296d0Smrg		    pScrn->driverVersion = TRIDENT_VERSION;
96395b296d0Smrg		    pScrn->driverName	 = TRIDENT_DRIVER_NAME;
96495b296d0Smrg		    pScrn->name		 = TRIDENT_NAME;
96595b296d0Smrg		    pScrn->Probe	 = TRIDENTProbe;
96695b296d0Smrg		    pScrn->PreInit	 = TRIDENTPreInit;
96795b296d0Smrg		    pScrn->ScreenInit	 = TRIDENTScreenInit;
96895b296d0Smrg		    pScrn->SwitchMode	 = TRIDENTSwitchMode;
96995b296d0Smrg		    pScrn->AdjustFrame	 = TRIDENTAdjustFrame;
97095b296d0Smrg		    pScrn->EnterVT	 = TRIDENTEnterVT;
97195b296d0Smrg		    pScrn->LeaveVT	 = TRIDENTLeaveVT;
97295b296d0Smrg		    pScrn->FreeScreen	 = TRIDENTFreeScreen;
97395b296d0Smrg		    pScrn->ValidMode	 = TRIDENTValidMode;
97495b296d0Smrg		    foundScreen = TRUE;
97595b296d0Smrg		}
97695b296d0Smrg	    }
97795b296d0Smrg	    xfree(usedChips);
97895b296d0Smrg	}
97995b296d0Smrg    }
98095b296d0Smrg
981ff89ac2bSmrg#ifdef HAVE_ISA
98295b296d0Smrg    /* Isa Bus */
98395b296d0Smrg    numUsed = xf86MatchIsaInstances(TRIDENT_NAME,TRIDENTChipsets,
98495b296d0Smrg				     TRIDENTISAchipsets,
98595b296d0Smrg				     drv,TridentFindIsaDevice,devSections,
98695b296d0Smrg				     numDevSections,&usedChips);
98795b296d0Smrg    if (numUsed > 0) {
98895b296d0Smrg	if (flags & PROBE_DETECT)
98995b296d0Smrg	    foundScreen = TRUE;
99095b296d0Smrg	else 	for (i = 0; i < numUsed; i++) {
99195b296d0Smrg	    ScrnInfoPtr pScrn = NULL;
99295b296d0Smrg	    if ((pScrn = xf86ConfigIsaEntity(pScrn,0,usedChips[i],
99395b296d0Smrg						  TRIDENTISAchipsets,NULL,
99495b296d0Smrg						  NULL,NULL,NULL,NULL))) {
99595b296d0Smrg		pScrn->driverVersion = TRIDENT_VERSION;
99695b296d0Smrg		pScrn->driverName    = TRIDENT_DRIVER_NAME;
99795b296d0Smrg		pScrn->name          = TRIDENT_NAME;
99895b296d0Smrg		pScrn->Probe         = TRIDENTProbe;
99995b296d0Smrg		pScrn->PreInit       = TRIDENTPreInit;
100095b296d0Smrg		pScrn->ScreenInit    = TRIDENTScreenInit;
100195b296d0Smrg		pScrn->SwitchMode    = TRIDENTSwitchMode;
100295b296d0Smrg		pScrn->AdjustFrame   = TRIDENTAdjustFrame;
100395b296d0Smrg		pScrn->EnterVT       = TRIDENTEnterVT;
100495b296d0Smrg		pScrn->LeaveVT       = TRIDENTLeaveVT;
100595b296d0Smrg		pScrn->FreeScreen    = TRIDENTFreeScreen;
100695b296d0Smrg		pScrn->ValidMode     = TRIDENTValidMode;
100795b296d0Smrg		foundScreen = TRUE;
100895b296d0Smrg	    }
100995b296d0Smrg	}
101095b296d0Smrg	xfree(usedChips);
101195b296d0Smrg    }
1012ff89ac2bSmrg#endif
1013ff89ac2bSmrg
101495b296d0Smrg    xfree(devSections);
101595b296d0Smrg    return foundScreen;
101695b296d0Smrg}
101795b296d0Smrg
101895b296d0Smrg/*
101995b296d0Smrg * GetAccelPitchValues -
102095b296d0Smrg *
102195b296d0Smrg * This function returns a list of display width (pitch) values that can
102295b296d0Smrg * be used in accelerated mode.
102395b296d0Smrg */
102495b296d0Smrgstatic int *
102595b296d0SmrgGetAccelPitchValues(ScrnInfoPtr pScrn)
102695b296d0Smrg{
102795b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
102895b296d0Smrg    int *linePitches = NULL;
102995b296d0Smrg    int lines[4] = { 512, 1024, 2048, 4096 }; /* 9440AGi */
103095b296d0Smrg    int i, n = 0;
103195b296d0Smrg
103295b296d0Smrg    if (pTrident->Chipset >= BLADEXP) {
103395b296d0Smrg	lines[0] = 1024;
103495b296d0Smrg	lines[1] = 2048;
103595b296d0Smrg	lines[2] = 4096;
103695b296d0Smrg	lines[3] = 8192;
103795b296d0Smrg    }
103895b296d0Smrg
103995b296d0Smrg    for (i = 0; i < 4; i++) {
104095b296d0Smrg	n++;
104195b296d0Smrg	linePitches = xnfrealloc(linePitches, n * sizeof(int));
104295b296d0Smrg	linePitches[n - 1] = lines[i];
104395b296d0Smrg    }
104495b296d0Smrg
104595b296d0Smrg    /* Mark the end of the list */
104695b296d0Smrg    if (n > 0) {
104795b296d0Smrg	linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
104895b296d0Smrg	linePitches[n] = 0;
104995b296d0Smrg    }
105095b296d0Smrg    return linePitches;
105195b296d0Smrg}
105295b296d0Smrg
105395b296d0Smrgstatic void
105495b296d0SmrgTRIDENTProbeDDC(ScrnInfoPtr pScrn, int index)
105595b296d0Smrg{
105695b296d0Smrg    vbeInfoPtr pVbe;
105795b296d0Smrg    if (xf86LoadSubModule(pScrn, "vbe")) {
105895b296d0Smrg	pVbe = VBEInit(NULL,index);
105995b296d0Smrg	ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
106095b296d0Smrg	vbeFree(pVbe);
106195b296d0Smrg    }
106295b296d0Smrg}
106395b296d0Smrg
106495b296d0Smrg/* Mandatory */
106595b296d0Smrgstatic Bool
106695b296d0SmrgTRIDENTPreInit(ScrnInfoPtr pScrn, int flags)
106795b296d0Smrg{
106895b296d0Smrg    TRIDENTPtr pTrident;
106995b296d0Smrg    vgaHWPtr hwp;
107095b296d0Smrg    MessageType from;
107195b296d0Smrg    CARD8 videoram, videorammask;
107295b296d0Smrg    char *ramtype = NULL, *chipset = NULL;
107395b296d0Smrg    Bool Support24bpp;
107495b296d0Smrg    int vgaIOBase;
107595b296d0Smrg    float mclk;
107695b296d0Smrg    double real;
107795b296d0Smrg    int i, NoClocks = 16;
107895b296d0Smrg    CARD8 revision;
107995b296d0Smrg    ClockRangePtr clockRanges;
108095b296d0Smrg    Bool ddcLoaded = FALSE;
108195b296d0Smrg    xf86MonPtr pMon = NULL;
108295b296d0Smrg    char *s;
108395b296d0Smrg    Bool tmp_bool;
108495b296d0Smrg
108595b296d0Smrg    /* Allocate the TRIDENTRec driverPrivate */
108695b296d0Smrg    if (!TRIDENTGetRec(pScrn)) {
108795b296d0Smrg	return FALSE;
108895b296d0Smrg    }
108995b296d0Smrg    pTrident = TRIDENTPTR(pScrn);
109095b296d0Smrg    pTrident->pScrn = pScrn;
109195b296d0Smrg
109295b296d0Smrg    if (pScrn->numEntities > 1)
109395b296d0Smrg	return FALSE;
109495b296d0Smrg    /* This is the general case */
109595b296d0Smrg    for (i = 0; i<pScrn->numEntities; i++) {
109695b296d0Smrg	pTrident->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
109795b296d0Smrg	if (pTrident->pEnt->resources) return FALSE;
109895b296d0Smrg	pTrident->Chipset = pTrident->pEnt->chipset;
109995b296d0Smrg	pScrn->chipset = (char *)xf86TokenToString(TRIDENTChipsets,
110095b296d0Smrg						   pTrident->pEnt->chipset);
110195b296d0Smrg	/* This driver can handle ISA and PCI buses */
110295b296d0Smrg	if (pTrident->pEnt->location.type == BUS_PCI) {
110395b296d0Smrg	    pTrident->PciInfo = xf86GetPciInfoForEntity(pTrident->pEnt->index);
1104ff89ac2bSmrg#ifndef XSERVER_LIBPCIACCESS
1105ff89ac2bSmrg	    pTrident->PciTag = PCI_DEV_TAG(pTrident->PciInfo);
1106ff89ac2bSmrg#endif
110795b296d0Smrg    	    pTrident->Linear = TRUE;
110895b296d0Smrg	} else {
110995b296d0Smrg    	    pTrident->Linear = FALSE;
111095b296d0Smrg	}
111195b296d0Smrg    }
111295b296d0Smrg
111395b296d0Smrg    if (flags & PROBE_DETECT) {
111495b296d0Smrg	TRIDENTProbeDDC(pScrn, pTrident->pEnt->index);
111595b296d0Smrg	return TRUE;
111695b296d0Smrg    }
111795b296d0Smrg
111895b296d0Smrg    /* Set pScrn->monitor */
111995b296d0Smrg    pScrn->monitor = pScrn->confScreen->monitor;
112095b296d0Smrg
112195b296d0Smrg    /*
112295b296d0Smrg     * The first thing we should figure out is the depth, bpp, etc.
112395b296d0Smrg     * Our preference for depth 24 is 24bpp, so tell it that too.
112495b296d0Smrg     */
112595b296d0Smrg    if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb |
112695b296d0Smrg			    SupportConvert32to24 /*| PreferConvert32to24*/)) {
112795b296d0Smrg	return FALSE;
112895b296d0Smrg    } else {
112995b296d0Smrg	/* Check that the returned depth is one we support */
113095b296d0Smrg	switch (pScrn->depth) {
113195b296d0Smrg	case 8:
113295b296d0Smrg	    if (pScrn->bitsPerPixel != pScrn->depth) {
113395b296d0Smrg	        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
113495b296d0Smrg	     "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
113595b296d0Smrg		       pScrn->depth, pScrn->bitsPerPixel);
113695b296d0Smrg		return FALSE;
113795b296d0Smrg	    }
113895b296d0Smrg	    break;
113995b296d0Smrg	case 15:
114095b296d0Smrg	case 16:
114195b296d0Smrg	    if (pScrn->bitsPerPixel != 16) {
114295b296d0Smrg	        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
114395b296d0Smrg	     "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
114495b296d0Smrg		       pScrn->depth, pScrn->bitsPerPixel);
114595b296d0Smrg		return FALSE;
114695b296d0Smrg	    }
114795b296d0Smrg	    break;
114895b296d0Smrg	case 24:
114995b296d0Smrg	    if ((pScrn->bitsPerPixel != 24) && (pScrn->bitsPerPixel != 32)) {
115095b296d0Smrg	        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
115195b296d0Smrg	     "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
115295b296d0Smrg		       pScrn->depth, pScrn->bitsPerPixel);
115395b296d0Smrg		return FALSE;
115495b296d0Smrg	    }
115595b296d0Smrg	    /* OK */
115695b296d0Smrg	    break;
115795b296d0Smrg	default:
115895b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
115995b296d0Smrg		       "Given depth (%d) is not supported by this driver\n",
116095b296d0Smrg		       pScrn->depth);
116195b296d0Smrg	    return FALSE;
116295b296d0Smrg	}
116395b296d0Smrg    }
116495b296d0Smrg
116595b296d0Smrg    xf86PrintDepthBpp(pScrn);
116695b296d0Smrg
116795b296d0Smrg    /* Get the depth24 pixmap format */
116895b296d0Smrg    if (pScrn->depth == 24 && pix24bpp == 0)
116995b296d0Smrg	pix24bpp = xf86GetBppFromDepth(pScrn, 24);
117095b296d0Smrg
117195b296d0Smrg    /* The vgahw module should be loaded here when needed */
117295b296d0Smrg    if (!xf86LoadSubModule(pScrn, "vgahw"))
117395b296d0Smrg	return FALSE;
117495b296d0Smrg
117595b296d0Smrg    xf86LoaderReqSymLists(vgahwSymbols, NULL);
117695b296d0Smrg
117795b296d0Smrg    /*
117895b296d0Smrg     * Allocate a vgaHWRec
117995b296d0Smrg     */
118095b296d0Smrg    if (!vgaHWGetHWRec(pScrn))
118195b296d0Smrg	return FALSE;
118295b296d0Smrg
118395b296d0Smrg    hwp = VGAHWPTR(pScrn);
118495b296d0Smrg    vgaHWGetIOBase(hwp);
118595b296d0Smrg    vgaIOBase = hwp->IOBase;
118695b296d0Smrg    pTrident->PIOBase = hwp->PIOOffset;
118795b296d0Smrg
118895b296d0Smrg    xf86SetOperatingState(resVga, pTrident->pEnt->index, ResUnusedOpr);
118995b296d0Smrg
119095b296d0Smrg    /* The ramdac module should be loaded here when needed */
119195b296d0Smrg    if (!xf86LoadSubModule(pScrn, "ramdac"))
119295b296d0Smrg	return FALSE;
119395b296d0Smrg
119495b296d0Smrg    xf86LoaderReqSymLists(ramdacSymbols, NULL);
119595b296d0Smrg
119695b296d0Smrg    /*
119795b296d0Smrg     * This must happen after pScrn->display has been set because
119895b296d0Smrg     * xf86SetWeight references it.
119995b296d0Smrg     */
120095b296d0Smrg    if (pScrn->depth > 8) {
120195b296d0Smrg	/* The defaults are OK for us */
120295b296d0Smrg	rgb zeros = {0, 0, 0};
120395b296d0Smrg
120495b296d0Smrg	if (!xf86SetWeight(pScrn, zeros, zeros)) {
120595b296d0Smrg	    return FALSE;
120695b296d0Smrg	} else {
120795b296d0Smrg	    /* XXX check that weight returned is supported */
120895b296d0Smrg            ;
120995b296d0Smrg        }
121095b296d0Smrg    }
121195b296d0Smrg
121295b296d0Smrg    if (!xf86SetDefaultVisual(pScrn, -1)) {
121395b296d0Smrg	return FALSE;
121495b296d0Smrg    } else {
121595b296d0Smrg	/* We don't currently support DirectColor at > 8bpp */
121695b296d0Smrg	if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
121795b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
121895b296d0Smrg		       " (%s) is not supported at depth %d\n",
121995b296d0Smrg		       xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
122095b296d0Smrg	    return FALSE;
122195b296d0Smrg	}
122295b296d0Smrg    }
122395b296d0Smrg
122495b296d0Smrg    /*
122595b296d0Smrg     * The new cmap layer needs this to be initialised.
122695b296d0Smrg     */
122795b296d0Smrg
122895b296d0Smrg    {
122995b296d0Smrg	Gamma zeros = {0.0, 0.0, 0.0};
123095b296d0Smrg
123195b296d0Smrg	if (!xf86SetGamma(pScrn, zeros)) {
123295b296d0Smrg	    return FALSE;
123395b296d0Smrg	}
123495b296d0Smrg    }
123595b296d0Smrg
123695b296d0Smrg    /* Collect all of the relevant option flags (fill in pScrn->options) */
123795b296d0Smrg    xf86CollectOptions(pScrn, NULL);
123895b296d0Smrg
123995b296d0Smrg    /* Process the options */
124095b296d0Smrg    if (!(pTrident->Options = xalloc(sizeof(TRIDENTOptions))))
124195b296d0Smrg	return FALSE;
124295b296d0Smrg    memcpy(pTrident->Options, TRIDENTOptions, sizeof(TRIDENTOptions));
124395b296d0Smrg    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTrident->Options);
124495b296d0Smrg
124595b296d0Smrg    /* Set the bits per RGB for 8bpp mode */
124695b296d0Smrg    if (pScrn->depth == 8) {
124795b296d0Smrg	/* XXX This is here just to test options. */
124895b296d0Smrg	/* Default to 8 */
124995b296d0Smrg	pScrn->rgbBits = 6;
125095b296d0Smrg#if 0
125195b296d0Smrg	if (xf86GetOptValInteger(pTrident->Options, OPTION_RGB_BITS,
125295b296d0Smrg				 &pScrn->rgbBits)) {
125395b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
125495b296d0Smrg		       pScrn->rgbBits);
125595b296d0Smrg	}
125695b296d0Smrg#endif
125795b296d0Smrg    }
125895b296d0Smrg    from = X_DEFAULT;
125995b296d0Smrg
126095b296d0Smrg    pTrident->useEXA = FALSE;
126195b296d0Smrg    if ((s = (char *)xf86GetOptValString(pTrident->Options,
126295b296d0Smrg					 OPTION_ACCELMETHOD))) {
126395b296d0Smrg	if (!xf86NameCmp(s, "EXA")) {
126495b296d0Smrg	    pTrident->useEXA = TRUE;
126595b296d0Smrg	    from = X_CONFIG;
126695b296d0Smrg	}
126795b296d0Smrg	else if (!xf86NameCmp(s, "XAA")) {
126895b296d0Smrg	    pTrident->useEXA = FALSE;
126995b296d0Smrg	    from = X_CONFIG;
127095b296d0Smrg	}
127195b296d0Smrg    }
127295b296d0Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n",
127395b296d0Smrg	       pTrident->useEXA ? "EXA" : "XAA");
127495b296d0Smrg
127595b296d0Smrg    pTrident->HWCursor = TRUE;
127695b296d0Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_SW_CURSOR, FALSE)) {
127795b296d0Smrg	from = X_CONFIG;
127895b296d0Smrg	pTrident->HWCursor = FALSE;
127995b296d0Smrg    }
128095b296d0Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOACCEL, FALSE)) {
128195b296d0Smrg	pTrident->NoAccel = TRUE;
128295b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
128395b296d0Smrg    }
128495b296d0Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_PCI_RETRY, FALSE)) {
128595b296d0Smrg	pTrident->UsePCIRetry = TRUE;
128695b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
128795b296d0Smrg    }
128895b296d0Smrg    pTrident->UsePCIBurst = TRUE;
128995b296d0Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOPCIBURST, FALSE)) {
129095b296d0Smrg	pTrident->UsePCIBurst = FALSE;
129195b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI Burst disbled\n");
129295b296d0Smrg    }
129395b296d0Smrg    /* Display Size override moved to DDC section */
129495b296d0Smrg    if(xf86GetOptValInteger(pTrident->Options, OPTION_VIDEO_KEY,
129595b296d0Smrg						&(pTrident->videoKey))) {
129695b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
129795b296d0Smrg							pTrident->videoKey);
129895b296d0Smrg    } else {
129995b296d0Smrg	pTrident->videoKey =  (1 << pScrn->offset.red) |
130095b296d0Smrg			(1 << pScrn->offset.green) |
130195b296d0Smrg			(((pScrn->mask.blue >> pScrn->offset.blue) - 1)
130295b296d0Smrg			<< pScrn->offset.blue);
130395b296d0Smrg    }
130495b296d0Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOMMIO, FALSE)) {
130595b296d0Smrg	pTrident->NoMMIO = TRUE;
130695b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO Disabled\n");
130795b296d0Smrg    }
130895b296d0Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_MMIO_ONLY, FALSE)) {
130995b296d0Smrg	if (pTrident->NoMMIO)
131095b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MMIO only cannot be set"
131195b296d0Smrg		       " with NoMMIO\n");
131295b296d0Smrg	else {
131395b296d0Smrg	    pTrident->MMIOonly = TRUE;
131495b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO only enabled\n");
131595b296d0Smrg	}
131695b296d0Smrg    }
131795b296d0Smrg
131895b296d0Smrg    pTrident->dspOverride = 0;
131995b296d0Smrg    if ((s = xf86GetOptValString(pTrident->Options, OPTION_DISPLAY))) {
132095b296d0Smrg	if(!xf86NameCmp(s, "CRT")) {
132195b296d0Smrg	    pTrident->dspOverride = CRT_ACTIVE;
132295b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD off CRT on\n");
132395b296d0Smrg	} else if (!xf86NameCmp(s, "LCD")) {
132495b296d0Smrg	    pTrident->dspOverride = LCD_ACTIVE;
132595b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT off\n");
132695b296d0Smrg	} else if (!xf86NameCmp(s, "Dual")) {
132795b296d0Smrg	    pTrident->dspOverride = LCD_ACTIVE | CRT_ACTIVE;
132895b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT on\n");
132995b296d0Smrg	} else
133095b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex,X_ERROR,
133195b296d0Smrg		       "%s is an unknown display option\n",s);
133295b296d0Smrg    }
133395b296d0Smrg    if ((s = xf86GetOptValString(pTrident->Options, OPTION_GB))) {
133495b296d0Smrg	int brightness = -1;
133595b296d0Smrg	double gamma = -1.0;
133695b296d0Smrg	Bool error = FALSE;
133795b296d0Smrg	int i;
133895b296d0Smrg
133995b296d0Smrg	i = sscanf(s,"%lf %i",&gamma,&brightness);
134095b296d0Smrg
134195b296d0Smrg	if (i != 2 || brightness == -1 || gamma == -1.0) {
134295b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
134395b296d0Smrg		       "Invalid Gamma/Brightness argument: %s\n",s);
134495b296d0Smrg	    error = TRUE;
134595b296d0Smrg	} else {
134695b296d0Smrg	    if (brightness < 0 || brightness > 128) {
134795b296d0Smrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
134895b296d0Smrg			   "brightness out of range [0,128]: %i\n",brightness);
134995b296d0Smrg		error = TRUE;
135095b296d0Smrg	    }
135195b296d0Smrg	    if (gamma <= 0.0 || gamma > 10.0) {
135295b296d0Smrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
135395b296d0Smrg			   "gamma out of range (0,10.0]: %f\n",gamma);
135495b296d0Smrg		error = TRUE;
135595b296d0Smrg	    }
135695b296d0Smrg	}
135795b296d0Smrg
135895b296d0Smrg	if (!error) {
135995b296d0Smrg	    pTrident->GammaBrightnessOn = TRUE;
136095b296d0Smrg	    pTrident->gamma = gamma;
136195b296d0Smrg	    pTrident->brightness = brightness;
136295b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Gamma: %f Brightness: %i\n",
136395b296d0Smrg		       gamma,brightness);
136495b296d0Smrg	}
136595b296d0Smrg    }
136695b296d0Smrg
136795b296d0Smrg    /* The following is a temporary hack */
136895b296d0Smrg    pTrident->FPDelay = 7; /* invalid value */
136995b296d0Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_FP_DELAY,
137095b296d0Smrg			     &pTrident->FPDelay)) {
137195b296d0Smrg	if (pTrident->FPDelay < -2 || pTrident->FPDelay > 5) {
137295b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "FPDelay %i out if range "
137395b296d0Smrg		       "(-2 < FPDelay < 5)\n",pTrident->FPDelay);
137495b296d0Smrg	    pTrident->FPDelay = 7;
137595b296d0Smrg	} else
137695b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "FP Delay set to %i\n",
137795b296d0Smrg		   pTrident->FPDelay);
137895b296d0Smrg    }
137995b296d0Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_SHADOW, FALSE)) {
138095b296d0Smrg	pTrident->CyberShadow = TRUE;
138195b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Shadow enabled\n");
138295b296d0Smrg    }
138395b296d0Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_STRETCH, FALSE)) {
138495b296d0Smrg	pTrident->CyberStretch = TRUE;
138595b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Stretch enabled\n");
138695b296d0Smrg    }
138795b296d0Smrg
138895b296d0Smrg    pTrident->MUXThreshold = 90000; /* 90MHz */
138995b296d0Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_MUX_THRESHOLD,
139095b296d0Smrg						&pTrident->MUXThreshold)) {
139195b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MUX Threshold set to %d\n",
139295b296d0Smrg						pTrident->MUXThreshold);
139395b296d0Smrg    }
139495b296d0Smrg    pTrident->OverrideHsync = 0;
139595b296d0Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC,
139695b296d0Smrg						&pTrident->OverrideHsync)) {
139795b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n",
139895b296d0Smrg						pTrident->OverrideHsync);
139995b296d0Smrg    }
140095b296d0Smrg    pTrident->OverrideVsync = 0;
140195b296d0Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC,
140295b296d0Smrg						&pTrident->OverrideVsync)) {
140395b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n",
140495b296d0Smrg						pTrident->OverrideVsync);
140595b296d0Smrg    }
140695b296d0Smrg    pTrident->OverrideHsync = 0;
140795b296d0Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC,
140895b296d0Smrg						&pTrident->OverrideHsync)) {
140995b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n",
141095b296d0Smrg						pTrident->OverrideHsync);
141195b296d0Smrg    }
141295b296d0Smrg    pTrident->OverrideVsync = 0;
141395b296d0Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC,
141495b296d0Smrg						&pTrident->OverrideVsync)) {
141595b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n",
141695b296d0Smrg						pTrident->OverrideVsync);
141795b296d0Smrg    }
141895b296d0Smrg    pTrident->OverrideRskew = 0;
141995b296d0Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_RSKEW,
142095b296d0Smrg						&pTrident->OverrideRskew)) {
142195b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Rskew set to %d\n",
142295b296d0Smrg						pTrident->OverrideRskew);
142395b296d0Smrg    }
142495b296d0Smrg    pTrident->OverrideBskew = 0;
142595b296d0Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_BSKEW,
142695b296d0Smrg						&pTrident->OverrideBskew)) {
142795b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Bskew set to %d\n",
142895b296d0Smrg						pTrident->OverrideBskew);
142995b296d0Smrg    }
143095b296d0Smrg    if (xf86ReturnOptValBool(pTrident->Options, OPTION_SHADOW_FB, FALSE)) {
143195b296d0Smrg        if (!pTrident->Linear)
143295b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option SHADOW_FB"
143395b296d0Smrg		       " in non-Linear Mode\n");
143495b296d0Smrg	else {
143595b296d0Smrg	    pTrident->ShadowFB = TRUE;
143695b296d0Smrg	    pTrident->NoAccel = TRUE;
143795b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
143895b296d0Smrg		    "Using \"Shadow Framebuffer\" - acceleration disabled\n");
143995b296d0Smrg	}
144095b296d0Smrg    }
144195b296d0Smrg    pTrident->Rotate = 0;
144295b296d0Smrg    if ((s = xf86GetOptValString(pTrident->Options, OPTION_ROTATE))) {
144395b296d0Smrg        if (!pTrident->Linear)
144495b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option ROTATE "
144595b296d0Smrg		       "in non-Linear Mode\n");
144695b296d0Smrg	else {
144795b296d0Smrg	    if(!xf86NameCmp(s, "CW")) {
144895b296d0Smrg	        /* accel is disabled below for shadowFB */
144995b296d0Smrg	        pTrident->ShadowFB = TRUE;
145095b296d0Smrg		pTrident->NoAccel = TRUE;
145195b296d0Smrg		pTrident->HWCursor = FALSE;
145295b296d0Smrg		pTrident->Rotate = 1;
145395b296d0Smrg		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
145495b296d0Smrg		       "Rotating screen clockwise - acceleration disabled\n");
145595b296d0Smrg	    } else if(!xf86NameCmp(s, "CCW")) {
145695b296d0Smrg 	        pTrident->ShadowFB = TRUE;
145795b296d0Smrg		pTrident->NoAccel = TRUE;
145895b296d0Smrg		pTrident->HWCursor = FALSE;
145995b296d0Smrg		pTrident->Rotate = -1;
146095b296d0Smrg		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,  "Rotating screen"
146195b296d0Smrg			   "counter clockwise - acceleration disabled\n");
146295b296d0Smrg	    } else {
146395b296d0Smrg	        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
146495b296d0Smrg			   "value for Option \"Rotate\"\n", s);
146595b296d0Smrg		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
146695b296d0Smrg			   "Valid options are \"CW\" or \"CCW\"\n");
146795b296d0Smrg	    }
146895b296d0Smrg	}
146995b296d0Smrg    }
147095b296d0Smrg
147195b296d0Smrg    pTrident->TVChipset = 0;
147295b296d0Smrg    if ((s = xf86GetOptValString(pTrident->Options, OPTION_TV_CHIPSET))) {
147395b296d0Smrg	if(!xf86NameCmp(s, "VT1621")) {
147495b296d0Smrg	    pTrident->TVChipset = 1;
147595b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Using VIA VT1621 TV chip\n");
147695b296d0Smrg	} else if (!xf86NameCmp(s, "CH7005")) {
147795b296d0Smrg	    pTrident->TVChipset = 2;
147895b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Using Chrontel CH7005 TV chip\n");
147995b296d0Smrg	} else
148095b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex,X_ERROR,
148195b296d0Smrg		       "%s is an unknown TV chipset option\n",s);
148295b296d0Smrg    }
148395b296d0Smrg    /* Default : NTSC */
148495b296d0Smrg    pTrident->TVSignalMode=0;
148595b296d0Smrg    if (xf86GetOptValInteger(pTrident->Options, OPTION_TV_SIGNALMODE,
148695b296d0Smrg						&pTrident->TVSignalMode)) {
148795b296d0Smrg	ErrorF("TV SignalMode set to %d\n",pTrident->TVSignalMode);
148895b296d0Smrg    }
148995b296d0Smrg
149095b296d0Smrg    /* FIXME ACCELERATION */
149195b296d0Smrg    if (!UseMMIO) pTrident->NoAccel = TRUE;
149295b296d0Smrg
149395b296d0Smrg    if (pTrident->Linear) {
149495b296d0Smrg    	if (pTrident->pEnt->device->MemBase != 0) {
149595b296d0Smrg	    /*
149695b296d0Smrg	     * XXX Should check that the config file value matches one of the
149795b296d0Smrg	     * PCI base address values.
149895b296d0Smrg	     */
149995b296d0Smrg	    pTrident->FbAddress = pTrident->pEnt->device->MemBase;
150095b296d0Smrg	    from = X_CONFIG;
150195b296d0Smrg    	} else {
150295b296d0Smrg    	    if (IsPciCard)
1503ff89ac2bSmrg	    	pTrident->FbAddress = PCI_REGION_BASE(pTrident->PciInfo, 0, REGION_MEM) & 0xFFFFFFF0;
150495b296d0Smrg	    else
150595b296d0Smrg	    	pTrident->FbAddress = 0xA0000;
150695b296d0Smrg    	}
150795b296d0Smrg
150895b296d0Smrg    	xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
150995b296d0Smrg	       (unsigned long)pTrident->FbAddress);
151095b296d0Smrg    }
151195b296d0Smrg
151295b296d0Smrg    if (UseMMIO) {
151395b296d0Smrg    	if (pTrident->pEnt->device->IOBase != 0) {
151495b296d0Smrg	    /*
151595b296d0Smrg	     * XXX Should check that the config file value matches one of the
151695b296d0Smrg	     * PCI base address values.
151795b296d0Smrg	     */
151895b296d0Smrg	    pTrident->IOAddress = pTrident->pEnt->device->IOBase;
151995b296d0Smrg	    from = X_CONFIG;
152095b296d0Smrg    	} else {
152195b296d0Smrg    	    if (IsPciCard)
1522ff89ac2bSmrg	    	pTrident->IOAddress = PCI_REGION_BASE(pTrident->PciInfo, 1, REGION_MEM) & 0xFFFFC000;
152395b296d0Smrg	    else
152495b296d0Smrg	    	/* FIXME - Multihead UNAWARE */
152595b296d0Smrg    	    	pTrident->IOAddress = 0xBF000;
152695b296d0Smrg    	}
152795b296d0Smrg
152895b296d0Smrg    	xf86DrvMsg(pScrn->scrnIndex,X_PROBED,"IO registers at 0x%lX\n",
152995b296d0Smrg		   (unsigned long)pTrident->IOAddress);
153095b296d0Smrg    }
153195b296d0Smrg
153295b296d0Smrg    /* Register the PCI-assigned resources. */
153395b296d0Smrg    if (xf86RegisterResources(pTrident->pEnt->index, NULL, ResExclusive)) {
153495b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
153595b296d0Smrg		   "xf86RegisterResources() found resource conflicts\n");
153695b296d0Smrg	return FALSE;
153795b296d0Smrg    }
153895b296d0Smrg
153995b296d0Smrg    /* Initialize VBE if possible
154095b296d0Smrg     * Don't move this past MMIO enable!!
154195b296d0Smrg     * PIO access will be blocked
154295b296d0Smrg     * when MMIO is turned on!
154395b296d0Smrg     */
154495b296d0Smrg
154595b296d0Smrg    if (xf86LoadSubModule(pScrn, "vbe")) {
154695b296d0Smrg	vbeInfoPtr pVbe;
154795b296d0Smrg
154895b296d0Smrg        xf86LoaderReqSymLists(vbeSymbols, NULL);
154995b296d0Smrg	pVbe =  VBEInit(NULL,pTrident->pEnt->index);
155095b296d0Smrg	pMon = vbeDoEDID(pVbe, NULL);
155195b296d0Smrg#ifdef VBE_INFO
155295b296d0Smrg	{
155395b296d0Smrg	    VbeInfoBlock* vbeInfoBlockPtr;
155495b296d0Smrg	    if ((vbeInfoBlockPtr = VBEGetVBEInfo(pVbe))) {
155595b296d0Smrg		pTrident->vbeModes = VBEBuildVbeModeList(pVbe,vbeInfoBlockPtr);
155695b296d0Smrg		VBEFreeVBEInfo(vbeInfoBlockPtr);
155795b296d0Smrg	    }
155895b296d0Smrg	}
155995b296d0Smrg#endif
156095b296d0Smrg	vbeFree(pVbe);
156195b296d0Smrg	if (pMon) {
156295b296d0Smrg	    if (!xf86LoadSubModule(pScrn, "ddc")) {
156395b296d0Smrg		TRIDENTFreeRec(pScrn);
156495b296d0Smrg		return FALSE;
156595b296d0Smrg	    } else {
156695b296d0Smrg		xf86LoaderReqSymLists(ddcSymbols, NULL);
156795b296d0Smrg		xf86SetDDCproperties(pScrn,xf86PrintEDID(pMon));
156895b296d0Smrg		ddcLoaded = TRUE;
156995b296d0Smrg	    }
157095b296d0Smrg	}
157195b296d0Smrg
157295b296d0Smrg    }
157395b296d0Smrg
157495b296d0Smrg    if (xf86GetOptValBool(pTrident->Options, OPTION_1400_DISPLAY, &tmp_bool)) {
157595b296d0Smrg	if (tmp_bool)
157695b296d0Smrg	    pTrident->displaySize = 1400;
157795b296d0Smrg    } else
157895b296d0Smrg	pTrident->displaySize = TRIDENTLcdDisplaySize(pMon);
157995b296d0Smrg
158095b296d0Smrg    if (IsPciCard && UseMMIO) {
158195b296d0Smrg    	if (!TRIDENTMapMem(pScrn))
158295b296d0Smrg	    return FALSE;
158395b296d0Smrg
158495b296d0Smrg    	TRIDENTEnableMMIO(pScrn);
158595b296d0Smrg    }
158695b296d0Smrg
158795b296d0Smrg    OUTB(0x3C4, RevisionID); revision = INB(0x3C5);
158895b296d0Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Revision is %d\n",revision);
158995b296d0Smrg
159095b296d0Smrg    pScrn->progClock = TRUE;
159195b296d0Smrg    pTrident->EngineOperation = 0x00;
159295b296d0Smrg    pTrident->IsCyber = FALSE;
159395b296d0Smrg    pTrident->HasSGRAM = FALSE;
159495b296d0Smrg    pTrident->NewClockCode = FALSE;
159595b296d0Smrg    pTrident->MUX = FALSE;
159695b296d0Smrg    Support24bpp = FALSE;
159795b296d0Smrg
159895b296d0Smrg    OUTB(vgaIOBase + 4, InterfaceSel);
159995b296d0Smrg
160095b296d0Smrg    switch (pTrident->Chipset) {
160195b296d0Smrg	case TVGA9000:
160295b296d0Smrg	case TVGA9000i:
160395b296d0Smrg	    pScrn->progClock = FALSE;
160495b296d0Smrg	    NoClocks = 16;
160595b296d0Smrg	    pTrident->NoMMIO = TRUE;
160695b296d0Smrg	    pTrident->NoAccel = TRUE;
160795b296d0Smrg	    pTrident->HWCursor = FALSE;
160895b296d0Smrg	    chipset = "TVGA9000/9000i";
160995b296d0Smrg	    ramtype = "Standard DRAM";
161095b296d0Smrg	    if (pTrident->UsePCIRetry)
161195b296d0Smrg	    	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
161295b296d0Smrg	    pTrident->UsePCIRetry = FALSE; /* Not Supported */
161395b296d0Smrg	    pTrident->frequency = NTSC;
161495b296d0Smrg	    break;
161595b296d0Smrg	case TVGA9100B:
161695b296d0Smrg	    pScrn->progClock = FALSE;
161795b296d0Smrg	    NoClocks = 8;
161895b296d0Smrg	    pTrident->NoMMIO = TRUE;
161995b296d0Smrg	    pTrident->NoAccel = TRUE;
162095b296d0Smrg	    pTrident->HWCursor = FALSE;
162195b296d0Smrg	    chipset = "TVGA9100B";
162295b296d0Smrg	    ramtype = "Standard DRAM";
162395b296d0Smrg	    if (pTrident->UsePCIRetry)
162495b296d0Smrg	    	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
162595b296d0Smrg	    pTrident->UsePCIRetry = FALSE; /* Not Supported */
162695b296d0Smrg	    pTrident->frequency = NTSC;
162795b296d0Smrg	    break;
162895b296d0Smrg	case TVGA8900B:
162995b296d0Smrg	    pScrn->progClock = FALSE;
163095b296d0Smrg	    NoClocks = 8;
163195b296d0Smrg	    pTrident->NoMMIO = TRUE;
163295b296d0Smrg	    pTrident->NoAccel = TRUE;
163395b296d0Smrg	    pTrident->HWCursor = FALSE;
163495b296d0Smrg	    chipset = "TVGA8900B";
163595b296d0Smrg	    ramtype = "Standard DRAM";
163695b296d0Smrg	    if (pTrident->UsePCIRetry)
163795b296d0Smrg	    	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
163895b296d0Smrg	    pTrident->UsePCIRetry = FALSE; /* Not Supported */
163995b296d0Smrg	    pTrident->frequency = NTSC;
164095b296d0Smrg	    break;
164195b296d0Smrg	case TVGA8900C:
164295b296d0Smrg	    pScrn->progClock = FALSE;
164395b296d0Smrg	    NoClocks = 16;
164495b296d0Smrg	    pTrident->NoMMIO = TRUE;
164595b296d0Smrg	    pTrident->NoAccel = TRUE;
164695b296d0Smrg	    pTrident->HWCursor = FALSE;
164795b296d0Smrg	    chipset = "TVGA8900C";
164895b296d0Smrg	    ramtype = "Standard DRAM";
164995b296d0Smrg	    if (pTrident->UsePCIRetry)
165095b296d0Smrg	    	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
165195b296d0Smrg	    pTrident->UsePCIRetry = FALSE; /* Not Supported */
165295b296d0Smrg	    pTrident->frequency = NTSC;
165395b296d0Smrg	    break;
165495b296d0Smrg	case TVGA8900D:
165595b296d0Smrg	    pScrn->progClock = FALSE;
165695b296d0Smrg	    NoClocks = 16;
165795b296d0Smrg	    pTrident->NoMMIO = TRUE;
165895b296d0Smrg	    pTrident->NoAccel = TRUE;
165995b296d0Smrg	    pTrident->HWCursor = FALSE;
166095b296d0Smrg	    chipset = "TVGA8900D";
166195b296d0Smrg	    ramtype = "Standard DRAM";
166295b296d0Smrg	    if (pTrident->UsePCIRetry)
166395b296d0Smrg	    	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
166495b296d0Smrg	    pTrident->UsePCIRetry = FALSE; /* Not Supported */
166595b296d0Smrg	    pTrident->frequency = NTSC;
166695b296d0Smrg	    break;
166795b296d0Smrg	case TVGA9200CXr:
166895b296d0Smrg	    pScrn->progClock = FALSE;
166995b296d0Smrg	    NoClocks = 16;
167095b296d0Smrg	    pTrident->NoMMIO = TRUE;
167195b296d0Smrg	    pTrident->NoAccel = TRUE;
167295b296d0Smrg	    pTrident->HWCursor = FALSE;
167395b296d0Smrg	    chipset = "TVGA9200CXr";
167495b296d0Smrg	    ramtype = "Standard DRAM";
167595b296d0Smrg	    if (pTrident->UsePCIRetry)
167695b296d0Smrg	    	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
167795b296d0Smrg	    pTrident->UsePCIRetry = FALSE; /* Not Supported */
167895b296d0Smrg	    pTrident->frequency = NTSC;
167995b296d0Smrg	    break;
168095b296d0Smrg	case TGUI9400CXi:
168195b296d0Smrg	    pScrn->progClock = FALSE;
168295b296d0Smrg	    NoClocks = 16;
168395b296d0Smrg	    pTrident->NoMMIO = TRUE;
168495b296d0Smrg	    pTrident->NoAccel = TRUE;
168595b296d0Smrg	    pTrident->HWCursor = FALSE;
168695b296d0Smrg	    chipset = "TVGA9200CXr";
168795b296d0Smrg	    ramtype = "Standard DRAM";
168895b296d0Smrg	    if (pTrident->UsePCIRetry)
168995b296d0Smrg	    	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
169095b296d0Smrg	    pTrident->UsePCIRetry = FALSE; /* Not Supported */
169195b296d0Smrg	    pTrident->frequency = NTSC;
169295b296d0Smrg	    break;
169395b296d0Smrg	case TGUI9440AGi:
169495b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
169595b296d0Smrg	    pTrident->HWCursor = FALSE;
169695b296d0Smrg	    chipset = "TGUI9440AGi";
169795b296d0Smrg	    ramtype = "Standard DRAM";
169895b296d0Smrg	    if (pTrident->UsePCIRetry)
169995b296d0Smrg	    	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
170095b296d0Smrg	    pTrident->UsePCIRetry = FALSE; /* Not Supported */
170195b296d0Smrg	    pTrident->frequency = NTSC;
170295b296d0Smrg	    break;
170395b296d0Smrg	case CYBER9320:
170495b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
170595b296d0Smrg	    chipset = "Cyber9320";
170695b296d0Smrg	    ramtype = "Standard DRAM";
170795b296d0Smrg	    if (pTrident->UsePCIRetry)
170895b296d0Smrg	    	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
170995b296d0Smrg	    pTrident->UsePCIRetry = FALSE; /* Not Supported */
171095b296d0Smrg	    break;
171195b296d0Smrg	/* Trident didn't update the PCI ID's and so we have to detemine
171295b296d0Smrg	 * which chips are right ! Then override pTrident->Chipset to
171395b296d0Smrg	 * correct values */
171495b296d0Smrg	case TGUI9660:
171595b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
171695b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
171795b296d0Smrg		ramtype = "EDO Ram";
171895b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C)
171995b296d0Smrg		ramtype = "Standard DRAM";
172095b296d0Smrg	    switch (revision) {
172195b296d0Smrg		case 0x00:
172295b296d0Smrg		    chipset = "TGUI9660";
172395b296d0Smrg		    pTrident->Chipset = TGUI9660;
172495b296d0Smrg		    if (pTrident->UsePCIRetry)
172595b296d0Smrg		    	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
172695b296d0Smrg		    pTrident->UsePCIRetry = FALSE; /* Not Supported */
172795b296d0Smrg		    break;
172895b296d0Smrg		case 0x01:
172995b296d0Smrg		    chipset = "TGUI9680";
173095b296d0Smrg		    pTrident->Chipset = TGUI9680;
173195b296d0Smrg		    if (pTrident->UsePCIRetry)
173295b296d0Smrg		    	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
173395b296d0Smrg		    pTrident->UsePCIRetry = FALSE; /* Not Supported */
173495b296d0Smrg		    break;
173595b296d0Smrg		case 0x10:
173695b296d0Smrg		    chipset = "ProVidia 9682";
173795b296d0Smrg		    Support24bpp = TRUE;
173895b296d0Smrg		    pTrident->Chipset = PROVIDIA9682;
173995b296d0Smrg		    break;
174095b296d0Smrg		case 0x21:
174195b296d0Smrg		    chipset = "ProVidia 9685";
174295b296d0Smrg		    Support24bpp = TRUE;
174395b296d0Smrg		    pTrident->NewClockCode = TRUE;
174495b296d0Smrg		    pTrident->Chipset = PROVIDIA9685;
174595b296d0Smrg		    break;
174695b296d0Smrg		case 0x22:
174795b296d0Smrg		case 0x23:
174895b296d0Smrg		    chipset = "Cyber 9397";
174995b296d0Smrg    	    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
175095b296d0Smrg			ramtype = "EDO Ram";
175195b296d0Smrg    	    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
175295b296d0Smrg			ramtype = "SDRAM";
175395b296d0Smrg    	    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
175495b296d0Smrg			pTrident->HasSGRAM = TRUE;
175595b296d0Smrg			ramtype = "SGRAM";
175695b296d0Smrg	    	    }
175795b296d0Smrg		    pTrident->NewClockCode = TRUE;
175895b296d0Smrg		    pTrident->Chipset = CYBER9397;
175995b296d0Smrg		    pTrident->IsCyber = TRUE;
176095b296d0Smrg		    break;
176195b296d0Smrg		case 0x2a:
176295b296d0Smrg		    chipset = "Cyber 9397/DVD";
176395b296d0Smrg    	    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
176495b296d0Smrg			ramtype = "EDO Ram";
176595b296d0Smrg    	    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
176695b296d0Smrg			ramtype = "SDRAM";
176795b296d0Smrg    	    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
176895b296d0Smrg			pTrident->HasSGRAM = TRUE;
176995b296d0Smrg			ramtype = "SGRAM";
177095b296d0Smrg	    	    }
177195b296d0Smrg		    pTrident->NewClockCode = TRUE;
177295b296d0Smrg		    pTrident->Chipset = CYBER9397DVD;
177395b296d0Smrg		    pTrident->IsCyber = TRUE;
177495b296d0Smrg		    break;
177595b296d0Smrg		case 0x30:
177695b296d0Smrg		case 0x33:
177795b296d0Smrg		case 0x34:
177895b296d0Smrg		case 0x35:
177995b296d0Smrg		case 0xB3:
178095b296d0Smrg		    chipset = "Cyber 9385";
178195b296d0Smrg		    pTrident->NewClockCode = TRUE;
178295b296d0Smrg		    pTrident->Chipset = CYBER9385;
178395b296d0Smrg		    pTrident->IsCyber = TRUE;
178495b296d0Smrg		    break;
178595b296d0Smrg		case 0x38:
178695b296d0Smrg		case 0x3A:
178795b296d0Smrg		    chipset = "Cyber 9385-1";
178895b296d0Smrg		    pTrident->NewClockCode = TRUE;
178995b296d0Smrg		    pTrident->Chipset = CYBER9385;
179095b296d0Smrg		    pTrident->IsCyber = TRUE;
179195b296d0Smrg		    break;
179295b296d0Smrg		case 0x40:
179395b296d0Smrg		case 0x41:
179495b296d0Smrg		case 0x42:
179595b296d0Smrg		case 0x43:
179695b296d0Smrg		    chipset = "Cyber 9382";
179795b296d0Smrg		    pTrident->NewClockCode = TRUE;
179895b296d0Smrg		    pTrident->Chipset = CYBER9382;
179995b296d0Smrg		    pTrident->IsCyber = TRUE;
180095b296d0Smrg		    break;
180195b296d0Smrg		case 0x4A:
180295b296d0Smrg		    chipset = "Cyber 9388";
180395b296d0Smrg    	    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
180495b296d0Smrg			ramtype = "EDO Ram";
180595b296d0Smrg    	    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
180695b296d0Smrg			ramtype = "SDRAM";
180795b296d0Smrg    	    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
180895b296d0Smrg			pTrident->HasSGRAM = TRUE;
180995b296d0Smrg			ramtype = "SGRAM";
181095b296d0Smrg	    	    }
181195b296d0Smrg		    pTrident->NewClockCode = TRUE;
181295b296d0Smrg		    pTrident->Chipset = CYBER9388;
181395b296d0Smrg		    pTrident->IsCyber = TRUE;
181495b296d0Smrg		    break;
181595b296d0Smrg		default:
181695b296d0Smrg		    chipset = "Unknown";
181795b296d0Smrg		    pTrident->Chipset = TGUI9660;
181895b296d0Smrg		    break;
181995b296d0Smrg	    }
182095b296d0Smrg	    break;
182195b296d0Smrg	case CYBER9388:
182295b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
182395b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
182495b296d0Smrg		ramtype = "EDO Ram";
182595b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
182695b296d0Smrg		ramtype = "SDRAM";
182795b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
182895b296d0Smrg		pTrident->HasSGRAM = TRUE;
182995b296d0Smrg		ramtype = "SGRAM";
183095b296d0Smrg	    }
183195b296d0Smrg	    pTrident->IsCyber = TRUE;
183295b296d0Smrg	    Support24bpp = TRUE;
183395b296d0Smrg	    chipset = "Cyber 9388";
183495b296d0Smrg	    pTrident->NewClockCode = TRUE;
183595b296d0Smrg	    break;
183695b296d0Smrg	case CYBER9397:
183795b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
183895b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
183995b296d0Smrg		ramtype = "EDO Ram";
184095b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
184195b296d0Smrg		ramtype = "SDRAM";
184295b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
184395b296d0Smrg		pTrident->HasSGRAM = TRUE;
184495b296d0Smrg		ramtype = "SGRAM";
184595b296d0Smrg	    }
184695b296d0Smrg	    pTrident->IsCyber = TRUE;
184795b296d0Smrg	    Support24bpp = TRUE;
184895b296d0Smrg	    chipset = "Cyber 9397";
184995b296d0Smrg	    pTrident->NewClockCode = TRUE;
185095b296d0Smrg	    break;
185195b296d0Smrg	case CYBER9397DVD:
185295b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
185395b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
185495b296d0Smrg		ramtype = "EDO Ram";
185595b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
185695b296d0Smrg		ramtype = "SDRAM";
185795b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
185895b296d0Smrg		pTrident->HasSGRAM = TRUE;
185995b296d0Smrg		ramtype = "SGRAM";
186095b296d0Smrg	    }
186195b296d0Smrg	    pTrident->IsCyber = TRUE;
186295b296d0Smrg	    Support24bpp = TRUE;
186395b296d0Smrg	    chipset = "Cyber 9397/DVD";
186495b296d0Smrg	    pTrident->NewClockCode = TRUE;
186595b296d0Smrg	    break;
186695b296d0Smrg	case CYBER9520:
186795b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
186895b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
186995b296d0Smrg		ramtype = "EDO Ram";
187095b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
187195b296d0Smrg		ramtype = "SDRAM";
187295b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
187395b296d0Smrg		pTrident->HasSGRAM = TRUE;
187495b296d0Smrg		ramtype = "SGRAM";
187595b296d0Smrg	    }
187695b296d0Smrg	    pTrident->IsCyber = TRUE;
187795b296d0Smrg	    Support24bpp = TRUE;
187895b296d0Smrg	    chipset = "Cyber 9520";
187995b296d0Smrg	    pTrident->NewClockCode = TRUE;
188095b296d0Smrg	    break;
188195b296d0Smrg	case CYBER9525DVD:
188295b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
188395b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
188495b296d0Smrg		ramtype = "EDO Ram";
188595b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
188695b296d0Smrg		ramtype = "SDRAM";
188795b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
188895b296d0Smrg		pTrident->HasSGRAM = TRUE;
188995b296d0Smrg		ramtype = "SGRAM";
189095b296d0Smrg	    }
189195b296d0Smrg	    pTrident->IsCyber = TRUE;
189295b296d0Smrg	    Support24bpp = TRUE;
189395b296d0Smrg	    chipset = "Cyber 9525/DVD";
189495b296d0Smrg	    pTrident->NewClockCode = TRUE;
189595b296d0Smrg	    break;
189695b296d0Smrg	case CYBERBLADEE4:
189795b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
189895b296d0Smrg	    ramtype = "SDRAM";
189995b296d0Smrg	    pTrident->IsCyber = TRUE;
190095b296d0Smrg	    Support24bpp = TRUE;
190195b296d0Smrg	    chipset = "CyberBlade e4/128";
190295b296d0Smrg	    pTrident->NewClockCode = TRUE;
190395b296d0Smrg	    break;
190495b296d0Smrg	case IMAGE975:
190595b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
190695b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
190795b296d0Smrg		ramtype = "EDO Ram";
190895b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
190995b296d0Smrg		ramtype = "SDRAM";
191095b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
191195b296d0Smrg		pTrident->HasSGRAM = TRUE;
191295b296d0Smrg		ramtype = "SGRAM";
191395b296d0Smrg	    }
191495b296d0Smrg	    Support24bpp = TRUE;
191595b296d0Smrg	    chipset = "3DImage975";
191695b296d0Smrg	    pTrident->NewClockCode = TRUE;
191795b296d0Smrg	    break;
191895b296d0Smrg	case IMAGE985:
191995b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
192095b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
192195b296d0Smrg		ramtype = "EDO Ram";
192295b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
192395b296d0Smrg		ramtype = "SDRAM";
192495b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
192595b296d0Smrg		pTrident->HasSGRAM = TRUE;
192695b296d0Smrg		ramtype = "SGRAM";
192795b296d0Smrg	    }
192895b296d0Smrg	    Support24bpp = TRUE;
192995b296d0Smrg	    chipset = "3DImage985";
193095b296d0Smrg	    pTrident->NewClockCode = TRUE;
193195b296d0Smrg	    break;
193295b296d0Smrg	case BLADE3D:
193395b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
193495b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
193595b296d0Smrg		ramtype = "SDRAM";
193695b296d0Smrg    	    if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
193795b296d0Smrg		pTrident->HasSGRAM = TRUE;
193895b296d0Smrg		ramtype = "SGRAM";
193995b296d0Smrg	    }
194095b296d0Smrg	    Support24bpp = TRUE;
194195b296d0Smrg	    chipset = "Blade3D";
194295b296d0Smrg	    pTrident->NewClockCode = TRUE;
194395b296d0Smrg	    pTrident->frequency = NTSC;
194495b296d0Smrg	    pTrident->UsePCIRetry = TRUE; /* To avoid lockups */
194595b296d0Smrg	    break;
194695b296d0Smrg	case CYBERBLADEI7:
194795b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
194895b296d0Smrg	    ramtype = "SDRAM";
194995b296d0Smrg	    /* pTrident->IsCyber = TRUE; VIA MVP4 integrated Desktop version */
195095b296d0Smrg	    Support24bpp = TRUE;
195195b296d0Smrg	    chipset = "CyberBlade/i7/VIA MVP4";
195295b296d0Smrg	    pTrident->NewClockCode = TRUE;
195395b296d0Smrg	    pTrident->frequency = NTSC;
195495b296d0Smrg	    break;
195595b296d0Smrg	case CYBERBLADEI7D:
195695b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
195795b296d0Smrg	    ramtype = "SDRAM";
195895b296d0Smrg	    pTrident->IsCyber = TRUE;
195995b296d0Smrg	    Support24bpp = TRUE;
196095b296d0Smrg	    chipset = "CyberBlade/DSTN/i7";
196195b296d0Smrg	    pTrident->NewClockCode = TRUE;
196295b296d0Smrg	    pTrident->frequency = NTSC;
196395b296d0Smrg	    break;
196495b296d0Smrg	case CYBERBLADEI1:
196595b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
196695b296d0Smrg	    ramtype = "SDRAM";
196795b296d0Smrg	    pTrident->IsCyber = TRUE;
196895b296d0Smrg	    Support24bpp = TRUE;
196995b296d0Smrg	    chipset = "CyberBlade/i1";
197095b296d0Smrg	    pTrident->NewClockCode = TRUE;
197195b296d0Smrg	    pTrident->frequency = NTSC;
197295b296d0Smrg	    break;
197395b296d0Smrg	case CYBERBLADEI1D:
197495b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
197595b296d0Smrg	    ramtype = "SDRAM";
197695b296d0Smrg	    pTrident->IsCyber = TRUE;
197795b296d0Smrg	    Support24bpp = TRUE;
197895b296d0Smrg	    chipset = "CyberBlade/DSTN/i1";
197995b296d0Smrg	    pTrident->NewClockCode = TRUE;
198095b296d0Smrg	    pTrident->frequency = NTSC;
198195b296d0Smrg	    break;
198295b296d0Smrg	case CYBERBLADEAI1:
198395b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
198495b296d0Smrg	    ramtype = "SDRAM";
198595b296d0Smrg	    pTrident->IsCyber = TRUE;
198695b296d0Smrg	    Support24bpp = TRUE;
198795b296d0Smrg	    chipset = "CyberBlade/Ai1";
198895b296d0Smrg	    pTrident->NewClockCode = TRUE;
198995b296d0Smrg	    pTrident->frequency = NTSC;
199095b296d0Smrg	    break;
199195b296d0Smrg	case CYBERBLADEAI1D:
199295b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
199395b296d0Smrg	    ramtype = "SDRAM";
199495b296d0Smrg	    pTrident->IsCyber = TRUE;
199595b296d0Smrg	    Support24bpp = TRUE;
199695b296d0Smrg	    chipset = "CyberBlade/DSTN/Ai1";
199795b296d0Smrg	    pTrident->NewClockCode = TRUE;
199895b296d0Smrg	    pTrident->frequency = NTSC;
199995b296d0Smrg	    break;
200095b296d0Smrg	case BLADEXP: /* 0x9910 */
200195b296d0Smrg	    pTrident->ddc1Read = Tridentddc1Read;
200295b296d0Smrg	    ramtype = "SGRAM";
200395b296d0Smrg	    pTrident->HasSGRAM = TRUE;
200495b296d0Smrg	    Support24bpp = TRUE;
200595b296d0Smrg	    pTrident->NewClockCode = TRUE;
200695b296d0Smrg	    pTrident->frequency = NTSC;
200795b296d0Smrg	    OUTB(0x3C4, 0x5D);
2008ff89ac2bSmrg	    if (PCI_SUB_VENDOR_ID(pTrident->PciInfo) != 0x1023) {
200995b296d0Smrg	    	chipset = "CyberBladeXP";
201095b296d0Smrg	    	pTrident->IsCyber = TRUE;
201195b296d0Smrg	    } else
201295b296d0Smrg	    if (!(INB(0x3C5) & 0x01)) {
201395b296d0Smrg	    	chipset = "BladeXP";
201495b296d0Smrg	    } else {
201595b296d0Smrg		CARD8 mem1, mem2;
201695b296d0Smrg		OUTB(vgaIOBase + 0x04, SPR);
201795b296d0Smrg		mem1 = INB(vgaIOBase + 5);
201895b296d0Smrg		OUTB(vgaIOBase + 0x04, 0xC1);
201995b296d0Smrg		mem2 = INB(vgaIOBase + 5);
202095b296d0Smrg		if ((mem1 & 0x0e) && (mem2 == 0x11)) {
202195b296d0Smrg	    	    chipset = "BladeT64";
202295b296d0Smrg		} else {
202395b296d0Smrg	    	    chipset = "BladeT16";
202495b296d0Smrg		}
202595b296d0Smrg	    }
202695b296d0Smrg	    break;
202795b296d0Smrg	case CYBERBLADEXPAI1:
202895b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
202995b296d0Smrg	    ramtype = "SGRAM";
203095b296d0Smrg            pTrident->HasSGRAM = TRUE;
203195b296d0Smrg	    pTrident->IsCyber = TRUE;
203295b296d0Smrg	    pTrident->shadowNew = TRUE;
203395b296d0Smrg	    Support24bpp = TRUE;
203495b296d0Smrg	    chipset = "CyberBladeXPAi1";
203595b296d0Smrg	    pTrident->NewClockCode = TRUE;
203695b296d0Smrg	    pTrident->frequency = NTSC;
203795b296d0Smrg	    break;
203895b296d0Smrg	case CYBERBLADEXP4:
203995b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
204095b296d0Smrg	    ramtype = "SGRAM";
204195b296d0Smrg            pTrident->HasSGRAM = TRUE;
204295b296d0Smrg	    pTrident->IsCyber = TRUE;
204395b296d0Smrg	    pTrident->shadowNew = TRUE;
204495b296d0Smrg	    Support24bpp = TRUE;
204595b296d0Smrg	    chipset = "CyberBladeXP4";
204695b296d0Smrg	    pTrident->NewClockCode = TRUE;
204795b296d0Smrg	    pTrident->frequency = NTSC;
204895b296d0Smrg	    break;
204995b296d0Smrg	case XP5:
205095b296d0Smrg    	    pTrident->ddc1Read = Tridentddc1Read;
205195b296d0Smrg	    ramtype = "SGRAM";
205295b296d0Smrg            pTrident->HasSGRAM = TRUE;
205395b296d0Smrg	    pTrident->IsCyber = TRUE;
205495b296d0Smrg	    pTrident->shadowNew = TRUE;
205595b296d0Smrg	    Support24bpp = TRUE;
205695b296d0Smrg	    chipset = "XP5";
205795b296d0Smrg	    pTrident->NewClockCode = TRUE;
205895b296d0Smrg	    pTrident->frequency = NTSC;
205995b296d0Smrg	    break;
206095b296d0Smrg    }
206195b296d0Smrg
206295b296d0Smrg    if (!pScrn->progClock) {
206395b296d0Smrg	pScrn->numClocks = NoClocks;
206495b296d0Smrg	xf86GetClocks(pScrn, NoClocks, TRIDENTClockSelect,
206595b296d0Smrg			  vgaHWProtectWeak(),
206695b296d0Smrg			  vgaHWBlankScreenWeak(),
206795b296d0Smrg			  vgaIOBase + 0x0A, 0x08, 1, 28322);
206895b296d0Smrg	from = X_PROBED;
206995b296d0Smrg	xf86ShowClocks(pScrn, from);
207095b296d0Smrg    }
207195b296d0Smrg
207295b296d0Smrg    if (!chipset) {
207395b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No support for \"%s\"\n",
207495b296d0Smrg			pScrn->chipset);
207595b296d0Smrg	if (IsPciCard && UseMMIO) {
207695b296d0Smrg    	    TRIDENTDisableMMIO(pScrn);
207795b296d0Smrg 	    TRIDENTUnmapMem(pScrn);
207895b296d0Smrg	}
207995b296d0Smrg	return FALSE;
208095b296d0Smrg    }
208195b296d0Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Found %s chip\n", chipset);
208295b296d0Smrg    if (ramtype)
208395b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RAM type is %s\n", ramtype);
208495b296d0Smrg
208595b296d0Smrg    if (pScrn->bitsPerPixel == 24 && !Support24bpp) {
208695b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No support for 24bpp on this chipset, use -pixmap32.\n");
208795b296d0Smrg	if (IsPciCard && UseMMIO) {
208895b296d0Smrg    	    TRIDENTDisableMMIO(pScrn);
208995b296d0Smrg 	    TRIDENTUnmapMem(pScrn);
209095b296d0Smrg	}
209195b296d0Smrg	return FALSE;
209295b296d0Smrg    }
209395b296d0Smrg
209495b296d0Smrg    /* HW bpp matches reported bpp */
209595b296d0Smrg    pTrident->HwBpp = pScrn->bitsPerPixel;
209695b296d0Smrg
209795b296d0Smrg    /* Due to bugs in the chip, turn it off */
209895b296d0Smrg    if (pTrident->Chipset >= CYBERBLADEI7 && pTrident->Chipset <= CYBERBLADEAI1D)
209995b296d0Smrg	pTrident->HWCursor = FALSE;
210095b296d0Smrg
210195b296d0Smrg    from = X_PROBED;
210295b296d0Smrg    if (pTrident->pEnt->device->videoRam != 0) {
210395b296d0Smrg	pScrn->videoRam = pTrident->pEnt->device->videoRam;
210495b296d0Smrg	from = X_CONFIG;
210595b296d0Smrg    } else {
210695b296d0Smrg      if (pTrident->Chipset == XP5) {
210795b296d0Smrg	OUTB(vgaIOBase + 4, 0x60);
210895b296d0Smrg	videoram = INB(vgaIOBase + 5);
210995b296d0Smrg	switch (videoram & 0x7) {
211095b296d0Smrg 	case 0x00:
211195b296d0Smrg	    pScrn->videoRam = 65536 /* 131072 */;
211295b296d0Smrg	    break;
211395b296d0Smrg	case 0x01:
211495b296d0Smrg	    pScrn->videoRam = 65536;
211595b296d0Smrg	    break;
211695b296d0Smrg	case 0x02:
211795b296d0Smrg	    pScrn->videoRam = 32768;
211895b296d0Smrg	    break;
211995b296d0Smrg	case 0x03:
212095b296d0Smrg	    pScrn->videoRam = 16384;
212195b296d0Smrg	    break;
212295b296d0Smrg	case 0x04:
212395b296d0Smrg	    pScrn->videoRam = 8192;
212495b296d0Smrg	    break;
212595b296d0Smrg	}
212695b296d0Smrg      } else
212795b296d0Smrg      if (pTrident->Chipset == CYBER9525DVD) {
212895b296d0Smrg	pScrn->videoRam = 2560;
212995b296d0Smrg      } else
213095b296d0Smrg      {
213195b296d0Smrg	OUTB(vgaIOBase + 4, SPR);
213295b296d0Smrg	videoram = INB(vgaIOBase + 5);
213395b296d0Smrg	if (pTrident->Chipset < TGUI9440AGi)
213495b296d0Smrg	    videorammask = 0x07;
213595b296d0Smrg	else
213695b296d0Smrg	    videorammask = 0x0F;
213795b296d0Smrg	switch (videoram & videorammask) {
213895b296d0Smrg  	case 0x01:
213995b296d0Smrg  	    pScrn->videoRam = 512;
214095b296d0Smrg  	    break;
214195b296d0Smrg 	case 0x02: /* XP */
214295b296d0Smrg 	    pScrn->videoRam = 6144;
214395b296d0Smrg 	    break;
214495b296d0Smrg  	case 0x03:
214595b296d0Smrg  	    pScrn->videoRam = 1024;
214695b296d0Smrg  	    break;
214795b296d0Smrg	case 0x04:
214895b296d0Smrg	    pScrn->videoRam = 8192;
214995b296d0Smrg	    break;
215095b296d0Smrg 	case 0x06: /* XP */
215195b296d0Smrg 	    pScrn->videoRam = 10240;
215295b296d0Smrg 	    break;
215395b296d0Smrg  	case 0x07:
215495b296d0Smrg  	    pScrn->videoRam = 2048;
215595b296d0Smrg  	    break;
215695b296d0Smrg 	case 0x08: /* XP */
215795b296d0Smrg 	    pScrn->videoRam = 12288;
215895b296d0Smrg 	    break;
215995b296d0Smrg 	case 0x0A: /* XP */
216095b296d0Smrg 	    pScrn->videoRam = 14336;
216195b296d0Smrg 	    break;
216295b296d0Smrg 	case 0x0C: /* XP */
216395b296d0Smrg 	    pScrn->videoRam = 16384;
216495b296d0Smrg 	    break;
216595b296d0Smrg 	case 0x0E: /* XP */
216695b296d0Smrg 	    OUTB(vgaIOBase + 4, 0xC1);
216795b296d0Smrg 	    switch (INB(vgaIOBase + 5) & 0x11) {
216895b296d0Smrg 		case 0x00:
216995b296d0Smrg 		    pScrn->videoRam = 20480;
217095b296d0Smrg 		    break;
217195b296d0Smrg 		case 0x01:
217295b296d0Smrg 		    pScrn->videoRam = 24576;
217395b296d0Smrg 		    break;
217495b296d0Smrg 		case 0x10:
217595b296d0Smrg 		    pScrn->videoRam = 28672;
217695b296d0Smrg 		    break;
217795b296d0Smrg 		case 0x11:
217895b296d0Smrg 		    pScrn->videoRam = 32768;
217995b296d0Smrg 		    break;
218095b296d0Smrg 	    }
218195b296d0Smrg 	    break;
218295b296d0Smrg 	case 0x0F:
218395b296d0Smrg  	    pScrn->videoRam = 4096;
218495b296d0Smrg  	    break;
218595b296d0Smrg	default:
218695b296d0Smrg	    pScrn->videoRam = 1024;
218795b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex, from,
218895b296d0Smrg			"Unable to determine VideoRam, defaulting to 1MB\n");
218995b296d0Smrg	    break;
219095b296d0Smrg	}
219195b296d0Smrg      }
219295b296d0Smrg    }
219395b296d0Smrg
219495b296d0Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
219595b296d0Smrg		pTrident->HWCursor ? "HW" : "SW");
219695b296d0Smrg
219795b296d0Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
219895b296d0Smrg               pScrn->videoRam);
219995b296d0Smrg
220095b296d0Smrg    if (pTrident->IsCyber) {
220195b296d0Smrg	unsigned char mod, dsp, dsp1;
220295b296d0Smrg
220395b296d0Smrg	pTrident->lcdMode = 0xff;
220495b296d0Smrg
220595b296d0Smrg	OUTB(0x3CE,0x42);
220695b296d0Smrg	dsp = INB(0x3CF);
220795b296d0Smrg	OUTB(0x3CE,0x43);
220895b296d0Smrg	dsp1 = INB(0x3CF);
220995b296d0Smrg	OUTB(0x3CE,0x52);
221095b296d0Smrg	mod = INB(0x3CF);
221195b296d0Smrg	/*
221295b296d0Smrg	 * Only allow display size override if 1280x1024 is detected
221395b296d0Smrg	 * Currently 1400x1050 is supported - which is detected as
221495b296d0Smrg	 * 1280x1024
221595b296d0Smrg	 */
221695b296d0Smrg	if (pTrident->displaySize) {
221795b296d0Smrg	    if (((mod >> 4) & 3) == 0) {
221895b296d0Smrg		for (i = 0; LCD[i].mode != 0xff; i++) {
221995b296d0Smrg		    if (pTrident->displaySize == LCD[i].display_x)
222095b296d0Smrg			pTrident->lcdMode = LCD[i].mode;
222195b296d0Smrg		}
222295b296d0Smrg		xf86DrvMsg(pScrn->scrnIndex,
222395b296d0Smrg			   X_INFO,"%s Panel %ix%i found\n",
222495b296d0Smrg			   (dsp & 0x80) ? "TFT" :
222595b296d0Smrg			   ((dsp1 & 0x20) ? "DSTN" : "STN"),
222695b296d0Smrg			   LCD[i].display_x,LCD[i].display_y);
222795b296d0Smrg	    } else {
222895b296d0Smrg		xf86DrvMsg(pScrn->scrnIndex,X_WARNING,
222995b296d0Smrg			   "Display size override only for 1280x1024\n");
223095b296d0Smrg		pTrident->displaySize = 0;
223195b296d0Smrg	    }
223295b296d0Smrg	}
223395b296d0Smrg
223495b296d0Smrg	if (!pTrident->displaySize) {
223595b296d0Smrg	    for (i = 0; LCD[i].mode != 0xff; i++) {
223695b296d0Smrg		if (LCD[i].mode == ((mod >> 4) & 3)) {
223795b296d0Smrg		    pTrident->lcdMode = i;
223895b296d0Smrg		    xf86DrvMsg(pScrn->scrnIndex,
223995b296d0Smrg			       X_PROBED,"%s Panel %ix%i found\n",
224095b296d0Smrg			       (dsp & 0x80) ? "TFT" :
224195b296d0Smrg			       ((dsp1 & 0x20) ? "DSTN" : "STN"),
224295b296d0Smrg			       LCD[i].display_x,LCD[i].display_y);
224395b296d0Smrg		}
224495b296d0Smrg	    }
224595b296d0Smrg	}
224695b296d0Smrg	if (pTrident->dspOverride) {
224795b296d0Smrg	    if (pTrident->dspOverride & LCD_ACTIVE)
224895b296d0Smrg		pTrident->lcdActive = TRUE;
224995b296d0Smrg	    else
225095b296d0Smrg		pTrident->lcdActive = FALSE;
225195b296d0Smrg	} else {
225295b296d0Smrg	    OUTB(0x3CE, FPConfig);
225395b296d0Smrg	    pTrident->lcdActive = (INB(0x3CF) & 0x10);
225495b296d0Smrg	}
225595b296d0Smrg    }
225695b296d0Smrg
225795b296d0Smrg    pTrident->MCLK = 0;
225895b296d0Smrg    mclk = CalculateMCLK(pScrn);
225995b296d0Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory Clock is %3.2f MHz\n", mclk);
226095b296d0Smrg    if (xf86GetOptValFreq(pTrident->Options, OPTION_SETMCLK, OPTUNITS_MHZ,
226195b296d0Smrg				&real)) {
226295b296d0Smrg	pTrident->MCLK = (int)(real * 1000.0);
226395b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Setting new Memory Clock to %3.2f MHz\n",
226495b296d0Smrg						(float)(pTrident->MCLK / 1000));
226595b296d0Smrg    }
226695b296d0Smrg
226795b296d0Smrg    /* Set the min pixel clock */
226895b296d0Smrg    pTrident->MinClock = 12000;	/* XXX Guess, need to check this */
226995b296d0Smrg    xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
227095b296d0Smrg	       pTrident->MinClock / 1000);
227195b296d0Smrg
227295b296d0Smrg    /*
227395b296d0Smrg     * If the user has specified ramdac speed in the XF86Config
227495b296d0Smrg     * file, we respect that setting.
227595b296d0Smrg     */
227695b296d0Smrg    if (pTrident->pEnt->device->dacSpeeds[0]) {
227795b296d0Smrg	int speed = 0;
227895b296d0Smrg
227995b296d0Smrg	switch (pScrn->bitsPerPixel) {
228095b296d0Smrg	case 8:
228195b296d0Smrg	   speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP8];
228295b296d0Smrg	   break;
228395b296d0Smrg	case 16:
228495b296d0Smrg	   speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP16];
228595b296d0Smrg	   break;
228695b296d0Smrg	case 24:
228795b296d0Smrg	   speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP24];
228895b296d0Smrg	   break;
228995b296d0Smrg	case 32:
229095b296d0Smrg	   speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP32];
229195b296d0Smrg	   break;
229295b296d0Smrg	}
229395b296d0Smrg	if (speed == 0)
229495b296d0Smrg	    pTrident->MaxClock = pTrident->pEnt->device->dacSpeeds[0];
229595b296d0Smrg	else
229695b296d0Smrg	    pTrident->MaxClock = speed;
229795b296d0Smrg	from = X_CONFIG;
229895b296d0Smrg    } else {
229995b296d0Smrg	switch (pScrn->bitsPerPixel) {
230095b296d0Smrg	    case 16:
230195b296d0Smrg		pTrident->MaxClock = ClockLimit16bpp[pTrident->Chipset];
230295b296d0Smrg		break;
230395b296d0Smrg	    case 24:
230495b296d0Smrg		pTrident->MaxClock = ClockLimit24bpp[pTrident->Chipset];
230595b296d0Smrg		break;
230695b296d0Smrg	    case 32:
230795b296d0Smrg		pTrident->MaxClock = ClockLimit32bpp[pTrident->Chipset];
230895b296d0Smrg		break;
230995b296d0Smrg	    default:
231095b296d0Smrg		pTrident->MaxClock = ClockLimit[pTrident->Chipset];
231195b296d0Smrg		break;
231295b296d0Smrg	}
231395b296d0Smrg    }
231495b296d0Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
231595b296d0Smrg	       pTrident->MaxClock / 1000);
231695b296d0Smrg
231795b296d0Smrg    /*
231895b296d0Smrg     * Setup the ClockRanges, which describe what clock ranges are available,
231995b296d0Smrg     * and what sort of modes they can be used for.
232095b296d0Smrg     */
232195b296d0Smrg    clockRanges = xnfcalloc(sizeof(ClockRange), 1);
232295b296d0Smrg    clockRanges->next = NULL;
232395b296d0Smrg    if (!pScrn->progClock) {
232495b296d0Smrg	if (pScrn->videoRam < 1024)
232595b296d0Smrg    	    clockRanges->ClockMulFactor = 2;
232695b296d0Smrg	if (pScrn->bitsPerPixel == 16)
232795b296d0Smrg    	    clockRanges->ClockMulFactor = 2;
232895b296d0Smrg    }
232995b296d0Smrg    clockRanges->minClock = pTrident->MinClock;
233095b296d0Smrg    clockRanges->maxClock = pTrident->MaxClock;
233195b296d0Smrg    clockRanges->clockIndex = -1;		/* programmable */
233295b296d0Smrg    clockRanges->interlaceAllowed = TRUE;
2333ff89ac2bSmrg    clockRanges->doubleScanAllowed = TRUE;
233495b296d0Smrg
233595b296d0Smrg    /*
233695b296d0Smrg     * xf86ValidateModes will check that the mode HTotal and VTotal values
233795b296d0Smrg     * don't exceed the chipset's limit if pScrn->maxHValue and
233895b296d0Smrg     * pScrn->maxVValue are set.  Since our TRIDENTValidMode() already takes
233995b296d0Smrg     * care of this, we don't worry about setting them here.
234095b296d0Smrg     */
234195b296d0Smrg
234295b296d0Smrg    if (pScrn->bitsPerPixel == 24) {
234395b296d0Smrg    	    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
234495b296d0Smrg		"Disabling Engine due to 24bpp.\n");
234595b296d0Smrg	    pTrident->NoAccel = TRUE;
234695b296d0Smrg    }
234795b296d0Smrg
234895b296d0Smrg    /* Select valid modes from those available */
234995b296d0Smrg    if (pTrident->NoAccel || Is3Dchip) {
235095b296d0Smrg	/*
235195b296d0Smrg	 * XXX Assuming min pitch 256, max 4096
235295b296d0Smrg	 * XXX Assuming min height 128, max 4096
235395b296d0Smrg	 */
235495b296d0Smrg	i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
235595b296d0Smrg			      pScrn->display->modes, clockRanges,
235695b296d0Smrg			      NULL, 256, 4096,
235795b296d0Smrg			      pScrn->bitsPerPixel, 128, 4096,
235895b296d0Smrg			      pScrn->display->virtualX,
235995b296d0Smrg			      pScrn->display->virtualY,
236095b296d0Smrg			      pTrident->FbMapSize,
236195b296d0Smrg			      LOOKUP_BEST_REFRESH);
236295b296d0Smrg    } else {
236395b296d0Smrg	/*
236495b296d0Smrg	 * XXX Assuming min height 128, max 2048
236595b296d0Smrg	 */
236695b296d0Smrg	i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
236795b296d0Smrg			      pScrn->display->modes, clockRanges,
236895b296d0Smrg			      GetAccelPitchValues(pScrn), 0, 0,
236995b296d0Smrg			      pScrn->bitsPerPixel, 128, 2048,
237095b296d0Smrg			      pScrn->display->virtualX,
237195b296d0Smrg			      pScrn->display->virtualY,
237295b296d0Smrg			      pTrident->FbMapSize,
237395b296d0Smrg			      LOOKUP_BEST_REFRESH);
237495b296d0Smrg    }
237595b296d0Smrg
237695b296d0Smrg    if (i == -1) {
237795b296d0Smrg	if (IsPciCard && UseMMIO) {
237895b296d0Smrg    	    TRIDENTDisableMMIO(pScrn);
237995b296d0Smrg 	    TRIDENTUnmapMem(pScrn);
238095b296d0Smrg	}
238195b296d0Smrg	TRIDENTFreeRec(pScrn);
238295b296d0Smrg	return FALSE;
238395b296d0Smrg    }
238495b296d0Smrg
238595b296d0Smrg    /* Prune the modes marked as invalid */
238695b296d0Smrg    xf86PruneDriverModes(pScrn);
238795b296d0Smrg
238895b296d0Smrg    if (i == 0 || pScrn->modes == NULL) {
238995b296d0Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
239095b296d0Smrg	if (IsPciCard && UseMMIO) {
239195b296d0Smrg    	    TRIDENTDisableMMIO(pScrn);
239295b296d0Smrg 	    TRIDENTUnmapMem(pScrn);
239395b296d0Smrg	}
239495b296d0Smrg	TRIDENTFreeRec(pScrn);
239595b296d0Smrg	return FALSE;
239695b296d0Smrg    }
239795b296d0Smrg
239895b296d0Smrg    xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
239995b296d0Smrg
240095b296d0Smrg    /* Set the current mode to the first in the list */
240195b296d0Smrg    pScrn->currentMode = pScrn->modes;
240295b296d0Smrg
240395b296d0Smrg    /* Print the list of modes being used */
240495b296d0Smrg    xf86PrintModes(pScrn);
240595b296d0Smrg
240695b296d0Smrg    /* Set display resolution */
240795b296d0Smrg    xf86SetDpi(pScrn, 0, 0);
240895b296d0Smrg
240995b296d0Smrg    /* Load bpp-specific modules */
241095b296d0Smrg    switch (pScrn->bitsPerPixel) {
241195b296d0Smrg    case 8:
241295b296d0Smrg	pTrident->EngineOperation |= 0x00;
241395b296d0Smrg	break;
241495b296d0Smrg    case 16:
241595b296d0Smrg	pTrident->EngineOperation |= 0x01;
241695b296d0Smrg	break;
241795b296d0Smrg    case 24:
241895b296d0Smrg	pTrident->EngineOperation |= 0x03;
241995b296d0Smrg	break;
242095b296d0Smrg    case 32:
242195b296d0Smrg	pTrident->EngineOperation |= 0x02;
242295b296d0Smrg	break;
242395b296d0Smrg    }
242495b296d0Smrg
242595b296d0Smrg    if (xf86LoadSubModule(pScrn, "fb") == NULL) {
242695b296d0Smrg	if (IsPciCard && UseMMIO) {
242795b296d0Smrg    	    TRIDENTDisableMMIO(pScrn);
242895b296d0Smrg 	    TRIDENTUnmapMem(pScrn);
242995b296d0Smrg	}
243095b296d0Smrg	TRIDENTFreeRec(pScrn);
243195b296d0Smrg	return FALSE;
243295b296d0Smrg    }
243395b296d0Smrg
243495b296d0Smrg    xf86LoaderReqSymLists(fbSymbols, NULL);
243595b296d0Smrg
243695b296d0Smrg    if (!xf86LoadSubModule(pScrn, "i2c")) {
243795b296d0Smrg	if (IsPciCard && UseMMIO) {
243895b296d0Smrg    	    TRIDENTDisableMMIO(pScrn);
243995b296d0Smrg 	    TRIDENTUnmapMem(pScrn);
244095b296d0Smrg	}
244195b296d0Smrg	TRIDENTFreeRec(pScrn);
244295b296d0Smrg	return FALSE;
244395b296d0Smrg    }
244495b296d0Smrg
244595b296d0Smrg    xf86LoaderReqSymLists(i2cSymbols, NULL);
244695b296d0Smrg
244795b296d0Smrg    /* Load shadow if needed */
244895b296d0Smrg    if (pTrident->ShadowFB) {
244995b296d0Smrg	if (!xf86LoadSubModule(pScrn, "shadow")) {
245095b296d0Smrg	    TRIDENTFreeRec(pScrn);
245195b296d0Smrg	    return FALSE;
245295b296d0Smrg	}
245395b296d0Smrg	xf86LoaderReqSymLists(shadowSymbols, NULL);
245495b296d0Smrg    }
245595b296d0Smrg
245695b296d0Smrg    /* Load XAA if needed */
245795b296d0Smrg    if (!pTrident->NoAccel) {
245895b296d0Smrg	if (!pTrident->useEXA) {
245995b296d0Smrg	    if (!xf86LoadSubModule(pScrn, "xaa")) {
246095b296d0Smrg		if (IsPciCard && UseMMIO) {
246195b296d0Smrg		    TRIDENTDisableMMIO(pScrn);
246295b296d0Smrg		    TRIDENTUnmapMem(pScrn);
246395b296d0Smrg		}
246495b296d0Smrg		TRIDENTFreeRec(pScrn);
246595b296d0Smrg		return FALSE;
246695b296d0Smrg	    }
246795b296d0Smrg	    xf86LoaderReqSymLists(xaaSymbols, NULL);
246895b296d0Smrg	}
246995b296d0Smrg
247095b296d0Smrg	if (pTrident->useEXA) {
247195b296d0Smrg	    XF86ModReqInfo req;
247295b296d0Smrg	    int errmaj, errmin;
247395b296d0Smrg
247495b296d0Smrg	    memset(&req, 0, sizeof(req));
247595b296d0Smrg
247695b296d0Smrg	    req.majorversion = 2;
247795b296d0Smrg            if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
247895b296d0Smrg		&errmaj, &errmin))
247995b296d0Smrg	    {
248095b296d0Smrg		LoaderErrorMsg(NULL, "exa", errmaj, errmin);
248195b296d0Smrg		if (IsPciCard && UseMMIO) {
248295b296d0Smrg		    TRIDENTDisableMMIO(pScrn);
248395b296d0Smrg		    TRIDENTUnmapMem(pScrn);
248495b296d0Smrg		}
248595b296d0Smrg		TRIDENTFreeRec(pScrn);
248695b296d0Smrg		return FALSE;
248795b296d0Smrg	    }
248895b296d0Smrg	    xf86LoaderReqSymLists(exaSymbols, NULL);
248995b296d0Smrg	}
249095b296d0Smrg
249195b296d0Smrg        switch (pScrn->displayWidth * pScrn->bitsPerPixel / 8) {
249295b296d0Smrg	    case 512:
249395b296d0Smrg	    case 8192:
249495b296d0Smrg		pTrident->EngineOperation |= 0x00;
249595b296d0Smrg		break;
249695b296d0Smrg	    case 1024:
249795b296d0Smrg		pTrident->EngineOperation |= 0x04;
249895b296d0Smrg		break;
249995b296d0Smrg	    case 2048:
250095b296d0Smrg		pTrident->EngineOperation |= 0x08;
250195b296d0Smrg		break;
250295b296d0Smrg	    case 4096:
250395b296d0Smrg		pTrident->EngineOperation |= 0x0C;
250495b296d0Smrg		break;
250595b296d0Smrg	}
250695b296d0Smrg    }
250795b296d0Smrg
250895b296d0Smrg    /* Load DDC if needed */
250995b296d0Smrg    /* This gives us DDC1 - we should be able to get DDC2B using i2c */
251095b296d0Smrg
251195b296d0Smrg    if (! ddcLoaded)
251295b296d0Smrg	if (!xf86LoadSubModule(pScrn, "ddc")) {
251395b296d0Smrg	    if (IsPciCard && UseMMIO) {
251495b296d0Smrg		TRIDENTDisableMMIO(pScrn);
251595b296d0Smrg		TRIDENTUnmapMem(pScrn);
251695b296d0Smrg	    }
251795b296d0Smrg	    TRIDENTFreeRec(pScrn);
251895b296d0Smrg	    return FALSE;
251995b296d0Smrg	}
252095b296d0Smrg
252195b296d0Smrg    xf86LoaderReqSymLists(ddcSymbols, NULL);
252295b296d0Smrg
252395b296d0Smrg    if (IsPciCard && UseMMIO) {
252495b296d0Smrg        TRIDENTDisableMMIO(pScrn);
252595b296d0Smrg	TRIDENTUnmapMem(pScrn);
252695b296d0Smrg    }
252795b296d0Smrg
252895b296d0Smrg    pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
252995b296d0Smrg
253095b296d0Smrg    if (pTrident->IsCyber && pTrident->MMIOonly)
253195b296d0Smrg	pScrn->racIoFlags = 0;
253295b296d0Smrg    else
253395b296d0Smrg	pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
253495b296d0Smrg
253595b296d0Smrg    pTrident->FbMapSize = pScrn->videoRam * 1024;
253695b296d0Smrg
253795b296d0Smrg    return TRUE;
253895b296d0Smrg}
253995b296d0Smrg
254095b296d0Smrg/*
254195b296d0Smrg * Map the framebuffer and MMIO memory.
254295b296d0Smrg */
254395b296d0Smrg
254495b296d0Smrgstatic Bool
254595b296d0SmrgTRIDENTMapMem(ScrnInfoPtr pScrn)
254695b296d0Smrg{
254795b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
254895b296d0Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
254995b296d0Smrg    int mapsize = 0x10000;
255095b296d0Smrg
255195b296d0Smrg    if (Is3Dchip) mapsize = 0x20000;
255295b296d0Smrg
255395b296d0Smrg    if (IsPciCard && UseMMIO)
2554ff89ac2bSmrg#ifndef XSERVER_LIBPCIACCESS
255595b296d0Smrg    	pTrident->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
255695b296d0Smrg		pTrident->PciTag, pTrident->IOAddress, mapsize);
2557ff89ac2bSmrg#else
2558ff89ac2bSmrg	{
2559ff89ac2bSmrg		void **result = (void **)&pTrident->IOBase;
2560ff89ac2bSmrg		int err = pci_device_map_range(pTrident->PciInfo,
2561ff89ac2bSmrg						pTrident->IOAddress,
2562ff89ac2bSmrg						mapsize,
2563ff89ac2bSmrg						PCI_DEV_MAP_FLAG_WRITABLE,
2564ff89ac2bSmrg						result);
2565ff89ac2bSmrg		if (err) {
2566ff89ac2bSmrg			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2567ff89ac2bSmrg				"Unable to map IO aperture. %s (%d)\n",
2568ff89ac2bSmrg				strerror(err), err);
2569ff89ac2bSmrg		}
2570ff89ac2bSmrg	}
2571ff89ac2bSmrg#endif
257295b296d0Smrg    else {
2573ff89ac2bSmrg#ifndef XSERVER_LIBPCIACCESS
257495b296d0Smrg    	pTrident->IOBase = xf86MapDomainMemory(pScrn->scrnIndex, VIDMEM_MMIO,
257595b296d0Smrg		pTrident->PciTag, pTrident->IOAddress, 0x1000);
257695b296d0Smrg    	pTrident->IOBase += 0xF00;
2577ff89ac2bSmrg#else
2578ff89ac2bSmrg	return FALSE;
2579ff89ac2bSmrg#endif
258095b296d0Smrg    }
258195b296d0Smrg
258295b296d0Smrg    if (pTrident->IOBase == NULL)
258395b296d0Smrg	return FALSE;
258495b296d0Smrg
258595b296d0Smrg    if (pTrident->Linear) {
258695b296d0Smrg        if (pTrident->FbMapSize != 0) {
2587ff89ac2bSmrg#ifndef XSERVER_LIBPCIACCESS
258895b296d0Smrg	    pTrident->FbBase = xf86MapPciMem(pScrn->scrnIndex,
258995b296d0Smrg				VIDMEM_FRAMEBUFFER,
259095b296d0Smrg				 pTrident->PciTag,
259195b296d0Smrg				 (unsigned long)pTrident->FbAddress,
259295b296d0Smrg				 pTrident->FbMapSize);
2593ff89ac2bSmrg#else
2594ff89ac2bSmrg	    {
2595ff89ac2bSmrg		void **result = (void **)&pTrident->FbBase;
2596ff89ac2bSmrg		int err = pci_device_map_range(pTrident->PciInfo,
2597ff89ac2bSmrg						pTrident->FbAddress,
2598ff89ac2bSmrg						pTrident->FbMapSize,
2599ff89ac2bSmrg						PCI_DEV_MAP_FLAG_WRITABLE |
2600ff89ac2bSmrg						PCI_DEV_MAP_FLAG_WRITE_COMBINE,
2601ff89ac2bSmrg						result);
2602ff89ac2bSmrg		if (err) {
2603ff89ac2bSmrg			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2604ff89ac2bSmrg				"Unable to map VRAM aperture. %s (%d)\n",
2605ff89ac2bSmrg				strerror(err), err);
2606ff89ac2bSmrg		}
2607ff89ac2bSmrg	    }
2608ff89ac2bSmrg#endif
260995b296d0Smrg	    if (pTrident->FbBase == NULL)
261095b296d0Smrg		return FALSE;
261195b296d0Smrg    	}
261295b296d0Smrg    }
261395b296d0Smrg    else
261495b296d0Smrg	pTrident->FbBase = hwp->Base;
261595b296d0Smrg
261695b296d0Smrg    return TRUE;
261795b296d0Smrg}
261895b296d0Smrg
261995b296d0Smrg/*
262095b296d0Smrg * Unmap the framebuffer and MMIO memory.
262195b296d0Smrg */
262295b296d0Smrg
262395b296d0Smrgstatic Bool
262495b296d0SmrgTRIDENTUnmapMem(ScrnInfoPtr pScrn)
262595b296d0Smrg{
262695b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
262795b296d0Smrg    int mapsize = 0x10000;
262895b296d0Smrg
262995b296d0Smrg    if (Is3Dchip) mapsize = 0x20000;
263095b296d0Smrg
263195b296d0Smrg    /*
263295b296d0Smrg     * Unmap IO registers to virtual address space
263395b296d0Smrg     */
2634ff89ac2bSmrg#ifdef XSERVER_LIBPCIACCESS
2635ff89ac2bSmrg    pci_device_unmap_range(pTrident->PciInfo, (pointer)pTrident->IOBase, mapsize);
2636ff89ac2bSmrg#else
2637ff89ac2bSmrg    if (IsPciCard && UseMMIO) {
263895b296d0Smrg    	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, mapsize);
2639ff89ac2bSmrg    } else {
264095b296d0Smrg    	pTrident->IOBase -= 0xF00;
264195b296d0Smrg    	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, 0x1000);
264295b296d0Smrg    }
2643ff89ac2bSmrg#endif
264495b296d0Smrg    pTrident->IOBase = NULL;
264595b296d0Smrg
264695b296d0Smrg    if (pTrident->Linear) {
264795b296d0Smrg    	if (pTrident->FbMapSize != 0) {
2648ff89ac2bSmrg#ifdef XSERVER_LIBPCIACCESS
2649ff89ac2bSmrg	    pci_device_unmap_range(pTrident->PciInfo, (pointer)pTrident->FbBase, pTrident->FbMapSize);
2650ff89ac2bSmrg#else
265195b296d0Smrg    	    xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->FbBase,
265295b296d0Smrg							pTrident->FbMapSize);
2653ff89ac2bSmrg#endif
2654ff89ac2bSmrg	    pTrident->FbBase = NULL;
265595b296d0Smrg        }
265695b296d0Smrg    }
265795b296d0Smrg
265895b296d0Smrg    return TRUE;
265995b296d0Smrg}
266095b296d0Smrg
266195b296d0Smrg
266295b296d0Smrg/*
266395b296d0Smrg * This function saves the video state.
266495b296d0Smrg */
266595b296d0Smrgstatic void
266695b296d0SmrgTRIDENTSave(ScrnInfoPtr pScrn)
266795b296d0Smrg{
266895b296d0Smrg    TRIDENTPtr pTrident;
266995b296d0Smrg    vgaRegPtr vgaReg;
267095b296d0Smrg    TRIDENTRegPtr tridentReg;
267195b296d0Smrg
267295b296d0Smrg    pTrident = TRIDENTPTR(pScrn);
267395b296d0Smrg    vgaReg = &VGAHWPTR(pScrn)->SavedReg;
267495b296d0Smrg    tridentReg = &pTrident->SavedReg;
267595b296d0Smrg
267695b296d0Smrg    vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP |
267795b296d0Smrg			     (IsPrimaryCard ? VGA_SR_FONTS : 0));
267895b296d0Smrg
267995b296d0Smrg    if (pScrn->progClock)
268095b296d0Smrg    	TridentSave(pScrn, tridentReg);
268195b296d0Smrg    else
268295b296d0Smrg    	TVGASave(pScrn, tridentReg);
268395b296d0Smrg
268495b296d0Smrg    if (pTrident->TVChipset != 0)
268595b296d0Smrg       VIA_SaveTVDepentVGAReg(pScrn);
268695b296d0Smrg}
268795b296d0Smrg
268895b296d0Smrg
268995b296d0Smrg/*
269095b296d0Smrg * Initialise a new mode.  This is currently still using the old
269195b296d0Smrg * "initialise struct, restore/write struct to HW" model.  That could
269295b296d0Smrg * be changed.
269395b296d0Smrg */
269495b296d0Smrg
269595b296d0Smrgstatic Bool
269695b296d0SmrgTRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
269795b296d0Smrg{
269895b296d0Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
269995b296d0Smrg    vgaRegPtr vgaReg;
270095b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
270195b296d0Smrg    TRIDENTRegPtr tridentReg;
270295b296d0Smrg
2703ff89ac2bSmrg    if (!xf86IsPc98()) WAITFORVSYNC;
270495b296d0Smrg
270595b296d0Smrg    TridentFindClock(pScrn,mode->Clock);
270695b296d0Smrg
270795b296d0Smrg    switch (pTrident->Chipset) {
270895b296d0Smrg	case TGUI9660:
270995b296d0Smrg	case TGUI9680:
271095b296d0Smrg	case PROVIDIA9682:
271195b296d0Smrg	case PROVIDIA9685:
271295b296d0Smrg	case IMAGE975:
271395b296d0Smrg	case IMAGE985:
271495b296d0Smrg	case BLADE3D:
271595b296d0Smrg	case CYBERBLADEI7:
271695b296d0Smrg	case CYBERBLADEI7D:
271795b296d0Smrg	case CYBERBLADEI1:
271895b296d0Smrg	case CYBERBLADEI1D:
271995b296d0Smrg	case CYBERBLADEAI1:
272095b296d0Smrg	case CYBERBLADEAI1D:
272195b296d0Smrg	case CYBER9520:
272295b296d0Smrg	case CYBER9525DVD:
272395b296d0Smrg	case CYBERBLADEE4:
272495b296d0Smrg	case CYBER9397:
272595b296d0Smrg	case CYBER9397DVD:
272695b296d0Smrg	case BLADEXP:
272795b296d0Smrg	case CYBERBLADEXPAI1:
272895b296d0Smrg	case CYBERBLADEXP4:
272995b296d0Smrg	case XP5:
273095b296d0Smrg	    /* Get ready for MUX mode */
273195b296d0Smrg	    if (pTrident->MUX &&
273295b296d0Smrg		pScrn->bitsPerPixel == 8 &&
273395b296d0Smrg		!mode->CrtcHAdjusted) {
273495b296d0Smrg		ErrorF("BARF\n");
273595b296d0Smrg		mode->CrtcHDisplay >>= 1;
273695b296d0Smrg		mode->CrtcHSyncStart >>= 1;
273795b296d0Smrg		mode->CrtcHSyncEnd >>= 1;
273895b296d0Smrg		mode->CrtcHBlankStart >>= 1;
273995b296d0Smrg		mode->CrtcHBlankEnd >>= 1;
274095b296d0Smrg		mode->CrtcHTotal >>= 1;
274195b296d0Smrg		mode->CrtcHAdjusted = TRUE;
274295b296d0Smrg	    }
274395b296d0Smrg	    break;
274495b296d0Smrg	default:
274595b296d0Smrg	    if (pScrn->videoRam < 1024 &&
274695b296d0Smrg		!mode->CrtcHAdjusted) {
274795b296d0Smrg		mode->CrtcHDisplay <<= 1;
274895b296d0Smrg		mode->CrtcHSyncStart <<= 1;
274995b296d0Smrg		mode->CrtcHSyncEnd <<= 1;
275095b296d0Smrg		mode->CrtcHBlankStart <<= 1;
275195b296d0Smrg		mode->CrtcHBlankEnd <<= 1;
275295b296d0Smrg		mode->CrtcHTotal <<= 1;
275395b296d0Smrg		mode->CrtcHAdjusted = TRUE;
275495b296d0Smrg	    }
275595b296d0Smrg	    break;
275695b296d0Smrg    }
275795b296d0Smrg
275895b296d0Smrg    vgaHWUnlock(hwp);
275995b296d0Smrg    /* Initialise the ModeReg values */
276095b296d0Smrg    if (!vgaHWInit(pScrn, mode))
276195b296d0Smrg	return FALSE;
276295b296d0Smrg
276395b296d0Smrg    pScrn->vtSema = TRUE;
276495b296d0Smrg    /*
276595b296d0Smrg     * We used to do this at a later time.
276695b296d0Smrg     * Now since READOUT isn't defined any more
276795b296d0Smrg     * we do it here.
276895b296d0Smrg     * The original NOTE read:
276995b296d0Smrg     * TridentInit() has to modify registers
277095b296d0Smrg     * that have already been set by vgaHWRestore().
277195b296d0Smrg     * So we call it _after_ vgaHWRestore() has
277295b296d0Smrg     * programmed these registers.
277395b296d0Smrg     */
277495b296d0Smrg    if (pScrn->progClock) {
277595b296d0Smrg    	if (!TridentInit(pScrn, mode))
277695b296d0Smrg	    return FALSE;
277795b296d0Smrg    } else {
277895b296d0Smrg    	if (!TVGAInit(pScrn, mode))
277995b296d0Smrg	    return FALSE;
278095b296d0Smrg    }
278195b296d0Smrg
278295b296d0Smrg    /* Program the registers */
278395b296d0Smrg    vgaHWProtect(pScrn, TRUE);
278495b296d0Smrg    vgaReg = &hwp->ModeReg;
278595b296d0Smrg    tridentReg = &pTrident->ModeReg;
278695b296d0Smrg
278795b296d0Smrg    vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
278895b296d0Smrg    if (pScrn->progClock)
278995b296d0Smrg    	TridentRestore(pScrn, tridentReg);
279095b296d0Smrg    else
279195b296d0Smrg	TVGARestore(pScrn, tridentReg);
279295b296d0Smrg
279395b296d0Smrg    vgaHWProtect(pScrn, FALSE);
279495b296d0Smrg
279595b296d0Smrg    if (xf86IsPc98())
279695b296d0Smrg	PC98TRIDENTEnable(pScrn);
279795b296d0Smrg
279895b296d0Smrg    if (pTrident->TVChipset != 0)
279995b296d0Smrg       VIA_TVInit(pScrn);
280095b296d0Smrg
280195b296d0Smrg    return TRUE;
280295b296d0Smrg}
280395b296d0Smrg
280495b296d0Smrg/*
280595b296d0Smrg * Restore the initial (text) mode.
280695b296d0Smrg */
280795b296d0Smrgstatic void
280895b296d0SmrgTRIDENTRestore(ScrnInfoPtr pScrn)
280995b296d0Smrg{
281095b296d0Smrg    vgaHWPtr hwp;
281195b296d0Smrg    vgaRegPtr vgaReg;
281295b296d0Smrg    TRIDENTPtr pTrident;
281395b296d0Smrg    TRIDENTRegPtr tridentReg;
281495b296d0Smrg
281595b296d0Smrg    hwp = VGAHWPTR(pScrn);
281695b296d0Smrg    pTrident = TRIDENTPTR(pScrn);
281795b296d0Smrg    vgaReg = &hwp->SavedReg;
281895b296d0Smrg    tridentReg = &pTrident->SavedReg;
281995b296d0Smrg
282095b296d0Smrg    vgaHWProtect(pScrn, TRUE);
282195b296d0Smrg
282295b296d0Smrg    if (pScrn->progClock)
282395b296d0Smrg    	TridentRestore(pScrn, tridentReg);
282495b296d0Smrg    else
282595b296d0Smrg	TVGARestore(pScrn, tridentReg);
282695b296d0Smrg
282795b296d0Smrg    vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP |
282895b296d0Smrg				(IsPrimaryCard ? VGA_SR_FONTS : 0));
282995b296d0Smrg
283095b296d0Smrg    if (pTrident->TVChipset != 0)
283195b296d0Smrg       VIA_RestoreTVDependVGAReg(pScrn);
283295b296d0Smrg
283395b296d0Smrg    vgaHWProtect(pScrn, FALSE);
283495b296d0Smrg}
283595b296d0Smrg
283695b296d0Smrg
283795b296d0Smrg/* Mandatory */
283895b296d0Smrg
283995b296d0Smrg/* This gets called at the start of each server generation */
284095b296d0Smrg
284195b296d0Smrgstatic Bool
284295b296d0SmrgTRIDENTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
284395b296d0Smrg{
284495b296d0Smrg    /* The vgaHW references will disappear one day */
284595b296d0Smrg    ScrnInfoPtr pScrn;
284695b296d0Smrg    vgaHWPtr hwp;
284795b296d0Smrg    TRIDENTPtr pTrident;
284895b296d0Smrg    int ret;
284995b296d0Smrg    VisualPtr visual;
285095b296d0Smrg    unsigned char *FBStart;
285195b296d0Smrg    int width, height, displayWidth;
285295b296d0Smrg
285395b296d0Smrg    /*
285495b296d0Smrg     * First get the ScrnInfoRec
285595b296d0Smrg     */
285695b296d0Smrg    pScrn = xf86Screens[pScreen->myNum];
285795b296d0Smrg    pTrident = TRIDENTPTR(pScrn);
285895b296d0Smrg
285995b296d0Smrg    if (IsPrimaryCard) {
286095b296d0Smrg	if (!vgaHWMapMem(pScrn))
286195b296d0Smrg   	    return FALSE;
286295b296d0Smrg    }
286395b296d0Smrg
286495b296d0Smrg    /* Map the TRIDENT memory and MMIO areas */
286595b296d0Smrg    if (!TRIDENTMapMem(pScrn))
286695b296d0Smrg	return FALSE;
286795b296d0Smrg
286895b296d0Smrg    if (!xf86IsPc98()) {
286995b296d0Smrg#ifdef VBE_INFO
287095b296d0Smrg	if (pTrident->vbeModes) {
287195b296d0Smrg	    pTrident->pVbe = VBEInit(NULL,pTrident->pEnt->index);
287295b296d0Smrg	    pTrident->Int10 = pTrident->pVbe->pInt10;
287395b296d0Smrg	} else
287495b296d0Smrg#endif
287595b296d0Smrg	{
287695b296d0Smrg	    if (xf86LoadSubModule(pScrn, "int10")) {
287795b296d0Smrg		xf86LoaderReqSymLists(int10Symbols, NULL);
287895b296d0Smrg		xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Initializing int10\n");
287995b296d0Smrg		pTrident->Int10 = xf86InitInt10(pTrident->pEnt->index);
288095b296d0Smrg	    }
288195b296d0Smrg	}
288295b296d0Smrg    }
288395b296d0Smrg
288495b296d0Smrg    hwp = VGAHWPTR(pScrn);
288595b296d0Smrg
288695b296d0Smrg    if (IsPciCard && UseMMIO) {
288795b296d0Smrg    	TRIDENTEnableMMIO(pScrn);
288895b296d0Smrg
288995b296d0Smrg    	/* Initialize the MMIO vgahw functions */
289095b296d0Smrg    	vgaHWSetMmioFuncs(hwp, pTrident->IOBase, 0);
289195b296d0Smrg    }
289295b296d0Smrg
289395b296d0Smrg    /* Save the current state */
289495b296d0Smrg    TRIDENTSave(pScrn);
289595b296d0Smrg
289695b296d0Smrg    /*
289795b296d0Smrg     * Some Trident chip on PC-9821 needs setup,
289895b296d0Smrg     * because VGA chip is not initialized by VGA BIOS.
289995b296d0Smrg     */
290095b296d0Smrg    if (IsPciCard && xf86IsPc98()) {
290195b296d0Smrg	 PC98TRIDENTInit(pScrn);
290295b296d0Smrg    } else tridentSetModeBIOS(pScrn,pScrn->currentMode);
290395b296d0Smrg
290495b296d0Smrg    /* Initialise the first mode */
290595b296d0Smrg    if (!TRIDENTModeInit(pScrn, pScrn->currentMode))
290695b296d0Smrg	return FALSE;
290795b296d0Smrg
290895b296d0Smrg    /* Darken the screen for aesthetic reasons and set the viewport */
290995b296d0Smrg    TRIDENTSaveScreen(pScreen, SCREEN_SAVER_ON);
291095b296d0Smrg    TRIDENTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
291195b296d0Smrg
291295b296d0Smrg    /*
291395b296d0Smrg     * The next step is to setup the screen's visuals, and initialise the
291495b296d0Smrg     * framebuffer code.  In cases where the framebuffer's default
291595b296d0Smrg     * choices for things like visual layouts and bits per RGB are OK,
291695b296d0Smrg     * this may be as simple as calling the framebuffer's ScreenInit()
291795b296d0Smrg     * function.  If not, the visuals will need to be setup before calling
291895b296d0Smrg     * a fb ScreenInit() function and fixed up after.
291995b296d0Smrg     *
292095b296d0Smrg     * For most PC hardware at depths >= 8, the defaults that fb uses
292195b296d0Smrg     * are not appropriate.  In this driver, we fixup the visuals after.
292295b296d0Smrg     */
292395b296d0Smrg
292495b296d0Smrg    /*
292595b296d0Smrg     * Reset visual list.
292695b296d0Smrg     */
292795b296d0Smrg    miClearVisualTypes();
292895b296d0Smrg
292995b296d0Smrg    /* Setup the visuals we support. */
293095b296d0Smrg
293195b296d0Smrg    if (!miSetVisualTypes(pScrn->depth,
293295b296d0Smrg			  miGetDefaultVisualMask(pScrn->depth),
293395b296d0Smrg			  pScrn->rgbBits, pScrn->defaultVisual)) {
293495b296d0Smrg	if (pTrident->pVbe)
293595b296d0Smrg	    	vbeFree(pTrident->pVbe);
293695b296d0Smrg	else
293795b296d0Smrg	    xf86FreeInt10(pTrident->Int10);
293895b296d0Smrg      return FALSE;
293995b296d0Smrg    }
294095b296d0Smrg
294195b296d0Smrg    miSetPixmapDepths ();
294295b296d0Smrg
294395b296d0Smrg    /* FIXME - we don't do shadowfb for < 4 */
294495b296d0Smrg    displayWidth = pScrn->displayWidth;
294595b296d0Smrg    if (pTrident->Rotate) {
294695b296d0Smrg	height = pScrn->virtualX;
294795b296d0Smrg	width = pScrn->virtualY;
294895b296d0Smrg    } else {
294995b296d0Smrg	width = pScrn->virtualX;
295095b296d0Smrg	height = pScrn->virtualY;
295195b296d0Smrg    }
295295b296d0Smrg
295395b296d0Smrg    if(pTrident->ShadowFB) {
295495b296d0Smrg 	pTrident->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
295595b296d0Smrg        pTrident->ShadowPtr = xalloc(pTrident->ShadowPitch * height);
295695b296d0Smrg	displayWidth = pTrident->ShadowPitch / (pScrn->bitsPerPixel >> 3);
295795b296d0Smrg        FBStart = pTrident->ShadowPtr;
295895b296d0Smrg    } else {
295995b296d0Smrg	pTrident->ShadowFB = FALSE;
296095b296d0Smrg	pTrident->ShadowPtr = NULL;
296195b296d0Smrg	FBStart = pTrident->FbBase;
296295b296d0Smrg    }
296395b296d0Smrg
296495b296d0Smrg    /*
296595b296d0Smrg     * Call the framebuffer layer's ScreenInit function, and fill in other
296695b296d0Smrg     * pScreen fields.
296795b296d0Smrg     */
296895b296d0Smrg
296995b296d0Smrg    switch (pScrn->bitsPerPixel) {
297095b296d0Smrg    case 8:
297195b296d0Smrg    case 16:
297295b296d0Smrg    case 24:
297395b296d0Smrg    case 32:
297495b296d0Smrg	ret = fbScreenInit(pScreen, FBStart, width,
297595b296d0Smrg			height, pScrn->xDpi, pScrn->yDpi,
297695b296d0Smrg			displayWidth, pScrn->bitsPerPixel);
297795b296d0Smrg
297895b296d0Smrg	break;
297995b296d0Smrg    default:
298095b296d0Smrg	xf86DrvMsg(scrnIndex, X_ERROR,
298195b296d0Smrg		   "Internal error: invalid bpp (%d) in TRIDENTScrnInit\n",
298295b296d0Smrg		   pScrn->bitsPerPixel);
298395b296d0Smrg	    ret = FALSE;
298495b296d0Smrg	break;
298595b296d0Smrg    }
298695b296d0Smrg    if (!ret) {
298795b296d0Smrg	if (pTrident->pVbe)
298895b296d0Smrg	    vbeFree(pTrident->pVbe);
298995b296d0Smrg	else
299095b296d0Smrg	    xf86FreeInt10(pTrident->Int10);
299195b296d0Smrg	return FALSE;
299295b296d0Smrg    }
299395b296d0Smrg    if (pScrn->bitsPerPixel > 8) {
299495b296d0Smrg        /* Fixup RGB ordering */
299595b296d0Smrg        visual = pScreen->visuals + pScreen->numVisuals;
299695b296d0Smrg        while (--visual >= pScreen->visuals) {
299795b296d0Smrg	    if ((visual->class | DynamicClass) == DirectColor) {
299895b296d0Smrg		visual->offsetRed = pScrn->offset.red;
299995b296d0Smrg		visual->offsetGreen = pScrn->offset.green;
300095b296d0Smrg		visual->offsetBlue = pScrn->offset.blue;
300195b296d0Smrg		visual->redMask = pScrn->mask.red;
300295b296d0Smrg		visual->greenMask = pScrn->mask.green;
300395b296d0Smrg		visual->blueMask = pScrn->mask.blue;
300495b296d0Smrg	    }
300595b296d0Smrg	}
300695b296d0Smrg    }
300795b296d0Smrg
300895b296d0Smrg    /* must be after RGB ordering fixed */
300995b296d0Smrg    fbPictureInit (pScreen, 0, 0);
301095b296d0Smrg
301195b296d0Smrg    xf86SetBlackWhitePixels(pScreen);
301295b296d0Smrg
301395b296d0Smrg    pTrident->BlockHandler = pScreen->BlockHandler;
301495b296d0Smrg    pScreen->BlockHandler = TRIDENTBlockHandler;
301595b296d0Smrg
301695b296d0Smrg    if (!pTrident->ShadowFB)
301795b296d0Smrg	TRIDENTDGAInit(pScreen);
301895b296d0Smrg
301995b296d0Smrg    if (!pTrident->Linear) {
302095b296d0Smrg	miBankInfoPtr pBankInfo;
302195b296d0Smrg
302295b296d0Smrg	/* Setup the vga banking variables */
302395b296d0Smrg	pBankInfo = xnfcalloc(sizeof(miBankInfoRec),1);
302495b296d0Smrg	if (pBankInfo == NULL) {
302595b296d0Smrg	    if (pTrident->pVbe)
302695b296d0Smrg		vbeFree(pTrident->pVbe);
302795b296d0Smrg	    else
302895b296d0Smrg		xf86FreeInt10(pTrident->Int10);
302995b296d0Smrg	    return FALSE;
303095b296d0Smrg	}
303195b296d0Smrg	pBankInfo->pBankA = pTrident->FbBase;
303295b296d0Smrg	pBankInfo->pBankB = pTrident->FbBase;
303395b296d0Smrg	pBankInfo->BankSize = 0x10000;
303495b296d0Smrg	pBankInfo->nBankDepth = (pScrn->depth == 4) ? 1 : pScrn->depth;
303595b296d0Smrg
303695b296d0Smrg	pBankInfo->SetSourceBank =
303795b296d0Smrg		(miBankProcPtr)TVGA8900SetRead;
303895b296d0Smrg	pBankInfo->SetDestinationBank =
303995b296d0Smrg		(miBankProcPtr)TVGA8900SetWrite;
304095b296d0Smrg	pBankInfo->SetSourceAndDestinationBanks =
304195b296d0Smrg		(miBankProcPtr)TVGA8900SetReadWrite;
304295b296d0Smrg	if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
304395b296d0Smrg				 pScrn->displayWidth, pBankInfo)) {
304495b296d0Smrg	    xfree(pBankInfo);
304595b296d0Smrg	    pBankInfo = NULL;
304695b296d0Smrg	    if (pTrident->pVbe)
304795b296d0Smrg	    	vbeFree(pTrident->pVbe);
304895b296d0Smrg	    else
304995b296d0Smrg		xf86FreeInt10(pTrident->Int10);
305095b296d0Smrg	    return FALSE;
305195b296d0Smrg	}
305295b296d0Smrg    }
305395b296d0Smrg
305495b296d0Smrg    {
305595b296d0Smrg    	BoxRec AvailFBArea;
305695b296d0Smrg
305795b296d0Smrg	AvailFBArea.x1 = 0;
305895b296d0Smrg    	AvailFBArea.y1 = 0;
305995b296d0Smrg    	AvailFBArea.x2 = pScrn->displayWidth;
306095b296d0Smrg    	AvailFBArea.y2 = pTrident->FbMapSize / (pScrn->displayWidth *
306195b296d0Smrg					    pScrn->bitsPerPixel / 8);
306295b296d0Smrg
306395b296d0Smrg    	if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047;
306495b296d0Smrg
306595b296d0Smrg    	if (xf86InitFBManager(pScreen, &AvailFBArea)) {
306695b296d0Smrg	    int cpp = pScrn->bitsPerPixel / 8;
306795b296d0Smrg	    int area = AvailFBArea.y2 * pScrn->displayWidth;
306895b296d0Smrg	    int areaoffset = area * cpp;
306995b296d0Smrg
307095b296d0Smrg    	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
307195b296d0Smrg	       "Using %i scanlines of offscreen memory for area's \n",
307295b296d0Smrg 	       AvailFBArea.y2 - pScrn->virtualY);
307395b296d0Smrg
307495b296d0Smrg	    if (xf86InitFBManagerLinear(pScreen, area, ((pTrident->FbMapSize/cpp) - area))) {
307595b296d0Smrg		xf86DrvMsg(scrnIndex, X_INFO,
307695b296d0Smrg			"Using %ld bytes of offscreen memory for linear (offset=0x%x)\n", (pTrident->FbMapSize - areaoffset), areaoffset);
307795b296d0Smrg	    }
307895b296d0Smrg    	}
307995b296d0Smrg    }
308095b296d0Smrg
308195b296d0Smrg    if (Is3Dchip) {
308295b296d0Smrg	if ((pTrident->Chipset == CYBERBLADEI7) ||
308395b296d0Smrg	    (pTrident->Chipset == CYBERBLADEI7D) ||
308495b296d0Smrg	    (pTrident->Chipset == CYBERBLADEI1) ||
308595b296d0Smrg	    (pTrident->Chipset == CYBERBLADEI1D) ||
308695b296d0Smrg	    (pTrident->Chipset == CYBERBLADEAI1) ||
308795b296d0Smrg	    (pTrident->Chipset == CYBERBLADEAI1D) ||
308895b296d0Smrg	    (pTrident->Chipset == CYBERBLADEE4) ||
308995b296d0Smrg	    (pTrident->Chipset == BLADE3D)) {
309095b296d0Smrg	    if (pTrident->useEXA)
309195b296d0Smrg		BladeExaInit(pScreen);
309295b296d0Smrg	    else
309395b296d0Smrg		BladeXaaInit(pScreen);
309495b296d0Smrg	} else
309595b296d0Smrg	if ((pTrident->Chipset == CYBERBLADEXP4) ||
309695b296d0Smrg	    (pTrident->Chipset == XP5)) {
309795b296d0Smrg	    if (pTrident->useEXA)
309895b296d0Smrg	    	XP4ExaInit(pScreen);
309995b296d0Smrg	    else
310095b296d0Smrg		XP4XaaInit(pScreen);
310195b296d0Smrg	} else
310295b296d0Smrg	if ((pTrident->Chipset == BLADEXP) ||
310395b296d0Smrg	    (pTrident->Chipset == CYBERBLADEXPAI1)) {
310495b296d0Smrg		XPAccelInit(pScreen);
310595b296d0Smrg	} else {
310695b296d0Smrg	    	ImageAccelInit(pScreen);
310795b296d0Smrg	}
310895b296d0Smrg    } else {
310995b296d0Smrg    	TridentAccelInit(pScreen);
311095b296d0Smrg    }
311195b296d0Smrg
311295b296d0Smrg    miInitializeBackingStore(pScreen);
311395b296d0Smrg    xf86SetBackingStore(pScreen);
311495b296d0Smrg
311595b296d0Smrg    /* Initialise cursor functions */
311695b296d0Smrg    miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
311795b296d0Smrg
311895b296d0Smrg    if (pTrident->HWCursor) {
311995b296d0Smrg        xf86SetSilkenMouse(pScreen);
312095b296d0Smrg	TridentHWCursorInit(pScreen);
312195b296d0Smrg    }
312295b296d0Smrg
312395b296d0Smrg    /* Initialise default colourmap */
312495b296d0Smrg    if (!miCreateDefColormap(pScreen)) {
312595b296d0Smrg	if (pTrident->pVbe)
312695b296d0Smrg	    vbeFree(pTrident->pVbe);
312795b296d0Smrg	else
312895b296d0Smrg	    xf86FreeInt10(pTrident->Int10);
312995b296d0Smrg	return FALSE;
313095b296d0Smrg    }
313195b296d0Smrg    if(!xf86HandleColormaps(pScreen, 256, 6, TridentLoadPalette,
313295b296d0Smrg			    TridentSetOverscan, CMAP_RELOAD_ON_MODE_SWITCH|CMAP_PALETTED_TRUECOLOR)) {
313395b296d0Smrg	if (pTrident->pVbe)
313495b296d0Smrg	    vbeFree(pTrident->pVbe);
313595b296d0Smrg	else
313695b296d0Smrg	    xf86FreeInt10(pTrident->Int10);
313795b296d0Smrg	return FALSE;
313895b296d0Smrg    }
313995b296d0Smrg    if(pTrident->ShadowFB) {
314095b296d0Smrg        if(pTrident->Rotate) {
314195b296d0Smrg	    if (!pTrident->PointerMoved) {
314295b296d0Smrg	        pTrident->PointerMoved = pScrn->PointerMoved;
314395b296d0Smrg		pScrn->PointerMoved = TRIDENTPointerMoved;
314495b296d0Smrg	    }
314595b296d0Smrg	    switch (pScrn->bitsPerPixel) {
314695b296d0Smrg	    case 8:    pTrident->RefreshArea = TRIDENTRefreshArea8; break;
314795b296d0Smrg	    case 16:   pTrident->RefreshArea = TRIDENTRefreshArea16; break;
314895b296d0Smrg	    case 24:   pTrident->RefreshArea = TRIDENTRefreshArea24; break;
314995b296d0Smrg	    case 32:   pTrident->RefreshArea = TRIDENTRefreshArea32; break;
315095b296d0Smrg	    }
315195b296d0Smrg	} else {
315295b296d0Smrg	  pTrident->RefreshArea = TRIDENTRefreshArea;
315395b296d0Smrg	}
315495b296d0Smrg	shadowInit (pScreen, TRIDENTShadowUpdate, 0);
315595b296d0Smrg    }
315695b296d0Smrg
315795b296d0Smrg    xf86DPMSInit(pScreen, (DPMSSetProcPtr)TRIDENTDisplayPowerManagementSet, 0);
315895b296d0Smrg
315995b296d0Smrg    pScrn->memPhysBase = pTrident->FbAddress;
316095b296d0Smrg    pScrn->fbOffset = 0;
316195b296d0Smrg
316295b296d0Smrg    if (pTrident->Chipset >= TGUI9660)
316395b296d0Smrg	TRIDENTInitVideo(pScreen);
316495b296d0Smrg
316595b296d0Smrg    pTrident->CloseScreen = pScreen->CloseScreen;
316695b296d0Smrg    pScreen->CloseScreen = TRIDENTCloseScreen;
316795b296d0Smrg    pScreen->SaveScreen = TRIDENTSaveScreen;
316895b296d0Smrg
316995b296d0Smrg    /* Report any unused options (only for the first generation) */
317095b296d0Smrg    if (serverGeneration == 1) {
317195b296d0Smrg	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
317295b296d0Smrg    }
317395b296d0Smrg
317495b296d0Smrg#if 0
317595b296d0Smrg    TRIDENTI2CInit(pScreen);
317695b296d0Smrg
317795b296d0Smrg    xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,pTrident->DDC));
317895b296d0Smrg#endif
317995b296d0Smrg
318095b296d0Smrg    return TRUE;
318195b296d0Smrg}
318295b296d0Smrg
318395b296d0Smrg/* Usually mandatory */
318495b296d0SmrgBool
318595b296d0SmrgTRIDENTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
318695b296d0Smrg{
318795b296d0Smrg    return TRIDENTModeInit(xf86Screens[scrnIndex], mode);
318895b296d0Smrg}
318995b296d0Smrg
319095b296d0Smrg
319195b296d0Smrg/*
319295b296d0Smrg * This function is used to initialize the Start Address - the first
319395b296d0Smrg * displayed location in the video memory.
319495b296d0Smrg */
319595b296d0Smrg/* Usually mandatory */
319695b296d0Smrgvoid
319795b296d0SmrgTRIDENTAdjustFrame(int scrnIndex, int x, int y, int flags)
319895b296d0Smrg{
319995b296d0Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
320095b296d0Smrg    TRIDENTPtr pTrident;
320195b296d0Smrg    int base = y * pScrn->displayWidth + x;
320295b296d0Smrg    int vgaIOBase;
320395b296d0Smrg    CARD8 temp;
320495b296d0Smrg
320595b296d0Smrg    pTrident = TRIDENTPTR(pScrn);
320695b296d0Smrg    vgaIOBase = VGAHWPTR(pScrn)->IOBase;
320795b296d0Smrg
320895b296d0Smrg    switch (pScrn->bitsPerPixel) {
320995b296d0Smrg	case 8:
321095b296d0Smrg	    if (pScrn->progClock)
321195b296d0Smrg	    	base = (base & 0xFFFFFFF8) >> 2;
321295b296d0Smrg	    else
321395b296d0Smrg	    	base = (base & 0xFFFFFFF8) >> 3;
321495b296d0Smrg	    break;
321595b296d0Smrg	case 16:
321695b296d0Smrg	    base >>= 1;
321795b296d0Smrg	    break;
321895b296d0Smrg	case 24:
321995b296d0Smrg	    base = (((base + 1) & ~0x03) * 3) >> 2;
322095b296d0Smrg	    break;
322195b296d0Smrg	case 32:
322295b296d0Smrg	    break;
322395b296d0Smrg    }
322495b296d0Smrg
322595b296d0Smrg    /* CRT bits 0-15 */
322695b296d0Smrg    OUTW(vgaIOBase + 4, (base & 0x00FF00) | 0x0C);
322795b296d0Smrg    OUTW(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D);
322895b296d0Smrg    /* CRT bit 16 */
322995b296d0Smrg    OUTB(vgaIOBase + 4, CRTCModuleTest); temp = INB(vgaIOBase + 5) & 0xDF;
323095b296d0Smrg    OUTB(vgaIOBase + 5, temp | ((base & 0x10000) >> 11));
323195b296d0Smrg    /* CRT bit 17-19 */
323295b296d0Smrg    OUTB(vgaIOBase + 4, CRTHiOrd); temp = INB(vgaIOBase + 5) & 0xF8;
323395b296d0Smrg    OUTB(vgaIOBase + 5, temp | ((base & 0xE0000) >> 17));
323495b296d0Smrg}
323595b296d0Smrg
323695b296d0Smrg
323795b296d0Smrg/*
323895b296d0Smrg * This is called when VT switching back to the X server.  Its job is
323995b296d0Smrg * to reinitialise the video mode.
324095b296d0Smrg */
324195b296d0Smrg
324295b296d0Smrg/* Mandatory */
324395b296d0Smrgstatic Bool
324495b296d0SmrgTRIDENTEnterVT(int scrnIndex, int flags)
324595b296d0Smrg{
324695b296d0Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
324795b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
324895b296d0Smrg
324995b296d0Smrg    if (IsPciCard && UseMMIO) TRIDENTEnableMMIO(pScrn);
325095b296d0Smrg
325195b296d0Smrg    /* Should we re-save the text mode on each VT enter? */
325295b296d0Smrg    if (!TRIDENTModeInit(pScrn, pScrn->currentMode))
325395b296d0Smrg	return FALSE;
325495b296d0Smrg
325595b296d0Smrg    if (pTrident->InitializeAccelerator)
325695b296d0Smrg        pTrident->InitializeAccelerator(pScrn);
325795b296d0Smrg
325895b296d0Smrg    return TRUE;
325995b296d0Smrg}
326095b296d0Smrg
326195b296d0Smrg
326295b296d0Smrg/*
326395b296d0Smrg * This is called when VT switching away from the X server.  Its job is
326495b296d0Smrg * to restore the previous (text) mode.
326595b296d0Smrg *
326695b296d0Smrg * We may wish to remap video/MMIO memory too.
326795b296d0Smrg */
326895b296d0Smrg
326995b296d0Smrg/* Mandatory */
327095b296d0Smrgstatic void
327195b296d0SmrgTRIDENTLeaveVT(int scrnIndex, int flags)
327295b296d0Smrg{
327395b296d0Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
327495b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
327595b296d0Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
327695b296d0Smrg
327795b296d0Smrg    if (!pTrident->NoAccel && !pTrident->useEXA)
327895b296d0Smrg	pTrident->AccelInfoRec->Sync(pScrn);
327995b296d0Smrg    else if (!pTrident->NoAccel && pTrident->useEXA)
328095b296d0Smrg	pTrident->EXADriverPtr->WaitMarker(pScrn->pScreen, 0);
328195b296d0Smrg
328295b296d0Smrg    TRIDENTRestore(pScrn);
328395b296d0Smrg    vgaHWLock(hwp);
328495b296d0Smrg
328595b296d0Smrg    if (xf86IsPc98())
328695b296d0Smrg	PC98TRIDENTDisable(pScrn);
328795b296d0Smrg
328895b296d0Smrg    if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn);
328995b296d0Smrg}
329095b296d0Smrg
329195b296d0Smrg
329295b296d0Smrg/*
329395b296d0Smrg * This is called at the end of each server generation.  It restores the
329495b296d0Smrg * original (text) mode.  It should really also unmap the video memory too.
329595b296d0Smrg */
329695b296d0Smrg
329795b296d0Smrg/* Mandatory */
329895b296d0Smrgstatic Bool
329995b296d0SmrgTRIDENTCloseScreen(int scrnIndex, ScreenPtr pScreen)
330095b296d0Smrg{
330195b296d0Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
330295b296d0Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
330395b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
330495b296d0Smrg
330595b296d0Smrg    if (pScrn->vtSema) {
330695b296d0Smrg    if (!pTrident->NoAccel && !pTrident->useEXA)
330795b296d0Smrg	pTrident->AccelInfoRec->Sync(pScrn);
330895b296d0Smrg    else if (!pTrident->NoAccel && pTrident->useEXA)
330995b296d0Smrg	pTrident->EXADriverPtr->WaitMarker(pScreen, 0);
331095b296d0Smrg
331195b296d0Smrg    if (xf86IsPc98())
331295b296d0Smrg	PC98TRIDENTDisable(pScrn);
331395b296d0Smrg
331495b296d0Smrg    	TRIDENTRestore(pScrn);
331595b296d0Smrg    	vgaHWLock(hwp);
331695b296d0Smrg	if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn);
331795b296d0Smrg    	TRIDENTUnmapMem(pScrn);
331895b296d0Smrg    }
331995b296d0Smrg    if (pTrident->AccelInfoRec)
332095b296d0Smrg	XAADestroyInfoRec(pTrident->AccelInfoRec);
332195b296d0Smrg    if (pTrident->EXADriverPtr) {
332295b296d0Smrg	exaDriverFini(pScreen);
332395b296d0Smrg	xfree(pTrident->EXADriverPtr);
332495b296d0Smrg	pTrident->EXADriverPtr = NULL;
332595b296d0Smrg    }
332695b296d0Smrg    if (pTrident->CursorInfoRec)
332795b296d0Smrg	xf86DestroyCursorInfoRec(pTrident->CursorInfoRec);
332895b296d0Smrg    if (pTrident->ShadowPtr)
332995b296d0Smrg	xfree(pTrident->ShadowPtr);
333095b296d0Smrg    if (pTrident->DGAModes)
333195b296d0Smrg	xfree(pTrident->DGAModes);
333295b296d0Smrg    pScrn->vtSema = FALSE;
333395b296d0Smrg
333495b296d0Smrg    if(pTrident->BlockHandler)
333595b296d0Smrg	pScreen->BlockHandler = pTrident->BlockHandler;
333695b296d0Smrg
333795b296d0Smrg    if (pTrident->pVbe)
333895b296d0Smrg	vbeFree(pTrident->pVbe);
333995b296d0Smrg    else
334095b296d0Smrg	xf86FreeInt10(pTrident->Int10);
334195b296d0Smrg    pScreen->CloseScreen = pTrident->CloseScreen;
334295b296d0Smrg    return (*pScreen->CloseScreen)(scrnIndex, pScreen);
334395b296d0Smrg}
334495b296d0Smrg
334595b296d0Smrg
334695b296d0Smrg/* Free up any per-generation data structures */
334795b296d0Smrg
334895b296d0Smrg/* Optional */
334995b296d0Smrgstatic void
335095b296d0SmrgTRIDENTFreeScreen(int scrnIndex, int flags)
335195b296d0Smrg{
335295b296d0Smrg    if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
335395b296d0Smrg	vgaHWFreeHWRec(xf86Screens[scrnIndex]);
335495b296d0Smrg    TRIDENTFreeRec(xf86Screens[scrnIndex]);
335595b296d0Smrg}
335695b296d0Smrg
335795b296d0Smrg
335895b296d0Smrg/* Checks if a mode is suitable for the selected chipset. */
335995b296d0Smrg
336095b296d0Smrg/* Optional */
336195b296d0Smrgstatic ModeStatus
336295b296d0SmrgTRIDENTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
336395b296d0Smrg{
336495b296d0Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
336595b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
336695b296d0Smrg
336795b296d0Smrg    if (pTrident->lcdActive && (pTrident->lcdMode != 0xff)){
336895b296d0Smrg	if (((mode->HDisplay > LCD[pTrident->lcdMode].display_x)
336995b296d0Smrg	|| (mode->VDisplay > LCD[pTrident->lcdMode].display_y))) {
337095b296d0Smrg	    xf86DrvMsg(scrnIndex,X_INFO, "Removing mode (%dx%d) "
337195b296d0Smrg		       "larger than the LCD panel (%dx%d)\n",
337295b296d0Smrg		       mode->HDisplay,
337395b296d0Smrg		       mode->VDisplay,
337495b296d0Smrg		       LCD[pTrident->lcdMode].display_x,
337595b296d0Smrg		       LCD[pTrident->lcdMode].display_y);
337695b296d0Smrg	    return(MODE_BAD);
337795b296d0Smrg	}
337895b296d0Smrg	if (((float)mode->HDisplay/(float)mode->VDisplay) > 2.0) {
337995b296d0Smrg	    xf86DrvMsg(scrnIndex,X_INFO, "Removing mode (%dx%d) "
338095b296d0Smrg		       "unusual aspect ratio\n",
338195b296d0Smrg		       mode->HDisplay,
338295b296d0Smrg		       mode->VDisplay);
338395b296d0Smrg	    return(MODE_BAD);
338495b296d0Smrg	}
338595b296d0Smrg    }
338695b296d0Smrg    return (MODE_OK);
338795b296d0Smrg}
338895b296d0Smrg
338995b296d0Smrg/* Do screen blanking */
339095b296d0Smrg
339195b296d0Smrg/* Mandatory */
339295b296d0Smrgstatic Bool
339395b296d0SmrgTRIDENTSaveScreen(ScreenPtr pScreen, int mode)
339495b296d0Smrg{
339595b296d0Smrg    return vgaHWSaveScreen(pScreen, mode);
339695b296d0Smrg}
339795b296d0Smrg
339895b296d0Smrgstatic void
339995b296d0SmrgTRIDENTEnableMMIO(ScrnInfoPtr pScrn)
340095b296d0Smrg{
340195b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
340295b296d0Smrg    IOADDRESS vgaIOBase = pTrident->PIOBase + VGAHWPTR(pScrn)->IOBase;
340395b296d0Smrg    CARD8 temp = 0, protect = 0;
340495b296d0Smrg
340595b296d0Smrg    /*
340695b296d0Smrg     * Skip MMIO Enable in PC-9821 PCI Trident Card!!
340795b296d0Smrg     * Because of lack of non PCI VGA port
340895b296d0Smrg     */
340995b296d0Smrg    if (IsPciCard && xf86IsPc98())
341095b296d0Smrg      return;
341195b296d0Smrg
341295b296d0Smrg    /* Goto New Mode */
341395b296d0Smrg    outb(pTrident->PIOBase + 0x3C4, 0x0B);
341495b296d0Smrg    inb(pTrident->PIOBase + 0x3C5);
341595b296d0Smrg
341695b296d0Smrg    /* Unprotect registers */
341795b296d0Smrg    if (pTrident->Chipset > PROVIDIA9685) {
341895b296d0Smrg    	outb(pTrident->PIOBase + 0x3C4, Protection);
341995b296d0Smrg    	protect = inb(pTrident->PIOBase + 0x3C5);
342095b296d0Smrg    	outb(pTrident->PIOBase + 0x3C5, 0x92);
342195b296d0Smrg    }
342295b296d0Smrg    outb(pTrident->PIOBase + 0x3C4, NewMode1);
342395b296d0Smrg    temp = inb(pTrident->PIOBase + 0x3C5);
342495b296d0Smrg    outb(pTrident->PIOBase + 0x3C5, 0x80);
342595b296d0Smrg
342695b296d0Smrg    /* Enable MMIO */
342795b296d0Smrg    outb(vgaIOBase + 4, PCIReg);
342895b296d0Smrg    pTrident->REGPCIReg = inb(vgaIOBase + 5);
342995b296d0Smrg    outb(vgaIOBase + 5, pTrident->REGPCIReg | 0x01); /* Enable it */
343095b296d0Smrg
343195b296d0Smrg    /* Protect registers */
343295b296d0Smrg    if (pTrident->Chipset > PROVIDIA9685) {
343395b296d0Smrg    	OUTB(0x3C4, Protection);
343495b296d0Smrg    	OUTB(0x3C5, protect);
343595b296d0Smrg    }
343695b296d0Smrg    OUTB(0x3C4, NewMode1);
343795b296d0Smrg    OUTB(0x3C5, temp);
343895b296d0Smrg}
343995b296d0Smrg
344095b296d0Smrgstatic void
344195b296d0SmrgTRIDENTDisableMMIO(ScrnInfoPtr pScrn)
344295b296d0Smrg{
344395b296d0Smrg    int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
344495b296d0Smrg    CARD8 temp = 0, protect = 0;
344595b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
344695b296d0Smrg
344795b296d0Smrg    /*
344895b296d0Smrg     * Skip MMIO Disable in PC-9821 PCI Trident Card!!
344995b296d0Smrg     * Because of lack of non PCI VGA port
345095b296d0Smrg     */
345195b296d0Smrg    if (IsPciCard && xf86IsPc98())
345295b296d0Smrg      return;
345395b296d0Smrg
345495b296d0Smrg    /* Goto New Mode */
345595b296d0Smrg    OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
345695b296d0Smrg
345795b296d0Smrg    /* Unprotect registers */
345895b296d0Smrg    OUTB(0x3C4, NewMode1); temp = INB(0x3C5);
345995b296d0Smrg    OUTB(0x3C5, 0x80);
346095b296d0Smrg    if (pTrident->Chipset > PROVIDIA9685) {
346195b296d0Smrg    	OUTB(0x3C4, Protection);
346295b296d0Smrg    	protect = INB(0x3C5);
346395b296d0Smrg    	OUTB(0x3C5, 0x92);
346495b296d0Smrg    }
346595b296d0Smrg
346695b296d0Smrg    /* Disable MMIO access */
346795b296d0Smrg    OUTB(vgaIOBase + 4, PCIReg);
346895b296d0Smrg    pTrident->REGPCIReg = INB(vgaIOBase + 5);
346995b296d0Smrg    OUTB(vgaIOBase + 5, pTrident->REGPCIReg & 0xFE);
347095b296d0Smrg
347195b296d0Smrg    /* Protect registers */
347295b296d0Smrg    if (pTrident->Chipset > PROVIDIA9685) {
347395b296d0Smrg    	outb(pTrident->PIOBase + 0x3C4, Protection);
347495b296d0Smrg    	outb(pTrident->PIOBase + 0x3C5, protect);
347595b296d0Smrg    }
347695b296d0Smrg    outb(pTrident->PIOBase + 0x3C4, NewMode1);
347795b296d0Smrg    outb(pTrident->PIOBase + 0x3C5, temp);
347895b296d0Smrg}
347995b296d0Smrg
348095b296d0Smrg/* Initialize VGA Block for Trident Chip on PC-98x1 */
348195b296d0Smrgstatic void
348295b296d0SmrgPC98TRIDENTInit(ScrnInfoPtr pScrn)
348395b296d0Smrg{
348495b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
348595b296d0Smrg    switch (pTrident->Chipset) {
348695b296d0Smrg    case TGUI9660:
348795b296d0Smrg    case TGUI9680:
348895b296d0Smrg    case PROVIDIA9682:
348995b296d0Smrg	PC98TRIDENT96xxInit(pScrn);
349095b296d0Smrg	break;
349195b296d0Smrg    case CYBER9320:
349295b296d0Smrg    case CYBER9385:
349395b296d0Smrg	PC98TRIDENT9385Init(pScrn);
349495b296d0Smrg	break;
349595b296d0Smrg    default: /* Run 96xx code as default */
349695b296d0Smrg	PC98TRIDENT96xxInit(pScrn);
349795b296d0Smrg	break;
349895b296d0Smrg    }
349995b296d0Smrg}
350095b296d0Smrg
350195b296d0Smrgstatic void
350295b296d0SmrgPC98TRIDENTEnable(ScrnInfoPtr pScrn)
350395b296d0Smrg{
350495b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
350595b296d0Smrg    switch (pTrident->Chipset) {
350695b296d0Smrg    case TGUI9660:
350795b296d0Smrg    case TGUI9680:
350895b296d0Smrg    case PROVIDIA9682:
350995b296d0Smrg	PC98TRIDENT96xxEnable(pScrn);
351095b296d0Smrg	break;
351195b296d0Smrg    case CYBER9320:
351295b296d0Smrg    case CYBER9385:
351395b296d0Smrg	PC98TRIDENT9385Enable(pScrn);
351495b296d0Smrg	break;
351595b296d0Smrg    default: /* Run 96xx code as default */
351695b296d0Smrg	PC98TRIDENT96xxEnable(pScrn);
351795b296d0Smrg	break;
351895b296d0Smrg    }
351995b296d0Smrg}
352095b296d0Smrg
352195b296d0Smrgstatic void
352295b296d0SmrgPC98TRIDENTDisable(ScrnInfoPtr pScrn)
352395b296d0Smrg{
352495b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
352595b296d0Smrg    switch (pTrident->Chipset) {
352695b296d0Smrg    case TGUI9660:
352795b296d0Smrg    case TGUI9680:
352895b296d0Smrg    case PROVIDIA9682:
352995b296d0Smrg	PC98TRIDENT96xxDisable(pScrn);
353095b296d0Smrg	break;
353195b296d0Smrg    case CYBER9320:
353295b296d0Smrg    case CYBER9385:
353395b296d0Smrg	PC98TRIDENT9385Disable(pScrn);
353495b296d0Smrg	break;
353595b296d0Smrg    default: /* Run 96xx code as default */
353695b296d0Smrg	PC98TRIDENT96xxDisable(pScrn);
353795b296d0Smrg	break;
353895b296d0Smrg    }
353995b296d0Smrg}
354095b296d0Smrg
354195b296d0Smrg/* Initialize VGA Block for Cyber9385 on PC-98x1 */
354295b296d0Smrgstatic void
354395b296d0SmrgPC98TRIDENT9385Init(ScrnInfoPtr pScrn)
354495b296d0Smrg{
354595b296d0Smrg/* Nothing to initialize */
354695b296d0Smrg}
354795b296d0Smrg
354895b296d0Smrgstatic void
354995b296d0SmrgPC98TRIDENT9385Enable(ScrnInfoPtr pScrn)
355095b296d0Smrg{
355195b296d0Smrg    outb(0xFAC, 0x02);
355295b296d0Smrg}
355395b296d0Smrg
355495b296d0Smrgstatic void
355595b296d0SmrgPC98TRIDENT9385Disable(ScrnInfoPtr pScrn)
355695b296d0Smrg{
355795b296d0Smrg    outb(0xFAC, 0x00);
355895b296d0Smrg}
355995b296d0Smrg
356095b296d0Smrg/* Initialize VGA Block for Trident96xx on PC-98x1 */
356195b296d0Smrgstatic void
356295b296d0SmrgPC98TRIDENT96xxInit(ScrnInfoPtr pScrn)
356395b296d0Smrg{
356495b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
356595b296d0Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
356695b296d0Smrg    CARD8 temp = 0;
356795b296d0Smrg
356895b296d0Smrg    vgaHWProtect(pScrn, TRUE);
356995b296d0Smrg
357095b296d0Smrg    /* Video SusSystem Enable */
357195b296d0Smrg    temp = INB(0x3CC);
357295b296d0Smrg    OUTB(0x3C2, temp | 0xC3);
357395b296d0Smrg    /* Switch Old */
357495b296d0Smrg    OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
357595b296d0Smrg    OUTW(0x3C4, 0x0B | (temp << 8));
357695b296d0Smrg    /* Select Configuration Port 1 */
357795b296d0Smrg    OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
357895b296d0Smrg    OUTW(0x3C4, 0x0E | ((temp | 0x20) << 8));
357995b296d0Smrg
358095b296d0Smrg    OUTB(0x3C4, 0x0c);
358195b296d0Smrg    if((INB(0x3C5) & 0x10) == 0x10)
358295b296d0Smrg    {
358395b296d0Smrg	OUTB(0x3C4, 0x0E | (temp << 8));
358495b296d0Smrg	OUTB(0x94,  0x00);
358595b296d0Smrg	OUTB(0x102, 0x01);
358695b296d0Smrg	OUTB(0x94,  0x20);
358795b296d0Smrg	temp = INB(0x3C3);
358895b296d0Smrg	OUTB(0x3C3, temp | 0x01);
358995b296d0Smrg    } else {
359095b296d0Smrg	OUTB(0x3C4, 0x0E | (temp << 8));
359195b296d0Smrg	OUTB(0x46E8, 0x10);
359295b296d0Smrg	OUTB(0x102,  0x01);
359395b296d0Smrg	OUTB(0x46E8, 0x08);
359495b296d0Smrg    }
359595b296d0Smrg
359695b296d0Smrg    INB(0x3DA);
359795b296d0Smrg    OUTB(0x3C0,0x10);
359895b296d0Smrg    OUTB(0x3C0,0x41);
359995b296d0Smrg
360095b296d0Smrg    /* Register Unlock */
360195b296d0Smrg    vgaHWUnlock(hwp);
360295b296d0Smrg    OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */
360395b296d0Smrg    OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
360495b296d0Smrg    OUTW(0x3C4, 0x0E | ((temp | 0x80) << 8));
360595b296d0Smrg
360695b296d0Smrg    /* For Speed Up [Facoor 2 at Xengine] */
360795b296d0Smrg    OUTW(0x3D4, 0x3820); /* Command FIFO Register */
360895b296d0Smrg    OUTW(0x3D4, 0x2020); /* Command FIFO Register */
360995b296d0Smrg    /* Latency Control Registers 0x30 - 0x32 */
361095b296d0Smrg    /* Parameter Range 0x00 - 0x0F */
361195b296d0Smrg    /* Tune these parameter to avoid GE Timeout */
361295b296d0Smrg    OUTW(0x3D4, 0x0E30); /* Display Queue Latency Control */
361395b296d0Smrg    /* 8bpp GE No Timeout Parameter 0x0D - 0x0F for PC-9821Xa7 TGUi9680 */
361495b296d0Smrg    OUTW(0x3D4, 0x0031); /* Frame Buffer Latency Control */
361595b296d0Smrg    OUTW(0x3D4, 0x0032); /* Display & Frame Buffer Latency Control */
361695b296d0Smrg    OUTW(0x3D4, 0x213B); /* Clock and Tuning */
361795b296d0Smrg
361895b296d0Smrg    /* MCLK Init */
361995b296d0Smrg    OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */
362095b296d0Smrg#if 0
362195b296d0Smrg    /* Sample MCLKs */
362295b296d0Smrg    OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */
362395b296d0Smrg    OUTB(0x43C6, 0xA7); OUTB(0x43C7, 0x00); /* 77.0MHz */
362495b296d0Smrg    OUTB(0x43C6, 0x8E); OUTB(0x43C7, 0x00); /* 75.0MHz */
362595b296d0Smrg    OUTB(0x43C6, 0x86); OUTB(0x43C7, 0x00); /* 72.0MHz */
362695b296d0Smrg    OUTB(0x43C6, 0x8F); OUTB(0x43C7, 0x00); /* 67.2MHz */
362795b296d0Smrg    OUTB(0x43C6, 0xD5); OUTB(0x43C7, 0x02); /* 61.6MHz */
362895b296d0Smrg#endif
362995b296d0Smrg
363095b296d0Smrg    /* Register Lock */
363195b296d0Smrg    OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */
363295b296d0Smrg    OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
363395b296d0Smrg    OUTW(0x3C4, 0x0E | ((temp & 0x7F) << 8));
363495b296d0Smrg    vgaHWLock(hwp);
363595b296d0Smrg
363695b296d0Smrg    vgaHWProtect(pScrn, FALSE);
363795b296d0Smrg}
363895b296d0Smrg
363995b296d0Smrgstatic void
364095b296d0SmrgPC98TRIDENT96xxEnable(ScrnInfoPtr pScrn)
364195b296d0Smrg{
364295b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
364395b296d0Smrg    CARD8 temp = 0;
364495b296d0Smrg
364595b296d0Smrg    outb(0x68, 0x0E);
364695b296d0Smrg    outb(0x6A, 0x07);
364795b296d0Smrg    outb(0x6A, 0x8F);
364895b296d0Smrg    outb(0x6A, 0x06);
364995b296d0Smrg
365095b296d0Smrg    vgaHWProtect(pScrn, TRUE);
365195b296d0Smrg
365295b296d0Smrg    OUTB(0x3D4, 0x23); temp = INB(0x3D5);
365395b296d0Smrg    OUTW(0x3D4, 0x23 | ((temp & 0xDF) << 8));
365495b296d0Smrg
365595b296d0Smrg    OUTB(0x3D4, 0x29); temp = INB(0x3D5);
365695b296d0Smrg    OUTW(0x3D4, 0x29 | ((temp | 0x04) << 8));
365795b296d0Smrg
365895b296d0Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
365995b296d0Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x06));
366095b296d0Smrg
366195b296d0Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
366295b296d0Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x08));
366395b296d0Smrg
366495b296d0Smrg    OUTB(0x3CE, 0x23); temp = INB(0x3CF);
366595b296d0Smrg    OUTW(0x3CE, 0x23 | ((temp & 0xFC) << 8));
366695b296d0Smrg
366795b296d0Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
366895b296d0Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x01));
366995b296d0Smrg
367095b296d0Smrg    OUTB(0x3C4, 0x01); temp = INB(0x3C5);
367195b296d0Smrg    OUTW(0x3C4, 0x01 | ((temp & 0xEF) << 8));
367295b296d0Smrg
367395b296d0Smrg    vgaHWProtect(pScrn, FALSE);
367495b296d0Smrg
367595b296d0Smrg    outb(0xFAC, 0x02);
367695b296d0Smrg}
367795b296d0Smrg
367895b296d0Smrgstatic void
367995b296d0SmrgPC98TRIDENT96xxDisable(ScrnInfoPtr pScrn)
368095b296d0Smrg{
368195b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
368295b296d0Smrg    CARD8 temp = 0;
368395b296d0Smrg
368495b296d0Smrg    outb(0xFAC, 0x00);
368595b296d0Smrg
368695b296d0Smrg    vgaHWProtect(pScrn, TRUE);
368795b296d0Smrg
368895b296d0Smrg    OUTB(0x3C4, 0x01); temp = INB(0x3C5);
368995b296d0Smrg    OUTW(0x3C4, 0x01 | ((temp | 0x10) << 8));
369095b296d0Smrg
369195b296d0Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
369295b296d0Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFE));
369395b296d0Smrg
369495b296d0Smrg    OUTB(0x3CE, 0x23); temp = INB(0x3CF);
369595b296d0Smrg    OUTW(0x3CE, 0x23 | (((temp & 0xFC) | 0x01) << 8));
369695b296d0Smrg
369795b296d0Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
369895b296d0Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFD));
369995b296d0Smrg
370095b296d0Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
370195b296d0Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xCF));
370295b296d0Smrg
370395b296d0Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
370495b296d0Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xF7));
370595b296d0Smrg
370695b296d0Smrg    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
370795b296d0Smrg    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFB));
370895b296d0Smrg
370995b296d0Smrg    OUTB(0x3D4, 0x29); temp = INB(0x3D5);
371095b296d0Smrg    OUTW(0x3D4, 0x29 | ((temp & 0xFB) << 8));
371195b296d0Smrg
371295b296d0Smrg    OUTB(0x3D4, 0x23); temp = INB(0x3D5);
371395b296d0Smrg    OUTW(0x3D4, 0x23 | ((temp | 0x20) << 8));
371495b296d0Smrg
371595b296d0Smrg    vgaHWProtect(pScrn, FALSE);
371695b296d0Smrg
371795b296d0Smrg    outb(0x6A, 0x07);
371895b296d0Smrg    outb(0x6A, 0x8E);
371995b296d0Smrg    outb(0x6A, 0x06);
372095b296d0Smrg    outb(0x68, 0x0F);
372195b296d0Smrg}
372295b296d0Smrg
372395b296d0Smrg
372495b296d0Smrg/*
372595b296d0Smrg * This is a terrible hack! If we are on a notebook in a stretched
372695b296d0Smrg * mode and don't want full screen we use the BIOS to set an unstreched
372795b296d0Smrg * mode.
372895b296d0Smrg */
372995b296d0Smrgvoid
373095b296d0SmrgtridentSetModeBIOS(ScrnInfoPtr pScrn, DisplayModePtr mode)
373195b296d0Smrg{
373295b296d0Smrg    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
373395b296d0Smrg
373495b296d0Smrg
373595b296d0Smrg#ifdef VBE_INFO
373695b296d0Smrg    if (pTrident->vbeModes) {
373795b296d0Smrg	vbeSaveRestoreRec vbesr;
373895b296d0Smrg	vbesr.stateMode = VBECalcVbeModeIndex(pTrident->vbeModes,
373995b296d0Smrg					     mode, pScrn->bitsPerPixel);
374095b296d0Smrg	vbesr.pstate = NULL;
374195b296d0Smrg	if (vbesr.stateMode) {
374295b296d0Smrg	    if (IsPciCard && UseMMIO)
374395b296d0Smrg		TRIDENTDisableMMIO(pScrn);
374495b296d0Smrg	    VBEVesaSaveRestore(pTrident->pVbe,&vbesr,MODE_RESTORE);
374595b296d0Smrg	    if (IsPciCard && UseMMIO)
374695b296d0Smrg		TRIDENTEnableMMIO(pScrn);
374795b296d0Smrg	    return;
374895b296d0Smrg	} else
374995b296d0Smrg	    xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"No BIOS Mode matches "
375095b296d0Smrg		       "%ix%I@%ibpp\n",mode->HDisplay,mode->VDisplay,
375195b296d0Smrg		       pScrn->bitsPerPixel);
375295b296d0Smrg    }
375395b296d0Smrg#endif
375495b296d0Smrg    /* This function is only for LCD screens, and also when we have
375595b296d0Smrg     * int10 available */
375695b296d0Smrg
375795b296d0Smrg    if (pTrident->IsCyber && pTrident->lcdMode && pTrident->Int10) {
375895b296d0Smrg        int i = pTrident->lcdMode;
375995b296d0Smrg	if ((pScrn->currentMode->HDisplay != LCD[i].display_x) /* !fullsize? */
376095b296d0Smrg	    || (pScrn->currentMode->VDisplay != LCD[i].display_y)) {
376195b296d0Smrg	    if (pTrident->lcdActive)  { /* LCD Active ?*/
376295b296d0Smrg	        int h_str, v_str;
376395b296d0Smrg
376495b296d0Smrg		OUTB(0x3CE,HorStretch);  h_str = INB(0x3CF) & 0x01;
376595b296d0Smrg		OUTB(0x3CE,VertStretch); v_str = INB(0x3CF) & 0x01;
376695b296d0Smrg		if (h_str || v_str) {
376795b296d0Smrg		    OUTB(0x3C4, 0x11); OUTB(0x3C5, 0x92);
376895b296d0Smrg		    OUTW(0x3CE, BiosReg );
376995b296d0Smrg		    pTrident->Int10->ax = 0x3;
377095b296d0Smrg		    pTrident->Int10->num = 0x10;
377195b296d0Smrg		    if (IsPciCard && UseMMIO)
377295b296d0Smrg			TRIDENTDisableMMIO(pScrn);
377395b296d0Smrg		    xf86ExecX86int10(pTrident->Int10);
377495b296d0Smrg		    if (IsPciCard && UseMMIO)
377595b296d0Smrg			TRIDENTEnableMMIO(pScrn);
377695b296d0Smrg		}
377795b296d0Smrg	    }
377895b296d0Smrg	}
377995b296d0Smrg    }
378095b296d0Smrg}
378195b296d0Smrg
378295b296d0Smrg/* Currently we only test for 1400 */
378395b296d0Smrgstatic int
378495b296d0SmrgTRIDENTLcdDisplaySize (xf86MonPtr pMon)
378595b296d0Smrg{
378695b296d0Smrg    if (pMon) {
378795b296d0Smrg	int i,j;
378895b296d0Smrg
378995b296d0Smrg	for (i = 0; i < STD_TIMINGS; i++) {
379095b296d0Smrg	    if (pMon->timings2[i].hsize == 1400) {
379195b296d0Smrg		return 1400;
379295b296d0Smrg	    }
379395b296d0Smrg	}
379495b296d0Smrg	/*
379595b296d0Smrg	 * If not explicitely set try to find out if the display supports
379695b296d0Smrg	 * the 1400 mode. For sanity check if DDC comes from a digital
379795b296d0Smrg	 * display.
379895b296d0Smrg	 */
379995b296d0Smrg	if (DIGITAL(pMon->features.input_type)) {
380095b296d0Smrg	    for (i = 0; i < DET_TIMINGS; i++) {
380195b296d0Smrg		if (pMon->det_mon[i].type == DS_STD_TIMINGS) {
380295b296d0Smrg		    for (j = 0; j < 5; j++) {
380395b296d0Smrg			if (pMon->det_mon[i].section.std_t[j].hsize == 1400) {
380495b296d0Smrg			    return 1400;
380595b296d0Smrg			}
380695b296d0Smrg		    }
380795b296d0Smrg		} else if (pMon->det_mon[i].type == DT) {
380895b296d0Smrg		    if (pMon->det_mon[i].section.d_timings.h_active == 1400) {
380995b296d0Smrg			return 1400;
381095b296d0Smrg		    }
381195b296d0Smrg		}
381295b296d0Smrg	    }
381395b296d0Smrg	}
381495b296d0Smrg    }
381595b296d0Smrg    return 0;
381695b296d0Smrg}
381795b296d0Smrg
3818