424 lines · c
1/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */2/*3 * Copyright 1996-1997 David J. McKay4 *5 * Permission is hereby granted, free of charge, to any person obtaining a6 * copy of this software and associated documentation files (the "Software"),7 * to deal in the Software without restriction, including without limitation8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,9 * and/or sell copies of the Software, and to permit persons to whom the10 * Software is furnished to do so, subject to the following conditions:11 *12 * The above copyright notice and this permission notice shall be included in13 * all copies or substantial portions of the Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18 * 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 OF20 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21 * SOFTWARE.22 */23 24/*25 * GPL licensing note -- nVidia is allowing a liberal interpretation of26 * the documentation restriction above, to merely say that this nVidia's27 * copyright and disclaimer should be included with all code derived28 * 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 Paananen32 <jpaana@s2.org> */33 34/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.18 2002/08/0355 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 void86riva_override_CRTC(struct riva_par *par)87{88 printk(KERN_INFO PFX89 "Detected CRTC controller %i being used\n",90 par->SecondCRTC ? 1 : 0);91 92 if(par->forceCRTC != -1) {93 printk(KERN_INFO PFX94 "Forcing usage of CRTC %i\n", par->forceCRTC);95 par->SecondCRTC = par->forceCRTC;96 }97}98 99static void100riva_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 else142 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 else148 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 314void315riva_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#endif385 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 424