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