aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/cirrusfb.c50
1 files changed, 21 insertions, 29 deletions
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 573bd456e5ab..30c47f167608 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -327,10 +327,6 @@ static const struct {
327#endif /* CONFIG_ZORRO */ 327#endif /* CONFIG_ZORRO */
328 328
329struct cirrusfb_regs { 329struct cirrusfb_regs {
330 long freq;
331 long nom;
332 long den;
333 long div;
334 long multiplexing; 330 long multiplexing;
335 long mclk; 331 long mclk;
336 long divMCLK; 332 long divMCLK;
@@ -429,9 +425,7 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
429 u_short width, u_short height, 425 u_short width, u_short height,
430 u_char color, u_short line_length); 426 u_char color, u_short line_length);
431 427
432static void bestclock(long freq, long *best, 428static void bestclock(long freq, int *nom, int *den, int *div);
433 long *nom, long *den,
434 long *div, long maxfreq);
435 429
436#ifdef CIRRUSFB_DEBUG 430#ifdef CIRRUSFB_DEBUG
437static void cirrusfb_dump(void); 431static void cirrusfb_dump(void);
@@ -711,9 +705,6 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
711 break; 705 break;
712 } 706 }
713#endif 707#endif
714
715 bestclock(freq, &regs->freq, &regs->nom, &regs->den, &regs->div,
716 maxclock);
717 regs->mclk = cirrusfb_get_mclk(freq, var->bits_per_pixel, 708 regs->mclk = cirrusfb_get_mclk(freq, var->bits_per_pixel,
718 &regs->divMCLK); 709 &regs->divMCLK);
719 710
@@ -756,6 +747,8 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
756 const struct cirrusfb_board_info_rec *bi; 747 const struct cirrusfb_board_info_rec *bi;
757 int hdispend, hsyncstart, hsyncend, htotal; 748 int hdispend, hsyncstart, hsyncend, htotal;
758 int yres, vdispend, vsyncstart, vsyncend, vtotal; 749 int yres, vdispend, vsyncstart, vsyncend, vtotal;
750 long freq;
751 int nom, den, div;
759 752
760 DPRINTK("ENTER\n"); 753 DPRINTK("ENTER\n");
761 DPRINTK("Requested mode: %dx%dx%d\n", 754 DPRINTK("Requested mode: %dx%dx%d\n",
@@ -903,14 +896,17 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
903 DPRINTK("CRT1a: %d\n", tmp); 896 DPRINTK("CRT1a: %d\n", tmp);
904 vga_wcrt(regbase, CL_CRT1A, tmp); 897 vga_wcrt(regbase, CL_CRT1A, tmp);
905 898
899 freq = PICOS2KHZ(var->pixclock);
900 bestclock(freq, &nom, &den, &div);
901
906 /* set VCLK0 */ 902 /* set VCLK0 */
907 /* hardware RefClock: 14.31818 MHz */ 903 /* hardware RefClock: 14.31818 MHz */
908 /* formula: VClk = (OSC * N) / (D * (1+P)) */ 904 /* formula: VClk = (OSC * N) / (D * (1+P)) */
909 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */ 905 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
910 906
911 vga_wseq(regbase, CL_SEQRB, regs.nom); 907 vga_wseq(regbase, CL_SEQRB, nom);
912 tmp = regs.den << 1; 908 tmp = den << 1;
913 if (regs.div != 0) 909 if (div != 0)
914 tmp |= 1; 910 tmp |= 1;
915 911
916 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ 912 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
@@ -2923,16 +2919,14 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2923 * bestclock() - determine closest possible clock lower(?) than the 2919 * bestclock() - determine closest possible clock lower(?) than the
2924 * desired pixel clock 2920 * desired pixel clock
2925 **************************************************************************/ 2921 **************************************************************************/
2926static void bestclock(long freq, long *best, long *nom, 2922static void bestclock(long freq, int *nom, int *den, int *div)
2927 long *den, long *div, long maxfreq)
2928{ 2923{
2929 long n, h, d, f; 2924 int n, d;
2925 long h, diff;
2930 2926
2931 assert(best != NULL);
2932 assert(nom != NULL); 2927 assert(nom != NULL);
2933 assert(den != NULL); 2928 assert(den != NULL);
2934 assert(div != NULL); 2929 assert(div != NULL);
2935 assert(maxfreq > 0);
2936 2930
2937 *nom = 0; 2931 *nom = 0;
2938 *den = 0; 2932 *den = 0;
@@ -2943,16 +2937,12 @@ static void bestclock(long freq, long *best, long *nom,
2943 if (freq < 8000) 2937 if (freq < 8000)
2944 freq = 8000; 2938 freq = 8000;
2945 2939
2946 if (freq > maxfreq) 2940 diff = freq;
2947 freq = maxfreq;
2948
2949 *best = 0;
2950 f = freq * 10;
2951 2941
2952 for (n = 32; n < 128; n++) { 2942 for (n = 32; n < 128; n++) {
2953 int s = 0; 2943 int s = 0;
2954 2944
2955 d = (143181 * n) / f; 2945 d = (14318 * n) / freq;
2956 if ((d >= 7) && (d <= 63)) { 2946 if ((d >= 7) && (d <= 63)) {
2957 int temp = d; 2947 int temp = d;
2958 2948
@@ -2961,8 +2951,9 @@ static void bestclock(long freq, long *best, long *nom,
2961 temp >>= 1; 2951 temp >>= 1;
2962 } 2952 }
2963 h = ((14318 * n) / temp) >> s; 2953 h = ((14318 * n) / temp) >> s;
2964 if (abs(h - freq) < abs(*best - freq)) { 2954 h = h > freq ? h - freq : freq - h;
2965 *best = h; 2955 if (h < diff) {
2956 diff = h;
2966 *nom = n; 2957 *nom = n;
2967 *den = temp; 2958 *den = temp;
2968 *div = s; 2959 *div = s;
@@ -2975,8 +2966,9 @@ static void bestclock(long freq, long *best, long *nom,
2975 d >>= 1; 2966 d >>= 1;
2976 } 2967 }
2977 h = ((14318 * n) / d) >> s; 2968 h = ((14318 * n) / d) >> s;
2978 if (abs(h - freq) < abs(*best - freq)) { 2969 h = h > freq ? h - freq : freq - h;
2979 *best = h; 2970 if (h < diff) {
2971 diff = h;
2980 *nom = n; 2972 *nom = n;
2981 *den = d; 2973 *den = d;
2982 *div = s; 2974 *div = s;
@@ -2985,7 +2977,7 @@ static void bestclock(long freq, long *best, long *nom,
2985 } 2977 }
2986 2978
2987 DPRINTK("Best possible values for given frequency:\n"); 2979 DPRINTK("Best possible values for given frequency:\n");
2988 DPRINTK(" best: %ld kHz nom: %ld den: %ld div: %ld\n", 2980 DPRINTK(" freq: %ld kHz nom: %d den: %d div: %d\n",
2989 freq, *nom, *den, *div); 2981 freq, *nom, *den, *div);
2990 2982
2991 DPRINTK("EXIT\n"); 2983 DPRINTK("EXIT\n");