Re: [PATCH] Clean-up and bug fix for tdfxfb framebuffer size detection
Hi Chris On Friday 22 April 2005 03:48 am, Chris Ross wrote: > I /do/ have the hardware, so I am very glad to see someone working on > support for the Voodoo 5. I am glad somebody is interested. ;-) > Are there any specific tests you would like me > to perform and send you the results from? It's quite simple really. With this patch, does tdfxfb report the right amount of framebuffer memory for your card? The method it used to determine the amount of memory for the Voodoo4/5 before was wrong. If it gave the right value before, then it was probably just a coincidence. Cheers, Rich - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] Clean-up and bug fix for tdfxfb framebuffer size detection
Attached is a patch against 2.6.11.7 which tidies up the tdfxfb framebuffer size detection code a little and fixes the broken support for Voodoo4/5 cards. (I haven't tested this on a Voodoo5, however, because I don't have the hardware). Signed-off-by: Richard Drummond <[EMAIL PROTECTED]> --- drivers/video/tdfxfb.c_orig 2005-04-20 15:04:23.0 -0500 +++ drivers/video/tdfxfb.c 2005-04-21 22:20:32.0 -0500 @@ -414,36 +414,35 @@ static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) { - u32 draminit0 = 0; - u32 draminit1 = 0; - u32 miscinit1 = 0; - u32 lfbsize = 0; - int sgram_p = 0; + u32 draminit0; + u32 draminit1; + u32 miscinit1; + + int num_chips; + int chip_size; /* in MB */ + u32 lfbsize; + int has_sgram; draminit0 = tdfx_inl(par, DRAMINIT0); draminit1 = tdfx_inl(par, DRAMINIT1); + + num_chips = (draminit0 & DRAMINIT0_SGRAM_NUM) ? 8 : 4; - if ((dev_id == PCI_DEVICE_ID_3DFX_BANSHEE) || - (dev_id == PCI_DEVICE_ID_3DFX_VOODOO3)) { - sgram_p = (draminit1 & DRAMINIT1_MEM_SDRAM) ? 0 : 1; - - lfbsize = sgram_p ? - (((draminit0 & DRAMINIT0_SGRAM_NUM) ? 2 : 1) * - ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 8 : 4) * 1024 * 1024) : - 16 * 1024 * 1024; + if (dev_id < PCI_DEVICE_ID_3DFX_VOODOO5) { + /* Banshee/Voodoo3 */ + has_sgram = draminit1 & DRAMINIT1_MEM_SDRAM; + chip_size = has_sgram ? ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 2 : 1) + : 2; } else { /* Voodoo4/5 */ - u32 chips, psize, banks; + has_sgram = 0; + chip_size = 1 << ((draminit0 & DRAMINIT0_SGRAM_TYPE_MASK) >> DRAMINIT0_SGRAM_TYPE_SHIFT); + } + lfbsize = num_chips * chip_size * 1024 * 1024; - chips = ((draminit0 & (1 << 26)) == 0) ? 4 : 8; - psize = 1 << ((draminit0 & 0x3800) >> 28); - banks = ((draminit0 & (1 << 30)) == 0) ? 2 : 4; - lfbsize = chips * psize * banks; - lfbsize <<= 20; - } - /* disable block writes for SDRAM (why?) */ + /* disable block writes for SDRAM */ miscinit1 = tdfx_inl(par, MISCINIT1); - miscinit1 |= sgram_p ? 0 : MISCINIT1_2DBLOCK_DIS; + miscinit1 |= has_sgram ? 0 : MISCINIT1_2DBLOCK_DIS; miscinit1 |= MISCINIT1_CLUT_INV; banshee_make_room(par, 1); --- include/video/tdfx.h_orig 2005-04-21 21:16:56.0 -0500 +++ include/video/tdfx.h 2005-04-21 09:39:42.0 -0500 @@ -99,6 +99,8 @@ #define MISCINIT1_2DBLOCK_DIS BIT(15) #define DRAMINIT0_SGRAM_NUM BIT(26) #define DRAMINIT0_SGRAM_TYPEBIT(27) +#define DRAMINIT0_SGRAM_TYPE_MASK (BIT(27)|BIT(28)|BIT(29)) +#define DRAMINIT0_SGRAM_TYPE_SHIFT 27 #define DRAMINIT1_MEM_SDRAM BIT(30) #define VGAINIT0_VGA_DISABLEBIT(0) #define VGAINIT0_EXT_TIMING BIT(1)
[PATCH] Better PLL frequency matching for tdfxfb driver
Attached is a patch against 2.6.11.7 which improves the PLL frequency matching in the tdfxfb driver. Instead of requiring 64260 iterations to obtain the closest supported PLL frequency, this code does it with the same degree of accuracy in at most 768 iterations. Signed-off-by: Richard Drummond <[EMAIL PROTECTED]> --- drivers/video/tdfxfb.c_orig 2005-04-20 15:04:23.0 -0500 +++ drivers/video/tdfxfb.c 2005-04-21 09:26:18.0 -0500 @@ -320,30 +320,40 @@ static u32 do_calc_pll(int freq, int* freq_out) { - int m, n, k, best_m, best_n, best_k, f_cur, best_error; + int m, n, k, best_m, best_n, best_k, best_error; int fref = 14318; - /* this really could be done with more intelligence -- - 255*63*4 = 64260 iterations is silly */ best_error = freq; best_n = best_m = best_k = 0; - for (n = 1; n < 256; n++) { - for (m = 1; m < 64; m++) { - for (k = 0; k < 4; k++) { -f_cur = fref*(n + 2)/(m + 2)/(1 << k); -if (abs(f_cur - freq) < best_error) { - best_error = abs(f_cur-freq); - best_n = n; - best_m = m; - best_k = k; -} + + for (k = 3; k >= 0; k--) { + for (m = 63; m >= 0; m--) { + /* Estimate value of n that produces target frequency with current m and k */ + int n_estimated = (freq * (m + 2) * (1 << k) / fref) - 2; + + /* Search neighborhood of estimated n */ + for (n = max(0, n_estimated - 1); n <= min(255, n_estimated + 1); n++) { +/* Calculate PLL freqency with current m, k and estimated n */ +int f = fref * (n + 2) / (m + 2) / (1 << k); +int error = abs (f - freq); + +/* If this is the closest we've come to the target frequency + * then remember n, m and k */ +if (error < best_error) { + best_error = error; + best_n = n; + best_m = m; + best_k = k; +} } } } + n = best_n; m = best_m; k = best_k; *freq_out = fref*(n + 2)/(m + 2)/(1 << k); + return (n << 8) | (m << 2) | k; }