linux/drivers/video/riva/nv_driver.c
<<
>>
Prefs
   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
 163        switch (chip->Architecture) {
 164        case NV_ARCH_03:
 165                if (NV_RD32(chip->PFB, 0x00000000) & 0x00000020) {
 166                        if (((NV_RD32(chip->PMC, 0x00000000) & 0xF0) == 0x20)
 167                            && ((NV_RD32(chip->PMC, 0x00000000)&0x0F)>=0x02)) {
 168                                /*
 169                                 * SDRAM 128 ZX.
 170                                 */
 171                                switch (NV_RD32(chip->PFB,0x00000000) & 0x03) {
 172                                case 2:
 173                                        memlen = 1024 * 4;
 174                                        break;
 175                                case 1:
 176                                        memlen = 1024 * 2;
 177                                        break;
 178                                default:
 179                                        memlen = 1024 * 8;
 180                                        break;
 181                                }
 182                        } else {
 183                                memlen = 1024 * 8;
 184                        }            
 185                } else  {
 186                        /*
 187                         * SGRAM 128.
 188                         */
 189                        switch (NV_RD32(chip->PFB, 0x00000000) & 0x00000003) {
 190                        case 0:
 191                                memlen = 1024 * 8;
 192                                break;
 193                        case 2:
 194                                memlen = 1024 * 4;
 195                                break;
 196                        default:
 197                                memlen = 1024 * 2;
 198                                break;
 199                        }
 200                }        
 201                break;
 202        case NV_ARCH_04:
 203                if (NV_RD32(chip->PFB, 0x00000000) & 0x00000100) {
 204                        memlen = ((NV_RD32(chip->PFB, 0x00000000)>>12)&0x0F) *
 205                                1024 * 2 + 1024 * 2;
 206                } else {
 207                        switch (NV_RD32(chip->PFB, 0x00000000) & 0x00000003) {
 208                        case 0:
 209                                memlen = 1024 * 32;
 210                                break;
 211                        case 1:
 212                                memlen = 1024 * 4;
 213                                break;
 214                        case 2:
 215                                memlen = 1024 * 8;
 216                                break;
 217                        case 3:
 218                        default:
 219                                memlen = 1024 * 16;
 220                                break;
 221                        }
 222                }
 223                break;
 224        case NV_ARCH_10:
 225        case NV_ARCH_20:
 226        case NV_ARCH_30:
 227                if(chipset == NV_CHIP_IGEFORCE2) {
 228
 229                        dev = pci_get_bus_and_slot(0, 1);
 230                        pci_read_config_dword(dev, 0x7C, &amt);
 231                        pci_dev_put(dev);
 232                        memlen = (((amt >> 6) & 31) + 1) * 1024;
 233                } else if (chipset == NV_CHIP_0x01F0) {
 234                        dev = pci_get_bus_and_slot(0, 1);
 235                        pci_read_config_dword(dev, 0x84, &amt);
 236                        pci_dev_put(dev);
 237                        memlen = (((amt >> 4) & 127) + 1) * 1024;
 238                } else {
 239                        switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) &
 240                                0x000000FF){
 241                        case 0x02:
 242                                memlen = 1024 * 2;
 243                                break;
 244                        case 0x04:
 245                                memlen = 1024 * 4;
 246                                break;
 247                        case 0x08:
 248                                memlen = 1024 * 8;
 249                                break;
 250                        case 0x10:
 251                                memlen = 1024 * 16;
 252                                break;
 253                        case 0x20:
 254                                memlen = 1024 * 32;
 255                                break;
 256                        case 0x40:
 257                                memlen = 1024 * 64;
 258                                break;
 259                        case 0x80:
 260                                memlen = 1024 * 128;
 261                                break;
 262                        default:
 263                                memlen = 1024 * 16;
 264                                break;
 265                        }
 266                }
 267                break;
 268        }
 269        return memlen;
 270}
 271
 272unsigned long riva_get_maxdclk(struct riva_par *par)
 273{
 274        RIVA_HW_INST *chip = &par->riva;
 275        unsigned long dclk = 0;
 276
 277        switch (chip->Architecture) {
 278        case NV_ARCH_03:
 279                if (NV_RD32(chip->PFB, 0x00000000) & 0x00000020) {
 280                        if (((NV_RD32(chip->PMC, 0x00000000) & 0xF0) == 0x20)
 281                            && ((NV_RD32(chip->PMC,0x00000000)&0x0F) >= 0x02)) {
 282                                /*
 283                                 * SDRAM 128 ZX.
 284                                 */
 285                                dclk = 800000;
 286                        } else {
 287                                dclk = 1000000;
 288                        }            
 289                } else {
 290                        /*
 291                         * SGRAM 128.
 292                         */
 293                        dclk = 1000000;
 294                } 
 295                break;
 296        case NV_ARCH_04:
 297        case NV_ARCH_10:
 298        case NV_ARCH_20:
 299        case NV_ARCH_30:
 300                switch ((NV_RD32(chip->PFB, 0x00000000) >> 3) & 0x00000003) {
 301                case 3:
 302                        dclk = 800000;
 303                        break;
 304                default:
 305                        dclk = 1000000;
 306                        break;
 307                }
 308                break;
 309        }
 310        return dclk;
 311}
 312
 313void
 314riva_common_setup(struct riva_par *par)
 315{
 316        par->riva.EnableIRQ = 0;
 317        par->riva.PRAMDAC0 =
 318                (volatile U032 __iomem *)(par->ctrl_base + 0x00680000);
 319        par->riva.PFB =
 320                (volatile U032 __iomem *)(par->ctrl_base + 0x00100000);
 321        par->riva.PFIFO =
 322                (volatile U032 __iomem *)(par->ctrl_base + 0x00002000);
 323        par->riva.PGRAPH =
 324                (volatile U032 __iomem *)(par->ctrl_base + 0x00400000);
 325        par->riva.PEXTDEV =
 326                (volatile U032 __iomem *)(par->ctrl_base + 0x00101000);
 327        par->riva.PTIMER =
 328                (volatile U032 __iomem *)(par->ctrl_base + 0x00009000);
 329        par->riva.PMC =
 330                (volatile U032 __iomem *)(par->ctrl_base + 0x00000000);
 331        par->riva.FIFO =
 332                (volatile U032 __iomem *)(par->ctrl_base + 0x00800000);
 333        par->riva.PCIO0 = par->ctrl_base + 0x00601000;
 334        par->riva.PDIO0 = par->ctrl_base + 0x00681000;
 335        par->riva.PVIO = par->ctrl_base + 0x000C0000;
 336
 337        par->riva.IO = (MISCin(par) & 0x01) ? 0x3D0 : 0x3B0;
 338        
 339        if (par->FlatPanel == -1) {
 340                switch (par->Chipset & 0xffff) {
 341                case 0x0112:   /* known laptop chips */
 342                case 0x0174:
 343                case 0x0175:
 344                case 0x0176:
 345                case 0x0177:
 346                case 0x0179:
 347                case 0x017C:
 348                case 0x017D:
 349                case 0x0186:
 350                case 0x0187:
 351                case 0x0286:
 352                case 0x028C:
 353                case 0x0316:
 354                case 0x0317:
 355                case 0x031A:
 356                case 0x031B:
 357                case 0x031C:
 358                case 0x031D:
 359                case 0x031E:
 360                case 0x031F:
 361                case 0x0324:
 362                case 0x0325:
 363                case 0x0328:
 364                case 0x0329:
 365                case 0x032C:
 366                case 0x032D:
 367                        printk(KERN_INFO PFX 
 368                                "On a laptop.  Assuming Digital Flat Panel\n");
 369                        par->FlatPanel = 1;
 370                        break;
 371                default:
 372                        break;
 373                }
 374        }
 375        
 376        switch (par->Chipset & 0x0ff0) {
 377        case 0x0110:
 378                if (par->Chipset == NV_CHIP_GEFORCE2_GO)
 379                        par->SecondCRTC = TRUE; 
 380#if defined(__powerpc__)
 381                if (par->FlatPanel == 1)
 382                        par->SecondCRTC = TRUE;
 383#endif
 384                riva_override_CRTC(par);
 385                break;
 386        case 0x0170:
 387        case 0x0180:
 388        case 0x01F0:
 389        case 0x0250:
 390        case 0x0280:
 391        case 0x0300:
 392        case 0x0310:
 393        case 0x0320:
 394        case 0x0330:
 395        case 0x0340:
 396                riva_is_second(par);
 397                break;
 398        default:
 399                break;
 400        }
 401
 402        if (par->SecondCRTC) {
 403                par->riva.PCIO = par->riva.PCIO0 + 0x2000;
 404                par->riva.PCRTC = par->riva.PCRTC0 + 0x800;
 405                par->riva.PRAMDAC = par->riva.PRAMDAC0 + 0x800;
 406                par->riva.PDIO = par->riva.PDIO0 + 0x2000;
 407        } else {
 408                par->riva.PCIO = par->riva.PCIO0;
 409                par->riva.PCRTC = par->riva.PCRTC0;
 410                par->riva.PRAMDAC = par->riva.PRAMDAC0;
 411                par->riva.PDIO = par->riva.PDIO0;
 412        }
 413
 414        if (par->FlatPanel == -1) {
 415                /* Fix me, need x86 DDC code */
 416                par->FlatPanel = 0;
 417        }
 418        par->riva.flatPanel = (par->FlatPanel > 0) ? TRUE : FALSE;
 419
 420        RivaGetConfig(&par->riva, par->Chipset);
 421}
 422
 423