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