diff options
Diffstat (limited to 'drivers/video/intelfb')
-rw-r--r-- | drivers/video/intelfb/intelfbhw.c | 71 |
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 | ||
43 | struct pll_min_max { | 43 | struct 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 | ||
59 | static struct pll_min_max plls[PLLS_MAX] = { | 55 | static 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 | ||
64 | int | 69 | int |
@@ -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 | ||