Re: [PATCH] nvidiafb support for 6600 and 6200

From: Antonino A. Daplas (adaplas_at_gmail.com)
Date: 11/26/05

  • Next message: Willy Tarreau: "Re: defective RAM: corrupted ext3 FS. How to identify corrupted files/directories?"
    Date:	Sat, 26 Nov 2005 14:33:28 +0800
    To: "Antonino A. Daplas" <adaplas@gmail.com>
    
    

    Antonino A. Daplas wrote:
    > Calin A. Culianu wrote:
    >> Hi,
    >>
    >> This patch can be applied against 2.6.15-rc1 to add support to the
    >> nvidiafb driver for a few obscure (yet on-the-market) nvidia
    >> boards/chipsets, including various versions of the Geforce 6600 and 6200.
    >>
    >> This patch has been tested and allows the above-mentioned boards to get
    >> framebuffer console support.
    >>
    >
    > Is this a pci-e card? With a pci-e card, the actual chipset type is located
    > in one of the registers (instead of deriving it from the pci device id) and
    > will resolve into one of the supported architectures, usually an NV_ARCH_40.
    >
    > Can you try this patch instead? And send me your dmesg whether it works or
    > not.
    >

    Uhh, disregard the previous patch, try this one.

    Tony

    diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c
    index b989358..7d51e3a 100644
    --- a/drivers/video/nvidia/nv_hw.c
    +++ b/drivers/video/nvidia/nv_hw.c
    @@ -925,6 +925,7 @@ void NVCalcStateExt(struct nvidia_par *p
     
     void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
     {
    + u32 tmp;
             int i;
     
             NV_WR32(par->PMC, 0x0140, 0x00000000);
    @@ -938,15 +939,25 @@ void NVLoadStateExt(struct nvidia_par *p
     
             if (par->Architecture == NV_ARCH_04) {
                     NV_WR32(par->PFB, 0x0200, state->config);
    - } else if ((par->Chipset & 0xfff0) == 0x0090) {
    - for (i = 0; i < 15; i++) {
    - NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0);
    - NV_WR32(par->PFB, 0x0604 + (i * 0x10), par->FbMapSize - 1);
    - }
    - } else {
    + } else if((par->Architecture < NV_ARCH_40) ||
    + ((par->Chipset & 0xfff0) == 0x0040)) {
                     for (i = 0; i < 8; i++) {
                             NV_WR32(par->PFB, 0x0240 + (i * 0x10), 0);
    - NV_WR32(par->PFB, 0x0244 + (i * 0x10), par->FbMapSize - 1);
    + NV_WR32(par->PFB, 0x0244 + (i * 0x10),
    + par->FbMapSize - 1);
    + }
    + } else {
    + int regions = 12;
    +
    + if(((par->Chipset & 0xfff0) == 0x0090) ||
    + ((par->Chipset & 0xfff0) == 0x01D0) ||
    + ((par->Chipset & 0xfff0) == 0x0290))
    + regions = 15;
    +
    + for(i = 0; i < regions; i++) {
    + NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0);
    + NV_WR32(par->PFB, 0x0604 + (i * 0x10),
    + par->FbMapSize - 1);
                     }
             }
     
    @@ -1187,6 +1198,10 @@ void NVLoadStateExt(struct nvidia_par *p
                                     NV_WR32(par->PGRAPH, 0x0090, 0x00008000);
                                     NV_WR32(par->PGRAPH, 0x0610, 0x00be3c5f);
     
    + tmp = NV_RD32(par->REGS, 0x1540) & 0xff;
    + for(i = 0; tmp && !(tmp & 1); tmp >>= 1, i++);
    + NV_WR32(par->PGRAPH, 0x5000, i);
    +
                                     if ((par->Chipset & 0xfff0) == 0x0040) {
                                             NV_WR32(par->PGRAPH, 0x09b0,
                                                     0x83280fff);
    @@ -1211,6 +1226,7 @@ void NVLoadStateExt(struct nvidia_par *p
                                                     0xffff7fff);
                                             break;
                                     case 0x00C0:
    + case 0x0120:
                                             NV_WR32(par->PGRAPH, 0x0828,
                                                     0x007596ff);
                                             NV_WR32(par->PGRAPH, 0x082C,
    @@ -1245,6 +1261,7 @@ void NVLoadStateExt(struct nvidia_par *p
                                                     0x00100000);
                                             break;
                                     case 0x0090:
    + case 0x0290:
                                             NV_WR32(par->PRAMDAC, 0x0608,
                                                     NV_RD32(par->PRAMDAC, 0x0608) |
                                                     0x00100000);
    @@ -1310,14 +1327,42 @@ void NVLoadStateExt(struct nvidia_par *p
                                     }
                             }
     
    - if ((par->Chipset & 0xfff0) == 0x0090) {
    - for (i = 0; i < 60; i++)
    - NV_WR32(par->PGRAPH, 0x0D00 + i,
    - NV_RD32(par->PFB, 0x0600 + i));
    - } else {
    - for (i = 0; i < 32; i++)
    + if ((par->Architecture < NV_ARCH_40) ||
    + ((par->Chipset & 0xfff0) == 0x0040)) {
    + for(i = 0; i < 32; i++) {
                                             NV_WR32(par->PGRAPH, 0x0900 + i,
                                                     NV_RD32(par->PFB, 0x0240 + i));
    + NV_WR32(par->PGRAPH, 0x6900 + i,
    + NV_RD32(par->PFB, 0x0240 + i));
    + }
    + } else {
    + if (((par->Chipset & 0xfff0) == 0x0090) ||
    + ((par->Chipset & 0xfff0) == 0x01D0) ||
    + ((par->Chipset & 0xfff0) == 0x0290)) {
    + for(i = 0; i < 60; i++) {
    + NV_WR32(par->PGRAPH, 0x0D00+i,
    + NV_RD32(par->PFB,
    + 0x0600 + i));
    + NV_WR32(par->PGRAPH, 0x6900+i,
    + NV_RD32(par->PFB,
    + 0x0600 + i));
    + }
    + } else {
    + for(i = 0; i < 48; i++) {
    + NV_WR32(par->PGRAPH, 0x0900+i,
    + NV_RD32(par->PFB,
    + 0x0600 + i));
    + if (((par->Chipset & 0xfff0) !=
    + 0x0160) &&
    + ((par->Chipset & 0xfff0) !=
    + 0x0220)) {
    + NV_WR32(par->PGRAPH,
    + 0x6900 + i,
    + NV_RD32(par->PFB,
    + 0x0600 + i));
    + }
    + }
    + }
                             }
     
                             if (par->Architecture >= NV_ARCH_40) {
    @@ -1338,11 +1383,15 @@ void NVLoadStateExt(struct nvidia_par *p
                                             NV_WR32(par->PGRAPH, 0x0868,
                                                     par->FbMapSize - 1);
                                     } else {
    - if((par->Chipset & 0xfff0) == 0x0090) {
    + if (((par->Chipset & 0xfff0)==0x0090)||
    + ((par->Chipset & 0xfff0)==0x01D0)||
    + ((par->Chipset & 0xfff0)==0x0290)){
                                                     NV_WR32(par->PGRAPH, 0x0DF0,
    - NV_RD32(par->PFB, 0x0200));
    + NV_RD32(par->PFB,
    + 0x0200));
                                                     NV_WR32(par->PGRAPH, 0x0DF4,
    - NV_RD32(par->PFB, 0x0204));
    + NV_RD32(par->PFB,
    + 0x0204));
                                             } else {
                                                     NV_WR32(par->PGRAPH, 0x09F0,
                                                             NV_RD32(par->PFB, 0x0200));
    diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
    index 1f06a9f..1330021 100644
    --- a/drivers/video/nvidia/nv_setup.c
    +++ b/drivers/video/nvidia/nv_setup.c
    @@ -277,6 +277,9 @@ static void nv10GetConfig(struct nvidia_
                         (NV_RD32(par->PFB, 0x020C) & 0xFFF00000) >> 10;
             }
     
    + if (par->RamAmountKBytes > 256*1024)
    + par->RamAmountKBytes = 256*1024;
    +
             par->CrystalFreqKHz = (NV_RD32(par->PEXTDEV, 0x0000) & (1 << 6)) ?
                 14318 : 13500;
     
    @@ -285,7 +288,6 @@ static void nv10GetConfig(struct nvidia_
                             par->CrystalFreqKHz = 27000;
             }
     
    - par->CursorStart = (par->RamAmountKBytes - 96) * 1024;
             par->CURSOR = NULL; /* can't set this here */
             par->MinVClockFreqKHz = 12000;
             par->MaxVClockFreqKHz = par->twoStagePLL ? 400000 : 350000;
    @@ -382,6 +384,8 @@ void NVCommonSetup(struct fb_info *info)
             case 0x0146:
             case 0x0147:
             case 0x0148:
    + case 0x0098:
    + case 0x0099:
                     mobile = 1;
                     break;
             default:
    diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
    index 961007d..19ab162 100644
    --- a/drivers/video/nvidia/nvidia.c
    +++ b/drivers/video/nvidia/nvidia.c
    @@ -1448,11 +1448,34 @@ static int __devinit nvidia_set_fbinfo(s
             return nvidiafb_check_var(&info->var, info);
     }
     
    -static u32 __devinit nvidia_get_arch(struct pci_dev *pd)
    +static u32 __devinit nvidia_get_chipset(struct fb_info *info)
     {
    + struct nvidia_par *par = info->par;
    + u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
    +
    + printk("nvidiafb: PCI id - %x\n", id);
    + if ((id & 0xfff0) == 0x00f0) {
    + /* pci-e */
    + printk("nvidiafb: PCI-E card\n");
    + id = NV_RD32(par->REGS, 0x1800);
    +
    + if ((id & 0x0000ffff) == 0x000010DE)
    + id = 0x10DE0000 | (id >> 16);
    + else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */
    + id = 0x10DE0000 | ((id << 8) & 0x0000ff00) |
    + ((id >> 8) & 0x000000ff);
    + }
    +
    + printk("nvidiafb: Actual id - %x\n", id);
    + return id;
    +}
    +
    +static u32 __devinit nvidia_get_arch(struct fb_info *info)
    +{
    + struct nvidia_par *par = info->par;
             u32 arch = 0;
     
    - switch (pd->device & 0x0ff0) {
    + switch (par->Chipset & 0x0ff0) {
             case 0x0100: /* GeForce 256 */
             case 0x0110: /* GeForce2 MX */
             case 0x0150: /* GeForce2 */
    @@ -1485,6 +1508,8 @@ static u32 __devinit nvidia_get_arch(str
             case 0x0210:
             case 0x0220:
             case 0x0230:
    + case 0x0290:
    + case 0x0390:
                     arch = NV_ARCH_40;
                     break;
             case 0x0020: /* TNT, TNT2 */
    @@ -1533,16 +1558,8 @@ static int __devinit nvidiafb_probe(stru
                     goto err_out_request;
             }
     
    - par->Architecture = nvidia_get_arch(pd);
    -
    - par->Chipset = (pd->vendor << 16) | pd->device;
             printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset);
     
    - if (par->Architecture == 0) {
    - printk(KERN_ERR PFX "unknown NV_ARCH\n");
    - goto err_out_free_base0;
    - }
    -
             sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
     
             par->FlatPanel = flatpanel;
    @@ -1570,6 +1587,14 @@ static int __devinit nvidiafb_probe(stru
                     goto err_out_free_base0;
             }
     
    + par->Chipset = nvidia_get_chipset(info);
    + par->Architecture = nvidia_get_arch(info);
    +
    + if (par->Architecture == 0) {
    + printk(KERN_ERR PFX "unknown NV_ARCH\n");
    + goto err_out_arch;
    + }
    +
             NVCommonSetup(info);
     
             par->FbAddress = nvidiafb_fix.smem_start;
    @@ -1581,10 +1606,15 @@ static int __devinit nvidiafb_probe(stru
             if (par->FbMapSize > 64 * 1024 * 1024)
                     par->FbMapSize = 64 * 1024 * 1024;
     
    - par->FbUsableSize = par->FbMapSize - (128 * 1024);
    + if(par->Architecture >= NV_ARCH_40)
    + par->FbUsableSize = par->FbMapSize - (560 * 1024);
    + else
    + par->FbUsableSize = par->FbMapSize - (128 * 1024);
    +
             par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
                 16 * 1024;
             par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
    + par->CursorStart = par->FbUsableSize + (32 * 1024);
             info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
             info->screen_size = par->FbUsableSize;
             nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
    @@ -1640,21 +1670,22 @@ static int __devinit nvidiafb_probe(stru
             NVTRACE_LEAVE();
             return 0;
     
    - err_out_iounmap_fb:
    +err_out_iounmap_fb:
             iounmap(info->screen_base);
    - err_out_free_base1:
    +err_out_free_base1:
             fb_destroy_modedb(info->monspecs.modedb);
             nvidia_delete_i2c_busses(par);
    +err_out_arch:
             iounmap(par->REGS);
    - err_out_free_base0:
    +err_out_free_base0:
             pci_release_regions(pd);
    - err_out_request:
    +err_out_request:
             pci_disable_device(pd);
    - err_out_enable:
    +err_out_enable:
             kfree(info->pixmap.addr);
    - err_out_kfree:
    +err_out_kfree:
             framebuffer_release(info);
    - err_out:
    +err_out:
             return -ENODEV;
     }
     
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/


  • Next message: Willy Tarreau: "Re: defective RAM: corrupted ext3 FS. How to identify corrupted files/directories?"

    Relevant Pages

    • Re: [PATCH] nvidiafb support for 6600 and 6200
      ... > in one of the registers (instead of deriving it from the pci device id) and ... after applying this patch. ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • Re: 2.6.12-rc2-mm3
      ... does the patch below fix the problem for you? ... register upon reloading. ... Now maybe reload the debug registers ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • [PATCH][RFC] Remove uneeded resource structures from pci_dev
      ... The following patch remove irq_resource and dma_resource from pci_dev. ... appears that the serial pci driver depends on irq_resource, however, it may be ... /* Use successive BARs (PCI base address registers), ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • Re: [PATCH] Reduce stack usage in module.c
      ... >> Before patch ... > So all function local variables are in registers? ... all function local variables of the patched who_is_doing_it ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • Re: [patch ide-dev 8/9] make ide_task_ioctl() use REQ_DRIVE_TASKFILE
      ... This patch should be modified to use flagged taskfile if the ... won't return valid result registers, TASK ioctl users won't get the ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)