smi_driver.c revision 7104f784
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 3009885543Smrg#ifdef HAVE_CONFIG_H 3109885543Smrg#include "config.h" 3209885543Smrg#endif 3309885543Smrg 3409885543Smrg#include "xf86Resources.h" 3509885543Smrg#include "xf86RAC.h" 3609885543Smrg#include "xf86DDC.h" 3709885543Smrg#include "xf86int10.h" 3809885543Smrg#include "vbe.h" 3909885543Smrg 4009885543Smrg#include "smi.h" 417104f784Smrg#include "smi_501.h" 427104f784Smrg#include "smilynx.h" 437104f784Smrg#include "smi_crtc.h" 4409885543Smrg 4509885543Smrg#include "globals.h" 4609885543Smrg#define DPMS_SERVER 4709885543Smrg#include <X11/extensions/dpms.h> 4809885543Smrg 4909885543Smrg/* 5009885543Smrg * Internals 5109885543Smrg */ 527104f784Smrgstatic Bool SMI_MapMmio(ScrnInfoPtr pScrn); 537104f784Smrgstatic Bool SMI_DetectMem(ScrnInfoPtr pScrn); 5409885543Smrgstatic void SMI_EnableMmio(ScrnInfoPtr pScrn); 5509885543Smrgstatic void SMI_DisableMmio(ScrnInfoPtr pScrn); 567104f784Smrgstatic Bool SMI_HWInit(ScrnInfoPtr pScrn); 5709885543Smrg 5809885543Smrg/* 5909885543Smrg * Forward definitions for the functions that make up the driver. 6009885543Smrg */ 6109885543Smrg 6209885543Smrgstatic const OptionInfoRec * SMI_AvailableOptions(int chipid, int busid); 6309885543Smrgstatic void SMI_Identify(int flags); 6409885543Smrgstatic Bool SMI_Probe(DriverPtr drv, int flags); 6509885543Smrgstatic Bool SMI_PreInit(ScrnInfoPtr pScrn, int flags); 6609885543Smrgstatic Bool SMI_EnterVT(int scrnIndex, int flags); 6709885543Smrgstatic void SMI_LeaveVT(int scrnIndex, int flags); 6809885543Smrgstatic Bool SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 6909885543Smrg char **argv); 7009885543Smrgstatic void SMI_DisableVideo(ScrnInfoPtr pScrn); 7109885543Smrgstatic void SMI_EnableVideo(ScrnInfoPtr pScrn); 7209885543Smrgstatic Bool SMI_CloseScreen(int scrnIndex, ScreenPtr pScreen); 7309885543Smrgstatic Bool SMI_SaveScreen(ScreenPtr pScreen, int mode); 7409885543Smrgstatic void SMI_FreeScreen(int ScrnIndex, int flags); 7509885543Smrgstatic void SMI_ProbeDDC(ScrnInfoPtr pScrn, int index); 7609885543Smrgstatic void SMI_DetectPanelSize(ScrnInfoPtr pScrn); 777104f784Smrgstatic void SMI_DetectMCLK(ScrnInfoPtr pScrn); 7809885543Smrg 797104f784Smrg/* 807104f784Smrg * xf86VDrvMsgVerb prints up to 14 characters prefix, where prefix has the 817104f784Smrg * format "%s(%d): " so, use name "SMI" instead of "Silicon Motion" 827104f784Smrg */ 837104f784Smrg#define SILICONMOTION_NAME "SMI" 8409885543Smrg#define SILICONMOTION_DRIVER_NAME "siliconmotion" 857104f784Smrg#define SILICONMOTION_VERSION_NAME PACKAGE_VERSION 867104f784Smrg#define SILICONMOTION_VERSION_MAJOR PACKAGE_VERSION_MAJOR 877104f784Smrg#define SILICONMOTION_VERSION_MINOR PACKAGE_VERSION_MINOR 887104f784Smrg#define SILICONMOTION_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 8909885543Smrg#define SILICONMOTION_DRIVER_VERSION ((SILICONMOTION_VERSION_MAJOR << 24) | \ 9009885543Smrg (SILICONMOTION_VERSION_MINOR << 16) | \ 9109885543Smrg (SILICONMOTION_PATCHLEVEL)) 9209885543Smrg 937104f784Smrg#if SMI_DEBUG 947104f784Smrgint smi_indent = 1; 957104f784Smrg#endif 967104f784Smrg 977104f784Smrg/* for dualhead */ 987104f784Smrgint gSMIEntityIndex = -1; 997104f784Smrg 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" }, 1297104f784Smrg { PCI_CHIP_SMI501, "MSOC" }, 13009885543Smrg { -1, NULL } 13109885543Smrg}; 13209885543Smrg 13309885543Smrgstatic PciChipsets SMIPciChipsets[] = 13409885543Smrg{ 1357104f784Smrg /* numChipset, PciID, Resource */ 13609885543Smrg { PCI_CHIP_SMI910, PCI_CHIP_SMI910, RES_SHARED_VGA }, 13709885543Smrg { PCI_CHIP_SMI810, PCI_CHIP_SMI810, RES_SHARED_VGA }, 13809885543Smrg { PCI_CHIP_SMI820, PCI_CHIP_SMI820, RES_SHARED_VGA }, 13909885543Smrg { PCI_CHIP_SMI710, PCI_CHIP_SMI710, RES_SHARED_VGA }, 14009885543Smrg { PCI_CHIP_SMI712, PCI_CHIP_SMI712, RES_SHARED_VGA }, 14109885543Smrg { PCI_CHIP_SMI720, PCI_CHIP_SMI720, RES_SHARED_VGA }, 14209885543Smrg { PCI_CHIP_SMI731, PCI_CHIP_SMI731, RES_SHARED_VGA }, 1437104f784Smrg { PCI_CHIP_SMI501, PCI_CHIP_SMI501, RES_UNDEFINED }, 1447104f784Smrg { -1, -1, RES_UNDEFINED } 14509885543Smrg}; 14609885543Smrg 14709885543Smrgtypedef enum 14809885543Smrg{ 14909885543Smrg OPTION_PCI_BURST, 15009885543Smrg OPTION_PCI_RETRY, 15109885543Smrg OPTION_NOACCEL, 15209885543Smrg OPTION_MCLK, 1537104f784Smrg OPTION_MXCLK, 15409885543Smrg OPTION_SWCURSOR, 15509885543Smrg OPTION_HWCURSOR, 15609885543Smrg OPTION_VIDEOKEY, 15709885543Smrg OPTION_BYTESWAP, 15809885543Smrg /* CZ 26.10.2001: interlaced video */ 15909885543Smrg OPTION_INTERLACED, 16009885543Smrg /* end CZ */ 16109885543Smrg OPTION_USEBIOS, 16209885543Smrg OPTION_DUALHEAD, 16309885543Smrg OPTION_ACCELMETHOD, 1647104f784Smrg OPTION_PANEL_SIZE, 1657104f784Smrg OPTION_USE_FBDEV, 1667104f784Smrg OPTION_CSCVIDEO, 16709885543Smrg NUMBER_OF_OPTIONS 16809885543Smrg} SMIOpts; 16909885543Smrg 17009885543Smrgstatic const OptionInfoRec SMIOptions[] = 17109885543Smrg{ 1727104f784Smrg { OPTION_PCI_BURST, "pci_burst", OPTV_BOOLEAN, {0}, TRUE }, 1737104f784Smrg { OPTION_PCI_RETRY, "pci_retry", OPTV_BOOLEAN, {0}, TRUE }, 17409885543Smrg { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 1757104f784Smrg { OPTION_MCLK, "MCLK", OPTV_FREQ, {0}, FALSE }, 1767104f784Smrg { OPTION_MXCLK, "MXCLK", OPTV_FREQ, {0}, FALSE }, 1777104f784Smrg { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, TRUE }, 17809885543Smrg { OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE }, 17909885543Smrg { OPTION_VIDEOKEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, 18009885543Smrg { OPTION_BYTESWAP, "ByteSwap", OPTV_BOOLEAN, {0}, FALSE }, 18109885543Smrg /* CZ 26.10.2001: interlaced video */ 1827104f784Smrg { OPTION_INTERLACED, "Interlaced", OPTV_BOOLEAN, {0}, FALSE }, 18309885543Smrg /* end CZ */ 18409885543Smrg { OPTION_USEBIOS, "UseBIOS", OPTV_BOOLEAN, {0}, FALSE }, 1857104f784Smrg { OPTION_DUALHEAD, "Dualhead", OPTV_BOOLEAN, {0}, TRUE }, 18609885543Smrg { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, 1877104f784Smrg { OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE }, 1887104f784Smrg { OPTION_USE_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, 1897104f784Smrg { OPTION_CSCVIDEO, "CSCVideo", OPTV_BOOLEAN, {0}, TRUE }, 19009885543Smrg { -1, NULL, OPTV_NONE, {0}, FALSE } 19109885543Smrg}; 19209885543Smrg 19309885543Smrg/* 19409885543Smrg * Lists of symbols that may/may not be required by this driver. 19509885543Smrg * This allows the loader to know which ones to issue warnings for. 19609885543Smrg * 19709885543Smrg * Note that vgahwSymbols and xaaSymbols are referenced outside the 19809885543Smrg * XFree86LOADER define in later code, so are defined outside of that 19909885543Smrg * define here also. 20009885543Smrg */ 20109885543Smrg 20209885543Smrgstatic const char *vgahwSymbols[] = 20309885543Smrg{ 20409885543Smrg "vgaHWCopyReg", 20509885543Smrg "vgaHWGetHWRec", 20609885543Smrg "vgaHWGetIOBase", 20709885543Smrg "vgaHWGetIndex", 20809885543Smrg "vgaHWInit", 20909885543Smrg "vgaHWLock", 21009885543Smrg "vgaHWMapMem", 21109885543Smrg "vgaHWProtect", 21209885543Smrg "vgaHWRestore", 21309885543Smrg "vgaHWSave", 21409885543Smrg "vgaHWSaveScreen", 21509885543Smrg "vgaHWSetMmioFuncs", 21609885543Smrg "vgaHWSetStdFuncs", 21709885543Smrg "vgaHWUnmapMem", 21809885543Smrg "vgaHWddc1SetSpeedWeak", 21909885543Smrg NULL 22009885543Smrg}; 22109885543Smrg 22209885543Smrgstatic const char *xaaSymbols[] = 22309885543Smrg{ 22409885543Smrg "XAAGetCopyROP", 22509885543Smrg "XAACreateInfoRec", 22609885543Smrg "XAADestroyInfoRec", 22709885543Smrg "XAAGetFallbackOps", 22809885543Smrg "XAAInit", 22909885543Smrg "XAAGetPatternROP", 23009885543Smrg NULL 23109885543Smrg}; 23209885543Smrg 23309885543Smrgstatic const char *exaSymbols[] = 23409885543Smrg{ 23509885543Smrg "exaDriverAlloc", 23609885543Smrg "exaDriverInit", 23709885543Smrg "exaDriverFini", 23809885543Smrg "exaOffscreenAlloc", 23909885543Smrg "exaOffscreenFree", 24009885543Smrg "exaGetPixmapPitch", 24109885543Smrg "exaGetPixmapOffset", 24209885543Smrg "exaGetPixmapSize", 24309885543Smrg NULL 24409885543Smrg}; 24509885543Smrg 24609885543Smrgstatic const char *ddcSymbols[] = 24709885543Smrg{ 24809885543Smrg "xf86PrintEDID", 24909885543Smrg "xf86DoEDID_DDC1", 25009885543Smrg "xf86DoEDID_DDC2", 25109885543Smrg "xf86SetDDCproperties", 25209885543Smrg NULL 25309885543Smrg}; 25409885543Smrg 25509885543Smrgstatic const char *i2cSymbols[] = 25609885543Smrg{ 25709885543Smrg "xf86CreateI2CBusRec", 25809885543Smrg "xf86CreateI2CDevRec", 25909885543Smrg "xf86DestroyI2CBusRec", 26009885543Smrg "xf86DestroyI2CDevRec", 26109885543Smrg "xf86I2CBusInit", 26209885543Smrg "xf86I2CDevInit", 26309885543Smrg "xf86I2CReadBytes", 26409885543Smrg "xf86I2CWriteByte", 26509885543Smrg NULL 26609885543Smrg}; 26709885543Smrg 26809885543Smrgstatic const char *int10Symbols[] = 26909885543Smrg{ 27009885543Smrg "xf86ExecX86int10", 27109885543Smrg "xf86FreeInt10", 27209885543Smrg "xf86InitInt10", 27309885543Smrg NULL 27409885543Smrg}; 27509885543Smrg 27609885543Smrgstatic const char *vbeSymbols[] = 27709885543Smrg{ 27809885543Smrg "VBEInit", 27909885543Smrg "vbeDoEDID", 28009885543Smrg "vbeFree", 28109885543Smrg NULL 28209885543Smrg}; 28309885543Smrg 28409885543Smrgstatic const char *fbSymbols[] = 28509885543Smrg{ 28609885543Smrg "fbPictureInit", 28709885543Smrg "fbScreenInit", 28809885543Smrg NULL 28909885543Smrg}; 29009885543Smrg 29109885543Smrg#ifdef XFree86LOADER 29209885543Smrg 29309885543Smrgstatic MODULESETUPPROTO(siliconmotionSetup); 29409885543Smrg 29509885543Smrgstatic XF86ModuleVersionInfo SMIVersRec = 29609885543Smrg{ 29709885543Smrg "siliconmotion", 29809885543Smrg MODULEVENDORSTRING, 29909885543Smrg MODINFOSTRING1, 30009885543Smrg MODINFOSTRING2, 30109885543Smrg XORG_VERSION_CURRENT, 30209885543Smrg SILICONMOTION_VERSION_MAJOR, 30309885543Smrg SILICONMOTION_VERSION_MINOR, 30409885543Smrg SILICONMOTION_PATCHLEVEL, 30509885543Smrg ABI_CLASS_VIDEODRV, 30609885543Smrg ABI_VIDEODRV_VERSION, 30709885543Smrg MOD_CLASS_VIDEODRV, 30809885543Smrg {0, 0, 0, 0} 30909885543Smrg}; 31009885543Smrg 31109885543Smrg/* 31209885543Smrg * This is the module init data for XFree86 modules. 31309885543Smrg * 31409885543Smrg * Its name has to be the driver name followed by ModuleData. 31509885543Smrg */ 31609885543Smrg_X_EXPORT XF86ModuleData siliconmotionModuleData = 31709885543Smrg{ 31809885543Smrg &SMIVersRec, 31909885543Smrg siliconmotionSetup, 32009885543Smrg NULL 32109885543Smrg}; 32209885543Smrg 32309885543Smrgstatic pointer 32409885543SmrgsiliconmotionSetup(pointer module, pointer opts, int *errmaj, int *errmin) 32509885543Smrg{ 32609885543Smrg static Bool setupDone = FALSE; 32709885543Smrg 32809885543Smrg if (!setupDone) { 32909885543Smrg setupDone = TRUE; 33009885543Smrg xf86AddDriver(&SILICONMOTION, module, 0); 33109885543Smrg 33209885543Smrg /* 33309885543Smrg * Modules that this driver always requires can be loaded here 33409885543Smrg * by calling LoadSubModule(). 33509885543Smrg */ 33609885543Smrg 33709885543Smrg /* 33809885543Smrg * Tell the loader about symbols from other modules that this module 33909885543Smrg * might refer to. 34009885543Smrg */ 3417104f784Smrg LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols, exaSymbols, 34209885543Smrg ddcSymbols, i2cSymbols, int10Symbols, vbeSymbols, 3437104f784Smrg NULL); 34409885543Smrg 34509885543Smrg /* 34609885543Smrg * The return value must be non-NULL on success even though there 34709885543Smrg * is no TearDownProc. 34809885543Smrg */ 34909885543Smrg return (pointer) 1; 35009885543Smrg 35109885543Smrg } else { 35209885543Smrg if (errmaj) { 35309885543Smrg *errmaj = LDR_ONCEONLY; 35409885543Smrg } 35509885543Smrg return NULL; 35609885543Smrg } 35709885543Smrg} 35809885543Smrg 35909885543Smrg#endif /* XFree86LOADER */ 36009885543Smrg 36109885543Smrgstatic Bool 36209885543SmrgSMI_GetRec(ScrnInfoPtr pScrn) 36309885543Smrg{ 3647104f784Smrg ENTER(); 36509885543Smrg 36609885543Smrg /* 36709885543Smrg * Allocate an 'Chip'Rec, and hook it into pScrn->driverPrivate. 36809885543Smrg * pScrn->driverPrivate is initialised to NULL, so we can check if 36909885543Smrg * the allocation has already been done. 37009885543Smrg */ 37109885543Smrg if (pScrn->driverPrivate == NULL) { 37209885543Smrg pScrn->driverPrivate = xnfcalloc(sizeof(SMIRec), 1); 37309885543Smrg } 37409885543Smrg 3757104f784Smrg LEAVE(TRUE); 37609885543Smrg} 37709885543Smrg 37809885543Smrgstatic void 37909885543SmrgSMI_FreeRec(ScrnInfoPtr pScrn) 38009885543Smrg{ 3817104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 38209885543Smrg 3837104f784Smrg ENTER(); 3847104f784Smrg 3857104f784Smrg if (pSmi) { 3867104f784Smrg xfree(pSmi->save); 3877104f784Smrg xfree(pSmi->mode); 38809885543Smrg xfree(pScrn->driverPrivate); 38909885543Smrg pScrn->driverPrivate = NULL; 39009885543Smrg } 39109885543Smrg 3927104f784Smrg LEAVE(); 39309885543Smrg} 39409885543Smrg 39509885543Smrgstatic const OptionInfoRec * 39609885543SmrgSMI_AvailableOptions(int chipid, int busid) 39709885543Smrg{ 3987104f784Smrg ENTER(); 3997104f784Smrg 4007104f784Smrg LEAVE(SMIOptions); 40109885543Smrg} 40209885543Smrg 40309885543Smrgstatic void 40409885543SmrgSMI_Identify(int flags) 40509885543Smrg{ 4067104f784Smrg ENTER(); 40709885543Smrg 40809885543Smrg xf86PrintChipsets(SILICONMOTION_NAME, "driver (version " 40909885543Smrg SILICONMOTION_VERSION_NAME ") for Silicon Motion Lynx chipsets", 41009885543Smrg SMIChipsets); 41109885543Smrg 4127104f784Smrg LEAVE(); 41309885543Smrg} 41409885543Smrg 41509885543Smrgstatic Bool 41609885543SmrgSMI_Probe(DriverPtr drv, int flags) 41709885543Smrg{ 41809885543Smrg int i; 41909885543Smrg GDevPtr *devSections; 42009885543Smrg int *usedChips; 42109885543Smrg int numDevSections; 42209885543Smrg int numUsed; 42309885543Smrg Bool foundScreen = FALSE; 42409885543Smrg 4257104f784Smrg ENTER(); 42609885543Smrg 42709885543Smrg numDevSections = xf86MatchDevice(SILICONMOTION_DRIVER_NAME, &devSections); 42809885543Smrg 4297104f784Smrg if (numDevSections <= 0) 43009885543Smrg /* There's no matching device section in the config file, so quit now. */ 4317104f784Smrg LEAVE(FALSE); 43209885543Smrg 4337104f784Smrg#ifndef XSERVER_LIBPCIACCESS 4347104f784Smrg if (xf86GetPciVideoInfo() == NULL) 4357104f784Smrg LEAVE(FALSE); 4367104f784Smrg#endif 43709885543Smrg 43809885543Smrg numUsed = xf86MatchPciInstances(SILICONMOTION_NAME, PCI_SMI_VENDOR_ID, 43909885543Smrg SMIChipsets, SMIPciChipsets, devSections, 44009885543Smrg numDevSections, drv, &usedChips); 44109885543Smrg 44209885543Smrg /* Free it since we don't need that list after this */ 44309885543Smrg xfree(devSections); 4447104f784Smrg if (numUsed <= 0) 4457104f784Smrg LEAVE(FALSE); 4467104f784Smrg 4477104f784Smrg if (flags & PROBE_DETECT) 4487104f784Smrg foundScreen = TRUE; 4497104f784Smrg else { 4507104f784Smrg ScrnInfoPtr pScrn; 4517104f784Smrg EntityInfoPtr pEnt; 45209885543Smrg 45309885543Smrg for (i = 0; i < numUsed; i++) { 4547104f784Smrg if ((pScrn = xf86ConfigPciEntity(NULL, 0, usedChips[i], 4557104f784Smrg SMIPciChipsets, NULL, 4567104f784Smrg NULL, NULL, NULL, NULL))) { 4577104f784Smrg pScrn->driverVersion = SILICONMOTION_DRIVER_VERSION; 4587104f784Smrg pScrn->driverName = SILICONMOTION_DRIVER_NAME; 4597104f784Smrg pScrn->name = SILICONMOTION_NAME; 4607104f784Smrg pScrn->Probe = SMI_Probe; 4617104f784Smrg pScrn->PreInit = SMI_PreInit; 4627104f784Smrg pScrn->ScreenInit = SMI_ScreenInit; 4637104f784Smrg pScrn->SwitchMode = SMI_SwitchMode; 4647104f784Smrg pScrn->AdjustFrame = SMI_AdjustFrame; 4657104f784Smrg 4667104f784Smrg if ((pEnt = xf86GetEntityInfo(usedChips[i]))) { 4677104f784Smrg pScrn->EnterVT = SMI_EnterVT; 4687104f784Smrg pScrn->LeaveVT = SMI_LeaveVT; 4697104f784Smrg xfree(pEnt); 4707104f784Smrg } 4717104f784Smrg pScrn->FreeScreen = SMI_FreeScreen; 4727104f784Smrg foundScreen = TRUE; 4737104f784Smrg } 47409885543Smrg } 47509885543Smrg } 47609885543Smrg xfree(usedChips); 47709885543Smrg 4787104f784Smrg LEAVE(foundScreen); 47909885543Smrg} 48009885543Smrg 48109885543Smrgstatic Bool 48209885543SmrgSMI_PreInit(ScrnInfoPtr pScrn, int flags) 48309885543Smrg{ 48409885543Smrg EntityInfoPtr pEnt; 48509885543Smrg SMIPtr pSmi; 48609885543Smrg MessageType from; 48709885543Smrg vgaHWPtr hwp; 48809885543Smrg 4897104f784Smrg ENTER(); 49009885543Smrg 49109885543Smrg /* Ignoring the Type list for now. It might be needed when multiple cards 49209885543Smrg * are supported. 49309885543Smrg */ 4947104f784Smrg if (pScrn->numEntities > 1) 4957104f784Smrg LEAVE(FALSE); 49609885543Smrg 4977104f784Smrg /* Allocate the SMIRec driverPrivate */ 4987104f784Smrg if (!SMI_GetRec(pScrn)) 4997104f784Smrg LEAVE(FALSE); 5007104f784Smrg pSmi = SMIPTR(pScrn); 50109885543Smrg 5027104f784Smrg /* Find the PCI slot for this screen */ 5037104f784Smrg pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 50409885543Smrg 5057104f784Smrg pSmi->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 5067104f784Smrg pSmi->Chipset = PCI_DEV_DEVICE_ID(pSmi->PciInfo); 5077104f784Smrg 5087104f784Smrg if (IS_MSOC(pSmi)) { 5097104f784Smrg pSmi->Save = SMI501_Save; 5107104f784Smrg pSmi->save = xnfcalloc(sizeof(MSOCRegRec), 1); 5117104f784Smrg pSmi->mode = xnfcalloc(sizeof(MSOCRegRec), 1); 5127104f784Smrg } 5137104f784Smrg else { 5147104f784Smrg pSmi->Save = SMILynx_Save; 5157104f784Smrg pSmi->save = xnfcalloc(sizeof(SMIRegRec), 1); 5167104f784Smrg pSmi->mode = xnfcalloc(sizeof(SMIRegRec), 1); 51709885543Smrg } 51809885543Smrg 5197104f784Smrg if (flags & PROBE_DETECT) { 5207104f784Smrg if (!IS_MSOC(pSmi)) 5217104f784Smrg SMI_ProbeDDC(pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index); 5227104f784Smrg LEAVE(TRUE); 52309885543Smrg } 5247104f784Smrg 5257104f784Smrg if (pEnt->location.type != BUS_PCI || pEnt->resources) { 5267104f784Smrg xfree(pEnt); 5277104f784Smrg SMI_FreeRec(pScrn); 5287104f784Smrg LEAVE(FALSE); 5297104f784Smrg } 5307104f784Smrg pSmi->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 53109885543Smrg 53209885543Smrg /* Set pScrn->monitor */ 53309885543Smrg pScrn->monitor = pScrn->confScreen->monitor; 53409885543Smrg 5357104f784Smrg if (!IS_MSOC(pSmi)) { 5367104f784Smrg /* The vgahw module should be loaded here when needed */ 5377104f784Smrg if (!xf86LoadSubModule(pScrn, "vgahw")) 5387104f784Smrg LEAVE(FALSE); 5397104f784Smrg 5407104f784Smrg xf86LoaderReqSymLists(vgahwSymbols, NULL); 5417104f784Smrg 5427104f784Smrg /* 5437104f784Smrg * Allocate a vgaHWRec 5447104f784Smrg */ 5457104f784Smrg if (!vgaHWGetHWRec(pScrn)) 5467104f784Smrg LEAVE(FALSE); 5477104f784Smrg 5487104f784Smrg hwp = VGAHWPTR(pScrn); 5497104f784Smrg pSmi->PIOBase = hwp->PIOOffset; 5507104f784Smrg 5517104f784Smrg xf86ErrorFVerb(VERBLEV, "\tSMI_PreInit vgaCRIndex=%x, vgaIOBase=%x, " 5527104f784Smrg "MMIOBase=%p\n", hwp->IOBase + VGA_CRTC_INDEX_OFFSET, 5537104f784Smrg hwp->IOBase, hwp->MMIOBase); 5547104f784Smrg } 5557104f784Smrg 55609885543Smrg /* 55709885543Smrg * The first thing we should figure out is the depth, bpp, etc. 55809885543Smrg */ 5597104f784Smrg if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) 5607104f784Smrg LEAVE(FALSE); 56109885543Smrg 56209885543Smrg /* Check that the returned depth is one we support */ 5637104f784Smrg if (pScrn->depth != 8 && pScrn->depth != 16 && pScrn->depth != 24) { 56409885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 56509885543Smrg "Given depth (%d) is not supported by this driver\n", 56609885543Smrg pScrn->depth); 5677104f784Smrg LEAVE(FALSE); 5687104f784Smrg } 5697104f784Smrg 5707104f784Smrg 5717104f784Smrg if(pScrn->bitsPerPixel != 8 && pScrn->bitsPerPixel != 16 && 5727104f784Smrg pScrn->bitsPerPixel != 24 && pScrn->bitsPerPixel != 32){ 5737104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 5747104f784Smrg "Given bpp (%d) is not supported by this driver\n", 5757104f784Smrg pScrn->bitsPerPixel); 5767104f784Smrg LEAVE(FALSE); 57709885543Smrg } 57809885543Smrg 57909885543Smrg xf86PrintDepthBpp(pScrn); 58009885543Smrg 58109885543Smrg /* 58209885543Smrg * This must happen after pScrn->display has been set because 58309885543Smrg * xf86SetWeight references it. 58409885543Smrg */ 58509885543Smrg if (pScrn->depth > 8) { 58609885543Smrg /* The defaults are OK for us */ 58709885543Smrg rgb zeros = {0, 0, 0}; 5887104f784Smrg#if __BYTE_ORDER == __BIG_ENDIAN 5897104f784Smrg rgb masks = {0xff00,0xff0000,0xff000000}; 5907104f784Smrg#else 5917104f784Smrg rgb masks = {0, 0, 0}; 5927104f784Smrg#endif 59309885543Smrg 5947104f784Smrg if (!xf86SetWeight(pScrn, zeros, masks)) 5957104f784Smrg LEAVE(FALSE); 59609885543Smrg } 59709885543Smrg 5987104f784Smrg if (!xf86SetDefaultVisual(pScrn, -1)) 5997104f784Smrg LEAVE(FALSE); 60009885543Smrg 60109885543Smrg /* We don't currently support DirectColor at > 8bpp */ 6027104f784Smrg 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); 6067104f784Smrg LEAVE(FALSE); 60709885543Smrg } 60809885543Smrg 60909885543Smrg /* We use a programmable clock */ 61009885543Smrg pScrn->progClock = TRUE; 61109885543Smrg 61209885543Smrg /* Collect all of the relevant option flags (fill in pScrn->options) */ 61309885543Smrg xf86CollectOptions(pScrn, NULL); 61409885543Smrg 61509885543Smrg /* Set the bits per RGB for 8bpp mode */ 6167104f784Smrg if (pScrn->depth == 8){ 6177104f784Smrg pScrn->rgbBits = IS_MSOC(pSmi) ? 8 : 6; 6187104f784Smrg }else if(pScrn->depth == 16){ 6197104f784Smrg /* Use 8 bit LUT for gamma correction*/ 6207104f784Smrg pScrn->rgbBits = 8; 62109885543Smrg } 62209885543Smrg 62309885543Smrg /* Process the options */ 62409885543Smrg if (!(pSmi->Options = xalloc(sizeof(SMIOptions)))) 6257104f784Smrg LEAVE(FALSE); 6267104f784Smrg 62709885543Smrg memcpy(pSmi->Options, SMIOptions, sizeof(SMIOptions)); 62809885543Smrg xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pSmi->Options); 62909885543Smrg 6307104f784Smrg /* Enable pci burst by default */ 6317104f784Smrg from = X_DEFAULT; 6327104f784Smrg pSmi->PCIBurst = TRUE; 6337104f784Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_PCI_BURST, &pSmi->PCIBurst)) 6347104f784Smrg from = X_CONFIG; 6357104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "PCI Burst %sabled\n", 6367104f784Smrg pSmi->PCIBurst ? "en" : "dis"); 63709885543Smrg 6387104f784Smrg /* Pci retry enabled by default if pci burst also enabled */ 6397104f784Smrg from = X_DEFAULT; 6407104f784Smrg pSmi->PCIRetry = pSmi->PCIBurst ? TRUE : FALSE; 6417104f784Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_PCI_RETRY, &pSmi->PCIRetry)) { 6427104f784Smrg from = X_CONFIG; 6437104f784Smrg if (pSmi->PCIRetry && !pSmi->PCIBurst) { 6447104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 6457104f784Smrg "\"pci_retry\" option requires \"pci_burst\".\n"); 6467104f784Smrg pSmi->PCIRetry = FALSE; 64709885543Smrg } 64809885543Smrg } 6497104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "PCI Retry %sabled\n", 6507104f784Smrg pSmi->PCIRetry ? "en" : "dis"); 65109885543Smrg 65209885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_NOACCEL, FALSE)) { 65309885543Smrg pSmi->NoAccel = TRUE; 65409885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - Acceleration " 65509885543Smrg "disabled\n"); 65609885543Smrg } else { 65709885543Smrg pSmi->NoAccel = FALSE; 65809885543Smrg } 65909885543Smrg 6607104f784Smrg if (IS_MSOC(pSmi)) { 6617104f784Smrg from = X_DEFAULT; 6627104f784Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_USE_FBDEV, &pSmi->UseFBDev)) 6637104f784Smrg from = X_CONFIG; 6647104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "UseFBDev %s.\n", 6657104f784Smrg pSmi->UseFBDev ? "enabled" : "disabled"); 6667104f784Smrg } 6677104f784Smrg 6687104f784Smrg from = X_CONFIG; 6697104f784Smrg pSmi->HwCursor = TRUE; 6707104f784Smrg /* SWCursor overrides HWCusor if both specified */ 6717104f784Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_SWCURSOR, FALSE)) 6727104f784Smrg pSmi->HwCursor = FALSE; 6737104f784Smrg else if (!xf86GetOptValBool(pSmi->Options, OPTION_HWCURSOR, &pSmi->HwCursor)) 6747104f784Smrg from = X_DEFAULT; 67509885543Smrg 6767104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Using %sware Cursor\n", 6777104f784Smrg pSmi->HwCursor ? "Hard" : "Soft"); 67809885543Smrg 67909885543Smrg if (xf86GetOptValInteger(pSmi->Options, OPTION_VIDEOKEY, &pSmi->videoKey)) { 68009885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Video key set to " 68109885543Smrg "0x%08X\n", pSmi->videoKey); 68209885543Smrg } else { 68309885543Smrg pSmi->videoKey = (1 << pScrn->offset.red) | 68409885543Smrg (1 << pScrn->offset.green) | 68509885543Smrg (((pScrn->mask.blue >> pScrn->offset.blue) - 1) 68609885543Smrg << pScrn->offset.blue); 68709885543Smrg } 68809885543Smrg 68909885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_BYTESWAP, FALSE)) { 69009885543Smrg pSmi->ByteSwap = TRUE; 69109885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: ByteSwap enabled.\n"); 69209885543Smrg } else { 69309885543Smrg pSmi->ByteSwap = FALSE; 69409885543Smrg } 69509885543Smrg 69609885543Smrg /* CZ 26.10.2001: interlaced video */ 69709885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_INTERLACED, FALSE)) { 69809885543Smrg pSmi->interlaced = TRUE; 69909885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Interlaced enabled.\n"); 70009885543Smrg } else { 70109885543Smrg pSmi->interlaced = FALSE; 70209885543Smrg } 70309885543Smrg /* end CZ */ 70409885543Smrg 7057104f784Smrg if (IS_MSOC(pSmi)) 7067104f784Smrg pSmi->useBIOS = FALSE; 7077104f784Smrg else if (xf86GetOptValBool(pSmi->Options, OPTION_USEBIOS, &pSmi->useBIOS)) { 70809885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: UseBIOS %s.\n", 70909885543Smrg pSmi->useBIOS ? "enabled" : "disabled"); 7107104f784Smrg } 7117104f784Smrg else if(pSmi->Chipset == SMI_LYNX3DM){ 7127104f784Smrg /* Default to UseBIOS disabled. */ 7137104f784Smrg pSmi->useBIOS = FALSE; 7147104f784Smrg } 7157104f784Smrg else { 71609885543Smrg /* Default to UseBIOS enabled. */ 71709885543Smrg pSmi->useBIOS = TRUE; 71809885543Smrg } 71909885543Smrg 7207104f784Smrg if (pSmi->useBIOS) { 7217104f784Smrg if (xf86LoadSubModule(pScrn,"int10")) { 7227104f784Smrg xf86LoaderReqSymLists(int10Symbols,NULL); 7237104f784Smrg pSmi->pInt10 = xf86InitInt10(pEnt->index); 7247104f784Smrg } 72509885543Smrg 7267104f784Smrg if (pSmi->pInt10 && xf86LoadSubModule(pScrn, "vbe")) { 7277104f784Smrg xf86LoaderReqSymLists(vbeSymbols, NULL); 7287104f784Smrg pSmi->pVbe = VBEInit(pSmi->pInt10, pEnt->index); 7297104f784Smrg } 73009885543Smrg 7317104f784Smrg if(!pSmi->pVbe){ 7327104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VBE initialization failed: falling back to UseBIOS disabled.\n"); 7337104f784Smrg pSmi->useBIOS = FALSE; 7347104f784Smrg } 73509885543Smrg } 73609885543Smrg 73709885543Smrg xf86RegisterResources(pEnt->index, NULL, ResExclusive); 73809885543Smrg/* xf86SetOperatingState(resVgaIo, pEnt->index, ResUnusedOpr); */ 73909885543Smrg/* xf86SetOperatingState(resVgaMem, pEnt->index, ResDisableOpr); */ 74009885543Smrg 74109885543Smrg /* 74209885543Smrg * Set the Chipset and ChipRev, allowing config file entries to 74309885543Smrg * override. 74409885543Smrg */ 74509885543Smrg if (pEnt->device->chipset && *pEnt->device->chipset) { 74609885543Smrg pScrn->chipset = pEnt->device->chipset; 74709885543Smrg pSmi->Chipset = xf86StringToToken(SMIChipsets, pScrn->chipset); 74809885543Smrg from = X_CONFIG; 7497104f784Smrg } 7507104f784Smrg else if (pEnt->device->chipID >= 0) { 75109885543Smrg pSmi->Chipset = pEnt->device->chipID; 75209885543Smrg pScrn->chipset = (char *) xf86TokenToString(SMIChipsets, pSmi->Chipset); 75309885543Smrg from = X_CONFIG; 75409885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 75509885543Smrg pSmi->Chipset); 7567104f784Smrg } 7577104f784Smrg else { 75809885543Smrg from = X_PROBED; 7597104f784Smrg pSmi->Chipset = PCI_DEV_DEVICE_ID(pSmi->PciInfo); 76009885543Smrg pScrn->chipset = (char *) xf86TokenToString(SMIChipsets, pSmi->Chipset); 76109885543Smrg } 76209885543Smrg 76309885543Smrg if (pEnt->device->chipRev >= 0) { 76409885543Smrg pSmi->ChipRev = pEnt->device->chipRev; 76509885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 76609885543Smrg pSmi->ChipRev); 76709885543Smrg } 7687104f784Smrg else 7697104f784Smrg pSmi->ChipRev = PCI_DEV_REVISION(pSmi->PciInfo); 77009885543Smrg xfree(pEnt); 77109885543Smrg 77209885543Smrg /* 77309885543Smrg * This shouldn't happen because such problems should be caught in 77409885543Smrg * SMI_Probe(), but check it just in case. 77509885543Smrg */ 77609885543Smrg if (pScrn->chipset == NULL) { 77709885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04X is not " 77809885543Smrg "recognised\n", pSmi->Chipset); 7797104f784Smrg LEAVE(FALSE); 78009885543Smrg } 78109885543Smrg 78209885543Smrg if (pSmi->Chipset < 0) { 78309885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Chipset \"%s\" is not " 78409885543Smrg "recognised\n", pScrn->chipset); 7857104f784Smrg LEAVE(FALSE); 78609885543Smrg } 78709885543Smrg 78809885543Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); 78909885543Smrg 7907104f784Smrg#ifndef XSERVER_LIBPCIACCESS 79109885543Smrg pSmi->PciTag = pciTag(pSmi->PciInfo->bus, pSmi->PciInfo->device, 79209885543Smrg pSmi->PciInfo->func); 7937104f784Smrg#endif 79409885543Smrg 7957104f784Smrg from = X_DEFAULT; 7967104f784Smrg if(pSmi->Chipset == SMI_LYNX3DM && 7977104f784Smrg pScrn->bitsPerPixel == 16) 79809885543Smrg pSmi->Dualhead = TRUE; 7997104f784Smrg else 8007104f784Smrg pSmi->Dualhead = FALSE; 8017104f784Smrg 8027104f784Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_DUALHEAD, &pSmi->Dualhead)) 8037104f784Smrg from = X_CONFIG; 8047104f784Smrg 8057104f784Smrg if (IS_MSOC(pSmi)) { 8067104f784Smrg pSmi->lcd = TRUE; 8077104f784Smrg if (pSmi->Dualhead && pSmi->UseFBDev) { 8087104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 8097104f784Smrg "Dual head disabled in fbdev mode\n"); 8107104f784Smrg pSmi->Dualhead = FALSE; 8117104f784Smrg } 8127104f784Smrg /* FIXME Randr cursor code only works properly when argb cursors 8137104f784Smrg * are also supported. 8147104f784Smrg * FIXME This probably is a randr cursor bug, and since access to 8157104f784Smrg * hw/xfree86/ramdac/xf86CursorPriv.h:xf86CursorScreenRec.SWCursor 8167104f784Smrg * field is not available, one cannot easily workaround the problem, 8177104f784Smrg * so, just disable it... 8187104f784Smrg * TODO Check with a X Server newer then 1.4.0.90 (that is being 8197104f784Smrg * used in the 502 OEM image). 8207104f784Smrg * */ 8217104f784Smrg if (pSmi->Dualhead && pSmi->HwCursor) { 8227104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 8237104f784Smrg "HW Cursor disabled in dual head mode\n"); 8247104f784Smrg pSmi->HwCursor = FALSE; 8257104f784Smrg } 8267104f784Smrg } 8277104f784Smrg else if (SMI_LYNXM_SERIES(pSmi->Chipset)) { 8287104f784Smrg /* tweak options for dualhead */ 8297104f784Smrg if (pSmi->Dualhead) { 8307104f784Smrg pSmi->useBIOS = FALSE; 8317104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "UseBIOS disabled in dualhead mode\n"); 8327104f784Smrg pSmi->HwCursor = FALSE; 8337104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No hardware cursor in dualhead mode\n"); 8347104f784Smrg if (pScrn->bitsPerPixel != 16) { 8357104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Dualhead only supported at " 8367104f784Smrg "depth 16\n"); 8377104f784Smrg LEAVE(FALSE); 8387104f784Smrg } 8397104f784Smrg } 84009885543Smrg } 8417104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Dual head %sabled\n", 8427104f784Smrg pSmi->Dualhead ? "en" : "dis"); 84309885543Smrg 8447104f784Smrg if (!pSmi->NoAccel) { 8457104f784Smrg char *strptr; 8467104f784Smrg 8477104f784Smrg from = X_DEFAULT; 8487104f784Smrg if ((strptr = (char *)xf86GetOptValString(pSmi->Options, 8497104f784Smrg OPTION_ACCELMETHOD))) { 8507104f784Smrg if (!xf86NameCmp(strptr,"XAA")) { 8517104f784Smrg from = X_CONFIG; 8527104f784Smrg pSmi->useEXA = FALSE; 8537104f784Smrg } else if(!xf86NameCmp(strptr,"EXA")) { 8547104f784Smrg from = X_CONFIG; 8557104f784Smrg pSmi->useEXA = TRUE; 8567104f784Smrg } 85709885543Smrg } 8587104f784Smrg 8597104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture\n", 8607104f784Smrg pSmi->useEXA ? "EXA" : "XAA"); 86109885543Smrg } 86209885543Smrg 8637104f784Smrg if (IS_MSOC(pSmi)) { 8647104f784Smrg pSmi->CSCVideo = !pSmi->useEXA || !pSmi->Dualhead; 8657104f784Smrg from = X_DEFAULT; 8667104f784Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_CSCVIDEO, &pSmi->CSCVideo)) { 8677104f784Smrg from = X_CONFIG; 8687104f784Smrg 8697104f784Smrg /* FIXME */ 8707104f784Smrg if (pSmi->CSCVideo && pSmi->useEXA && pSmi->Dualhead) { 8717104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 8727104f784Smrg "CSCVideo requires XAA or EXA in single head mode.\n"); 8737104f784Smrg pSmi->CSCVideo = FALSE; 8747104f784Smrg } 8757104f784Smrg } 87609885543Smrg 8777104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "CSC Video %sabled\n", 8787104f784Smrg pSmi->CSCVideo ? "en" : "dis"); 8797104f784Smrg } 88009885543Smrg 8817104f784Smrg SMI_MapMmio(pScrn); 8827104f784Smrg SMI_DetectMem(pScrn); 8837104f784Smrg SMI_MapMem(pScrn); 8847104f784Smrg SMI_DisableVideo(pScrn); 88509885543Smrg 88609885543Smrg /* detect the panel size */ 88709885543Smrg SMI_DetectPanelSize(pScrn); 88809885543Smrg 8897104f784Smrg if(!IS_MSOC(pSmi)){ 8907104f784Smrg if (xf86LoadSubModule(pScrn, "i2c")) { 8917104f784Smrg xf86LoaderReqSymLists(i2cSymbols, NULL); 8927104f784Smrg SMI_I2CInit(pScrn); 8937104f784Smrg } 8947104f784Smrg if (xf86LoadSubModule(pScrn, "ddc")) { 8957104f784Smrg xf86LoaderReqSymLists(ddcSymbols, NULL); 8967104f784Smrg } 89709885543Smrg } 89809885543Smrg 89909885543Smrg /* 90009885543Smrg * If the driver can do gamma correction, it should call xf86SetGamma() 90109885543Smrg */ 90209885543Smrg { 90309885543Smrg Gamma zeros = { 0.0, 0.0, 0.0 }; 90409885543Smrg 90509885543Smrg if (!xf86SetGamma(pScrn, zeros)) { 90609885543Smrg SMI_EnableVideo(pScrn); 90709885543Smrg SMI_UnmapMem(pScrn); 9087104f784Smrg LEAVE(FALSE); 90909885543Smrg } 91009885543Smrg } 91109885543Smrg 9127104f784Smrg SMI_DetectMCLK(pScrn); 91309885543Smrg 91409885543Smrg /* 91509885543Smrg * Setup the ClockRanges, which describe what clock ranges are available, 91609885543Smrg * and what sort of modes they can be used for. 91709885543Smrg */ 9187104f784Smrg pSmi->clockRange.next = NULL; 9197104f784Smrg pSmi->clockRange.minClock = 20000; 92009885543Smrg 9217104f784Smrg if (SMI_LYNXM_SERIES(pSmi->Chipset) || 9227104f784Smrg IS_MSOC(pSmi)) 9237104f784Smrg pSmi->clockRange.maxClock = 200000; 92409885543Smrg else 9257104f784Smrg pSmi->clockRange.maxClock = 135000; 92609885543Smrg 9277104f784Smrg pSmi->clockRange.clockIndex = -1; 9287104f784Smrg pSmi->clockRange.interlaceAllowed = FALSE; 9297104f784Smrg pSmi->clockRange.doubleScanAllowed = FALSE; 93009885543Smrg 9317104f784Smrg if(!SMI_CrtcPreInit(pScrn)) 9327104f784Smrg LEAVE(FALSE); 9337104f784Smrg 9347104f784Smrg if(!SMI_OutputPreInit(pScrn)) 9357104f784Smrg LEAVE(FALSE); 9367104f784Smrg 9377104f784Smrg /* Only allow growing the screen dimensions if EXA is being used */ 9387104f784Smrg if (!xf86InitialConfiguration (pScrn, !pSmi->NoAccel && pSmi->useEXA)){ 93909885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 9407104f784Smrg LEAVE(FALSE); 94109885543Smrg } 94209885543Smrg 94309885543Smrg 9447104f784Smrg SMI_EnableVideo(pScrn); 9457104f784Smrg SMI_UnmapMem(pScrn); 9467104f784Smrg 9477104f784Smrg if(pSmi->pVbe){ 9487104f784Smrg vbeFree(pSmi->pVbe); 9497104f784Smrg pSmi->pVbe = NULL; 9507104f784Smrg } 9517104f784Smrg if(pSmi->pInt10){ 9527104f784Smrg xf86FreeInt10(pSmi->pInt10); 9537104f784Smrg pSmi->pInt10 = NULL; 9547104f784Smrg } 95509885543Smrg 95609885543Smrg /* Set display resolution */ 95709885543Smrg xf86SetDpi(pScrn, 0, 0); 95809885543Smrg 9597104f784Smrg if (xf86LoadSubModule(pScrn, "fb") == NULL) { 96009885543Smrg SMI_FreeRec(pScrn); 9617104f784Smrg LEAVE(FALSE); 96209885543Smrg } 96309885543Smrg 96409885543Smrg xf86LoaderReqSymLists(fbSymbols, NULL); 96509885543Smrg 96609885543Smrg /* Load XAA or EXA if needed */ 96709885543Smrg if (!pSmi->NoAccel) { 96809885543Smrg if (!pSmi->useEXA) { 96909885543Smrg if (!xf86LoadSubModule(pScrn, "xaa")) { 97009885543Smrg SMI_FreeRec(pScrn); 9717104f784Smrg LEAVE(FALSE); 97209885543Smrg } 97309885543Smrg xf86LoaderReqSymLists(xaaSymbols, NULL); 97409885543Smrg } else { 97509885543Smrg XF86ModReqInfo req; 97609885543Smrg int errmaj, errmin; 97709885543Smrg 97809885543Smrg memset(&req, 0, sizeof(XF86ModReqInfo)); 97909885543Smrg req.majorversion = 2; 9807104f784Smrg req.minorversion = 1; 98109885543Smrg 98209885543Smrg if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, 98309885543Smrg &req, &errmaj, &errmin)) { 98409885543Smrg LoaderErrorMsg(NULL, "exa", errmaj, errmin); 98509885543Smrg SMI_FreeRec(pScrn); 9867104f784Smrg LEAVE(FALSE); 98709885543Smrg } 98809885543Smrg xf86LoaderReqSymLists(exaSymbols, NULL); 98909885543Smrg } 99009885543Smrg } 99109885543Smrg 99209885543Smrg /* Load ramdac if needed */ 9937104f784Smrg if (pSmi->HwCursor) { 99409885543Smrg if (!xf86LoadSubModule(pScrn, "ramdac")) { 99509885543Smrg SMI_FreeRec(pScrn); 9967104f784Smrg LEAVE(FALSE); 99709885543Smrg } 99809885543Smrg } 99909885543Smrg 10007104f784Smrg LEAVE(TRUE); 100109885543Smrg} 100209885543Smrg 100309885543Smrg/* 100409885543Smrg * This is called when VT switching back to the X server. Its job is to 100509885543Smrg * reinitialise the video mode. We may wish to unmap video/MMIO memory too. 100609885543Smrg */ 100709885543Smrg 100809885543Smrgstatic Bool 100909885543SmrgSMI_EnterVT(int scrnIndex, int flags) 101009885543Smrg{ 101109885543Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 101209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 101309885543Smrg 10147104f784Smrg ENTER(); 101509885543Smrg 101609885543Smrg /* Enable MMIO and map memory */ 101709885543Smrg SMI_MapMem(pScrn); 101809885543Smrg 10197104f784Smrg pSmi->Save(pScrn); 102009885543Smrg 10217104f784Smrg /* FBBase may have changed after remapping the memory */ 10227104f784Smrg pScrn->pScreen->ModifyPixmapHeader(pScrn->pScreen->GetScreenPixmap(pScrn->pScreen), 10237104f784Smrg -1,-1,-1,-1,-1, pSmi->FBBase + pSmi->FBOffset); 10247104f784Smrg pScrn->pixmapPrivate.ptr=pSmi->FBBase + pSmi->FBOffset; 102509885543Smrg 10267104f784Smrg if(pSmi->useEXA) 10277104f784Smrg pSmi->EXADriverPtr->memoryBase=pSmi->FBBase; 102809885543Smrg 10297104f784Smrg /* Do the CRTC independent initialization */ 10307104f784Smrg if(!SMI_HWInit(pScrn)) 10317104f784Smrg LEAVE(FALSE); 103209885543Smrg 10337104f784Smrg /* Initialize the chosen modes */ 10347104f784Smrg if (!xf86SetDesiredModes(pScrn)) 10357104f784Smrg LEAVE(FALSE); 103609885543Smrg 10377104f784Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 10387104f784Smrg "Done writing mode. Register dump:\n"); 10397104f784Smrg SMI_PrintRegs(pScrn); 104009885543Smrg 104109885543Smrg /* Reset the grapics engine */ 104209885543Smrg if (!pSmi->NoAccel) 104309885543Smrg SMI_EngineReset(pScrn); 104409885543Smrg 10457104f784Smrg LEAVE(TRUE); 104609885543Smrg} 104709885543Smrg 104809885543Smrg/* 104909885543Smrg * This is called when VT switching away from the X server. Its job is to 105009885543Smrg * restore the previous (text) mode. We may wish to remap video/MMIO memory 105109885543Smrg * too. 105209885543Smrg */ 105309885543Smrg 105409885543Smrgstatic void 105509885543SmrgSMI_LeaveVT(int scrnIndex, int flags) 105609885543Smrg{ 10577104f784Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 10587104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 105909885543Smrg 10607104f784Smrg ENTER(); 106109885543Smrg 10627104f784Smrg SMI_AccelSync(pScrn); 106309885543Smrg 10647104f784Smrg /* Ensure that the rotation BlockHandler is unwrapped, and the shadow 10657104f784Smrg pixmaps are deallocated, as the video memory is going to be 10667104f784Smrg unmapped. */ 10677104f784Smrg xf86RotateCloseScreen(pScrn->pScreen); 106809885543Smrg 10697104f784Smrg /* Pixmaps that by chance get allocated near the former aperture 10707104f784Smrg address shouldn't be considered offscreen. */ 10717104f784Smrg if(pSmi->useEXA) 10727104f784Smrg pSmi->EXADriverPtr->memoryBase=NULL; 107309885543Smrg 10747104f784Smrg /* Clear frame buffer */ 10757104f784Smrg memset(pSmi->FBBase, 0, pSmi->videoRAMBytes); 10767104f784Smrg 10777104f784Smrg if (!IS_MSOC(pSmi)) { 10787104f784Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 10797104f784Smrg 10807104f784Smrg SMILynx_WriteMode(pScrn, &hwp->SavedReg, pSmi->save); 108109885543Smrg } 10827104f784Smrg else 10837104f784Smrg SMI501_WriteMode(pScrn, pSmi->save); 108409885543Smrg 108509885543Smrg SMI_UnmapMem(pScrn); 108609885543Smrg 10877104f784Smrg LEAVE(); 108809885543Smrg} 108909885543Smrg 109009885543Smrgstatic void 10917104f784SmrgSMI_DetectPanelSize(ScrnInfoPtr pScrn) 109209885543Smrg{ 10937104f784Smrg char *s; 10947104f784Smrg int width, height; 10957104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 109609885543Smrg 10977104f784Smrg pSmi->lcdWidth = 0; 10987104f784Smrg pSmi->lcdHeight = 0; 10997104f784Smrg if ((s = xf86GetOptValString(pSmi->Options, OPTION_PANEL_SIZE)) != NULL) { 11007104f784Smrg if (sscanf(s, "%dx%d", &width, &height) != 2) 11017104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 11027104f784Smrg "Invalid PanelSize option: %s\n", s); 11037104f784Smrg else { 11047104f784Smrg pSmi->lcdWidth = width; 11057104f784Smrg pSmi->lcdHeight = height; 110609885543Smrg } 110709885543Smrg } 110809885543Smrg 11097104f784Smrg if (pSmi->lcdWidth == 0 || pSmi->lcdHeight == 0) { 11107104f784Smrg /* panel size detection ... requires BIOS call on 730 hardware */ 11117104f784Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 11127104f784Smrg if (pSmi->pInt10 != NULL) { 11137104f784Smrg pSmi->pInt10->num = 0x10; 11147104f784Smrg pSmi->pInt10->ax = 0x5F00; 11157104f784Smrg pSmi->pInt10->bx = 0; 11167104f784Smrg pSmi->pInt10->cx = 0; 11177104f784Smrg pSmi->pInt10->dx = 0; 11187104f784Smrg xf86ExecX86int10(pSmi->pInt10); 11197104f784Smrg if (pSmi->pInt10->ax == 0x005F) { 11207104f784Smrg switch (pSmi->pInt10->cx & 0x0F) { 11217104f784Smrg case PANEL_640x480: 11227104f784Smrg pSmi->lcdWidth = 640; 11237104f784Smrg pSmi->lcdHeight = 480; 11247104f784Smrg break; 11257104f784Smrg case PANEL_800x600: 11267104f784Smrg pSmi->lcdWidth = 800; 11277104f784Smrg pSmi->lcdHeight = 600; 11287104f784Smrg break; 11297104f784Smrg case PANEL_1024x768: 11307104f784Smrg pSmi->lcdWidth = 1024; 11317104f784Smrg pSmi->lcdHeight = 768; 11327104f784Smrg break; 11337104f784Smrg case PANEL_1280x1024: 11347104f784Smrg pSmi->lcdWidth = 1280; 11357104f784Smrg pSmi->lcdHeight = 1024; 11367104f784Smrg break; 11377104f784Smrg case PANEL_1600x1200: 11387104f784Smrg pSmi->lcdWidth = 1600; 11397104f784Smrg pSmi->lcdHeight = 1200; 11407104f784Smrg break; 11417104f784Smrg case PANEL_1400x1050: 11427104f784Smrg pSmi->lcdWidth = 1400; 11437104f784Smrg pSmi->lcdHeight = 1050; 11447104f784Smrg break; 11457104f784Smrg } 114609885543Smrg 11477104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 11487104f784Smrg "Detected panel size via BIOS: %d x %d\n", 11497104f784Smrg pSmi->lcdWidth, pSmi->lcdHeight); 115009885543Smrg } 11517104f784Smrg else 11527104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 11537104f784Smrg "BIOS error during 730 panel detection!\n"); 115409885543Smrg } 11557104f784Smrg else { 11567104f784Smrg /* int10 support isn't setup on the second call to this function, 11577104f784Smrg o if this is the second call, don't do detection again */ 11587104f784Smrg if (pSmi->lcd == 0) 11597104f784Smrg /* If we get here, int10 support is not loaded or not working */ 11607104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 11617104f784Smrg "No BIOS support for 730 panel detection!\n"); 116209885543Smrg } 116309885543Smrg 11647104f784Smrg /* Set this to indicate that we've done the detection */ 11657104f784Smrg pSmi->lcd = 1; 116609885543Smrg } 11677104f784Smrg else if (IS_MSOC(pSmi)) { 11687104f784Smrg pSmi->lcdWidth = (READ_SCR(pSmi, PANEL_WWIDTH) >> 16) & 2047; 11697104f784Smrg pSmi->lcdHeight = (READ_SCR(pSmi, PANEL_WHEIGHT) >> 16) & 2047; 117009885543Smrg } 11717104f784Smrg else { 11727104f784Smrg /* panel size detection for hardware other than 730 */ 11737104f784Smrg pSmi->lcd = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 11747104f784Smrg 0x31) & 0x01; 117509885543Smrg 11767104f784Smrg if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 11777104f784Smrg 0x30) & 0x01) { 11787104f784Smrg pSmi->lcd <<= 1; 11797104f784Smrg } 11807104f784Smrg switch (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 11817104f784Smrg 0x30) & 0x0C) { 11827104f784Smrg case 0x00: 118309885543Smrg pSmi->lcdWidth = 640; 118409885543Smrg pSmi->lcdHeight = 480; 118509885543Smrg break; 11867104f784Smrg case 0x04: 118709885543Smrg pSmi->lcdWidth = 800; 118809885543Smrg pSmi->lcdHeight = 600; 118909885543Smrg break; 11907104f784Smrg case 0x08: 11917104f784Smrg if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 11927104f784Smrg 0x74) & 0x02) { 11937104f784Smrg pSmi->lcdWidth = 1024; 11947104f784Smrg pSmi->lcdHeight = 600; 11957104f784Smrg } 11967104f784Smrg else { 11977104f784Smrg pSmi->lcdWidth = 1024; 11987104f784Smrg pSmi->lcdHeight = 768; 11997104f784Smrg } 120009885543Smrg break; 12017104f784Smrg case 0x0C: 120209885543Smrg pSmi->lcdWidth = 1280; 120309885543Smrg pSmi->lcdHeight = 1024; 120409885543Smrg break; 120509885543Smrg } 120609885543Smrg } 120709885543Smrg } 120809885543Smrg 12097104f784Smrg if (!pSmi->lcdWidth && (pSmi->lcdWidth = pScrn->virtualX) == 0) 12107104f784Smrg pSmi->lcdWidth = 1024; 12117104f784Smrg if (!pSmi->lcdHeight && (pSmi->lcdHeight = pScrn->virtualY) == 0) 12127104f784Smrg pSmi->lcdHeight = 768; 12137104f784Smrg 121409885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s Panel Size = %dx%d\n", 121509885543Smrg (pSmi->lcd == 0) ? "OFF" : (pSmi->lcd == 1) ? "TFT" : "DSTN", 121609885543Smrg pSmi->lcdWidth, pSmi->lcdHeight); 121709885543Smrg 121809885543Smrg} 121909885543Smrg 12207104f784Smrgstatic void 12217104f784SmrgSMI_DetectMCLK(ScrnInfoPtr pScrn) 12227104f784Smrg{ 12237104f784Smrg double real; 12247104f784Smrg MSOCClockRec clock; 12257104f784Smrg int mclk, mxclk; 12267104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 12277104f784Smrg 12287104f784Smrg /* MCLK defaults */ 12297104f784Smrg if (pSmi->Chipset == SMI_LYNXEMplus){ 12307104f784Smrg /* The SM712 can be safely clocked up to 157MHz, according to 12317104f784Smrg Silicon Motion engineers. */ 12327104f784Smrg pSmi->MCLK = 157000; 12337104f784Smrg }else 12347104f784Smrg pSmi->MCLK = 0; 12357104f784Smrg 12367104f784Smrg pSmi->MXCLK = 0; 12377104f784Smrg 12387104f784Smrg /* MCLK from user settings */ 12397104f784Smrg if (xf86GetOptValFreq(pSmi->Options, OPTION_MCLK, OPTUNITS_MHZ, &real)) { 12407104f784Smrg if (IS_MSOC(pSmi) || (int)real <= 120) { 12417104f784Smrg pSmi->MCLK = (int)(real * 1000.0); 12427104f784Smrg } else { 12437104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 12447104f784Smrg "Memory Clock %1.3f MHz larger than limit of 120 MHz\n", 12457104f784Smrg real); 12467104f784Smrg } 12477104f784Smrg } 12487104f784Smrg mclk = pSmi->MCLK; 12497104f784Smrg 12507104f784Smrg if (IS_MSOC(pSmi)) { 12517104f784Smrg clock.value = READ_SCR(pSmi, CURRENT_CLOCK); 12527104f784Smrg if (xf86GetOptValFreq(pSmi->Options, OPTION_MXCLK, 12537104f784Smrg OPTUNITS_MHZ, &real)) 12547104f784Smrg pSmi->MXCLK = (int)(real * 1000.0); 12557104f784Smrg } 12567104f784Smrg 12577104f784Smrg /* Already programmed MCLK */ 12587104f784Smrg if (pSmi->MCLK == 0) { 12597104f784Smrg if (IS_MSOC(pSmi)) 12607104f784Smrg mclk = ((clock.f.m_select ? 336 : 288) / 12617104f784Smrg ((clock.f.m_divider ? 3 : 1) << 12627104f784Smrg (unsigned)clock.f.m_shift)) * 1000; 12637104f784Smrg else { 12647104f784Smrg unsigned char shift, m, n; 12657104f784Smrg 12667104f784Smrg m = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A); 12677104f784Smrg n = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B); 12687104f784Smrg switch (n >> 6) { 12697104f784Smrg case 1: 12707104f784Smrg shift = 4; 12717104f784Smrg break; 12727104f784Smrg case 2: 12737104f784Smrg shift = 2; 12747104f784Smrg break; 12757104f784Smrg default: 12767104f784Smrg shift = 1; 12777104f784Smrg break; 12787104f784Smrg } 12797104f784Smrg n &= 0x3F; 12807104f784Smrg mclk = ((1431818 * m) / n / shift + 50) / 100; 12817104f784Smrg } 12827104f784Smrg } 12837104f784Smrg 12847104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MCLK = %1.3f\n", mclk / 1000.0); 12857104f784Smrg if (IS_MSOC(pSmi)) { 12867104f784Smrg if (pSmi->MXCLK == 0) { 12877104f784Smrg mxclk = ((clock.f.m1_select ? 336 : 288) / 12887104f784Smrg ((clock.f.m1_divider ? 3 : 1) << 12897104f784Smrg (unsigned)clock.f.m1_shift)) * 1000; 12907104f784Smrg } 12917104f784Smrg else 12927104f784Smrg mxclk = pSmi->MXCLK; 12937104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MXCLK = %1.3f\n", mxclk / 1000.0); 12947104f784Smrg } 12957104f784Smrg} 12967104f784Smrg 129709885543Smrgstatic Bool 12987104f784SmrgSMI_MapMmio(ScrnInfoPtr pScrn) 129909885543Smrg{ 13007104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 13017104f784Smrg CARD32 memBase; 130209885543Smrg 13037104f784Smrg SMI_EnableMmio(pScrn); 130409885543Smrg 130509885543Smrg switch (pSmi->Chipset) { 13067104f784Smrg case SMI_COUGAR3DR: 13077104f784Smrg memBase = PCI_REGION_BASE(pSmi->PciInfo, 1, REGION_MEM); 13087104f784Smrg pSmi->MapSize = 0x200000; 13097104f784Smrg break; 13107104f784Smrg case SMI_LYNX3D: 13117104f784Smrg memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + 0x680000; 13127104f784Smrg pSmi->MapSize = 0x180000; 13137104f784Smrg break; 13147104f784Smrg case SMI_LYNXEM: 13157104f784Smrg case SMI_LYNXEMplus: 13167104f784Smrg memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + 0x400000; 13177104f784Smrg pSmi->MapSize = 0x400000; 13187104f784Smrg break; 13197104f784Smrg case SMI_LYNX3DM: 13207104f784Smrg memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM); 13217104f784Smrg pSmi->MapSize = 0x200000; 13227104f784Smrg break; 13237104f784Smrg case SMI_MSOC: 13247104f784Smrg memBase = PCI_REGION_BASE(pSmi->PciInfo, 1, REGION_MEM); 13257104f784Smrg pSmi->MapSize = 0x200000; 13267104f784Smrg break; 13277104f784Smrg default: 13287104f784Smrg memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + 0x400000; 13297104f784Smrg pSmi->MapSize = 0x10000; 13307104f784Smrg break; 133109885543Smrg } 13327104f784Smrg 13337104f784Smrg#ifndef XSERVER_LIBPCIACCESS 133409885543Smrg pSmi->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pSmi->PciTag, 133509885543Smrg memBase, pSmi->MapSize); 13367104f784Smrg#else 13377104f784Smrg { 13387104f784Smrg void **result = (void**)&pSmi->MapBase; 13397104f784Smrg int err = pci_device_map_range(pSmi->PciInfo, 13407104f784Smrg memBase, 13417104f784Smrg pSmi->MapSize, 13427104f784Smrg PCI_DEV_MAP_FLAG_WRITABLE, 13437104f784Smrg result); 13447104f784Smrg 13457104f784Smrg if (err) 13467104f784Smrg return (FALSE); 13477104f784Smrg } 13487104f784Smrg#endif 134909885543Smrg 135009885543Smrg if (pSmi->MapBase == NULL) { 135109885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Internal error: could not map " 135209885543Smrg "MMIO registers.\n"); 13537104f784Smrg return (FALSE); 135409885543Smrg } 135509885543Smrg 135609885543Smrg switch (pSmi->Chipset) { 13577104f784Smrg case SMI_COUGAR3DR: 13587104f784Smrg pSmi->DPRBase = pSmi->MapBase + 0x000000; 13597104f784Smrg pSmi->VPRBase = pSmi->MapBase + 0x000800; 13607104f784Smrg pSmi->CPRBase = pSmi->MapBase + 0x001000; 13617104f784Smrg pSmi->FPRBase = pSmi->MapBase + 0x005800; 13627104f784Smrg pSmi->IOBase = pSmi->MapBase + 0x0C0000; 13637104f784Smrg pSmi->DataPortBase = pSmi->MapBase + 0x100000; 13647104f784Smrg pSmi->DataPortSize = 0x100000; 13657104f784Smrg break; 13667104f784Smrg case SMI_LYNX3D: 13677104f784Smrg pSmi->DPRBase = pSmi->MapBase + 0x000000; 13687104f784Smrg pSmi->VPRBase = pSmi->MapBase + 0x000800; 13697104f784Smrg pSmi->CPRBase = pSmi->MapBase + 0x001000; 13707104f784Smrg pSmi->IOBase = pSmi->MapBase + 0x040000; 13717104f784Smrg pSmi->DataPortBase = pSmi->MapBase + 0x080000; 13727104f784Smrg pSmi->DataPortSize = 0x100000; 13737104f784Smrg break; 13747104f784Smrg case SMI_LYNXEM: 13757104f784Smrg case SMI_LYNXEMplus: 13767104f784Smrg pSmi->DPRBase = pSmi->MapBase + 0x008000; 13777104f784Smrg pSmi->VPRBase = pSmi->MapBase + 0x00C000; 13787104f784Smrg pSmi->CPRBase = pSmi->MapBase + 0x00E000; 13797104f784Smrg pSmi->IOBase = pSmi->MapBase + 0x300000; 13807104f784Smrg pSmi->DataPortBase = pSmi->MapBase /*+ 0x100000*/; 13817104f784Smrg pSmi->DataPortSize = 0x8000 /*0x200000*/; 13827104f784Smrg break; 13837104f784Smrg case SMI_LYNX3DM: 13847104f784Smrg pSmi->DPRBase = pSmi->MapBase + 0x000000; 13857104f784Smrg pSmi->VPRBase = pSmi->MapBase + 0x000800; 13867104f784Smrg pSmi->CPRBase = pSmi->MapBase + 0x001000; 13877104f784Smrg pSmi->IOBase = pSmi->MapBase + 0x0C0000; 13887104f784Smrg pSmi->DataPortBase = pSmi->MapBase + 0x100000; 13897104f784Smrg pSmi->DataPortSize = 0x100000; 13907104f784Smrg break; 13917104f784Smrg case SMI_MSOC: 13927104f784Smrg pSmi->DPRBase = pSmi->MapBase + 0x100000; 13937104f784Smrg pSmi->VPRBase = pSmi->MapBase + 0x000000; 13947104f784Smrg pSmi->CPRBase = pSmi->MapBase + 0x090000; 13957104f784Smrg pSmi->DCRBase = pSmi->MapBase + 0x080000; 13967104f784Smrg pSmi->SCRBase = pSmi->MapBase + 0x000000; 13977104f784Smrg pSmi->IOBase = 0; 13987104f784Smrg pSmi->DataPortBase = pSmi->MapBase + 0x110000; 13997104f784Smrg pSmi->DataPortSize = 0x10000; 14007104f784Smrg break; 14017104f784Smrg default: 14027104f784Smrg pSmi->DPRBase = pSmi->MapBase + 0x8000; 14037104f784Smrg pSmi->VPRBase = pSmi->MapBase + 0xC000; 14047104f784Smrg pSmi->CPRBase = pSmi->MapBase + 0xE000; 14057104f784Smrg pSmi->IOBase = NULL; 14067104f784Smrg pSmi->DataPortBase = pSmi->MapBase; 14077104f784Smrg pSmi->DataPortSize = 0x8000; 14087104f784Smrg break; 140909885543Smrg } 14107104f784Smrg 141109885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 141209885543Smrg "Physical MMIO at 0x%08lX\n", (unsigned long)memBase); 141309885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 141409885543Smrg "Logical MMIO at %p - %p\n", pSmi->MapBase, 141509885543Smrg pSmi->MapBase + pSmi->MapSize - 1); 141609885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 141709885543Smrg "DPR=%p, VPR=%p, IOBase=%p\n", 141809885543Smrg pSmi->DPRBase, pSmi->VPRBase, pSmi->IOBase); 141909885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 142009885543Smrg "DataPort=%p - %p\n", pSmi->DataPortBase, 142109885543Smrg pSmi->DataPortBase + pSmi->DataPortSize - 1); 142209885543Smrg 14237104f784Smrg return (TRUE); 14247104f784Smrg} 142509885543Smrg 14267104f784Smrgstatic Bool 14277104f784SmrgSMI_DetectMem(ScrnInfoPtr pScrn) 14287104f784Smrg{ 14297104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 14307104f784Smrg MessageType from; 143109885543Smrg 14327104f784Smrg if ((pScrn->videoRam = pScrn->confScreen->device->videoRam)){ 14337104f784Smrg pSmi->videoRAMKBytes = pScrn->videoRam; 14347104f784Smrg from = X_CONFIG; 14357104f784Smrg } 14367104f784Smrg else { 14377104f784Smrg unsigned char config; 14387104f784Smrg static int lynx3d_table[4] = { 0, 2, 4, 6 }; 14397104f784Smrg static int lynx3dm_table[4] = { 16, 2, 4, 8 }; 14407104f784Smrg static int msoc_table[8] = { 4, 8, 16, 32, 64, 2, 0, 0 }; 14417104f784Smrg static int default_table[4] = { 1, 2, 4, 0 }; 14427104f784Smrg 14437104f784Smrg if (IS_MSOC(pSmi)) { 14447104f784Smrg config = (READ_SCR(pSmi, DRAM_CTL) >> 13) & 7; 14457104f784Smrg pSmi->videoRAMKBytes = msoc_table[config] * 1024 - 14467104f784Smrg SHARED_USB_DMA_BUFFER_SIZE; 14477104f784Smrg } 14487104f784Smrg else { 14497104f784Smrg config = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x71); 14507104f784Smrg switch (pSmi->Chipset) { 14517104f784Smrg case SMI_LYNX3D: 14527104f784Smrg pSmi->videoRAMKBytes = lynx3d_table[config >> 6] * 1024 + 14537104f784Smrg 512; 14547104f784Smrg break; 14557104f784Smrg case SMI_LYNX3DM: 14567104f784Smrg pSmi->videoRAMKBytes = lynx3dm_table[config >> 6] * 1024; 14577104f784Smrg break; 14587104f784Smrg case SMI_COUGAR3DR: 14597104f784Smrg /* DANGER - Cougar3DR BIOS is broken - hardcode video ram 14607104f784Smrg * size per instructions from Silicon Motion engineers */ 14617104f784Smrg pSmi->videoRAMKBytes = 16 * 1024; 14627104f784Smrg break; 14637104f784Smrg default: 14647104f784Smrg pSmi->videoRAMKBytes = default_table[config >> 6] * 1024; 14657104f784Smrg break; 14667104f784Smrg } 146709885543Smrg } 14687104f784Smrg from = X_PROBED; 14697104f784Smrg } 147009885543Smrg 14717104f784Smrg pSmi->videoRAMBytes = pSmi->videoRAMKBytes * 1024; 14727104f784Smrg pScrn->videoRam = pSmi->videoRAMKBytes; 14737104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, 14747104f784Smrg "videoram: %dkB\n", pSmi->videoRAMKBytes); 147509885543Smrg 14767104f784Smrg return (TRUE); 14777104f784Smrg} 147809885543Smrg 14797104f784SmrgBool 14807104f784SmrgSMI_MapMem(ScrnInfoPtr pScrn) 14817104f784Smrg{ 14827104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 14837104f784Smrg vgaHWPtr hwp; 148409885543Smrg 14857104f784Smrg ENTER(); 14867104f784Smrg 14877104f784Smrg if (pSmi->MapBase == NULL && SMI_MapMmio(pScrn) == FALSE) 14887104f784Smrg LEAVE(FALSE); 14897104f784Smrg 14907104f784Smrg pScrn->memPhysBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM); 14917104f784Smrg 14927104f784Smrg if (pSmi->Chipset == SMI_LYNX3DM) 14937104f784Smrg pSmi->fbMapOffset = 0x200000; 14947104f784Smrg else 14957104f784Smrg pSmi->fbMapOffset = 0x0; 14967104f784Smrg 14977104f784Smrg#ifndef XSERVER_LIBPCIACCESS 14987104f784Smrg pSmi->FBBase = xf86MapPciMem(pScrn->scrnIndex, 14997104f784Smrg VIDMEM_FRAMEBUFFER, 15007104f784Smrg pSmi->PciTag, 15017104f784Smrg pScrn->memPhysBase + pSmi->fbMapOffset, 15027104f784Smrg pSmi->videoRAMBytes); 15037104f784Smrg#else 15047104f784Smrg { 15057104f784Smrg void **result = (void**)&pSmi->FBBase; 15067104f784Smrg int err = pci_device_map_range(pSmi->PciInfo, 15077104f784Smrg pScrn->memPhysBase + 15087104f784Smrg pSmi->fbMapOffset, 15097104f784Smrg pSmi->videoRAMBytes, 15107104f784Smrg PCI_DEV_MAP_FLAG_WRITABLE | 15117104f784Smrg PCI_DEV_MAP_FLAG_WRITE_COMBINE, 15127104f784Smrg result); 15137104f784Smrg 15147104f784Smrg if (err) 15157104f784Smrg LEAVE(FALSE); 15167104f784Smrg } 15177104f784Smrg#endif 15187104f784Smrg 15197104f784Smrg if (pSmi->FBBase == NULL) { 15207104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 15217104f784Smrg "Internal error: could not map framebuffer.\n"); 15227104f784Smrg LEAVE(FALSE); 15237104f784Smrg } 15247104f784Smrg 15257104f784Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 15267104f784Smrg "Physical frame buffer at 0x%08lX offset: 0x%08lX\n", 15277104f784Smrg pScrn->memPhysBase, pSmi->fbMapOffset); 15287104f784Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 15297104f784Smrg "Logical frame buffer at %p - %p\n", pSmi->FBBase, 15307104f784Smrg pSmi->FBBase + pSmi->videoRAMBytes - 1); 15317104f784Smrg 15327104f784Smrg if (IS_MSOC(pSmi)) { 15337104f784Smrg /* Reserve space for panel cursr, and crt if in dual head mode */ 15347104f784Smrg#if SMI_CURSOR_ALPHA_PLANE 15357104f784Smrg pSmi->FBReserved = pSmi->FBCursorOffset = pSmi->videoRAMBytes - 15367104f784Smrg (pSmi->Dualhead ? SMI501_CURSOR_SIZE << 1 : SMI501_ARGB_CURSOR_SIZE); 15377104f784Smrg#else 15387104f784Smrg pSmi->FBReserved = pSmi->FBCursorOffset = pSmi->videoRAMBytes - 15397104f784Smrg (pSmi->Dualhead ? SMI501_CURSOR_SIZE << 1 : SMI501_CURSOR_SIZE); 15407104f784Smrg 15417104f784Smrg# if SMI501_CLI_DEBUG 15427104f784Smrg if (pSmi->useEXA) { 15437104f784Smrg pSmi->batch_active = FALSE; 15447104f784Smrg pSmi->batch_length = 4096; 15457104f784Smrg pSmi->FBReserved -= pSmi->batch_length << 3; 15467104f784Smrg pSmi->batch_offset = pSmi->FBReserved; 15477104f784Smrg pSmi->batch_handle = (int64_t *)(pSmi->FBBase + pSmi->batch_offset); 15487104f784Smrg pSmi->batch_finish = -1; 15497104f784Smrg pSmi->batch_index = 0; 15507104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 15517104f784Smrg "Using command list interpreter debug code\n"); 15527104f784Smrg } 15537104f784Smrg# endif 15547104f784Smrg 15557104f784Smrg#endif 15567104f784Smrg } 15577104f784Smrg else { 15587104f784Smrg /* Set up offset to hwcursor memory area, at the end of 15597104f784Smrg * the frame buffer. 15607104f784Smrg */ 15617104f784Smrg pSmi->FBCursorOffset = pSmi->videoRAMBytes - SMILYNX_CURSOR_SIZE; 156209885543Smrg /* set up the fifo reserved space */ 156309885543Smrg if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30) & 0x01)/* #1074 */ { 156409885543Smrg CARD32 fifoOffset = 0; 15657104f784Smrg fifoOffset |= VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 15667104f784Smrg 0x46) << 3; 15677104f784Smrg fifoOffset |= VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 15687104f784Smrg 0x47) << 11; 15697104f784Smrg fifoOffset |= (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 15707104f784Smrg 0x49) & 0x1C) << 17; 157109885543Smrg pSmi->FBReserved = fifoOffset; /* PDR#1074 */ 157209885543Smrg } 15737104f784Smrg else 15747104f784Smrg pSmi->FBReserved = pSmi->videoRAMBytes - 2048; 157509885543Smrg 15767104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Cursor Offset: %08lX\n", 15777104f784Smrg (unsigned long)pSmi->FBCursorOffset); 157809885543Smrg 15797104f784Smrg /* Assign hwp->MemBase & IOBase here */ 15807104f784Smrg hwp = VGAHWPTR(pScrn); 15817104f784Smrg if (pSmi->IOBase != NULL) 15827104f784Smrg vgaHWSetMmioFuncs(hwp, pSmi->MapBase, pSmi->IOBase - pSmi->MapBase); 15837104f784Smrg vgaHWGetIOBase(hwp); 158409885543Smrg 15857104f784Smrg /* Map the VGA memory when the primary video */ 15867104f784Smrg if (xf86IsPrimaryPci(pSmi->PciInfo)) { 15877104f784Smrg hwp->MapSize = 0x10000; 15887104f784Smrg if (!vgaHWMapMem(pScrn)) 15897104f784Smrg LEAVE(FALSE); 15907104f784Smrg pSmi->PrimaryVidMapped = TRUE; 159109885543Smrg } 159209885543Smrg } 159309885543Smrg 15947104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reserved: %08lX\n", 15957104f784Smrg (unsigned long)pSmi->FBReserved); 15967104f784Smrg 15977104f784Smrg LEAVE(TRUE); 159809885543Smrg} 159909885543Smrg 160009885543Smrg/* UnMapMem - contains half of pre-4.0 EnterLeave function. The EnterLeave 160109885543Smrg * function which en/disable access to IO ports and ext. regs 160209885543Smrg */ 160309885543Smrg 16047104f784Smrgvoid 160509885543SmrgSMI_UnmapMem(ScrnInfoPtr pScrn) 160609885543Smrg{ 160709885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 160809885543Smrg 16097104f784Smrg ENTER(); 161009885543Smrg 161109885543Smrg /* Unmap VGA mem if mapped. */ 161209885543Smrg if (pSmi->PrimaryVidMapped) { 161309885543Smrg vgaHWUnmapMem(pScrn); 161409885543Smrg pSmi->PrimaryVidMapped = FALSE; 161509885543Smrg } 161609885543Smrg 161709885543Smrg SMI_DisableMmio(pScrn); 161809885543Smrg 16197104f784Smrg if (pSmi->MapBase) { 16207104f784Smrg#ifndef XSERVER_LIBPCIACCESS 16217104f784Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSmi->MapBase, 16227104f784Smrg pSmi->MapSize); 16237104f784Smrg#else 16247104f784Smrg pci_device_unmap_range(pSmi->PciInfo, (pointer)pSmi->MapBase, 16257104f784Smrg pSmi->MapSize); 16267104f784Smrg#endif 16277104f784Smrg pSmi->MapBase = NULL; 16287104f784Smrg } 16297104f784Smrg 16307104f784Smrg if (pSmi->FBBase) { 16317104f784Smrg#ifndef XSERVER_LIBPCIACCESS 163209885543Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pSmi->FBBase, 163309885543Smrg pSmi->videoRAMBytes); 16347104f784Smrg#else 16357104f784Smrg pci_device_unmap_range(pSmi->PciInfo, (pointer)pSmi->FBBase, 16367104f784Smrg pSmi->videoRAMBytes); 16377104f784Smrg#endif 16387104f784Smrg pSmi->FBBase = NULL; 163909885543Smrg } 164009885543Smrg 16417104f784Smrg LEAVE(); 164209885543Smrg} 164309885543Smrg 164409885543Smrg/* This gets called at the start of each server generation. */ 164509885543Smrg 164609885543Smrgstatic Bool 164709885543SmrgSMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 164809885543Smrg{ 16497104f784Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 16507104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 16517104f784Smrg EntityInfoPtr pEnt; 165209885543Smrg 16537104f784Smrg ENTER(); 165409885543Smrg 165509885543Smrg /* Map MMIO regs and framebuffer */ 16567104f784Smrg if (!SMI_MapMem(pScrn)) 16577104f784Smrg LEAVE(FALSE); 165809885543Smrg 165909885543Smrg pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 166009885543Smrg 16617104f784Smrg if (!pSmi->pInt10 && pSmi->useBIOS) { 16627104f784Smrg pSmi->pInt10 = xf86InitInt10(pEnt->index); 166309885543Smrg } 16647104f784Smrg if (!pSmi->pVbe && pSmi->pInt10 && xf86LoaderCheckSymbol("VBEInit")) { 16657104f784Smrg pSmi->pVbe = VBEInit(pSmi->pInt10, pEnt->index); 166609885543Smrg } 166709885543Smrg 16687104f784Smrg /* Save the chip/graphics state */ 16697104f784Smrg pSmi->Save(pScrn); 167009885543Smrg 16717104f784Smrg /* Fill in some needed pScrn fields */ 16727104f784Smrg pScrn->vtSema = TRUE; 16737104f784Smrg pScrn->pScreen = pScreen; 167409885543Smrg 16757104f784Smrg pSmi->Bpp = pScrn->bitsPerPixel >> 3; 16767104f784Smrg pScrn->displayWidth = ((pScrn->virtualX * pSmi->Bpp + 15) & ~15) / pSmi->Bpp; 167709885543Smrg 16787104f784Smrg pSmi->fbArea = NULL; 16797104f784Smrg pSmi->FBOffset = 0; 16807104f784Smrg pScrn->fbOffset = pSmi->FBOffset + pSmi->fbMapOffset; 168109885543Smrg 16827104f784Smrg /* Clear frame buffer */ 16837104f784Smrg memset(pSmi->FBBase, 0, pSmi->videoRAMBytes); 168409885543Smrg 168509885543Smrg /* 16867104f784Smrg * The next step is to setup the screen's visuals, and initialise the 16877104f784Smrg * framebuffer code. In cases where the framebuffer's default choises for 16887104f784Smrg * things like visual layouts and bits per RGB are OK, this may be as simple 16897104f784Smrg * as calling the framebuffer's ScreenInit() function. If not, the visuals 16907104f784Smrg * will need to be setup before calling a fb ScreenInit() function and fixed 16917104f784Smrg * up after. 16927104f784Smrg */ 169309885543Smrg 16947104f784Smrg /* 16957104f784Smrg * Reset the visual list. 16967104f784Smrg */ 16977104f784Smrg miClearVisualTypes(); 169809885543Smrg 16997104f784Smrg /* Setup the visuals we support. */ 170009885543Smrg 17017104f784Smrg if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 17027104f784Smrg pScrn->rgbBits, pScrn->defaultVisual)) 17037104f784Smrg LEAVE(FALSE); 170409885543Smrg 17057104f784Smrg if (!miSetPixmapDepths ()) 17067104f784Smrg LEAVE(FALSE); 170709885543Smrg 17087104f784Smrg /* 17097104f784Smrg * Call the framebuffer layer's ScreenInit function 17107104f784Smrg */ 171109885543Smrg 17127104f784Smrg DEBUG("\tInitializing FB @ 0x%08X for %dx%d (%d)\n", 17137104f784Smrg pSmi->FBBase, pScrn->virtualX, pScrn->virtualY, pScrn->displayWidth); 17147104f784Smrg if(!fbScreenInit(pScreen, pSmi->FBBase, pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, 17157104f784Smrg pScrn->yDpi, pScrn->displayWidth, pScrn->bitsPerPixel)) 17167104f784Smrg LEAVE(FALSE); 171709885543Smrg 17187104f784Smrg xf86SetBlackWhitePixels(pScreen); 171909885543Smrg 17207104f784Smrg if (pScrn->bitsPerPixel > 8) { 17217104f784Smrg VisualPtr visual; 17227104f784Smrg /* Fixup RGB ordering */ 17237104f784Smrg visual = pScreen->visuals + pScreen->numVisuals; 17247104f784Smrg while (--visual >= pScreen->visuals) { 17257104f784Smrg if ((visual->class | DynamicClass) == DirectColor) { 17267104f784Smrg visual->offsetRed = pScrn->offset.red; 17277104f784Smrg visual->offsetGreen = pScrn->offset.green; 17287104f784Smrg visual->offsetBlue = pScrn->offset.blue; 17297104f784Smrg visual->redMask = pScrn->mask.red; 17307104f784Smrg visual->greenMask = pScrn->mask.green; 17317104f784Smrg visual->blueMask = pScrn->mask.blue; 17327104f784Smrg } 173309885543Smrg } 173409885543Smrg } 173509885543Smrg 17367104f784Smrg /* must be after RGB ordering fixed */ 17377104f784Smrg fbPictureInit(pScreen, 0, 0); 17387104f784Smrg 17397104f784Smrg /* Do the CRTC independent initialization */ 17407104f784Smrg if(!SMI_HWInit(pScrn)) 17417104f784Smrg LEAVE(FALSE); 174209885543Smrg 17437104f784Smrg /* Unless using EXA, regardless or using XAA or not, needs offscreen 17447104f784Smrg * management at least for video. */ 17457104f784Smrg if (pSmi->NoAccel || !pSmi->useEXA) { 17467104f784Smrg int numLines; 17477104f784Smrg BoxRec AvailFBArea; 174809885543Smrg 17497104f784Smrg numLines = pSmi->FBReserved / (pScrn->displayWidth * pSmi->Bpp); 17507104f784Smrg AvailFBArea.x1 = 0; 17517104f784Smrg AvailFBArea.y1 = 0; 17527104f784Smrg AvailFBArea.x2 = pScrn->virtualX; 17537104f784Smrg AvailFBArea.y2 = numLines; 175409885543Smrg 17557104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 17567104f784Smrg "FrameBuffer Box: %d,%d - %d,%d\n", 17577104f784Smrg AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, 17587104f784Smrg AvailFBArea.y2); 175909885543Smrg 17607104f784Smrg xf86InitFBManager(pScreen, &AvailFBArea); 176109885543Smrg } 176209885543Smrg 17637104f784Smrg /* Initialize acceleration layer */ 17647104f784Smrg if (!pSmi->NoAccel) { 17657104f784Smrg if (pSmi->useEXA && !SMI_EXAInit(pScreen)) 17667104f784Smrg LEAVE(FALSE); 17677104f784Smrg else if (!pSmi->useEXA && !SMI_XAAInit(pScreen)) 17687104f784Smrg LEAVE(FALSE); 176909885543Smrg } 177009885543Smrg 17717104f784Smrg /* Initialize the chosen modes */ 17727104f784Smrg if (!xf86SetDesiredModes(pScrn)) 17737104f784Smrg LEAVE(FALSE); 177409885543Smrg 17757104f784Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 17767104f784Smrg "Done writing mode. Register dump:\n"); 17777104f784Smrg SMI_PrintRegs(pScrn); 177809885543Smrg 17797104f784Smrg miInitializeBackingStore(pScreen); 178009885543Smrg 17817104f784Smrg#ifdef HAVE_XMODES 17827104f784Smrg xf86DiDGAInit(pScreen, (unsigned long)(pSmi->FBBase + pScrn->fbOffset)); 17837104f784Smrg#endif 178409885543Smrg 17857104f784Smrg /* Initialise cursor functions */ 17867104f784Smrg miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 178709885543Smrg 17887104f784Smrg /* Initialize HW cursor layer. Must follow software cursor 17897104f784Smrg * initialization. 17907104f784Smrg */ 17917104f784Smrg if (pSmi->HwCursor) { 17927104f784Smrg int size, flags; 17937104f784Smrg 17947104f784Smrg if (IS_MSOC(pSmi)) { 17957104f784Smrg size = SMI501_MAX_CURSOR; 17967104f784Smrg flags = (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | 17977104f784Smrg HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK); 17987104f784Smrg#if SMI_CURSOR_ALPHA_PLANE 17997104f784Smrg if (!pSmi->Dualhead) 18007104f784Smrg flags |= HARDWARE_CURSOR_ARGB; 18017104f784Smrg#endif 18027104f784Smrg } 18037104f784Smrg else { 18047104f784Smrg size = SMILYNX_MAX_CURSOR; 18057104f784Smrg flags = (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 | 18067104f784Smrg HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | 18077104f784Smrg HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 18087104f784Smrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 18097104f784Smrg HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 18107104f784Smrg HARDWARE_CURSOR_INVERT_MASK); 18117104f784Smrg } 181209885543Smrg 18137104f784Smrg if (!xf86_cursors_init(pScreen, size, size, flags)) 18147104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 18157104f784Smrg "Hardware cursor initialization failed\n"); 181609885543Smrg } 181709885543Smrg 18187104f784Smrg /* Initialise default colormap */ 18197104f784Smrg if (!miCreateDefColormap(pScreen)) 18207104f784Smrg LEAVE(FALSE); 182109885543Smrg 18227104f784Smrg /* Initialize colormap layer. Must follow initialization of the default 18237104f784Smrg * colormap. And SetGamma call, else it will load palette with solid white. 18247104f784Smrg */ 18257104f784Smrg if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,SMI_LoadPalette, NULL, 18267104f784Smrg CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) 18277104f784Smrg LEAVE(FALSE); 182809885543Smrg 18297104f784Smrg pScreen->SaveScreen = SMI_SaveScreen; 18307104f784Smrg pSmi->CloseScreen = pScreen->CloseScreen; 18317104f784Smrg pScreen->CloseScreen = SMI_CloseScreen; 183209885543Smrg 18337104f784Smrg if ((IS_MSOC(pSmi) && 18347104f784Smrg !xf86DPMSInit(pScreen, SMI501_DisplayPowerManagementSet, 0)) || 18357104f784Smrg (!IS_MSOC(pSmi) && 18367104f784Smrg !xf86DPMSInit(pScreen, SMILynx_DisplayPowerManagementSet, 0))) 18377104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed!\n"); 183809885543Smrg 18397104f784Smrg SMI_InitVideo(pScreen); 184009885543Smrg 18417104f784Smrg if(!xf86CrtcScreenInit(pScreen)) 18427104f784Smrg LEAVE(FALSE); 184309885543Smrg 18447104f784Smrg /* Report any unused options (only for the first generation) */ 18457104f784Smrg if (serverGeneration == 1) { 18467104f784Smrg xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 18477104f784Smrg } 184809885543Smrg 18497104f784Smrg LEAVE(TRUE); 185009885543Smrg} 185109885543Smrg 185209885543Smrg/* 185309885543Smrg * This is called at the end of each server generation. It restores the 185409885543Smrg * original (text) mode. It should also unmap the video memory, and free any 185509885543Smrg * per-generation data allocated by the driver. It should finish by unwrapping 185609885543Smrg * and calling the saved CloseScreen function. 185709885543Smrg */ 185809885543Smrg 185909885543Smrgstatic Bool 186009885543SmrgSMI_CloseScreen(int scrnIndex, ScreenPtr pScreen) 186109885543Smrg{ 18627104f784Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 18637104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 18647104f784Smrg Bool ret; 186509885543Smrg 18667104f784Smrg ENTER(); 186709885543Smrg 18687104f784Smrg if (pSmi->HwCursor) 18697104f784Smrg xf86_cursors_fini(pScreen); 18707104f784Smrg 18717104f784Smrg if (pScrn->vtSema) 18727104f784Smrg /* Restore console mode and unmap framebuffer */ 18737104f784Smrg SMI_LeaveVT(scrnIndex, 0); 187409885543Smrg 187509885543Smrg if (pSmi->XAAInfoRec != NULL) { 187609885543Smrg XAADestroyInfoRec(pSmi->XAAInfoRec); 187709885543Smrg } 187809885543Smrg if (pSmi->EXADriverPtr) { 187909885543Smrg exaDriverFini(pScreen); 188009885543Smrg pSmi->EXADriverPtr = NULL; 188109885543Smrg } 18827104f784Smrg if (pSmi->pVbe != NULL) { 18837104f784Smrg vbeFree(pSmi->pVbe); 18847104f784Smrg pSmi->pVbe = NULL; 188509885543Smrg } 188609885543Smrg if (pSmi->pInt10 != NULL) { 188709885543Smrg xf86FreeInt10(pSmi->pInt10); 188809885543Smrg pSmi->pInt10 = NULL; 188909885543Smrg } 189009885543Smrg if (pSmi->ptrAdaptor != NULL) { 189109885543Smrg xfree(pSmi->ptrAdaptor); 189209885543Smrg } 189309885543Smrg if (pSmi->BlockHandler != NULL) { 189409885543Smrg pScreen->BlockHandler = pSmi->BlockHandler; 189509885543Smrg } 189609885543Smrg 189709885543Smrg pScrn->vtSema = FALSE; 189809885543Smrg pScreen->CloseScreen = pSmi->CloseScreen; 189909885543Smrg ret = (*pScreen->CloseScreen)(scrnIndex, pScreen); 190009885543Smrg 19017104f784Smrg LEAVE(ret); 190209885543Smrg} 190309885543Smrg 190409885543Smrgstatic void 190509885543SmrgSMI_FreeScreen(int scrnIndex, int flags) 190609885543Smrg{ 190709885543Smrg SMI_FreeRec(xf86Screens[scrnIndex]); 190809885543Smrg} 190909885543Smrg 191009885543Smrgstatic Bool 191109885543SmrgSMI_SaveScreen(ScreenPtr pScreen, int mode) 191209885543Smrg{ 19137104f784Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 191409885543Smrg 19157104f784Smrg ENTER(); 191609885543Smrg 19177104f784Smrg if(xf86IsUnblank(mode)){ 19187104f784Smrg pScrn->DPMSSet(pScrn, DPMSModeOn, 0); 19197104f784Smrg }else{ 19207104f784Smrg pScrn->DPMSSet(pScrn, DPMSModeOff, 0); 19217104f784Smrg } 192209885543Smrg 19237104f784Smrg LEAVE(TRUE); 192409885543Smrg} 192509885543Smrg 192609885543Smrgvoid 192709885543SmrgSMI_AdjustFrame(int scrnIndex, int x, int y, int flags) 192809885543Smrg{ 19297104f784Smrg xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(xf86Screens[scrnIndex]); 19307104f784Smrg xf86CrtcPtr compat_crtc = crtcConf->output[crtcConf->compat_output]->crtc; 193109885543Smrg 19327104f784Smrg ENTER(); 193309885543Smrg 19347104f784Smrg SMICRTC(compat_crtc)->adjust_frame(compat_crtc,x,y); 193509885543Smrg 19367104f784Smrg LEAVE(); 193709885543Smrg} 193809885543Smrg 193909885543SmrgBool 194009885543SmrgSMI_SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 194109885543Smrg{ 194209885543Smrg Bool ret; 19437104f784Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 19447104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 19457104f784Smrg 19467104f784Smrg ENTER(); 194709885543Smrg 19487104f784Smrg ret = xf86SetSingleMode(pScrn, mode, RR_Rotate_0); 194909885543Smrg 19507104f784Smrg if (!pSmi->NoAccel) 19517104f784Smrg SMI_EngineReset(pScrn); 195209885543Smrg 19537104f784Smrg LEAVE(ret); 195409885543Smrg} 195509885543Smrg 195609885543Smrgvoid 19577104f784SmrgSMI_LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, 19587104f784Smrg LOCO *colors, VisualPtr pVisual) 195909885543Smrg{ 19607104f784Smrg xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); 19617104f784Smrg int crtc_idx,i,j; 19627104f784Smrg 19637104f784Smrg ENTER(); 19647104f784Smrg 19657104f784Smrg if(pScrn->bitsPerPixel == 16){ 19667104f784Smrg /* Expand the RGB 565 palette into the 256-elements LUT */ 196709885543Smrg 19687104f784Smrg for(crtc_idx=0; crtc_idx<crtcConf->num_crtc; crtc_idx++){ 19697104f784Smrg SMICrtcPrivatePtr crtcPriv = SMICRTC(crtcConf->crtc[crtc_idx]); 197009885543Smrg 19717104f784Smrg for(i=0; i<numColors; i++){ 19727104f784Smrg int idx = indicies[i]; 197309885543Smrg 19747104f784Smrg if(idx<32){ 19757104f784Smrg for(j=0; j<8; j++){ 19767104f784Smrg crtcPriv->lut_r[idx*8 + j] = colors[idx].red << 8; 19777104f784Smrg crtcPriv->lut_b[idx*8 + j] = colors[idx].blue << 8; 19787104f784Smrg } 19797104f784Smrg } 19807104f784Smrg 19817104f784Smrg for(j=0; j<4; j++) 19827104f784Smrg crtcPriv->lut_g[idx*4 + j] = colors[idx].green << 8; 19837104f784Smrg } 19847104f784Smrg 19857104f784Smrg crtcPriv->load_lut(crtcConf->crtc[crtc_idx]); 198609885543Smrg } 19877104f784Smrg }else{ 19887104f784Smrg for(crtc_idx=0; crtc_idx<crtcConf->num_crtc; crtc_idx++){ 19897104f784Smrg SMICrtcPrivatePtr crtcPriv = SMICRTC(crtcConf->crtc[crtc_idx]); 199009885543Smrg 199109885543Smrg for(i = 0; i < numColors; i++) { 19927104f784Smrg int idx = indicies[i]; 19937104f784Smrg 19947104f784Smrg crtcPriv->lut_r[idx] = colors[idx].red << 8; 19957104f784Smrg crtcPriv->lut_g[idx] = colors[idx].green << 8; 19967104f784Smrg crtcPriv->lut_b[idx] = colors[idx].blue << 8; 19977104f784Smrg } 19987104f784Smrg 19997104f784Smrg crtcPriv->load_lut(crtcConf->crtc[crtc_idx]); 20007104f784Smrg } 200109885543Smrg } 200209885543Smrg 20037104f784Smrg LEAVE(); 200409885543Smrg} 200509885543Smrg 200609885543Smrgstatic void 200709885543SmrgSMI_DisableVideo(ScrnInfoPtr pScrn) 200809885543Smrg{ 200909885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 201009885543Smrg CARD8 tmp; 201109885543Smrg 20127104f784Smrg if (!IS_MSOC(pSmi)) { 20137104f784Smrg if (!(tmp = VGAIN8(pSmi, VGA_DAC_MASK))) 20147104f784Smrg return; 20157104f784Smrg pSmi->DACmask = tmp; 20167104f784Smrg VGAOUT8(pSmi, VGA_DAC_MASK, 0); 20177104f784Smrg } 201809885543Smrg} 201909885543Smrg 202009885543Smrgstatic void 202109885543SmrgSMI_EnableVideo(ScrnInfoPtr pScrn) 202209885543Smrg{ 202309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 202409885543Smrg 20257104f784Smrg if (!IS_MSOC(pSmi)) { 20267104f784Smrg VGAOUT8(pSmi, VGA_DAC_MASK, pSmi->DACmask); 20277104f784Smrg } 202809885543Smrg} 202909885543Smrg 203009885543Smrg 203109885543Smrgvoid 203209885543SmrgSMI_EnableMmio(ScrnInfoPtr pScrn) 203309885543Smrg{ 203409885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 203509885543Smrg 20367104f784Smrg ENTER(); 203709885543Smrg 20387104f784Smrg if (!IS_MSOC(pSmi)) { 20397104f784Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 20407104f784Smrg CARD8 tmp; 20417104f784Smrg 20427104f784Smrg /* 20437104f784Smrg * Enable chipset (seen on uninitialized secondary cards) might not be 20447104f784Smrg * needed once we use the VGA softbooter 20457104f784Smrg */ 20467104f784Smrg vgaHWSetStdFuncs(hwp); 204709885543Smrg 20487104f784Smrg /* Enable linear mode */ 20497104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); 20507104f784Smrg tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); 20517104f784Smrg pSmi->SR18Value = tmp; /* PDR#521 */ 20527104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp | 0x11); 205309885543Smrg 20547104f784Smrg /* Enable 2D/3D Engine and Video Processor */ 20557104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x21); 20567104f784Smrg tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); 20577104f784Smrg pSmi->SR21Value = tmp; /* PDR#521 */ 20587104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp & ~0x03); 20597104f784Smrg } 206009885543Smrg 20617104f784Smrg LEAVE(); 206209885543Smrg} 206309885543Smrg 206409885543Smrgvoid 206509885543SmrgSMI_DisableMmio(ScrnInfoPtr pScrn) 206609885543Smrg{ 206709885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 206809885543Smrg 20697104f784Smrg ENTER(); 207009885543Smrg 20717104f784Smrg if (!IS_MSOC(pSmi)) { 20727104f784Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 207309885543Smrg 20747104f784Smrg vgaHWSetStdFuncs(hwp); 207509885543Smrg 20767104f784Smrg /* Disable 2D/3D Engine and Video Processor */ 20777104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x21); 20787104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, pSmi->SR21Value); /* PDR#521 */ 20797104f784Smrg 20807104f784Smrg /* Disable linear mode */ 20817104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); 20827104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, pSmi->SR18Value); /* PDR#521 */ 20837104f784Smrg } 208409885543Smrg 20857104f784Smrg LEAVE(); 208609885543Smrg} 208709885543Smrg 208809885543Smrgstatic void 20897104f784SmrgSMI_ProbeDDC(ScrnInfoPtr pScrn, int index) 20907104f784Smrg{ 20917104f784Smrg vbeInfoPtr pVbe; 20927104f784Smrg if (xf86LoadSubModule(pScrn, "vbe")) { 20937104f784Smrg pVbe = VBEInit(NULL, index); 20947104f784Smrg ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 20957104f784Smrg vbeFree(pVbe); 20967104f784Smrg } 20977104f784Smrg} 20987104f784Smrg 20997104f784Smrgstatic Bool 21007104f784SmrgSMI_HWInit(ScrnInfoPtr pScrn) 210109885543Smrg{ 210209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 210309885543Smrg 21047104f784Smrg ENTER(); 210509885543Smrg 21067104f784Smrg if(IS_MSOC(pSmi)) 21077104f784Smrg LEAVE(SMI501_HWInit(pScrn)); 21087104f784Smrg else 21097104f784Smrg LEAVE(SMILynx_HWInit(pScrn)); 21107104f784Smrg} 211109885543Smrg 21127104f784Smrgvoid 21137104f784SmrgSMI_PrintRegs(ScrnInfoPtr pScrn) 21147104f784Smrg{ 21157104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 21167104f784Smrg int i; 211709885543Smrg 21187104f784Smrg ENTER(); 211909885543Smrg 21207104f784Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 21217104f784Smrg "START register dump ------------------\n"); 21227104f784Smrg 21237104f784Smrg if(IS_MSOC(pSmi)) 21247104f784Smrg SMI501_PrintRegs(pScrn); 21257104f784Smrg else 21267104f784Smrg SMILynx_PrintRegs(pScrn); 212709885543Smrg 212809885543Smrg 212909885543Smrg xf86ErrorFVerb(VERBLEV, "\n\nDPR x0 x4 x8 xC"); 213009885543Smrg for (i = 0x00; i <= 0x44; i += 4) { 213109885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 213209885543Smrg xf86ErrorFVerb(VERBLEV, " %08lX", (unsigned long)READ_DPR(pSmi, i)); 213309885543Smrg } 213409885543Smrg 213509885543Smrg xf86ErrorFVerb(VERBLEV, "\n\nVPR x0 x4 x8 xC"); 213609885543Smrg for (i = 0x00; i <= 0x60; i += 4) { 213709885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 213809885543Smrg xf86ErrorFVerb(VERBLEV, " %08lX", (unsigned long)READ_VPR(pSmi, i)); 213909885543Smrg } 214009885543Smrg 214109885543Smrg xf86ErrorFVerb(VERBLEV, "\n\nCPR x0 x4 x8 xC"); 214209885543Smrg for (i = 0x00; i <= 0x18; i += 4) { 214309885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 214409885543Smrg xf86ErrorFVerb(VERBLEV, " %08lX", (unsigned long)READ_CPR(pSmi, i)); 214509885543Smrg } 214609885543Smrg 214709885543Smrg xf86ErrorFVerb(VERBLEV, "\n\n"); 214809885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 214909885543Smrg "END register dump --------------------\n"); 215009885543Smrg 21517104f784Smrg LEAVE(); 215209885543Smrg} 2153