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