aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/intelfb/intelfbhw.c102
-rw-r--r--drivers/video/intelfb/intelfbhw.h15
2 files changed, 63 insertions, 54 deletions
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 624c4bc96f0d..a3a94642b79b 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -40,6 +40,26 @@
40#include "intelfb.h" 40#include "intelfb.h"
41#include "intelfbhw.h" 41#include "intelfbhw.h"
42 42
43struct pll_min_max {
44 int min_m, max_m;
45 int min_m1, max_m1;
46 int min_m2, max_m2;
47 int min_n, max_n;
48 int min_p, max_p;
49 int min_p1, max_p1;
50 int min_vco_freq, max_vco_freq;
51 int p_transition_clock;
52};
53
54#define PLLS_I8xx 0
55#define PLLS_I9xx 1
56#define PLLS_MAX 2
57
58struct pll_min_max plls[PLLS_MAX] = {
59 { 108, 140, 18, 26, 6, 16, 3, 16, 4, 128, 0, 31, 930000, 1400000, 165000 }, //I8xx
60 { 75, 120, 10, 20, 5, 9, 4, 7, 5, 80, 1, 8, 930000, 2800000, 200000 } //I9xx
61};
62
43int 63int
44intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, int *chipset, 64intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, int *chipset,
45 int *mobile) 65 int *mobile)
@@ -697,17 +717,17 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
697 717
698/* Split the M parameter into M1 and M2. */ 718/* Split the M parameter into M1 and M2. */
699static int 719static int
700splitm(unsigned int m, unsigned int *retm1, unsigned int *retm2) 720splitm(int index, unsigned int m, unsigned int *retm1, unsigned int *retm2)
701{ 721{
702 int m1, m2; 722 int m1, m2;
703 723
704 m1 = (m - 2 - (MIN_M2 + MAX_M2) / 2) / 5 - 2; 724 m1 = (m - 2 - (plls[index].min_m1 + plls[index].max_m2) / 2) / 5 - 2;
705 if (m1 < MIN_M1) 725 if (m1 < plls[index].min_m1)
706 m1 = MIN_M1; 726 m1 = plls[index].min_m1;
707 if (m1 > MAX_M1) 727 if (m1 > plls[index].max_m1)
708 m1 = MAX_M1; 728 m1 = plls[index].max_m1;
709 m2 = m - 5 * (m1 + 2) - 2; 729 m2 = m - 5 * (m1 + 2) - 2;
710 if (m2 < MIN_M2 || m2 > MAX_M2 || m2 >= m1) { 730 if (m2 < plls[index].min_m2 || m2 > plls[index].max_m2 || m2 >= m1) {
711 return 1; 731 return 1;
712 } else { 732 } else {
713 *retm1 = (unsigned int)m1; 733 *retm1 = (unsigned int)m1;
@@ -718,30 +738,34 @@ splitm(unsigned int m, unsigned int *retm1, unsigned int *retm2)
718 738
719/* Split the P parameter into P1 and P2. */ 739/* Split the P parameter into P1 and P2. */
720static int 740static int
721splitp(unsigned int p, unsigned int *retp1, unsigned int *retp2) 741splitp(int index, unsigned int p, unsigned int *retp1, unsigned int *retp2)
722{ 742{
723 int p1, p2; 743 int p1, p2;
724 744
725 if (p % 4 == 0) 745 if (index==PLLS_I8xx)
726 p2 = 1; 746 {
727 else 747 if (p % 4 == 0)
728 p2 = 0; 748 p2 = 1;
729 p1 = (p / (1 << (p2 + 1))) - 2; 749 else
730 if (p % 4 == 0 && p1 < MIN_P1) { 750 p2 = 0;
731 p2 = 0;
732 p1 = (p / (1 << (p2 + 1))) - 2; 751 p1 = (p / (1 << (p2 + 1))) - 2;
752 if (p % 4 == 0 && p1 < plls[index].min_p1) {
753 p2 = 0;
754 p1 = (p / (1 << (p2 + 1))) - 2;
755 }
756 if (p1 < plls[index].min_p1 || p1 > plls[index].max_p1 || (p1 + 2) * (1 << (p2 + 1)) != p) {
757 return 1;
758 } else {
759 *retp1 = (unsigned int)p1;
760 *retp2 = (unsigned int)p2;
761 return 0;
762 }
733 } 763 }
734 if (p1 < MIN_P1 || p1 > MAX_P1 || (p1 + 2) * (1 << (p2 + 1)) != p) { 764 return 1;
735 return 1;
736 } else {
737 *retp1 = (unsigned int)p1;
738 *retp2 = (unsigned int)p2;
739 return 0;
740 }
741} 765}
742 766
743static int 767static int
744calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1, 768calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1,
745 u32 *retp2, u32 *retclock) 769 u32 *retp2, u32 *retclock)
746{ 770{
747 u32 m1, m2, n, p1, p2, n1; 771 u32 m1, m2, n, p1, p2, n1;
@@ -756,40 +780,40 @@ calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1,
756 780
757 DBG_MSG("Clock is %d\n", clock); 781 DBG_MSG("Clock is %d\n", clock);
758 782
759 div_max = MAX_VCO_FREQ / clock; 783 div_max = plls[index].max_vco_freq / clock;
760 div_min = ROUND_UP_TO(MIN_VCO_FREQ, clock) / clock; 784 div_min = ROUND_UP_TO(plls[index].min_vco_freq, clock) / clock;
761 785
762 if (clock <= P_TRANSITION_CLOCK) 786 if (clock <= plls[index].p_transition_clock)
763 p_inc = 4; 787 p_inc = 4;
764 else 788 else
765 p_inc = 2; 789 p_inc = 2;
766 p_min = ROUND_UP_TO(div_min, p_inc); 790 p_min = ROUND_UP_TO(div_min, p_inc);
767 p_max = ROUND_DOWN_TO(div_max, p_inc); 791 p_max = ROUND_DOWN_TO(div_max, p_inc);
768 if (p_min < MIN_P) 792 if (p_min < plls[index].min_p)
769 p_min = 4; 793 p_min = 4;
770 if (p_max > MAX_P) 794 if (p_max > plls[index].max_p)
771 p_max = 128; 795 p_max = 128;
772 796
773 DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc); 797 DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc);
774 798
775 p = p_min; 799 p = p_min;
776 do { 800 do {
777 if (splitp(p, &p1, &p2)) { 801 if (splitp(index, p, &p1, &p2)) {
778 WRN_MSG("cannot split p = %d\n", p); 802 WRN_MSG("cannot split p = %d\n", p);
779 p += p_inc; 803 p += p_inc;
780 continue; 804 continue;
781 } 805 }
782 n = MIN_N; 806 n = plls[index].min_n;
783 f_vco = clock * p; 807 f_vco = clock * p;
784 808
785 do { 809 do {
786 m = ROUND_UP_TO(f_vco * n, PLL_REFCLK) / PLL_REFCLK; 810 m = ROUND_UP_TO(f_vco * n, PLL_REFCLK) / PLL_REFCLK;
787 if (m < MIN_M) 811 if (m < plls[index].min_m)
788 m = MIN_M; 812 m = plls[index].min_m;
789 if (m > MAX_M) 813 if (m > plls[index].max_m)
790 m = MAX_M; 814 m = plls[index].max_m;
791 f_out = CALC_VCLOCK3(m, n, p); 815 f_out = CALC_VCLOCK3(m, n, p);
792 if (splitm(m, &m1, &m2)) { 816 if (splitm(index, m, &m1, &m2)) {
793 WRN_MSG("cannot split m = %d\n", m); 817 WRN_MSG("cannot split m = %d\n", m);
794 n++; 818 n++;
795 continue; 819 continue;
@@ -807,7 +831,7 @@ calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1,
807 err_best = f_err; 831 err_best = f_err;
808 } 832 }
809 n++; 833 n++;
810 } while ((n <= MAX_N) && (f_out >= clock)); 834 } while ((n <= plls[index].max_n) && (f_out >= clock));
811 p += p_inc; 835 p += p_inc;
812 } while ((p <= p_max)); 836 } while ((p <= p_max));
813 837
@@ -818,8 +842,8 @@ calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1,
818 m = m_best; 842 m = m_best;
819 n = n_best; 843 n = n_best;
820 p = p_best; 844 p = p_best;
821 splitm(m, &m1, &m2); 845 splitm(index, m, &m1, &m2);
822 splitp(p, &p1, &p2); 846 splitp(index, p, &p1, &p2);
823 n1 = n - 2; 847 n1 = n - 2;
824 848
825 DBG_MSG("m, n, p: %d (%d,%d), %d (%d), %d (%d,%d), " 849 DBG_MSG("m, n, p: %d (%d,%d), %d (%d), %d (%d,%d), "
@@ -929,7 +953,7 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
929 /* Desired clock in kHz */ 953 /* Desired clock in kHz */
930 clock_target = 1000000000 / var->pixclock; 954 clock_target = 1000000000 / var->pixclock;
931 955
932 if (calc_pll_params(clock_target, &m1, &m2, &n, &p1, &p2, &clock)) { 956 if (calc_pll_params(PLLS_I8xx, clock_target, &m1, &m2, &n, &p1, &p2, &clock)) {
933 WRN_MSG("calc_pll_params failed\n"); 957 WRN_MSG("calc_pll_params failed\n");
934 return 1; 958 return 1;
935 } 959 }
diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/intelfb/intelfbhw.h
index ba1920159f52..e3c305c66d5c 100644
--- a/drivers/video/intelfb/intelfbhw.h
+++ b/drivers/video/intelfb/intelfbhw.h
@@ -155,23 +155,8 @@
155/* PLL parameters (these are for 852GM/855GM/865G, check earlier chips). */ 155/* PLL parameters (these are for 852GM/855GM/865G, check earlier chips). */
156/* Clock values are in units of kHz */ 156/* Clock values are in units of kHz */
157#define PLL_REFCLK 48000 157#define PLL_REFCLK 48000
158#define MIN_VCO_FREQ 930000
159#define MAX_VCO_FREQ 1400000
160#define MIN_CLOCK 25000 158#define MIN_CLOCK 25000
161#define MAX_CLOCK 350000 159#define MAX_CLOCK 350000
162#define P_TRANSITION_CLOCK 165000
163#define MIN_M 108
164#define MAX_M 140
165#define MIN_M1 18
166#define MAX_M1 26
167#define MIN_M2 6
168#define MAX_M2 16
169#define MIN_P 4
170#define MAX_P 128
171#define MIN_P1 0
172#define MAX_P1 31
173#define MIN_N 3
174#define MAX_N 16
175 160
176#define CALC_VCLOCK(m1, m2, n, p1, p2) \ 161#define CALC_VCLOCK(m1, m2, n, p1, p2) \
177 ((PLL_REFCLK * (5 * ((m1) + 2) + ((m2) + 2)) / ((n) + 2)) / \ 162 ((PLL_REFCLK * (5 * ((m1) + 2) + ((m2) + 2)) / ((n) + 2)) / \