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