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