1/* 2 * Copyright 2010 NVIDIA Corporation 3 * Copyright 1996-1997 David J. McKay 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 20 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 */ 23 24#ifdef HAVE_CONFIG_H 25#include "config.h" 26#endif 27 28/* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen 29 <jpaana@s2.org> */ 30 31#include "nv_include.h" 32 33#include "xf86int10.h" 34#include "vbeModes.h" 35 36const OptionInfoRec * RivaAvailableOptions(int chipid, int busid); 37Bool RivaGetScrnInfoRec(PciChipsets *chips, int chip); 38Bool G80GetScrnInfoRec(PciChipsets *chips, int chip); 39 40/* 41 * Forward definitions for the functions that make up the driver. 42 */ 43/* Mandatory functions */ 44static const OptionInfoRec * NVAvailableOptions(int chipid, int busid); 45static void NVIdentify(int flags); 46#ifdef XSERVER_LIBPCIACCESS 47static Bool NVPciProbe(DriverPtr, int entity, struct pci_device*, intptr_t data); 48#else 49static Bool NVProbe(DriverPtr drv, int flags); 50#endif 51static Bool NVPreInit(ScrnInfoPtr pScrn, int flags); 52static Bool NVScreenInit(SCREEN_INIT_ARGS_DECL); 53static Bool NVEnterVT(VT_FUNC_ARGS_DECL); 54static Bool NVEnterVTFBDev(VT_FUNC_ARGS_DECL); 55static void NVLeaveVT(VT_FUNC_ARGS_DECL); 56static Bool NVCloseScreen(CLOSE_SCREEN_ARGS_DECL); 57static Bool NVSaveScreen(ScreenPtr pScreen, int mode); 58 59/* Optional functions */ 60static void NVFreeScreen(FREE_SCREEN_ARGS_DECL); 61static ModeStatus NVValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, 62 Bool verbose, int flags); 63#ifdef RANDR 64static Bool NVDriverFunc(ScrnInfoPtr pScrnInfo, xorgDriverFuncOp op, 65 pointer data); 66#endif 67 68/* Internally used functions */ 69 70static Bool NVMapMem(ScrnInfoPtr pScrn); 71static Bool NVMapMemFBDev(ScrnInfoPtr pScrn); 72static Bool NVUnmapMem(ScrnInfoPtr pScrn); 73static void NVSave(ScrnInfoPtr pScrn); 74static void NVSaveRestoreVBE(ScrnInfoPtr, vbeSaveRestoreFunction); 75static void NVRestore(ScrnInfoPtr pScrn); 76static Bool NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 77static Bool NVSetModeVBE(ScrnInfoPtr pScrn, DisplayModePtr pMode); 78 79#ifdef XSERVER_LIBPCIACCESS 80/* For now, just match any NVIDIA display device and sort through them in the 81 * probe routine */ 82 83/* 84 * libpciaccess's masks are shifted by 8 bits compared to the ones in xf86Pci.h. 85 */ 86#define LIBPCIACCESS_CLASS_SHIFT (PCI_CLASS_SHIFT - 8) 87#define LIBPCIACCESS_CLASS_MASK (PCI_CLASS_MASK >> 8) 88 89static const struct pci_id_match NVPciIdMatchList[] = { 90 { PCI_VENDOR_NVIDIA, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 91 PCI_CLASS_DISPLAY << LIBPCIACCESS_CLASS_SHIFT, LIBPCIACCESS_CLASS_MASK, 0 }, 92 93 { PCI_VENDOR_NVIDIA_SGS, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 94 PCI_CLASS_DISPLAY << LIBPCIACCESS_CLASS_SHIFT, LIBPCIACCESS_CLASS_MASK, 0 }, 95 96 { 0, 0, 0 } 97}; 98#endif 99 100/* 101 * This contains the functions needed by the server after loading the 102 * driver module. It must be supplied, and gets added the driver list by 103 * the Module Setup function in the dynamic case. In the static case a 104 * reference to this is compiled in, and this requires that the name of 105 * this DriverRec be an upper-case version of the driver name. 106 */ 107 108_X_EXPORT DriverRec NV = { 109 NV_VERSION, 110 NV_DRIVER_NAME, 111 NVIdentify, 112#ifdef XSERVER_LIBPCIACCESS 113 NULL, 114#else 115 NVProbe, 116#endif 117 NVAvailableOptions, 118 NULL, 119 0, 120 NULL, 121#ifdef XSERVER_LIBPCIACCESS 122 NVPciIdMatchList, 123 NVPciProbe, 124#endif 125}; 126 127/* Known cards as of 2010/07/19 */ 128 129static SymTabRec NVKnownChipsets[] = 130{ 131 { 0x12D20018, "RIVA 128" }, 132 133 { 0x10DE0020, "RIVA TNT" }, 134 135 { 0x10DE0028, "RIVA TNT2" }, 136 { 0x10DE002A, "Unknown TNT2" }, 137 { 0x10DE002C, "Vanta" }, 138 { 0x10DE0029, "RIVA TNT2 Ultra" }, 139 { 0x10DE002D, "RIVA TNT2 Model 64" }, 140 141 { 0x10DE00A0, "Aladdin TNT2" }, 142 143 { 0x10DE0100, "GeForce 256" }, 144 { 0x10DE0101, "GeForce DDR" }, 145 { 0x10DE0103, "Quadro" }, 146 147 { 0x10DE0110, "GeForce2 MX/MX 400" }, 148 { 0x10DE0111, "GeForce2 MX 100/200" }, 149 { 0x10DE0112, "GeForce2 Go" }, 150 { 0x10DE0113, "Quadro2 MXR/EX/Go" }, 151 152 { 0x10DE01A0, "GeForce2 Integrated GPU" }, 153 154 { 0x10DE0150, "GeForce2 GTS" }, 155 { 0x10DE0151, "GeForce2 Ti" }, 156 { 0x10DE0152, "GeForce2 Ultra" }, 157 { 0x10DE0153, "Quadro2 Pro" }, 158 159 { 0x10DE0170, "GeForce4 MX 460" }, 160 { 0x10DE0171, "GeForce4 MX 440" }, 161 { 0x10DE0172, "GeForce4 MX 420" }, 162 { 0x10DE0173, "GeForce4 MX 440-SE" }, 163 { 0x10DE0174, "GeForce4 440 Go" }, 164 { 0x10DE0175, "GeForce4 420 Go" }, 165 { 0x10DE0176, "GeForce4 420 Go 32M" }, 166 { 0x10DE0177, "GeForce4 460 Go" }, 167 { 0x10DE0178, "Quadro4 550 XGL" }, 168#if defined(__powerpc__) 169 { 0x10DE0179, "GeForce4 MX (Mac)" }, 170#else 171 { 0x10DE0179, "GeForce4 440 Go 64M" }, 172#endif 173 { 0x10DE017A, "Quadro NVS" }, 174 { 0x10DE017C, "Quadro4 500 GoGL" }, 175 { 0x10DE017D, "GeForce4 410 Go 16M" }, 176 177 { 0x10DE0181, "GeForce4 MX 440 with AGP8X" }, 178 { 0x10DE0182, "GeForce4 MX 440SE with AGP8X" }, 179 { 0x10DE0183, "GeForce4 MX 420 with AGP8X" }, 180 { 0x10DE0185, "GeForce4 MX 4000" }, 181 { 0x10DE0186, "GeForce4 448 Go" }, 182 { 0x10DE0187, "GeForce4 488 Go" }, 183 { 0x10DE0188, "Quadro4 580 XGL" }, 184#if defined(__powerpc__) 185 { 0x10DE0189, "GeForce4 MX with AGP8X (Mac)" }, 186#endif 187 { 0x10DE018A, "Quadro4 NVS 280 SD" }, 188 { 0x10DE018B, "Quadro4 380 XGL" }, 189 { 0x10DE018C, "Quadro NVS 50 PCI" }, 190 { 0x10DE018D, "GeForce4 448 Go" }, 191 192 { 0x10DE01F0, "GeForce4 MX Integrated GPU" }, 193 194 { 0x10DE0200, "GeForce3" }, 195 { 0x10DE0201, "GeForce3 Ti 200" }, 196 { 0x10DE0202, "GeForce3 Ti 500" }, 197 { 0x10DE0203, "Quadro DCC" }, 198 199 { 0x10DE0250, "GeForce4 Ti 4600" }, 200 { 0x10DE0251, "GeForce4 Ti 4400" }, 201 { 0x10DE0253, "GeForce4 Ti 4200" }, 202 { 0x10DE0258, "Quadro4 900 XGL" }, 203 { 0x10DE0259, "Quadro4 750 XGL" }, 204 { 0x10DE025B, "Quadro4 700 XGL" }, 205 206 { 0x10DE0280, "GeForce4 Ti 4800" }, 207 { 0x10DE0281, "GeForce4 Ti 4200 with AGP8X" }, 208 { 0x10DE0282, "GeForce4 Ti 4800 SE" }, 209 { 0x10DE0286, "GeForce4 4200 Go" }, 210 { 0x10DE028C, "Quadro4 700 GoGL" }, 211 { 0x10DE0288, "Quadro4 980 XGL" }, 212 { 0x10DE0289, "Quadro4 780 XGL" }, 213 214 { 0x10DE0301, "GeForce FX 5800 Ultra" }, 215 { 0x10DE0302, "GeForce FX 5800" }, 216 { 0x10DE0308, "Quadro FX 2000" }, 217 { 0x10DE0309, "Quadro FX 1000" }, 218 219 { 0x10DE0311, "GeForce FX 5600 Ultra" }, 220 { 0x10DE0312, "GeForce FX 5600" }, 221 { 0x10DE0314, "GeForce FX 5600XT" }, 222 { 0x10DE031A, "GeForce FX Go5600" }, 223 { 0x10DE031B, "GeForce FX Go5650" }, 224 { 0x10DE031C, "Quadro FX Go700" }, 225 226 { 0x10DE0320, "GeForce FX 5200" }, 227 { 0x10DE0321, "GeForce FX 5200 Ultra" }, 228 { 0x10DE0322, "GeForce FX 5200" }, 229 { 0x10DE0323, "GeForce FX 5200LE" }, 230 { 0x10DE0324, "GeForce FX Go5200" }, 231 { 0x10DE0325, "GeForce FX Go5250" }, 232 { 0x10DE0326, "GeForce FX 5500" }, 233 { 0x10DE0327, "GeForce FX 5100" }, 234 { 0x10DE0328, "GeForce FX Go5200 32M/64M" }, 235#if defined(__powerpc__) 236 { 0x10DE0329, "GeForce FX 5200 (Mac)" }, 237#endif 238 { 0x10DE032A, "Quadro NVS 55/280 PCI" }, 239 { 0x10DE032B, "Quadro FX 500/600 PCI" }, 240 { 0x10DE032C, "GeForce FX Go53xx Series" }, 241 { 0x10DE032D, "GeForce FX Go5100" }, 242 243 { 0x10DE0330, "GeForce FX 5900 Ultra" }, 244 { 0x10DE0331, "GeForce FX 5900" }, 245 { 0x10DE0332, "GeForce FX 5900XT" }, 246 { 0x10DE0333, "GeForce FX 5950 Ultra" }, 247 { 0x10DE0334, "GeForce FX 5900ZT" }, 248 { 0x10DE0338, "Quadro FX 3000" }, 249 { 0x10DE033F, "Quadro FX 700" }, 250 251 { 0x10DE0341, "GeForce FX 5700 Ultra" }, 252 { 0x10DE0342, "GeForce FX 5700" }, 253 { 0x10DE0343, "GeForce FX 5700LE" }, 254 { 0x10DE0344, "GeForce FX 5700VE" }, 255 { 0x10DE0347, "GeForce FX Go5700" }, 256 { 0x10DE0348, "GeForce FX Go5700" }, 257 { 0x10DE034C, "Quadro FX Go1000" }, 258 { 0x10DE034E, "Quadro FX 1100" }, 259 260 { 0x10DE0040, "GeForce 6800 Ultra" }, 261 { 0x10DE0041, "GeForce 6800" }, 262 { 0x10DE0042, "GeForce 6800 LE" }, 263 { 0x10DE0043, "GeForce 6800 XE" }, 264 { 0x10DE0044, "GeForce 6800 XT" }, 265 { 0x10DE0045, "GeForce 6800 GT" }, 266 { 0x10DE0046, "GeForce 6800 GT" }, 267 { 0x10DE0047, "GeForce 6800 GS" }, 268 { 0x10DE0048, "GeForce 6800 XT" }, 269 { 0x10DE004E, "Quadro FX 4000" }, 270 271 { 0x10DE00C0, "GeForce 6800 GS" }, 272 { 0x10DE00C1, "GeForce 6800" }, 273 { 0x10DE00C2, "GeForce 6800 LE" }, 274 { 0x10DE00C3, "GeForce 6800 XT" }, 275 { 0x10DE00C8, "GeForce Go 6800" }, 276 { 0x10DE00C9, "GeForce Go 6800 Ultra" }, 277 { 0x10DE00CC, "Quadro FX Go1400" }, 278 { 0x10DE00CD, "Quadro FX 3450/4000 SDI" }, 279 { 0x10DE00CE, "Quadro FX 1400" }, 280 281 { 0x10DE0140, "GeForce 6600 GT" }, 282 { 0x10DE0141, "GeForce 6600" }, 283 { 0x10DE0142, "GeForce 6600 LE" }, 284 { 0x10DE0143, "GeForce 6600 VE" }, 285 { 0x10DE0144, "GeForce Go 6600" }, 286 { 0x10DE0145, "GeForce 6610 XL" }, 287 { 0x10DE0146, "GeForce Go 6600 TE/6200 TE" }, 288 { 0x10DE0147, "GeForce 6700 XL" }, 289 { 0x10DE0148, "GeForce Go 6600" }, 290 { 0x10DE0149, "GeForce Go 6600 GT" }, 291 { 0x10DE014A, "Quadro NVS 440" }, 292 { 0x10DE014C, "Quadro FX 550" }, 293 { 0x10DE014D, "Quadro FX 550" }, 294 { 0x10DE014E, "Quadro FX 540" }, 295 { 0x10DE014F, "GeForce 6200" }, 296 297 { 0x10DE0160, "GeForce 6500" }, 298 { 0x10DE0161, "GeForce 6200 TurboCache(TM)" }, 299 { 0x10DE0162, "GeForce 6200SE TurboCache(TM)" }, 300 { 0x10DE0163, "GeForce 6200 LE" }, 301 { 0x10DE0164, "GeForce Go 6200" }, 302 { 0x10DE0165, "Quadro NVS 285" }, 303 { 0x10DE0166, "GeForce Go 6400" }, 304 { 0x10DE0167, "GeForce Go 6200" }, 305 { 0x10DE0168, "GeForce Go 6400" }, 306 { 0x10DE0169, "GeForce 6250" }, 307 { 0x10DE016A, "GeForce 7100 GS" }, 308 309 { 0x10DE0211, "GeForce 6800" }, 310 { 0x10DE0212, "GeForce 6800 LE" }, 311 { 0x10DE0215, "GeForce 6800 GT" }, 312 { 0x10DE0218, "GeForce 6800 XT" }, 313 314 { 0x10DE0221, "GeForce 6200" }, 315 { 0x10DE0222, "GeForce 6200 A-LE" }, 316 317 { 0x10DE0090, "GeForce 7800 GTX" }, 318 { 0x10DE0091, "GeForce 7800 GTX" }, 319 { 0x10DE0092, "GeForce 7800 GT" }, 320 { 0x10DE0093, "GeForce 7800 GS" }, 321 { 0x10DE0095, "GeForce 7800 SLI" }, 322 { 0x10DE0098, "GeForce Go 7800" }, 323 { 0x10DE0099, "GeForce Go 7800 GTX" }, 324 { 0x10DE009D, "Quadro FX 4500" }, 325 326 { 0x10DE01D0, "GeForce 7350 LE" }, 327 { 0x10DE01D1, "GeForce 7300 LE" }, 328 { 0x10DE01D3, "GeForce 7300 SE" }, 329 { 0x10DE01D6, "GeForce Go 7200" }, 330 { 0x10DE01D7, "GeForce Go 7300" }, 331 { 0x10DE01D8, "GeForce Go 7400" }, 332 { 0x10DE01D9, "GeForce Go 7400 GS" }, 333 { 0x10DE01DA, "Quadro NVS 110M" }, 334 { 0x10DE01DB, "Quadro NVS 120M" }, 335 { 0x10DE01DC, "Quadro FX 350M" }, 336 { 0x10DE01DD, "GeForce 7500 LE" }, 337 { 0x10DE01DE, "Quadro FX 350" }, 338 { 0x10DE01DF, "GeForce 7300 GS" }, 339 340 { 0x10DE0390, "GeForce 7650 GS" }, 341 { 0x10DE0391, "GeForce 7600 GT" }, 342 { 0x10DE0392, "GeForce 7600 GS" }, 343 { 0x10DE0393, "GeForce 7300 GT" }, 344 { 0x10DE0394, "GeForce 7600 LE" }, 345 { 0x10DE0395, "GeForce 7300 GT" }, 346 { 0x10DE0397, "GeForce Go 7700" }, 347 { 0x10DE0398, "GeForce Go 7600" }, 348 { 0x10DE0399, "GeForce Go 7600 GT"}, 349 { 0x10DE039A, "Quadro NVS 300M" }, 350 { 0x10DE039B, "GeForce Go 7900 SE" }, 351 { 0x10DE039C, "Quadro FX 550M" }, 352 { 0x10DE039E, "Quadro FX 560" }, 353 354 { 0x10DE0290, "GeForce 7900 GTX" }, 355 { 0x10DE0291, "GeForce 7900 GT" }, 356 { 0x10DE0292, "GeForce 7900 GS" }, 357 { 0x10DE0293, "GeForce 7950 GX2" }, 358 { 0x10DE0294, "GeForce 7950 GX2" }, 359 { 0x10DE0295, "GeForce 7950 GT"}, 360 { 0x10DE0297, "GeForce Go 7950 GTX" }, 361 { 0x10DE0298, "GeForce Go 7900 GS" }, 362 { 0x10DE0299, "GeForce Go 7900 GTX" }, 363 { 0x10DE029A, "Quadro FX 2500M" }, 364 { 0x10DE029B, "Quadro FX 1500M" }, 365 { 0x10DE029C, "Quadro FX 5500" }, 366 { 0x10DE029D, "Quadro FX 3500" }, 367 { 0x10DE029E, "Quadro FX 1500" }, 368 { 0x10DE029F, "Quadro FX 4500 X2" }, 369 370 { 0x10DE0240, "GeForce 6150" }, 371 { 0x10DE0241, "GeForce 6150 LE" }, 372 { 0x10DE0242, "GeForce 6100" }, 373 { 0x10DE0244, "GeForce Go 6150" }, 374 { 0x10DE0245, "Quadro NVS 210S / NVIDIA GeForce 6150LE" }, 375 { 0x10DE0247, "GeForce Go 6100" }, 376 377 { 0x10DE03D0, "GeForce 6150SE" }, 378 { 0x10DE03D1, "GeForce 6100 nForce 405" }, 379 { 0x10DE03D2, "GeForce 6100 nForce 400" }, 380 { 0x10DE03D5, "GeForce 6100 nForce 420" }, 381 382 { 0x10DE0531, "GeForce 7150M / nForce 630M" }, 383 { 0x10DE0533, "GeForce 7000M / nForce 610M" }, 384 { 0x10DE053A, "GeForce 7050 PV / nForce 630a" }, 385 { 0x10DE053B, "GeForce 7050 PV / nForce 630a" }, 386 { 0x10DE053E, "GeForce 7025 / nForce 630a" }, 387 388/*************** G8x ***************/ 389 { 0x10DE0191, "GeForce 8800 GTX" }, 390 { 0x10DE0193, "GeForce 8800 GTS" }, 391 { 0x10DE0194, "GeForce 8800 Ultra" }, 392 { 0x10DE019D, "Quadro FX 5600" }, 393 { 0x10DE019E, "Quadro FX 4600" }, 394 { 0x10DE0400, "GeForce 8600 GTS" }, 395 { 0x10DE0401, "GeForce 8600 GT" }, 396 { 0x10DE0402, "GeForce 8600 GT" }, 397 { 0x10DE0403, "GeForce 8600 GS" }, 398 { 0x10DE0404, "GeForce 8400 GS" }, 399 { 0x10DE0405, "GeForce 9500M GS" }, 400 { 0x10DE0406, "GeForce 8300 GS" }, 401 { 0x10DE0407, "GeForce 8600M GT" }, 402 { 0x10DE0408, "GeForce 9650M GS" }, 403 { 0x10DE0409, "GeForce 8700M GT" }, 404 { 0x10DE040A, "Quadro FX 370" }, 405 { 0x10DE040B, "Quadro NVS 320M" }, 406 { 0x10DE040C, "Quadro FX 570M" }, 407 { 0x10DE040D, "Quadro FX 1600M" }, 408 { 0x10DE040E, "Quadro FX 570" }, 409 { 0x10DE040F, "Quadro FX 1700" }, 410 { 0x10DE0410, "GeForce GT 330" }, 411 { 0x10DE0420, "GeForce 8400 SE" }, 412 { 0x10DE0421, "GeForce 8500 GT" }, 413 { 0x10DE0422, "GeForce 8400 GS" }, 414 { 0x10DE0423, "GeForce 8300 GS" }, 415 { 0x10DE0424, "GeForce 8400 GS" }, 416 { 0x10DE0425, "GeForce 8600M GS" }, 417 { 0x10DE0426, "GeForce 8400M GT" }, 418 { 0x10DE0427, "GeForce 8400M GS" }, 419 { 0x10DE0428, "GeForce 8400M G" }, 420 { 0x10DE0429, "Quadro NVS 140M" }, 421 { 0x10DE042A, "Quadro NVS 130M" }, 422 { 0x10DE042B, "Quadro NVS 135M" }, 423 { 0x10DE042C, "GeForce 9400 GT" }, 424 { 0x10DE042D, "Quadro FX 360M" }, 425 { 0x10DE042E, "GeForce 9300M G" }, 426 { 0x10DE042F, "Quadro NVS 290" }, 427 { 0x10DE05E0, "GeForce GTX 295" }, 428 { 0x10DE05E1, "GeForce GTX 280" }, 429 { 0x10DE05E2, "GeForce GTX 260" }, 430 { 0x10DE05E3, "GeForce GTX 285" }, 431 { 0x10DE05E6, "GeForce GTX 275" }, 432 { 0x10DE05EA, "GeForce GTX 260" }, 433 { 0x10DE05EB, "GeForce GTX 295" }, 434 { 0x10DE05ED, "Quadroplex 2200 D2" }, 435 { 0x10DE05F8, "Quadroplex 2200 S4" }, 436 { 0x10DE05F9, "Quadro CX" }, 437 { 0x10DE05FD, "Quadro FX 5800" }, 438 { 0x10DE05FE, "Quadro FX 4800" }, 439 { 0x10DE05FF, "Quadro FX 3800" }, 440 { 0x10DE0600, "GeForce 8800 GTS 512" }, 441 { 0x10DE0601, "GeForce 9800 GT" }, 442 { 0x10DE0602, "GeForce 8800 GT" }, 443 { 0x10DE0603, "GeForce GT 230" }, 444 { 0x10DE0604, "GeForce 9800 GX2" }, 445 { 0x10DE0605, "GeForce 9800 GT" }, 446 { 0x10DE0606, "GeForce 8800 GS" }, 447 { 0x10DE0607, "GeForce GTS 240" }, 448 { 0x10DE0608, "GeForce 9800M GTX" }, 449 { 0x10DE0609, "GeForce 8800M GTS" }, 450 { 0x10DE060A, "GeForce GTX 280M" }, 451 { 0x10DE060B, "GeForce 9800M GT" }, 452 { 0x10DE060C, "GeForce 8800M GTX" }, 453 { 0x10DE060D, "GeForce 8800 GS" }, 454 { 0x10DE060F, "GeForce GTX 285M" }, 455 { 0x10DE0610, "GeForce 9600 GSO" }, 456 { 0x10DE0611, "GeForce 8800 GT" }, 457 { 0x10DE0612, "GeForce 9800 GTX/9800 GTX+" }, 458 { 0x10DE0613, "GeForce 9800 GTX+" }, 459 { 0x10DE0614, "GeForce 9800 GT" }, 460 { 0x10DE0615, "GeForce GTS 250" }, 461 { 0x10DE0617, "GeForce 9800M GTX" }, 462 { 0x10DE0618, "GeForce GTX 260M" }, 463 { 0x10DE0619, "Quadro FX 4700 X2" }, 464 { 0x10DE061A, "Quadro FX 3700" }, 465 { 0x10DE061B, "Quadro VX 200" }, 466 { 0x10DE061C, "Quadro FX 3600M" }, 467 { 0x10DE061D, "Quadro FX 2800M" }, 468 { 0x10DE061E, "Quadro FX 3700M" }, 469 { 0x10DE061F, "Quadro FX 3800M" }, 470 { 0x10DE0622, "GeForce 9600 GT" }, 471 { 0x10DE0623, "GeForce 9600 GS" }, 472 { 0x10DE0625, "GeForce 9600 GSO 512" }, 473 { 0x10DE0626, "GeForce GT 130" }, 474 { 0x10DE0627, "GeForce GT 140" }, 475 { 0x10DE0628, "GeForce 9800M GTS" }, 476 { 0x10DE062A, "GeForce 9700M GTS" }, 477 { 0x10DE062B, "GeForce 9800M GS" }, 478 { 0x10DE062C, "GeForce 9800M GTS" }, 479 { 0x10DE062D, "GeForce 9600 GT" }, 480 { 0x10DE062E, "GeForce 9600 GT" }, 481 { 0x10DE0631, "GeForce GTS 160M" }, 482 { 0x10DE0632, "GeForce GTS 150M" }, 483 { 0x10DE0635, "GeForce 9600 GSO" }, 484 { 0x10DE0637, "GeForce 9600 GT" }, 485 { 0x10DE0638, "Quadro FX 1800" }, 486 { 0x10DE063A, "Quadro FX 2700M" }, 487 { 0x10DE0640, "GeForce 9500 GT" }, 488 { 0x10DE0641, "GeForce 9400 GT" }, 489 { 0x10DE0643, "GeForce 9500 GT" }, 490 { 0x10DE0644, "GeForce 9500 GS" }, 491 { 0x10DE0645, "GeForce 9500 GS" }, 492 { 0x10DE0646, "GeForce GT 120" }, 493 { 0x10DE0647, "GeForce 9600M GT" }, 494 { 0x10DE0648, "GeForce 9600M GS" }, 495 { 0x10DE0649, "GeForce 9600M GT" }, 496 { 0x10DE064A, "GeForce 9700M GT" }, 497 { 0x10DE064B, "GeForce 9500M G" }, 498 { 0x10DE064C, "GeForce 9650M GT" }, 499 { 0x10DE0651, "GeForce G 110M" }, 500 { 0x10DE0652, "GeForce GT 130M" }, 501 { 0x10DE0653, "GeForce GT 120M" }, 502 { 0x10DE0654, "GeForce GT 220M" }, 503 { 0x10DE0656, "GeForce 9650 S" }, 504 { 0x10DE0658, "Quadro FX 380" }, 505 { 0x10DE0659, "Quadro FX 580" }, 506 { 0x10DE065A, "Quadro FX 1700M" }, 507 { 0x10DE065B, "GeForce 9400 GT" }, 508 { 0x10DE065C, "Quadro FX 770M" }, 509 { 0x10DE06E0, "GeForce 9300 GE" }, 510 { 0x10DE06E1, "GeForce 9300 GS" }, 511 { 0x10DE06E2, "GeForce 8400" }, 512 { 0x10DE06E3, "GeForce 8400 SE" }, 513 { 0x10DE06E4, "GeForce 8400 GS" }, 514 { 0x10DE06E5, "GeForce 9300M GS" }, 515 { 0x10DE06E6, "GeForce G100" }, 516 { 0x10DE06E7, "GeForce 9300 SE" }, 517 { 0x10DE06E8, "GeForce 9200M GS" }, 518 { 0x10DE06E9, "GeForce 9300M GS" }, 519 { 0x10DE06EA, "Quadro NVS 150M" }, 520 { 0x10DE06EB, "Quadro NVS 160M" }, 521 { 0x10DE06EC, "GeForce G 105M" }, 522 { 0x10DE06EF, "GeForce G 103M" }, 523 { 0x10DE06F1, "GeForce G105M" }, 524 { 0x10DE06F8, "Quadro NVS 420" }, 525 { 0x10DE06F9, "Quadro FX 370 LP" }, 526 { 0x10DE06FA, "Quadro NVS 450" }, 527 { 0x10DE06FB, "Quadro FX 370M" }, 528 { 0x10DE06FD, "Quadro NVS 295" }, 529 { 0x10DE0844, "GeForce 9100M G" }, 530 { 0x10DE0845, "GeForce 8200M G" }, 531 { 0x10DE0846, "GeForce 9200" }, 532 { 0x10DE0847, "GeForce 9100" }, 533 { 0x10DE0848, "GeForce 8300" }, 534 { 0x10DE0849, "GeForce 8200" }, 535 { 0x10DE084A, "nForce 730a" }, 536 { 0x10DE084B, "GeForce 9200" }, 537 { 0x10DE084C, "nForce 980a/780a SLI" }, 538 { 0x10DE084D, "nForce 750a SLI" }, 539 { 0x10DE084F, "GeForce 8100 / nForce 720a" }, 540 { 0x10DE0860, "GeForce 9400" }, 541 { 0x10DE0861, "GeForce 9400" }, 542 { 0x10DE0862, "GeForce 9400M G" }, 543 { 0x10DE0863, "GeForce 9400M" }, 544 { 0x10DE0864, "GeForce 9300" }, 545 { 0x10DE0865, "ION" }, 546 { 0x10DE0866, "GeForce 9400M G" }, 547 { 0x10DE0867, "GeForce 9400" }, 548 { 0x10DE0868, "nForce 760i SLI" }, 549 { 0x10DE086A, "GeForce 9400" }, 550 { 0x10DE086C, "GeForce 9300 / nForce 730i" }, 551 { 0x10DE086D, "GeForce 9200" }, 552 { 0x10DE086E, "GeForce 9100M G" }, 553 { 0x10DE086F, "GeForce 8200M G" }, 554 { 0x10DE0870, "GeForce 9400M" }, 555 { 0x10DE0871, "GeForce 9200" }, 556 { 0x10DE0872, "GeForce G102M" }, 557 { 0x10DE0873, "GeForce G102M" }, 558 { 0x10DE0874, "ION" }, 559 { 0x10DE0876, "ION" }, 560 { 0x10DE087A, "GeForce 9400" }, 561 { 0x10DE087D, "ION" }, 562 { 0x10DE087E, "ION LE" }, 563 { 0x10DE087F, "ION LE" }, 564 { 0x10DE0A20, "GeForce GT 220" }, 565 { 0x10DE0A22, "GeForce 315" }, 566 { 0x10DE0A23, "GeForce 210" }, 567 { 0x10DE0A28, "GeForce GT 230M" }, 568 { 0x10DE0A29, "GeForce GT 330M" }, 569 { 0x10DE0A2A, "GeForce GT 230M" }, 570 { 0x10DE0A2B, "GeForce GT 330M" }, 571 { 0x10DE0A2C, "NVS 5100M" }, 572 { 0x10DE0A2D, "GeForce GT 320M" }, 573 { 0x10DE0A34, "GeForce GT 240M" }, 574 { 0x10DE0A35, "GeForce GT 325M" }, 575 { 0x10DE0A3C, "Quadro FX 880M" }, 576 { 0x10DE0A60, "GeForce G210" }, 577 { 0x10DE0A62, "GeForce 205" }, 578 { 0x10DE0A63, "GeForce 310" }, 579 { 0x10DE0A64, "ION" }, 580 { 0x10DE0A65, "GeForce 210" }, 581 { 0x10DE0A66, "GeForce 310" }, 582 { 0x10DE0A67, "GeForce 315" }, 583 { 0x10DE0A68, "GeForce G105M" }, 584 { 0x10DE0A69, "GeForce G105M" }, 585 { 0x10DE0A6A, "NVS 2100M" }, 586 { 0x10DE0A6C, "NVS 3100M" }, 587 { 0x10DE0A6E, "GeForce 305M" }, 588 { 0x10DE0A6F, "ION" }, 589 { 0x10DE0A70, "GeForce 310M" }, 590 { 0x10DE0A71, "GeForce 305M" }, 591 { 0x10DE0A72, "GeForce 310M" }, 592 { 0x10DE0A73, "GeForce 305M" }, 593 { 0x10DE0A74, "GeForce G210M" }, 594 { 0x10DE0A75, "GeForce 310M" }, 595 { 0x10DE0A78, "Quadro FX 380 LP" }, 596 { 0x10DE0A7C, "Quadro FX 380M" }, 597 { 0x10DE0CA0, "GeForce GT 330" }, 598 { 0x10DE0CA2, "GeForce GT 320" }, 599 { 0x10DE0CA3, "GeForce GT 240" }, 600 { 0x10DE0CA4, "GeForce GT 340" }, 601 { 0x10DE0CA7, "GeForce GT 330" }, 602 { 0x10DE0CA8, "GeForce GTS 260M" }, 603 { 0x10DE0CA9, "GeForce GTS 250M" }, 604 { 0x10DE0CAC, "GeForce 315" }, 605 { 0x10DE0CAF, "GeForce GT 335M" }, 606 { 0x10DE0CB0, "GeForce GTS 350M" }, 607 { 0x10DE0CB1, "GeForce GTS 360M" }, 608 { 0x10DE0CBC, "Quadro FX 1800M" }, 609 610 {-1, NULL} 611}; 612 613#ifdef XFree86LOADER 614 615static MODULESETUPPROTO(nvSetup); 616 617static XF86ModuleVersionInfo nvVersRec = 618{ 619 "nv", 620 MODULEVENDORSTRING, 621 MODINFOSTRING1, 622 MODINFOSTRING2, 623 XORG_VERSION_CURRENT, 624 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, 625 ABI_CLASS_VIDEODRV, /* This is a video driver */ 626 ABI_VIDEODRV_VERSION, 627 MOD_CLASS_VIDEODRV, 628 {0,0,0,0} 629}; 630 631_X_EXPORT XF86ModuleData nvModuleData = { &nvVersRec, nvSetup, NULL }; 632#endif 633 634 635typedef enum { 636 OPTION_SW_CURSOR, 637 OPTION_HW_CURSOR, 638 OPTION_NOACCEL, 639 OPTION_SHADOW_FB, 640 OPTION_FBDEV, 641 OPTION_ROTATE, 642 OPTION_VIDEO_KEY, 643 OPTION_FLAT_PANEL, 644 OPTION_FP_DITHER, 645 OPTION_CRTC_NUMBER, 646 OPTION_FP_SCALE, 647 OPTION_FP_TWEAK, 648 OPTION_DUALHEAD, 649} NVOpts; 650 651 652static const OptionInfoRec NVOptions[] = { 653 { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 654 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 655 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 656 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 657 { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, 658 { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, 659 { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, 660 { OPTION_FLAT_PANEL, "FlatPanel", OPTV_BOOLEAN, {0}, FALSE }, 661 { OPTION_FP_DITHER, "FPDither", OPTV_BOOLEAN, {0}, FALSE }, 662 { OPTION_CRTC_NUMBER, "CrtcNumber", OPTV_INTEGER, {0}, FALSE }, 663 { OPTION_FP_SCALE, "FPScale", OPTV_BOOLEAN, {0}, FALSE }, 664 { OPTION_FP_TWEAK, "FPTweak", OPTV_INTEGER, {0}, FALSE }, 665 { OPTION_DUALHEAD, "DualHead", OPTV_BOOLEAN, {0}, FALSE }, 666 { -1, NULL, OPTV_NONE, {0}, FALSE } 667}; 668 669/* 670 * This is intentionally screen-independent. It indicates the binding 671 * choice made in the first PreInit. 672 */ 673static int pix24bpp = 0; 674 675 676static Bool 677NVGetRec(ScrnInfoPtr pScrn) 678{ 679 /* 680 * Allocate an NVRec, and hook it into pScrn->driverPrivate. 681 * pScrn->driverPrivate is initialised to NULL, so we can check if 682 * the allocation has already been done. 683 */ 684 if (pScrn->driverPrivate != NULL) 685 return TRUE; 686 687 pScrn->driverPrivate = xnfcalloc(sizeof(NVRec), 1); 688 /* Initialise it */ 689 690 return TRUE; 691} 692 693static void 694NVFreeRec(ScrnInfoPtr pScrn) 695{ 696 if (pScrn->driverPrivate == NULL) 697 return; 698 free(pScrn->driverPrivate); 699 pScrn->driverPrivate = NULL; 700} 701 702 703#ifdef XFree86LOADER 704 705static pointer 706nvSetup(pointer module, pointer opts, int *errmaj, int *errmin) 707{ 708 static Bool setupDone = FALSE; 709 710 /* This module should be loaded only once, but check to be sure. */ 711 712 if (!setupDone) { 713 setupDone = TRUE; 714 xf86AddDriver(&NV, module, 715#ifdef XSERVER_LIBPCIACCESS 716 HaveDriverFuncs 717#else 718 0 719#endif 720 ); 721 722 /* 723 * The return value must be non-NULL on success even though there 724 * is no TearDownProc. 725 */ 726 return (pointer)1; 727 } else { 728 if (errmaj) *errmaj = LDR_ONCEONLY; 729 return NULL; 730 } 731} 732 733 734#endif /* XFree86LOADER */ 735 736static const OptionInfoRec * 737NVAvailableOptions(int chipid, int busid) 738{ 739 if(chipid == 0x12D20018) { 740 return RivaAvailableOptions(chipid, busid); 741 } 742 743 return NVOptions; 744} 745 746/* Mandatory */ 747static void 748NVIdentify(int flags) 749{ 750 xf86PrintChipsets(NV_NAME, "driver for NVIDIA chipsets", NVKnownChipsets); 751} 752 753 754static Bool 755NVGetScrnInfoRec(PciChipsets *chips, int chip) 756{ 757 ScrnInfoPtr pScrn; 758 759 pScrn = xf86ConfigPciEntity(NULL, 0, chip, 760 chips, NULL, NULL, NULL, 761 NULL, NULL); 762 763 if(!pScrn) return FALSE; 764 765 pScrn->driverVersion = NV_VERSION; 766 pScrn->driverName = NV_DRIVER_NAME; 767 pScrn->name = NV_NAME; 768 769#ifndef XSERVER_LIBPCIACCESS 770 pScrn->Probe = NVProbe; 771#endif 772 pScrn->PreInit = NVPreInit; 773 pScrn->ScreenInit = NVScreenInit; 774 pScrn->SwitchMode = NVSwitchMode; 775 pScrn->AdjustFrame = NVAdjustFrame; 776 pScrn->EnterVT = NVEnterVT; 777 pScrn->LeaveVT = NVLeaveVT; 778 pScrn->FreeScreen = NVFreeScreen; 779 pScrn->ValidMode = NVValidMode; 780 781 return TRUE; 782} 783 784#define MAX_CHIPS MAXSCREENS 785 786 787static CARD32 788#ifdef XSERVER_LIBPCIACCESS 789NVGetPCIXpressChip (struct pci_device *dev) 790#else 791NVGetPCIXpressChip (pciVideoPtr pVideo) 792#endif 793{ 794 volatile CARD32 *regs; 795#ifdef XSERVER_LIBPCIACCESS 796 uint32_t pciid, pcicmd; 797 void *tmp; 798 799 pci_device_cfg_read_u32(dev, &pcicmd, PCI_CMD_STAT_REG); 800 pci_device_cfg_write_u32(dev, pcicmd | PCI_CMD_MEM_ENABLE, 801 PCI_CMD_STAT_REG); 802 803 pci_device_map_range(dev, dev->regions[0].base_addr, 0x2000, 804 PCI_DEV_MAP_FLAG_WRITABLE, &tmp); 805 regs = tmp; 806 pciid = regs[0x1800/4]; 807 pci_device_unmap_range(dev, tmp, 0x2000); 808 809 pci_device_cfg_write_u32(dev, pcicmd, PCI_CMD_STAT_REG); 810#else 811 CARD32 pciid, pcicmd; 812 PCITAG Tag = ((pciConfigPtr)(pVideo->thisCard))->tag; 813 814 pcicmd = pciReadLong(Tag, PCI_CMD_STAT_REG); 815 pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd | PCI_CMD_MEM_ENABLE); 816 817 regs = xf86MapPciMem(-1, VIDMEM_MMIO, Tag, pVideo->memBase[0], 0x2000); 818 819 pciid = regs[0x1800/4]; 820 821 xf86UnMapVidMem(-1, (pointer)regs, 0x2000); 822 823 pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd); 824#endif 825 826 if((pciid & 0x0000ffff) == 0x000010DE) 827 pciid = 0x10DE0000 | (pciid >> 16); 828 else 829 if((pciid & 0xffff0000) == 0xDE100000) /* wrong endian */ 830 pciid = 0x10DE0000 | ((pciid << 8) & 0x0000ff00) | 831 ((pciid >> 8) & 0x000000ff); 832 833 return pciid; 834} 835 836static Bool 837NVIsG80(int chipType) 838{ 839 switch(chipType & 0xfff0) { 840 case 0x0190: 841 case 0x0400: 842 case 0x0420: 843 case 0x05e0: 844 case 0x05f0: 845 case 0x0600: 846 case 0x0610: 847 case 0x0620: 848 case 0x0630: 849 case 0x0640: 850 case 0x0650: 851 case 0x06e0: 852 case 0x06f0: 853 case 0x0840: 854 case 0x0850: 855 case 0x0860: 856 case 0x0870: 857 case 0x0a20: 858 case 0x0a30: 859 case 0x0a60: 860 case 0x0a70: 861 case 0x0ca0: 862 case 0x0cb0: 863 return TRUE; 864 } 865 866 return FALSE; 867} 868 869static Bool 870NVIsSupported(CARD32 id) 871{ 872 /* look for a compatible devices which may be newer than 873 the NVKnownChipsets list above. */ 874 switch(id & 0xfff0) { 875 case 0x0040: 876 case 0x0090: 877 case 0x00C0: 878 case 0x0120: 879 case 0x0140: 880 case 0x0160: 881 case 0x0170: 882 case 0x0180: 883 case 0x01D0: 884 case 0x0210: 885 case 0x0220: 886 case 0x0240: 887 case 0x0250: 888 case 0x0280: 889 case 0x0290: 890 case 0x0300: 891 case 0x0310: 892 case 0x0320: 893 case 0x0330: 894 case 0x0340: 895 case 0x0390: 896 case 0x03D0: 897 case 0x0530: 898 return TRUE; 899 } 900 901 return FALSE; 902} 903 904/* Mandatory */ 905#ifdef XSERVER_LIBPCIACCESS 906static Bool 907NVPciProbe(DriverPtr drv, int entity, struct pci_device *dev, intptr_t data) 908{ 909 const CARD32 id = ((dev->device_id & 0xfff0) == 0x00F0 || 910 (dev->device_id & 0xfff0) == 0x02E0) ? 911 NVGetPCIXpressChip(dev) : dev->vendor_id << 16 | dev->device_id; 912 const char *name = xf86TokenToString(NVKnownChipsets, id); 913 914/* 915 * XXX 916 * disable this test for now since it's bogus 917 * it will trigger whenever there's a driver other than vga attached to the 918 * device we're trying to probe, yet this works fine on top of gffb or genfb 919 * might need to revisit this when we have working DRM on non-x86 920 */ 921#if NV_TEST_FOR_KERNEL_DRIVER 922 if (pci_device_has_kernel_driver(dev)) { 923 xf86DrvMsg(0, X_ERROR, 924 NV_NAME ": The PCI device 0x%"PRIx32" (%s) at %2.2d@%2.2d:%2.2d:%1.1d has a kernel module claiming it.\n", 925 id, name, dev->bus, dev->domain, dev->dev, dev->func); 926 xf86DrvMsg(0, X_ERROR, 927 NV_NAME ": This driver cannot operate until it has been unloaded.\n"); 928 return FALSE; 929 } 930#endif 931 if(dev->vendor_id == PCI_VENDOR_NVIDIA && !name && 932 !NVIsSupported(id) && !NVIsG80(id)) { 933 /* See if pci.ids knows what the heck this thing is */ 934 name = pci_device_get_device_name(dev); 935 if(name) 936 xf86DrvMsg(0, X_WARNING, 937 NV_NAME ": Ignoring unsupported device 0x%"PRIx32" (%s) at %2.2d@%2.2d:%2.2d:%1.1d\n", 938 (uint32_t)id, name, dev->bus, dev->domain, dev->dev, dev->func); 939 else 940 xf86DrvMsg(0, X_WARNING, 941 NV_NAME ": Ignoring unsupported device 0x%"PRIx32" at %2.2d@%2.2d:%2.2d:%1.1d\n", 942 (uint32_t)id, dev->bus, dev->domain, dev->dev, dev->func); 943 return FALSE; 944 } 945 946 if(!name) 947 name = pci_device_get_device_name(dev); 948 if(!name) 949 name = "Unknown GPU"; 950 951 xf86DrvMsg(0, X_PROBED, 952 NV_NAME ": Found NVIDIA %s at %2.2d@%2.2d:%2.2d:%1.1d\n", 953 name, dev->bus, dev->domain, dev->dev, dev->func); 954 955 if(NVIsG80(id)) 956 return G80GetScrnInfoRec(NULL, entity); 957 else if(dev->vendor_id == PCI_VENDOR_NVIDIA_SGS) 958 return RivaGetScrnInfoRec(NULL, entity); 959 else 960 return NVGetScrnInfoRec(NULL, entity); 961} 962#else 963static Bool 964NVProbe(DriverPtr drv, int flags) 965{ 966 int i; 967 GDevPtr *devSections; 968 int *usedChips; 969 SymTabRec NVChipsets[MAX_CHIPS + 1]; 970 PciChipsets NVPciChipsets[MAX_CHIPS + 1]; 971 pciVideoPtr *ppPci; 972 int numDevSections; 973 int numUsed; 974 Bool foundScreen = FALSE; 975 976 977 if ((numDevSections = xf86MatchDevice(NV_DRIVER_NAME, &devSections)) <= 0) 978 return FALSE; /* no matching device section */ 979 980 if (!(ppPci = xf86GetPciVideoInfo())) 981 return FALSE; /* no PCI cards found */ 982 983 numUsed = 0; 984 985 /* Create the NVChipsets and NVPciChipsets from found devices */ 986 while (*ppPci && (numUsed < MAX_CHIPS)) { 987 if(((*ppPci)->vendor == PCI_VENDOR_NVIDIA_SGS) || 988 ((*ppPci)->vendor == PCI_VENDOR_NVIDIA)) 989 { 990 SymTabRec *nvchips = NVKnownChipsets; 991 int pciid = ((*ppPci)->vendor << 16) | (*ppPci)->chipType; 992 int token = pciid; 993 994 if(((token & 0xfff0) == 0x00F0) || 995 ((token & 0xfff0) == 0x02E0)) 996 { 997 token = NVGetPCIXpressChip(*ppPci); 998 } 999 1000 while(nvchips->name) { 1001 if(token == nvchips->token) 1002 break; 1003 nvchips++; 1004 } 1005 1006 if(nvchips->name || 1007 ((*ppPci)->vendor == PCI_VENDOR_NVIDIA && 1008 (NVIsSupported(token) || NVIsG80((*ppPci)->chipType)))) { 1009 NVChipsets[numUsed].token = pciid; 1010 NVChipsets[numUsed].name = nvchips->name ? nvchips->name : "Unknown NVIDIA chip"; 1011 NVPciChipsets[numUsed].numChipset = pciid; 1012 NVPciChipsets[numUsed].PCIid = pciid; 1013 NVPciChipsets[numUsed].resList = RES_SHARED_VGA; 1014 numUsed++; 1015 } 1016 } 1017 ppPci++; 1018 } 1019 1020 /* terminate the list */ 1021 NVChipsets[numUsed].token = -1; 1022 NVChipsets[numUsed].name = NULL; 1023 NVPciChipsets[numUsed].numChipset = -1; 1024 NVPciChipsets[numUsed].PCIid = -1; 1025 NVPciChipsets[numUsed].resList = RES_UNDEFINED; 1026 1027 numUsed = xf86MatchPciInstances(NV_NAME, 0, NVChipsets, NVPciChipsets, 1028 devSections, numDevSections, drv, 1029 &usedChips); 1030 1031 if (numUsed <= 0) 1032 return FALSE; 1033 1034 if (flags & PROBE_DETECT) 1035 foundScreen = TRUE; 1036 else for (i = 0; i < numUsed; i++) { 1037 pciVideoPtr pPci; 1038 1039 pPci = xf86GetPciInfoForEntity(usedChips[i]); 1040 if(pPci->vendor == PCI_VENDOR_NVIDIA_SGS) { 1041 if(RivaGetScrnInfoRec(NVPciChipsets, usedChips[i])) 1042 foundScreen = TRUE; 1043 } else if (NVIsG80(pPci->chipType)) { 1044 if(G80GetScrnInfoRec(NVPciChipsets, usedChips[i])) 1045 foundScreen = TRUE; 1046 } else { 1047 if(NVGetScrnInfoRec(NVPciChipsets, usedChips[i])) 1048 foundScreen = TRUE; 1049 } 1050 } 1051 1052 free(devSections); 1053 free(usedChips); 1054 1055 return foundScreen; 1056} 1057#endif /* XSERVER_LIBPCIACCESS */ 1058 1059/* Usually mandatory */ 1060Bool 1061NVSwitchMode(SWITCH_MODE_ARGS_DECL) 1062{ 1063 SCRN_INFO_PTR(arg); 1064 1065 NVSync(pScrn); 1066 return NVModeInit(pScrn, mode); 1067} 1068 1069static Bool 1070NVSwitchModeVBE(SWITCH_MODE_ARGS_DECL) 1071{ 1072 SCRN_INFO_PTR(arg); 1073 NVPtr pNv = NVPTR(pScrn); 1074 const Bool disableAccess = pNv->accessEnabled; 1075 1076 if(disableAccess) 1077 pScrn->EnableDisableFBAccess(XF86_SCRN_ARG(pScrn), FALSE); 1078 1079 NVSync(pScrn); 1080 if (!NVSetModeVBE(pScrn, mode)) 1081 return FALSE; 1082 NVAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 1083 1084 if(disableAccess) 1085 pScrn->EnableDisableFBAccess(XF86_SCRN_ARG(pScrn), TRUE); 1086 1087 return TRUE; 1088} 1089 1090/* 1091 * This function is used to initialize the Start Address - the first 1092 * displayed location in the video memory. 1093 */ 1094/* Usually mandatory */ 1095void 1096NVAdjustFrame(ADJUST_FRAME_ARGS_DECL) 1097{ 1098 SCRN_INFO_PTR(arg); 1099 int startAddr; 1100 NVPtr pNv = NVPTR(pScrn); 1101 NVFBLayout *pLayout = &pNv->CurrentLayout; 1102 1103 startAddr = (((y*pLayout->displayWidth)+x)*(pLayout->bitsPerPixel/8)); 1104 NVSetStartAddress(pNv, startAddr); 1105} 1106 1107 1108/* 1109 * This is called when VT switching back to the X server. Its job is 1110 * to reinitialise the video mode. 1111 * 1112 * We may wish to unmap video/MMIO memory too. 1113 */ 1114 1115/* Mandatory */ 1116static Bool 1117NVEnterVT(VT_FUNC_ARGS_DECL) 1118{ 1119 SCRN_INFO_PTR(arg); 1120 NVPtr pNv = NVPTR(pScrn); 1121 1122 if (!NVModeInit(pScrn, pScrn->currentMode)) 1123 return FALSE; 1124 NVAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 1125 1126 if(pNv->overlayAdaptor) 1127 NVResetVideo(pScrn); 1128 return TRUE; 1129} 1130 1131static Bool 1132NVEnterVTFBDev(VT_FUNC_ARGS_DECL) 1133{ 1134 SCRN_INFO_PTR(arg); 1135 fbdevHWEnterVT(VT_FUNC_ARGS); 1136 return TRUE; 1137} 1138 1139static Bool 1140NVEnterVTVBE(VT_FUNC_ARGS_DECL) 1141{ 1142 SCRN_INFO_PTR(arg); 1143 1144 if (!NVSetModeVBE(pScrn, pScrn->currentMode)) 1145 return FALSE; 1146 NVAdjustFrame(ADJUST_FRAME_ARGS(pScrn, 0, 0)); 1147 return TRUE; 1148} 1149 1150/* 1151 * This is called when VT switching away from the X server. Its job is 1152 * to restore the previous (text) mode. 1153 * 1154 * We may wish to remap video/MMIO memory too. 1155 */ 1156 1157/* Mandatory */ 1158static void 1159NVLeaveVT(VT_FUNC_ARGS_DECL) 1160{ 1161 SCRN_INFO_PTR(arg); 1162 NVPtr pNv = NVPTR(pScrn); 1163 1164 NVSync(pScrn); 1165 NVRestore(pScrn); 1166 NVLockUnlock(pNv, 1); 1167} 1168 1169static void 1170NVLeaveVTVBE(VT_FUNC_ARGS_DECL) 1171{ 1172 SCRN_INFO_PTR(arg); 1173 1174 NVSync(pScrn); 1175 NVSaveRestoreVBE(pScrn, MODE_RESTORE); 1176} 1177 1178static void 1179NVBlockHandler (BLOCKHANDLER_ARGS_DECL) 1180{ 1181 SCREEN_PTR(arg); 1182 ScrnInfoPtr pScrnInfo = xf86ScreenToScrn(pScreen); 1183 NVPtr pNv = NVPTR(pScrnInfo); 1184 1185 if (pNv->DMAKickoffCallback) 1186 (*pNv->DMAKickoffCallback)(pScrnInfo); 1187 1188 pScreen->BlockHandler = pNv->BlockHandler; 1189 (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); 1190 pScreen->BlockHandler = NVBlockHandler; 1191 1192 if (pNv->VideoTimerCallback) 1193 (*pNv->VideoTimerCallback)(pScrnInfo, currentTime.milliseconds); 1194 1195} 1196 1197 1198/* 1199 * This is called at the end of each server generation. It restores the 1200 * original (text) mode. It should also unmap the video memory, and free 1201 * any per-generation data allocated by the driver. It should finish 1202 * by unwrapping and calling the saved CloseScreen function. 1203 */ 1204 1205/* Mandatory */ 1206static Bool 1207NVCloseScreen(CLOSE_SCREEN_ARGS_DECL) 1208{ 1209 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1210 NVPtr pNv = NVPTR(pScrn); 1211 1212 if (pScrn->vtSema) { 1213 if (!pNv->NoAccel) 1214 NVSync(pScrn); 1215 1216 if (pNv->VBEDualhead) { 1217 NVSaveRestoreVBE(pScrn, MODE_RESTORE); 1218 } else { 1219 NVRestore(pScrn); 1220 NVLockUnlock(pNv, 1); 1221 } 1222 } 1223 1224 NVUnmapMem(pScrn); 1225#ifndef AVOID_VGAHW 1226 vgaHWUnmapMem(pScrn); 1227#endif 1228#ifdef HAVE_XAA_H 1229 if (pNv->AccelInfoRec) 1230 XAADestroyInfoRec(pNv->AccelInfoRec); 1231#endif 1232 if (pNv->CursorInfoRec) 1233 xf86DestroyCursorInfoRec(pNv->CursorInfoRec); 1234 if (pNv->ShadowPtr) 1235 free(pNv->ShadowPtr); 1236 if (pNv->DGAModes) 1237 free(pNv->DGAModes); 1238 if (pNv->overlayAdaptor) 1239 free(pNv->overlayAdaptor); 1240 if (pNv->blitAdaptor) 1241 free(pNv->blitAdaptor); 1242 1243 pScrn->vtSema = FALSE; 1244 pScreen->CloseScreen = pNv->CloseScreen; 1245 pScreen->BlockHandler = pNv->BlockHandler; 1246 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 1247} 1248 1249static void 1250NVEnableDisableFBAccess(SCRN_ARG_TYPE arg, Bool enable) 1251{ 1252 SCRN_INFO_PTR(arg); 1253 NVPtr pNv = NVPTR(pScrn); 1254 1255 pNv->accessEnabled = enable; 1256 pNv->EnableDisableFBAccess(arg, enable); 1257} 1258 1259 1260/* Free up any persistent data structures */ 1261 1262/* Optional */ 1263static void 1264NVFreeScreen(FREE_SCREEN_ARGS_DECL) 1265{ 1266 SCRN_INFO_PTR(arg); 1267 /* 1268 * This only gets called when a screen is being deleted. It does not 1269 * get called routinely at the end of a server generation. 1270 */ 1271 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 1272 vgaHWFreeHWRec(pScrn); 1273 NVFreeRec(pScrn); 1274} 1275 1276 1277/* Checks if a mode is suitable for the selected chipset. */ 1278 1279/* Optional */ 1280static ModeStatus 1281NVValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 1282{ 1283 SCRN_INFO_PTR(arg); 1284 NVPtr pNv = NVPTR(pScrn); 1285 1286 if(pNv->fpWidth && pNv->fpHeight) 1287 if((pNv->fpWidth < mode->HDisplay) || (pNv->fpHeight < mode->VDisplay)) 1288 return (MODE_PANEL); 1289 1290 return (MODE_OK); 1291} 1292 1293static void 1294nvProbeDDC(ScrnInfoPtr pScrn, int index) 1295{ 1296 vbeInfoPtr pVbe; 1297 1298 if (xf86LoadSubModule(pScrn, "vbe")) { 1299 pVbe = VBEInit(NULL,index); 1300 ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 1301 vbeFree(pVbe); 1302 } 1303} 1304 1305 1306Bool NVI2CInit(ScrnInfoPtr pScrn) 1307{ 1308 const char *mod = "i2c"; 1309 1310 if (xf86LoadSubModule(pScrn, mod)) { 1311 1312 mod = "ddc"; 1313 if(xf86LoadSubModule(pScrn, mod)) { 1314 return NVDACi2cInit(pScrn); 1315 } 1316 } 1317 1318 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1319 "Couldn't load %s module. DDC probing can't be done\n", mod); 1320 1321 return FALSE; 1322} 1323 1324 1325/* Copied from ddc/Property.c */ 1326static DisplayModePtr 1327NVModesAdd(DisplayModePtr Modes, DisplayModePtr Additions) 1328{ 1329 if (!Modes) { 1330 if (Additions) 1331 return Additions; 1332 else 1333 return NULL; 1334 } 1335 1336 if (Additions) { 1337 DisplayModePtr Mode = Modes; 1338 1339 while (Mode->next) 1340 Mode = Mode->next; 1341 1342 Mode->next = Additions; 1343 Additions->prev = Mode; 1344 } 1345 1346 return Modes; 1347} 1348 1349/* Mandatory */ 1350static Bool 1351NVPreInit(ScrnInfoPtr pScrn, int flags) 1352{ 1353 NVPtr pNv; 1354 MessageType from; 1355 int i, max_width, max_height; 1356 ClockRangePtr clockRanges; 1357 const char *s; 1358 Bool config_mon_rates; 1359 1360 if (flags & PROBE_DETECT) { 1361 EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 1362 1363 if (!pEnt) 1364 return FALSE; 1365 1366 i = pEnt->index; 1367 free(pEnt); 1368 1369 nvProbeDDC(pScrn, i); 1370 return TRUE; 1371 } 1372 1373 /* 1374 * Note: This function is only called once at server startup, and 1375 * not at the start of each server generation. This means that 1376 * only things that are persistent across server generations can 1377 * be initialised here. xf86Screens[] is (pScrn is a pointer to one 1378 * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() 1379 * are too, and should be used for data that must persist across 1380 * server generations. 1381 * 1382 * Per-generation data should be allocated with 1383 * AllocateScreenPrivateIndex() from the ScreenInit() function. 1384 */ 1385 1386 /* Check the number of entities, and fail if it isn't one. */ 1387 if (pScrn->numEntities != 1) 1388 return FALSE; 1389 1390 /* Allocate the NVRec driverPrivate */ 1391 if (!NVGetRec(pScrn)) { 1392 return FALSE; 1393 } 1394 pNv = NVPTR(pScrn); 1395 1396 /* Get the entity, and make sure it is PCI. */ 1397 pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 1398 if (pNv->pEnt->location.type != BUS_PCI) 1399 return FALSE; 1400 1401 /* Find the PCI info for this screen */ 1402 pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index); 1403#ifndef XSERVER_LIBPCIACCESS 1404 pNv->PciTag = pciTag(pNv->PciInfo->bus, pNv->PciInfo->device, 1405 pNv->PciInfo->func); 1406#endif 1407 1408 pNv->Primary = xf86IsPrimaryPci(pNv->PciInfo); 1409 1410 /* Initialize the card through int10 interface if needed */ 1411 if (xf86LoadSubModule(pScrn, "int10")) { 1412#if !defined(__alpha__) && !defined(__powerpc__) 1413 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n"); 1414 pNv->pInt = xf86InitInt10(pNv->pEnt->index); 1415#endif 1416 } 1417 1418#ifndef XSERVER_LIBPCIACCESS 1419 xf86SetOperatingState(resVgaIo, pNv->pEnt->index, ResUnusedOpr); 1420 xf86SetOperatingState(resVgaMem, pNv->pEnt->index, ResDisableOpr); 1421#endif 1422 1423 /* Set pScrn->monitor */ 1424 pScrn->monitor = pScrn->confScreen->monitor; 1425 1426 /* 1427 * Set the Chipset and ChipRev, allowing config file entries to 1428 * override. 1429 */ 1430 if (pNv->pEnt->device->chipset && *pNv->pEnt->device->chipset) { 1431 pScrn->chipset = pNv->pEnt->device->chipset; 1432 pNv->Chipset = xf86StringToToken(NVKnownChipsets, pScrn->chipset); 1433 from = X_CONFIG; 1434 } else if (pNv->pEnt->device->chipID >= 0) { 1435 pNv->Chipset = pNv->pEnt->device->chipID; 1436 pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, 1437 pNv->Chipset); 1438 from = X_CONFIG; 1439 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 1440 pNv->Chipset); 1441 } else { 1442 from = X_PROBED; 1443 pNv->Chipset = VENDOR_ID(pNv->PciInfo) << 16 | DEVICE_ID(pNv->PciInfo); 1444 1445 if(((pNv->Chipset & 0xfff0) == 0x00F0) || 1446 ((pNv->Chipset & 0xfff0) == 0x02E0)) 1447 { 1448 pNv->Chipset = NVGetPCIXpressChip(pNv->PciInfo); 1449 } 1450 1451 pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, 1452 pNv->Chipset); 1453 if(!pScrn->chipset) 1454 pScrn->chipset = "Unknown NVIDIA chipset"; 1455 } 1456 1457 if (pNv->pEnt->device->chipRev >= 0) { 1458 pNv->ChipRev = pNv->pEnt->device->chipRev; 1459 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 1460 pNv->ChipRev); 1461 } else { 1462 pNv->ChipRev = CHIP_REVISION(pNv->PciInfo); 1463 } 1464 1465 /* 1466 * This shouldn't happen because such problems should be caught in 1467 * NVProbe(), but check it just in case. 1468 */ 1469 if (pScrn->chipset == NULL) { 1470 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1471 "ChipID 0x%04X is not recognised\n", pNv->Chipset); 1472 xf86FreeInt10(pNv->pInt); 1473 return FALSE; 1474 } 1475 if (pNv->Chipset < 0) { 1476 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1477 "Chipset \"%s\" is not recognised\n", pScrn->chipset); 1478 xf86FreeInt10(pNv->pInt); 1479 return FALSE; 1480 } 1481 1482 xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); 1483 1484 1485 /* 1486 * The first thing we should figure out is the depth, bpp, etc. 1487 */ 1488 1489 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) { 1490 xf86FreeInt10(pNv->pInt); 1491 return FALSE; 1492 } else { 1493 /* Check that the returned depth is one we support */ 1494 switch (pScrn->depth) { 1495 case 8: 1496 case 15: 1497 case 16: 1498 case 24: 1499 /* OK */ 1500 break; 1501 default: 1502 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1503 "Given depth (%d) is not supported by this driver\n", 1504 pScrn->depth); 1505 xf86FreeInt10(pNv->pInt); 1506 return FALSE; 1507 } 1508 } 1509 xf86PrintDepthBpp(pScrn); 1510 1511 /* Get the depth24 pixmap format */ 1512 if (pScrn->depth == 24 && pix24bpp == 0) 1513 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 1514 1515 /* 1516 * This must happen after pScrn->display has been set because 1517 * xf86SetWeight references it. 1518 */ 1519 if (pScrn->depth > 8) { 1520 /* The defaults are OK for us */ 1521 rgb zeros = {0, 0, 0}; 1522 1523 if (!xf86SetWeight(pScrn, zeros, zeros)) { 1524 xf86FreeInt10(pNv->pInt); 1525 return FALSE; 1526 } 1527 } 1528 1529 if (!xf86SetDefaultVisual(pScrn, -1)) { 1530 xf86FreeInt10(pNv->pInt); 1531 return FALSE; 1532 } else { 1533 /* We don't currently support DirectColor at > 8bpp */ 1534 if (pScrn->depth > 8 && (pScrn->defaultVisual != TrueColor)) { 1535 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 1536 " (%s) is not supported at depth %d\n", 1537 xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 1538 xf86FreeInt10(pNv->pInt); 1539 return FALSE; 1540 } 1541 } 1542 1543 /* The vgahw module should be loaded here when needed */ 1544 if (!xf86LoadSubModule(pScrn, "vgahw")) { 1545 xf86FreeInt10(pNv->pInt); 1546 return FALSE; 1547 } 1548 1549 /* 1550 * Allocate a vgaHWRec 1551 */ 1552 if (!vgaHWGetHWRec(pScrn)) { 1553 xf86FreeInt10(pNv->pInt); 1554 return FALSE; 1555 } 1556#ifdef __powerpc__ /* XXX probably MI */ 1557 vgaHWSetMmioFuncs(VGAHWPTR(pScrn), (char *)pNv->IOAddress, 0); 1558#else 1559 vgaHWSetStdFuncs(VGAHWPTR(pScrn)); 1560#endif 1561 1562 /* We use a programmable clock */ 1563 pScrn->progClock = TRUE; 1564 1565 /* Collect all of the relevant option flags (fill in pScrn->options) */ 1566 xf86CollectOptions(pScrn, NULL); 1567 1568 /* Process the options */ 1569 if (!(pNv->Options = malloc(sizeof(NVOptions)))) 1570 return FALSE; 1571 memcpy(pNv->Options, NVOptions, sizeof(NVOptions)); 1572 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options); 1573 1574 /* Set the bits per RGB for 8bpp mode */ 1575 if (pScrn->depth == 8) 1576 pScrn->rgbBits = 8; 1577 1578 from = X_DEFAULT; 1579 pNv->HWCursor = TRUE; 1580 /* 1581 * The preferred method is to use the "hw cursor" option as a tri-state 1582 * option, with the default set above. 1583 */ 1584 if (xf86GetOptValBool(pNv->Options, OPTION_HW_CURSOR, &pNv->HWCursor)) { 1585 from = X_CONFIG; 1586 } 1587 /* For compatibility, accept this too (as an override) */ 1588 if (xf86ReturnOptValBool(pNv->Options, OPTION_SW_CURSOR, FALSE)) { 1589 from = X_CONFIG; 1590 pNv->HWCursor = FALSE; 1591 } 1592 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 1593 pNv->HWCursor ? "HW" : "SW"); 1594 1595 pNv->FpScale = TRUE; 1596 if (xf86GetOptValBool(pNv->Options, OPTION_FP_SCALE, &pNv->FpScale)) { 1597 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Flat panel scaling %s\n", 1598 pNv->FpScale ? "on" : "off"); 1599 } 1600 if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) { 1601 pNv->NoAccel = TRUE; 1602 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 1603 } 1604 if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) { 1605 pNv->ShadowFB = TRUE; 1606 pNv->NoAccel = TRUE; 1607 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1608 "Using \"Shadow Framebuffer\" - acceleration disabled\n"); 1609 } 1610 if (xf86ReturnOptValBool(pNv->Options, OPTION_FBDEV, FALSE)) { 1611 pNv->FBDev = TRUE; 1612 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1613 "Using framebuffer device\n"); 1614 } 1615 if (pNv->FBDev) { 1616 /* check for linux framebuffer device */ 1617 if (!xf86LoadSubModule(pScrn, "fbdevhw")) { 1618 xf86FreeInt10(pNv->pInt); 1619 return FALSE; 1620 } 1621 1622 if (!fbdevHWInit(pScrn, pNv->PciInfo, NULL)) { 1623 xf86FreeInt10(pNv->pInt); 1624 return FALSE; 1625 } 1626 pScrn->SwitchMode = fbdevHWSwitchModeWeak(); 1627 pScrn->AdjustFrame = fbdevHWAdjustFrameWeak(); 1628 pScrn->EnterVT = NVEnterVTFBDev; 1629 pScrn->LeaveVT = fbdevHWLeaveVTWeak(); 1630 pScrn->ValidMode = fbdevHWValidModeWeak(); 1631 } 1632 pNv->Rotate = 0; 1633 pNv->RandRRotation = FALSE; 1634 if ((s = xf86GetOptValString(pNv->Options, OPTION_ROTATE))) { 1635 if(!xf86NameCmp(s, "CW")) { 1636 pNv->ShadowFB = TRUE; 1637 pNv->NoAccel = TRUE; 1638 pNv->HWCursor = FALSE; 1639 pNv->Rotate = 1; 1640 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1641 "Rotating screen clockwise - acceleration disabled\n"); 1642 } else 1643 if(!xf86NameCmp(s, "CCW")) { 1644 pNv->ShadowFB = TRUE; 1645 pNv->NoAccel = TRUE; 1646 pNv->HWCursor = FALSE; 1647 pNv->Rotate = -1; 1648 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1649 "Rotating screen counter clockwise - acceleration disabled\n"); 1650 } else 1651 if(!xf86NameCmp(s, "RandR")) { 1652#ifdef RANDR 1653 pNv->ShadowFB = TRUE; 1654 pNv->NoAccel = TRUE; 1655 pNv->HWCursor = FALSE; 1656 pNv->RandRRotation = TRUE; 1657 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1658 "Using RandR rotation - acceleration disabled\n"); 1659#else 1660 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1661 "This driver was not compiled with support for the Resize and " 1662 "Rotate extension. Cannot honor 'Option \"Rotate\" " 1663 "\"RandR\"'.\n"); 1664#endif 1665 } else { 1666 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1667 "\"%s\" is not a valid value for Option \"Rotate\"\n", s); 1668 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1669 "Valid options are \"CW\", \"CCW\", and \"RandR\"\n"); 1670 } 1671 } 1672 1673 if(xf86GetOptValInteger(pNv->Options, OPTION_VIDEO_KEY, &(pNv->videoKey))) { 1674 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", 1675 pNv->videoKey); 1676 } else { 1677 pNv->videoKey = (1 << pScrn->offset.red) | 1678 (1 << pScrn->offset.green) | 1679 (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue); 1680 } 1681 1682 if (xf86GetOptValBool(pNv->Options, OPTION_FLAT_PANEL, &(pNv->FlatPanel))) { 1683 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "forcing %s usage\n", 1684 pNv->FlatPanel ? "DFP" : "CRTC"); 1685 } else { 1686 pNv->FlatPanel = -1; /* autodetect later */ 1687 } 1688 1689 pNv->FPDither = FALSE; 1690 if (xf86GetOptValBool(pNv->Options, OPTION_FP_DITHER, &(pNv->FPDither))) 1691 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "enabling flat panel dither\n"); 1692 1693 if (xf86GetOptValInteger(pNv->Options, OPTION_CRTC_NUMBER, 1694 &pNv->CRTCnumber)) 1695 { 1696 if((pNv->CRTCnumber < 0) || (pNv->CRTCnumber > 1)) { 1697 pNv->CRTCnumber = -1; 1698 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1699 "Invalid CRTC number. Must be 0 or 1\n"); 1700 } 1701 } else { 1702 pNv->CRTCnumber = -1; /* autodetect later */ 1703 } 1704 1705 1706 if (xf86GetOptValInteger(pNv->Options, OPTION_FP_TWEAK, 1707 &pNv->PanelTweak)) 1708 { 1709 pNv->usePanelTweak = TRUE; 1710 } else { 1711 pNv->usePanelTweak = FALSE; 1712 } 1713 1714 if (xf86ReturnOptValBool(pNv->Options, OPTION_DUALHEAD, FALSE)) { 1715 if (pNv->FBDev) 1716 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1717 "FBDev and Dualhead are incompatible.\n"); 1718 else 1719 pNv->VBEDualhead = TRUE; 1720 } 1721 1722 if (pNv->VBEDualhead) { 1723 if (!xf86LoadSubModule(pScrn, "vbe")) { 1724 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1725 "Couldn't load the VBE module and Dualhead is " 1726 "enabled.\n"); 1727 return FALSE; 1728 } 1729 pNv->pVbe = VBEExtendedInit(NULL, pNv->pEnt->index, 1730 SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); 1731 if (!pNv->pVbe) return FALSE; 1732 1733 pNv->pVbeInfo = VBEGetVBEInfo(pNv->pVbe); 1734 if (!pNv->pVbeInfo) return FALSE; 1735 1736 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1737 "Using VBE dual-head mode.\n"); 1738 1739 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1740 "Using software cursor.\n"); 1741 pNv->HWCursor = FALSE; 1742 1743 pScrn->SwitchMode = NVSwitchModeVBE; 1744 pScrn->EnterVT = NVEnterVTVBE; 1745 pScrn->LeaveVT = NVLeaveVTVBE; 1746 pScrn->ValidMode = NULL; 1747 } 1748 1749 if (pNv->pEnt->device->MemBase != 0) { 1750 /* Require that the config file value matches one of the PCI values. */ 1751 if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->MemBase)) { 1752 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1753 "MemBase 0x%08lX doesn't match any PCI base register.\n", 1754 pNv->pEnt->device->MemBase); 1755 xf86FreeInt10(pNv->pInt); 1756 NVFreeRec(pScrn); 1757 return FALSE; 1758 } 1759 pNv->FbAddress = pNv->pEnt->device->MemBase; 1760 from = X_CONFIG; 1761 } else { 1762 if (MEMBASE(pNv->PciInfo, 1) != 0) { 1763 pNv->FbAddress = MEMBASE(pNv->PciInfo, 1) & 0xff800000; 1764 from = X_PROBED; 1765 } else { 1766 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1767 "No valid FB address in PCI config space\n"); 1768 xf86FreeInt10(pNv->pInt); 1769 NVFreeRec(pScrn); 1770 return FALSE; 1771 } 1772 } 1773 xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", 1774 (unsigned long)pNv->FbAddress); 1775 1776 if (pNv->pEnt->device->IOBase != 0) { 1777 /* Require that the config file value matches one of the PCI values. */ 1778 if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->IOBase)) { 1779 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1780 "IOBase 0x%08lX doesn't match any PCI base register.\n", 1781 pNv->pEnt->device->IOBase); 1782 xf86FreeInt10(pNv->pInt); 1783 NVFreeRec(pScrn); 1784 return FALSE; 1785 } 1786 pNv->IOAddress = pNv->pEnt->device->IOBase; 1787 from = X_CONFIG; 1788 } else { 1789 if (MEMBASE(pNv->PciInfo, 0) != 0) { 1790 pNv->IOAddress = MEMBASE(pNv->PciInfo, 0) & 0xffffc000; 1791 from = X_PROBED; 1792 } else { 1793 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1794 "No valid MMIO address in PCI config space\n"); 1795 xf86FreeInt10(pNv->pInt); 1796 NVFreeRec(pScrn); 1797 return FALSE; 1798 } 1799 } 1800 xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n", 1801 (unsigned long)pNv->IOAddress); 1802 1803#ifndef XSERVER_LIBPCIACCESS 1804 if (xf86RegisterResources(pNv->pEnt->index, NULL, ResExclusive)) { 1805 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1806 "xf86RegisterResources() found resource conflicts\n"); 1807 xf86FreeInt10(pNv->pInt); 1808 NVFreeRec(pScrn); 1809 return FALSE; 1810 } 1811#endif 1812 1813 switch (pNv->Chipset & 0x0ff0) { 1814 case 0x0100: /* GeForce 256 */ 1815 case 0x0110: /* GeForce2 MX */ 1816 case 0x0150: /* GeForce2 */ 1817 case 0x0170: /* GeForce4 MX */ 1818 case 0x0180: /* GeForce4 MX (8x AGP) */ 1819 case 0x01A0: /* nForce */ 1820 case 0x01F0: /* nForce2 */ 1821 pNv->Architecture = NV_ARCH_10; 1822 break; 1823 case 0x0200: /* GeForce3 */ 1824 case 0x0250: /* GeForce4 Ti */ 1825 case 0x0280: /* GeForce4 Ti (8x AGP) */ 1826 pNv->Architecture = NV_ARCH_20; 1827 break; 1828 case 0x0300: /* GeForce FX 5800 */ 1829 case 0x0310: /* GeForce FX 5600 */ 1830 case 0x0320: /* GeForce FX 5200 */ 1831 case 0x0330: /* GeForce FX 5900 */ 1832 case 0x0340: /* GeForce FX 5700 */ 1833 pNv->Architecture = NV_ARCH_30; 1834 break; 1835 case 0x0040: /* GeForce 6800 */ 1836 case 0x00C0: /* GeForce 6800 */ 1837 case 0x0120: /* GeForce 6800 */ 1838 case 0x0140: /* GeForce 6600 */ 1839 case 0x0160: /* GeForce 6200 */ 1840 case 0x01D0: /* GeForce 7200, 7300, 7400 */ 1841 case 0x0090: /* GeForce 7800 */ 1842 case 0x0210: /* GeForce 6800 */ 1843 case 0x0220: /* GeForce 6200 */ 1844 case 0x0290: /* GeForce 7900 */ 1845 case 0x0390: /* GeForce 7600 */ 1846 case 0x0240: /* GeForce 6100 */ 1847 case 0x0530: /* GeForce 7050, 7025 */ 1848 case 0x03D0: 1849 pNv->Architecture = NV_ARCH_40; 1850 break; 1851 default: 1852 pNv->Architecture = NV_ARCH_04; 1853 break; 1854 } 1855 1856 pNv->alphaCursor = (pNv->Architecture >= NV_ARCH_10) && 1857 ((pNv->Chipset & 0x0ff0) != 0x0100); 1858 1859 if ((pScrn->monitor->nHsync == 0) && 1860 (pScrn->monitor->nVrefresh == 0)) 1861 config_mon_rates = FALSE; 1862 else 1863 config_mon_rates = TRUE; 1864 1865 NVCommonSetup(pScrn); 1866 1867 if (pNv->FBDev) { 1868 pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024; 1869 } else { 1870 pScrn->videoRam = pNv->RamAmountKBytes; 1871 } 1872 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kBytes\n", 1873 pScrn->videoRam); 1874 1875 pNv->FbMapSize = pScrn->videoRam * 1024; 1876 1877 /* 1878 * If the driver can do gamma correction, it should call xf86SetGamma() 1879 * here. 1880 */ 1881 1882 { 1883 Gamma zeros = {0.0, 0.0, 0.0}; 1884 1885 if (!xf86SetGamma(pScrn, zeros)) { 1886 xf86FreeInt10(pNv->pInt); 1887 return FALSE; 1888 } 1889 } 1890 1891 if(pNv->Architecture >= NV_ARCH_40) 1892 pNv->FbUsableSize = pNv->FbMapSize - (560 * 1024); 1893 else 1894 pNv->FbUsableSize = pNv->FbMapSize - (128 * 1024); 1895 pNv->ScratchBufferSize = (pNv->Architecture < NV_ARCH_10) ? 8192 : 16384; 1896 pNv->ScratchBufferStart = pNv->FbUsableSize - pNv->ScratchBufferSize; 1897 pNv->CursorStart = pNv->FbUsableSize + (32 * 1024); 1898 1899 /* 1900 * Setup the ClockRanges, which describe what clock ranges are available, 1901 * and what sort of modes they can be used for. 1902 */ 1903 1904 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 1905 clockRanges->next = NULL; 1906 clockRanges->minClock = pNv->MinVClockFreqKHz; 1907 clockRanges->maxClock = pNv->MaxVClockFreqKHz; 1908 clockRanges->clockIndex = -1; /* programmable */ 1909 clockRanges->doubleScanAllowed = TRUE; 1910 if((pNv->Architecture == NV_ARCH_20) || 1911 ((pNv->Architecture == NV_ARCH_10) && 1912 ((pNv->Chipset & 0x0ff0) != 0x0100) && 1913 ((pNv->Chipset & 0x0ff0) != 0x0150))) 1914 { 1915 /* HW is broken */ 1916 clockRanges->interlaceAllowed = FALSE; 1917 } else { 1918 clockRanges->interlaceAllowed = TRUE; 1919 } 1920 1921 if(pNv->FlatPanel == 1) { 1922 clockRanges->interlaceAllowed = FALSE; 1923 clockRanges->doubleScanAllowed = FALSE; 1924 } 1925 1926 if(pNv->Architecture < NV_ARCH_10) { 1927 max_width = (pScrn->bitsPerPixel > 16) ? 2032 : 2048; 1928 max_height = 2048; 1929 } else { 1930 max_width = (pScrn->bitsPerPixel > 16) ? 4080 : 4096; 1931 max_height = 4096; 1932 } 1933 1934 /* If DFP, add a modeline corresponding to its panel size */ 1935 if (pNv->FlatPanel && !pNv->Television && pNv->fpWidth && pNv->fpHeight) { 1936 DisplayModePtr Mode; 1937 1938 Mode = xf86CVTMode(pNv->fpWidth, pNv->fpHeight, 60.00, TRUE, FALSE); 1939 Mode->type = M_T_DRIVER; 1940 xf86SetModeDefaultName(Mode); 1941 1942 pScrn->monitor->Modes = NVModesAdd(pScrn->monitor->Modes, Mode); 1943 1944 if (!config_mon_rates) { 1945 if (!Mode->HSync) 1946 Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal); 1947 if (!Mode->VRefresh) 1948 Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / 1949 ((float) (Mode->HTotal * Mode->VTotal)); 1950 1951 if (Mode->HSync < pScrn->monitor->hsync[0].lo) 1952 pScrn->monitor->hsync[0].lo = Mode->HSync; 1953 if (Mode->HSync > pScrn->monitor->hsync[0].hi) 1954 pScrn->monitor->hsync[0].hi = Mode->HSync; 1955 if (Mode->VRefresh < pScrn->monitor->vrefresh[0].lo) 1956 pScrn->monitor->vrefresh[0].lo = Mode->VRefresh; 1957 if (Mode->VRefresh > pScrn->monitor->vrefresh[0].hi) 1958 pScrn->monitor->vrefresh[0].hi = Mode->VRefresh; 1959 1960 pScrn->monitor->nHsync = 1; 1961 pScrn->monitor->nVrefresh = 1; 1962 } 1963 } 1964 1965 /* 1966 * xf86ValidateModes will check that the mode HTotal and VTotal values 1967 * don't exceed the chipset's limit if pScrn->maxHValue and 1968 * pScrn->maxVValue are set. Since our NVValidMode() already takes 1969 * care of this, we don't worry about setting them here. 1970 */ 1971 if (pNv->VBEDualhead) { 1972 pScrn->modePool = VBEGetModePool(pScrn, pNv->pVbe, pNv->pVbeInfo, 1973 V_MODETYPE_VBE); 1974 1975 VBESetModeNames(pScrn->modePool); 1976 i = VBEValidateModes(pScrn, pScrn->monitor->Modes, 1977 pScrn->display->modes, clockRanges, 1978 NULL, 256, max_width, 1979 512, 128, max_height, 1980 pScrn->display->virtualX, 1981 pScrn->display->virtualY, 1982 pNv->ScratchBufferStart, 1983 LOOKUP_BEST_REFRESH); 1984 if (i > 0) 1985 VBESetModeParameters(pScrn, pNv->pVbe); 1986 } else { 1987 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 1988 pScrn->display->modes, clockRanges, 1989 NULL, 256, max_width, 1990 512, 128, max_height, 1991 pScrn->display->virtualX, 1992 pScrn->display->virtualY, 1993 pNv->ScratchBufferStart, 1994 LOOKUP_BEST_REFRESH); 1995 } 1996 1997 if (i < 1 && pNv->FBDev) { 1998 fbdevHWUseBuildinMode(pScrn); 1999 pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ 2000 i = 1; 2001 } 2002 if (i == -1) { 2003 xf86FreeInt10(pNv->pInt); 2004 NVFreeRec(pScrn); 2005 return FALSE; 2006 } 2007 2008 /* Prune the modes marked as invalid */ 2009 xf86PruneDriverModes(pScrn); 2010 2011 if (i == 0 || pScrn->modes == NULL) { 2012 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 2013 xf86FreeInt10(pNv->pInt); 2014 NVFreeRec(pScrn); 2015 return FALSE; 2016 } 2017 2018 /* 2019 * Set the CRTC parameters for all of the modes based on the type 2020 * of mode, and the chipset's interlace requirements. 2021 * 2022 * Calling this is required if the mode->Crtc* values are used by the 2023 * driver and if the driver doesn't provide code to set them. They 2024 * are not pre-initialised at all. 2025 */ 2026 xf86SetCrtcForModes(pScrn, 0); 2027 2028 if (pNv->VBEDualhead) { 2029 DisplayModePtr p = pScrn->modes; 2030 2031 /* 2032 * Loop through modes and double their widths. Stash the real width in 2033 * CrtcHDisplay. Also adjust the screen dimensions. 2034 */ 2035 do { 2036 p->CrtcHDisplay = p->HDisplay; 2037 p->HDisplay *= 2; 2038 } while ((p = p->next) != pScrn->modes); 2039 2040 pScrn->virtualX *= 2; 2041 pScrn->displayWidth *= 2; 2042 } 2043 2044 /* Set the current mode to the first in the list */ 2045 pScrn->currentMode = pScrn->modes; 2046 2047 /* Print the list of modes being used */ 2048 xf86PrintModes(pScrn); 2049 2050 /* Set display resolution */ 2051 xf86SetDpi(pScrn, 0, 0); 2052 2053 2054 /* 2055 * XXX This should be taken into account in some way in the mode valdation 2056 * section. 2057 */ 2058 2059 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 2060 xf86FreeInt10(pNv->pInt); 2061 NVFreeRec(pScrn); 2062 return FALSE; 2063 } 2064 2065 /* Load XAA if needed */ 2066 if (!pNv->NoAccel) { 2067 pNv->UseEXA = 1; 2068#ifdef HAVE_XAA_H 2069 if (!xf86LoadSubModule(pScrn, "xaa")) { 2070 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Falling back to shadowfb\n"); 2071 pNv->NoAccel = 1; 2072 pNv->ShadowFB = 1; 2073 } else 2074 pNv->UseEXA = 0; 2075#else 2076 if (!xf86LoadSubModule(pScrn, "exa")) { 2077 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Falling back to shadowfb\n"); 2078 pNv->NoAccel = 1; 2079 pNv->UseEXA = 0; 2080 pNv->ShadowFB = 1; 2081 } 2082#endif 2083 } 2084 2085 /* Load ramdac if needed */ 2086 if (pNv->HWCursor) { 2087 if (!xf86LoadSubModule(pScrn, "ramdac")) { 2088 xf86FreeInt10(pNv->pInt); 2089 NVFreeRec(pScrn); 2090 return FALSE; 2091 } 2092 } 2093 2094 /* Load shadowfb if needed */ 2095 if (pNv->ShadowFB) { 2096 if (!xf86LoadSubModule(pScrn, "shadow")) { 2097 xf86FreeInt10(pNv->pInt); 2098 NVFreeRec(pScrn); 2099 return FALSE; 2100 } 2101 } 2102 2103 pNv->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; 2104 pNv->CurrentLayout.depth = pScrn->depth; 2105 pNv->CurrentLayout.displayWidth = pScrn->displayWidth; 2106 pNv->CurrentLayout.weight.red = pScrn->weight.red; 2107 pNv->CurrentLayout.weight.green = pScrn->weight.green; 2108 pNv->CurrentLayout.weight.blue = pScrn->weight.blue; 2109 pNv->CurrentLayout.mode = pScrn->currentMode; 2110 2111 xf86FreeInt10(pNv->pInt); 2112 2113 pNv->pInt = NULL; 2114 return TRUE; 2115} 2116 2117 2118/* 2119 * Map the framebuffer and MMIO memory. 2120 */ 2121 2122static Bool 2123NVMapMem(ScrnInfoPtr pScrn) 2124{ 2125 NVPtr pNv = NVPTR(pScrn); 2126 2127#ifdef XSERVER_LIBPCIACCESS 2128 void *tmp; 2129 2130 pci_device_map_range(pNv->PciInfo, pNv->FbAddress, pNv->FbMapSize, 2131 PCI_DEV_MAP_FLAG_WRITABLE | 2132 PCI_DEV_MAP_FLAG_WRITE_COMBINE, &tmp); 2133 pNv->FbBase = tmp; 2134#else 2135 pNv->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 2136 pNv->PciTag, pNv->FbAddress, 2137 pNv->FbMapSize); 2138#endif 2139 if (pNv->FbBase == NULL) 2140 return FALSE; 2141 2142 pNv->FbStart = pNv->FbBase; 2143 2144 return TRUE; 2145} 2146 2147static Bool 2148NVMapMemFBDev(ScrnInfoPtr pScrn) 2149{ 2150 NVPtr pNv; 2151 2152 pNv = NVPTR(pScrn); 2153 2154 pNv->FbBase = fbdevHWMapVidmem(pScrn); 2155 if (pNv->FbBase == NULL) 2156 return FALSE; 2157 2158 pNv->FbStart = pNv->FbBase; 2159 2160 return TRUE; 2161} 2162 2163/* 2164 * Unmap the framebuffer and MMIO memory. 2165 */ 2166 2167static Bool 2168NVUnmapMem(ScrnInfoPtr pScrn) 2169{ 2170 NVPtr pNv; 2171 2172 pNv = NVPTR(pScrn); 2173 2174#ifdef XSERVER_LIBPCIACCESS 2175 pci_device_unmap_range(pNv->PciInfo, pNv->FbBase, pNv->FbMapSize); 2176#else 2177 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pNv->FbBase, pNv->FbMapSize); 2178#endif 2179 pNv->FbBase = NULL; 2180 pNv->FbStart = NULL; 2181 2182 return TRUE; 2183} 2184 2185 2186/* 2187 * Initialise a new mode. 2188 */ 2189 2190static Bool 2191NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 2192{ 2193 vgaHWPtr hwp = VGAHWPTR(pScrn); 2194 vgaRegPtr vgaReg; 2195 NVPtr pNv = NVPTR(pScrn); 2196 NVRegPtr nvReg; 2197 2198 /* Initialise the ModeReg values */ 2199 if (!vgaHWInit(pScrn, mode)) 2200 return FALSE; 2201 pScrn->vtSema = TRUE; 2202 2203 vgaReg = &hwp->ModeReg; 2204 nvReg = &pNv->ModeReg; 2205 2206 if(!NVDACInit(pScrn, mode)) 2207 return FALSE; 2208 2209 NVLockUnlock(pNv, 0); 2210 if(pNv->twoHeads) { 2211 VGA_WR08(pNv->PCIO, 0x03D4, 0x44); 2212 VGA_WR08(pNv->PCIO, 0x03D5, nvReg->crtcOwner); 2213 NVLockUnlock(pNv, 0); 2214 } 2215 2216 /* Program the registers */ 2217 vgaHWProtect(pScrn, TRUE); 2218 2219 NVDACRestore(pScrn, vgaReg, nvReg, FALSE); 2220 2221#if X_BYTE_ORDER == X_BIG_ENDIAN 2222 /* turn on LFB swapping */ 2223 { 2224 unsigned char tmp; 2225 2226 VGA_WR08(pNv->PCIO, 0x3d4, 0x46); 2227 tmp = VGA_RD08(pNv->PCIO, 0x3d5); 2228 tmp |= (1 << 7); 2229 VGA_WR08(pNv->PCIO, 0x3d5, tmp); 2230 } 2231#endif 2232 2233 NVResetGraphics(pScrn); 2234 2235 vgaHWProtect(pScrn, FALSE); 2236 2237 pNv->CurrentLayout.mode = mode; 2238 2239 return TRUE; 2240} 2241 2242static Bool 2243NVSetModeVBE(ScrnInfoPtr pScrn, DisplayModePtr pMode) 2244{ 2245 NVPtr pNv = NVPTR(pScrn); 2246 VbeModeInfoData *data; 2247 int mode; 2248 2249 data = (VbeModeInfoData*)pMode->Private; 2250 mode = data->mode | 1 << 14; 2251 2252 if(!VBESetVBEMode(pNv->pVbe, mode, data->block)) 2253 return FALSE; 2254 pNv->PCRTC0[0x820/4] = pNv->PCRTC0[0x2820/4] = 2255 pScrn->displayWidth * (pScrn->bitsPerPixel / 8); 2256 pNv->vbeCRTC1Offset = pMode->CrtcHDisplay * (pScrn->bitsPerPixel / 8); 2257 2258 pScrn->vtSema = TRUE; 2259 2260 NVLoadStateExt(pNv, NULL); 2261 NVResetGraphics(pScrn); 2262 2263 pNv->CurrentLayout.mode = pMode; 2264 2265 return TRUE; 2266} 2267 2268/* 2269 * Restore the initial (text) mode. 2270 */ 2271static void 2272NVRestore(ScrnInfoPtr pScrn) 2273{ 2274 vgaHWPtr hwp = VGAHWPTR(pScrn); 2275 vgaRegPtr vgaReg = &hwp->SavedReg; 2276 NVPtr pNv = NVPTR(pScrn); 2277 NVRegPtr nvReg = &pNv->SavedReg; 2278 2279 if(pNv->HWCursor) { 2280 NVShowHideCursor(pNv, 0); 2281 sleep(1); 2282 } 2283 NVLockUnlock(pNv, 0); 2284 2285 if(pNv->twoHeads) { 2286 VGA_WR08(pNv->PCIO, 0x03D4, 0x44); 2287 VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3); 2288 NVLockUnlock(pNv, 0); 2289 } 2290 2291 /* Only restore text mode fonts/text for the primary card */ 2292 vgaHWProtect(pScrn, TRUE); 2293 NVDACRestore(pScrn, vgaReg, nvReg, pNv->Primary); 2294 if(pNv->twoHeads) { 2295 VGA_WR08(pNv->PCIO, 0x03D4, 0x44); 2296 VGA_WR08(pNv->PCIO, 0x03D5, nvReg->crtcOwner); 2297 } 2298 vgaHWProtect(pScrn, FALSE); 2299} 2300 2301static void NVBacklightEnable(NVPtr pNv, Bool on) 2302{ 2303 /* This is done differently on each laptop. Here we 2304 define the ones we know for sure. */ 2305 2306#if defined(__powerpc__) 2307 if((pNv->Chipset == 0x10DE0179) || 2308 (pNv->Chipset == 0x10DE0189) || 2309 (pNv->Chipset == 0x10DE0329)) 2310 { 2311 /* NV17,18,34 Apple iMac, iBook, PowerBook */ 2312 CARD32 tmp_pmc, tmp_pcrt; 2313 tmp_pmc = pNv->PMC[0x10F0/4] & 0x7FFFFFFF; 2314 tmp_pcrt = pNv->PCRTC0[0x081C/4] & 0xFFFFFFFC; 2315 if(on) { 2316 tmp_pmc |= (1 << 31); 2317 tmp_pcrt |= 0x1; 2318 } 2319 pNv->PMC[0x10F0/4] = tmp_pmc; 2320 pNv->PCRTC0[0x081C/4] = tmp_pcrt; 2321 } 2322#endif 2323 2324 if(pNv->LVDS) { 2325 if(pNv->twoHeads) { 2326 if((pNv->Chipset & 0x0ff0) != 0x0110) { 2327 pNv->PMC[0x130C/4] = on ? 3 : 7; 2328 } else if(SUBVENDOR_ID(pNv->PciInfo) == 0x1028 && 2329 SUBDEVICE_ID(pNv->PciInfo) == 0xd4) { 2330 // Dell Inspiron 8200, GeForce2 Go 2331 CARD32 tmp_pcrt = pNv->PCRTC0[0x081C/4] & 0xFFFFFFFC; 2332 if(on) 2333 tmp_pcrt |= 0x1; 2334 pNv->PCRTC0[0x081C/4] = tmp_pcrt; 2335 } 2336 } 2337 } else { 2338 CARD32 fpcontrol; 2339 2340 fpcontrol = pNv->PRAMDAC[0x0848/4] & 0xCfffffCC; 2341 2342 /* cut the TMDS output */ 2343 if(on) fpcontrol |= pNv->fpSyncs; 2344 else fpcontrol |= 0x20000022; 2345 2346 pNv->PRAMDAC[0x0848/4] = fpcontrol; 2347 } 2348} 2349 2350static void 2351NVDPMSSetLCD(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) 2352{ 2353 NVPtr pNv = NVPTR(pScrn); 2354 2355 if (!pScrn->vtSema) return; 2356 2357 vgaHWDPMSSet(pScrn, PowerManagementMode, flags); 2358 2359 switch (PowerManagementMode) { 2360 case DPMSModeStandby: /* HSync: Off, VSync: On */ 2361 case DPMSModeSuspend: /* HSync: On, VSync: Off */ 2362 case DPMSModeOff: /* HSync: Off, VSync: Off */ 2363 NVBacklightEnable(pNv, 0); 2364 break; 2365 case DPMSModeOn: /* HSync: On, VSync: On */ 2366 NVBacklightEnable(pNv, 1); 2367 default: 2368 break; 2369 } 2370} 2371 2372 2373static void 2374NVDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) 2375{ 2376 unsigned char crtc1A; 2377 vgaHWPtr hwp = VGAHWPTR(pScrn); 2378 2379 if (!pScrn->vtSema) return; 2380 2381 crtc1A = hwp->readCrtc(hwp, 0x1A) & ~0xC0; 2382 2383 switch (PowerManagementMode) { 2384 case DPMSModeStandby: /* HSync: Off, VSync: On */ 2385 crtc1A |= 0x80; 2386 break; 2387 case DPMSModeSuspend: /* HSync: On, VSync: Off */ 2388 crtc1A |= 0x40; 2389 break; 2390 case DPMSModeOff: /* HSync: Off, VSync: Off */ 2391 crtc1A |= 0xC0; 2392 break; 2393 case DPMSModeOn: /* HSync: On, VSync: On */ 2394 default: 2395 break; 2396 } 2397 2398 /* vgaHWDPMSSet will merely cut the dac output */ 2399 vgaHWDPMSSet(pScrn, PowerManagementMode, flags); 2400 2401 hwp->writeCrtc(hwp, 0x1A, crtc1A); 2402} 2403 2404static Bool 2405NVCreateScreenResources(ScreenPtr pScreen) 2406{ 2407 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2408 NVPtr pNv = NVPTR(pScrn); 2409 PixmapPtr pPixmap; 2410 Bool ret; 2411 2412 pScreen->CreateScreenResources = pNv->CreateScreenResources; 2413 ret = pScreen->CreateScreenResources(pScreen); 2414 pScreen->CreateScreenResources = NVCreateScreenResources; 2415 2416 if (!ret) 2417 return FALSE; 2418 2419 pPixmap = pScreen->GetScreenPixmap(pScreen); 2420 2421 if (!shadowAdd(pScreen, pPixmap, NVShadowUpdate, 2422 NULL, 0, NULL)) { 2423 return FALSE; 2424 } 2425 return TRUE; 2426} 2427 2428static Bool 2429NVShadowInit(ScreenPtr pScreen) 2430{ 2431 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2432 NVPtr pNv = NVPTR(pScrn); 2433 2434 if (!shadowSetup(pScreen)) 2435 return FALSE; 2436 pNv->CreateScreenResources = pScreen->CreateScreenResources; 2437 pScreen->CreateScreenResources = NVCreateScreenResources; 2438 2439 return TRUE; 2440} 2441 2442 2443/* Mandatory */ 2444 2445/* This gets called at the start of each server generation */ 2446 2447static Bool 2448NVScreenInit(SCREEN_INIT_ARGS_DECL) 2449{ 2450 ScrnInfoPtr pScrn; 2451 vgaHWPtr hwp; 2452 NVPtr pNv; 2453 int ret; 2454 VisualPtr visual; 2455 unsigned char *FBStart; 2456 int width, height, displayWidth, offscreenHeight, shadowHeight; 2457 BoxRec AvailFBArea; 2458 2459 /* 2460 * First get the ScrnInfoRec 2461 */ 2462 pScrn = xf86ScreenToScrn(pScreen); 2463 2464 hwp = VGAHWPTR(pScrn); 2465 pNv = NVPTR(pScrn); 2466 2467 /* Map the NV memory and MMIO areas */ 2468 if (pNv->FBDev) { 2469 if (!NVMapMemFBDev(pScrn)) { 2470 return FALSE; 2471 } 2472 } else { 2473 if (!NVMapMem(pScrn)) { 2474 return FALSE; 2475 } 2476 } 2477 2478 /* Map the VGA memory when the primary video */ 2479#ifndef AVOID_VGAHW 2480 if (pNv->Primary && !pNv->FBDev) { 2481 hwp->MapSize = 0x10000; 2482 if (!vgaHWMapMem(pScrn)) 2483 return FALSE; 2484 } 2485#endif 2486 2487 if (pNv->FBDev) { 2488 fbdevHWSave(pScrn); 2489 if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) 2490 return FALSE; 2491 } else if (pNv->VBEDualhead) { 2492 NVSaveRestoreVBE(pScrn, MODE_SAVE); 2493 if (!NVSetModeVBE(pScrn, pScrn->currentMode)) 2494 return FALSE; 2495 } else { 2496 /* Save the current state */ 2497 NVSave(pScrn); 2498 /* Initialise the first mode */ 2499 if (!NVModeInit(pScrn, pScrn->currentMode)) 2500 return FALSE; 2501 } 2502 2503 /* Darken the screen for aesthetic reasons and set the viewport */ 2504 NVSaveScreen(pScreen, SCREEN_SAVER_ON); 2505 pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 2506 2507 /* 2508 * The next step is to setup the screen's visuals, and initialise the 2509 * framebuffer code. In cases where the framebuffer's default 2510 * choices for things like visual layouts and bits per RGB are OK, 2511 * this may be as simple as calling the framebuffer's ScreenInit() 2512 * function. If not, the visuals will need to be setup before calling 2513 * a fb ScreenInit() function and fixed up after. 2514 * 2515 * For most PC hardware at depths >= 8, the defaults that fb uses 2516 * are not appropriate. In this driver, we fixup the visuals after. 2517 */ 2518 2519 /* 2520 * Reset the visual list. 2521 */ 2522 miClearVisualTypes(); 2523 2524 /* Setup the visuals we support. */ 2525 2526 if (!miSetVisualTypes(pScrn->depth, 2527 miGetDefaultVisualMask(pScrn->depth), 8, 2528 pScrn->defaultVisual)) 2529 return FALSE; 2530 if (!miSetPixmapDepths ()) return FALSE; 2531 2532 /* 2533 * Call the framebuffer layer's ScreenInit function, and fill in other 2534 * pScreen fields. 2535 */ 2536 2537 width = pScrn->virtualX; 2538 height = pScrn->virtualY; 2539 displayWidth = pScrn->displayWidth; 2540 2541 2542 if(pNv->Rotate) { 2543 height = pScrn->virtualX; 2544 width = pScrn->virtualY; 2545 } 2546 2547 /* If RandR rotation is enabled, leave enough space in the 2548 * framebuffer for us to rotate the screen dimensions without 2549 * changing the pitch. 2550 */ 2551 if(pNv->RandRRotation) 2552 shadowHeight = max(width, height); 2553 else 2554 shadowHeight = height; 2555 2556 if(pNv->ShadowFB) { 2557 pNv->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); 2558 pNv->ShadowPtr = malloc(pNv->ShadowPitch * shadowHeight); 2559 displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3); 2560 FBStart = pNv->ShadowPtr; 2561 } else { 2562 pNv->ShadowPtr = NULL; 2563 FBStart = pNv->FbStart; 2564 } 2565 2566 switch (pScrn->bitsPerPixel) { 2567 case 8: 2568 case 16: 2569 case 32: 2570 ret = fbScreenInit(pScreen, FBStart, width, height, 2571 pScrn->xDpi, pScrn->yDpi, 2572 displayWidth, pScrn->bitsPerPixel); 2573 break; 2574 default: 2575 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2576 "Internal error: invalid bpp (%d) in NVScreenInit\n", 2577 pScrn->bitsPerPixel); 2578 ret = FALSE; 2579 break; 2580 } 2581 if (!ret) 2582 return FALSE; 2583 2584 if (pScrn->bitsPerPixel > 8) { 2585 /* Fixup RGB ordering */ 2586 visual = pScreen->visuals + pScreen->numVisuals; 2587 while (--visual >= pScreen->visuals) { 2588 if ((visual->class | DynamicClass) == DirectColor) { 2589 visual->offsetRed = pScrn->offset.red; 2590 visual->offsetGreen = pScrn->offset.green; 2591 visual->offsetBlue = pScrn->offset.blue; 2592 visual->redMask = pScrn->mask.red; 2593 visual->greenMask = pScrn->mask.green; 2594 visual->blueMask = pScrn->mask.blue; 2595 } 2596 } 2597 } 2598 2599 fbPictureInit (pScreen, 0, 0); 2600 2601 xf86SetBlackWhitePixels(pScreen); 2602 2603 if(!pNv->ShadowFB) /* hardware cursor needs to wrap this layer */ 2604 NVDGAInit(pScreen); 2605 2606 offscreenHeight = pNv->ScratchBufferStart / 2607 (pScrn->displayWidth * pScrn->bitsPerPixel >> 3); 2608 if(offscreenHeight > 32767) 2609 offscreenHeight = 32767; 2610 2611#ifdef HAVE_XAA_H 2612 AvailFBArea.x1 = 0; 2613 AvailFBArea.y1 = 0; 2614 AvailFBArea.x2 = pScrn->displayWidth; 2615 AvailFBArea.y2 = offscreenHeight; 2616 xf86InitFBManager(pScreen, &AvailFBArea); 2617 2618 if (!pNv->NoAccel) 2619 NVAccelInit(pScreen); 2620#endif 2621 if ((!pNv->NoAccel) && (pNv->UseEXA == 1)) 2622 NvInitExa(pScreen); 2623 2624 xf86SetBackingStore(pScreen); 2625 xf86SetSilkenMouse(pScreen); 2626 2627 /* Initialize software cursor. 2628 Must precede creation of the default colormap */ 2629 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 2630 2631 /* Initialize HW cursor layer. 2632 Must follow software cursor initialization*/ 2633 if (pNv->HWCursor) { 2634 if(!NVCursorInit(pScreen)) 2635 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2636 "Hardware cursor initialization failed\n"); 2637 } 2638 2639 /* Initialise default colourmap */ 2640 if (!miCreateDefColormap(pScreen)) 2641 return FALSE; 2642 2643 /* Initialize colormap layer. 2644 Must follow initialization of the default colormap */ 2645 if(!xf86HandleColormaps(pScreen, 256, 8, 2646 (pNv->FBDev ? fbdevHWLoadPaletteWeak() : NVDACLoadPalette), 2647 NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) 2648 return FALSE; 2649 2650 if(pNv->ShadowFB) { 2651 RefreshAreaFuncPtr refreshArea = NVRefreshArea; 2652 2653 if(pNv->Rotate || pNv->RandRRotation) { 2654 pNv->PointerMoved = pScrn->PointerMoved; 2655 if(pNv->Rotate) 2656 pScrn->PointerMoved = NVPointerMoved; 2657 2658 switch(pScrn->bitsPerPixel) { 2659 case 8: refreshArea = NVRefreshArea8; break; 2660 case 16: refreshArea = NVRefreshArea16; break; 2661 case 32: refreshArea = NVRefreshArea32; break; 2662 } 2663 if(!pNv->RandRRotation) { 2664#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 24 2665 xf86DisableRandR(); 2666 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2667 "Driver rotation enabled, RandR disabled\n"); 2668#else 2669 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2670 "Driver rotation enabled\n"); 2671#endif 2672 } 2673 } 2674 pNv->refreshArea = refreshArea; 2675 NVShadowInit(pScreen); 2676 } 2677 2678 if(pNv->FlatPanel) 2679 xf86DPMSInit(pScreen, NVDPMSSetLCD, 0); 2680 else 2681 xf86DPMSInit(pScreen, NVDPMSSet, 0); 2682 2683 pScrn->memPhysBase = pNv->FbAddress; 2684 pScrn->fbOffset = 0; 2685 2686 if(pNv->Rotate == 0 && !pNv->RandRRotation) 2687 NVInitVideo(pScreen); 2688 2689 pScreen->SaveScreen = NVSaveScreen; 2690 2691 /* Wrap the current CloseScreen function */ 2692 pNv->CloseScreen = pScreen->CloseScreen; 2693 pScreen->CloseScreen = NVCloseScreen; 2694 2695 pNv->BlockHandler = pScreen->BlockHandler; 2696 pScreen->BlockHandler = NVBlockHandler; 2697 2698 pNv->accessEnabled = TRUE; 2699 pNv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess; 2700 pScrn->EnableDisableFBAccess = NVEnableDisableFBAccess; 2701 2702#ifdef RANDR 2703 /* Install our DriverFunc. We have to do it this way instead of using the 2704 * HaveDriverFuncs argument to xf86AddDriver, because InitOutput clobbers 2705 * pScrn->DriverFunc */ 2706 pScrn->DriverFunc = NVDriverFunc; 2707#endif 2708 2709 /* Report any unused options (only for the first generation) */ 2710 if (serverGeneration == 1) { 2711 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 2712 } 2713 return TRUE; 2714} 2715 2716static Bool 2717NVSaveScreen(ScreenPtr pScreen, int mode) 2718{ 2719 return vgaHWSaveScreen(pScreen, mode); 2720} 2721 2722static void 2723NVSave(ScrnInfoPtr pScrn) 2724{ 2725 NVPtr pNv = NVPTR(pScrn); 2726 NVRegPtr nvReg = &pNv->SavedReg; 2727 vgaHWPtr pVga = VGAHWPTR(pScrn); 2728 vgaRegPtr vgaReg = &pVga->SavedReg; 2729 2730 NVLockUnlock(pNv, 0); 2731 if(pNv->twoHeads) { 2732 VGA_WR08(pNv->PCIO, 0x03D4, 0x44); 2733 VGA_WR08(pNv->PCIO, 0x03D5, pNv->CRTCnumber * 0x3); 2734 NVLockUnlock(pNv, 0); 2735 } 2736 2737 NVDACSave(pScrn, vgaReg, nvReg, pNv->Primary); 2738} 2739 2740static void 2741NVSaveRestoreVBE(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function) 2742{ 2743 NVPtr pNv = NVPTR(pScrn); 2744 2745 if (function == MODE_SAVE) { 2746 VBEGetVBEMode(pNv->pVbe, &pNv->vbeMode); 2747 NVSave(pScrn); 2748 } else if (function == MODE_RESTORE) { 2749 NVRestore(pScrn); 2750 VBESetVBEMode(pNv->pVbe, pNv->vbeMode, NULL); 2751 } 2752} 2753 2754#ifdef RANDR 2755static Bool 2756NVRandRGetInfo(ScrnInfoPtr pScrn, Rotation *rotations) 2757{ 2758 NVPtr pNv = NVPTR(pScrn); 2759 2760 if(pNv->RandRRotation) 2761 *rotations = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_270; 2762 else 2763 *rotations = RR_Rotate_0; 2764 2765 return TRUE; 2766} 2767 2768static Bool 2769NVRandRSetConfig(ScrnInfoPtr pScrn, xorgRRConfig *config) 2770{ 2771 NVPtr pNv = NVPTR(pScrn); 2772 2773 switch(config->rotation) { 2774 case RR_Rotate_0: 2775 pNv->Rotate = 0; 2776 pScrn->PointerMoved = pNv->PointerMoved; 2777 break; 2778 2779 case RR_Rotate_90: 2780 pNv->Rotate = -1; 2781 pScrn->PointerMoved = NVPointerMoved; 2782 break; 2783 2784 case RR_Rotate_270: 2785 pNv->Rotate = 1; 2786 pScrn->PointerMoved = NVPointerMoved; 2787 break; 2788 2789 default: 2790 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2791 "Unexpected rotation in NVRandRSetConfig!\n"); 2792 pNv->Rotate = 0; 2793 pScrn->PointerMoved = pNv->PointerMoved; 2794 return FALSE; 2795 } 2796 2797 return TRUE; 2798} 2799 2800static Bool 2801NVDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer data) 2802{ 2803 switch(op) { 2804 case RR_GET_INFO: 2805 return NVRandRGetInfo(pScrn, (Rotation*)data); 2806 case RR_SET_CONFIG: 2807 return NVRandRSetConfig(pScrn, (xorgRRConfig*)data); 2808 default: 2809 return FALSE; 2810 } 2811 2812 return FALSE; 2813} 2814#endif /* RANDR */ 2815