root/drivers/video/fbdev/nvidia/nv_setup.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. NVWriteCrtc
  2. NVReadCrtc
  3. NVWriteGr
  4. NVReadGr
  5. NVWriteSeq
  6. NVReadSeq
  7. NVWriteAttr
  8. NVReadAttr
  9. NVWriteMiscOut
  10. NVReadMiscOut
  11. NVWriteDacMask
  12. NVWriteDacReadAddr
  13. NVWriteDacWriteAddr
  14. NVWriteDacData
  15. NVReadDacData
  16. NVIsConnected
  17. NVSelectHeadRegisters
  18. nv4GetConfig
  19. nv10GetConfig
  20. NVCommonSetup

   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 <linux/slab.h>
  54 #include "nv_type.h"
  55 #include "nv_local.h"
  56 #include "nv_proto.h"
  57 /*
  58  * Override VGA I/O routines.
  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         /* turn on big endian register access */
 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;     /* can't set this here */
 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;     /* really means the CRTC is slaved */
 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         /* 8 bit registers */
 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         /* look for known laptop chips */
 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                         /* NV4 doesn't support FlatPanels */
 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 }

/* [<][>][^][v][top][bottom][index][help] */