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