aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/tdfxfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/tdfxfb.c')
-rw-r--r--drivers/video/tdfxfb.c88
1 files changed, 53 insertions, 35 deletions
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index c34ba39b6f7e..7044226c5d4c 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -317,30 +317,49 @@ static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c)
317 317
318static u32 do_calc_pll(int freq, int* freq_out) 318static u32 do_calc_pll(int freq, int* freq_out)
319{ 319{
320 int m, n, k, best_m, best_n, best_k, f_cur, best_error; 320 int m, n, k, best_m, best_n, best_k, best_error;
321 int fref = 14318; 321 int fref = 14318;
322 322
323 /* this really could be done with more intelligence --
324 255*63*4 = 64260 iterations is silly */
325 best_error = freq; 323 best_error = freq;
326 best_n = best_m = best_k = 0; 324 best_n = best_m = best_k = 0;
327 for (n = 1; n < 256; n++) { 325
328 for (m = 1; m < 64; m++) { 326 for (k = 3; k >= 0; k--) {
329 for (k = 0; k < 4; k++) { 327 for (m = 63; m >= 0; m--) {
330 f_cur = fref*(n + 2)/(m + 2)/(1 << k); 328 /*
331 if (abs(f_cur - freq) < best_error) { 329 * Estimate value of n that produces target frequency
332 best_error = abs(f_cur-freq); 330 * with current m and k
333 best_n = n; 331 */
334 best_m = m; 332 int n_estimated = (freq * (m + 2) * (1 << k) / fref) - 2;
335 best_k = k; 333
334 /* Search neighborhood of estimated n */
335 for (n = max(0, n_estimated - 1);
336 n <= min(255, n_estimated + 1); n++) {
337 /*
338 * Calculate PLL freqency with current m, k and
339 * estimated n
340 */
341 int f = fref * (n + 2) / (m + 2) / (1 << k);
342 int error = abs (f - freq);
343
344 /*
345 * If this is the closest we've come to the
346 * target frequency then remember n, m and k
347 */
348 if (error < best_error) {
349 best_error = error;
350 best_n = n;
351 best_m = m;
352 best_k = k;
336 } 353 }
337 } 354 }
338 } 355 }
339 } 356 }
357
340 n = best_n; 358 n = best_n;
341 m = best_m; 359 m = best_m;
342 k = best_k; 360 k = best_k;
343 *freq_out = fref*(n + 2)/(m + 2)/(1 << k); 361 *freq_out = fref*(n + 2)/(m + 2)/(1 << k);
362
344 return (n << 8) | (m << 2) | k; 363 return (n << 8) | (m << 2) | k;
345} 364}
346 365
@@ -411,36 +430,35 @@ static void do_write_regs(struct fb_info *info, struct banshee_reg* reg)
411 430
412static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) 431static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id)
413{ 432{
414 u32 draminit0 = 0; 433 u32 draminit0;
415 u32 draminit1 = 0; 434 u32 draminit1;
416 u32 miscinit1 = 0; 435 u32 miscinit1;
417 u32 lfbsize = 0; 436
418 int sgram_p = 0; 437 int num_chips;
438 int chip_size; /* in MB */
439 u32 lfbsize;
440 int has_sgram;
419 441
420 draminit0 = tdfx_inl(par, DRAMINIT0); 442 draminit0 = tdfx_inl(par, DRAMINIT0);
421 draminit1 = tdfx_inl(par, DRAMINIT1); 443 draminit1 = tdfx_inl(par, DRAMINIT1);
444
445 num_chips = (draminit0 & DRAMINIT0_SGRAM_NUM) ? 8 : 4;
422 446
423 if ((dev_id == PCI_DEVICE_ID_3DFX_BANSHEE) || 447 if (dev_id < PCI_DEVICE_ID_3DFX_VOODOO5) {
424 (dev_id == PCI_DEVICE_ID_3DFX_VOODOO3)) { 448 /* Banshee/Voodoo3 */
425 sgram_p = (draminit1 & DRAMINIT1_MEM_SDRAM) ? 0 : 1; 449 has_sgram = draminit1 & DRAMINIT1_MEM_SDRAM;
426 450 chip_size = has_sgram ? ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 2 : 1)
427 lfbsize = sgram_p ? 451 : 2;
428 (((draminit0 & DRAMINIT0_SGRAM_NUM) ? 2 : 1) *
429 ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 8 : 4) * 1024 * 1024) :
430 16 * 1024 * 1024;
431 } else { 452 } else {
432 /* Voodoo4/5 */ 453 /* Voodoo4/5 */
433 u32 chips, psize, banks; 454 has_sgram = 0;
434 455 chip_size = 1 << ((draminit0 & DRAMINIT0_SGRAM_TYPE_MASK) >> DRAMINIT0_SGRAM_TYPE_SHIFT);
435 chips = ((draminit0 & (1 << 26)) == 0) ? 4 : 8; 456 }
436 psize = 1 << ((draminit0 & 0x38000000) >> 28); 457 lfbsize = num_chips * chip_size * 1024 * 1024;
437 banks = ((draminit0 & (1 << 30)) == 0) ? 2 : 4; 458
438 lfbsize = chips * psize * banks; 459 /* disable block writes for SDRAM */
439 lfbsize <<= 20;
440 }
441 /* disable block writes for SDRAM (why?) */
442 miscinit1 = tdfx_inl(par, MISCINIT1); 460 miscinit1 = tdfx_inl(par, MISCINIT1);
443 miscinit1 |= sgram_p ? 0 : MISCINIT1_2DBLOCK_DIS; 461 miscinit1 |= has_sgram ? 0 : MISCINIT1_2DBLOCK_DIS;
444 miscinit1 |= MISCINIT1_CLUT_INV; 462 miscinit1 |= MISCINIT1_CLUT_INV;
445 463
446 banshee_make_room(par, 1); 464 banshee_make_room(par, 1);