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