[PATCH] Patch for nvidia divide by zero error for 7600 pci-express card
authorWink Saville <wink@saville.com>
Fri, 10 Nov 2006 20:27:52 +0000 (12:27 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 13 Nov 2006 15:40:42 +0000 (07:40 -0800)
The following patch resolves the divide by zero error I encountered on my
system:

http://marc.10east.com/?l=linux-fbdev-devel&m=116058257024413&w=2

I accomplished this by merging what I thought was appropriate from:

http://webcvs.freedesktop.org/xorg/driver/xf86-video-nv/src/

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/video/nvidia/nv_hw.c
drivers/video/nvidia/nv_setup.c
drivers/video/nvidia/nv_type.h
drivers/video/nvidia/nvidia.c

index 9ed640d..ea42611 100644 (file)
@@ -145,12 +145,18 @@ static void nvGetClocks(struct nvidia_par *par, unsigned int *MClk,
 
        if (par->Architecture >= NV_ARCH_40) {
                pll = NV_RD32(par->PMC, 0x4020);
-               P = (pll >> 16) & 0x03;
+               P = (pll >> 16) & 0x07;
                pll = NV_RD32(par->PMC, 0x4024);
                M = pll & 0xFF;
                N = (pll >> 8) & 0xFF;
-               MB = (pll >> 16) & 0xFF;
-               NB = (pll >> 24) & 0xFF;
+               if (((par->Chipset & 0xfff0) == 0x0290) ||
+                               ((par->Chipset & 0xfff0) == 0x0390)) {
+                       MB = 1;
+                       NB = 1;
+               } else {
+                       MB = (pll >> 16) & 0xFF;
+                       NB = (pll >> 24) & 0xFF;
+               }
                *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P;
 
                pll = NV_RD32(par->PMC, 0x4000);
index a18a9ae..61dc46f 100644 (file)
@@ -359,6 +359,7 @@ int NVCommonSetup(struct fb_info *info)
        case 0x0186:
        case 0x0187:
        case 0x018D:
+       case 0x0228:
        case 0x0286:
        case 0x028C:
        case 0x0316:
@@ -382,6 +383,10 @@ int NVCommonSetup(struct fb_info *info)
        case 0x034C:
        case 0x0160:
        case 0x0166:
+       case 0x0169:
+       case 0x016B:
+       case 0x016C:
+       case 0x016D:
        case 0x00C8:
        case 0x00CC:
        case 0x0144:
@@ -639,12 +644,23 @@ int NVCommonSetup(struct fb_info *info)
                par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1;
                par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033;
 
-               printk("Panel size is %i x %i\n", par->fpWidth, par->fpHeight);
+               printk("nvidiafb: Panel size is %i x %i\n", par->fpWidth, par->fpHeight);
        }
 
        if (monA)
                info->monspecs = *monA;
 
+       if (!par->FlatPanel || !par->twoHeads)
+               par->FPDither = 0;
+
+       par->LVDS = 0;
+       if (par->FlatPanel && par->twoHeads) {
+               NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004);
+               if (par->PRAMDAC0[0x08b4] & 1)
+                       par->LVDS = 1;
+               printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS");
+       }
+
        kfree(edidA);
        kfree(edidB);
 done:
index acdc266..86e65de 100644 (file)
@@ -129,6 +129,7 @@ struct nvidia_par {
        int fpHeight;
        int PanelTweak;
        int paneltweak;
+       int LVDS;
        int pm_state;
        u32 crtcSync_read;
        u32 fpSyncs;
index eb24107..538e947 100644 (file)
@@ -1160,20 +1160,20 @@ static u32 __devinit nvidia_get_arch(struct fb_info *info)
        case 0x0340:            /* GeForceFX 5700 */
                arch = NV_ARCH_30;
                break;
-       case 0x0040:
-       case 0x00C0:
-       case 0x0120:
+       case 0x0040:            /* GeForce 6800 */
+       case 0x00C0:            /* GeForce 6800 */
+       case 0x0120:            /* GeForce 6800 */
        case 0x0130:
-       case 0x0140:
-       case 0x0160:
-       case 0x01D0:
-       case 0x0090:
-       case 0x0210:
-       case 0x0220:
+       case 0x0140:            /* GeForce 6600 */
+       case 0x0160:            /* GeForce 6200 */
+       case 0x01D0:            /* GeForce 7200, 7300, 7400 */
+       case 0x0090:            /* GeForce 7800 */
+       case 0x0210:            /* GeForce 6800 */
+       case 0x0220:            /* GeForce 6200 */
        case 0x0230:
-       case 0x0240:
-       case 0x0290:
-       case 0x0390:
+       case 0x0240:            /* GeForce 6100 */
+       case 0x0290:            /* GeForce 7900 */
+       case 0x0390:            /* GeForce 7600 */
                arch = NV_ARCH_40;
                break;
        case 0x0020:            /* TNT, TNT2 */