alp_driver.c revision 1ae1b5e8
176888252Smrg/*
276888252Smrg * Driver for CL-GD5480.
376888252Smrg * Itai Nahshon.
476888252Smrg *
576888252Smrg * Support for the CL-GD7548: David Monniaux
676888252Smrg *
776888252Smrg * This is mainly a cut & paste from the MGA driver.
876888252Smrg * Original autors and contributors list include:
976888252Smrg *    Radoslaw Kapitan, Andrew Vanderstock, Dirk Hohndel,
1076888252Smrg *    David Dawes, Andrew E. Mileski, Leonard N. Zubkoff,
1176888252Smrg *    Guy DESBIEF
1276888252Smrg */
1376888252Smrg
1476888252Smrg#ifdef HAVE_CONFIG_H
1576888252Smrg#include "config.h"
1676888252Smrg#endif
1776888252Smrg
1876888252Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_driver.c,v 1.35 2003/11/03 05:11:09 tsi Exp $ */
1976888252Smrg
2076888252Smrg/* All drivers should typically include these */
2176888252Smrg#include "xf86.h"
2276888252Smrg#include "xf86_OSproc.h"
2376888252Smrg
2476888252Smrg/* All drivers need this */
2576888252Smrg
2676888252Smrg/* Everything using inb/outb, etc needs "compiler.h" */
2776888252Smrg#include "compiler.h"
2876888252Smrg
2976888252Smrg/* Drivers for PCI hardware need this */
3076888252Smrg#include "xf86PciInfo.h"
3176888252Smrg
3276888252Smrg/* Drivers that need to access the PCI config space directly need this */
3376888252Smrg#include "xf86Pci.h"
3476888252Smrg
3576888252Smrg/* All drivers using the vgahw module need this */
3676888252Smrg/* This driver needs to be modified to not use vgaHW for multihead operation */
3776888252Smrg#include "vgaHW.h"
3876888252Smrg
3976888252Smrg#include "xf86RAC.h"
4076888252Smrg#include "xf86Resources.h"
4176888252Smrg
4276888252Smrg/* All drivers initialising the SW cursor need this */
4376888252Smrg#include "mipointer.h"
4476888252Smrg
4576888252Smrg/* All drivers implementing backing store need this */
4676888252Smrg#include "mibstore.h"
4776888252Smrg
4876888252Smrg#include "micmap.h"
4976888252Smrg
5076888252Smrg/* Needed by the Shadow Framebuffer */
5176888252Smrg#include "shadowfb.h"
5276888252Smrg
5376888252Smrg/* Note: can HWCUR64 be set even though the hw cursor is disabled for
5476888252Smrg   want of memory ? */
5576888252Smrg
5676888252Smrg/* Framebuffer memory manager */
5776888252Smrg#include "xf86fbman.h"
5876888252Smrg
591ae1b5e8Smrg#if HAVE_XF4BPP
6076888252Smrg#include "xf4bpp.h"
611ae1b5e8Smrg#endif
621ae1b5e8Smrg#if HAVE_XF1BPP
6376888252Smrg#include "xf1bpp.h"
641ae1b5e8Smrg#endif
651ae1b5e8Smrg
6676888252Smrg#include "fb.h"
6776888252Smrg
6876888252Smrg
6976888252Smrg#include "xf86DDC.h"
7076888252Smrg#include "xf86int10.h"
7176888252Smrg
7276888252Smrg#include "cir.h"
7376888252Smrg#define _ALP_PRIVATE_
7476888252Smrg#include "alp.h"
7576888252Smrg
7676888252Smrg#include "xf86xv.h"
7776888252Smrg#include <X11/extensions/Xv.h>
7876888252Smrg
7976888252Smrg#ifdef ALPPROBEI2C
8076888252Smrg/* For debugging... should go away. */
8176888252Smrgstatic void AlpProbeI2C(int scrnIndex);
8276888252Smrg#endif
8376888252Smrg
8476888252Smrg/*
8576888252Smrg * Forward definitions for the functions that make up the driver.
8676888252Smrg */
8776888252Smrg
8876888252Smrg/* Mandatory functions */
8976888252Smrg
9076888252SmrgBool AlpPreInit(ScrnInfoPtr pScrn, int flags);
9176888252SmrgBool AlpScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv);
9276888252SmrgBool AlpEnterVT(int scrnIndex, int flags);
9376888252Smrgvoid AlpLeaveVT(int scrnIndex, int flags);
9476888252Smrgstatic Bool	AlpCloseScreen(int scrnIndex, ScreenPtr pScreen);
9576888252Smrgstatic Bool	AlpSaveScreen(ScreenPtr pScreen, int mode);
9676888252Smrg
9776888252Smrg/* Required if the driver supports mode switching */
9876888252SmrgBool AlpSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
9976888252Smrg/* Required if the driver supports moving the viewport */
10076888252Smrgvoid AlpAdjustFrame(int scrnIndex, int x, int y, int flags);
10176888252Smrg
10276888252Smrg/* Optional functions */
10376888252Smrgvoid AlpFreeScreen(int scrnIndex, int flags);
10476888252SmrgModeStatus AlpValidMode(int scrnIndex, DisplayModePtr mode,
10576888252Smrg			Bool verbose, int flags);
10676888252Smrg/* Internally used functions */
10776888252Smrgstatic void	AlpSave(ScrnInfoPtr pScrn);
10876888252Smrgstatic void	AlpRestore(ScrnInfoPtr pScrn);
10976888252Smrgstatic Bool	AlpModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
11076888252Smrg
11176888252Smrgstatic void AlpProbeLCD(ScrnInfoPtr pScrn);
11276888252Smrg
11376888252Smrgstatic void AlpSetClock(CirPtr pCir, vgaHWPtr hwp, int freq);
11476888252Smrg
11576888252Smrgstatic void AlpOffscreenAccelInit(ScrnInfoPtr pScrn);
11676888252Smrg
11776888252Smrgstatic void	AlpDisplayPowerManagementSet(ScrnInfoPtr pScrn,
11876888252Smrg											int PowerManagementMode, int flags);
11976888252Smrg
12076888252Smrg/*
12176888252Smrg * This is intentionally screen-independent.  It indicates the binding
12276888252Smrg * choice made in the first PreInit.
12376888252Smrg */
12476888252Smrgstatic int pix24bpp = 0;
12576888252Smrg
12676888252Smrgtypedef enum {
12776888252Smrg	OPTION_HW_CURSOR,
12876888252Smrg	OPTION_PCI_RETRY,
12976888252Smrg	OPTION_NOACCEL,
13076888252Smrg	OPTION_MMIO,
13176888252Smrg	OPTION_ROTATE,
13276888252Smrg	OPTION_SHADOW_FB,
13376888252Smrg	OPTION_MEMCFG1,
13476888252Smrg	OPTION_MEMCFG2
13576888252Smrg} CirOpts;
13676888252Smrg
13776888252Smrgstatic const OptionInfoRec CirOptions[] = {
13876888252Smrg	{ OPTION_HW_CURSOR,	"HWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
13976888252Smrg	{ OPTION_NOACCEL,	"NoAccel",	OPTV_BOOLEAN,	{0}, FALSE },
14076888252Smrg	{ OPTION_MMIO,		"MMIO",		OPTV_BOOLEAN,	{0}, FALSE },
14176888252Smrg	{ OPTION_SHADOW_FB,	"ShadowFB",	OPTV_BOOLEAN,	{0}, FALSE },
14276888252Smrg	{ OPTION_ROTATE, 	 "Rotate",	OPTV_ANYSTR,	{0}, FALSE },
14376888252Smrg	{ OPTION_MEMCFG1,	"MemCFG1",	OPTV_INTEGER,	{0}, -1 },
14476888252Smrg	{ OPTION_MEMCFG2,	"MemCFG2",	OPTV_INTEGER,	{0}, -1 },
14576888252Smrg	{ -1,				NULL,		OPTV_NONE,		{0}, FALSE }
14676888252Smrg};
14776888252Smrg
14876888252Smrg/*                                1/4bpp   8bpp   15/16bpp  24bpp  32bpp
14976888252Smrgstatic int unsupp_MaxClocks[] = {      0,      0,      0,      0,      0 }; */
15076888252Smrgstatic int gd5430_MaxClocks[] = {  85500,  85500,  50000,  28500,      0 };
15176888252Smrgstatic int gd5446_MaxClocks[] = { 135100, 135100,  85500,  85500,      0 };
15276888252Smrgstatic int gd5480_MaxClocks[] = { 135100, 200000, 200000, 135100, 135100 };
15376888252Smrgstatic int gd7548_MaxClocks[] = {  80100,  80100,  80100,  80100,  80100 };
15476888252Smrg
15576888252Smrg/*
15676888252Smrg * List of symbols from other modules that this module references.  This
15776888252Smrg * list is used to tell the loader that it is OK for symbols here to be
15876888252Smrg * unresolved providing that it hasn't been told that they haven't been
15976888252Smrg * told that they are essential via a call to xf86LoaderReqSymbols() or
16076888252Smrg * xf86LoaderReqSymLists().  The purpose is this is to avoid warnings about
16176888252Smrg * unresolved symbols that are not required.
16276888252Smrg */
16376888252Smrg
16476888252Smrgstatic const char *vgahwSymbols[] = {
16576888252Smrg	"vgaHWFreeHWRec",
16676888252Smrg	"vgaHWGetHWRec",
16776888252Smrg	"vgaHWGetIOBase",
16876888252Smrg	"vgaHWGetIndex",
16976888252Smrg	"vgaHWHandleColormaps",
17076888252Smrg	"vgaHWInit",
17176888252Smrg	"vgaHWLock",
17276888252Smrg	"vgaHWMapMem",
17376888252Smrg	"vgaHWProtect",
17476888252Smrg	"vgaHWRestore",
17576888252Smrg	"vgaHWSave",
17676888252Smrg	"vgaHWSaveScreen",
17776888252Smrg	"vgaHWSetMmioFuncs",
17876888252Smrg	"vgaHWSetStdFuncs",
17976888252Smrg	"vgaHWUnlock",
18076888252Smrg	NULL
18176888252Smrg};
18276888252Smrg
18376888252Smrg#ifdef XFree86LOADER
18476888252Smrgstatic const char *miscfbSymbols[] = {
18576888252Smrg    "xf1bppScreenInit",
18676888252Smrg    "xf4bppScreenInit",
18776888252Smrg    NULL
18876888252Smrg};
18976888252Smrg#endif
19076888252Smrg
19176888252Smrgstatic const char *fbSymbols[] = {
19276888252Smrg    "fbScreenInit",
19376888252Smrg    "fbPictureInit",
19476888252Smrg    NULL
19576888252Smrg};
19676888252Smrg
19776888252Smrgstatic const char *xaaSymbols[] = {
19876888252Smrg	"XAACreateInfoRec",
19976888252Smrg	"XAADestroyInfoRec",
20076888252Smrg	"XAAInit",
20176888252Smrg	NULL
20276888252Smrg};
20376888252Smrg
20476888252Smrgstatic const char *ramdacSymbols[] = {
20576888252Smrg	"xf86CreateCursorInfoRec",
20676888252Smrg	"xf86DestroyCursorInfoRec",
20776888252Smrg	"xf86InitCursor",
20876888252Smrg	NULL
20976888252Smrg};
21076888252Smrg
21176888252Smrgstatic const char *int10Symbols[] = {
21276888252Smrg    "xf86FreeInt10",
21376888252Smrg    "xf86InitInt10",
21476888252Smrg    NULL
21576888252Smrg};
21676888252Smrg
21776888252Smrgstatic const char *shadowSymbols[] = {
21876888252Smrg    "ShadowFBInit",
21976888252Smrg    NULL
22076888252Smrg};
22176888252Smrg
22276888252Smrgstatic const char *ddcSymbols[] = {
22376888252Smrg	"xf86PrintEDID",
22476888252Smrg	"xf86DoEDID_DDC2",
22576888252Smrg	"xf86SetDDCproperties",
22676888252Smrg	NULL
22776888252Smrg};
22876888252Smrg
22976888252Smrgstatic const char *i2cSymbols[] = {
23076888252Smrg	"xf86CreateI2CBusRec",
23176888252Smrg	"xf86I2CBusInit",
23276888252Smrg	NULL
23376888252Smrg};
23476888252Smrg
23576888252Smrg#ifdef XFree86LOADER
23676888252Smrg
23776888252Smrg#define ALP_MAJOR_VERSION 1
23876888252Smrg#define ALP_MINOR_VERSION 0
23976888252Smrg#define ALP_PATCHLEVEL 0
24076888252Smrg
24176888252Smrgstatic MODULESETUPPROTO(alpSetup);
24276888252Smrg
24376888252Smrgstatic XF86ModuleVersionInfo alpVersRec =
24476888252Smrg{
24576888252Smrg	"cirrus_alpine",
24676888252Smrg	MODULEVENDORSTRING,
24776888252Smrg	MODINFOSTRING1,
24876888252Smrg	MODINFOSTRING2,
24976888252Smrg	XORG_VERSION_CURRENT,
25076888252Smrg	ALP_MAJOR_VERSION, ALP_MINOR_VERSION, ALP_PATCHLEVEL,
25176888252Smrg	ABI_CLASS_VIDEODRV,			/* This is a video driver */
25276888252Smrg	ABI_VIDEODRV_VERSION,
25376888252Smrg	MOD_CLASS_NONE,
25476888252Smrg	{0,0,0,0}
25576888252Smrg};
25676888252Smrg
25776888252Smrg/*
25876888252Smrg * This is the module init data.
25976888252Smrg * Its name has to be the driver name followed by ModuleData.
26076888252Smrg */
26176888252Smrg_X_EXPORT XF86ModuleData cirrus_alpineModuleData = {
26276888252Smrg    &alpVersRec,
26376888252Smrg    alpSetup,
26476888252Smrg    NULL
26576888252Smrg};
26676888252Smrg
26776888252Smrgstatic pointer
26876888252SmrgalpSetup(pointer module, pointer opts, int *errmaj, int *errmin)
26976888252Smrg{
27076888252Smrg	static Bool setupDone = FALSE;
27176888252Smrg	if (!setupDone) {
27276888252Smrg		setupDone = TRUE;
27376888252Smrg		LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols,
27476888252Smrg				  miscfbSymbols, ramdacSymbols,int10Symbols,
27576888252Smrg				  ddcSymbols, i2cSymbols, shadowSymbols, NULL);
27676888252Smrg	}
27776888252Smrg	return (pointer)1;
27876888252Smrg}
27976888252Smrg
28076888252Smrg#endif /* XFree86LOADER */
28176888252Smrg
28276888252Smrg_X_EXPORT const OptionInfoRec *
28376888252SmrgAlpAvailableOptions(int chipid)
28476888252Smrg{
28576888252Smrg    return CirOptions;
28676888252Smrg}
28776888252Smrg
28876888252Smrg_X_EXPORT ScrnInfoPtr
28976888252SmrgAlpProbe(int entity)
29076888252Smrg{
29176888252Smrg    ScrnInfoPtr pScrn = NULL;
29276888252Smrg
29376888252Smrg    if ((pScrn = xf86ConfigPciEntity(pScrn, 0, entity, CIRPciChipsets,
29476888252Smrg					   NULL,NULL, NULL, NULL, NULL))) {
29576888252Smrg	pScrn->PreInit		= AlpPreInit;
29676888252Smrg	pScrn->ScreenInit	= AlpScreenInit;
29776888252Smrg	pScrn->SwitchMode	= AlpSwitchMode;
29876888252Smrg	pScrn->AdjustFrame	= AlpAdjustFrame;
29976888252Smrg	pScrn->EnterVT		= AlpEnterVT;
30076888252Smrg	pScrn->LeaveVT		= AlpLeaveVT;
30176888252Smrg	pScrn->FreeScreen	= AlpFreeScreen;
30276888252Smrg	pScrn->ValidMode	= AlpValidMode;
30376888252Smrg    }
30476888252Smrg
30576888252Smrg    return pScrn;
30676888252Smrg}
30776888252Smrg
30876888252Smrg
30976888252Smrgstatic Bool
31076888252SmrgAlpGetRec(ScrnInfoPtr pScrn)
31176888252Smrg{
31276888252Smrg#ifdef ALP_DEBUG
31376888252Smrg	ErrorF("AlpGetRec\n");
31476888252Smrg#endif
31576888252Smrg	if (pScrn->driverPrivate != NULL)
31676888252Smrg		return TRUE;
31776888252Smrg
31876888252Smrg	pScrn->driverPrivate = xnfcalloc(sizeof(CirRec), 1);
31976888252Smrg	((CirPtr)pScrn->driverPrivate)->chip.alp = xnfcalloc(sizeof(AlpRec),1);
32076888252Smrg
32176888252Smrg#ifdef ALP_DEBUG
32276888252Smrg	ErrorF("AlpGetRec 0x%x\n", CIRPTR(pScrn));
32376888252Smrg#endif
32476888252Smrg	return TRUE;
32576888252Smrg}
32676888252Smrg
32776888252Smrgstatic void
32876888252SmrgAlpFreeRec(ScrnInfoPtr pScrn)
32976888252Smrg{
33076888252Smrg	if (pScrn->driverPrivate == NULL)
33176888252Smrg		return;
33276888252Smrg	xfree(pScrn->driverPrivate);
33376888252Smrg	pScrn->driverPrivate = NULL;
33476888252Smrg}
33576888252Smrg
33676888252Smrg
33776888252Smrg/*
33876888252Smrg * AlpCountRAM --
33976888252Smrg *
34076888252Smrg * Counts amount of installed RAM
34176888252Smrg *
34276888252Smrg * XXX Can use options to configure memory on non-primary cards.
34376888252Smrg */
34476888252Smrgstatic int
34576888252SmrgAlpCountRam(ScrnInfoPtr pScrn)
34676888252Smrg{
34776888252Smrg    CirPtr pCir = CIRPTR(pScrn);
34876888252Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
34976888252Smrg    MessageType from;
35076888252Smrg    int videoram = 0;
35176888252Smrg
35276888252Smrg    /* Map the Alp memory and MMIO areas */
35376888252Smrg    pCir->FbMapSize = 1024*1024; /* XX temp */
3541ae1b5e8Smrg    if (!pCir->IoMapSize)
3551ae1b5e8Smrg    	pCir->IoMapSize = 0x4000;	/* 16K for moment */
35676888252Smrg    if (!CirMapMem(pCir, pScrn->scrnIndex))
35776888252Smrg	return 0;
35876888252Smrg
35976888252Smrg    /* The 754x supports MMIO for the BitBlt engine but
36076888252Smrg       not for the VGA registers */
36176888252Smrg    switch (pCir->Chipset)
36276888252Smrg    {
36376888252Smrg    case PCI_CHIP_GD7548:
36476888252Smrg      break;
36576888252Smrg    default:
36676888252Smrg      if (pCir->UseMMIO)
36776888252Smrg	vgaHWSetMmioFuncs(hwp, pCir->IOBase, -0x3C0);
36876888252Smrg    }
36976888252Smrg
37076888252Smrg    if (pCir->chip.alp->sr0f != (CARD32)-1) {
37176888252Smrg	from = X_CONFIG;
37276888252Smrg	hwp->writeSeq(hwp, 0x0F, pCir->chip.alp->sr0f);
37376888252Smrg    } else {
37476888252Smrg	from = X_PROBED;
37576888252Smrg	pCir->chip.alp->sr0f = hwp->readSeq(hwp, 0x0F);
37676888252Smrg    }
37776888252Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 1 is 0x%02X\n",
37876888252Smrg	       (unsigned int)pCir->chip.alp->sr0f);
37976888252Smrg
38076888252Smrg    switch (pCir->Chipset) {
38176888252Smrg    case PCI_CHIP_GD5430:
38276888252Smrg/*  case PCI_CHIP_GD5440: */
38376888252Smrg	switch (pCir->chip.alp->sr0f & 0x18) {
38476888252Smrg	case 0x08:
38576888252Smrg	    videoram =  512;
38676888252Smrg	    break;
38776888252Smrg	case 0x10:
38876888252Smrg	    videoram = 1024;
38976888252Smrg	    break;
39076888252Smrg	case 0x18:
39176888252Smrg	    videoram = 2048;
39276888252Smrg	    break;
39376888252Smrg	}
39476888252Smrg	break;
39576888252Smrg
39676888252Smrg    case PCI_CHIP_GD5434_4:
39776888252Smrg    case PCI_CHIP_GD5434_8:
39876888252Smrg    case PCI_CHIP_GD5436:
39976888252Smrg	switch (pCir->chip.alp->sr0f & 0x18) {
40076888252Smrg	case 0x10:
40176888252Smrg	    videoram = 1024;
40276888252Smrg	    break;
40376888252Smrg	case 0x18:
40476888252Smrg	    videoram = 2048;
40576888252Smrg	    if (pCir->chip.alp->sr0f & 0x80)
40676888252Smrg		videoram = 4096;
40776888252Smrg	    break;
40876888252Smrg	}
40976888252Smrg
41076888252Smrg    case PCI_CHIP_GD5446:
41176888252Smrg	videoram = 1024;
41276888252Smrg
41376888252Smrg	if (pCir->chip.alp->sr17 != (CARD32)-1) {
41476888252Smrg	    from = X_CONFIG;
41576888252Smrg	    hwp->writeSeq(hwp, 0x17, pCir->chip.alp->sr17);
41676888252Smrg	} else {
41776888252Smrg	    from = X_PROBED;
41876888252Smrg	    pCir->chip.alp->sr17 = hwp->readSeq(hwp, 0x17);
41976888252Smrg	}
42076888252Smrg	xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 2 is 0x%02X\n",
42176888252Smrg		   (unsigned int)pCir->chip.alp->sr17);
42276888252Smrg
42376888252Smrg	if ((pCir->chip.alp->sr0f & 0x18) == 0x18) {
42476888252Smrg	    if (pCir->chip.alp->sr0f & 0x80) {
42576888252Smrg		if (pCir->chip.alp->sr17 & 0x80)
42676888252Smrg		    videoram = 2048;
42776888252Smrg		else if (pCir->chip.alp->sr17 & 0x02)
42876888252Smrg		    videoram = 3072;
42976888252Smrg		else
43076888252Smrg		    videoram = 4096;
43176888252Smrg	    } else {
43276888252Smrg		if ((pCir->chip.alp->sr17 & 80) == 0)
43376888252Smrg		    videoram = 2048;
43476888252Smrg	    }
43576888252Smrg	}
43676888252Smrg	break;
43776888252Smrg
43876888252Smrg    case PCI_CHIP_GD5480:
43976888252Smrg	if (pCir->chip.alp->sr17 != (CARD32)-1) {
44076888252Smrg	    from = X_CONFIG;
44176888252Smrg	    hwp->writeSeq(hwp, 0x17, pCir->chip.alp->sr17);
44276888252Smrg	} else {
44376888252Smrg	    from = X_PROBED;
44476888252Smrg	    pCir->chip.alp->sr17 = hwp->readSeq(hwp, 0x17);
44576888252Smrg	}
44676888252Smrg	xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 2 is 0x%02X\n",
44776888252Smrg		   (unsigned int)pCir->chip.alp->sr17);
44876888252Smrg	videoram = 1024;
44976888252Smrg	if ((pCir->chip.alp->sr0f & 0x18) == 0x18) {	/* 2 or 4 MB */
45076888252Smrg	    videoram = 2048;
45176888252Smrg	    if (pCir->chip.alp->sr0f & 0x80)	/* Second bank enable */
45276888252Smrg		videoram = 4096;
45376888252Smrg	}
45476888252Smrg	if (pCir->chip.alp->sr17 & 0x80)
45576888252Smrg	    videoram <<= 1;
45676888252Smrg	break;
45776888252Smrg
45876888252Smrg    case PCI_CHIP_GD7548:
45976888252Smrg	videoram = 1024;
46076888252Smrg	switch (pCir->chip.alp->sr0f & 0x90) {
46176888252Smrg		case 0x10:
46276888252Smrg			/* TODO: 2 256K X 16 DRAMs (1024) or 4 512K X 8 DRAMs (2048)? */
46376888252Smrg			break;
46476888252Smrg		case 0x90:
46576888252Smrg			videoram <<= 1;
46676888252Smrg			break;
46776888252Smrg	}
46876888252Smrg	break;
46976888252Smrg    }
47076888252Smrg
47176888252Smrg    /* UNMap the Alp memory and MMIO areas */
47276888252Smrg    if (!CirUnmapMem(pCir, pScrn->scrnIndex))
47376888252Smrg	return 0;
47476888252Smrg    vgaHWSetStdFuncs(hwp);
47576888252Smrg
47676888252Smrg    return videoram;
47776888252Smrg}
47876888252Smrg
47976888252Smrg
48076888252Smrg/*
48176888252Smrg * GetAccelPitchValues -
48276888252Smrg *
48376888252Smrg * This function returns a list of display width (pitch) values that can
48476888252Smrg * be used in accelerated mode.
48576888252Smrg */
48676888252Smrgstatic int *
48776888252SmrgGetAccelPitchValues(ScrnInfoPtr pScrn)
48876888252Smrg{
48976888252Smrg	int *linePitches = NULL;
49076888252Smrg	int i, n = 0;
49176888252Smrg	CirPtr pCir = CIRPTR(pScrn);
49276888252Smrg
49376888252Smrg	/* XXX ajv - 512, 576, and 1536 may not be supported
49476888252Smrg	   line pitches. see sdk pp 4-59 for more
49576888252Smrg	   details. Why anyone would want less than 640 is
49676888252Smrg	   bizarre. (maybe lots of pixels tall?) */
49776888252Smrg
49876888252Smrg	/* The only line pitches the accelerator supports */
49976888252Smrg#if 1
50076888252Smrg	int accelWidths[] = { 640, 768, 800, 960, 1024, 1152, 1280,
50176888252Smrg							1600, 1920, 2048, 0 };
50276888252Smrg#else
50376888252Smrg	int accelWidths[] = { 512, 576, 640, 768, 800, 960, 1024, 1152,
50476888252Smrg							1280, 1536, 1600, 1920, 2048, 0 };
50576888252Smrg#endif
50676888252Smrg
50776888252Smrg	for (i = 0; accelWidths[i] != 0; i++) {
50876888252Smrg		if (accelWidths[i] % pCir->Rounding == 0) {
50976888252Smrg			n++;
51076888252Smrg			linePitches = xnfrealloc(linePitches, n * sizeof(int));
51176888252Smrg			linePitches[n - 1] = accelWidths[i];
51276888252Smrg		}
51376888252Smrg	}
51476888252Smrg	/* Mark the end of the list */
51576888252Smrg	if (n > 0) {
51676888252Smrg		linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
51776888252Smrg		linePitches[n] = 0;
51876888252Smrg	}
51976888252Smrg	return linePitches;
52076888252Smrg}
52176888252Smrg
52276888252Smrg
52376888252Smrg/* Mandatory */
52476888252SmrgBool
52576888252SmrgAlpPreInit(ScrnInfoPtr pScrn, int flags)
52676888252Smrg{
52776888252Smrg	CirPtr pCir;
52876888252Smrg	vgaHWPtr hwp;
52976888252Smrg	MessageType from, from1;
53076888252Smrg	int i;
5311ae1b5e8Smrg	int depth_flags;
53276888252Smrg	ClockRangePtr clockRanges;
53376888252Smrg	char *s;
53476888252Smrg 	xf86Int10InfoPtr pInt = NULL;
53576888252Smrg
53676888252Smrg	if (flags & PROBE_DETECT)  {
53776888252Smrg	  cirProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index );
53876888252Smrg	  return TRUE;
53976888252Smrg	}
54076888252Smrg
54176888252Smrg#ifdef ALP_DEBUG
54276888252Smrg	ErrorF("AlpPreInit\n");
54376888252Smrg#endif
54476888252Smrg
54576888252Smrg	/* Check the number of entities, and fail if it isn't one. */
54676888252Smrg	if (pScrn->numEntities != 1)
54776888252Smrg		return FALSE;
54876888252Smrg
54976888252Smrg	if (!xf86LoadSubModule(pScrn, "vgahw"))
55076888252Smrg		return FALSE;
55176888252Smrg
55276888252Smrg	xf86LoaderReqSymLists(vgahwSymbols, NULL);
55376888252Smrg
55476888252Smrg	/*
55576888252Smrg	 * Allocate a vgaHWRec
55676888252Smrg	 */
55776888252Smrg	if (!vgaHWGetHWRec(pScrn))
55876888252Smrg		return FALSE;
55976888252Smrg	hwp = VGAHWPTR(pScrn);
56076888252Smrg	vgaHWGetIOBase(hwp);
56176888252Smrg
56276888252Smrg	/* Allocate the AlpRec driverPrivate */
56376888252Smrg	if (!AlpGetRec(pScrn))
56476888252Smrg		return FALSE;
56576888252Smrg
56676888252Smrg	pCir = CIRPTR(pScrn);
56776888252Smrg	pCir->pScrn = pScrn;
56876888252Smrg	pCir->PIOReg = hwp->PIOOffset + 0x3CE;
56976888252Smrg
57076888252Smrg	/* Get the entity, and make sure it is PCI. */
57176888252Smrg	pCir->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
57276888252Smrg	if (pCir->pEnt->location.type != BUS_PCI) {
57376888252Smrg		xfree(pCir->pEnt);
57476888252Smrg		return FALSE;
57576888252Smrg	}
57676888252Smrg
57776888252Smrg	pCir->Chipset = pCir->pEnt->chipset;
57876888252Smrg	/* Find the PCI info for this screen */
57976888252Smrg	pCir->PciInfo = xf86GetPciInfoForEntity(pCir->pEnt->index);
5801ae1b5e8Smrg	pCir->PciTag = pciTag(PCI_DEV_BUS(pCir->PciInfo),
5811ae1b5e8Smrg			      PCI_DEV_DEV(pCir->PciInfo),
5821ae1b5e8Smrg			      PCI_DEV_FUNC(pCir->PciInfo));
58376888252Smrg
58476888252Smrg    if (xf86LoadSubModule(pScrn, "int10")) {
58576888252Smrg	xf86LoaderReqSymLists(int10Symbols,NULL);
58676888252Smrg	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n");
58776888252Smrg	pInt = xf86InitInt10(pCir->pEnt->index);
58876888252Smrg	xf86FreeInt10(pInt);
58976888252Smrg	/*
59076888252Smrg	 * This is a hack: We restore the PCI base regs as some Colorgraphic
59176888252Smrg	 * BIOSes tend to mess them up
59276888252Smrg	 */
5931ae1b5e8Smrg
5941ae1b5e8Smrg	PCI_WRITE_LONG(pCir->PciInfo, PCI_REGION_BASE(pCir->PciInfo, 0, REGION_MEM), 0x10);
5951ae1b5e8Smrg	PCI_WRITE_LONG(pCir->PciInfo, PCI_REGION_BASE(pCir->PciInfo, 1, REGION_MEM), 0x14);
59676888252Smrg
59776888252Smrg    }
59876888252Smrg
59976888252Smrg    /* Set pScrn->monitor */
60076888252Smrg	pScrn->monitor = pScrn->confScreen->monitor;
60176888252Smrg
6021ae1b5e8Smrg	/* 32bpp only works on 5480 and 7548 */
6031ae1b5e8Smrg	depth_flags = Support24bppFb;
6041ae1b5e8Smrg	if (pCir->Chipset == PCI_CHIP_GD5480 || pCir->Chipset ==PCI_CHIP_GD7548)
6051ae1b5e8Smrg	    depth_flags |= Support32bppFb |
6061ae1b5e8Smrg			   SupportConvert32to24 |
6071ae1b5e8Smrg			   PreferConvert32to24;
60876888252Smrg	/*
60976888252Smrg	 * The first thing we should figure out is the depth, bpp, etc.
61076888252Smrg	 * We support both 24bpp and 32bpp layouts, so indicate that.
61176888252Smrg	 */
6121ae1b5e8Smrg	if (!xf86SetDepthBpp(pScrn, 0, 0, 24, depth_flags)) {
61376888252Smrg		return FALSE;
61476888252Smrg	} else {
61576888252Smrg		/* Check that the returned depth is one we support */
61676888252Smrg		switch (pScrn->depth) {
61776888252Smrg		case 1:
61876888252Smrg		case 4:
61976888252Smrg		case 8:
62076888252Smrg		case 15:
62176888252Smrg		case 16:
62276888252Smrg		case 24:
62376888252Smrg			/* OK */
62476888252Smrg			break;
62576888252Smrg		default:
62676888252Smrg			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
62776888252Smrg				"Given depth (%d) is not supported by this driver\n",
62876888252Smrg				pScrn->depth);
62976888252Smrg			return FALSE;
63076888252Smrg		}
63176888252Smrg	}
63276888252Smrg	xf86PrintDepthBpp(pScrn);
63376888252Smrg
63476888252Smrg	/* Get the depth24 pixmap format */
63576888252Smrg	if (pScrn->depth == 24 && pix24bpp == 0)
63676888252Smrg		pix24bpp = xf86GetBppFromDepth(pScrn, 24);
63776888252Smrg
63876888252Smrg	/*
63976888252Smrg	 * This must happen after pScrn->display has been set because
64076888252Smrg	 * xf86SetWeight references it.
64176888252Smrg	 */
64276888252Smrg	if (pScrn->depth > 8) {
64376888252Smrg		/* The defaults are OK for us */
64476888252Smrg		rgb zeros = {0, 0, 0};
64576888252Smrg
64676888252Smrg		if (!xf86SetWeight(pScrn, zeros, zeros)) {
64776888252Smrg			return FALSE;
64876888252Smrg		} else {
64976888252Smrg			/* XXX check that weight returned is supported */
65076888252Smrg			;
65176888252Smrg		}
65276888252Smrg	}
65376888252Smrg
65476888252Smrg	if (!xf86SetDefaultVisual(pScrn, -1)) {
65576888252Smrg		return FALSE;
65676888252Smrg	}
65776888252Smrg	/* Collect all of the relevant option flags (fill in pScrn->options) */
65876888252Smrg	xf86CollectOptions(pScrn, NULL);
65976888252Smrg
66076888252Smrg	/* Process the options */
66176888252Smrg	if (!(pCir->Options = xalloc(sizeof(CirOptions))))
66276888252Smrg		return FALSE;
66376888252Smrg	memcpy(pCir->Options, CirOptions, sizeof(CirOptions));
66476888252Smrg	xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCir->Options);
66576888252Smrg
66676888252Smrg	if (!xf86IsPrimaryPci(pCir->PciInfo)
66776888252Smrg	    && !(pInt || (xf86IsOptionSet(pCir->Options,OPTION_MEMCFG1)
66876888252Smrg			   && xf86IsOptionSet(pCir->Options,OPTION_MEMCFG2))))
66976888252Smrg	    return FALSE;
67076888252Smrg
67176888252Smrg	if (pScrn->depth == 8)
67276888252Smrg	    pScrn->rgbBits = 6;
67376888252Smrg
67476888252Smrg	from = X_DEFAULT;
67576888252Smrg	pCir->HWCursor = FALSE;
67676888252Smrg	if (xf86GetOptValBool(pCir->Options, OPTION_HW_CURSOR, &pCir->HWCursor))
67776888252Smrg		from = X_CONFIG;
67876888252Smrg
67976888252Smrg	xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
68076888252Smrg		pCir->HWCursor ? "HW" : "SW");
68176888252Smrg	if (xf86ReturnOptValBool(pCir->Options, OPTION_NOACCEL, FALSE)) {
68276888252Smrg		pCir->NoAccel = TRUE;
68376888252Smrg		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
68476888252Smrg	}
68576888252Smrg	if(pScrn->bitsPerPixel < 8) {
68676888252Smrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
68776888252Smrg			"Cannot use accelerations in less than 8 bpp\n");
68876888252Smrg		pCir->NoAccel = TRUE;
68976888252Smrg	}
69076888252Smrg
69176888252Smrg	/*
69276888252Smrg	 * Set the ChipRev, allowing config file entries to
69376888252Smrg	 * override.
69476888252Smrg	 */
69576888252Smrg	if (pCir->pEnt->device->chipRev >= 0) {
69676888252Smrg		pCir->ChipRev = pCir->pEnt->device->chipRev;
69776888252Smrg		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
69876888252Smrg			pCir->ChipRev);
69976888252Smrg	} else {
7001ae1b5e8Smrg 	        pCir->ChipRev = PCI_DEV_REVISION(pCir->PciInfo);
70176888252Smrg	}
70276888252Smrg
70376888252Smrg	/* Find the frame buffer base address */
70476888252Smrg	if (pCir->pEnt->device->MemBase != 0) {
70576888252Smrg	    if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->MemBase)) {
70676888252Smrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
70776888252Smrg			   "MemBase 0x%08lX doesn't match any PCI base register.\n",
70876888252Smrg			   pCir->pEnt->device->MemBase);
70976888252Smrg		return FALSE;
71076888252Smrg		}
71176888252Smrg		pCir->FbAddress = pCir->pEnt->device->MemBase;
71276888252Smrg		from = X_CONFIG;
71376888252Smrg	} else {
7141ae1b5e8Smrg		if (PCI_REGION_BASE(pCir->PciInfo, 0, REGION_MEM) != 0) {
71576888252Smrg			/* 5446B and 5480 use mask of 0xfe000000.
71676888252Smrg			   5446A uses 0xff000000. */
7171ae1b5e8Smrg			pCir->FbAddress = PCI_REGION_BASE(pCir->PciInfo, 0, REGION_MEM) & 0xff000000;
71876888252Smrg			from = X_PROBED;
71976888252Smrg		} else {
72076888252Smrg			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
72176888252Smrg				"No valid FB address in PCI config space\n");
72276888252Smrg			AlpFreeRec(pScrn);
72376888252Smrg			return FALSE;
72476888252Smrg		}
72576888252Smrg	}
72676888252Smrg	xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
72776888252Smrg		(unsigned long)pCir->FbAddress);
72876888252Smrg
72976888252Smrg	if (pCir->pEnt->device->IOBase != 0) {
73076888252Smrg	    /* Require that the config file value matches one of the PCI values. */
73176888252Smrg	    if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->IOBase)) {
73276888252Smrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
73376888252Smrg			   "IOBase 0x%08lX doesn't match any PCI base register.\n",
73476888252Smrg			   pCir->pEnt->device->IOBase);
73576888252Smrg		return FALSE;
73676888252Smrg	    }
73776888252Smrg	    pCir->IOAddress = pCir->pEnt->device->IOBase;
73876888252Smrg		from = X_CONFIG;
73976888252Smrg	} else {
7401ae1b5e8Smrg		if (PCI_REGION_BASE(pCir->PciInfo, 1, REGION_MEM) != 0) {
7411ae1b5e8Smrg			pCir->IOAddress = PCI_REGION_BASE(pCir->PciInfo, 1, REGION_MEM) & 0xfffff000;
7421ae1b5e8Smrg			pCir->IoMapSize = PCI_REGION_SIZE(pCir->PciInfo, 1);
74376888252Smrg			from = X_PROBED;
74476888252Smrg		} else {
74576888252Smrg			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
74676888252Smrg				"No valid MMIO address in PCI config space\n");
74776888252Smrg			/* 5446 rev A do not use a separate MMIO segment */
74876888252Smrg			/* We do not really need that YET. */
74976888252Smrg		}
75076888252Smrg	}
75176888252Smrg
75276888252Smrg	/* User options can override the MMIO default */
75376888252Smrg#if 0
75476888252Smrg	/* Will we ever support MMIO on 5446A or older? */
75576888252Smrg	if (xf86ReturnOptValBool(pCir->Options, OPTION_MMIO, FALSE)) {
75676888252Smrg		pCir->UseMMIO = TRUE;
75776888252Smrg		from = X_CONFIG;
75876888252Smrg	}
75976888252Smrg#endif
76076888252Smrg	if (!xf86ReturnOptValBool(pCir->Options, OPTION_MMIO, TRUE)) {
76176888252Smrg		pCir->UseMMIO = FALSE;
76276888252Smrg		from1 = X_CONFIG;
76376888252Smrg 	} else if (pCir->IOAddress) {
76476888252Smrg 	  /* Default to MMIO if we have a separate IOAddress and
76576888252Smrg 	       not in monochrome mode (IO 0x3Bx is not relocated!) */
76676888252Smrg 	    if (pScrn->bitsPerPixel != 1) {
76776888252Smrg 	        pCir->UseMMIO = TRUE;
76876888252Smrg 		from1 = X_PROBED;
76976888252Smrg 	    } else {
77076888252Smrg 	        pCir->UseMMIO = FALSE;
77176888252Smrg 	        from1 = X_PROBED;
77276888252Smrg 	    }
77376888252Smrg 	} else {
77476888252Smrg 	    pCir->UseMMIO = FALSE;
77576888252Smrg 	    from1 = X_PROBED;
77676888252Smrg 	}
77776888252Smrg
77876888252Smrg 	if (pCir->UseMMIO) {
77976888252Smrg 		xf86DrvMsg(pScrn->scrnIndex, from1, "Using MMIO\n");
78076888252Smrg 		xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
78176888252Smrg 			(unsigned long)pCir->IOAddress);
78276888252Smrg 	} else
78376888252Smrg 	    xf86DrvMsg(pScrn->scrnIndex, from1, "Not Using MMIO\n");
78476888252Smrg
78576888252Smrg     /*
78676888252Smrg      * XXX Check if this is correct
78776888252Smrg      */
78876888252Smrg     if (!pCir->UseMMIO) {
78976888252Smrg         pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT | RAC_FB;
79076888252Smrg         xf86SetOperatingState(resVgaMem, pCir->pEnt->index, ResUnusedOpr);
79176888252Smrg     } else {
79276888252Smrg         xf86SetOperatingState(resVga, pCir->pEnt->index, ResUnusedOpr);
79376888252Smrg     }
79476888252Smrg
79576888252Smrg     /* Register the PCI-assigned resources. */
79676888252Smrg     if (xf86RegisterResources(pCir->pEnt->index, NULL, ResExclusive)) {
79776888252Smrg	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
79876888252Smrg		    "xf86RegisterResources() found resource conflicts\n");
79976888252Smrg	 return FALSE;
80076888252Smrg     }
80176888252Smrg
80276888252Smrg     if (!xf86LoadSubModule(pScrn, "i2c")) {
80376888252Smrg	 AlpFreeRec(pScrn);
80476888252Smrg 	return FALSE;
80576888252Smrg     }
80676888252Smrg     xf86LoaderReqSymLists(i2cSymbols,NULL);
80776888252Smrg
80876888252Smrg     if (!xf86LoadSubModule(pScrn, "ddc")) {
80976888252Smrg 	AlpFreeRec(pScrn);
81076888252Smrg 	return FALSE;
81176888252Smrg     }
81276888252Smrg     xf86LoaderReqSymLists(ddcSymbols, NULL);
81376888252Smrg
81476888252Smrg     if(!AlpI2CInit(pScrn)) {
81576888252Smrg         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
81676888252Smrg             "I2C initialization failed\n");
81776888252Smrg     }
81876888252Smrg     else
81976888252Smrg 	xf86SetDDCproperties(pScrn,xf86PrintEDID(
82076888252Smrg 	    xf86DoEDID_DDC2(pScrn->scrnIndex,pCir->I2CPtr1)));
82176888252Smrg
82276888252Smrg     /* Probe the possible LCD display */
82376888252Smrg     AlpProbeLCD(pScrn);
82476888252Smrg
82576888252Smrg#ifdef CIRPROBEI2C
82676888252Smrg     CirProbeI2C(pScrn->scrnIndex);
82776888252Smrg#endif
82876888252Smrg
82976888252Smrg     /* The gamma fields must be initialised when using the new cmap code */
83076888252Smrg     if (pScrn->depth > 1) {
83176888252Smrg 	Gamma zeros = {0.0, 0.0, 0.0};
83276888252Smrg
83376888252Smrg 	if (!xf86SetGamma(pScrn, zeros))
83476888252Smrg 	    return FALSE;
83576888252Smrg     }
83676888252Smrg
83776888252Smrg	/* XXX If UseMMIO == TRUE and for any reason we cannot do MMIO,
83876888252Smrg	   abort here */
83976888252Smrg
84076888252Smrg	if (xf86GetOptValBool(pCir->Options,
84176888252Smrg			      OPTION_SHADOW_FB,&pCir->shadowFB))
84276888252Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n",
84376888252Smrg		       pCir->shadowFB ? "enabled" : "disabled");
84476888252Smrg
84576888252Smrg	if ((s = xf86GetOptValString(pCir->Options, OPTION_ROTATE))) {
84676888252Smrg	    if(!xf86NameCmp(s, "CW")) {
84776888252Smrg		/* accel is disabled below for shadowFB */
84876888252Smrg		pCir->shadowFB = TRUE;
84976888252Smrg		pCir->rotate = 1;
85076888252Smrg		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
85176888252Smrg			   "Rotating screen clockwise - acceleration disabled\n");
85276888252Smrg	    } else if(!xf86NameCmp(s, "CCW")) {
85376888252Smrg		pCir->shadowFB = TRUE;
85476888252Smrg		pCir->rotate = -1;
85576888252Smrg		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,  "Rotating screen"
85676888252Smrg			   "counter clockwise - acceleration disabled\n");
85776888252Smrg	    } else {
85876888252Smrg		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
85976888252Smrg			   "value for Option \"Rotate\"\n", s);
86076888252Smrg		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
86176888252Smrg			   "Valid options are \"CW\" or \"CCW\"\n");
86276888252Smrg	    }
86376888252Smrg	}
86476888252Smrg	if (pCir->shadowFB && (pScrn->depth < 8)) {
86576888252Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
86676888252Smrg		       "shadowFB not supported at this depth.\n");
86776888252Smrg	    pCir->shadowFB = FALSE;
86876888252Smrg	    pCir->rotate = 0;
86976888252Smrg	}
87076888252Smrg
87176888252Smrg	if (pCir->shadowFB && !pCir->NoAccel) {
87276888252Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
87376888252Smrg		       "HW acceleration not supported with \"shadowFB\".\n");
87476888252Smrg	    pCir->NoAccel = TRUE;
87576888252Smrg	}
87676888252Smrg
87776888252Smrg	if (pCir->rotate && pCir->HWCursor) {
87876888252Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
87976888252Smrg		       "HW cursor not supported with \"rotate\".\n");
88076888252Smrg	    pCir->HWCursor = FALSE;
88176888252Smrg	}
88276888252Smrg
88376888252Smrg	/* XXX We do not know yet how to configure memory on this card.
88476888252Smrg	   Use options MemCFG1 and MemCFG2 to set registers SR0F and
88576888252Smrg	   SR17 before trying to count ram size. */
88676888252Smrg
88776888252Smrg	pCir->chip.alp->sr0f = (CARD32)-1;
88876888252Smrg	pCir->chip.alp->sr17 = (CARD32)-1;
88976888252Smrg
89076888252Smrg	(void) xf86GetOptValULong(pCir->Options, OPTION_MEMCFG1, (unsigned long *)&pCir->chip.alp->sr0f);
89176888252Smrg	(void) xf86GetOptValULong(pCir->Options, OPTION_MEMCFG2, (unsigned long *)&pCir->chip.alp->sr17);
89276888252Smrg	/*
89376888252Smrg	 * If the user has specified the amount of memory in the XF86Config
89476888252Smrg	 * file, we respect that setting.
89576888252Smrg	 */
89676888252Smrg	if (pCir->pEnt->device->videoRam != 0) {
89776888252Smrg		pScrn->videoRam = pCir->pEnt->device->videoRam;
89876888252Smrg		pCir->IoMapSize = 0x4000;	/* 16K for moment */
89976888252Smrg		from = X_CONFIG;
90076888252Smrg	} else {
90176888252Smrg		pScrn->videoRam = AlpCountRam(pScrn);
90276888252Smrg		from = X_PROBED;
90376888252Smrg	}
90476888252Smrg	xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", pScrn->videoRam);
90576888252Smrg
90676888252Smrg	pCir->FbMapSize = pScrn->videoRam * 1024;
90776888252Smrg
90876888252Smrg	/* properties */
90976888252Smrg	pCir->properties = 0;
91076888252Smrg
91176888252Smrg	if ((pCir->chip.alp->sr0f & 0x18) > 0x8)
91276888252Smrg	  pCir->properties |= HWCUR64;
91376888252Smrg
91476888252Smrg	switch (pCir->Chipset) {
91576888252Smrg        case PCI_CHIP_GD7548:
91676888252Smrg	  pCir->properties |= HWCUR64;
91776888252Smrg	  pCir->properties |= ACCEL_AUTOSTART;
91876888252Smrg	  break;
91976888252Smrg	case PCI_CHIP_GD5436:
92076888252Smrg	case PCI_CHIP_GD5480:
92176888252Smrg	  pCir->properties |= ACCEL_AUTOSTART;
92276888252Smrg	  break;
92376888252Smrg	default:
92476888252Smrg	  break;
92576888252Smrg	}
92676888252Smrg
92776888252Smrg     /* We use a programmable clock */
92876888252Smrg     pScrn->progClock = TRUE;
92976888252Smrg
93076888252Smrg	/* XXX Set HW cursor use */
93176888252Smrg
93276888252Smrg	/* Set the min pixel clock */
93376888252Smrg	pCir->MinClock = 12000;	/* XXX Guess, need to check this */
93476888252Smrg	xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
93576888252Smrg		pCir->MinClock / 1000);
93676888252Smrg	/*
93776888252Smrg	 * If the user has specified ramdac speed in the XF86Config
93876888252Smrg	 * file, we respect that setting.
93976888252Smrg	 */
94076888252Smrg	if (pCir->pEnt->device->dacSpeeds[0]) {
94176888252Smrg		ErrorF("Do not specily a Clocks line for Cirrus chips\n");
94276888252Smrg		return FALSE;
94376888252Smrg	} else {
94476888252Smrg		int speed;
94576888252Smrg		int *p = NULL;
94676888252Smrg		switch (pCir->Chipset) {
94776888252Smrg		case PCI_CHIP_GD5430:
94876888252Smrg		case PCI_CHIP_GD5434_4:
94976888252Smrg		case PCI_CHIP_GD5434_8:
95076888252Smrg		case PCI_CHIP_GD5436:
95176888252Smrg	/*	case PCI_CHIP_GD5440: */
95276888252Smrg			p = gd5430_MaxClocks;
95376888252Smrg			break;
95476888252Smrg		case PCI_CHIP_GD5446:
95576888252Smrg			p = gd5446_MaxClocks;
95676888252Smrg			break;
95776888252Smrg		case PCI_CHIP_GD5480:
95876888252Smrg			p = gd5480_MaxClocks;
95976888252Smrg			break;
96076888252Smrg		case PCI_CHIP_GD7548:
96176888252Smrg		        p = gd7548_MaxClocks;
96276888252Smrg                        break;
96376888252Smrg		}
96476888252Smrg		if (!p)
96576888252Smrg			return FALSE;
96676888252Smrg		switch(pScrn->bitsPerPixel) {
96776888252Smrg		case 1:
96876888252Smrg		case 4:
96976888252Smrg			speed = p[0];
97076888252Smrg			break;
97176888252Smrg		case 8:
97276888252Smrg			speed = p[1];
97376888252Smrg			break;
97476888252Smrg		case 15:
97576888252Smrg		case 16:
97676888252Smrg			speed = p[2];
97776888252Smrg			break;
97876888252Smrg		case 24:
97976888252Smrg			speed = p[3];
98076888252Smrg			break;
98176888252Smrg		case 32:
98276888252Smrg			speed = p[4];
98376888252Smrg			break;
98476888252Smrg		default:
98576888252Smrg			/* Should not get here */
98676888252Smrg			speed = 0;
98776888252Smrg			break;
98876888252Smrg		}
98976888252Smrg		pCir->MaxClock = speed;
99076888252Smrg		from = X_PROBED;
99176888252Smrg	}
99276888252Smrg	xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
99376888252Smrg	pCir->MaxClock / 1000);
99476888252Smrg
99576888252Smrg	/*
99676888252Smrg	 * Setup the ClockRanges, which describe what clock ranges are available,
99776888252Smrg	 * and what sort of modes they can be used for.
99876888252Smrg	 */
99976888252Smrg	clockRanges = xnfcalloc(sizeof(ClockRange), 1);
100076888252Smrg	clockRanges->next = NULL;
100176888252Smrg	clockRanges->minClock = pCir->MinClock;
100276888252Smrg	clockRanges->maxClock = pCir->MaxClock;
100376888252Smrg	clockRanges->clockIndex = -1;		/* programmable */
100476888252Smrg	clockRanges->interlaceAllowed = FALSE;	/* XXX check this */
100576888252Smrg	clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
100676888252Smrg	clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
100776888252Smrg	clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
100876888252Smrg	clockRanges->ClockMulFactor = 1;
100976888252Smrg	clockRanges->ClockDivFactor = 1;
101076888252Smrg	clockRanges->PrivFlags = 0;
101176888252Smrg
101276888252Smrg	switch (pCir->Chipset)
101376888252Smrg	{
101476888252Smrg	case PCI_CHIP_GD7548:
101576888252Smrg	  pCir->Rounding = 1;
101676888252Smrg	  break;
101776888252Smrg
101876888252Smrg	default:
101976888252Smrg	  pCir->Rounding = 128 >> pCir->BppShift;
102076888252Smrg        }
102176888252Smrg
102276888252Smrg#if 0
102376888252Smrg	if (pCir->Chipset != PCI_CHIP_GD5446 &&
102476888252Smrg		pCir->Chipset != PCI_CHIP_GD5480) {
102576888252Smrg		/* XXX Kludge */
102676888252Smrg		pCir->NoAccel = TRUE;
102776888252Smrg	}
102876888252Smrg#endif
102976888252Smrg
103076888252Smrg	/*
103176888252Smrg	 * xf86ValidateModes will check that the mode HTotal and VTotal values
103276888252Smrg	 * don't exceed the chipset's limit if pScrn->maxHValue and
103376888252Smrg	 * pScrn->maxVValue are set.  Since our AlpValidMode() already takes
103476888252Smrg	 * care of this, we don't worry about setting them here.
103576888252Smrg	 */
103676888252Smrg
103776888252Smrg	/* Select valid modes from those available */
103876888252Smrg	if (pCir->NoAccel) {
103976888252Smrg		/*
104076888252Smrg		 * XXX Assuming min pitch 256, max 2048
104176888252Smrg		 * XXX Assuming min height 128, max 2048
104276888252Smrg		 */
104376888252Smrg		i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
104476888252Smrg						pScrn->display->modes, clockRanges,
104576888252Smrg						NULL, 256, 2048,
104676888252Smrg						pCir->Rounding * pScrn->bitsPerPixel, 128, 2048,
104776888252Smrg						pScrn->display->virtualX,
104876888252Smrg						pScrn->display->virtualY,
104976888252Smrg						pCir->FbMapSize,
105076888252Smrg						LOOKUP_BEST_REFRESH);
105176888252Smrg	} else {
105276888252Smrg		/*
105376888252Smrg		 * XXX Assuming min height 128, max 2048
105476888252Smrg		 */
105576888252Smrg		i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
105676888252Smrg						pScrn->display->modes, clockRanges,
105776888252Smrg						GetAccelPitchValues(pScrn), 0, 0,
105876888252Smrg						pCir->Rounding * pScrn->bitsPerPixel, 128, 2048,
105976888252Smrg						pScrn->display->virtualX,
106076888252Smrg						pScrn->display->virtualY,
106176888252Smrg						pCir->FbMapSize,
106276888252Smrg						LOOKUP_BEST_REFRESH);
106376888252Smrg	}
106476888252Smrg	if (i == -1) {
106576888252Smrg		AlpFreeRec(pScrn);
106676888252Smrg		return FALSE;
106776888252Smrg	}
106876888252Smrg
106976888252Smrg	/* Prune the modes marked as invalid */
107076888252Smrg	xf86PruneDriverModes(pScrn);
107176888252Smrg
107276888252Smrg	if (i == 0 || pScrn->modes == NULL) {
107376888252Smrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
107476888252Smrg		AlpFreeRec(pScrn);
107576888252Smrg		return FALSE;
107676888252Smrg	}
107776888252Smrg
107876888252Smrg	/*
107976888252Smrg	 * Set the CRTC parameters for all of the modes based on the type
108076888252Smrg	 * of mode, and the chipset's interlace requirements.
108176888252Smrg	 *
108276888252Smrg	 * Calling this is required if the mode->Crtc* values are used by the
108376888252Smrg	 * driver and if the driver doesn't provide code to set them.  They
108476888252Smrg	 * are not pre-initialised at all.
108576888252Smrg	 */
108676888252Smrg	xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
108776888252Smrg
108876888252Smrg	/* Set the current mode to the first in the list */
108976888252Smrg	pScrn->currentMode = pScrn->modes;
109076888252Smrg
109176888252Smrg	/* Print the list of modes being used */
109276888252Smrg	xf86PrintModes(pScrn);
109376888252Smrg
109476888252Smrg	/* Set display resolution */
109576888252Smrg	xf86SetDpi(pScrn, 0, 0);
109676888252Smrg
109776888252Smrg	/* Load bpp-specific modules */
109876888252Smrg	switch (pScrn->bitsPerPixel) {
10991ae1b5e8Smrg#ifdef HAVE_XF1BPP
110076888252Smrg	case 1:
110176888252Smrg	    if (xf86LoadSubModule(pScrn, "xf1bpp") == NULL) {
110276888252Smrg	        AlpFreeRec(pScrn);
110376888252Smrg		return FALSE;
110476888252Smrg	    }
110576888252Smrg	    xf86LoaderReqSymbols("xf1bppScreenInit",NULL);
110676888252Smrg	    break;
11071ae1b5e8Smrg#endif
11081ae1b5e8Smrg#ifdef HAVE_XF4BPP
110976888252Smrg	case 4:
111076888252Smrg	    if (xf86LoadSubModule(pScrn, "xf4bpp") == NULL) {
111176888252Smrg	        AlpFreeRec(pScrn);
111276888252Smrg		return FALSE;
111376888252Smrg	    }
111476888252Smrg	    xf86LoaderReqSymbols("xf4bppScreenInit",NULL);
111576888252Smrg	    break;
11161ae1b5e8Smrg#endif
111776888252Smrg	case 8:
111876888252Smrg	case 16:
111976888252Smrg	case 24:
112076888252Smrg	case 32:
112176888252Smrg	    if (xf86LoadSubModule(pScrn, "fb") == NULL) {
112276888252Smrg	        AlpFreeRec(pScrn);
112376888252Smrg		return FALSE;
112476888252Smrg	    }
112576888252Smrg	    xf86LoaderReqSymLists(fbSymbols, NULL);
112676888252Smrg	    break;
112776888252Smrg	}
112876888252Smrg
112976888252Smrg	/* Load XAA if needed */
113076888252Smrg	if (!pCir->NoAccel) {
113176888252Smrg		if (!xf86LoadSubModule(pScrn, "xaa")) {
113276888252Smrg			AlpFreeRec(pScrn);
113376888252Smrg			return FALSE;
113476888252Smrg		}
113576888252Smrg		xf86LoaderReqSymLists(xaaSymbols, NULL);
113676888252Smrg	}
113776888252Smrg
113876888252Smrg	/* Load ramdac if needed */
113976888252Smrg	if (pCir->HWCursor) {
114076888252Smrg		if (!xf86LoadSubModule(pScrn, "ramdac")) {
114176888252Smrg			AlpFreeRec(pScrn);
114276888252Smrg			return FALSE;
114376888252Smrg		}
114476888252Smrg		xf86LoaderReqSymLists(ramdacSymbols, NULL);
114576888252Smrg	}
114676888252Smrg
114776888252Smrg	if (pCir->shadowFB) {
114876888252Smrg	    if (!xf86LoadSubModule(pScrn, "shadowfb")) {
114976888252Smrg		AlpFreeRec(pScrn);
115076888252Smrg		return FALSE;
115176888252Smrg	    }
115276888252Smrg	    xf86LoaderReqSymLists(shadowSymbols, NULL);
115376888252Smrg	}
115476888252Smrg
115576888252Smrg	return TRUE;
115676888252Smrg}
115776888252Smrg
115876888252Smrg/*
115976888252Smrg * This function saves the video state.
116076888252Smrg */
116176888252Smrgstatic void
116276888252SmrgAlpSave(ScrnInfoPtr pScrn)
116376888252Smrg{
116476888252Smrg	CirPtr pCir = CIRPTR(pScrn);
116576888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
116676888252Smrg
116776888252Smrg#ifdef ALP_DEBUG
116876888252Smrg	ErrorF("AlpSave\n");
116976888252Smrg#endif
117076888252Smrg	vgaHWSave(pScrn, &VGAHWPTR(pScrn)->SavedReg, VGA_SR_ALL);
117176888252Smrg
117276888252Smrg	pCir->chip.alp->ModeReg.ExtVga[CR1A] = pCir->chip.alp->SavedReg.ExtVga[CR1A] = hwp->readCrtc(hwp, 0x1A);
117376888252Smrg	pCir->chip.alp->ModeReg.ExtVga[CR1B] = pCir->chip.alp->SavedReg.ExtVga[CR1B] = hwp->readCrtc(hwp, 0x1B);
117476888252Smrg	pCir->chip.alp->ModeReg.ExtVga[CR1D] = pCir->chip.alp->SavedReg.ExtVga[CR1D] = hwp->readCrtc(hwp, 0x1D);
117576888252Smrg	pCir->chip.alp->ModeReg.ExtVga[SR07] = pCir->chip.alp->SavedReg.ExtVga[SR07] = hwp->readSeq(hwp, 0x07);
117676888252Smrg	pCir->chip.alp->ModeReg.ExtVga[SR0E] = pCir->chip.alp->SavedReg.ExtVga[SR0E] = hwp->readSeq(hwp, 0x0E);
117776888252Smrg	pCir->chip.alp->ModeReg.ExtVga[SR12] = pCir->chip.alp->SavedReg.ExtVga[SR12] = hwp->readSeq(hwp, 0x12);
117876888252Smrg	pCir->chip.alp->ModeReg.ExtVga[SR13] = pCir->chip.alp->SavedReg.ExtVga[SR13] = hwp->readSeq(hwp, 0x13);
117976888252Smrg	pCir->chip.alp->ModeReg.ExtVga[SR17] = pCir->chip.alp->SavedReg.ExtVga[SR17] = hwp->readSeq(hwp, 0x17);
118076888252Smrg	pCir->chip.alp->ModeReg.ExtVga[SR1E] = pCir->chip.alp->SavedReg.ExtVga[SR1E] = hwp->readSeq(hwp, 0x1E);
118176888252Smrg	pCir->chip.alp->ModeReg.ExtVga[SR21] = pCir->chip.alp->SavedReg.ExtVga[SR21] = hwp->readSeq(hwp, 0x21);
118276888252Smrg	pCir->chip.alp->ModeReg.ExtVga[SR2D] = pCir->chip.alp->SavedReg.ExtVga[SR2D] = hwp->readSeq(hwp, 0x2D);
118376888252Smrg	pCir->chip.alp->ModeReg.ExtVga[GR17] = pCir->chip.alp->SavedReg.ExtVga[GR17] = hwp->readGr(hwp, 0x17);
118476888252Smrg	pCir->chip.alp->ModeReg.ExtVga[GR18] = pCir->chip.alp->SavedReg.ExtVga[GR18] = hwp->readGr(hwp, 0x18);
118576888252Smrg	/* The first 4 reads are for the pixel mask register. After 4 times that
118676888252Smrg	   this register is accessed in succession reading/writing this address
118776888252Smrg	   accesses the HDR. */
118876888252Smrg	hwp->readDacMask(hwp);
118976888252Smrg	hwp->readDacMask(hwp);
119076888252Smrg	hwp->readDacMask(hwp);
119176888252Smrg	hwp->readDacMask(hwp);
119276888252Smrg	pCir->chip.alp->ModeReg.ExtVga[HDR] = pCir->chip.alp->SavedReg.ExtVga[HDR] = hwp->readDacMask(hwp);
119376888252Smrg}
119476888252Smrg
119576888252Smrg/* XXX */
119676888252Smrgstatic void
119776888252SmrgAlpFix1bppColorMap(ScrnInfoPtr pScrn)
119876888252Smrg{
119976888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
120076888252Smrg/* In 1 bpp we have color 0 at LUT 0 and color 1 at LUT 0x3f.
120176888252Smrg   This makes white and black look right (otherwise they were both
120276888252Smrg   black. I'm sure there's a better way to do that, just lazy to
120376888252Smrg   search the docs.  */
120476888252Smrg
120576888252Smrg	hwp->writeDacWriteAddr(hwp, 0x00);
120676888252Smrg	hwp->writeDacData(hwp, 0x00); hwp->writeDacData(hwp, 0x00); hwp->writeDacData(hwp, 0x00);
120776888252Smrg	hwp->writeDacWriteAddr(hwp, 0x3F);
120876888252Smrg	hwp->writeDacData(hwp, 0x3F); hwp->writeDacData(hwp, 0x3F); hwp->writeDacData(hwp, 0x3F);
120976888252Smrg}
121076888252Smrg
121176888252Smrgstatic void
121276888252SmrgalpRestore(vgaHWPtr hwp, AlpRegPtr cirReg)
121376888252Smrg{
121476888252Smrg    hwp->writeCrtc(hwp, 0x1A, cirReg->ExtVga[CR1A]);
121576888252Smrg    hwp->writeCrtc(hwp, 0x1B, cirReg->ExtVga[CR1B]);
121676888252Smrg    hwp->writeCrtc(hwp, 0x1D, cirReg->ExtVga[CR1D]);
121776888252Smrg    hwp->writeSeq(hwp, 0x07, cirReg->ExtVga[SR07]);
121876888252Smrg    hwp->writeSeq(hwp, 0x0E, cirReg->ExtVga[SR0E]);
121976888252Smrg    hwp->writeSeq(hwp, 0x12, cirReg->ExtVga[SR12]);
122076888252Smrg    hwp->writeSeq(hwp, 0x13, cirReg->ExtVga[SR13]);
122176888252Smrg    hwp->writeSeq(hwp, 0x17, cirReg->ExtVga[SR17]);
122276888252Smrg    hwp->writeSeq(hwp, 0x1E, cirReg->ExtVga[SR1E]);
122376888252Smrg    hwp->writeSeq(hwp, 0x21, cirReg->ExtVga[SR21]);
122476888252Smrg    hwp->writeSeq(hwp, 0x2D, cirReg->ExtVga[SR2D]);
122576888252Smrg    hwp->writeGr(hwp, 0x17, cirReg->ExtVga[GR17]);
122676888252Smrg    hwp->writeGr(hwp, 0x18, cirReg->ExtVga[GR18]);
122776888252Smrg    /* The first 4 reads are for the pixel mask register. After 4 times that
122876888252Smrg       this register is accessed in succession reading/writing this address
122976888252Smrg       accesses the HDR. */
123076888252Smrg    hwp->readDacMask(hwp);
123176888252Smrg    hwp->readDacMask(hwp);
123276888252Smrg    hwp->readDacMask(hwp);
123376888252Smrg    hwp->readDacMask(hwp);
123476888252Smrg    hwp->writeDacMask(hwp, cirReg->ExtVga[HDR ]);
123576888252Smrg}
123676888252Smrg
123776888252Smrg
123876888252Smrg/*
123976888252Smrg * Initialise a new mode.  This is currently still using the old
124076888252Smrg * "initialise struct, restore/write struct to HW" model.  That could
124176888252Smrg * be changed.
124276888252Smrg * Why?? (EE)
124376888252Smrg */
124476888252Smrg
124576888252Smrgstatic Bool
124676888252SmrgAlpModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
124776888252Smrg{
124876888252Smrg	vgaHWPtr hwp;
124976888252Smrg	CirPtr pCir;
125076888252Smrg	int depthcode;
125176888252Smrg	int width;
125276888252Smrg	Bool HDiv2 = FALSE, VDiv2 = FALSE;
125376888252Smrg
125476888252Smrg#ifdef ALP_DEBUG
125576888252Smrg	ErrorF("AlpModeInit %d bpp,   %d   %d %d %d %d   %d %d %d %d\n",
125676888252Smrg		pScrn->bitsPerPixel,
125776888252Smrg		mode->Clock,
125876888252Smrg		mode->HDisplay,
125976888252Smrg		mode->HSyncStart,
126076888252Smrg		mode->HSyncEnd,
126176888252Smrg		mode->HTotal,
126276888252Smrg		mode->VDisplay,
126376888252Smrg		mode->VSyncStart,
126476888252Smrg		mode->VSyncEnd,
126576888252Smrg		mode->VTotal);
126676888252Smrg
126776888252Smrg	ErrorF("AlpModeInit: depth %d bits\n", pScrn->depth);
126876888252Smrg#endif
126976888252Smrg
127076888252Smrg	pCir = CIRPTR(pScrn);
127176888252Smrg	hwp = VGAHWPTR(pScrn);
127276888252Smrg	vgaHWUnlock(hwp);
127376888252Smrg
127476888252Smrg	pCir->pitch = pScrn->displayWidth * pScrn->bitsPerPixel >> 3;
127576888252Smrg
127676888252Smrg	depthcode = pScrn->depth;
127776888252Smrg	if (pScrn->bitsPerPixel == 32)
127876888252Smrg		depthcode = 32;
127976888252Smrg
128076888252Smrg	if ((pCir->Chipset == PCI_CHIP_GD5480 && mode->Clock > 135100) ||
128176888252Smrg		(pCir->Chipset == PCI_CHIP_GD5446 && mode->Clock >  85500)) {
128276888252Smrg		/* The actual DAC register value is set later. */
128376888252Smrg		/* The CRTC is clocked at VCLK / 2, so we must half the */
128476888252Smrg		/* horizontal timings. */
128576888252Smrg		if (!mode->CrtcHAdjusted) {
128676888252Smrg			mode->CrtcHDisplay >>= 1;
128776888252Smrg			mode->CrtcHSyncStart >>= 1;
128876888252Smrg			mode->CrtcHTotal >>= 1;
128976888252Smrg			mode->CrtcHSyncEnd >>= 1;
129076888252Smrg			mode->SynthClock >>= 1;
129176888252Smrg			mode->CrtcHAdjusted = TRUE;
129276888252Smrg		}
129376888252Smrg		depthcode += 64;
129476888252Smrg		HDiv2 = TRUE;
129576888252Smrg	}
129676888252Smrg
129776888252Smrg	if (mode->VTotal >= 1024 && !(mode->Flags & V_INTERLACE)) {
129876888252Smrg		/* For non-interlaced vertical timing >= 1024, the vertical timings */
129976888252Smrg		/* are divided by 2 and VGA CRTC 0x17 bit 2 is set. */
130076888252Smrg		if (!mode->CrtcVAdjusted) {
130176888252Smrg			mode->CrtcVDisplay >>= 1;
130276888252Smrg			mode->CrtcVSyncStart >>= 1;
130376888252Smrg			mode->CrtcVSyncEnd >>= 1;
130476888252Smrg			mode->CrtcVTotal >>= 1;
130576888252Smrg			mode->CrtcVAdjusted = TRUE;
130676888252Smrg		}
130776888252Smrg		VDiv2 = TRUE;
130876888252Smrg	}
130976888252Smrg
131076888252Smrg	/* Initialise the ModeReg values */
131176888252Smrg	if (!vgaHWInit(pScrn, mode))
131276888252Smrg		return FALSE;
131376888252Smrg	pScrn->vtSema = TRUE;
131476888252Smrg
131576888252Smrg	/* Turn off HW cursor, gamma correction, overscan color protect.  */
131676888252Smrg	pCir->chip.alp->ModeReg.ExtVga[SR12] = 0;
131776888252Smrg	if ((pCir->properties & HWCUR64) == HWCUR64)
131876888252Smrg	{
131976888252Smrg            pCir->chip.alp->ModeReg.ExtVga[SR12] = 0x4;
132076888252Smrg            switch (pCir->Chipset)
132176888252Smrg	    {
132276888252Smrg            case PCI_CHIP_GD7548:
132376888252Smrg	      pCir->chip.alp->ModeReg.ExtVga[SR21] |= 0x10;
132476888252Smrg	      break;
132576888252Smrg	    }
132676888252Smrg
132776888252Smrg	}
132876888252Smrg	else
132976888252Smrg	    pCir->chip.alp->ModeReg.ExtVga[SR12] = 0;
133076888252Smrg
133176888252Smrg
133276888252Smrg	if(VDiv2)
133376888252Smrg		hwp->ModeReg.CRTC[0x17] |= 0x04;
133476888252Smrg
133576888252Smrg#ifdef ALP_DEBUG
133676888252Smrg	ErrorF("SynthClock = %d\n", mode->SynthClock);
133776888252Smrg#endif
133876888252Smrg
133976888252Smrg	/* Disable DCLK pin driver, interrupts. */
134076888252Smrg	pCir->chip.alp->ModeReg.ExtVga[GR17] |= 0x08;
134176888252Smrg	pCir->chip.alp->ModeReg.ExtVga[GR17] &= ~0x04;
134276888252Smrg
134376888252Smrg	pCir->chip.alp->ModeReg.ExtVga[HDR] = 0;
134476888252Smrg	/* Enable linear mode and high-res packed pixel mode */
134576888252Smrg	pCir->chip.alp->ModeReg.ExtVga[SR07] &= 0xe0;
134676888252Smrg#ifdef ALP_DEBUG
134776888252Smrg	ErrorF("depthcode = %d\n", depthcode);
134876888252Smrg#endif
134976888252Smrg
135076888252Smrg	if (pScrn->bitsPerPixel == 1) {
135176888252Smrg		hwp->IOBase = 0x3B0;
135276888252Smrg		hwp->ModeReg.MiscOutReg &= ~0x01;
135376888252Smrg	} else {
135476888252Smrg		hwp->IOBase = 0x3D0;
135576888252Smrg		hwp->ModeReg.MiscOutReg |= 0x01;
135676888252Smrg	}
135776888252Smrg
135876888252Smrg	switch (depthcode) {
135976888252Smrg	case 1:
136076888252Smrg	case 4:
136176888252Smrg		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x10;
136276888252Smrg		break;
136376888252Smrg	case 8:
136476888252Smrg		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x11;
136576888252Smrg		break;
136676888252Smrg	case 64+8:
136776888252Smrg		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x17;
136876888252Smrg		break;
136976888252Smrg	case 15:
137076888252Smrg		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x17;
137176888252Smrg		pCir->chip.alp->ModeReg.ExtVga[HDR ]  = 0xC0;
137276888252Smrg		break;
137376888252Smrg	case 64+15:
137476888252Smrg		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x19;
137576888252Smrg		pCir->chip.alp->ModeReg.ExtVga[HDR ]  = 0xC0;
137676888252Smrg		break;
137776888252Smrg	case 16:
137876888252Smrg		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x17;
137976888252Smrg		pCir->chip.alp->ModeReg.ExtVga[HDR ]  = 0xC1;
138076888252Smrg		break;
138176888252Smrg	case 64+16:
138276888252Smrg		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x19;
138376888252Smrg		pCir->chip.alp->ModeReg.ExtVga[HDR ]  = 0xC1;
138476888252Smrg		break;
138576888252Smrg	case 24:
138676888252Smrg		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x15;
138776888252Smrg		pCir->chip.alp->ModeReg.ExtVga[HDR ]  = 0xC5;
138876888252Smrg		break;
138976888252Smrg	case 32:
139076888252Smrg		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x19;
139176888252Smrg		pCir->chip.alp->ModeReg.ExtVga[HDR ]  = 0xC5;
139276888252Smrg		break;
139376888252Smrg	default:
139476888252Smrg		ErrorF("X11: Internal error: AlpModeInit: Cannot Initialize display to requested mode\n");
139576888252Smrg#ifdef ALP_DEBUG
139676888252Smrg		ErrorF("AlpModeInit returning FALSE on depthcode %d\n", depthcode);
139776888252Smrg#endif
139876888252Smrg		return FALSE;
139976888252Smrg	}
140076888252Smrg	if (HDiv2)
140176888252Smrg		pCir->chip.alp->ModeReg.ExtVga[GR18] |= 0x20;
140276888252Smrg	else
140376888252Smrg		pCir->chip.alp->ModeReg.ExtVga[GR18] &= ~0x20;
140476888252Smrg
140576888252Smrg
140676888252Smrg	/* Some extra init stuff */
140776888252Smrg	switch (pCir->Chipset)
140876888252Smrg        {
140976888252Smrg          case PCI_CHIP_GD7548:
141076888252Smrg	    /* Do we use MMIO ?
141176888252Smrg	       If we do and we are on a 7548, we need to tell the board
141276888252Smrg	       that we want MMIO. */
141376888252Smrg	    if (pCir->UseMMIO)
141476888252Smrg	    {
141576888252Smrg	      pCir->chip.alp->ModeReg.ExtVga[SR17] =
141676888252Smrg		(pCir->chip.alp->ModeReg.ExtVga[SR17] & ~0x40) | 4;
141776888252Smrg	      ErrorF("UseMMIO: SR17=%2X\n", (int) (pCir->chip.alp->ModeReg.ExtVga[SR17]));
141876888252Smrg	    }
141976888252Smrg#ifdef ALP_SETUP
142076888252Smrg	    ErrorF("SR2D=%2X\n", (int) (pCir->chip.alp->ModeReg.ExtVga[SR17]));
142176888252Smrg#endif
142276888252Smrg	    pCir->chip.alp->ModeReg.ExtVga[SR2D] |= 0xC0;
142376888252Smrg	    break;
142476888252Smrg	}
142576888252Smrg
142676888252Smrg	/* No support for interlace (yet) */
142776888252Smrg	pCir->chip.alp->ModeReg.ExtVga[CR1A] = 0x00;
142876888252Smrg
142976888252Smrg	width = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
143076888252Smrg	if (pScrn->bitsPerPixel == 1)
143176888252Smrg		width <<= 2;
143276888252Smrg	hwp->ModeReg.CRTC[0x13] = width >> 3;
143376888252Smrg	/* Offset extension (see CR13) */
143476888252Smrg	pCir->chip.alp->ModeReg.ExtVga[CR1B] &= 0xAF;
143576888252Smrg	pCir->chip.alp->ModeReg.ExtVga[CR1B] |= (width >> (3+4)) & 0x10;
143676888252Smrg	pCir->chip.alp->ModeReg.ExtVga[CR1B] |= (width >> (3+3)) & 0x40;
143776888252Smrg	pCir->chip.alp->ModeReg.ExtVga[CR1B] |= 0x22;
143876888252Smrg
143976888252Smrg	/* Programme the registers */
144076888252Smrg	vgaHWProtect(pScrn, TRUE);
144176888252Smrg	hwp->writeMiscOut(hwp, hwp->ModeReg.MiscOutReg);
144276888252Smrg	alpRestore(hwp,&pCir->chip.alp->ModeReg);
144376888252Smrg	AlpSetClock(pCir, hwp, mode->SynthClock);
144476888252Smrg
144576888252Smrg	vgaHWRestore(pScrn, &hwp->ModeReg, VGA_SR_MODE | VGA_SR_CMAP);
144676888252Smrg
144776888252Smrg	/* XXX */
144876888252Smrg	if (pScrn->bitsPerPixel == 1)
144976888252Smrg		AlpFix1bppColorMap(pScrn);
145076888252Smrg
145176888252Smrg	vgaHWProtect(pScrn, FALSE);
145276888252Smrg
145376888252Smrg	return TRUE;
145476888252Smrg}
145576888252Smrg
145676888252Smrg/*
145776888252Smrg * Restore the initial (text) mode.
145876888252Smrg */
145976888252Smrgstatic void
146076888252SmrgAlpRestore(ScrnInfoPtr pScrn)
146176888252Smrg{
146276888252Smrg	vgaHWPtr hwp;
146376888252Smrg	vgaRegPtr vgaReg;
146476888252Smrg	CirPtr pCir;
146576888252Smrg	AlpRegPtr alpReg;
146676888252Smrg
146776888252Smrg#ifdef ALP_DEBUG
146876888252Smrg	ErrorF("AlpRestore\n");
146976888252Smrg#endif
147076888252Smrg
147176888252Smrg	hwp = VGAHWPTR(pScrn);
147276888252Smrg	pCir = CIRPTR(pScrn);
147376888252Smrg	vgaReg = &hwp->SavedReg;
147476888252Smrg	alpReg = &pCir->chip.alp->SavedReg;
147576888252Smrg
147676888252Smrg	vgaHWProtect(pScrn, TRUE);
147776888252Smrg
147876888252Smrg	alpRestore(hwp,alpReg);
147976888252Smrg
148076888252Smrg	vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
148176888252Smrg	vgaHWProtect(pScrn, FALSE);
148276888252Smrg}
148376888252Smrg
148476888252Smrg/* Mandatory */
148576888252Smrg
148676888252Smrg/* This gets called at the start of each server generation */
148776888252Smrg
148876888252SmrgBool
148976888252SmrgAlpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
149076888252Smrg{
149176888252Smrg	ScrnInfoPtr pScrn;
149276888252Smrg	vgaHWPtr hwp;
149376888252Smrg	CirPtr pCir;
149476888252Smrg	int i, ret;
149576888252Smrg	int init_picture = 0;
149676888252Smrg	VisualPtr visual;
149776888252Smrg	int displayWidth,width,height;
149876888252Smrg	unsigned char * FbBase = NULL;
149976888252Smrg	int cursor_size = 0;
150076888252Smrg
150176888252Smrg#ifdef ALP_DEBUG
150276888252Smrg	ErrorF("AlpScreenInit\n");
150376888252Smrg#endif
150476888252Smrg
150576888252Smrg	/*
150676888252Smrg	 * First get the ScrnInfoRec
150776888252Smrg	 */
150876888252Smrg	pScrn = xf86Screens[pScreen->myNum];
150976888252Smrg
151076888252Smrg	hwp = VGAHWPTR(pScrn);
151176888252Smrg	pCir = CIRPTR(pScrn);
151276888252Smrg
151376888252Smrg	/* Map the VGA memory when the primary video */
151476888252Smrg	if (!vgaHWMapMem(pScrn))
151576888252Smrg	    return FALSE;
151676888252Smrg
151776888252Smrg	/* Map the Alp memory and MMIO areas */
151876888252Smrg	if (!CirMapMem(pCir, pScrn->scrnIndex))
151976888252Smrg		return FALSE;
152076888252Smrg
152176888252Smrg	/* The 754x supports MMIO for the BitBlt engine but
152276888252Smrg	   not for the VGA registers */
152376888252Smrg	switch (pCir->Chipset)
152476888252Smrg	{
152576888252Smrg	case PCI_CHIP_GD7548:
152676888252Smrg	  break;
152776888252Smrg	default:
152876888252Smrg	  if(pCir->UseMMIO)
152976888252Smrg		vgaHWSetMmioFuncs(hwp, pCir->IOBase, -0x3C0);
153076888252Smrg        }
153176888252Smrg
153276888252Smrg	vgaHWGetIOBase(hwp);
153376888252Smrg
153476888252Smrg	/* Save the current state */
153576888252Smrg	AlpSave(pScrn);
153676888252Smrg
153776888252Smrg	/* Initialise the first mode */
153876888252Smrg	if (!AlpModeInit(pScrn, pScrn->currentMode))
153976888252Smrg		return FALSE;
154076888252Smrg
154176888252Smrg	/* Make things beautiful */
154276888252Smrg	AlpSaveScreen(pScreen, SCREEN_SAVER_ON);
154376888252Smrg
154476888252Smrg	/* Set the viewport */
154576888252Smrg	AlpAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
154676888252Smrg
154776888252Smrg	/*
154876888252Smrg	 * The next step is to setup the screen's visuals, and initialise the
154976888252Smrg	 * framebuffer code.  In cases where the framebuffer's default
155076888252Smrg	 * choices for things like visual layouts and bits per RGB are OK,
155176888252Smrg	 * this may be as simple as calling the framebuffer's ScreenInit()
155276888252Smrg	 * function.  If not, the visuals will need to be setup before calling
155376888252Smrg	 * a fb ScreenInit() function and fixed up after.
155476888252Smrg	 *
155576888252Smrg	 */
155676888252Smrg
155776888252Smrg	/*
155876888252Smrg	 * Reset the visual list.
155976888252Smrg	 */
156076888252Smrg	miClearVisualTypes();
156176888252Smrg
156276888252Smrg	/* Setup the visuals we support. */
156376888252Smrg
156476888252Smrg	if (!miSetVisualTypes(pScrn->depth,
156576888252Smrg			      miGetDefaultVisualMask(pScrn->depth),
156676888252Smrg			      pScrn->rgbBits, pScrn->defaultVisual))
156776888252Smrg			return FALSE;
156876888252Smrg
156976888252Smrg	miSetPixmapDepths ();
157076888252Smrg
157176888252Smrg	displayWidth = pScrn->displayWidth;
157276888252Smrg	if (pCir->rotate) {
157376888252Smrg	    height = pScrn->virtualX;
157476888252Smrg	    width = pScrn->virtualY;
157576888252Smrg	} else {
157676888252Smrg	    width = pScrn->virtualX;
157776888252Smrg	    height = pScrn->virtualY;
157876888252Smrg	}
157976888252Smrg
158076888252Smrg	if(pCir->shadowFB) {
158176888252Smrg	    pCir->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
158276888252Smrg	    pCir->ShadowPtr = xalloc(pCir->ShadowPitch * height);
158376888252Smrg	    displayWidth = pCir->ShadowPitch / (pScrn->bitsPerPixel >> 3);
158476888252Smrg	    FbBase = pCir->ShadowPtr;
158576888252Smrg	} else {
158676888252Smrg	    pCir->ShadowPtr = NULL;
158776888252Smrg	    FbBase = pCir->FbBase;
158876888252Smrg	}
158976888252Smrg
159076888252Smrg	/*
159176888252Smrg	 * Call the framebuffer layer's ScreenInit function, and fill in other
159276888252Smrg	 * pScreen fields.
159376888252Smrg	 */
159476888252Smrg
159576888252Smrg	switch (pScrn->bitsPerPixel) {
15961ae1b5e8Smrg#ifdef HAVE_XF1BPP
159776888252Smrg	case 1:
159876888252Smrg	    ret = xf1bppScreenInit(pScreen, FbBase,
159976888252Smrg				   width, height,
160076888252Smrg				   pScrn->xDpi, pScrn->yDpi,
160176888252Smrg				   displayWidth);
160276888252Smrg	    break;
16031ae1b5e8Smrg#endif
16041ae1b5e8Smrg#ifdef HAVE_XF4BPP
160576888252Smrg	case 4:
160676888252Smrg	    ret = xf4bppScreenInit(pScreen, FbBase,
160776888252Smrg				   width, height,
160876888252Smrg				   pScrn->xDpi, pScrn->yDpi,
160976888252Smrg				   displayWidth);
161076888252Smrg	    break;
16111ae1b5e8Smrg#endif
161276888252Smrg	case 8:
161376888252Smrg	case 16:
161476888252Smrg	case 24:
161576888252Smrg	case 32:
161676888252Smrg	    ret = fbScreenInit(pScreen, FbBase,
161776888252Smrg				width,height,
161876888252Smrg				pScrn->xDpi, pScrn->yDpi,
161976888252Smrg				displayWidth,pScrn->bitsPerPixel);
162076888252Smrg	    init_picture = 1;
162176888252Smrg	    break;
162276888252Smrg	default:
162376888252Smrg	    xf86DrvMsg(scrnIndex, X_ERROR,
162476888252Smrg		       "X11: Internal error: invalid bpp (%d) in AlpScreenInit\n",
162576888252Smrg		       pScrn->bitsPerPixel);
162676888252Smrg	    ret = FALSE;
162776888252Smrg	    break;
162876888252Smrg	}
162976888252Smrg	if (!ret)
163076888252Smrg		return FALSE;
163176888252Smrg
163276888252Smrg#ifdef ALP_DEBUG
163376888252Smrg	ErrorF("AlpScreenInit after depth dependent init\n");
163476888252Smrg#endif
163576888252Smrg
163676888252Smrg	/* Override the default mask/offset settings */
163776888252Smrg	if (pScrn->bitsPerPixel > 8) {
163876888252Smrg		for (i = 0; i < pScreen->numVisuals; i++) {
163976888252Smrg			visual = &pScreen->visuals[i];
164076888252Smrg			if ((visual->class | DynamicClass) == DirectColor) {
164176888252Smrg				visual->offsetRed = pScrn->offset.red;
164276888252Smrg				visual->offsetGreen = pScrn->offset.green;
164376888252Smrg				visual->offsetBlue = pScrn->offset.blue;
164476888252Smrg				visual->redMask = pScrn->mask.red;
164576888252Smrg				visual->greenMask = pScrn->mask.green;
164676888252Smrg				visual->blueMask = pScrn->mask.blue;
164776888252Smrg			}
164876888252Smrg		}
164976888252Smrg	}
165076888252Smrg
165176888252Smrg	/* must be after RGB ordering fixed */
165276888252Smrg	if (init_picture)
165376888252Smrg		fbPictureInit (pScreen, 0, 0);
165476888252Smrg
165576888252Smrg	miInitializeBackingStore(pScreen);
165676888252Smrg
165776888252Smrg	/*
165876888252Smrg	 * Set initial black & white colourmap indices.
165976888252Smrg	 */
166076888252Smrg	xf86SetBlackWhitePixels(pScreen);
166176888252Smrg
166276888252Smrg	/*
166376888252Smrg	   Allocation of off-screen memory to various stuff
166476888252Smrg	   (hardware cursor, 8x8 mono pattern...)
166576888252Smrg	   Allocation goes top-down in memory, since the cursor
166676888252Smrg	   *must* be in the last videoram locations
166776888252Smrg	*/
166876888252Smrg	pCir->offscreen_offset = pScrn->videoRam*1024;
166976888252Smrg	pCir->offscreen_size = pScrn->videoRam * 1024 - pScrn->virtualY *
167076888252Smrg	    (BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel));
167176888252Smrg
167276888252Smrg#ifdef ALP_DEBUG
167376888252Smrg	ErrorF("offscreen_offset=%d, offscreen_size=%d\n",
167476888252Smrg	       pCir->offscreen_offset, pCir->offscreen_size);
167576888252Smrg#endif
167676888252Smrg
167776888252Smrg	/* Initialise cursor functions */
167876888252Smrg	if (pCir->HWCursor) { /* Initialize HW cursor layer */
167976888252Smrg
168076888252Smrg	    if ((pCir->properties & HWCUR64)
168176888252Smrg		&& (pCir->offscreen_size >= 64*8*2)) {
168276888252Smrg	        cursor_size = 64;
168376888252Smrg	        pCir->offscreen_size -= 64*8*2;
168476888252Smrg	        pCir->offscreen_offset -= 64*8*2;
168576888252Smrg	    } else if (pCir->offscreen_size >= 32*4*2) {
168676888252Smrg	        cursor_size = 32;
168776888252Smrg		pCir->offscreen_size -= 32*8*2;
168876888252Smrg		pCir->offscreen_offset -= 32*8*2;
168976888252Smrg	    }
169076888252Smrg	}
169176888252Smrg
169276888252Smrg	if (!pCir->NoAccel) { /* Initialize XAA functions */
169376888252Smrg	    AlpOffscreenAccelInit(pScrn);
169476888252Smrg	    if (!(pCir->UseMMIO ? AlpXAAInitMMIO(pScreen) :
169576888252Smrg		  AlpXAAInit(pScreen)))
169676888252Smrg	      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
169776888252Smrg			 "Could not initialize XAA\n");
169876888252Smrg	}
169976888252Smrg
170076888252Smrg#if 1
170176888252Smrg	pCir->DGAModeInit = AlpModeInit;
170276888252Smrg	if (!CirDGAInit(pScreen))
170376888252Smrg	  xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
170476888252Smrg		     "DGA initialization failed\n");
170576888252Smrg#endif
170676888252Smrg        xf86SetSilkenMouse(pScreen);
170776888252Smrg
170876888252Smrg	/* Initialise cursor functions */
170976888252Smrg	miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
171076888252Smrg
171176888252Smrg	if (pCir->HWCursor) {
171276888252Smrg	    if (!AlpHWCursorInit(pScreen, cursor_size))
171376888252Smrg	        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
171476888252Smrg			   "Hardware cursor initialization failed\n");
171576888252Smrg#ifdef ALP_DEBUG
171676888252Smrg	    ErrorF("AlpHWCursorInit() complete\n");
171776888252Smrg#endif
171876888252Smrg	}
171976888252Smrg
172076888252Smrg	if (pCir->shadowFB) {
172176888252Smrg	    RefreshAreaFuncPtr refreshArea = cirRefreshArea;
172276888252Smrg
172376888252Smrg	    if(pCir->rotate) {
172476888252Smrg		if (!pCir->PointerMoved) {
172576888252Smrg		    pCir->PointerMoved = pScrn->PointerMoved;
172676888252Smrg		    pScrn->PointerMoved = cirPointerMoved;
172776888252Smrg		}
172876888252Smrg
172976888252Smrg		switch(pScrn->bitsPerPixel) {
173076888252Smrg		case 8:	refreshArea = cirRefreshArea8;	break;
173176888252Smrg		case 16:	refreshArea = cirRefreshArea16;	break;
173276888252Smrg		case 24:	refreshArea = cirRefreshArea24;	break;
173376888252Smrg		case 32:	refreshArea = cirRefreshArea32;	break;
173476888252Smrg		}
173576888252Smrg	    }
173676888252Smrg
173776888252Smrg	    ShadowFBInit(pScreen, refreshArea);
173876888252Smrg	}
173976888252Smrg
174076888252Smrg	/* Initialise default colourmap */
174176888252Smrg	if (!miCreateDefColormap(pScreen))
174276888252Smrg		return FALSE;
174376888252Smrg
174476888252Smrg	if (pScrn->bitsPerPixel > 1 && pScrn->bitsPerPixel <= 8)
174576888252Smrg		vgaHWHandleColormaps(pScreen);
174676888252Smrg
174776888252Smrg	xf86DPMSInit(pScreen, AlpDisplayPowerManagementSet, 0);
174876888252Smrg
174976888252Smrg	pScrn->memPhysBase = pCir->FbAddress;
175076888252Smrg	pScrn->fbOffset = 0;
175176888252Smrg
175276888252Smrg	{
175376888252Smrg		XF86VideoAdaptorPtr *ptr;
175476888252Smrg		int n;
175576888252Smrg
175676888252Smrg		n = xf86XVListGenericAdaptors(pScrn,&ptr);
175776888252Smrg		if (n)
175876888252Smrg			xf86XVScreenInit(pScreen, ptr, n);
175976888252Smrg	}
176076888252Smrg
176176888252Smrg	/*
176276888252Smrg	 * Wrap the CloseScreen vector and set SaveScreen.
176376888252Smrg	 */
176476888252Smrg	pScreen->SaveScreen = AlpSaveScreen;
176576888252Smrg	pCir->CloseScreen = pScreen->CloseScreen;
176676888252Smrg	pScreen->CloseScreen = AlpCloseScreen;
176776888252Smrg
176876888252Smrg	/* Report any unused options (only for the first generation) */
176976888252Smrg	if (serverGeneration == 1)
177076888252Smrg		xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
177176888252Smrg
177276888252Smrg	/* Done */
177376888252Smrg	return TRUE;
177476888252Smrg}
177576888252Smrg
177676888252Smrg
177776888252Smrg/* Usually mandatory */
177876888252SmrgBool
177976888252SmrgAlpSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
178076888252Smrg{
178176888252Smrg	return AlpModeInit(xf86Screens[scrnIndex], mode);
178276888252Smrg}
178376888252Smrg
178476888252Smrg
178576888252Smrg/*
178676888252Smrg * This function is used to initialize the Start Address - the first
178776888252Smrg * displayed location in the video memory.
178876888252Smrg */
178976888252Smrg/* Usually mandatory */
179076888252Smrgvoid
179176888252SmrgAlpAdjustFrame(int scrnIndex, int x, int y, int flags)
179276888252Smrg{
179376888252Smrg	ScrnInfoPtr pScrn;
179476888252Smrg	int Base, tmp;
179576888252Smrg	vgaHWPtr hwp;
179676888252Smrg
179776888252Smrg	pScrn = xf86Screens[scrnIndex];
179876888252Smrg	hwp = VGAHWPTR(pScrn);
179976888252Smrg
180076888252Smrg	Base = ((y * pScrn->displayWidth + x) / 8);
180176888252Smrg	if (pScrn->bitsPerPixel != 1)
180276888252Smrg		Base *= (pScrn->bitsPerPixel/4);
180376888252Smrg
180476888252Smrg#ifdef ALP_DEBUG
180576888252Smrg	ErrorF("AlpAdjustFrame %d %d 0x%x %d %x\n", x, y, flags, Base, Base);
180676888252Smrg#endif
180776888252Smrg
180876888252Smrg	if ((Base & ~0x000FFFFF) != 0) {
180976888252Smrg		ErrorF("X11: Internal error: AlpAdjustFrame: cannot handle overflow\n");
181076888252Smrg		return;
181176888252Smrg	}
181276888252Smrg
181376888252Smrg	hwp->writeCrtc(hwp, 0x0C, (Base >> 8) & 0xff);
181476888252Smrg	hwp->writeCrtc(hwp, 0x0D, Base & 0xff);
181576888252Smrg	tmp = hwp->readCrtc(hwp, 0x1B);
181676888252Smrg	tmp &= 0xF2;
181776888252Smrg	tmp |= (Base >> 16) & 0x01;
181876888252Smrg	tmp |= (Base >> 15) & 0x0C;
181976888252Smrg	hwp->writeCrtc(hwp, 0x1B, tmp);
182076888252Smrg	tmp = hwp->readCrtc(hwp, 0x1D);
182176888252Smrg	tmp &= 0x7F;
182276888252Smrg	tmp |= (Base >> 12) & 0x80;
182376888252Smrg	hwp->writeCrtc(hwp, 0x1D, tmp);
182476888252Smrg}
182576888252Smrg
182676888252Smrg/*
182776888252Smrg * This is called when VT switching back to the X server.  Its job is
182876888252Smrg * to reinitialise the video mode.
182976888252Smrg *
183076888252Smrg * We may wish to unmap video/MMIO memory too.
183176888252Smrg */
183276888252Smrg
183376888252Smrg/* Mandatory */
183476888252SmrgBool
183576888252SmrgAlpEnterVT(int scrnIndex, int flags)
183676888252Smrg{
183776888252Smrg	ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
183876888252Smrg	CirPtr pCir = CIRPTR(pScrn);
183976888252Smrg	Bool ret;
184076888252Smrg
184176888252Smrg#ifdef ALP_DEBUG
184276888252Smrg	ErrorF("AlpEnterVT\n");
184376888252Smrg#endif
184476888252Smrg
184576888252Smrg	/* Should we re-save the text mode on each VT enter? */
184676888252Smrg	if (!(ret = AlpModeInit(pScrn, pScrn->currentMode)))
184776888252Smrg		return FALSE;
184876888252Smrg
184976888252Smrg	if (!pCir->NoAccel)
185076888252Smrg		pCir->InitAccel(pScrn);
185176888252Smrg
185276888252Smrg	return ret;
185376888252Smrg}
185476888252Smrg
185576888252Smrg
185676888252Smrg/*
185776888252Smrg * This is called when VT switching away from the X server.  Its job is
185876888252Smrg * to restore the previous (text) mode.
185976888252Smrg *
186076888252Smrg * We may wish to remap video/MMIO memory too.
186176888252Smrg */
186276888252Smrg
186376888252Smrg/* Mandatory */
186476888252Smrgvoid
186576888252SmrgAlpLeaveVT(int scrnIndex, int flags)
186676888252Smrg{
186776888252Smrg	ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
186876888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
186976888252Smrg#ifdef ALP_DEBUG
187076888252Smrg	ErrorF("AlpLeaveVT\n");
187176888252Smrg#endif
187276888252Smrg
187376888252Smrg	AlpRestore(pScrn);
187476888252Smrg	vgaHWLock(hwp);
187576888252Smrg}
187676888252Smrg
187776888252Smrg
187876888252Smrg/*
187976888252Smrg * This is called at the end of each server generation.  It restores the
188076888252Smrg * original (text) mode.  It should also unmap the video memory, and free
188176888252Smrg * any per-generation data allocated by the driver.  It should finish
188276888252Smrg * by unwrapping and calling the saved CloseScreen function.
188376888252Smrg */
188476888252Smrg
188576888252Smrg/* Mandatory */
188676888252Smrgstatic Bool
188776888252SmrgAlpCloseScreen(int scrnIndex, ScreenPtr pScreen)
188876888252Smrg{
188976888252Smrg	ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
189076888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
189176888252Smrg	CirPtr pCir = CIRPTR(pScrn);
189276888252Smrg
189376888252Smrg	if(pScrn->vtSema) {
189476888252Smrg	    AlpRestore(pScrn);
189576888252Smrg	    vgaHWLock(hwp);
189676888252Smrg	    CirUnmapMem(pCir, pScrn->scrnIndex);
189776888252Smrg	}
189876888252Smrg
189976888252Smrg	if (pCir->AccelInfoRec)
190076888252Smrg		XAADestroyInfoRec(pCir->AccelInfoRec);
190176888252Smrg	pCir->AccelInfoRec = NULL;
190276888252Smrg	if (pCir->CursorInfoRec)
190376888252Smrg		xf86DestroyCursorInfoRec(pCir->CursorInfoRec);
190476888252Smrg	pCir->CursorInfoRec = NULL;
190576888252Smrg	if (pCir->DGAModes)
190676888252Smrg		xfree(pCir->DGAModes);
190776888252Smrg	pCir->DGAnumModes = 0;
190876888252Smrg	pCir->DGAModes = NULL;
190976888252Smrg
191076888252Smrg	pScrn->vtSema = FALSE;
191176888252Smrg
191276888252Smrg	pScreen->CloseScreen = pCir->CloseScreen;
191376888252Smrg	return (*pScreen->CloseScreen)(scrnIndex, pScreen);
191476888252Smrg}
191576888252Smrg
191676888252Smrg
191776888252Smrg/* Free up any persistent data structures */
191876888252Smrg
191976888252Smrg/* Optional */
192076888252Smrgvoid
192176888252SmrgAlpFreeScreen(int scrnIndex, int flags)
192276888252Smrg{
192376888252Smrg#ifdef ALP_DEBUG
192476888252Smrg	ErrorF("AlpFreeScreen\n");
192576888252Smrg#endif
192676888252Smrg	/*
192776888252Smrg	 * This only gets called when a screen is being deleted.  It does not
192876888252Smrg	 * get called routinely at the end of a server generation.
192976888252Smrg	 */
193076888252Smrg	if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
193176888252Smrg		vgaHWFreeHWRec(xf86Screens[scrnIndex]);
193276888252Smrg	AlpFreeRec(xf86Screens[scrnIndex]);
193376888252Smrg}
193476888252Smrg
193576888252Smrg
193676888252Smrg/* Checks if a mode is suitable for the selected chipset. */
193776888252Smrg
193876888252Smrg/* Optional */
193976888252SmrgModeStatus
194076888252SmrgAlpValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
194176888252Smrg{
194276888252Smrg	int lace;
194376888252Smrg
194476888252Smrg	lace = 1 + ((mode->Flags & V_INTERLACE) != 0);
194576888252Smrg
194676888252Smrg	if ((mode->CrtcHDisplay <= 2048) &&
194776888252Smrg		(mode->CrtcHSyncStart <= 4096) &&
194876888252Smrg		(mode->CrtcHSyncEnd <= 4096) &&
194976888252Smrg		(mode->CrtcHTotal <= 4096) &&
195076888252Smrg		(mode->CrtcVDisplay <= 2048 * lace) &&
195176888252Smrg		(mode->CrtcVSyncStart <= 4096 * lace) &&
195276888252Smrg		(mode->CrtcVSyncEnd <= 4096 * lace) &&
195376888252Smrg		(mode->CrtcVTotal <= 4096 * lace)) {
195476888252Smrg		return(MODE_OK);
195576888252Smrg	} else {
195676888252Smrg		return(MODE_BAD);
195776888252Smrg	}
195876888252Smrg}
195976888252Smrg
196076888252Smrg/* Do screen blanking */
196176888252Smrg
196276888252Smrg/* Mandatory */
196376888252Smrgstatic Bool
196476888252SmrgAlpSaveScreen(ScreenPtr pScreen, int mode)
196576888252Smrg{
196676888252Smrg	return vgaHWSaveScreen(pScreen, mode);
196776888252Smrg}
196876888252Smrg
196976888252Smrg/*
197076888252Smrg * Set the clock to the requested frequency.  If the MCLK is very close
197176888252Smrg * to the requested frequency, it sets a flag so that the MCLK can be used
197276888252Smrg * as VCLK.  However this flag is not yet acted upon.
197376888252Smrg */
197476888252Smrgstatic void
197576888252SmrgAlpSetClock(CirPtr pCir, vgaHWPtr hwp, int freq)
197676888252Smrg{
197776888252Smrg	int num, den, ffreq;
197876888252Smrg	CARD8 tmp;
197976888252Smrg
198076888252Smrg#ifdef ALP_DEBUG
198176888252Smrg	ErrorF("AlpSetClock freq=%d.%03dMHz\n", freq / 1000, freq % 1000);
198276888252Smrg#endif
198376888252Smrg
198476888252Smrg	ffreq = freq;
198576888252Smrg	if (!CirrusFindClock(&ffreq, pCir->MaxClock, &num, &den))
198676888252Smrg		return;
198776888252Smrg
198876888252Smrg#ifdef ALP_DEBUG
198976888252Smrg	ErrorF("AlpSetClock: nom=%x den=%x ffreq=%d.%03dMHz\n",
199076888252Smrg		num, den, ffreq / 1000, ffreq % 1000);
199176888252Smrg#endif
199276888252Smrg	/* So - how do we use MCLK here for the VCLK ? */
199376888252Smrg
199476888252Smrg	/* Set VCLK3. */
199576888252Smrg	tmp = hwp->readSeq(hwp, 0x0E);
199676888252Smrg	hwp->writeSeq(hwp, 0x0E, (tmp & 0x80) | num);
199776888252Smrg	hwp->writeSeq(hwp, 0x1E, den);
199876888252Smrg}
199976888252Smrg
200076888252Smrg/*
200176888252Smrg * AlpDisplayPowerManagementSet --
200276888252Smrg *
200376888252Smrg * Sets VESA Display Power Management Signaling (DPMS) Mode.
200476888252Smrg */
200576888252Smrgstatic void
200676888252SmrgAlpDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
200776888252Smrg			     int flags)
200876888252Smrg{
200976888252Smrg	unsigned char sr01, gr0e;
201076888252Smrg	vgaHWPtr hwp;
201176888252Smrg
201276888252Smrg#ifdef ALP_DEBUG
201376888252Smrg	ErrorF("AlpDisplayPowerManagementSet\n");
201476888252Smrg#endif
201576888252Smrg
201676888252Smrg	hwp = VGAHWPTR(pScrn);
201776888252Smrg
201876888252Smrg#ifdef ALP_DEBUG
201976888252Smrg	ErrorF("AlpDisplayPowerManagementSet: %d\n", PowerManagementMode);
202076888252Smrg#endif
202176888252Smrg
202276888252Smrg	switch (PowerManagementMode) {
202376888252Smrg	case DPMSModeOn:
202476888252Smrg		/* Screen: On; HSync: On, VSync: On */
202576888252Smrg		sr01 = 0x00;
202676888252Smrg		gr0e = 0x00;
202776888252Smrg		break;
202876888252Smrg	case DPMSModeStandby:
202976888252Smrg		/* Screen: Off; HSync: Off, VSync: On */
203076888252Smrg		sr01 = 0x20;
203176888252Smrg		gr0e = 0x02;
203276888252Smrg		break;
203376888252Smrg	case DPMSModeSuspend:
203476888252Smrg		/* Screen: Off; HSync: On, VSync: Off */
203576888252Smrg		sr01 = 0x20;
203676888252Smrg		gr0e = 0x04;
203776888252Smrg		break;
203876888252Smrg	case DPMSModeOff:
203976888252Smrg		/* Screen: Off; HSync: Off, VSync: Off */
204076888252Smrg		sr01 = 0x20;
204176888252Smrg		gr0e = 0x06;
204276888252Smrg		break;
204376888252Smrg	default:
204476888252Smrg		return;
204576888252Smrg	}
204676888252Smrg
204776888252Smrg	sr01 |= hwp->readSeq(hwp, 0x01) & ~0x20;
204876888252Smrg	hwp->writeSeq(hwp, 0x01, sr01);
204976888252Smrg	gr0e |= hwp->readGr(hwp, 0x0E) & ~0x06;
205076888252Smrg	hwp->writeGr(hwp, 0x0E, gr0e);
205176888252Smrg}
205276888252Smrg
205376888252Smrg#ifdef ALPPROBEI2C
205476888252Smrgstatic void AlpProbeI2C(int scrnIndex)
205576888252Smrg{
205676888252Smrg	int i;
205776888252Smrg	I2CBusPtr b;
205876888252Smrg
205976888252Smrg	b = xf86I2CFindBus(scrnIndex, "I2C bus 1");
206076888252Smrg	if (b == NULL)
206176888252Smrg		ErrorF("Could not find I2C bus \"%s\"\n", "I2C bus 1");
206276888252Smrg	else {
206376888252Smrg		for (i = 2; i < 256; i += 2)
206476888252Smrg			if (xf86I2CProbeAddress(b, i))
206576888252Smrg				ErrorF("Found device 0x%02x on bus \"%s\"\n", i, b->BusName);
206676888252Smrg	}
206776888252Smrg	b = xf86I2CFindBus(scrnIndex, "I2C bus 2");
206876888252Smrg	if (b == NULL)
206976888252Smrg		ErrorF("Could not find I2C bus \"%s\"\n", "I2C bus 2");
207076888252Smrg	else {
207176888252Smrg		for (i = 2; i < 256; i += 2)
207276888252Smrg			if (xf86I2CProbeAddress(b, i))
207376888252Smrg				ErrorF("Found device 0x%02x on bus \"%s\"\n", i, b->BusName);
207476888252Smrg	}
207576888252Smrg}
207676888252Smrg#endif
207776888252Smrg
207876888252Smrgstatic void
207976888252SmrgAlpProbeLCD(ScrnInfoPtr pScrn)
208076888252Smrg{
208176888252Smrg    CirPtr pCir = CIRPTR(pScrn);
208276888252Smrg    AlpPtr pAlp = ALPPTR(pCir);
208376888252Smrg
208476888252Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
208576888252Smrg    CARD8 lcdCrtl;
208676888252Smrg
208776888252Smrg    static const char* lcd_type_names[] =
208876888252Smrg    {
208976888252Smrg        "none",
209076888252Smrg	"dual-scan monochrome",
209176888252Smrg	"unknown",
209276888252Smrg	"DSTN (dual scan color)",
209376888252Smrg	"TFT (active matrix)"
209476888252Smrg    };
209576888252Smrg
209676888252Smrg
209776888252Smrg    pAlp->lcdType = LCD_NONE;
209876888252Smrg
209976888252Smrg    switch (pCir->Chipset)  {
210076888252Smrg    case PCI_CHIP_GD7548:
210176888252Smrg        switch (hwp->readCrtc(hwp, 0x2C) >> 6) {
210276888252Smrg	case 0: pAlp->lcdType = LCD_DUAL_MONO; break;
210376888252Smrg	case 1: pAlp->lcdType = LCD_UNKNOWN; break;
210476888252Smrg	case 2: pAlp->lcdType = LCD_DSTN; break;
210576888252Smrg	case 3: pAlp->lcdType = LCD_TFT; break;
210676888252Smrg	}
210776888252Smrg
210876888252Smrg	/* Enable LCD control registers instead of normal CRTC registers */
210976888252Smrg	lcdCrtl = hwp->readCrtc(hwp, 0x2D);
211076888252Smrg	hwp->writeCrtc(hwp, 0x2D, lcdCrtl | 0x80);
211176888252Smrg
211276888252Smrg	switch ((hwp->readCrtc(hwp, 0x9) >> 2) & 3)  {
211376888252Smrg	  case 0:
211476888252Smrg	      pAlp->lcdWidth = 640;
211576888252Smrg	      pAlp->lcdHeight = 480;
211676888252Smrg	      break;
211776888252Smrg
211876888252Smrg	 case 1:
211976888252Smrg	      pAlp->lcdWidth = 800;
212076888252Smrg	      pAlp->lcdHeight = 600;
212176888252Smrg	      break;
212276888252Smrg
212376888252Smrg	  case 2:
212476888252Smrg	      pAlp->lcdWidth = 1024;
212576888252Smrg	      pAlp->lcdHeight = 768;
212676888252Smrg	      break;
212776888252Smrg
212876888252Smrg	  case 3:
212976888252Smrg	      pAlp->lcdWidth = 0;
213076888252Smrg	      pAlp->lcdHeight = 0;
213176888252Smrg	      break;
213276888252Smrg	}
213376888252Smrg
213476888252Smrg	/* Disable LCD control registers */
213576888252Smrg	hwp->writeCrtc(hwp, 0x2D, lcdCrtl);
213676888252Smrg	break;
213776888252Smrg    }
213876888252Smrg
213976888252Smrg    if (pAlp->lcdType != LCD_NONE) {
214076888252Smrg      xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
214176888252Smrg		 "LCD display: %dx%d %s\n",
214276888252Smrg		 pAlp->lcdWidth, pAlp->lcdHeight,
214376888252Smrg		 lcd_type_names[pAlp->lcdType]);
214476888252Smrg    }
214576888252Smrg}
214676888252Smrg
214776888252Smrgstatic void
214876888252SmrgAlpOffscreenAccelInit(ScrnInfoPtr pScrn)
214976888252Smrg{
215076888252Smrg    CirPtr pCir = CIRPTR(pScrn);
215176888252Smrg    AlpPtr pAlp = ALPPTR(pCir);
215276888252Smrg
215376888252Smrg    if (pCir->offscreen_size >= 8  && pCir->Chipset == PCI_CHIP_GD7548) {
215476888252Smrg        pCir->offscreen_offset -= 8;
215576888252Smrg	pCir->offscreen_size -= 8;
215676888252Smrg	pAlp->monoPattern8x8 = pCir->offscreen_offset;
215776888252Smrg#ifdef ALP_DEBUG
215876888252Smrg	ErrorF("monoPattern8x8=%d\n", pAlp->monoPattern8x8);
215976888252Smrg#endif
216076888252Smrg    }  else pAlp->monoPattern8x8 = 0;
216176888252Smrg
216276888252Smrg    {
216376888252Smrg    /* TODO: probably not correct if rotated */
216476888252Smrg        BoxRec box;
216576888252Smrg	box.x1=0;
216676888252Smrg	box.y1=0;
216776888252Smrg	box.x2=pScrn->virtualX;
216876888252Smrg	box.y2= pCir->offscreen_offset / pCir->pitch;
216976888252Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
217076888252Smrg		   "Using %d lines for offscreen memory\n",
217176888252Smrg		   box.y2 - pScrn->virtualY);
217276888252Smrg    }
217376888252Smrg}
2174