1/*
2 * Copyright 1992-2003 by Alan Hourihane, North Wales, UK.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Author:  Alan Hourihane, alanh@fairlite.demon.co.uk
23 *          Re-written for XFree86 v4.0
24 *
25 * Previous driver (pre-XFree86 v4.0) by
26 *          Alan Hourihane, alanh@fairlite.demon.co.uk
27 *          David Wexelblat (major contributor)
28 *          Massimiliano Ghilardi, max@Linuz.sns.it, some fixes to the
29 *                                 clockchip programming code.
30 */
31
32#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
36#include "fb.h"
37
38#ifdef HAVE_ISA
39#include "mibank.h"
40#endif
41#include "micmap.h"
42#include "xf86.h"
43#include "xf86_OSproc.h"
44#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
45#include "xf86Resources.h"
46#include "xf86RAC.h"
47#endif
48#include "xf86Pci.h"
49#include "xf86cmap.h"
50#include "vgaHW.h"
51
52#include "vbe.h"
53#include "dixstruct.h"
54#include "compiler.h"
55
56#include "mipointer.h"
57
58#include "shadow.h"
59#include "trident.h"
60#include "trident_regs.h"
61
62#ifdef XFreeXDGA
63#define _XF86DGA_SERVER_
64#include <X11/extensions/xf86dgaproto.h>
65#endif
66
67#include "globals.h"
68#ifdef HAVE_XEXTPROTO_71
69#include <X11/extensions/dpmsconst.h>
70#else
71#define DPMS_SERVER
72#include <X11/extensions/dpms.h>
73#endif
74
75#include "xf86xv.h"
76
77static const OptionInfoRec * TRIDENTAvailableOptions(int chipid, int busid);
78static void     TRIDENTIdentify(int flags);
79static Bool     TRIDENTProbe(DriverPtr drv, int flags);
80static Bool     TRIDENTPreInit(ScrnInfoPtr pScrn, int flags);
81static Bool     TRIDENTScreenInit(SCREEN_INIT_ARGS_DECL);
82
83/*
84 * This is intentionally screen-independent.  It indicates the binding
85 * choice made in the first PreInit.
86 */
87static int pix24bpp = 0;
88
89#define TRIDENT_VERSION 4000
90#define TRIDENT_NAME "TRIDENT"
91#define TRIDENT_DRIVER_NAME "trident"
92#define TRIDENT_MAJOR_VERSION PACKAGE_VERSION_MAJOR
93#define TRIDENT_MINOR_VERSION PACKAGE_VERSION_MINOR
94#define TRIDENT_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL
95
96/*
97 * This contains the functions needed by the server after loading the driver
98 * module.  It must be supplied, and gets passed back by the SetupProc
99 * function in the dynamic case.  In the static case, a reference to this
100 * is compiled in, and this requires that the name of this DriverRec be
101 * an upper-case version of the driver name.
102 */
103
104_X_EXPORT DriverRec TRIDENT = {
105    TRIDENT_VERSION,
106    TRIDENT_DRIVER_NAME,
107    TRIDENTIdentify,
108    TRIDENTProbe,
109    TRIDENTAvailableOptions,
110    NULL,
111    0
112};
113
114static SymTabRec TRIDENTChipsets[] = {
115    { TVGA9000,         "tvga9000" },
116    { TVGA9000i,        "tvga9000i" },
117    { TVGA8900C,        "tvga8900c" },
118    { TVGA8900D,        "tvga8900d" },
119    { TVGA9200CXr,      "tvga9200cxr" },
120    { TGUI9400CXi,      "tgui9400cxi" },
121    { CYBER9320,        "cyber9320" },
122    { CYBER9388,        "cyber9388" },
123    { CYBER9397,        "cyber9397" },
124    { CYBER9397DVD,     "cyber9397dvd" },
125    { CYBER9520,        "cyber9520" },
126    { CYBER9525DVD,     "cyber9525dvd" },
127    { CYBERBLADEE4,     "cyberblade/e4" },
128    { TGUI9420DGi,      "tgui9420dgi" },
129    { TGUI9440AGi,      "tgui9440agi" },
130    { TGUI9660,         "tgui9660" },
131    { TGUI9680,         "tgui9680" },
132    { PROVIDIA9682,     "providia9682" },
133    { PROVIDIA9685,     "providia9685" },
134    { CYBER9382,        "cyber9382" },
135    { CYBER9385,        "cyber9385" },
136    { IMAGE975,         "3dimage975" },
137    { IMAGE985,         "3dimage985" },
138    { BLADE3D,          "blade3d" },
139    { CYBERBLADEI7,     "cyberbladei7" },
140    { CYBERBLADEI7D,    "cyberbladei7d" },
141    { CYBERBLADEI1,     "cyberbladei1" },
142    { CYBERBLADEI1D,    "cyberbladei1d" },
143    { CYBERBLADEAI1,    "cyberbladeAi1" },
144    { CYBERBLADEAI1D,   "cyberbladeAi1d" },
145    { BLADEXP,          "bladeXP" },
146    { CYBERBLADEXPAI1,  "cyberbladeXPAi1" },
147    { CYBERBLADEXP4,    "cyberbladeXP4" },
148    { XP5,              "XP5" },
149    { -1,               NULL }
150};
151
152#ifdef HAVE_ISA
153static IsaChipsets TRIDENTISAchipsets[] = {
154    { TVGA9000,         RES_EXCLUSIVE_VGA },
155    { TVGA9000i,        RES_EXCLUSIVE_VGA },
156    { TVGA8900C,        RES_EXCLUSIVE_VGA },
157    { TVGA8900D,        RES_EXCLUSIVE_VGA },
158    { TVGA9200CXr,      RES_EXCLUSIVE_VGA },
159    { TGUI9400CXi,      RES_EXCLUSIVE_VGA },
160    { CYBER9320,        RES_EXCLUSIVE_VGA },
161    { TGUI9440AGi,      RES_EXCLUSIVE_VGA },
162    { -1,               RES_UNDEFINED }
163};
164#endif
165
166static PciChipsets TRIDENTPciChipsets[] = {
167    { CYBER9320,        PCI_CHIP_9320,  RES_SHARED_VGA },
168    { CYBER9388,        PCI_CHIP_9388,  RES_SHARED_VGA },
169    { CYBER9397,        PCI_CHIP_9397,  RES_SHARED_VGA },
170    { CYBER9397DVD,     PCI_CHIP_939A,  RES_SHARED_VGA },
171    { CYBER9520,        PCI_CHIP_9520,  RES_SHARED_VGA },
172    { CYBER9525DVD,     PCI_CHIP_9525,  RES_SHARED_VGA },
173    { CYBERBLADEE4,     PCI_CHIP_9540,  RES_SHARED_VGA },
174    { TGUI9420DGi,      PCI_CHIP_9420,  RES_SHARED_VGA },
175    { TGUI9440AGi,      PCI_CHIP_9440,  RES_SHARED_VGA },
176    { TGUI9660,         PCI_CHIP_9660,  RES_SHARED_VGA },
177    { TGUI9680,         PCI_CHIP_9660,  RES_SHARED_VGA },
178    { PROVIDIA9682,     PCI_CHIP_9660,  RES_SHARED_VGA },
179    { PROVIDIA9685,     PCI_CHIP_9660,  RES_SHARED_VGA },
180    { CYBER9382,        PCI_CHIP_9660,  RES_SHARED_VGA },
181    { CYBER9385,        PCI_CHIP_9660,  RES_SHARED_VGA },
182    { IMAGE975,         PCI_CHIP_9750,  RES_SHARED_VGA },
183    { IMAGE985,         PCI_CHIP_9850,  RES_SHARED_VGA },
184    { BLADE3D,          PCI_CHIP_9880,  RES_SHARED_VGA },
185    { CYBERBLADEI7,     PCI_CHIP_8400,  RES_SHARED_VGA },
186    { CYBERBLADEI7D,    PCI_CHIP_8420,  RES_SHARED_VGA },
187    { CYBERBLADEI1,     PCI_CHIP_8500,  RES_SHARED_VGA },
188    { CYBERBLADEI1D,    PCI_CHIP_8520,  RES_SHARED_VGA },
189    { CYBERBLADEAI1,    PCI_CHIP_8600,  RES_SHARED_VGA },
190    { CYBERBLADEAI1D,   PCI_CHIP_8620,  RES_SHARED_VGA },
191    { BLADEXP,          PCI_CHIP_9910,  RES_SHARED_VGA },
192    { CYBERBLADEXPAI1,  PCI_CHIP_8820,  RES_SHARED_VGA },
193    { CYBERBLADEXP4,    PCI_CHIP_2100,  RES_SHARED_VGA },
194    { XP5,              PCI_CHIP_2200,  RES_SHARED_VGA },
195    { -1,               -1,             RES_UNDEFINED }
196};
197
198typedef enum {
199    OPTION_ACCELMETHOD,
200    OPTION_SW_CURSOR,
201    OPTION_PCI_RETRY,
202    OPTION_RGB_BITS,
203    OPTION_NOACCEL,
204    OPTION_SETMCLK,
205    OPTION_MUX_THRESHOLD,
206    OPTION_SHADOW_FB,
207    OPTION_ROTATE,
208    OPTION_MMIO_ONLY,
209    OPTION_VIDEO_KEY,
210    OPTION_NOMMIO,
211    OPTION_NOPCIBURST,
212    OPTION_CYBER_SHADOW,
213    OPTION_CYBER_STRETCH,
214    OPTION_XV_HSYNC,
215    OPTION_XV_VSYNC,
216    OPTION_XV_BSKEW,
217    OPTION_XV_RSKEW,
218    OPTION_FP_DELAY,
219    OPTION_1400_DISPLAY,
220    OPTION_DISPLAY,
221    OPTION_GB,
222    OPTION_TV_CHIPSET,
223    OPTION_TV_SIGNALMODE
224} TRIDENTOpts;
225
226static const OptionInfoRec TRIDENTOptions[] = {
227    { OPTION_ACCELMETHOD,       "AccelMethod",      OPTV_ANYSTR,    {0}, FALSE },
228    { OPTION_SW_CURSOR,         "SWcursor",         OPTV_BOOLEAN,   {0}, FALSE },
229    { OPTION_PCI_RETRY,         "PciRetry",         OPTV_BOOLEAN,   {0}, FALSE },
230    { OPTION_NOACCEL,           "NoAccel",          OPTV_BOOLEAN,   {0}, FALSE },
231    { OPTION_SETMCLK,           "SetMClk",          OPTV_FREQ,      {0}, FALSE },
232    { OPTION_MUX_THRESHOLD,     "MUXThreshold",     OPTV_INTEGER,   {0}, FALSE },
233    { OPTION_SHADOW_FB,         "ShadowFB",         OPTV_BOOLEAN,   {0}, FALSE },
234    { OPTION_ROTATE,            "Rotate",           OPTV_ANYSTR,    {0}, FALSE },
235    { OPTION_VIDEO_KEY,         "VideoKey",         OPTV_INTEGER,   {0}, FALSE },
236    { OPTION_NOMMIO,            "NoMMIO",           OPTV_BOOLEAN,   {0}, FALSE },
237    { OPTION_NOPCIBURST,        "NoPciBurst",       OPTV_BOOLEAN,   {0}, FALSE },
238    { OPTION_MMIO_ONLY,         "MMIOonly",         OPTV_BOOLEAN,   {0}, FALSE },
239    { OPTION_CYBER_SHADOW,      "CyberShadow",      OPTV_BOOLEAN,   {0}, FALSE },
240    { OPTION_CYBER_STRETCH,     "CyberStretch",     OPTV_BOOLEAN,   {0}, FALSE },
241    { OPTION_XV_HSYNC,          "XvHsync",          OPTV_INTEGER,   {0}, FALSE },
242    { OPTION_XV_VSYNC,          "XvVsync",          OPTV_INTEGER,   {0}, FALSE },
243    { OPTION_XV_BSKEW,          "XvBskew",          OPTV_INTEGER,   {0}, FALSE },
244    { OPTION_XV_RSKEW,          "XvRskew",          OPTV_INTEGER,   {0}, FALSE },
245    { OPTION_FP_DELAY,          "FpDelay",          OPTV_INTEGER,   {0}, FALSE },
246    { OPTION_1400_DISPLAY,      "Display1400",      OPTV_BOOLEAN,   {0}, FALSE },
247    { OPTION_DISPLAY,           "Display",          OPTV_ANYSTR,    {0}, FALSE },
248    { OPTION_GB,                "GammaBrightness",  OPTV_ANYSTR,    {0}, FALSE },
249    { OPTION_TV_CHIPSET,        "TVChipset",        OPTV_ANYSTR,    {0}, FALSE },
250    { OPTION_TV_SIGNALMODE,     "TVSignal",         OPTV_INTEGER,   {0}, FALSE },
251    { -1,                       NULL,               OPTV_NONE,      {0}, FALSE }
252};
253
254/* Clock Limits */
255static int ClockLimit[] = {
256    80000,
257    80000,
258    80000,
259    80000,
260    80000,
261    80000,
262    80000,
263    80000,
264    80000,
265    80000,
266    80000,
267    80000,
268    80000,
269    80000,
270    90000,
271    90000,
272    135000,
273    135000,
274    170000,
275    170000,
276    170000,
277    170000,
278    170000,
279    170000,
280    170000,
281    230000,
282    230000,
283    230000,
284    230000,
285    230000,
286    230000,
287    230000,
288    230000,
289    230000,
290    230000,
291    230000,
292    230000,
293    230000,
294    230000,
295    230000,
296    230000,
297};
298
299static int ClockLimit16bpp[] = {
300    40000,
301    40000,
302    40000,
303    40000,
304    40000,
305    40000,
306    40000,
307    40000,
308    40000,
309    40000,
310    40000,
311    40000,
312    40000,
313    40000,
314    45000,
315    45000,
316    90000,
317    90000,
318    135000,
319    135000,
320    170000,
321    170000,
322    170000,
323    170000,
324    170000,
325    230000,
326    230000,
327    230000,
328    230000,
329    230000,
330    230000,
331    230000,
332    230000,
333    230000,
334    230000,
335    230000,
336    230000,
337    230000,
338    230000,
339    230000,
340    230000,
341};
342
343static int ClockLimit24bpp[] = {
344    25180,
345    25180,
346    25180,
347    25180,
348    25180,
349    25180,
350    25180,
351    25180,
352    25180,
353    25180,
354    25180,
355    25180,
356    25180,
357    25180,
358    25180,
359    25180,
360    40000,
361    40000,
362    70000,
363    70000,
364    70000,
365    115000,
366    115000,
367    115000,
368    115000,
369    115000,
370    115000,
371    115000,
372    115000,
373    115000,
374    115000,
375    115000,
376    115000,
377    115000,
378    115000,
379    115000,
380    115000,
381    115000,
382    115000,
383    115000,
384    115000,
385};
386
387static int ClockLimit32bpp[] = {
388    25180,
389    25180,
390    25180,
391    25180,
392    25180,
393    25180,
394    25180,
395    25180,
396    25180,
397    25180,
398    25180,
399    25180,
400    25180,
401    25180,
402    25180,
403    25180,
404    40000,
405    40000,
406    70000,
407    70000,
408    70000,
409    115000,
410    115000,
411    115000,
412    115000,
413    115000,
414    115000,
415    115000,
416    115000,
417    115000,
418    115000,
419    115000,
420    115000,
421    115000,
422    115000,
423    115000,
424    115000,
425    115000,
426    115000,
427    115000,
428    115000,
429    115000,
430};
431
432/*
433 * These are fixed modelines for all physical display dimensions the
434 *  chipsets supports on FPs. Most of them are not tested yet.
435 */
436#if 0
437tridentLCD LCD[] = {   /* 0    3    4    5   6    7    10   11  16 */
438    { 0,"640x480",25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08},
439    { 1,"800x600",40000,0x7f,0x99,0x69,0x99,0x72,0xf0,0x59,0x2d,0x5e,0x08},
440    { 2,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08},
441    { 3,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, /*0x96*/
442    { 4,"1280x1024",108000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08},
443    { 5,"1024x600",50500 ,0xa3,0x6,0x8f,0xa0,0xb,0x3e,0xea,0x8c,0xb,0x08},
444    { 0xff,"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
445};
446#else
447#if 0
448tridentLCD LCD[] = {
449    { 1,640,480,25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08},
450    { 3,800,600,40000,0x7f,0x82,0x6b,0x1b,0x72,0xf8,0x58,0x8c,0x72,0x08},
451    { 2,1024,768,65000,0xa3,/*0x6*/0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x24,0x0a,0x08},
452    { 0,1280,1024,108000,0xce,0x81,0xa6,0x9a,0x27,0x50,0x00,0x03,0x26,0xa8},
453    { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
454};
455#else
456tridentLCD LCD[] = {
457    { 1,640,480,25200,0x5f,0x80,0x52,0x1e,0xb,0x3e,0xea,0x0c,0xb,0x08},
458    { 3,800,600,40000,0x7f,0x00,0x69,0x7f,0x72,0xf0,0x59,0x0d,0x00,0x08},
459    { 2,1024,768,65000,0xa3,0x00,0x84,0x94,0x24,0xf5,0x03,0x09,0x24,0x08},
460    { 0,1280,1024,108000,0xce,0x91,0xa6,0x14,0x28,0x5a,0x01,0x04,0x28,0xa8},
461    { 4,1400,1050,122000,0xe6,0x8d,0xba,0x1d,0x38,0x00,0x1c,0x28,0x28,0xf8},
462    { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
463};
464#endif
465#endif
466
467#ifdef XFree86LOADER
468
469static MODULESETUPPROTO(tridentSetup);
470
471static XF86ModuleVersionInfo tridentVersRec =
472{
473    "trident",
474    MODULEVENDORSTRING,
475    MODINFOSTRING1,
476    MODINFOSTRING2,
477    XORG_VERSION_CURRENT,
478    TRIDENT_MAJOR_VERSION, TRIDENT_MINOR_VERSION, TRIDENT_PATCHLEVEL,
479    ABI_CLASS_VIDEODRV,			/* This is a video driver */
480    ABI_VIDEODRV_VERSION,
481    MOD_CLASS_VIDEODRV,
482    {0,0,0,0}
483};
484
485_X_EXPORT XF86ModuleData tridentModuleData = {
486    &tridentVersRec,
487    tridentSetup,
488    NULL
489};
490
491pointer
492tridentSetup(pointer module, pointer opts, int *errmaj, int *errmin)
493{
494    static Bool setupDone = FALSE;
495
496    if (!setupDone) {
497        setupDone = TRUE;
498        xf86AddDriver(&TRIDENT, module, 0);
499        return (pointer)TRUE;
500    }
501
502    if (errmaj) *errmaj = LDR_ONCEONLY;
503    return NULL;
504}
505
506#endif /* XFree86LOADER */
507
508static void
509TRIDENTEnableMMIO(ScrnInfoPtr pScrn)
510{
511    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
512    unsigned long vgaIOBase = pTrident->PIOBase + VGAHWPTR(pScrn)->IOBase;
513    CARD8 temp = 0, protect = 0;
514
515    /*
516     * Skip MMIO Enable in PC-9821 PCI Trident Card!!
517     * Because of lack of non PCI VGA port
518     */
519#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
520    if (IsPciCard && xf86IsPc98())
521        return;
522#endif
523
524    /* Goto New Mode */
525    outb(pTrident->PIOBase + 0x3C4, 0x0B);
526    inb(pTrident->PIOBase + 0x3C5);
527
528    /* Unprotect registers */
529    if (pTrident->Chipset > PROVIDIA9685) {
530        outb(pTrident->PIOBase + 0x3C4, Protection);
531        protect = inb(pTrident->PIOBase + 0x3C5);
532        outb(pTrident->PIOBase + 0x3C5, 0x92);
533    }
534    outb(pTrident->PIOBase + 0x3C4, NewMode1);
535    temp = inb(pTrident->PIOBase + 0x3C5);
536    outb(pTrident->PIOBase + 0x3C5, 0x80);
537
538    /* Enable MMIO */
539    outb(vgaIOBase + 4, PCIReg);
540    pTrident->REGPCIReg = inb(vgaIOBase + 5);
541    outb(vgaIOBase + 5, pTrident->REGPCIReg | 0x01); /* Enable it */
542
543    /* Protect registers */
544    if (pTrident->Chipset > PROVIDIA9685) {
545        OUTB(0x3C4, Protection);
546        OUTB(0x3C5, protect);
547    }
548    OUTB(0x3C4, NewMode1);
549    OUTB(0x3C5, temp);
550}
551
552static void
553TRIDENTDisableMMIO(ScrnInfoPtr pScrn)
554{
555    int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
556    CARD8 temp = 0, protect = 0;
557    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
558
559    /*
560     * Skip MMIO Disable in PC-9821 PCI Trident Card!!
561     * Because of lack of non PCI VGA port
562     */
563#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
564    if (IsPciCard && xf86IsPc98())
565        return;
566#endif
567
568    /* Goto New Mode */
569    OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
570
571    /* Unprotect registers */
572    OUTB(0x3C4, NewMode1); temp = INB(0x3C5);
573    OUTB(0x3C5, 0x80);
574    if (pTrident->Chipset > PROVIDIA9685) {
575        OUTB(0x3C4, Protection);
576        protect = INB(0x3C5);
577        OUTB(0x3C5, 0x92);
578    }
579
580    /* Disable MMIO access */
581    OUTB(vgaIOBase + 4, PCIReg);
582    pTrident->REGPCIReg = INB(vgaIOBase + 5);
583    OUTB(vgaIOBase + 5, pTrident->REGPCIReg & 0xFE);
584
585    /* Protect registers */
586    if (pTrident->Chipset > PROVIDIA9685) {
587        outb(pTrident->PIOBase + 0x3C4, Protection);
588        outb(pTrident->PIOBase + 0x3C5, protect);
589    }
590    outb(pTrident->PIOBase + 0x3C4, NewMode1);
591    outb(pTrident->PIOBase + 0x3C5, temp);
592}
593
594#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
595/* Initialize VGA Block for Cyber9385 on PC-98x1 */
596static void
597PC98TRIDENT9385Init(ScrnInfoPtr pScrn)
598{
599    /* Nothing to initialize */
600}
601
602static void
603PC98TRIDENT9385Enable(ScrnInfoPtr pScrn)
604{
605    outb(0xFAC, 0x02);
606}
607
608static void
609PC98TRIDENT9385Disable(ScrnInfoPtr pScrn)
610{
611    outb(0xFAC, 0x00);
612}
613
614/* Initialize VGA Block for Trident96xx on PC-98x1 */
615static void
616PC98TRIDENT96xxInit(ScrnInfoPtr pScrn)
617{
618    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
619    vgaHWPtr hwp = VGAHWPTR(pScrn);
620    CARD8 temp = 0;
621
622    vgaHWProtect(pScrn, TRUE);
623
624    /* Video SusSystem Enable */
625    temp = INB(0x3CC);
626    OUTB(0x3C2, temp | 0xC3);
627    /* Switch Old */
628    OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
629    OUTW(0x3C4, 0x0B | (temp << 8));
630    /* Select Configuration Port 1 */
631    OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
632    OUTW(0x3C4, 0x0E | ((temp | 0x20) << 8));
633
634    OUTB(0x3C4, 0x0c);
635    if((INB(0x3C5) & 0x10) == 0x10)
636    {
637        OUTB(0x3C4, 0x0E | (temp << 8));
638        OUTB(0x94,  0x00);
639        OUTB(0x102, 0x01);
640        OUTB(0x94,  0x20);
641        temp = INB(0x3C3);
642        OUTB(0x3C3, temp | 0x01);
643    } else {
644        OUTB(0x3C4, 0x0E | (temp << 8));
645        OUTB(0x46E8, 0x10);
646        OUTB(0x102,  0x01);
647        OUTB(0x46E8, 0x08);
648    }
649
650    INB(0x3DA);
651    OUTB(0x3C0,0x10);
652    OUTB(0x3C0,0x41);
653
654    /* Register Unlock */
655    vgaHWUnlock(hwp);
656    OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */
657    OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
658    OUTW(0x3C4, 0x0E | ((temp | 0x80) << 8));
659
660    /* For Speed Up [Facoor 2 at Xengine] */
661    OUTW(0x3D4, 0x3820); /* Command FIFO Register */
662    OUTW(0x3D4, 0x2020); /* Command FIFO Register */
663    /* Latency Control Registers 0x30 - 0x32 */
664    /* Parameter Range 0x00 - 0x0F */
665    /* Tune these parameter to avoid GE Timeout */
666    OUTW(0x3D4, 0x0E30); /* Display Queue Latency Control */
667    /* 8bpp GE No Timeout Parameter 0x0D - 0x0F for PC-9821Xa7 TGUi9680 */
668    OUTW(0x3D4, 0x0031); /* Frame Buffer Latency Control */
669    OUTW(0x3D4, 0x0032); /* Display & Frame Buffer Latency Control */
670    OUTW(0x3D4, 0x213B); /* Clock and Tuning */
671
672    /* MCLK Init */
673    OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */
674#if 0
675    /* Sample MCLKs */
676    OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */
677    OUTB(0x43C6, 0xA7); OUTB(0x43C7, 0x00); /* 77.0MHz */
678    OUTB(0x43C6, 0x8E); OUTB(0x43C7, 0x00); /* 75.0MHz */
679    OUTB(0x43C6, 0x86); OUTB(0x43C7, 0x00); /* 72.0MHz */
680    OUTB(0x43C6, 0x8F); OUTB(0x43C7, 0x00); /* 67.2MHz */
681    OUTB(0x43C6, 0xD5); OUTB(0x43C7, 0x02); /* 61.6MHz */
682#endif
683
684    /* Register Lock */
685    OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */
686    OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
687    OUTW(0x3C4, 0x0E | ((temp & 0x7F) << 8));
688    vgaHWLock(hwp);
689
690    vgaHWProtect(pScrn, FALSE);
691}
692
693static void
694PC98TRIDENT96xxEnable(ScrnInfoPtr pScrn)
695{
696    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
697    CARD8 temp = 0;
698
699    outb(0x68, 0x0E);
700    outb(0x6A, 0x07);
701    outb(0x6A, 0x8F);
702    outb(0x6A, 0x06);
703
704    vgaHWProtect(pScrn, TRUE);
705
706    OUTB(0x3D4, 0x23); temp = INB(0x3D5);
707    OUTW(0x3D4, 0x23 | ((temp & 0xDF) << 8));
708
709    OUTB(0x3D4, 0x29); temp = INB(0x3D5);
710    OUTW(0x3D4, 0x29 | ((temp | 0x04) << 8));
711
712    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
713    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x06));
714
715    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
716    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x08));
717
718    OUTB(0x3CE, 0x23); temp = INB(0x3CF);
719    OUTW(0x3CE, 0x23 | ((temp & 0xFC) << 8));
720
721    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
722    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x01));
723
724    OUTB(0x3C4, 0x01); temp = INB(0x3C5);
725    OUTW(0x3C4, 0x01 | ((temp & 0xEF) << 8));
726
727    vgaHWProtect(pScrn, FALSE);
728
729    outb(0xFAC, 0x02);
730}
731
732static void
733PC98TRIDENT96xxDisable(ScrnInfoPtr pScrn)
734{
735    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
736    CARD8 temp = 0;
737
738    outb(0xFAC, 0x00);
739
740    vgaHWProtect(pScrn, TRUE);
741
742    OUTB(0x3C4, 0x01); temp = INB(0x3C5);
743    OUTW(0x3C4, 0x01 | ((temp | 0x10) << 8));
744
745    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
746    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFE));
747
748    OUTB(0x3CE, 0x23); temp = INB(0x3CF);
749    OUTW(0x3CE, 0x23 | (((temp & 0xFC) | 0x01) << 8));
750
751    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
752    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFD));
753
754    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
755    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xCF));
756
757    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
758    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xF7));
759
760    OUTB(0x83C8, 0x04); temp = INB(0x83c6);
761    OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFB));
762
763    OUTB(0x3D4, 0x29); temp = INB(0x3D5);
764    OUTW(0x3D4, 0x29 | ((temp & 0xFB) << 8));
765
766    OUTB(0x3D4, 0x23); temp = INB(0x3D5);
767    OUTW(0x3D4, 0x23 | ((temp | 0x20) << 8));
768
769    vgaHWProtect(pScrn, FALSE);
770
771    outb(0x6A, 0x07);
772    outb(0x6A, 0x8E);
773    outb(0x6A, 0x06);
774    outb(0x68, 0x0F);
775}
776
777/* Initialize VGA Block for Trident Chip on PC-98x1 */
778static void
779PC98TRIDENTInit(ScrnInfoPtr pScrn)
780{
781    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
782    switch (pTrident->Chipset) {
783    case TGUI9660:
784    case TGUI9680:
785    case PROVIDIA9682:
786        PC98TRIDENT96xxInit(pScrn);
787        break;
788    case CYBER9320:
789    case CYBER9385:
790        PC98TRIDENT9385Init(pScrn);
791        break;
792    default: /* Run 96xx code as default */
793        PC98TRIDENT96xxInit(pScrn);
794        break;
795    }
796}
797
798static void
799PC98TRIDENTEnable(ScrnInfoPtr pScrn)
800{
801    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
802    switch (pTrident->Chipset) {
803    case TGUI9660:
804    case TGUI9680:
805    case PROVIDIA9682:
806        PC98TRIDENT96xxEnable(pScrn);
807        break;
808    case CYBER9320:
809    case CYBER9385:
810        PC98TRIDENT9385Enable(pScrn);
811        break;
812    default: /* Run 96xx code as default */
813        PC98TRIDENT96xxEnable(pScrn);
814        break;
815    }
816}
817
818static void
819PC98TRIDENTDisable(ScrnInfoPtr pScrn)
820{
821    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
822    switch (pTrident->Chipset) {
823    case TGUI9660:
824    case TGUI9680:
825    case PROVIDIA9682:
826        PC98TRIDENT96xxDisable(pScrn);
827        break;
828    case CYBER9320:
829    case CYBER9385:
830        PC98TRIDENT9385Disable(pScrn);
831        break;
832    default: /* Run 96xx code as default */
833        PC98TRIDENT96xxDisable(pScrn);
834        break;
835    }
836}
837#endif
838
839/*
840 * This is a terrible hack! If we are on a notebook in a stretched
841 * mode and don't want full screen we use the BIOS to set an unstreched
842 * mode.
843 */
844void
845tridentSetModeBIOS(ScrnInfoPtr pScrn, DisplayModePtr mode)
846{
847    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
848
849
850#ifdef VBE_INFO
851    if (pTrident->vbeModes) {
852        vbeSaveRestoreRec vbesr;
853        vbesr.stateMode = VBECalcVbeModeIndex(pTrident->vbeModes,
854                mode, pScrn->bitsPerPixel);
855        vbesr.pstate = NULL;
856        if (vbesr.stateMode) {
857            if (IsPciCard && UseMMIO)
858                TRIDENTDisableMMIO(pScrn);
859            VBEVesaSaveRestore(pTrident->pVbe,&vbesr,MODE_RESTORE);
860            if (IsPciCard && UseMMIO)
861                TRIDENTEnableMMIO(pScrn);
862            return;
863        } else
864            xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"No BIOS Mode matches "
865                    "%ix%I@%ibpp\n",mode->HDisplay,mode->VDisplay,
866                    pScrn->bitsPerPixel);
867    }
868#endif
869    /* This function is only for LCD screens, and also when we have
870     * int10 available */
871
872    if (pTrident->IsCyber && pTrident->lcdMode && pTrident->Int10) {
873        int i = pTrident->lcdMode;
874        if ((pScrn->currentMode->HDisplay != LCD[i].display_x) /* !fullsize? */
875                || (pScrn->currentMode->VDisplay != LCD[i].display_y)) {
876            if (pTrident->lcdActive)  { /* LCD Active ?*/
877                int h_str, v_str;
878
879                OUTB(0x3CE,HorStretch);  h_str = INB(0x3CF) & 0x01;
880                OUTB(0x3CE,VertStretch); v_str = INB(0x3CF) & 0x01;
881                if (h_str || v_str) {
882                    OUTB(0x3C4, 0x11); OUTB(0x3C5, 0x92);
883                    OUTW(0x3CE, BiosReg );
884                    pTrident->Int10->ax = 0x3;
885                    pTrident->Int10->num = 0x10;
886                    if (IsPciCard && UseMMIO)
887                        TRIDENTDisableMMIO(pScrn);
888                    xf86ExecX86int10(pTrident->Int10);
889                    if (IsPciCard && UseMMIO)
890                        TRIDENTEnableMMIO(pScrn);
891                }
892            }
893        }
894    }
895}
896
897/* Currently we only test for 1400 */
898static int
899TRIDENTLcdDisplaySize (xf86MonPtr pMon)
900{
901    if (pMon) {
902        int i,j;
903
904        for (i = 0; i < STD_TIMINGS; i++) {
905            if (pMon->timings2[i].hsize == 1400) {
906                return 1400;
907            }
908        }
909        /*
910         * If not explicitly set try to find out if the display supports
911         * the 1400 mode. For sanity check if DDC comes from a digital
912         * display.
913         */
914        if (DIGITAL(pMon->features.input_type)) {
915            for (i = 0; i < DET_TIMINGS; i++) {
916                if (pMon->det_mon[i].type == DS_STD_TIMINGS) {
917                    for (j = 0; j < 5; j++) {
918                        if (pMon->det_mon[i].section.std_t[j].hsize == 1400) {
919                            return 1400;
920                        }
921                    }
922                } else if (pMon->det_mon[i].type == DT) {
923                    if (pMon->det_mon[i].section.d_timings.h_active == 1400) {
924                        return 1400;
925                    }
926                }
927            }
928        }
929    }
930    return 0;
931}
932
933/*
934 * Initialise a new mode.  This is currently still using the old
935 * "initialise struct, restore/write struct to HW" model.  That could
936 * be changed.
937 */
938
939static Bool
940TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
941{
942    vgaHWPtr hwp = VGAHWPTR(pScrn);
943    vgaRegPtr vgaReg;
944    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
945    TRIDENTRegPtr tridentReg;
946
947#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
948    if (!xf86IsPc98())
949#endif
950        WAITFORVSYNC;
951
952    TridentFindClock(pScrn,mode->Clock);
953
954    switch (pTrident->Chipset) {
955    case TGUI9660:
956    case TGUI9680:
957    case PROVIDIA9682:
958    case PROVIDIA9685:
959    case IMAGE975:
960    case IMAGE985:
961    case BLADE3D:
962    case CYBERBLADEI7:
963    case CYBERBLADEI7D:
964    case CYBERBLADEI1:
965    case CYBERBLADEI1D:
966    case CYBERBLADEAI1:
967    case CYBERBLADEAI1D:
968    case CYBER9520:
969    case CYBER9525DVD:
970    case CYBERBLADEE4:
971    case CYBER9397:
972    case CYBER9397DVD:
973    case BLADEXP:
974    case CYBERBLADEXPAI1:
975    case CYBERBLADEXP4:
976    case XP5:
977        /* Get ready for MUX mode */
978        if (pTrident->MUX &&
979                pScrn->bitsPerPixel == 8 &&
980                !mode->CrtcHAdjusted) {
981            ErrorF("BARF\n");
982            mode->CrtcHDisplay >>= 1;
983            mode->CrtcHSyncStart >>= 1;
984            mode->CrtcHSyncEnd >>= 1;
985            mode->CrtcHBlankStart >>= 1;
986            mode->CrtcHBlankEnd >>= 1;
987            mode->CrtcHTotal >>= 1;
988            mode->CrtcHAdjusted = TRUE;
989        }
990        break;
991    default:
992        if (pScrn->videoRam < 1024 &&
993                !mode->CrtcHAdjusted) {
994            mode->CrtcHDisplay <<= 1;
995            mode->CrtcHSyncStart <<= 1;
996            mode->CrtcHSyncEnd <<= 1;
997            mode->CrtcHBlankStart <<= 1;
998            mode->CrtcHBlankEnd <<= 1;
999            mode->CrtcHTotal <<= 1;
1000            mode->CrtcHAdjusted = TRUE;
1001        }
1002        break;
1003    }
1004
1005    vgaHWUnlock(hwp);
1006    /* Initialise the ModeReg values */
1007    if (!vgaHWInit(pScrn, mode))
1008        return FALSE;
1009
1010    pScrn->vtSema = TRUE;
1011    /*
1012     * We used to do this at a later time.
1013     * Now since READOUT isn't defined any more
1014     * we do it here.
1015     * The original NOTE read:
1016     * TridentInit() has to modify registers
1017     * that have already been set by vgaHWRestore().
1018     * So we call it _after_ vgaHWRestore() has
1019     * programmed these registers.
1020     */
1021    if (pScrn->progClock) {
1022        if (!TridentInit(pScrn, mode))
1023            return FALSE;
1024    } else {
1025        if (!TVGAInit(pScrn, mode))
1026            return FALSE;
1027    }
1028
1029    /* Program the registers */
1030    vgaHWProtect(pScrn, TRUE);
1031    vgaReg = &hwp->ModeReg;
1032    tridentReg = &pTrident->ModeReg;
1033
1034    vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
1035    if (pScrn->progClock)
1036        TridentRestore(pScrn, tridentReg);
1037    else
1038        TVGARestore(pScrn, tridentReg);
1039
1040    vgaHWProtect(pScrn, FALSE);
1041
1042#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
1043    if (xf86IsPc98())
1044        PC98TRIDENTEnable(pScrn);
1045#endif
1046
1047    if (pTrident->TVChipset != 0)
1048        VIA_TVInit(pScrn);
1049
1050    return TRUE;
1051}
1052
1053static Bool
1054TRIDENTGetRec(ScrnInfoPtr pScrn)
1055{
1056    /*
1057     * Allocate an TRIDENTRec, and hook it into pScrn->driverPrivate.
1058     * pScrn->driverPrivate is initialised to NULL, so we can check if
1059     * the allocation has already been done.
1060     */
1061    if (pScrn->driverPrivate != NULL)
1062        return TRUE;
1063
1064    pScrn->driverPrivate = xnfcalloc(sizeof(TRIDENTRec), 1);
1065    /* Initialise it */
1066
1067    return TRUE;
1068}
1069
1070static void
1071TRIDENTFreeRec(ScrnInfoPtr pScrn)
1072{
1073    if (pScrn->driverPrivate == NULL)
1074        return;
1075    free(pScrn->driverPrivate);
1076    pScrn->driverPrivate = NULL;
1077}
1078
1079
1080/*
1081 * This function saves the video state.
1082 */
1083static void
1084TRIDENTSave(ScrnInfoPtr pScrn)
1085{
1086    TRIDENTPtr pTrident;
1087    vgaRegPtr vgaReg;
1088    TRIDENTRegPtr tridentReg;
1089
1090    pTrident = TRIDENTPTR(pScrn);
1091    vgaReg = &VGAHWPTR(pScrn)->SavedReg;
1092    tridentReg = &pTrident->SavedReg;
1093
1094    vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP |
1095            (IsPrimaryCard ? VGA_SR_FONTS : 0));
1096
1097    if (pScrn->progClock)
1098        TridentSave(pScrn, tridentReg);
1099    else
1100        TVGASave(pScrn, tridentReg);
1101
1102    if (pTrident->TVChipset != 0)
1103        VIA_SaveTVDepentVGAReg(pScrn);
1104}
1105
1106
1107/*
1108 * Restore the initial (text) mode.
1109 */
1110static void
1111TRIDENTRestore(ScrnInfoPtr pScrn)
1112{
1113    vgaHWPtr hwp;
1114    vgaRegPtr vgaReg;
1115    TRIDENTPtr pTrident;
1116    TRIDENTRegPtr tridentReg;
1117
1118    hwp = VGAHWPTR(pScrn);
1119    pTrident = TRIDENTPTR(pScrn);
1120    vgaReg = &hwp->SavedReg;
1121    tridentReg = &pTrident->SavedReg;
1122
1123    vgaHWProtect(pScrn, TRUE);
1124
1125    if (pScrn->progClock)
1126        TridentRestore(pScrn, tridentReg);
1127    else
1128        TVGARestore(pScrn, tridentReg);
1129
1130    vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP |
1131            (IsPrimaryCard ? VGA_SR_FONTS : 0));
1132
1133    if (pTrident->TVChipset != 0)
1134        VIA_RestoreTVDependVGAReg(pScrn);
1135
1136    vgaHWProtect(pScrn, FALSE);
1137}
1138
1139/* Usually mandatory */
1140Bool
1141TRIDENTSwitchMode(SWITCH_MODE_ARGS_DECL)
1142{
1143    SCRN_INFO_PTR(arg);
1144    return TRIDENTModeInit(pScrn, mode);
1145}
1146
1147
1148/*
1149 * This function is used to initialize the Start Address - the first
1150 * displayed location in the video memory.
1151 */
1152/* Usually mandatory */
1153void
1154TRIDENTAdjustFrame(ADJUST_FRAME_ARGS_DECL)
1155{
1156    SCRN_INFO_PTR(arg);
1157    TRIDENTPtr pTrident;
1158    int base = y * pScrn->displayWidth + x;
1159    int vgaIOBase;
1160    CARD8 temp;
1161
1162    pTrident = TRIDENTPTR(pScrn);
1163    vgaIOBase = VGAHWPTR(pScrn)->IOBase;
1164
1165    switch (pScrn->bitsPerPixel) {
1166    case 8:
1167        if (pScrn->progClock)
1168            base = (base & 0xFFFFFFF8) >> 2;
1169        else
1170            base = (base & 0xFFFFFFF8) >> 3;
1171        break;
1172    case 16:
1173        base >>= 1;
1174        break;
1175    case 24:
1176        base = (((base + 1) & ~0x03) * 3) >> 2;
1177        break;
1178    case 32:
1179        break;
1180    }
1181
1182    /* CRT bits 0-15 */
1183    OUTW(vgaIOBase + 4, (base & 0x00FF00) | 0x0C);
1184    OUTW(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D);
1185    /* CRT bit 16 */
1186    OUTB(vgaIOBase + 4, CRTCModuleTest); temp = INB(vgaIOBase + 5) & 0xDF;
1187    OUTB(vgaIOBase + 5, temp | ((base & 0x10000) >> 11));
1188    /* CRT bit 17-19 */
1189    OUTB(vgaIOBase + 4, CRTHiOrd); temp = INB(vgaIOBase + 5) & 0xF8;
1190    OUTB(vgaIOBase + 5, temp | ((base & 0xE0000) >> 17));
1191}
1192
1193
1194/*
1195 * This is called when VT switching back to the X server.  Its job is
1196 * to reinitialise the video mode.
1197 */
1198
1199/* Mandatory */
1200static Bool
1201TRIDENTEnterVT(VT_FUNC_ARGS_DECL)
1202{
1203    SCRN_INFO_PTR(arg);
1204    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1205
1206    if (IsPciCard && UseMMIO) TRIDENTEnableMMIO(pScrn);
1207
1208    /* Should we re-save the text mode on each VT enter? */
1209    if (!TRIDENTModeInit(pScrn, pScrn->currentMode))
1210        return FALSE;
1211
1212    if (pTrident->InitializeAccelerator)
1213        pTrident->InitializeAccelerator(pScrn);
1214
1215    return TRUE;
1216}
1217
1218
1219/*
1220 * This is called when VT switching away from the X server.  Its job is
1221 * to restore the previous (text) mode.
1222 *
1223 * We may wish to remap video/MMIO memory too.
1224 */
1225
1226/* Mandatory */
1227static void
1228TRIDENTLeaveVT(VT_FUNC_ARGS_DECL)
1229{
1230    SCRN_INFO_PTR(arg);
1231    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1232    vgaHWPtr hwp = VGAHWPTR(pScrn);
1233
1234#ifdef HAVE_XAA_H
1235    if (!pTrident->NoAccel && !pTrident->useEXA)
1236        pTrident->AccelInfoRec->Sync(pScrn);
1237    else
1238#endif
1239        if (!pTrident->NoAccel && pTrident->useEXA)
1240            pTrident->EXADriverPtr->WaitMarker(pScrn->pScreen, 0);
1241
1242    TRIDENTRestore(pScrn);
1243    vgaHWLock(hwp);
1244
1245#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
1246    if (xf86IsPc98())
1247        PC98TRIDENTDisable(pScrn);
1248#endif
1249
1250    if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn);
1251}
1252
1253
1254/* Free up any per-generation data structures */
1255
1256/* Optional */
1257static void
1258TRIDENTFreeScreen(FREE_SCREEN_ARGS_DECL)
1259{
1260    SCRN_INFO_PTR(arg);
1261    if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
1262        vgaHWFreeHWRec(pScrn);
1263    TRIDENTFreeRec(pScrn);
1264}
1265
1266
1267/* Checks if a mode is suitable for the selected chipset. */
1268
1269/* Optional */
1270static ModeStatus
1271TRIDENTValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
1272{
1273    SCRN_INFO_PTR(arg);
1274    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1275
1276    if (pTrident->lcdActive && (pTrident->lcdMode != 0xff)){
1277        if (((mode->HDisplay > LCD[pTrident->lcdMode].display_x)
1278                || (mode->VDisplay > LCD[pTrident->lcdMode].display_y))) {
1279            xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Removing mode (%dx%d) "
1280                    "larger than the LCD panel (%dx%d)\n",
1281                    mode->HDisplay,
1282                    mode->VDisplay,
1283                    LCD[pTrident->lcdMode].display_x,
1284                    LCD[pTrident->lcdMode].display_y);
1285            return(MODE_BAD);
1286        }
1287        if (((float)mode->HDisplay/(float)mode->VDisplay) > 2.0) {
1288            xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Removing mode (%dx%d) "
1289                    "unusual aspect ratio\n",
1290                    mode->HDisplay,
1291                    mode->VDisplay);
1292            return(MODE_BAD);
1293        }
1294    }
1295    return (MODE_OK);
1296}
1297
1298static void
1299TRIDENTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
1300{
1301    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1302    CARD8 DPMSCont, PMCont, temp;
1303
1304    if (!pScrn->vtSema)
1305        return;
1306
1307    OUTB(0x3C4, 0x0E);
1308    temp = INB(0x3C5);
1309    OUTB(0x3C5, 0xC2);
1310    OUTB(0x83C8, 0x04); /* Read DPMS Control */
1311    PMCont = INB(0x83C6) & 0xFC;
1312    OUTB(0x3CE, 0x23);
1313    DPMSCont = INB(0x3CF) & 0xFC;
1314    switch (PowerManagementMode)
1315    {
1316    case DPMSModeOn:
1317        /* Screen: On, HSync: On, VSync: On */
1318        PMCont |= 0x03;
1319        DPMSCont |= 0x00;
1320        break;
1321    case DPMSModeStandby:
1322        /* Screen: Off, HSync: Off, VSync: On */
1323        PMCont |= 0x02;
1324        DPMSCont |= 0x01;
1325        break;
1326    case DPMSModeSuspend:
1327        /* Screen: Off, HSync: On, VSync: Off */
1328        PMCont |= 0x02;
1329        DPMSCont |= 0x02;
1330        break;
1331    case DPMSModeOff:
1332        /* Screen: Off, HSync: Off, VSync: Off */
1333        PMCont |= 0x00;
1334        DPMSCont |= 0x03;
1335        break;
1336    }
1337    OUTB(0x3CF, DPMSCont);
1338    OUTB(0x83C8, 0x04);
1339    OUTB(0x83C6, PMCont);
1340    OUTW(0x3C4, (temp<<8) | 0x0E);
1341}
1342
1343static void
1344TRIDENTBlockHandler (BLOCKHANDLER_ARGS_DECL)
1345{
1346    SCREEN_PTR(arg);
1347    ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
1348    TRIDENTPtr     pTrident = TRIDENTPTR(pScrn);
1349
1350    pScreen->BlockHandler = pTrident->BlockHandler;
1351    (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
1352    pScreen->BlockHandler = TRIDENTBlockHandler;
1353
1354    if(pTrident->VideoTimerCallback) {
1355        UpdateCurrentTime();
1356        (*pTrident->VideoTimerCallback)(pScrn, currentTime.milliseconds);
1357    }
1358}
1359
1360static const OptionInfoRec *
1361TRIDENTAvailableOptions(int chipid, int busid)
1362{
1363    return TRIDENTOptions;
1364}
1365
1366/* Mandatory */
1367static void
1368TRIDENTIdentify(int flags)
1369{
1370    xf86PrintChipsets(TRIDENT_NAME, "driver for Trident chipsets", TRIDENTChipsets);
1371}
1372
1373Bool
1374TRIDENTClockSelect(ScrnInfoPtr pScrn, int no)
1375{
1376    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1377    unsigned char temp;
1378
1379    /*
1380     * CS0 and CS1 are in MiscOutReg
1381     *
1382     * For 8900B, 8900C, 8900CL and 9000, CS2 is bit 0 of
1383     * New Mode Control Register 2.
1384     *
1385     * For 8900CL, CS3 is bit 4 of Old Mode Control Register 1.
1386     *
1387     * For 9000, CS3 is bit 6 of New Mode Control Register 2.
1388     *
1389     * For TGUI, we don't use the ClockSelect function at all.
1390     */
1391    switch(no) {
1392    case CLK_REG_SAVE:
1393        pTrident->SaveClock1 = INB(0x3CC);
1394        if (pTrident->Chipset != TVGA8800CS) {
1395            if ( (pScrn->numClocks == 16) &&
1396                    (pTrident->Chipset != TVGA9000) &&
1397                    (pTrident->Chipset != TVGA9000i) )
1398            {
1399                OUTW(0x3C4, 0x000B);	/* Switch to Old Mode */
1400                OUTB(0x3C4, 0x0E); pTrident->SaveClock3 = INB(0x3C5);
1401            }
1402            OUTB(0x3C4, 0x0B);
1403            INB(0x3C5);		/* Now to New Mode */
1404            OUTB(0x3C4, 0x0D); pTrident->SaveClock2 = INB(0x3C5);
1405        }
1406        break;
1407    case CLK_REG_RESTORE:
1408        OUTB(0x3C2, pTrident->SaveClock1);
1409        if (pTrident->Chipset != TVGA8800CS) {
1410            if ( (pScrn->numClocks == 16) &&
1411                    (pTrident->Chipset != TVGA9000) &&
1412                    (pTrident->Chipset != TVGA9000i) )
1413            {
1414                OUTW(0x3C4, 0x000B);	/* Switch to Old Mode */
1415                OUTW(0x3C4, (pTrident->SaveClock3 << 8) | 0x0E);
1416            }
1417            OUTB(0x3C4, 0x0B);
1418            INB(0x3C5);		/* Now to New Mode */
1419            OUTW(0x3C4, (pTrident->SaveClock2 << 8) | 0x0D);
1420        }
1421        break;
1422    default:
1423        /*
1424         * Do CS0 and CS1
1425         */
1426        temp = INB(0x3CC);
1427        OUTB(0x3C2, (temp & 0xF3) | ((no << 2) & 0x0C));
1428        if (pTrident->Chipset != TVGA8800CS) {
1429            if ( (pScrn->numClocks == 16) &&
1430                    (pTrident->Chipset != TVGA9000) &&
1431                    (pTrident->Chipset != TVGA9000i) )
1432            {
1433                /*
1434                 * Go to Old Mode for CS3.
1435                 */
1436                OUTW(0x3C4, 0x000B);	/* Switch to Old Mode */
1437                OUTB(0x3C4, 0x0E);
1438                temp = INB(0x3C5) & 0xEF;
1439                temp |= (no & 0x08) << 1;
1440                OUTB(0x3C5, temp);
1441            }
1442            /*
1443             * Go to New Mode for CS2 and TVGA9000 CS3.
1444             */
1445            OUTB(0x3C4, 0x0B);
1446            INB(0x3C5);		/* Now to New Mode */
1447            OUTB(0x3C4, 0x0D);
1448            /*
1449             * Bits 1 & 2 are dividers - set to 0 to get no
1450             * clock division.
1451             */
1452            temp = INB(0x3C5) & 0xF8;
1453            temp |= (no & 0x04) >> 2;
1454            if ( (pTrident->Chipset == TVGA9000) ||
1455                    (pTrident->Chipset == TVGA9000i) )
1456            {
1457                temp &= ~0x40;
1458                temp |= (no & 0x08) << 3;
1459            }
1460            OUTB(0x3C5, temp);
1461        }
1462    }
1463    return(TRUE);
1464}
1465
1466#ifdef HAVE_ISA
1467static int
1468TridentFindIsaDevice(GDevPtr dev)
1469{
1470    int found = -1;
1471    unsigned char temp, origVal, newVal;
1472
1473    /*
1474     * Check first that we have a Trident card.
1475     */
1476    outb(0x3C4, 0x0B);
1477    temp = inb(0x3C5);	/* Save old value */
1478    outb(0x3C4, 0x0B);	/* Switch to Old Mode */
1479    outb(0x3C5, 0x00);
1480    inb(0x3C5);		/* Now to New Mode */
1481    outb(0x3C4, 0x0E);
1482    origVal = inb(0x3C5);
1483    outb(0x3C5, 0x00);
1484    newVal = inb(0x3C5) & 0x0F;
1485    outb(0x3C5, (origVal ^ 0x02));
1486
1487    /*
1488     * Is it a Trident card ??
1489     */
1490    if (newVal != 2) {
1491        /*
1492         * Nope, so quit
1493         */
1494        outb(0x3C4, 0x0B);	/* Restore value of 0x0B */
1495        outb(0x3C5, temp);
1496        outb(0x3C4, 0x0E);
1497        outb(0x3C5, origVal);
1498        return found;
1499    }
1500
1501    outb(0x3C4, 0x0B);
1502    temp = inb(0x3C5);
1503    switch (temp) {
1504    case 0x01:
1505        found = TVGA8800BR;
1506        break;
1507    case 0x02:
1508        found = TVGA8800CS;
1509        break;
1510    case 0x03:
1511        found = TVGA8900B;
1512        break;
1513    case 0x04:
1514    case 0x13:
1515        found = TVGA8900C;
1516        break;
1517    case 0x23:
1518        found = TVGA9000;
1519        break;
1520    case 0x33:
1521        found = TVGA8900D;
1522        break;
1523    case 0x43:
1524        found = TVGA9000i;
1525        break;
1526    case 0x53:
1527        found = TVGA9200CXr;
1528        break;
1529    case 0x63:
1530        found = TVGA9100B;
1531        break;
1532    case 0x73:
1533    case 0xC3:
1534        found = TGUI9420DGi;
1535        break;
1536    case 0x83:
1537        found = TVGA8200LX;
1538        break;
1539    case 0x93:
1540        found = TGUI9400CXi;
1541        break;
1542    case 0xA3:
1543        found = CYBER9320;
1544        break;
1545    case 0xD3:
1546        found = TGUI9660;
1547        break;
1548    case 0xE3:
1549        found = TGUI9440AGi;
1550        break;
1551    case 0xF3:
1552        found = TGUI9430DGi;
1553        break;
1554    }
1555    return found;
1556}
1557#endif
1558
1559/*
1560 * Map the framebuffer and MMIO memory.
1561 */
1562
1563static Bool
1564TRIDENTMapMem(ScrnInfoPtr pScrn)
1565{
1566    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1567    vgaHWPtr hwp = VGAHWPTR(pScrn);
1568    int mapsize = 0x10000;
1569
1570    if (Is3Dchip) mapsize = 0x20000;
1571
1572    if (IsPciCard && UseMMIO)
1573#ifndef XSERVER_LIBPCIACCESS
1574        pTrident->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
1575                pTrident->PciTag, pTrident->IOAddress, mapsize);
1576#else
1577    {
1578        void **result = (void **)&pTrident->IOBase;
1579        int err = pci_device_map_range(pTrident->PciInfo,
1580                pTrident->IOAddress,
1581                mapsize,
1582                PCI_DEV_MAP_FLAG_WRITABLE,
1583                result);
1584        if (err) {
1585            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1586                    "Unable to map IO aperture. %s (%d)\n",
1587                    strerror(err), err);
1588        }
1589    }
1590#endif
1591    else {
1592#ifndef XSERVER_LIBPCIACCESS
1593        pTrident->IOBase = xf86MapDomainMemory(pScrn->scrnIndex, VIDMEM_MMIO,
1594                pTrident->PciTag, pTrident->IOAddress, 0x1000);
1595        pTrident->IOBase += 0xF00;
1596#else
1597        return FALSE;
1598#endif
1599    }
1600
1601    if (pTrident->IOBase == NULL)
1602        return FALSE;
1603
1604    if (LINEAR()) {
1605        if (pTrident->FbMapSize != 0) {
1606#ifndef XSERVER_LIBPCIACCESS
1607            pTrident->FbBase = xf86MapPciMem(pScrn->scrnIndex,
1608                    VIDMEM_FRAMEBUFFER,
1609                    pTrident->PciTag,
1610                    (unsigned long)pTrident->FbAddress,
1611                    pTrident->FbMapSize);
1612#else
1613            {
1614                void **result = (void **)&pTrident->FbBase;
1615                int err = pci_device_map_range(pTrident->PciInfo,
1616                        pTrident->FbAddress,
1617                        pTrident->FbMapSize,
1618                        PCI_DEV_MAP_FLAG_WRITABLE |
1619                        PCI_DEV_MAP_FLAG_WRITE_COMBINE,
1620                        result);
1621                if (err) {
1622                    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1623                            "Unable to map VRAM aperture. %s (%d)\n",
1624                            strerror(err), err);
1625                }
1626            }
1627#endif
1628            if (pTrident->FbBase == NULL)
1629                return FALSE;
1630        }
1631    }
1632    else
1633        pTrident->FbBase = hwp->Base;
1634
1635    return TRUE;
1636}
1637
1638/*
1639 * Unmap the framebuffer and MMIO memory.
1640 */
1641
1642static Bool
1643TRIDENTUnmapMem(ScrnInfoPtr pScrn)
1644{
1645    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1646    int mapsize = 0x10000;
1647
1648    if (Is3Dchip) mapsize = 0x20000;
1649
1650    /*
1651     * Unmap IO registers to virtual address space
1652     */
1653#ifdef XSERVER_LIBPCIACCESS
1654    pci_device_unmap_range(pTrident->PciInfo, (pointer)pTrident->IOBase, mapsize);
1655#else
1656    if (IsPciCard && UseMMIO) {
1657        xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, mapsize);
1658    } else {
1659        pTrident->IOBase -= 0xF00;
1660        xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, 0x1000);
1661    }
1662#endif
1663    pTrident->IOBase = NULL;
1664
1665    if (LINEAR()) {
1666        if (pTrident->FbMapSize != 0) {
1667#ifdef XSERVER_LIBPCIACCESS
1668            pci_device_unmap_range(pTrident->PciInfo, (pointer)pTrident->FbBase, pTrident->FbMapSize);
1669#else
1670            xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->FbBase,
1671                    pTrident->FbMapSize);
1672#endif
1673            pTrident->FbBase = NULL;
1674        }
1675    }
1676
1677    return TRUE;
1678}
1679
1680/*
1681 * GetAccelPitchValues -
1682 *
1683 * This function returns a list of display width (pitch) values that can
1684 * be used in accelerated mode.
1685 */
1686static int *
1687GetAccelPitchValues(ScrnInfoPtr pScrn)
1688{
1689    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
1690    int *linePitches = NULL;
1691    int lines[4] = { 512, 1024, 2048, 4096 }; /* 9440AGi */
1692    int i, n = 0;
1693
1694    if (pTrident->Chipset >= BLADEXP) {
1695        lines[0] = 1024;
1696        lines[1] = 2048;
1697        lines[2] = 4096;
1698        lines[3] = 8192;
1699    }
1700
1701    for (i = 0; i < 4; i++) {
1702        n++;
1703        linePitches = xnfrealloc(linePitches, n * sizeof(int));
1704        linePitches[n - 1] = lines[i];
1705    }
1706
1707    /* Mark the end of the list */
1708    if (n > 0) {
1709        linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
1710        linePitches[n] = 0;
1711    }
1712    return linePitches;
1713}
1714
1715static void
1716TRIDENTProbeDDC(ScrnInfoPtr pScrn, int index)
1717{
1718    vbeInfoPtr pVbe;
1719    if (xf86LoadSubModule(pScrn, "vbe")) {
1720        pVbe = VBEInit(NULL,index);
1721        ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
1722        vbeFree(pVbe);
1723    }
1724}
1725
1726static void
1727TRIDENTProtect(ScrnInfoPtr pScrn, Bool on)
1728{
1729    vgaHWProtect(pScrn, on);
1730}
1731
1732static void
1733TRIDENTBlankScreen(ScrnInfoPtr pScrn, Bool on)
1734{
1735    vgaHWBlankScreen(pScrn, on);
1736}
1737
1738/* Mandatory */
1739static Bool
1740TRIDENTProbe(DriverPtr drv, int flags)
1741{
1742    int i;
1743    GDevPtr *devSections;
1744    int *usedChips = NULL;
1745    int numDevSections;
1746    int numUsed;
1747    Bool foundScreen = FALSE;
1748
1749    if ((numDevSections = xf86MatchDevice(TRIDENT_DRIVER_NAME,
1750            &devSections)) <= 0) {
1751        /*
1752         * There's no matching device section in the config file, so quit
1753         * now.
1754         */
1755        return FALSE;
1756    }
1757
1758    /*
1759     * While we're VGA-dependent, can really only have one such instance, but
1760     * we'll ignore that.
1761     */
1762
1763    /*
1764     * We need to probe the hardware first.  We then need to see how this
1765     * fits in with what is given in the config file, and allow the config
1766     * file info to override any contradictions.
1767     */
1768
1769    /*
1770     * All of the cards this driver supports are PCI, so the "probing" just
1771     * amounts to checking the PCI data that the server has already collected.
1772     */
1773#ifndef XSERVER_LIBPCIACCESS
1774    if (xf86GetPciVideoInfo()== NULL) {
1775        return FALSE;
1776    }
1777#endif
1778    {
1779        numUsed = xf86MatchPciInstances(TRIDENT_NAME, PCI_VENDOR_TRIDENT,
1780                TRIDENTChipsets, TRIDENTPciChipsets, devSections,
1781                numDevSections, drv, &usedChips);
1782
1783        if (numUsed > 0) {
1784            if (flags & PROBE_DETECT)
1785                foundScreen = TRUE;
1786            else for (i = 0; i < numUsed; i++) {
1787                ScrnInfoPtr pScrn = NULL;
1788
1789                if ((pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i],
1790                        TRIDENTPciChipsets, NULL,
1791                        NULL, NULL, NULL, NULL))) {
1792                    /* Fill in what we can of the ScrnInfoRec */
1793                    pScrn->driverVersion = TRIDENT_VERSION;
1794                    pScrn->driverName	 = TRIDENT_DRIVER_NAME;
1795                    pScrn->name		 = TRIDENT_NAME;
1796                    pScrn->Probe	 = TRIDENTProbe;
1797                    pScrn->PreInit	 = TRIDENTPreInit;
1798                    pScrn->ScreenInit	 = TRIDENTScreenInit;
1799                    pScrn->SwitchMode	 = TRIDENTSwitchMode;
1800                    pScrn->AdjustFrame	 = TRIDENTAdjustFrame;
1801                    pScrn->EnterVT	 = TRIDENTEnterVT;
1802                    pScrn->LeaveVT	 = TRIDENTLeaveVT;
1803                    pScrn->FreeScreen	 = TRIDENTFreeScreen;
1804                    pScrn->ValidMode	 = TRIDENTValidMode;
1805                    foundScreen = TRUE;
1806                }
1807            }
1808            free(usedChips);
1809        }
1810    }
1811
1812#ifdef HAVE_ISA
1813    /* Isa Bus */
1814    numUsed = xf86MatchIsaInstances(TRIDENT_NAME,TRIDENTChipsets,
1815            TRIDENTISAchipsets,
1816            drv,TridentFindIsaDevice,devSections,
1817            numDevSections,&usedChips);
1818    if (numUsed > 0) {
1819        if (flags & PROBE_DETECT)
1820            foundScreen = TRUE;
1821        else 	for (i = 0; i < numUsed; i++) {
1822            ScrnInfoPtr pScrn = NULL;
1823            if ((pScrn = xf86ConfigIsaEntity(pScrn,0,usedChips[i],
1824                    TRIDENTISAchipsets,NULL,
1825                    NULL,NULL,NULL,NULL))) {
1826                pScrn->driverVersion = TRIDENT_VERSION;
1827                pScrn->driverName    = TRIDENT_DRIVER_NAME;
1828                pScrn->name          = TRIDENT_NAME;
1829                pScrn->Probe         = TRIDENTProbe;
1830                pScrn->PreInit       = TRIDENTPreInit;
1831                pScrn->ScreenInit    = TRIDENTScreenInit;
1832                pScrn->SwitchMode    = TRIDENTSwitchMode;
1833                pScrn->AdjustFrame   = TRIDENTAdjustFrame;
1834                pScrn->EnterVT       = TRIDENTEnterVT;
1835                pScrn->LeaveVT       = TRIDENTLeaveVT;
1836                pScrn->FreeScreen    = TRIDENTFreeScreen;
1837                pScrn->ValidMode     = TRIDENTValidMode;
1838                foundScreen = TRUE;
1839            }
1840        }
1841        free(usedChips);
1842    }
1843#endif
1844
1845    free(devSections);
1846    return foundScreen;
1847}
1848
1849/* Mandatory */
1850static Bool
1851TRIDENTPreInit(ScrnInfoPtr pScrn, int flags)
1852{
1853    TRIDENTPtr pTrident;
1854    vgaHWPtr hwp;
1855    MessageType from;
1856    CARD8 videoram, videorammask;
1857    const char *ramtype = NULL, *chipset = NULL;
1858    Bool Support24bpp;
1859    int vgaIOBase;
1860    float mclk;
1861    double real;
1862    int i, NoClocks = 16;
1863    CARD8 revision;
1864    ClockRangePtr clockRanges;
1865    Bool ddcLoaded = FALSE;
1866    xf86MonPtr pMon = NULL;
1867    const char *s;
1868    Bool tmp_bool;
1869
1870    /* Allocate the TRIDENTRec driverPrivate */
1871    if (!TRIDENTGetRec(pScrn)) {
1872        return FALSE;
1873    }
1874    pTrident = TRIDENTPTR(pScrn);
1875    pTrident->pScrn = pScrn;
1876
1877    if (pScrn->numEntities > 1)
1878        return FALSE;
1879    /* This is the general case */
1880    for (i = 0; i<pScrn->numEntities; i++) {
1881        pTrident->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
1882#ifndef XSERVER_LIBPCIACCESS
1883        if (pTrident->pEnt->resources) return FALSE;
1884#endif
1885        pTrident->Chipset = pTrident->pEnt->chipset;
1886        pScrn->chipset = (char *)xf86TokenToString(TRIDENTChipsets,
1887                pTrident->pEnt->chipset);
1888        /* This driver can handle ISA and PCI buses */
1889        if (pTrident->pEnt->location.type == BUS_PCI) {
1890            pTrident->PciInfo = xf86GetPciInfoForEntity(pTrident->pEnt->index);
1891#ifndef XSERVER_LIBPCIACCESS
1892            pTrident->PciTag = PCI_DEV_TAG(pTrident->PciInfo);
1893#endif
1894            pTrident->Linear = TRUE;
1895        } else {
1896            pTrident->Linear = FALSE;
1897        }
1898    }
1899
1900    if (flags & PROBE_DETECT) {
1901        TRIDENTProbeDDC(pScrn, pTrident->pEnt->index);
1902        return TRUE;
1903    }
1904
1905    /* Set pScrn->monitor */
1906    pScrn->monitor = pScrn->confScreen->monitor;
1907
1908    /*
1909     * The first thing we should figure out is the depth, bpp, etc.
1910     * Our preference for depth 24 is 24bpp, so tell it that too.
1911     */
1912    if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb |
1913            SupportConvert32to24 /*| PreferConvert32to24*/)) {
1914        return FALSE;
1915    } else {
1916        /* Check that the returned depth is one we support */
1917        switch (pScrn->depth) {
1918        case 8:
1919            if (pScrn->bitsPerPixel != pScrn->depth) {
1920                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1921                        "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
1922                        pScrn->depth, pScrn->bitsPerPixel);
1923                return FALSE;
1924            }
1925            break;
1926        case 15:
1927        case 16:
1928            if (pScrn->bitsPerPixel != 16) {
1929                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1930                        "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
1931                        pScrn->depth, pScrn->bitsPerPixel);
1932                return FALSE;
1933            }
1934            break;
1935        case 24:
1936            if ((pScrn->bitsPerPixel != 24) && (pScrn->bitsPerPixel != 32)) {
1937                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1938                        "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
1939                        pScrn->depth, pScrn->bitsPerPixel);
1940                return FALSE;
1941            }
1942            /* OK */
1943            break;
1944        default:
1945            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1946                    "Given depth (%d) is not supported by this driver\n",
1947                    pScrn->depth);
1948            return FALSE;
1949        }
1950    }
1951
1952    xf86PrintDepthBpp(pScrn);
1953
1954    /* Get the depth24 pixmap format */
1955    if (pScrn->depth == 24 && pix24bpp == 0)
1956        pix24bpp = xf86GetBppFromDepth(pScrn, 24);
1957
1958    /* The vgahw module should be loaded here when needed */
1959    if (!xf86LoadSubModule(pScrn, "vgahw"))
1960        return FALSE;
1961
1962    /*
1963     * Allocate a vgaHWRec
1964     */
1965    if (!vgaHWGetHWRec(pScrn))
1966        return FALSE;
1967
1968    hwp = VGAHWPTR(pScrn);
1969    vgaHWSetStdFuncs(hwp);
1970    vgaHWGetIOBase(hwp);
1971    vgaIOBase = hwp->IOBase;
1972
1973#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
1974    pTrident->PIOBase = hwp->PIOOffset;
1975#else
1976    pTrident->PIOBase = 0;
1977#endif
1978
1979#ifndef XSERVER_LIBPCIACCESS
1980    xf86SetOperatingState(resVga, pTrident->pEnt->index, ResUnusedOpr);
1981#endif
1982
1983    /* The ramdac module should be loaded here when needed */
1984    if (!xf86LoadSubModule(pScrn, "ramdac"))
1985        return FALSE;
1986
1987    /*
1988     * This must happen after pScrn->display has been set because
1989     * xf86SetWeight references it.
1990     */
1991    if (pScrn->depth > 8) {
1992        /* The defaults are OK for us */
1993        rgb zeros = {0, 0, 0};
1994
1995        if (!xf86SetWeight(pScrn, zeros, zeros)) {
1996            return FALSE;
1997        } else {
1998            /* XXX check that weight returned is supported */
1999            ;
2000        }
2001    }
2002
2003    if (!xf86SetDefaultVisual(pScrn, -1)) {
2004        return FALSE;
2005    } else {
2006        /* We don't currently support DirectColor at > 8bpp */
2007        if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
2008            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
2009                    " (%s) is not supported at depth %d\n",
2010                    xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
2011            return FALSE;
2012        }
2013    }
2014
2015    /*
2016     * The new cmap layer needs this to be initialised.
2017     */
2018
2019    {
2020        Gamma zeros = {0.0, 0.0, 0.0};
2021
2022        if (!xf86SetGamma(pScrn, zeros)) {
2023            return FALSE;
2024        }
2025    }
2026
2027    /* Collect all of the relevant option flags (fill in pScrn->options) */
2028    xf86CollectOptions(pScrn, NULL);
2029
2030    /* Process the options */
2031    if (!(pTrident->Options = malloc(sizeof(TRIDENTOptions))))
2032        return FALSE;
2033    memcpy(pTrident->Options, TRIDENTOptions, sizeof(TRIDENTOptions));
2034    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTrident->Options);
2035
2036    /* Set the bits per RGB for 8bpp mode */
2037    if (pScrn->depth == 8) {
2038        /* XXX This is here just to test options. */
2039        /* Default to 8 */
2040        pScrn->rgbBits = 6;
2041#if 0
2042        if (xf86GetOptValInteger(pTrident->Options, OPTION_RGB_BITS,
2043                &pScrn->rgbBits)) {
2044            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
2045                    pScrn->rgbBits);
2046        }
2047#endif
2048    }
2049    from = X_DEFAULT;
2050
2051    pTrident->useEXA = FALSE;
2052    if ((s = (char *)xf86GetOptValString(pTrident->Options,
2053            OPTION_ACCELMETHOD))) {
2054        if (!xf86NameCmp(s, "EXA")) {
2055            pTrident->useEXA = TRUE;
2056            from = X_CONFIG;
2057        }
2058        else if (!xf86NameCmp(s, "XAA")) {
2059            pTrident->useEXA = FALSE;
2060            from = X_CONFIG;
2061        }
2062    }
2063    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n",
2064            pTrident->useEXA ? "EXA" : "XAA");
2065
2066    pTrident->HWCursor = TRUE;
2067    if (xf86ReturnOptValBool(pTrident->Options, OPTION_SW_CURSOR, FALSE)) {
2068        from = X_CONFIG;
2069        pTrident->HWCursor = FALSE;
2070    }
2071    if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOACCEL, FALSE)) {
2072        pTrident->NoAccel = TRUE;
2073        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
2074    }
2075    if (xf86ReturnOptValBool(pTrident->Options, OPTION_PCI_RETRY, FALSE)) {
2076        pTrident->UsePCIRetry = TRUE;
2077        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
2078    }
2079    pTrident->UsePCIBurst = TRUE;
2080    if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOPCIBURST, FALSE)) {
2081        pTrident->UsePCIBurst = FALSE;
2082        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI Burst disabled\n");
2083    }
2084    /* Display Size override moved to DDC section */
2085    if(xf86GetOptValInteger(pTrident->Options, OPTION_VIDEO_KEY,
2086            &(pTrident->videoKey))) {
2087        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
2088                pTrident->videoKey);
2089    } else {
2090        pTrident->videoKey =  (1 << pScrn->offset.red) |
2091                (1 << pScrn->offset.green) |
2092                (((pScrn->mask.blue >> pScrn->offset.blue) - 1)
2093                        << pScrn->offset.blue);
2094    }
2095    if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOMMIO, FALSE)) {
2096        pTrident->NoMMIO = TRUE;
2097        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO Disabled\n");
2098    }
2099    if (xf86ReturnOptValBool(pTrident->Options, OPTION_MMIO_ONLY, FALSE)) {
2100        if (pTrident->NoMMIO)
2101            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MMIO only cannot be set"
2102                    " with NoMMIO\n");
2103        else {
2104            pTrident->MMIOonly = TRUE;
2105            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO only enabled\n");
2106        }
2107    }
2108
2109    pTrident->dspOverride = 0;
2110    if ((s = xf86GetOptValString(pTrident->Options, OPTION_DISPLAY))) {
2111        if(!xf86NameCmp(s, "CRT")) {
2112            pTrident->dspOverride = CRT_ACTIVE;
2113            xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD off CRT on\n");
2114        } else if (!xf86NameCmp(s, "LCD")) {
2115            pTrident->dspOverride = LCD_ACTIVE;
2116            xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT off\n");
2117        } else if (!xf86NameCmp(s, "Dual")) {
2118            pTrident->dspOverride = LCD_ACTIVE | CRT_ACTIVE;
2119            xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT on\n");
2120        } else
2121            xf86DrvMsg(pScrn->scrnIndex,X_ERROR,
2122                    "%s is an unknown display option\n",s);
2123    }
2124    if ((s = xf86GetOptValString(pTrident->Options, OPTION_GB))) {
2125        int brightness = -1;
2126        double gamma = -1.0;
2127        Bool error = FALSE;
2128        int i;
2129
2130        i = sscanf(s,"%lf %i",&gamma,&brightness);
2131
2132        if (i != 2 || brightness == -1 || gamma == -1.0) {
2133            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2134                    "Invalid Gamma/Brightness argument: %s\n",s);
2135            error = TRUE;
2136        } else {
2137            if (brightness < 0 || brightness > 128) {
2138                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2139                        "brightness out of range [0,128]: %i\n",brightness);
2140                error = TRUE;
2141            }
2142            if (gamma <= 0.0 || gamma > 10.0) {
2143                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2144                        "gamma out of range (0,10.0]: %f\n",gamma);
2145                error = TRUE;
2146            }
2147        }
2148
2149        if (!error) {
2150            pTrident->GammaBrightnessOn = TRUE;
2151            pTrident->gamma = gamma;
2152            pTrident->brightness = brightness;
2153            xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Gamma: %f Brightness: %i\n",
2154                    gamma,brightness);
2155        }
2156    }
2157
2158    /* The following is a temporary hack */
2159    pTrident->FPDelay = 7; /* invalid value */
2160    if (xf86GetOptValInteger(pTrident->Options, OPTION_FP_DELAY,
2161            &pTrident->FPDelay)) {
2162        if (pTrident->FPDelay < -2 || pTrident->FPDelay > 5) {
2163            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "FPDelay %i out if range "
2164                    "(-2 < FPDelay < 5)\n",pTrident->FPDelay);
2165            pTrident->FPDelay = 7;
2166        } else
2167            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "FP Delay set to %i\n",
2168                    pTrident->FPDelay);
2169    }
2170    if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_SHADOW, FALSE)) {
2171        pTrident->CyberShadow = TRUE;
2172        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Shadow enabled\n");
2173    }
2174    if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_STRETCH, FALSE)) {
2175        pTrident->CyberStretch = TRUE;
2176        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Stretch enabled\n");
2177    }
2178
2179    pTrident->MUXThreshold = 90000; /* 90MHz */
2180    if (xf86GetOptValInteger(pTrident->Options, OPTION_MUX_THRESHOLD,
2181            &pTrident->MUXThreshold)) {
2182        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MUX Threshold set to %d\n",
2183                pTrident->MUXThreshold);
2184    }
2185    pTrident->OverrideHsync = 0;
2186    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC,
2187            &pTrident->OverrideHsync)) {
2188        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n",
2189                pTrident->OverrideHsync);
2190    }
2191    pTrident->OverrideVsync = 0;
2192    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC,
2193            &pTrident->OverrideVsync)) {
2194        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n",
2195                pTrident->OverrideVsync);
2196    }
2197    pTrident->OverrideHsync = 0;
2198    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC,
2199            &pTrident->OverrideHsync)) {
2200        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n",
2201                pTrident->OverrideHsync);
2202    }
2203    pTrident->OverrideVsync = 0;
2204    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC,
2205            &pTrident->OverrideVsync)) {
2206        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n",
2207                pTrident->OverrideVsync);
2208    }
2209    pTrident->OverrideRskew = 0;
2210    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_RSKEW,
2211            &pTrident->OverrideRskew)) {
2212        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Rskew set to %d\n",
2213                pTrident->OverrideRskew);
2214    }
2215    pTrident->OverrideBskew = 0;
2216    if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_BSKEW,
2217            &pTrident->OverrideBskew)) {
2218        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Bskew set to %d\n",
2219                pTrident->OverrideBskew);
2220    }
2221    if (xf86ReturnOptValBool(pTrident->Options, OPTION_SHADOW_FB, FALSE)) {
2222        if (!LINEAR())
2223            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option SHADOW_FB"
2224                    " in non-Linear Mode\n");
2225        else {
2226            pTrident->ShadowFB = TRUE;
2227            pTrident->NoAccel = TRUE;
2228            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2229                    "Using \"Shadow Framebuffer\" - acceleration disabled\n");
2230        }
2231    }
2232    pTrident->Rotate = 0;
2233    if ((s = xf86GetOptValString(pTrident->Options, OPTION_ROTATE))) {
2234        if (!LINEAR())
2235            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option ROTATE "
2236                    "in non-Linear Mode\n");
2237        else {
2238            if(!xf86NameCmp(s, "CW")) {
2239                /* accel is disabled below for shadowFB */
2240                pTrident->ShadowFB = TRUE;
2241                pTrident->NoAccel = TRUE;
2242                pTrident->HWCursor = FALSE;
2243                pTrident->Rotate = 1;
2244                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
2245                        "Rotating screen clockwise - acceleration disabled\n");
2246            } else if(!xf86NameCmp(s, "CCW")) {
2247                pTrident->ShadowFB = TRUE;
2248                pTrident->NoAccel = TRUE;
2249                pTrident->HWCursor = FALSE;
2250                pTrident->Rotate = -1;
2251                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,  "Rotating screen"
2252                        "counter clockwise - acceleration disabled\n");
2253            } else {
2254                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
2255                        "value for Option \"Rotate\"\n", s);
2256                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2257                        "Valid options are \"CW\" or \"CCW\"\n");
2258            }
2259        }
2260    }
2261
2262    pTrident->TVChipset = 0;
2263    if ((s = xf86GetOptValString(pTrident->Options, OPTION_TV_CHIPSET))) {
2264        if(!xf86NameCmp(s, "VT1621")) {
2265            pTrident->TVChipset = 1;
2266            xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Using VIA VT1621 TV chip\n");
2267        } else if (!xf86NameCmp(s, "CH7005")) {
2268            pTrident->TVChipset = 2;
2269            xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Using Chrontel CH7005 TV chip\n");
2270        } else
2271            xf86DrvMsg(pScrn->scrnIndex,X_ERROR,
2272                    "%s is an unknown TV chipset option\n",s);
2273    }
2274    /* Default : NTSC */
2275    pTrident->TVSignalMode=0;
2276    if (xf86GetOptValInteger(pTrident->Options, OPTION_TV_SIGNALMODE,
2277            &pTrident->TVSignalMode)) {
2278        ErrorF("TV SignalMode set to %d\n",pTrident->TVSignalMode);
2279    }
2280
2281    /* FIXME ACCELERATION */
2282    if (!UseMMIO) pTrident->NoAccel = TRUE;
2283
2284    if (LINEAR()) {
2285        if (pTrident->pEnt->device->MemBase != 0) {
2286            /*
2287             * XXX Should check that the config file value matches one of the
2288             * PCI base address values.
2289             */
2290            pTrident->FbAddress = pTrident->pEnt->device->MemBase;
2291            from = X_CONFIG;
2292        } else {
2293            if (IsPciCard)
2294                pTrident->FbAddress = PCI_REGION_BASE(pTrident->PciInfo, 0, REGION_MEM) & 0xFFFFFFF0;
2295            else
2296                pTrident->FbAddress = 0xA0000;
2297        }
2298
2299        xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
2300                (unsigned long)pTrident->FbAddress);
2301    }
2302
2303    if (UseMMIO) {
2304        if (pTrident->pEnt->device->IOBase != 0) {
2305            /*
2306             * XXX Should check that the config file value matches one of the
2307             * PCI base address values.
2308             */
2309            pTrident->IOAddress = pTrident->pEnt->device->IOBase;
2310            from = X_CONFIG;
2311        } else {
2312            if (IsPciCard)
2313                pTrident->IOAddress = PCI_REGION_BASE(pTrident->PciInfo, 1, REGION_MEM) & 0xFFFFC000;
2314            else
2315                /* FIXME - Multihead UNAWARE */
2316                pTrident->IOAddress = 0xBF000;
2317        }
2318
2319        xf86DrvMsg(pScrn->scrnIndex,X_PROBED,"IO registers at 0x%lX\n",
2320                (unsigned long)pTrident->IOAddress);
2321    }
2322
2323#ifndef XSERVER_LIBPCIACCESS
2324    /* Register the PCI-assigned resources. */
2325    if (xf86RegisterResources(pTrident->pEnt->index, NULL, ResExclusive)) {
2326        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2327                "xf86RegisterResources() found resource conflicts\n");
2328        return FALSE;
2329    }
2330#endif
2331    /* Initialize VBE if possible
2332     * Don't move this past MMIO enable!!
2333     * PIO access will be blocked
2334     * when MMIO is turned on!
2335     */
2336
2337    if (xf86LoadSubModule(pScrn, "vbe")) {
2338        vbeInfoPtr pVbe;
2339
2340        pVbe =  VBEInit(NULL,pTrident->pEnt->index);
2341        pMon = vbeDoEDID(pVbe, NULL);
2342#ifdef VBE_INFO
2343        {
2344            VbeInfoBlock* vbeInfoBlockPtr;
2345            if ((vbeInfoBlockPtr = VBEGetVBEInfo(pVbe))) {
2346                pTrident->vbeModes = VBEBuildVbeModeList(pVbe,vbeInfoBlockPtr);
2347                VBEFreeVBEInfo(vbeInfoBlockPtr);
2348            }
2349        }
2350#endif
2351        vbeFree(pVbe);
2352        if (pMon) {
2353            if (!xf86LoadSubModule(pScrn, "ddc")) {
2354                TRIDENTFreeRec(pScrn);
2355                return FALSE;
2356            } else {
2357                xf86SetDDCproperties(pScrn,xf86PrintEDID(pMon));
2358                ddcLoaded = TRUE;
2359            }
2360        }
2361
2362    }
2363
2364    if (xf86GetOptValBool(pTrident->Options, OPTION_1400_DISPLAY, &tmp_bool)) {
2365        if (tmp_bool)
2366            pTrident->displaySize = 1400;
2367    } else
2368        pTrident->displaySize = TRIDENTLcdDisplaySize(pMon);
2369
2370    if (IsPciCard && UseMMIO) {
2371        if (!TRIDENTMapMem(pScrn))
2372            return FALSE;
2373
2374        TRIDENTEnableMMIO(pScrn);
2375    }
2376
2377    OUTB(0x3C4, RevisionID); revision = INB(0x3C5);
2378    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Revision is %d\n",revision);
2379
2380    pScrn->progClock = TRUE;
2381    pTrident->EngineOperation = 0x00;
2382    pTrident->IsCyber = FALSE;
2383    pTrident->HasSGRAM = FALSE;
2384    pTrident->NewClockCode = FALSE;
2385    pTrident->MUX = FALSE;
2386    Support24bpp = FALSE;
2387
2388    OUTB(vgaIOBase + 4, InterfaceSel);
2389
2390    switch (pTrident->Chipset) {
2391    case TVGA9000:
2392    case TVGA9000i:
2393        pScrn->progClock = FALSE;
2394        NoClocks = 16;
2395        pTrident->NoMMIO = TRUE;
2396        pTrident->NoAccel = TRUE;
2397        pTrident->HWCursor = FALSE;
2398        chipset = "TVGA9000/9000i";
2399        ramtype = "Standard DRAM";
2400        if (pTrident->UsePCIRetry)
2401            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
2402        pTrident->UsePCIRetry = FALSE; /* Not Supported */
2403        pTrident->frequency = NTSC;
2404        break;
2405    case TVGA9100B:
2406        pScrn->progClock = FALSE;
2407        NoClocks = 8;
2408        pTrident->NoMMIO = TRUE;
2409        pTrident->NoAccel = TRUE;
2410        pTrident->HWCursor = FALSE;
2411        chipset = "TVGA9100B";
2412        ramtype = "Standard DRAM";
2413        if (pTrident->UsePCIRetry)
2414            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
2415        pTrident->UsePCIRetry = FALSE; /* Not Supported */
2416        pTrident->frequency = NTSC;
2417        break;
2418    case TVGA8900B:
2419        pScrn->progClock = FALSE;
2420        NoClocks = 8;
2421        pTrident->NoMMIO = TRUE;
2422        pTrident->NoAccel = TRUE;
2423        pTrident->HWCursor = FALSE;
2424        chipset = "TVGA8900B";
2425        ramtype = "Standard DRAM";
2426        if (pTrident->UsePCIRetry)
2427            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
2428        pTrident->UsePCIRetry = FALSE; /* Not Supported */
2429        pTrident->frequency = NTSC;
2430        break;
2431    case TVGA8900C:
2432        pScrn->progClock = FALSE;
2433        NoClocks = 16;
2434        pTrident->NoMMIO = TRUE;
2435        pTrident->NoAccel = TRUE;
2436        pTrident->HWCursor = FALSE;
2437        chipset = "TVGA8900C";
2438        ramtype = "Standard DRAM";
2439        if (pTrident->UsePCIRetry)
2440            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
2441        pTrident->UsePCIRetry = FALSE; /* Not Supported */
2442        pTrident->frequency = NTSC;
2443        break;
2444    case TVGA8900D:
2445        pScrn->progClock = FALSE;
2446        NoClocks = 16;
2447        pTrident->NoMMIO = TRUE;
2448        pTrident->NoAccel = TRUE;
2449        pTrident->HWCursor = FALSE;
2450        chipset = "TVGA8900D";
2451        ramtype = "Standard DRAM";
2452        if (pTrident->UsePCIRetry)
2453            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
2454        pTrident->UsePCIRetry = FALSE; /* Not Supported */
2455        pTrident->frequency = NTSC;
2456        break;
2457    case TVGA9200CXr:
2458        pScrn->progClock = FALSE;
2459        NoClocks = 16;
2460        pTrident->NoMMIO = TRUE;
2461        pTrident->NoAccel = TRUE;
2462        pTrident->HWCursor = FALSE;
2463        chipset = "TVGA9200CXr";
2464        ramtype = "Standard DRAM";
2465        if (pTrident->UsePCIRetry)
2466            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
2467        pTrident->UsePCIRetry = FALSE; /* Not Supported */
2468        pTrident->frequency = NTSC;
2469        break;
2470    case TGUI9400CXi:
2471        pScrn->progClock = FALSE;
2472        NoClocks = 16;
2473        pTrident->NoMMIO = TRUE;
2474        pTrident->NoAccel = TRUE;
2475        pTrident->HWCursor = FALSE;
2476        chipset = "TVGA9200CXr";
2477        ramtype = "Standard DRAM";
2478        if (pTrident->UsePCIRetry)
2479            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
2480        pTrident->UsePCIRetry = FALSE; /* Not Supported */
2481        pTrident->frequency = NTSC;
2482        break;
2483    case TGUI9440AGi:
2484        pTrident->ddc1Read = Tridentddc1Read;
2485        pTrident->HWCursor = FALSE;
2486        chipset = "TGUI9440AGi";
2487        ramtype = "Standard DRAM";
2488        if (pTrident->UsePCIRetry)
2489            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
2490        pTrident->UsePCIRetry = FALSE; /* Not Supported */
2491        pTrident->frequency = NTSC;
2492        break;
2493    case CYBER9320:
2494        pTrident->ddc1Read = Tridentddc1Read;
2495        chipset = "Cyber9320";
2496        ramtype = "Standard DRAM";
2497        if (pTrident->UsePCIRetry)
2498            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
2499        pTrident->UsePCIRetry = FALSE; /* Not Supported */
2500        break;
2501        /* Trident didn't update the PCI ID's and so we have to determine
2502         * which chips are right ! Then override pTrident->Chipset to
2503         * correct values */
2504    case TGUI9660:
2505        pTrident->ddc1Read = Tridentddc1Read;
2506        if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
2507            ramtype = "EDO Ram";
2508        if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C)
2509            ramtype = "Standard DRAM";
2510        switch (revision) {
2511        case 0x00:
2512            chipset = "TGUI9660";
2513            pTrident->Chipset = TGUI9660;
2514            if (pTrident->UsePCIRetry)
2515                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
2516            pTrident->UsePCIRetry = FALSE; /* Not Supported */
2517            break;
2518        case 0x01:
2519            chipset = "TGUI9680";
2520            pTrident->Chipset = TGUI9680;
2521            if (pTrident->UsePCIRetry)
2522                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
2523            pTrident->UsePCIRetry = FALSE; /* Not Supported */
2524            break;
2525        case 0x10:
2526            chipset = "ProVidia 9682";
2527            Support24bpp = TRUE;
2528            pTrident->Chipset = PROVIDIA9682;
2529            break;
2530        case 0x21:
2531            chipset = "ProVidia 9685";
2532            Support24bpp = TRUE;
2533            pTrident->NewClockCode = TRUE;
2534            pTrident->Chipset = PROVIDIA9685;
2535            break;
2536        case 0x22:
2537        case 0x23:
2538            chipset = "Cyber 9397";
2539            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
2540                ramtype = "EDO Ram";
2541            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
2542                ramtype = "SDRAM";
2543            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
2544                pTrident->HasSGRAM = TRUE;
2545                ramtype = "SGRAM";
2546            }
2547            pTrident->NewClockCode = TRUE;
2548            pTrident->Chipset = CYBER9397;
2549            pTrident->IsCyber = TRUE;
2550            break;
2551        case 0x2a:
2552            chipset = "Cyber 9397/DVD";
2553            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
2554                ramtype = "EDO Ram";
2555            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
2556                ramtype = "SDRAM";
2557            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
2558                pTrident->HasSGRAM = TRUE;
2559                ramtype = "SGRAM";
2560            }
2561            pTrident->NewClockCode = TRUE;
2562            pTrident->Chipset = CYBER9397DVD;
2563            pTrident->IsCyber = TRUE;
2564            break;
2565        case 0x30:
2566        case 0x33:
2567        case 0x34:
2568        case 0x35:
2569        case 0xB3:
2570            chipset = "Cyber 9385";
2571            pTrident->NewClockCode = TRUE;
2572            pTrident->Chipset = CYBER9385;
2573            pTrident->IsCyber = TRUE;
2574            break;
2575        case 0x38:
2576        case 0x3A:
2577            chipset = "Cyber 9385-1";
2578            pTrident->NewClockCode = TRUE;
2579            pTrident->Chipset = CYBER9385;
2580            pTrident->IsCyber = TRUE;
2581            break;
2582        case 0x40:
2583        case 0x41:
2584        case 0x42:
2585        case 0x43:
2586            chipset = "Cyber 9382";
2587            pTrident->NewClockCode = TRUE;
2588            pTrident->Chipset = CYBER9382;
2589            pTrident->IsCyber = TRUE;
2590            break;
2591        case 0x4A:
2592            chipset = "Cyber 9388";
2593            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
2594                ramtype = "EDO Ram";
2595            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
2596                ramtype = "SDRAM";
2597            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
2598                pTrident->HasSGRAM = TRUE;
2599                ramtype = "SGRAM";
2600            }
2601            pTrident->NewClockCode = TRUE;
2602            pTrident->Chipset = CYBER9388;
2603            pTrident->IsCyber = TRUE;
2604            break;
2605        default:
2606            chipset = "Unknown";
2607            pTrident->Chipset = TGUI9660;
2608            break;
2609        }
2610        break;
2611        case CYBER9388:
2612            pTrident->ddc1Read = Tridentddc1Read;
2613            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
2614                ramtype = "EDO Ram";
2615            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
2616                ramtype = "SDRAM";
2617            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
2618                pTrident->HasSGRAM = TRUE;
2619                ramtype = "SGRAM";
2620            }
2621            pTrident->IsCyber = TRUE;
2622            Support24bpp = TRUE;
2623            chipset = "Cyber 9388";
2624            pTrident->NewClockCode = TRUE;
2625            break;
2626        case CYBER9397:
2627            pTrident->ddc1Read = Tridentddc1Read;
2628            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
2629                ramtype = "EDO Ram";
2630            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
2631                ramtype = "SDRAM";
2632            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
2633                pTrident->HasSGRAM = TRUE;
2634                ramtype = "SGRAM";
2635            }
2636            pTrident->IsCyber = TRUE;
2637            Support24bpp = TRUE;
2638            chipset = "Cyber 9397";
2639            pTrident->NewClockCode = TRUE;
2640            break;
2641        case CYBER9397DVD:
2642            pTrident->ddc1Read = Tridentddc1Read;
2643            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
2644                ramtype = "EDO Ram";
2645            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
2646                ramtype = "SDRAM";
2647            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
2648                pTrident->HasSGRAM = TRUE;
2649                ramtype = "SGRAM";
2650            }
2651            pTrident->IsCyber = TRUE;
2652            Support24bpp = TRUE;
2653            chipset = "Cyber 9397/DVD";
2654            pTrident->NewClockCode = TRUE;
2655            break;
2656        case CYBER9520:
2657            pTrident->ddc1Read = Tridentddc1Read;
2658            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
2659                ramtype = "EDO Ram";
2660            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
2661                ramtype = "SDRAM";
2662            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
2663                pTrident->HasSGRAM = TRUE;
2664                ramtype = "SGRAM";
2665            }
2666            pTrident->IsCyber = TRUE;
2667            Support24bpp = TRUE;
2668            chipset = "Cyber 9520";
2669            pTrident->NewClockCode = TRUE;
2670            break;
2671        case CYBER9525DVD:
2672            pTrident->ddc1Read = Tridentddc1Read;
2673            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
2674                ramtype = "EDO Ram";
2675            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
2676                ramtype = "SDRAM";
2677            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
2678                pTrident->HasSGRAM = TRUE;
2679                ramtype = "SGRAM";
2680            }
2681            pTrident->IsCyber = TRUE;
2682            Support24bpp = TRUE;
2683            chipset = "Cyber 9525/DVD";
2684            pTrident->NewClockCode = TRUE;
2685            break;
2686        case CYBERBLADEE4:
2687            pTrident->ddc1Read = Tridentddc1Read;
2688            ramtype = "SDRAM";
2689            pTrident->IsCyber = TRUE;
2690            Support24bpp = TRUE;
2691            chipset = "CyberBlade e4/128";
2692            pTrident->NewClockCode = TRUE;
2693            break;
2694        case IMAGE975:
2695            pTrident->ddc1Read = Tridentddc1Read;
2696            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
2697                ramtype = "EDO Ram";
2698            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
2699                ramtype = "SDRAM";
2700            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
2701                pTrident->HasSGRAM = TRUE;
2702                ramtype = "SGRAM";
2703            }
2704            Support24bpp = TRUE;
2705            chipset = "3DImage975";
2706            pTrident->NewClockCode = TRUE;
2707            break;
2708        case IMAGE985:
2709            pTrident->ddc1Read = Tridentddc1Read;
2710            if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
2711                ramtype = "EDO Ram";
2712            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
2713                ramtype = "SDRAM";
2714            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
2715                pTrident->HasSGRAM = TRUE;
2716                ramtype = "SGRAM";
2717            }
2718            Support24bpp = TRUE;
2719            chipset = "3DImage985";
2720            pTrident->NewClockCode = TRUE;
2721            break;
2722        case BLADE3D:
2723            pTrident->ddc1Read = Tridentddc1Read;
2724            if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
2725                ramtype = "SDRAM";
2726            if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
2727                pTrident->HasSGRAM = TRUE;
2728                ramtype = "SGRAM";
2729            }
2730            Support24bpp = TRUE;
2731            chipset = "Blade3D";
2732            pTrident->NewClockCode = TRUE;
2733            pTrident->frequency = NTSC;
2734            pTrident->UsePCIRetry = TRUE; /* To avoid lockups */
2735            break;
2736        case CYBERBLADEI7:
2737            pTrident->ddc1Read = Tridentddc1Read;
2738            ramtype = "SDRAM";
2739            /* pTrident->IsCyber = TRUE; VIA MVP4 integrated Desktop version */
2740            Support24bpp = TRUE;
2741            chipset = "CyberBlade/i7/VIA MVP4";
2742            pTrident->NewClockCode = TRUE;
2743            pTrident->frequency = NTSC;
2744            break;
2745        case CYBERBLADEI7D:
2746            pTrident->ddc1Read = Tridentddc1Read;
2747            ramtype = "SDRAM";
2748            pTrident->IsCyber = TRUE;
2749            Support24bpp = TRUE;
2750            chipset = "CyberBlade/DSTN/i7";
2751            pTrident->NewClockCode = TRUE;
2752            pTrident->frequency = NTSC;
2753            break;
2754        case CYBERBLADEI1:
2755            pTrident->ddc1Read = Tridentddc1Read;
2756            ramtype = "SDRAM";
2757            pTrident->IsCyber = TRUE;
2758            Support24bpp = TRUE;
2759            chipset = "CyberBlade/i1";
2760            pTrident->NewClockCode = TRUE;
2761            pTrident->frequency = NTSC;
2762            break;
2763        case CYBERBLADEI1D:
2764            pTrident->ddc1Read = Tridentddc1Read;
2765            ramtype = "SDRAM";
2766            pTrident->IsCyber = TRUE;
2767            Support24bpp = TRUE;
2768            chipset = "CyberBlade/DSTN/i1";
2769            pTrident->NewClockCode = TRUE;
2770            pTrident->frequency = NTSC;
2771            break;
2772        case CYBERBLADEAI1:
2773            pTrident->ddc1Read = Tridentddc1Read;
2774            ramtype = "SDRAM";
2775            pTrident->IsCyber = TRUE;
2776            Support24bpp = TRUE;
2777            chipset = "CyberBlade/Ai1";
2778            pTrident->NewClockCode = TRUE;
2779            pTrident->frequency = NTSC;
2780            break;
2781        case CYBERBLADEAI1D:
2782            pTrident->ddc1Read = Tridentddc1Read;
2783            ramtype = "SDRAM";
2784            pTrident->IsCyber = TRUE;
2785            Support24bpp = TRUE;
2786            chipset = "CyberBlade/DSTN/Ai1";
2787            pTrident->NewClockCode = TRUE;
2788            pTrident->frequency = NTSC;
2789            break;
2790        case BLADEXP: /* 0x9910 */
2791            pTrident->ddc1Read = Tridentddc1Read;
2792            ramtype = "SGRAM";
2793            pTrident->HasSGRAM = TRUE;
2794            Support24bpp = TRUE;
2795            pTrident->NewClockCode = TRUE;
2796            pTrident->frequency = NTSC;
2797            OUTB(0x3C4, 0x5D);
2798            if (PCI_SUB_VENDOR_ID(pTrident->PciInfo) != 0x1023) {
2799                chipset = "CyberBladeXP";
2800                pTrident->IsCyber = TRUE;
2801            } else
2802                if (!(INB(0x3C5) & 0x01)) {
2803                    chipset = "BladeXP";
2804                } else {
2805                    CARD8 mem1, mem2;
2806                    OUTB(vgaIOBase + 0x04, SPR);
2807                    mem1 = INB(vgaIOBase + 5);
2808                    OUTB(vgaIOBase + 0x04, 0xC1);
2809                    mem2 = INB(vgaIOBase + 5);
2810                    if ((mem1 & 0x0e) && (mem2 == 0x11)) {
2811                        chipset = "BladeT64";
2812                    } else {
2813                        chipset = "BladeT16";
2814                    }
2815                }
2816            break;
2817        case CYBERBLADEXPAI1:
2818            pTrident->ddc1Read = Tridentddc1Read;
2819            ramtype = "SGRAM";
2820            pTrident->HasSGRAM = TRUE;
2821            pTrident->IsCyber = TRUE;
2822            pTrident->shadowNew = TRUE;
2823            Support24bpp = TRUE;
2824            chipset = "CyberBladeXPAi1";
2825            pTrident->NewClockCode = TRUE;
2826            pTrident->frequency = NTSC;
2827            break;
2828        case CYBERBLADEXP4:
2829            pTrident->ddc1Read = Tridentddc1Read;
2830            ramtype = "SGRAM";
2831            pTrident->HasSGRAM = TRUE;
2832            pTrident->IsCyber = TRUE;
2833            pTrident->shadowNew = TRUE;
2834            Support24bpp = TRUE;
2835            chipset = "CyberBladeXP4";
2836            pTrident->NewClockCode = TRUE;
2837            pTrident->frequency = NTSC;
2838            break;
2839        case XP5:
2840            pTrident->ddc1Read = Tridentddc1Read;
2841            ramtype = "SGRAM";
2842            pTrident->HasSGRAM = TRUE;
2843            pTrident->IsCyber = TRUE;
2844            pTrident->shadowNew = TRUE;
2845            Support24bpp = TRUE;
2846            chipset = "XP5";
2847            pTrident->NewClockCode = TRUE;
2848            pTrident->frequency = NTSC;
2849            break;
2850    }
2851
2852    if (!pScrn->progClock) {
2853        pScrn->numClocks = NoClocks;
2854        xf86GetClocks(pScrn, NoClocks, TRIDENTClockSelect,
2855                TRIDENTProtect, TRIDENTBlankScreen,
2856                vgaIOBase + 0x0A, 0x08, 1, 28322);
2857        from = X_PROBED;
2858        xf86ShowClocks(pScrn, from);
2859    }
2860
2861    if (!chipset) {
2862        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No support for \"%s\"\n",
2863                pScrn->chipset);
2864        if (IsPciCard && UseMMIO) {
2865            TRIDENTDisableMMIO(pScrn);
2866            TRIDENTUnmapMem(pScrn);
2867        }
2868        return FALSE;
2869    }
2870    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Found %s chip\n", chipset);
2871    if (ramtype)
2872        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RAM type is %s\n", ramtype);
2873
2874    if (pScrn->bitsPerPixel == 24 && !Support24bpp) {
2875        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No support for 24bpp on this chipset, use -pixmap32.\n");
2876        if (IsPciCard && UseMMIO) {
2877            TRIDENTDisableMMIO(pScrn);
2878            TRIDENTUnmapMem(pScrn);
2879        }
2880        return FALSE;
2881    }
2882
2883    /* HW bpp matches reported bpp */
2884    pTrident->HwBpp = pScrn->bitsPerPixel;
2885
2886    /* Due to bugs in the chip, turn it off */
2887    if (pTrident->Chipset >= CYBERBLADEI7 && pTrident->Chipset <= CYBERBLADEAI1D)
2888        pTrident->HWCursor = FALSE;
2889
2890    from = X_PROBED;
2891    if (pTrident->pEnt->device->videoRam != 0) {
2892        pScrn->videoRam = pTrident->pEnt->device->videoRam;
2893        from = X_CONFIG;
2894    } else {
2895        if (pTrident->Chipset == XP5) {
2896            OUTB(vgaIOBase + 4, 0x60);
2897            videoram = INB(vgaIOBase + 5);
2898            switch (videoram & 0x7) {
2899            case 0x00:
2900                pScrn->videoRam = 65536 /* 131072 */;
2901                break;
2902            case 0x01:
2903                pScrn->videoRam = 65536;
2904                break;
2905            case 0x02:
2906                pScrn->videoRam = 32768;
2907                break;
2908            case 0x03:
2909                pScrn->videoRam = 16384;
2910                break;
2911            case 0x04:
2912                pScrn->videoRam = 8192;
2913                break;
2914            }
2915        } else
2916            if (pTrident->Chipset == CYBER9525DVD) {
2917                pScrn->videoRam = 2560;
2918            } else
2919            {
2920                OUTB(vgaIOBase + 4, SPR);
2921                videoram = INB(vgaIOBase + 5);
2922                if (pTrident->Chipset < TGUI9440AGi)
2923                    videorammask = 0x07;
2924                else
2925                    videorammask = 0x0F;
2926                switch (videoram & videorammask) {
2927                case 0x01:
2928                    pScrn->videoRam = 512;
2929                    break;
2930                case 0x02: /* XP */
2931                    pScrn->videoRam = 6144;
2932                    break;
2933                case 0x03:
2934                    pScrn->videoRam = 1024;
2935                    break;
2936                case 0x04:
2937                    pScrn->videoRam = 8192;
2938                    break;
2939                case 0x06: /* XP */
2940                    pScrn->videoRam = 10240;
2941                    break;
2942                case 0x07:
2943                    pScrn->videoRam = 2048;
2944                    break;
2945                case 0x08: /* XP */
2946                    pScrn->videoRam = 12288;
2947                    break;
2948                case 0x0A: /* XP */
2949                    pScrn->videoRam = 14336;
2950                    break;
2951                case 0x0C: /* XP */
2952                    pScrn->videoRam = 16384;
2953                    break;
2954                case 0x0E: /* XP */
2955                    OUTB(vgaIOBase + 4, 0xC1);
2956                    switch (INB(vgaIOBase + 5) & 0x11) {
2957                    case 0x00:
2958                        pScrn->videoRam = 20480;
2959                        break;
2960                    case 0x01:
2961                        pScrn->videoRam = 24576;
2962                        break;
2963                    case 0x10:
2964                        pScrn->videoRam = 28672;
2965                        break;
2966                    case 0x11:
2967                        pScrn->videoRam = 32768;
2968                        break;
2969                    }
2970                    break;
2971                    case 0x0F:
2972                        pScrn->videoRam = 4096;
2973                        break;
2974                    default:
2975                        pScrn->videoRam = 1024;
2976                        xf86DrvMsg(pScrn->scrnIndex, from,
2977                                "Unable to determine VideoRam, defaulting to 1MB\n");
2978                        break;
2979                }
2980            }
2981    }
2982
2983    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
2984            pTrident->HWCursor ? "HW" : "SW");
2985
2986    xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
2987            pScrn->videoRam);
2988
2989    if (pTrident->IsCyber) {
2990        unsigned char mod, dsp, dsp1;
2991
2992        pTrident->lcdMode = 0xff;
2993
2994        OUTB(0x3CE,0x42);
2995        dsp = INB(0x3CF);
2996        OUTB(0x3CE,0x43);
2997        dsp1 = INB(0x3CF);
2998        OUTB(0x3CE,0x52);
2999        mod = INB(0x3CF);
3000        /*
3001         * Only allow display size override if 1280x1024 is detected
3002         * Currently 1400x1050 is supported - which is detected as
3003         * 1280x1024
3004         */
3005        if (pTrident->displaySize) {
3006            if (((mod >> 4) & 3) == 0) {
3007                for (i = 0; LCD[i].mode != 0xff; i++) {
3008                    if (pTrident->displaySize == LCD[i].display_x)
3009                        pTrident->lcdMode = LCD[i].mode;
3010                }
3011                xf86DrvMsg(pScrn->scrnIndex,
3012                        X_INFO,"%s Panel %ix%i found\n",
3013                        (dsp & 0x80) ? "TFT" :
3014                                ((dsp1 & 0x20) ? "DSTN" : "STN"),
3015                                LCD[i].display_x,LCD[i].display_y);
3016            } else {
3017                xf86DrvMsg(pScrn->scrnIndex,X_WARNING,
3018                        "Display size override only for 1280x1024\n");
3019                pTrident->displaySize = 0;
3020            }
3021        }
3022
3023        if (!pTrident->displaySize) {
3024            for (i = 0; LCD[i].mode != 0xff; i++) {
3025                if (LCD[i].mode == ((mod >> 4) & 3)) {
3026                    pTrident->lcdMode = i;
3027                    xf86DrvMsg(pScrn->scrnIndex,
3028                            X_PROBED,"%s Panel %ix%i found\n",
3029                            (dsp & 0x80) ? "TFT" :
3030                                    ((dsp1 & 0x20) ? "DSTN" : "STN"),
3031                                    LCD[i].display_x,LCD[i].display_y);
3032                }
3033            }
3034        }
3035        if (pTrident->dspOverride) {
3036            if (pTrident->dspOverride & LCD_ACTIVE)
3037                pTrident->lcdActive = TRUE;
3038            else
3039                pTrident->lcdActive = FALSE;
3040        } else {
3041            OUTB(0x3CE, FPConfig);
3042            pTrident->lcdActive = (INB(0x3CF) & 0x10);
3043        }
3044    }
3045
3046    pTrident->MCLK = 0;
3047    mclk = CalculateMCLK(pScrn);
3048    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory Clock is %3.2f MHz\n", mclk);
3049    if (xf86GetOptValFreq(pTrident->Options, OPTION_SETMCLK, OPTUNITS_MHZ,
3050            &real)) {
3051        pTrident->MCLK = (int)(real * 1000.0);
3052        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Setting new Memory Clock to %3.2f MHz\n",
3053                (float)(pTrident->MCLK / 1000));
3054    }
3055
3056    /* Set the min pixel clock */
3057    pTrident->MinClock = 12000;	/* XXX Guess, need to check this */
3058    xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
3059            pTrident->MinClock / 1000);
3060
3061    /*
3062     * If the user has specified ramdac speed in the XF86Config
3063     * file, we respect that setting.
3064     */
3065    if (pTrident->pEnt->device->dacSpeeds[0]) {
3066        int speed = 0;
3067
3068        switch (pScrn->bitsPerPixel) {
3069        case 8:
3070            speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP8];
3071            break;
3072        case 16:
3073            speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP16];
3074            break;
3075        case 24:
3076            speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP24];
3077            break;
3078        case 32:
3079            speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP32];
3080            break;
3081        }
3082        if (speed == 0)
3083            pTrident->MaxClock = pTrident->pEnt->device->dacSpeeds[0];
3084        else
3085            pTrident->MaxClock = speed;
3086        from = X_CONFIG;
3087    } else {
3088        switch (pScrn->bitsPerPixel) {
3089        case 16:
3090            pTrident->MaxClock = ClockLimit16bpp[pTrident->Chipset];
3091            break;
3092        case 24:
3093            pTrident->MaxClock = ClockLimit24bpp[pTrident->Chipset];
3094            break;
3095        case 32:
3096            pTrident->MaxClock = ClockLimit32bpp[pTrident->Chipset];
3097            break;
3098        default:
3099            pTrident->MaxClock = ClockLimit[pTrident->Chipset];
3100            break;
3101        }
3102    }
3103    xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
3104            pTrident->MaxClock / 1000);
3105
3106    /*
3107     * Setup the ClockRanges, which describe what clock ranges are available,
3108     * and what sort of modes they can be used for.
3109     */
3110    clockRanges = xnfcalloc(sizeof(ClockRange), 1);
3111    clockRanges->next = NULL;
3112    if (!pScrn->progClock) {
3113        if (pScrn->videoRam < 1024)
3114            clockRanges->ClockMulFactor = 2;
3115        if (pScrn->bitsPerPixel == 16)
3116            clockRanges->ClockMulFactor = 2;
3117    }
3118    clockRanges->minClock = pTrident->MinClock;
3119    clockRanges->maxClock = pTrident->MaxClock;
3120    clockRanges->clockIndex = -1;		/* programmable */
3121    clockRanges->interlaceAllowed = TRUE;
3122    clockRanges->doubleScanAllowed = TRUE;
3123
3124    /*
3125     * xf86ValidateModes will check that the mode HTotal and VTotal values
3126     * don't exceed the chipset's limit if pScrn->maxHValue and
3127     * pScrn->maxVValue are set.  Since our TRIDENTValidMode() already takes
3128     * care of this, we don't worry about setting them here.
3129     */
3130
3131    if (pScrn->bitsPerPixel == 24) {
3132        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
3133                "Disabling Engine due to 24bpp.\n");
3134        pTrident->NoAccel = TRUE;
3135    }
3136
3137    /* Select valid modes from those available */
3138    if (pTrident->NoAccel || Is3Dchip) {
3139        /*
3140         * XXX Assuming min pitch 256, max 4096
3141         * XXX Assuming min height 128, max 4096
3142         */
3143        i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
3144                pScrn->display->modes, clockRanges,
3145                NULL, 256, 4096,
3146                pScrn->bitsPerPixel, 128, 4096,
3147                pScrn->display->virtualX,
3148                pScrn->display->virtualY,
3149                pTrident->FbMapSize,
3150                LOOKUP_BEST_REFRESH);
3151    } else {
3152        /*
3153         * XXX Assuming min height 128, max 2048
3154         */
3155        i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
3156                pScrn->display->modes, clockRanges,
3157                GetAccelPitchValues(pScrn), 0, 0,
3158                pScrn->bitsPerPixel, 128, 2048,
3159                pScrn->display->virtualX,
3160                pScrn->display->virtualY,
3161                pTrident->FbMapSize,
3162                LOOKUP_BEST_REFRESH);
3163    }
3164
3165    if (i == -1) {
3166        if (IsPciCard && UseMMIO) {
3167            TRIDENTDisableMMIO(pScrn);
3168            TRIDENTUnmapMem(pScrn);
3169        }
3170        TRIDENTFreeRec(pScrn);
3171        return FALSE;
3172    }
3173
3174    /* Prune the modes marked as invalid */
3175    xf86PruneDriverModes(pScrn);
3176
3177    if (i == 0 || pScrn->modes == NULL) {
3178        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
3179        if (IsPciCard && UseMMIO) {
3180            TRIDENTDisableMMIO(pScrn);
3181            TRIDENTUnmapMem(pScrn);
3182        }
3183        TRIDENTFreeRec(pScrn);
3184        return FALSE;
3185    }
3186
3187    xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
3188
3189    /* Set the current mode to the first in the list */
3190    pScrn->currentMode = pScrn->modes;
3191
3192    /* Print the list of modes being used */
3193    xf86PrintModes(pScrn);
3194
3195    /* Set display resolution */
3196    xf86SetDpi(pScrn, 0, 0);
3197
3198    /* Load bpp-specific modules */
3199    switch (pScrn->bitsPerPixel) {
3200    case 8:
3201        pTrident->EngineOperation |= 0x00;
3202        break;
3203    case 16:
3204        pTrident->EngineOperation |= 0x01;
3205        break;
3206    case 24:
3207        pTrident->EngineOperation |= 0x03;
3208        break;
3209    case 32:
3210        pTrident->EngineOperation |= 0x02;
3211        break;
3212    }
3213
3214    if (xf86LoadSubModule(pScrn, "fb") == NULL) {
3215        if (IsPciCard && UseMMIO) {
3216            TRIDENTDisableMMIO(pScrn);
3217            TRIDENTUnmapMem(pScrn);
3218        }
3219        TRIDENTFreeRec(pScrn);
3220        return FALSE;
3221    }
3222
3223    if (!xf86LoadSubModule(pScrn, "i2c")) {
3224        if (IsPciCard && UseMMIO) {
3225            TRIDENTDisableMMIO(pScrn);
3226            TRIDENTUnmapMem(pScrn);
3227        }
3228        TRIDENTFreeRec(pScrn);
3229        return FALSE;
3230    }
3231
3232    /* Load XAA if needed */
3233    if (!pTrident->NoAccel) {
3234        if (!pTrident->useEXA) {
3235            if (!xf86LoadSubModule(pScrn, "xaa")) {
3236                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3237                        "Falling back to shadowfb\n");
3238                pTrident->NoAccel = 1;
3239                pTrident->ShadowFB = 1;
3240            }
3241        }
3242
3243        if (pTrident->useEXA) {
3244            XF86ModReqInfo req;
3245            int errmaj, errmin;
3246
3247            memset(&req, 0, sizeof(req));
3248
3249            req.majorversion = 2;
3250            if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
3251                    &errmaj, &errmin))
3252            {
3253                LoaderErrorMsg(NULL, "exa", errmaj, errmin);
3254                if (IsPciCard && UseMMIO) {
3255                    TRIDENTDisableMMIO(pScrn);
3256                    TRIDENTUnmapMem(pScrn);
3257                }
3258                TRIDENTFreeRec(pScrn);
3259                return FALSE;
3260            }
3261        }
3262
3263        switch (pScrn->displayWidth * pScrn->bitsPerPixel / 8) {
3264        case 512:
3265        case 8192:
3266            pTrident->EngineOperation |= 0x00;
3267            break;
3268        case 1024:
3269            pTrident->EngineOperation |= 0x04;
3270            break;
3271        case 2048:
3272            pTrident->EngineOperation |= 0x08;
3273            break;
3274        case 4096:
3275            pTrident->EngineOperation |= 0x0C;
3276            break;
3277        }
3278    }
3279
3280    /* Load shadow if needed */
3281    if (pTrident->ShadowFB) {
3282        if (!xf86LoadSubModule(pScrn, "shadow")) {
3283            TRIDENTFreeRec(pScrn);
3284            return FALSE;
3285        }
3286    }
3287
3288    /* Load DDC if needed */
3289    /* This gives us DDC1 - we should be able to get DDC2B using i2c */
3290
3291    if (! ddcLoaded)
3292        if (!xf86LoadSubModule(pScrn, "ddc")) {
3293            if (IsPciCard && UseMMIO) {
3294                TRIDENTDisableMMIO(pScrn);
3295                TRIDENTUnmapMem(pScrn);
3296            }
3297            TRIDENTFreeRec(pScrn);
3298            return FALSE;
3299        }
3300
3301    if (IsPciCard && UseMMIO) {
3302        TRIDENTDisableMMIO(pScrn);
3303        TRIDENTUnmapMem(pScrn);
3304    }
3305
3306#ifndef XSERVER_LIBPCIACCESS
3307    pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
3308
3309    if (pTrident->IsCyber && pTrident->MMIOonly)
3310        pScrn->racIoFlags = 0;
3311    else
3312        pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
3313#endif
3314    pTrident->FbMapSize = pScrn->videoRam * 1024;
3315
3316    return TRUE;
3317}
3318
3319
3320/*
3321 * This is called at the end of each server generation.  It restores the
3322 * original (text) mode.  It should really also unmap the video memory too.
3323 */
3324
3325/* Mandatory */
3326static Bool
3327TRIDENTCloseScreen(CLOSE_SCREEN_ARGS_DECL)
3328{
3329    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
3330    vgaHWPtr hwp = VGAHWPTR(pScrn);
3331    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
3332
3333    if (pScrn->vtSema) {
3334#ifdef HAVE_XAA_H
3335        if (!pTrident->NoAccel && !pTrident->useEXA)
3336            pTrident->AccelInfoRec->Sync(pScrn);
3337        else
3338#endif
3339            if (!pTrident->NoAccel && pTrident->useEXA)
3340                pTrident->EXADriverPtr->WaitMarker(pScreen, 0);
3341
3342#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
3343        if (xf86IsPc98())
3344            PC98TRIDENTDisable(pScrn);
3345#endif
3346
3347        TRIDENTRestore(pScrn);
3348        vgaHWLock(hwp);
3349        if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn);
3350        TRIDENTUnmapMem(pScrn);
3351    }
3352
3353#ifdef HAVE_XAA_H
3354    if (pTrident->AccelInfoRec)
3355        XAADestroyInfoRec(pTrident->AccelInfoRec);
3356#endif
3357    if (pTrident->EXADriverPtr) {
3358        exaDriverFini(pScreen);
3359        free(pTrident->EXADriverPtr);
3360        pTrident->EXADriverPtr = NULL;
3361    }
3362    if (pTrident->CursorInfoRec)
3363        xf86DestroyCursorInfoRec(pTrident->CursorInfoRec);
3364    if (pTrident->ShadowPtr) {
3365        shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen));
3366        free(pTrident->ShadowPtr);
3367        pScreen->CreateScreenResources = pTrident->CreateScreenResources;
3368    }
3369    if (pTrident->DGAModes)
3370        free(pTrident->DGAModes);
3371    pScrn->vtSema = FALSE;
3372
3373    if(pTrident->BlockHandler)
3374        pScreen->BlockHandler = pTrident->BlockHandler;
3375
3376    if (pTrident->pVbe)
3377        vbeFree(pTrident->pVbe);
3378    else
3379        xf86FreeInt10(pTrident->Int10);
3380    pScreen->CloseScreen = pTrident->CloseScreen;
3381    return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
3382}
3383
3384/* Do screen blanking */
3385
3386/* Mandatory */
3387static Bool
3388TRIDENTSaveScreen(ScreenPtr pScreen, int mode)
3389{
3390    return vgaHWSaveScreen(pScreen, mode);
3391}
3392
3393
3394static Bool
3395TRIDENTCreateScreenResources(ScreenPtr pScreen)
3396{
3397    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
3398    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
3399    Bool ret;
3400
3401    pScreen->CreateScreenResources = pTrident->CreateScreenResources;
3402    ret = pScreen->CreateScreenResources(pScreen);
3403    pTrident->CreateScreenResources = pScreen->CreateScreenResources;
3404    pScreen->CreateScreenResources = TRIDENTCreateScreenResources;
3405
3406    if (ret)
3407        ret = shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen),
3408                TRIDENTShadowUpdate, NULL, 0, 0);
3409
3410    return ret;
3411}
3412
3413/* Mandatory */
3414
3415/* This gets called at the start of each server generation */
3416
3417static Bool
3418TRIDENTScreenInit(SCREEN_INIT_ARGS_DECL)
3419{
3420    /* The vgaHW references will disappear one day */
3421    ScrnInfoPtr pScrn;
3422    vgaHWPtr hwp;
3423    TRIDENTPtr pTrident;
3424    int ret;
3425    VisualPtr visual;
3426    unsigned char *FBStart;
3427    int width, height, displayWidth;
3428
3429    /*
3430     * First get the ScrnInfoRec
3431     */
3432    pScrn = xf86ScreenToScrn(pScreen);
3433    pTrident = TRIDENTPTR(pScrn);
3434
3435    if (IsPrimaryCard) {
3436        if (!vgaHWMapMem(pScrn))
3437            return FALSE;
3438    }
3439
3440    /* Map the TRIDENT memory and MMIO areas */
3441    if (!TRIDENTMapMem(pScrn))
3442        return FALSE;
3443
3444#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
3445    if (!xf86IsPc98())
3446#endif
3447    {
3448#ifdef VBE_INFO
3449        if (pTrident->vbeModes) {
3450            pTrident->pVbe = VBEInit(NULL,pTrident->pEnt->index);
3451            pTrident->Int10 = pTrident->pVbe->pInt10;
3452        } else
3453#endif
3454        {
3455            if (xf86LoadSubModule(pScrn, "int10")) {
3456                xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Initializing int10\n");
3457                pTrident->Int10 = xf86InitInt10(pTrident->pEnt->index);
3458            }
3459        }
3460    }
3461
3462    hwp = VGAHWPTR(pScrn);
3463
3464    if (IsPciCard && UseMMIO) {
3465        TRIDENTEnableMMIO(pScrn);
3466
3467        /* Initialize the MMIO vgahw functions */
3468        vgaHWSetMmioFuncs(hwp, pTrident->IOBase, 0);
3469    }
3470
3471    /* Save the current state */
3472    TRIDENTSave(pScrn);
3473
3474    /*
3475     * Some Trident chip on PC-9821 needs setup,
3476     * because VGA chip is not initialized by VGA BIOS.
3477     */
3478#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
3479    if (IsPciCard && xf86IsPc98()) {
3480        PC98TRIDENTInit(pScrn);
3481    } else
3482#endif
3483        tridentSetModeBIOS(pScrn,pScrn->currentMode);
3484
3485    /* Initialise the first mode */
3486    if (!TRIDENTModeInit(pScrn, pScrn->currentMode))
3487        return FALSE;
3488
3489    /* Darken the screen for aesthetic reasons and set the viewport */
3490    TRIDENTSaveScreen(pScreen, SCREEN_SAVER_ON);
3491    TRIDENTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
3492
3493    /*
3494     * The next step is to setup the screen's visuals, and initialise the
3495     * framebuffer code.  In cases where the framebuffer's default
3496     * choices for things like visual layouts and bits per RGB are OK,
3497     * this may be as simple as calling the framebuffer's ScreenInit()
3498     * function.  If not, the visuals will need to be setup before calling
3499     * a fb ScreenInit() function and fixed up after.
3500     *
3501     * For most PC hardware at depths >= 8, the defaults that fb uses
3502     * are not appropriate.  In this driver, we fixup the visuals after.
3503     */
3504
3505    /*
3506     * Reset visual list.
3507     */
3508    miClearVisualTypes();
3509
3510    /* Setup the visuals we support. */
3511
3512    if (!miSetVisualTypes(pScrn->depth,
3513            miGetDefaultVisualMask(pScrn->depth),
3514            pScrn->rgbBits, pScrn->defaultVisual)) {
3515        if (pTrident->pVbe)
3516            vbeFree(pTrident->pVbe);
3517        else
3518            xf86FreeInt10(pTrident->Int10);
3519        return FALSE;
3520    }
3521
3522    miSetPixmapDepths ();
3523
3524    /* FIXME - we don't do shadowfb for < 4 */
3525    displayWidth = pScrn->displayWidth;
3526    if (pTrident->Rotate) {
3527        height = pScrn->virtualX;
3528        width = pScrn->virtualY;
3529    } else {
3530        width = pScrn->virtualX;
3531        height = pScrn->virtualY;
3532    }
3533
3534    if(pTrident->ShadowFB) {
3535        pTrident->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
3536        pTrident->ShadowPtr = malloc(pTrident->ShadowPitch * height);
3537        displayWidth = pTrident->ShadowPitch / (pScrn->bitsPerPixel >> 3);
3538        FBStart = pTrident->ShadowPtr;
3539    } else {
3540        pTrident->ShadowFB = FALSE;
3541        pTrident->ShadowPtr = NULL;
3542        FBStart = pTrident->FbBase;
3543    }
3544
3545    /*
3546     * Call the framebuffer layer's ScreenInit function, and fill in other
3547     * pScreen fields.
3548     */
3549
3550    switch (pScrn->bitsPerPixel) {
3551    case 8:
3552    case 16:
3553    case 24:
3554    case 32:
3555        ret = fbScreenInit(pScreen, FBStart, width,
3556                height, pScrn->xDpi, pScrn->yDpi,
3557                displayWidth, pScrn->bitsPerPixel);
3558
3559        break;
3560    default:
3561        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3562                "Internal error: invalid bpp (%d) in TRIDENTScrnInit\n",
3563                pScrn->bitsPerPixel);
3564        ret = FALSE;
3565        break;
3566    }
3567    if (!ret) {
3568        if (pTrident->pVbe)
3569            vbeFree(pTrident->pVbe);
3570        else
3571            xf86FreeInt10(pTrident->Int10);
3572        return FALSE;
3573    }
3574    if (pScrn->bitsPerPixel > 8) {
3575        /* Fixup RGB ordering */
3576        visual = pScreen->visuals + pScreen->numVisuals;
3577        while (--visual >= pScreen->visuals) {
3578            if ((visual->class | DynamicClass) == DirectColor) {
3579                visual->offsetRed = pScrn->offset.red;
3580                visual->offsetGreen = pScrn->offset.green;
3581                visual->offsetBlue = pScrn->offset.blue;
3582                visual->redMask = pScrn->mask.red;
3583                visual->greenMask = pScrn->mask.green;
3584                visual->blueMask = pScrn->mask.blue;
3585            }
3586        }
3587    }
3588
3589    /* must be after RGB ordering fixed */
3590    fbPictureInit (pScreen, 0, 0);
3591
3592    xf86SetBlackWhitePixels(pScreen);
3593
3594    pTrident->BlockHandler = pScreen->BlockHandler;
3595    pScreen->BlockHandler = TRIDENTBlockHandler;
3596
3597    if (!pTrident->ShadowFB)
3598        TRIDENTDGAInit(pScreen);
3599
3600#ifdef HAVE_ISA
3601    if (!LINEAR()) {
3602        miBankInfoPtr pBankInfo;
3603
3604        /* Setup the vga banking variables */
3605        pBankInfo = xnfcalloc(sizeof(miBankInfoRec),1);
3606        if (pBankInfo == NULL) {
3607            if (pTrident->pVbe)
3608                vbeFree(pTrident->pVbe);
3609            else
3610                xf86FreeInt10(pTrident->Int10);
3611            return FALSE;
3612        }
3613        pBankInfo->pBankA = pTrident->FbBase;
3614        pBankInfo->pBankB = pTrident->FbBase;
3615        pBankInfo->BankSize = 0x10000;
3616        pBankInfo->nBankDepth = (pScrn->depth == 4) ? 1 : pScrn->depth;
3617
3618        pBankInfo->SetSourceBank =
3619                (miBankProcPtr)TVGA8900SetRead;
3620        pBankInfo->SetDestinationBank =
3621                (miBankProcPtr)TVGA8900SetWrite;
3622        pBankInfo->SetSourceAndDestinationBanks =
3623                (miBankProcPtr)TVGA8900SetReadWrite;
3624        if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
3625                pScrn->displayWidth, pBankInfo)) {
3626            free(pBankInfo);
3627            pBankInfo = NULL;
3628            if (pTrident->pVbe)
3629                vbeFree(pTrident->pVbe);
3630            else
3631                xf86FreeInt10(pTrident->Int10);
3632            return FALSE;
3633        }
3634    }
3635#endif
3636
3637    {
3638        BoxRec AvailFBArea;
3639
3640        AvailFBArea.x1 = 0;
3641        AvailFBArea.y1 = 0;
3642        AvailFBArea.x2 = pScrn->displayWidth;
3643        AvailFBArea.y2 = pTrident->FbMapSize / (pScrn->displayWidth *
3644                pScrn->bitsPerPixel / 8);
3645
3646        if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047;
3647
3648        if (xf86InitFBManager(pScreen, &AvailFBArea)) {
3649            int cpp = pScrn->bitsPerPixel / 8;
3650            int area = AvailFBArea.y2 * pScrn->displayWidth;
3651            int areaoffset = area * cpp;
3652
3653            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3654                    "Using %i scanlines of offscreen memory for area's \n",
3655                    AvailFBArea.y2 - pScrn->virtualY);
3656
3657            if (xf86InitFBManagerLinear(pScreen, area, ((pTrident->FbMapSize/cpp) - area))) {
3658                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3659                        "Using %ld bytes of offscreen memory for linear (offset=0x%x)\n", (pTrident->FbMapSize - areaoffset), areaoffset);
3660            }
3661        }
3662    }
3663
3664    if (Is3Dchip) {
3665        if ((pTrident->Chipset == CYBERBLADEI7) ||
3666                (pTrident->Chipset == CYBERBLADEI7D) ||
3667                (pTrident->Chipset == CYBERBLADEI1) ||
3668                (pTrident->Chipset == CYBERBLADEI1D) ||
3669                (pTrident->Chipset == CYBERBLADEAI1) ||
3670                (pTrident->Chipset == CYBERBLADEAI1D) ||
3671                (pTrident->Chipset == CYBERBLADEE4) ||
3672                (pTrident->Chipset == BLADE3D)) {
3673            if (pTrident->useEXA)
3674                BladeExaInit(pScreen);
3675            else
3676                BladeXaaInit(pScreen);
3677        } else
3678            if ((pTrident->Chipset == CYBERBLADEXP4) ||
3679                    (pTrident->Chipset == XP5)) {
3680                if (pTrident->useEXA)
3681                    XP4ExaInit(pScreen);
3682                else
3683                    XP4XaaInit(pScreen);
3684            } else
3685                if ((pTrident->Chipset == BLADEXP) ||
3686                        (pTrident->Chipset == CYBERBLADEXPAI1)) {
3687                    XPAccelInit(pScreen);
3688                } else {
3689                    ImageAccelInit(pScreen);
3690                }
3691    } else {
3692        TridentAccelInit(pScreen);
3693    }
3694
3695    xf86SetBackingStore(pScreen);
3696
3697    /* Initialise cursor functions */
3698    miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
3699
3700    if (pTrident->HWCursor) {
3701        xf86SetSilkenMouse(pScreen);
3702        TridentHWCursorInit(pScreen);
3703    }
3704
3705    /* Initialise default colourmap */
3706    if (!miCreateDefColormap(pScreen)) {
3707        if (pTrident->pVbe)
3708            vbeFree(pTrident->pVbe);
3709        else
3710            xf86FreeInt10(pTrident->Int10);
3711        return FALSE;
3712    }
3713    if(!xf86HandleColormaps(pScreen, 256, 6, TridentLoadPalette,
3714            TridentSetOverscan, CMAP_RELOAD_ON_MODE_SWITCH|CMAP_PALETTED_TRUECOLOR)) {
3715        if (pTrident->pVbe)
3716            vbeFree(pTrident->pVbe);
3717        else
3718            xf86FreeInt10(pTrident->Int10);
3719        return FALSE;
3720    }
3721    if(pTrident->ShadowFB) {
3722        if(pTrident->Rotate) {
3723            if (!pTrident->PointerMoved) {
3724                pTrident->PointerMoved = pScrn->PointerMoved;
3725                pScrn->PointerMoved = TRIDENTPointerMoved;
3726            }
3727            switch (pScrn->bitsPerPixel) {
3728            case 8:    pTrident->RefreshArea = TRIDENTRefreshArea8; break;
3729            case 16:   pTrident->RefreshArea = TRIDENTRefreshArea16; break;
3730            case 24:   pTrident->RefreshArea = TRIDENTRefreshArea24; break;
3731            case 32:   pTrident->RefreshArea = TRIDENTRefreshArea32; break;
3732            }
3733        } else {
3734            pTrident->RefreshArea = TRIDENTRefreshArea;
3735        }
3736        if (!shadowSetup(pScreen))
3737            return FALSE;
3738        pTrident->CreateScreenResources = pScreen->CreateScreenResources;
3739        pScreen->CreateScreenResources = TRIDENTCreateScreenResources;
3740    }
3741
3742    xf86DPMSInit(pScreen, (DPMSSetProcPtr)TRIDENTDisplayPowerManagementSet, 0);
3743
3744    pScrn->memPhysBase = pTrident->FbAddress;
3745    pScrn->fbOffset = 0;
3746
3747    if (pTrident->Chipset >= TGUI9660)
3748        TRIDENTInitVideo(pScreen);
3749
3750    pTrident->CloseScreen = pScreen->CloseScreen;
3751    pScreen->CloseScreen = TRIDENTCloseScreen;
3752    pScreen->SaveScreen = TRIDENTSaveScreen;
3753
3754    /* Report any unused options (only for the first generation) */
3755    if (serverGeneration == 1) {
3756        xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
3757    }
3758
3759#if 0
3760    TRIDENTI2CInit(pScreen);
3761
3762    xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,pTrident->DDC));
3763#endif
3764
3765    return TRUE;
3766}
3767
3768