[PATCH] Patch for nvidia divide by zero error for 7600 pci-express card

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>

authored by Wink Saville and committed by Linus Torvalds e40c6759 7947d2cc

+39 -16
+9 -3
drivers/video/nvidia/nv_hw.c
··· 145 146 if (par->Architecture >= NV_ARCH_40) { 147 pll = NV_RD32(par->PMC, 0x4020); 148 - P = (pll >> 16) & 0x03; 149 pll = NV_RD32(par->PMC, 0x4024); 150 M = pll & 0xFF; 151 N = (pll >> 8) & 0xFF; 152 - MB = (pll >> 16) & 0xFF; 153 - NB = (pll >> 24) & 0xFF; 154 *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P; 155 156 pll = NV_RD32(par->PMC, 0x4000);
··· 145 146 if (par->Architecture >= NV_ARCH_40) { 147 pll = NV_RD32(par->PMC, 0x4020); 148 + P = (pll >> 16) & 0x07; 149 pll = NV_RD32(par->PMC, 0x4024); 150 M = pll & 0xFF; 151 N = (pll >> 8) & 0xFF; 152 + if (((par->Chipset & 0xfff0) == 0x0290) || 153 + ((par->Chipset & 0xfff0) == 0x0390)) { 154 + MB = 1; 155 + NB = 1; 156 + } else { 157 + MB = (pll >> 16) & 0xFF; 158 + NB = (pll >> 24) & 0xFF; 159 + } 160 *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P; 161 162 pll = NV_RD32(par->PMC, 0x4000);
+17 -1
drivers/video/nvidia/nv_setup.c
··· 359 case 0x0186: 360 case 0x0187: 361 case 0x018D: 362 case 0x0286: 363 case 0x028C: 364 case 0x0316: ··· 383 case 0x034C: 384 case 0x0160: 385 case 0x0166: 386 case 0x00C8: 387 case 0x00CC: 388 case 0x0144: ··· 644 par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1; 645 par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033; 646 647 - printk("Panel size is %i x %i\n", par->fpWidth, par->fpHeight); 648 } 649 650 if (monA) 651 info->monspecs = *monA; 652 653 kfree(edidA); 654 kfree(edidB);
··· 359 case 0x0186: 360 case 0x0187: 361 case 0x018D: 362 + case 0x0228: 363 case 0x0286: 364 case 0x028C: 365 case 0x0316: ··· 382 case 0x034C: 383 case 0x0160: 384 case 0x0166: 385 + case 0x0169: 386 + case 0x016B: 387 + case 0x016C: 388 + case 0x016D: 389 case 0x00C8: 390 case 0x00CC: 391 case 0x0144: ··· 639 par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1; 640 par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033; 641 642 + printk("nvidiafb: Panel size is %i x %i\n", par->fpWidth, par->fpHeight); 643 } 644 645 if (monA) 646 info->monspecs = *monA; 647 + 648 + if (!par->FlatPanel || !par->twoHeads) 649 + par->FPDither = 0; 650 + 651 + par->LVDS = 0; 652 + if (par->FlatPanel && par->twoHeads) { 653 + NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004); 654 + if (par->PRAMDAC0[0x08b4] & 1) 655 + par->LVDS = 1; 656 + printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS"); 657 + } 658 659 kfree(edidA); 660 kfree(edidB);
+1
drivers/video/nvidia/nv_type.h
··· 129 int fpHeight; 130 int PanelTweak; 131 int paneltweak; 132 int pm_state; 133 u32 crtcSync_read; 134 u32 fpSyncs;
··· 129 int fpHeight; 130 int PanelTweak; 131 int paneltweak; 132 + int LVDS; 133 int pm_state; 134 u32 crtcSync_read; 135 u32 fpSyncs;
+12 -12
drivers/video/nvidia/nvidia.c
··· 1160 case 0x0340: /* GeForceFX 5700 */ 1161 arch = NV_ARCH_30; 1162 break; 1163 - case 0x0040: 1164 - case 0x00C0: 1165 - case 0x0120: 1166 case 0x0130: 1167 - case 0x0140: 1168 - case 0x0160: 1169 - case 0x01D0: 1170 - case 0x0090: 1171 - case 0x0210: 1172 - case 0x0220: 1173 case 0x0230: 1174 - case 0x0240: 1175 - case 0x0290: 1176 - case 0x0390: 1177 arch = NV_ARCH_40; 1178 break; 1179 case 0x0020: /* TNT, TNT2 */
··· 1160 case 0x0340: /* GeForceFX 5700 */ 1161 arch = NV_ARCH_30; 1162 break; 1163 + case 0x0040: /* GeForce 6800 */ 1164 + case 0x00C0: /* GeForce 6800 */ 1165 + case 0x0120: /* GeForce 6800 */ 1166 case 0x0130: 1167 + case 0x0140: /* GeForce 6600 */ 1168 + case 0x0160: /* GeForce 6200 */ 1169 + case 0x01D0: /* GeForce 7200, 7300, 7400 */ 1170 + case 0x0090: /* GeForce 7800 */ 1171 + case 0x0210: /* GeForce 6800 */ 1172 + case 0x0220: /* GeForce 6200 */ 1173 case 0x0230: 1174 + case 0x0240: /* GeForce 6100 */ 1175 + case 0x0290: /* GeForce 7900 */ 1176 + case 0x0390: /* GeForce 7600 */ 1177 arch = NV_ARCH_40; 1178 break; 1179 case 0x0020: /* TNT, TNT2 */