i128_driver.c revision 7965d9ac
150806d53Smrg/*
250806d53Smrg * Copyright 1995-2000 by Robin Cutshaw <robin@XFree86.Org>
350806d53Smrg * Copyright 1998 by Number Nine Visual Technology, Inc.
450806d53Smrg *
550806d53Smrg * Permission to use, copy, modify, distribute, and sell this software and its
650806d53Smrg * documentation for any purpose is hereby granted without fee, provided that
750806d53Smrg * the above copyright notice appear in all copies and that both that
850806d53Smrg * copyright notice and this permission notice appear in supporting
950806d53Smrg * documentation, and that the name of Robin Cutshaw not be used in
1050806d53Smrg * advertising or publicity pertaining to distribution of the software without
1150806d53Smrg * specific, written prior permission.  Robin Cutshaw and Number Nine make no
1250806d53Smrg * representations about the suitability of this software for any purpose.  It
1350806d53Smrg * is provided "as is" without express or implied warranty.
1450806d53Smrg *
1550806d53Smrg * ROBIN CUTSHAW AND NUMBER NINE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
1650806d53Smrg * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
1750806d53Smrg * FITNESS, IN NO EVENT SHALL ROBIN CUTSHAW OR NUMBER NINE BE LIABLE FOR
1850806d53Smrg * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1950806d53Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
2050806d53Smrg * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
2150806d53Smrg * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2250806d53Smrg *
2350806d53Smrg */
2450806d53Smrg
2550806d53Smrg#ifdef HAVE_CONFIG_H
2650806d53Smrg#include "config.h"
2750806d53Smrg#endif
2850806d53Smrg
2950806d53Smrg
3050806d53Smrg
3150806d53Smrg/* All drivers should typically include these */
3250806d53Smrg#include "xf86.h"
3350806d53Smrg#include "xf86_OSproc.h"
3450806d53Smrg#include "xf86Resources.h"
3550806d53Smrg
3650806d53Smrg#include "compiler.h"
3750806d53Smrg
3850806d53Smrg/* Drivers for PCI hardware need this */
3950806d53Smrg#include "xf86PciInfo.h"
4050806d53Smrg
4150806d53Smrg/* Drivers that need to access the PCI config space directly need this */
4250806d53Smrg#include "xf86Pci.h"
4350806d53Smrg
4450806d53Smrg/* vgaHW module is only used to save/restore fonts by this driver */
4550806d53Smrg#include "vgaHW.h"
4650806d53Smrg
4750806d53Smrg/* All drivers initialising the SW cursor need this */
4850806d53Smrg#include "mipointer.h"
4950806d53Smrg
5050806d53Smrg/* All drivers implementing backing store need this */
5150806d53Smrg#include "mibstore.h"
5250806d53Smrg#include "micmap.h"
5350806d53Smrg
5450806d53Smrg#include "xf86DDC.h"
5550806d53Smrg#include "xf86RAC.h"
5650806d53Smrg#include "vbe.h"
5750806d53Smrg
5850806d53Smrg#include "xaa.h"
5950806d53Smrg#include "xf86cmap.h"
6050806d53Smrg#include "fb.h"
6150806d53Smrg
6250806d53Smrg#include "xf86xv.h"
6350806d53Smrg#include <X11/extensions/Xv.h>
6450806d53Smrg
6550806d53Smrg/* driver specific includes */
6650806d53Smrg#include "i128.h"
6750806d53Smrg#include "i128reg.h"
6850806d53Smrg
697965d9acSmrg#include <unistd.h>
707965d9acSmrg
7150806d53Smrg/*
7250806d53Smrg * Forward definitions for the functions that make up the driver.
7350806d53Smrg */
7450806d53Smrg
7550806d53Smrg/* Mandatory functions */
7650806d53Smrgstatic const OptionInfoRec *	I128AvailableOptions(int chipid, int busid);
7750806d53Smrgstatic void	I128Identify(int flags);
7850806d53Smrgstatic Bool	I128Probe(DriverPtr drv, int flags);
7950806d53Smrgstatic Bool	I128PreInit(ScrnInfoPtr pScrn, int flags);
8050806d53Smrgstatic Bool	I128ScreenInit(int Index, ScreenPtr pScreen, int argc,
8150806d53Smrg			      char **argv);
8250806d53Smrgstatic Bool	I128EnterVT(int scrnIndex, int flags);
8350806d53Smrgstatic void	I128LeaveVT(int scrnIndex, int flags);
8450806d53Smrgstatic Bool	I128CloseScreen(int scrnIndex, ScreenPtr pScreen);
8550806d53Smrgstatic Bool	I128SaveScreen(ScreenPtr pScreen, int mode);
8650806d53Smrg
8750806d53Smrgstatic void I128DumpBaseRegisters(ScrnInfoPtr pScrn);
8850806d53Smrgstatic void I128DumpIBMDACRegisters(ScrnInfoPtr pScrn, volatile CARD32 *vrbg);
8950806d53Smrg
9050806d53Smrg/* Optional functions */
9150806d53Smrgstatic void	I128FreeScreen(int scrnIndex, int flags);
9250806d53Smrgstatic ModeStatus I128ValidMode(int scrnIndex, DisplayModePtr mode,
9350806d53Smrg				Bool verbose, int flags);
9450806d53Smrgstatic void	I128DisplayPowerManagementSet(ScrnInfoPtr pScrn,
9550806d53Smrg					     int PowerManagementMode,
9650806d53Smrg					     int flags);
9750806d53Smrg
9850806d53Smrg/* Internally used functions */
9950806d53Smrgstatic Bool	I128GetRec(ScrnInfoPtr pScrn);
10050806d53Smrgstatic void	I128FreeRec(ScrnInfoPtr pScrn);
10150806d53Smrgstatic Bool	I128MapMem(ScrnInfoPtr pScrn);
10250806d53Smrgstatic Bool	I128UnmapMem(ScrnInfoPtr pScrn);
10350806d53Smrgstatic void	I128Save(ScrnInfoPtr pScrn);
10450806d53Smrgstatic void	I128Restore(ScrnInfoPtr pScrn);
10550806d53Smrgstatic Bool	I128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
10650806d53Smrgstatic int	I128CountRam(ScrnInfoPtr pScrn);
10750806d53Smrgstatic void	I128SoftReset(ScrnInfoPtr pScrn);
10850806d53Smrgstatic Bool     I128I2CInit(ScrnInfoPtr pScrn);
10950806d53Smrgstatic xf86MonPtr I128getDDC(ScrnInfoPtr pScrn);
11050806d53Smrg#if 0
11150806d53Smrgstatic unsigned int I128DDC1Read(ScrnInfoPtr pScrn);
11250806d53Smrg#endif
11350806d53Smrg
11450806d53Smrg#define I128_VERSION 4000
11550806d53Smrg#define I128_NAME "I128"
11650806d53Smrg#define I128_DRIVER_NAME "i128"
1177965d9acSmrg#define I128_MAJOR_VERSION PACKAGE_VERSION_MAJOR
1187965d9acSmrg#define I128_MINOR_VERSION PACKAGE_VERSION_MINOR
1197965d9acSmrg#define I128_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL
12050806d53Smrg
12150806d53Smrg/*
12250806d53Smrg * This contains the functions needed by the server after loading the
12350806d53Smrg * driver module.  It must be supplied, and gets added the driver list by
12450806d53Smrg * the Module Setup funtion in the dynamic case.  In the static case a
12550806d53Smrg * reference to this is compiled in, and this requires that the name of
12650806d53Smrg * this DriverRec be an upper-case version of the driver name.
12750806d53Smrg */
12850806d53Smrg
12950806d53Smrg_X_EXPORT DriverRec I128 = {
13050806d53Smrg    I128_VERSION,
13150806d53Smrg    I128_DRIVER_NAME,
13250806d53Smrg    I128Identify,
13350806d53Smrg    I128Probe,
13450806d53Smrg    I128AvailableOptions,
13550806d53Smrg    NULL,
13650806d53Smrg    0
13750806d53Smrg};
13850806d53Smrg
13950806d53Smrg#ifdef XFree86LOADER
14050806d53Smrg
14150806d53Smrgstatic MODULESETUPPROTO(i128Setup);
14250806d53Smrg
14350806d53Smrgstatic XF86ModuleVersionInfo i128VersRec =
14450806d53Smrg{
14550806d53Smrg	"i128",
14650806d53Smrg	MODULEVENDORSTRING,
14750806d53Smrg	MODINFOSTRING1,
14850806d53Smrg	MODINFOSTRING2,
14950806d53Smrg	XORG_VERSION_CURRENT,
15050806d53Smrg	I128_MAJOR_VERSION, I128_MINOR_VERSION, I128_PATCHLEVEL,
15150806d53Smrg	ABI_CLASS_VIDEODRV,			/* This is a video driver */
15250806d53Smrg	ABI_VIDEODRV_VERSION,
15350806d53Smrg	MOD_CLASS_VIDEODRV,
15450806d53Smrg	{0,0,0,0}
15550806d53Smrg};
15650806d53Smrg
15750806d53Smrg/*
15850806d53Smrg * XF86ModuleData structure is the first part of the driver that is used
15950806d53Smrg * by the module loader.  It provides the XF86ModuleVersionInfo structure
16050806d53Smrg * used to verify that the module version is compatable with the loader
16150806d53Smrg * version.  It also provides a pointer to the module specific
16250806d53Smrg * ModuleSetupProc() and ModuleTearDownProc() functions.
16350806d53Smrg */
16450806d53Smrg
16550806d53Smrg_X_EXPORT XF86ModuleData i128ModuleData = { &i128VersRec, i128Setup, NULL };
16650806d53Smrg
16750806d53Smrg#endif
16850806d53Smrg
16950806d53Smrg
17050806d53Smrg/*
17150806d53Smrg * List of symbols from other modules that this module references.  This
17250806d53Smrg * list is used to tell the loader that it is OK for symbols here to be
17350806d53Smrg * unresolved providing that it hasn't been told that they haven't been
17450806d53Smrg * told that they are essential via a call to xf86LoaderReqSymbols() or
17550806d53Smrg * xf86LoaderReqSymLists().  The purpose is this is to avoid warnings about
17650806d53Smrg * unresolved symbols that are not required.  These are provided to the
17750806d53Smrg * LoaderRefSymLists() function in the module specific Setup() function.
17850806d53Smrg */
17950806d53Smrg
18050806d53Smrgstatic const char *vgahwSymbols[] = {
18150806d53Smrg    "vgaHWFreeHWRec",
18250806d53Smrg    "vgaHWGetHWRec",
18350806d53Smrg    "vgaHWGetIOBase",
18450806d53Smrg    "vgaHWGetIndex",
18550806d53Smrg    "vgaHWProtect",
18650806d53Smrg    "vgaHWRestore",
18750806d53Smrg    "vgaHWSave",
18850806d53Smrg    NULL
18950806d53Smrg};
19050806d53Smrg
19150806d53Smrgstatic const char *fbSymbols[] = {
19250806d53Smrg    "fbScreenInit",
19350806d53Smrg    "fbPictureInit",
19450806d53Smrg    NULL
19550806d53Smrg};
19650806d53Smrg
19750806d53Smrgstatic const char *exaSymbols[] = {
19850806d53Smrg    "exaDriverAlloc",
19950806d53Smrg    "exaDriverInit",
20050806d53Smrg    "exaDriverFini",
20150806d53Smrg    "exaGetPixmapOffset",
20250806d53Smrg    NULL
20350806d53Smrg};
20450806d53Smrg
20550806d53Smrgstatic const char *xaaSymbols[] = {
20650806d53Smrg    "XAACreateInfoRec",
20750806d53Smrg    "XAADestroyInfoRec",
20850806d53Smrg    "XAAInit",
20950806d53Smrg    NULL
21050806d53Smrg};
21150806d53Smrg
21250806d53Smrgstatic const char *ramdacSymbols[] = {
21350806d53Smrg    "xf86CreateCursorInfoRec",
21450806d53Smrg    "xf86DestroyCursorInfoRec",
21550806d53Smrg    "xf86InitCursor",
21650806d53Smrg    NULL
21750806d53Smrg};
21850806d53Smrg
21950806d53Smrgstatic const char *ddcSymbols[] = {
22050806d53Smrg    "xf86DoEDID_DDC1",
22150806d53Smrg    "xf86DoEDID_DDC2",
22250806d53Smrg    "xf86PrintEDID",
22350806d53Smrg    "xf86SetDDCproperties",
22450806d53Smrg    NULL
22550806d53Smrg};
22650806d53Smrg
22750806d53Smrgstatic const char *i2cSymbols[] = {
22850806d53Smrg    "xf86CreateI2CBusRec",
22950806d53Smrg    "xf86I2CBusInit",
23050806d53Smrg    NULL
23150806d53Smrg};
23250806d53Smrg
23350806d53Smrg#ifdef XFree86LOADER
23450806d53Smrg/* XXX The vbe module isn't currently loaded. */
23550806d53Smrgstatic const char *vbeSymbols[] = {
23650806d53Smrg    "VBEInit",
23750806d53Smrg    "vbeDoEDID",
23850806d53Smrg    NULL
23950806d53Smrg};
24050806d53Smrg
24150806d53Smrg/* XXX The int10 module isn't currently loaded. */
24250806d53Smrgstatic const char *int10Symbols[] = {
24350806d53Smrg    "xf86InitInt10",
24450806d53Smrg    "xf86FreeInt10",
24550806d53Smrg    NULL
24650806d53Smrg};
24750806d53Smrg#endif
24850806d53Smrg
24950806d53Smrg
25050806d53Smrg#ifdef XFree86LOADER
25150806d53Smrg
25250806d53Smrg/* Mandatory
25350806d53Smrg *
25450806d53Smrg * The Setup() function is the first entry point called once that the
25550806d53Smrg * module has been linked into the server.  It adds this driver to
25650806d53Smrg * the driver list and lets the server know which symbols it might use.
25750806d53Smrg * This is only called once, not called with each server generation.
25850806d53Smrg *
25950806d53Smrg * Arguments:
26050806d53Smrg *		pointer module - module being loaded, passed to xf86AddDriver()
26150806d53Smrg *		pointer opts   - unused but contains options from config file
26250806d53Smrg *		int *errmaj    - if function error returns major error value
26350806d53Smrg *		int *errmin    - if function error returns minor error value
26450806d53Smrg * Returns:
26550806d53Smrg *		pointer to TearDownData which is passed to TearDownProc()
26650806d53Smrg *		or NULL for failure.
26750806d53Smrg */
26850806d53Smrg
26950806d53Smrgstatic pointer
27050806d53Smrgi128Setup(pointer module, pointer opts, int *errmaj, int *errmin)
27150806d53Smrg{
27250806d53Smrg    static Bool setupDone = FALSE;
27350806d53Smrg
27450806d53Smrg    /* This module should be loaded only once, but check to be sure. */
27550806d53Smrg
27650806d53Smrg    if (!setupDone) {
27750806d53Smrg	setupDone = TRUE;
27850806d53Smrg	xf86AddDriver(&I128, module, 0);
27950806d53Smrg
28050806d53Smrg	/*
28150806d53Smrg	 * Modules that this driver always requires may be loaded here
28250806d53Smrg	 * by calling LoadSubModule().
28350806d53Smrg	 */
28450806d53Smrg
28550806d53Smrg	/*
28650806d53Smrg	 * Tell the loader about symbols from other modules that this module
28750806d53Smrg	 * might refer to.
28850806d53Smrg	 */
28950806d53Smrg	LoaderRefSymLists(fbSymbols,
29050806d53Smrg			  exaSymbols,
29150806d53Smrg			  xaaSymbols,
29250806d53Smrg			  ramdacSymbols,
29350806d53Smrg			  ddcSymbols,
29450806d53Smrg			  ddcSymbols,
29550806d53Smrg			  i2cSymbols,
29650806d53Smrg			  vbeSymbols,
29750806d53Smrg			  int10Symbols,
29850806d53Smrg			  vgahwSymbols,
29950806d53Smrg			  NULL);
30050806d53Smrg
30150806d53Smrg	/*
30250806d53Smrg	 * The return value must be non-NULL on success even though there
30350806d53Smrg	 * is no TearDownProc.
30450806d53Smrg	 */
30550806d53Smrg	return (pointer)1;
30650806d53Smrg    } else {
30750806d53Smrg	if (errmaj) *errmaj = LDR_ONCEONLY;
30850806d53Smrg	return NULL;
30950806d53Smrg    }
31050806d53Smrg}
31150806d53Smrg
31250806d53Smrg#endif /* XFree86LOADER */
31350806d53Smrg
31450806d53Smrg
31550806d53Smrg/* Define supported chipsets.  Used by Probe(). */
31650806d53Smrg
31750806d53Smrgstatic SymTabRec I128Chipsets[] = {
31850806d53Smrg    { PCI_CHIP_I128,		"i128" },
31950806d53Smrg    { PCI_CHIP_I128_2,		"i128v2" },
32050806d53Smrg    { PCI_CHIP_I128_T2R,	"i128t2r" },
32150806d53Smrg    { PCI_CHIP_I128_T2R4,	"i128t2r4" },
32250806d53Smrg    {-1,			NULL }
32350806d53Smrg};
32450806d53Smrg
32550806d53Smrgstatic PciChipsets I128PciChipsets[] = {
32650806d53Smrg    { PCI_CHIP_I128,		PCI_CHIP_I128,		NULL },
32750806d53Smrg    { PCI_CHIP_I128_2,		PCI_CHIP_I128_2,	NULL },
32850806d53Smrg    { PCI_CHIP_I128_T2R,	PCI_CHIP_I128_T2R,	NULL },
32950806d53Smrg    { PCI_CHIP_I128_T2R4,	PCI_CHIP_I128_T2R4,	NULL },
33050806d53Smrg    { -1,			-1,			RES_UNDEFINED }
33150806d53Smrg};
33250806d53Smrg
33350806d53Smrg/* Mandatory
33450806d53Smrg *
33550806d53Smrg * The Probe() function is the second entry point called once that the
33650806d53Smrg * module has been linked into the server.  This function finds all
33750806d53Smrg * instances of hardware that it supports and allocates a ScrnInfoRec
33850806d53Smrg * using xf86ConfigPciEntity() for each unclaimed slot.  This should be
33950806d53Smrg * a minimal probe and under no circumstances should it leave the hardware
34050806d53Smrg * state changed.  No initialisations other than the required ScrnInfoRec
34150806d53Smrg * should be done and no data structures should be allocated.
34250806d53Smrg *
34350806d53Smrg * Arguments:
34450806d53Smrg *		DriverPtr drv - pointer to the driver structure
34550806d53Smrg *		int flags     - PROBE_DEFAULT for normal function
34650806d53Smrg *		                PROBE_DETECT for use with "-config" and "-probe"
34750806d53Smrg * Returns:
34850806d53Smrg *		Bool TRUE if a screen was allocated, FALSE otherwise
34950806d53Smrg */
35050806d53Smrg
35150806d53Smrgstatic Bool
35250806d53SmrgI128Probe(DriverPtr drv, int flags)
35350806d53Smrg{
35450806d53Smrg    int i;
35550806d53Smrg    GDevPtr *devSections;
35650806d53Smrg    int *usedChips;
35750806d53Smrg    int numDevSections;
35850806d53Smrg    int numUsed;
35950806d53Smrg    Bool foundScreen = FALSE;
36050806d53Smrg
36150806d53Smrg    /*
36250806d53Smrg     * Check if there has been a chipset override in the config file.
36350806d53Smrg     * For this we must find out if there is an active device section which
36450806d53Smrg     * is relevant, i.e., which has no driver specified or has THIS driver
36550806d53Smrg     * specified.
36650806d53Smrg     */
36750806d53Smrg
36850806d53Smrg    if ((numDevSections = xf86MatchDevice(I128_DRIVER_NAME,
36950806d53Smrg					  &devSections)) <= 0) {
37050806d53Smrg	/*
37150806d53Smrg	 * There's no matching device section in the config file, so quit
37250806d53Smrg	 * now.
37350806d53Smrg	 */
37450806d53Smrg	return FALSE;
37550806d53Smrg    }
37650806d53Smrg
37750806d53Smrg    /*
37850806d53Smrg     * We need to probe the hardware first.  We then need to see how this
37950806d53Smrg     * fits in with what is given in the config file, and allow the config
38050806d53Smrg     * file info to override any contradictions.
38150806d53Smrg     */
38250806d53Smrg
38350806d53Smrg    /*
38450806d53Smrg     * All of the cards this driver supports are PCI, so the "probing" just
38550806d53Smrg     * amounts to checking the PCI data that the server has already collected.
38650806d53Smrg     */
3877965d9acSmrg#ifndef XSERVER_LIBPCIACCESS
38850806d53Smrg    if (xf86GetPciVideoInfo() == NULL) {
38950806d53Smrg	/*
39050806d53Smrg	 * We won't let anything in the config file override finding no
39150806d53Smrg	 * PCI video cards at all.  This seems reasonable now, but we'll see.
39250806d53Smrg	 */
39350806d53Smrg	return FALSE;
39450806d53Smrg    }
3957965d9acSmrg#endif
39650806d53Smrg
39750806d53Smrg    numUsed = xf86MatchPciInstances(I128_NAME, PCI_VENDOR_NUMNINE,
39850806d53Smrg			I128Chipsets, I128PciChipsets, devSections,
39950806d53Smrg			numDevSections, drv, &usedChips);
40050806d53Smrg
40150806d53Smrg    /* Free it since we don't need that list after this */
40250806d53Smrg    xfree(devSections);
40350806d53Smrg
40450806d53Smrg    if (numUsed <= 0)
40550806d53Smrg	return FALSE;
40650806d53Smrg
40750806d53Smrg    if (flags & PROBE_DETECT) {
40850806d53Smrg	xfree(usedChips);
40950806d53Smrg	return FALSE;
41050806d53Smrg    }
41150806d53Smrg
41250806d53Smrg    for (i = 0; i < numUsed; i++) {
41350806d53Smrg	ScrnInfoPtr pScrn = NULL;
41450806d53Smrg
41550806d53Smrg	/* Allocate a ScrnInfoRec and claim the slot */
41650806d53Smrg        if ((pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i],
41750806d53Smrg                                         I128PciChipsets, NULL, NULL,
41850806d53Smrg                                         NULL, NULL, NULL)) == NULL)
41950806d53Smrg		continue;
42050806d53Smrg
42150806d53Smrg
42250806d53Smrg	/* Fill in what we can of the ScrnInfoRec */
42350806d53Smrg	pScrn->driverVersion	= I128_VERSION;
42450806d53Smrg	pScrn->driverName	= I128_DRIVER_NAME;
42550806d53Smrg	pScrn->name		= I128_NAME;
42650806d53Smrg	pScrn->Probe		= I128Probe;
42750806d53Smrg	pScrn->PreInit		= I128PreInit;
42850806d53Smrg	pScrn->ScreenInit	= I128ScreenInit;
42950806d53Smrg	pScrn->SwitchMode	= I128SwitchMode;
43050806d53Smrg	pScrn->AdjustFrame	= I128AdjustFrame;
43150806d53Smrg	pScrn->EnterVT		= I128EnterVT;
43250806d53Smrg	pScrn->LeaveVT		= I128LeaveVT;
43350806d53Smrg	pScrn->FreeScreen	= I128FreeScreen;
43450806d53Smrg	pScrn->ValidMode	= I128ValidMode;
43550806d53Smrg	foundScreen = TRUE;
43650806d53Smrg    }
43750806d53Smrg
43850806d53Smrg    xfree(usedChips);
43950806d53Smrg
44050806d53Smrg    return foundScreen;
44150806d53Smrg}
44250806d53Smrg
44350806d53Smrg
44450806d53Smrg/* Mandatory
44550806d53Smrg *
44650806d53Smrg * The Identify() function is the third entry point called once that the
44750806d53Smrg * module has been linked into the server.  This function prints driver
44850806d53Smrg * identity information.
44950806d53Smrg *
45050806d53Smrg * Arguments:
45150806d53Smrg *		int flags     - currently unused
45250806d53Smrg * Returns:
45350806d53Smrg *		no return
45450806d53Smrg */
45550806d53Smrg
45650806d53Smrgstatic void
45750806d53SmrgI128Identify(int flags)
45850806d53Smrg{
45950806d53Smrg    xf86PrintChipsets(I128_NAME, "driver for Number Nine I128 chipsets",
46050806d53Smrg	I128Chipsets);
46150806d53Smrg}
46250806d53Smrg
46350806d53Smrg
46450806d53Smrg/*
46550806d53Smrg * Define options that this driver will accept.  Used by AvailableOptions().
46650806d53Smrg */
46750806d53Smrg
46850806d53Smrgtypedef enum {
46950806d53Smrg    OPTION_FLATPANEL,
47050806d53Smrg    OPTION_SW_CURSOR,
47150806d53Smrg    OPTION_HW_CURSOR,
47250806d53Smrg    OPTION_SYNC_ON_GREEN,
47350806d53Smrg    OPTION_NOACCEL,
47450806d53Smrg    OPTION_SHOWCACHE,
47550806d53Smrg    OPTION_DAC6BIT,
47650806d53Smrg    OPTION_DEBUG,
47750806d53Smrg    OPTION_ACCELMETHOD
47850806d53Smrg} I128Opts;
47950806d53Smrg
48050806d53Smrgstatic const OptionInfoRec I128Options[] = {
48150806d53Smrg    { OPTION_FLATPANEL,		"FlatPanel",	OPTV_BOOLEAN,	{0}, FALSE },
48250806d53Smrg    { OPTION_SW_CURSOR,		"SWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
48350806d53Smrg    { OPTION_HW_CURSOR,		"HWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
48450806d53Smrg    { OPTION_SYNC_ON_GREEN,	"SyncOnGreen",	OPTV_BOOLEAN,	{0}, FALSE },
48550806d53Smrg    { OPTION_NOACCEL,		"NoAccel",	OPTV_BOOLEAN,	{0}, FALSE },
48650806d53Smrg    { OPTION_SHOWCACHE,		"ShowCache",	OPTV_BOOLEAN,	{0}, FALSE },
48750806d53Smrg    { OPTION_DAC6BIT,		"Dac6Bit",	OPTV_BOOLEAN,	{0}, FALSE },
48850806d53Smrg    { OPTION_DEBUG,		"Debug",	OPTV_BOOLEAN,	{0}, FALSE },
48950806d53Smrg    { OPTION_ACCELMETHOD,       "AccelMethod",  OPTV_STRING,    {0}, FALSE },
49050806d53Smrg    { -1,			NULL,		OPTV_NONE,	{0}, FALSE }
49150806d53Smrg};
49250806d53Smrg
49350806d53Smrg
49450806d53Smrg/* Mandatory
49550806d53Smrg *
49650806d53Smrg * The AvailableOptions() function is called to provide the options that
49750806d53Smrg * this driver will accept.  This is used with the "-configure" server option.
49850806d53Smrg *
49950806d53Smrg * Arguments:
50050806d53Smrg *		int chipid  - currently unused
50150806d53Smrg *		int busid   - currently unused
50250806d53Smrg * Returns:
50350806d53Smrg *		const OptionInfoRec * - all accepted options
50450806d53Smrg */
50550806d53Smrg
50650806d53Smrgstatic const OptionInfoRec *
50750806d53SmrgI128AvailableOptions(int chipid, int busid)
50850806d53Smrg{
50950806d53Smrg    return I128Options;
51050806d53Smrg}
51150806d53Smrg
51250806d53Smrg
51350806d53Smrg/* Mandatory
51450806d53Smrg *
51550806d53Smrg * The PreInit() function called after the Probe() function once at
51650806d53Smrg * server startup and not at each server generation.  Only things that
51750806d53Smrg * are persistent across server generations can be initialized here.
51850806d53Smrg * This function determines if the configuration is usable and, if so,
51950806d53Smrg * initializes those parts of the ScrnInfoRec that can be set at the
52050806d53Smrg * beginning of the first server generation.  This should be done in
52150806d53Smrg * the least intrusive way possible.  Note that although the ScrnInfoRec
52250806d53Smrg * has been allocated, the ScreenRec has not.
52350806d53Smrg *
52450806d53Smrg * Use xf86AllocateScrnInfoPrivateIndex() for persistent data across
52550806d53Smrg * screen generations and AllocateScreenprivateIndex() in ScreenInit()
52650806d53Smrg * for per-generation data.
52750806d53Smrg *
52850806d53Smrg * Arguments:
52950806d53Smrg *		ScrnInfoPtr pScrn -
53050806d53Smrg *		int flags     - PROBE_DEFAULT for normal function
53150806d53Smrg *		                PROBE_DETECT for use with "-config" and "-probe"
53250806d53Smrg * Returns:
53350806d53Smrg *		Bool TRUE if ScrnInfoRec was initialized, FALSE otherwise
53450806d53Smrg */
53550806d53Smrg
53650806d53Smrgstatic Bool
53750806d53SmrgI128PreInit(ScrnInfoPtr pScrn, int flags)
53850806d53Smrg{
53950806d53Smrg    I128Ptr pI128;
54050806d53Smrg    vgaHWPtr hwp;
54150806d53Smrg    int i;
54250806d53Smrg    ClockRangePtr clockRanges;
54350806d53Smrg    MessageType from;
54450806d53Smrg    IOADDRESS iobase;
54550806d53Smrg    char *ramdac = NULL;
54650806d53Smrg    CARD32 tmpl, tmph, tmp;
54750806d53Smrg    unsigned char n, m, p, mdc, df;
54850806d53Smrg    float mclk;
54950806d53Smrg    xf86MonPtr mon;
55050806d53Smrg
55150806d53Smrg    /* Check the number of entities, and fail if it isn't one. */
55250806d53Smrg    if (pScrn->numEntities != 1)
55350806d53Smrg	return FALSE;
55450806d53Smrg
55550806d53Smrg    /* Allocate the I128Rec driverPrivate */
55650806d53Smrg    I128GetRec(pScrn);
55750806d53Smrg
55850806d53Smrg    pI128 = I128PTR(pScrn);
55950806d53Smrg
56050806d53Smrg    /* Get the entity, and make sure it is PCI. */
56150806d53Smrg    pI128->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
56250806d53Smrg    if (pI128->pEnt->location.type != BUS_PCI)
56350806d53Smrg	return FALSE;
56450806d53Smrg
56550806d53Smrg    if (flags & PROBE_DETECT) {
56650806d53Smrg	/* I128ProbeDDC(pScrn, pI128->pEnt->index); */
56750806d53Smrg	return TRUE;
56850806d53Smrg    }
56950806d53Smrg
57050806d53Smrg    /* Find the PCI info for this screen */
57150806d53Smrg    pI128->PciInfo = xf86GetPciInfoForEntity(pI128->pEnt->index);
5727965d9acSmrg#ifndef XSERVER_LIBPCIACCESS
57350806d53Smrg    pI128->PciTag = pciTag(pI128->PciInfo->bus, pI128->PciInfo->device,
57450806d53Smrg			  pI128->PciInfo->func);
5757965d9acSmrg#endif
57650806d53Smrg
57750806d53Smrg    pI128->Primary = xf86IsPrimaryPci(pI128->PciInfo);
57850806d53Smrg
57950806d53Smrg    /* The vgahw module should be allocated here when needed */
58050806d53Smrg    if (!xf86LoadSubModule(pScrn, "vgahw"))
58150806d53Smrg        return FALSE;
58250806d53Smrg
58350806d53Smrg    xf86LoaderReqSymLists(vgahwSymbols, NULL);
58450806d53Smrg
58550806d53Smrg    /*
58650806d53Smrg     * Allocate a vgaHWRec
58750806d53Smrg     */
58850806d53Smrg    if (!vgaHWGetHWRec(pScrn))
58950806d53Smrg        return FALSE;
59050806d53Smrg
59150806d53Smrg    hwp = VGAHWPTR(pScrn);
59250806d53Smrg    vgaHWGetIOBase(hwp);
59350806d53Smrg
59450806d53Smrg    /* Set pScrn->monitor */
59550806d53Smrg    pScrn->monitor = pScrn->confScreen->monitor;
59650806d53Smrg
59750806d53Smrg    /*
59850806d53Smrg     * The first thing we should figure out is the depth, bpp, etc.
59950806d53Smrg     * Our default depth is 8, so pass it to the helper function.
60050806d53Smrg     * We support both 24bpp and 32bpp layouts, so indicate that.
60150806d53Smrg     */
60250806d53Smrg
60350806d53Smrg    if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
60450806d53Smrg	return FALSE;
60550806d53Smrg    } else {
60650806d53Smrg	/* Check that the returned depth is one we support */
60750806d53Smrg	switch (pScrn->depth) {
60850806d53Smrg	case 8:
60950806d53Smrg	case 15:
61050806d53Smrg	case 16:
61150806d53Smrg	case 24:
61250806d53Smrg	    /* OK */
61350806d53Smrg	    break;
61450806d53Smrg	default:
61550806d53Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
61650806d53Smrg		       "Given depth (%d) is not supported by this driver\n",
61750806d53Smrg		       pScrn->depth);
61850806d53Smrg	    return FALSE;
61950806d53Smrg	}
62050806d53Smrg    }
62150806d53Smrg    xf86PrintDepthBpp(pScrn);
62250806d53Smrg
62350806d53Smrg    /*
62450806d53Smrg     * This must happen after pScrn->display has been set because
62550806d53Smrg     * xf86SetWeight references it.
62650806d53Smrg     */
62750806d53Smrg    if (pScrn->depth > 8) {
62850806d53Smrg	/* The defaults are OK for us */
62950806d53Smrg	rgb zeros = {0, 0, 0};
63050806d53Smrg
63150806d53Smrg	if (!xf86SetWeight(pScrn, zeros, zeros)) {
63250806d53Smrg	    return FALSE;
63350806d53Smrg	} else {
63450806d53Smrg	    /* XXX check that weight returned is supported */
63550806d53Smrg            ;
63650806d53Smrg        }
63750806d53Smrg    }
63850806d53Smrg
63950806d53Smrg    if (!xf86SetDefaultVisual(pScrn, -1)) {
64050806d53Smrg	return FALSE;
64150806d53Smrg    } else {
64250806d53Smrg	/* We don't currently support DirectColor at > 8bpp */
64350806d53Smrg	if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
64450806d53Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
64550806d53Smrg		       " (%s) is not supported at depth %d\n",
64650806d53Smrg		       xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
64750806d53Smrg	    return FALSE;
64850806d53Smrg	}
64950806d53Smrg    }
65050806d53Smrg
65150806d53Smrg    /* We use a programmable clock */
65250806d53Smrg    pScrn->progClock = TRUE;
65350806d53Smrg
65450806d53Smrg    /* Collect all of the relevant option flags (fill in pScrn->options) */
65550806d53Smrg    xf86CollectOptions(pScrn, NULL);
65650806d53Smrg
65750806d53Smrg    /* Process the options */
65850806d53Smrg    if (!(pI128->Options = xalloc(sizeof(I128Options))))
65950806d53Smrg	return FALSE;
66050806d53Smrg    memcpy(pI128->Options, I128Options, sizeof(I128Options));
66150806d53Smrg    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI128->Options);
66250806d53Smrg
66350806d53Smrg    if (pScrn->depth == 8)
66450806d53Smrg	pScrn->rgbBits = 8;
66550806d53Smrg
66650806d53Smrg    /*
66750806d53Smrg     * The preferred method is to use the "hw cursor" option as a tri-state
66850806d53Smrg     * option, with the default set above.
66950806d53Smrg     */
67050806d53Smrg    from = X_DEFAULT;
67150806d53Smrg    pI128->HWCursor = TRUE;
67250806d53Smrg    if (xf86GetOptValBool(pI128->Options, OPTION_HW_CURSOR, &pI128->HWCursor)) {
67350806d53Smrg	from = X_CONFIG;
67450806d53Smrg    }
67550806d53Smrg    /* For compatibility, accept this too (as an override) */
67650806d53Smrg    if (xf86ReturnOptValBool(pI128->Options, OPTION_SW_CURSOR, FALSE)) {
67750806d53Smrg	from = X_CONFIG;
67850806d53Smrg	pI128->HWCursor = FALSE;
67950806d53Smrg    }
68050806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
68150806d53Smrg		pI128->HWCursor ? "HW" : "SW");
68250806d53Smrg    if (xf86ReturnOptValBool(pI128->Options, OPTION_NOACCEL, FALSE)) {
68350806d53Smrg	pI128->NoAccel = TRUE;
68450806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
68550806d53Smrg    } else {
68650806d53Smrg        int from = X_DEFAULT;
68750806d53Smrg        char *s = xf86GetOptValString(pI128->Options, OPTION_ACCELMETHOD);
68850806d53Smrg        pI128->NoAccel = FALSE;
68950806d53Smrg        if (!xf86NameCmp(s, "EXA")) {
69050806d53Smrg            pI128->exa = TRUE;
69150806d53Smrg            from = X_CONFIG;
69250806d53Smrg        }
69350806d53Smrg        xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration\n",
69450806d53Smrg                   pI128->exa ? "EXA" : "XAA");
69550806d53Smrg    }
69650806d53Smrg    if (xf86ReturnOptValBool(pI128->Options, OPTION_SYNC_ON_GREEN, FALSE)) {
69750806d53Smrg	pI128->DACSyncOnGreen = TRUE;
69850806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n");
69950806d53Smrg    } else pI128->DACSyncOnGreen = FALSE;
70050806d53Smrg    if (xf86ReturnOptValBool(pI128->Options, OPTION_SHOWCACHE, FALSE)) {
70150806d53Smrg	pI128->ShowCache = TRUE;
70250806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n");
70350806d53Smrg    } else pI128->ShowCache = FALSE;
70450806d53Smrg    if (xf86ReturnOptValBool(pI128->Options, OPTION_DAC6BIT, FALSE)) {
70550806d53Smrg	pI128->DAC8Bit = FALSE;
70650806d53Smrg	pScrn->rgbBits = 6;
70750806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Dac6Bit enabled\n");
70850806d53Smrg    } else pI128->DAC8Bit = TRUE;
70950806d53Smrg    if (xf86ReturnOptValBool(pI128->Options, OPTION_DEBUG, FALSE)) {
71050806d53Smrg	pI128->Debug = TRUE;
71150806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Debug enabled\n");
71250806d53Smrg    } else pI128->Debug = FALSE;
71350806d53Smrg    if (xf86ReturnOptValBool(pI128->Options, OPTION_FLATPANEL, FALSE)) {
71450806d53Smrg	pI128->FlatPanel = TRUE;
71550806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "FlatPanel forced\n");
71650806d53Smrg    } else pI128->FlatPanel = FALSE;
71750806d53Smrg
71850806d53Smrg    /*
71950806d53Smrg     * Set the Chipset and ChipRev.
72050806d53Smrg     */
72150806d53Smrg    from = X_PROBED;
7227965d9acSmrg    pI128->Chipset = PCI_DEV_DEVICE_ID(pI128->PciInfo);
72350806d53Smrg    pScrn->chipset = (char *)xf86TokenToString(I128Chipsets, pI128->Chipset);
7247965d9acSmrg    pI128->ChipRev = PCI_DEV_REVISION(pI128->PciInfo);
72550806d53Smrg
72650806d53Smrg    /*
72750806d53Smrg     * This shouldn't happen because such problems should be caught in
72850806d53Smrg     * I128Probe(), but check it just in case.
72950806d53Smrg     */
73050806d53Smrg    if (pScrn->chipset == NULL) {
73150806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
73250806d53Smrg		   "ChipID 0x%04X is not recognised\n", pI128->Chipset);
73350806d53Smrg	return FALSE;
73450806d53Smrg    }
73550806d53Smrg    if (pI128->Chipset < 0) {
73650806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
73750806d53Smrg		   "Chipset \"%s\" is not recognised\n", pScrn->chipset);
73850806d53Smrg	return FALSE;
73950806d53Smrg    }
74050806d53Smrg
74150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
7427965d9acSmrg    if (PCI_SUB_VENDOR_ID(pI128->PciInfo) == 0x105D)
74350806d53Smrg        xf86DrvMsg(pScrn->scrnIndex, from, "Subsystem Vendor: \"Number Nine\"\n");
7447965d9acSmrg    else if (PCI_SUB_VENDOR_ID(pI128->PciInfo) == 0x10F0)
74550806d53Smrg        xf86DrvMsg(pScrn->scrnIndex, from, "Subsystem Vendor: \"Peritek\"\n");
74650806d53Smrg    else
74750806d53Smrg        xf86DrvMsg(pScrn->scrnIndex, from, "Subsystem Vendor: \"%x\"\n",
7487965d9acSmrg    	    PCI_SUB_VENDOR_ID(pI128->PciInfo));
74950806d53Smrg
7507965d9acSmrg    iobase = (PCI_REGION_BASE(pI128->PciInfo, 5, REGION_IO) & 0xFFFFFF00) + hwp->PIOOffset;
75150806d53Smrg    pI128->RegRec.iobase = iobase;
75250806d53Smrg
75350806d53Smrg    pI128->io.rbase_g = inl(iobase)        & 0xFFFFFF00;
75450806d53Smrg    pI128->io.rbase_w = inl(iobase + 0x04) & 0xFFFFFF00;
75550806d53Smrg    pI128->io.rbase_a = inl(iobase + 0x08) & 0xFFFFFF00;
75650806d53Smrg    pI128->io.rbase_b = inl(iobase + 0x0C) & 0xFFFFFF00;
75750806d53Smrg    pI128->io.rbase_i = inl(iobase + 0x10) & 0xFFFFFF00;
75850806d53Smrg    pI128->io.rbase_e = inl(iobase + 0x14) & 0xFFFF8003;
75950806d53Smrg    pI128->io.id =      inl(iobase + 0x18) & /* 0x7FFFFFFF */ 0xFFFFFFFF;
76050806d53Smrg    pI128->io.config1 = inl(iobase + 0x1C) & /* 0xF3333F1F */ 0xFF133706;
76150806d53Smrg    pI128->io.config2 = inl(iobase + 0x20) & 0xC1F70FFF;
76250806d53Smrg    pI128->io.sgram   = inl(iobase + 0x24) & 0xFFFFFFFF;
76350806d53Smrg    pI128->io.soft_sw = inl(iobase + 0x28) & 0x0000FFFF;
76450806d53Smrg    pI128->io.vga_ctl = inl(iobase + 0x30) & 0x0000FFFF;
76550806d53Smrg
76650806d53Smrg    if (pI128->Debug)
76750806d53Smrg	I128DumpBaseRegisters(pScrn);
76850806d53Smrg
76950806d53Smrg    pI128->RegRec.config1 = pI128->io.config1;
77050806d53Smrg    pI128->RegRec.config2 = pI128->io.config2;
77150806d53Smrg    pI128->RegRec.sgram = pI128->io.sgram;
77250806d53Smrg    if (pI128->Chipset == PCI_CHIP_I128_T2R4)
77350806d53Smrg	pI128->io.sgram = 0x211BF030;
77450806d53Smrg    else
77550806d53Smrg	pI128->io.sgram = 0x21089030;
77650806d53Smrg    /* vga_ctl is saved later */
77750806d53Smrg
77850806d53Smrg    /* enable all of the memory mapped windows */
77950806d53Smrg
78050806d53Smrg    pI128->io.config1 &= 0x3300001F;
78150806d53Smrg    pI128->io.config1 |= 0x00331F10;
78250806d53Smrg    outl(iobase + 0x1C, pI128->io.config1);
78350806d53Smrg
78450806d53Smrg    pI128->MemoryType = I128_MEMORY_UNKNOWN;
78550806d53Smrg
78650806d53Smrg    if (pI128->Chipset == PCI_CHIP_I128_T2R4)
78750806d53Smrg	pI128->MemoryType = I128_MEMORY_SGRAM;
78850806d53Smrg    else if (pI128->Chipset == PCI_CHIP_I128_T2R) {
78950806d53Smrg	if ((pI128->io.config2&6) == 2)
79050806d53Smrg		pI128->MemoryType = I128_MEMORY_SGRAM;
79150806d53Smrg	else
79250806d53Smrg		pI128->MemoryType = I128_MEMORY_WRAM;
79350806d53Smrg    } else if (pI128->Chipset == PCI_CHIP_I128_2) {
7947965d9acSmrg#ifndef XSERVER_LIBPCIACCESS
79550806d53Smrg   	if (((((pciConfigPtr)pI128->PciInfo->thisCard)->pci_command & 0x03)
7967965d9acSmrg	    == 0x03) && (PCI_SUB_DEVICE_ID(pI128->PciInfo) == 0x08))
79750806d53Smrg   	   pI128->MemoryType = I128_MEMORY_DRAM;
7987965d9acSmrg#else
7997965d9acSmrg	{
8007965d9acSmrg	    unsigned short temp;
8017965d9acSmrg	    pci_device_cfg_read_u16(pI128->PciInfo, &temp, 0x4);
8027965d9acSmrg	    if (((temp & 0x03) == 0x03) && (PCI_SUB_DEVICE_ID(pI128->PciInfo) == 0x08))
8037965d9acSmrg		pI128->MemoryType = I128_MEMORY_DRAM;
8047965d9acSmrg	}
8057965d9acSmrg#endif
80650806d53Smrg    }
80750806d53Smrg
80850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory type %s\n",
80950806d53Smrg	pI128->MemoryType == I128_MEMORY_SGRAM ? "SGRAM" :
81050806d53Smrg	pI128->MemoryType == I128_MEMORY_DRAM ? "DRAM" :
81150806d53Smrg	pI128->MemoryType == I128_MEMORY_WRAM ? "WRAM" : "UNKNOWN");
81250806d53Smrg
81350806d53Smrg    pI128->io.config2 &= 0xFF0FFF7F;
81450806d53Smrg    pI128->io.config2 |= 0x00100000;
81550806d53Smrg    if (pI128->MemoryType != I128_MEMORY_SGRAM)
81650806d53Smrg   	pI128->io.config2 |= 0x00400000;
81750806d53Smrg    outl(pI128->RegRec.iobase + 0x20, pI128->io.config2);
81850806d53Smrg
81950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Linear framebuffer at 0x%lX\n",
8207965d9acSmrg	       (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 0, REGION_MEM));
82150806d53Smrg
82250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MMIO registers at 0x%lX\n",
8237965d9acSmrg	       (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 5, REGION_IO));
82450806d53Smrg
82550806d53Smrg    if (xf86RegisterResources(pI128->pEnt->index, NULL, ResExclusive)) {
82650806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
82750806d53Smrg		"xf86RegisterResources() found resource conflicts\n");
82850806d53Smrg	I128FreeRec(pScrn);
82950806d53Smrg	return FALSE;
83050806d53Smrg    }
83150806d53Smrg
83250806d53Smrg    /* HW bpp matches reported bpp */
83350806d53Smrg    pI128->bitsPerPixel = pScrn->bitsPerPixel;
83450806d53Smrg    pI128->depth = pScrn->depth;
83550806d53Smrg    pI128->weight.red =  pScrn->weight.red;
83650806d53Smrg    pI128->weight.green =  pScrn->weight.green;
83750806d53Smrg    pI128->weight.blue =  pScrn->weight.blue;
83850806d53Smrg    pI128->mode = pScrn->modes;
83950806d53Smrg
84050806d53Smrg    pScrn->videoRam = I128CountRam(pScrn);
84150806d53Smrg    pI128->MemorySize = pScrn->videoRam;
84250806d53Smrg
84350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n",
84450806d53Smrg               pScrn->videoRam);
84550806d53Smrg
84650806d53Smrg
84750806d53Smrg    /*
84850806d53Smrg     * If the driver can do gamma correction, it should call xf86SetGamma()
84950806d53Smrg     * here.
85050806d53Smrg     */
85150806d53Smrg
85250806d53Smrg    {
85350806d53Smrg	Gamma zeros = {0.0, 0.0, 0.0};
85450806d53Smrg
85550806d53Smrg	if (!xf86SetGamma(pScrn, zeros)) {
85650806d53Smrg	    return FALSE;
85750806d53Smrg	}
85850806d53Smrg    }
85950806d53Smrg
86050806d53Smrg    if (!I128MapMem(pScrn))
86150806d53Smrg	return FALSE;
86250806d53Smrg
86350806d53Smrg    /*
86450806d53Smrg     * Reset card if it isn't primary one (must be done after config1 is set)
86550806d53Smrg     */
86650806d53Smrg    if (!pI128->Primary)
86750806d53Smrg        I128SoftReset(pScrn);
86850806d53Smrg
86950806d53Smrg    if (pI128->Chipset != PCI_CHIP_I128) {
87050806d53Smrg	pI128->ddc1Read = NULL /*I128DDC1Read*/;
87150806d53Smrg	pI128->i2cInit = I128I2CInit;
87250806d53Smrg    }
87350806d53Smrg
87450806d53Smrg    /* Load DDC if we have the code to use it */
87550806d53Smrg    /* This gives us DDC1 */
87650806d53Smrg    if (pI128->ddc1Read || pI128->i2cInit) {
87750806d53Smrg        if (xf86LoadSubModule(pScrn, "ddc")) {
87850806d53Smrg          xf86LoaderReqSymLists(ddcSymbols, NULL);
87950806d53Smrg        } else {
88050806d53Smrg          /* ddc module not found, we can do without it */
88150806d53Smrg          pI128->ddc1Read = NULL;
88250806d53Smrg
88350806d53Smrg          /* Without DDC, we have no use for the I2C bus */
88450806d53Smrg          pI128->i2cInit = NULL;
88550806d53Smrg        }
88650806d53Smrg    }
88750806d53Smrg    /* - DDC can use I2C bus */
88850806d53Smrg    /* Load I2C if we have the code to use it */
88950806d53Smrg    if (pI128->i2cInit) {
89050806d53Smrg      if ( xf86LoadSubModule(pScrn, "i2c") ) {
89150806d53Smrg        xf86LoaderReqSymLists(i2cSymbols,NULL);
89250806d53Smrg      } else {
89350806d53Smrg        /* i2c module not found, we can do without it */
89450806d53Smrg        pI128->i2cInit = NULL;
89550806d53Smrg        pI128->I2C = NULL;
89650806d53Smrg      }
89750806d53Smrg    }
89850806d53Smrg
89950806d53Smrg    /* Read and print the Monitor DDC info */
90050806d53Smrg    mon = I128getDDC(pScrn);
90150806d53Smrg
90250806d53Smrg    /* see if we can find a flatpanel */
90350806d53Smrg    if (!pI128->FlatPanel && mon) {
90450806d53Smrg        for (i=0; i<4; i++)
90550806d53Smrg    	    if (mon->det_mon[i].type == DS_NAME) {
90650806d53Smrg		if (strncmp((char *)mon->det_mon[i].section.name,
90750806d53Smrg			    "SGI 1600SW FP", 13) == 0) {
90850806d53Smrg			pI128->FlatPanel = TRUE;
90950806d53Smrg    			xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
91050806d53Smrg				"Found FlatPanel via DDC2\n");
91150806d53Smrg		}
91250806d53Smrg		break;
91350806d53Smrg	    }
91450806d53Smrg    }
91550806d53Smrg
91650806d53Smrg    pI128->maxClock = 175000;
91750806d53Smrg
91850806d53Smrg    switch (pI128->Chipset) {
91950806d53Smrg    	case PCI_CHIP_I128:
92050806d53Smrg	    if (pI128->io.id & 0x0400)       /* 2 banks VRAM   */
92150806d53Smrg		pI128->RamdacType = IBM528_DAC;
92250806d53Smrg	    else
92350806d53Smrg		pI128->RamdacType = TI3025_DAC;
92450806d53Smrg	    break;
92550806d53Smrg    	case PCI_CHIP_I128_2:
92650806d53Smrg	    if (pI128->io.id & 0x0400)       /* 2 banks VRAM   */
92750806d53Smrg		pI128->RamdacType = IBM528_DAC;
92850806d53Smrg	    else
92950806d53Smrg		pI128->RamdacType = IBM526_DAC;
93050806d53Smrg	    pI128->maxClock = 220000;
93150806d53Smrg	    break;
93250806d53Smrg    	case PCI_CHIP_I128_T2R:
93350806d53Smrg	    pI128->RamdacType = IBM526_DAC;
93450806d53Smrg	    pI128->maxClock = 220000;
93550806d53Smrg	    break;
93650806d53Smrg    	case PCI_CHIP_I128_T2R4:
93750806d53Smrg	    pI128->RamdacType = SILVER_HAMMER_DAC;
93850806d53Smrg	    pI128->maxClock = 270000;
93950806d53Smrg	    break;
94050806d53Smrg	default:
94150806d53Smrg    	    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
94250806d53Smrg			"Unknown I128 chipset: %d\n",
94350806d53Smrg               		pI128->Chipset);
94450806d53Smrg            return(FALSE);
94550806d53Smrg    }
94650806d53Smrg
94750806d53Smrg    if ((pI128->maxClock == 175000) && (pI128->MemorySize == 8192))
94850806d53Smrg	pI128->maxClock = 220000;
94950806d53Smrg
95050806d53Smrg    switch(pI128->RamdacType) {
95150806d53Smrg       case TI3025_DAC:
95250806d53Smrg          /* verify that the ramdac is a TVP3025 */
95350806d53Smrg
95450806d53Smrg          pI128->mem.rbase_g[INDEX_TI] = TI_ID;				MB;
95550806d53Smrg          if ((pI128->mem.rbase_g[DATA_TI]&0xFF) != TI_VIEWPOINT25_ID) {
95650806d53Smrg    	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
95750806d53Smrg			"Ti3025 Ramdac not found\n");
95850806d53Smrg             return(FALSE);
95950806d53Smrg          }
96050806d53Smrg          ramdac = "TI3025";
96150806d53Smrg
96250806d53Smrg          pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
96350806d53Smrg          pI128->mem.rbase_g[DATA_TI] = 0x00;				MB;
96450806d53Smrg          pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA;		MB;
96550806d53Smrg          n = pI128->mem.rbase_g[DATA_TI]&0x7f;
96650806d53Smrg          pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
96750806d53Smrg          pI128->mem.rbase_g[DATA_TI] = 0x01;				MB;
96850806d53Smrg          pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA;		MB;
96950806d53Smrg          m = pI128->mem.rbase_g[DATA_TI]&0x7f;
97050806d53Smrg          pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
97150806d53Smrg          pI128->mem.rbase_g[DATA_TI] = 0x02;				MB;
97250806d53Smrg          pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA;		MB;
97350806d53Smrg          p = pI128->mem.rbase_g[DATA_TI]&0x03;
97450806d53Smrg          pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_DCLK_CONTROL;		MB;
97550806d53Smrg          mdc = pI128->mem.rbase_g[DATA_TI]&0xFF;
97650806d53Smrg          if (mdc&0x08)
97750806d53Smrg	    mdc = (mdc&0x07)*2 + 2;
97850806d53Smrg          else
97950806d53Smrg	    mdc = 1;
98050806d53Smrg          mclk = ((1431818 * ((m+2) * 8)) / (n+2) / (1 << p) / mdc + 50) / 100;
98150806d53Smrg
98250806d53Smrg    	  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
98350806d53Smrg			"Using TI 3025 programmable clock (MCLK %1.3f MHz)\n",
98450806d53Smrg			mclk / 1000.0);
98550806d53Smrg	  pI128->minClock = 20000;
98650806d53Smrg	  pI128->ProgramDAC = I128ProgramTi3025;
98750806d53Smrg	  break;
98850806d53Smrg
98950806d53Smrg       case IBM524_DAC:
99050806d53Smrg    	  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
99150806d53Smrg			"IBM524 Ramdac not supported\n");
99250806d53Smrg          return(FALSE);
99350806d53Smrg
99450806d53Smrg       case IBM526_DAC:
99550806d53Smrg          /* verify that the ramdac is an IBM526 */
99650806d53Smrg
99750806d53Smrg          ramdac = "IBM526";
99850806d53Smrg	  tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
99950806d53Smrg	  tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
100050806d53Smrg          pI128->mem.rbase_g[IDXH_I] = 0;				MB;
100150806d53Smrg          pI128->mem.rbase_g[IDXL_I] = IBMRGB_id;			MB;
100250806d53Smrg	  tmp = pI128->mem.rbase_g[DATA_I] & 0xFF;
100350806d53Smrg
100450806d53Smrg          pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div;		MB;
100550806d53Smrg	  n = pI128->mem.rbase_g[DATA_I] & 0x1f;
100650806d53Smrg          pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div;		MB;
100750806d53Smrg	  m = pI128->mem.rbase_g[DATA_I];
100850806d53Smrg	  df = m>>6;
100950806d53Smrg	  m &= 0x3f;
101050806d53Smrg	  if (n == 0) { m=0; n=1; }
101150806d53Smrg	  mclk = ((2517500 * (m+65)) / n / (8>>df) + 50) / 100;
101250806d53Smrg
101350806d53Smrg	  pI128->mem.rbase_g[IDXL_I] = tmpl;				MB;
101450806d53Smrg	  pI128->mem.rbase_g[IDXH_I] = tmph;				MB;
101550806d53Smrg          if (tmp != 2) {
101650806d53Smrg    	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
101750806d53Smrg			"IBM526 Ramdac not found\n");
101850806d53Smrg             return(FALSE);
101950806d53Smrg          }
102050806d53Smrg
102150806d53Smrg    	  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
102250806d53Smrg			"Using IBM 526 programmable clock (MCLK %1.3f MHz)\n",
102350806d53Smrg			mclk / 1000.0);
102450806d53Smrg	  pI128->minClock = 25000;
102550806d53Smrg	  pI128->ProgramDAC = I128ProgramIBMRGB;
102650806d53Smrg          break;
102750806d53Smrg
102850806d53Smrg       case IBM528_DAC:
102950806d53Smrg          /* verify that the ramdac is an IBM528 */
103050806d53Smrg
103150806d53Smrg          ramdac = "IBM528";
103250806d53Smrg	  tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
103350806d53Smrg	  tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
103450806d53Smrg          pI128->mem.rbase_g[IDXH_I] = 0;				MB;
103550806d53Smrg          pI128->mem.rbase_g[IDXL_I] = IBMRGB_id;			MB;
103650806d53Smrg	  tmp = pI128->mem.rbase_g[DATA_I] & 0xFF;
103750806d53Smrg
103850806d53Smrg          pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div;		MB;
103950806d53Smrg	  n = pI128->mem.rbase_g[DATA_I] & 0x1f;
104050806d53Smrg          pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div;		MB;
104150806d53Smrg	  m = pI128->mem.rbase_g[DATA_I] & 0xFF;
104250806d53Smrg	  df = m>>6;
104350806d53Smrg	  m &= 0x3f;
104450806d53Smrg	  if (n == 0) { m=0; n=1; }
104550806d53Smrg	  mclk = ((2517500 * (m+65)) / n / (8>>df) + 50) / 100;
104650806d53Smrg
104750806d53Smrg	  pI128->mem.rbase_g[IDXL_I] = tmpl;				MB;
104850806d53Smrg	  pI128->mem.rbase_g[IDXH_I] = tmph;				MB;
104950806d53Smrg          if (tmp != 2) {
105050806d53Smrg    	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
105150806d53Smrg			"IBM528 Ramdac not found\n");
105250806d53Smrg             return(FALSE);
105350806d53Smrg          }
105450806d53Smrg
105550806d53Smrg    	  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
105650806d53Smrg			"Using IBM 528 programmable clock (MCLK %1.3f MHz)\n",
105750806d53Smrg			mclk / 1000.0);
105850806d53Smrg	  pI128->minClock = 25000;
105950806d53Smrg	  pI128->ProgramDAC = I128ProgramIBMRGB;
106050806d53Smrg          break;
106150806d53Smrg
106250806d53Smrg       case SILVER_HAMMER_DAC:
106350806d53Smrg          /* verify that the ramdac is a Silver Hammer */
106450806d53Smrg
106550806d53Smrg          ramdac = "SilverHammer";
106650806d53Smrg	  tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
106750806d53Smrg	  tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
106850806d53Smrg	  tmp = pI128->mem.rbase_g[DATA_I] & 0xFF;
106950806d53Smrg
107050806d53Smrg          pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div;		MB;
107150806d53Smrg	  n = pI128->mem.rbase_g[DATA_I] & 0x1f;
107250806d53Smrg          pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div;		MB;
107350806d53Smrg	  m = pI128->mem.rbase_g[DATA_I];
107450806d53Smrg	  df = m>>6;
107550806d53Smrg	  m &= 0x3f;
107650806d53Smrg	  if (n == 0) { m=0; n=1; }
107750806d53Smrg	  mclk = ((3750000 * (m+65)) / n / (8>>df) + 50) / 100;
107850806d53Smrg
107950806d53Smrg	  pI128->mem.rbase_g[IDXL_I] = tmpl;				MB;
108050806d53Smrg	  pI128->mem.rbase_g[IDXH_I] = tmph;				MB;
108150806d53Smrg          if (pI128->Chipset != PCI_CHIP_I128_T2R4) {
108250806d53Smrg    	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
108350806d53Smrg			"SilverHammer Ramdac not found\n");
108450806d53Smrg             return(FALSE);
108550806d53Smrg          }
108650806d53Smrg
108750806d53Smrg	  if (pI128->mem.rbase_g[CRT_1CON] & 0x00000100) {
108850806d53Smrg             pI128->FlatPanel = TRUE;
108950806d53Smrg    	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
109050806d53Smrg			"Digital flat panel detected\n");
109150806d53Smrg          } else if (pI128->FlatPanel)
109250806d53Smrg    	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
109350806d53Smrg			"Digital flat panel forced\n");
109450806d53Smrg
109550806d53Smrg    	  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
109650806d53Smrg			"Using SilverHammer programmable clock (MCLK %1.3f MHz)\n",
109750806d53Smrg			mclk / 1000.0);
109850806d53Smrg	  pI128->minClock = 25000;
109950806d53Smrg	  pI128->ProgramDAC = I128ProgramSilverHammer;
110050806d53Smrg          break;
110150806d53Smrg
110250806d53Smrg       default:
110350806d53Smrg    	 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
110450806d53Smrg		"Ramdac Unknown\n");
110550806d53Smrg          return(FALSE);
110650806d53Smrg     }
110750806d53Smrg
110850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
110950806d53Smrg		"Ramdac Type min/max speed: %s %d/%d MHz\n",
111050806d53Smrg		ramdac, pI128->minClock/1000, pI128->maxClock/1000);
111150806d53Smrg
111250806d53Smrg    /*
111350806d53Smrg     * Setup the ClockRanges, which describe what clock ranges are available,
111450806d53Smrg     * and what sort of modes they can be used for.
111550806d53Smrg     */
111650806d53Smrg    clockRanges = xnfcalloc(sizeof(ClockRange),1);
111750806d53Smrg    clockRanges->next = NULL;
111850806d53Smrg    clockRanges->minClock = pI128->minClock;
111950806d53Smrg    clockRanges->maxClock = pI128->maxClock;
112050806d53Smrg    clockRanges->clockIndex = -1;		/* programmable */
112150806d53Smrg    clockRanges->interlaceAllowed = TRUE;
112250806d53Smrg    clockRanges->doubleScanAllowed = TRUE;
112350806d53Smrg    clockRanges->ClockMulFactor = 1;
112450806d53Smrg    clockRanges->ClockDivFactor = 1;
112550806d53Smrg
112650806d53Smrg    /*
112750806d53Smrg     * xf86ValidateModes will check that the mode HTotal and VTotal values
112850806d53Smrg     * don't exceed the chipset's limit if pScrn->maxHValue and
112950806d53Smrg     * pScrn->maxVValue are set.  Since our I128ValidMode() already takes
113050806d53Smrg     * care of this, we don't worry about setting them here.
113150806d53Smrg     */
113250806d53Smrg    {
113350806d53Smrg	int *linePitches = NULL;
113450806d53Smrg	int minPitch = 256;
113550806d53Smrg	int maxPitch = 2048;
113650806d53Smrg	int pitchAlignment = 256;
113750806d53Smrg
113850806d53Smrg	if (pI128->MemoryType == I128_MEMORY_WRAM)
113950806d53Smrg	   pitchAlignment = (128 * 8);
114050806d53Smrg	pitchAlignment /= pI128->bitsPerPixel;
114150806d53Smrg
114250806d53Smrg	i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
114350806d53Smrg			      pScrn->display->modes, clockRanges,
114450806d53Smrg			      linePitches, minPitch, maxPitch,
114550806d53Smrg			      pitchAlignment * pI128->bitsPerPixel,
114650806d53Smrg			      128, 2048,
114750806d53Smrg			      pScrn->display->virtualX,
114850806d53Smrg			      pScrn->display->virtualY,
114950806d53Smrg			      pI128->MemorySize,
115050806d53Smrg			      LOOKUP_BEST_REFRESH);
115150806d53Smrg
115250806d53Smrg	pI128->displayWidth = pScrn->virtualX;
115350806d53Smrg
115450806d53Smrg	if ((pScrn->virtualX % pitchAlignment) != 0)
115550806d53Smrg	   pI128->displayWidth += pitchAlignment -
115650806d53Smrg				  (pScrn->virtualX % pitchAlignment);
115750806d53Smrg    }
115850806d53Smrg
115950806d53Smrg    if (i == -1) {
116050806d53Smrg	I128FreeRec(pScrn);
116150806d53Smrg	return FALSE;
116250806d53Smrg    }
116350806d53Smrg
116450806d53Smrg    /* Prune the modes marked as invalid */
116550806d53Smrg    xf86PruneDriverModes(pScrn);
116650806d53Smrg
116750806d53Smrg    if (i == 0 || pScrn->modes == NULL) {
116850806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
116950806d53Smrg	I128FreeRec(pScrn);
117050806d53Smrg	return FALSE;
117150806d53Smrg    }
117250806d53Smrg
117350806d53Smrg    if ((pI128->MemorySize > 4096) &&
117450806d53Smrg        (pI128->MemoryType != I128_MEMORY_DRAM) &&
117550806d53Smrg        (pI128->MemoryType != I128_MEMORY_SGRAM))
117650806d53Smrg        pI128->displayOffset = 0x400000L %
117750806d53Smrg		          (pI128->displayWidth * (pI128->bitsPerPixel/8));
117850806d53Smrg    else
117950806d53Smrg        pI128->displayOffset = 0;
118050806d53Smrg
118150806d53Smrg    pI128->MemoryPtr =
118250806d53Smrg	    (pointer)&((char *)pI128->MemoryPtr)[pI128->displayOffset];
118350806d53Smrg
118450806d53Smrg    /* Set the current mode to the first in the list */
118550806d53Smrg    pScrn->currentMode = pScrn->modes;
118650806d53Smrg
118750806d53Smrg    /* Print the list of modes being used */
118850806d53Smrg    xf86PrintModes(pScrn);
118950806d53Smrg
119050806d53Smrg    /* Set display resolution */
119150806d53Smrg    xf86SetDpi(pScrn, 0, 0);
119250806d53Smrg
119350806d53Smrg    if (!xf86LoadSubModule(pScrn, "fb")) {
119450806d53Smrg	I128FreeRec(pScrn);
119550806d53Smrg	return FALSE;
119650806d53Smrg    }
119750806d53Smrg    xf86LoaderReqSymLists(fbSymbols, NULL);
119850806d53Smrg
119950806d53Smrg    /* Load the acceleration engine */
120050806d53Smrg    if (!pI128->NoAccel) {
120150806d53Smrg	if (pI128->exa) {
120250806d53Smrg	    XF86ModReqInfo req;
120350806d53Smrg	    int errmaj, errmin;
120450806d53Smrg
120550806d53Smrg	    memset(&req, 0, sizeof(req));
120650806d53Smrg	    req.majorversion = 2;
120750806d53Smrg	    req.minorversion = 0;
120850806d53Smrg            if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
120950806d53Smrg		&errmaj, &errmin))
121050806d53Smrg	    {
121150806d53Smrg		LoaderErrorMsg(NULL, "exa", errmaj, errmin);
121250806d53Smrg                I128FreeRec(pScrn);
121350806d53Smrg                return FALSE;
121450806d53Smrg            } else xf86LoaderReqSymLists(exaSymbols, NULL);
121550806d53Smrg        } else {
121650806d53Smrg            if (!xf86LoadSubModule(pScrn, "xaa")) {
121750806d53Smrg	        I128FreeRec(pScrn);
121850806d53Smrg	        return FALSE;
121950806d53Smrg	    } else xf86LoaderReqSymLists(xaaSymbols, NULL);
122050806d53Smrg        }
122150806d53Smrg    }
122250806d53Smrg
122350806d53Smrg    /* Load ramdac if needed */
122450806d53Smrg    if (pI128->HWCursor) {
122550806d53Smrg	if (!xf86LoadSubModule(pScrn, "ramdac")) {
122650806d53Smrg	    I128FreeRec(pScrn);
122750806d53Smrg	    return FALSE;
122850806d53Smrg	}
122950806d53Smrg	xf86LoaderReqSymLists(ramdacSymbols, NULL);
123050806d53Smrg    }
123150806d53Smrg
123250806d53Smrg    I128UnmapMem(pScrn);
123350806d53Smrg
123450806d53Smrg    if (pI128->Debug)
123550806d53Smrg    	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PreInit complete\n");
123650806d53Smrg    return TRUE;
123750806d53Smrg}
123850806d53Smrg
123950806d53Smrg
124050806d53Smrgstatic Bool
124150806d53SmrgI128GetRec(ScrnInfoPtr pScrn)
124250806d53Smrg{
124350806d53Smrg    /*
124450806d53Smrg     * Allocate an I128Rec, and hook it into pScrn->driverPrivate.
124550806d53Smrg     * pScrn->driverPrivate is initialised to NULL, so we can check if
124650806d53Smrg     * the allocation has already been done.
124750806d53Smrg     */
124850806d53Smrg    if (pScrn->driverPrivate != NULL)
124950806d53Smrg	return TRUE;
125050806d53Smrg
125150806d53Smrg    pScrn->driverPrivate = xnfcalloc(sizeof(I128Rec), 1);
125250806d53Smrg
125350806d53Smrg    return TRUE;
125450806d53Smrg}
125550806d53Smrg
125650806d53Smrgstatic void
125750806d53SmrgI128FreeRec(ScrnInfoPtr pScrn)
125850806d53Smrg{
125950806d53Smrg    if (pScrn->driverPrivate == NULL)
126050806d53Smrg	return;
126150806d53Smrg    xfree(pScrn->driverPrivate);
126250806d53Smrg    pScrn->driverPrivate = NULL;
126350806d53Smrg}
126450806d53Smrg
126550806d53Smrg
126650806d53Smrg
126750806d53Smrg/*
126850806d53Smrg * I128SoftReset --
126950806d53Smrg *
127050806d53Smrg * Resets drawing engine
127150806d53Smrg */
127250806d53Smrgstatic void
127350806d53SmrgI128SoftReset(ScrnInfoPtr pScrn)
127450806d53Smrg{
127550806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
127650806d53Smrg
127750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Performing soft reset\n");
127850806d53Smrg    pI128->io.config1 |= 0x00000002;
127950806d53Smrg    outl(pI128->RegRec.iobase + 0x1C, pI128->io.config1);
128050806d53Smrg    usleep(10000);
128150806d53Smrg    pI128->io.config1 &= 0xFFFFFFFD;
128250806d53Smrg    outl(pI128->RegRec.iobase + 0x1C, pI128->io.config1);
128350806d53Smrg}
128450806d53Smrg
128550806d53Smrg/*
128650806d53Smrg * I128CountRAM --
128750806d53Smrg *
128850806d53Smrg * Counts amount of installed RAM
128950806d53Smrg */
129050806d53Smrgstatic int
129150806d53SmrgI128CountRam(ScrnInfoPtr pScrn)
129250806d53Smrg{
129350806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
129450806d53Smrg    int SizeFound = 0;
129550806d53Smrg
129650806d53Smrg    SizeFound = 0;
129750806d53Smrg
129850806d53Smrg    switch(pI128->Chipset) {
129950806d53Smrg    case PCI_CHIP_I128_T2R4:
130050806d53Smrg      /* Use the subsystem ID to determine the memory size */
13017965d9acSmrg      switch ((PCI_SUB_DEVICE_ID(pI128->PciInfo)) & 0x0007) {
130250806d53Smrg         case 0x00:      /* 4MB card */
130350806d53Smrg	    SizeFound = 4 * 1024; break;
130450806d53Smrg         case 0x01:      /* 8MB card */
130550806d53Smrg	    SizeFound = 8 * 1024; break;
130650806d53Smrg         case 0x02:      /* 12MB card */
130750806d53Smrg            SizeFound = 12 * 1024; break;
130850806d53Smrg         case 0x03:      /* 16MB card */
130950806d53Smrg	    SizeFound = 16 * 1024; break;
131050806d53Smrg         case 0x04:      /* 20MB card */
131150806d53Smrg	    SizeFound = 20 * 1024; break;
131250806d53Smrg         case 0x05:      /* 24MB card */
131350806d53Smrg	    SizeFound = 24 * 1024; break;
131450806d53Smrg         case 0x06:      /* 28MB card */
131550806d53Smrg	    SizeFound = 28 * 1024; break;
131650806d53Smrg         case 0x07:      /* 32MB card */
131750806d53Smrg	    SizeFound = 32 * 1024; break;
131850806d53Smrg         default: /* Unknown board... */
131950806d53Smrg            break;
132050806d53Smrg      }
132150806d53Smrg      break;
132250806d53Smrg    case PCI_CHIP_I128_T2R:
13237965d9acSmrg      switch ((PCI_SUB_DEVICE_ID(pI128->PciInfo)) & 0xFFF7) {
132450806d53Smrg	 case 0x00:	/* 4MB card, no daughtercard */
132550806d53Smrg	    SizeFound = 4 * 1024; break;
132650806d53Smrg	 case 0x01:	/* 4MB card, 4MB daughtercard */
132750806d53Smrg	 case 0x04:	/* 8MB card, no daughtercard */
132850806d53Smrg	    SizeFound = 8 * 1024; break;
132950806d53Smrg	 case 0x02:	/* 4MB card, 8MB daughtercard */
133050806d53Smrg	 case 0x05:	/* 8MB card, 4MB daughtercard */
133150806d53Smrg	    SizeFound = 12 * 1024; break;
133250806d53Smrg	 case 0x06:	/* 8MB card, 8MB daughtercard */
133350806d53Smrg	    SizeFound = 16 * 1024; break;
133450806d53Smrg	 case 0x03:	/* 4MB card, 16 daughtercard */
133550806d53Smrg	    SizeFound = 20 * 1024; break;
133650806d53Smrg	 case 0x07:	/* 8MB card, 16MB daughtercard */
133750806d53Smrg	    SizeFound = 24 * 1024; break;
133850806d53Smrg	 default:
133950806d53Smrg	    break;
134050806d53Smrg      }
134150806d53Smrg    }
134250806d53Smrg
134350806d53Smrg    if (SizeFound == 0) {
134450806d53Smrg      SizeFound = 2048;  /* default to 2MB */
134550806d53Smrg      if (pI128->io.config1 & 0x04)    /* 128 bit mode   */
134650806d53Smrg         SizeFound <<= 1;
134750806d53Smrg      if (pI128->io.id & 0x0400)       /* 2 banks VRAM   */
134850806d53Smrg         SizeFound <<= 1;
134950806d53Smrg    }
135050806d53Smrg    return SizeFound;
135150806d53Smrg}
135250806d53Smrg
135350806d53Smrg
135450806d53Smrg/*
135550806d53Smrg * Map the framebuffer and MMIO memory.
135650806d53Smrg */
135750806d53Smrg
135850806d53Smrgstatic Bool
135950806d53SmrgI128MapMem(ScrnInfoPtr pScrn)
136050806d53Smrg{
136150806d53Smrg    I128Ptr pI128;
136250806d53Smrg
136350806d53Smrg    pI128 = I128PTR(pScrn);
136450806d53Smrg
136550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Mapping memory\n");
136650806d53Smrg
136750806d53Smrg    if (pI128->mem.rbase_g != NULL)
136850806d53Smrg	return TRUE;
136950806d53Smrg
137050806d53Smrg    /*
137150806d53Smrg     * Map IO registers to virtual address space
137250806d53Smrg     */
13737965d9acSmrg#ifndef XSERVER_LIBPCIACCESS
137450806d53Smrg    pI128->mem.mw0_ad = (unsigned char *)xf86MapPciMem(pScrn->scrnIndex,
137550806d53Smrg				VIDMEM_FRAMEBUFFER,
137650806d53Smrg				pI128->PciTag,
137750806d53Smrg				pI128->PciInfo->memBase[0] & 0xFFC00000,
137850806d53Smrg				pI128->MemorySize*1024);
13797965d9acSmrg#else
13807965d9acSmrg    {
13817965d9acSmrg	void** result = (void**)&pI128->mem.mw0_ad;
13827965d9acSmrg	int err = pci_device_map_range(pI128->PciInfo,
13837965d9acSmrg				       PCI_REGION_BASE(pI128->PciInfo, 0, REGION_MEM) & 0xffc00000,
13847965d9acSmrg				       pI128->MemorySize * 1024,
13857965d9acSmrg				       PCI_DEV_MAP_FLAG_WRITABLE |
13867965d9acSmrg				       PCI_DEV_MAP_FLAG_WRITE_COMBINE,
13877965d9acSmrg				       result);
13887965d9acSmrg	if (err)
13897965d9acSmrg	    return FALSE;
13907965d9acSmrg    }
13917965d9acSmrg#endif
13927965d9acSmrg
139350806d53Smrg    if (pI128->mem.mw0_ad == NULL)
139450806d53Smrg	return FALSE;
139550806d53Smrg
139650806d53Smrg    pI128->MemoryPtr = pI128->mem.mw0_ad;
139750806d53Smrg
13987965d9acSmrg#ifndef XSERVER_LIBPCIACCESS
139950806d53Smrg    pI128->mem.rbase_g = (CARD32 *)xf86MapPciMem(pScrn->scrnIndex,
140050806d53Smrg				VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
140150806d53Smrg				pI128->PciTag,
140250806d53Smrg				pI128->PciInfo->memBase[4] & 0xFFFF0000,
140350806d53Smrg				64*1024);
14047965d9acSmrg#else
14057965d9acSmrg    {
14067965d9acSmrg	void** result = (void**)&pI128->mem.rbase_g;
14077965d9acSmrg	int err = pci_device_map_range(pI128->PciInfo,
14087965d9acSmrg				       PCI_REGION_BASE(pI128->PciInfo, 4, REGION_MEM) & 0xffff0000,
14097965d9acSmrg				       64 * 1024,
14107965d9acSmrg				       PCI_DEV_MAP_FLAG_WRITABLE,
14117965d9acSmrg				       result);
14127965d9acSmrg	if (err)
14137965d9acSmrg	    return FALSE;
14147965d9acSmrg    }
14157965d9acSmrg#endif
141650806d53Smrg    if (pI128->mem.rbase_g == NULL)
141750806d53Smrg	return FALSE;
141850806d53Smrg
141950806d53Smrg    pI128->mem.rbase_w = pI128->mem.rbase_g + ( 8 * 1024)/4;
142050806d53Smrg    pI128->mem.rbase_a = pI128->mem.rbase_g + (16 * 1024)/4;
142150806d53Smrg    pI128->mem.rbase_b = pI128->mem.rbase_g + (24 * 1024)/4;
142250806d53Smrg    pI128->mem.rbase_i = pI128->mem.rbase_g + (32 * 1024)/4;
142350806d53Smrg
142450806d53Smrg    return TRUE;
142550806d53Smrg}
142650806d53Smrg
142750806d53Smrg
142850806d53Smrg/*
142950806d53Smrg * Unmap the framebuffer and MMIO memory.
143050806d53Smrg */
143150806d53Smrg
143250806d53Smrgstatic Bool
143350806d53SmrgI128UnmapMem(ScrnInfoPtr pScrn)
143450806d53Smrg{
143550806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
143650806d53Smrg
143750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unmapping memory\n");
143850806d53Smrg
143950806d53Smrg    if (pI128->mem.rbase_g == NULL)
144050806d53Smrg	return TRUE;
144150806d53Smrg
144250806d53Smrg    /*
144350806d53Smrg     * Unmap IO registers to virtual address space
144450806d53Smrg     */
144550806d53Smrg    xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pI128->mem.mw0_ad,
144650806d53Smrg	pI128->MemorySize*1024);
144750806d53Smrg    pI128->mem.mw0_ad = NULL;
144850806d53Smrg    pI128->MemoryPtr = NULL;
144950806d53Smrg
145050806d53Smrg    xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pI128->mem.rbase_g, 64*1024);
145150806d53Smrg    pI128->mem.rbase_g = NULL;
145250806d53Smrg    pI128->mem.rbase_w = NULL;
145350806d53Smrg    pI128->mem.rbase_a = NULL;
145450806d53Smrg    pI128->mem.rbase_b = NULL;
145550806d53Smrg    pI128->mem.rbase_i = NULL;
145650806d53Smrg
145750806d53Smrg    return TRUE;
145850806d53Smrg}
145950806d53Smrg
146050806d53Smrg
146150806d53Smrg/*
146250806d53Smrg * This function saves the video state.
146350806d53Smrg */
146450806d53Smrgstatic void
146550806d53SmrgI128Save(ScrnInfoPtr pScrn)
146650806d53Smrg{
146750806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
146850806d53Smrg    vgaHWPtr vgaHWP = VGAHWPTR(pScrn);
146950806d53Smrg
147050806d53Smrg    if (pI128->Primary)
147150806d53Smrg	vgaHWSave(pScrn, &vgaHWP->SavedReg, VGA_SR_ALL);
147250806d53Smrg
147350806d53Smrg    I128SaveState(pScrn);
147450806d53Smrg}
147550806d53Smrg
147650806d53Smrg/*
147750806d53Smrg * Restore the initial (text) mode.
147850806d53Smrg */
147950806d53Smrgstatic void
148050806d53SmrgI128Restore(ScrnInfoPtr pScrn)
148150806d53Smrg{
148250806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
148350806d53Smrg    vgaHWPtr vgaHWP = VGAHWPTR(pScrn);
148450806d53Smrg
148550806d53Smrg    I128RestoreState(pScrn);
148650806d53Smrg
148750806d53Smrg    if (pI128->Primary) {
148850806d53Smrg	vgaHWProtect(pScrn, TRUE);
148950806d53Smrg	vgaHWRestore(pScrn, &vgaHWP->SavedReg, VGA_SR_ALL);
149050806d53Smrg	vgaHWProtect(pScrn, FALSE);
149150806d53Smrg    }
149250806d53Smrg}
149350806d53Smrg
149450806d53Smrg/* Usually mandatory */
149550806d53SmrgBool
149650806d53SmrgI128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
149750806d53Smrg{
149850806d53Smrg    return I128ModeInit(xf86Screens[scrnIndex], mode);
149950806d53Smrg}
150050806d53Smrg
150150806d53Smrg
150250806d53Smrgstatic Bool
150350806d53SmrgI128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
150450806d53Smrg{
150550806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
150650806d53Smrg
150750806d53Smrg    if (pI128->Debug)
150850806d53Smrg    	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ModeInit start\n");
150950806d53Smrg
151050806d53Smrg    /* Initialise the ModeReg values */
151150806d53Smrg    pScrn->vtSema = TRUE;
151250806d53Smrg
151350806d53Smrg    if (!I128Init(pScrn, mode))
151450806d53Smrg	return FALSE;
151550806d53Smrg
151650806d53Smrg    pI128->ModeSwitched = TRUE;
151750806d53Smrg
151850806d53Smrg    pI128->mode = mode;
151950806d53Smrg
152050806d53Smrg    if (pI128->Debug)
152150806d53Smrg    	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ModeInit complete\n");
152250806d53Smrg
152350806d53Smrg    return TRUE;
152450806d53Smrg}
152550806d53Smrg
152650806d53Smrg
152750806d53Smrg/* Mandatory */
152850806d53Smrg
152950806d53Smrg/* This gets called at the start of each server generation */
153050806d53Smrg
153150806d53Smrgstatic Bool
153250806d53SmrgI128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
153350806d53Smrg{
153450806d53Smrg    ScrnInfoPtr pScrn;
153550806d53Smrg    I128Ptr pI128;
153650806d53Smrg    int ret;
153750806d53Smrg    VisualPtr visual;
153850806d53Smrg    unsigned char *FBStart;
153950806d53Smrg    int width, height, displayWidth;
154050806d53Smrg
154150806d53Smrg    /*
154250806d53Smrg     * First get the ScrnInfoRec
154350806d53Smrg     */
154450806d53Smrg    pScrn = xf86Screens[pScreen->myNum];
154550806d53Smrg
154650806d53Smrg    pI128 = I128PTR(pScrn);
154750806d53Smrg
154850806d53Smrg    if (pI128->Debug)
154950806d53Smrg    	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ScreenInit start\n");
155050806d53Smrg
155150806d53Smrg    /* Map the I128 memory and MMIO areas */
155250806d53Smrg    if (!I128MapMem(pScrn))
155350806d53Smrg        return FALSE;
155450806d53Smrg
155550806d53Smrg    pI128->MemoryPtr =
155650806d53Smrg	    (pointer)&((char *)pI128->MemoryPtr)[pI128->displayOffset];
155750806d53Smrg
155850806d53Smrg    /* Save the current state */
155950806d53Smrg    I128Save(pScrn);
156050806d53Smrg
156150806d53Smrg    /* Initialise the first mode */
156250806d53Smrg    if (!I128ModeInit(pScrn, pScrn->currentMode))
156350806d53Smrg        return FALSE;
156450806d53Smrg
156550806d53Smrg    /* Darken the screen for aesthetic reasons and set the viewport */
156650806d53Smrg    I128SaveScreen(pScreen, SCREEN_SAVER_ON);
156750806d53Smrg    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
156850806d53Smrg
156950806d53Smrg    /*
157050806d53Smrg     * The next step is to setup the screen's visuals, and initialise the
157150806d53Smrg     * framebuffer code.  In cases where the framebuffer's default
157250806d53Smrg     * choices for things like visual layouts and bits per RGB are OK,
157350806d53Smrg     * this may be as simple as calling the framebuffer's ScreenInit()
157450806d53Smrg     * function.  If not, the visuals will need to be setup before calling
157550806d53Smrg     * a fb ScreenInit() function and fixed up after.
157650806d53Smrg     *
157750806d53Smrg     * For most PC hardware at depths >= 8, the defaults that fb uses
157850806d53Smrg     * are not appropriate.  In this driver, we fixup the visuals after.
157950806d53Smrg     */
158050806d53Smrg
158150806d53Smrg    /*
158250806d53Smrg     * Reset the visual list.
158350806d53Smrg     */
158450806d53Smrg    miClearVisualTypes();
158550806d53Smrg
158650806d53Smrg    /* Setup the visuals we support. */
158750806d53Smrg
158850806d53Smrg    if (!miSetVisualTypes(pScrn->depth,
158950806d53Smrg			  miGetDefaultVisualMask(pScrn->depth),
159050806d53Smrg			  pScrn->rgbBits, pScrn->defaultVisual))
159150806d53Smrg	return FALSE;
159250806d53Smrg
159350806d53Smrg    if (!miSetPixmapDepths())
159450806d53Smrg	return FALSE;
159550806d53Smrg
159650806d53Smrg
159750806d53Smrg    /*
159850806d53Smrg     * Call the framebuffer layer's ScreenInit function, and fill in other
159950806d53Smrg     * pScreen fields.
160050806d53Smrg     */
160150806d53Smrg
160250806d53Smrg    width = pScrn->virtualX;
160350806d53Smrg    height = pScrn->virtualY;
160450806d53Smrg    displayWidth = pScrn->displayWidth;
160550806d53Smrg
160650806d53Smrg    FBStart = pI128->MemoryPtr;
160750806d53Smrg
160850806d53Smrg    ret = fbScreenInit(pScreen, FBStart,
160950806d53Smrg			width, height,
161050806d53Smrg			pScrn->xDpi, pScrn->yDpi,
161150806d53Smrg			displayWidth, pScrn->bitsPerPixel);
161250806d53Smrg    if (!ret)
161350806d53Smrg	return FALSE;
161450806d53Smrg
161550806d53Smrg    fbPictureInit(pScreen, 0, 0);
161650806d53Smrg
161750806d53Smrg    if (pScrn->bitsPerPixel > 8) {
161850806d53Smrg        /* Fixup RGB ordering */
161950806d53Smrg        visual = pScreen->visuals + pScreen->numVisuals;
162050806d53Smrg        while (--visual >= pScreen->visuals) {
162150806d53Smrg	    if ((visual->class | DynamicClass) == DirectColor) {
162250806d53Smrg		visual->offsetRed = pScrn->offset.red;
162350806d53Smrg		visual->offsetGreen = pScrn->offset.green;
162450806d53Smrg		visual->offsetBlue = pScrn->offset.blue;
162550806d53Smrg		visual->redMask = pScrn->mask.red;
162650806d53Smrg		visual->greenMask = pScrn->mask.green;
162750806d53Smrg		visual->blueMask = pScrn->mask.blue;
162850806d53Smrg	    }
162950806d53Smrg	}
163050806d53Smrg    }
163150806d53Smrg
163250806d53Smrg    xf86SetBlackWhitePixels(pScreen);
163350806d53Smrg
163450806d53Smrg    if (!pI128->NoAccel) {
163550806d53Smrg	if (pI128->exa)
163650806d53Smrg            ret = I128ExaInit(pScreen);
163750806d53Smrg        else {
163850806d53Smrg            I128DGAInit(pScreen);
163950806d53Smrg            ret = I128XaaInit(pScreen);
164050806d53Smrg        }
164150806d53Smrg    }
164250806d53Smrg
164350806d53Smrg    if (!ret) {
164450806d53Smrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Acceleration setup failed\n");
164550806d53Smrg        return FALSE;
164650806d53Smrg    }
164750806d53Smrg
164850806d53Smrg    miInitializeBackingStore(pScreen);
164950806d53Smrg    xf86SetBackingStore(pScreen);
165050806d53Smrg    xf86SetSilkenMouse(pScreen);
165150806d53Smrg
165250806d53Smrg    /* Initialize software cursor.
165350806d53Smrg	Must precede creation of the default colormap */
165450806d53Smrg    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
165550806d53Smrg
165650806d53Smrg    /* Initialize HW cursor layer.
165750806d53Smrg	Must follow software cursor initialization*/
165850806d53Smrg    if (pI128->HWCursor) {
165950806d53Smrg	ret = TRUE;
166050806d53Smrg    	switch(pI128->RamdacType) {
166150806d53Smrg	       case TI3025_DAC:
166250806d53Smrg		  ret = I128TIHWCursorInit(pScrn); break;
166350806d53Smrg	       case IBM524_DAC:
166450806d53Smrg	       case IBM526_DAC:
166550806d53Smrg	       case IBM528_DAC:
166650806d53Smrg		  ret = I128IBMHWCursorInit(pScrn); break;
166750806d53Smrg	       case SILVER_HAMMER_DAC:
166850806d53Smrg		  ret = I128IBMHWCursorInit(pScrn); break;
166950806d53Smrg	       default:
167050806d53Smrg		  break;
167150806d53Smrg	    }
167250806d53Smrg	if(!ret)
167350806d53Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
167450806d53Smrg		"Hardware cursor initialization failed\n");
167550806d53Smrg    }
167650806d53Smrg
167750806d53Smrg    /* Initialise default colourmap */
167850806d53Smrg    if (!miCreateDefColormap(pScreen))
167950806d53Smrg	return FALSE;
168050806d53Smrg
168150806d53Smrg    /* Initialize colormap layer.
168250806d53Smrg	Must follow initialization of the default colormap */
168350806d53Smrg    if(!xf86HandleColormaps(pScreen, 256, 8,
168450806d53Smrg	I128LoadPalette, NULL,
168550806d53Smrg	CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH))
168650806d53Smrg	return FALSE;
168750806d53Smrg
168850806d53Smrg    xf86DPMSInit(pScreen, I128DisplayPowerManagementSet, 0);
168950806d53Smrg
169050806d53Smrg    pScrn->memPhysBase = (unsigned long)pI128->MemoryPtr;
169150806d53Smrg    pScrn->fbOffset = 0;
169250806d53Smrg
169350806d53Smrg    pScreen->SaveScreen = I128SaveScreen;
169450806d53Smrg
169550806d53Smrg    /* Wrap the current CloseScreen function */
169650806d53Smrg    pI128->CloseScreen = pScreen->CloseScreen;
169750806d53Smrg    pScreen->CloseScreen = I128CloseScreen;
169850806d53Smrg
169950806d53Smrg    /* Report any unused options (only for the first generation) */
170050806d53Smrg    if (serverGeneration == 1) {
170150806d53Smrg	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
170250806d53Smrg    }
170350806d53Smrg
170450806d53Smrg    if (pI128->Debug)
170550806d53Smrg    	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ScreenInit complete\n");
170650806d53Smrg
170750806d53Smrg    /* Done */
170850806d53Smrg    return TRUE;
170950806d53Smrg}
171050806d53Smrg
171150806d53Smrg
171250806d53Smrg/*
171350806d53Smrg * This function is used to initialize the Start Address - the first
171450806d53Smrg * displayed location in the video memory.
171550806d53Smrg */
171650806d53Smrg/* Usually mandatory */
171750806d53Smrgvoid
171850806d53SmrgI128AdjustFrame(int scrnIndex, int x, int y, int flags)
171950806d53Smrg{
172050806d53Smrg    ScrnInfoPtr pScrn;
172150806d53Smrg    int   Base;
172250806d53Smrg    I128Ptr pI128;
172350806d53Smrg#define I128_PAN_MASK 0x01FFFFE0
172450806d53Smrg
172550806d53Smrg    pScrn = xf86Screens[scrnIndex];
172650806d53Smrg    pI128 = I128PTR(pScrn);
172750806d53Smrg
172850806d53Smrg    if (pI128->ShowCache && y && pScrn->vtSema)
172950806d53Smrg        y += pScrn->virtualY - 1;
173050806d53Smrg
173150806d53Smrg    if (x > (pI128->displayWidth - pI128->mode->HDisplay))
173250806d53Smrg        x = pI128->displayWidth - pI128->mode->HDisplay;
173350806d53Smrg
173450806d53Smrg    Base = ((y*pI128->displayWidth + x) * (pI128->bitsPerPixel/8));
173550806d53Smrg    pI128->mem.rbase_g[DB_ADR] =
173650806d53Smrg	(Base & I128_PAN_MASK) + pI128->displayOffset; MB;
173750806d53Smrg
173850806d53Smrg    /* now warp the cursor after the screen move */
173950806d53Smrg    pI128->AdjustCursorXPos = (Base - (Base & I128_PAN_MASK))
174050806d53Smrg                             / (pI128->bitsPerPixel/8);
174150806d53Smrg}
174250806d53Smrg
174350806d53Smrg/*
174450806d53Smrg * This is called when VT switching back to the X server.  Its job is
174550806d53Smrg * to reinitialise the video mode.
174650806d53Smrg *
174750806d53Smrg */
174850806d53Smrg
174950806d53Smrg/* Mandatory */
175050806d53Smrgstatic Bool
175150806d53SmrgI128EnterVT(int scrnIndex, int flags)
175250806d53Smrg{
175350806d53Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
175450806d53Smrg
175550806d53Smrg    if (!I128ModeInit(pScrn, pScrn->currentMode))
175650806d53Smrg	return FALSE;
175750806d53Smrg    I128AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
175850806d53Smrg    return TRUE;
175950806d53Smrg}
176050806d53Smrg
176150806d53Smrg/*
176250806d53Smrg * This is called when VT switching away from the X server.  Its job is
176350806d53Smrg * to restore the previous (text) mode.
176450806d53Smrg *
176550806d53Smrg */
176650806d53Smrg
176750806d53Smrg/* Mandatory */
176850806d53Smrgstatic void
176950806d53SmrgI128LeaveVT(int scrnIndex, int flags)
177050806d53Smrg{
177150806d53Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
177250806d53Smrg
177350806d53Smrg    I128Restore(pScrn);
177450806d53Smrg}
177550806d53Smrg
177650806d53Smrg
177750806d53Smrg/*
177850806d53Smrg * This is called at the end of each server generation.  It restores the
177950806d53Smrg * original (text) mode.  It should also unmap the video memory, and free
178050806d53Smrg * any per-generation data allocated by the driver.  It should finish
178150806d53Smrg * by unwrapping and calling the saved CloseScreen function.
178250806d53Smrg */
178350806d53Smrg
178450806d53Smrg/* Mandatory */
178550806d53Smrgstatic Bool
178650806d53SmrgI128CloseScreen(int scrnIndex, ScreenPtr pScreen)
178750806d53Smrg{
178850806d53Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
178950806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
179050806d53Smrg
179150806d53Smrg    if (pScrn->vtSema) {
179250806d53Smrg	I128Restore(pScrn);
179350806d53Smrg	I128UnmapMem(pScrn);
179450806d53Smrg    }
179550806d53Smrg    if (pI128->XaaInfoRec)
179650806d53Smrg	XAADestroyInfoRec(pI128->XaaInfoRec);
179750806d53Smrg    if (pI128->ExaDriver) {
179850806d53Smrg        exaDriverFini(pScreen);
179950806d53Smrg        xfree(pI128->ExaDriver);
180050806d53Smrg    }
180150806d53Smrg    if (pI128->CursorInfoRec)
180250806d53Smrg    	xf86DestroyCursorInfoRec(pI128->CursorInfoRec);
180350806d53Smrg    if (pI128->DGAModes)
180450806d53Smrg    	xfree(pI128->DGAModes);
180550806d53Smrg    pScrn->vtSema = FALSE;
180650806d53Smrg
180750806d53Smrg    pScreen->CloseScreen = pI128->CloseScreen;
180850806d53Smrg    return (*pScreen->CloseScreen)(scrnIndex, pScreen);
180950806d53Smrg}
181050806d53Smrg
181150806d53Smrg
181250806d53Smrg/* Free up any persistent data structures */
181350806d53Smrg
181450806d53Smrg/* Optional */
181550806d53Smrgstatic void
181650806d53SmrgI128FreeScreen(int scrnIndex, int flags)
181750806d53Smrg{
181850806d53Smrg    /*
181950806d53Smrg     * This only gets called when a screen is being deleted.  It does not
182050806d53Smrg     * get called routinely at the end of a server generation.
182150806d53Smrg     */
182250806d53Smrg    if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
182350806d53Smrg        vgaHWFreeHWRec(xf86Screens[scrnIndex]);
182450806d53Smrg
182550806d53Smrg    I128FreeRec(xf86Screens[scrnIndex]);
182650806d53Smrg}
182750806d53Smrg
182850806d53Smrg
182950806d53Smrg/* Checks if a mode is suitable for the selected chipset. */
183050806d53Smrg
183150806d53Smrg/* Optional */
183250806d53Smrgstatic ModeStatus
183350806d53SmrgI128ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
183450806d53Smrg{
183550806d53Smrg    int lace;
183650806d53Smrg
183750806d53Smrg    lace = 1 + ((mode->Flags & V_INTERLACE) != 0);
183850806d53Smrg
183950806d53Smrg    if ((mode->CrtcHDisplay <= 2048) &&
184050806d53Smrg	(mode->CrtcHSyncStart <= 4096) &&
184150806d53Smrg	(mode->CrtcHSyncEnd <= 4096) &&
184250806d53Smrg	(mode->CrtcHTotal <= 4096) &&
184350806d53Smrg	(mode->CrtcVDisplay <= 2048 * lace) &&
184450806d53Smrg	(mode->CrtcVSyncStart <= 4096 * lace) &&
184550806d53Smrg	(mode->CrtcVSyncEnd <= 4096 * lace) &&
184650806d53Smrg	(mode->CrtcVTotal <= 4096 * lace)) {
184750806d53Smrg	return(MODE_OK);
184850806d53Smrg    } else {
184950806d53Smrg	return(MODE_BAD);
185050806d53Smrg    }
185150806d53Smrg}
185250806d53Smrg
185350806d53Smrg
185450806d53Smrg/* Do screen blanking */
185550806d53Smrg
185650806d53Smrg/* Mandatory */
185750806d53Smrgstatic Bool
185850806d53SmrgI128SaveScreen(ScreenPtr pScreen, int mode)
185950806d53Smrg{
186050806d53Smrg    ScrnInfoPtr pScrn = NULL;
186150806d53Smrg    I128Ptr pI128;
186250806d53Smrg    Bool on;
186350806d53Smrg
186450806d53Smrg    if (pScreen != NULL)
186550806d53Smrg	pScrn = xf86Screens[pScreen->myNum];
186650806d53Smrg
186750806d53Smrg    on = xf86IsUnblank(mode);
186850806d53Smrg
186950806d53Smrg    if ((pScrn != NULL) && pScrn->vtSema) {
187050806d53Smrg        pI128 = I128PTR(pScrn);
187150806d53Smrg        if (on) {
187250806d53Smrg	    pI128->mem.rbase_g[CRT_1CON] |= 0x40;                           MB;
187350806d53Smrg	} else {
187450806d53Smrg	    pI128->mem.rbase_g[CRT_1CON] &= ~0x40;                          MB;
187550806d53Smrg	}
187650806d53Smrg    }
187750806d53Smrg    return TRUE;
187850806d53Smrg}
187950806d53Smrg
188050806d53Smrg
188150806d53Smrgstatic const int DDC_SDA_IN_MASK = 1 << 1;
188250806d53Smrgstatic const int DDC_SDA_OUT_MASK = 1 << 2;
188350806d53Smrgstatic const int DDC_SCL_IN_MASK = 1 << 3;
188450806d53Smrgstatic const int DDC_SCL_OUT_MASK = 1 << 0;
188550806d53Smrg
188650806d53Smrgstatic const int DDC_MODE_MASK = 3 << 8;
188750806d53Smrg#if 0
188850806d53Smrgstatic const int DDC_MODE_DDC1 = 1 << 8;
188950806d53Smrg#endif
189050806d53Smrgstatic const int DDC_MODE_DDC2 = 2 << 8;
189150806d53Smrg
189250806d53Smrg#if 0
189350806d53Smrgstatic unsigned int
189450806d53SmrgI128DDC1Read(ScrnInfoPtr pScrn)
189550806d53Smrg{
189650806d53Smrg  I128Ptr pI128 = I128PTR(pScrn);
189750806d53Smrg  unsigned char val;
189850806d53Smrg  unsigned long tmp, ddc;
189950806d53Smrg  IOADDRESS iobase;
190050806d53Smrg
190150806d53Smrg  iobase = pI128->RegRec.iobase;
190250806d53Smrg  ddc = inl(iobase + 0x2C);
190350806d53Smrg  if ((ddc & DDC_MODE_MASK) != DDC_MODE_DDC1) {
190450806d53Smrg      outl(iobase + 0x2C, DDC_MODE_DDC1);
19057965d9acSmrg      usleep(40);
190650806d53Smrg  }
190750806d53Smrg
190850806d53Smrg  /* wait for Vsync */
190950806d53Smrg  do {
191050806d53Smrg      tmp = inl(iobase + 0x2C);
191150806d53Smrg  } while (tmp & 1);
191250806d53Smrg  do {
191350806d53Smrg      tmp = inl(iobase + 0x2C);
191450806d53Smrg  } while (!(tmp & 1));
191550806d53Smrg
191650806d53Smrg  /* Get the result */
191750806d53Smrg  tmp = inl(iobase + 0x2C);
191850806d53Smrg  val = tmp & DDC_SDA_IN_MASK;
191950806d53Smrg
192050806d53Smrg  if ((ddc & DDC_MODE_MASK) != DDC_MODE_DDC1) {
192150806d53Smrg      outl(iobase + 0x2C, ~DDC_MODE_MASK & ddc);
19227965d9acSmrg      usleep(40);
192350806d53Smrg  }
192450806d53Smrg
192550806d53Smrg  return val;
192650806d53Smrg}
192750806d53Smrg#endif
192850806d53Smrg
192950806d53Smrgstatic void
193050806d53SmrgI128I2CGetBits(I2CBusPtr b, int *clock, int *data)
193150806d53Smrg{
193250806d53Smrg  I128Ptr pI128 = I128PTR(xf86Screens[b->scrnIndex]);
193350806d53Smrg  unsigned long ddc;
193450806d53Smrg  IOADDRESS iobase;
193550806d53Smrg#if 0
193650806d53Smrg  static int lastclock = -1, lastdata = -1;
193750806d53Smrg#endif
193850806d53Smrg
193950806d53Smrg  /* Get the result. */
194050806d53Smrg  iobase = pI128->RegRec.iobase;
194150806d53Smrg  ddc = inl(iobase + 0x2C);
194250806d53Smrg
194350806d53Smrg  *clock = (ddc & DDC_SCL_IN_MASK) != 0;
194450806d53Smrg  *data  = (ddc & DDC_SDA_IN_MASK) != 0;
194550806d53Smrg
194650806d53Smrg#if 0
194750806d53Smrg  if (pI128->Debug && ((lastclock != *clock) || (lastdata != *data))) {
194850806d53Smrg    xf86DrvMsg(b->scrnIndex, X_INFO, "i2c> c %d d %d\n", *clock, *data);
194950806d53Smrg    lastclock = *clock;
195050806d53Smrg    lastdata = *data;
195150806d53Smrg  }
195250806d53Smrg#endif
195350806d53Smrg}
195450806d53Smrg
195550806d53Smrgstatic void
195650806d53SmrgI128I2CPutBits(I2CBusPtr b, int clock, int data)
195750806d53Smrg{
195850806d53Smrg  I128Ptr pI128 = I128PTR(xf86Screens[b->scrnIndex]);
195950806d53Smrg  unsigned char drv, val;
196050806d53Smrg  unsigned long ddc;
196150806d53Smrg  unsigned long tmp;
196250806d53Smrg  IOADDRESS iobase;
196350806d53Smrg
196450806d53Smrg  iobase = pI128->RegRec.iobase;
196550806d53Smrg  ddc = inl(iobase + 0x2C);
196650806d53Smrg
196750806d53Smrg  val = (clock ? DDC_SCL_IN_MASK : 0) | (data ? DDC_SDA_IN_MASK : 0);
196850806d53Smrg  drv = ((clock) ? DDC_SCL_OUT_MASK : 0) | ((data) ? DDC_SDA_OUT_MASK : 0);
196950806d53Smrg
197050806d53Smrg  tmp = (DDC_MODE_MASK & ddc) | val | drv;
197150806d53Smrg  outl(iobase + 0x2C, tmp);
197250806d53Smrg#if 0
197350806d53Smrg  if (pI128->Debug)
197450806d53Smrg    xf86DrvMsg(b->scrnIndex, X_INFO, "i2c> 0x%x\n", tmp);
197550806d53Smrg#endif
197650806d53Smrg}
197750806d53Smrg
197850806d53Smrg
197950806d53Smrgstatic Bool
198050806d53SmrgI128I2CInit(ScrnInfoPtr pScrn)
198150806d53Smrg{
198250806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
198350806d53Smrg    I2CBusPtr I2CPtr;
198450806d53Smrg    IOADDRESS iobase;
198550806d53Smrg    unsigned long soft_sw, ddc;
198650806d53Smrg
198750806d53Smrg    I2CPtr = xf86CreateI2CBusRec();
198850806d53Smrg    if(!I2CPtr) return FALSE;
198950806d53Smrg
199050806d53Smrg    pI128->I2C = I2CPtr;
199150806d53Smrg
199250806d53Smrg    I2CPtr->BusName    = "DDC";
199350806d53Smrg    I2CPtr->scrnIndex  = pScrn->scrnIndex;
199450806d53Smrg    I2CPtr->I2CPutBits = I128I2CPutBits;
199550806d53Smrg    I2CPtr->I2CGetBits = I128I2CGetBits;
199650806d53Smrg    I2CPtr->BitTimeout = 4;
199750806d53Smrg    I2CPtr->ByteTimeout = 4;
199850806d53Smrg    I2CPtr->AcknTimeout = 4;
199950806d53Smrg    I2CPtr->StartTimeout = 4;
200050806d53Smrg
200150806d53Smrg    /* soft switch register bits 1,0 control I2C channel */
200250806d53Smrg    iobase = pI128->RegRec.iobase;
200350806d53Smrg    soft_sw = inl(iobase + 0x28);
200450806d53Smrg    soft_sw &= 0xfffffffc;
200550806d53Smrg    soft_sw |= 0x00000001;
200650806d53Smrg    outl(iobase + 0x28, soft_sw);
20077965d9acSmrg    usleep(1000);
200850806d53Smrg
200950806d53Smrg    /* set default as ddc2 mode */
201050806d53Smrg    ddc = inl(iobase + 0x2C);
201150806d53Smrg    ddc &= ~DDC_MODE_MASK;
201250806d53Smrg    ddc |= DDC_MODE_DDC2;
201350806d53Smrg    outl(iobase + 0x2C, ddc);
20147965d9acSmrg    usleep(40);
201550806d53Smrg
201650806d53Smrg    if (!xf86I2CBusInit(I2CPtr)) {
201750806d53Smrg        return FALSE;
201850806d53Smrg    }
201950806d53Smrg    return TRUE;
202050806d53Smrg}
202150806d53Smrg
202250806d53Smrg
202350806d53Smrgstatic xf86MonPtr
202450806d53SmrgI128getDDC(ScrnInfoPtr pScrn)
202550806d53Smrg{
202650806d53Smrg  I128Ptr pI128 = I128PTR(pScrn);
202750806d53Smrg  xf86MonPtr MonInfo = NULL;
202850806d53Smrg
202950806d53Smrg  /* Initialize I2C bus - used by DDC if available */
203050806d53Smrg  if (pI128->i2cInit) {
203150806d53Smrg    pI128->i2cInit(pScrn);
203250806d53Smrg  }
203350806d53Smrg  /* Read and output monitor info using DDC2 over I2C bus */
203450806d53Smrg  if (pI128->I2C) {
203550806d53Smrg    MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pI128->I2C);
203650806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I2C Monitor info: %p\n",
203750806d53Smrg	       (void *)MonInfo);
203850806d53Smrg    xf86PrintEDID(MonInfo);
203950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of I2C Monitor info\n");
204050806d53Smrg  }
204150806d53Smrg  if (!MonInfo) {
204250806d53Smrg    /* Read and output monitor info using DDC1 */
204350806d53Smrg    if (pI128->ddc1Read) {
204450806d53Smrg      MonInfo = xf86DoEDID_DDC1(pScrn->scrnIndex, NULL, pI128->ddc1Read ) ;
204550806d53Smrg      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Monitor info: %p\n",
204650806d53Smrg		 (void *)MonInfo);
204750806d53Smrg      xf86PrintEDID(MonInfo);
204850806d53Smrg      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of DDC Monitor info\n");
204950806d53Smrg    }
205050806d53Smrg  }
205150806d53Smrg
205250806d53Smrg  if (MonInfo)
205350806d53Smrg    xf86SetDDCproperties(pScrn, MonInfo);
205450806d53Smrg
205550806d53Smrg  return MonInfo;
205650806d53Smrg}
205750806d53Smrg
205850806d53Smrg
205950806d53Smrg/*
206050806d53Smrg * I128DisplayPowerManagementSet --
206150806d53Smrg *
206250806d53Smrg * Sets VESA Display Power Management Signaling (DPMS) Mode.
206350806d53Smrg */
206450806d53Smrgvoid
206550806d53SmrgI128DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
206650806d53Smrg			     int flags)
206750806d53Smrg{
206850806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
206950806d53Smrg    CARD32 snc;
207050806d53Smrg
207150806d53Smrg    if (pI128->Debug)
207250806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128DisplayPowerManagementSet: %d\n", PowerManagementMode);
207350806d53Smrg
207450806d53Smrg    if (pI128->RamdacType == TI3025_DAC) return;
207550806d53Smrg
207650806d53Smrg    snc = pI128->mem.rbase_g[CRT_1CON];
207750806d53Smrg
207850806d53Smrg    switch (PowerManagementMode)
207950806d53Smrg    {
208050806d53Smrg    case DPMSModeOn:
208150806d53Smrg	/* HSync: On, VSync: On */
208250806d53Smrg	snc |= 0x30;
208350806d53Smrg	break;
208450806d53Smrg    case DPMSModeStandby:
208550806d53Smrg	/* HSync: Off, VSync: On */
208650806d53Smrg	snc = (snc & ~0x10) | 0x20;
208750806d53Smrg	break;
208850806d53Smrg    case DPMSModeSuspend:
208950806d53Smrg	/* HSync: On, VSync: Off */
209050806d53Smrg	snc = (snc & ~0x20) | 0x10;
209150806d53Smrg	break;
209250806d53Smrg    case DPMSModeOff:
209350806d53Smrg	/* HSync: Off, VSync: Off */
209450806d53Smrg	snc &= ~0x30;
209550806d53Smrg	break;
209650806d53Smrg    }
209750806d53Smrg    pI128->mem.rbase_g[CRT_1CON] = snc;					MB;
209850806d53Smrg}
209950806d53Smrg
210050806d53Smrgstatic void
210150806d53SmrgI128DumpBaseRegisters(ScrnInfoPtr pScrn)
210250806d53Smrg{
210350806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
210450806d53Smrg
210550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
210650806d53Smrg	"  PCI Registers\n");
210750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
210850806d53Smrg	"    MW0_AD    0x%08lx  addr 0x%08lx  %spre-fetchable\n",
21097965d9acSmrg	    (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 0, REGION_MEM),
21107965d9acSmrg	    (unsigned long)(PCI_REGION_BASE(pI128->PciInfo, 0, REGION_MEM) & 0xFFC00000),
21117965d9acSmrg	    PCI_REGION_BASE(pI128->PciInfo, 0, REGION_MEM) & 0x8 ? "" : "not-");
211250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
211350806d53Smrg	"    MW1_AD    0x%08lx  addr 0x%08lx  %spre-fetchable\n",
21147965d9acSmrg	    (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 1, REGION_MEM),
21157965d9acSmrg	    (unsigned long)(PCI_REGION_BASE(pI128->PciInfo, 1, REGION_MEM) & 0xFFC00000),
21167965d9acSmrg	    PCI_REGION_BASE(pI128->PciInfo, 1, REGION_MEM) & 0x8 ? "" : "not-");
211750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
211850806d53Smrg	"    XYW_AD(A) 0x%08lx  addr 0x%08lx\n",
21197965d9acSmrg	    (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 2, REGION_MEM),
21207965d9acSmrg	    (unsigned long)(PCI_REGION_BASE(pI128->PciInfo, 2, REGION_MEM) & 0xFFC00000));
212150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
212250806d53Smrg	"    XYW_AD(B) 0x%08lx  addr 0x%08lx\n",
21237965d9acSmrg	    (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 3, REGION_MEM),
21247965d9acSmrg	    (unsigned long)(PCI_REGION_BASE(pI128->PciInfo, 3, REGION_MEM) & 0xFFC00000));
212550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
212650806d53Smrg	"    RBASE_G   0x%08lx  addr 0x%08lx\n",
21277965d9acSmrg	    (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 4, REGION_MEM),
21287965d9acSmrg	    (unsigned long)(PCI_REGION_BASE(pI128->PciInfo, 4, REGION_MEM) & 0xFFFF0000));
212950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
213050806d53Smrg	"    IO        0x%08lx  addr 0x%08lx\n",
21317965d9acSmrg	    (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 5, REGION_IO),
21327965d9acSmrg	    (unsigned long)(PCI_REGION_BASE(pI128->PciInfo, 5, REGION_IO) & 0xFFFFFF00));
213350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
213450806d53Smrg	"    SSC       0x%08x  addr 0x%08x\n",
21357965d9acSmrg    	    (unsigned int)PCI_SUB_DEVICE_ID(pI128->PciInfo),
21367965d9acSmrg	    (unsigned int)(PCI_SUB_DEVICE_ID(pI128->PciInfo) & 0xFFFFFF00));
213750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
213850806d53Smrg	"    SSV       0x%08x  addr 0x%08x\n",
21397965d9acSmrg    	    (unsigned int)PCI_SUB_VENDOR_ID(pI128->PciInfo),
21407965d9acSmrg	    (unsigned int)(PCI_SUB_VENDOR_ID(pI128->PciInfo) & 0xFFFFFF00));
21417965d9acSmrg#ifndef XSERVER_LIBPCIACCESS
214250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
214350806d53Smrg	"    RBASE_E   0x%08lx  addr 0x%08lx  %sdecode-enabled\n\n",
214450806d53Smrg    	    pI128->PciInfo->biosBase,
214550806d53Smrg	    pI128->PciInfo->biosBase & 0xFFFF8000,
214650806d53Smrg	    pI128->PciInfo->biosBase & 0x1 ? "" : "not-");
214750806d53Smrg
214850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
214950806d53Smrg	"    PCICMDST  0x%08x       0x%08x\n",
215050806d53Smrg   	    ((pciConfigPtr)pI128->PciInfo->thisCard)->pci_command,
215150806d53Smrg   	    ((pciConfigPtr)pI128->PciInfo->thisCard)->pci_status);
21527965d9acSmrg#endif
215350806d53Smrg
215450806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
215550806d53Smrg	"  IO Mapped Registers\n");
215650806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
215750806d53Smrg	"    RBASE_G   0x%08lx  addr 0x%08lx\n",
215850806d53Smrg	    (unsigned long)pI128->io.rbase_g, pI128->io.rbase_g & 0xFFFFFF00UL);
215950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
216050806d53Smrg	"    RBASE_W   0x%08lx  addr 0x%08lx\n",
216150806d53Smrg	    (unsigned long)pI128->io.rbase_w, pI128->io.rbase_w & 0xFFFFFF00UL);
216250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
216350806d53Smrg	"    RBASE_A   0x%08lx  addr 0x%08lx\n",
216450806d53Smrg	    (unsigned long)pI128->io.rbase_a, pI128->io.rbase_a & 0xFFFFFF00UL);
216550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
216650806d53Smrg	"    RBASE_B   0x%08lx  addr 0x%08lx\n",
216750806d53Smrg	    (unsigned long)pI128->io.rbase_b, pI128->io.rbase_b & 0xFFFFFF00UL);
216850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
216950806d53Smrg	"    RBASE_I   0x%08lx  addr 0x%08lx\n",
217050806d53Smrg	    (unsigned long)pI128->io.rbase_i, pI128->io.rbase_i & 0xFFFFFF00UL);
217150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
217250806d53Smrg	"    RBASE_E   0x%08lx  addr 0x%08lx  size 0x%lx\n\n",
217350806d53Smrg	    (unsigned long)pI128->io.rbase_e, pI128->io.rbase_e & 0xFFFF8000UL,
217450806d53Smrg	    pI128->io.rbase_e & 0x7UL);
217550806d53Smrg
217650806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
217750806d53Smrg	"  Miscellaneous IO Registers\n");
217850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
217950806d53Smrg	"    ID        0x%08lx\n", (unsigned long)pI128->io.id);
218050806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
218150806d53Smrg	"    CONFIG1   0x%08lx\n", (unsigned long)pI128->io.config1);
218250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
218350806d53Smrg	"    CONFIG2   0x%08lx\n", (unsigned long)pI128->io.config2);
218450806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
218550806d53Smrg	"    SGRAM     0x%08lx\n", (unsigned long)pI128->io.sgram);
218650806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
218750806d53Smrg	"    SOFT_SW   0x%08lx\n", (unsigned long)pI128->io.soft_sw);
218850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
218950806d53Smrg	"    VGA_CTL   0x%08lx\n", (unsigned long)pI128->io.vga_ctl);
219050806d53Smrg}
219150806d53Smrg
219250806d53Smrg
219350806d53Smrgvoid
219450806d53SmrgI128DumpActiveRegisters(ScrnInfoPtr pScrn)
219550806d53Smrg{
219650806d53Smrg    I128Ptr pI128 = I128PTR(pScrn);
219750806d53Smrg    IOADDRESS iobase;
219850806d53Smrg    unsigned long rbase_g, rbase_w, rbase_a, rbase_b, rbase_i, rbase_e;
219950806d53Smrg    unsigned long id, config1, config2, sgram, soft_sw, ddc, vga_ctl;
220050806d53Smrg    volatile CARD32 *vrba, *vrbg, *vrbw;
220150806d53Smrg
220250806d53Smrg    vrba = pI128->mem.rbase_a;
220350806d53Smrg    vrbg = pI128->mem.rbase_g;
220450806d53Smrg    vrbw = pI128->mem.rbase_w;
220550806d53Smrg
220650806d53Smrg    iobase = pI128->RegRec.iobase;
220750806d53Smrg    rbase_g = inl(iobase);
220850806d53Smrg    rbase_w = inl(iobase + 0x04);
220950806d53Smrg    rbase_a = inl(iobase + 0x08);
221050806d53Smrg    rbase_b = inl(iobase + 0x0C);
221150806d53Smrg    rbase_i = inl(iobase + 0x10);
221250806d53Smrg    rbase_e = inl(iobase + 0x14);
221350806d53Smrg    id = inl(iobase + 0x18);
221450806d53Smrg    config1 = inl(iobase + 0x1C);
221550806d53Smrg    config2 = inl(iobase + 0x20);
221650806d53Smrg    sgram = inl(iobase + 0x24);
221750806d53Smrg    soft_sw = inl(iobase + 0x28);
221850806d53Smrg    ddc = inl(iobase + 0x2C);
221950806d53Smrg    vga_ctl = inl(iobase + 0x30);
222050806d53Smrg
222150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "IO Mapped Registers\n");
222250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
222350806d53Smrg		"  RBASE_G   0x%08lx  addr 0x%08lx\n",
222450806d53Smrg       		rbase_g, rbase_g & 0xFFFFFF00);
222550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
222650806d53Smrg		"  RBASE_W   0x%08lx  addr 0x%08lx\n",
222750806d53Smrg       		rbase_w, rbase_w & 0xFFFFFF00);
222850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
222950806d53Smrg		"  RBASE_A   0x%08lx  addr 0x%08lx\n",
223050806d53Smrg       		rbase_a, rbase_a & 0xFFFFFF00);
223150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
223250806d53Smrg		"  RBASE_B   0x%08lx  addr 0x%08lx\n",
223350806d53Smrg       		rbase_b, rbase_b & 0xFFFFFF00);
223450806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
223550806d53Smrg		"  RBASE_I   0x%08lx  addr 0x%08lx\n",
223650806d53Smrg       		rbase_i, rbase_i & 0xFFFFFF00);
223750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
223850806d53Smrg		"  RBASE_E   0x%08lx  addr 0x%08lx  size 0x%lx\n",
223950806d53Smrg       		rbase_e, rbase_e & 0xFFFF8000, rbase_e & 0x7);
224050806d53Smrg
224150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Miscellaneous IO Registers\n");
224250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  ID        0x%08lx\n", id);
224350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    REV  %ld  HBT %ld  BASE0 %ld  VDEN %ld  VB %ld  BASE1 %ld  BASE2 %ld  DS %ld\n",
224450806d53Smrg    	id&7, (id>>3)&3, (id>>6)&3, (id>>8)&3, (id>>10)&1,
224550806d53Smrg    	(id>>11)&3, (id>>13)&3, (id>>15)&1);
224650806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    DDEN %ld  DB  %ld  BASE3 %ld  BASER %ld  MDEN %ld  TR %ld  VS    %ld\n",
224750806d53Smrg    	(id>>16)&3, (id>>18)&1, (id>>19)&3, (id>>21)&7, (id>>24)&3,
224850806d53Smrg	(id>>26)&1, (id>>27)&1);
224950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    CLASS %ld  EE %ld\n",
225050806d53Smrg	(id>>28)&3, (id>>30)&1);
225150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CONFIG1   0x%08lx\n", config1);
225250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    VE %ld  SFT_RST %ld  ONE28 %ld  VS %ld\n",
225350806d53Smrg    	config1&1, (config1>>1)&1,
225450806d53Smrg    	(config1>>2)&1, (config1>>3)&1);
225550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    G %ld  W %ld  A %ld  B %ld  I %ld  E %ld  W0 %ld  W1 %ld  XA %ld  XB %ld\n",
225650806d53Smrg    	(config1>>8)&1, (config1>>9)&1,
225750806d53Smrg    	(config1>>10)&1, (config1>>11)&1,
225850806d53Smrg    	(config1>>12)&1, (config1>>13)&1,
225950806d53Smrg    	(config1>>16)&1, (config1>>17)&1,
226050806d53Smrg    	(config1>>20)&1, (config1>>21)&1);
226150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    HBPRI %ld  VBPRI %ld  DE1PRI %ld  ISAPRI %ld\n",
226250806d53Smrg    	(config1>>24)&3, (config1>>26)&3,
226350806d53Smrg    	(config1>>28)&3, (config1>>30)&3);
226450806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CONFIG2   0x%08lx\n", config2);
226550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    DWT %lx  EWS %lx  DWS %lx  MC %lx  FBB %ld  IOB %ld  FST %ld  CNT %ld  DEC %ld\n",
226650806d53Smrg    	config2&0x3, (config2>>8)&0xF,
226750806d53Smrg    	(config2>>16)&0x7, (config2>>20)&0xF,
226850806d53Smrg    	(config2>>24)&1, (config2>>25)&1,
226950806d53Smrg    	(config2>>26)&1, (config2>>27)&1,
227050806d53Smrg    	(config2>>28)&1);
227150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    PRE %ld  RVD %ld  SDAC %ld\n",
227250806d53Smrg	(config2>>29)&1, (config2>>30)&1, (config2>>31)&1);
227350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  SGRAM     0x%08lx\n", sgram);
227450806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  SOFT_SW   0x%08lx\n", soft_sw);
227550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DDC       0x%08lx\n", ddc);
227650806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  VGA_CTL   0x%08lx\n", vga_ctl);
227750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    MEMMUX %ld  VGADEC %ld  VIDMUX %ld  ENA %ld  BUFSEL %ld  STR %ld\n",
227850806d53Smrg    	vga_ctl&1, (vga_ctl>>1)&1,
227950806d53Smrg    	(vga_ctl>>2)&1, (vga_ctl>>3)&1,
228050806d53Smrg    	(vga_ctl>>4)&1, (vga_ctl>>5)&1);
228150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    3C2 %ld  DACDEC %ld  MSK 0x%02lx\n",
228250806d53Smrg    	(vga_ctl>>6)&1,
228350806d53Smrg    	(vga_ctl>>7)&1,
228450806d53Smrg    	(vga_ctl>>8)&0xff);
228550806d53Smrg
228650806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT Registers\n");
228750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  INT_VCNT 0x%08lx  (%ld)\n",
228850806d53Smrg    	vrbg[0x20/4]&0x000000FFUL, vrbg[0x20/4]&0x000000FFUL);
228950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  INT_HCNT 0x%08lx  (%ld)\n",
229050806d53Smrg    	vrbg[0x24/4]&0x00000FFFUL, vrbg[0x24/4]&0x00000FFFUL);
229150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DB_ADR   0x%08lx  (%ld)\n",
229250806d53Smrg    	vrbg[0x28/4]&0x01FFFFF0UL, vrbg[0x28/4]&0x01FFFFF0UL);
229350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DB_PTCH  0x%08lx  (%ld)\n",
229450806d53Smrg    	vrbg[0x2C/4]&0x0000FFF0UL, vrbg[0x2C/4]&0x0000FFF0UL);
229550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_HAC  0x%08lx  (%ld)\n",
229650806d53Smrg    	vrbg[0x30/4]&0x00003FFFUL, vrbg[0x30/4]&0x00003FFFUL);
229750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_HBL  0x%08lx  (%ld)\n",
229850806d53Smrg    	vrbg[0x34/4]&0x00003FFFUL, vrbg[0x34/4]&0x00003FFFUL);
229950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_HFP  0x%08lx  (%ld)\n",
230050806d53Smrg    	vrbg[0x38/4]&0x00003FFFUL, vrbg[0x38/4]&0x00003FFFUL);
230150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_HS   0x%08lx  (%ld)\n",
230250806d53Smrg    	vrbg[0x3C/4]&0x00003FFFUL, vrbg[0x3C/4]&0x00003FFFUL);
230350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_VAC  0x%08lx  (%ld)\n",
230450806d53Smrg    	vrbg[0x40/4]&0x00000FFFUL, vrbg[0x40/4]&0x00000FFFUL);
230550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_VBL  0x%08lx  (%ld)\n",
230650806d53Smrg    	vrbg[0x44/4]&0x00000FFFUL, vrbg[0x44/4]&0x00000FFFUL);
230750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_VFP  0x%08lx  (%ld)\n",
230850806d53Smrg    	vrbg[0x48/4]&0x00000FFFUL, vrbg[0x48/4]&0x00000FFFUL);
230950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_VS   0x%08lx  (%ld)\n",
231050806d53Smrg    	vrbg[0x4C/4]&0x00000FFFUL, vrbg[0x4C/4]&0x00000FFFUL);
231150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_LCNT 0x%08lx\n",
231250806d53Smrg	vrbg[0x50/4]&0x00000FFFUL);
231350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_ZOOM 0x%08lx\n",
231450806d53Smrg	vrbg[0x54/4]&0x0000000FUL);
231550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_1CON 0x%08lx  PH %ld  PV %ld  CS %ld INL %ld H/VSE %ld/%ld VE %ld BTS %ld\n",
231650806d53Smrg        (unsigned long)vrbg[0x58/4],
231750806d53Smrg    	vrbg[0x58/4]&1UL, (vrbg[0x58/4]>>1)&1UL, (vrbg[0x58/4]>>2)&1UL,
231850806d53Smrg    	(vrbg[0x58/4]>>3)&1UL, (vrbg[0x58/4]>>4)&1UL, (vrbg[0x58/4]>>5)&1UL,
231950806d53Smrg    	(vrbg[0x58/4]>>6)&1UL, (vrbg[0x58/4]>>8)&1UL);
232050806d53Smrg
232150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_2CON 0x%08lx  MEM %ld  RFR %ld  TRD %ld  SPL %ld\n",
232250806d53Smrg        (unsigned long)vrbg[0x5C/4],
232350806d53Smrg    	vrbg[0x5C/4]&7UL, (vrbg[0x5C/4]>>8)&1UL,
232450806d53Smrg    	(vrbg[0x5C/4]>>16)&7UL, (vrbg[0x5C/4]>>24)&1UL);
232550806d53Smrg
232650806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory Windows Registers\n");
232750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW0_CTRL 0x%08lx\n",
232850806d53Smrg	(unsigned long)vrbw[0x00]);
232950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    AMV %ld  MP %ld  AMD %ld  SEN %ld  BSY %ld  MDM %ld  DEN %ld  PSZ %ld\n",
233050806d53Smrg    	(vrbw[0x00]>>1)&1UL, (vrbw[0x00]>>2)&1UL, (vrbw[0x00]>>3)&1UL,
233150806d53Smrg    	(vrbw[0x00]>>4)&3UL, (vrbw[0x00]>>8)&1UL, (vrbw[0x00]>>21)&3UL,
233250806d53Smrg    	(vrbw[0x00]>>24)&3UL, (vrbw[0x00]>>26)&3UL);
233350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "M/V/DSE %ld/%ld/%ld\n",
233450806d53Smrg	(vrbw[0x00]>>28)&1UL, (vrbw[0x00]>>29)&1UL, (vrbw[0x00]>>30)&1UL);
233550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW0_AD    0x%08lx  MW0_SZ    0x%08lx  MW0_PGE   0x%08lx\n",
233650806d53Smrg    	vrbw[0x04/4]&0xFFFFF000UL, vrbw[0x08/4]&0x0000000FUL,
233750806d53Smrg    	vrbw[0x0C/4]&0x000F001FUL);
233850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW0_ORG10 0x%08lx  MW0_ORG14 0x%08lx  MW0_MSRC  0x%08lx\n",
233950806d53Smrg    	vrbw[0x10/4]&0x01FFF000UL, vrbw[0x14/4]&0x01FFF000UL,
234050806d53Smrg    	vrbw[0x18/4]&0x00FFFF00UL);
234150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW0_WKEY  0x%08lx  MW0_KYDAT 0x%08lx  MW0_MASK  0x%08lx\n",
234250806d53Smrg    	(unsigned long)vrbw[0x1C/4], vrbw[0x20/4]&0x000F000FUL,
234350806d53Smrg	(unsigned long)vrbw[0x24/4]);
234450806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW1_CTRL 0x%08lx\n",
234550806d53Smrg	(unsigned long)vrbw[0x28/4]);
234650806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    AMV %ld  MP %ld  AMD %ld  SEN %ld  BSY %ld  MDM %ld  DEN %ld  PSZ %ld\n",
234750806d53Smrg    	(vrbw[0x28/4]>>1)&1UL, (vrbw[0x28/4]>>2)&1UL, (vrbw[0x28/4]>>3)&1UL,
234850806d53Smrg    	(vrbw[0x28/4]>>4)&3UL, (vrbw[0x28/4]>>8)&1UL, (vrbw[0x28/4]>>21)&3UL,
234950806d53Smrg    	(vrbw[0x28/4]>>24)&3UL, (vrbw[0x28/4]>>26)&3UL);
235050806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "M/V/DSE %ld/%ld/%ld\n",
235150806d53Smrg	(vrbw[0x28/4]>>28)&1UL, (vrbw[0x28/4]>>29)&1UL, (vrbw[0x28/4]>>30)&1UL);
235250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW1_AD    0x%08lx  MW1_SZ    0x%08lx  MW1_PGE   0x%08lx\n",
235350806d53Smrg    	vrbw[0x2C/4]&0xFFFFF000UL, vrbw[0x30/4]&0x0000000FUL,
235450806d53Smrg    	vrbw[0x34/4]&0x000F001FUL);
235550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW1_ORG10 0x%08lx  MW1_ORG14 0x%08lx  MW1_MSRC  0x%08lx\n",
235650806d53Smrg    	vrbw[0x38/4]&0x01FFF000UL, vrbw[0x3c/4]&0x01FFF000UL,
235750806d53Smrg    	vrbw[0x40/4]&0x00FFFF00UL);
235850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW1_WKEY  0x%08lx  MW1_KYDAT 0x%08lx  MW1_MASK  0x%08lx\n",
235950806d53Smrg    	(unsigned long)vrbw[0x44/4], vrbw[0x48/4]&0x000F000FUL,
236050806d53Smrg	(unsigned long)vrbw[0x4C/4]);
236150806d53Smrg
236250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Engine A Registers\n");
236350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  INTP      0x%08lx\n",
236450806d53Smrg	vrba[0x00/4]&0x03UL);
236550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  INTM      0x%08lx\n",
236650806d53Smrg	vrba[0x04/4]&0x03UL);
236750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  FLOW      0x%08lx\n",
236850806d53Smrg	vrba[0x08/4]&0x0FUL);
236950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  BUSY      0x%08lx\n",
237050806d53Smrg	vrba[0x0C/4]&0x01UL);
237150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XYW_AD    0x%08lx  SIZE 0x%lx  ADDR 0x%lx\n",
237250806d53Smrg    	vrba[0x10/4]&0xFFFFFF00UL, (vrba[0x10/4]>>8)&0x0000000FUL,
237350806d53Smrg    	vrba[0x10/4]&0xFFFFF000UL);
237450806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  ZCTL      0x%08lx\n",
237550806d53Smrg	(unsigned long)vrba[0x18/4]);
237650806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  BUF_CTRL  0x%08lx\n",
237750806d53Smrg	(unsigned long)vrba[0x20/4]);
237850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    AMV %ld  MP %ld  AMD %ld  SEN %ld  DEN %ld  DSE %ld  VSE %ld  MSE %ld\n",
237950806d53Smrg    	(vrba[0x20/4]>>1)&1UL, (vrba[0x20/4]>>2)&1UL, (vrba[0x20/4]>>3)&1UL,
238050806d53Smrg    	(vrba[0x20/4]>>8)&3UL, (vrba[0x20/4]>>10)&3UL, (vrba[0x20/4]>>12)&1UL,
238150806d53Smrg    	(vrba[0x20/4]>>13)&1UL, (vrba[0x20/4]>>14)&1UL);
238250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    PS %ld  MDM %ld  PSIZE %ld  CRCO %ld\n",
238350806d53Smrg	(vrba[0x20/4]>>16)&0x1FUL,
238450806d53Smrg    	(vrba[0x20/4]>>21)&3UL, (vrba[0x20/4]>>24)&3UL, (vrba[0x20/4]>>30)&3UL);
238550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_PGE    0x%08lx  DVPGE 0x%lx  MPGE 0x%lx\n",
238650806d53Smrg    	vrba[0x24/4]&0x000F001FUL, (vrba[0x24/4]>>8)&0x01FUL,
238750806d53Smrg    	(vrba[0x24/4]&0x000F0000UL)>>16);
238850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_SORG   0x%08lx\n",
238950806d53Smrg	vrba[0x28/4]&0x0FFFFFFFUL);
239050806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_DORG   0x%08lx\n",
239150806d53Smrg	vrba[0x2C/4]&0x0FFFFFFFUL);
239250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_MSRC   0x%08lx\n",
239350806d53Smrg	vrba[0x30/4]&0x03FFFFF0UL);
239450806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_WKEY   0x%08lx\n",
239550806d53Smrg	(unsigned long)vrba[0x38/4]);
239650806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_ZPTCH  0x%08lx\n",
239750806d53Smrg	vrba[0x3C/4]&0x000FFFF0UL);
239850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_SPTCH  0x%08lx\n",
239950806d53Smrg	vrba[0x40/4]&0x0000FFF0UL);
240050806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_DPTCH  0x%08lx\n",
240150806d53Smrg	vrba[0x44/4]&0x0000FFF0UL);
240250806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD       0x%08lx\n",
240350806d53Smrg	vrba[0x48/4]&0x7FFFFFFFUL);
240450806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    OPC 0x%02lx  ROP 0x%02lx  STYLE 0x%02lx  CLP 0x%lx  PATRN 0x%lx  HDF %ld\n",
240550806d53Smrg    	vrba[0x48/4]&0x00FFUL, (vrba[0x48/4]>>8)&0x00FFUL, (vrba[0x48/4]>>16)&0x001FUL,
240650806d53Smrg    	(vrba[0x48/4]>>21)&7UL, (vrba[0x48/4]>>24)&0x0FUL, (vrba[0x48/4]>>28)&7UL);
240750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_SHADE 0x%02lx\n",
240850806d53Smrg	vrba[0x4C/4]&0x00FFUL);
240950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_OPC   0x%02lx\n",
241050806d53Smrg	vrba[0x50/4]&0x00FFUL);
241150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_ROP   0x%02lx\n",
241250806d53Smrg	vrba[0x54/4]&0x00FFUL);
241350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_STYLE 0x%02lx\n",
241450806d53Smrg	vrba[0x58/4]&0x001FUL);
241550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_PATRN 0x%02lx\n",
241650806d53Smrg	vrba[0x5C/4]&0x000FUL);
241750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_CLP   0x%02lx\n",
241850806d53Smrg	vrba[0x60/4]&0x0007UL);
241950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_HDF   0x%02lx\n",
242050806d53Smrg	vrba[0x64/4]&0x0007UL);
242150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  FORE      0x%08lx\n",
242250806d53Smrg	(unsigned long)vrba[0x68/4]);
242350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  BACK      0x%08lx\n",
242450806d53Smrg	(unsigned long)vrba[0x6C/4]);
242550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MASK      0x%08lx\n",
242650806d53Smrg	(unsigned long)vrba[0x70/4]);
242750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  RMSK      0x%08lx\n",
242850806d53Smrg	(unsigned long)vrba[0x74/4]);
242950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  LPAT      0x%08lx\n",
243050806d53Smrg	(unsigned long)vrba[0x78/4]);
243150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  PCTRL     0x%08lx\n",
243250806d53Smrg	(unsigned long)vrba[0x7C/4]);
243350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    PLEN 0x%02ld  PSCL 0x%02ld  SPTR 0x%02ld  SSCL 0x%lx  STATE 0x%04lx\n",
243450806d53Smrg    	vrba[0x7C/4]&0x1FUL, (vrba[0x7C/4]>>5)&7UL, (vrba[0x7C/4]>>8)&0x1FUL,
243550806d53Smrg    	(vrba[0x7C/4]>>13)&7UL, (vrba[0x7C/4]>>16)&0xFFFFUL);
243650806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CLPTL     0x%08lx  CLPTLY 0x%04lx  CLPTLX 0x%04lx\n",
243750806d53Smrg    	(unsigned long)vrba[0x80/4], vrba[0x80/4]&0x00FFFFUL, (vrba[0x80/4]>>16)&0x00FFFFUL);
243850806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CLPBR     0x%08lx  CLPBRY 0x%04lx  CLPBRX 0x%04lx\n",
243950806d53Smrg    	(unsigned long)vrba[0x84/4],
244050806d53Smrg	vrba[0x84/4]&0x00FFFFUL, (vrba[0x84/4]>>16)&0x00FFFFUL);
244150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY0       0x%08lx\n",
244250806d53Smrg	(unsigned long)vrba[0x88/4]);
244350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY1       0x%08lx\n",
244450806d53Smrg	(unsigned long)vrba[0x8C/4]);
244550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY2       0x%08lx\n",
244650806d53Smrg	(unsigned long)vrba[0x90/4]);
244750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY3       0x%08lx\n",
244850806d53Smrg	(unsigned long)vrba[0x94/4]);
244950806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY4       0x%08lx\n",
245050806d53Smrg	(unsigned long)vrba[0x98/4]);
245150806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY5       0x%08lx\n",
245250806d53Smrg	(unsigned long)vrba[0x9C/4]);
245350806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY6       0x%08lx\n",
245450806d53Smrg	(unsigned long)vrba[0xA0/4]);
245550806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY7       0x%08lx\n",
245650806d53Smrg	(unsigned long)vrba[0xA4/4]);
245750806d53Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY8       0x%08lx\n",
245850806d53Smrg	(unsigned long)vrba[0xA8/4]);
245950806d53Smrg    if (pI128->RamdacType != TI3025_DAC)
246050806d53Smrg	I128DumpIBMDACRegisters(pScrn, vrbg);
246150806d53Smrg}
246250806d53Smrg
246350806d53Smrgstatic const unsigned char ibm52Xmask[0xA0] = {
246450806d53Smrg0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   /* 00-07 */
246550806d53Smrg0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,   /* 08-0F */
246650806d53Smrg0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00,   /* 10-17 */
246750806d53Smrg0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 18-1F */
246850806d53Smrg0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,   /* 20-27 */
246950806d53Smrg0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 28-2F */
247050806d53Smrg0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,   /* 30-37 */
247150806d53Smrg0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 38-3F */
247250806d53Smrg0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   /* 40-47 */
247350806d53Smrg0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 48-4F */
247450806d53Smrg0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 58-5F */
247550806d53Smrg0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 58-5F */
247650806d53Smrg0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 60-67 */
247750806d53Smrg0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 68-6F */
247850806d53Smrg0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,   /* 70-77 */
247950806d53Smrg0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 78-7F */
248050806d53Smrg0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,   /* 80-87 */
248150806d53Smrg0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,   /* 88-8F */
248250806d53Smrg0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,   /* 90-97 */
248350806d53Smrg0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 98-9F */
248450806d53Smrg};
248550806d53Smrg
248650806d53Smrgstatic void
248750806d53SmrgI128DumpIBMDACRegisters(ScrnInfoPtr pScrn, volatile CARD32 *vrbg)
248850806d53Smrg{
248950806d53Smrg	unsigned char ibmr[0x100];
249050806d53Smrg	char buf[128], tbuf[10];
249150806d53Smrg	int i;
249250806d53Smrg
249350806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "IBM52X Registers\n");
249450806d53Smrg
249550806d53Smrg	vrbg[IDXH_I] = 0x00;
249650806d53Smrg	vrbg[IDXH_I] = 0x00;
249750806d53Smrg	vrbg[IDXCTL_I] = 0x01;
249850806d53Smrg	buf[0] = '\0';
249950806d53Smrg
250050806d53Smrg	for (i=0; i<0xA0; i++) {
250150806d53Smrg		if ((i%16 == 0) && (i != 0)) {
250250806d53Smrg			xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s\n", buf);
250350806d53Smrg			buf[0] = '\0';
250450806d53Smrg		}
250550806d53Smrg		if (ibm52Xmask[i] == 0x00) {
250650806d53Smrg			strcat(buf, " ..");
250750806d53Smrg		} else {
250850806d53Smrg			vrbg[IDXL_I] = i;
250950806d53Smrg			ibmr[i] = vrbg[DATA_I] & 0xFF;
251050806d53Smrg			ibmr[i] &= ibm52Xmask[i];
251150806d53Smrg			sprintf(tbuf, " %02x", ibmr[i]);
251250806d53Smrg			strcat(buf, tbuf);
251350806d53Smrg		}
251450806d53Smrg	}
251550806d53Smrg	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s\n", buf);
251650806d53Smrg}
251750806d53Smrg
2518