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 34b698ba48Smrg#include "xf86.h" 3509885543Smrg#include "xf86DDC.h" 3609885543Smrg#include "xf86int10.h" 3709885543Smrg#include "vbe.h" 3809885543Smrg 39b698ba48Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 40b698ba48Smrg#include "xf86Resources.h" 41b698ba48Smrg#include "xf86RAC.h" 42b698ba48Smrg#endif 43b698ba48Smrg 4409885543Smrg#include "smi.h" 457104f784Smrg#include "smi_501.h" 467104f784Smrg#include "smilynx.h" 477104f784Smrg#include "smi_crtc.h" 4809885543Smrg 4909885543Smrg#include "globals.h" 50b698ba48Smrg#ifdef HAVE_XEXTPROTO_71 51b698ba48Smrg#include <X11/extensions/dpmsconst.h> 52b698ba48Smrg#else 5309885543Smrg#define DPMS_SERVER 5409885543Smrg#include <X11/extensions/dpms.h> 55b698ba48Smrg#endif 56b698ba48Smrg 575788ca14Smrg 5809885543Smrg/* 5909885543Smrg * Internals 6009885543Smrg */ 617104f784Smrgstatic Bool SMI_MapMmio(ScrnInfoPtr pScrn); 627104f784Smrgstatic Bool SMI_DetectMem(ScrnInfoPtr pScrn); 6309885543Smrgstatic void SMI_EnableMmio(ScrnInfoPtr pScrn); 6409885543Smrgstatic void SMI_DisableMmio(ScrnInfoPtr pScrn); 657104f784Smrgstatic Bool SMI_HWInit(ScrnInfoPtr pScrn); 6609885543Smrg 6709885543Smrg/* 6809885543Smrg * Forward definitions for the functions that make up the driver. 6909885543Smrg */ 7009885543Smrg 7109885543Smrgstatic const OptionInfoRec * SMI_AvailableOptions(int chipid, int busid); 7209885543Smrgstatic void SMI_Identify(int flags); 7309885543Smrgstatic Bool SMI_Probe(DriverPtr drv, int flags); 7409885543Smrgstatic Bool SMI_PreInit(ScrnInfoPtr pScrn, int flags); 755788ca14Smrgstatic Bool SMI_EnterVT(VT_FUNC_ARGS_DECL); 765788ca14Smrgstatic void SMI_LeaveVT(VT_FUNC_ARGS_DECL); 775788ca14Smrgstatic Bool SMI_ScreenInit(SCREEN_INIT_ARGS_DECL); 7809885543Smrgstatic void SMI_DisableVideo(ScrnInfoPtr pScrn); 7909885543Smrgstatic void SMI_EnableVideo(ScrnInfoPtr pScrn); 805788ca14Smrgstatic Bool SMI_CloseScreen(CLOSE_SCREEN_ARGS_DECL); 8109885543Smrgstatic Bool SMI_SaveScreen(ScreenPtr pScreen, int mode); 825788ca14Smrgstatic void SMI_FreeScreen(FREE_SCREEN_ARGS_DECL); 8309885543Smrgstatic void SMI_ProbeDDC(ScrnInfoPtr pScrn, int index); 8409885543Smrgstatic void SMI_DetectPanelSize(ScrnInfoPtr pScrn); 857104f784Smrgstatic void SMI_DetectMCLK(ScrnInfoPtr pScrn); 8609885543Smrg 87407d2e45Smacallanstatic Bool SMI_driverFunc(ScrnInfoPtr, xorgDriverFuncOp, pointer); 88407d2e45Smacallan 897104f784Smrg/* 907104f784Smrg * xf86VDrvMsgVerb prints up to 14 characters prefix, where prefix has the 917104f784Smrg * format "%s(%d): " so, use name "SMI" instead of "Silicon Motion" 927104f784Smrg */ 937104f784Smrg#define SILICONMOTION_NAME "SMI" 9409885543Smrg#define SILICONMOTION_DRIVER_NAME "siliconmotion" 957104f784Smrg#define SILICONMOTION_VERSION_NAME PACKAGE_VERSION 967104f784Smrg#define SILICONMOTION_VERSION_MAJOR PACKAGE_VERSION_MAJOR 977104f784Smrg#define SILICONMOTION_VERSION_MINOR PACKAGE_VERSION_MINOR 987104f784Smrg#define SILICONMOTION_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 9909885543Smrg#define SILICONMOTION_DRIVER_VERSION ((SILICONMOTION_VERSION_MAJOR << 24) | \ 10009885543Smrg (SILICONMOTION_VERSION_MINOR << 16) | \ 10109885543Smrg (SILICONMOTION_PATCHLEVEL)) 10209885543Smrg 1037104f784Smrg#if SMI_DEBUG 1047104f784Smrgint smi_indent = 1; 1057104f784Smrg#endif 1067104f784Smrg 1077104f784Smrg/* for dualhead */ 1087104f784Smrgint gSMIEntityIndex = -1; 1097104f784Smrg 11009885543Smrg/* 11109885543Smrg * This contains the functions needed by the server after loading the 11209885543Smrg * driver module. It must be supplied, and gets added the driver list by 11372320d7bSmrg * the Module Setup function in the dynamic case. In the static case a 11409885543Smrg * reference to this is compiled in, and this requires that the name of 11509885543Smrg * this DriverRec be an upper-case version of the driver name. 11609885543Smrg */ 11709885543Smrg 11809885543Smrg_X_EXPORT DriverRec SILICONMOTION = 11909885543Smrg{ 12009885543Smrg SILICONMOTION_DRIVER_VERSION, 12109885543Smrg SILICONMOTION_DRIVER_NAME, 12209885543Smrg SMI_Identify, 12309885543Smrg SMI_Probe, 12409885543Smrg SMI_AvailableOptions, 12509885543Smrg NULL, 126407d2e45Smacallan 0, 127407d2e45Smacallan SMI_driverFunc 12809885543Smrg}; 12909885543Smrg 13009885543Smrg/* Supported chipsets */ 13109885543Smrgstatic SymTabRec SMIChipsets[] = 13209885543Smrg{ 13309885543Smrg { PCI_CHIP_SMI910, "Lynx" }, 13409885543Smrg { PCI_CHIP_SMI810, "LynxE" }, 13509885543Smrg { PCI_CHIP_SMI820, "Lynx3D" }, 13609885543Smrg { PCI_CHIP_SMI710, "LynxEM" }, 13709885543Smrg { PCI_CHIP_SMI712, "LynxEM+" }, 13809885543Smrg { PCI_CHIP_SMI720, "Lynx3DM" }, 13909885543Smrg { PCI_CHIP_SMI731, "Cougar3DR" }, 1407104f784Smrg { PCI_CHIP_SMI501, "MSOC" }, 14109885543Smrg { -1, NULL } 14209885543Smrg}; 14309885543Smrg 14409885543Smrgstatic PciChipsets SMIPciChipsets[] = 14509885543Smrg{ 1467104f784Smrg /* numChipset, PciID, Resource */ 14709885543Smrg { PCI_CHIP_SMI910, PCI_CHIP_SMI910, RES_SHARED_VGA }, 14809885543Smrg { PCI_CHIP_SMI810, PCI_CHIP_SMI810, RES_SHARED_VGA }, 14909885543Smrg { PCI_CHIP_SMI820, PCI_CHIP_SMI820, RES_SHARED_VGA }, 15009885543Smrg { PCI_CHIP_SMI710, PCI_CHIP_SMI710, RES_SHARED_VGA }, 15109885543Smrg { PCI_CHIP_SMI712, PCI_CHIP_SMI712, RES_SHARED_VGA }, 15209885543Smrg { PCI_CHIP_SMI720, PCI_CHIP_SMI720, RES_SHARED_VGA }, 15309885543Smrg { PCI_CHIP_SMI731, PCI_CHIP_SMI731, RES_SHARED_VGA }, 1547104f784Smrg { PCI_CHIP_SMI501, PCI_CHIP_SMI501, RES_UNDEFINED }, 1557104f784Smrg { -1, -1, RES_UNDEFINED } 15609885543Smrg}; 15709885543Smrg 15809885543Smrgtypedef enum 15909885543Smrg{ 16009885543Smrg OPTION_PCI_BURST, 16109885543Smrg OPTION_PCI_RETRY, 16209885543Smrg OPTION_NOACCEL, 16309885543Smrg OPTION_MCLK, 1647104f784Smrg OPTION_MXCLK, 16509885543Smrg OPTION_SWCURSOR, 16609885543Smrg OPTION_HWCURSOR, 16709885543Smrg OPTION_VIDEOKEY, 16809885543Smrg OPTION_BYTESWAP, 16909885543Smrg /* CZ 26.10.2001: interlaced video */ 17009885543Smrg OPTION_INTERLACED, 17109885543Smrg /* end CZ */ 17209885543Smrg OPTION_USEBIOS, 17309885543Smrg OPTION_DUALHEAD, 17409885543Smrg OPTION_ACCELMETHOD, 1757104f784Smrg OPTION_PANEL_SIZE, 1767104f784Smrg OPTION_USE_FBDEV, 1777104f784Smrg OPTION_CSCVIDEO, 17809885543Smrg NUMBER_OF_OPTIONS 17909885543Smrg} SMIOpts; 18009885543Smrg 18109885543Smrgstatic const OptionInfoRec SMIOptions[] = 18209885543Smrg{ 1837104f784Smrg { OPTION_PCI_BURST, "pci_burst", OPTV_BOOLEAN, {0}, TRUE }, 1847104f784Smrg { OPTION_PCI_RETRY, "pci_retry", OPTV_BOOLEAN, {0}, TRUE }, 18509885543Smrg { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 1867104f784Smrg { OPTION_MCLK, "MCLK", OPTV_FREQ, {0}, FALSE }, 1877104f784Smrg { OPTION_MXCLK, "MXCLK", OPTV_FREQ, {0}, FALSE }, 1887104f784Smrg { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, TRUE }, 18909885543Smrg { OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE }, 19009885543Smrg { OPTION_VIDEOKEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, 19109885543Smrg { OPTION_BYTESWAP, "ByteSwap", OPTV_BOOLEAN, {0}, FALSE }, 19209885543Smrg /* CZ 26.10.2001: interlaced video */ 1937104f784Smrg { OPTION_INTERLACED, "Interlaced", OPTV_BOOLEAN, {0}, FALSE }, 19409885543Smrg /* end CZ */ 19509885543Smrg { OPTION_USEBIOS, "UseBIOS", OPTV_BOOLEAN, {0}, FALSE }, 1967104f784Smrg { OPTION_DUALHEAD, "Dualhead", OPTV_BOOLEAN, {0}, TRUE }, 19709885543Smrg { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, 1987104f784Smrg { OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE }, 1997104f784Smrg { OPTION_USE_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, 2007104f784Smrg { OPTION_CSCVIDEO, "CSCVideo", OPTV_BOOLEAN, {0}, TRUE }, 20109885543Smrg { -1, NULL, OPTV_NONE, {0}, FALSE } 20209885543Smrg}; 20309885543Smrg 20409885543Smrgstatic MODULESETUPPROTO(siliconmotionSetup); 20509885543Smrg 20609885543Smrgstatic XF86ModuleVersionInfo SMIVersRec = 20709885543Smrg{ 20809885543Smrg "siliconmotion", 20909885543Smrg MODULEVENDORSTRING, 21009885543Smrg MODINFOSTRING1, 21109885543Smrg MODINFOSTRING2, 21209885543Smrg XORG_VERSION_CURRENT, 21309885543Smrg SILICONMOTION_VERSION_MAJOR, 21409885543Smrg SILICONMOTION_VERSION_MINOR, 21509885543Smrg SILICONMOTION_PATCHLEVEL, 21609885543Smrg ABI_CLASS_VIDEODRV, 21709885543Smrg ABI_VIDEODRV_VERSION, 21809885543Smrg MOD_CLASS_VIDEODRV, 21909885543Smrg {0, 0, 0, 0} 22009885543Smrg}; 22109885543Smrg 22209885543Smrg/* 22309885543Smrg * This is the module init data for XFree86 modules. 22409885543Smrg * 22509885543Smrg * Its name has to be the driver name followed by ModuleData. 22609885543Smrg */ 22709885543Smrg_X_EXPORT XF86ModuleData siliconmotionModuleData = 22809885543Smrg{ 22909885543Smrg &SMIVersRec, 23009885543Smrg siliconmotionSetup, 23109885543Smrg NULL 23209885543Smrg}; 23309885543Smrg 23409885543Smrgstatic pointer 23509885543SmrgsiliconmotionSetup(pointer module, pointer opts, int *errmaj, int *errmin) 23609885543Smrg{ 23709885543Smrg static Bool setupDone = FALSE; 23809885543Smrg 23909885543Smrg if (!setupDone) { 24009885543Smrg setupDone = TRUE; 241407d2e45Smacallan xf86AddDriver(&SILICONMOTION, module, HaveDriverFuncs); 24209885543Smrg 24309885543Smrg /* 24409885543Smrg * The return value must be non-NULL on success even though there 24509885543Smrg * is no TearDownProc. 24609885543Smrg */ 24709885543Smrg return (pointer) 1; 24809885543Smrg 24909885543Smrg } else { 25009885543Smrg if (errmaj) { 25109885543Smrg *errmaj = LDR_ONCEONLY; 25209885543Smrg } 25309885543Smrg return NULL; 25409885543Smrg } 25509885543Smrg} 25609885543Smrg 25709885543Smrgstatic Bool 25809885543SmrgSMI_GetRec(ScrnInfoPtr pScrn) 25909885543Smrg{ 2607104f784Smrg ENTER(); 26109885543Smrg 26209885543Smrg /* 26309885543Smrg * Allocate an 'Chip'Rec, and hook it into pScrn->driverPrivate. 26409885543Smrg * pScrn->driverPrivate is initialised to NULL, so we can check if 26509885543Smrg * the allocation has already been done. 26609885543Smrg */ 26709885543Smrg if (pScrn->driverPrivate == NULL) { 26809885543Smrg pScrn->driverPrivate = xnfcalloc(sizeof(SMIRec), 1); 26909885543Smrg } 27009885543Smrg 2717104f784Smrg LEAVE(TRUE); 27209885543Smrg} 27309885543Smrg 27409885543Smrgstatic void 27509885543SmrgSMI_FreeRec(ScrnInfoPtr pScrn) 27609885543Smrg{ 2777104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 27809885543Smrg 2797104f784Smrg ENTER(); 2807104f784Smrg 2817104f784Smrg if (pSmi) { 2827b58d2e0Smrg free(pSmi->save); 2837b58d2e0Smrg free(pSmi->mode); 2847b58d2e0Smrg free(pScrn->driverPrivate); 28509885543Smrg pScrn->driverPrivate = NULL; 28609885543Smrg } 28709885543Smrg 2887104f784Smrg LEAVE(); 28909885543Smrg} 29009885543Smrg 29109885543Smrgstatic const OptionInfoRec * 29209885543SmrgSMI_AvailableOptions(int chipid, int busid) 29309885543Smrg{ 2947104f784Smrg ENTER(); 2957104f784Smrg 2967104f784Smrg LEAVE(SMIOptions); 29709885543Smrg} 29809885543Smrg 29909885543Smrgstatic void 30009885543SmrgSMI_Identify(int flags) 30109885543Smrg{ 3027104f784Smrg ENTER(); 30309885543Smrg 30409885543Smrg xf86PrintChipsets(SILICONMOTION_NAME, "driver (version " 30509885543Smrg SILICONMOTION_VERSION_NAME ") for Silicon Motion Lynx chipsets", 30609885543Smrg SMIChipsets); 30709885543Smrg 3087104f784Smrg LEAVE(); 30909885543Smrg} 31009885543Smrg 31109885543Smrgstatic Bool 31209885543SmrgSMI_Probe(DriverPtr drv, int flags) 31309885543Smrg{ 31409885543Smrg int i; 31509885543Smrg GDevPtr *devSections; 31609885543Smrg int *usedChips; 31709885543Smrg int numDevSections; 31809885543Smrg int numUsed; 31909885543Smrg Bool foundScreen = FALSE; 32009885543Smrg 3217104f784Smrg ENTER(); 32209885543Smrg 32309885543Smrg numDevSections = xf86MatchDevice(SILICONMOTION_DRIVER_NAME, &devSections); 32409885543Smrg 3257104f784Smrg if (numDevSections <= 0) 32609885543Smrg /* There's no matching device section in the config file, so quit now. */ 3277104f784Smrg LEAVE(FALSE); 32809885543Smrg 3297104f784Smrg#ifndef XSERVER_LIBPCIACCESS 3307104f784Smrg if (xf86GetPciVideoInfo() == NULL) 3317104f784Smrg LEAVE(FALSE); 3327104f784Smrg#endif 33309885543Smrg 33409885543Smrg numUsed = xf86MatchPciInstances(SILICONMOTION_NAME, PCI_SMI_VENDOR_ID, 33509885543Smrg SMIChipsets, SMIPciChipsets, devSections, 33609885543Smrg numDevSections, drv, &usedChips); 33709885543Smrg 33809885543Smrg /* Free it since we don't need that list after this */ 3397b58d2e0Smrg free(devSections); 3407104f784Smrg if (numUsed <= 0) 3417104f784Smrg LEAVE(FALSE); 3427104f784Smrg 3437104f784Smrg if (flags & PROBE_DETECT) 3447104f784Smrg foundScreen = TRUE; 3457104f784Smrg else { 3467104f784Smrg ScrnInfoPtr pScrn; 3477104f784Smrg EntityInfoPtr pEnt; 34809885543Smrg 34909885543Smrg for (i = 0; i < numUsed; i++) { 3507104f784Smrg if ((pScrn = xf86ConfigPciEntity(NULL, 0, usedChips[i], 3517104f784Smrg SMIPciChipsets, NULL, 3527104f784Smrg NULL, NULL, NULL, NULL))) { 3537104f784Smrg pScrn->driverVersion = SILICONMOTION_DRIVER_VERSION; 3547104f784Smrg pScrn->driverName = SILICONMOTION_DRIVER_NAME; 3557104f784Smrg pScrn->name = SILICONMOTION_NAME; 3567104f784Smrg pScrn->Probe = SMI_Probe; 3577104f784Smrg pScrn->PreInit = SMI_PreInit; 3587104f784Smrg pScrn->ScreenInit = SMI_ScreenInit; 3597104f784Smrg pScrn->SwitchMode = SMI_SwitchMode; 3607104f784Smrg pScrn->AdjustFrame = SMI_AdjustFrame; 3617104f784Smrg 3627104f784Smrg if ((pEnt = xf86GetEntityInfo(usedChips[i]))) { 3637104f784Smrg pScrn->EnterVT = SMI_EnterVT; 3647104f784Smrg pScrn->LeaveVT = SMI_LeaveVT; 3657b58d2e0Smrg free(pEnt); 3667104f784Smrg } 3677104f784Smrg pScrn->FreeScreen = SMI_FreeScreen; 3687104f784Smrg foundScreen = TRUE; 3697104f784Smrg } 37009885543Smrg } 37109885543Smrg } 3727b58d2e0Smrg free(usedChips); 37309885543Smrg 3747104f784Smrg LEAVE(foundScreen); 37509885543Smrg} 37609885543Smrg 37709885543Smrgstatic Bool 37809885543SmrgSMI_PreInit(ScrnInfoPtr pScrn, int flags) 37909885543Smrg{ 38009885543Smrg EntityInfoPtr pEnt; 38109885543Smrg SMIPtr pSmi; 38209885543Smrg MessageType from; 38309885543Smrg vgaHWPtr hwp; 38409885543Smrg 3857104f784Smrg ENTER(); 38609885543Smrg 38709885543Smrg /* Ignoring the Type list for now. It might be needed when multiple cards 38809885543Smrg * are supported. 38909885543Smrg */ 3907104f784Smrg if (pScrn->numEntities > 1) 3917104f784Smrg LEAVE(FALSE); 39209885543Smrg 3937104f784Smrg /* Allocate the SMIRec driverPrivate */ 3947104f784Smrg if (!SMI_GetRec(pScrn)) 3957104f784Smrg LEAVE(FALSE); 3967104f784Smrg pSmi = SMIPTR(pScrn); 39709885543Smrg 3987104f784Smrg /* Find the PCI slot for this screen */ 3997104f784Smrg pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 40009885543Smrg 4017104f784Smrg pSmi->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 4027104f784Smrg pSmi->Chipset = PCI_DEV_DEVICE_ID(pSmi->PciInfo); 4037104f784Smrg 4047104f784Smrg if (IS_MSOC(pSmi)) { 4057104f784Smrg pSmi->Save = SMI501_Save; 4067104f784Smrg pSmi->save = xnfcalloc(sizeof(MSOCRegRec), 1); 4077104f784Smrg pSmi->mode = xnfcalloc(sizeof(MSOCRegRec), 1); 4087104f784Smrg } 4097104f784Smrg else { 4107104f784Smrg pSmi->Save = SMILynx_Save; 4117104f784Smrg pSmi->save = xnfcalloc(sizeof(SMIRegRec), 1); 4127104f784Smrg pSmi->mode = xnfcalloc(sizeof(SMIRegRec), 1); 41309885543Smrg } 41409885543Smrg 4157104f784Smrg if (flags & PROBE_DETECT) { 4167104f784Smrg if (!IS_MSOC(pSmi)) 4177104f784Smrg SMI_ProbeDDC(pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index); 4187104f784Smrg LEAVE(TRUE); 41909885543Smrg } 4207104f784Smrg 421b698ba48Smrg if (pEnt->location.type != BUS_PCI) { 4227b58d2e0Smrg free(pEnt); 4237104f784Smrg SMI_FreeRec(pScrn); 4247104f784Smrg LEAVE(FALSE); 4257104f784Smrg } 4267104f784Smrg pSmi->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 42709885543Smrg 42809885543Smrg /* Set pScrn->monitor */ 42909885543Smrg pScrn->monitor = pScrn->confScreen->monitor; 43009885543Smrg 4317104f784Smrg if (!IS_MSOC(pSmi)) { 4327104f784Smrg /* The vgahw module should be loaded here when needed */ 4337104f784Smrg if (!xf86LoadSubModule(pScrn, "vgahw")) 4347104f784Smrg LEAVE(FALSE); 4357104f784Smrg 4367104f784Smrg /* 4377104f784Smrg * Allocate a vgaHWRec 4387104f784Smrg */ 4397104f784Smrg if (!vgaHWGetHWRec(pScrn)) 4407104f784Smrg LEAVE(FALSE); 4417104f784Smrg 4427104f784Smrg hwp = VGAHWPTR(pScrn); 4435788ca14Smrg vgaHWSetStdFuncs(hwp); 4445788ca14Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12 4457104f784Smrg pSmi->PIOBase = hwp->PIOOffset; 4465788ca14Smrg#else 4475788ca14Smrg pSmi->PIOBase = 0; 4485788ca14Smrg#endif 4497104f784Smrg 4507104f784Smrg xf86ErrorFVerb(VERBLEV, "\tSMI_PreInit vgaCRIndex=%x, vgaIOBase=%x, " 4517104f784Smrg "MMIOBase=%p\n", hwp->IOBase + VGA_CRTC_INDEX_OFFSET, 4527104f784Smrg hwp->IOBase, hwp->MMIOBase); 4537104f784Smrg } 4547104f784Smrg 45509885543Smrg /* 45609885543Smrg * The first thing we should figure out is the depth, bpp, etc. 45709885543Smrg */ 4587104f784Smrg if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) 4597104f784Smrg LEAVE(FALSE); 46009885543Smrg 46109885543Smrg /* Check that the returned depth is one we support */ 4627104f784Smrg if (pScrn->depth != 8 && pScrn->depth != 16 && pScrn->depth != 24) { 46309885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 46409885543Smrg "Given depth (%d) is not supported by this driver\n", 46509885543Smrg pScrn->depth); 4667104f784Smrg LEAVE(FALSE); 4677104f784Smrg } 4687104f784Smrg 4697104f784Smrg 4707104f784Smrg if(pScrn->bitsPerPixel != 8 && pScrn->bitsPerPixel != 16 && 4717104f784Smrg pScrn->bitsPerPixel != 24 && pScrn->bitsPerPixel != 32){ 4727104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4737104f784Smrg "Given bpp (%d) is not supported by this driver\n", 4747104f784Smrg pScrn->bitsPerPixel); 4757104f784Smrg LEAVE(FALSE); 47609885543Smrg } 47709885543Smrg 47809885543Smrg xf86PrintDepthBpp(pScrn); 47909885543Smrg 4802ec8c4b4Smrg pSmi->Bpp = pScrn->bitsPerPixel >> 3; 4812ec8c4b4Smrg 48209885543Smrg /* 48309885543Smrg * This must happen after pScrn->display has been set because 48409885543Smrg * xf86SetWeight references it. 48509885543Smrg */ 48609885543Smrg if (pScrn->depth > 8) { 48709885543Smrg /* The defaults are OK for us */ 48809885543Smrg rgb zeros = {0, 0, 0}; 489eee1ded1Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN 4907104f784Smrg rgb masks = {0xff00,0xff0000,0xff000000}; 4917104f784Smrg#else 4927104f784Smrg rgb masks = {0, 0, 0}; 4937104f784Smrg#endif 49409885543Smrg 4957104f784Smrg if (!xf86SetWeight(pScrn, zeros, masks)) 4967104f784Smrg LEAVE(FALSE); 49709885543Smrg } 49809885543Smrg 4997104f784Smrg if (!xf86SetDefaultVisual(pScrn, -1)) 5007104f784Smrg LEAVE(FALSE); 50109885543Smrg 50209885543Smrg /* We don't currently support DirectColor at > 8bpp */ 5037104f784Smrg if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 50409885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual (%s) " 50509885543Smrg "is not supported at depth %d\n", 50609885543Smrg xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 5077104f784Smrg LEAVE(FALSE); 50809885543Smrg } 50909885543Smrg 51009885543Smrg /* We use a programmable clock */ 51109885543Smrg pScrn->progClock = TRUE; 51209885543Smrg 51309885543Smrg /* Collect all of the relevant option flags (fill in pScrn->options) */ 51409885543Smrg xf86CollectOptions(pScrn, NULL); 51509885543Smrg 51609885543Smrg /* Set the bits per RGB for 8bpp mode */ 5177104f784Smrg if (pScrn->depth == 8){ 5187104f784Smrg pScrn->rgbBits = IS_MSOC(pSmi) ? 8 : 6; 5197104f784Smrg }else if(pScrn->depth == 16){ 5207104f784Smrg /* Use 8 bit LUT for gamma correction*/ 5217104f784Smrg pScrn->rgbBits = 8; 52209885543Smrg } 52309885543Smrg 52409885543Smrg /* Process the options */ 5257b58d2e0Smrg if (!(pSmi->Options = malloc(sizeof(SMIOptions)))) 5267104f784Smrg LEAVE(FALSE); 5277104f784Smrg 52809885543Smrg memcpy(pSmi->Options, SMIOptions, sizeof(SMIOptions)); 52909885543Smrg xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pSmi->Options); 53009885543Smrg 5317104f784Smrg /* Enable pci burst by default */ 5327104f784Smrg from = X_DEFAULT; 5337104f784Smrg pSmi->PCIBurst = TRUE; 5347104f784Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_PCI_BURST, &pSmi->PCIBurst)) 5357104f784Smrg from = X_CONFIG; 5367104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "PCI Burst %sabled\n", 5377104f784Smrg pSmi->PCIBurst ? "en" : "dis"); 53809885543Smrg 5397104f784Smrg /* Pci retry enabled by default if pci burst also enabled */ 5407104f784Smrg from = X_DEFAULT; 5417104f784Smrg pSmi->PCIRetry = pSmi->PCIBurst ? TRUE : FALSE; 5427104f784Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_PCI_RETRY, &pSmi->PCIRetry)) { 5437104f784Smrg from = X_CONFIG; 5447104f784Smrg if (pSmi->PCIRetry && !pSmi->PCIBurst) { 5457104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 5467104f784Smrg "\"pci_retry\" option requires \"pci_burst\".\n"); 5477104f784Smrg pSmi->PCIRetry = FALSE; 54809885543Smrg } 54909885543Smrg } 5507104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "PCI Retry %sabled\n", 5517104f784Smrg pSmi->PCIRetry ? "en" : "dis"); 55209885543Smrg 55309885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_NOACCEL, FALSE)) { 55409885543Smrg pSmi->NoAccel = TRUE; 55509885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - Acceleration " 55609885543Smrg "disabled\n"); 55709885543Smrg } else { 55809885543Smrg pSmi->NoAccel = FALSE; 55909885543Smrg } 56009885543Smrg 5617104f784Smrg if (IS_MSOC(pSmi)) { 5627104f784Smrg from = X_DEFAULT; 5637104f784Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_USE_FBDEV, &pSmi->UseFBDev)) 5647104f784Smrg from = X_CONFIG; 5657104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "UseFBDev %s.\n", 5667104f784Smrg pSmi->UseFBDev ? "enabled" : "disabled"); 5677104f784Smrg } 5687104f784Smrg 5697104f784Smrg from = X_CONFIG; 5707104f784Smrg pSmi->HwCursor = TRUE; 5717104f784Smrg /* SWCursor overrides HWCusor if both specified */ 5727104f784Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_SWCURSOR, FALSE)) 5737104f784Smrg pSmi->HwCursor = FALSE; 5747104f784Smrg else if (!xf86GetOptValBool(pSmi->Options, OPTION_HWCURSOR, &pSmi->HwCursor)) 5757104f784Smrg from = X_DEFAULT; 57609885543Smrg 5777104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Using %sware Cursor\n", 5787104f784Smrg pSmi->HwCursor ? "Hard" : "Soft"); 57909885543Smrg 58009885543Smrg if (xf86GetOptValInteger(pSmi->Options, OPTION_VIDEOKEY, &pSmi->videoKey)) { 58109885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Video key set to " 58209885543Smrg "0x%08X\n", pSmi->videoKey); 58309885543Smrg } else { 58409885543Smrg pSmi->videoKey = (1 << pScrn->offset.red) | 58509885543Smrg (1 << pScrn->offset.green) | 58609885543Smrg (((pScrn->mask.blue >> pScrn->offset.blue) - 1) 58709885543Smrg << pScrn->offset.blue); 58809885543Smrg } 58909885543Smrg 59009885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_BYTESWAP, FALSE)) { 59109885543Smrg pSmi->ByteSwap = TRUE; 59209885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: ByteSwap enabled.\n"); 59309885543Smrg } else { 59409885543Smrg pSmi->ByteSwap = FALSE; 59509885543Smrg } 59609885543Smrg 59709885543Smrg /* CZ 26.10.2001: interlaced video */ 59809885543Smrg if (xf86ReturnOptValBool(pSmi->Options, OPTION_INTERLACED, FALSE)) { 59909885543Smrg pSmi->interlaced = TRUE; 60009885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Interlaced enabled.\n"); 60109885543Smrg } else { 60209885543Smrg pSmi->interlaced = FALSE; 60309885543Smrg } 60409885543Smrg /* end CZ */ 60509885543Smrg 6067104f784Smrg if (IS_MSOC(pSmi)) 6077104f784Smrg pSmi->useBIOS = FALSE; 6087104f784Smrg else if (xf86GetOptValBool(pSmi->Options, OPTION_USEBIOS, &pSmi->useBIOS)) { 60909885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: UseBIOS %s.\n", 61009885543Smrg pSmi->useBIOS ? "enabled" : "disabled"); 6117104f784Smrg } 6127104f784Smrg else if(pSmi->Chipset == SMI_LYNX3DM){ 6137104f784Smrg /* Default to UseBIOS disabled. */ 6147104f784Smrg pSmi->useBIOS = FALSE; 6157104f784Smrg } 6167104f784Smrg else { 61709885543Smrg /* Default to UseBIOS enabled. */ 61809885543Smrg pSmi->useBIOS = TRUE; 61909885543Smrg } 62009885543Smrg 6217104f784Smrg if (pSmi->useBIOS) { 6227104f784Smrg if (xf86LoadSubModule(pScrn,"int10")) { 6237104f784Smrg pSmi->pInt10 = xf86InitInt10(pEnt->index); 6247104f784Smrg } 62509885543Smrg 6267104f784Smrg if (pSmi->pInt10 && xf86LoadSubModule(pScrn, "vbe")) { 6277104f784Smrg pSmi->pVbe = VBEInit(pSmi->pInt10, pEnt->index); 6287104f784Smrg } 62909885543Smrg 6307104f784Smrg if(!pSmi->pVbe){ 6317104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VBE initialization failed: falling back to UseBIOS disabled.\n"); 6327104f784Smrg pSmi->useBIOS = FALSE; 6337104f784Smrg } 63409885543Smrg } 63509885543Smrg 636b698ba48Smrg#ifndef XSERVER_LIBPCIACCESS 63709885543Smrg xf86RegisterResources(pEnt->index, NULL, ResExclusive); 638b698ba48Smrg#endif 63909885543Smrg /* 64009885543Smrg * Set the Chipset and ChipRev, allowing config file entries to 64109885543Smrg * override. 64209885543Smrg */ 64309885543Smrg if (pEnt->device->chipset && *pEnt->device->chipset) { 64409885543Smrg pScrn->chipset = pEnt->device->chipset; 64509885543Smrg pSmi->Chipset = xf86StringToToken(SMIChipsets, pScrn->chipset); 64609885543Smrg from = X_CONFIG; 6477104f784Smrg } 6487104f784Smrg else if (pEnt->device->chipID >= 0) { 64909885543Smrg pSmi->Chipset = pEnt->device->chipID; 65009885543Smrg pScrn->chipset = (char *) xf86TokenToString(SMIChipsets, pSmi->Chipset); 65109885543Smrg from = X_CONFIG; 65209885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 65309885543Smrg pSmi->Chipset); 6547104f784Smrg } 6557104f784Smrg else { 65609885543Smrg from = X_PROBED; 6577104f784Smrg pSmi->Chipset = PCI_DEV_DEVICE_ID(pSmi->PciInfo); 65809885543Smrg pScrn->chipset = (char *) xf86TokenToString(SMIChipsets, pSmi->Chipset); 65909885543Smrg } 66009885543Smrg 66109885543Smrg if (pEnt->device->chipRev >= 0) { 66209885543Smrg pSmi->ChipRev = pEnt->device->chipRev; 66309885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 66409885543Smrg pSmi->ChipRev); 66509885543Smrg } 6667104f784Smrg else 6677104f784Smrg pSmi->ChipRev = PCI_DEV_REVISION(pSmi->PciInfo); 6687b58d2e0Smrg free(pEnt); 66909885543Smrg 67009885543Smrg /* 67109885543Smrg * This shouldn't happen because such problems should be caught in 67209885543Smrg * SMI_Probe(), but check it just in case. 67309885543Smrg */ 67409885543Smrg if (pScrn->chipset == NULL) { 67509885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04X is not " 67609885543Smrg "recognised\n", pSmi->Chipset); 6777104f784Smrg LEAVE(FALSE); 67809885543Smrg } 67909885543Smrg 68009885543Smrg if (pSmi->Chipset < 0) { 68109885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Chipset \"%s\" is not " 68209885543Smrg "recognised\n", pScrn->chipset); 6837104f784Smrg LEAVE(FALSE); 68409885543Smrg } 68509885543Smrg 68609885543Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); 68709885543Smrg 6887104f784Smrg#ifndef XSERVER_LIBPCIACCESS 68909885543Smrg pSmi->PciTag = pciTag(pSmi->PciInfo->bus, pSmi->PciInfo->device, 69009885543Smrg pSmi->PciInfo->func); 6917104f784Smrg#endif 69209885543Smrg 6937104f784Smrg from = X_DEFAULT; 6947104f784Smrg if(pSmi->Chipset == SMI_LYNX3DM && 6957104f784Smrg pScrn->bitsPerPixel == 16) 69609885543Smrg pSmi->Dualhead = TRUE; 6977104f784Smrg else 6987104f784Smrg pSmi->Dualhead = FALSE; 6997104f784Smrg 7007104f784Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_DUALHEAD, &pSmi->Dualhead)) 7017104f784Smrg from = X_CONFIG; 7027104f784Smrg 7037104f784Smrg if (IS_MSOC(pSmi)) { 7047104f784Smrg pSmi->lcd = TRUE; 7057104f784Smrg if (pSmi->Dualhead && pSmi->UseFBDev) { 7067104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 7077104f784Smrg "Dual head disabled in fbdev mode\n"); 7087104f784Smrg pSmi->Dualhead = FALSE; 7097104f784Smrg } 7107104f784Smrg /* FIXME Randr cursor code only works properly when argb cursors 7117104f784Smrg * are also supported. 7127104f784Smrg * FIXME This probably is a randr cursor bug, and since access to 7137104f784Smrg * hw/xfree86/ramdac/xf86CursorPriv.h:xf86CursorScreenRec.SWCursor 7147104f784Smrg * field is not available, one cannot easily workaround the problem, 7157104f784Smrg * so, just disable it... 7167104f784Smrg * TODO Check with a X Server newer then 1.4.0.90 (that is being 7177104f784Smrg * used in the 502 OEM image). 7187104f784Smrg * */ 7197104f784Smrg if (pSmi->Dualhead && pSmi->HwCursor) { 7207104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 7217104f784Smrg "HW Cursor disabled in dual head mode\n"); 7227104f784Smrg pSmi->HwCursor = FALSE; 7237104f784Smrg } 7247104f784Smrg } 7257104f784Smrg else if (SMI_LYNXM_SERIES(pSmi->Chipset)) { 7267104f784Smrg /* tweak options for dualhead */ 7277104f784Smrg if (pSmi->Dualhead) { 7287104f784Smrg pSmi->useBIOS = FALSE; 7297104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "UseBIOS disabled in dualhead mode\n"); 7307104f784Smrg pSmi->HwCursor = FALSE; 7317104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No hardware cursor in dualhead mode\n"); 7327104f784Smrg if (pScrn->bitsPerPixel != 16) { 7337104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Dualhead only supported at " 7347104f784Smrg "depth 16\n"); 7357104f784Smrg LEAVE(FALSE); 7367104f784Smrg } 7377104f784Smrg } 73809885543Smrg } 7397104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Dual head %sabled\n", 7407104f784Smrg pSmi->Dualhead ? "en" : "dis"); 74109885543Smrg 7427104f784Smrg if (!pSmi->NoAccel) { 7437104f784Smrg char *strptr; 7447104f784Smrg 7457104f784Smrg from = X_DEFAULT; 7465805b606Smacallan pSmi->useEXA = TRUE; 7477104f784Smrg if ((strptr = (char *)xf86GetOptValString(pSmi->Options, 7487104f784Smrg OPTION_ACCELMETHOD))) { 7497104f784Smrg if (!xf86NameCmp(strptr,"XAA")) { 7507104f784Smrg from = X_CONFIG; 7517104f784Smrg pSmi->useEXA = FALSE; 7527104f784Smrg } else if(!xf86NameCmp(strptr,"EXA")) { 7537104f784Smrg from = X_CONFIG; 7547104f784Smrg pSmi->useEXA = TRUE; 7557104f784Smrg } 75609885543Smrg } 7577104f784Smrg 7587104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture\n", 7597104f784Smrg pSmi->useEXA ? "EXA" : "XAA"); 76009885543Smrg } 76109885543Smrg 7627104f784Smrg if (IS_MSOC(pSmi)) { 7637104f784Smrg pSmi->CSCVideo = !pSmi->useEXA || !pSmi->Dualhead; 7647104f784Smrg from = X_DEFAULT; 7657104f784Smrg if (xf86GetOptValBool(pSmi->Options, OPTION_CSCVIDEO, &pSmi->CSCVideo)) { 7667104f784Smrg from = X_CONFIG; 7677104f784Smrg 7687104f784Smrg /* FIXME */ 7697104f784Smrg if (pSmi->CSCVideo && pSmi->useEXA && pSmi->Dualhead) { 7707104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 7717104f784Smrg "CSCVideo requires XAA or EXA in single head mode.\n"); 7727104f784Smrg pSmi->CSCVideo = FALSE; 7737104f784Smrg } 7747104f784Smrg } 77509885543Smrg 7767104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, "CSC Video %sabled\n", 7777104f784Smrg pSmi->CSCVideo ? "en" : "dis"); 7787104f784Smrg } 77909885543Smrg 7807104f784Smrg SMI_MapMmio(pScrn); 7817104f784Smrg SMI_DetectMem(pScrn); 7827104f784Smrg SMI_MapMem(pScrn); 7837104f784Smrg SMI_DisableVideo(pScrn); 78409885543Smrg 78509885543Smrg /* detect the panel size */ 78609885543Smrg SMI_DetectPanelSize(pScrn); 78709885543Smrg 7887104f784Smrg if(!IS_MSOC(pSmi)){ 7897104f784Smrg if (xf86LoadSubModule(pScrn, "i2c")) { 7907104f784Smrg SMI_I2CInit(pScrn); 7917104f784Smrg } 7922ec8c4b4Smrg xf86LoadSubModule(pScrn, "ddc"); 79309885543Smrg } 79409885543Smrg 79509885543Smrg /* 79609885543Smrg * If the driver can do gamma correction, it should call xf86SetGamma() 79709885543Smrg */ 79809885543Smrg { 79909885543Smrg Gamma zeros = { 0.0, 0.0, 0.0 }; 80009885543Smrg 80109885543Smrg if (!xf86SetGamma(pScrn, zeros)) { 80209885543Smrg SMI_EnableVideo(pScrn); 80309885543Smrg SMI_UnmapMem(pScrn); 8047104f784Smrg LEAVE(FALSE); 80509885543Smrg } 80609885543Smrg } 80709885543Smrg 8087104f784Smrg SMI_DetectMCLK(pScrn); 80909885543Smrg 81009885543Smrg /* 81109885543Smrg * Setup the ClockRanges, which describe what clock ranges are available, 81209885543Smrg * and what sort of modes they can be used for. 81309885543Smrg */ 8147104f784Smrg pSmi->clockRange.next = NULL; 8157104f784Smrg pSmi->clockRange.minClock = 20000; 81609885543Smrg 8177104f784Smrg if (SMI_LYNXM_SERIES(pSmi->Chipset) || 8187104f784Smrg IS_MSOC(pSmi)) 8197104f784Smrg pSmi->clockRange.maxClock = 200000; 82009885543Smrg else 8217104f784Smrg pSmi->clockRange.maxClock = 135000; 82209885543Smrg 8237104f784Smrg pSmi->clockRange.clockIndex = -1; 8247104f784Smrg pSmi->clockRange.interlaceAllowed = FALSE; 8257104f784Smrg pSmi->clockRange.doubleScanAllowed = FALSE; 82609885543Smrg 8277104f784Smrg if(!SMI_CrtcPreInit(pScrn)) 8287104f784Smrg LEAVE(FALSE); 8297104f784Smrg 8307104f784Smrg if(!SMI_OutputPreInit(pScrn)) 8317104f784Smrg LEAVE(FALSE); 8327104f784Smrg 8337104f784Smrg /* Only allow growing the screen dimensions if EXA is being used */ 8347104f784Smrg if (!xf86InitialConfiguration (pScrn, !pSmi->NoAccel && pSmi->useEXA)){ 83509885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 8362ec8c4b4Smrg 8372ec8c4b4Smrg SMI_EnableVideo(pScrn); 8382ec8c4b4Smrg SMI_UnmapMem(pScrn); 8397104f784Smrg LEAVE(FALSE); 84009885543Smrg } 84109885543Smrg 8422ec8c4b4Smrg /* Ensure that the framebuffer size just set fits in video memory. */ 8432ec8c4b4Smrg { 8442ec8c4b4Smrg int aligned_pitch = (pScrn->virtualX*pSmi->Bpp + 15) & ~15; 8452ec8c4b4Smrg 8462ec8c4b4Smrg if(aligned_pitch * pScrn->virtualY > pSmi->FBReserved){ 8472ec8c4b4Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Not enough video memory " 8482ec8c4b4Smrg "for the configured screen size (%dx%d) and color depth.\n", 8492ec8c4b4Smrg pScrn->virtualX, pScrn->virtualY); 8502ec8c4b4Smrg 8512ec8c4b4Smrg SMI_EnableVideo(pScrn); 8522ec8c4b4Smrg SMI_UnmapMem(pScrn); 8532ec8c4b4Smrg LEAVE(FALSE); 8542ec8c4b4Smrg } 8552ec8c4b4Smrg } 8562ec8c4b4Smrg 85709885543Smrg 8587104f784Smrg SMI_EnableVideo(pScrn); 8597104f784Smrg SMI_UnmapMem(pScrn); 8607104f784Smrg 8617104f784Smrg if(pSmi->pVbe){ 8627104f784Smrg vbeFree(pSmi->pVbe); 8637104f784Smrg pSmi->pVbe = NULL; 8647104f784Smrg } 8657104f784Smrg if(pSmi->pInt10){ 8667104f784Smrg xf86FreeInt10(pSmi->pInt10); 8677104f784Smrg pSmi->pInt10 = NULL; 8687104f784Smrg } 86909885543Smrg 87009885543Smrg /* Set display resolution */ 87109885543Smrg xf86SetDpi(pScrn, 0, 0); 87209885543Smrg 8737104f784Smrg if (xf86LoadSubModule(pScrn, "fb") == NULL) { 87409885543Smrg SMI_FreeRec(pScrn); 8757104f784Smrg LEAVE(FALSE); 87609885543Smrg } 87709885543Smrg 87809885543Smrg /* Load XAA or EXA if needed */ 87909885543Smrg if (!pSmi->NoAccel) { 88009885543Smrg if (!pSmi->useEXA) { 88109885543Smrg if (!xf86LoadSubModule(pScrn, "xaa")) { 8825788ca14Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No acceleration\n"); 8835788ca14Smrg pSmi->NoAccel = 1; 88409885543Smrg } 88509885543Smrg } else { 88609885543Smrg XF86ModReqInfo req; 88709885543Smrg int errmaj, errmin; 88809885543Smrg 88909885543Smrg memset(&req, 0, sizeof(XF86ModReqInfo)); 89009885543Smrg req.majorversion = 2; 8917104f784Smrg req.minorversion = 1; 89209885543Smrg 89309885543Smrg if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, 89409885543Smrg &req, &errmaj, &errmin)) { 89509885543Smrg LoaderErrorMsg(NULL, "exa", errmaj, errmin); 89609885543Smrg SMI_FreeRec(pScrn); 8977104f784Smrg LEAVE(FALSE); 89809885543Smrg } 89909885543Smrg } 90009885543Smrg } 90109885543Smrg 90209885543Smrg /* Load ramdac if needed */ 9037104f784Smrg if (pSmi->HwCursor) { 90409885543Smrg if (!xf86LoadSubModule(pScrn, "ramdac")) { 90509885543Smrg SMI_FreeRec(pScrn); 9067104f784Smrg LEAVE(FALSE); 90709885543Smrg } 90809885543Smrg } 90909885543Smrg 9107104f784Smrg LEAVE(TRUE); 91109885543Smrg} 91209885543Smrg 91309885543Smrg/* 91409885543Smrg * This is called when VT switching back to the X server. Its job is to 91509885543Smrg * reinitialise the video mode. We may wish to unmap video/MMIO memory too. 91609885543Smrg */ 91709885543Smrg 91809885543Smrgstatic Bool 9195788ca14SmrgSMI_EnterVT(VT_FUNC_ARGS_DECL) 92009885543Smrg{ 9215788ca14Smrg SCRN_INFO_PTR(arg); 92209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 92309885543Smrg 9247104f784Smrg ENTER(); 92509885543Smrg 92609885543Smrg /* Enable MMIO and map memory */ 92709885543Smrg SMI_MapMem(pScrn); 92809885543Smrg 9297104f784Smrg pSmi->Save(pScrn); 93009885543Smrg 9317104f784Smrg /* FBBase may have changed after remapping the memory */ 9327104f784Smrg pScrn->pScreen->ModifyPixmapHeader(pScrn->pScreen->GetScreenPixmap(pScrn->pScreen), 9337104f784Smrg -1,-1,-1,-1,-1, pSmi->FBBase + pSmi->FBOffset); 9347b58d2e0Smrg#if (XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 9, 99, 1, 0)) 9357104f784Smrg pScrn->pixmapPrivate.ptr=pSmi->FBBase + pSmi->FBOffset; 9367b58d2e0Smrg#endif 93709885543Smrg 9387104f784Smrg if(pSmi->useEXA) 9397104f784Smrg pSmi->EXADriverPtr->memoryBase=pSmi->FBBase; 94009885543Smrg 9417104f784Smrg /* Do the CRTC independent initialization */ 9427104f784Smrg if(!SMI_HWInit(pScrn)) 9437104f784Smrg LEAVE(FALSE); 94409885543Smrg 9457104f784Smrg /* Initialize the chosen modes */ 9467104f784Smrg if (!xf86SetDesiredModes(pScrn)) 9477104f784Smrg LEAVE(FALSE); 94809885543Smrg 9497104f784Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 9507104f784Smrg "Done writing mode. Register dump:\n"); 9517104f784Smrg SMI_PrintRegs(pScrn); 95209885543Smrg 95372320d7bSmrg /* Reset the graphics engine */ 95409885543Smrg if (!pSmi->NoAccel) 95509885543Smrg SMI_EngineReset(pScrn); 95609885543Smrg 9577104f784Smrg LEAVE(TRUE); 95809885543Smrg} 95909885543Smrg 96009885543Smrg/* 96109885543Smrg * This is called when VT switching away from the X server. Its job is to 96209885543Smrg * restore the previous (text) mode. We may wish to remap video/MMIO memory 96309885543Smrg * too. 96409885543Smrg */ 96509885543Smrg 96609885543Smrgstatic void 9675788ca14SmrgSMI_LeaveVT(VT_FUNC_ARGS_DECL) 96809885543Smrg{ 9695788ca14Smrg SCRN_INFO_PTR(arg); 9707104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 97109885543Smrg 9727104f784Smrg ENTER(); 97309885543Smrg 9747104f784Smrg SMI_AccelSync(pScrn); 97509885543Smrg 9767104f784Smrg /* Ensure that the rotation BlockHandler is unwrapped, and the shadow 9777104f784Smrg pixmaps are deallocated, as the video memory is going to be 9787104f784Smrg unmapped. */ 9797104f784Smrg xf86RotateCloseScreen(pScrn->pScreen); 98009885543Smrg 9817104f784Smrg /* Pixmaps that by chance get allocated near the former aperture 9827104f784Smrg address shouldn't be considered offscreen. */ 9837104f784Smrg if(pSmi->useEXA) 9847104f784Smrg pSmi->EXADriverPtr->memoryBase=NULL; 98509885543Smrg 9867104f784Smrg /* Clear frame buffer */ 9877104f784Smrg memset(pSmi->FBBase, 0, pSmi->videoRAMBytes); 9887104f784Smrg 9897104f784Smrg if (!IS_MSOC(pSmi)) { 9907104f784Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 9917104f784Smrg 9927104f784Smrg SMILynx_WriteMode(pScrn, &hwp->SavedReg, pSmi->save); 99309885543Smrg } 9947104f784Smrg else 9957104f784Smrg SMI501_WriteMode(pScrn, pSmi->save); 99609885543Smrg 99709885543Smrg SMI_UnmapMem(pScrn); 99809885543Smrg 9997104f784Smrg LEAVE(); 100009885543Smrg} 100109885543Smrg 100209885543Smrgstatic void 10037104f784SmrgSMI_DetectPanelSize(ScrnInfoPtr pScrn) 100409885543Smrg{ 1005621ff18cSmrg const char *s; 10067104f784Smrg int width, height; 10077104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 100809885543Smrg 10097104f784Smrg pSmi->lcdWidth = 0; 10107104f784Smrg pSmi->lcdHeight = 0; 10117104f784Smrg if ((s = xf86GetOptValString(pSmi->Options, OPTION_PANEL_SIZE)) != NULL) { 10127104f784Smrg if (sscanf(s, "%dx%d", &width, &height) != 2) 10137104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 10147104f784Smrg "Invalid PanelSize option: %s\n", s); 10157104f784Smrg else { 10167104f784Smrg pSmi->lcdWidth = width; 10177104f784Smrg pSmi->lcdHeight = height; 101809885543Smrg } 101909885543Smrg } 102009885543Smrg 10217104f784Smrg if (pSmi->lcdWidth == 0 || pSmi->lcdHeight == 0) { 10227104f784Smrg /* panel size detection ... requires BIOS call on 730 hardware */ 1023eb3dced6Smacallan#ifdef USE_INT10 10247104f784Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 10257104f784Smrg if (pSmi->pInt10 != NULL) { 10267104f784Smrg pSmi->pInt10->num = 0x10; 10277104f784Smrg pSmi->pInt10->ax = 0x5F00; 10287104f784Smrg pSmi->pInt10->bx = 0; 10297104f784Smrg pSmi->pInt10->cx = 0; 10307104f784Smrg pSmi->pInt10->dx = 0; 10317104f784Smrg xf86ExecX86int10(pSmi->pInt10); 10327104f784Smrg if (pSmi->pInt10->ax == 0x005F) { 10337104f784Smrg switch (pSmi->pInt10->cx & 0x0F) { 10347104f784Smrg case PANEL_640x480: 10357104f784Smrg pSmi->lcdWidth = 640; 10367104f784Smrg pSmi->lcdHeight = 480; 10377104f784Smrg break; 10387104f784Smrg case PANEL_800x600: 10397104f784Smrg pSmi->lcdWidth = 800; 10407104f784Smrg pSmi->lcdHeight = 600; 10417104f784Smrg break; 10427104f784Smrg case PANEL_1024x768: 10437104f784Smrg pSmi->lcdWidth = 1024; 10447104f784Smrg pSmi->lcdHeight = 768; 10457104f784Smrg break; 10467104f784Smrg case PANEL_1280x1024: 10477104f784Smrg pSmi->lcdWidth = 1280; 10487104f784Smrg pSmi->lcdHeight = 1024; 10497104f784Smrg break; 10507104f784Smrg case PANEL_1600x1200: 10517104f784Smrg pSmi->lcdWidth = 1600; 10527104f784Smrg pSmi->lcdHeight = 1200; 10537104f784Smrg break; 10547104f784Smrg case PANEL_1400x1050: 10557104f784Smrg pSmi->lcdWidth = 1400; 10567104f784Smrg pSmi->lcdHeight = 1050; 10577104f784Smrg break; 10587104f784Smrg } 105909885543Smrg 10607104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 10617104f784Smrg "Detected panel size via BIOS: %d x %d\n", 10627104f784Smrg pSmi->lcdWidth, pSmi->lcdHeight); 106309885543Smrg } 10647104f784Smrg else 10657104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 10667104f784Smrg "BIOS error during 730 panel detection!\n"); 106709885543Smrg } 10687104f784Smrg else { 10697104f784Smrg /* int10 support isn't setup on the second call to this function, 10707104f784Smrg o if this is the second call, don't do detection again */ 10717104f784Smrg if (pSmi->lcd == 0) 10727104f784Smrg /* If we get here, int10 support is not loaded or not working */ 10737104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 10747104f784Smrg "No BIOS support for 730 panel detection!\n"); 107509885543Smrg } 107609885543Smrg 10777104f784Smrg /* Set this to indicate that we've done the detection */ 10787104f784Smrg pSmi->lcd = 1; 107909885543Smrg } 1080eb3dced6Smacallan else 1081eb3dced6Smacallan#endif /* USE_INT10 */ 1082eb3dced6Smacallan if (IS_MSOC(pSmi)) { 10837104f784Smrg pSmi->lcdWidth = (READ_SCR(pSmi, PANEL_WWIDTH) >> 16) & 2047; 10847104f784Smrg pSmi->lcdHeight = (READ_SCR(pSmi, PANEL_WHEIGHT) >> 16) & 2047; 108509885543Smrg } 10867104f784Smrg else { 10877104f784Smrg /* panel size detection for hardware other than 730 */ 10887104f784Smrg pSmi->lcd = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 10897104f784Smrg 0x31) & 0x01; 109009885543Smrg 10917104f784Smrg if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 10927104f784Smrg 0x30) & 0x01) { 10937104f784Smrg pSmi->lcd <<= 1; 10947104f784Smrg } 10957104f784Smrg switch (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 10967104f784Smrg 0x30) & 0x0C) { 10977104f784Smrg case 0x00: 109809885543Smrg pSmi->lcdWidth = 640; 109909885543Smrg pSmi->lcdHeight = 480; 110009885543Smrg break; 11017104f784Smrg case 0x04: 110209885543Smrg pSmi->lcdWidth = 800; 110309885543Smrg pSmi->lcdHeight = 600; 110409885543Smrg break; 11057104f784Smrg case 0x08: 11067104f784Smrg if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 11077104f784Smrg 0x74) & 0x02) { 11087104f784Smrg pSmi->lcdWidth = 1024; 11097104f784Smrg pSmi->lcdHeight = 600; 11107104f784Smrg } 11117104f784Smrg else { 11127104f784Smrg pSmi->lcdWidth = 1024; 11137104f784Smrg pSmi->lcdHeight = 768; 11147104f784Smrg } 111509885543Smrg break; 11167104f784Smrg case 0x0C: 111709885543Smrg pSmi->lcdWidth = 1280; 111809885543Smrg pSmi->lcdHeight = 1024; 111909885543Smrg break; 112009885543Smrg } 112109885543Smrg } 112209885543Smrg } 112309885543Smrg 11247104f784Smrg if (!pSmi->lcdWidth && (pSmi->lcdWidth = pScrn->virtualX) == 0) 11257104f784Smrg pSmi->lcdWidth = 1024; 11267104f784Smrg if (!pSmi->lcdHeight && (pSmi->lcdHeight = pScrn->virtualY) == 0) 11277104f784Smrg pSmi->lcdHeight = 768; 11287104f784Smrg 112909885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s Panel Size = %dx%d\n", 113009885543Smrg (pSmi->lcd == 0) ? "OFF" : (pSmi->lcd == 1) ? "TFT" : "DSTN", 113109885543Smrg pSmi->lcdWidth, pSmi->lcdHeight); 113209885543Smrg 113309885543Smrg} 113409885543Smrg 11357104f784Smrgstatic void 11367104f784SmrgSMI_DetectMCLK(ScrnInfoPtr pScrn) 11377104f784Smrg{ 11387104f784Smrg double real; 11397104f784Smrg MSOCClockRec clock; 11407104f784Smrg int mclk, mxclk; 11417104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 11427104f784Smrg 11437104f784Smrg /* MCLK defaults */ 11447104f784Smrg if (pSmi->Chipset == SMI_LYNXEMplus){ 11457104f784Smrg /* The SM712 can be safely clocked up to 157MHz, according to 11467104f784Smrg Silicon Motion engineers. */ 11477104f784Smrg pSmi->MCLK = 157000; 11487104f784Smrg 11492ec8c4b4Smrg } else if (IS_MSOC(pSmi)) { 11502ec8c4b4Smrg /* Set some sane defaults for the clock settings if we are on a 11512ec8c4b4Smrg SM502 and it's likely to be uninitialized. */ 11522ec8c4b4Smrg 11532ec8c4b4Smrg if (!xf86IsPrimaryPci(pSmi->PciInfo) && 11542ec8c4b4Smrg (READ_SCR(pSmi, DEVICE_ID) & 0xFF) >= 0xC0) { 11552ec8c4b4Smrg pSmi->MCLK = 112000; 11562ec8c4b4Smrg pSmi->MXCLK = 144000; 11572ec8c4b4Smrg } 11582ec8c4b4Smrg 11592ec8c4b4Smrg } else { 11602ec8c4b4Smrg pSmi->MCLK = 0; 11612ec8c4b4Smrg pSmi->MXCLK = 0; 11622ec8c4b4Smrg } 11637104f784Smrg 11647104f784Smrg /* MCLK from user settings */ 11657104f784Smrg if (xf86GetOptValFreq(pSmi->Options, OPTION_MCLK, OPTUNITS_MHZ, &real)) { 11667104f784Smrg if (IS_MSOC(pSmi) || (int)real <= 120) { 11677104f784Smrg pSmi->MCLK = (int)(real * 1000.0); 11687104f784Smrg } else { 11697104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 11707104f784Smrg "Memory Clock %1.3f MHz larger than limit of 120 MHz\n", 11717104f784Smrg real); 11727104f784Smrg } 11737104f784Smrg } 11747104f784Smrg mclk = pSmi->MCLK; 11757104f784Smrg 11767104f784Smrg if (IS_MSOC(pSmi)) { 11777104f784Smrg clock.value = READ_SCR(pSmi, CURRENT_CLOCK); 11787104f784Smrg if (xf86GetOptValFreq(pSmi->Options, OPTION_MXCLK, 11797104f784Smrg OPTUNITS_MHZ, &real)) 11807104f784Smrg pSmi->MXCLK = (int)(real * 1000.0); 11817104f784Smrg } 11827104f784Smrg 11837104f784Smrg /* Already programmed MCLK */ 11847104f784Smrg if (pSmi->MCLK == 0) { 11857104f784Smrg if (IS_MSOC(pSmi)) 11867104f784Smrg mclk = ((clock.f.m_select ? 336 : 288) / 11877104f784Smrg ((clock.f.m_divider ? 3 : 1) << 11887104f784Smrg (unsigned)clock.f.m_shift)) * 1000; 11897104f784Smrg else { 11907104f784Smrg unsigned char shift, m, n; 11917104f784Smrg 11927104f784Smrg m = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A); 11937104f784Smrg n = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B); 11947104f784Smrg switch (n >> 6) { 11957104f784Smrg case 1: 11967104f784Smrg shift = 4; 11977104f784Smrg break; 11987104f784Smrg case 2: 11997104f784Smrg shift = 2; 12007104f784Smrg break; 12017104f784Smrg default: 12027104f784Smrg shift = 1; 12037104f784Smrg break; 12047104f784Smrg } 12057104f784Smrg n &= 0x3F; 12067104f784Smrg mclk = ((1431818 * m) / n / shift + 50) / 100; 12077104f784Smrg } 12087104f784Smrg } 12097104f784Smrg 12107104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MCLK = %1.3f\n", mclk / 1000.0); 12117104f784Smrg if (IS_MSOC(pSmi)) { 12127104f784Smrg if (pSmi->MXCLK == 0) { 12137104f784Smrg mxclk = ((clock.f.m1_select ? 336 : 288) / 12147104f784Smrg ((clock.f.m1_divider ? 3 : 1) << 12157104f784Smrg (unsigned)clock.f.m1_shift)) * 1000; 12167104f784Smrg } 12177104f784Smrg else 12187104f784Smrg mxclk = pSmi->MXCLK; 12197104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MXCLK = %1.3f\n", mxclk / 1000.0); 12207104f784Smrg } 12217104f784Smrg} 12227104f784Smrg 122309885543Smrgstatic Bool 12247104f784SmrgSMI_MapMmio(ScrnInfoPtr pScrn) 122509885543Smrg{ 12267104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 12277104f784Smrg CARD32 memBase; 122809885543Smrg 12297104f784Smrg SMI_EnableMmio(pScrn); 123009885543Smrg 123109885543Smrg switch (pSmi->Chipset) { 12327104f784Smrg case SMI_COUGAR3DR: 12337104f784Smrg memBase = PCI_REGION_BASE(pSmi->PciInfo, 1, REGION_MEM); 12347104f784Smrg pSmi->MapSize = 0x200000; 12357104f784Smrg break; 12367104f784Smrg case SMI_LYNX3D: 12377104f784Smrg memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + 0x680000; 12387104f784Smrg pSmi->MapSize = 0x180000; 12397104f784Smrg break; 12407104f784Smrg case SMI_LYNXEM: 12417104f784Smrg case SMI_LYNXEMplus: 12427104f784Smrg memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + 0x400000; 12437104f784Smrg pSmi->MapSize = 0x400000; 12447104f784Smrg break; 12457104f784Smrg case SMI_LYNX3DM: 12467104f784Smrg memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM); 12477104f784Smrg pSmi->MapSize = 0x200000; 12487104f784Smrg break; 12497104f784Smrg case SMI_MSOC: 12507104f784Smrg memBase = PCI_REGION_BASE(pSmi->PciInfo, 1, REGION_MEM); 12517104f784Smrg pSmi->MapSize = 0x200000; 12527104f784Smrg break; 12537104f784Smrg default: 12547104f784Smrg memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + 0x400000; 12557104f784Smrg pSmi->MapSize = 0x10000; 12567104f784Smrg break; 125709885543Smrg } 12587104f784Smrg 12597104f784Smrg#ifndef XSERVER_LIBPCIACCESS 126009885543Smrg pSmi->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pSmi->PciTag, 126109885543Smrg memBase, pSmi->MapSize); 12627104f784Smrg#else 12637104f784Smrg { 12647104f784Smrg void **result = (void**)&pSmi->MapBase; 12657104f784Smrg int err = pci_device_map_range(pSmi->PciInfo, 12667104f784Smrg memBase, 12677104f784Smrg pSmi->MapSize, 12687104f784Smrg PCI_DEV_MAP_FLAG_WRITABLE, 12697104f784Smrg result); 12707104f784Smrg 12717104f784Smrg if (err) 1272eb3dced6Smacallan pSmi->MapBase = NULL; 12737104f784Smrg } 12747104f784Smrg#endif 127509885543Smrg 127609885543Smrg if (pSmi->MapBase == NULL) { 127709885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Internal error: could not map " 127809885543Smrg "MMIO registers.\n"); 12797104f784Smrg return (FALSE); 128009885543Smrg } 128109885543Smrg 128209885543Smrg switch (pSmi->Chipset) { 12837104f784Smrg case SMI_COUGAR3DR: 12847104f784Smrg pSmi->DPRBase = pSmi->MapBase + 0x000000; 12857104f784Smrg pSmi->VPRBase = pSmi->MapBase + 0x000800; 12867104f784Smrg pSmi->CPRBase = pSmi->MapBase + 0x001000; 12877104f784Smrg pSmi->FPRBase = pSmi->MapBase + 0x005800; 12887104f784Smrg pSmi->IOBase = pSmi->MapBase + 0x0C0000; 12897104f784Smrg pSmi->DataPortBase = pSmi->MapBase + 0x100000; 12907104f784Smrg pSmi->DataPortSize = 0x100000; 12917104f784Smrg break; 12927104f784Smrg case SMI_LYNX3D: 12937104f784Smrg pSmi->DPRBase = pSmi->MapBase + 0x000000; 12947104f784Smrg pSmi->VPRBase = pSmi->MapBase + 0x000800; 12957104f784Smrg pSmi->CPRBase = pSmi->MapBase + 0x001000; 12967104f784Smrg pSmi->IOBase = pSmi->MapBase + 0x040000; 12977104f784Smrg pSmi->DataPortBase = pSmi->MapBase + 0x080000; 12987104f784Smrg pSmi->DataPortSize = 0x100000; 12997104f784Smrg break; 13007104f784Smrg case SMI_LYNXEM: 13017104f784Smrg case SMI_LYNXEMplus: 13027104f784Smrg pSmi->DPRBase = pSmi->MapBase + 0x008000; 13037104f784Smrg pSmi->VPRBase = pSmi->MapBase + 0x00C000; 13047104f784Smrg pSmi->CPRBase = pSmi->MapBase + 0x00E000; 13057104f784Smrg pSmi->IOBase = pSmi->MapBase + 0x300000; 13067104f784Smrg pSmi->DataPortBase = pSmi->MapBase /*+ 0x100000*/; 13077104f784Smrg pSmi->DataPortSize = 0x8000 /*0x200000*/; 13087104f784Smrg break; 13097104f784Smrg case SMI_LYNX3DM: 13107104f784Smrg pSmi->DPRBase = pSmi->MapBase + 0x000000; 13117104f784Smrg pSmi->VPRBase = pSmi->MapBase + 0x000800; 13127104f784Smrg pSmi->CPRBase = pSmi->MapBase + 0x001000; 13137104f784Smrg pSmi->IOBase = pSmi->MapBase + 0x0C0000; 13147104f784Smrg pSmi->DataPortBase = pSmi->MapBase + 0x100000; 13157104f784Smrg pSmi->DataPortSize = 0x100000; 13167104f784Smrg break; 13177104f784Smrg case SMI_MSOC: 13187104f784Smrg pSmi->DPRBase = pSmi->MapBase + 0x100000; 13197104f784Smrg pSmi->VPRBase = pSmi->MapBase + 0x000000; 13207104f784Smrg pSmi->CPRBase = pSmi->MapBase + 0x090000; 13217104f784Smrg pSmi->DCRBase = pSmi->MapBase + 0x080000; 13227104f784Smrg pSmi->SCRBase = pSmi->MapBase + 0x000000; 13237104f784Smrg pSmi->IOBase = 0; 13247104f784Smrg pSmi->DataPortBase = pSmi->MapBase + 0x110000; 13257104f784Smrg pSmi->DataPortSize = 0x10000; 13267104f784Smrg break; 13277104f784Smrg default: 13287104f784Smrg pSmi->DPRBase = pSmi->MapBase + 0x8000; 13297104f784Smrg pSmi->VPRBase = pSmi->MapBase + 0xC000; 13307104f784Smrg pSmi->CPRBase = pSmi->MapBase + 0xE000; 13317104f784Smrg pSmi->IOBase = NULL; 13327104f784Smrg pSmi->DataPortBase = pSmi->MapBase; 13337104f784Smrg pSmi->DataPortSize = 0x8000; 13347104f784Smrg break; 133509885543Smrg } 13367104f784Smrg 133709885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 133809885543Smrg "Physical MMIO at 0x%08lX\n", (unsigned long)memBase); 133909885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 134009885543Smrg "Logical MMIO at %p - %p\n", pSmi->MapBase, 134109885543Smrg pSmi->MapBase + pSmi->MapSize - 1); 134209885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 134309885543Smrg "DPR=%p, VPR=%p, IOBase=%p\n", 134409885543Smrg pSmi->DPRBase, pSmi->VPRBase, pSmi->IOBase); 134509885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 134609885543Smrg "DataPort=%p - %p\n", pSmi->DataPortBase, 134709885543Smrg pSmi->DataPortBase + pSmi->DataPortSize - 1); 134809885543Smrg 13497104f784Smrg return (TRUE); 13507104f784Smrg} 135109885543Smrg 13522ec8c4b4Smrg/* HACK - In some cases the BIOS hasn't filled in the "scratchpad 13532ec8c4b4Smrg registers" (SR71) with the right amount of memory installed (e.g. MIPS 13542ec8c4b4Smrg platform). Probe it manually. */ 13552ec8c4b4Smrgstatic unsigned long 13562ec8c4b4SmrgSMI_ProbeMem(ScrnInfoPtr pScrn, unsigned long mem_skip, unsigned long mem_max) 13572ec8c4b4Smrg{ 13582ec8c4b4Smrg SMIPtr pSmi = SMIPTR(pScrn); 13592ec8c4b4Smrg unsigned long mem_probe = 1024*1024; 13602ec8c4b4Smrg unsigned long aperture_base; 13612ec8c4b4Smrg void* mem; 13622ec8c4b4Smrg 13632ec8c4b4Smrg ENTER(); 13642ec8c4b4Smrg 13652ec8c4b4Smrg aperture_base = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + mem_skip; 13662ec8c4b4Smrg mem_max = min(mem_max , PCI_REGION_SIZE(pSmi->PciInfo, 0) - mem_skip); 13672ec8c4b4Smrg 13682ec8c4b4Smrg#ifndef XSERVER_LIBPCIACCESS 13692ec8c4b4Smrg mem = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pSmi->PciTag, 13702ec8c4b4Smrg aperture_base, mem_max); 13712ec8c4b4Smrg 13722ec8c4b4Smrg if(!mem) 13732ec8c4b4Smrg LEAVE(0); 13742ec8c4b4Smrg#else 13752ec8c4b4Smrg if(pci_device_map_range(pSmi->PciInfo, aperture_base, mem_max, 13762ec8c4b4Smrg PCI_DEV_MAP_FLAG_WRITABLE, &mem)) 13772ec8c4b4Smrg LEAVE(0); 13782ec8c4b4Smrg#endif 13792ec8c4b4Smrg 13802ec8c4b4Smrg while(mem_probe <= mem_max){ 13812ec8c4b4Smrg MMIO_OUT32(mem, mem_probe-4, 0x55555555); 13822ec8c4b4Smrg if(MMIO_IN32(mem, mem_probe-4) != 0x55555555) 13832ec8c4b4Smrg break; 13842ec8c4b4Smrg 13852ec8c4b4Smrg MMIO_OUT32(mem, mem_probe-4, 0xAAAAAAAA); 13862ec8c4b4Smrg if(MMIO_IN32(mem, mem_probe-4) != 0xAAAAAAAA) 13872ec8c4b4Smrg break; 13882ec8c4b4Smrg 13892ec8c4b4Smrg mem_probe <<= 1; 13902ec8c4b4Smrg } 13912ec8c4b4Smrg 13922ec8c4b4Smrg#ifndef XSERVER_LIBPCIACCESS 13932ec8c4b4Smrg xf86UnMapVidMem(pScrn->scrnIndex, mem, mem_max); 13942ec8c4b4Smrg#else 13952ec8c4b4Smrg pci_device_unmap_range(pSmi->PciInfo, mem, mem_max); 13962ec8c4b4Smrg#endif 13972ec8c4b4Smrg 13982ec8c4b4Smrg LEAVE(mem_probe >> 1); 13992ec8c4b4Smrg} 14002ec8c4b4Smrg 14017104f784Smrgstatic Bool 14027104f784SmrgSMI_DetectMem(ScrnInfoPtr pScrn) 14037104f784Smrg{ 14047104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 14057104f784Smrg MessageType from; 140609885543Smrg 14077104f784Smrg if ((pScrn->videoRam = pScrn->confScreen->device->videoRam)){ 14087104f784Smrg pSmi->videoRAMKBytes = pScrn->videoRam; 14097104f784Smrg from = X_CONFIG; 14107104f784Smrg } 14117104f784Smrg else { 14127104f784Smrg unsigned char config; 14137104f784Smrg static int lynx3d_table[4] = { 0, 2, 4, 6 }; 14147104f784Smrg static int lynx3dm_table[4] = { 16, 2, 4, 8 }; 14157104f784Smrg static int msoc_table[8] = { 4, 8, 16, 32, 64, 2, 0, 0 }; 14167104f784Smrg static int default_table[4] = { 1, 2, 4, 0 }; 14177104f784Smrg 14187104f784Smrg if (IS_MSOC(pSmi)) { 14197104f784Smrg config = (READ_SCR(pSmi, DRAM_CTL) >> 13) & 7; 14207104f784Smrg pSmi->videoRAMKBytes = msoc_table[config] * 1024 - 14217104f784Smrg SHARED_USB_DMA_BUFFER_SIZE; 14227104f784Smrg } 14237104f784Smrg else { 14247104f784Smrg config = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x71); 14257104f784Smrg switch (pSmi->Chipset) { 14267104f784Smrg case SMI_LYNX3D: 14277104f784Smrg pSmi->videoRAMKBytes = lynx3d_table[config >> 6] * 1024 + 14287104f784Smrg 512; 14297104f784Smrg break; 14302ec8c4b4Smrg case SMI_LYNXEMplus: 14312ec8c4b4Smrg pSmi->videoRAMKBytes = SMI_ProbeMem(pScrn, 0, 0x400000) / 1024; 14322ec8c4b4Smrg break; 14337104f784Smrg case SMI_LYNX3DM: 14347104f784Smrg pSmi->videoRAMKBytes = lynx3dm_table[config >> 6] * 1024; 14357104f784Smrg break; 14367104f784Smrg case SMI_COUGAR3DR: 14377104f784Smrg /* DANGER - Cougar3DR BIOS is broken - hardcode video ram 14387104f784Smrg * size per instructions from Silicon Motion engineers */ 14397104f784Smrg pSmi->videoRAMKBytes = 16 * 1024; 14407104f784Smrg break; 14417104f784Smrg default: 14427104f784Smrg pSmi->videoRAMKBytes = default_table[config >> 6] * 1024; 14437104f784Smrg break; 14447104f784Smrg } 144509885543Smrg } 14467104f784Smrg from = X_PROBED; 14477104f784Smrg } 144809885543Smrg 14497104f784Smrg pSmi->videoRAMBytes = pSmi->videoRAMKBytes * 1024; 14507104f784Smrg pScrn->videoRam = pSmi->videoRAMKBytes; 14517104f784Smrg xf86DrvMsg(pScrn->scrnIndex, from, 14527104f784Smrg "videoram: %dkB\n", pSmi->videoRAMKBytes); 145309885543Smrg 14547104f784Smrg return (TRUE); 14557104f784Smrg} 145609885543Smrg 14577104f784SmrgBool 14587104f784SmrgSMI_MapMem(ScrnInfoPtr pScrn) 14597104f784Smrg{ 14607104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 14617104f784Smrg vgaHWPtr hwp; 146209885543Smrg 14637104f784Smrg ENTER(); 14647104f784Smrg 14657104f784Smrg if (pSmi->MapBase == NULL && SMI_MapMmio(pScrn) == FALSE) 14667104f784Smrg LEAVE(FALSE); 14677104f784Smrg 14687104f784Smrg pScrn->memPhysBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM); 14697104f784Smrg 14707104f784Smrg if (pSmi->Chipset == SMI_LYNX3DM) 14717104f784Smrg pSmi->fbMapOffset = 0x200000; 14727104f784Smrg else 14737104f784Smrg pSmi->fbMapOffset = 0x0; 14747104f784Smrg 14757104f784Smrg#ifndef XSERVER_LIBPCIACCESS 14767104f784Smrg pSmi->FBBase = xf86MapPciMem(pScrn->scrnIndex, 14777104f784Smrg VIDMEM_FRAMEBUFFER, 14787104f784Smrg pSmi->PciTag, 14797104f784Smrg pScrn->memPhysBase + pSmi->fbMapOffset, 14807104f784Smrg pSmi->videoRAMBytes); 14817104f784Smrg#else 14827104f784Smrg { 14837104f784Smrg void **result = (void**)&pSmi->FBBase; 14847104f784Smrg int err = pci_device_map_range(pSmi->PciInfo, 14857104f784Smrg pScrn->memPhysBase + 14867104f784Smrg pSmi->fbMapOffset, 14877104f784Smrg pSmi->videoRAMBytes, 14887104f784Smrg PCI_DEV_MAP_FLAG_WRITABLE | 14897104f784Smrg PCI_DEV_MAP_FLAG_WRITE_COMBINE, 14907104f784Smrg result); 14917104f784Smrg 14927104f784Smrg if (err) 14937104f784Smrg LEAVE(FALSE); 14947104f784Smrg } 14957104f784Smrg#endif 14967104f784Smrg 14977104f784Smrg if (pSmi->FBBase == NULL) { 14987104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 14997104f784Smrg "Internal error: could not map framebuffer.\n"); 15007104f784Smrg LEAVE(FALSE); 15017104f784Smrg } 15027104f784Smrg 15037104f784Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 15047104f784Smrg "Physical frame buffer at 0x%08lX offset: 0x%08lX\n", 15057b58d2e0Smrg pScrn->memPhysBase, (unsigned long)pSmi->fbMapOffset); 15067104f784Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 15077104f784Smrg "Logical frame buffer at %p - %p\n", pSmi->FBBase, 15087104f784Smrg pSmi->FBBase + pSmi->videoRAMBytes - 1); 15097104f784Smrg 15107104f784Smrg if (IS_MSOC(pSmi)) { 15117104f784Smrg /* Reserve space for panel cursr, and crt if in dual head mode */ 15127104f784Smrg#if SMI_CURSOR_ALPHA_PLANE 15137104f784Smrg pSmi->FBReserved = pSmi->FBCursorOffset = pSmi->videoRAMBytes - 15147104f784Smrg (pSmi->Dualhead ? SMI501_CURSOR_SIZE << 1 : SMI501_ARGB_CURSOR_SIZE); 15157104f784Smrg#else 15167104f784Smrg pSmi->FBReserved = pSmi->FBCursorOffset = pSmi->videoRAMBytes - 15177104f784Smrg (pSmi->Dualhead ? SMI501_CURSOR_SIZE << 1 : SMI501_CURSOR_SIZE); 15187104f784Smrg 15197104f784Smrg# if SMI501_CLI_DEBUG 15207104f784Smrg if (pSmi->useEXA) { 15217104f784Smrg pSmi->batch_active = FALSE; 15227104f784Smrg pSmi->batch_length = 4096; 15237104f784Smrg pSmi->FBReserved -= pSmi->batch_length << 3; 15247104f784Smrg pSmi->batch_offset = pSmi->FBReserved; 15257104f784Smrg pSmi->batch_handle = (int64_t *)(pSmi->FBBase + pSmi->batch_offset); 15267104f784Smrg pSmi->batch_finish = -1; 15277104f784Smrg pSmi->batch_index = 0; 15287104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 15297104f784Smrg "Using command list interpreter debug code\n"); 15307104f784Smrg } 15317104f784Smrg# endif 15327104f784Smrg 15337104f784Smrg#endif 15347104f784Smrg } 15357104f784Smrg else { 15367104f784Smrg /* Set up offset to hwcursor memory area, at the end of 15377104f784Smrg * the frame buffer. 15387104f784Smrg */ 15397104f784Smrg pSmi->FBCursorOffset = pSmi->videoRAMBytes - SMILYNX_CURSOR_SIZE; 154009885543Smrg /* set up the fifo reserved space */ 154109885543Smrg if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30) & 0x01)/* #1074 */ { 154209885543Smrg CARD32 fifoOffset = 0; 15437104f784Smrg fifoOffset |= VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 15447104f784Smrg 0x46) << 3; 15457104f784Smrg fifoOffset |= VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 15467104f784Smrg 0x47) << 11; 15477104f784Smrg fifoOffset |= (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 15487104f784Smrg 0x49) & 0x1C) << 17; 154909885543Smrg pSmi->FBReserved = fifoOffset; /* PDR#1074 */ 155009885543Smrg } 15517104f784Smrg else 15527104f784Smrg pSmi->FBReserved = pSmi->videoRAMBytes - 2048; 155309885543Smrg 15547104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Cursor Offset: %08lX\n", 15557104f784Smrg (unsigned long)pSmi->FBCursorOffset); 155609885543Smrg 15577104f784Smrg /* Assign hwp->MemBase & IOBase here */ 15587104f784Smrg hwp = VGAHWPTR(pScrn); 15597104f784Smrg if (pSmi->IOBase != NULL) 15607104f784Smrg vgaHWSetMmioFuncs(hwp, pSmi->MapBase, pSmi->IOBase - pSmi->MapBase); 15617104f784Smrg vgaHWGetIOBase(hwp); 156209885543Smrg 15637104f784Smrg /* Map the VGA memory when the primary video */ 15647104f784Smrg if (xf86IsPrimaryPci(pSmi->PciInfo)) { 15657104f784Smrg hwp->MapSize = 0x10000; 15667104f784Smrg if (!vgaHWMapMem(pScrn)) 15677104f784Smrg LEAVE(FALSE); 15687104f784Smrg pSmi->PrimaryVidMapped = TRUE; 156909885543Smrg } 157009885543Smrg } 157109885543Smrg 15727104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reserved: %08lX\n", 15737104f784Smrg (unsigned long)pSmi->FBReserved); 15747104f784Smrg 15757104f784Smrg LEAVE(TRUE); 157609885543Smrg} 157709885543Smrg 157809885543Smrg/* UnMapMem - contains half of pre-4.0 EnterLeave function. The EnterLeave 157909885543Smrg * function which en/disable access to IO ports and ext. regs 158009885543Smrg */ 158109885543Smrg 15827104f784Smrgvoid 158309885543SmrgSMI_UnmapMem(ScrnInfoPtr pScrn) 158409885543Smrg{ 158509885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 158609885543Smrg 15877104f784Smrg ENTER(); 158809885543Smrg 158909885543Smrg /* Unmap VGA mem if mapped. */ 159009885543Smrg if (pSmi->PrimaryVidMapped) { 159109885543Smrg vgaHWUnmapMem(pScrn); 159209885543Smrg pSmi->PrimaryVidMapped = FALSE; 159309885543Smrg } 159409885543Smrg 159509885543Smrg SMI_DisableMmio(pScrn); 159609885543Smrg 15977104f784Smrg if (pSmi->MapBase) { 15987104f784Smrg#ifndef XSERVER_LIBPCIACCESS 15997104f784Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSmi->MapBase, 16007104f784Smrg pSmi->MapSize); 16017104f784Smrg#else 16027104f784Smrg pci_device_unmap_range(pSmi->PciInfo, (pointer)pSmi->MapBase, 16037104f784Smrg pSmi->MapSize); 16047104f784Smrg#endif 16057104f784Smrg pSmi->MapBase = NULL; 16067104f784Smrg } 16077104f784Smrg 16087104f784Smrg if (pSmi->FBBase) { 16097104f784Smrg#ifndef XSERVER_LIBPCIACCESS 161009885543Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pSmi->FBBase, 161109885543Smrg pSmi->videoRAMBytes); 16127104f784Smrg#else 16137104f784Smrg pci_device_unmap_range(pSmi->PciInfo, (pointer)pSmi->FBBase, 16147104f784Smrg pSmi->videoRAMBytes); 16157104f784Smrg#endif 16167104f784Smrg pSmi->FBBase = NULL; 161709885543Smrg } 161809885543Smrg 16197104f784Smrg LEAVE(); 162009885543Smrg} 162109885543Smrg 162209885543Smrg/* This gets called at the start of each server generation. */ 162309885543Smrg 162409885543Smrgstatic Bool 16255788ca14SmrgSMI_ScreenInit(SCREEN_INIT_ARGS_DECL) 162609885543Smrg{ 16275788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 16287104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 16297104f784Smrg EntityInfoPtr pEnt; 163009885543Smrg 16317104f784Smrg ENTER(); 163209885543Smrg 163309885543Smrg /* Map MMIO regs and framebuffer */ 16347104f784Smrg if (!SMI_MapMem(pScrn)) 16357104f784Smrg LEAVE(FALSE); 163609885543Smrg 163709885543Smrg pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 163809885543Smrg 16397104f784Smrg if (!pSmi->pInt10 && pSmi->useBIOS) { 16407104f784Smrg pSmi->pInt10 = xf86InitInt10(pEnt->index); 164109885543Smrg } 16427104f784Smrg if (!pSmi->pVbe && pSmi->pInt10 && xf86LoaderCheckSymbol("VBEInit")) { 16437104f784Smrg pSmi->pVbe = VBEInit(pSmi->pInt10, pEnt->index); 164409885543Smrg } 164509885543Smrg 16467104f784Smrg /* Save the chip/graphics state */ 16477104f784Smrg pSmi->Save(pScrn); 164809885543Smrg 16497104f784Smrg /* Fill in some needed pScrn fields */ 16507104f784Smrg pScrn->vtSema = TRUE; 16517104f784Smrg pScrn->pScreen = pScreen; 165209885543Smrg 16537104f784Smrg pScrn->displayWidth = ((pScrn->virtualX * pSmi->Bpp + 15) & ~15) / pSmi->Bpp; 165409885543Smrg 16557104f784Smrg pSmi->fbArea = NULL; 16567104f784Smrg pSmi->FBOffset = 0; 16577104f784Smrg pScrn->fbOffset = pSmi->FBOffset + pSmi->fbMapOffset; 165809885543Smrg 16597104f784Smrg /* Clear frame buffer */ 16607104f784Smrg memset(pSmi->FBBase, 0, pSmi->videoRAMBytes); 166109885543Smrg 166209885543Smrg /* 16637104f784Smrg * The next step is to setup the screen's visuals, and initialise the 166472320d7bSmrg * framebuffer code. In cases where the framebuffer's default choices for 16657104f784Smrg * things like visual layouts and bits per RGB are OK, this may be as simple 16667104f784Smrg * as calling the framebuffer's ScreenInit() function. If not, the visuals 16677104f784Smrg * will need to be setup before calling a fb ScreenInit() function and fixed 16687104f784Smrg * up after. 16697104f784Smrg */ 167009885543Smrg 16717104f784Smrg /* 16727104f784Smrg * Reset the visual list. 16737104f784Smrg */ 16747104f784Smrg miClearVisualTypes(); 167509885543Smrg 16767104f784Smrg /* Setup the visuals we support. */ 167709885543Smrg 16787104f784Smrg if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 16797104f784Smrg pScrn->rgbBits, pScrn->defaultVisual)) 16807104f784Smrg LEAVE(FALSE); 168109885543Smrg 16827104f784Smrg if (!miSetPixmapDepths ()) 16837104f784Smrg LEAVE(FALSE); 168409885543Smrg 16857104f784Smrg /* 16867104f784Smrg * Call the framebuffer layer's ScreenInit function 16877104f784Smrg */ 168809885543Smrg 16897104f784Smrg DEBUG("\tInitializing FB @ 0x%08X for %dx%d (%d)\n", 16907104f784Smrg pSmi->FBBase, pScrn->virtualX, pScrn->virtualY, pScrn->displayWidth); 16917104f784Smrg if(!fbScreenInit(pScreen, pSmi->FBBase, pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, 16927104f784Smrg pScrn->yDpi, pScrn->displayWidth, pScrn->bitsPerPixel)) 16937104f784Smrg LEAVE(FALSE); 169409885543Smrg 16957104f784Smrg xf86SetBlackWhitePixels(pScreen); 169609885543Smrg 16977104f784Smrg if (pScrn->bitsPerPixel > 8) { 16987104f784Smrg VisualPtr visual; 16997104f784Smrg /* Fixup RGB ordering */ 17007104f784Smrg visual = pScreen->visuals + pScreen->numVisuals; 17017104f784Smrg while (--visual >= pScreen->visuals) { 17027104f784Smrg if ((visual->class | DynamicClass) == DirectColor) { 17037104f784Smrg visual->offsetRed = pScrn->offset.red; 17047104f784Smrg visual->offsetGreen = pScrn->offset.green; 17057104f784Smrg visual->offsetBlue = pScrn->offset.blue; 17067104f784Smrg visual->redMask = pScrn->mask.red; 17077104f784Smrg visual->greenMask = pScrn->mask.green; 17087104f784Smrg visual->blueMask = pScrn->mask.blue; 17097104f784Smrg } 171009885543Smrg } 171109885543Smrg } 171209885543Smrg 17137104f784Smrg /* must be after RGB ordering fixed */ 17147104f784Smrg fbPictureInit(pScreen, 0, 0); 17157104f784Smrg 17167104f784Smrg /* Do the CRTC independent initialization */ 17177104f784Smrg if(!SMI_HWInit(pScrn)) 17187104f784Smrg LEAVE(FALSE); 171909885543Smrg 17207104f784Smrg /* Unless using EXA, regardless or using XAA or not, needs offscreen 17217104f784Smrg * management at least for video. */ 17227104f784Smrg if (pSmi->NoAccel || !pSmi->useEXA) { 17237104f784Smrg int numLines; 17247104f784Smrg BoxRec AvailFBArea; 172509885543Smrg 17267104f784Smrg numLines = pSmi->FBReserved / (pScrn->displayWidth * pSmi->Bpp); 17277104f784Smrg AvailFBArea.x1 = 0; 17287104f784Smrg AvailFBArea.y1 = 0; 17297104f784Smrg AvailFBArea.x2 = pScrn->virtualX; 17307104f784Smrg AvailFBArea.y2 = numLines; 173109885543Smrg 17327104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 17337104f784Smrg "FrameBuffer Box: %d,%d - %d,%d\n", 17347104f784Smrg AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, 17357104f784Smrg AvailFBArea.y2); 173609885543Smrg 17377104f784Smrg xf86InitFBManager(pScreen, &AvailFBArea); 173809885543Smrg } 173909885543Smrg 17407104f784Smrg /* Initialize acceleration layer */ 17417104f784Smrg if (!pSmi->NoAccel) { 17427104f784Smrg if (pSmi->useEXA && !SMI_EXAInit(pScreen)) 17437104f784Smrg LEAVE(FALSE); 17447104f784Smrg else if (!pSmi->useEXA && !SMI_XAAInit(pScreen)) 17457104f784Smrg LEAVE(FALSE); 174609885543Smrg } 174709885543Smrg 17487104f784Smrg /* Initialize the chosen modes */ 17497104f784Smrg if (!xf86SetDesiredModes(pScrn)) 17507104f784Smrg LEAVE(FALSE); 175109885543Smrg 17527104f784Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 17537104f784Smrg "Done writing mode. Register dump:\n"); 17547104f784Smrg SMI_PrintRegs(pScrn); 175509885543Smrg 17567104f784Smrg#ifdef HAVE_XMODES 17577104f784Smrg xf86DiDGAInit(pScreen, (unsigned long)(pSmi->FBBase + pScrn->fbOffset)); 17587104f784Smrg#endif 175909885543Smrg 17607104f784Smrg /* Initialise cursor functions */ 17617104f784Smrg miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 176209885543Smrg 17637104f784Smrg /* Initialize HW cursor layer. Must follow software cursor 17647104f784Smrg * initialization. 17657104f784Smrg */ 17667104f784Smrg if (pSmi->HwCursor) { 17677104f784Smrg int size, flags; 17687104f784Smrg 17697104f784Smrg if (IS_MSOC(pSmi)) { 17707104f784Smrg size = SMI501_MAX_CURSOR; 17717104f784Smrg flags = (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | 17727104f784Smrg HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK); 17737104f784Smrg#if SMI_CURSOR_ALPHA_PLANE 17747104f784Smrg if (!pSmi->Dualhead) 17757104f784Smrg flags |= HARDWARE_CURSOR_ARGB; 17767104f784Smrg#endif 17777104f784Smrg } 17787104f784Smrg else { 17797104f784Smrg size = SMILYNX_MAX_CURSOR; 17807104f784Smrg flags = (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 | 17817104f784Smrg HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | 17827104f784Smrg HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 17837104f784Smrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 17847104f784Smrg HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 17857104f784Smrg HARDWARE_CURSOR_INVERT_MASK); 17867104f784Smrg } 178709885543Smrg 17887104f784Smrg if (!xf86_cursors_init(pScreen, size, size, flags)) 17897104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 17907104f784Smrg "Hardware cursor initialization failed\n"); 179109885543Smrg } 179209885543Smrg 17937104f784Smrg /* Initialise default colormap */ 17947104f784Smrg if (!miCreateDefColormap(pScreen)) 17957104f784Smrg LEAVE(FALSE); 179609885543Smrg 17977104f784Smrg /* Initialize colormap layer. Must follow initialization of the default 17987104f784Smrg * colormap. And SetGamma call, else it will load palette with solid white. 17997104f784Smrg */ 18007104f784Smrg if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,SMI_LoadPalette, NULL, 18017104f784Smrg CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) 18027104f784Smrg LEAVE(FALSE); 180309885543Smrg 18047104f784Smrg pScreen->SaveScreen = SMI_SaveScreen; 18057104f784Smrg pSmi->CloseScreen = pScreen->CloseScreen; 18067104f784Smrg pScreen->CloseScreen = SMI_CloseScreen; 180709885543Smrg 18087104f784Smrg if ((IS_MSOC(pSmi) && 18097104f784Smrg !xf86DPMSInit(pScreen, SMI501_DisplayPowerManagementSet, 0)) || 18107104f784Smrg (!IS_MSOC(pSmi) && 18117104f784Smrg !xf86DPMSInit(pScreen, SMILynx_DisplayPowerManagementSet, 0))) 18127104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed!\n"); 181309885543Smrg 18147104f784Smrg SMI_InitVideo(pScreen); 181509885543Smrg 18167104f784Smrg if(!xf86CrtcScreenInit(pScreen)) 18177104f784Smrg LEAVE(FALSE); 181809885543Smrg 18197104f784Smrg /* Report any unused options (only for the first generation) */ 18207104f784Smrg if (serverGeneration == 1) { 18217104f784Smrg xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 18227104f784Smrg } 182309885543Smrg 18247104f784Smrg LEAVE(TRUE); 182509885543Smrg} 182609885543Smrg 182709885543Smrg/* 182809885543Smrg * This is called at the end of each server generation. It restores the 182909885543Smrg * original (text) mode. It should also unmap the video memory, and free any 183009885543Smrg * per-generation data allocated by the driver. It should finish by unwrapping 183109885543Smrg * and calling the saved CloseScreen function. 183209885543Smrg */ 183309885543Smrg 183409885543Smrgstatic Bool 18355788ca14SmrgSMI_CloseScreen(CLOSE_SCREEN_ARGS_DECL) 183609885543Smrg{ 18375788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 18387104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 18397104f784Smrg Bool ret; 184009885543Smrg 18417104f784Smrg ENTER(); 184209885543Smrg 18437104f784Smrg if (pSmi->HwCursor) 18447104f784Smrg xf86_cursors_fini(pScreen); 18457104f784Smrg 18467104f784Smrg if (pScrn->vtSema) 18477104f784Smrg /* Restore console mode and unmap framebuffer */ 18485788ca14Smrg SMI_LeaveVT(VT_FUNC_ARGS); 184909885543Smrg 18505788ca14Smrg#ifdef HAVE_XAA_H 185109885543Smrg if (pSmi->XAAInfoRec != NULL) { 185209885543Smrg XAADestroyInfoRec(pSmi->XAAInfoRec); 185309885543Smrg } 18545788ca14Smrg#endif 185509885543Smrg if (pSmi->EXADriverPtr) { 185609885543Smrg exaDriverFini(pScreen); 185709885543Smrg pSmi->EXADriverPtr = NULL; 185809885543Smrg } 18597104f784Smrg if (pSmi->pVbe != NULL) { 18607104f784Smrg vbeFree(pSmi->pVbe); 18617104f784Smrg pSmi->pVbe = NULL; 186209885543Smrg } 186309885543Smrg if (pSmi->pInt10 != NULL) { 186409885543Smrg xf86FreeInt10(pSmi->pInt10); 186509885543Smrg pSmi->pInt10 = NULL; 186609885543Smrg } 186709885543Smrg if (pSmi->ptrAdaptor != NULL) { 18687b58d2e0Smrg free(pSmi->ptrAdaptor); 186909885543Smrg } 187009885543Smrg if (pSmi->BlockHandler != NULL) { 187109885543Smrg pScreen->BlockHandler = pSmi->BlockHandler; 187209885543Smrg } 187309885543Smrg 187409885543Smrg pScrn->vtSema = FALSE; 187509885543Smrg pScreen->CloseScreen = pSmi->CloseScreen; 18765788ca14Smrg ret = (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 187709885543Smrg 18787104f784Smrg LEAVE(ret); 187909885543Smrg} 188009885543Smrg 188109885543Smrgstatic void 18825788ca14SmrgSMI_FreeScreen(FREE_SCREEN_ARGS_DECL) 188309885543Smrg{ 18845788ca14Smrg SCRN_INFO_PTR(arg); 18855788ca14Smrg SMI_FreeRec(pScrn); 188609885543Smrg} 188709885543Smrg 188809885543Smrgstatic Bool 188909885543SmrgSMI_SaveScreen(ScreenPtr pScreen, int mode) 189009885543Smrg{ 18915788ca14Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 189209885543Smrg 18937104f784Smrg ENTER(); 189409885543Smrg 18957104f784Smrg if(xf86IsUnblank(mode)){ 18967104f784Smrg pScrn->DPMSSet(pScrn, DPMSModeOn, 0); 18977104f784Smrg }else{ 18987104f784Smrg pScrn->DPMSSet(pScrn, DPMSModeOff, 0); 18997104f784Smrg } 190009885543Smrg 19017104f784Smrg LEAVE(TRUE); 190209885543Smrg} 190309885543Smrg 190409885543Smrgvoid 1905621ff18cSmrgSMI_AdjustFrame(ADJUST_FRAME_ARGS_DECL) 190609885543Smrg{ 1907621ff18cSmrg SCRN_INFO_PTR(arg); 1908621ff18cSmrg xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); 19097104f784Smrg xf86CrtcPtr compat_crtc = crtcConf->output[crtcConf->compat_output]->crtc; 191009885543Smrg 19117104f784Smrg ENTER(); 191209885543Smrg 19137104f784Smrg SMICRTC(compat_crtc)->adjust_frame(compat_crtc,x,y); 191409885543Smrg 19157104f784Smrg LEAVE(); 191609885543Smrg} 191709885543Smrg 191809885543SmrgBool 1919621ff18cSmrgSMI_SwitchMode(SWITCH_MODE_ARGS_DECL) 192009885543Smrg{ 192109885543Smrg Bool ret; 1922621ff18cSmrg SCRN_INFO_PTR(arg); 19237104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 19247104f784Smrg 19257104f784Smrg ENTER(); 192609885543Smrg 19277104f784Smrg ret = xf86SetSingleMode(pScrn, mode, RR_Rotate_0); 192809885543Smrg 19297104f784Smrg if (!pSmi->NoAccel) 19307104f784Smrg SMI_EngineReset(pScrn); 193109885543Smrg 19327104f784Smrg LEAVE(ret); 193309885543Smrg} 193409885543Smrg 193509885543Smrgvoid 193672320d7bSmrgSMI_LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 19377104f784Smrg LOCO *colors, VisualPtr pVisual) 193809885543Smrg{ 19397104f784Smrg xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); 19407104f784Smrg int crtc_idx,i,j; 19417104f784Smrg 19427104f784Smrg ENTER(); 19437104f784Smrg 19447104f784Smrg if(pScrn->bitsPerPixel == 16){ 19457104f784Smrg /* Expand the RGB 565 palette into the 256-elements LUT */ 194609885543Smrg 19477104f784Smrg for(crtc_idx=0; crtc_idx<crtcConf->num_crtc; crtc_idx++){ 19487104f784Smrg SMICrtcPrivatePtr crtcPriv = SMICRTC(crtcConf->crtc[crtc_idx]); 194909885543Smrg 19507104f784Smrg for(i=0; i<numColors; i++){ 195172320d7bSmrg int idx = indices[i]; 195209885543Smrg 19537104f784Smrg if(idx<32){ 19547104f784Smrg for(j=0; j<8; j++){ 19557104f784Smrg crtcPriv->lut_r[idx*8 + j] = colors[idx].red << 8; 19567104f784Smrg crtcPriv->lut_b[idx*8 + j] = colors[idx].blue << 8; 19577104f784Smrg } 19587104f784Smrg } 19597104f784Smrg 19607104f784Smrg for(j=0; j<4; j++) 19617104f784Smrg crtcPriv->lut_g[idx*4 + j] = colors[idx].green << 8; 19627104f784Smrg } 19637104f784Smrg 19647104f784Smrg crtcPriv->load_lut(crtcConf->crtc[crtc_idx]); 196509885543Smrg } 19667104f784Smrg }else{ 19677104f784Smrg for(crtc_idx=0; crtc_idx<crtcConf->num_crtc; crtc_idx++){ 19687104f784Smrg SMICrtcPrivatePtr crtcPriv = SMICRTC(crtcConf->crtc[crtc_idx]); 196909885543Smrg 197009885543Smrg for(i = 0; i < numColors; i++) { 197172320d7bSmrg int idx = indices[i]; 19727104f784Smrg 19737104f784Smrg crtcPriv->lut_r[idx] = colors[idx].red << 8; 19747104f784Smrg crtcPriv->lut_g[idx] = colors[idx].green << 8; 19757104f784Smrg crtcPriv->lut_b[idx] = colors[idx].blue << 8; 19767104f784Smrg } 19777104f784Smrg 19787104f784Smrg crtcPriv->load_lut(crtcConf->crtc[crtc_idx]); 19797104f784Smrg } 198009885543Smrg } 198109885543Smrg 19827104f784Smrg LEAVE(); 198309885543Smrg} 198409885543Smrg 198509885543Smrgstatic void 198609885543SmrgSMI_DisableVideo(ScrnInfoPtr pScrn) 198709885543Smrg{ 198809885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 198909885543Smrg CARD8 tmp; 199009885543Smrg 19917104f784Smrg if (!IS_MSOC(pSmi)) { 19927104f784Smrg if (!(tmp = VGAIN8(pSmi, VGA_DAC_MASK))) 19937104f784Smrg return; 19947104f784Smrg pSmi->DACmask = tmp; 19957104f784Smrg VGAOUT8(pSmi, VGA_DAC_MASK, 0); 19967104f784Smrg } 199709885543Smrg} 199809885543Smrg 199909885543Smrgstatic void 200009885543SmrgSMI_EnableVideo(ScrnInfoPtr pScrn) 200109885543Smrg{ 200209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 200309885543Smrg 20047104f784Smrg if (!IS_MSOC(pSmi)) { 20057104f784Smrg VGAOUT8(pSmi, VGA_DAC_MASK, pSmi->DACmask); 20067104f784Smrg } 200709885543Smrg} 200809885543Smrg 200909885543Smrg 201009885543Smrgvoid 201109885543SmrgSMI_EnableMmio(ScrnInfoPtr pScrn) 201209885543Smrg{ 2013bbcda59bSjmcneill#if !defined(__mips__) 201409885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 201509885543Smrg 20167104f784Smrg ENTER(); 201709885543Smrg 20187104f784Smrg if (!IS_MSOC(pSmi)) { 20197104f784Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 20207104f784Smrg CARD8 tmp; 20217104f784Smrg 20227104f784Smrg /* 20237104f784Smrg * Enable chipset (seen on uninitialized secondary cards) might not be 20247104f784Smrg * needed once we use the VGA softbooter 20257104f784Smrg */ 20267104f784Smrg vgaHWSetStdFuncs(hwp); 202709885543Smrg 20287104f784Smrg /* Enable linear mode */ 20297104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); 20307104f784Smrg tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); 20317104f784Smrg pSmi->SR18Value = tmp; /* PDR#521 */ 20327104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp | 0x11); 203309885543Smrg 20347104f784Smrg /* Enable 2D/3D Engine and Video Processor */ 20357104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x21); 20367104f784Smrg tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); 20377104f784Smrg pSmi->SR21Value = tmp; /* PDR#521 */ 20387104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp & ~0x03); 20397104f784Smrg } 204009885543Smrg 20417104f784Smrg LEAVE(); 2042bbcda59bSjmcneill#endif 204309885543Smrg} 204409885543Smrg 204509885543Smrgvoid 204609885543SmrgSMI_DisableMmio(ScrnInfoPtr pScrn) 204709885543Smrg{ 2048bbcda59bSjmcneill#if !defined(__mips__) 204909885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 205009885543Smrg 20517104f784Smrg ENTER(); 205209885543Smrg 20537104f784Smrg if (!IS_MSOC(pSmi)) { 20547104f784Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 205509885543Smrg 20567104f784Smrg vgaHWSetStdFuncs(hwp); 205709885543Smrg 20587104f784Smrg /* Disable 2D/3D Engine and Video Processor */ 20597104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x21); 20607104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, pSmi->SR21Value); /* PDR#521 */ 20617104f784Smrg 20627104f784Smrg /* Disable linear mode */ 20637104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); 20647104f784Smrg outb(pSmi->PIOBase + VGA_SEQ_DATA, pSmi->SR18Value); /* PDR#521 */ 20657104f784Smrg } 206609885543Smrg 20677104f784Smrg LEAVE(); 2068bbcda59bSjmcneill#endif 206909885543Smrg} 207009885543Smrg 207109885543Smrgstatic void 20727104f784SmrgSMI_ProbeDDC(ScrnInfoPtr pScrn, int index) 20737104f784Smrg{ 20747104f784Smrg vbeInfoPtr pVbe; 20757104f784Smrg if (xf86LoadSubModule(pScrn, "vbe")) { 20767104f784Smrg pVbe = VBEInit(NULL, index); 20777104f784Smrg ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 20787104f784Smrg vbeFree(pVbe); 20797104f784Smrg } 20807104f784Smrg} 20817104f784Smrg 20827104f784Smrgstatic Bool 20837104f784SmrgSMI_HWInit(ScrnInfoPtr pScrn) 208409885543Smrg{ 208509885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 208609885543Smrg 20877104f784Smrg ENTER(); 208809885543Smrg 20897104f784Smrg if(IS_MSOC(pSmi)) 20907104f784Smrg LEAVE(SMI501_HWInit(pScrn)); 20917104f784Smrg else 20927104f784Smrg LEAVE(SMILynx_HWInit(pScrn)); 20937104f784Smrg} 209409885543Smrg 20957104f784Smrgvoid 20967104f784SmrgSMI_PrintRegs(ScrnInfoPtr pScrn) 20977104f784Smrg{ 20987104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 20997104f784Smrg int i; 210009885543Smrg 21017104f784Smrg ENTER(); 210209885543Smrg 21037104f784Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 21047104f784Smrg "START register dump ------------------\n"); 21057104f784Smrg 21067104f784Smrg if(IS_MSOC(pSmi)) 21077104f784Smrg SMI501_PrintRegs(pScrn); 21087104f784Smrg else 21097104f784Smrg SMILynx_PrintRegs(pScrn); 211009885543Smrg 211109885543Smrg 211209885543Smrg xf86ErrorFVerb(VERBLEV, "\n\nDPR x0 x4 x8 xC"); 211309885543Smrg for (i = 0x00; i <= 0x44; i += 4) { 211409885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 211509885543Smrg xf86ErrorFVerb(VERBLEV, " %08lX", (unsigned long)READ_DPR(pSmi, i)); 211609885543Smrg } 211709885543Smrg 211809885543Smrg xf86ErrorFVerb(VERBLEV, "\n\nVPR x0 x4 x8 xC"); 211909885543Smrg for (i = 0x00; i <= 0x60; i += 4) { 212009885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 212109885543Smrg xf86ErrorFVerb(VERBLEV, " %08lX", (unsigned long)READ_VPR(pSmi, i)); 212209885543Smrg } 212309885543Smrg 212409885543Smrg xf86ErrorFVerb(VERBLEV, "\n\nCPR x0 x4 x8 xC"); 212509885543Smrg for (i = 0x00; i <= 0x18; i += 4) { 212609885543Smrg if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 212709885543Smrg xf86ErrorFVerb(VERBLEV, " %08lX", (unsigned long)READ_CPR(pSmi, i)); 212809885543Smrg } 212909885543Smrg 213009885543Smrg xf86ErrorFVerb(VERBLEV, "\n\n"); 213109885543Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 213209885543Smrg "END register dump --------------------\n"); 213309885543Smrg 21347104f784Smrg LEAVE(); 213509885543Smrg} 2136407d2e45Smacallan 2137407d2e45Smacallanstatic Bool 2138407d2e45SmacallanSMI_driverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 2139407d2e45Smacallan pointer ptr) 2140407d2e45Smacallan{ 2141407d2e45Smacallan xorgHWFlags *flag; 2142407d2e45Smacallan 2143407d2e45Smacallan switch (op) { 2144407d2e45Smacallan case GET_REQUIRED_HW_INTERFACES: 2145407d2e45Smacallan flag = (CARD32*)ptr; 2146407d2e45Smacallan (*flag) = HW_MMIO; 2147407d2e45Smacallan return TRUE; 2148407d2e45Smacallan default: 2149407d2e45Smacallan return FALSE; 2150407d2e45Smacallan } 2151407d2e45Smacallan} 2152