smi_driver.c revision b698ba48
11.376Spalle/* Header: //Mercury/Projects/archives/XFree86/4.0/smi_driver.c-arc 1.42 03 Jan 2001 13:52:16 Frido $ */ 21.1Sabs 31.123Sjmc/* 41.123SjmcCopyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. 51.123SjmcCopyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. 61.1Sabs 71.123SjmcPermission is hereby granted, free of charge, to any person obtaining a copy of 81.123Sjmcthis software and associated documentation files (the "Software"), to deal in 91.123Sjmcthe Software without restriction, including without limitation the rights to 101.123Sjmcuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 111.123Sjmcof the Software, and to permit persons to whom the Software is furnished to do 121.123Sjmcso, subject to the following conditions: 131.123Sjmc 141.257SapbThe above copyright notice and this permission notice shall be included in all 151.257Sapbcopies or substantial portions of the Software. 161.257Sapb 171.123SjmcTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 181.1SabsIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 191.1SabsNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 201.1SabsXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 211.230StlsAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 221.375SchristosWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 231.375Schristos 241.376SpalleExcept as contained in this notice, the names of The XFree86 Project and 251.367SriastradSilicon Motion shall not be used in advertising or otherwise to promote the 261.373Sriastradsale, use or other dealings in this Software without prior written 271.373Sriastradauthorization from The XFree86 Project or Silicon Motion. 281.368Sriastrad*/ 291.372Sriastrad 301.370Sriastrad#ifdef HAVE_CONFIG_H 311.372Sriastrad#include "config.h" 321.368Sriastrad#endif 331.374Sriastrad 341.374Sriastrad#include "xf86.h" 351.374Sriastrad#include "xf86DDC.h" 361.374Sriastrad#include "xf86int10.h" 371.374Sriastrad#include "vbe.h" 381.374Sriastrad 391.374Sriastrad#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 401.367Sriastrad#include "xf86Resources.h" 411.367Sriastrad#include "xf86RAC.h" 421.367Sriastrad#endif 431.367Sriastrad 441.367Sriastrad#include "smi.h" 451.367Sriastrad#include "smi_501.h" 461.367Sriastrad#include "smilynx.h" 471.367Sriastrad#include "smi_crtc.h" 481.367Sriastrad 491.363Smartin#include "globals.h" 501.363Smartin#ifdef HAVE_XEXTPROTO_71 511.363Smartin#include <X11/extensions/dpmsconst.h> 521.366Sriastrad#else 531.366Sriastrad#define DPMS_SERVER 541.366Sriastrad#include <X11/extensions/dpms.h> 551.366Sriastrad#endif 561.366Sriastrad 571.366Sriastrad 581.366Sriastrad/* 591.366Sriastrad * Internals 601.366Sriastrad */ 611.366Sriastradstatic Bool SMI_MapMmio(ScrnInfoPtr pScrn); 621.366Sriastradstatic Bool SMI_DetectMem(ScrnInfoPtr pScrn); 631.366Sriastradstatic void SMI_EnableMmio(ScrnInfoPtr pScrn); 641.366Sriastradstatic void SMI_DisableMmio(ScrnInfoPtr pScrn); 651.366Sriastradstatic Bool SMI_HWInit(ScrnInfoPtr pScrn); 661.366Sriastrad 671.363Smartin/* 681.360Swiz * Forward definitions for the functions that make up the driver. 691.360Swiz */ 701.360Swiz 711.360Swizstatic const OptionInfoRec * SMI_AvailableOptions(int chipid, int busid); 721.360Swizstatic void SMI_Identify(int flags); 731.360Swizstatic Bool SMI_Probe(DriverPtr drv, int flags); 741.360Swizstatic Bool SMI_PreInit(ScrnInfoPtr pScrn, int flags); 751.358Smartinstatic Bool SMI_EnterVT(int scrnIndex, int flags); 761.358Smartinstatic void SMI_LeaveVT(int scrnIndex, int flags); 771.359Smartinstatic Bool SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 781.359Smartin char **argv); 791.359Smartinstatic void SMI_DisableVideo(ScrnInfoPtr pScrn); 801.359Smartinstatic void SMI_EnableVideo(ScrnInfoPtr pScrn); 811.359Smartinstatic Bool SMI_CloseScreen(int scrnIndex, ScreenPtr pScreen); 821.358Smartinstatic Bool SMI_SaveScreen(ScreenPtr pScreen, int mode); 831.357Schristosstatic void SMI_FreeScreen(int ScrnIndex, int flags); 841.357Schristosstatic void SMI_ProbeDDC(ScrnInfoPtr pScrn, int index); 851.357Schristosstatic void SMI_DetectPanelSize(ScrnInfoPtr pScrn); 861.357Schristosstatic void SMI_DetectMCLK(ScrnInfoPtr pScrn); 871.358Smartin 881.355Smartin/* 891.355Smartin * xf86VDrvMsgVerb prints up to 14 characters prefix, where prefix has the 901.355Smartin * format "%s(%d): " so, use name "SMI" instead of "Silicon Motion" 911.355Smartin */ 921.356Sriastrad#define SILICONMOTION_NAME "SMI" 931.354Smartin#define SILICONMOTION_DRIVER_NAME "siliconmotion" 941.353Smartin#define SILICONMOTION_VERSION_NAME PACKAGE_VERSION 951.353Smartin#define SILICONMOTION_VERSION_MAJOR PACKAGE_VERSION_MAJOR 961.353Smartin#define SILICONMOTION_VERSION_MINOR PACKAGE_VERSION_MINOR 971.352Skre#define SILICONMOTION_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 981.352Skre#define SILICONMOTION_DRIVER_VERSION ((SILICONMOTION_VERSION_MAJOR << 24) | \ 991.352Skre (SILICONMOTION_VERSION_MINOR << 16) | \ 1001.352Skre (SILICONMOTION_PATCHLEVEL)) 1011.352Skre 1021.350Sriastrad#if SMI_DEBUG 1031.350Sriastradint smi_indent = 1; 1041.350Sriastrad#endif 1051.350Sriastrad 1061.349Smaya/* for dualhead */ 1071.349Smayaint gSMIEntityIndex = -1; 1081.349Smaya 1091.346Sriastrad/* 1101.346Sriastrad * This contains the functions needed by the server after loading the 1111.346Sriastrad * driver module. It must be supplied, and gets added the driver list by 1121.346Sriastrad * the Module Setup funtion in the dynamic case. In the static case a 1131.346Sriastrad * reference to this is compiled in, and this requires that the name of 1141.347Snia * this DriverRec be an upper-case version of the driver name. 1151.347Snia */ 1161.347Snia 1171.347Snia_X_EXPORT DriverRec SILICONMOTION = 1181.343Sriastrad{ 1191.343Sriastrad SILICONMOTION_DRIVER_VERSION, 1201.343Sriastrad SILICONMOTION_DRIVER_NAME, 1211.343Sriastrad SMI_Identify, 1221.343Sriastrad SMI_Probe, 1231.343Sriastrad SMI_AvailableOptions, 1241.343Sriastrad NULL, 1251.343Sriastrad 0 1261.343Sriastrad}; 1271.343Sriastrad 1281.343Sriastrad/* Supported chipsets */ 1291.343Sriastradstatic SymTabRec SMIChipsets[] = 1301.343Sriastrad{ 1311.343Sriastrad { PCI_CHIP_SMI910, "Lynx" }, 1321.343Sriastrad { PCI_CHIP_SMI810, "LynxE" }, 1331.341Slukem { PCI_CHIP_SMI820, "Lynx3D" }, 1341.341Slukem { PCI_CHIP_SMI710, "LynxEM" }, 1351.341Slukem { PCI_CHIP_SMI712, "LynxEM+" }, 1361.341Slukem { PCI_CHIP_SMI720, "Lynx3DM" }, 1371.342Smartin { PCI_CHIP_SMI731, "Cougar3DR" }, 1381.342Smartin { PCI_CHIP_SMI501, "MSOC" }, 1391.342Smartin { -1, NULL } 1401.342Smartin}; 1411.342Smartin 1421.342Smartinstatic PciChipsets SMIPciChipsets[] = 1431.339Smartin{ 1441.339Smartin /* numChipset, PciID, Resource */ 1451.339Smartin { PCI_CHIP_SMI910, PCI_CHIP_SMI910, RES_SHARED_VGA }, 1461.339Smartin { PCI_CHIP_SMI810, PCI_CHIP_SMI810, RES_SHARED_VGA }, 1471.339Smartin { PCI_CHIP_SMI820, PCI_CHIP_SMI820, RES_SHARED_VGA }, 1481.338Slukem { PCI_CHIP_SMI710, PCI_CHIP_SMI710, RES_SHARED_VGA }, 1491.338Slukem { PCI_CHIP_SMI712, PCI_CHIP_SMI712, RES_SHARED_VGA }, 1501.338Slukem { PCI_CHIP_SMI720, PCI_CHIP_SMI720, RES_SHARED_VGA }, 1511.338Slukem { PCI_CHIP_SMI731, PCI_CHIP_SMI731, RES_SHARED_VGA }, 1521.338Slukem { PCI_CHIP_SMI501, PCI_CHIP_SMI501, RES_UNDEFINED }, 1531.340Smartin { -1, -1, RES_UNDEFINED } 1541.340Smartin}; 1551.345Sandvar 1561.340Smartintypedef enum 1571.340Smartin{ 1581.340Smartin OPTION_PCI_BURST, 1591.337Smrg OPTION_PCI_RETRY, 1601.337Smrg OPTION_NOACCEL, 1611.337Smrg OPTION_MCLK, 1621.337Smrg OPTION_MXCLK, 1631.337Smrg OPTION_SWCURSOR, 1641.337Smrg OPTION_HWCURSOR, 1651.336Smartin OPTION_VIDEOKEY, 1661.336Smartin OPTION_BYTESWAP, 1671.336Smartin /* CZ 26.10.2001: interlaced video */ 1681.336Smartin OPTION_INTERLACED, 1691.336Smartin /* end CZ */ 1701.336Smartin OPTION_USEBIOS, 1711.335Schs OPTION_DUALHEAD, 1721.335Schs OPTION_ACCELMETHOD, 1731.335Schs OPTION_PANEL_SIZE, 1741.335Schs OPTION_USE_FBDEV, 1751.335Schs OPTION_CSCVIDEO, 1761.335Schs NUMBER_OF_OPTIONS 1771.335Schs} SMIOpts; 1781.335Schs 1791.335Schsstatic const OptionInfoRec SMIOptions[] = 1801.335Schs{ 1811.335Schs { OPTION_PCI_BURST, "pci_burst", OPTV_BOOLEAN, {0}, TRUE }, 1821.335Schs { OPTION_PCI_RETRY, "pci_retry", OPTV_BOOLEAN, {0}, TRUE }, 1831.335Schs { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 1841.335Schs { OPTION_MCLK, "MCLK", OPTV_FREQ, {0}, FALSE }, 1851.335Schs { OPTION_MXCLK, "MXCLK", OPTV_FREQ, {0}, FALSE }, 1861.335Schs { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, TRUE }, 1871.335Schs { OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE }, 1881.335Schs { OPTION_VIDEOKEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, 1891.335Schs { OPTION_BYTESWAP, "ByteSwap", OPTV_BOOLEAN, {0}, FALSE }, 1901.335Schs /* CZ 26.10.2001: interlaced video */ 1911.335Schs { OPTION_INTERLACED, "Interlaced", OPTV_BOOLEAN, {0}, FALSE }, 1921.335Schs /* end CZ */ 1931.335Schs { OPTION_USEBIOS, "UseBIOS", OPTV_BOOLEAN, {0}, FALSE }, 1941.335Schs { OPTION_DUALHEAD, "Dualhead", OPTV_BOOLEAN, {0}, TRUE }, 1951.335Schs { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, 1961.335Schs { OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE }, 1971.334Smrg { OPTION_USE_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, 1981.334Smrg { OPTION_CSCVIDEO, "CSCVideo", OPTV_BOOLEAN, {0}, TRUE }, 1991.334Smrg { -1, NULL, OPTV_NONE, {0}, FALSE } 2001.334Smrg}; 2011.334Smrg 2021.334Smrg#ifdef XFree86LOADER 2031.334Smrg 2041.334Smrgstatic MODULESETUPPROTO(siliconmotionSetup); 2051.334Smrg 2061.334Smrgstatic XF86ModuleVersionInfo SMIVersRec = 2071.334Smrg{ 2081.331Sriastrad "siliconmotion", 2091.331Sriastrad MODULEVENDORSTRING, 2101.333Sriastrad MODINFOSTRING1, 2111.333Sriastrad MODINFOSTRING2, 2121.333Sriastrad XORG_VERSION_CURRENT, 2131.333Sriastrad SILICONMOTION_VERSION_MAJOR, 2141.333Sriastrad SILICONMOTION_VERSION_MINOR, 2151.333Sriastrad SILICONMOTION_PATCHLEVEL, 2161.333Sriastrad ABI_CLASS_VIDEODRV, 2171.333Sriastrad ABI_VIDEODRV_VERSION, 2181.333Sriastrad MOD_CLASS_VIDEODRV, 2191.333Sriastrad {0, 0, 0, 0} 2201.333Sriastrad}; 2211.333Sriastrad 2221.333Sriastrad/* 2231.333Sriastrad * This is the module init data for XFree86 modules. 2241.333Sriastrad * 2251.333Sriastrad * Its name has to be the driver name followed by ModuleData. 2261.333Sriastrad */ 2271.333Sriastrad_X_EXPORT XF86ModuleData siliconmotionModuleData = 2281.333Sriastrad{ 2291.333Sriastrad &SMIVersRec, 2301.333Sriastrad siliconmotionSetup, 2311.333Sriastrad NULL 2321.333Sriastrad}; 2331.333Sriastrad 2341.333Sriastradstatic pointer 2351.333SriastradsiliconmotionSetup(pointer module, pointer opts, int *errmaj, int *errmin) 2361.331Sriastrad{ 2371.330Slukem static Bool setupDone = FALSE; 2381.330Slukem 2391.330Slukem if (!setupDone) { 2401.330Slukem setupDone = TRUE; 2411.329Smrg xf86AddDriver(&SILICONMOTION, module, 0); 2421.329Smrg 2431.329Smrg /* 2441.329Smrg * The return value must be non-NULL on success even though there 2451.328Smartin * is no TearDownProc. 2461.328Smartin */ 2471.328Smartin return (pointer) 1; 2481.328Smartin 2491.324Smartin } else { 2501.324Smartin if (errmaj) { 2511.325Smartin *errmaj = LDR_ONCEONLY; 2521.324Smartin } 2531.323Snia return NULL; 2541.323Snia } 2551.323Snia} 2561.323Snia 2571.322Smartin#endif /* XFree86LOADER */ 2581.323Snia 2591.322Smartinstatic Bool 2601.321SchristosSMI_GetRec(ScrnInfoPtr pScrn) 2611.321Schristos{ 2621.321Schristos ENTER(); 2631.321Schristos 2641.321Schristos /* 2651.319Smrg * Allocate an 'Chip'Rec, and hook it into pScrn->driverPrivate. 2661.319Smrg * pScrn->driverPrivate is initialised to NULL, so we can check if 2671.319Smrg * the allocation has already been done. 2681.319Smrg */ 2691.318Smrg if (pScrn->driverPrivate == NULL) { 2701.318Smrg pScrn->driverPrivate = xnfcalloc(sizeof(SMIRec), 1); 2711.351Sgutterid } 2721.318Smrg 2731.318Smrg LEAVE(TRUE); 2741.316Smrg} 2751.316Smrg 2761.316Smrgstatic void 2771.316SmrgSMI_FreeRec(ScrnInfoPtr pScrn) 2781.315Smrg{ 2791.315Smrg SMIPtr pSmi = SMIPTR(pScrn); 2801.315Smrg 2811.315Smrg ENTER(); 2821.314Smrg 2831.314Smrg if (pSmi) { 2841.314Smrg xfree(pSmi->save); 2851.314Smrg xfree(pSmi->mode); 2861.313Smrg xfree(pScrn->driverPrivate); 2871.313Smrg pScrn->driverPrivate = NULL; 2881.313Smrg } 2891.313Smrg 2901.311Smrg LEAVE(); 2911.312Smrg} 2921.312Smrg 2931.312Smrgstatic const OptionInfoRec * 2941.311SmrgSMI_AvailableOptions(int chipid, int busid) 2951.309Schristos{ 2961.310Schristos ENTER(); 2971.332Sgutterid 2981.309Schristos LEAVE(SMIOptions); 2991.308Schristos} 3001.308Schristos 3011.308Schristosstatic void 3021.308SchristosSMI_Identify(int flags) 3031.307Smrg{ 3041.307Smrg ENTER(); 3051.307Smrg 3061.307Smrg xf86PrintChipsets(SILICONMOTION_NAME, "driver (version " 3071.306Schristos SILICONMOTION_VERSION_NAME ") for Silicon Motion Lynx chipsets", 3081.306Schristos SMIChipsets); 3091.306Schristos 3101.306Schristos LEAVE(); 3111.306Schristos} 3121.305Smartin 3131.305Smartinstatic Bool 3141.305SmartinSMI_Probe(DriverPtr drv, int flags) 3151.305Smartin{ 3161.304Smartin int i; 3171.304Smartin GDevPtr *devSections; 3181.304Smartin int *usedChips; 3191.304Smartin int numDevSections; 3201.304Smartin int numUsed; 3211.306Schristos Bool foundScreen = FALSE; 3221.304Smartin 3231.304Smartin ENTER(); 3241.303Smrg 3251.303Smrg numDevSections = xf86MatchDevice(SILICONMOTION_DRIVER_NAME, &devSections); 3261.303Smrg 3271.303Smrg if (numDevSections <= 0) 3281.303Smrg /* There's no matching device section in the config file, so quit now. */ 3291.302Sriastrad LEAVE(FALSE); 3301.306Schristos 3311.302Sriastrad#ifndef XSERVER_LIBPCIACCESS 3321.302Sriastrad if (xf86GetPciVideoInfo() == NULL) 3331.302Sriastrad LEAVE(FALSE); 3341.302Sriastrad#endif 3351.302Sriastrad 3361.302Sriastrad numUsed = xf86MatchPciInstances(SILICONMOTION_NAME, PCI_SMI_VENDOR_ID, 3371.302Sriastrad SMIChipsets, SMIPciChipsets, devSections, 3381.302Sriastrad numDevSections, drv, &usedChips); 3391.302Sriastrad 3401.302Sriastrad /* Free it since we don't need that list after this */ 3411.302Sriastrad xfree(devSections); 3421.302Sriastrad if (numUsed <= 0) 3431.302Sriastrad LEAVE(FALSE); 3441.302Sriastrad 3451.302Sriastrad if (flags & PROBE_DETECT) 3461.302Sriastrad foundScreen = TRUE; 3471.302Sriastrad else { 3481.302Sriastrad ScrnInfoPtr pScrn; 3491.302Sriastrad EntityInfoPtr pEnt; 3501.302Sriastrad 3511.302Sriastrad for (i = 0; i < numUsed; i++) { 3521.302Sriastrad if ((pScrn = xf86ConfigPciEntity(NULL, 0, usedChips[i], 3531.302Sriastrad SMIPciChipsets, NULL, 3541.302Sriastrad NULL, NULL, NULL, NULL))) { 3551.302Sriastrad pScrn->driverVersion = SILICONMOTION_DRIVER_VERSION; 3561.302Sriastrad pScrn->driverName = SILICONMOTION_DRIVER_NAME; 3571.302Sriastrad pScrn->name = SILICONMOTION_NAME; 3581.302Sriastrad pScrn->Probe = SMI_Probe; 3591.302Sriastrad pScrn->PreInit = SMI_PreInit; 3601.302Sriastrad pScrn->ScreenInit = SMI_ScreenInit; 3611.302Sriastrad pScrn->SwitchMode = SMI_SwitchMode; 3621.302Sriastrad pScrn->AdjustFrame = SMI_AdjustFrame; 3631.302Sriastrad 3641.302Sriastrad if ((pEnt = xf86GetEntityInfo(usedChips[i]))) { 3651.302Sriastrad pScrn->EnterVT = SMI_EnterVT; 3661.302Sriastrad pScrn->LeaveVT = SMI_LeaveVT; 3671.302Sriastrad xfree(pEnt); 3681.302Sriastrad } 3691.302Sriastrad pScrn->FreeScreen = SMI_FreeScreen; 3701.302Sriastrad foundScreen = TRUE; 3711.302Sriastrad } 3721.302Sriastrad } 3731.302Sriastrad } 3741.302Sriastrad xfree(usedChips); 3751.302Sriastrad 3761.302Sriastrad LEAVE(foundScreen); 3771.302Sriastrad} 3781.302Sriastrad 3791.302Sriastradstatic Bool 3801.302SriastradSMI_PreInit(ScrnInfoPtr pScrn, int flags) 3811.302Sriastrad{ 3821.302Sriastrad EntityInfoPtr pEnt; 3831.302Sriastrad SMIPtr pSmi; 3841.302Sriastrad MessageType from; 3851.302Sriastrad vgaHWPtr hwp; 3861.302Sriastrad 3871.302Sriastrad ENTER(); 3881.302Sriastrad 3891.302Sriastrad /* Ignoring the Type list for now. It might be needed when multiple cards 3901.302Sriastrad * are supported. 3911.302Sriastrad */ 3921.302Sriastrad if (pScrn->numEntities > 1) 3931.302Sriastrad LEAVE(FALSE); 3941.302Sriastrad 3951.302Sriastrad /* Allocate the SMIRec driverPrivate */ 3961.302Sriastrad if (!SMI_GetRec(pScrn)) 3971.302Sriastrad LEAVE(FALSE); 3981.302Sriastrad pSmi = SMIPTR(pScrn); 3991.302Sriastrad 4001.302Sriastrad /* Find the PCI slot for this screen */ 4011.302Sriastrad pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 4021.302Sriastrad 4031.302Sriastrad pSmi->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 4041.302Sriastrad pSmi->Chipset = PCI_DEV_DEVICE_ID(pSmi->PciInfo); 4051.302Sriastrad 4061.302Sriastrad if (IS_MSOC(pSmi)) { 4071.302Sriastrad pSmi->Save = SMI501_Save; 4081.302Sriastrad pSmi->save = xnfcalloc(sizeof(MSOCRegRec), 1); 4091.301Smartin pSmi->mode = xnfcalloc(sizeof(MSOCRegRec), 1); 4101.301Smartin } 4111.301Smartin else { 4121.301Smartin pSmi->Save = SMILynx_Save; 4131.301Smartin pSmi->save = xnfcalloc(sizeof(SMIRegRec), 1); 4141.301Smartin pSmi->mode = xnfcalloc(sizeof(SMIRegRec), 1); 4151.300Smartin } 4161.344Sgutterid 4171.300Smartin if (flags & PROBE_DETECT) { 4181.326Sandvar if (!IS_MSOC(pSmi)) 4191.300Smartin SMI_ProbeDDC(pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index); 4201.300Smartin LEAVE(TRUE); 4211.300Smartin } 4221.299Smrg 4231.299Smrg if (pEnt->location.type != BUS_PCI) { 4241.299Smrg xfree(pEnt); 4251.1Sabs SMI_FreeRec(pScrn); 4261.1Sabs LEAVE(FALSE); 4271.123Sjmc } 4281.132Sjmmv pSmi->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 4291.123Sjmc 4301.123Sjmc /* Set pScrn->monitor */ 4311.123Sjmc pScrn->monitor = pScrn->confScreen->monitor; 4321.123Sjmc 4331.2Smrg if (!IS_MSOC(pSmi)) { 4341.2Smrg /* The vgahw module should be loaded here when needed */ 4351.2Smrg if (!xf86LoadSubModule(pScrn, "vgahw")) 4361.2Smrg LEAVE(FALSE); 4371.1Sabs 4381.1Sabs /* 4391.1Sabs * Allocate a vgaHWRec 4401.1Sabs */ 4411.1Sabs if (!vgaHWGetHWRec(pScrn)) 4421.1Sabs LEAVE(FALSE); 4431.123Sjmc 4441.123Sjmc hwp = VGAHWPTR(pScrn); 4451.123Sjmc pSmi->PIOBase = hwp->PIOOffset; 4461.1Sabs 4471.2Smrg xf86ErrorFVerb(VERBLEV, "\tSMI_PreInit vgaCRIndex=%x, vgaIOBase=%x, " 4481.2Smrg "MMIOBase=%p\n", hwp->IOBase + VGA_CRTC_INDEX_OFFSET, 4491.1Sabs hwp->IOBase, hwp->MMIOBase); 4501.2Smrg } 4511.2Smrg 4521.1Sabs /* 4531.123Sjmc * The first thing we should figure out is the depth, bpp, etc. 4541.123Sjmc */ 4551.123Sjmc if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) 4561.123Sjmc LEAVE(FALSE); 4571.123Sjmc 4581.123Sjmc /* Check that the returned depth is one we support */ 4591.123Sjmc if (pScrn->depth != 8 && pScrn->depth != 16 && pScrn->depth != 24) { 4601.123Sjmc xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4611.123Sjmc "Given depth (%d) is not supported by this driver\n", 4621.123Sjmc pScrn->depth); 4631.1Sabs LEAVE(FALSE); 4641.1Sabs } 4651.1Sabs 4661.123Sjmc 4671.123Sjmc if(pScrn->bitsPerPixel != 8 && pScrn->bitsPerPixel != 16 && 4681.241Swiz pScrn->bitsPerPixel != 24 && pScrn->bitsPerPixel != 32){ 4691.1Sabs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4701.1Sabs "Given bpp (%d) is not supported by this driver\n", 4711.230Stls pScrn->bitsPerPixel); 4721.1Sabs LEAVE(FALSE); 4731.1Sabs } 4741.1Sabs 4751.1Sabs xf86PrintDepthBpp(pScrn); 4761.1Sabs 4771.1Sabs pSmi->Bpp = pScrn->bitsPerPixel >> 3; 4781.1Sabs 4791.1Sabs /* 4801.1Sabs * This must happen after pScrn->display has been set because 4811.1Sabs * xf86SetWeight references it. 4821.1Sabs */ 4831.1Sabs if (pScrn->depth > 8) { 4841.1Sabs /* The defaults are OK for us */ 4851.1Sabs rgb zeros = {0, 0, 0}; 4861.1Sabs#if __BYTE_ORDER == __BIG_ENDIAN 4871.1Sabs rgb masks = {0xff00,0xff0000,0xff000000}; 4881.1Sabs#else 4891.1Sabs rgb masks = {0, 0, 0}; 4901.1Sabs#endif 4911.1Sabs 4921.1Sabs if (!xf86SetWeight(pScrn, zeros, masks)) 4931.1Sabs LEAVE(FALSE); 4941.1Sabs } 4951.2Smrg 4961.2Smrg if (!xf86SetDefaultVisual(pScrn, -1)) 4971.2Smrg LEAVE(FALSE); 4981.1Sabs 4991.1Sabs /* We don't currently support DirectColor at > 8bpp */ 5001.1Sabs if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 5011.1Sabs xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual (%s) " 5021.1Sabs "is not supported at depth %d\n", 5031.58Slukem xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 5041.58Slukem LEAVE(FALSE); 5051.1Sabs } 5061.58Slukem 5071.1Sabs /* We use a programmable clock */ 5081.1Sabs pScrn->progClock = TRUE; 5091.1Sabs 5101.58Slukem /* Collect all of the relevant option flags (fill in pScrn->options) */ 5111.1Sabs xf86CollectOptions(pScrn, NULL); 5121.1Sabs 5131.1Sabs /* Set the bits per RGB for 8bpp mode */ 5141.1Sabs if (pScrn->depth == 8){ 5151.1Sabs pScrn->rgbBits = IS_MSOC(pSmi) ? 8 : 6; 5161.1Sabs }else if(pScrn->depth == 16){ 5171.1Sabs /* Use 8 bit LUT for gamma correction*/ 5181.1Sabs pScrn->rgbBits = 8; 5191.58Slukem } 5201.1Sabs 5211.1Sabs /* Process the options */ 5221.1Sabs if (!(pSmi->Options = xalloc(sizeof(SMIOptions)))) 5231.1Sabs LEAVE(FALSE); 5241.1Sabs 5251.1Sabs memcpy(pSmi->Options, SMIOptions, sizeof(SMIOptions)); 5261.1Sabs xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pSmi->Options); 5271.1Sabs 5281.11Slukem /* Enable pci burst by default */ 5291.142Sdrochner from = X_DEFAULT; 5301.1Sabs pSmi->PCIBurst = TRUE; 5311.34Ssimonb if (xf86GetOptValBool(pSmi->Options, OPTION_PCI_BURST, &pSmi->PCIBurst)) 5321.1Sabs from = X_CONFIG; 5331.1Sabs xf86DrvMsg(pScrn->scrnIndex, from, "PCI Burst %sabled\n", 5341.17Serh pSmi->PCIBurst ? "en" : "dis"); 5351.17Serh 5361.111Ssimonb /* Pci retry enabled by default if pci burst also enabled */ 5371.348Srillig from = X_DEFAULT; 5381.348Srillig pSmi->PCIRetry = pSmi->PCIBurst ? TRUE : FALSE; 5391.17Serh if (xf86GetOptValBool(pSmi->Options, OPTION_PCI_RETRY, &pSmi->PCIRetry)) { 5401.1Sabs from = X_CONFIG; 5411.1Sabs if (pSmi->PCIRetry && !pSmi->PCIBurst) { 5421.2Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 5431.2Smrg "\"pci_retry\" option requires \"pci_burst\".\n"); 5441.142Sdrochner pSmi->PCIRetry = FALSE; 5451.1Sabs } 5461.4Sitojun } 5471.4Sitojun xf86DrvMsg(pScrn->scrnIndex, from, "PCI Retry %sabled\n", 5481.4Sitojun pSmi->PCIRetry ? "en" : "dis"); 5491.4Sitojun 5501.4Sitojun if (xf86ReturnOptValBool(pSmi->Options, OPTION_NOACCEL, FALSE)) { 5511.5Swiz pSmi->NoAccel = TRUE; 5521.207Smbalmer xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - Acceleration " 5531.207Smbalmer "disabled\n"); 5541.5Swiz } else { 5551.12Sitojun pSmi->NoAccel = FALSE; 5561.12Sitojun } 5571.12Sitojun 5581.13Sdogcow if (IS_MSOC(pSmi)) { 5591.86Skleink from = X_DEFAULT; 5601.13Sdogcow if (xf86GetOptValBool(pSmi->Options, OPTION_USE_FBDEV, &pSmi->UseFBDev)) 5611.13Sdogcow from = X_CONFIG; 5621.142Sdrochner xf86DrvMsg(pScrn->scrnIndex, from, "UseFBDev %s.\n", 5631.19Scgd pSmi->UseFBDev ? "enabled" : "disabled"); 5641.13Sdogcow } 5651.19Scgd 5661.19Scgd from = X_CONFIG; 5671.24Sabs pSmi->HwCursor = TRUE; 5681.223Sjoerg /* SWCursor overrides HWCusor if both specified */ 5691.223Sjoerg if (xf86ReturnOptValBool(pSmi->Options, OPTION_SWCURSOR, FALSE)) 5701.223Sjoerg pSmi->HwCursor = FALSE; 5711.257Sapb else if (!xf86GetOptValBool(pSmi->Options, OPTION_HWCURSOR, &pSmi->HwCursor)) 5721.257Sapb from = X_DEFAULT; 5731.257Sapb 5741.257Sapb xf86DrvMsg(pScrn->scrnIndex, from, "Using %sware Cursor\n", 5751.257Sapb pSmi->HwCursor ? "Hard" : "Soft"); 5761.257Sapb 5771.257Sapb if (xf86GetOptValInteger(pSmi->Options, OPTION_VIDEOKEY, &pSmi->videoKey)) { 5781.257Sapb xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Video key set to " 5791.257Sapb "0x%08X\n", pSmi->videoKey); 5801.257Sapb } else { 581 pSmi->videoKey = (1 << pScrn->offset.red) | 582 (1 << pScrn->offset.green) | 583 (((pScrn->mask.blue >> pScrn->offset.blue) - 1) 584 << pScrn->offset.blue); 585 } 586 587 if (xf86ReturnOptValBool(pSmi->Options, OPTION_BYTESWAP, FALSE)) { 588 pSmi->ByteSwap = TRUE; 589 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: ByteSwap enabled.\n"); 590 } else { 591 pSmi->ByteSwap = FALSE; 592 } 593 594 /* CZ 26.10.2001: interlaced video */ 595 if (xf86ReturnOptValBool(pSmi->Options, OPTION_INTERLACED, FALSE)) { 596 pSmi->interlaced = TRUE; 597 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Interlaced enabled.\n"); 598 } else { 599 pSmi->interlaced = FALSE; 600 } 601 /* end CZ */ 602 603 if (IS_MSOC(pSmi)) 604 pSmi->useBIOS = FALSE; 605 else if (xf86GetOptValBool(pSmi->Options, OPTION_USEBIOS, &pSmi->useBIOS)) { 606 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: UseBIOS %s.\n", 607 pSmi->useBIOS ? "enabled" : "disabled"); 608 } 609 else if(pSmi->Chipset == SMI_LYNX3DM){ 610 /* Default to UseBIOS disabled. */ 611 pSmi->useBIOS = FALSE; 612 } 613 else { 614 /* Default to UseBIOS enabled. */ 615 pSmi->useBIOS = TRUE; 616 } 617 618 if (pSmi->useBIOS) { 619 if (xf86LoadSubModule(pScrn,"int10")) { 620 pSmi->pInt10 = xf86InitInt10(pEnt->index); 621 } 622 623 if (pSmi->pInt10 && xf86LoadSubModule(pScrn, "vbe")) { 624 pSmi->pVbe = VBEInit(pSmi->pInt10, pEnt->index); 625 } 626 627 if(!pSmi->pVbe){ 628 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VBE initialization failed: falling back to UseBIOS disabled.\n"); 629 pSmi->useBIOS = FALSE; 630 } 631 } 632 633#ifndef XSERVER_LIBPCIACCESS 634 xf86RegisterResources(pEnt->index, NULL, ResExclusive); 635#endif 636 /* 637 * Set the Chipset and ChipRev, allowing config file entries to 638 * override. 639 */ 640 if (pEnt->device->chipset && *pEnt->device->chipset) { 641 pScrn->chipset = pEnt->device->chipset; 642 pSmi->Chipset = xf86StringToToken(SMIChipsets, pScrn->chipset); 643 from = X_CONFIG; 644 } 645 else if (pEnt->device->chipID >= 0) { 646 pSmi->Chipset = pEnt->device->chipID; 647 pScrn->chipset = (char *) xf86TokenToString(SMIChipsets, pSmi->Chipset); 648 from = X_CONFIG; 649 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 650 pSmi->Chipset); 651 } 652 else { 653 from = X_PROBED; 654 pSmi->Chipset = PCI_DEV_DEVICE_ID(pSmi->PciInfo); 655 pScrn->chipset = (char *) xf86TokenToString(SMIChipsets, pSmi->Chipset); 656 } 657 658 if (pEnt->device->chipRev >= 0) { 659 pSmi->ChipRev = pEnt->device->chipRev; 660 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 661 pSmi->ChipRev); 662 } 663 else 664 pSmi->ChipRev = PCI_DEV_REVISION(pSmi->PciInfo); 665 xfree(pEnt); 666 667 /* 668 * This shouldn't happen because such problems should be caught in 669 * SMI_Probe(), but check it just in case. 670 */ 671 if (pScrn->chipset == NULL) { 672 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04X is not " 673 "recognised\n", pSmi->Chipset); 674 LEAVE(FALSE); 675 } 676 677 if (pSmi->Chipset < 0) { 678 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Chipset \"%s\" is not " 679 "recognised\n", pScrn->chipset); 680 LEAVE(FALSE); 681 } 682 683 xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); 684 685#ifndef XSERVER_LIBPCIACCESS 686 pSmi->PciTag = pciTag(pSmi->PciInfo->bus, pSmi->PciInfo->device, 687 pSmi->PciInfo->func); 688#endif 689 690 from = X_DEFAULT; 691 if(pSmi->Chipset == SMI_LYNX3DM && 692 pScrn->bitsPerPixel == 16) 693 pSmi->Dualhead = TRUE; 694 else 695 pSmi->Dualhead = FALSE; 696 697 if (xf86GetOptValBool(pSmi->Options, OPTION_DUALHEAD, &pSmi->Dualhead)) 698 from = X_CONFIG; 699 700 if (IS_MSOC(pSmi)) { 701 pSmi->lcd = TRUE; 702 if (pSmi->Dualhead && pSmi->UseFBDev) { 703 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 704 "Dual head disabled in fbdev mode\n"); 705 pSmi->Dualhead = FALSE; 706 } 707 /* FIXME Randr cursor code only works properly when argb cursors 708 * are also supported. 709 * FIXME This probably is a randr cursor bug, and since access to 710 * hw/xfree86/ramdac/xf86CursorPriv.h:xf86CursorScreenRec.SWCursor 711 * field is not available, one cannot easily workaround the problem, 712 * so, just disable it... 713 * TODO Check with a X Server newer then 1.4.0.90 (that is being 714 * used in the 502 OEM image). 715 * */ 716 if (pSmi->Dualhead && pSmi->HwCursor) { 717 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 718 "HW Cursor disabled in dual head mode\n"); 719 pSmi->HwCursor = FALSE; 720 } 721 } 722 else if (SMI_LYNXM_SERIES(pSmi->Chipset)) { 723 /* tweak options for dualhead */ 724 if (pSmi->Dualhead) { 725 pSmi->useBIOS = FALSE; 726 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "UseBIOS disabled in dualhead mode\n"); 727 pSmi->HwCursor = FALSE; 728 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No hardware cursor in dualhead mode\n"); 729 if (pScrn->bitsPerPixel != 16) { 730 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Dualhead only supported at " 731 "depth 16\n"); 732 LEAVE(FALSE); 733 } 734 } 735 } 736 xf86DrvMsg(pScrn->scrnIndex, from, "Dual head %sabled\n", 737 pSmi->Dualhead ? "en" : "dis"); 738 739 if (!pSmi->NoAccel) { 740 char *strptr; 741 742 from = X_DEFAULT; 743 if ((strptr = (char *)xf86GetOptValString(pSmi->Options, 744 OPTION_ACCELMETHOD))) { 745 if (!xf86NameCmp(strptr,"XAA")) { 746 from = X_CONFIG; 747 pSmi->useEXA = FALSE; 748 } else if(!xf86NameCmp(strptr,"EXA")) { 749 from = X_CONFIG; 750 pSmi->useEXA = TRUE; 751 } 752 } 753 754 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture\n", 755 pSmi->useEXA ? "EXA" : "XAA"); 756 } 757 758 if (IS_MSOC(pSmi)) { 759 pSmi->CSCVideo = !pSmi->useEXA || !pSmi->Dualhead; 760 from = X_DEFAULT; 761 if (xf86GetOptValBool(pSmi->Options, OPTION_CSCVIDEO, &pSmi->CSCVideo)) { 762 from = X_CONFIG; 763 764 /* FIXME */ 765 if (pSmi->CSCVideo && pSmi->useEXA && pSmi->Dualhead) { 766 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 767 "CSCVideo requires XAA or EXA in single head mode.\n"); 768 pSmi->CSCVideo = FALSE; 769 } 770 } 771 772 xf86DrvMsg(pScrn->scrnIndex, from, "CSC Video %sabled\n", 773 pSmi->CSCVideo ? "en" : "dis"); 774 } 775 776 SMI_MapMmio(pScrn); 777 SMI_DetectMem(pScrn); 778 SMI_MapMem(pScrn); 779 SMI_DisableVideo(pScrn); 780 781 /* detect the panel size */ 782 SMI_DetectPanelSize(pScrn); 783 784 if(!IS_MSOC(pSmi)){ 785 if (xf86LoadSubModule(pScrn, "i2c")) { 786 SMI_I2CInit(pScrn); 787 } 788 xf86LoadSubModule(pScrn, "ddc"); 789 } 790 791 /* 792 * If the driver can do gamma correction, it should call xf86SetGamma() 793 */ 794 { 795 Gamma zeros = { 0.0, 0.0, 0.0 }; 796 797 if (!xf86SetGamma(pScrn, zeros)) { 798 SMI_EnableVideo(pScrn); 799 SMI_UnmapMem(pScrn); 800 LEAVE(FALSE); 801 } 802 } 803 804 SMI_DetectMCLK(pScrn); 805 806 /* 807 * Setup the ClockRanges, which describe what clock ranges are available, 808 * and what sort of modes they can be used for. 809 */ 810 pSmi->clockRange.next = NULL; 811 pSmi->clockRange.minClock = 20000; 812 813 if (SMI_LYNXM_SERIES(pSmi->Chipset) || 814 IS_MSOC(pSmi)) 815 pSmi->clockRange.maxClock = 200000; 816 else 817 pSmi->clockRange.maxClock = 135000; 818 819 pSmi->clockRange.clockIndex = -1; 820 pSmi->clockRange.interlaceAllowed = FALSE; 821 pSmi->clockRange.doubleScanAllowed = FALSE; 822 823 if(!SMI_CrtcPreInit(pScrn)) 824 LEAVE(FALSE); 825 826 if(!SMI_OutputPreInit(pScrn)) 827 LEAVE(FALSE); 828 829 /* Only allow growing the screen dimensions if EXA is being used */ 830 if (!xf86InitialConfiguration (pScrn, !pSmi->NoAccel && pSmi->useEXA)){ 831 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 832 833 SMI_EnableVideo(pScrn); 834 SMI_UnmapMem(pScrn); 835 LEAVE(FALSE); 836 } 837 838 /* Ensure that the framebuffer size just set fits in video memory. */ 839 { 840 int aligned_pitch = (pScrn->virtualX*pSmi->Bpp + 15) & ~15; 841 842 if(aligned_pitch * pScrn->virtualY > pSmi->FBReserved){ 843 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Not enough video memory " 844 "for the configured screen size (%dx%d) and color depth.\n", 845 pScrn->virtualX, pScrn->virtualY); 846 847 SMI_EnableVideo(pScrn); 848 SMI_UnmapMem(pScrn); 849 LEAVE(FALSE); 850 } 851 } 852 853 854 SMI_EnableVideo(pScrn); 855 SMI_UnmapMem(pScrn); 856 857 if(pSmi->pVbe){ 858 vbeFree(pSmi->pVbe); 859 pSmi->pVbe = NULL; 860 } 861 if(pSmi->pInt10){ 862 xf86FreeInt10(pSmi->pInt10); 863 pSmi->pInt10 = NULL; 864 } 865 866 /* Set display resolution */ 867 xf86SetDpi(pScrn, 0, 0); 868 869 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 870 SMI_FreeRec(pScrn); 871 LEAVE(FALSE); 872 } 873 874 /* Load XAA or EXA if needed */ 875 if (!pSmi->NoAccel) { 876 if (!pSmi->useEXA) { 877 if (!xf86LoadSubModule(pScrn, "xaa")) { 878 SMI_FreeRec(pScrn); 879 LEAVE(FALSE); 880 } 881 } else { 882 XF86ModReqInfo req; 883 int errmaj, errmin; 884 885 memset(&req, 0, sizeof(XF86ModReqInfo)); 886 req.majorversion = 2; 887 req.minorversion = 1; 888 889 if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, 890 &req, &errmaj, &errmin)) { 891 LoaderErrorMsg(NULL, "exa", errmaj, errmin); 892 SMI_FreeRec(pScrn); 893 LEAVE(FALSE); 894 } 895 } 896 } 897 898 /* Load ramdac if needed */ 899 if (pSmi->HwCursor) { 900 if (!xf86LoadSubModule(pScrn, "ramdac")) { 901 SMI_FreeRec(pScrn); 902 LEAVE(FALSE); 903 } 904 } 905 906 LEAVE(TRUE); 907} 908 909/* 910 * This is called when VT switching back to the X server. Its job is to 911 * reinitialise the video mode. We may wish to unmap video/MMIO memory too. 912 */ 913 914static Bool 915SMI_EnterVT(int scrnIndex, int flags) 916{ 917 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 918 SMIPtr pSmi = SMIPTR(pScrn); 919 920 ENTER(); 921 922 /* Enable MMIO and map memory */ 923 SMI_MapMem(pScrn); 924 925 pSmi->Save(pScrn); 926 927 /* FBBase may have changed after remapping the memory */ 928 pScrn->pScreen->ModifyPixmapHeader(pScrn->pScreen->GetScreenPixmap(pScrn->pScreen), 929 -1,-1,-1,-1,-1, pSmi->FBBase + pSmi->FBOffset); 930 pScrn->pixmapPrivate.ptr=pSmi->FBBase + pSmi->FBOffset; 931 932 if(pSmi->useEXA) 933 pSmi->EXADriverPtr->memoryBase=pSmi->FBBase; 934 935 /* Do the CRTC independent initialization */ 936 if(!SMI_HWInit(pScrn)) 937 LEAVE(FALSE); 938 939 /* Initialize the chosen modes */ 940 if (!xf86SetDesiredModes(pScrn)) 941 LEAVE(FALSE); 942 943 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 944 "Done writing mode. Register dump:\n"); 945 SMI_PrintRegs(pScrn); 946 947 /* Reset the grapics engine */ 948 if (!pSmi->NoAccel) 949 SMI_EngineReset(pScrn); 950 951 LEAVE(TRUE); 952} 953 954/* 955 * This is called when VT switching away from the X server. Its job is to 956 * restore the previous (text) mode. We may wish to remap video/MMIO memory 957 * too. 958 */ 959 960static void 961SMI_LeaveVT(int scrnIndex, int flags) 962{ 963 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 964 SMIPtr pSmi = SMIPTR(pScrn); 965 966 ENTER(); 967 968 SMI_AccelSync(pScrn); 969 970 /* Ensure that the rotation BlockHandler is unwrapped, and the shadow 971 pixmaps are deallocated, as the video memory is going to be 972 unmapped. */ 973 xf86RotateCloseScreen(pScrn->pScreen); 974 975 /* Pixmaps that by chance get allocated near the former aperture 976 address shouldn't be considered offscreen. */ 977 if(pSmi->useEXA) 978 pSmi->EXADriverPtr->memoryBase=NULL; 979 980 /* Clear frame buffer */ 981 memset(pSmi->FBBase, 0, pSmi->videoRAMBytes); 982 983 if (!IS_MSOC(pSmi)) { 984 vgaHWPtr hwp = VGAHWPTR(pScrn); 985 986 SMILynx_WriteMode(pScrn, &hwp->SavedReg, pSmi->save); 987 } 988 else 989 SMI501_WriteMode(pScrn, pSmi->save); 990 991 SMI_UnmapMem(pScrn); 992 993 LEAVE(); 994} 995 996static void 997SMI_DetectPanelSize(ScrnInfoPtr pScrn) 998{ 999 char *s; 1000 int width, height; 1001 SMIPtr pSmi = SMIPTR(pScrn); 1002 1003 pSmi->lcdWidth = 0; 1004 pSmi->lcdHeight = 0; 1005 if ((s = xf86GetOptValString(pSmi->Options, OPTION_PANEL_SIZE)) != NULL) { 1006 if (sscanf(s, "%dx%d", &width, &height) != 2) 1007 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1008 "Invalid PanelSize option: %s\n", s); 1009 else { 1010 pSmi->lcdWidth = width; 1011 pSmi->lcdHeight = height; 1012 } 1013 } 1014 1015 if (pSmi->lcdWidth == 0 || pSmi->lcdHeight == 0) { 1016 /* panel size detection ... requires BIOS call on 730 hardware */ 1017 if (pSmi->Chipset == SMI_COUGAR3DR) { 1018 if (pSmi->pInt10 != NULL) { 1019 pSmi->pInt10->num = 0x10; 1020 pSmi->pInt10->ax = 0x5F00; 1021 pSmi->pInt10->bx = 0; 1022 pSmi->pInt10->cx = 0; 1023 pSmi->pInt10->dx = 0; 1024 xf86ExecX86int10(pSmi->pInt10); 1025 if (pSmi->pInt10->ax == 0x005F) { 1026 switch (pSmi->pInt10->cx & 0x0F) { 1027 case PANEL_640x480: 1028 pSmi->lcdWidth = 640; 1029 pSmi->lcdHeight = 480; 1030 break; 1031 case PANEL_800x600: 1032 pSmi->lcdWidth = 800; 1033 pSmi->lcdHeight = 600; 1034 break; 1035 case PANEL_1024x768: 1036 pSmi->lcdWidth = 1024; 1037 pSmi->lcdHeight = 768; 1038 break; 1039 case PANEL_1280x1024: 1040 pSmi->lcdWidth = 1280; 1041 pSmi->lcdHeight = 1024; 1042 break; 1043 case PANEL_1600x1200: 1044 pSmi->lcdWidth = 1600; 1045 pSmi->lcdHeight = 1200; 1046 break; 1047 case PANEL_1400x1050: 1048 pSmi->lcdWidth = 1400; 1049 pSmi->lcdHeight = 1050; 1050 break; 1051 } 1052 1053 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1054 "Detected panel size via BIOS: %d x %d\n", 1055 pSmi->lcdWidth, pSmi->lcdHeight); 1056 } 1057 else 1058 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1059 "BIOS error during 730 panel detection!\n"); 1060 } 1061 else { 1062 /* int10 support isn't setup on the second call to this function, 1063 o if this is the second call, don't do detection again */ 1064 if (pSmi->lcd == 0) 1065 /* If we get here, int10 support is not loaded or not working */ 1066 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1067 "No BIOS support for 730 panel detection!\n"); 1068 } 1069 1070 /* Set this to indicate that we've done the detection */ 1071 pSmi->lcd = 1; 1072 } 1073 else if (IS_MSOC(pSmi)) { 1074 pSmi->lcdWidth = (READ_SCR(pSmi, PANEL_WWIDTH) >> 16) & 2047; 1075 pSmi->lcdHeight = (READ_SCR(pSmi, PANEL_WHEIGHT) >> 16) & 2047; 1076 } 1077 else { 1078 /* panel size detection for hardware other than 730 */ 1079 pSmi->lcd = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 1080 0x31) & 0x01; 1081 1082 if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 1083 0x30) & 0x01) { 1084 pSmi->lcd <<= 1; 1085 } 1086 switch (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 1087 0x30) & 0x0C) { 1088 case 0x00: 1089 pSmi->lcdWidth = 640; 1090 pSmi->lcdHeight = 480; 1091 break; 1092 case 0x04: 1093 pSmi->lcdWidth = 800; 1094 pSmi->lcdHeight = 600; 1095 break; 1096 case 0x08: 1097 if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 1098 0x74) & 0x02) { 1099 pSmi->lcdWidth = 1024; 1100 pSmi->lcdHeight = 600; 1101 } 1102 else { 1103 pSmi->lcdWidth = 1024; 1104 pSmi->lcdHeight = 768; 1105 } 1106 break; 1107 case 0x0C: 1108 pSmi->lcdWidth = 1280; 1109 pSmi->lcdHeight = 1024; 1110 break; 1111 } 1112 } 1113 } 1114 1115 if (!pSmi->lcdWidth && (pSmi->lcdWidth = pScrn->virtualX) == 0) 1116 pSmi->lcdWidth = 1024; 1117 if (!pSmi->lcdHeight && (pSmi->lcdHeight = pScrn->virtualY) == 0) 1118 pSmi->lcdHeight = 768; 1119 1120 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s Panel Size = %dx%d\n", 1121 (pSmi->lcd == 0) ? "OFF" : (pSmi->lcd == 1) ? "TFT" : "DSTN", 1122 pSmi->lcdWidth, pSmi->lcdHeight); 1123 1124} 1125 1126static void 1127SMI_DetectMCLK(ScrnInfoPtr pScrn) 1128{ 1129 double real; 1130 MSOCClockRec clock; 1131 int mclk, mxclk; 1132 SMIPtr pSmi = SMIPTR(pScrn); 1133 1134 /* MCLK defaults */ 1135 if (pSmi->Chipset == SMI_LYNXEMplus){ 1136 /* The SM712 can be safely clocked up to 157MHz, according to 1137 Silicon Motion engineers. */ 1138 pSmi->MCLK = 157000; 1139 1140 } else if (IS_MSOC(pSmi)) { 1141 /* Set some sane defaults for the clock settings if we are on a 1142 SM502 and it's likely to be uninitialized. */ 1143 1144 if (!xf86IsPrimaryPci(pSmi->PciInfo) && 1145 (READ_SCR(pSmi, DEVICE_ID) & 0xFF) >= 0xC0) { 1146 pSmi->MCLK = 112000; 1147 pSmi->MXCLK = 144000; 1148 } 1149 1150 } else { 1151 pSmi->MCLK = 0; 1152 pSmi->MXCLK = 0; 1153 } 1154 1155 /* MCLK from user settings */ 1156 if (xf86GetOptValFreq(pSmi->Options, OPTION_MCLK, OPTUNITS_MHZ, &real)) { 1157 if (IS_MSOC(pSmi) || (int)real <= 120) { 1158 pSmi->MCLK = (int)(real * 1000.0); 1159 } else { 1160 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1161 "Memory Clock %1.3f MHz larger than limit of 120 MHz\n", 1162 real); 1163 } 1164 } 1165 mclk = pSmi->MCLK; 1166 1167 if (IS_MSOC(pSmi)) { 1168 clock.value = READ_SCR(pSmi, CURRENT_CLOCK); 1169 if (xf86GetOptValFreq(pSmi->Options, OPTION_MXCLK, 1170 OPTUNITS_MHZ, &real)) 1171 pSmi->MXCLK = (int)(real * 1000.0); 1172 } 1173 1174 /* Already programmed MCLK */ 1175 if (pSmi->MCLK == 0) { 1176 if (IS_MSOC(pSmi)) 1177 mclk = ((clock.f.m_select ? 336 : 288) / 1178 ((clock.f.m_divider ? 3 : 1) << 1179 (unsigned)clock.f.m_shift)) * 1000; 1180 else { 1181 unsigned char shift, m, n; 1182 1183 m = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A); 1184 n = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B); 1185 switch (n >> 6) { 1186 case 1: 1187 shift = 4; 1188 break; 1189 case 2: 1190 shift = 2; 1191 break; 1192 default: 1193 shift = 1; 1194 break; 1195 } 1196 n &= 0x3F; 1197 mclk = ((1431818 * m) / n / shift + 50) / 100; 1198 } 1199 } 1200 1201 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MCLK = %1.3f\n", mclk / 1000.0); 1202 if (IS_MSOC(pSmi)) { 1203 if (pSmi->MXCLK == 0) { 1204 mxclk = ((clock.f.m1_select ? 336 : 288) / 1205 ((clock.f.m1_divider ? 3 : 1) << 1206 (unsigned)clock.f.m1_shift)) * 1000; 1207 } 1208 else 1209 mxclk = pSmi->MXCLK; 1210 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MXCLK = %1.3f\n", mxclk / 1000.0); 1211 } 1212} 1213 1214static Bool 1215SMI_MapMmio(ScrnInfoPtr pScrn) 1216{ 1217 SMIPtr pSmi = SMIPTR(pScrn); 1218 CARD32 memBase; 1219 1220 SMI_EnableMmio(pScrn); 1221 1222 switch (pSmi->Chipset) { 1223 case SMI_COUGAR3DR: 1224 memBase = PCI_REGION_BASE(pSmi->PciInfo, 1, REGION_MEM); 1225 pSmi->MapSize = 0x200000; 1226 break; 1227 case SMI_LYNX3D: 1228 memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + 0x680000; 1229 pSmi->MapSize = 0x180000; 1230 break; 1231 case SMI_LYNXEM: 1232 case SMI_LYNXEMplus: 1233 memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + 0x400000; 1234 pSmi->MapSize = 0x400000; 1235 break; 1236 case SMI_LYNX3DM: 1237 memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM); 1238 pSmi->MapSize = 0x200000; 1239 break; 1240 case SMI_MSOC: 1241 memBase = PCI_REGION_BASE(pSmi->PciInfo, 1, REGION_MEM); 1242 pSmi->MapSize = 0x200000; 1243 break; 1244 default: 1245 memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + 0x400000; 1246 pSmi->MapSize = 0x10000; 1247 break; 1248 } 1249 1250#ifndef XSERVER_LIBPCIACCESS 1251 pSmi->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pSmi->PciTag, 1252 memBase, pSmi->MapSize); 1253#else 1254 { 1255 void **result = (void**)&pSmi->MapBase; 1256 int err = pci_device_map_range(pSmi->PciInfo, 1257 memBase, 1258 pSmi->MapSize, 1259 PCI_DEV_MAP_FLAG_WRITABLE, 1260 result); 1261 1262 if (err) 1263 return (FALSE); 1264 } 1265#endif 1266 1267 if (pSmi->MapBase == NULL) { 1268 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Internal error: could not map " 1269 "MMIO registers.\n"); 1270 return (FALSE); 1271 } 1272 1273 switch (pSmi->Chipset) { 1274 case SMI_COUGAR3DR: 1275 pSmi->DPRBase = pSmi->MapBase + 0x000000; 1276 pSmi->VPRBase = pSmi->MapBase + 0x000800; 1277 pSmi->CPRBase = pSmi->MapBase + 0x001000; 1278 pSmi->FPRBase = pSmi->MapBase + 0x005800; 1279 pSmi->IOBase = pSmi->MapBase + 0x0C0000; 1280 pSmi->DataPortBase = pSmi->MapBase + 0x100000; 1281 pSmi->DataPortSize = 0x100000; 1282 break; 1283 case SMI_LYNX3D: 1284 pSmi->DPRBase = pSmi->MapBase + 0x000000; 1285 pSmi->VPRBase = pSmi->MapBase + 0x000800; 1286 pSmi->CPRBase = pSmi->MapBase + 0x001000; 1287 pSmi->IOBase = pSmi->MapBase + 0x040000; 1288 pSmi->DataPortBase = pSmi->MapBase + 0x080000; 1289 pSmi->DataPortSize = 0x100000; 1290 break; 1291 case SMI_LYNXEM: 1292 case SMI_LYNXEMplus: 1293 pSmi->DPRBase = pSmi->MapBase + 0x008000; 1294 pSmi->VPRBase = pSmi->MapBase + 0x00C000; 1295 pSmi->CPRBase = pSmi->MapBase + 0x00E000; 1296 pSmi->IOBase = pSmi->MapBase + 0x300000; 1297 pSmi->DataPortBase = pSmi->MapBase /*+ 0x100000*/; 1298 pSmi->DataPortSize = 0x8000 /*0x200000*/; 1299 break; 1300 case SMI_LYNX3DM: 1301 pSmi->DPRBase = pSmi->MapBase + 0x000000; 1302 pSmi->VPRBase = pSmi->MapBase + 0x000800; 1303 pSmi->CPRBase = pSmi->MapBase + 0x001000; 1304 pSmi->IOBase = pSmi->MapBase + 0x0C0000; 1305 pSmi->DataPortBase = pSmi->MapBase + 0x100000; 1306 pSmi->DataPortSize = 0x100000; 1307 break; 1308 case SMI_MSOC: 1309 pSmi->DPRBase = pSmi->MapBase + 0x100000; 1310 pSmi->VPRBase = pSmi->MapBase + 0x000000; 1311 pSmi->CPRBase = pSmi->MapBase + 0x090000; 1312 pSmi->DCRBase = pSmi->MapBase + 0x080000; 1313 pSmi->SCRBase = pSmi->MapBase + 0x000000; 1314 pSmi->IOBase = 0; 1315 pSmi->DataPortBase = pSmi->MapBase + 0x110000; 1316 pSmi->DataPortSize = 0x10000; 1317 break; 1318 default: 1319 pSmi->DPRBase = pSmi->MapBase + 0x8000; 1320 pSmi->VPRBase = pSmi->MapBase + 0xC000; 1321 pSmi->CPRBase = pSmi->MapBase + 0xE000; 1322 pSmi->IOBase = NULL; 1323 pSmi->DataPortBase = pSmi->MapBase; 1324 pSmi->DataPortSize = 0x8000; 1325 break; 1326 } 1327 1328 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 1329 "Physical MMIO at 0x%08lX\n", (unsigned long)memBase); 1330 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 1331 "Logical MMIO at %p - %p\n", pSmi->MapBase, 1332 pSmi->MapBase + pSmi->MapSize - 1); 1333 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 1334 "DPR=%p, VPR=%p, IOBase=%p\n", 1335 pSmi->DPRBase, pSmi->VPRBase, pSmi->IOBase); 1336 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 1337 "DataPort=%p - %p\n", pSmi->DataPortBase, 1338 pSmi->DataPortBase + pSmi->DataPortSize - 1); 1339 1340 return (TRUE); 1341} 1342 1343/* HACK - In some cases the BIOS hasn't filled in the "scratchpad 1344 registers" (SR71) with the right amount of memory installed (e.g. MIPS 1345 platform). Probe it manually. */ 1346static unsigned long 1347SMI_ProbeMem(ScrnInfoPtr pScrn, unsigned long mem_skip, unsigned long mem_max) 1348{ 1349 SMIPtr pSmi = SMIPTR(pScrn); 1350 unsigned long mem_probe = 1024*1024; 1351 unsigned long aperture_base; 1352 void* mem; 1353 1354 ENTER(); 1355 1356 aperture_base = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + mem_skip; 1357 mem_max = min(mem_max , PCI_REGION_SIZE(pSmi->PciInfo, 0) - mem_skip); 1358 1359#ifndef XSERVER_LIBPCIACCESS 1360 mem = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pSmi->PciTag, 1361 aperture_base, mem_max); 1362 1363 if(!mem) 1364 LEAVE(0); 1365#else 1366 if(pci_device_map_range(pSmi->PciInfo, aperture_base, mem_max, 1367 PCI_DEV_MAP_FLAG_WRITABLE, &mem)) 1368 LEAVE(0); 1369#endif 1370 1371 while(mem_probe <= mem_max){ 1372 MMIO_OUT32(mem, mem_probe-4, 0x55555555); 1373 if(MMIO_IN32(mem, mem_probe-4) != 0x55555555) 1374 break; 1375 1376 MMIO_OUT32(mem, mem_probe-4, 0xAAAAAAAA); 1377 if(MMIO_IN32(mem, mem_probe-4) != 0xAAAAAAAA) 1378 break; 1379 1380 mem_probe <<= 1; 1381 } 1382 1383#ifndef XSERVER_LIBPCIACCESS 1384 xf86UnMapVidMem(pScrn->scrnIndex, mem, mem_max); 1385#else 1386 pci_device_unmap_range(pSmi->PciInfo, mem, mem_max); 1387#endif 1388 1389 LEAVE(mem_probe >> 1); 1390} 1391 1392static Bool 1393SMI_DetectMem(ScrnInfoPtr pScrn) 1394{ 1395 SMIPtr pSmi = SMIPTR(pScrn); 1396 MessageType from; 1397 1398 if ((pScrn->videoRam = pScrn->confScreen->device->videoRam)){ 1399 pSmi->videoRAMKBytes = pScrn->videoRam; 1400 from = X_CONFIG; 1401 } 1402 else { 1403 unsigned char config; 1404 static int lynx3d_table[4] = { 0, 2, 4, 6 }; 1405 static int lynx3dm_table[4] = { 16, 2, 4, 8 }; 1406 static int msoc_table[8] = { 4, 8, 16, 32, 64, 2, 0, 0 }; 1407 static int default_table[4] = { 1, 2, 4, 0 }; 1408 1409 if (IS_MSOC(pSmi)) { 1410 config = (READ_SCR(pSmi, DRAM_CTL) >> 13) & 7; 1411 pSmi->videoRAMKBytes = msoc_table[config] * 1024 - 1412 SHARED_USB_DMA_BUFFER_SIZE; 1413 } 1414 else { 1415 config = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x71); 1416 switch (pSmi->Chipset) { 1417 case SMI_LYNX3D: 1418 pSmi->videoRAMKBytes = lynx3d_table[config >> 6] * 1024 + 1419 512; 1420 break; 1421 case SMI_LYNXEMplus: 1422 pSmi->videoRAMKBytes = SMI_ProbeMem(pScrn, 0, 0x400000) / 1024; 1423 break; 1424 case SMI_LYNX3DM: 1425 pSmi->videoRAMKBytes = lynx3dm_table[config >> 6] * 1024; 1426 break; 1427 case SMI_COUGAR3DR: 1428 /* DANGER - Cougar3DR BIOS is broken - hardcode video ram 1429 * size per instructions from Silicon Motion engineers */ 1430 pSmi->videoRAMKBytes = 16 * 1024; 1431 break; 1432 default: 1433 pSmi->videoRAMKBytes = default_table[config >> 6] * 1024; 1434 break; 1435 } 1436 } 1437 from = X_PROBED; 1438 } 1439 1440 pSmi->videoRAMBytes = pSmi->videoRAMKBytes * 1024; 1441 pScrn->videoRam = pSmi->videoRAMKBytes; 1442 xf86DrvMsg(pScrn->scrnIndex, from, 1443 "videoram: %dkB\n", pSmi->videoRAMKBytes); 1444 1445 return (TRUE); 1446} 1447 1448Bool 1449SMI_MapMem(ScrnInfoPtr pScrn) 1450{ 1451 SMIPtr pSmi = SMIPTR(pScrn); 1452 vgaHWPtr hwp; 1453 1454 ENTER(); 1455 1456 if (pSmi->MapBase == NULL && SMI_MapMmio(pScrn) == FALSE) 1457 LEAVE(FALSE); 1458 1459 pScrn->memPhysBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM); 1460 1461 if (pSmi->Chipset == SMI_LYNX3DM) 1462 pSmi->fbMapOffset = 0x200000; 1463 else 1464 pSmi->fbMapOffset = 0x0; 1465 1466#ifndef XSERVER_LIBPCIACCESS 1467 pSmi->FBBase = xf86MapPciMem(pScrn->scrnIndex, 1468 VIDMEM_FRAMEBUFFER, 1469 pSmi->PciTag, 1470 pScrn->memPhysBase + pSmi->fbMapOffset, 1471 pSmi->videoRAMBytes); 1472#else 1473 { 1474 void **result = (void**)&pSmi->FBBase; 1475 int err = pci_device_map_range(pSmi->PciInfo, 1476 pScrn->memPhysBase + 1477 pSmi->fbMapOffset, 1478 pSmi->videoRAMBytes, 1479 PCI_DEV_MAP_FLAG_WRITABLE | 1480 PCI_DEV_MAP_FLAG_WRITE_COMBINE, 1481 result); 1482 1483 if (err) 1484 LEAVE(FALSE); 1485 } 1486#endif 1487 1488 if (pSmi->FBBase == NULL) { 1489 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1490 "Internal error: could not map framebuffer.\n"); 1491 LEAVE(FALSE); 1492 } 1493 1494 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 1495 "Physical frame buffer at 0x%08lX offset: 0x%08lX\n", 1496 pScrn->memPhysBase, pSmi->fbMapOffset); 1497 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 1498 "Logical frame buffer at %p - %p\n", pSmi->FBBase, 1499 pSmi->FBBase + pSmi->videoRAMBytes - 1); 1500 1501 if (IS_MSOC(pSmi)) { 1502 /* Reserve space for panel cursr, and crt if in dual head mode */ 1503#if SMI_CURSOR_ALPHA_PLANE 1504 pSmi->FBReserved = pSmi->FBCursorOffset = pSmi->videoRAMBytes - 1505 (pSmi->Dualhead ? SMI501_CURSOR_SIZE << 1 : SMI501_ARGB_CURSOR_SIZE); 1506#else 1507 pSmi->FBReserved = pSmi->FBCursorOffset = pSmi->videoRAMBytes - 1508 (pSmi->Dualhead ? SMI501_CURSOR_SIZE << 1 : SMI501_CURSOR_SIZE); 1509 1510# if SMI501_CLI_DEBUG 1511 if (pSmi->useEXA) { 1512 pSmi->batch_active = FALSE; 1513 pSmi->batch_length = 4096; 1514 pSmi->FBReserved -= pSmi->batch_length << 3; 1515 pSmi->batch_offset = pSmi->FBReserved; 1516 pSmi->batch_handle = (int64_t *)(pSmi->FBBase + pSmi->batch_offset); 1517 pSmi->batch_finish = -1; 1518 pSmi->batch_index = 0; 1519 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1520 "Using command list interpreter debug code\n"); 1521 } 1522# endif 1523 1524#endif 1525 } 1526 else { 1527 /* Set up offset to hwcursor memory area, at the end of 1528 * the frame buffer. 1529 */ 1530 pSmi->FBCursorOffset = pSmi->videoRAMBytes - SMILYNX_CURSOR_SIZE; 1531 /* set up the fifo reserved space */ 1532 if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30) & 0x01)/* #1074 */ { 1533 CARD32 fifoOffset = 0; 1534 fifoOffset |= VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 1535 0x46) << 3; 1536 fifoOffset |= VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 1537 0x47) << 11; 1538 fifoOffset |= (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 1539 0x49) & 0x1C) << 17; 1540 pSmi->FBReserved = fifoOffset; /* PDR#1074 */ 1541 } 1542 else 1543 pSmi->FBReserved = pSmi->videoRAMBytes - 2048; 1544 1545 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Cursor Offset: %08lX\n", 1546 (unsigned long)pSmi->FBCursorOffset); 1547 1548 /* Assign hwp->MemBase & IOBase here */ 1549 hwp = VGAHWPTR(pScrn); 1550 if (pSmi->IOBase != NULL) 1551 vgaHWSetMmioFuncs(hwp, pSmi->MapBase, pSmi->IOBase - pSmi->MapBase); 1552 vgaHWGetIOBase(hwp); 1553 1554 /* Map the VGA memory when the primary video */ 1555 if (xf86IsPrimaryPci(pSmi->PciInfo)) { 1556 hwp->MapSize = 0x10000; 1557 if (!vgaHWMapMem(pScrn)) 1558 LEAVE(FALSE); 1559 pSmi->PrimaryVidMapped = TRUE; 1560 } 1561 } 1562 1563 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reserved: %08lX\n", 1564 (unsigned long)pSmi->FBReserved); 1565 1566 LEAVE(TRUE); 1567} 1568 1569/* UnMapMem - contains half of pre-4.0 EnterLeave function. The EnterLeave 1570 * function which en/disable access to IO ports and ext. regs 1571 */ 1572 1573void 1574SMI_UnmapMem(ScrnInfoPtr pScrn) 1575{ 1576 SMIPtr pSmi = SMIPTR(pScrn); 1577 1578 ENTER(); 1579 1580 /* Unmap VGA mem if mapped. */ 1581 if (pSmi->PrimaryVidMapped) { 1582 vgaHWUnmapMem(pScrn); 1583 pSmi->PrimaryVidMapped = FALSE; 1584 } 1585 1586 SMI_DisableMmio(pScrn); 1587 1588 if (pSmi->MapBase) { 1589#ifndef XSERVER_LIBPCIACCESS 1590 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSmi->MapBase, 1591 pSmi->MapSize); 1592#else 1593 pci_device_unmap_range(pSmi->PciInfo, (pointer)pSmi->MapBase, 1594 pSmi->MapSize); 1595#endif 1596 pSmi->MapBase = NULL; 1597 } 1598 1599 if (pSmi->FBBase) { 1600#ifndef XSERVER_LIBPCIACCESS 1601 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pSmi->FBBase, 1602 pSmi->videoRAMBytes); 1603#else 1604 pci_device_unmap_range(pSmi->PciInfo, (pointer)pSmi->FBBase, 1605 pSmi->videoRAMBytes); 1606#endif 1607 pSmi->FBBase = NULL; 1608 } 1609 1610 LEAVE(); 1611} 1612 1613/* This gets called at the start of each server generation. */ 1614 1615static Bool 1616SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 1617{ 1618 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1619 SMIPtr pSmi = SMIPTR(pScrn); 1620 EntityInfoPtr pEnt; 1621 1622 ENTER(); 1623 1624 /* Map MMIO regs and framebuffer */ 1625 if (!SMI_MapMem(pScrn)) 1626 LEAVE(FALSE); 1627 1628 pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 1629 1630 if (!pSmi->pInt10 && pSmi->useBIOS) { 1631 pSmi->pInt10 = xf86InitInt10(pEnt->index); 1632 } 1633 if (!pSmi->pVbe && pSmi->pInt10 && xf86LoaderCheckSymbol("VBEInit")) { 1634 pSmi->pVbe = VBEInit(pSmi->pInt10, pEnt->index); 1635 } 1636 1637 /* Save the chip/graphics state */ 1638 pSmi->Save(pScrn); 1639 1640 /* Fill in some needed pScrn fields */ 1641 pScrn->vtSema = TRUE; 1642 pScrn->pScreen = pScreen; 1643 1644 pScrn->displayWidth = ((pScrn->virtualX * pSmi->Bpp + 15) & ~15) / pSmi->Bpp; 1645 1646 pSmi->fbArea = NULL; 1647 pSmi->FBOffset = 0; 1648 pScrn->fbOffset = pSmi->FBOffset + pSmi->fbMapOffset; 1649 1650 /* Clear frame buffer */ 1651 memset(pSmi->FBBase, 0, pSmi->videoRAMBytes); 1652 1653 /* 1654 * The next step is to setup the screen's visuals, and initialise the 1655 * framebuffer code. In cases where the framebuffer's default choises for 1656 * things like visual layouts and bits per RGB are OK, this may be as simple 1657 * as calling the framebuffer's ScreenInit() function. If not, the visuals 1658 * will need to be setup before calling a fb ScreenInit() function and fixed 1659 * up after. 1660 */ 1661 1662 /* 1663 * Reset the visual list. 1664 */ 1665 miClearVisualTypes(); 1666 1667 /* Setup the visuals we support. */ 1668 1669 if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 1670 pScrn->rgbBits, pScrn->defaultVisual)) 1671 LEAVE(FALSE); 1672 1673 if (!miSetPixmapDepths ()) 1674 LEAVE(FALSE); 1675 1676 /* 1677 * Call the framebuffer layer's ScreenInit function 1678 */ 1679 1680 DEBUG("\tInitializing FB @ 0x%08X for %dx%d (%d)\n", 1681 pSmi->FBBase, pScrn->virtualX, pScrn->virtualY, pScrn->displayWidth); 1682 if(!fbScreenInit(pScreen, pSmi->FBBase, pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, 1683 pScrn->yDpi, pScrn->displayWidth, pScrn->bitsPerPixel)) 1684 LEAVE(FALSE); 1685 1686 xf86SetBlackWhitePixels(pScreen); 1687 1688 if (pScrn->bitsPerPixel > 8) { 1689 VisualPtr visual; 1690 /* Fixup RGB ordering */ 1691 visual = pScreen->visuals + pScreen->numVisuals; 1692 while (--visual >= pScreen->visuals) { 1693 if ((visual->class | DynamicClass) == DirectColor) { 1694 visual->offsetRed = pScrn->offset.red; 1695 visual->offsetGreen = pScrn->offset.green; 1696 visual->offsetBlue = pScrn->offset.blue; 1697 visual->redMask = pScrn->mask.red; 1698 visual->greenMask = pScrn->mask.green; 1699 visual->blueMask = pScrn->mask.blue; 1700 } 1701 } 1702 } 1703 1704 /* must be after RGB ordering fixed */ 1705 fbPictureInit(pScreen, 0, 0); 1706 1707 /* Do the CRTC independent initialization */ 1708 if(!SMI_HWInit(pScrn)) 1709 LEAVE(FALSE); 1710 1711 /* Unless using EXA, regardless or using XAA or not, needs offscreen 1712 * management at least for video. */ 1713 if (pSmi->NoAccel || !pSmi->useEXA) { 1714 int numLines; 1715 BoxRec AvailFBArea; 1716 1717 numLines = pSmi->FBReserved / (pScrn->displayWidth * pSmi->Bpp); 1718 AvailFBArea.x1 = 0; 1719 AvailFBArea.y1 = 0; 1720 AvailFBArea.x2 = pScrn->virtualX; 1721 AvailFBArea.y2 = numLines; 1722 1723 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1724 "FrameBuffer Box: %d,%d - %d,%d\n", 1725 AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, 1726 AvailFBArea.y2); 1727 1728 xf86InitFBManager(pScreen, &AvailFBArea); 1729 } 1730 1731 /* Initialize acceleration layer */ 1732 if (!pSmi->NoAccel) { 1733 if (pSmi->useEXA && !SMI_EXAInit(pScreen)) 1734 LEAVE(FALSE); 1735 else if (!pSmi->useEXA && !SMI_XAAInit(pScreen)) 1736 LEAVE(FALSE); 1737 } 1738 1739 /* Initialize the chosen modes */ 1740 if (!xf86SetDesiredModes(pScrn)) 1741 LEAVE(FALSE); 1742 1743 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 1744 "Done writing mode. Register dump:\n"); 1745 SMI_PrintRegs(pScrn); 1746 1747 miInitializeBackingStore(pScreen); 1748 1749#ifdef HAVE_XMODES 1750 xf86DiDGAInit(pScreen, (unsigned long)(pSmi->FBBase + pScrn->fbOffset)); 1751#endif 1752 1753 /* Initialise cursor functions */ 1754 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 1755 1756 /* Initialize HW cursor layer. Must follow software cursor 1757 * initialization. 1758 */ 1759 if (pSmi->HwCursor) { 1760 int size, flags; 1761 1762 if (IS_MSOC(pSmi)) { 1763 size = SMI501_MAX_CURSOR; 1764 flags = (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | 1765 HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK); 1766#if SMI_CURSOR_ALPHA_PLANE 1767 if (!pSmi->Dualhead) 1768 flags |= HARDWARE_CURSOR_ARGB; 1769#endif 1770 } 1771 else { 1772 size = SMILYNX_MAX_CURSOR; 1773 flags = (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 | 1774 HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | 1775 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 1776 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 1777 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 1778 HARDWARE_CURSOR_INVERT_MASK); 1779 } 1780 1781 if (!xf86_cursors_init(pScreen, size, size, flags)) 1782 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1783 "Hardware cursor initialization failed\n"); 1784 } 1785 1786 /* Initialise default colormap */ 1787 if (!miCreateDefColormap(pScreen)) 1788 LEAVE(FALSE); 1789 1790 /* Initialize colormap layer. Must follow initialization of the default 1791 * colormap. And SetGamma call, else it will load palette with solid white. 1792 */ 1793 if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,SMI_LoadPalette, NULL, 1794 CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) 1795 LEAVE(FALSE); 1796 1797 pScreen->SaveScreen = SMI_SaveScreen; 1798 pSmi->CloseScreen = pScreen->CloseScreen; 1799 pScreen->CloseScreen = SMI_CloseScreen; 1800 1801 if ((IS_MSOC(pSmi) && 1802 !xf86DPMSInit(pScreen, SMI501_DisplayPowerManagementSet, 0)) || 1803 (!IS_MSOC(pSmi) && 1804 !xf86DPMSInit(pScreen, SMILynx_DisplayPowerManagementSet, 0))) 1805 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed!\n"); 1806 1807 SMI_InitVideo(pScreen); 1808 1809 if(!xf86CrtcScreenInit(pScreen)) 1810 LEAVE(FALSE); 1811 1812 /* Report any unused options (only for the first generation) */ 1813 if (serverGeneration == 1) { 1814 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 1815 } 1816 1817 LEAVE(TRUE); 1818} 1819 1820/* 1821 * This is called at the end of each server generation. It restores the 1822 * original (text) mode. It should also unmap the video memory, and free any 1823 * per-generation data allocated by the driver. It should finish by unwrapping 1824 * and calling the saved CloseScreen function. 1825 */ 1826 1827static Bool 1828SMI_CloseScreen(int scrnIndex, ScreenPtr pScreen) 1829{ 1830 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1831 SMIPtr pSmi = SMIPTR(pScrn); 1832 Bool ret; 1833 1834 ENTER(); 1835 1836 if (pSmi->HwCursor) 1837 xf86_cursors_fini(pScreen); 1838 1839 if (pScrn->vtSema) 1840 /* Restore console mode and unmap framebuffer */ 1841 SMI_LeaveVT(scrnIndex, 0); 1842 1843 if (pSmi->XAAInfoRec != NULL) { 1844 XAADestroyInfoRec(pSmi->XAAInfoRec); 1845 } 1846 if (pSmi->EXADriverPtr) { 1847 exaDriverFini(pScreen); 1848 pSmi->EXADriverPtr = NULL; 1849 } 1850 if (pSmi->pVbe != NULL) { 1851 vbeFree(pSmi->pVbe); 1852 pSmi->pVbe = NULL; 1853 } 1854 if (pSmi->pInt10 != NULL) { 1855 xf86FreeInt10(pSmi->pInt10); 1856 pSmi->pInt10 = NULL; 1857 } 1858 if (pSmi->ptrAdaptor != NULL) { 1859 xfree(pSmi->ptrAdaptor); 1860 } 1861 if (pSmi->BlockHandler != NULL) { 1862 pScreen->BlockHandler = pSmi->BlockHandler; 1863 } 1864 1865 pScrn->vtSema = FALSE; 1866 pScreen->CloseScreen = pSmi->CloseScreen; 1867 ret = (*pScreen->CloseScreen)(scrnIndex, pScreen); 1868 1869 LEAVE(ret); 1870} 1871 1872static void 1873SMI_FreeScreen(int scrnIndex, int flags) 1874{ 1875 SMI_FreeRec(xf86Screens[scrnIndex]); 1876} 1877 1878static Bool 1879SMI_SaveScreen(ScreenPtr pScreen, int mode) 1880{ 1881 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1882 1883 ENTER(); 1884 1885 if(xf86IsUnblank(mode)){ 1886 pScrn->DPMSSet(pScrn, DPMSModeOn, 0); 1887 }else{ 1888 pScrn->DPMSSet(pScrn, DPMSModeOff, 0); 1889 } 1890 1891 LEAVE(TRUE); 1892} 1893 1894void 1895SMI_AdjustFrame(int scrnIndex, int x, int y, int flags) 1896{ 1897 xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(xf86Screens[scrnIndex]); 1898 xf86CrtcPtr compat_crtc = crtcConf->output[crtcConf->compat_output]->crtc; 1899 1900 ENTER(); 1901 1902 SMICRTC(compat_crtc)->adjust_frame(compat_crtc,x,y); 1903 1904 LEAVE(); 1905} 1906 1907Bool 1908SMI_SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 1909{ 1910 Bool ret; 1911 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1912 SMIPtr pSmi = SMIPTR(pScrn); 1913 1914 ENTER(); 1915 1916 ret = xf86SetSingleMode(pScrn, mode, RR_Rotate_0); 1917 1918 if (!pSmi->NoAccel) 1919 SMI_EngineReset(pScrn); 1920 1921 LEAVE(ret); 1922} 1923 1924void 1925SMI_LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, 1926 LOCO *colors, VisualPtr pVisual) 1927{ 1928 xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); 1929 int crtc_idx,i,j; 1930 1931 ENTER(); 1932 1933 if(pScrn->bitsPerPixel == 16){ 1934 /* Expand the RGB 565 palette into the 256-elements LUT */ 1935 1936 for(crtc_idx=0; crtc_idx<crtcConf->num_crtc; crtc_idx++){ 1937 SMICrtcPrivatePtr crtcPriv = SMICRTC(crtcConf->crtc[crtc_idx]); 1938 1939 for(i=0; i<numColors; i++){ 1940 int idx = indicies[i]; 1941 1942 if(idx<32){ 1943 for(j=0; j<8; j++){ 1944 crtcPriv->lut_r[idx*8 + j] = colors[idx].red << 8; 1945 crtcPriv->lut_b[idx*8 + j] = colors[idx].blue << 8; 1946 } 1947 } 1948 1949 for(j=0; j<4; j++) 1950 crtcPriv->lut_g[idx*4 + j] = colors[idx].green << 8; 1951 } 1952 1953 crtcPriv->load_lut(crtcConf->crtc[crtc_idx]); 1954 } 1955 }else{ 1956 for(crtc_idx=0; crtc_idx<crtcConf->num_crtc; crtc_idx++){ 1957 SMICrtcPrivatePtr crtcPriv = SMICRTC(crtcConf->crtc[crtc_idx]); 1958 1959 for(i = 0; i < numColors; i++) { 1960 int idx = indicies[i]; 1961 1962 crtcPriv->lut_r[idx] = colors[idx].red << 8; 1963 crtcPriv->lut_g[idx] = colors[idx].green << 8; 1964 crtcPriv->lut_b[idx] = colors[idx].blue << 8; 1965 } 1966 1967 crtcPriv->load_lut(crtcConf->crtc[crtc_idx]); 1968 } 1969 } 1970 1971 LEAVE(); 1972} 1973 1974static void 1975SMI_DisableVideo(ScrnInfoPtr pScrn) 1976{ 1977 SMIPtr pSmi = SMIPTR(pScrn); 1978 CARD8 tmp; 1979 1980 if (!IS_MSOC(pSmi)) { 1981 if (!(tmp = VGAIN8(pSmi, VGA_DAC_MASK))) 1982 return; 1983 pSmi->DACmask = tmp; 1984 VGAOUT8(pSmi, VGA_DAC_MASK, 0); 1985 } 1986} 1987 1988static void 1989SMI_EnableVideo(ScrnInfoPtr pScrn) 1990{ 1991 SMIPtr pSmi = SMIPTR(pScrn); 1992 1993 if (!IS_MSOC(pSmi)) { 1994 VGAOUT8(pSmi, VGA_DAC_MASK, pSmi->DACmask); 1995 } 1996} 1997 1998 1999void 2000SMI_EnableMmio(ScrnInfoPtr pScrn) 2001{ 2002 SMIPtr pSmi = SMIPTR(pScrn); 2003 2004 ENTER(); 2005 2006 if (!IS_MSOC(pSmi)) { 2007 vgaHWPtr hwp = VGAHWPTR(pScrn); 2008 CARD8 tmp; 2009 2010 /* 2011 * Enable chipset (seen on uninitialized secondary cards) might not be 2012 * needed once we use the VGA softbooter 2013 */ 2014 vgaHWSetStdFuncs(hwp); 2015 2016 /* Enable linear mode */ 2017 outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); 2018 tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); 2019 pSmi->SR18Value = tmp; /* PDR#521 */ 2020 outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp | 0x11); 2021 2022 /* Enable 2D/3D Engine and Video Processor */ 2023 outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x21); 2024 tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); 2025 pSmi->SR21Value = tmp; /* PDR#521 */ 2026 outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp & ~0x03); 2027 } 2028 2029 LEAVE(); 2030} 2031 2032void 2033SMI_DisableMmio(ScrnInfoPtr pScrn) 2034{ 2035 SMIPtr pSmi = SMIPTR(pScrn); 2036 2037 ENTER(); 2038 2039 if (!IS_MSOC(pSmi)) { 2040 vgaHWPtr hwp = VGAHWPTR(pScrn); 2041 2042 vgaHWSetStdFuncs(hwp); 2043 2044 /* Disable 2D/3D Engine and Video Processor */ 2045 outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x21); 2046 outb(pSmi->PIOBase + VGA_SEQ_DATA, pSmi->SR21Value); /* PDR#521 */ 2047 2048 /* Disable linear mode */ 2049 outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); 2050 outb(pSmi->PIOBase + VGA_SEQ_DATA, pSmi->SR18Value); /* PDR#521 */ 2051 } 2052 2053 LEAVE(); 2054} 2055 2056static void 2057SMI_ProbeDDC(ScrnInfoPtr pScrn, int index) 2058{ 2059 vbeInfoPtr pVbe; 2060 if (xf86LoadSubModule(pScrn, "vbe")) { 2061 pVbe = VBEInit(NULL, index); 2062 ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 2063 vbeFree(pVbe); 2064 } 2065} 2066 2067static Bool 2068SMI_HWInit(ScrnInfoPtr pScrn) 2069{ 2070 SMIPtr pSmi = SMIPTR(pScrn); 2071 2072 ENTER(); 2073 2074 if(IS_MSOC(pSmi)) 2075 LEAVE(SMI501_HWInit(pScrn)); 2076 else 2077 LEAVE(SMILynx_HWInit(pScrn)); 2078} 2079 2080void 2081SMI_PrintRegs(ScrnInfoPtr pScrn) 2082{ 2083 SMIPtr pSmi = SMIPTR(pScrn); 2084 int i; 2085 2086 ENTER(); 2087 2088 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 2089 "START register dump ------------------\n"); 2090 2091 if(IS_MSOC(pSmi)) 2092 SMI501_PrintRegs(pScrn); 2093 else 2094 SMILynx_PrintRegs(pScrn); 2095 2096 2097 xf86ErrorFVerb(VERBLEV, "\n\nDPR x0 x4 x8 xC"); 2098 for (i = 0x00; i <= 0x44; i += 4) { 2099 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 2100 xf86ErrorFVerb(VERBLEV, " %08lX", (unsigned long)READ_DPR(pSmi, i)); 2101 } 2102 2103 xf86ErrorFVerb(VERBLEV, "\n\nVPR x0 x4 x8 xC"); 2104 for (i = 0x00; i <= 0x60; i += 4) { 2105 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 2106 xf86ErrorFVerb(VERBLEV, " %08lX", (unsigned long)READ_VPR(pSmi, i)); 2107 } 2108 2109 xf86ErrorFVerb(VERBLEV, "\n\nCPR x0 x4 x8 xC"); 2110 for (i = 0x00; i <= 0x18; i += 4) { 2111 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 2112 xf86ErrorFVerb(VERBLEV, " %08lX", (unsigned long)READ_CPR(pSmi, i)); 2113 } 2114 2115 xf86ErrorFVerb(VERBLEV, "\n\n"); 2116 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 2117 "END register dump --------------------\n"); 2118 2119 LEAVE(); 2120} 2121