e:/XFree86 for RH 8.0/XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_driver.c

Go to the documentation of this file.
00001 /* Header: //Mercury/Projects/archives/XFree86/4.0/smi_driver.c-arc 1.42 03 Jan 2001 13:52:16 Frido $ */ 00002 00003 /* 00004 Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. 00005 Copyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. 00006 00007 Permission is hereby granted, free of charge, to any person obtaining a copy of 00008 this software and associated documentation files (the "Software"), to deal in 00009 the Software without restriction, including without limitation the rights to 00010 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 00011 of the Software, and to permit persons to whom the Software is furnished to do 00012 so, subject to the following conditions: 00013 00014 The above copyright notice and this permission notice shall be included in all 00015 copies or substantial portions of the Software. 00016 00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 00019 NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00020 XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00022 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 00024 Except as contained in this notice, the names of The XFree86 Project and 00025 Silicon Motion shall not be used in advertising or otherwise to promote the 00026 sale, use or other dealings in this Software without prior written 00027 authorization from The XFree86 Project or Silicon Motion. 00028 */ 00029 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_driver.c,v 1.19 2001/12/20 21:35:38 eich Exp $ */ 00030 00031 #include "xf86Resources.h" 00032 #include "xf86RAC.h" 00033 #include "xf86DDC.h" 00034 #include "xf86int10.h" 00035 #include "vbe.h" 00036 #include "shadowfb.h" 00037 00038 #include "smi.h" 00039 00040 #include "globals.h" 00041 #define DPMS_SERVER 00042 #include "extensions/dpms.h" 00043 00044 /* 00045 * Internals 00046 */ 00047 static void SMI_EnableMmio(ScrnInfoPtr pScrn); 00048 static void SMI_DisableMmio(ScrnInfoPtr pScrn); 00049 00050 /* 00051 * Forward definitions for the functions that make up the driver. 00052 */ 00053 00054 static const OptionInfoRec * SMI_AvailableOptions(int chipid, int busid); 00055 static void SMI_Identify(int flags); 00056 static Bool SMI_Probe(DriverPtr drv, int flags); 00057 static Bool SMI_PreInit(ScrnInfoPtr pScrn, int flags); 00058 static Bool SMI_EnterVT(int scrnIndex, int flags); 00059 static void SMI_LeaveVT(int scrnIndex, int flags); 00060 static void SMI_Save (ScrnInfoPtr pScrn); 00061 static void SMI_WriteMode (ScrnInfoPtr pScrn, vgaRegPtr, SMIRegPtr); 00062 static Bool SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 00063 char **argv); 00064 static int SMI_InternalScreenInit(int scrnIndex, ScreenPtr pScreen); 00065 static void SMI_PrintRegs(ScrnInfoPtr); 00066 static ModeStatus SMI_ValidMode(int scrnIndex, DisplayModePtr mode, 00067 Bool verbose, int flags); 00068 static void SMI_DisableVideo(ScrnInfoPtr pScrn); 00069 static void SMI_EnableVideo(ScrnInfoPtr pScrn); 00070 static Bool SMI_MapMem(ScrnInfoPtr pScrn); 00071 static void SMI_UnmapMem(ScrnInfoPtr pScrn); 00072 static Bool SMI_ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 00073 static Bool SMI_CloseScreen(int scrnIndex, ScreenPtr pScreen); 00074 static Bool SMI_SaveScreen(ScreenPtr pScreen, int mode); 00075 static void SMI_LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, 00076 LOCO *colors, VisualPtr pVisual); 00077 static void SMI_DisplayPowerManagementSet(ScrnInfoPtr pScrn, 00078 int PowerManagementMode, int flags); 00079 static Bool SMI_ddc1(int scrnIndex); 00080 static unsigned int SMI_ddc1Read(ScrnInfoPtr pScrn); 00081 static void SMI_FreeScreen(int ScrnIndex, int flags); 00082 static void SMI_ProbeDDC(ScrnInfoPtr pScrn, int index); 00083 00084 00085 #define SILICONMOTION_NAME "Silicon Motion" 00086 #define SILICONMOTION_DRIVER_NAME "siliconmotion" 00087 #define SILICONMOTION_VERSION_NAME "1.3.1" 00088 #define SILICONMOTION_VERSION_MAJOR 1 00089 #define SILICONMOTION_VERSION_MINOR 3 00090 #define SILICONMOTION_PATCHLEVEL 1 00091 #define SILICONMOTION_DRIVER_VERSION ( (SILICONMOTION_VERSION_MAJOR << 24) \ 00092 | (SILICONMOTION_VERSION_MINOR << 16) \ 00093 | (SILICONMOTION_PATCHLEVEL) \ 00094 ) 00095 00096 /* 00097 * This contains the functions needed by the server after loading the 00098 * driver module. It must be supplied, and gets added the driver list by 00099 * the Module Setup funtion in the dynamic case. In the static case a 00100 * reference to this is compiled in, and this requires that the name of 00101 * this DriverRec be an upper-case version of the driver name. 00102 */ 00103 00104 DriverRec SILICONMOTION = 00105 { 00106 SILICONMOTION_DRIVER_VERSION, 00107 SILICONMOTION_DRIVER_NAME, 00108 SMI_Identify, 00109 SMI_Probe, 00110 SMI_AvailableOptions, 00111 NULL, 00112 0 00113 }; 00114 00115 /* Supported chipsets */ 00116 static SymTabRec SMIChipsets[] = 00117 { 00118 { PCI_CHIP_SMI910, "Lynx" }, 00119 { PCI_CHIP_SMI810, "LynxE" }, 00120 { PCI_CHIP_SMI820, "Lynx3D" }, 00121 { PCI_CHIP_SMI710, "LynxEM" }, 00122 { PCI_CHIP_SMI712, "LynxEM+" }, 00123 { PCI_CHIP_SMI720, "Lynx3DM" }, 00124 { -1, NULL } 00125 }; 00126 00127 static PciChipsets SMIPciChipsets[] = 00128 { 00129 /* numChipset, PciID, Resource */ 00130 { PCI_CHIP_SMI910, PCI_CHIP_SMI910, RES_SHARED_VGA }, 00131 { PCI_CHIP_SMI810, PCI_CHIP_SMI810, RES_SHARED_VGA }, 00132 { PCI_CHIP_SMI820, PCI_CHIP_SMI820, RES_SHARED_VGA }, 00133 { PCI_CHIP_SMI710, PCI_CHIP_SMI710, RES_SHARED_VGA }, 00134 { PCI_CHIP_SMI712, PCI_CHIP_SMI712, RES_SHARED_VGA }, 00135 { PCI_CHIP_SMI720, PCI_CHIP_SMI720, RES_SHARED_VGA }, 00136 { -1, -1, RES_UNDEFINED } 00137 }; 00138 00139 typedef enum 00140 { 00141 OPTION_PCI_BURST, 00142 OPTION_FIFO_CONSERV, 00143 OPTION_FIFO_MODERATE, 00144 OPTION_FIFO_AGGRESSIVE, 00145 OPTION_PCI_RETRY, 00146 OPTION_NOACCEL, 00147 OPTION_MCLK, 00148 OPTION_SHOWCACHE, 00149 OPTION_SWCURSOR, 00150 OPTION_HWCURSOR, 00151 OPTION_SHADOW_FB, 00152 OPTION_ROTATE, 00153 #ifdef XvExtension 00154 OPTION_VIDEOKEY, 00155 OPTION_BYTESWAP, 00156 /* CZ 26.10.2001: interlaced video */ 00157 OPTION_INTERLACED, 00158 /* end CZ */ 00159 #endif 00160 OPTION_USEBIOS, 00161 OPTION_ZOOMONLCD, 00162 NUMBER_OF_OPTIONS 00163 00164 } SMIOpts; 00165 00166 static const OptionInfoRec SMIOptions[] = 00167 { 00168 { OPTION_PCI_BURST, "pci_burst", OPTV_BOOLEAN, {0}, FALSE }, 00169 { OPTION_FIFO_CONSERV, "fifo_conservative", OPTV_BOOLEAN, {0}, FALSE }, 00170 { OPTION_FIFO_MODERATE, "fifo_moderate", OPTV_BOOLEAN, {0}, FALSE }, 00171 { OPTION_FIFO_AGGRESSIVE, "fifo_aggressive", OPTV_BOOLEAN, {0}, FALSE }, 00172 { OPTION_PCI_RETRY, "pci_retry", OPTV_BOOLEAN, {0}, FALSE }, 00173 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 00174 { OPTION_MCLK, "set_mclk", OPTV_FREQ, {0}, FALSE }, 00175 { OPTION_SHOWCACHE, "show_cache", OPTV_BOOLEAN, {0}, FALSE }, 00176 { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE }, 00177 { OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE }, 00178 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 00179 { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, 00180 #ifdef XvExtension 00181 { OPTION_VIDEOKEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, 00182 { OPTION_BYTESWAP, "ByteSwap", OPTV_BOOLEAN, {0}, FALSE }, 00183 /* CZ 26.10.2001: interlaced video */ 00184 { OPTION_INTERLACED, "Interlaced", OPTV_BOOLEAN, {0}, FALSE }, 00185 /* end CZ */ 00186 #endif 00187 { OPTION_USEBIOS, "UseBIOS", OPTV_BOOLEAN, {0}, FALSE }, 00188 { OPTION_ZOOMONLCD, "ZoomOnLCD", OPTV_BOOLEAN, {0}, FALSE }, 00189 { -1, NULL, OPTV_NONE, {0}, FALSE } 00190 }; 00191 00192 /* 00193 * Lists of symbols that may/may not be required by this driver. 00194 * This allows the loader to know which ones to issue warnings for. 00195 * 00196 * Note that vgahwSymbols and xaaSymbols are referenced outside the 00197 * XFree86LOADER define in later code, so are defined outside of that 00198 * define here also. 00199 */ 00200 00201 static const char *vgahwSymbols[] = 00202 { 00203 "vgaHWCopyReg", 00204 "vgaHWGetHWRec", 00205 "vgaHWGetIOBase", 00206 "vgaHWGetIndex", 00207 "vgaHWInit", 00208 "vgaHWLock", 00209 "vgaHWMapMem", 00210 "vgaHWProtect", 00211 "vgaHWRestore", 00212 "vgaHWSave", 00213 "vgaHWSaveScreen", 00214 "vgaHWSetMmioFuncs", 00215 "vgaHWSetStdFuncs", 00216 "vgaHWUnmapMem", 00217 "vgaHWddc1SetSpeed", 00218 NULL 00219 }; 00220 00221 static const char *xaaSymbols[] = 00222 { 00223 "XAACopyROP", 00224 "XAACreateInfoRec", 00225 "XAADestroyInfoRec", 00226 "XAAFallbackOps", 00227 "XAAFillSolidRects", 00228 "XAAInit", 00229 "XAAPatternROP", 00230 "XAAScreenIndex", 00231 NULL 00232 }; 00233 00234 static const char *ramdacSymbols[] = 00235 { 00236 "xf86CreateCursorInfoRec", 00237 "xf86DestroyCursorInfoRec", 00238 "xf86InitCursor", 00239 NULL 00240 }; 00241 00242 static const char *ddcSymbols[] = 00243 { 00244 "xf86PrintEDID", 00245 "xf86DoEDID_DDC1", 00246 "xf86DoEDID_DDC2", 00247 "xf86SetDDCproperties", 00248 NULL 00249 }; 00250 00251 static const char *i2cSymbols[] = 00252 { 00253 "xf86CreateI2CBusRec", 00254 "xf86CreateI2CDevRec", 00255 "xf86DestroyI2CBusRec", 00256 "xf86DestroyI2CDevRec", 00257 "xf86I2CBusInit", 00258 "xf86I2CDevInit", 00259 "xf86I2CWriteByte", 00260 NULL 00261 }; 00262 00263 static const char *shadowSymbols[] = 00264 { 00265 "ShadowFBInit", 00266 NULL 00267 }; 00268 00269 static const char *int10Symbols[] = 00270 { 00271 "xf86ExecX86int10", 00272 "xf86FreeInt10", 00273 "xf86InitInt10", 00274 NULL 00275 }; 00276 00277 static const char *vbeSymbols[] = 00278 { 00279 "VBEInit", 00280 "vbeDoEDID", 00281 "vbeFree", 00282 NULL 00283 }; 00284 00285 static const char *fbSymbols[] = 00286 { 00287 #ifdef USE_FB 00288 "fbPictureInit", 00289 "fbScreenInit", 00290 #else 00291 "cfbScreenInit", 00292 "cfb16ScreenInit", 00293 "cfb24ScreenInit", 00294 "cfb24_32ScreenInit", 00295 "cfb32ScreenInit", 00296 "cfb16BresS", 00297 "cfb24BresS", 00298 #endif 00299 NULL 00300 }; 00301 00302 #ifdef XFree86LOADER 00303 00304 static MODULESETUPPROTO(siliconmotionSetup); 00305 00306 static XF86ModuleVersionInfo SMIVersRec = 00307 { 00308 "siliconmotion", 00309 MODULEVENDORSTRING, 00310 MODINFOSTRING1, 00311 MODINFOSTRING2, 00312 XF86_VERSION_CURRENT, 00313 SILICONMOTION_VERSION_MAJOR, 00314 SILICONMOTION_VERSION_MINOR, 00315 SILICONMOTION_PATCHLEVEL, 00316 ABI_CLASS_VIDEODRV, 00317 ABI_VIDEODRV_VERSION, 00318 MOD_CLASS_VIDEODRV, 00319 {0, 0, 0, 0} 00320 }; 00321 00322 /* 00323 * This is the module init data for XFree86 modules. 00324 * 00325 * Its name has to be the driver name followed by ModuleData. 00326 */ 00327 XF86ModuleData siliconmotionModuleData = 00328 { 00329 &SMIVersRec, 00330 siliconmotionSetup, 00331 NULL 00332 }; 00333 00334 static pointer 00335 siliconmotionSetup(pointer module, pointer opts, int *errmaj, int *errmin) 00336 { 00337 static Bool setupDone = FALSE; 00338 00339 if (!setupDone) 00340 { 00341 setupDone = TRUE; 00342 xf86AddDriver(&SILICONMOTION, module, 0); 00343 00344 /* 00345 * Modules that this driver always requires can be loaded here 00346 * by calling LoadSubModule(). 00347 */ 00348 00349 /* 00350 * Tell the loader about symbols from other modules that this module 00351 * might refer to. 00352 */ 00353 LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols, ramdacSymbols, 00354 ddcSymbols, i2cSymbols, int10Symbols, vbeSymbols, 00355 shadowSymbols, NULL); 00356 00357 /* 00358 * The return value must be non-NULL on success even though there 00359 * is no TearDownProc. 00360 */ 00361 return (pointer) 1; 00362 } 00363 else 00364 { 00365 if (errmaj) 00366 { 00367 *errmaj = LDR_ONCEONLY; 00368 } 00369 return(NULL); 00370 } 00371 } 00372 00373 #endif /* XFree86LOADER */ 00374 00375 static Bool 00376 SMI_GetRec(ScrnInfoPtr pScrn) 00377 { 00378 ENTER_PROC("SMI_GetRec"); 00379 00380 /* 00381 * Allocate an 'Chip'Rec, and hook it into pScrn->driverPrivate. 00382 * pScrn->driverPrivate is initialised to NULL, so we can check if 00383 * the allocation has already been done. 00384 */ 00385 if (pScrn->driverPrivate == NULL) 00386 { 00387 pScrn->driverPrivate = xnfcalloc(sizeof(SMIRec), 1); 00388 } 00389 00390 LEAVE_PROC("SMI_GetRec"); 00391 return(TRUE); 00392 } 00393 00394 static void 00395 SMI_FreeRec(ScrnInfoPtr pScrn) 00396 { 00397 ENTER_PROC("SMI_FreeRec"); 00398 00399 if (pScrn->driverPrivate != NULL) 00400 { 00401 xfree(pScrn->driverPrivate); 00402 pScrn->driverPrivate = NULL; 00403 } 00404 00405 LEAVE_PROC("SMI_FreeRec"); 00406 } 00407 00408 static const OptionInfoRec * 00409 SMI_AvailableOptions(int chipid, int busid) 00410 { 00411 ENTER_PROC("SMI_AvailableOptions"); 00412 LEAVE_PROC("SMI_AvailableOptions"); 00413 return(SMIOptions); 00414 } 00415 00416 static void 00417 SMI_Identify(int flags) 00418 { 00419 ENTER_PROC("SMI_Identify"); 00420 00421 xf86PrintChipsets(SILICONMOTION_NAME, "driver (version " 00422 SILICONMOTION_VERSION_NAME ") for Silicon Motion Lynx chipsets", 00423 SMIChipsets); 00424 00425 LEAVE_PROC("SMI_Identify"); 00426 } 00427 00428 static Bool 00429 SMI_Probe(DriverPtr drv, int flags) 00430 { 00431 int i; 00432 GDevPtr *devSections; 00433 int *usedChips; 00434 int numDevSections; 00435 int numUsed; 00436 Bool foundScreen = FALSE; 00437 00438 ENTER_PROC("SMI_Probe"); 00439 00440 numDevSections = xf86MatchDevice(SILICONMOTION_DRIVER_NAME, &devSections); 00441 if (numDevSections <= 0) 00442 { 00443 /* There's no matching device section in the config file, so quit now. 00444 */ 00445 LEAVE_PROC("SMI_Probe"); 00446 return(FALSE); 00447 } 00448 00449 if (xf86GetPciVideoInfo() == NULL) 00450 { 00451 LEAVE_PROC("SMI_Probe"); 00452 return(FALSE); 00453 } 00454 00455 numUsed = xf86MatchPciInstances(SILICONMOTION_NAME, PCI_SMI_VENDOR_ID, 00456 SMIChipsets, SMIPciChipsets, devSections, 00457 numDevSections, drv, &usedChips); 00458 00459 /* Free it since we don't need that list after this */ 00460 xfree(devSections); 00461 if (numUsed <= 0) 00462 { 00463 LEAVE_PROC("SMI_Probe"); 00464 return(FALSE); 00465 } 00466 00467 if (flags & PROBE_DETECT) 00468 { 00469 foundScreen = TRUE; 00470 } 00471 else 00472 { 00473 for (i = 0; i < numUsed; i++) 00474 { 00475 /* Allocate a ScrnInfoRec and claim the slot */ 00476 ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); 00477 00478 /* Fill in what we can of the ScrnInfoRec */ 00479 pScrn->driverVersion = SILICONMOTION_DRIVER_VERSION; 00480 pScrn->driverName = SILICONMOTION_DRIVER_NAME; 00481 pScrn->name = SILICONMOTION_NAME; 00482 pScrn->Probe = SMI_Probe; 00483 pScrn->PreInit = SMI_PreInit; 00484 pScrn->ScreenInit = SMI_ScreenInit; 00485 pScrn->SwitchMode = SMI_SwitchMode; 00486 pScrn->AdjustFrame = SMI_AdjustFrame; 00487 pScrn->EnterVT = SMI_EnterVT; 00488 pScrn->LeaveVT = SMI_LeaveVT; 00489 pScrn->FreeScreen = SMI_FreeScreen; 00490 pScrn->ValidMode = SMI_ValidMode; 00491 foundScreen = TRUE; 00492 00493 xf86ConfigActivePciEntity(pScrn, usedChips[i], SMIPciChipsets, NULL, 00494 NULL, NULL, NULL, NULL); 00495 } 00496 } 00497 xfree(usedChips); 00498 00499 LEAVE_PROC("SMI_Probe"); 00500 return(foundScreen); 00501 } 00502 00503 static Bool 00504 SMI_PreInit(ScrnInfoPtr pScrn, int flags) 00505 { 00506 EntityInfoPtr pEnt; 00507 SMIPtr pSmi; 00508 MessageType from; 00509 int i; 00510 double real; 00511 ClockRangePtr clockRanges; 00512 #ifndef USE_FB 00513 char *mod = NULL; 00514 const char *reqSym = NULL; 00515 #endif 00516 char *s; 00517 unsigned char config, m, n, shift; 00518 int mclk; 00519 vgaHWPtr hwp; 00520 int vgaCRIndex, vgaCRReg, vgaIOBase; 00521 00522 ENTER_PROC("SMI_PreInit"); 00523 00524 if (flags & PROBE_DETECT) 00525 { 00526 SMI_ProbeDDC(pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index); 00527 LEAVE_PROC("SMI_PreInit"); 00528 return(TRUE); 00529 } 00530 00531 /* Ignoring the Type list for now. It might be needed when multiple cards 00532 * are supported. 00533 */ 00534 if (pScrn->numEntities > 1) 00535 { 00536 LEAVE_PROC("SMI_PreInit"); 00537 return(FALSE); 00538 } 00539 00540 /* The vgahw module should be loaded here when needed */ 00541 if (!xf86LoadSubModule(pScrn, "vgahw")) 00542 { 00543 LEAVE_PROC("SMI_PreInit"); 00544 return(FALSE); 00545 } 00546 00547 xf86LoaderReqSymLists(vgahwSymbols, NULL); 00548 00549 /* 00550 * Allocate a vgaHWRec 00551 */ 00552 if (!vgaHWGetHWRec(pScrn)) 00553 { 00554 LEAVE_PROC("SMI_PreInit"); 00555 return(FALSE); 00556 } 00557 00558 /* Allocate the SMIRec driverPrivate */ 00559 if (!SMI_GetRec(pScrn)) 00560 { 00561 LEAVE_PROC("SMI_PreInit"); 00562 return(FALSE); 00563 } 00564 pSmi = SMIPTR(pScrn); 00565 00566 /* Set pScrn->monitor */ 00567 pScrn->monitor = pScrn->confScreen->monitor; 00568 00569 /* 00570 * The first thing we should figure out is the depth, bpp, etc. Our 00571 * default depth is 8, so pass it to the helper function. We support 00572 * only 24bpp layouts, so indicate that. 00573 */ 00574 if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb)) 00575 { 00576 LEAVE_PROC("SMI_PreInit"); 00577 return(FALSE); 00578 } 00579 00580 /* Check that the returned depth is one we support */ 00581 switch (pScrn->depth) 00582 { 00583 case 8: 00584 case 16: 00585 case 24: 00586 /* OK */ 00587 break; 00588 00589 default: 00590 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 00591 "Given depth (%d) is not supported by this driver\n", 00592 pScrn->depth); 00593 LEAVE_PROC("SMI_PreInit"); 00594 return(FALSE); 00595 } 00596 xf86PrintDepthBpp(pScrn); 00597 00598 /* 00599 * This must happen after pScrn->display has been set because 00600 * xf86SetWeight references it. 00601 */ 00602 if (pScrn->depth > 8) 00603 { 00604 /* The defaults are OK for us */ 00605 rgb zeros = {0, 0, 0}; 00606 00607 if (!xf86SetWeight(pScrn, zeros, zeros)) 00608 { 00609 LEAVE_PROC("SMI_PreInit"); 00610 return(FALSE); 00611 } 00612 } 00613 00614 if (!xf86SetDefaultVisual(pScrn, -1)) 00615 { 00616 LEAVE_PROC("SMI_PreInit"); 00617 return(FALSE); 00618 } 00619 00620 /* We don't currently support DirectColor at > 8bpp */ 00621 if ((pScrn->depth > 8) && (pScrn->defaultVisual != TrueColor)) 00622 { 00623 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual (%s) " 00624 "is not supported at depth %d\n", 00625 xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 00626 LEAVE_PROC("SMI_PreInit"); 00627 return(FALSE); 00628 } 00629 00630 /* We use a programmable clock */ 00631 pScrn->progClock = TRUE; 00632 00633 /* Collect all of the relevant option flags (fill in pScrn->options) */ 00634 xf86CollectOptions(pScrn, NULL); 00635 00636 /* Set the bits per RGB for 8bpp mode */ 00637 if (pScrn->depth == 8) 00638 { 00639 pScrn->rgbBits = 6; 00640 } 00641 00642 /* Process the options */ 00643 if (!(pSmi->Options = xalloc(sizeof(SMIOptions)))) 00644 return FALSE; 00645 memcpy(pSmi->Options, SMIOptions, sizeof(SMIOptions)); 00646 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pSmi->Options); 00647 00648 if (xf86ReturnOptValBool(pSmi->Options, OPTION_PCI_BURST, FALSE)) 00649 { 00650 pSmi->pci_burst = TRUE; 00651 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: pci_burst - PCI burst " 00652 "read enabled\n"); 00653 } 00654 else 00655 { 00656 pSmi->pci_burst = FALSE; 00657 } 00658 00659 pSmi->NoPCIRetry = TRUE; 00660 if (xf86ReturnOptValBool(pSmi->Options, OPTION_PCI_RETRY, FALSE)) 00661 { 00662 if (xf86ReturnOptValBool(pSmi->Options, OPTION_PCI_BURST, FALSE)) 00663 { 00664 pSmi->NoPCIRetry = FALSE; 00665 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: pci_retry\n"); 00666 } 00667 else 00668 { 00669 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"pci_retry\" option " 00670 "requires \"pci_burst\".\n"); 00671 } 00672 } 00673 00674 if (xf86IsOptionSet(pSmi->Options, OPTION_FIFO_CONSERV)) 00675 { 00676 pSmi->fifo_conservative = TRUE; 00677 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo_conservative " 00678 "set\n"); 00679 } 00680 else 00681 { 00682 pSmi->fifo_conservative = FALSE; 00683 } 00684 00685 if (xf86IsOptionSet(pSmi->Options, OPTION_FIFO_MODERATE)) 00686 { 00687 pSmi->fifo_moderate = TRUE; 00688 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo_moderate set\n"); 00689 } 00690 else 00691 { 00692 pSmi->fifo_moderate = FALSE; 00693 } 00694 00695 if (xf86IsOptionSet(pSmi->Options, OPTION_FIFO_AGGRESSIVE)) 00696 { 00697 pSmi->fifo_aggressive = TRUE; 00698 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo_aggressive set\n"); 00699 } 00700 else 00701 { 00702 pSmi->fifo_aggressive = FALSE; 00703 } 00704 00705 if (xf86ReturnOptValBool(pSmi->Options, OPTION_NOACCEL, FALSE)) 00706 { 00707 pSmi->NoAccel = TRUE; 00708 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - Acceleration " 00709 "disabled\n"); 00710 } 00711 else 00712 { 00713 pSmi->NoAccel = FALSE; 00714 } 00715 00716 if (xf86ReturnOptValBool(pSmi->Options, OPTION_SHOWCACHE, FALSE)) 00717 { 00718 pSmi->ShowCache = TRUE; 00719 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: show_cache set\n"); 00720 } 00721 else 00722 { 00723 pSmi->ShowCache = FALSE; 00724 } 00725 00726 if (xf86GetOptValFreq(pSmi->Options, OPTION_MCLK, OPTUNITS_MHZ, &real)) 00727 { 00728 pSmi->MCLK = (int)(real * 1000.0); 00729 if (pSmi->MCLK <= 120000) 00730 { 00731 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: set_mclk set to " 00732 "%1.3f MHz\n", pSmi->MCLK / 1000.0); 00733 } 00734 else 00735 { 00736 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Memory Clock value of " 00737 "%1.3f MHz is larger than limit of 120 MHz\n", 00738 pSmi->MCLK / 1000.0); 00739 pSmi->MCLK = 0; 00740 } 00741 } 00742 else 00743 { 00744 pSmi->MCLK = 0; 00745 } 00746 00747 from = X_DEFAULT; 00748 pSmi->hwcursor = TRUE; 00749 if (xf86GetOptValBool(pSmi->Options, OPTION_HWCURSOR, &pSmi->hwcursor)) 00750 { 00751 from = X_CONFIG; 00752 } 00753 if (xf86ReturnOptValBool(pSmi->Options, OPTION_SWCURSOR, FALSE)) 00754 { 00755 pSmi->hwcursor = FALSE; 00756 from = X_CONFIG; 00757 } 00758 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s Cursor\n", 00759 pSmi->hwcursor ? "Hardware" : "Software"); 00760 00761 if (xf86GetOptValBool(pSmi->Options, OPTION_SHADOW_FB, &pSmi->shadowFB)) 00762 { 00763 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n", 00764 pSmi->shadowFB ? "enabled" : "disabled"); 00765 } 00766 00767 #if 1 /* PDR#932 */ 00768 if ((pScrn->depth == 8) || (pScrn->depth == 16)) 00769 #endif /* PDR#932 */ 00770 if ((s = xf86GetOptValString(pSmi->Options, OPTION_ROTATE))) 00771 { 00772 if(!xf86NameCmp(s, "CW")) 00773 { 00774 pSmi->shadowFB = TRUE; 00775 pSmi->rotate = SMI_ROTATE_CCW; 00776 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen " 00777 "clockwise\n"); 00778 } 00779 else if (!xf86NameCmp(s, "CCW")) 00780 { 00781 pSmi->shadowFB = TRUE; 00782 pSmi->rotate = SMI_ROTATE_CW; 00783 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen counter " 00784 "clockwise\n"); 00785 } 00786 else 00787 { 00788 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid " 00789 "value for Option \"Rotate\"\n", s); 00790 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Valid options are \"CW\" or " 00791 "\"CCW\"\n"); 00792 } 00793 } 00794 00795 #ifdef XvExtension 00796 if (xf86GetOptValInteger(pSmi->Options, OPTION_VIDEOKEY, &pSmi->videoKey)) 00797 { 00798 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Video key set to " 00799 "0x%08X\n", pSmi->videoKey); 00800 } 00801 else 00802 { 00803 pSmi->videoKey = (1 << pScrn->offset.red) | (1 << pScrn->offset.green) 00804 | (((pScrn->mask.blue >> pScrn->offset.blue) - 1) 00805 << pScrn->offset.blue); 00806 } 00807 00808 if (xf86ReturnOptValBool(pSmi->Options, OPTION_BYTESWAP, FALSE)) 00809 { 00810 pSmi->ByteSwap = TRUE; 00811 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: ByteSwap enabled.\n"); 00812 } 00813 else 00814 { 00815 pSmi->ByteSwap = FALSE; 00816 } 00817 00818 /* CZ 26.10.2001: interlaced video */ 00819 if (xf86ReturnOptValBool(pSmi->Options, OPTION_INTERLACED, FALSE)) 00820 { 00821 pSmi->interlaced = TRUE; 00822 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Interlaced enabled.\n"); 00823 } 00824 else 00825 { 00826 pSmi->interlaced = FALSE; 00827 } 00828 /* end CZ */ 00829 #endif 00830 00831 if (xf86GetOptValBool(pSmi->Options, OPTION_USEBIOS, &pSmi->useBIOS)) 00832 { 00833 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: UseBIOS %s.\n", 00834 pSmi->useBIOS ? "enabled" : "disabled"); 00835 } 00836 else 00837 { 00838 /* Default to UseBIOS enabled. */ 00839 pSmi->useBIOS = TRUE; 00840 } 00841 00842 if (xf86GetOptValBool(pSmi->Options, OPTION_ZOOMONLCD, &pSmi->zoomOnLCD)) 00843 { 00844 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: ZoomOnLCD %s.\n", 00845 pSmi->zoomOnLCD ? "enabled" : "disabled"); 00846 } 00847 else 00848 { 00849 /* Default to ZoomOnLCD enabled. */ 00850 pSmi->zoomOnLCD = TRUE; 00851 } 00852 00853 /* Find the PCI slot for this screen */ 00854 pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 00855 if ((pEnt->location.type != BUS_PCI) || (pEnt->resources)) 00856 { 00857 xfree(pEnt); 00858 SMI_FreeRec(pScrn); 00859 LEAVE_PROC("SMI_PreInit"); 00860 return(FALSE); 00861 } 00862 00863 if (xf86LoadSubModule(pScrn, "vbe")) 00864 { 00865 xf86LoaderReqSymLists(vbeSymbols, NULL); 00866 pSmi->pVbe = VBEInit(NULL, pEnt->index); 00867 } 00868 00869 pSmi->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 00870 xf86RegisterResources(pEnt->index, NULL, ResExclusive); 00871 /* xf86SetOperatingState(RES_SHARED_VGA, pEnt->index, ResUnusedOpr);*/ 00872 /* xf86SetOperatingState(resVgaMemShared, pEnt->index, ResDisableOpr);*/ 00873 00874 /* 00875 * Set the Chipset and ChipRev, allowing config file entries to 00876 * override. 00877 */ 00878 if (pEnt->device->chipset && *pEnt->device->chipset) 00879 { 00880 pScrn->chipset = pEnt->device->chipset; 00881 pSmi->Chipset = xf86StringToToken(SMIChipsets, pScrn->chipset); 00882 from = X_CONFIG; 00883 } 00884 else if (pEnt->device->chipID >= 0) 00885 { 00886 pSmi->Chipset = pEnt->device->chipID; 00887 pScrn->chipset = (char *) xf86TokenToString(SMIChipsets, pSmi->Chipset); 00888 from = X_CONFIG; 00889 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 00890 pSmi->Chipset); 00891 } 00892 else 00893 { 00894 from = X_PROBED; 00895 pSmi->Chipset = pSmi->PciInfo->chipType; 00896 pScrn->chipset = (char *) xf86TokenToString(SMIChipsets, pSmi->Chipset); 00897 } 00898 00899 if (pEnt->device->chipRev >= 0) 00900 { 00901 pSmi->ChipRev = pEnt->device->chipRev; 00902 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 00903 pSmi->ChipRev); 00904 } 00905 else 00906 { 00907 pSmi->ChipRev = pSmi->PciInfo->chipRev; 00908 } 00909 xfree(pEnt); 00910 00911 /* 00912 * This shouldn't happen because such problems should be caught in 00913 * SMI_Probe(), but check it just in case. 00914 */ 00915 if (pScrn->chipset == NULL) 00916 { 00917 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04X is not " 00918 "recognised\n", pSmi->Chipset); 00919 LEAVE_PROC("SMI_PreInit"); 00920 return(FALSE); 00921 } 00922 if (pSmi->Chipset < 0) 00923 { 00924 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Chipset \"%s\" is not " 00925 "recognised\n", pScrn->chipset); 00926 LEAVE_PROC("SMI_PreInit"); 00927 return(FALSE); 00928 } 00929 00930 xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); 00931 00932 pSmi->PciTag = pciTag(pSmi->PciInfo->bus, pSmi->PciInfo->device, 00933 pSmi->PciInfo->func); 00934 00935 SMI_MapMem(pScrn); 00936 SMI_DisableVideo(pScrn); 00937 00938 hwp = VGAHWPTR(pScrn); 00939 vgaIOBase = hwp->IOBase; 00940 vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; 00941 vgaCRReg = vgaIOBase + VGA_CRTC_DATA_OFFSET; 00942 00943 xf86ErrorFVerb(VERBLEV, "\tSMI_PreInit vgaCRIndex=%x, vgaIOBase=%x, " 00944 "MMIOBase=%x\n", vgaCRIndex, vgaIOBase, hwp->MMIOBase); 00945 00946 /* Next go on to detect amount of installed ram */ 00947 config = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x71); 00948 00949 if (xf86LoadSubModule(pScrn, "i2c")) 00950 { 00951 xf86LoaderReqSymLists(i2cSymbols, NULL); 00952 SMI_I2CInit(pScrn); 00953 } 00954 if (xf86LoadSubModule(pScrn, "ddc")) 00955 { 00956 xf86MonPtr pMon = NULL; 00957 00958 xf86LoaderReqSymLists(ddcSymbols, NULL); 00959 #if 1 /* PDR#579 */ 00960 if (pSmi->pVbe) 00961 { 00962 pMon = vbeDoEDID(pSmi->pVbe, NULL); 00963 if (pMon != NULL) 00964 { 00965 if ( (pMon->rawData[0] == 0x00) 00966 && (pMon->rawData[1] == 0xFF) 00967 && (pMon->rawData[2] == 0xFF) 00968 && (pMon->rawData[3] == 0xFF) 00969 && (pMon->rawData[4] == 0xFF) 00970 && (pMon->rawData[5] == 0xFF) 00971 && (pMon->rawData[6] == 0xFF) 00972 && (pMon->rawData[7] == 0x00) 00973 ) 00974 { 00975 pMon = xf86PrintEDID(pMon); 00976 if (pMon != NULL) 00977 { 00978 xf86SetDDCproperties(pScrn, pMon); 00979 } 00980 } 00981 } 00982 } 00983 #else 00984 if ( (pSmi->pVbe) 00985 && ((pMon = xf86PrintEDID(vbeDoEDID(pSmi->pVbe, NULL))) != NULL) 00986 ) 00987 { 00988 xf86SetDDCproperties(pScrn, pMon); 00989 } 00990 #endif 00991 else if (!SMI_ddc1(pScrn->scrnIndex)) 00992 { 00993 if (pSmi->I2C) 00994 { 00995 xf86SetDDCproperties(pScrn, 00996 xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex, 00997 pSmi->I2C))); 00998 } 00999 } 01000 } 01001 if (pSmi->pVbe) 01002 { 01003 vbeFree(pSmi->pVbe); 01004 pSmi->pVbe = NULL; 01005 } 01006 01007 /* 01008 * If the driver can do gamma correction, it should call xf86SetGamma() 01009 * here. (from MGA, no ViRGE gamma support yet, but needed for 01010 * xf86HandleColormaps support.) 01011 */ 01012 { 01013 Gamma zeros = { 0.0, 0.0, 0.0 }; 01014 01015 if (!xf86SetGamma(pScrn, zeros)) 01016 { 01017 LEAVE_PROC("SMI_PreInit"); 01018 SMI_EnableVideo(pScrn); 01019 SMI_UnmapMem(pScrn); 01020 return(FALSE); 01021 } 01022 } 01023 01024 /* And compute the amount of video memory and offscreen memory */ 01025 pSmi->videoRAMKBytes = 0; 01026 01027 if (!pScrn->videoRam) 01028 { 01029 switch (pSmi->Chipset) 01030 { 01031 default: 01032 { 01033 int mem_table[4] = { 1, 2, 4, 0 }; 01034 pSmi->videoRAMKBytes = mem_table[(config >> 6)] * 1024; 01035 break; 01036 } 01037 01038 case SMI_LYNX3D: 01039 { 01040 int mem_table[4] = { 0, 2, 4, 6 }; 01041 pSmi->videoRAMKBytes = mem_table[(config >> 6)] * 1024 + 512; 01042 break; 01043 } 01044 01045 case SMI_LYNX3DM: 01046 { 01047 int mem_table[4] = { 16, 2, 4, 8 }; 01048 pSmi->videoRAMKBytes = mem_table[(config >> 6)] * 1024; 01049 break; 01050 } 01051 } 01052 pSmi->videoRAMBytes = pSmi->videoRAMKBytes * 1024; 01053 pScrn->videoRam = pSmi->videoRAMKBytes; 01054 01055 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "videoram: %dkB\n", 01056 pSmi->videoRAMKBytes); 01057 } 01058 else 01059 { 01060 pSmi->videoRAMKBytes = pScrn->videoRam; 01061 pSmi->videoRAMBytes = pScrn->videoRam * 1024; 01062 01063 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "videoram: %dk\n", 01064 pSmi->videoRAMKBytes); 01065 } 01066 01067 /* Lynx built-in ramdac speeds */ 01068 pScrn->numClocks = 4; 01069 01070 if ((pScrn->clock[3] <= 0) && (pScrn->clock[2] > 0)) 01071 { 01072 pScrn->clock[3] = pScrn->clock[2]; 01073 } 01074 01075 if (pSmi->Chipset == SMI_LYNX3DM) 01076 { 01077 if (pScrn->clock[0] <= 0) pScrn->clock[0] = 200000; 01078 if (pScrn->clock[1] <= 0) pScrn->clock[1] = 200000; 01079 if (pScrn->clock[2] <= 0) pScrn->clock[2] = 200000; 01080 if (pScrn->clock[3] <= 0) pScrn->clock[3] = 200000; 01081 } 01082 else 01083 { 01084 if (pScrn->clock[0] <= 0) pScrn->clock[0] = 135000; 01085 if (pScrn->clock[1] <= 0) pScrn->clock[1] = 135000; 01086 if (pScrn->clock[2] <= 0) pScrn->clock[2] = 135000; 01087 if (pScrn->clock[3] <= 0) pScrn->clock[3] = 135000; 01088 } 01089 01090 /* Now set RAMDAC limits */ 01091 switch (pSmi->Chipset) 01092 { 01093 default: 01094 pSmi->minClock = 20000; 01095 pSmi->maxClock = 135000; 01096 break; 01097 } 01098 xf86ErrorFVerb(VERBLEV, "\tSMI_PreInit minClock=%d, maxClock=%d\n", 01099 pSmi->minClock, pSmi->maxClock); 01100 01101 /* Detect current MCLK and print it for user */ 01102 m = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A); 01103 n = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B); 01104 switch (n >> 6) 01105 { 01106 default: 01107 shift = 1; 01108 break; 01109 01110 case 1: 01111 shift = 4; 01112 break; 01113 01114 case 2: 01115 shift = 2; 01116 break; 01117 } 01118 n &= 0x3F; 01119 mclk = ((1431818 * m) / n / shift + 50) / 100; 01120 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected current MCLK value of " 01121 "%1.3f MHz\n", mclk / 1000.0); 01122 01123 SMI_EnableVideo(pScrn); 01124 SMI_UnmapMem(pScrn); 01125 01126 pScrn->virtualX = pScrn->display->virtualX; 01127 01128 /* 01129 * Setup the ClockRanges, which describe what clock ranges are available, 01130 * and what sort of modes they can be used for. 01131 */ 01132 clockRanges = xnfalloc(sizeof(ClockRange)); 01133 clockRanges->next = NULL; 01134 clockRanges->minClock = pSmi->minClock; 01135 clockRanges->maxClock = pSmi->maxClock; 01136 clockRanges->clockIndex = -1; 01137 clockRanges->interlaceAllowed = FALSE; 01138 clockRanges->doubleScanAllowed = FALSE; 01139 01140 01141 i = xf86ValidateModes( 01142 pScrn, /* Screen pointer */ 01143 pScrn->monitor->Modes, /* Available monitor modes */ 01144 pScrn->display->modes, /* req mode names for screen */ 01145 clockRanges, /* list of clock ranges allowed */ 01146 NULL, /* use min/max below */ 01147 128, /* min line pitch (width) */ 01148 4096, /* maximum line pitch (width) */ 01149 128, /* bits of granularity for line pitch */ 01150 /* (width) above */ 01151 128, /* min virtual height */ 01152 4096, /* max virtual height */ 01153 pScrn->display->virtualX, /* force virtual x */ 01154 pScrn->display->virtualY, /* force virtual Y */ 01155 pSmi->videoRAMBytes, /* size of aperture used to access */ 01156 /* video memory */ 01157 LOOKUP_BEST_REFRESH); /* how to pick modes */ 01158 01159 if (i == -1) 01160 { 01161 SMI_FreeRec(pScrn); 01162 LEAVE_PROC("SMI_PreInit"); 01163 return(FALSE); 01164 } 01165 01166 /* Prune the modes marked as invalid */ 01167 xf86PruneDriverModes(pScrn); 01168 01169 if ((i == 0) || (pScrn->modes == NULL)) 01170 { 01171 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 01172 SMI_FreeRec(pScrn); 01173 LEAVE_PROC("SMI_PreInit"); 01174 return(FALSE); 01175 } 01176 xf86SetCrtcForModes(pScrn, 0); 01177 01178 /* Set the current mode to the first in the list */ 01179 pScrn->currentMode = pScrn->modes; 01180 01181 /* Print the list of modes being used */ 01182 xf86PrintModes(pScrn); 01183 01184 /* Set display resolution */ 01185 xf86SetDpi(pScrn, 0, 0); 01186 01187 #ifdef USE_FB 01188 if ((xf86LoadSubModule(pScrn, "fb") == NULL)) 01189 { 01190 SMI_FreeRec(pScrn); 01191 LEAVE_PROC("SMI_PreInit"); 01192 return(FALSE); 01193 } 01194 01195 xf86LoaderReqSymLists(fbSymbols, NULL); 01196 #else 01197 /* Load bpp-specific modules */ 01198 switch (pScrn->bitsPerPixel) 01199 { 01200 case 8: 01201 mod = "cfb"; 01202 reqSym = "cfbScreenInit"; 01203 break; 01204 01205 case 16: 01206 mod = "cfb16"; 01207 reqSym = "cfb16ScreenInit"; 01208 break; 01209 01210 case 24: 01211 mod = "cfb24"; 01212 reqSym = "cfb24ScreenInit"; 01213 break; 01214 } 01215 01216 if (mod && (xf86LoadSubModule(pScrn, mod) == NULL)) 01217 { 01218 SMI_FreeRec(pScrn); 01219 LEAVE_PROC("SMI_PreInit"); 01220 return(FALSE); 01221 } 01222 01223 xf86LoaderReqSymbols(reqSym, NULL); 01224 #endif 01225 /* Load XAA if needed */ 01226 if (!pSmi->NoAccel || pSmi->hwcursor) 01227 { 01228 if (!xf86LoadSubModule(pScrn, "xaa")) 01229 { 01230 SMI_FreeRec(pScrn); 01231 LEAVE_PROC("SMI_PreInit"); 01232 return(FALSE); 01233 } 01234 xf86LoaderReqSymLists(xaaSymbols, NULL); 01235 } 01236 01237 /* Load ramdac if needed */ 01238 if (pSmi->hwcursor) 01239 { 01240 if (!xf86LoadSubModule(pScrn, "ramdac")) 01241 { 01242 SMI_FreeRec(pScrn); 01243 LEAVE_PROC("SMI_PreInit"); 01244 return(FALSE); 01245 } 01246 xf86LoaderReqSymLists(ramdacSymbols, NULL); 01247 } 01248 01249 if (pSmi->shadowFB) 01250 { 01251 if (!xf86LoadSubModule(pScrn, "shadowfb")) 01252 { 01253 SMI_FreeRec(pScrn); 01254 LEAVE_PROC("SMI_PreInit"); 01255 return(FALSE); 01256 } 01257 xf86LoaderReqSymLists(shadowSymbols, NULL); 01258 } 01259 01260 LEAVE_PROC("SMI_PreInit"); 01261 return(TRUE); 01262 } 01263 01264 /* 01265 * This is called when VT switching back to the X server. Its job is to 01266 * reinitialise the video mode. We may wish to unmap video/MMIO memory too. 01267 */ 01268 01269 static Bool 01270 SMI_EnterVT(int scrnIndex, int flags) 01271 { 01272 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 01273 SMIPtr pSmi = SMIPTR(pScrn); 01274 Bool ret; 01275 01276 ENTER_PROC("SMI_EnterVT"); 01277 01278 /* Enable MMIO and map memory */ 01279 SMI_MapMem(pScrn); 01280 SMI_Save(pScrn); 01281 01282 /* #670 */ 01283 if (pSmi->shadowFB) 01284 { 01285 pSmi->FBOffset = pSmi->savedFBOffset; 01286 pSmi->FBReserved = pSmi->savedFBReserved; 01287 } 01288 01289 ret = SMI_ModeInit(pScrn, pScrn->currentMode); 01290 01291 /* #670 */ 01292 if (ret && pSmi->shadowFB) 01293 { 01294 BoxRec box; 01295 01296 /* #920 */ 01297 if (pSmi->paletteBuffer) 01298 { 01299 int i; 01300 01301 VGAOUT8(pSmi, VGA_DAC_WRITE_ADDR, 0); 01302 for(i = 0; i < 256 * 3; i++) 01303 { 01304 VGAOUT8(pSmi, VGA_DAC_DATA, pSmi->paletteBuffer[i]); 01305 } 01306 xfree(pSmi->paletteBuffer); 01307 pSmi->paletteBuffer = NULL; 01308 } 01309 01310 if (pSmi->pSaveBuffer) 01311 { 01312 memcpy(pSmi->FBBase, pSmi->pSaveBuffer, pSmi->saveBufferSize); 01313 xfree(pSmi->pSaveBuffer); 01314 pSmi->pSaveBuffer = NULL; 01315 } 01316 01317 box.x1 = 0; 01318 box.y1 = 0; 01319 box.x2 = pScrn->virtualY; 01320 box.y2 = pScrn->virtualX; 01321 SMI_RefreshArea(pScrn, 1, &box); 01322 } 01323 01324 /* Reset the grapics engine */ 01325 if (!pSmi->NoAccel) 01326 SMI_EngineReset(pScrn); 01327 01328 LEAVE_PROC("SMI_EnterVT"); 01329 return(ret); 01330 } 01331 01332 /* 01333 * This is called when VT switching away from the X server. Its job is to 01334 * restore the previous (text) mode. We may wish to remap video/MMIO memory 01335 * too. 01336 */ 01337 01338 static void 01339 SMI_LeaveVT(int scrnIndex, int flags) 01340 { 01341 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 01342 vgaHWPtr hwp = VGAHWPTR(pScrn); 01343 SMIPtr pSmi = SMIPTR(pScrn); 01344 vgaRegPtr vgaSavePtr = &hwp->SavedReg; 01345 SMIRegPtr SMISavePtr = &pSmi->SavedReg; 01346 01347 ENTER_PROC("SMI_LeaveVT"); 01348 01349 /* #670 */ 01350 if (pSmi->shadowFB) 01351 { 01352 pSmi->pSaveBuffer = xnfalloc(pSmi->saveBufferSize); 01353 if (pSmi->pSaveBuffer) 01354 { 01355 memcpy(pSmi->pSaveBuffer, pSmi->FBBase, pSmi->saveBufferSize); 01356 } 01357 01358 pSmi->savedFBOffset = pSmi->FBOffset; 01359 pSmi->savedFBReserved = pSmi->FBReserved; 01360 01361 /* #920 */ 01362 if (pSmi->Bpp == 1) 01363 { 01364 pSmi->paletteBuffer = xnfalloc(256 * 3); 01365 if (pSmi->paletteBuffer) 01366 { 01367 int i; 01368 01369 VGAOUT8(pSmi, VGA_DAC_READ_ADDR, 0); 01370 for (i = 0; i < 256 * 3; i++) 01371 { 01372 pSmi->paletteBuffer[i] = VGAIN8(pSmi, VGA_DAC_DATA); 01373 } 01374 } 01375 } 01376 } 01377 01378 memset(pSmi->FBBase, 0, 256 * 1024); /* #689 */ 01379 SMI_WriteMode(pScrn, vgaSavePtr, SMISavePtr); 01380 SMI_UnmapMem(pScrn); 01381 01382 LEAVE_PROC("SMI_LeaveVT"); 01383 } 01384 01385 /* 01386 * This function performs the inverse of the restore function: It saves all the 01387 * standard and extended registers that we are going to modify to set up a video 01388 * mode. 01389 */ 01390 01391 static void 01392 SMI_Save(ScrnInfoPtr pScrn) 01393 { 01394 int i; 01395 CARD32 offset; 01396 01397 vgaHWPtr hwp = VGAHWPTR(pScrn); 01398 vgaRegPtr vgaSavePtr = &hwp->SavedReg; 01399 SMIPtr pSmi = SMIPTR(pScrn); 01400 SMIRegPtr save = &pSmi->SavedReg; 01401 01402 int vgaIOBase = hwp->IOBase; 01403 int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; 01404 int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; 01405 01406 ENTER_PROC("SMI_Save"); 01407 01408 /* Save the standard VGA registers */ 01409 vgaHWSave(pScrn, vgaSavePtr, VGA_SR_MODE); 01410 save->smiDACMask = VGAIN8(pSmi, VGA_DAC_MASK); 01411 VGAOUT8(pSmi, VGA_DAC_READ_ADDR, 0); 01412 for (i = 0; i < 256; i++) 01413 { 01414 save->smiDacRegs[i][0] = VGAIN8(pSmi, VGA_DAC_DATA); 01415 save->smiDacRegs[i][1] = VGAIN8(pSmi, VGA_DAC_DATA); 01416 save->smiDacRegs[i][2] = VGAIN8(pSmi, VGA_DAC_DATA); 01417 } 01418 for (i = 0, offset = 2; i < 8192; i++, offset += 8) 01419 { 01420 save->smiFont[i] = *(pSmi->FBBase + offset); 01421 } 01422 01423 /* Now we save all the extended registers we need. */ 01424 save->SR17 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17); 01425 save->SR18 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18); 01426 save->SR21 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 01427 save->SR31 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31); 01428 save->SR32 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32); 01429 save->SR6A = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A); 01430 save->SR6B = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B); 01431 save->SR81 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81); 01432 save->SRA0 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0); 01433 01434 if (SMI_LYNXM_SERIES(pSmi->Chipset)) 01435 { 01436 /* Save primary registers */ 01437 save->CR90[14] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E); 01438 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, 01439 save->CR90[14] & ~0x20); 01440 01441 for (i = 0; i < 16; i++) 01442 { 01443 save->CR90[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x90 + i); 01444 } 01445 save->CR33 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33); 01446 save->CR3A = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A); 01447 for (i = 0; i < 14; i++) 01448 { 01449 save->CR40[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i); 01450 } 01451 01452 /* Save secondary registers */ 01453 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14] | 0x20); 01454 save->CR33_2 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33); 01455 for (i = 0; i < 14; i++) 01456 { 01457 save->CR40_2[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 01458 0x40 + i); 01459 } 01460 save->CR9F_2 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F); 01461 01462 /* Save common registers */ 01463 for (i = 0; i < 14; i++) 01464 { 01465 save->CRA0[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0xA0 + i); 01466 } 01467 01468 /* PDR#1069 */ 01469 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14]); 01470 } 01471 else 01472 { 01473 save->CR33 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33); 01474 save->CR3A = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A); 01475 for (i = 0; i < 14; i++) 01476 { 01477 save->CR40[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i); 01478 } 01479 } 01480 01481 /* CZ 2.11.2001: for gamma correction (TODO: other chipsets?) */ 01482 if (pSmi->Chipset == SMI_LYNX3DM) { 01483 save->CCR66 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66); 01484 } 01485 /* end CZ */ 01486 01487 save->DPR10 = READ_DPR(pSmi, 0x10); 01488 save->DPR1C = READ_DPR(pSmi, 0x1C); 01489 save->DPR20 = READ_DPR(pSmi, 0x20); 01490 save->DPR24 = READ_DPR(pSmi, 0x24); 01491 save->DPR28 = READ_DPR(pSmi, 0x28); 01492 save->DPR2C = READ_DPR(pSmi, 0x2C); 01493 save->DPR30 = READ_DPR(pSmi, 0x30); 01494 save->DPR3C = READ_DPR(pSmi, 0x3C); 01495 save->DPR40 = READ_DPR(pSmi, 0x40); 01496 save->DPR44 = READ_DPR(pSmi, 0x44); 01497 01498 save->VPR00 = READ_VPR(pSmi, 0x00); 01499 save->VPR0C = READ_VPR(pSmi, 0x0C); 01500 save->VPR10 = READ_VPR(pSmi, 0x10); 01501 01502 save->CPR00 = READ_CPR(pSmi, 0x00); 01503 01504 if (!pSmi->ModeStructInit) 01505 { 01506 /* XXX Should check the return value of vgaHWCopyReg() */ 01507 vgaHWCopyReg(&hwp->ModeReg, vgaSavePtr); 01508 memcpy(&pSmi->ModeReg, save, sizeof(SMIRegRec)); 01509 pSmi->ModeStructInit = TRUE; 01510 } 01511 01512 if (pSmi->useBIOS && (pSmi->pVbe != NULL)) 01513 { 01514 pSmi->pVbe->pInt10->num = 0x10; 01515 pSmi->pVbe->pInt10->ax = 0x0F00; 01516 xf86ExecX86int10(pSmi->pVbe->pInt10); 01517 save->mode = pSmi->pVbe->pInt10->ax & 0x007F; 01518 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode 0x%02X.\n", 01519 save->mode); 01520 } 01521 01522 if (xf86GetVerbosity() > 1) 01523 { 01524 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 01525 "Saved current video mode. Register dump:\n"); 01526 SMI_PrintRegs(pScrn); 01527 } 01528 01529 LEAVE_PROC("SMI_Save"); 01530 } 01531 01532 /* 01533 * This function is used to restore a video mode. It writes out all of the 01534 * standard VGA and extended registers needed to setup a video mode. 01535 */ 01536 01537 static void 01538 SMI_WriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, SMIRegPtr restore) 01539 { 01540 int i; 01541 CARD8 tmp; 01542 CARD32 offset; 01543 01544 vgaHWPtr hwp = VGAHWPTR(pScrn); 01545 SMIPtr pSmi = SMIPTR(pScrn); 01546 int vgaIOBase = hwp->IOBase; 01547 int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; 01548 int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; 01549 01550 ENTER_PROC("SMI_WriteMode"); 01551 01552 vgaHWProtect(pScrn, TRUE); 01553 01554 /* Wait for engine to become idle */ 01555 WaitIdle(); 01556 01557 if (pSmi->useBIOS && (pSmi->pVbe->pInt10 != NULL) 01558 && (restore->mode != 0)) 01559 { 01560 pSmi->pVbe->pInt10->num = 0x10; 01561 pSmi->pVbe->pInt10->ax = restore->mode | 0x80; 01562 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%02X\n", 01563 restore->mode); 01564 xf86ExecX86int10(pSmi->pVbe->pInt10); 01565 01566 /* Enable linear mode. */ 01567 outb(VGA_SEQ_INDEX, 0x18); 01568 tmp = inb(VGA_SEQ_DATA); 01569 outb(VGA_SEQ_DATA, tmp | 0x01); 01570 01571 /* Enable DPR/VPR registers. */ 01572 tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 01573 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03); 01574 } 01575 else 01576 { 01577 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17, restore->SR17); 01578 tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18) & ~0x1F; 01579 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18, tmp | 01580 (restore->SR18 & 0x1F)); 01581 tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 01582 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03); 01583 tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31) & ~0xC0; 01584 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, tmp | 01585 (restore->SR31 & 0xC0)); 01586 tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32) & ~0x07; 01587 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32, tmp | 01588 (restore->SR32 & 0x07)); 01589 if (restore->SR6B != 0xFF) 01590 { 01591 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A, 01592 restore->SR6A); 01593 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B, 01594 restore->SR6B); 01595 } 01596 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, restore->SR81); 01597 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0, restore->SRA0); 01598 01599 /* Restore the standard VGA registers */ 01600 vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_MODE); 01601 if (restore->smiDACMask) 01602 { 01603 VGAOUT8(pSmi, VGA_DAC_MASK, restore->smiDACMask); 01604 } 01605 else 01606 { 01607 VGAOUT8(pSmi, VGA_DAC_MASK, 0xFF); 01608 } 01609 VGAOUT8(pSmi, VGA_DAC_WRITE_ADDR, 0); 01610 for (i = 0; i < 256; i++) 01611 { 01612 VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][0]); 01613 VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][1]); 01614 VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][2]); 01615 } 01616 for (i = 0, offset = 2; i < 8192; i++, offset += 8) 01617 { 01618 *(pSmi->FBBase + offset) = restore->smiFont[i]; 01619 } 01620 01621 if (SMI_LYNXM_SERIES(pSmi->Chipset)) 01622 { 01623 /* Restore secondary registers */ 01624 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, 01625 restore->CR90[14] | 0x20); 01626 01627 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33_2); 01628 for (i = 0; i < 14; i++) 01629 { 01630 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, 01631 restore->CR40_2[i]); 01632 } 01633 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F, restore->CR9F_2); 01634 01635 /* Restore primary registers */ 01636 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, 01637 restore->CR90[14] & ~0x20); 01638 01639 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33); 01640 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A); 01641 for (i = 0; i < 14; i++) 01642 { 01643 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, 01644 restore->CR40[i]); 01645 } 01646 for (i = 0; i < 16; i++) 01647 { 01648 if (i != 14) 01649 { 01650 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x90 + i, 01651 restore->CR90[i]); 01652 } 01653 } 01654 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, restore->CR90[14]); 01655 01656 /* Restore common registers */ 01657 for (i = 0; i < 14; i++) 01658 { 01659 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0xA0 + i, 01660 restore->CRA0[i]); 01661 } 01662 } 01663 01664 /* Restore the standard VGA registers */ 01665 if (xf86IsPrimaryPci(pSmi->PciInfo)) 01666 { 01667 vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL); 01668 } 01669 else 01670 { 01671 vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_MODE); 01672 } 01673 01674 if (!SMI_LYNXM_SERIES(pSmi->Chipset)) 01675 { 01676 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33); 01677 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A); 01678 for (i = 0; i < 14; i++) 01679 { 01680 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, 01681 restore->CR40[i]); 01682 } 01683 } 01684 } 01685 01686 /* CZ 2.11.2001: for gamma correction (TODO: other chipsets?) */ 01687 if (pSmi->Chipset == SMI_LYNX3DM) { 01688 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66, restore->CCR66); 01689 } 01690 /* end CZ */ 01691 01692 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, 0x00); 01693 01694 WRITE_DPR(pSmi, 0x10, restore->DPR10); 01695 WRITE_DPR(pSmi, 0x1C, restore->DPR1C); 01696 WRITE_DPR(pSmi, 0x20, restore->DPR20); 01697 WRITE_DPR(pSmi, 0x24, restore->DPR24); 01698 WRITE_DPR(pSmi, 0x28, restore->DPR28); 01699 WRITE_DPR(pSmi, 0x2C, restore->DPR2C); 01700 WRITE_DPR(pSmi, 0x30, restore->DPR30); 01701 WRITE_DPR(pSmi, 0x3C, restore->DPR3C); 01702 WRITE_DPR(pSmi, 0x40, restore->DPR40); 01703 WRITE_DPR(pSmi, 0x44, restore->DPR44); 01704 01705 WRITE_VPR(pSmi, 0x00, restore->VPR00); 01706 WRITE_VPR(pSmi, 0x0C, restore->VPR0C); 01707 WRITE_VPR(pSmi, 0x10, restore->VPR10); 01708 01709 WRITE_CPR(pSmi, 0x00, restore->CPR00); 01710 01711 if (xf86GetVerbosity() > 1) 01712 { 01713 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 01714 "Done restoring mode. Register dump:\n"); 01715 SMI_PrintRegs(pScrn); 01716 } 01717 01718 vgaHWProtect(pScrn, FALSE); 01719 01720 LEAVE_PROC("SMI_WriteMode"); 01721 } 01722 01723 static Bool 01724 SMI_MapMem(ScrnInfoPtr pScrn) 01725 { 01726 SMIPtr pSmi = SMIPTR(pScrn); 01727 vgaHWPtr hwp; 01728 CARD32 memBase; 01729 01730 ENTER_PROC("SMI_MapMem"); 01731 01732 /* Map the Lynx register space */ 01733 switch (pSmi->Chipset) 01734 { 01735 default: 01736 memBase = pSmi->PciInfo->memBase[0] + 0x400000; 01737 pSmi->MapSize = 0x10000; 01738 break; 01739 01740 case SMI_LYNX3D: 01741 memBase = pSmi->PciInfo->memBase[0] + 0x680000; 01742 pSmi->MapSize = 0x180000; 01743 break; 01744 01745 case SMI_LYNXEM: 01746 case SMI_LYNXEMplus: 01747 memBase = pSmi->PciInfo->memBase[0] + 0x400000; 01748 pSmi->MapSize = 0x400000; 01749 break; 01750 01751 case SMI_LYNX3DM: 01752 memBase = pSmi->PciInfo->memBase[0]; 01753 pSmi->MapSize = 0x200000; 01754 break; 01755 } 01756 pSmi->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pSmi->PciTag, 01757 memBase, pSmi->MapSize); 01758 01759 if (pSmi->MapBase == NULL) 01760 { 01761 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Internal error: could not map " 01762 "MMIO registers.\n"); 01763 LEAVE_PROC("SMI_MapMem"); 01764 return(FALSE); 01765 } 01766 01767 switch (pSmi->Chipset) 01768 { 01769 default: 01770 pSmi->DPRBase = pSmi->MapBase + 0x8000; 01771 pSmi->VPRBase = pSmi->MapBase + 0xC000; 01772 pSmi->CPRBase = pSmi->MapBase + 0xE000; 01773 pSmi->IOBase = NULL; 01774 pSmi->DataPortBase = pSmi->MapBase; 01775 pSmi->DataPortSize = 0x8000; 01776 break; 01777 01778 case SMI_LYNX3D: 01779 pSmi->DPRBase = pSmi->MapBase + 0x000000; 01780 pSmi->VPRBase = pSmi->MapBase + 0x000800; 01781 pSmi->CPRBase = pSmi->MapBase + 0x001000; 01782 pSmi->IOBase = pSmi->MapBase + 0x040000; 01783 pSmi->DataPortBase = pSmi->MapBase + 0x080000; 01784 pSmi->DataPortSize = 0x100000; 01785 break; 01786 01787 case SMI_LYNXEM: 01788 case SMI_LYNXEMplus: 01789 pSmi->DPRBase = pSmi->MapBase + 0x008000; 01790 pSmi->VPRBase = pSmi->MapBase + 0x00C000; 01791 pSmi->CPRBase = pSmi->MapBase + 0x00E000; 01792 pSmi->IOBase = pSmi->MapBase + 0x300000; 01793 pSmi->DataPortBase = pSmi->MapBase /*+ 0x100000*/; 01794 pSmi->DataPortSize = 0x8000 /*0x200000*/; 01795 break; 01796 01797 case SMI_LYNX3DM: 01798 pSmi->DPRBase = pSmi->MapBase + 0x000000; 01799 pSmi->VPRBase = pSmi->MapBase + 0x000800; 01800 pSmi->CPRBase = pSmi->MapBase + 0x001000; 01801 pSmi->IOBase = pSmi->MapBase + 0x0C0000; 01802 pSmi->DataPortBase = pSmi->MapBase + 0x100000; 01803 pSmi->DataPortSize = 0x100000; 01804 break; 01805 } 01806 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 01807 "Physical MMIO at 0x%08X\n", memBase); 01808 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 01809 "Logical MMIO at 0x%08X - 0x%08X\n", pSmi->MapBase, 01810 pSmi->MapBase + pSmi->MapSize - 1); 01811 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 01812 "DPR=0x%08X, VPR=0x%08X, IOBase=0x%08X\n", pSmi->DPRBase, 01813 pSmi->VPRBase, pSmi->IOBase); 01814 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 01815 "DataPort=0x%08X - 0x%08X\n", pSmi->DataPortBase, 01816 pSmi->DataPortBase + pSmi->DataPortSize - 1); 01817 01818 /* Map the frame buffer */ 01819 if (pSmi->Chipset == SMI_LYNX3DM) 01820 { 01821 pScrn->memPhysBase = pSmi->PciInfo->memBase[0] + 0x200000; 01822 } 01823 else 01824 { 01825 pScrn->memPhysBase = pSmi->PciInfo->memBase[0]; 01826 } 01827 if (pSmi->videoRAMBytes) 01828 { 01829 pSmi->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 01830 pSmi->PciTag, pScrn->memPhysBase, pSmi->videoRAMBytes); 01831 01832 if (pSmi->FBBase == NULL) 01833 { 01834 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Internal error: could not " 01835 "map framebuffer.\n"); 01836 LEAVE_PROC("SMI_MapMem"); 01837 return(FALSE); 01838 } 01839 } 01840 pSmi->FBOffset = pScrn->fbOffset = 0; 01841 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 01842 "Physical frame buffer at 0x%08X\n", pScrn->memPhysBase); 01843 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 01844 "Logical frame buffer at 0x%08X - 0x%08X\n", pSmi->FBBase, 01845 pSmi->FBBase + pSmi->videoRAMBytes - 1); 01846 01847 SMI_EnableMmio(pScrn); 01848 01849 /* Set up offset to hwcursor memory area. It's a 1K chunk at the end of 01850 * the frame buffer. Also set up the reserved memory space. 01851 */ 01852 pSmi->FBCursorOffset = pSmi->videoRAMBytes - 1024; 01853 if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30) & 0x01)/* #1074 */ 01854 { 01855 CARD32 fifoOffset = 0; 01856 fifoOffset |= VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x46) 01857 << 3; 01858 fifoOffset |= VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x47) 01859 << 11; 01860 fifoOffset |= (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49) 01861 & 0x1C) << 17; 01862 pSmi->FBReserved = fifoOffset; /* PDR#1074 */ 01863 } 01864 else 01865 { 01866 pSmi->FBReserved = pSmi->videoRAMBytes - 2048; 01867 } 01868 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Cursor Offset: %08X Reserved: %08X\n", 01869 pSmi->FBCursorOffset, pSmi->FBReserved); 01870 01871 pSmi->lcd = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31) & 0x01; 01872 if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30) & 0x01) 01873 { 01874 pSmi->lcd <<= 1; 01875 } 01876 switch (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30) & 0x0C) 01877 { 01878 case 0x00: 01879 pSmi->lcdWidth = 640; 01880 pSmi->lcdHeight = 480; 01881 break; 01882 01883 case 0x04: 01884 pSmi->lcdWidth = 800; 01885 pSmi->lcdHeight = 600; 01886 break; 01887 01888 case 0x08: 01889 if (VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x74) & 0x02) 01890 { 01891 pSmi->lcdWidth = 1024; 01892 pSmi->lcdHeight = 600; 01893 } 01894 else 01895 { 01896 pSmi->lcdWidth = 1024; 01897 pSmi->lcdHeight = 768; 01898 } 01899 break; 01900 01901 case 0x0C: 01902 pSmi->lcdWidth = 1280; 01903 pSmi->lcdHeight = 1024; 01904 break; 01905 } 01906 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s Panel Size = %dx%d\n", 01907 (pSmi->lcd == 0) ? "OFF" : (pSmi->lcd == 1) ? "TFT" : "DSTN", 01908 pSmi->lcdWidth, pSmi->lcdHeight); 01909 01910 /* Assign hwp->MemBase & IOBase here */ 01911 hwp = VGAHWPTR(pScrn); 01912 if (pSmi->IOBase != NULL) 01913 { 01914 vgaHWSetMmioFuncs(hwp, pSmi->MapBase, pSmi->IOBase - pSmi->MapBase); 01915 } 01916 vgaHWGetIOBase(hwp); 01917 01918 /* Map the VGA memory when the primary video */ 01919 if (xf86IsPrimaryPci(pSmi->PciInfo)) 01920 { 01921 hwp->MapSize = 0x10000; 01922 if (!vgaHWMapMem(pScrn)) 01923 { 01924 LEAVE_PROC("SMI_MapMem"); 01925 return(FALSE); 01926 } 01927 pSmi->PrimaryVidMapped = TRUE; 01928 } 01929 01930 LEAVE_PROC("SMI_MapMem"); 01931 return(TRUE); 01932 } 01933 01934 /* UnMapMem - contains half of pre-4.0 EnterLeave function. The EnterLeave 01935 * function which en/disable access to IO ports and ext. regs 01936 */ 01937 01938 static void 01939 SMI_UnmapMem(ScrnInfoPtr pScrn) 01940 { 01941 SMIPtr pSmi = SMIPTR(pScrn); 01942 01943 ENTER_PROC("SMI_UnmapMem"); 01944 01945 /* Unmap VGA mem if mapped. */ 01946 if (pSmi->PrimaryVidMapped) 01947 { 01948 vgaHWUnmapMem(pScrn); 01949 pSmi->PrimaryVidMapped = FALSE; 01950 } 01951 01952 SMI_DisableMmio(pScrn); 01953 01954 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pSmi->MapBase, pSmi->MapSize); 01955 if (pSmi->FBBase != NULL) 01956 { 01957 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pSmi->FBBase, 01958 pSmi->videoRAMBytes); 01959 } 01960 01961 LEAVE_PROC("SMI_UnmapMem"); 01962 } 01963 01964 /* This gets called at the start of each server generation. */ 01965 01966 static Bool 01967 SMI_ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 01968 { 01969 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 01970 SMIPtr pSmi = SMIPTR(pScrn); 01971 EntityInfoPtr pEnt; 01972 01973 ENTER_PROC("SMI_ScreenInit"); 01974 01975 /* Map MMIO regs and framebuffer */ 01976 if (!SMI_MapMem(pScrn)) 01977 { 01978 LEAVE_PROC("SMI_ScreenInit"); 01979 return(FALSE); 01980 } 01981 01982 pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 01983 01984 /* Save the chip/graphics state */ 01985 SMI_Save(pScrn); 01986 01987 if (!pSmi->pVbe) { 01988 pSmi->pVbe = VBEInit(NULL, pEnt->index); 01989 } 01990 /* Zero the frame buffer, #258 */ 01991 memset(pSmi->FBBase, 0, pSmi->videoRAMBytes); 01992 01993 /* Initialize the first mode */ 01994 if (!SMI_ModeInit(pScrn, pScrn->currentMode)) 01995 { 01996 LEAVE_PROC("SMI_ScreenInit"); 01997 return(FALSE); 01998 } 01999 02000 /* 02001 * The next step is to setup the screen's visuals, and initialise the 02002 * framebuffer code. In cases where the framebuffer's default choises for 02003 * things like visual layouts and bits per RGB are OK, this may be as simple 02004 * as calling the framebuffer's ScreenInit() function. If not, the visuals 02005 * will need to be setup before calling a fb ScreenInit() function and fixed 02006 * up after. 02007 * 02008 * For most PC hardware at depths >= 8, the defaults that cfb uses are not 02009 * appropriate. In this driver, we fixup the visuals after. 02010 */ 02011 02012 /* 02013 * Reset the visual list. 02014 */ 02015 miClearVisualTypes(); 02016 02017 /* Setup the visuals we support. */ 02018 02019 /* 02020 * For bpp > 8, the default visuals are not acceptable because we only 02021 * support TrueColor and not DirectColor. To deal with this, call 02022 * miSetVisualTypes with the appropriate visual mask. 02023 */ 02024 #ifndef USE_FB 02025 if (pScrn->bitsPerPixel > 8) 02026 { 02027 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, 02028 pScrn->defaultVisual)) 02029 { 02030 LEAVE_PROC("SMI_ScreenInit"); 02031 return(FALSE); 02032 } 02033 } 02034 else 02035 #endif 02036 { 02037 if (!miSetVisualTypes(pScrn->depth, 02038 miGetDefaultVisualMask(pScrn->depth), pScrn->rgbBits, 02039 pScrn->defaultVisual)) 02040 { 02041 LEAVE_PROC("SMI_ScreenInit"); 02042 return(FALSE); 02043 } 02044 } 02045 #ifdef USE_FB 02046 if (!miSetPixmapDepths ()) return FALSE; 02047 #endif 02048 02049 if (!SMI_InternalScreenInit(scrnIndex, pScreen)) 02050 { 02051 LEAVE_PROC("SMI_ScreenInit"); 02052 return(FALSE); 02053 } 02054 02055 xf86SetBlackWhitePixels(pScreen); 02056 02057 if (pScrn->bitsPerPixel > 8) 02058 { 02059 VisualPtr visual; 02060 /* Fixup RGB ordering */ 02061 visual = pScreen->visuals + pScreen->numVisuals; 02062 while (--visual >= pScreen->visuals) 02063 { 02064 if ((visual->class | DynamicClass) == DirectColor) 02065 { 02066 visual->offsetRed = pScrn->offset.red; 02067 visual->offsetGreen = pScrn->offset.green; 02068 visual->offsetBlue = pScrn->offset.blue; 02069 visual->redMask = pScrn->mask.red; 02070 visual->greenMask = pScrn->mask.green; 02071 visual->blueMask = pScrn->mask.blue; 02072 } 02073 } 02074 } 02075 02076 #ifdef USE_FB 02077 /* must be after RGB ordering fixed */ 02078 fbPictureInit(pScreen, 0, 0); 02079 #endif 02080 02081 /* CZ 18.06.2001: moved here from smi_accel.c to have offscreen 02082 framebuffer in NoAccel mode */ 02083 { 02084 int numLines, maxLines; 02085 BoxRec AvailFBArea; 02086 02087 maxLines = pSmi->FBReserved / (pSmi->width * pSmi->Bpp); 02088 if (pSmi->rotate) { 02089 numLines = maxLines; 02090 } else { 02091 /* CZ 3.11.2001: What does the following code? see also smi_video.c aaa line 1226 */ 02092 /*#if defined(XvExtension) && SMI_USE_VIDEO */ 02093 #if 0 02094 numLines = ((pSmi->FBReserved - pSmi->width * pSmi->Bpp 02095 * pSmi->height) * 25 / 100 + pSmi->width 02096 * pSmi->Bpp - 1) / (pSmi->width * pSmi->Bpp); 02097 numLines += pSmi->height; 02098 #else 02099 numLines = maxLines; 02100 #endif 02101 } 02102 02103 AvailFBArea.x1 = 0; 02104 AvailFBArea.y1 = 0; 02105 AvailFBArea.x2 = pSmi->width; 02106 AvailFBArea.y2 = numLines; 02107 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 02108 "FrameBuffer Box: %d,%d - %d,%d\n", 02109 AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, 02110 AvailFBArea.y2); 02111 xf86InitFBManager(pScreen, &AvailFBArea); 02112 } 02113 /* end CZ */ 02114 02115 02116 /* Initialize acceleration layer */ 02117 if (!pSmi->NoAccel) { 02118 if (!SMI_AccelInit(pScreen)) { 02119 LEAVE_PROC("SMI_ScreenInit"); 02120 return(FALSE); 02121 } 02122 } 02123 02124 miInitializeBackingStore(pScreen); 02125 02126 /* hardware cursor needs to wrap this layer */ 02127 SMI_DGAInit(pScreen); 02128 02129 /* Initialise cursor functions */ 02130 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 02131 02132 /* Initialize HW cursor layer. Must follow software cursor 02133 * initialization. 02134 */ 02135 if (pSmi->hwcursor) 02136 { 02137 if (!SMI_HWCursorInit(pScreen)) 02138 { 02139 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Hardware cursor " 02140 "initialization failed\n"); 02141 } 02142 } 02143 02144 if (pSmi->shadowFB) 02145 { 02146 RefreshAreaFuncPtr refreshArea = SMI_RefreshArea; 02147 02148 if (pSmi->rotate) 02149 { 02150 if (pSmi->PointerMoved == NULL) 02151 { 02152 pSmi->PointerMoved = pScrn->PointerMoved; 02153 pScrn->PointerMoved = SMI_PointerMoved; 02154 } 02155 } 02156 02157 ShadowFBInit(pScreen, refreshArea); 02158 } 02159 02160 /* Initialise default colormap */ 02161 if (!miCreateDefColormap(pScreen)) 02162 { 02163 LEAVE_PROC("SMI_ScreenInit"); 02164 return(FALSE); 02165 } 02166 02167 /* Initialize colormap layer. Must follow initialization of the default 02168 * colormap. And SetGamma call, else it will load palette with solid white. 02169 */ 02170 /* CZ 2.11.2001: CMAP_PALETTED_TRUECOLOR for gamma correction */ 02171 if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, SMI_LoadPalette, NULL, 02172 CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) 02173 { 02174 LEAVE_PROC("SMI_ScreenInit"); 02175 return(FALSE); 02176 } 02177 02178 pScreen->SaveScreen = SMI_SaveScreen; 02179 pSmi->CloseScreen = pScreen->CloseScreen; 02180 pScreen->CloseScreen = SMI_CloseScreen; 02181 02182 if (!xf86DPMSInit(pScreen, SMI_DisplayPowerManagementSet, 0)) 02183 { 02184 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed!\n"); 02185 } 02186 02187 SMI_InitVideo(pScreen); 02188 02189 /* Report any unused options (only for the first generation) */ 02190 if (serverGeneration == 1) 02191 { 02192 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 02193 } 02194 02195 LEAVE_PROC("SMI_ScreenInit"); 02196 return(TRUE); 02197 } 02198 02199 /* Common init routines needed in EnterVT and ScreenInit */ 02200 02201 static int 02202 SMI_InternalScreenInit(int scrnIndex, ScreenPtr pScreen) 02203 { 02204 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 02205 SMIPtr pSmi = SMIPTR(pScrn); 02206 int width, height, displayWidth; 02207 int bytesPerPixel = pScrn->bitsPerPixel / 8; 02208 int xDpi, yDpi; 02209 int ret; 02210 02211 ENTER_PROC("SMI_InternalScreenInit"); 02212 02213 if (pSmi->rotate) 02214 { 02215 width = pScrn->virtualY; 02216 height = pScrn->virtualX; 02217 xDpi = pScrn->yDpi; 02218 yDpi = pScrn->xDpi; 02219 displayWidth = ((width * bytesPerPixel + 15) & ~15) / bytesPerPixel; 02220 } 02221 else 02222 { 02223 width = pScrn->virtualX; 02224 height = pScrn->virtualY; 02225 xDpi = pScrn->xDpi; 02226 yDpi = pScrn->yDpi; 02227 displayWidth = pScrn->displayWidth; 02228 } 02229 02230 if (pSmi->shadowFB) 02231 { 02232 pSmi->ShadowWidth = width; 02233 pSmi->ShadowHeight = height; 02234 pSmi->ShadowWidthBytes = (width * bytesPerPixel + 15) & ~15; 02235 if (bytesPerPixel == 3) 02236 { 02237 pSmi->ShadowPitch = ((height * 3) << 16) 02238 | pSmi->ShadowWidthBytes; 02239 } 02240 else 02241 { 02242 pSmi->ShadowPitch = (height << 16) 02243 | (pSmi->ShadowWidthBytes / bytesPerPixel); 02244 } 02245 02246 pSmi->saveBufferSize = pSmi->ShadowWidthBytes * pSmi->ShadowHeight; 02247 pSmi->FBReserved -= pSmi->saveBufferSize; 02248 pSmi->FBReserved &= ~0x15; 02249 WRITE_VPR(pSmi, 0x0C, (pSmi->FBOffset = pSmi->FBReserved) >> 3); 02250 02251 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Shadow: width=%d height=%d " 02252 "offset=0x%08X pitch=0x%08X\n", pSmi->ShadowWidth, 02253 pSmi->ShadowHeight, pSmi->FBOffset, pSmi->ShadowPitch); 02254 } 02255 else 02256 { 02257 pSmi->FBOffset = 0; 02258 } 02259 02260 /* 02261 * Call the framebuffer layer's ScreenInit function, and fill in other 02262 * pScreen fields. 02263 */ 02264 02265 DEBUG((VERBLEV, "\tInitializing FB @ 0x%08X for %dx%d (%d)\n", 02266 pSmi->FBBase, width, height, displayWidth)); 02267 switch (pScrn->bitsPerPixel) 02268 { 02269 #ifdef USE_FB 02270 case 8: 02271 case 16: 02272 case 24: 02273 ret = fbScreenInit(pScreen, pSmi->FBBase, width, height, xDpi, 02274 yDpi, displayWidth,pScrn->bitsPerPixel); 02275 break; 02276 #else 02277 case 8: 02278 ret = cfbScreenInit(pScreen, pSmi->FBBase, width, height, xDpi, 02279 yDpi, displayWidth); 02280 break; 02281 02282 case 16: 02283 ret = cfb16ScreenInit(pScreen, pSmi->FBBase, width, height, xDpi, 02284 yDpi, displayWidth); 02285 break; 02286 02287 case 24: 02288 ret = cfb24ScreenInit(pScreen, pSmi->FBBase, width, height, xDpi, 02289 yDpi, displayWidth); 02290 break; 02291 #endif 02292 default: 02293 xf86DrvMsg(scrnIndex, X_ERROR, "Internal error: invalid bpp (%d) " 02294 "in SMI_InternalScreenInit\n", pScrn->bitsPerPixel); 02295 LEAVE_PROC("SMI_InternalScreenInit"); 02296 return(FALSE); 02297 } 02298 02299 LEAVE_PROC("SMI_InternalScreenInit"); 02300 return(ret); 02301 } 02302 02303 /* Checks if a mode is suitable for the selected configuration. */ 02304 static ModeStatus 02305 SMI_ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 02306 { 02307 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 02308 SMIPtr pSmi = SMIPTR(pScrn); 02309 float refresh; 02310 02311 ENTER_PROC("SMI_ValidMode"); 02312 refresh = (mode->VRefresh > 0) ? mode->VRefresh 02313 : mode->Clock * 1000.0 / mode->VTotal / mode->HTotal; 02314 xf86DrvMsg(scrnIndex, X_INFO, "Mode: %dx%d %d-bpp, %fHz\n", mode->HDisplay, 02315 mode->VDisplay, pScrn->bitsPerPixel, refresh); 02316 02317 if (pSmi->shadowFB) 02318 { 02319 int mem; 02320 02321 if (pScrn->bitsPerPixel == 24) 02322 { 02323 LEAVE_PROC("SMI_ValidMode"); 02324 return(MODE_BAD); 02325 } 02326 02327 mem = (pScrn->virtualX * pScrn->bitsPerPixel / 8 + 15) & ~15; 02328 mem *= pScrn->virtualY * 2; 02329 02330 if (mem > pSmi->FBReserved) /* PDR#1074 */ 02331 { 02332 LEAVE_PROC("SMI_ValidMode"); 02333 return(MODE_MEM); 02334 } 02335 } 02336 02337 if (!pSmi->useBIOS || pSmi->lcd) 02338 { 02339 #if 1 /* PDR#983 */ 02340 if (pSmi->zoomOnLCD) 02341 { 02342 if ( (mode->HDisplay > pSmi->lcdWidth) 02343 || (mode->VDisplay > pSmi->lcdHeight) 02344 ) 02345 { 02346 LEAVE_PROC("SMI_ValidMode"); 02347 return(MODE_PANEL); 02348 } 02349 } 02350 else 02351 #endif 02352 { 02353 if ( (mode->HDisplay != pSmi->lcdWidth) 02354 || (mode->VDisplay != pSmi->lcdHeight) 02355 ) 02356 { 02357 LEAVE_PROC("SMI_ValidMode"); 02358 return(MODE_PANEL); 02359 } 02360 } 02361 02362 } 02363 02364 #if 1 /* PDR#944 */ 02365 if (pSmi->rotate) 02366 { 02367 if ( (mode->HDisplay != pSmi->lcdWidth) 02368 || (mode->VDisplay != pSmi->lcdHeight) 02369 ) 02370 { 02371 LEAVE_PROC("SMI_ValidMode"); 02372 return(MODE_PANEL); 02373 } 02374 } 02375 #endif 02376 02377 LEAVE_PROC("SMI_ValidMode"); 02378 return(MODE_OK); 02379 } 02380 02381 static Bool 02382 SMI_ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 02383 { 02384 vgaHWPtr hwp = VGAHWPTR(pScrn); 02385 SMIPtr pSmi = SMIPTR(pScrn); 02386 unsigned char tmp; 02387 int panelIndex, modeIndex, i; 02388 int xyAddress[] = { 320, 400, 512, 640, 800, 1024, 1280, 1600, 2048 }; 02389 CARD32 DEDataFormat = 0; 02390 02391 /* Store values to current mode register structs */ 02392 SMIRegPtr new = &pSmi->ModeReg; 02393 vgaRegPtr vganew = &hwp->ModeReg; 02394 02395 ENTER_PROC("SMI_ModeInit"); 02396 02397 if(!vgaHWInit(pScrn, mode)) 02398 { 02399 LEAVE_PROC("SMI_ModeInit"); 02400 return(FALSE); 02401 } 02402 02403 if (pSmi->rotate) 02404 { 02405 pSmi->width = pScrn->virtualY; 02406 pSmi->height = pScrn->virtualX; 02407 } 02408 else 02409 { 02410 pSmi->width = pScrn->virtualX; 02411 pSmi->height = pScrn->virtualY; 02412 } 02413 pSmi->Bpp = pScrn->bitsPerPixel / 8; 02414 02415 outb(VGA_SEQ_INDEX, 0x17); 02416 tmp = inb(VGA_SEQ_DATA); 02417 if (pSmi->pci_burst) 02418 { 02419 new->SR17 = tmp | 0x20; 02420 } 02421 else 02422 { 02423 new->SR17 = tmp & ~0x20; 02424 } 02425 02426 outb(VGA_SEQ_INDEX, 0x18); 02427 new->SR18 = inb(VGA_SEQ_DATA) | 0x11; 02428 02429 outb(VGA_SEQ_INDEX, 0x21); 02430 new->SR21 = inb(VGA_SEQ_DATA) & ~0x03; 02431 02432 outb(VGA_SEQ_INDEX, 0x31); 02433 new->SR31 = inb(VGA_SEQ_DATA) & ~0xC0; 02434 02435 outb(VGA_SEQ_INDEX, 0x32); 02436 new->SR32 = inb(VGA_SEQ_DATA) & ~0x07; 02437 if (SMI_LYNXM_SERIES(pSmi->Chipset)) 02438 { 02439 new->SR32 |= 0x04; 02440 } 02441 02442 new->SRA0 = new->CR33 = new->CR3A = 0x00; 02443 02444 if (pSmi->lcdWidth == 640) 02445 { 02446 panelIndex = 0; 02447 } 02448 else if (pSmi->lcdWidth == 800) 02449 { 02450 panelIndex = 1; 02451 } 02452 else 02453 { 02454 panelIndex = 2; 02455 } 02456 02457 if (mode->HDisplay == 640) 02458 { 02459 modeIndex = 0; 02460 } 02461 else if (mode->HDisplay == 800) 02462 { 02463 modeIndex = 1; 02464 } 02465 else 02466 { 02467 modeIndex = 2; 02468 } 02469 02470 if (SMI_LYNXM_SERIES(pSmi->Chipset)) 02471 { 02472 static unsigned char PanelTable[3][14] = 02473 { 02474 { 0x5F, 0x4F, 0x00, 0x52, 0x1E, 0x0B, 0xDF, 0x00, 0xE9, 0x0B, 0x2E, 02475 0x00, 0x4F, 0xDF }, 02476 { 0x7F, 0x63, 0x00, 0x69, 0x19, 0x72, 0x57, 0x00, 0x58, 0x0C, 0xA2, 02477 0x20, 0x4F, 0xDF }, 02478 { 0xA3, 0x7F, 0x00, 0x83, 0x14, 0x24, 0xFF, 0x00, 0x02, 0x08, 0xA7, 02479 0xE0, 0x4F, 0xDF }, 02480 }; 02481 02482 for (i = 0; i < 14; i++) 02483 { 02484 new->CR40[i] = PanelTable[panelIndex][i]; 02485 } 02486 new->CR90[14] = 0x03; 02487 new->CR90[15] = 0x00; 02488 if (mode->VDisplay < pSmi->lcdHeight) 02489 { 02490 new->CRA0[6] = (pSmi->lcdHeight - mode->VDisplay) / 8; 02491 } 02492 else 02493 { 02494 new->CRA0[6] = 0; 02495 } 02496 02497 if (mode->HDisplay < pSmi->lcdWidth) 02498 { 02499 new->CRA0[7] = (pSmi->lcdWidth - mode->HDisplay) / 16; 02500 } 02501 else 02502 { 02503 new->CRA0[7] = 0; 02504 } 02505 } 02506 else 02507 { 02508 static unsigned char PanelTable[3][3][14] = 02509 { 02510 { /* 640x480 panel */ 02511 { 0x5F, 0x4F, 0x00, 0x53, 0x00, 0x0B, 0xDF, 0x00, 0xEA, 0x0C, 02512 0x2E, 0x00, 0x4F, 0xDF }, 02513 { 0x5F, 0x4F, 0x00, 0x53, 0x00, 0x0B, 0xDF, 0x00, 0xEA, 0x0C, 02514 0x2E, 0x00, 0x4F, 0xDF }, 02515 { 0x5F, 0x4F, 0x00, 0x53, 0x00, 0x0B, 0xDF, 0x00, 0xEA, 0x0C, 02516 0x2E, 0x00, 0x4F, 0xDF }, 02517 }, 02518 { /* 800x600 panel */ 02519 { 0x7F, 0x59, 0x19, 0x5E, 0x8E, 0x72, 0x1C, 0x37, 0x1D, 0x00, 02520 0xA2, 0x20, 0x4F, 0xDF }, 02521 { 0x7F, 0x63, 0x00, 0x68, 0x18, 0x72, 0x58, 0x00, 0x59, 0x0C, 02522 0xE0, 0x20, 0x63, 0x57 }, 02523 { 0x7F, 0x63, 0x00, 0x68, 0x18, 0x72, 0x58, 0x00, 0x59, 0x0C, 02524 0xE0, 0x20, 0x63, 0x57 }, 02525 }, 02526 { /* 1024x768 panel */ 02527 { 0xA3, 0x67, 0x0F, 0x6D, 0x1D, 0x24, 0x70, 0x95, 0x72, 0x07, 02528 0xA3, 0x20, 0x4F, 0xDF }, 02529 { 0xA3, 0x71, 0x19, 0x77, 0x07, 0x24, 0xAC, 0xD1, 0xAE, 0x03, 02530 0xE1, 0x20, 0x63, 0x57 }, 02531 { 0xA3, 0x7F, 0x00, 0x85, 0x15, 0x24, 0xFF, 0x00, 0x01, 0x07, 02532 0xE5, 0x20, 0x7F, 0xFF }, 02533 }, 02534 }; 02535 02536 for (i = 0; i < 14; i++) 02537 { 02538 new->CR40[i] = PanelTable[panelIndex][modeIndex][i]; 02539 } 02540 } 02541 02542 02543 /* CZ 2.11.2001: for gamma correction (TODO: other chipsets?) */ 02544 new->CCR66 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66); 02545 if (pSmi->Chipset == SMI_LYNX3DM) { 02546 switch (pScrn->bitsPerPixel) { 02547 case 8: 02548 new->CCR66 = (new->CCR66 & 0xF3) | 0x00; /* 6 bits-RAM */ 02549 break; 02550 case 16: 02551 new->CCR66 = (new->CCR66 & 0xF3) | 0x00; /* 6 bits-RAM */ 02552 /* no Gamma correction in 16 Bit mode (s. Release.txt 1.3.1) */ 02553 break; 02554 case 24: 02555 case 32: 02556 new->CCR66 = (new->CCR66 & 0xF3) | 0x04; /* Gamma correct ON */ 02557 break; 02558 default: 02559 LEAVE_PROC("SMI_ModeInit"); 02560 return(FALSE); 02561 } 02562 } 02563 /* end CZ */ 02564 02565 outb(VGA_SEQ_INDEX, 0x30); 02566 if (inb(VGA_SEQ_DATA) & 0x01) 02567 { 02568 new->SR21 = 0x00; 02569 } 02570 02571 if (pSmi->MCLK > 0) 02572 { 02573 SMI_CommonCalcClock(pScrn->scrnIndex,pSmi->MCLK, 02574 1, 1, 31, 0, 2, pSmi->minClock, 02575 pSmi->maxClock, &new->SR6A, &new->SR6B); 02576 } 02577 else 02578 { 02579 new->SR6B = 0xFF; 02580 } 02581 02582 if ((mode->HDisplay == 640) && SMI_LYNXM_SERIES(pSmi->Chipset)) 02583 { 02584 vganew->MiscOutReg &= ~0x0C; 02585 } 02586 else 02587 { 02588 vganew->MiscOutReg |= 0x0C; 02589 } 02590 vganew->MiscOutReg |= 0xE0; 02591 if (mode->HDisplay == 800) 02592 { 02593 vganew->MiscOutReg &= ~0xC0; 02594 } 02595 if ((mode->HDisplay == 1024) && SMI_LYNXM_SERIES(pSmi->Chipset)) 02596 { 02597 vganew->MiscOutReg &= ~0xC0; 02598 } 02599 02600 /* Set DPR registers */ 02601 pSmi->Stride = (pSmi->width * pSmi->Bpp + 15) & ~15; 02602 switch (pScrn->bitsPerPixel) 02603 { 02604 case 8: 02605 DEDataFormat = 0x00000000; 02606 break; 02607 02608 case 16: 02609 pSmi->Stride >>= 1; 02610 DEDataFormat = 0x00100000; 02611 break; 02612 02613 case 24: 02614 DEDataFormat = 0x00300000; 02615 break; 02616 02617 case 32: 02618 pSmi->Stride >>= 2; 02619 DEDataFormat = 0x00200000; 02620 break; 02621 } 02622 for (i = 0; i < sizeof(xyAddress) / sizeof(xyAddress[0]); i++) 02623 { 02624 if (pSmi->rotate) 02625 { 02626 if (xyAddress[i] == pSmi->height) 02627 { 02628 DEDataFormat |= i << 16; 02629 break; 02630 } 02631 } 02632 else 02633 { 02634 if (xyAddress[i] == pSmi->width) 02635 { 02636 DEDataFormat |= i << 16; 02637 break; 02638 } 02639 } 02640 } 02641 new->DPR10 = (pSmi->Stride << 16) | pSmi->Stride; 02642 new->DPR1C = DEDataFormat; 02643 new->DPR20 = 0; 02644 new->DPR24 = 0xFFFFFFFF; 02645 new->DPR28 = 0xFFFFFFFF; 02646 new->DPR2C = 0; 02647 new->DPR30 = 0; 02648 new->DPR3C = (pSmi->Stride << 16) | pSmi->Stride; 02649 new->DPR40 = 0; 02650 new->DPR44 = 0; 02651 02652 /* Set VPR registers */ 02653 switch (pScrn->bitsPerPixel) 02654 { 02655 case 8: 02656 new->VPR00 = 0x00000000; 02657 break; 02658 02659 case 16: 02660 new->VPR00 = 0x00020000; 02661 break; 02662 02663 case 24: 02664 new->VPR00 = 0x00040000; 02665 break; 02666 02667 case 32: 02668 new->VPR00 = 0x00030000; 02669 break; 02670 } 02671 new->VPR0C = pSmi->FBOffset >> 3; 02672 if (pSmi->rotate) 02673 { 02674 new->VPR10 = ((((min(pSmi->lcdWidth, pSmi->height) * pSmi->Bpp) >> 3) 02675 + 2) << 16) | ((pSmi->height * pSmi->Bpp) >> 3); 02676 } 02677 else 02678 { 02679 new->VPR10 = ((((min(pSmi->lcdWidth, pSmi->width) * pSmi->Bpp) >> 3) 02680 + 2) << 16) | ((pSmi->width * pSmi->Bpp) >> 3); 02681 } 02682 02683 /* Set CPR registers */ 02684 new->CPR00 = 0x00000000; 02685 02686 pScrn->vtSema = TRUE; 02687 02688 /* Find the INT 10 mode number */ 02689 { 02690 static struct 02691 { 02692 int x, y, bpp; 02693 CARD16 mode; 02694 02695 } modeTable[] = 02696 { 02697 { 640, 480, 8, 0x50 }, 02698 { 640, 480, 16, 0x52 }, 02699 { 640, 480, 24, 0x53 }, 02700 { 640, 480, 32, 0x54 }, 02701 { 800, 600, 8, 0x55 }, 02702 { 800, 600, 16, 0x57 }, 02703 { 800, 600, 24, 0x58 }, 02704 { 800, 600, 32, 0x59 }, 02705 { 1024, 768, 8, 0x60 }, 02706 { 1024, 768, 16, 0x62 }, 02707 { 1024, 768, 24, 0x63 }, 02708 { 1024, 768, 32, 0x64 }, 02709 { 1280, 1024, 8, 0x65 }, 02710 { 1280, 1024, 16, 0x67 }, 02711 { 1280, 1024, 24, 0x68 }, 02712 { 1280, 1024, 32, 0x69 }, 02713 }; 02714 02715 new->mode = 0; 02716 for (i = 0; i < sizeof(modeTable) / sizeof(modeTable[0]); i++) 02717 { 02718 if ( (modeTable[i].x == mode->HDisplay) 02719 && (modeTable[i].y == mode->VDisplay) 02720 && (modeTable[i].bpp == pScrn->bitsPerPixel) 02721 ) 02722 { 02723 new->mode = modeTable[i].mode; 02724 break; 02725 } 02726 } 02727 } 02728 02729 /* Zero the font memory */ 02730 memset(new->smiFont, 0, sizeof(new->smiFont)); 02731 02732 /* Write the mode registers to hardware */ 02733 SMI_WriteMode(pScrn, vganew, new); 02734 02735 /* Adjust the viewport */ 02736 SMI_AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 02737 02738 LEAVE_PROC("SMI_ModeInit"); 02739 return(TRUE); 02740 } 02741 02742 /* 02743 * This is called at the end of each server generation. It restores the 02744 * original (text) mode. It should also unmap the video memory, and free any 02745 * per-generation data allocated by the driver. It should finish by unwrapping 02746 * and calling the saved CloseScreen function. 02747 */ 02748 02749 static Bool 02750 SMI_CloseScreen(int scrnIndex, ScreenPtr pScreen) 02751 { 02752 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 02753 vgaHWPtr hwp = VGAHWPTR(pScrn); 02754 SMIPtr pSmi = SMIPTR(pScrn); 02755 vgaRegPtr vgaSavePtr = &hwp->SavedReg; 02756 SMIRegPtr SMISavePtr = &pSmi->SavedReg; 02757 Bool ret; 02758 02759 ENTER_PROC("SMI_CloseScreen"); 02760 02761 if (pScrn->vtSema) 02762 { 02763 SMI_WriteMode(pScrn, vgaSavePtr, SMISavePtr); 02764 vgaHWLock(hwp); 02765 SMI_UnmapMem(pScrn); 02766 } 02767 02768 if (pSmi->AccelInfoRec != NULL) 02769 { 02770 XAADestroyInfoRec(pSmi->AccelInfoRec); 02771 } 02772 if (pSmi->CursorInfoRec != NULL) 02773 { 02774 xf86DestroyCursorInfoRec(pSmi->CursorInfoRec); 02775 } 02776 if (pSmi->DGAModes != NULL) 02777 { 02778 xfree(pSmi->DGAModes); 02779 } 02780 if (pSmi->pVbe != NULL) 02781 { 02782 vbeFree(pSmi->pVbe); 02783 pSmi->pVbe = NULL; 02784 } 02785 #ifdef XvExtension 02786 if (pSmi->ptrAdaptor != NULL) 02787 { 02788 xfree(pSmi->ptrAdaptor); 02789 } 02790 if (pSmi->BlockHandler != NULL) 02791 { 02792 pScreen->BlockHandler = pSmi->BlockHandler; 02793 } 02794 #endif 02795 if (pSmi->I2C != NULL) 02796 { 02797 xf86DestroyI2CBusRec(pSmi->I2C, FALSE, TRUE); 02798 xfree(pSmi->I2C); 02799 pSmi->I2C = NULL; 02800 } 02801 /* #670 */ 02802 if (pSmi->pSaveBuffer) 02803 { 02804 xfree(pSmi->pSaveBuffer); 02805 } 02806 /* #920 */ 02807 if (pSmi->paletteBuffer) 02808 { 02809 xfree(pSmi->paletteBuffer); 02810 } 02811 02812 pScrn->vtSema = FALSE; 02813 pScreen->CloseScreen = pSmi->CloseScreen; 02814 ret = (*pScreen->CloseScreen)(scrnIndex, pScreen); 02815 02816 LEAVE_PROC("SMI_CloseScreen"); 02817 return(ret); 02818 } 02819 02820 static void 02821 SMI_FreeScreen(int scrnIndex, int flags) 02822 { 02823 SMI_FreeRec(xf86Screens[scrnIndex]); 02824 } 02825 02826 static Bool 02827 SMI_SaveScreen(ScreenPtr pScreen, int mode) 02828 { 02829 Bool ret; 02830 02831 ENTER_PROC("SMI_SaveScreen"); 02832 02833 ret = vgaHWSaveScreen(pScreen, mode); 02834 02835 LEAVE_PROC("SMI_SaveScreen"); 02836 return(ret); 02837 } 02838 02839 void 02840 SMI_AdjustFrame(int scrnIndex, int x, int y, int flags) 02841 { 02842 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 02843 SMIPtr pSmi = SMIPTR(pScrn); 02844 CARD32 Base; 02845 02846 ENTER_PROC("SMI_AdjustFrame"); 02847 02848 if (pSmi->ShowCache && y) 02849 { 02850 y += pScrn->virtualY - 1; 02851 } 02852 02853 Base = pSmi->FBOffset + (x + y * pScrn->virtualX) * pSmi->Bpp; 02854 if (SMI_LYNX3D_SERIES(pSmi->Chipset)) 02855 { 02856 Base = (Base + 15) & ~15; 02857 #if 1 /* PDR#1058 */ 02858 while ((Base % pSmi->Bpp) > 0) 02859 { 02860 Base -= 16; 02861 } 02862 #endif 02863 } 02864 else 02865 { 02866 Base = (Base + 7) & ~7; 02867 #if 1 /* PDR#1058 */ 02868 while ((Base % pSmi->Bpp) > 0) 02869 { 02870 Base -= 8; 02871 } 02872 #endif 02873 } 02874 02875 WRITE_VPR(pSmi, 0x0C, Base >> 3); 02876 02877 LEAVE_PROC("SMI_AdjustFrame"); 02878 } 02879 02880 Bool 02881 SMI_SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 02882 { 02883 Bool ret; 02884 02885 ENTER_PROC("SMI_SwitchMode"); 02886 02887 ret = SMI_ModeInit(xf86Screens[scrnIndex], mode); 02888 02889 LEAVE_PROC("SMI_SwitchMode"); 02890 return(ret); 02891 } 02892 02893 void 02894 SMI_LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors, 02895 VisualPtr pVisual) 02896 { 02897 SMIPtr pSmi = SMIPTR(pScrn); 02898 int i; 02899 02900 ENTER_PROC("SMI_LoadPalette"); 02901 02902 for(i = 0; i < numColors; i++) 02903 { 02904 DEBUG((VERBLEV, "pal[%d] = %d %d %d\n", indicies[i], 02905 colors[indicies[i]].red, colors[indicies[i]].green, colors[indicies[i]].blue)); 02906 VGAOUT8(pSmi, VGA_DAC_WRITE_ADDR, indicies[i]); 02907 VGAOUT8(pSmi, VGA_DAC_DATA, colors[indicies[i]].red); 02908 VGAOUT8(pSmi, VGA_DAC_DATA, colors[indicies[i]].green); 02909 VGAOUT8(pSmi, VGA_DAC_DATA, colors[indicies[i]].blue); 02910 } 02911 02912 LEAVE_PROC("SMI_LoadPalette"); 02913 } 02914 02915 static void 02916 SMI_DisableVideo(ScrnInfoPtr pScrn) 02917 { 02918 SMIPtr pSmi = SMIPTR(pScrn); 02919 CARD8 tmp; 02920 02921 if (!(tmp = VGAIN8(pSmi, VGA_DAC_MASK))) 02922 return; 02923 pSmi->DACmask = tmp; 02924 VGAOUT8(pSmi, VGA_DAC_MASK, 0); 02925 } 02926 02927 static void 02928 SMI_EnableVideo(ScrnInfoPtr pScrn) 02929 { 02930 SMIPtr pSmi = SMIPTR(pScrn); 02931 02932 VGAOUT8(pSmi, VGA_DAC_MASK, pSmi->DACmask); 02933 } 02934 02935 02936 void 02937 SMI_EnableMmio(ScrnInfoPtr pScrn) 02938 { 02939 vgaHWPtr hwp = VGAHWPTR(pScrn); 02940 SMIPtr pSmi = SMIPTR(pScrn); 02941 CARD8 tmp; 02942 02943 ENTER_PROC("SMI_EnableMmio"); 02944 02945 /* 02946 * Enable chipset (seen on uninitialized secondary cards) might not be 02947 * needed once we use the VGA softbooter 02948 */ 02949 vgaHWSetStdFuncs(hwp); 02950 02951 /* Enable linear mode */ 02952 outb(VGA_SEQ_INDEX, 0x18); 02953 tmp = inb(VGA_SEQ_DATA); 02954 pSmi->SR18Value = tmp; /* PDR#521 */ 02955 outb(VGA_SEQ_DATA, tmp | 0x11); 02956 02957 /* Enable 2D/3D Engine and Video Processor */ 02958 outb(VGA_SEQ_INDEX, 0x21); 02959 tmp = inb(VGA_SEQ_DATA); 02960 pSmi->SR21Value = tmp; /* PDR#521 */ 02961 outb(VGA_SEQ_DATA, tmp & ~0x03); 02962 02963 LEAVE_PROC("SMI_EnableMmio"); 02964 } 02965 02966 void 02967 SMI_DisableMmio(ScrnInfoPtr pScrn) 02968 { 02969 vgaHWPtr hwp = VGAHWPTR(pScrn); 02970 SMIPtr pSmi = SMIPTR(pScrn); 02971 02972 ENTER_PROC("SMI_DisableMmio"); 02973 02974 vgaHWSetStdFuncs(hwp); 02975 02976 /* Disable 2D/3D Engine and Video Processor */ 02977 outb(VGA_SEQ_INDEX, 0x21); 02978 outb(VGA_SEQ_DATA, pSmi->SR21Value); /* PDR#521 */ 02979 02980 /* Disable linear mode */ 02981 outb(VGA_SEQ_INDEX, 0x18); 02982 outb(VGA_SEQ_DATA, pSmi->SR18Value); /* PDR#521 */ 02983 02984 LEAVE_PROC("SMI_DisableMmio"); 02985 } 02986 02987 /* This function is used to debug, it prints out the contents of Lynx regs */ 02988 static void 02989 SMI_PrintRegs(ScrnInfoPtr pScrn) 02990 { 02991 unsigned char i, tmp; 02992 vgaHWPtr hwp = VGAHWPTR(pScrn); 02993 SMIPtr pSmi = SMIPTR(pScrn); 02994 int vgaCRIndex = hwp->IOBase + VGA_CRTC_INDEX_OFFSET; 02995 int vgaCRReg = hwp->IOBase + VGA_CRTC_DATA_OFFSET; 02996 int vgaStatus = hwp->IOBase + VGA_IN_STAT_1_OFFSET; 02997 02998 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 02999 "START register dump ------------------\n"); 03000 03001 xf86ErrorFVerb(VERBLEV, "MISCELLANEOUS OUTPUT\n %02X\n", 03002 VGAIN8(pSmi, VGA_MISC_OUT_R)); 03003 03004 xf86ErrorFVerb(VERBLEV, "\nSEQUENCER\n" 03005 " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 03006 for (i = 0x00; i <= 0xAF; i++) 03007 { 03008 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 03009 if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 03010 xf86ErrorFVerb(VERBLEV, "%02X ", 03011 VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, i)); 03012 } 03013 03014 xf86ErrorFVerb(VERBLEV, "\n\nCRT CONTROLLER\n" 03015 " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 03016 for (i = 0x00; i <= 0xAD; i++) 03017 { 03018 if (i == 0x20) i = 0x30; 03019 if (i == 0x50) i = 0x90; 03020 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 03021 if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 03022 xf86ErrorFVerb(VERBLEV, "%02X ", 03023 VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRReg, i)); 03024 } 03025 03026 xf86ErrorFVerb(VERBLEV, "\n\nGRAPHICS CONTROLLER\n" 03027 " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 03028 for (i = 0x00; i <= 0x08; i++) 03029 { 03030 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 03031 if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 03032 xf86ErrorFVerb(VERBLEV, "%02X ", 03033 VGAIN8_INDEX(pSmi, VGA_GRAPH_INDEX, VGA_GRAPH_DATA, i)); 03034 } 03035 03036 xf86ErrorFVerb(VERBLEV, "\n\nATTRIBUTE 0CONTROLLER\n" 03037 " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 03038 for (i = 0x00; i <= 0x14; i++) 03039 { 03040 tmp = VGAIN8(pSmi, vgaStatus); 03041 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 03042 if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 03043 xf86ErrorFVerb(VERBLEV, "%02X ", 03044 VGAIN8_INDEX(pSmi, VGA_ATTR_INDEX, VGA_ATTR_DATA_R, i)); 03045 } 03046 tmp = VGAIN8(pSmi, vgaStatus); 03047 VGAOUT8(pSmi, VGA_ATTR_INDEX, 0x20); 03048 03049 xf86ErrorFVerb(VERBLEV, "\n\nDPR x0 x4 x8 xC"); 03050 for (i = 0x00; i <= 0x44; i += 4) 03051 { 03052 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 03053 xf86ErrorFVerb(VERBLEV, " %08X", READ_DPR(pSmi, i)); 03054 } 03055 03056 xf86ErrorFVerb(VERBLEV, "\n\nVPR x0 x4 x8 xC"); 03057 for (i = 0x00; i <= 0x60; i += 4) 03058 { 03059 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 03060 xf86ErrorFVerb(VERBLEV, " %08X", READ_VPR(pSmi, i)); 03061 } 03062 03063 xf86ErrorFVerb(VERBLEV, "\n\nCPR x0 x4 x8 xC"); 03064 for (i = 0x00; i <= 0x18; i += 4) 03065 { 03066 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 03067 xf86ErrorFVerb(VERBLEV, " %08X", READ_CPR(pSmi, i)); 03068 } 03069 03070 xf86ErrorFVerb(VERBLEV, "\n\n"); 03071 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 03072 "END register dump --------------------\n"); 03073 } 03074 03075 /* 03076 * SMI_DisplayPowerManagementSet -- Sets VESA Display Power Management 03077 * Signaling (DPMS) Mode. 03078 */ 03079 static void 03080 SMI_DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 03081 int flags) 03082 { 03083 vgaHWPtr hwp = VGAHWPTR(pScrn); 03084 SMIPtr pSmi = SMIPTR(pScrn); 03085 CARD8 SR01, SR20, SR21, SR22, SR23, SR24, SR31, SR34; 03086 03087 ENTER_PROC("SMI_DisplayPowerManagementSet"); 03088 03089 /* If we already are in the requested DPMS mode, just return */ 03090 if (pSmi->CurrentDPMS == PowerManagementMode) 03091 { 03092 LEAVE_PROC("SMI_DisplayPowerManagementSet"); 03093 return; 03094 } 03095 03096 #if 1 /* PDR#735 */ 03097 if (pSmi->pVbe->pInt10 != NULL) 03098 { 03099 pSmi->pVbe->pInt10->ax = 0x4F10; 03100 switch (PowerManagementMode) 03101 { 03102 case DPMSModeOn: 03103 pSmi->pVbe->pInt10->bx = 0x0001; 03104 break; 03105 03106 case DPMSModeStandby: 03107 pSmi->pVbe->pInt10->bx = 0x0101; 03108 break; 03109 03110 case DPMSModeSuspend: 03111 pSmi->pVbe->pInt10->bx = 0x0201; 03112 break; 03113 03114 case DPMSModeOff: 03115 pSmi->pVbe->pInt10->bx = 0x0401; 03116 break; 03117 } 03118 pSmi->pVbe->pInt10->cx = 0x0000; 03119 pSmi->pVbe->pInt10->num = 0x10; 03120 xf86ExecX86int10(pSmi->pVbe->pInt10); 03121 if (pSmi->pVbe->pInt10->ax == 0x004F) 03122 { 03123 pSmi->CurrentDPMS = PowerManagementMode; 03124 #if 1 /* PDR#835 */ 03125 if (PowerManagementMode == DPMSModeOn) 03126 { 03127 SR01 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01); 03128 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01, 03129 SR01 & ~0x20); 03130 } 03131 #endif 03132 LEAVE_PROC("SMI_DisplayPowerManagementSet"); 03133 return; 03134 } 03135 } 03136 #endif 03137 03138 /* Save the current SR registers */ 03139 if (pSmi->CurrentDPMS == DPMSModeOn) 03140 { 03141 pSmi->DPMS_SR20 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20); 03142 pSmi->DPMS_SR21 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 03143 pSmi->DPMS_SR31 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31); 03144 pSmi->DPMS_SR34 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x34); 03145 } 03146 03147 /* Read the required SR registers for the DPMS handler */ 03148 SR01 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01); 03149 SR20 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20); 03150 SR21 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 03151 SR22 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22); 03152 SR23 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23); 03153 SR24 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24); 03154 SR31 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31); 03155 SR34 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x34); 03156 03157 switch (PowerManagementMode) 03158 { 03159 case DPMSModeOn: 03160 /* Screen On: HSync: On, VSync : On */ 03161 SR01 &= ~0x20; 03162 SR20 = pSmi->DPMS_SR20; 03163 SR21 = pSmi->DPMS_SR21; 03164 SR22 &= ~0x30; 03165 SR23 &= ~0xC0; 03166 SR24 |= 0x01; 03167 SR31 = pSmi->DPMS_SR31; 03168 SR34 = pSmi->DPMS_SR34; 03169 break; 03170 03171 case DPMSModeStandby: 03172 /* Screen: Off; HSync: Off, VSync: On */ 03173 SR01 |= 0x20; 03174 SR20 = (SR20 & ~0xB0) | 0x10; 03175 SR21 |= 0x88; 03176 SR22 = (SR22 & ~0x30) | 0x10; 03177 SR23 = (SR23 & ~0x07) | 0xD8; 03178 SR24 &= ~0x01; 03179 SR31 = (SR31 & ~0x07) | 0x00; 03180 SR34 |= 0x80; 03181 break; 03182 03183 case DPMSModeSuspend: 03184 /* Screen: Off; HSync: On, VSync: Off */ 03185 SR01 |= 0x20; 03186 SR20 = (SR20 & ~0xB0) | 0x10; 03187 SR21 |= 0x88; 03188 SR22 = (SR22 & ~0x30) | 0x20; 03189 SR23 = (SR23 & ~0x07) | 0xD8; 03190 SR24 &= ~0x01; 03191 SR31 = (SR31 & ~0x07) | 0x00; 03192 SR34 |= 0x80; 03193 break; 03194 03195 case DPMSModeOff: 03196 /* Screen: Off; HSync: Off, VSync: Off */ 03197 SR01 |= 0x20; 03198 SR20 = (SR20 & ~0xB0) | 0x10; 03199 SR21 |= 0x88; 03200 SR22 = (SR22 & ~0x30) | 0x30; 03201 SR23 = (SR23 & ~0x07) | 0xD8; 03202 SR24 &= ~0x01; 03203 SR31 = (SR31 & ~0x07) | 0x00; 03204 SR34 |= 0x80; 03205 break; 03206 03207 default: 03208 xf86ErrorFVerb(VERBLEV, "Invalid PowerManagementMode %d passed to " 03209 "SMI_DisplayPowerManagementSet\n", PowerManagementMode); 03210 LEAVE_PROC("SMI_DisplayPowerManagementSet"); 03211 return; 03212 } 03213 03214 /* Wait for vertical retrace */ 03215 while (hwp->readST01(hwp) & 0x8) ; 03216 while (!(hwp->readST01(hwp) & 0x8)) ; 03217 03218 /* Write the registers */ 03219 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01, SR01); 03220 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x34, SR34); 03221 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, SR31); 03222 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20, SR20); 03223 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, SR22); 03224 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23, SR23); 03225 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, SR21); 03226 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24, SR24); 03227 03228 /* Save the current power state */ 03229 pSmi->CurrentDPMS = PowerManagementMode; 03230 03231 LEAVE_PROC("SMI_DisplayPowerManagementSet"); 03232 } 03233 03234 static void 03235 SMI_ProbeDDC(ScrnInfoPtr pScrn, int index) 03236 { 03237 vbeInfoPtr pVbe; 03238 if (xf86LoadSubModule(pScrn, "vbe")) 03239 { 03240 pVbe = VBEInit(NULL, index); 03241 ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 03242 vbeFree(pVbe); 03243 } 03244 } 03245 03246 static unsigned int 03247 SMI_ddc1Read(ScrnInfoPtr pScrn) 03248 { 03249 register vgaHWPtr hwp = VGAHWPTR(pScrn); 03250 SMIPtr pSmi = SMIPTR(pScrn); 03251 unsigned int ret; 03252 03253 ENTER_PROC("SMI_ddc1Read"); 03254 03255 while (hwp->readST01(hwp) & 0x8) ; 03256 while (!(hwp->readST01(hwp) & 0x8)) ; 03257 03258 ret = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72) & 0x08; 03259 03260 LEAVE_PROC("SMI_ddc1Read"); 03261 return(ret); 03262 } 03263 03264 static Bool 03265 SMI_ddc1(int scrnIndex) 03266 { 03267 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 03268 SMIPtr pSmi = SMIPTR(pScrn); 03269 Bool success = FALSE; 03270 xf86MonPtr pMon; 03271 unsigned char tmp; 03272 03273 ENTER_PROC("SMI_ddc1"); 03274 03275 tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72); 03276 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72, tmp | 0x20); 03277 03278 pMon = xf86PrintEDID(xf86DoEDID_DDC1(scrnIndex, vgaHWddc1SetSpeed, 03279 SMI_ddc1Read)); 03280 if (pMon != NULL) 03281 { 03282 success = TRUE; 03283 } 03284 xf86SetDDCproperties(pScrn, pMon); 03285 03286 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72, tmp); 03287 03288 LEAVE_PROC("SMI_ddc1"); 03289 return(success); 03290 }

Generated on Mon May 10 20:38:13 2004 for XFree86 by doxygen 1.3.7