Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.30-rc2 675 lines 19 kB view raw
1 /***************************************************************************\ 2|* *| 3|* Copyright 2003 NVIDIA, Corporation. All rights reserved. *| 4|* *| 5|* NOTICE TO USER: The source code is copyrighted under U.S. and *| 6|* international laws. Users and possessors of this source code are *| 7|* hereby granted a nonexclusive, royalty-free copyright license to *| 8|* use this code in individual and commercial software. *| 9|* *| 10|* Any use of this source code must include, in the user documenta- *| 11|* tion and internal comments to the code, notices to the end user *| 12|* as follows: *| 13|* *| 14|* Copyright 2003 NVIDIA, Corporation. All rights reserved. *| 15|* *| 16|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *| 17|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *| 18|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *| 19|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *| 20|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *| 21|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *| 22|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *| 23|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *| 24|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *| 25|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *| 26|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *| 27|* *| 28|* U.S. Government End Users. This source code is a "commercial *| 29|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *| 30|* consisting of "commercial computer software" and "commercial *| 31|* computer software documentation," as such terms are used in *| 32|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *| 33|* ment only as a commercial end item. Consistent with 48 C.F.R. *| 34|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *| 35|* all U.S. Government End Users acquire the source code with only *| 36|* those rights set forth herein. *| 37|* *| 38 \***************************************************************************/ 39 40/* 41 * GPL Licensing Note - According to Mark Vojkovich, author of the Xorg/ 42 * XFree86 'nv' driver, this source code is provided under MIT-style licensing 43 * where the source code is provided "as is" without warranty of any kind. 44 * The only usage restriction is for the copyright notices to be retained 45 * whenever code is used. 46 * 47 * Antonino Daplas <adaplas@pol.net> 2005-03-11 48 */ 49 50#include <video/vga.h> 51#include <linux/delay.h> 52#include <linux/pci.h> 53#include "nv_type.h" 54#include "nv_local.h" 55#include "nv_proto.h" 56/* 57 * Override VGA I/O routines. 58 */ 59void NVWriteCrtc(struct nvidia_par *par, u8 index, u8 value) 60{ 61 VGA_WR08(par->PCIO, par->IOBase + 0x04, index); 62 VGA_WR08(par->PCIO, par->IOBase + 0x05, value); 63} 64u8 NVReadCrtc(struct nvidia_par *par, u8 index) 65{ 66 VGA_WR08(par->PCIO, par->IOBase + 0x04, index); 67 return (VGA_RD08(par->PCIO, par->IOBase + 0x05)); 68} 69void NVWriteGr(struct nvidia_par *par, u8 index, u8 value) 70{ 71 VGA_WR08(par->PVIO, VGA_GFX_I, index); 72 VGA_WR08(par->PVIO, VGA_GFX_D, value); 73} 74u8 NVReadGr(struct nvidia_par *par, u8 index) 75{ 76 VGA_WR08(par->PVIO, VGA_GFX_I, index); 77 return (VGA_RD08(par->PVIO, VGA_GFX_D)); 78} 79void NVWriteSeq(struct nvidia_par *par, u8 index, u8 value) 80{ 81 VGA_WR08(par->PVIO, VGA_SEQ_I, index); 82 VGA_WR08(par->PVIO, VGA_SEQ_D, value); 83} 84u8 NVReadSeq(struct nvidia_par *par, u8 index) 85{ 86 VGA_WR08(par->PVIO, VGA_SEQ_I, index); 87 return (VGA_RD08(par->PVIO, VGA_SEQ_D)); 88} 89void NVWriteAttr(struct nvidia_par *par, u8 index, u8 value) 90{ 91 volatile u8 tmp; 92 93 tmp = VGA_RD08(par->PCIO, par->IOBase + 0x0a); 94 if (par->paletteEnabled) 95 index &= ~0x20; 96 else 97 index |= 0x20; 98 VGA_WR08(par->PCIO, VGA_ATT_IW, index); 99 VGA_WR08(par->PCIO, VGA_ATT_W, value); 100} 101u8 NVReadAttr(struct nvidia_par *par, u8 index) 102{ 103 volatile u8 tmp; 104 105 tmp = VGA_RD08(par->PCIO, par->IOBase + 0x0a); 106 if (par->paletteEnabled) 107 index &= ~0x20; 108 else 109 index |= 0x20; 110 VGA_WR08(par->PCIO, VGA_ATT_IW, index); 111 return (VGA_RD08(par->PCIO, VGA_ATT_R)); 112} 113void NVWriteMiscOut(struct nvidia_par *par, u8 value) 114{ 115 VGA_WR08(par->PVIO, VGA_MIS_W, value); 116} 117u8 NVReadMiscOut(struct nvidia_par *par) 118{ 119 return (VGA_RD08(par->PVIO, VGA_MIS_R)); 120} 121#if 0 122void NVEnablePalette(struct nvidia_par *par) 123{ 124 volatile u8 tmp; 125 126 tmp = VGA_RD08(par->PCIO, par->IOBase + 0x0a); 127 VGA_WR08(par->PCIO, VGA_ATT_IW, 0x00); 128 par->paletteEnabled = 1; 129} 130void NVDisablePalette(struct nvidia_par *par) 131{ 132 volatile u8 tmp; 133 134 tmp = VGA_RD08(par->PCIO, par->IOBase + 0x0a); 135 VGA_WR08(par->PCIO, VGA_ATT_IW, 0x20); 136 par->paletteEnabled = 0; 137} 138#endif /* 0 */ 139void NVWriteDacMask(struct nvidia_par *par, u8 value) 140{ 141 VGA_WR08(par->PDIO, VGA_PEL_MSK, value); 142} 143#if 0 144u8 NVReadDacMask(struct nvidia_par *par) 145{ 146 return (VGA_RD08(par->PDIO, VGA_PEL_MSK)); 147} 148#endif /* 0 */ 149void NVWriteDacReadAddr(struct nvidia_par *par, u8 value) 150{ 151 VGA_WR08(par->PDIO, VGA_PEL_IR, value); 152} 153void NVWriteDacWriteAddr(struct nvidia_par *par, u8 value) 154{ 155 VGA_WR08(par->PDIO, VGA_PEL_IW, value); 156} 157void NVWriteDacData(struct nvidia_par *par, u8 value) 158{ 159 VGA_WR08(par->PDIO, VGA_PEL_D, value); 160} 161u8 NVReadDacData(struct nvidia_par *par) 162{ 163 return (VGA_RD08(par->PDIO, VGA_PEL_D)); 164} 165 166static int NVIsConnected(struct nvidia_par *par, int output) 167{ 168 volatile u32 __iomem *PRAMDAC = par->PRAMDAC0; 169 u32 reg52C, reg608, dac0_reg608 = 0; 170 int present; 171 172 if (output) { 173 dac0_reg608 = NV_RD32(PRAMDAC, 0x0608); 174 PRAMDAC += 0x800; 175 } 176 177 reg52C = NV_RD32(PRAMDAC, 0x052C); 178 reg608 = NV_RD32(PRAMDAC, 0x0608); 179 180 NV_WR32(PRAMDAC, 0x0608, reg608 & ~0x00010000); 181 182 NV_WR32(PRAMDAC, 0x052C, reg52C & 0x0000FEEE); 183 msleep(1); 184 NV_WR32(PRAMDAC, 0x052C, NV_RD32(PRAMDAC, 0x052C) | 1); 185 186 NV_WR32(par->PRAMDAC0, 0x0610, 0x94050140); 187 NV_WR32(par->PRAMDAC0, 0x0608, NV_RD32(par->PRAMDAC0, 0x0608) | 188 0x00001000); 189 190 msleep(1); 191 192 present = (NV_RD32(PRAMDAC, 0x0608) & (1 << 28)) ? 1 : 0; 193 194 if (present) 195 printk("nvidiafb: CRTC%i analog found\n", output); 196 else 197 printk("nvidiafb: CRTC%i analog not found\n", output); 198 199 if (output) 200 NV_WR32(par->PRAMDAC0, 0x0608, dac0_reg608); 201 202 NV_WR32(PRAMDAC, 0x052C, reg52C); 203 NV_WR32(PRAMDAC, 0x0608, reg608); 204 205 return present; 206} 207 208static void NVSelectHeadRegisters(struct nvidia_par *par, int head) 209{ 210 if (head) { 211 par->PCIO = par->PCIO0 + 0x2000; 212 par->PCRTC = par->PCRTC0 + 0x800; 213 par->PRAMDAC = par->PRAMDAC0 + 0x800; 214 par->PDIO = par->PDIO0 + 0x2000; 215 } else { 216 par->PCIO = par->PCIO0; 217 par->PCRTC = par->PCRTC0; 218 par->PRAMDAC = par->PRAMDAC0; 219 par->PDIO = par->PDIO0; 220 } 221} 222 223static void nv4GetConfig(struct nvidia_par *par) 224{ 225 if (NV_RD32(par->PFB, 0x0000) & 0x00000100) { 226 par->RamAmountKBytes = 227 ((NV_RD32(par->PFB, 0x0000) >> 12) & 0x0F) * 1024 * 2 + 228 1024 * 2; 229 } else { 230 switch (NV_RD32(par->PFB, 0x0000) & 0x00000003) { 231 case 0: 232 par->RamAmountKBytes = 1024 * 32; 233 break; 234 case 1: 235 par->RamAmountKBytes = 1024 * 4; 236 break; 237 case 2: 238 par->RamAmountKBytes = 1024 * 8; 239 break; 240 case 3: 241 default: 242 par->RamAmountKBytes = 1024 * 16; 243 break; 244 } 245 } 246 par->CrystalFreqKHz = (NV_RD32(par->PEXTDEV, 0x0000) & 0x00000040) ? 247 14318 : 13500; 248 par->CURSOR = &par->PRAMIN[0x1E00]; 249 par->MinVClockFreqKHz = 12000; 250 par->MaxVClockFreqKHz = 350000; 251} 252 253static void nv10GetConfig(struct nvidia_par *par) 254{ 255 struct pci_dev *dev; 256 u32 implementation = par->Chipset & 0x0ff0; 257 258#ifdef __BIG_ENDIAN 259 /* turn on big endian register access */ 260 if (!(NV_RD32(par->PMC, 0x0004) & 0x01000001)) { 261 NV_WR32(par->PMC, 0x0004, 0x01000001); 262 mb(); 263 } 264#endif 265 266 dev = pci_get_bus_and_slot(0, 1); 267 if ((par->Chipset & 0xffff) == 0x01a0) { 268 u32 amt; 269 270 pci_read_config_dword(dev, 0x7c, &amt); 271 par->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024; 272 } else if ((par->Chipset & 0xffff) == 0x01f0) { 273 u32 amt; 274 275 pci_read_config_dword(dev, 0x84, &amt); 276 par->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024; 277 } else { 278 par->RamAmountKBytes = 279 (NV_RD32(par->PFB, 0x020C) & 0xFFF00000) >> 10; 280 } 281 pci_dev_put(dev); 282 283 par->CrystalFreqKHz = (NV_RD32(par->PEXTDEV, 0x0000) & (1 << 6)) ? 284 14318 : 13500; 285 286 if (par->twoHeads && (implementation != 0x0110)) { 287 if (NV_RD32(par->PEXTDEV, 0x0000) & (1 << 22)) 288 par->CrystalFreqKHz = 27000; 289 } 290 291 par->CURSOR = NULL; /* can't set this here */ 292 par->MinVClockFreqKHz = 12000; 293 par->MaxVClockFreqKHz = par->twoStagePLL ? 400000 : 350000; 294} 295 296int NVCommonSetup(struct fb_info *info) 297{ 298 struct nvidia_par *par = info->par; 299 struct fb_var_screeninfo *var; 300 u16 implementation = par->Chipset & 0x0ff0; 301 u8 *edidA = NULL, *edidB = NULL; 302 struct fb_monspecs *monitorA, *monitorB; 303 struct fb_monspecs *monA = NULL, *monB = NULL; 304 int mobile = 0; 305 int tvA = 0; 306 int tvB = 0; 307 int FlatPanel = -1; /* really means the CRTC is slaved */ 308 int Television = 0; 309 int err = 0; 310 311 var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); 312 monitorA = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL); 313 monitorB = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL); 314 315 if (!var || !monitorA || !monitorB) { 316 err = -ENOMEM; 317 goto done; 318 } 319 320 par->PRAMIN = par->REGS + (0x00710000 / 4); 321 par->PCRTC0 = par->REGS + (0x00600000 / 4); 322 par->PRAMDAC0 = par->REGS + (0x00680000 / 4); 323 par->PFB = par->REGS + (0x00100000 / 4); 324 par->PFIFO = par->REGS + (0x00002000 / 4); 325 par->PGRAPH = par->REGS + (0x00400000 / 4); 326 par->PEXTDEV = par->REGS + (0x00101000 / 4); 327 par->PTIMER = par->REGS + (0x00009000 / 4); 328 par->PMC = par->REGS + (0x00000000 / 4); 329 par->FIFO = par->REGS + (0x00800000 / 4); 330 331 /* 8 bit registers */ 332 par->PCIO0 = (u8 __iomem *) par->REGS + 0x00601000; 333 par->PDIO0 = (u8 __iomem *) par->REGS + 0x00681000; 334 par->PVIO = (u8 __iomem *) par->REGS + 0x000C0000; 335 336 par->twoHeads = (par->Architecture >= NV_ARCH_10) && 337 (implementation != 0x0100) && 338 (implementation != 0x0150) && 339 (implementation != 0x01A0) && (implementation != 0x0200); 340 341 par->fpScaler = (par->FpScale && par->twoHeads && 342 (implementation != 0x0110)); 343 344 par->twoStagePLL = (implementation == 0x0310) || 345 (implementation == 0x0340) || (par->Architecture >= NV_ARCH_40); 346 347 par->WaitVSyncPossible = (par->Architecture >= NV_ARCH_10) && 348 (implementation != 0x0100); 349 350 par->BlendingPossible = ((par->Chipset & 0xffff) != 0x0020); 351 352 /* look for known laptop chips */ 353 switch (par->Chipset & 0xffff) { 354 case 0x0112: 355 case 0x0174: 356 case 0x0175: 357 case 0x0176: 358 case 0x0177: 359 case 0x0179: 360 case 0x017C: 361 case 0x017D: 362 case 0x0186: 363 case 0x0187: 364 case 0x018D: 365 case 0x01D7: 366 case 0x0228: 367 case 0x0286: 368 case 0x028C: 369 case 0x0316: 370 case 0x0317: 371 case 0x031A: 372 case 0x031B: 373 case 0x031C: 374 case 0x031D: 375 case 0x031E: 376 case 0x031F: 377 case 0x0324: 378 case 0x0325: 379 case 0x0328: 380 case 0x0329: 381 case 0x032C: 382 case 0x032D: 383 case 0x0347: 384 case 0x0348: 385 case 0x0349: 386 case 0x034B: 387 case 0x034C: 388 case 0x0160: 389 case 0x0166: 390 case 0x0169: 391 case 0x016B: 392 case 0x016C: 393 case 0x016D: 394 case 0x00C8: 395 case 0x00CC: 396 case 0x0144: 397 case 0x0146: 398 case 0x0147: 399 case 0x0148: 400 case 0x0098: 401 case 0x0099: 402 mobile = 1; 403 break; 404 default: 405 break; 406 } 407 408 if (par->Architecture == NV_ARCH_04) 409 nv4GetConfig(par); 410 else 411 nv10GetConfig(par); 412 413 NVSelectHeadRegisters(par, 0); 414 415 NVLockUnlock(par, 0); 416 417 par->IOBase = (NVReadMiscOut(par) & 0x01) ? 0x3d0 : 0x3b0; 418 419 par->Television = 0; 420 421 nvidia_create_i2c_busses(par); 422 if (!par->twoHeads) { 423 par->CRTCnumber = 0; 424 if (nvidia_probe_i2c_connector(info, 1, &edidA)) 425 nvidia_probe_of_connector(info, 1, &edidA); 426 if (edidA && !fb_parse_edid(edidA, var)) { 427 printk("nvidiafb: EDID found from BUS1\n"); 428 monA = monitorA; 429 fb_edid_to_monspecs(edidA, monA); 430 FlatPanel = (monA->input & FB_DISP_DDI) ? 1 : 0; 431 432 /* NV4 doesn't support FlatPanels */ 433 if ((par->Chipset & 0x0fff) <= 0x0020) 434 FlatPanel = 0; 435 } else { 436 VGA_WR08(par->PCIO, 0x03D4, 0x28); 437 if (VGA_RD08(par->PCIO, 0x03D5) & 0x80) { 438 VGA_WR08(par->PCIO, 0x03D4, 0x33); 439 if (!(VGA_RD08(par->PCIO, 0x03D5) & 0x01)) 440 Television = 1; 441 FlatPanel = 1; 442 } else { 443 FlatPanel = 0; 444 } 445 printk("nvidiafb: HW is currently programmed for %s\n", 446 FlatPanel ? (Television ? "TV" : "DFP") : 447 "CRT"); 448 } 449 450 if (par->FlatPanel == -1) { 451 par->FlatPanel = FlatPanel; 452 par->Television = Television; 453 } else { 454 printk("nvidiafb: Forcing display type to %s as " 455 "specified\n", par->FlatPanel ? "DFP" : "CRT"); 456 } 457 } else { 458 u8 outputAfromCRTC, outputBfromCRTC; 459 int CRTCnumber = -1; 460 u8 slaved_on_A, slaved_on_B; 461 int analog_on_A, analog_on_B; 462 u32 oldhead; 463 u8 cr44; 464 465 if (implementation != 0x0110) { 466 if (NV_RD32(par->PRAMDAC0, 0x0000052C) & 0x100) 467 outputAfromCRTC = 1; 468 else 469 outputAfromCRTC = 0; 470 if (NV_RD32(par->PRAMDAC0, 0x0000252C) & 0x100) 471 outputBfromCRTC = 1; 472 else 473 outputBfromCRTC = 0; 474 analog_on_A = NVIsConnected(par, 0); 475 analog_on_B = NVIsConnected(par, 1); 476 } else { 477 outputAfromCRTC = 0; 478 outputBfromCRTC = 1; 479 analog_on_A = 0; 480 analog_on_B = 0; 481 } 482 483 VGA_WR08(par->PCIO, 0x03D4, 0x44); 484 cr44 = VGA_RD08(par->PCIO, 0x03D5); 485 486 VGA_WR08(par->PCIO, 0x03D5, 3); 487 NVSelectHeadRegisters(par, 1); 488 NVLockUnlock(par, 0); 489 490 VGA_WR08(par->PCIO, 0x03D4, 0x28); 491 slaved_on_B = VGA_RD08(par->PCIO, 0x03D5) & 0x80; 492 if (slaved_on_B) { 493 VGA_WR08(par->PCIO, 0x03D4, 0x33); 494 tvB = !(VGA_RD08(par->PCIO, 0x03D5) & 0x01); 495 } 496 497 VGA_WR08(par->PCIO, 0x03D4, 0x44); 498 VGA_WR08(par->PCIO, 0x03D5, 0); 499 NVSelectHeadRegisters(par, 0); 500 NVLockUnlock(par, 0); 501 502 VGA_WR08(par->PCIO, 0x03D4, 0x28); 503 slaved_on_A = VGA_RD08(par->PCIO, 0x03D5) & 0x80; 504 if (slaved_on_A) { 505 VGA_WR08(par->PCIO, 0x03D4, 0x33); 506 tvA = !(VGA_RD08(par->PCIO, 0x03D5) & 0x01); 507 } 508 509 oldhead = NV_RD32(par->PCRTC0, 0x00000860); 510 NV_WR32(par->PCRTC0, 0x00000860, oldhead | 0x00000010); 511 512 if (nvidia_probe_i2c_connector(info, 1, &edidA)) 513 nvidia_probe_of_connector(info, 1, &edidA); 514 if (edidA && !fb_parse_edid(edidA, var)) { 515 printk("nvidiafb: EDID found from BUS1\n"); 516 monA = monitorA; 517 fb_edid_to_monspecs(edidA, monA); 518 } 519 520 if (nvidia_probe_i2c_connector(info, 2, &edidB)) 521 nvidia_probe_of_connector(info, 2, &edidB); 522 if (edidB && !fb_parse_edid(edidB, var)) { 523 printk("nvidiafb: EDID found from BUS2\n"); 524 monB = monitorB; 525 fb_edid_to_monspecs(edidB, monB); 526 } 527 528 if (slaved_on_A && !tvA) { 529 CRTCnumber = 0; 530 FlatPanel = 1; 531 printk("nvidiafb: CRTC 0 is currently programmed for " 532 "DFP\n"); 533 } else if (slaved_on_B && !tvB) { 534 CRTCnumber = 1; 535 FlatPanel = 1; 536 printk("nvidiafb: CRTC 1 is currently programmed " 537 "for DFP\n"); 538 } else if (analog_on_A) { 539 CRTCnumber = outputAfromCRTC; 540 FlatPanel = 0; 541 printk("nvidiafb: CRTC %i appears to have a " 542 "CRT attached\n", CRTCnumber); 543 } else if (analog_on_B) { 544 CRTCnumber = outputBfromCRTC; 545 FlatPanel = 0; 546 printk("nvidiafb: CRTC %i" 547 "appears to have a " 548 "CRT attached\n", CRTCnumber); 549 } else if (slaved_on_A) { 550 CRTCnumber = 0; 551 FlatPanel = 1; 552 Television = 1; 553 printk("nvidiafb: CRTC 0 is currently programmed " 554 "for TV\n"); 555 } else if (slaved_on_B) { 556 CRTCnumber = 1; 557 FlatPanel = 1; 558 Television = 1; 559 printk("nvidiafb: CRTC 1 is currently programmed for " 560 "TV\n"); 561 } else if (monA) { 562 FlatPanel = (monA->input & FB_DISP_DDI) ? 1 : 0; 563 } else if (monB) { 564 FlatPanel = (monB->input & FB_DISP_DDI) ? 1 : 0; 565 } 566 567 if (par->FlatPanel == -1) { 568 if (FlatPanel != -1) { 569 par->FlatPanel = FlatPanel; 570 par->Television = Television; 571 } else { 572 printk("nvidiafb: Unable to detect display " 573 "type...\n"); 574 if (mobile) { 575 printk("...On a laptop, assuming " 576 "DFP\n"); 577 par->FlatPanel = 1; 578 } else { 579 printk("...Using default of CRT\n"); 580 par->FlatPanel = 0; 581 } 582 } 583 } else { 584 printk("nvidiafb: Forcing display type to %s as " 585 "specified\n", par->FlatPanel ? "DFP" : "CRT"); 586 } 587 588 if (par->CRTCnumber == -1) { 589 if (CRTCnumber != -1) 590 par->CRTCnumber = CRTCnumber; 591 else { 592 printk("nvidiafb: Unable to detect which " 593 "CRTCNumber...\n"); 594 if (par->FlatPanel) 595 par->CRTCnumber = 1; 596 else 597 par->CRTCnumber = 0; 598 printk("...Defaulting to CRTCNumber %i\n", 599 par->CRTCnumber); 600 } 601 } else { 602 printk("nvidiafb: Forcing CRTCNumber %i as " 603 "specified\n", par->CRTCnumber); 604 } 605 606 if (monA) { 607 if (((monA->input & FB_DISP_DDI) && 608 par->FlatPanel) || 609 ((!(monA->input & FB_DISP_DDI)) && 610 !par->FlatPanel)) { 611 if (monB) { 612 fb_destroy_modedb(monB->modedb); 613 monB = NULL; 614 } 615 } else { 616 fb_destroy_modedb(monA->modedb); 617 monA = NULL; 618 } 619 } 620 621 if (monB) { 622 if (((monB->input & FB_DISP_DDI) && 623 !par->FlatPanel) || 624 ((!(monB->input & FB_DISP_DDI)) && 625 par->FlatPanel)) { 626 fb_destroy_modedb(monB->modedb); 627 monB = NULL; 628 } else 629 monA = monB; 630 } 631 632 if (implementation == 0x0110) 633 cr44 = par->CRTCnumber * 0x3; 634 635 NV_WR32(par->PCRTC0, 0x00000860, oldhead); 636 637 VGA_WR08(par->PCIO, 0x03D4, 0x44); 638 VGA_WR08(par->PCIO, 0x03D5, cr44); 639 NVSelectHeadRegisters(par, par->CRTCnumber); 640 } 641 642 printk("nvidiafb: Using %s on CRTC %i\n", 643 par->FlatPanel ? (par->Television ? "TV" : "DFP") : "CRT", 644 par->CRTCnumber); 645 646 if (par->FlatPanel && !par->Television) { 647 par->fpWidth = NV_RD32(par->PRAMDAC, 0x0820) + 1; 648 par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1; 649 par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033; 650 651 printk("nvidiafb: Panel size is %i x %i\n", par->fpWidth, par->fpHeight); 652 } 653 654 if (monA) 655 info->monspecs = *monA; 656 657 if (!par->FlatPanel || !par->twoHeads) 658 par->FPDither = 0; 659 660 par->LVDS = 0; 661 if (par->FlatPanel && par->twoHeads) { 662 NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004); 663 if (NV_RD32(par->PRAMDAC0, 0x08b4) & 1) 664 par->LVDS = 1; 665 printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS"); 666 } 667 668 kfree(edidA); 669 kfree(edidB); 670done: 671 kfree(var); 672 kfree(monitorA); 673 kfree(monitorB); 674 return err; 675}