nv_driver.c (9774B)
1/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */ 2/* 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/* 25 * GPL licensing note -- nVidia is allowing a liberal interpretation of 26 * the documentation restriction above, to merely say that this nVidia's 27 * copyright and disclaimer should be included with all code derived 28 * from this source. -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 29 */ 30 31/* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen 32 <jpaana@s2.org> */ 33 34/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.18 2002/08/0 355 20:47:06 mvojkovi Exp $ */ 36 37#include <linux/delay.h> 38#include <linux/pci.h> 39#include <linux/pci_ids.h> 40#include "nv_type.h" 41#include "rivafb.h" 42#include "nvreg.h" 43 44#define PFX "rivafb: " 45 46static inline unsigned char MISCin(struct riva_par *par) 47{ 48 return (VGA_RD08(par->riva.PVIO, 0x3cc)); 49} 50 51static Bool 52riva_is_connected(struct riva_par *par, Bool second) 53{ 54 volatile U032 __iomem *PRAMDAC = par->riva.PRAMDAC0; 55 U032 reg52C, reg608; 56 Bool present; 57 58 if(second) PRAMDAC += 0x800; 59 60 reg52C = NV_RD32(PRAMDAC, 0x052C); 61 reg608 = NV_RD32(PRAMDAC, 0x0608); 62 63 NV_WR32(PRAMDAC, 0x0608, reg608 & ~0x00010000); 64 65 NV_WR32(PRAMDAC, 0x052C, reg52C & 0x0000FEEE); 66 mdelay(1); 67 NV_WR32(PRAMDAC, 0x052C, NV_RD32(PRAMDAC, 0x052C) | 1); 68 69 NV_WR32(par->riva.PRAMDAC0, 0x0610, 0x94050140); 70 NV_WR32(par->riva.PRAMDAC0, 0x0608, 0x00001000); 71 72 mdelay(1); 73 74 present = (NV_RD32(PRAMDAC, 0x0608) & (1 << 28)) ? TRUE : FALSE; 75 76 NV_WR32(par->riva.PRAMDAC0, 0x0608, 77 NV_RD32(par->riva.PRAMDAC0, 0x0608) & 0x0000EFFF); 78 79 NV_WR32(PRAMDAC, 0x052C, reg52C); 80 NV_WR32(PRAMDAC, 0x0608, reg608); 81 82 return present; 83} 84 85static void 86riva_override_CRTC(struct riva_par *par) 87{ 88 printk(KERN_INFO PFX 89 "Detected CRTC controller %i being used\n", 90 par->SecondCRTC ? 1 : 0); 91 92 if(par->forceCRTC != -1) { 93 printk(KERN_INFO PFX 94 "Forcing usage of CRTC %i\n", par->forceCRTC); 95 par->SecondCRTC = par->forceCRTC; 96 } 97} 98 99static void 100riva_is_second(struct riva_par *par) 101{ 102 if (par->FlatPanel == 1) { 103 switch(par->Chipset & 0xffff) { 104 case 0x0174: 105 case 0x0175: 106 case 0x0176: 107 case 0x0177: 108 case 0x0179: 109 case 0x017C: 110 case 0x017D: 111 case 0x0186: 112 case 0x0187: 113 /* this might not be a good default for the chips below */ 114 case 0x0286: 115 case 0x028C: 116 case 0x0316: 117 case 0x0317: 118 case 0x031A: 119 case 0x031B: 120 case 0x031C: 121 case 0x031D: 122 case 0x031E: 123 case 0x031F: 124 case 0x0324: 125 case 0x0325: 126 case 0x0328: 127 case 0x0329: 128 case 0x032C: 129 case 0x032D: 130 par->SecondCRTC = TRUE; 131 break; 132 default: 133 par->SecondCRTC = FALSE; 134 break; 135 } 136 } else { 137 if(riva_is_connected(par, 0)) { 138 139 if (NV_RD32(par->riva.PRAMDAC0, 0x0000052C) & 0x100) 140 par->SecondCRTC = TRUE; 141 else 142 par->SecondCRTC = FALSE; 143 } else 144 if (riva_is_connected(par, 1)) { 145 if(NV_RD32(par->riva.PRAMDAC0, 0x0000252C) & 0x100) 146 par->SecondCRTC = TRUE; 147 else 148 par->SecondCRTC = FALSE; 149 } else /* default */ 150 par->SecondCRTC = FALSE; 151 } 152 riva_override_CRTC(par); 153} 154 155unsigned long riva_get_memlen(struct riva_par *par) 156{ 157 RIVA_HW_INST *chip = &par->riva; 158 unsigned long memlen = 0; 159 unsigned int chipset = par->Chipset; 160 struct pci_dev* dev; 161 u32 amt; 162 int domain = pci_domain_nr(par->pdev->bus); 163 164 switch (chip->Architecture) { 165 case NV_ARCH_03: 166 if (NV_RD32(chip->PFB, 0x00000000) & 0x00000020) { 167 if (((NV_RD32(chip->PMC, 0x00000000) & 0xF0) == 0x20) 168 && ((NV_RD32(chip->PMC, 0x00000000)&0x0F)>=0x02)) { 169 /* 170 * SDRAM 128 ZX. 171 */ 172 switch (NV_RD32(chip->PFB,0x00000000) & 0x03) { 173 case 2: 174 memlen = 1024 * 4; 175 break; 176 case 1: 177 memlen = 1024 * 2; 178 break; 179 default: 180 memlen = 1024 * 8; 181 break; 182 } 183 } else { 184 memlen = 1024 * 8; 185 } 186 } else { 187 /* 188 * SGRAM 128. 189 */ 190 switch (NV_RD32(chip->PFB, 0x00000000) & 0x00000003) { 191 case 0: 192 memlen = 1024 * 8; 193 break; 194 case 2: 195 memlen = 1024 * 4; 196 break; 197 default: 198 memlen = 1024 * 2; 199 break; 200 } 201 } 202 break; 203 case NV_ARCH_04: 204 if (NV_RD32(chip->PFB, 0x00000000) & 0x00000100) { 205 memlen = ((NV_RD32(chip->PFB, 0x00000000)>>12)&0x0F) * 206 1024 * 2 + 1024 * 2; 207 } else { 208 switch (NV_RD32(chip->PFB, 0x00000000) & 0x00000003) { 209 case 0: 210 memlen = 1024 * 32; 211 break; 212 case 1: 213 memlen = 1024 * 4; 214 break; 215 case 2: 216 memlen = 1024 * 8; 217 break; 218 case 3: 219 default: 220 memlen = 1024 * 16; 221 break; 222 } 223 } 224 break; 225 case NV_ARCH_10: 226 case NV_ARCH_20: 227 case NV_ARCH_30: 228 if(chipset == NV_CHIP_IGEFORCE2) { 229 230 dev = pci_get_domain_bus_and_slot(domain, 0, 1); 231 pci_read_config_dword(dev, 0x7C, &amt); 232 pci_dev_put(dev); 233 memlen = (((amt >> 6) & 31) + 1) * 1024; 234 } else if (chipset == NV_CHIP_0x01F0) { 235 dev = pci_get_domain_bus_and_slot(domain, 0, 1); 236 pci_read_config_dword(dev, 0x84, &amt); 237 pci_dev_put(dev); 238 memlen = (((amt >> 4) & 127) + 1) * 1024; 239 } else { 240 switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) & 241 0x000000FF){ 242 case 0x02: 243 memlen = 1024 * 2; 244 break; 245 case 0x04: 246 memlen = 1024 * 4; 247 break; 248 case 0x08: 249 memlen = 1024 * 8; 250 break; 251 case 0x10: 252 memlen = 1024 * 16; 253 break; 254 case 0x20: 255 memlen = 1024 * 32; 256 break; 257 case 0x40: 258 memlen = 1024 * 64; 259 break; 260 case 0x80: 261 memlen = 1024 * 128; 262 break; 263 default: 264 memlen = 1024 * 16; 265 break; 266 } 267 } 268 break; 269 } 270 return memlen; 271} 272 273unsigned long riva_get_maxdclk(struct riva_par *par) 274{ 275 RIVA_HW_INST *chip = &par->riva; 276 unsigned long dclk = 0; 277 278 switch (chip->Architecture) { 279 case NV_ARCH_03: 280 if (NV_RD32(chip->PFB, 0x00000000) & 0x00000020) { 281 if (((NV_RD32(chip->PMC, 0x00000000) & 0xF0) == 0x20) 282 && ((NV_RD32(chip->PMC,0x00000000)&0x0F) >= 0x02)) { 283 /* 284 * SDRAM 128 ZX. 285 */ 286 dclk = 800000; 287 } else { 288 dclk = 1000000; 289 } 290 } else { 291 /* 292 * SGRAM 128. 293 */ 294 dclk = 1000000; 295 } 296 break; 297 case NV_ARCH_04: 298 case NV_ARCH_10: 299 case NV_ARCH_20: 300 case NV_ARCH_30: 301 switch ((NV_RD32(chip->PFB, 0x00000000) >> 3) & 0x00000003) { 302 case 3: 303 dclk = 800000; 304 break; 305 default: 306 dclk = 1000000; 307 break; 308 } 309 break; 310 } 311 return dclk; 312} 313 314void 315riva_common_setup(struct riva_par *par) 316{ 317 par->riva.EnableIRQ = 0; 318 par->riva.PRAMDAC0 = 319 (volatile U032 __iomem *)(par->ctrl_base + 0x00680000); 320 par->riva.PFB = 321 (volatile U032 __iomem *)(par->ctrl_base + 0x00100000); 322 par->riva.PFIFO = 323 (volatile U032 __iomem *)(par->ctrl_base + 0x00002000); 324 par->riva.PGRAPH = 325 (volatile U032 __iomem *)(par->ctrl_base + 0x00400000); 326 par->riva.PEXTDEV = 327 (volatile U032 __iomem *)(par->ctrl_base + 0x00101000); 328 par->riva.PTIMER = 329 (volatile U032 __iomem *)(par->ctrl_base + 0x00009000); 330 par->riva.PMC = 331 (volatile U032 __iomem *)(par->ctrl_base + 0x00000000); 332 par->riva.FIFO = 333 (volatile U032 __iomem *)(par->ctrl_base + 0x00800000); 334 par->riva.PCIO0 = par->ctrl_base + 0x00601000; 335 par->riva.PDIO0 = par->ctrl_base + 0x00681000; 336 par->riva.PVIO = par->ctrl_base + 0x000C0000; 337 338 par->riva.IO = (MISCin(par) & 0x01) ? 0x3D0 : 0x3B0; 339 340 if (par->FlatPanel == -1) { 341 switch (par->Chipset & 0xffff) { 342 case 0x0112: /* known laptop chips */ 343 case 0x0174: 344 case 0x0175: 345 case 0x0176: 346 case 0x0177: 347 case 0x0179: 348 case 0x017C: 349 case 0x017D: 350 case 0x0186: 351 case 0x0187: 352 case 0x0286: 353 case 0x028C: 354 case 0x0316: 355 case 0x0317: 356 case 0x031A: 357 case 0x031B: 358 case 0x031C: 359 case 0x031D: 360 case 0x031E: 361 case 0x031F: 362 case 0x0324: 363 case 0x0325: 364 case 0x0328: 365 case 0x0329: 366 case 0x032C: 367 case 0x032D: 368 printk(KERN_INFO PFX 369 "On a laptop. Assuming Digital Flat Panel\n"); 370 par->FlatPanel = 1; 371 break; 372 default: 373 break; 374 } 375 } 376 377 switch (par->Chipset & 0x0ff0) { 378 case 0x0110: 379 if (par->Chipset == NV_CHIP_GEFORCE2_GO) 380 par->SecondCRTC = TRUE; 381#if defined(__powerpc__) 382 if (par->FlatPanel == 1) 383 par->SecondCRTC = TRUE; 384#endif 385 riva_override_CRTC(par); 386 break; 387 case 0x0170: 388 case 0x0180: 389 case 0x01F0: 390 case 0x0250: 391 case 0x0280: 392 case 0x0300: 393 case 0x0310: 394 case 0x0320: 395 case 0x0330: 396 case 0x0340: 397 riva_is_second(par); 398 break; 399 default: 400 break; 401 } 402 403 if (par->SecondCRTC) { 404 par->riva.PCIO = par->riva.PCIO0 + 0x2000; 405 par->riva.PCRTC = par->riva.PCRTC0 + 0x800; 406 par->riva.PRAMDAC = par->riva.PRAMDAC0 + 0x800; 407 par->riva.PDIO = par->riva.PDIO0 + 0x2000; 408 } else { 409 par->riva.PCIO = par->riva.PCIO0; 410 par->riva.PCRTC = par->riva.PCRTC0; 411 par->riva.PRAMDAC = par->riva.PRAMDAC0; 412 par->riva.PDIO = par->riva.PDIO0; 413 } 414 415 if (par->FlatPanel == -1) { 416 /* Fix me, need x86 DDC code */ 417 par->FlatPanel = 0; 418 } 419 par->riva.flatPanel = (par->FlatPanel > 0) ? TRUE : FALSE; 420 421 RivaGetConfig(&par->riva, par->pdev, par->Chipset); 422} 423