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