smi_driver.c revision 09885543
109885543Smrg/* Header: //Mercury/Projects/archives/XFree86/4.0/smi_driver.c-arc 1.42 03 Jan 2001 13:52:16 Frido $ */ 209885543Smrg 309885543Smrg/* 409885543SmrgCopyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. 509885543SmrgCopyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. 609885543Smrg 709885543SmrgPermission is hereby granted, free of charge, to any person obtaining a copy of 809885543Smrgthis software and associated documentation files (the "Software"), to deal in 909885543Smrgthe Software without restriction, including without limitation the rights to 1009885543Smrguse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 1109885543Smrgof the Software, and to permit persons to whom the Software is furnished to do 1209885543Smrgso, subject to the following conditions: 1309885543Smrg 1409885543SmrgThe above copyright notice and this permission notice shall be included in all 1509885543Smrgcopies or substantial portions of the Software. 1609885543Smrg 1709885543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1809885543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 1909885543SmrgNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2009885543SmrgXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2109885543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2209885543SmrgWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2309885543Smrg 2409885543SmrgExcept as contained in this notice, the names of The XFree86 Project and 2509885543SmrgSilicon Motion shall not be used in advertising or otherwise to promote the 2609885543Smrgsale, use or other dealings in this Software without prior written 2709885543Smrgauthorization from The XFree86 Project or Silicon Motion. 2809885543Smrg*/ 2909885543Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_driver.c,v 1.36tsi Exp $ */ 3009885543Smrg 3109885543Smrg#ifdef HAVE_CONFIG_H 3209885543Smrg#include "config.h" 3309885543Smrg#endif 3409885543Smrg 3509885543Smrg#include "xf86Resources.h" 3609885543Smrg#include "xf86RAC.h" 3709885543Smrg#include "xf86DDC.h" 3809885543Smrg#include "xf86int10.h" 3909885543Smrg#include "vbe.h" 4009885543Smrg#include "shadowfb.h" 4109885543Smrg 4209885543Smrg#include "smi.h" 4309885543Smrg 4409885543Smrg#include "globals.h" 4509885543Smrg#define DPMS_SERVER 4609885543Smrg#include <X11/extensions/dpms.h> 4709885543Smrg 4809885543Smrg/* 4909885543Smrg * Internals 5009885543Smrg */ 5109885543Smrgstatic void SMI_EnableMmio(ScrnInfoPtr pScrn); 5209885543Smrgstatic void SMI_DisableMmio(ScrnInfoPtr pScrn); 5309885543Smrg 5409885543Smrg/* 5509885543Smrg * Forward definitions for the functions that make up the driver. 5609885543Smrg */ 5709885543Smrg 5809885543Smrgstatic const OptionInfoRec * SMI_AvailableOptions(int chipid, int busid); 5909885543Smrgstatic void SMI_Identify(int flags); 6009885543Smrgstatic Bool SMI_Probe(DriverPtr drv, int flags); 6109885543Smrgstatic Bool SMI_PreInit(ScrnInfoPtr pScrn, int flags); 6209885543Smrgstatic Bool SMI_EnterVT(int scrnIndex, int flags); 6309885543Smrgstatic void SMI_LeaveVT(int scrnIndex, int flags); 6409885543Smrgstatic void SMI_Save (ScrnInfoPtr pScrn); 6509885543Smrgstatic void SMI_WriteMode (ScrnInfoPtr pScrn, vgaRegPtr, SMIRegPtr); 6609885543Smrgstatic Bool SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 6709885543Smrg char **argv); 6809885543Smrgstatic int SMI_InternalScreenInit(int scrnIndex, ScreenPtr pScreen); 6909885543Smrgstatic void SMI_PrintRegs(ScrnInfoPtr); 7009885543Smrgstatic ModeStatus SMI_ValidMode(int scrnIndex, DisplayModePtr mode, 7109885543Smrg Bool verbose, int flags); 7209885543Smrgstatic void SMI_DisableVideo(ScrnInfoPtr pScrn); 7309885543Smrgstatic void SMI_EnableVideo(ScrnInfoPtr pScrn); 7409885543Smrgstatic Bool SMI_MapMem(ScrnInfoPtr pScrn); 7509885543Smrgstatic void SMI_UnmapMem(ScrnInfoPtr pScrn); 7609885543Smrgstatic Bool SMI_ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 7709885543Smrgstatic Bool SMI_CloseScreen(int scrnIndex, ScreenPtr pScreen); 7809885543Smrgstatic Bool SMI_SaveScreen(ScreenPtr pScreen, int mode); 7909885543Smrgstatic void SMI_LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, 8009885543Smrg LOCO *colors, VisualPtr pVisual); 8109885543Smrgstatic void SMI_DisplayPowerManagementSet(ScrnInfoPtr pScrn, 8209885543Smrg int PowerManagementMode, int flags); 8309885543Smrgstatic Bool SMI_ddc1(int scrnIndex); 8409885543Smrgstatic unsigned int SMI_ddc1Read(ScrnInfoPtr pScrn); 8509885543Smrgstatic void SMI_FreeScreen(int ScrnIndex, int flags); 8609885543Smrgstatic void SMI_ProbeDDC(ScrnInfoPtr pScrn, int index); 8709885543Smrgstatic void SMI_DetectPanelSize(ScrnInfoPtr pScrn); 8809885543Smrg 8909885543Smrg 9009885543Smrg#define SILICONMOTION_NAME "Silicon Motion" 9109885543Smrg#define SILICONMOTION_DRIVER_NAME "siliconmotion" 9209885543Smrg#define SILICONMOTION_VERSION_NAME "1.4.1" 9309885543Smrg#define SILICONMOTION_VERSION_MAJOR 1 9409885543Smrg#define SILICONMOTION_VERSION_MINOR 4 9509885543Smrg#define SILICONMOTION_PATCHLEVEL 1 9609885543Smrg#define SILICONMOTION_DRIVER_VERSION ((SILICONMOTION_VERSION_MAJOR << 24) | \ 9709885543Smrg (SILICONMOTION_VERSION_MINOR << 16) | \ 9809885543Smrg (SILICONMOTION_PATCHLEVEL)) 9909885543Smrg 10009885543Smrg/* 10109885543Smrg * This contains the functions needed by the server after loading the 10209885543Smrg * driver module. It must be supplied, and gets added the driver list by 10309885543Smrg * the Module Setup funtion in the dynamic case. In the static case a 10409885543Smrg * reference to this is compiled in, and this requires that the name of 10509885543Smrg * this DriverRec be an upper-case version of the driver name. 10609885543Smrg */ 10709885543Smrg 10809885543Smrg_X_EXPORT DriverRec SILICONMOTION = 10909885543Smrg{ 11009885543Smrg SILICONMOTION_DRIVER_VERSION, 11109885543Smrg SILICONMOTION_DRIVER_NAME, 11209885543Smrg SMI_Identify, 11309885543Smrg SMI_Probe, 11409885543Smrg SMI_AvailableOptions, 11509885543Smrg NULL, 11609885543Smrg 0 11709885543Smrg}; 11809885543Smrg 11909885543Smrg/* Supported chipsets */ 12009885543Smrgstatic SymTabRec SMIChipsets[] = 12109885543Smrg{ 12209885543Smrg { PCI_CHIP_SMI910, "Lynx" }, 12309885543Smrg { PCI_CHIP_SMI810, "LynxE" }, 12409885543Smrg { PCI_CHIP_SMI820, "Lynx3D" }, 12509885543Smrg { PCI_CHIP_SMI710, "LynxEM" }, 12609885543Smrg { PCI_CHIP_SMI712, "LynxEM+" }, 12709885543Smrg { PCI_CHIP_SMI720, "Lynx3DM" }, 12809885543Smrg { PCI_CHIP_SMI731, "Cougar3DR" }, 12909885543Smrg { -1, NULL } 13009885543Smrg}; 13109885543Smrg 13209885543Smrgstatic PciChipsets SMIPciChipsets[] = 13309885543Smrg{ 13409885543Smrg /* numChipset, PciID, Resource */ 13509885543Smrg { PCI_CHIP_SMI910, PCI_CHIP_SMI910, RES_SHARED_VGA }, 13609885543Smrg { PCI_CHIP_SMI810, PCI_CHIP_SMI810, RES_SHARED_VGA }, 13709885543Smrg { PCI_CHIP_SMI820, PCI_CHIP_SMI820, RES_SHARED_VGA }, 13809885543Smrg { PCI_CHIP_SMI710, PCI_CHIP_SMI710, RES_SHARED_VGA }, 13909885543Smrg { PCI_CHIP_SMI712, PCI_CHIP_SMI712, RES_SHARED_VGA }, 14009885543Smrg { PCI_CHIP_SMI720, PCI_CHIP_SMI720, RES_SHARED_VGA }, 14109885543Smrg { PCI_CHIP_SMI731, PCI_CHIP_SMI731, RES_SHARED_VGA }, 14209885543Smrg { -1, -1, RES_UNDEFINED } 14309885543Smrg}; 14409885543Smrg 14509885543Smrgtypedef enum 14609885543Smrg{ 14709885543Smrg OPTION_PCI_BURST, 14809885543Smrg OPTION_FIFO_CONSERV, 14909885543Smrg OPTION_FIFO_MODERATE, 15009885543Smrg OPTION_FIFO_AGGRESSIVE, 15109885543Smrg OPTION_PCI_RETRY, 15209885543Smrg OPTION_NOACCEL, 15309885543Smrg OPTION_MCLK, 15409885543Smrg OPTION_SHOWCACHE, 15509885543Smrg OPTION_SWCURSOR, 15609885543Smrg OPTION_HWCURSOR, 15709885543Smrg OPTION_SHADOW_FB, 15809885543Smrg OPTION_ROTATE, 15909885543Smrg OPTION_VIDEOKEY, 16009885543Smrg OPTION_BYTESWAP, 16109885543Smrg /* CZ 26.10.2001: interlaced video */ 16209885543Smrg OPTION_INTERLACED, 16309885543Smrg /* end CZ */ 16409885543Smrg OPTION_USEBIOS, 16509885543Smrg OPTION_ZOOMONLCD, 16609885543Smrg OPTION_DUALHEAD, 16709885543Smrg OPTION_ACCELMETHOD, 16809885543Smrg NUMBER_OF_OPTIONS 16909885543Smrg} SMIOpts; 17009885543Smrg 17109885543Smrgstatic const OptionInfoRec SMIOptions[] = 17209885543Smrg{ 17309885543Smrg { OPTION_PCI_BURST, "pci_burst", OPTV_BOOLEAN, {0}, FALSE }, 17409885543Smrg { OPTION_FIFO_CONSERV, "fifo_conservative", OPTV_BOOLEAN, {0}, FALSE }, 17509885543Smrg { OPTION_FIFO_MODERATE, "fifo_moderate", OPTV_BOOLEAN, {0}, FALSE }, 17609885543Smrg { OPTION_FIFO_AGGRESSIVE, "fifo_aggressive", OPTV_BOOLEAN, {0}, FALSE }, 17709885543Smrg { OPTION_PCI_RETRY, "pci_retry", OPTV_BOOLEAN, {0}, FALSE }, 17809885543Smrg { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 17909885543Smrg { OPTION_MCLK, "set_mclk", OPTV_FREQ, {0}, FALSE }, 18009885543Smrg { OPTION_SHOWCACHE, "show_cache", OPTV_BOOLEAN, {0}, FALSE }, 18109885543Smrg { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE }, 18209885543Smrg { OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE }, 18309885543Smrg { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 18409885543Smrg { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, 18509885543Smrg { OPTION_VIDEOKEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, 18609885543Smrg { OPTION_BYTESWAP, "ByteSwap", OPTV_BOOLEAN, {0}, FALSE }, 18709885543Smrg /* CZ 26.10.2001: interlaced video */ 18809885543Smrg { OPTION_INTERLACED, "Interlaced", OPTV_BOOLEAN, {0}, FALSE }, 18909885543Smrg /* end CZ */ 19009885543Smrg { OPTION_USEBIOS, "UseBIOS", OPTV_BOOLEAN, {0}, FALSE }, 19109885543Smrg { OPTION_ZOOMONLCD, "ZoomOnLCD", OPTV_BOOLEAN, {0}, FALSE }, 19209885543Smrg { OPTION_DUALHEAD, "Dualhead", OPTV_BOOLEAN, {0}, FALSE }, 19309885543Smrg { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, 19409885543Smrg { -1, NULL, OPTV_NONE, {0}, FALSE } 19509885543Smrg}; 19609885543Smrg 19709885543Smrg/* 19809885543Smrg * Lists of symbols that may/may not be required by this driver. 19909885543Smrg * This allows the loader to know which ones to issue warnings for. 20009885543Smrg * 20109885543Smrg * Note that vgahwSymbols and xaaSymbols are referenced outside the 20209885543Smrg * XFree86LOADER define in later code, so are defined outside of that 20309885543Smrg * define here also. 20409885543Smrg */ 20509885543Smrg 20609885543Smrgstatic const char *vgahwSymbols[] = 20709885543Smrg{ 20809885543Smrg "vgaHWCopyReg", 20909885543Smrg "vgaHWGetHWRec", 21009885543Smrg "vgaHWGetIOBase", 21109885543Smrg "vgaHWGetIndex", 21209885543Smrg "vgaHWInit", 21309885543Smrg "vgaHWLock", 21409885543Smrg "vgaHWMapMem", 21509885543Smrg "vgaHWProtect", 21609885543Smrg "vgaHWRestore", 21709885543Smrg "vgaHWSave", 21809885543Smrg "vgaHWSaveScreen", 21909885543Smrg "vgaHWSetMmioFuncs", 22009885543Smrg "vgaHWSetStdFuncs", 22109885543Smrg "vgaHWUnmapMem", 22209885543Smrg "vgaHWddc1SetSpeedWeak", 22309885543Smrg NULL 22409885543Smrg}; 22509885543Smrg 22609885543Smrgstatic const char *xaaSymbols[] = 22709885543Smrg{ 22809885543Smrg "XAAGetCopyROP", 22909885543Smrg "XAACreateInfoRec", 23009885543Smrg "XAADestroyInfoRec", 23109885543Smrg "XAAGetFallbackOps", 23209885543Smrg "XAAInit", 23309885543Smrg "XAAGetPatternROP", 23409885543Smrg NULL 23509885543Smrg}; 23609885543Smrg 23709885543Smrgstatic const char *exaSymbols[] = 23809885543Smrg{ 23909885543Smrg "exaDriverAlloc", 24009885543Smrg "exaDriverInit", 24109885543Smrg "exaDriverFini", 24209885543Smrg "exaOffscreenAlloc", 24309885543Smrg "exaOffscreenFree", 24409885543Smrg "exaGetPixmapPitch", 24509885543Smrg "exaGetPixmapOffset", 24609885543Smrg "exaGetPixmapSize", 24709885543Smrg NULL 24809885543Smrg}; 24909885543Smrg 25009885543Smrgstatic const char *ramdacSymbols[] = 25109885543Smrg{ 25209885543Smrg "xf86CreateCursorInfoRec", 25309885543Smrg "xf86DestroyCursorInfoRec", 25409885543Smrg "xf86InitCursor", 25509885543Smrg NULL 25609885543Smrg}; 25709885543Smrg 25809885543Smrgstatic const char *ddcSymbols[] = 25909885543Smrg{ 26009885543Smrg "xf86PrintEDID", 26109885543Smrg "xf86DoEDID_DDC1", 26209885543Smrg "xf86DoEDID_DDC2", 26309885543Smrg "xf86SetDDCproperties", 26409885543Smrg NULL 26509885543Smrg}; 26609885543Smrg 26709885543Smrgstatic const char *i2cSymbols[] = 26809885543Smrg{ 26909885543Smrg "xf86CreateI2CBusRec", 27009885543Smrg "xf86CreateI2CDevRec", 27109885543Smrg "xf86DestroyI2CBusRec", 27209885543Smrg "xf86DestroyI2CDevRec", 27309885543Smrg "xf86I2CBusInit", 27409885543Smrg "xf86I2CDevInit", 27509885543Smrg "xf86I2CReadBytes", 27609885543Smrg "xf86I2CWriteByte", 27709885543Smrg NULL 27809885543Smrg}; 27909885543Smrg 28009885543Smrgstatic const char *shadowSymbols[] = 28109885543Smrg{ 28209885543Smrg "ShadowFBInit", 28309885543Smrg NULL 28409885543Smrg}; 28509885543Smrg 28609885543Smrgstatic const char *int10Symbols[] = 28709885543Smrg{ 28809885543Smrg "xf86ExecX86int10", 28909885543Smrg "xf86FreeInt10", 29009885543Smrg "xf86InitInt10", 29109885543Smrg NULL 29209885543Smrg}; 29309885543Smrg 29409885543Smrgstatic const char *vbeSymbols[] = 29509885543Smrg{ 29609885543Smrg "VBEInit", 29709885543Smrg "vbeDoEDID", 29809885543Smrg "vbeFree", 29909885543Smrg NULL 30009885543Smrg}; 30109885543Smrg 30209885543Smrgstatic const char *fbSymbols[] = 30309885543Smrg{ 30409885543Smrg "fbPictureInit", 30509885543Smrg "fbScreenInit", 30609885543Smrg NULL 30709885543Smrg}; 30809885543Smrg 30909885543Smrg#ifdef XFree86LOADER 31009885543Smrg 31109885543Smrgstatic MODULESETUPPROTO(siliconmotionSetup); 31209885543Smrg 31309885543Smrgstatic XF86ModuleVersionInfo SMIVersRec = 31409885543Smrg{ 31509885543Smrg "siliconmotion", 31609885543Smrg MODULEVENDORSTRING, 31709885543Smrg MODINFOSTRING1, 31809885543Smrg MODINFOSTRING2, 31909885543Smrg XORG_VERSION_CURRENT, 32009885543Smrg SILICONMOTION_VERSION_MAJOR, 32109885543Smrg SILICONMOTION_VERSION_MINOR, 32209885543Smrg SILICONMOTION_PATCHLEVEL, 32309885543Smrg ABI_CLASS_VIDEODRV, 32409885543Smrg ABI_VIDEODRV_VERSION, 32509885543Smrg MOD_CLASS_VIDEODRV, 32609885543Smrg {0, 0, 0, 0} 32709885543Smrg}; 32809885543Smrg 32909885543Smrg/* 33009885543Smrg * This is the module init data for XFree86 modules. 33109885543Smrg * 33209885543Smrg * Its name has to be the driver name followed by ModuleData. 33309885543Smrg */ 33409885543Smrg_X_EXPORT XF86ModuleData siliconmotionModuleData = 33509885543Smrg{ 33609885543Smrg &SMIVersRec, 33709885543Smrg siliconmotionSetup, 33809885543Smrg NULL 33909885543Smrg}; 34009885543Smrg 34109885543Smrgstatic pointer 34209885543SmrgsiliconmotionSetup(pointer module, pointer opts, int *errmaj, int *errmin) 34309885543Smrg{ 34409885543Smrg static Bool setupDone = FALSE; 34509885543Smrg 34609885543Smrg if (!setupDone) { 34709885543Smrg setupDone = TRUE; 34809885543Smrg xf86AddDriver(&SILICONMOTION, module, 0); 34909885543Smrg 35009885543Smrg /* 35109885543Smrg * Modules that this driver always requires can be loaded here 35209885543Smrg * by calling LoadSubModule(). 35309885543Smrg */ 35409885543Smrg 35509885543Smrg /* 35609885543Smrg * Tell the loader about symbols from other modules that this module 35709885543Smrg * might refer to. 35809885543Smrg */ 35909885543Smrg LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols, exaSymbols, ramdacSymbols, 36009885543Smrg ddcSymbols, i2cSymbols, int10Symbols, vbeSymbols, 36109885543Smrg shadowSymbols, NULL); 36209885543Smrg 36309885543Smrg /* 36409885543Smrg * The return value must be non-NULL on success even though there 36509885543Smrg * is no TearDownProc. 36609885543Smrg */ 36709885543Smrg return (pointer) 1; 36809885543Smrg 36909885543Smrg } else { 37009885543Smrg if (errmaj) { 37109885543Smrg *errmaj = LDR_ONCEONLY; 37209885543Smrg } 37309885543Smrg return NULL; 37409885543Smrg } 37509885543Smrg} 37609885543Smrg 37709885543Smrg#endif /* XFree86LOADER */ 37809885543Smrg 37909885543Smrgstatic Bool 38009885543SmrgSMI_GetRec(ScrnInfoPtr pScrn) 38109885543Smrg{ 38209885543Smrg ENTER_PROC("SMI_GetRec"); 38309885543Smrg 38409885543Smrg /* 38509885543Smrg * Allocate an 'Chip'Rec, and hook it into pScrn->driverPrivate. 38609885543Smrg * pScrn->driverPrivate is initialised to NULL, so we can check if 38709885543Smrg * the allocation has already been done. 38809885543Smrg */ 38909885543Smrg if (pScrn->driverPrivate == NULL) { 39009885543Smrg pScrn->driverPrivate = xnfcalloc(sizeof(SMIRec), 1); 39109885543Smrg } 39209885543Smrg 39309885543Smrg LEAVE_PROC("SMI_GetRec"); 39409885543Smrg return TRUE; 39509885543Smrg} 39609885543Smrg 39709885543Smrgstatic void 39809885543SmrgSMI_FreeRec(ScrnInfoPtr pScrn) 39909885543Smrg{ 40009885543Smrg ENTER_PROC("SMI_FreeRec"); 40109885543Smrg 40209885543Smrg if (pScrn->driverPrivate != NULL) { 40309885543Smrg xfree(pScrn->driverPrivate); 40409885543Smrg pScrn->driverPrivate = NULL; 40509885543Smrg } 40609885543Smrg 40709885543Smrg LEAVE_PROC("SMI_FreeRec"); 40809885543Smrg} 40909885543Smrg 41009885543Smrgstatic const OptionInfoRec * 41109885543SmrgSMI_AvailableOptions(int chipid, int busid) 41209885543Smrg{ 41309885543Smrg ENTER_PROC("SMI_AvailableOptions"); 41409885543Smrg LEAVE_PROC("SMI_AvailableOptions"); 41509885543Smrg return SMIOptions; 41609885543Smrg} 41709885543Smrg 41809885543Smrgstatic void 41909885543SmrgSMI_Identify(int flags) 42009885543Smrg{ 42109885543Smrg ENTER_PROC("SMI_Identify"); 42209885543Smrg 42309885543Smrg xf86PrintChipsets(SILICONMOTION_NAME, "driver (version " 42409885543Smrg SILICONMOTION_VERSION_NAME ") for Silicon Motion Lynx chipsets", 42509885543Smrg SMIChipsets); 42609885543Smrg 42709885543Smrg LEAVE_PROC("SMI_Identify"); 42809885543Smrg} 42909885543Smrg 43009885543Smrgstatic Bool 43109885543SmrgSMI_Probe(DriverPtr drv, int flags) 43209885543Smrg{ 43309885543Smrg int i; 43409885543Smrg GDevPtr *devSections; 43509885543Smrg int *usedChips; 43609885543Smrg int numDevSections; 43709885543Smrg int numUsed; 43809885543Smrg Bool foundScreen = FALSE; 43909885543Smrg 44009885543Smrg ENTER_PROC("SMI_Probe"); 44109885543Smrg 44209885543Smrg numDevSections = xf86MatchDevice(SILICONMOTION_DRIVER_NAME, &devSections); 44309885543Smrg 44409885543Smrg if (numDevSections <= 0) { 44509885543Smrg /* There's no matching device section in the config file, so quit now. */ 44609885543Smrg LEAVE_PROC("SMI_Probe"); 44709885543Smrg return FALSE; 44809885543Smrg } 44909885543Smrg 45009885543Smrg if (xf86GetPciVideoInfo() == NULL) { 45109885543Smrg LEAVE_PROC("SMI_Probe"); 45209885543Smrg return FALSE; 45309885543Smrg } 45409885543Smrg 45509885543Smrg numUsed = xf86MatchPciInstances(SILICONMOTION_NAME, PCI_SMI_VENDOR_ID, 45609885543Smrg SMIChipsets, SMIPciChipsets, devSections, 45709885543Smrg numDevSections, drv, &usedChips); 45809885543Smrg 45909885543Smrg /* Free it since we don't need that list after this */ 46009885543Smrg xfree(devSections); 46109885543Smrg if (numUsed <= 0) { 46209885543Smrg LEAVE_PROC("SMI_Probe"); 46309885543Smrg return FALSE; 46409885543Smrg } 46509885543Smrg 46609885543Smrg if (flags & PROBE_DETECT) { 46709885543Smrg foundScreen = TRUE; 46809885543Smrg } else { 46909885543Smrg for (i = 0; i < numUsed; i++) { 47009885543Smrg /* Allocate a ScrnInfoRec and claim the slot */ 47109885543Smrg ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); 47209885543Smrg 47309885543Smrg /* Fill in what we can of the ScrnInfoRec */ 47409885543Smrg pScrn->driverVersion = SILICONMOTION_DRIVER_VERSION; 47509885543Smrg pScrn->driverName = SILICONMOTION_DRIVER_NAME; 47609885543Smrg pScrn->name = SILICONMOTION_NAME; 47709885543Smrg pScrn->Probe = SMI_Probe; 47809885543Smrg pScrn->PreInit = SMI_PreInit; 47909885543Smrg pScrn->ScreenInit = SMI_ScreenInit; 48009885543Smrg pScrn->SwitchMode = SMI_SwitchMode; 48109885543Smrg pScrn->AdjustFrame = SMI_AdjustFrame; 48209885543Smrg pScrn->EnterVT = SMI_EnterVT; 48309885543Smrg pScrn->LeaveVT = SMI_LeaveVT; 48409885543Smrg pScrn->FreeScreen = SMI_FreeScreen; 48509885543Smrg pScrn->ValidMode = SMI_ValidMode; 48609885543Smrg foundScreen = TRUE; 48709885543Smrg 48809885543Smrg xf86ConfigActivePciEntity(pScrn, usedChips[i], SMIPciChipsets, NULL, 48909885543Smrg NULL, NULL, NULL, NULL); 49009885543Smrg } 49109885543Smrg } 49209885543Smrg xfree(usedChips); 49309885543Smrg 49409885543Smrg LEAVE_PROC("SMI_Probe"); 49509885543Smrg return foundScreen; 49609885543Smrg} 49709885543Smrg 49809885543Smrgstatic Bool 49909885543SmrgSMI_PreInit(ScrnInfoPtr pScrn, int flags) 50009885543Smrg{ 50109885543Smrg EntityInfoPtr pEnt; 50209885543Smrg SMIPtr pSmi; 50309885543Smrg MessageType from; 50409885543Smrg int i; 50509885543Smrg double real; 50609885543Smrg ClockRangePtr clockRanges; 50709885543Smrg char *s; 50809885543Smrg unsigned char config, m, n, shift; 50909885543Smrg int mclk; 51009885543Smrg vgaHWPtr hwp; 51109885543Smrg int vgaCRIndex, vgaIOBase; 51209885543Smrg vbeInfoPtr pVbe = NULL; 51309885543Smrg 51409885543Smrg ENTER_PROC("SMI_PreInit"); 51509885543Smrg 51609885543Smrg if (flags & PROBE_DETECT) { 51709885543Smrg SMI_ProbeDDC(pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index); 51809885543Smrg LEAVE_PROC("SMI_PreInit"); 51909885543Smrg return TRUE; 52009885543Smrg } 52109885543Smrg 52209885543Smrg /* Ignoring the Type list for now. It might be needed when multiple cards 52309885543Smrg * are supported. 52409885543Smrg */ 52509885543Smrg if (pScrn->numEntities > 1) { 52609885543Smrg LEAVE_PROC("SMI_PreInit"); 52709885543Smrg return FALSE; 52809885543Smrg } 52909885543Smrg 53009885543Smrg /* The vgahw module should be loaded here when needed */ 53109885543Smrg if (!xf86LoadSubModule(pScrn, "vgahw")) { 53209885543Smrg LEAVE_PROC("SMI_PreInit"); 53309885543Smrg return FALSE; 53409885543Smrg } 53509885543Smrg 53609885543Smrg xf86LoaderReqSymLists(vgahwSymbols, NULL); 53709885543Smrg 53809885543Smrg /* 53909885543Smrg * Allocate a vgaHWRec 54009885543Smrg */ 54109885543Smrg if (!vgaHWGetHWRec(pScrn)) { 54209885543Smrg LEAVE_PROC("SMI_PreInit"); 54309885543Smrg return FALSE; 54409885543Smrg } 54509885543Smrg 54609885543Smrg /* Allocate the SMIRec driverPrivate */ 54709885543Smrg if (!SMI_GetRec(pScrn)) { 54809885543Smrg LEAVE_PROC("SMI_PreInit"); 54909885543Smrg return FALSE; 55009885543Smrg } 55109885543Smrg pSmi = SMIPTR(pScrn); 55209885543Smrg 55309885543Smrg /* Set pScrn->monitor */ 55409885543Smrg pScrn->monitor = pScrn->confScreen->monitor; 55509885543Smrg 55609885543Smrg /* 55709885543Smrg * The first thing we should figure out is the depth, bpp, etc. 55809885543Smrg */ 55909885543Smrg if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) { 56009885543Smrg LEAVE_PROC("SMI_PreInit"); 56109885543Smrg return FALSE; 56209885543Smrg } 56309885543Smrg 56409885543Smrg /* Check that the returned depth is one we support */ 56509885543Smrg switch (pScrn->depth) { 56609885543Smrg case 8: 56709885543Smrg case 16: 56809885543Smrg case 24: 56909885543Smrg /* OK */ 57009885543Smrg break; 57109885543Smrg 57209885543Smrg default: 57309885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 57409885543Smrg "Given depth (%d) is not supported by this driver\n", 57509885543Smrg pScrn->depth); 57609885543Smrg LEAVE_PROC("SMI_PreInit"); 57709885543Smrg return FALSE; 57809885543Smrg } 57909885543Smrg 58009885543Smrg xf86PrintDepthBpp(pScrn); 58109885543Smrg 58209885543Smrg /* 58309885543Smrg * This must happen after pScrn->display has been set because 58409885543Smrg * xf86SetWeight references it. 58509885543Smrg */ 58609885543Smrg if (pScrn->depth > 8) { 58709885543Smrg /* The defaults are OK for us */ 58809885543Smrg rgb zeros = {0, 0, 0}; 58909885543Smrg 59009885543Smrg if (!xf86SetWeight(pScrn, zeros, zeros)) { 59109885543Smrg LEAVE_PROC("SMI_PreInit"); 59209885543Smrg return FALSE; 59309885543Smrg } 59409885543Smrg } 59509885543Smrg 59609885543Smrg if (!xf86SetDefaultVisual(pScrn, -1)) { 59709885543Smrg LEAVE_PROC("SMI_PreInit"); 59809885543Smrg return FALSE; 59909885543Smrg } 60009885543Smrg 60109885543Smrg /* We don't currently support DirectColor at > 8bpp */ 60209885543Smrg if ((pScrn->depth > 8) && (pScrn->defaultVisual != TrueColor)) { 60309885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual (%s) " 60409885543Smrg "is not supported at depth %d\n", 60509885543Smrg xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 60609885543Smrg LEAVE_PROC("SMI_PreInit"); 60709885543Smrg return FALSE; 60809885543Smrg } 60909885543Smrg 61009885543Smrg /* We use a programmable clock */ 61109885543Smrg pScrn->progClock = TRUE; 61209885543Smrg 61309885543Smrg /* Collect all of the relevant option flags (fill in pScrn->options) */ 61409885543Smrg xf86CollectOptions(pScrn, NULL); 61509885543Smrg 61609885543Smrg /* Set the bits per RGB for 8bpp mode */ 61709885543Smrg if (pScrn->depth == 8) { 61809885543Smrg pScrn->rgbBits = 6; 61909885543Smrg } 62009885543Smrg 62109885543Smrg /* Process the options */ 62209885543Smrg if (!(pSmi->Options = xalloc(sizeof(SMIOptions)))) 62309885543Smrg return FALSE; 62409885543Smrg memcpy(pSmi->Options, SMIOptions, sizeof(SMIOptions)); 62509885543Smrg xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pSmi->Options); 62609885543Smrg 62709885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_PCI_BURST, FALSE)) { 62809885543Smrg pSmi->pci_burst = TRUE; 62909885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: pci_burst - PCI burst " 63009885543Smrg "read enabled\n"); 63109885543Smrg } else { 63209885543Smrg pSmi->pci_burst = FALSE; 63309885543Smrg } 63409885543Smrg 63509885543Smrg pSmi->NoPCIRetry = TRUE; 63609885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_PCI_RETRY, FALSE)) { 63709885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_PCI_BURST, FALSE)) { 63809885543Smrg pSmi->NoPCIRetry = FALSE; 63909885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: pci_retry\n"); 64009885543Smrg } else { 64109885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"pci_retry\" option " 64209885543Smrg "requires \"pci_burst\".\n"); 64309885543Smrg } 64409885543Smrg } 64509885543Smrg 64609885543Smrg if (xf86IsOptionSet(pSmi->Options, OPTION_FIFO_CONSERV)) { 64709885543Smrg pSmi->fifo_conservative = TRUE; 64809885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo_conservative " 64909885543Smrg "set\n"); 65009885543Smrg } else { 65109885543Smrg pSmi->fifo_conservative = FALSE; 65209885543Smrg } 65309885543Smrg 65409885543Smrg if (xf86IsOptionSet(pSmi->Options, OPTION_FIFO_MODERATE)) { 65509885543Smrg pSmi->fifo_moderate = TRUE; 65609885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo_moderate set\n"); 65709885543Smrg } else { 65809885543Smrg pSmi->fifo_moderate = FALSE; 65909885543Smrg } 66009885543Smrg 66109885543Smrg if (xf86IsOptionSet(pSmi->Options, OPTION_FIFO_AGGRESSIVE)) { 66209885543Smrg pSmi->fifo_aggressive = TRUE; 66309885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo_aggressive set\n"); 66409885543Smrg } else { 66509885543Smrg pSmi->fifo_aggressive = FALSE; 66609885543Smrg } 66709885543Smrg 66809885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_NOACCEL, FALSE)) { 66909885543Smrg pSmi->NoAccel = TRUE; 67009885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - Acceleration " 67109885543Smrg "disabled\n"); 67209885543Smrg } else { 67309885543Smrg pSmi->NoAccel = FALSE; 67409885543Smrg } 67509885543Smrg 67609885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_SHOWCACHE, FALSE)) { 67709885543Smrg pSmi->ShowCache = TRUE; 67809885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: show_cache set\n"); 67909885543Smrg } else { 68009885543Smrg pSmi->ShowCache = FALSE; 68109885543Smrg } 68209885543Smrg 68309885543Smrg if (xf86GetOptValFreq(pSmi->Options, OPTION_MCLK, OPTUNITS_MHZ, &real)) { 68409885543Smrg pSmi->MCLK = (int)(real * 1000.0); 68509885543Smrg if (pSmi->MCLK <= 120000) { 68609885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: set_mclk set to " 68709885543Smrg "%1.3f MHz\n", pSmi->MCLK / 1000.0); 68809885543Smrg } else { 68909885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Memory Clock value of " 69009885543Smrg "%1.3f MHz is larger than limit of 120 MHz\n", 69109885543Smrg pSmi->MCLK / 1000.0); 69209885543Smrg pSmi->MCLK = 0; 69309885543Smrg } 69409885543Smrg } else { 69509885543Smrg pSmi->MCLK = 0; 69609885543Smrg } 69709885543Smrg 69809885543Smrg from = X_DEFAULT; 69909885543Smrg pSmi->hwcursor = TRUE; 70009885543Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_HWCURSOR, &pSmi->hwcursor)) { 70109885543Smrg from = X_CONFIG; 70209885543Smrg } 70309885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_SWCURSOR, FALSE)) { 70409885543Smrg pSmi->hwcursor = FALSE; 70509885543Smrg from = X_CONFIG; 70609885543Smrg } 70709885543Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Using %s Cursor\n", 70809885543Smrg pSmi->hwcursor ? "Hardware" : "Software"); 70909885543Smrg 71009885543Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_SHADOW_FB, &pSmi->shadowFB)) { 71109885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n", 71209885543Smrg pSmi->shadowFB ? "enabled" : "disabled"); 71309885543Smrg } 71409885543Smrg 71509885543Smrg#if 1 /* PDR#932 */ 71609885543Smrg if ((pScrn->depth == 8) || (pScrn->depth == 16)) 71709885543Smrg#endif /* PDR#932 */ 71809885543Smrg if ((s = xf86GetOptValString(pSmi->Options, OPTION_ROTATE))) { 71909885543Smrg if (!xf86NameCmp(s, "CW")) { 72009885543Smrg pSmi->shadowFB = TRUE; 72109885543Smrg pSmi->rotate = SMI_ROTATE_CCW; 72209885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen " 72309885543Smrg "clockwise\n"); 72409885543Smrg } else if (!xf86NameCmp(s, "CCW")) { 72509885543Smrg pSmi->shadowFB = TRUE; 72609885543Smrg pSmi->rotate = SMI_ROTATE_CW; 72709885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen counter " 72809885543Smrg "clockwise\n"); 72909885543Smrg } else { 73009885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid " 73109885543Smrg "value for Option \"Rotate\"\n", s); 73209885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Valid options are \"CW\" or " 73309885543Smrg "\"CCW\"\n"); 73409885543Smrg } 73509885543Smrg } 73609885543Smrg 73709885543Smrg if (pSmi->rotate) { 73809885543Smrg /* Disable the RandR extension, it messes up the internal rotation stuff */ 73909885543Smrg xf86DisableRandR(); 74009885543Smrg } 74109885543Smrg 74209885543Smrg if (xf86GetOptValInteger(pSmi->Options, OPTION_VIDEOKEY, &pSmi->videoKey)) { 74309885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Video key set to " 74409885543Smrg "0x%08X\n", pSmi->videoKey); 74509885543Smrg } else { 74609885543Smrg pSmi->videoKey = (1 << pScrn->offset.red) | 74709885543Smrg (1 << pScrn->offset.green) | 74809885543Smrg (((pScrn->mask.blue >> pScrn->offset.blue) - 1) 74909885543Smrg << pScrn->offset.blue); 75009885543Smrg } 75109885543Smrg 75209885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_BYTESWAP, FALSE)) { 75309885543Smrg pSmi->ByteSwap = TRUE; 75409885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: ByteSwap enabled.\n"); 75509885543Smrg } else { 75609885543Smrg pSmi->ByteSwap = FALSE; 75709885543Smrg } 75809885543Smrg 75909885543Smrg /* CZ 26.10.2001: interlaced video */ 76009885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_INTERLACED, FALSE)) { 76109885543Smrg pSmi->interlaced = TRUE; 76209885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Interlaced enabled.\n"); 76309885543Smrg } else { 76409885543Smrg pSmi->interlaced = FALSE; 76509885543Smrg } 76609885543Smrg /* end CZ */ 76709885543Smrg 76809885543Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_USEBIOS, &pSmi->useBIOS)) { 76909885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: UseBIOS %s.\n", 77009885543Smrg pSmi->useBIOS ? "enabled" : "disabled"); 77109885543Smrg } else { 77209885543Smrg /* Default to UseBIOS enabled. */ 77309885543Smrg pSmi->useBIOS = TRUE; 77409885543Smrg } 77509885543Smrg 77609885543Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_ZOOMONLCD, &pSmi->zoomOnLCD)) { 77709885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: ZoomOnLCD %s.\n", 77809885543Smrg pSmi->zoomOnLCD ? "enabled" : "disabled"); 77909885543Smrg } else { 78009885543Smrg /* Default to ZoomOnLCD enabled. */ 78109885543Smrg pSmi->zoomOnLCD = TRUE; 78209885543Smrg } 78309885543Smrg 78409885543Smrg /* Find the PCI slot for this screen */ 78509885543Smrg pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 78609885543Smrg if ((pEnt->location.type != BUS_PCI) || (pEnt->resources)) { 78709885543Smrg xfree(pEnt); 78809885543Smrg SMI_FreeRec(pScrn); 78909885543Smrg LEAVE_PROC("SMI_PreInit"); 79009885543Smrg return FALSE; 79109885543Smrg } 79209885543Smrg 79309885543Smrg if (xf86LoadSubModule(pScrn,"int10")) { 79409885543Smrg xf86LoaderReqSymLists(int10Symbols,NULL); 79509885543Smrg pSmi->pInt10 = xf86InitInt10(pEnt->index); 79609885543Smrg } 79709885543Smrg 79809885543Smrg if (pSmi->pInt10 && xf86LoadSubModule(pScrn, "vbe")) { 79909885543Smrg xf86LoaderReqSymLists(vbeSymbols, NULL); 80009885543Smrg pVbe = VBEInit(pSmi->pInt10, pEnt->index); 80109885543Smrg } 80209885543Smrg 80309885543Smrg pSmi->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 80409885543Smrg xf86RegisterResources(pEnt->index, NULL, ResExclusive); 80509885543Smrg/* xf86SetOperatingState(resVgaIo, pEnt->index, ResUnusedOpr); */ 80609885543Smrg/* xf86SetOperatingState(resVgaMem, pEnt->index, ResDisableOpr); */ 80709885543Smrg 80809885543Smrg /* 80909885543Smrg * Set the Chipset and ChipRev, allowing config file entries to 81009885543Smrg * override. 81109885543Smrg */ 81209885543Smrg if (pEnt->device->chipset && *pEnt->device->chipset) { 81309885543Smrg pScrn->chipset = pEnt->device->chipset; 81409885543Smrg pSmi->Chipset = xf86StringToToken(SMIChipsets, pScrn->chipset); 81509885543Smrg from = X_CONFIG; 81609885543Smrg } else if (pEnt->device->chipID >= 0) { 81709885543Smrg pSmi->Chipset = pEnt->device->chipID; 81809885543Smrg pScrn->chipset = (char *) xf86TokenToString(SMIChipsets, pSmi->Chipset); 81909885543Smrg from = X_CONFIG; 82009885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 82109885543Smrg pSmi->Chipset); 82209885543Smrg } else { 82309885543Smrg from = X_PROBED; 82409885543Smrg pSmi->Chipset = pSmi->PciInfo->chipType; 82509885543Smrg pScrn->chipset = (char *) xf86TokenToString(SMIChipsets, pSmi->Chipset); 82609885543Smrg } 82709885543Smrg 82809885543Smrg if (pEnt->device->chipRev >= 0) { 82909885543Smrg pSmi->ChipRev = pEnt->device->chipRev; 83009885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 83109885543Smrg pSmi->ChipRev); 83209885543Smrg } else { 83309885543Smrg pSmi->ChipRev = pSmi->PciInfo->chipRev; 83409885543Smrg } 83509885543Smrg xfree(pEnt); 83609885543Smrg 83709885543Smrg /* 83809885543Smrg * This shouldn't happen because such problems should be caught in 83909885543Smrg * SMI_Probe(), but check it just in case. 84009885543Smrg */ 84109885543Smrg if (pScrn->chipset == NULL) { 84209885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04X is not " 84309885543Smrg "recognised\n", pSmi->Chipset); 84409885543Smrg LEAVE_PROC("SMI_PreInit"); 84509885543Smrg return FALSE; 84609885543Smrg } 84709885543Smrg 84809885543Smrg if (pSmi->Chipset < 0) { 84909885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Chipset \"%s\" is not " 85009885543Smrg "recognised\n", pScrn->chipset); 85109885543Smrg LEAVE_PROC("SMI_PreInit"); 85209885543Smrg return FALSE; 85309885543Smrg } 85409885543Smrg 85509885543Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); 85609885543Smrg 85709885543Smrg pSmi->PciTag = pciTag(pSmi->PciInfo->bus, pSmi->PciInfo->device, 85809885543Smrg pSmi->PciInfo->func); 85909885543Smrg 86009885543Smrg pSmi->Dualhead = FALSE; 86109885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_DUALHEAD, FALSE) && 86209885543Smrg SMI_LYNXM_SERIES(pSmi->Chipset)) { 86309885543Smrg pSmi->Dualhead = TRUE; 86409885543Smrg } 86509885543Smrg 86609885543Smrg /* tweak options for dualhead */ 86709885543Smrg if (pSmi->Dualhead) { 86809885543Smrg pSmi->useBIOS = FALSE; 86909885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "UseBIOS disabled in dualhead mode\n"); 87009885543Smrg pSmi->hwcursor = FALSE; 87109885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No hardware cursor in dualhead mode\n"); 87209885543Smrg if (pScrn->bitsPerPixel != 16) { 87309885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Dualhead only supported at " 87409885543Smrg "depth 16\n"); 87509885543Smrg return FALSE; 87609885543Smrg } 87709885543Smrg } 87809885543Smrg 87909885543Smrg SMI_MapMem(pScrn); 88009885543Smrg SMI_DisableVideo(pScrn); 88109885543Smrg 88209885543Smrg hwp = VGAHWPTR(pScrn); 88309885543Smrg vgaIOBase = hwp->IOBase; 88409885543Smrg vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; 88509885543Smrg pSmi->PIOBase = hwp->PIOOffset; 88609885543Smrg 88709885543Smrg xf86ErrorFVerb(VERBLEV, "\tSMI_PreInit vgaCRIndex=%x, vgaIOBase=%x, " 88809885543Smrg "MMIOBase=%p\n", vgaCRIndex, vgaIOBase, hwp->MMIOBase); 88909885543Smrg 89009885543Smrg /* detect the panel size */ 89109885543Smrg SMI_DetectPanelSize(pScrn); 89209885543Smrg 89309885543Smrg if (xf86LoadSubModule(pScrn, "i2c")) { 89409885543Smrg xf86LoaderReqSymLists(i2cSymbols, NULL); 89509885543Smrg SMI_I2CInit(pScrn); 89609885543Smrg } 89709885543Smrg 89809885543Smrg if (xf86LoadSubModule(pScrn, "ddc")) { 89909885543Smrg xf86MonPtr pMon = NULL; 90009885543Smrg 90109885543Smrg xf86LoaderReqSymLists(ddcSymbols, NULL); 90209885543Smrg#if 1 /* PDR#579 */ 90309885543Smrg if (pVbe) { 90409885543Smrg pMon = vbeDoEDID(pVbe, NULL); 90509885543Smrg if (pMon != NULL) { 90609885543Smrg if ((pMon->rawData[0] == 0x00) && 90709885543Smrg (pMon->rawData[1] == 0xFF) && 90809885543Smrg (pMon->rawData[2] == 0xFF) && 90909885543Smrg (pMon->rawData[3] == 0xFF) && 91009885543Smrg (pMon->rawData[4] == 0xFF) && 91109885543Smrg (pMon->rawData[5] == 0xFF) && 91209885543Smrg (pMon->rawData[6] == 0xFF) && 91309885543Smrg (pMon->rawData[7] == 0x00)) { 91409885543Smrg pMon = xf86PrintEDID(pMon); 91509885543Smrg if (pMon != NULL) { 91609885543Smrg xf86SetDDCproperties(pScrn, pMon); 91709885543Smrg } 91809885543Smrg } 91909885543Smrg } 92009885543Smrg#else 92109885543Smrg if ((pVbe) && 92209885543Smrg ((pMon = xf86PrintEDID(vbeDoEDID(pVbe, NULL))) != NULL)) { 92309885543Smrg xf86SetDDCproperties(pScrn, pMon); 92409885543Smrg#endif 92509885543Smrg } else if (!SMI_ddc1(pScrn->scrnIndex)) { 92609885543Smrg if (pSmi->I2C) { 92709885543Smrg xf86SetDDCproperties(pScrn, 92809885543Smrg xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex, 92909885543Smrg pSmi->I2C))); 93009885543Smrg } 93109885543Smrg } 93209885543Smrg } 93309885543Smrg 93409885543Smrg vbeFree(pVbe); 93509885543Smrg xf86FreeInt10(pSmi->pInt10); 93609885543Smrg pSmi->pInt10 = NULL; 93709885543Smrg 93809885543Smrg /* 93909885543Smrg * If the driver can do gamma correction, it should call xf86SetGamma() 94009885543Smrg * here. (from MGA, no ViRGE gamma support yet, but needed for 94109885543Smrg * xf86HandleColormaps support.) 94209885543Smrg */ 94309885543Smrg { 94409885543Smrg Gamma zeros = { 0.0, 0.0, 0.0 }; 94509885543Smrg 94609885543Smrg if (!xf86SetGamma(pScrn, zeros)) { 94709885543Smrg LEAVE_PROC("SMI_PreInit"); 94809885543Smrg SMI_EnableVideo(pScrn); 94909885543Smrg SMI_UnmapMem(pScrn); 95009885543Smrg return FALSE; 95109885543Smrg } 95209885543Smrg } 95309885543Smrg 95409885543Smrg 95509885543Smrg /* Next go on to detect amount of installed ram */ 95609885543Smrg config = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x71); 95709885543Smrg 95809885543Smrg /* And compute the amount of video memory and offscreen memory */ 95909885543Smrg pSmi->videoRAMKBytes = 0; 96009885543Smrg 96109885543Smrg if (!pScrn->videoRam) { 96209885543Smrg switch (pSmi->Chipset) { 96309885543Smrg default: 96409885543Smrg { 96509885543Smrg int mem_table[4] = { 1, 2, 4, 0 }; 96609885543Smrg pSmi->videoRAMKBytes = mem_table[(config >> 6)] * 1024; 96709885543Smrg break; 96809885543Smrg } 96909885543Smrg case SMI_LYNX3D: 97009885543Smrg { 97109885543Smrg int mem_table[4] = { 0, 2, 4, 6 }; 97209885543Smrg pSmi->videoRAMKBytes = mem_table[(config >> 6)] * 1024 + 512; 97309885543Smrg break; 97409885543Smrg } 97509885543Smrg case SMI_LYNX3DM: 97609885543Smrg { 97709885543Smrg int mem_table[4] = { 16, 2, 4, 8 }; 97809885543Smrg pSmi->videoRAMKBytes = mem_table[(config >> 6)] * 1024; 97909885543Smrg break; 98009885543Smrg } 98109885543Smrg case SMI_COUGAR3DR: 98209885543Smrg { 98309885543Smrg /* DANGER - Cougar3DR BIOS is broken - hardcode video ram size */ 98409885543Smrg /* per instructions from Silicon Motion engineers */ 98509885543Smrg pSmi->videoRAMKBytes = 16 * 1024; 98609885543Smrg break; 98709885543Smrg } 98809885543Smrg } 98909885543Smrg pSmi->videoRAMBytes = pSmi->videoRAMKBytes * 1024; 99009885543Smrg pScrn->videoRam = pSmi->videoRAMKBytes; 99109885543Smrg 99209885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "videoram: %dkB\n", 99309885543Smrg pSmi->videoRAMKBytes); 99409885543Smrg } else { 99509885543Smrg pSmi->videoRAMKBytes = pScrn->videoRam; 99609885543Smrg pSmi->videoRAMBytes = pScrn->videoRam * 1024; 99709885543Smrg 99809885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "videoram: %dk\n", 99909885543Smrg pSmi->videoRAMKBytes); 100009885543Smrg } 100109885543Smrg 100209885543Smrg /* Detect current MCLK and print it for user */ 100309885543Smrg m = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A); 100409885543Smrg n = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B); 100509885543Smrg switch (n >> 6) { 100609885543Smrg default: 100709885543Smrg shift = 1; 100809885543Smrg break; 100909885543Smrg case 1: 101009885543Smrg shift = 4; 101109885543Smrg break; 101209885543Smrg case 2: 101309885543Smrg shift = 2; 101409885543Smrg break; 101509885543Smrg } 101609885543Smrg n &= 0x3F; 101709885543Smrg mclk = ((1431818 * m) / n / shift + 50) / 100; 101809885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected current MCLK value of " 101909885543Smrg "%1.3f MHz\n", mclk / 1000.0); 102009885543Smrg 102109885543Smrg SMI_EnableVideo(pScrn); 102209885543Smrg SMI_UnmapMem(pScrn); 102309885543Smrg 102409885543Smrg pSmi->IsSwitching = FALSE; 102509885543Smrg 102609885543Smrg if (pSmi->Dualhead) { 102709885543Smrg pScrn->display->virtualX = 2 * pSmi->lcdWidth; 102809885543Smrg pScrn->display->virtualY = pSmi->lcdHeight; 102909885543Smrg } 103009885543Smrg 103109885543Smrg pScrn->virtualX = pScrn->display->virtualX; 103209885543Smrg 103309885543Smrg /* 103409885543Smrg * Setup the ClockRanges, which describe what clock ranges are available, 103509885543Smrg * and what sort of modes they can be used for. 103609885543Smrg */ 103709885543Smrg clockRanges = xnfcalloc(sizeof(ClockRange),1); 103809885543Smrg clockRanges->next = NULL; 103909885543Smrg clockRanges->minClock = 20000; 104009885543Smrg 104109885543Smrg if ((pSmi->Chipset == SMI_LYNX3DM) || (pSmi->Chipset == SMI_COUGAR3DR)) 104209885543Smrg clockRanges->maxClock = 200000; 104309885543Smrg else 104409885543Smrg clockRanges->maxClock = 135000; 104509885543Smrg 104609885543Smrg clockRanges->clockIndex = -1; 104709885543Smrg clockRanges->interlaceAllowed = FALSE; 104809885543Smrg clockRanges->doubleScanAllowed = FALSE; 104909885543Smrg 105009885543Smrg i = xf86ValidateModes( 105109885543Smrg pScrn, /* Screen pointer */ 105209885543Smrg pScrn->monitor->Modes, /* Available monitor modes */ 105309885543Smrg pScrn->display->modes, /* req mode names for screen */ 105409885543Smrg clockRanges, /* list of clock ranges allowed */ 105509885543Smrg NULL, /* use min/max below */ 105609885543Smrg 128, /* min line pitch (width) */ 105709885543Smrg 4096, /* maximum line pitch (width) */ 105809885543Smrg 128, /* bits of granularity for line pitch */ 105909885543Smrg /* (width) above */ 106009885543Smrg 128, /* min virtual height */ 106109885543Smrg 4096, /* max virtual height */ 106209885543Smrg pScrn->display->virtualX, /* force virtual x */ 106309885543Smrg pScrn->display->virtualY, /* force virtual Y */ 106409885543Smrg pSmi->videoRAMBytes, /* size of aperture used to access */ 106509885543Smrg /* video memory */ 106609885543Smrg LOOKUP_BEST_REFRESH); /* how to pick modes */ 106709885543Smrg 106809885543Smrg if (i == -1) { 106909885543Smrg SMI_FreeRec(pScrn); 107009885543Smrg LEAVE_PROC("SMI_PreInit"); 107109885543Smrg return FALSE; 107209885543Smrg } 107309885543Smrg 107409885543Smrg /* Prune the modes marked as invalid */ 107509885543Smrg xf86PruneDriverModes(pScrn); 107609885543Smrg 107709885543Smrg if ((i == 0) || (pScrn->modes == NULL)) { 107809885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 107909885543Smrg SMI_FreeRec(pScrn); 108009885543Smrg LEAVE_PROC("SMI_PreInit"); 108109885543Smrg return FALSE; 108209885543Smrg } 108309885543Smrg xf86SetCrtcForModes(pScrn, 0); 108409885543Smrg 108509885543Smrg /* Set the current mode to the first in the list */ 108609885543Smrg pScrn->currentMode = pScrn->modes; 108709885543Smrg 108809885543Smrg /* Print the list of modes being used */ 108909885543Smrg xf86PrintModes(pScrn); 109009885543Smrg 109109885543Smrg /* Set display resolution */ 109209885543Smrg xf86SetDpi(pScrn, 0, 0); 109309885543Smrg 109409885543Smrg if ((xf86LoadSubModule(pScrn, "fb") == NULL)) { 109509885543Smrg SMI_FreeRec(pScrn); 109609885543Smrg LEAVE_PROC("SMI_PreInit"); 109709885543Smrg return FALSE; 109809885543Smrg } 109909885543Smrg 110009885543Smrg if (!pSmi->NoAccel) { 110109885543Smrg from = X_DEFAULT; 110209885543Smrg char *strptr; 110309885543Smrg 110409885543Smrg if ((strptr = (char *)xf86GetOptValString(pSmi->Options, OPTION_ACCELMETHOD))) { 110509885543Smrg if (!xf86NameCmp(strptr,"XAA")) { 110609885543Smrg from = X_CONFIG; 110709885543Smrg pSmi->useEXA = FALSE; 110809885543Smrg } else if(!xf86NameCmp(strptr,"EXA")) { 110909885543Smrg from = X_CONFIG; 111009885543Smrg pSmi->useEXA = TRUE; 111109885543Smrg } 111209885543Smrg } 111309885543Smrg 111409885543Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture\n", 111509885543Smrg pSmi->useEXA ? "EXA" : "XAA"); 111609885543Smrg } 111709885543Smrg 111809885543Smrg xf86LoaderReqSymLists(fbSymbols, NULL); 111909885543Smrg 112009885543Smrg /* Load XAA or EXA if needed */ 112109885543Smrg if (!pSmi->NoAccel) { 112209885543Smrg if (!pSmi->useEXA) { 112309885543Smrg if (!xf86LoadSubModule(pScrn, "xaa")) { 112409885543Smrg SMI_FreeRec(pScrn); 112509885543Smrg LEAVE_PROC("SMI_PreInit"); 112609885543Smrg return FALSE; 112709885543Smrg } 112809885543Smrg xf86LoaderReqSymLists(xaaSymbols, NULL); 112909885543Smrg } else { 113009885543Smrg XF86ModReqInfo req; 113109885543Smrg int errmaj, errmin; 113209885543Smrg 113309885543Smrg memset(&req, 0, sizeof(XF86ModReqInfo)); 113409885543Smrg req.majorversion = 2; 113509885543Smrg req.minorversion = 0; 113609885543Smrg 113709885543Smrg if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, 113809885543Smrg &req, &errmaj, &errmin)) { 113909885543Smrg LoaderErrorMsg(NULL, "exa", errmaj, errmin); 114009885543Smrg SMI_FreeRec(pScrn); 114109885543Smrg LEAVE_PROC("SMI_PreInit"); 114209885543Smrg return FALSE; 114309885543Smrg } 114409885543Smrg xf86LoaderReqSymLists(exaSymbols, NULL); 114509885543Smrg } 114609885543Smrg } 114709885543Smrg 114809885543Smrg /* Load ramdac if needed */ 114909885543Smrg if (pSmi->hwcursor) { 115009885543Smrg if (!xf86LoadSubModule(pScrn, "ramdac")) { 115109885543Smrg SMI_FreeRec(pScrn); 115209885543Smrg LEAVE_PROC("SMI_PreInit"); 115309885543Smrg return FALSE; 115409885543Smrg } 115509885543Smrg xf86LoaderReqSymLists(ramdacSymbols, NULL); 115609885543Smrg } 115709885543Smrg 115809885543Smrg if (pSmi->shadowFB) { 115909885543Smrg if (!xf86LoadSubModule(pScrn, "shadowfb")) { 116009885543Smrg SMI_FreeRec(pScrn); 116109885543Smrg LEAVE_PROC("SMI_PreInit"); 116209885543Smrg return FALSE; 116309885543Smrg } 116409885543Smrg xf86LoaderReqSymLists(shadowSymbols, NULL); 116509885543Smrg } 116609885543Smrg 116709885543Smrg LEAVE_PROC("SMI_PreInit"); 116809885543Smrg return TRUE; 116909885543Smrg} 117009885543Smrg 117109885543Smrg/* 117209885543Smrg * This is called when VT switching back to the X server. Its job is to 117309885543Smrg * reinitialise the video mode. We may wish to unmap video/MMIO memory too. 117409885543Smrg */ 117509885543Smrg 117609885543Smrgstatic Bool 117709885543SmrgSMI_EnterVT(int scrnIndex, int flags) 117809885543Smrg{ 117909885543Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 118009885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 118109885543Smrg Bool ret; 118209885543Smrg 118309885543Smrg ENTER_PROC("SMI_EnterVT"); 118409885543Smrg 118509885543Smrg /* Enable MMIO and map memory */ 118609885543Smrg SMI_MapMem(pScrn); 118709885543Smrg SMI_Save(pScrn); 118809885543Smrg 118909885543Smrg /* #670 */ 119009885543Smrg if (pSmi->shadowFB) { 119109885543Smrg pSmi->FBOffset = pSmi->savedFBOffset; 119209885543Smrg pSmi->FBReserved = pSmi->savedFBReserved; 119309885543Smrg } 119409885543Smrg 119509885543Smrg ret = SMI_ModeInit(pScrn, pScrn->currentMode); 119609885543Smrg 119709885543Smrg /* #670 */ 119809885543Smrg if (ret && pSmi->shadowFB) { 119909885543Smrg BoxRec box; 120009885543Smrg 120109885543Smrg /* #920 */ 120209885543Smrg if (pSmi->paletteBuffer) { 120309885543Smrg int i; 120409885543Smrg 120509885543Smrg VGAOUT8(pSmi, VGA_DAC_WRITE_ADDR, 0); 120609885543Smrg for (i = 0; i < 256 * 3; i++) { 120709885543Smrg VGAOUT8(pSmi, VGA_DAC_DATA, pSmi->paletteBuffer[i]); 120809885543Smrg } 120909885543Smrg xfree(pSmi->paletteBuffer); 121009885543Smrg pSmi->paletteBuffer = NULL; 121109885543Smrg } 121209885543Smrg 121309885543Smrg if (pSmi->pSaveBuffer) { 121409885543Smrg memcpy(pSmi->FBBase, pSmi->pSaveBuffer, pSmi->saveBufferSize); 121509885543Smrg xfree(pSmi->pSaveBuffer); 121609885543Smrg pSmi->pSaveBuffer = NULL; 121709885543Smrg } 121809885543Smrg 121909885543Smrg box.x1 = 0; 122009885543Smrg box.y1 = 0; 122109885543Smrg box.x2 = pScrn->virtualY; 122209885543Smrg box.y2 = pScrn->virtualX; 122309885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 122409885543Smrg SMI_RefreshArea730(pScrn, 1, &box); 122509885543Smrg } else { 122609885543Smrg SMI_RefreshArea(pScrn, 1, &box); 122709885543Smrg } 122809885543Smrg } 122909885543Smrg 123009885543Smrg /* Reset the grapics engine */ 123109885543Smrg if (!pSmi->NoAccel) 123209885543Smrg SMI_EngineReset(pScrn); 123309885543Smrg 123409885543Smrg LEAVE_PROC("SMI_EnterVT"); 123509885543Smrg return ret; 123609885543Smrg} 123709885543Smrg 123809885543Smrg/* 123909885543Smrg * This is called when VT switching away from the X server. Its job is to 124009885543Smrg * restore the previous (text) mode. We may wish to remap video/MMIO memory 124109885543Smrg * too. 124209885543Smrg */ 124309885543Smrg 124409885543Smrgstatic void 124509885543SmrgSMI_LeaveVT(int scrnIndex, int flags) 124609885543Smrg{ 124709885543Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 124809885543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 124909885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 125009885543Smrg vgaRegPtr vgaSavePtr = &hwp->SavedReg; 125109885543Smrg SMIRegPtr SMISavePtr = &pSmi->SavedReg; 125209885543Smrg 125309885543Smrg ENTER_PROC("SMI_LeaveVT"); 125409885543Smrg 125509885543Smrg /* #670 */ 125609885543Smrg if (pSmi->shadowFB) { 125709885543Smrg pSmi->pSaveBuffer = xnfalloc(pSmi->saveBufferSize); 125809885543Smrg if (pSmi->pSaveBuffer) { 125909885543Smrg memcpy(pSmi->pSaveBuffer, pSmi->FBBase, pSmi->saveBufferSize); 126009885543Smrg } 126109885543Smrg 126209885543Smrg pSmi->savedFBOffset = pSmi->FBOffset; 126309885543Smrg pSmi->savedFBReserved = pSmi->FBReserved; 126409885543Smrg 126509885543Smrg /* #920 */ 126609885543Smrg if (pSmi->Bpp == 1) { 126709885543Smrg pSmi->paletteBuffer = xnfalloc(256 * 3); 126809885543Smrg if (pSmi->paletteBuffer) { 126909885543Smrg int i; 127009885543Smrg 127109885543Smrg VGAOUT8(pSmi, VGA_DAC_READ_ADDR, 0); 127209885543Smrg for (i = 0; i < 256 * 3; i++) { 127309885543Smrg pSmi->paletteBuffer[i] = VGAIN8(pSmi, VGA_DAC_DATA); 127409885543Smrg } 127509885543Smrg } 127609885543Smrg } 127709885543Smrg } 127809885543Smrg 127909885543Smrg memset(pSmi->FBBase, 0, 256 * 1024); /* #689 */ 128009885543Smrg SMI_WriteMode(pScrn, vgaSavePtr, SMISavePtr); 128109885543Smrg SMI_UnmapMem(pScrn); 128209885543Smrg 128309885543Smrg LEAVE_PROC("SMI_LeaveVT"); 128409885543Smrg} 128509885543Smrg 128609885543Smrg/* 128709885543Smrg * This function performs the inverse of the restore function: It saves all the 128809885543Smrg * standard and extended registers that we are going to modify to set up a video 128909885543Smrg * mode. 129009885543Smrg */ 129109885543Smrg 129209885543Smrgstatic void 129309885543SmrgSMI_Save(ScrnInfoPtr pScrn) 129409885543Smrg{ 129509885543Smrg int i; 129609885543Smrg CARD32 offset; 129709885543Smrg 129809885543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 129909885543Smrg vgaRegPtr vgaSavePtr = &hwp->SavedReg; 130009885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 130109885543Smrg SMIRegPtr save = &pSmi->SavedReg; 130209885543Smrg 130309885543Smrg int vgaIOBase = hwp->IOBase; 130409885543Smrg int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; 130509885543Smrg int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; 130609885543Smrg 130709885543Smrg ENTER_PROC("SMI_Save"); 130809885543Smrg 130909885543Smrg /* Save the standard VGA registers */ 131009885543Smrg vgaHWSave(pScrn, vgaSavePtr, VGA_SR_ALL); 131109885543Smrg save->smiDACMask = VGAIN8(pSmi, VGA_DAC_MASK); 131209885543Smrg VGAOUT8(pSmi, VGA_DAC_READ_ADDR, 0); 131309885543Smrg for (i = 0; i < 256; i++) { 131409885543Smrg save->smiDacRegs[i][0] = VGAIN8(pSmi, VGA_DAC_DATA); 131509885543Smrg save->smiDacRegs[i][1] = VGAIN8(pSmi, VGA_DAC_DATA); 131609885543Smrg save->smiDacRegs[i][2] = VGAIN8(pSmi, VGA_DAC_DATA); 131709885543Smrg } 131809885543Smrg for (i = 0, offset = 2; i < 8192; i++, offset += 8) { 131909885543Smrg save->smiFont[i] = *(pSmi->FBBase + offset); 132009885543Smrg } 132109885543Smrg 132209885543Smrg /* Now we save all the extended registers we need. */ 132309885543Smrg save->SR17 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17); 132409885543Smrg save->SR18 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18); 132509885543Smrg save->SR21 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 132609885543Smrg save->SR31 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31); 132709885543Smrg save->SR32 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32); 132809885543Smrg save->SR6A = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A); 132909885543Smrg save->SR6B = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B); 133009885543Smrg save->SR81 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81); 133109885543Smrg save->SRA0 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0); 133209885543Smrg 133309885543Smrg /* vclk1 */ 133409885543Smrg save->SR6C = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C); 133509885543Smrg save->SR6D = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D); 133609885543Smrg /* vclk1 control */ 133709885543Smrg save->SR68 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68); 133809885543Smrg 133909885543Smrg if (pSmi->Dualhead) { 134009885543Smrg /* dualhead stuff */ 134109885543Smrg save->SR22 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22); 134209885543Smrg save->SR40 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40); 134309885543Smrg save->SR41 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41); 134409885543Smrg save->SR42 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42); 134509885543Smrg save->SR43 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43); 134609885543Smrg save->SR44 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x44); 134709885543Smrg save->SR45 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45); 134809885543Smrg save->SR48 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x48); 134909885543Smrg save->SR49 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49); 135009885543Smrg save->SR4A = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4A); 135109885543Smrg save->SR4B = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4B); 135209885543Smrg save->SR4C = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4C); 135309885543Smrg /* PLL2 stuff */ 135409885543Smrg save->SR69 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69); 135509885543Smrg save->SR6E = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E); 135609885543Smrg save->SR6F = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F); 135709885543Smrg } 135809885543Smrg 135909885543Smrg if (SMI_LYNXM_SERIES(pSmi->Chipset)) { 136009885543Smrg /* Save primary registers */ 136109885543Smrg save->CR90[14] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E); 136209885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14] & ~0x20); 136309885543Smrg 136409885543Smrg for (i = 0; i < 16; i++) { 136509885543Smrg save->CR90[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x90 + i); 136609885543Smrg } 136709885543Smrg save->CR33 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33); 136809885543Smrg save->CR3A = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A); 136909885543Smrg for (i = 0; i < 14; i++) { 137009885543Smrg save->CR40[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i); 137109885543Smrg } 137209885543Smrg 137309885543Smrg /* Save secondary registers */ 137409885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14] | 0x20); 137509885543Smrg save->CR33_2 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33); 137609885543Smrg for (i = 0; i < 14; i++) { 137709885543Smrg save->CR40_2[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i); 137809885543Smrg } 137909885543Smrg save->CR9F_2 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F); 138009885543Smrg 138109885543Smrg /* Save common registers */ 138209885543Smrg for (i = 0; i < 14; i++) { 138309885543Smrg save->CRA0[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0xA0 + i); 138409885543Smrg } 138509885543Smrg 138609885543Smrg /* PDR#1069 */ 138709885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14]); 138809885543Smrg } else { 138909885543Smrg save->CR33 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33); 139009885543Smrg save->CR3A = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A); 139109885543Smrg for (i = 0; i < 14; i++) { 139209885543Smrg save->CR40[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i); 139309885543Smrg } 139409885543Smrg } 139509885543Smrg 139609885543Smrg /* CZ 2.11.2001: for gamma correction (TODO: other chipsets?) */ 139709885543Smrg if ((pSmi->Chipset == SMI_LYNX3DM) || (pSmi->Chipset == SMI_COUGAR3DR)) { 139809885543Smrg save->CCR66 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66); 139909885543Smrg } 140009885543Smrg /* end CZ */ 140109885543Smrg 140209885543Smrg save->DPR10 = READ_DPR(pSmi, 0x10); 140309885543Smrg save->DPR1C = READ_DPR(pSmi, 0x1C); 140409885543Smrg save->DPR20 = READ_DPR(pSmi, 0x20); 140509885543Smrg save->DPR24 = READ_DPR(pSmi, 0x24); 140609885543Smrg save->DPR28 = READ_DPR(pSmi, 0x28); 140709885543Smrg save->DPR2C = READ_DPR(pSmi, 0x2C); 140809885543Smrg save->DPR30 = READ_DPR(pSmi, 0x30); 140909885543Smrg save->DPR3C = READ_DPR(pSmi, 0x3C); 141009885543Smrg save->DPR40 = READ_DPR(pSmi, 0x40); 141109885543Smrg save->DPR44 = READ_DPR(pSmi, 0x44); 141209885543Smrg 141309885543Smrg save->VPR00 = READ_VPR(pSmi, 0x00); 141409885543Smrg save->VPR0C = READ_VPR(pSmi, 0x0C); 141509885543Smrg save->VPR10 = READ_VPR(pSmi, 0x10); 141609885543Smrg 141709885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 141809885543Smrg save->FPR00_ = READ_FPR(pSmi, FPR00); 141909885543Smrg save->FPR0C_ = READ_FPR(pSmi, FPR0C); 142009885543Smrg save->FPR10_ = READ_FPR(pSmi, FPR10); 142109885543Smrg } 142209885543Smrg 142309885543Smrg save->CPR00 = READ_CPR(pSmi, 0x00); 142409885543Smrg 142509885543Smrg if (!pSmi->ModeStructInit) { 142609885543Smrg /* XXX Should check the return value of vgaHWCopyReg() */ 142709885543Smrg vgaHWCopyReg(&hwp->ModeReg, vgaSavePtr); 142809885543Smrg memcpy(&pSmi->ModeReg, save, sizeof(SMIRegRec)); 142909885543Smrg pSmi->ModeStructInit = TRUE; 143009885543Smrg } 143109885543Smrg 143209885543Smrg if (pSmi->useBIOS && (pSmi->pInt10 != NULL)) { 143309885543Smrg pSmi->pInt10->num = 0x10; 143409885543Smrg pSmi->pInt10->ax = 0x0F00; 143509885543Smrg xf86ExecX86int10(pSmi->pInt10); 143609885543Smrg save->mode = pSmi->pInt10->ax & 0x007F; 143709885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode 0x%02X.\n", 143809885543Smrg save->mode); 143909885543Smrg } 144009885543Smrg 144109885543Smrg if (xf86GetVerbosity() > 1) { 144209885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 144309885543Smrg "Saved current video mode. Register dump:\n"); 144409885543Smrg SMI_PrintRegs(pScrn); 144509885543Smrg } 144609885543Smrg 144709885543Smrg LEAVE_PROC("SMI_Save"); 144809885543Smrg} 144909885543Smrg 145009885543Smrg/* 145109885543Smrg * This function is used to restore a video mode. It writes out all of the 145209885543Smrg * standard VGA and extended registers needed to setup a video mode. 145309885543Smrg */ 145409885543Smrg 145509885543Smrgstatic void 145609885543SmrgSMI_WriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, SMIRegPtr restore) 145709885543Smrg{ 145809885543Smrg int i; 145909885543Smrg CARD8 tmp; 146009885543Smrg CARD32 offset; 146109885543Smrg 146209885543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 146309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 146409885543Smrg int vgaIOBase = hwp->IOBase; 146509885543Smrg int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; 146609885543Smrg int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; 146709885543Smrg 146809885543Smrg ENTER_PROC("SMI_WriteMode"); 146909885543Smrg 147009885543Smrg vgaHWProtect(pScrn, TRUE); 147109885543Smrg 147209885543Smrg /* Wait for engine to become idle */ 147309885543Smrg if (pSmi->IsSwitching) 147409885543Smrg WaitIdle(); 147509885543Smrg 147609885543Smrg if (pSmi->useBIOS && (pSmi->pInt10 != NULL) && (restore->mode != 0)) { 147709885543Smrg pSmi->pInt10->num = 0x10; 147809885543Smrg pSmi->pInt10->ax = restore->mode | 0x80; 147909885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%02X\n", 148009885543Smrg restore->mode); 148109885543Smrg xf86ExecX86int10(pSmi->pInt10); 148209885543Smrg 148309885543Smrg /* Enable linear mode. */ 148409885543Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); 148509885543Smrg tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); 148609885543Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp | 0x01); 148709885543Smrg 148809885543Smrg /* Enable DPR/VPR registers. */ 148909885543Smrg tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 149009885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03); 149109885543Smrg } else { 149209885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17, restore->SR17); 149309885543Smrg tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18) & ~0x1F; 149409885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18, tmp | 149509885543Smrg (restore->SR18 & 0x1F)); 149609885543Smrg tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 149709885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03); 149809885543Smrg tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31) & ~0xC0; 149909885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, tmp | 150009885543Smrg (restore->SR31 & 0xC0)); 150109885543Smrg tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32) & ~0x07; 150209885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32, tmp | 150309885543Smrg (restore->SR32 & 0x07)); 150409885543Smrg if (restore->SR6B != 0xFF) { 150509885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A, restore->SR6A); 150609885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B, restore->SR6B); 150709885543Smrg } 150809885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, restore->SR81); 150909885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0, restore->SRA0); 151009885543Smrg 151109885543Smrg /* Restore the standard VGA registers */ 151209885543Smrg vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL); 151309885543Smrg if (restore->smiDACMask) { 151409885543Smrg VGAOUT8(pSmi, VGA_DAC_MASK, restore->smiDACMask); 151509885543Smrg } else { 151609885543Smrg VGAOUT8(pSmi, VGA_DAC_MASK, 0xFF); 151709885543Smrg } 151809885543Smrg VGAOUT8(pSmi, VGA_DAC_WRITE_ADDR, 0); 151909885543Smrg for (i = 0; i < 256; i++) { 152009885543Smrg VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][0]); 152109885543Smrg VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][1]); 152209885543Smrg VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][2]); 152309885543Smrg } 152409885543Smrg for (i = 0, offset = 2; i < 8192; i++, offset += 8) { 152509885543Smrg *(pSmi->FBBase + offset) = restore->smiFont[i]; 152609885543Smrg } 152709885543Smrg 152809885543Smrg if (SMI_LYNXM_SERIES(pSmi->Chipset)) { 152909885543Smrg /* Restore secondary registers */ 153009885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, 153109885543Smrg restore->CR90[14] | 0x20); 153209885543Smrg 153309885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33_2); 153409885543Smrg for (i = 0; i < 14; i++) { 153509885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, 153609885543Smrg restore->CR40_2[i]); 153709885543Smrg } 153809885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F, restore->CR9F_2); 153909885543Smrg 154009885543Smrg /* Restore primary registers */ 154109885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, 154209885543Smrg restore->CR90[14] & ~0x20); 154309885543Smrg 154409885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33); 154509885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A); 154609885543Smrg for (i = 0; i < 14; i++) { 154709885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, 154809885543Smrg restore->CR40[i]); 154909885543Smrg } 155009885543Smrg for (i = 0; i < 16; i++) { 155109885543Smrg if (i != 14) { 155209885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x90 + i, 155309885543Smrg restore->CR90[i]); 155409885543Smrg } 155509885543Smrg } 155609885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, restore->CR90[14]); 155709885543Smrg 155809885543Smrg /* Restore common registers */ 155909885543Smrg for (i = 0; i < 14; i++) { 156009885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0xA0 + i, 156109885543Smrg restore->CRA0[i]); 156209885543Smrg } 156309885543Smrg } 156409885543Smrg 156509885543Smrg /* Restore the standard VGA registers */ 156609885543Smrg if (xf86IsPrimaryPci(pSmi->PciInfo)) { 156709885543Smrg vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_CMAP | VGA_SR_FONTS); 156809885543Smrg } 156909885543Smrg 157009885543Smrg if (restore->modeInit) 157109885543Smrg vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL); 157209885543Smrg 157309885543Smrg if (!SMI_LYNXM_SERIES(pSmi->Chipset)) { 157409885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33); 157509885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A); 157609885543Smrg for (i = 0; i < 14; i++) { 157709885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, 157809885543Smrg restore->CR40[i]); 157909885543Smrg } 158009885543Smrg } 158109885543Smrg 158209885543Smrg /* vclk1 */ 158309885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68, restore->SR68); 158409885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C, restore->SR6C); 158509885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D, restore->SR6D); 158609885543Smrg 158709885543Smrg if (pSmi->Dualhead) { 158809885543Smrg 158909885543Smrg /* TFT panel uses FIFO1, DSTN panel uses FIFO1 for upper panel and 159009885543Smrg * FIFO2 for lower panel. I don't have a DSTN panel, so it's untested. 159109885543Smrg * -- AGD 159209885543Smrg */ 159309885543Smrg 159409885543Smrg /* PLL2 regs */ 159509885543Smrg 159609885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69, restore->SR69); 159709885543Smrg 159809885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E, restore->SR6E); 159909885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F, restore->SR6F); 160009885543Smrg 160109885543Smrg /* setting SR21 bit 2 disables ZV circuitry, 160209885543Smrg * if ZV is needed, SR21 = 0x20 160309885543Smrg */ 160409885543Smrg /* enable DAC, PLL, etc. */ 160509885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, restore->SR21); 160609885543Smrg 160709885543Smrg /* clear DPMS state */ 160809885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, restore->SR22); 160909885543Smrg 161009885543Smrg /* enable virtual refresh and LCD and CRT outputs */ 161109885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, restore->SR31); 161209885543Smrg 161309885543Smrg /* FIFO1 Read Offset */ 161409885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x44, restore->SR44); 161509885543Smrg /* FIFO2 Read Offset */ 161609885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4B, restore->SR4B); 161709885543Smrg /* FIFO1/2 Read Offset overflow */ 161809885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4C, restore->SR4C); 161909885543Smrg 162009885543Smrg /* FIFO Write Offset */ 162109885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x48, restore->SR48); 162209885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49, restore->SR49); 162309885543Smrg 162409885543Smrg /* set FIFO levels */ 162509885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4A, restore->SR4A); 162609885543Smrg 162709885543Smrg VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33); 162809885543Smrg 162909885543Smrg } 163009885543Smrg } 163109885543Smrg 163209885543Smrg /* CZ 2.11.2001: for gamma correction (TODO: other chipsets?) */ 163309885543Smrg if ((pSmi->Chipset == SMI_LYNX3DM) || (pSmi->Chipset == SMI_COUGAR3DR)) { 163409885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66, restore->CCR66); 163509885543Smrg } 163609885543Smrg /* end CZ */ 163709885543Smrg 163809885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, 0x00); 163909885543Smrg 164009885543Smrg /* Reset the graphics engine */ 164109885543Smrg WRITE_DPR(pSmi, 0x10, restore->DPR10); 164209885543Smrg WRITE_DPR(pSmi, 0x1C, restore->DPR1C); 164309885543Smrg WRITE_DPR(pSmi, 0x20, restore->DPR20); 164409885543Smrg WRITE_DPR(pSmi, 0x24, restore->DPR24); 164509885543Smrg WRITE_DPR(pSmi, 0x28, restore->DPR28); 164609885543Smrg WRITE_DPR(pSmi, 0x2C, restore->DPR2C); 164709885543Smrg WRITE_DPR(pSmi, 0x30, restore->DPR30); 164809885543Smrg WRITE_DPR(pSmi, 0x3C, restore->DPR3C); 164909885543Smrg WRITE_DPR(pSmi, 0x40, restore->DPR40); 165009885543Smrg WRITE_DPR(pSmi, 0x44, restore->DPR44); 165109885543Smrg 165209885543Smrg /* write video controller regs */ 165309885543Smrg WRITE_VPR(pSmi, 0x00, restore->VPR00); 165409885543Smrg WRITE_VPR(pSmi, 0x0C, restore->VPR0C); 165509885543Smrg WRITE_VPR(pSmi, 0x10, restore->VPR10); 165609885543Smrg 165709885543Smrg if(pSmi->Chipset == SMI_COUGAR3DR) { 165809885543Smrg WRITE_FPR(pSmi, FPR00, restore->FPR00_); 165909885543Smrg WRITE_FPR(pSmi, FPR0C, restore->FPR0C_); 166009885543Smrg WRITE_FPR(pSmi, FPR10, restore->FPR10_); 166109885543Smrg } 166209885543Smrg 166309885543Smrg WRITE_CPR(pSmi, 0x00, restore->CPR00); 166409885543Smrg 166509885543Smrg if (xf86GetVerbosity() > 1) { 166609885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 166709885543Smrg "Done restoring mode. Register dump:\n"); 166809885543Smrg SMI_PrintRegs(pScrn); 166909885543Smrg } 167009885543Smrg 167109885543Smrg vgaHWProtect(pScrn, FALSE); 167209885543Smrg 167309885543Smrg LEAVE_PROC("SMI_WriteMode"); 167409885543Smrg} 167509885543Smrg 167609885543Smrgstatic void 167709885543SmrgSMI_DetectPanelSize(ScrnInfoPtr pScrn) 167809885543Smrg{ 167909885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 168009885543Smrg 168109885543Smrg /* panel size detection ... requires BIOS call on 730 hardware */ 168209885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 168309885543Smrg if (pSmi->pInt10 != NULL) { 168409885543Smrg pSmi->pInt10->num = 0x10; 168509885543Smrg pSmi->pInt10->ax = 0x5F00; 168609885543Smrg pSmi->pInt10->bx = 0; 168709885543Smrg pSmi->pInt10->cx = 0; 168809885543Smrg pSmi->pInt10->dx = 0; 168909885543Smrg xf86ExecX86int10(pSmi->pInt10); 169009885543Smrg if (pSmi->pInt10->ax == 0x005F) { 169109885543Smrg switch (pSmi->pInt10->cx & 0x0F) { 169209885543Smrg case PANEL_640x480: 169309885543Smrg pSmi->lcdWidth = 640; 169409885543Smrg pSmi->lcdHeight = 480; 169509885543Smrg break; 169609885543Smrg case PANEL_800x600: 169709885543Smrg pSmi->lcdWidth = 800; 169809885543Smrg pSmi->lcdHeight = 600; 169909885543Smrg break; 170009885543Smrg case PANEL_1024x768: 170109885543Smrg pSmi->lcdWidth = 1024; 170209885543Smrg pSmi->lcdHeight = 768; 170309885543Smrg break; 170409885543Smrg case PANEL_1280x1024: 170509885543Smrg pSmi->lcdWidth = 1280; 170609885543Smrg pSmi->lcdHeight = 1024; 170709885543Smrg break; 170809885543Smrg case PANEL_1600x1200: 170909885543Smrg pSmi->lcdWidth = 1600; 171009885543Smrg pSmi->lcdHeight = 1200; 171109885543Smrg break; 171209885543Smrg case PANEL_1400x1050: 171309885543Smrg pSmi->lcdWidth = 1400; 171409885543Smrg pSmi->lcdHeight = 1050; 171509885543Smrg break; 171609885543Smrg } 171709885543Smrg 171809885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected panel size via BIOS: %d x %d\n", 171909885543Smrg pSmi->lcdWidth, pSmi->lcdHeight); 172009885543Smrg } else { 172109885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS error during 730 panel detection!\n"); 172209885543Smrg pSmi->lcdWidth = pScrn->virtualX; 172309885543Smrg pSmi->lcdHeight = pScrn->virtualY; 172409885543Smrg } 172509885543Smrg } else { 172609885543Smrg /* int10 support isn't setup on the second call to this function, 172709885543Smrg so if this is the second call, don't do detection again */ 172809885543Smrg if (pSmi->lcd == 0) { 172909885543Smrg /* If we get here, int10 support is not loaded or not working */ 173009885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No BIOS support for 730 panel detection!\n"); 173109885543Smrg pSmi->lcdWidth = pScrn->virtualX; 173209885543Smrg pSmi->lcdHeight = pScrn->virtualY; 173309885543Smrg } 173409885543Smrg } 173509885543Smrg 173609885543Smrg /* Set this to indicate that we've done the detection */ 173709885543Smrg pSmi->lcd = 1; 173809885543Smrg } else { 173909885543Smrg /* panel size detection for hardware other than 730 */ 174009885543Smrg pSmi->lcd = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31) & 0x01; 174109885543Smrg 174209885543Smrg if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30) & 0x01) { 174309885543Smrg pSmi->lcd <<= 1; 174409885543Smrg } 174509885543Smrg switch (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30) & 0x0C) { 174609885543Smrg case 0x00: 174709885543Smrg pSmi->lcdWidth = 640; 174809885543Smrg pSmi->lcdHeight = 480; 174909885543Smrg break; 175009885543Smrg case 0x04: 175109885543Smrg pSmi->lcdWidth = 800; 175209885543Smrg pSmi->lcdHeight = 600; 175309885543Smrg break; 175409885543Smrg case 0x08: 175509885543Smrg if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x74) & 0x02) { 175609885543Smrg pSmi->lcdWidth = 1024; 175709885543Smrg pSmi->lcdHeight = 600; 175809885543Smrg } else { 175909885543Smrg pSmi->lcdWidth = 1024; 176009885543Smrg pSmi->lcdHeight = 768; 176109885543Smrg } 176209885543Smrg break; 176309885543Smrg case 0x0C: 176409885543Smrg pSmi->lcdWidth = 1280; 176509885543Smrg pSmi->lcdHeight = 1024; 176609885543Smrg break; 176709885543Smrg } 176809885543Smrg } 176909885543Smrg 177009885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s Panel Size = %dx%d\n", 177109885543Smrg (pSmi->lcd == 0) ? "OFF" : (pSmi->lcd == 1) ? "TFT" : "DSTN", 177209885543Smrg pSmi->lcdWidth, pSmi->lcdHeight); 177309885543Smrg 177409885543Smrg} 177509885543Smrg 177609885543Smrgstatic Bool 177709885543SmrgSMI_MapMem(ScrnInfoPtr pScrn) 177809885543Smrg{ 177909885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 178009885543Smrg vgaHWPtr hwp; 178109885543Smrg CARD32 memBase; 178209885543Smrg 178309885543Smrg ENTER_PROC("SMI_MapMem"); 178409885543Smrg 178509885543Smrg /* Map the Lynx register space */ 178609885543Smrg switch (pSmi->Chipset) { 178709885543Smrg default: 178809885543Smrg memBase = pSmi->PciInfo->memBase[0] + 0x400000; 178909885543Smrg pSmi->MapSize = 0x10000; 179009885543Smrg break; 179109885543Smrg case SMI_COUGAR3DR: 179209885543Smrg memBase = pSmi->PciInfo->memBase[1]; 179309885543Smrg pSmi->MapSize = 0x200000; 179409885543Smrg break; 179509885543Smrg case SMI_LYNX3D: 179609885543Smrg memBase = pSmi->PciInfo->memBase[0] + 0x680000; 179709885543Smrg pSmi->MapSize = 0x180000; 179809885543Smrg break; 179909885543Smrg case SMI_LYNXEM: 180009885543Smrg case SMI_LYNXEMplus: 180109885543Smrg memBase = pSmi->PciInfo->memBase[0] + 0x400000; 180209885543Smrg pSmi->MapSize = 0x400000; 180309885543Smrg break; 180409885543Smrg case SMI_LYNX3DM: 180509885543Smrg memBase = pSmi->PciInfo->memBase[0]; 180609885543Smrg pSmi->MapSize = 0x200000; 180709885543Smrg break; 180809885543Smrg } 180909885543Smrg pSmi->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pSmi->PciTag, 181009885543Smrg memBase, pSmi->MapSize); 181109885543Smrg 181209885543Smrg if (pSmi->MapBase == NULL) { 181309885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Internal error: could not map " 181409885543Smrg "MMIO registers.\n"); 181509885543Smrg LEAVE_PROC("SMI_MapMem"); 181609885543Smrg return FALSE; 181709885543Smrg } 181809885543Smrg 181909885543Smrg switch (pSmi->Chipset) { 182009885543Smrg default: 182109885543Smrg pSmi->DPRBase = pSmi->MapBase + 0x8000; 182209885543Smrg pSmi->VPRBase = pSmi->MapBase + 0xC000; 182309885543Smrg pSmi->CPRBase = pSmi->MapBase + 0xE000; 182409885543Smrg pSmi->IOBase = NULL; 182509885543Smrg pSmi->DataPortBase = pSmi->MapBase; 182609885543Smrg pSmi->DataPortSize = 0x8000; 182709885543Smrg break; 182809885543Smrg case SMI_COUGAR3DR: 182909885543Smrg pSmi->DPRBase = pSmi->MapBase + 0x000000; 183009885543Smrg pSmi->VPRBase = pSmi->MapBase + 0x000800; 183109885543Smrg pSmi->CPRBase = pSmi->MapBase + 0x001000; 183209885543Smrg pSmi->FPRBase = pSmi->MapBase + 0x005800; 183309885543Smrg pSmi->IOBase = pSmi->MapBase + 0x0C0000; 183409885543Smrg pSmi->DataPortBase = pSmi->MapBase + 0x100000; 183509885543Smrg pSmi->DataPortSize = 0x100000; 183609885543Smrg break; 183709885543Smrg case SMI_LYNX3D: 183809885543Smrg pSmi->DPRBase = pSmi->MapBase + 0x000000; 183909885543Smrg pSmi->VPRBase = pSmi->MapBase + 0x000800; 184009885543Smrg pSmi->CPRBase = pSmi->MapBase + 0x001000; 184109885543Smrg pSmi->IOBase = pSmi->MapBase + 0x040000; 184209885543Smrg pSmi->DataPortBase = pSmi->MapBase + 0x080000; 184309885543Smrg pSmi->DataPortSize = 0x100000; 184409885543Smrg break; 184509885543Smrg case SMI_LYNXEM: 184609885543Smrg case SMI_LYNXEMplus: 184709885543Smrg pSmi->DPRBase = pSmi->MapBase + 0x008000; 184809885543Smrg pSmi->VPRBase = pSmi->MapBase + 0x00C000; 184909885543Smrg pSmi->CPRBase = pSmi->MapBase + 0x00E000; 185009885543Smrg pSmi->IOBase = pSmi->MapBase + 0x300000; 185109885543Smrg pSmi->DataPortBase = pSmi->MapBase /*+ 0x100000*/; 185209885543Smrg pSmi->DataPortSize = 0x8000 /*0x200000*/; 185309885543Smrg break; 185409885543Smrg case SMI_LYNX3DM: 185509885543Smrg pSmi->DPRBase = pSmi->MapBase + 0x000000; 185609885543Smrg pSmi->VPRBase = pSmi->MapBase + 0x000800; 185709885543Smrg pSmi->CPRBase = pSmi->MapBase + 0x001000; 185809885543Smrg pSmi->IOBase = pSmi->MapBase + 0x0C0000; 185909885543Smrg pSmi->DataPortBase = pSmi->MapBase + 0x100000; 186009885543Smrg pSmi->DataPortSize = 0x100000; 186109885543Smrg break; 186209885543Smrg } 186309885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 186409885543Smrg "Physical MMIO at 0x%08lX\n", (unsigned long)memBase); 186509885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 186609885543Smrg "Logical MMIO at %p - %p\n", pSmi->MapBase, 186709885543Smrg pSmi->MapBase + pSmi->MapSize - 1); 186809885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 186909885543Smrg "DPR=%p, VPR=%p, IOBase=%p\n", 187009885543Smrg pSmi->DPRBase, pSmi->VPRBase, pSmi->IOBase); 187109885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 187209885543Smrg "DataPort=%p - %p\n", pSmi->DataPortBase, 187309885543Smrg pSmi->DataPortBase + pSmi->DataPortSize - 1); 187409885543Smrg 187509885543Smrg pScrn->memPhysBase = pSmi->PciInfo->memBase[0]; 187609885543Smrg 187709885543Smrg SMI_EnableMmio(pScrn); 187809885543Smrg 187909885543Smrg if (pSmi->videoRAMBytes) { 188009885543Smrg /* Map the frame buffer */ 188109885543Smrg if (pSmi->Chipset == SMI_LYNX3DM) 188209885543Smrg pSmi->fbMapOffset = 0x200000; 188309885543Smrg else 188409885543Smrg pSmi->fbMapOffset = 0x0; 188509885543Smrg 188609885543Smrg pSmi->FBOffset = 0; 188709885543Smrg 188809885543Smrg pScrn->fbOffset = pSmi->FBOffset + pSmi->fbMapOffset; 188909885543Smrg 189009885543Smrg pSmi->FBBase = xf86MapPciMem(pScrn->scrnIndex, 189109885543Smrg VIDMEM_FRAMEBUFFER, 189209885543Smrg pSmi->PciTag, 189309885543Smrg pScrn->memPhysBase + pSmi->fbMapOffset, 189409885543Smrg pSmi->videoRAMBytes); 189509885543Smrg 189609885543Smrg if (pSmi->FBBase == NULL) { 189709885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Internal error: could not " 189809885543Smrg "map framebuffer.\n"); 189909885543Smrg LEAVE_PROC("SMI_MapMem"); 190009885543Smrg return FALSE; 190109885543Smrg } 190209885543Smrg 190309885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 190409885543Smrg "Physical frame buffer at 0x%08lX offset: 0x%08lX\n", 190509885543Smrg pScrn->memPhysBase, pScrn->fbOffset); 190609885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 190709885543Smrg "Logical frame buffer at %p - %p\n", pSmi->FBBase, 190809885543Smrg pSmi->FBBase + pSmi->videoRAMBytes - 1); 190909885543Smrg 191009885543Smrg /* Set up offset to hwcursor memory area. It's a 1K chunk at the end of 191109885543Smrg * the frame buffer. 191209885543Smrg */ 191309885543Smrg pSmi->FBCursorOffset = pSmi->videoRAMBytes - 1024; 191409885543Smrg 191509885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 191609885543Smrg "Cursor Offset: %08lX\n", 191709885543Smrg (unsigned long)pSmi->FBCursorOffset); 191809885543Smrg 191909885543Smrg /* set up the fifo reserved space */ 192009885543Smrg if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30) & 0x01)/* #1074 */ { 192109885543Smrg CARD32 fifoOffset = 0; 192209885543Smrg fifoOffset |= VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x46) << 3; 192309885543Smrg fifoOffset |= VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x47) << 11; 192409885543Smrg fifoOffset |= (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49) 192509885543Smrg & 0x1C) << 17; 192609885543Smrg pSmi->FBReserved = fifoOffset; /* PDR#1074 */ 192709885543Smrg } else { 192809885543Smrg pSmi->FBReserved = pSmi->videoRAMBytes - 2048; 192909885543Smrg } 193009885543Smrg 193109885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reserved: %08lX\n", 193209885543Smrg (unsigned long)pSmi->FBReserved); 193309885543Smrg 193409885543Smrg } 193509885543Smrg 193609885543Smrg /* Assign hwp->MemBase & IOBase here */ 193709885543Smrg hwp = VGAHWPTR(pScrn); 193809885543Smrg if (pSmi->IOBase != NULL) { 193909885543Smrg vgaHWSetMmioFuncs(hwp, pSmi->MapBase, pSmi->IOBase - pSmi->MapBase); 194009885543Smrg } 194109885543Smrg vgaHWGetIOBase(hwp); 194209885543Smrg 194309885543Smrg /* Map the VGA memory when the primary video */ 194409885543Smrg if (xf86IsPrimaryPci(pSmi->PciInfo)) { 194509885543Smrg hwp->MapSize = 0x10000; 194609885543Smrg if (!vgaHWMapMem(pScrn)) { 194709885543Smrg LEAVE_PROC("SMI_MapMem"); 194809885543Smrg return FALSE; 194909885543Smrg } 195009885543Smrg pSmi->PrimaryVidMapped = TRUE; 195109885543Smrg } 195209885543Smrg 195309885543Smrg LEAVE_PROC("SMI_MapMem"); 195409885543Smrg return TRUE; 195509885543Smrg} 195609885543Smrg 195709885543Smrg/* UnMapMem - contains half of pre-4.0 EnterLeave function. The EnterLeave 195809885543Smrg * function which en/disable access to IO ports and ext. regs 195909885543Smrg */ 196009885543Smrg 196109885543Smrgstatic void 196209885543SmrgSMI_UnmapMem(ScrnInfoPtr pScrn) 196309885543Smrg{ 196409885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 196509885543Smrg 196609885543Smrg ENTER_PROC("SMI_UnmapMem"); 196709885543Smrg 196809885543Smrg /* Unmap VGA mem if mapped. */ 196909885543Smrg if (pSmi->PrimaryVidMapped) { 197009885543Smrg vgaHWUnmapMem(pScrn); 197109885543Smrg pSmi->PrimaryVidMapped = FALSE; 197209885543Smrg } 197309885543Smrg 197409885543Smrg SMI_DisableMmio(pScrn); 197509885543Smrg 197609885543Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pSmi->MapBase, pSmi->MapSize); 197709885543Smrg if (pSmi->FBBase != NULL) { 197809885543Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pSmi->FBBase, 197909885543Smrg pSmi->videoRAMBytes); 198009885543Smrg } 198109885543Smrg 198209885543Smrg LEAVE_PROC("SMI_UnmapMem"); 198309885543Smrg} 198409885543Smrg 198509885543Smrg/* This gets called at the start of each server generation. */ 198609885543Smrg 198709885543Smrgstatic Bool 198809885543SmrgSMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 198909885543Smrg{ 199009885543Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 199109885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 199209885543Smrg EntityInfoPtr pEnt; 199309885543Smrg 199409885543Smrg ENTER_PROC("SMI_ScreenInit"); 199509885543Smrg 199609885543Smrg /* Map MMIO regs and framebuffer */ 199709885543Smrg if (!SMI_MapMem(pScrn)) { 199809885543Smrg LEAVE_PROC("SMI_ScreenInit"); 199909885543Smrg return FALSE; 200009885543Smrg } 200109885543Smrg 200209885543Smrg pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 200309885543Smrg 200409885543Smrg if (!pSmi->pInt10) { 200509885543Smrg pSmi->pInt10 = xf86InitInt10(pEnt->index); 200609885543Smrg } 200709885543Smrg 200809885543Smrg /* Save the chip/graphics state */ 200909885543Smrg SMI_Save(pScrn); 201009885543Smrg 201109885543Smrg /* Zero the frame buffer, #258 */ 201209885543Smrg memset(pSmi->FBBase, 0, pSmi->videoRAMBytes); 201309885543Smrg 201409885543Smrg /* Initialize the first mode */ 201509885543Smrg if (!SMI_ModeInit(pScrn, pScrn->currentMode)) { 201609885543Smrg LEAVE_PROC("SMI_ScreenInit"); 201709885543Smrg return FALSE; 201809885543Smrg } 201909885543Smrg 202009885543Smrg /* 202109885543Smrg * The next step is to setup the screen's visuals, and initialise the 202209885543Smrg * framebuffer code. In cases where the framebuffer's default choises for 202309885543Smrg * things like visual layouts and bits per RGB are OK, this may be as simple 202409885543Smrg * as calling the framebuffer's ScreenInit() function. If not, the visuals 202509885543Smrg * will need to be setup before calling a fb ScreenInit() function and fixed 202609885543Smrg * up after. 202709885543Smrg */ 202809885543Smrg 202909885543Smrg /* 203009885543Smrg * Reset the visual list. 203109885543Smrg */ 203209885543Smrg miClearVisualTypes(); 203309885543Smrg 203409885543Smrg /* Setup the visuals we support. */ 203509885543Smrg 203609885543Smrg if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 203709885543Smrg pScrn->rgbBits, pScrn->defaultVisual)) { 203809885543Smrg LEAVE_PROC("SMI_ScreenInit"); 203909885543Smrg return FALSE; 204009885543Smrg } 204109885543Smrg if (!miSetPixmapDepths ()) return FALSE; 204209885543Smrg 204309885543Smrg if (!SMI_InternalScreenInit(scrnIndex, pScreen)) { 204409885543Smrg LEAVE_PROC("SMI_ScreenInit"); 204509885543Smrg return FALSE; 204609885543Smrg } 204709885543Smrg 204809885543Smrg xf86SetBlackWhitePixels(pScreen); 204909885543Smrg 205009885543Smrg if (pScrn->bitsPerPixel > 8) { 205109885543Smrg VisualPtr visual; 205209885543Smrg /* Fixup RGB ordering */ 205309885543Smrg visual = pScreen->visuals + pScreen->numVisuals; 205409885543Smrg while (--visual >= pScreen->visuals) { 205509885543Smrg if ((visual->class | DynamicClass) == DirectColor) { 205609885543Smrg visual->offsetRed = pScrn->offset.red; 205709885543Smrg visual->offsetGreen = pScrn->offset.green; 205809885543Smrg visual->offsetBlue = pScrn->offset.blue; 205909885543Smrg visual->redMask = pScrn->mask.red; 206009885543Smrg visual->greenMask = pScrn->mask.green; 206109885543Smrg visual->blueMask = pScrn->mask.blue; 206209885543Smrg } 206309885543Smrg } 206409885543Smrg } 206509885543Smrg 206609885543Smrg /* must be after RGB ordering fixed */ 206709885543Smrg fbPictureInit(pScreen, 0, 0); 206809885543Smrg 206909885543Smrg /* CZ 18.06.2001: moved here from smi_accel.c to have offscreen 207009885543Smrg framebuffer in NoAccel mode */ 207109885543Smrg if (!pSmi->useEXA) { 207209885543Smrg int numLines, maxLines; 207309885543Smrg BoxRec AvailFBArea; 207409885543Smrg 207509885543Smrg maxLines = pSmi->FBReserved / (pSmi->width * pSmi->Bpp); 207609885543Smrg if (pSmi->rotate) { 207709885543Smrg numLines = maxLines; 207809885543Smrg } else { 207909885543Smrg /* CZ 3.11.2001: What does the following code? see also smi_video.c aaa line 1226 */ 208009885543Smrg/*#if SMI_USE_VIDEO */ 208109885543Smrg#if 0 208209885543Smrg numLines = ((pSmi->FBReserved - pSmi->width * pSmi->Bpp 208309885543Smrg * pSmi->height) * 25 / 100 + pSmi->width 208409885543Smrg * pSmi->Bpp - 1) / (pSmi->width * pSmi->Bpp); 208509885543Smrg numLines += pSmi->height; 208609885543Smrg#else 208709885543Smrg numLines = maxLines; 208809885543Smrg#endif 208909885543Smrg } 209009885543Smrg 209109885543Smrg AvailFBArea.x1 = 0; 209209885543Smrg AvailFBArea.y1 = 0; 209309885543Smrg AvailFBArea.x2 = pSmi->width; 209409885543Smrg AvailFBArea.y2 = numLines; 209509885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 209609885543Smrg "FrameBuffer Box: %d,%d - %d,%d\n", 209709885543Smrg AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, 209809885543Smrg AvailFBArea.y2); 209909885543Smrg xf86InitFBManager(pScreen, &AvailFBArea); 210009885543Smrg } 210109885543Smrg /* end CZ */ 210209885543Smrg 210309885543Smrg 210409885543Smrg /* Initialize acceleration layer */ 210509885543Smrg if (!pSmi->NoAccel) { 210609885543Smrg if (!pSmi->useEXA) { 210709885543Smrg if (!SMI_XAAInit(pScreen)) { 210809885543Smrg LEAVE_PROC("SMI_ScreenInit"); 210909885543Smrg return FALSE; 211009885543Smrg } 211109885543Smrg } else { 211209885543Smrg if (!SMI_EXAInit(pScreen)) { 211309885543Smrg LEAVE_PROC("SMI_ScreenInit"); 211409885543Smrg return FALSE; 211509885543Smrg } 211609885543Smrg } 211709885543Smrg } 211809885543Smrg 211909885543Smrg miInitializeBackingStore(pScreen); 212009885543Smrg 212109885543Smrg /* hardware cursor needs to wrap this layer */ 212209885543Smrg if(!pSmi->NoAccel && !pSmi->useEXA) 212309885543Smrg SMI_DGAInit(pScreen); 212409885543Smrg 212509885543Smrg /* Initialise cursor functions */ 212609885543Smrg miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 212709885543Smrg 212809885543Smrg /* Initialize HW cursor layer. Must follow software cursor 212909885543Smrg * initialization. 213009885543Smrg */ 213109885543Smrg if (pSmi->hwcursor) { 213209885543Smrg if (!SMI_HWCursorInit(pScreen)) { 213309885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Hardware cursor " 213409885543Smrg "initialization failed\n"); 213509885543Smrg } 213609885543Smrg } 213709885543Smrg 213809885543Smrg if (pSmi->shadowFB) { 213909885543Smrg RefreshAreaFuncPtr refreshArea; 214009885543Smrg 214109885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 214209885543Smrg refreshArea = SMI_RefreshArea730; 214309885543Smrg } else { 214409885543Smrg refreshArea = SMI_RefreshArea; 214509885543Smrg } 214609885543Smrg 214709885543Smrg if (pSmi->rotate) { 214809885543Smrg if (pSmi->PointerMoved == NULL) { 214909885543Smrg pSmi->PointerMoved = pScrn->PointerMoved; 215009885543Smrg pScrn->PointerMoved = SMI_PointerMoved; 215109885543Smrg } 215209885543Smrg } 215309885543Smrg 215409885543Smrg ShadowFBInit(pScreen, refreshArea); 215509885543Smrg } 215609885543Smrg 215709885543Smrg /* Initialise default colormap */ 215809885543Smrg if (!miCreateDefColormap(pScreen)) { 215909885543Smrg LEAVE_PROC("SMI_ScreenInit"); 216009885543Smrg return FALSE; 216109885543Smrg } 216209885543Smrg 216309885543Smrg /* Initialize colormap layer. Must follow initialization of the default 216409885543Smrg * colormap. And SetGamma call, else it will load palette with solid white. 216509885543Smrg */ 216609885543Smrg /* CZ 2.11.2001: CMAP_PALETTED_TRUECOLOR for gamma correction */ 216709885543Smrg if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, SMI_LoadPalette, NULL, 216809885543Smrg CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) { 216909885543Smrg LEAVE_PROC("SMI_ScreenInit"); 217009885543Smrg return FALSE; 217109885543Smrg } 217209885543Smrg 217309885543Smrg pScreen->SaveScreen = SMI_SaveScreen; 217409885543Smrg pSmi->CloseScreen = pScreen->CloseScreen; 217509885543Smrg pScreen->CloseScreen = SMI_CloseScreen; 217609885543Smrg 217709885543Smrg if (!xf86DPMSInit(pScreen, SMI_DisplayPowerManagementSet, 0)) { 217809885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed!\n"); 217909885543Smrg } 218009885543Smrg 218109885543Smrg if (!pSmi->Dualhead) 218209885543Smrg SMI_InitVideo(pScreen); 218309885543Smrg else 218409885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No overlay in dualhead mode\n"); 218509885543Smrg 218609885543Smrg /* Report any unused options (only for the first generation) */ 218709885543Smrg if (serverGeneration == 1) { 218809885543Smrg xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 218909885543Smrg } 219009885543Smrg 219109885543Smrg LEAVE_PROC("SMI_ScreenInit"); 219209885543Smrg return TRUE; 219309885543Smrg} 219409885543Smrg 219509885543Smrg/* Common init routines needed in EnterVT and ScreenInit */ 219609885543Smrg 219709885543Smrgstatic int 219809885543SmrgSMI_InternalScreenInit(int scrnIndex, ScreenPtr pScreen) 219909885543Smrg{ 220009885543Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 220109885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 220209885543Smrg int width, height, displayWidth; 220309885543Smrg int bytesPerPixel = pScrn->bitsPerPixel / 8; 220409885543Smrg int xDpi, yDpi; 220509885543Smrg int ret; 220609885543Smrg 220709885543Smrg ENTER_PROC("SMI_InternalScreenInit"); 220809885543Smrg 220909885543Smrg if (pSmi->rotate) { 221009885543Smrg width = pScrn->virtualY; 221109885543Smrg height = pScrn->virtualX; 221209885543Smrg xDpi = pScrn->yDpi; 221309885543Smrg yDpi = pScrn->xDpi; 221409885543Smrg displayWidth = ((width * bytesPerPixel + 15) & ~15) / bytesPerPixel; 221509885543Smrg } else { 221609885543Smrg width = pScrn->virtualX; 221709885543Smrg height = pScrn->virtualY; 221809885543Smrg xDpi = pScrn->xDpi; 221909885543Smrg yDpi = pScrn->yDpi; 222009885543Smrg displayWidth = pScrn->displayWidth; 222109885543Smrg } 222209885543Smrg 222309885543Smrg if (pSmi->shadowFB) { 222409885543Smrg pSmi->ShadowWidth = width; 222509885543Smrg pSmi->ShadowHeight = height; 222609885543Smrg pSmi->ShadowWidthBytes = (width * bytesPerPixel + 15) & ~15; 222709885543Smrg if (bytesPerPixel == 3) { 222809885543Smrg pSmi->ShadowPitch = ((height * 3) << 16) 222909885543Smrg | pSmi->ShadowWidthBytes; 223009885543Smrg } else { 223109885543Smrg pSmi->ShadowPitch = (height << 16) 223209885543Smrg | (pSmi->ShadowWidthBytes / bytesPerPixel); 223309885543Smrg } 223409885543Smrg 223509885543Smrg pSmi->saveBufferSize = pSmi->ShadowWidthBytes * pSmi->ShadowHeight; 223609885543Smrg pSmi->FBReserved -= pSmi->saveBufferSize; 223709885543Smrg pSmi->FBReserved &= ~0x15; 223809885543Smrg WRITE_VPR(pSmi, 0x0C, (pSmi->FBOffset = pSmi->FBReserved) >> 3); 223909885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 224009885543Smrg WRITE_FPR(pSmi, FPR0C, (pSmi->FBOffset = pSmi->FBReserved) >> 3); 224109885543Smrg } 224209885543Smrg pScrn->fbOffset = pSmi->FBOffset + pSmi->fbMapOffset; 224309885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 224409885543Smrg "Shadow: width=%d height=%d " 224509885543Smrg "offset=0x%08lX pitch=0x%08X\n", 224609885543Smrg pSmi->ShadowWidth, pSmi->ShadowHeight, 224709885543Smrg (unsigned long)pSmi->FBOffset, 224809885543Smrg pSmi->ShadowPitch); 224909885543Smrg } else { 225009885543Smrg pSmi->FBOffset = 0; 225109885543Smrg pScrn->fbOffset = pSmi->FBOffset + pSmi->fbMapOffset; 225209885543Smrg } 225309885543Smrg 225409885543Smrg /* 225509885543Smrg * Call the framebuffer layer's ScreenInit function, and fill in other 225609885543Smrg * pScreen fields. 225709885543Smrg */ 225809885543Smrg 225909885543Smrg DEBUG((VERBLEV, "\tInitializing FB @ 0x%08X for %dx%d (%d)\n", 226009885543Smrg pSmi->FBBase, width, height, displayWidth)); 226109885543Smrg switch (pScrn->bitsPerPixel) { 226209885543Smrg case 8: 226309885543Smrg case 16: 226409885543Smrg case 24: 226509885543Smrg case 32: 226609885543Smrg ret = fbScreenInit(pScreen, pSmi->FBBase, width, height, xDpi, 226709885543Smrg yDpi, displayWidth, pScrn->bitsPerPixel); 226809885543Smrg break; 226909885543Smrg default: 227009885543Smrg xf86DrvMsg(scrnIndex, X_ERROR, "Internal error: invalid bpp (%d) " 227109885543Smrg "in SMI_InternalScreenInit\n", pScrn->bitsPerPixel); 227209885543Smrg LEAVE_PROC("SMI_InternalScreenInit"); 227309885543Smrg return FALSE; 227409885543Smrg } 227509885543Smrg 227609885543Smrg LEAVE_PROC("SMI_InternalScreenInit"); 227709885543Smrg return ret; 227809885543Smrg} 227909885543Smrg 228009885543Smrg/* Checks if a mode is suitable for the selected configuration. */ 228109885543Smrgstatic ModeStatus 228209885543SmrgSMI_ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 228309885543Smrg{ 228409885543Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 228509885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 228609885543Smrg float refresh; 228709885543Smrg 228809885543Smrg ENTER_PROC("SMI_ValidMode"); 228909885543Smrg refresh = (mode->VRefresh > 0) ? mode->VRefresh 229009885543Smrg : mode->Clock * 1000.0 / mode->VTotal / mode->HTotal; 229109885543Smrg xf86DrvMsg(scrnIndex, X_INFO, "Mode: %dx%d %d-bpp, %fHz\n", mode->HDisplay, 229209885543Smrg mode->VDisplay, pScrn->bitsPerPixel, refresh); 229309885543Smrg 229409885543Smrg if (pSmi->shadowFB) { 229509885543Smrg int mem; 229609885543Smrg 229709885543Smrg if (pScrn->bitsPerPixel == 24) { 229809885543Smrg LEAVE_PROC("SMI_ValidMode"); 229909885543Smrg return MODE_BAD; 230009885543Smrg } 230109885543Smrg 230209885543Smrg mem = (pScrn->virtualX * pScrn->bitsPerPixel / 8 + 15) & ~15; 230309885543Smrg mem *= pScrn->virtualY * 2; 230409885543Smrg 230509885543Smrg if (mem > pSmi->FBReserved) /* PDR#1074 */ { 230609885543Smrg LEAVE_PROC("SMI_ValidMode"); 230709885543Smrg return MODE_MEM; 230809885543Smrg } 230909885543Smrg } 231009885543Smrg 231109885543Smrg if (!pSmi->useBIOS || pSmi->lcd) { 231209885543Smrg#if 1 /* PDR#983 */ 231309885543Smrg if (pSmi->zoomOnLCD) { 231409885543Smrg if ((mode->HDisplay > pSmi->lcdWidth) || 231509885543Smrg (mode->VDisplay > pSmi->lcdHeight)) { 231609885543Smrg LEAVE_PROC("SMI_ValidMode"); 231709885543Smrg return MODE_PANEL; 231809885543Smrg } 231909885543Smrg } else 232009885543Smrg#endif 232109885543Smrg { 232209885543Smrg if ((mode->HDisplay != pSmi->lcdWidth) || 232309885543Smrg (mode->VDisplay != pSmi->lcdHeight)) { 232409885543Smrg LEAVE_PROC("SMI_ValidMode"); 232509885543Smrg return MODE_PANEL; 232609885543Smrg } 232709885543Smrg } 232809885543Smrg } 232909885543Smrg 233009885543Smrg#if 1 /* PDR#944 */ 233109885543Smrg if (pSmi->rotate) { 233209885543Smrg if ((mode->HDisplay != pSmi->lcdWidth) || 233309885543Smrg (mode->VDisplay != pSmi->lcdHeight)) { 233409885543Smrg LEAVE_PROC("SMI_ValidMode"); 233509885543Smrg return MODE_PANEL; 233609885543Smrg } 233709885543Smrg } 233809885543Smrg#endif 233909885543Smrg 234009885543Smrg LEAVE_PROC("SMI_ValidMode"); 234109885543Smrg return MODE_OK; 234209885543Smrg} 234309885543Smrg 234409885543Smrgstatic void 234509885543SmrgSMI_DPRInit(ScrnInfoPtr pScrn) 234609885543Smrg{ 234709885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 234809885543Smrg int i; 234909885543Smrg int xyAddress[] = { 320, 400, 512, 640, 800, 1024, 1280, 1600, 2048 }; 235009885543Smrg CARD32 DEDataFormat = 0; 235109885543Smrg 235209885543Smrg /* Store values to current mode register structs */ 235309885543Smrg SMIRegPtr new = &pSmi->ModeReg; 235409885543Smrg 235509885543Smrg /* Set DPR registers */ 235609885543Smrg pSmi->Stride = (pSmi->width * pSmi->Bpp + 15) & ~15; 235709885543Smrg switch (pScrn->bitsPerPixel) { 235809885543Smrg case 8: 235909885543Smrg DEDataFormat = 0x00000000; 236009885543Smrg break; 236109885543Smrg case 16: 236209885543Smrg pSmi->Stride >>= 1; 236309885543Smrg DEDataFormat = 0x00100000; 236409885543Smrg break; 236509885543Smrg case 24: 236609885543Smrg DEDataFormat = 0x00300000; 236709885543Smrg break; 236809885543Smrg case 32: 236909885543Smrg pSmi->Stride >>= 2; 237009885543Smrg DEDataFormat = 0x00200000; 237109885543Smrg break; 237209885543Smrg } 237309885543Smrg 237409885543Smrg for (i = 0; i < sizeof(xyAddress) / sizeof(xyAddress[0]); i++) { 237509885543Smrg if (pSmi->rotate) { 237609885543Smrg if (xyAddress[i] == pSmi->height) { 237709885543Smrg DEDataFormat |= i << 16; 237809885543Smrg break; 237909885543Smrg } 238009885543Smrg } else { 238109885543Smrg if (xyAddress[i] == pSmi->width) { 238209885543Smrg DEDataFormat |= i << 16; 238309885543Smrg break; 238409885543Smrg } 238509885543Smrg } 238609885543Smrg } 238709885543Smrg 238809885543Smrg new->DPR10 = (pSmi->Stride << 16) | pSmi->Stride; 238909885543Smrg new->DPR1C = DEDataFormat; 239009885543Smrg new->DPR20 = 0; 239109885543Smrg new->DPR24 = 0xFFFFFFFF; 239209885543Smrg new->DPR28 = 0xFFFFFFFF; 239309885543Smrg new->DPR2C = 0; 239409885543Smrg new->DPR30 = 0; 239509885543Smrg new->DPR3C = (pSmi->Stride << 16) | pSmi->Stride; 239609885543Smrg new->DPR40 = pSmi->FBOffset >> 3; 239709885543Smrg new->DPR44 = pSmi->FBOffset >> 3; 239809885543Smrg 239909885543Smrg} 240009885543Smrg 240109885543Smrgstatic Bool 240209885543SmrgSMI_ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 240309885543Smrg{ 240409885543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 240509885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 240609885543Smrg unsigned char tmp; 240709885543Smrg int panelIndex, modeIndex, i, vclk; 240809885543Smrg 240909885543Smrg /* Store values to current mode register structs */ 241009885543Smrg SMIRegPtr new = &pSmi->ModeReg; 241109885543Smrg vgaRegPtr vganew = &hwp->ModeReg; 241209885543Smrg 241309885543Smrg ENTER_PROC("SMI_ModeInit"); 241409885543Smrg 241509885543Smrg if (!vgaHWInit(pScrn, mode)) { 241609885543Smrg LEAVE_PROC("SMI_ModeInit"); 241709885543Smrg return FALSE; 241809885543Smrg } 241909885543Smrg 242009885543Smrg new->modeInit = TRUE; 242109885543Smrg 242209885543Smrg if (pSmi->rotate) { 242309885543Smrg pSmi->width = pScrn->virtualY; 242409885543Smrg pSmi->height = pScrn->virtualX; 242509885543Smrg } else { 242609885543Smrg pSmi->width = pScrn->virtualX; 242709885543Smrg pSmi->height = pScrn->virtualY; 242809885543Smrg } 242909885543Smrg pSmi->Bpp = pScrn->bitsPerPixel / 8; 243009885543Smrg 243109885543Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x17); 243209885543Smrg tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); 243309885543Smrg if (pSmi->pci_burst) { 243409885543Smrg new->SR17 = tmp | 0x20; 243509885543Smrg } else { 243609885543Smrg new->SR17 = tmp & ~0x20; 243709885543Smrg } 243809885543Smrg 243909885543Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); 244009885543Smrg new->SR18 = inb(pSmi->PIOBase + VGA_SEQ_DATA) | 0x11; 244109885543Smrg 244209885543Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x21); 244309885543Smrg new->SR21 = inb(pSmi->PIOBase + VGA_SEQ_DATA) & ~0x03; 244409885543Smrg 244509885543Smrg if (pSmi->Chipset != SMI_COUGAR3DR) { 244609885543Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x31); 244709885543Smrg new->SR31 = inb(pSmi->PIOBase + VGA_SEQ_DATA) & ~0xC0; 244809885543Smrg 244909885543Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x32); 245009885543Smrg new->SR32 = inb(pSmi->PIOBase + VGA_SEQ_DATA) & ~0x07; 245109885543Smrg 245209885543Smrg if (SMI_LYNXM_SERIES(pSmi->Chipset)) { 245309885543Smrg new->SR32 |= 0x04; 245409885543Smrg } 245509885543Smrg } 245609885543Smrg 245709885543Smrg new->SRA0 = new->CR33 = new->CR3A = 0x00; 245809885543Smrg 245909885543Smrg if (pSmi->lcdWidth == 640) { 246009885543Smrg panelIndex = 0; 246109885543Smrg } else if (pSmi->lcdWidth == 800) { 246209885543Smrg panelIndex = 1; 246309885543Smrg } else { 246409885543Smrg panelIndex = 2; 246509885543Smrg } 246609885543Smrg 246709885543Smrg if (mode->HDisplay == 640) { 246809885543Smrg modeIndex = 0; 246909885543Smrg } else if (mode->HDisplay == 800) { 247009885543Smrg modeIndex = 1; 247109885543Smrg } else { 247209885543Smrg modeIndex = 2; 247309885543Smrg } 247409885543Smrg 247509885543Smrg if (SMI_LYNXM_SERIES(pSmi->Chipset)) { 247609885543Smrg static unsigned char PanelTable[3][14] = 247709885543Smrg { 247809885543Smrg { 0x5F, 0x4F, 0x00, 0x52, 0x1E, 0x0B, 0xDF, 0x00, 0xE9, 0x0B, 0x2E, 247909885543Smrg 0x00, 0x4F, 0xDF }, 248009885543Smrg { 0x7F, 0x63, 0x00, 0x69, 0x19, 0x72, 0x57, 0x00, 0x58, 0x0C, 0xA2, 248109885543Smrg 0x20, 0x4F, 0xDF }, 248209885543Smrg { 0xA3, 0x7F, 0x00, 0x83, 0x14, 0x24, 0xFF, 0x00, 0x02, 0x08, 0xA7, 248309885543Smrg 0xE0, 0x4F, 0xDF }, 248409885543Smrg }; 248509885543Smrg 248609885543Smrg for (i = 0; i < 14; i++) { 248709885543Smrg new->CR40[i] = PanelTable[panelIndex][i]; 248809885543Smrg } 248909885543Smrg new->CR90[14] = 0x03; 249009885543Smrg new->CR90[15] = 0x00; 249109885543Smrg if (mode->VDisplay < pSmi->lcdHeight) { 249209885543Smrg new->CRA0[6] = (pSmi->lcdHeight - mode->VDisplay) / 8; 249309885543Smrg } else { 249409885543Smrg new->CRA0[6] = 0; 249509885543Smrg } 249609885543Smrg 249709885543Smrg if (mode->HDisplay < pSmi->lcdWidth) { 249809885543Smrg new->CRA0[7] = (pSmi->lcdWidth - mode->HDisplay) / 16; 249909885543Smrg } else { 250009885543Smrg new->CRA0[7] = 0; 250109885543Smrg } 250209885543Smrg } else { 250309885543Smrg static unsigned char PanelTable[3][3][14] = 250409885543Smrg { 250509885543Smrg { /* 640x480 panel */ 250609885543Smrg { 0x5F, 0x4F, 0x00, 0x53, 0x00, 0x0B, 0xDF, 0x00, 0xEA, 0x0C, 250709885543Smrg 0x2E, 0x00, 0x4F, 0xDF }, 250809885543Smrg { 0x5F, 0x4F, 0x00, 0x53, 0x00, 0x0B, 0xDF, 0x00, 0xEA, 0x0C, 250909885543Smrg 0x2E, 0x00, 0x4F, 0xDF }, 251009885543Smrg { 0x5F, 0x4F, 0x00, 0x53, 0x00, 0x0B, 0xDF, 0x00, 0xEA, 0x0C, 251109885543Smrg 0x2E, 0x00, 0x4F, 0xDF }, 251209885543Smrg }, 251309885543Smrg { /* 800x600 panel */ 251409885543Smrg { 0x7F, 0x59, 0x19, 0x5E, 0x8E, 0x72, 0x1C, 0x37, 0x1D, 0x00, 251509885543Smrg 0xA2, 0x20, 0x4F, 0xDF }, 251609885543Smrg { 0x7F, 0x63, 0x00, 0x68, 0x18, 0x72, 0x58, 0x00, 0x59, 0x0C, 251709885543Smrg 0xE0, 0x20, 0x63, 0x57 }, 251809885543Smrg { 0x7F, 0x63, 0x00, 0x68, 0x18, 0x72, 0x58, 0x00, 0x59, 0x0C, 251909885543Smrg 0xE0, 0x20, 0x63, 0x57 }, 252009885543Smrg }, 252109885543Smrg { /* 1024x768 panel */ 252209885543Smrg { 0xA3, 0x67, 0x0F, 0x6D, 0x1D, 0x24, 0x70, 0x95, 0x72, 0x07, 252309885543Smrg 0xA3, 0x20, 0x4F, 0xDF }, 252409885543Smrg { 0xA3, 0x71, 0x19, 0x77, 0x07, 0x24, 0xAC, 0xD1, 0xAE, 0x03, 252509885543Smrg 0xE1, 0x20, 0x63, 0x57 }, 252609885543Smrg { 0xA3, 0x7F, 0x00, 0x85, 0x15, 0x24, 0xFF, 0x00, 0x01, 0x07, 252709885543Smrg 0xE5, 0x20, 0x7F, 0xFF }, 252809885543Smrg }, 252909885543Smrg }; 253009885543Smrg 253109885543Smrg for (i = 0; i < 14; i++) { 253209885543Smrg new->CR40[i] = PanelTable[panelIndex][modeIndex][i]; 253309885543Smrg } 253409885543Smrg } 253509885543Smrg 253609885543Smrg /* CZ 2.11.2001: for gamma correction (TODO: other chipsets?) */ 253709885543Smrg new->CCR66 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66); 253809885543Smrg if ((pSmi->Chipset == SMI_LYNX3DM) || (pSmi->Chipset == SMI_COUGAR3DR)) { 253909885543Smrg switch (pScrn->bitsPerPixel) { 254009885543Smrg case 8: 254109885543Smrg new->CCR66 = (new->CCR66 & 0xF3) | 0x00; /* 6 bits-RAM */ 254209885543Smrg break; 254309885543Smrg case 16: 254409885543Smrg new->CCR66 = (new->CCR66 & 0xF3) | 0x00; /* 6 bits-RAM */ 254509885543Smrg /* no Gamma correction in 16 Bit mode (s. Release.txt 1.3.1) */ 254609885543Smrg break; 254709885543Smrg case 24: 254809885543Smrg case 32: 254909885543Smrg new->CCR66 = (new->CCR66 & 0xF3) | 0x04; /* Gamma correct ON */ 255009885543Smrg break; 255109885543Smrg default: 255209885543Smrg LEAVE_PROC("SMI_ModeInit"); 255309885543Smrg return FALSE; 255409885543Smrg } 255509885543Smrg } 255609885543Smrg 255709885543Smrg if (pSmi->Chipset != SMI_COUGAR3DR) { 255809885543Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x30); 255909885543Smrg if (inb(pSmi->PIOBase + VGA_SEQ_DATA) & 0x01) { 256009885543Smrg new->SR21 = 0x00; 256109885543Smrg } 256209885543Smrg } 256309885543Smrg 256409885543Smrg if (pSmi->MCLK > 0) { 256509885543Smrg SMI_CommonCalcClock(pScrn->scrnIndex, pSmi->MCLK, 256609885543Smrg 1, 1, 63, 0, 2, 256709885543Smrg pScrn->clockRanges->minClock, 256809885543Smrg pScrn->clockRanges->maxClock, 256909885543Smrg &new->SR6A, &new->SR6B); 257009885543Smrg } else { 257109885543Smrg new->SR6B = 0xFF; 257209885543Smrg } 257309885543Smrg 257409885543Smrg if ((mode->HDisplay == 640) && SMI_LYNXM_SERIES(pSmi->Chipset)) { 257509885543Smrg vganew->MiscOutReg &= ~0x0C; 257609885543Smrg } else { 257709885543Smrg vganew->MiscOutReg |= 0x0C; 257809885543Smrg } 257909885543Smrg vganew->MiscOutReg |= 0xE0; 258009885543Smrg if (mode->HDisplay == 800) { 258109885543Smrg vganew->MiscOutReg &= ~0xC0; 258209885543Smrg } 258309885543Smrg if ((mode->HDisplay == 1024) && SMI_LYNXM_SERIES(pSmi->Chipset)) { 258409885543Smrg vganew->MiscOutReg &= ~0xC0; 258509885543Smrg } 258609885543Smrg 258709885543Smrg /* calculate vclk1 */ 258809885543Smrg vclk = mode->Clock; 258909885543Smrg if (SMI_LYNX_SERIES(pSmi->Chipset)) { 259009885543Smrg SMI_CommonCalcClock(pScrn->scrnIndex, vclk, 259109885543Smrg 1, 1, 63, 0, 2, 259209885543Smrg pScrn->clockRanges->minClock, 259309885543Smrg pScrn->clockRanges->maxClock, 259409885543Smrg &new->SR6C, &new->SR6D); 259509885543Smrg } else { 259609885543Smrg SMI_CommonCalcClock(pScrn->scrnIndex, vclk, 259709885543Smrg 1, 1, 63, 0, 1, 259809885543Smrg pScrn->clockRanges->minClock, 259909885543Smrg pScrn->clockRanges->maxClock, 260009885543Smrg &new->SR6C, &new->SR6D); 260109885543Smrg } 260209885543Smrg 260309885543Smrg /* use vclk1 */ 260409885543Smrg new->SR68 = 0x54; 260509885543Smrg 260609885543Smrg /* dualhead */ 260709885543Smrg if (pSmi->Dualhead) { 260809885543Smrg /* PLL controls */ 260909885543Smrg /* set LCD to vclk2 */ 261009885543Smrg new->SR69 = 0x04; 261109885543Smrg 261209885543Smrg if (pSmi->lcdWidth == 640) { 261309885543Smrg /* vclk */ 261409885543Smrg new->SR6C = 0x07; 261509885543Smrg new->SR6D = 0x04; 261609885543Smrg 261709885543Smrg /* vclk2 */ 261809885543Smrg new->SR6E = 0x07; 261909885543Smrg new->SR6F = 0x04; 262009885543Smrg } else if (pSmi->lcdWidth == 800) { 262109885543Smrg /* vclk */ 262209885543Smrg new->SR6C = 0x0B; 262309885543Smrg new->SR6D = 0x82; 262409885543Smrg 262509885543Smrg /* vclk2 */ 262609885543Smrg new->SR6E = 0x0B; 262709885543Smrg new->SR6F = 0x82; 262809885543Smrg } else { 262909885543Smrg /* vclk */ 263009885543Smrg new->SR6C = 0x52; 263109885543Smrg new->SR6D = 0x89; 263209885543Smrg 263309885543Smrg /* vclk2 */ 263409885543Smrg new->SR6E = 0x52; 263509885543Smrg new->SR6F = 0x89; 263609885543Smrg } 263709885543Smrg 263809885543Smrg /* TFT panel uses FIFO1, DSTN panel uses FIFO1 for upper panel and 263909885543Smrg * FIFO2 for lower panel. I don't have a DSTN panel, so it's untested. 264009885543Smrg * -- AGD 264109885543Smrg */ 264209885543Smrg CARD32 fifo1_readoffset, fifo2_readoffset, fifo_writeoffset; 264309885543Smrg 264409885543Smrg /* setting SR21 bit 2 disables ZV circuitry, 264509885543Smrg * if ZV is needed, SR21 = 0x20 264609885543Smrg */ 264709885543Smrg /* enable DAC, PLL, etc. */ 264809885543Smrg new->SR21 = 0x24; 264909885543Smrg 265009885543Smrg /* clear DPMS state */ 265109885543Smrg new->SR22 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22) & ~0x30; 265209885543Smrg 265309885543Smrg /* enable virtual refresh and LCD and CRT outputs */ 265409885543Smrg if (pScrn->bitsPerPixel > 8) 265509885543Smrg new->SR31 = /*0xCB*/ 0xC3; /* 16 bpp */ 265609885543Smrg else 265709885543Smrg new->SR31 = /*0x8B*/ 0x83; /* 8 bpp */ 265809885543Smrg 265909885543Smrg /* FIFO1 Read Offset */ 266009885543Smrg fifo1_readoffset = pSmi->lcdWidth / 2; 266109885543Smrg fifo2_readoffset = pSmi->lcdWidth / 2; 266209885543Smrg new->SR44 = fifo1_readoffset & 0x000000FF; 266309885543Smrg /* FIFO2 Read Offset */ 266409885543Smrg new->SR4B = fifo2_readoffset & 0x000000FF; 266509885543Smrg /* FIFO1/2 Read Offset overflow */ 266609885543Smrg new->SR4C = (((fifo1_readoffset & 0x00000300) >> 8) << 2) | 266709885543Smrg (((fifo2_readoffset & 0x00000300) >> 8) << 6); 266809885543Smrg 266909885543Smrg /* FIFO Write Offset */ 267009885543Smrg fifo_writeoffset = pSmi->lcdWidth / 4; 267109885543Smrg new->SR48 = fifo_writeoffset & 0x000000FF; 267209885543Smrg new->SR49 = (fifo_writeoffset & 0x00000300) >> 8; 267309885543Smrg 267409885543Smrg /* set FIFO levels */ 267509885543Smrg new->SR4A = 0x41; 267609885543Smrg 267709885543Smrg /* something related to tv... */ 267809885543Smrg new->CR33 |= 0x07; 267909885543Smrg 268009885543Smrg } 268109885543Smrg 268209885543Smrg /* init graphics engine regs */ 268309885543Smrg SMI_DPRInit(pScrn); 268409885543Smrg 268509885543Smrg /* Set VPR registers (and FPR registers for SM731) */ 268609885543Smrg switch (pScrn->bitsPerPixel) { 268709885543Smrg case 8: 268809885543Smrg new->VPR00 = 0x00000000; 268909885543Smrg new->FPR00_= 0x00080000; 269009885543Smrg break; 269109885543Smrg case 16: 269209885543Smrg new->VPR00 = 0x00020000; 269309885543Smrg new->FPR00_= 0x000A0000; 269409885543Smrg break; 269509885543Smrg case 24: 269609885543Smrg new->VPR00 = 0x00040000; 269709885543Smrg new->FPR00_= 0x000C0000; 269809885543Smrg break; 269909885543Smrg case 32: 270009885543Smrg new->VPR00 = 0x00030000; 270109885543Smrg new->FPR00_= 0x000B0000; 270209885543Smrg break; 270309885543Smrg } 270409885543Smrg new->VPR0C = pSmi->FBOffset >> 3; 270509885543Smrg if (pSmi->rotate) { 270609885543Smrg new->VPR10 = (((( pSmi->height * pSmi->Bpp) >> 3) + 2) << 16) | 270709885543Smrg ((pSmi->height * pSmi->Bpp) >> 3); 270809885543Smrg } else { 270909885543Smrg new->VPR10 = ((((pSmi->width * pSmi->Bpp) >> 3) + 2) << 16) | 271009885543Smrg ((pSmi->width * pSmi->Bpp) >> 3); 271109885543Smrg } 271209885543Smrg 271309885543Smrg new->FPR0C_ = new->VPR0C; 271409885543Smrg new->FPR10_ = new->VPR10; 271509885543Smrg 271609885543Smrg /* Set CPR registers */ 271709885543Smrg new->CPR00 = 0x00000000; 271809885543Smrg 271909885543Smrg pScrn->vtSema = TRUE; 272009885543Smrg 272109885543Smrg /* Find the INT 10 mode number */ 272209885543Smrg { 272309885543Smrg static struct { 272409885543Smrg int x, y, bpp; 272509885543Smrg CARD16 mode; 272609885543Smrg } modeTable[] = 272709885543Smrg { 272809885543Smrg { 640, 480, 8, 0x50 }, 272909885543Smrg { 640, 480, 16, 0x52 }, 273009885543Smrg { 640, 480, 24, 0x53 }, 273109885543Smrg { 640, 480, 32, 0x54 }, 273209885543Smrg { 800, 480, 8, 0x4A }, 273309885543Smrg { 800, 480, 16, 0x4C }, 273409885543Smrg { 800, 480, 24, 0x4D }, 273509885543Smrg { 800, 600, 8, 0x55 }, 273609885543Smrg { 800, 600, 16, 0x57 }, 273709885543Smrg { 800, 600, 24, 0x58 }, 273809885543Smrg { 800, 600, 32, 0x59 }, 273909885543Smrg { 1024, 768, 8, 0x60 }, 274009885543Smrg { 1024, 768, 16, 0x62 }, 274109885543Smrg { 1024, 768, 24, 0x63 }, 274209885543Smrg { 1024, 768, 32, 0x64 }, 274309885543Smrg { 1280, 1024, 8, 0x65 }, 274409885543Smrg { 1280, 1024, 16, 0x67 }, 274509885543Smrg { 1280, 1024, 24, 0x68 }, 274609885543Smrg { 1280, 1024, 32, 0x69 }, 274709885543Smrg }; 274809885543Smrg 274909885543Smrg new->mode = 0; 275009885543Smrg for (i = 0; i < sizeof(modeTable) / sizeof(modeTable[0]); i++) { 275109885543Smrg if ((modeTable[i].x == mode->HDisplay) && 275209885543Smrg (modeTable[i].y == mode->VDisplay) && 275309885543Smrg (modeTable[i].bpp == pScrn->bitsPerPixel)) { 275409885543Smrg new->mode = modeTable[i].mode; 275509885543Smrg break; 275609885543Smrg } 275709885543Smrg } 275809885543Smrg } 275909885543Smrg 276009885543Smrg /* Zero the font memory */ 276109885543Smrg memset(new->smiFont, 0, sizeof(new->smiFont)); 276209885543Smrg 276309885543Smrg /* Write the mode registers to hardware */ 276409885543Smrg SMI_WriteMode(pScrn, vganew, new); 276509885543Smrg 276609885543Smrg /* Adjust the viewport */ 276709885543Smrg SMI_AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 276809885543Smrg 276909885543Smrg LEAVE_PROC("SMI_ModeInit"); 277009885543Smrg return TRUE; 277109885543Smrg} 277209885543Smrg 277309885543Smrg/* 277409885543Smrg * This is called at the end of each server generation. It restores the 277509885543Smrg * original (text) mode. It should also unmap the video memory, and free any 277609885543Smrg * per-generation data allocated by the driver. It should finish by unwrapping 277709885543Smrg * and calling the saved CloseScreen function. 277809885543Smrg */ 277909885543Smrg 278009885543Smrgstatic Bool 278109885543SmrgSMI_CloseScreen(int scrnIndex, ScreenPtr pScreen) 278209885543Smrg{ 278309885543Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 278409885543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 278509885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 278609885543Smrg vgaRegPtr vgaSavePtr = &hwp->SavedReg; 278709885543Smrg SMIRegPtr SMISavePtr = &pSmi->SavedReg; 278809885543Smrg Bool ret; 278909885543Smrg 279009885543Smrg ENTER_PROC("SMI_CloseScreen"); 279109885543Smrg 279209885543Smrg if (pScrn->vtSema) { 279309885543Smrg SMI_WriteMode(pScrn, vgaSavePtr, SMISavePtr); 279409885543Smrg vgaHWLock(hwp); 279509885543Smrg SMI_UnmapMem(pScrn); 279609885543Smrg } 279709885543Smrg 279809885543Smrg if (pSmi->XAAInfoRec != NULL) { 279909885543Smrg XAADestroyInfoRec(pSmi->XAAInfoRec); 280009885543Smrg } 280109885543Smrg if (pSmi->EXADriverPtr) { 280209885543Smrg exaDriverFini(pScreen); 280309885543Smrg pSmi->EXADriverPtr = NULL; 280409885543Smrg } 280509885543Smrg if (pSmi->CursorInfoRec != NULL) { 280609885543Smrg xf86DestroyCursorInfoRec(pSmi->CursorInfoRec); 280709885543Smrg } 280809885543Smrg if (pSmi->DGAModes != NULL) { 280909885543Smrg xfree(pSmi->DGAModes); 281009885543Smrg } 281109885543Smrg if (pSmi->pInt10 != NULL) { 281209885543Smrg xf86FreeInt10(pSmi->pInt10); 281309885543Smrg pSmi->pInt10 = NULL; 281409885543Smrg } 281509885543Smrg if (pSmi->ptrAdaptor != NULL) { 281609885543Smrg xfree(pSmi->ptrAdaptor); 281709885543Smrg } 281809885543Smrg if (pSmi->BlockHandler != NULL) { 281909885543Smrg pScreen->BlockHandler = pSmi->BlockHandler; 282009885543Smrg } 282109885543Smrg /* #670 */ 282209885543Smrg if (pSmi->pSaveBuffer) { 282309885543Smrg xfree(pSmi->pSaveBuffer); 282409885543Smrg } 282509885543Smrg/* #920 */ 282609885543Smrg if (pSmi->paletteBuffer) { 282709885543Smrg xfree(pSmi->paletteBuffer); 282809885543Smrg } 282909885543Smrg 283009885543Smrg pScrn->vtSema = FALSE; 283109885543Smrg pScreen->CloseScreen = pSmi->CloseScreen; 283209885543Smrg ret = (*pScreen->CloseScreen)(scrnIndex, pScreen); 283309885543Smrg 283409885543Smrg LEAVE_PROC("SMI_CloseScreen"); 283509885543Smrg return ret; 283609885543Smrg} 283709885543Smrg 283809885543Smrgstatic void 283909885543SmrgSMI_FreeScreen(int scrnIndex, int flags) 284009885543Smrg{ 284109885543Smrg SMI_FreeRec(xf86Screens[scrnIndex]); 284209885543Smrg} 284309885543Smrg 284409885543Smrgstatic Bool 284509885543SmrgSMI_SaveScreen(ScreenPtr pScreen, int mode) 284609885543Smrg{ 284709885543Smrg Bool ret; 284809885543Smrg 284909885543Smrg ENTER_PROC("SMI_SaveScreen"); 285009885543Smrg 285109885543Smrg ret = vgaHWSaveScreen(pScreen, mode); 285209885543Smrg 285309885543Smrg LEAVE_PROC("SMI_SaveScreen"); 285409885543Smrg return ret; 285509885543Smrg} 285609885543Smrg 285709885543Smrgvoid 285809885543SmrgSMI_AdjustFrame(int scrnIndex, int x, int y, int flags) 285909885543Smrg{ 286009885543Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 286109885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 286209885543Smrg CARD32 Base, lcdBase; 286309885543Smrg 286409885543Smrg ENTER_PROC("SMI_AdjustFrame"); 286509885543Smrg 286609885543Smrg if (pSmi->ShowCache && y) { 286709885543Smrg y += pScrn->virtualY - 1; 286809885543Smrg } 286909885543Smrg 287009885543Smrg if (pSmi->Dualhead) { 287109885543Smrg lcdBase = 0; 287209885543Smrg x = pSmi->lcdWidth; 287309885543Smrg y = 0; 287409885543Smrg } 287509885543Smrg 287609885543Smrg Base = pSmi->FBOffset + (x + y * pScrn->virtualX) * pSmi->Bpp; 287709885543Smrg if (SMI_LYNX3D_SERIES(pSmi->Chipset) || 287809885543Smrg SMI_COUGAR_SERIES(pSmi->Chipset)) { 287909885543Smrg Base = (Base + 15) & ~15; 288009885543Smrg#if 1 /* PDR#1058 */ 288109885543Smrg while ((Base % pSmi->Bpp) > 0) { 288209885543Smrg Base -= 16; 288309885543Smrg } 288409885543Smrg#endif 288509885543Smrg } else { 288609885543Smrg Base = (Base + 7) & ~7; 288709885543Smrg#if 1 /* PDR#1058 */ 288809885543Smrg while ((Base % pSmi->Bpp) > 0) { 288909885543Smrg Base -= 8; 289009885543Smrg } 289109885543Smrg#endif 289209885543Smrg } 289309885543Smrg 289409885543Smrg if (pSmi->Dualhead) { 289509885543Smrg 289609885543Smrg /* FIFO1 read start address */ 289709885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40, 289809885543Smrg (lcdBase & 0x000000FF)); 289909885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41, 290009885543Smrg ((lcdBase & 0x0000FF00) >> 8)); 290109885543Smrg 290209885543Smrg /* FIFO2 read start address */ 290309885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42, 290409885543Smrg (lcdBase & 0x000000FF)); 290509885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43, 290609885543Smrg ((lcdBase & 0x0000FF00) >> 8)); 290709885543Smrg 290809885543Smrg /* FIFO1/2 read start address overflow */ 290909885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45, 291009885543Smrg ((lcdBase & 0x000F0000) >> 12) | (((lcdBase & 0x000F0000) >> 12) << 4)); 291109885543Smrg 291209885543Smrg } 291309885543Smrg 291409885543Smrg WRITE_VPR(pSmi, 0x0C, Base >> 3); 291509885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 291609885543Smrg WRITE_FPR(pSmi, FPR0C, Base >> 3); 291709885543Smrg } 291809885543Smrg 291909885543Smrg LEAVE_PROC("SMI_AdjustFrame"); 292009885543Smrg} 292109885543Smrg 292209885543SmrgBool 292309885543SmrgSMI_SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 292409885543Smrg{ 292509885543Smrg Bool ret; 292609885543Smrg SMIPtr pSmi = SMIPTR(xf86Screens[scrnIndex]); 292709885543Smrg 292809885543Smrg ENTER_PROC("SMI_SwitchMode"); 292909885543Smrg 293009885543Smrg pSmi->IsSwitching = TRUE; 293109885543Smrg ret = SMI_ModeInit(xf86Screens[scrnIndex], mode); 293209885543Smrg pSmi->IsSwitching = FALSE; 293309885543Smrg 293409885543Smrg LEAVE_PROC("SMI_SwitchMode"); 293509885543Smrg return ret; 293609885543Smrg} 293709885543Smrg 293809885543Smrgvoid 293909885543SmrgSMI_LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors, 294009885543Smrg VisualPtr pVisual) 294109885543Smrg{ 294209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 294309885543Smrg int i; 294409885543Smrg 294509885543Smrg ENTER_PROC("SMI_LoadPalette"); 294609885543Smrg 294709885543Smrg /* Enable both the CRT and LCD DAC RAM paths, so both palettes are updated */ 294809885543Smrg if ((pSmi->Chipset == SMI_LYNX3DM) || 294909885543Smrg (pSmi->Chipset == SMI_COUGAR3DR)) { 295009885543Smrg CARD8 ccr66; 295109885543Smrg 295209885543Smrg ccr66 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66); 295309885543Smrg ccr66 &= 0x0f; 295409885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66, ccr66); 295509885543Smrg } 295609885543Smrg 295709885543Smrg for(i = 0; i < numColors; i++) { 295809885543Smrg DEBUG((VERBLEV, "pal[%d] = %d %d %d\n", indicies[i], 295909885543Smrg colors[indicies[i]].red, colors[indicies[i]].green, colors[indicies[i]].blue)); 296009885543Smrg VGAOUT8(pSmi, VGA_DAC_WRITE_ADDR, indicies[i]); 296109885543Smrg VGAOUT8(pSmi, VGA_DAC_DATA, colors[indicies[i]].red); 296209885543Smrg VGAOUT8(pSmi, VGA_DAC_DATA, colors[indicies[i]].green); 296309885543Smrg VGAOUT8(pSmi, VGA_DAC_DATA, colors[indicies[i]].blue); 296409885543Smrg } 296509885543Smrg 296609885543Smrg LEAVE_PROC("SMI_LoadPalette"); 296709885543Smrg} 296809885543Smrg 296909885543Smrgstatic void 297009885543SmrgSMI_DisableVideo(ScrnInfoPtr pScrn) 297109885543Smrg{ 297209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 297309885543Smrg CARD8 tmp; 297409885543Smrg 297509885543Smrg if (!(tmp = VGAIN8(pSmi, VGA_DAC_MASK))) 297609885543Smrg return; 297709885543Smrg pSmi->DACmask = tmp; 297809885543Smrg VGAOUT8(pSmi, VGA_DAC_MASK, 0); 297909885543Smrg} 298009885543Smrg 298109885543Smrgstatic void 298209885543SmrgSMI_EnableVideo(ScrnInfoPtr pScrn) 298309885543Smrg{ 298409885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 298509885543Smrg 298609885543Smrg VGAOUT8(pSmi, VGA_DAC_MASK, pSmi->DACmask); 298709885543Smrg} 298809885543Smrg 298909885543Smrg 299009885543Smrgvoid 299109885543SmrgSMI_EnableMmio(ScrnInfoPtr pScrn) 299209885543Smrg{ 299309885543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 299409885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 299509885543Smrg CARD8 tmp; 299609885543Smrg 299709885543Smrg ENTER_PROC("SMI_EnableMmio"); 299809885543Smrg 299909885543Smrg /* 300009885543Smrg * Enable chipset (seen on uninitialized secondary cards) might not be 300109885543Smrg * needed once we use the VGA softbooter 300209885543Smrg */ 300309885543Smrg vgaHWSetStdFuncs(hwp); 300409885543Smrg 300509885543Smrg /* Enable linear mode */ 300609885543Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); 300709885543Smrg tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); 300809885543Smrg pSmi->SR18Value = tmp; /* PDR#521 */ 300909885543Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp | 0x11); 301009885543Smrg 301109885543Smrg /* Enable 2D/3D Engine and Video Processor */ 301209885543Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x21); 301309885543Smrg tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); 301409885543Smrg pSmi->SR21Value = tmp; /* PDR#521 */ 301509885543Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp & ~0x03); 301609885543Smrg 301709885543Smrg LEAVE_PROC("SMI_EnableMmio"); 301809885543Smrg} 301909885543Smrg 302009885543Smrgvoid 302109885543SmrgSMI_DisableMmio(ScrnInfoPtr pScrn) 302209885543Smrg{ 302309885543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 302409885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 302509885543Smrg 302609885543Smrg ENTER_PROC("SMI_DisableMmio"); 302709885543Smrg 302809885543Smrg vgaHWSetStdFuncs(hwp); 302909885543Smrg 303009885543Smrg /* Disable 2D/3D Engine and Video Processor */ 303109885543Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x21); 303209885543Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, pSmi->SR21Value); /* PDR#521 */ 303309885543Smrg 303409885543Smrg /* Disable linear mode */ 303509885543Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); 303609885543Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, pSmi->SR18Value); /* PDR#521 */ 303709885543Smrg 303809885543Smrg LEAVE_PROC("SMI_DisableMmio"); 303909885543Smrg} 304009885543Smrg 304109885543Smrg/* This function is used to debug, it prints out the contents of Lynx regs */ 304209885543Smrgstatic void 304309885543SmrgSMI_PrintRegs(ScrnInfoPtr pScrn) 304409885543Smrg{ 304509885543Smrg unsigned char i; 304609885543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 304709885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 304809885543Smrg int vgaCRIndex = hwp->IOBase + VGA_CRTC_INDEX_OFFSET; 304909885543Smrg int vgaCRReg = hwp->IOBase + VGA_CRTC_DATA_OFFSET; 305009885543Smrg int vgaStatus = hwp->IOBase + VGA_IN_STAT_1_OFFSET; 305109885543Smrg 305209885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 305309885543Smrg "START register dump ------------------\n"); 305409885543Smrg 305509885543Smrg xf86ErrorFVerb(VERBLEV, "MISCELLANEOUS OUTPUT\n %02X\n", 305609885543Smrg VGAIN8(pSmi, VGA_MISC_OUT_R)); 305709885543Smrg 305809885543Smrg xf86ErrorFVerb(VERBLEV, "\nSEQUENCER\n" 305909885543Smrg " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 306009885543Smrg for (i = 0x00; i <= 0xAF; i++) { 306109885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 306209885543Smrg if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 306309885543Smrg xf86ErrorFVerb(VERBLEV, "%02X ", 306409885543Smrg VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, i)); 306509885543Smrg } 306609885543Smrg 306709885543Smrg xf86ErrorFVerb(VERBLEV, "\n\nCRT CONTROLLER\n" 306809885543Smrg " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 306909885543Smrg for (i = 0x00; i <= 0xAD; i++) { 307009885543Smrg if (i == 0x20) i = 0x30; 307109885543Smrg if (i == 0x50) i = 0x90; 307209885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 307309885543Smrg if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 307409885543Smrg xf86ErrorFVerb(VERBLEV, "%02X ", 307509885543Smrg VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRReg, i)); 307609885543Smrg } 307709885543Smrg 307809885543Smrg xf86ErrorFVerb(VERBLEV, "\n\nGRAPHICS CONTROLLER\n" 307909885543Smrg " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 308009885543Smrg for (i = 0x00; i <= 0x08; i++) { 308109885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 308209885543Smrg if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 308309885543Smrg xf86ErrorFVerb(VERBLEV, "%02X ", 308409885543Smrg VGAIN8_INDEX(pSmi, VGA_GRAPH_INDEX, VGA_GRAPH_DATA, i)); 308509885543Smrg } 308609885543Smrg 308709885543Smrg xf86ErrorFVerb(VERBLEV, "\n\nATTRIBUTE 0CONTROLLER\n" 308809885543Smrg " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 308909885543Smrg for (i = 0x00; i <= 0x14; i++) { 309009885543Smrg (void) VGAIN8(pSmi, vgaStatus); 309109885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 309209885543Smrg if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 309309885543Smrg xf86ErrorFVerb(VERBLEV, "%02X ", 309409885543Smrg VGAIN8_INDEX(pSmi, VGA_ATTR_INDEX, VGA_ATTR_DATA_R, i)); 309509885543Smrg } 309609885543Smrg (void) VGAIN8(pSmi, vgaStatus); 309709885543Smrg VGAOUT8(pSmi, VGA_ATTR_INDEX, 0x20); 309809885543Smrg 309909885543Smrg xf86ErrorFVerb(VERBLEV, "\n\nDPR x0 x4 x8 xC"); 310009885543Smrg for (i = 0x00; i <= 0x44; i += 4) { 310109885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 310209885543Smrg xf86ErrorFVerb(VERBLEV, " %08lX", (unsigned long)READ_DPR(pSmi, i)); 310309885543Smrg } 310409885543Smrg 310509885543Smrg xf86ErrorFVerb(VERBLEV, "\n\nVPR x0 x4 x8 xC"); 310609885543Smrg for (i = 0x00; i <= 0x60; i += 4) { 310709885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 310809885543Smrg xf86ErrorFVerb(VERBLEV, " %08lX", (unsigned long)READ_VPR(pSmi, i)); 310909885543Smrg } 311009885543Smrg 311109885543Smrg xf86ErrorFVerb(VERBLEV, "\n\nCPR x0 x4 x8 xC"); 311209885543Smrg for (i = 0x00; i <= 0x18; i += 4) { 311309885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 311409885543Smrg xf86ErrorFVerb(VERBLEV, " %08lX", (unsigned long)READ_CPR(pSmi, i)); 311509885543Smrg } 311609885543Smrg 311709885543Smrg xf86ErrorFVerb(VERBLEV, "\n\n"); 311809885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 311909885543Smrg "END register dump --------------------\n"); 312009885543Smrg} 312109885543Smrg 312209885543Smrg/* 312309885543Smrg * SMI_DisplayPowerManagementSet -- Sets VESA Display Power Management 312409885543Smrg * Signaling (DPMS) Mode. 312509885543Smrg */ 312609885543Smrgstatic void 312709885543SmrgSMI_DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 312809885543Smrg int flags) 312909885543Smrg{ 313009885543Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 313109885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 313209885543Smrg CARD8 SR01, SR20, SR21, SR22, SR23, SR24, SR31, SR34; 313309885543Smrg 313409885543Smrg ENTER_PROC("SMI_DisplayPowerManagementSet"); 313509885543Smrg 313609885543Smrg /* If we already are in the requested DPMS mode, just return */ 313709885543Smrg if (pSmi->CurrentDPMS == PowerManagementMode) { 313809885543Smrg LEAVE_PROC("SMI_DisplayPowerManagementSet"); 313909885543Smrg return; 314009885543Smrg } 314109885543Smrg 314209885543Smrg#if 1 /* PDR#735 */ 314309885543Smrg if (pSmi->useBIOS && pSmi->pInt10 != NULL) { 314409885543Smrg pSmi->pInt10->ax = 0x4F10; 314509885543Smrg switch (PowerManagementMode) { 314609885543Smrg case DPMSModeOn: 314709885543Smrg pSmi->pInt10->bx = 0x0001; 314809885543Smrg break; 314909885543Smrg case DPMSModeStandby: 315009885543Smrg pSmi->pInt10->bx = 0x0101; 315109885543Smrg break; 315209885543Smrg case DPMSModeSuspend: 315309885543Smrg pSmi->pInt10->bx = 0x0201; 315409885543Smrg break; 315509885543Smrg case DPMSModeOff: 315609885543Smrg pSmi->pInt10->bx = 0x0401; 315709885543Smrg break; 315809885543Smrg } 315909885543Smrg pSmi->pInt10->cx = 0x0000; 316009885543Smrg pSmi->pInt10->num = 0x10; 316109885543Smrg xf86ExecX86int10(pSmi->pInt10); 316209885543Smrg if (pSmi->pInt10->ax == 0x004F) { 316309885543Smrg pSmi->CurrentDPMS = PowerManagementMode; 316409885543Smrg#if 1 /* PDR#835 */ 316509885543Smrg if (PowerManagementMode == DPMSModeOn) { 316609885543Smrg SR01 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01); 316709885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01, 316809885543Smrg SR01 & ~0x20); 316909885543Smrg } 317009885543Smrg#endif 317109885543Smrg LEAVE_PROC("SMI_DisplayPowerManagementSet"); 317209885543Smrg return; 317309885543Smrg } 317409885543Smrg } 317509885543Smrg#endif 317609885543Smrg 317709885543Smrg /* Save the current SR registers */ 317809885543Smrg if (pSmi->CurrentDPMS == DPMSModeOn) { 317909885543Smrg pSmi->DPMS_SR20 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20); 318009885543Smrg pSmi->DPMS_SR21 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 318109885543Smrg pSmi->DPMS_SR31 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31); 318209885543Smrg pSmi->DPMS_SR34 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x34); 318309885543Smrg } 318409885543Smrg 318509885543Smrg /* Read the required SR registers for the DPMS handler */ 318609885543Smrg SR01 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01); 318709885543Smrg SR20 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20); 318809885543Smrg SR21 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 318909885543Smrg SR22 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22); 319009885543Smrg SR23 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23); 319109885543Smrg SR24 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24); 319209885543Smrg SR31 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31); 319309885543Smrg SR34 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x34); 319409885543Smrg 319509885543Smrg switch (PowerManagementMode) { 319609885543Smrg case DPMSModeOn: 319709885543Smrg /* Screen On: HSync: On, VSync : On */ 319809885543Smrg SR01 &= ~0x20; 319909885543Smrg SR20 = pSmi->DPMS_SR20; 320009885543Smrg SR21 = pSmi->DPMS_SR21; 320109885543Smrg SR22 &= ~0x30; 320209885543Smrg SR23 &= ~0xC0; 320309885543Smrg SR24 |= 0x01; 320409885543Smrg SR31 = pSmi->DPMS_SR31; 320509885543Smrg SR34 = pSmi->DPMS_SR34; 320609885543Smrg break; 320709885543Smrg case DPMSModeStandby: 320809885543Smrg /* Screen: Off; HSync: Off, VSync: On */ 320909885543Smrg SR01 |= 0x20; 321009885543Smrg SR20 = (SR20 & ~0xB0) | 0x10; 321109885543Smrg SR21 |= 0x88; 321209885543Smrg SR22 = (SR22 & ~0x30) | 0x10; 321309885543Smrg SR23 = (SR23 & ~0x07) | 0xD8; 321409885543Smrg SR24 &= ~0x01; 321509885543Smrg SR31 = (SR31 & ~0x07) | 0x00; 321609885543Smrg SR34 |= 0x80; 321709885543Smrg break; 321809885543Smrg case DPMSModeSuspend: 321909885543Smrg /* Screen: Off; HSync: On, VSync: Off */ 322009885543Smrg SR01 |= 0x20; 322109885543Smrg SR20 = (SR20 & ~0xB0) | 0x10; 322209885543Smrg SR21 |= 0x88; 322309885543Smrg SR22 = (SR22 & ~0x30) | 0x20; 322409885543Smrg SR23 = (SR23 & ~0x07) | 0xD8; 322509885543Smrg SR24 &= ~0x01; 322609885543Smrg SR31 = (SR31 & ~0x07) | 0x00; 322709885543Smrg SR34 |= 0x80; 322809885543Smrg break; 322909885543Smrg case DPMSModeOff: 323009885543Smrg /* Screen: Off; HSync: Off, VSync: Off */ 323109885543Smrg SR01 |= 0x20; 323209885543Smrg SR20 = (SR20 & ~0xB0) | 0x10; 323309885543Smrg SR21 |= 0x88; 323409885543Smrg SR22 = (SR22 & ~0x30) | 0x30; 323509885543Smrg SR23 = (SR23 & ~0x07) | 0xD8; 323609885543Smrg SR24 &= ~0x01; 323709885543Smrg SR31 = (SR31 & ~0x07) | 0x00; 323809885543Smrg SR34 |= 0x80; 323909885543Smrg break; 324009885543Smrg default: 324109885543Smrg xf86ErrorFVerb(VERBLEV, "Invalid PowerManagementMode %d passed to " 324209885543Smrg "SMI_DisplayPowerManagementSet\n", PowerManagementMode); 324309885543Smrg LEAVE_PROC("SMI_DisplayPowerManagementSet"); 324409885543Smrg return; 324509885543Smrg } 324609885543Smrg 324709885543Smrg /* Wait for vertical retrace */ 324809885543Smrg while (hwp->readST01(hwp) & 0x8) ; 324909885543Smrg while (!(hwp->readST01(hwp) & 0x8)) ; 325009885543Smrg 325109885543Smrg /* Write the registers */ 325209885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01, SR01); 325309885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x34, SR34); 325409885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, SR31); 325509885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20, SR20); 325609885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, SR22); 325709885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23, SR23); 325809885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, SR21); 325909885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24, SR24); 326009885543Smrg 326109885543Smrg /* Save the current power state */ 326209885543Smrg pSmi->CurrentDPMS = PowerManagementMode; 326309885543Smrg 326409885543Smrg LEAVE_PROC("SMI_DisplayPowerManagementSet"); 326509885543Smrg} 326609885543Smrg 326709885543Smrgstatic void 326809885543SmrgSMI_ProbeDDC(ScrnInfoPtr pScrn, int index) 326909885543Smrg{ 327009885543Smrg vbeInfoPtr pVbe; 327109885543Smrg if (xf86LoadSubModule(pScrn, "vbe")) { 327209885543Smrg pVbe = VBEInit(NULL, index); 327309885543Smrg ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 327409885543Smrg vbeFree(pVbe); 327509885543Smrg } 327609885543Smrg} 327709885543Smrg 327809885543Smrgstatic unsigned int 327909885543SmrgSMI_ddc1Read(ScrnInfoPtr pScrn) 328009885543Smrg{ 328109885543Smrg register vgaHWPtr hwp = VGAHWPTR(pScrn); 328209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 328309885543Smrg unsigned int ret; 328409885543Smrg 328509885543Smrg ENTER_PROC("SMI_ddc1Read"); 328609885543Smrg 328709885543Smrg while (hwp->readST01(hwp) & 0x8) ; 328809885543Smrg while (!(hwp->readST01(hwp) & 0x8)) ; 328909885543Smrg 329009885543Smrg ret = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72) & 0x08; 329109885543Smrg 329209885543Smrg LEAVE_PROC("SMI_ddc1Read"); 329309885543Smrg return ret; 329409885543Smrg} 329509885543Smrg 329609885543Smrgstatic Bool 329709885543SmrgSMI_ddc1(int scrnIndex) 329809885543Smrg{ 329909885543Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 330009885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 330109885543Smrg Bool success = FALSE; 330209885543Smrg xf86MonPtr pMon; 330309885543Smrg unsigned char tmp; 330409885543Smrg 330509885543Smrg ENTER_PROC("SMI_ddc1"); 330609885543Smrg 330709885543Smrg tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72); 330809885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72, tmp | 0x20); 330909885543Smrg 331009885543Smrg pMon = xf86PrintEDID(xf86DoEDID_DDC1(scrnIndex, 331109885543Smrg vgaHWddc1SetSpeedWeak(), 331209885543Smrg SMI_ddc1Read)); 331309885543Smrg if (pMon != NULL) { 331409885543Smrg success = TRUE; 331509885543Smrg } 331609885543Smrg xf86SetDDCproperties(pScrn, pMon); 331709885543Smrg 331809885543Smrg VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72, tmp); 331909885543Smrg 332009885543Smrg LEAVE_PROC("SMI_ddc1"); 332109885543Smrg return success; 332209885543Smrg} 332309885543Smrg 3324