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