aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/intelfb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/intelfb')
-rw-r--r--drivers/video/intelfb/intelfbhw.c71
1 files changed, 34 insertions, 37 deletions
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 4284c7554512..05f0a3c9440f 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -41,14 +41,10 @@
41#include "intelfbhw.h" 41#include "intelfbhw.h"
42 42
43struct pll_min_max { 43struct pll_min_max {
44 int min_m, max_m; 44 int min_m, max_m, min_m1, max_m1;
45 int min_m1, max_m1; 45 int min_m2, max_m2, min_n, max_n;
46 int min_m2, max_m2; 46 int min_p, max_p, min_p1, max_p1;
47 int min_n, max_n; 47 int min_vco, max_vco, p_transition_clk, ref_clk;
48 int min_p, max_p;
49 int min_p1, max_p1;
50 int min_vco, max_vco;
51 int p_transition_clk, ref_clk;
52 int p_inc_lo, p_inc_hi; 48 int p_inc_lo, p_inc_hi;
53}; 49};
54 50
@@ -57,8 +53,17 @@ struct pll_min_max {
57#define PLLS_MAX 2 53#define PLLS_MAX 2
58 54
59static struct pll_min_max plls[PLLS_MAX] = { 55static struct pll_min_max plls[PLLS_MAX] = {
60 { 108, 140, 18, 26, 6, 16, 3, 16, 4, 128, 0, 31, 930000, 1400000, 165000, 48000, 4, 22 }, //I8xx 56 { 108, 140, 18, 26,
61 { 75, 120, 10, 20, 5, 9, 4, 7, 5, 80, 1, 8, 930000, 2800000, 200000, 96000, 10, 5 } //I9xx 57 6, 16, 3, 16,
58 4, 128, 0, 31,
59 930000, 1400000, 165000, 48000,
60 4, 2 }, //I8xx
61
62 { 75, 120, 10, 20,
63 5, 9, 4, 7,
64 5, 80, 1, 8,
65 1400000, 2800000, 200000, 96000,
66 10, 5 } //I9xx
62}; 67};
63 68
64int 69int
@@ -698,8 +703,7 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
698 703
699 tmpp1 = p1; 704 tmpp1 = p1;
700 705
701 switch (tmpp1) 706 switch (tmpp1) {
702 {
703 case 0x1: p1 = 1; break; 707 case 0x1: p1 = 1; break;
704 case 0x2: p1 = 2; break; 708 case 0x2: p1 = 2; break;
705 case 0x4: p1 = 3; break; 709 case 0x4: p1 = 3; break;
@@ -710,7 +714,7 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
710 case 0x80: p1 = 8; break; 714 case 0x80: p1 = 8; break;
711 default: break; 715 default: break;
712 } 716 }
713 717
714 p2 = (hw->dpll_a >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK; 718 p2 = (hw->dpll_a >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK;
715 719
716 } else { 720 } else {
@@ -849,8 +853,7 @@ splitp(int index, unsigned int p, unsigned int *retp1, unsigned int *retp2)
849 int p1, p2; 853 int p1, p2;
850 854
851 if (index == PLLS_I9xx) { 855 if (index == PLLS_I9xx) {
852 856 p2 = (p % 10) ? 1 : 0;
853 p2 = 0; // for now
854 857
855 p1 = p / (p2 ? 5 : 10); 858 p1 = p / (p2 ? 5 : 10);
856 859
@@ -890,7 +893,8 @@ calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *re
890 u32 f_vco, p, p_best = 0, m, f_out = 0; 893 u32 f_vco, p, p_best = 0, m, f_out = 0;
891 u32 err_max, err_target, err_best = 10000000; 894 u32 err_max, err_target, err_best = 10000000;
892 u32 n_best = 0, m_best = 0, f_best, f_err; 895 u32 n_best = 0, m_best = 0, f_best, f_err;
893 u32 p_min, p_max, p_inc, div_min, div_max; 896 u32 p_min, p_max, p_inc, div_max;
897 struct pll_min_max *pll = &plls[index];
894 898
895 /* Accept 0.5% difference, but aim for 0.1% */ 899 /* Accept 0.5% difference, but aim for 0.1% */
896 err_max = 5 * clock / 1000; 900 err_max = 5 * clock / 1000;
@@ -898,22 +902,15 @@ calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *re
898 902
899 DBG_MSG("Clock is %d\n", clock); 903 DBG_MSG("Clock is %d\n", clock);
900 904
901 div_max = plls[index].max_vco / clock; 905 div_max = pll->max_vco / clock;
902 if (index == PLLS_I9xx)
903 div_min = 5;
904 else
905 div_min = ROUND_UP_TO(plls[index].min_vco, clock) / clock;
906 906
907 if (clock <= plls[index].p_transition_clk) 907 p_inc = (clock <= pll->p_transition_clk) ? pll->p_inc_lo : pll->p_inc_hi;
908 p_inc = plls[index].p_inc_lo; 908 p_min = p_inc;
909 else
910 p_inc = plls[index].p_inc_hi;
911 p_min = ROUND_UP_TO(div_min, p_inc);
912 p_max = ROUND_DOWN_TO(div_max, p_inc); 909 p_max = ROUND_DOWN_TO(div_max, p_inc);
913 if (p_min < plls[index].min_p) 910 if (p_min < pll->min_p)
914 p_min = plls[index].min_p; 911 p_min = pll->min_p;
915 if (p_max > plls[index].max_p) 912 if (p_max > pll->max_p)
916 p_max = plls[index].max_p; 913 p_max = pll->max_p;
917 914
918 DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc); 915 DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc);
919 916
@@ -924,15 +921,15 @@ calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *re
924 p += p_inc; 921 p += p_inc;
925 continue; 922 continue;
926 } 923 }
927 n = plls[index].min_n; 924 n = pll->min_n;
928 f_vco = clock * p; 925 f_vco = clock * p;
929 926
930 do { 927 do {
931 m = ROUND_UP_TO(f_vco * n, plls[index].ref_clk) / plls[index].ref_clk; 928 m = ROUND_UP_TO(f_vco * n, pll->ref_clk) / pll->ref_clk;
932 if (m < plls[index].min_m) 929 if (m < pll->min_m)
933 m = plls[index].min_m + 1; 930 m = pll->min_m + 1;
934 if (m > plls[index].max_m) 931 if (m > pll->max_m)
935 m = plls[index].max_m - 1; 932 m = pll->max_m - 1;
936 for (testm = m - 1; testm <= m; testm++) { 933 for (testm = m - 1; testm <= m; testm++) {
937 f_out = calc_vclock3(index, m, n, p); 934 f_out = calc_vclock3(index, m, n, p);
938 if (splitm(index, m, &m1, &m2)) { 935 if (splitm(index, m, &m1, &m2)) {
@@ -954,7 +951,7 @@ calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *re
954 } 951 }
955 } 952 }
956 n++; 953 n++;
957 } while ((n <= plls[index].max_n) && (f_out >= clock)); 954 } while ((n <= pll->max_n) && (f_out >= clock));
958 p += p_inc; 955 p += p_inc;
959 } while ((p <= p_max)); 956 } while ((p <= p_max));
960 957