aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-03-21 09:28:26 -0400
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-03-23 09:01:37 -0400
commiteb0536c5e2815e3e38ed2b2f31401e114faec016 (patch)
tree5e2488ab57cd5f02a1cef53f1458c18e1396458e
parent3f086fe93f734ba76f2e130777687f81e0cbb318 (diff)
viafb: allow some pll calculations
This patch allows calculating the pll multiplier within limits based on the previous table. All available information supports that it should be possible/sane to choose the multiplier free within some ranges. Storing the multiplier ranges instead of lots of pll configurations reduces the memory needed and may as well improve the performance. It is also expected to provide better pll values resulting in better frequencies for the connected devices. Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
-rw-r--r--drivers/video/via/hw.c377
-rw-r--r--drivers/video/via/hw.h11
2 files changed, 106 insertions, 282 deletions
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index dc4c778877ce..063ff65fbea6 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -22,272 +22,80 @@
22#include <linux/via-core.h> 22#include <linux/via-core.h>
23#include "global.h" 23#include "global.h"
24 24
25static struct pll_config cle266_pll_config[] = { 25static struct pll_limit cle266_pll_limits[] = {
26 {19, 4, 0}, 26 {19, 19, 4, 0},
27 {26, 5, 0}, 27 {26, 102, 5, 0},
28 {28, 5, 0}, 28 {53, 112, 6, 0},
29 {31, 5, 0}, 29 {41, 100, 7, 0},
30 {33, 5, 0}, 30 {83, 108, 8, 0},
31 {55, 5, 0}, 31 {87, 118, 9, 0},
32 {102, 5, 0}, 32 {95, 115, 12, 0},
33 {53, 6, 0}, 33 {108, 108, 13, 0},
34 {92, 6, 0}, 34 {83, 83, 17, 0},
35 {98, 6, 0}, 35 {67, 98, 20, 0},
36 {112, 6, 0}, 36 {121, 121, 24, 0},
37 {41, 7, 0}, 37 {99, 99, 29, 0},
38 {60, 7, 0}, 38 {33, 33, 3, 1},
39 {99, 7, 0}, 39 {15, 23, 4, 1},
40 {100, 7, 0}, 40 {37, 121, 5, 1},
41 {83, 8, 0}, 41 {82, 82, 6, 1},
42 {86, 8, 0}, 42 {31, 84, 7, 1},
43 {108, 8, 0}, 43 {83, 83, 8, 1},
44 {87, 9, 0}, 44 {76, 127, 9, 1},
45 {118, 9, 0}, 45 {33, 121, 4, 2},
46 {95, 12, 0}, 46 {91, 118, 5, 2},
47 {115, 12, 0}, 47 {83, 109, 6, 2},
48 {108, 13, 0}, 48 {90, 90, 7, 2},
49 {83, 17, 0}, 49 {93, 93, 2, 3},
50 {67, 20, 0}, 50 {53, 53, 3, 3},
51 {86, 20, 0}, 51 {73, 117, 4, 3},
52 {98, 20, 0}, 52 {101, 127, 5, 3},
53 {121, 24, 0}, 53 {99, 99, 7, 3}
54 {99, 29, 0},
55 {33, 3, 1},
56 {15, 4, 1},
57 {23, 4, 1},
58 {37, 5, 1},
59 {83, 5, 1},
60 {85, 5, 1},
61 {94, 5, 1},
62 {103, 5, 1},
63 {109, 5, 1},
64 {113, 5, 1},
65 {121, 5, 1},
66 {82, 6, 1},
67 {31, 7, 1},
68 {55, 7, 1},
69 {84, 7, 1},
70 {83, 8, 1},
71 {76, 9, 1},
72 {127, 9, 1},
73 {33, 4, 2},
74 {75, 4, 2},
75 {119, 4, 2},
76 {121, 4, 2},
77 {91, 5, 2},
78 {118, 5, 2},
79 {83, 6, 2},
80 {109, 6, 2},
81 {90, 7, 2},
82 {93, 2, 3},
83 {53, 3, 3},
84 {73, 4, 3},
85 {89, 4, 3},
86 {105, 4, 3},
87 {117, 4, 3},
88 {101, 5, 3},
89 {121, 5, 3},
90 {127, 5, 3},
91 {99, 7, 3}
92}; 54};
93 55
94static struct pll_config k800_pll_config[] = { 56static struct pll_limit k800_pll_limits[] = {
95 {22, 2, 0}, 57 {22, 22, 2, 0},
96 {28, 3, 0}, 58 {28, 28, 3, 0},
97 {81, 3, 1}, 59 {81, 112, 3, 1},
98 {85, 3, 1}, 60 {86, 166, 4, 1},
99 {98, 3, 1}, 61 {109, 153, 5, 1},
100 {112, 3, 1}, 62 {66, 116, 3, 2},
101 {86, 4, 1}, 63 {93, 137, 4, 2},
102 {166, 4, 1}, 64 {117, 208, 5, 2},
103 {109, 5, 1}, 65 {30, 30, 2, 3},
104 {113, 5, 1}, 66 {69, 125, 3, 3},
105 {121, 5, 1}, 67 {89, 161, 4, 3},
106 {131, 5, 1}, 68 {121, 208, 5, 3},
107 {143, 5, 1}, 69 {66, 66, 2, 4},
108 {153, 5, 1}, 70 {85, 85, 3, 4},
109 {66, 3, 2}, 71 {141, 161, 4, 4},
110 {68, 3, 2}, 72 {177, 177, 5, 4}
111 {95, 3, 2},
112 {106, 3, 2},
113 {116, 3, 2},
114 {93, 4, 2},
115 {119, 4, 2},
116 {121, 4, 2},
117 {133, 4, 2},
118 {137, 4, 2},
119 {117, 5, 2},
120 {118, 5, 2},
121 {120, 5, 2},
122 {124, 5, 2},
123 {132, 5, 2},
124 {137, 5, 2},
125 {141, 5, 2},
126 {166, 5, 2},
127 {170, 5, 2},
128 {191, 5, 2},
129 {206, 5, 2},
130 {208, 5, 2},
131 {30, 2, 3},
132 {69, 3, 3},
133 {82, 3, 3},
134 {83, 3, 3},
135 {109, 3, 3},
136 {114, 3, 3},
137 {125, 3, 3},
138 {89, 4, 3},
139 {103, 4, 3},
140 {117, 4, 3},
141 {126, 4, 3},
142 {150, 4, 3},
143 {161, 4, 3},
144 {121, 5, 3},
145 {127, 5, 3},
146 {131, 5, 3},
147 {134, 5, 3},
148 {148, 5, 3},
149 {169, 5, 3},
150 {172, 5, 3},
151 {182, 5, 3},
152 {195, 5, 3},
153 {196, 5, 3},
154 {208, 5, 3},
155 {66, 2, 4},
156 {85, 3, 4},
157 {141, 4, 4},
158 {146, 4, 4},
159 {161, 4, 4},
160 {177, 5, 4}
161}; 73};
162 74
163static struct pll_config cx700_pll_config[] = { 75static struct pll_limit cx700_pll_limits[] = {
164 {98, 3, 1}, 76 {98, 98, 3, 1},
165 {86, 4, 1}, 77 {86, 86, 4, 1},
166 {109, 5, 1}, 78 {109, 208, 5, 1},
167 {110, 5, 1}, 79 {68, 68, 2, 2},
168 {113, 5, 1}, 80 {95, 116, 3, 2},
169 {121, 5, 1}, 81 {93, 166, 4, 2},
170 {131, 5, 1}, 82 {110, 206, 5, 2},
171 {135, 5, 1}, 83 {174, 174, 7, 2},
172 {142, 5, 1}, 84 {82, 109, 3, 3},
173 {143, 5, 1}, 85 {117, 161, 4, 3},
174 {153, 5, 1}, 86 {112, 208, 5, 3},
175 {187, 5, 1}, 87 {141, 202, 5, 4}
176 {208, 5, 1},
177 {68, 2, 2},
178 {95, 3, 2},
179 {116, 3, 2},
180 {93, 4, 2},
181 {119, 4, 2},
182 {133, 4, 2},
183 {137, 4, 2},
184 {151, 4, 2},
185 {166, 4, 2},
186 {110, 5, 2},
187 {112, 5, 2},
188 {117, 5, 2},
189 {118, 5, 2},
190 {120, 5, 2},
191 {132, 5, 2},
192 {137, 5, 2},
193 {141, 5, 2},
194 {151, 5, 2},
195 {166, 5, 2},
196 {175, 5, 2},
197 {191, 5, 2},
198 {206, 5, 2},
199 {174, 7, 2},
200 {82, 3, 3},
201 {109, 3, 3},
202 {117, 4, 3},
203 {150, 4, 3},
204 {161, 4, 3},
205 {112, 5, 3},
206 {115, 5, 3},
207 {121, 5, 3},
208 {127, 5, 3},
209 {129, 5, 3},
210 {131, 5, 3},
211 {134, 5, 3},
212 {138, 5, 3},
213 {148, 5, 3},
214 {157, 5, 3},
215 {169, 5, 3},
216 {172, 5, 3},
217 {190, 5, 3},
218 {195, 5, 3},
219 {196, 5, 3},
220 {208, 5, 3},
221 {141, 5, 4},
222 {150, 5, 4},
223 {166, 5, 4},
224 {176, 5, 4},
225 {177, 5, 4},
226 {183, 5, 4},
227 {202, 5, 4}
228}; 88};
229 89
230static struct pll_config vx855_pll_config[] = { 90static struct pll_limit vx855_pll_limits[] = {
231 {86, 4, 1}, 91 {86, 86, 4, 1},
232 {108, 5, 1}, 92 {108, 208, 5, 1},
233 {110, 5, 1}, 93 {110, 208, 5, 2},
234 {113, 5, 1}, 94 {83, 112, 3, 3},
235 {121, 5, 1}, 95 {103, 161, 4, 3},
236 {131, 5, 1}, 96 {112, 209, 5, 3},
237 {135, 5, 1}, 97 {142, 161, 4, 4},
238 {142, 5, 1}, 98 {141, 176, 5, 4}
239 {143, 5, 1},
240 {153, 5, 1},
241 {164, 5, 1},
242 {187, 5, 1},
243 {208, 5, 1},
244 {110, 5, 2},
245 {112, 5, 2},
246 {117, 5, 2},
247 {118, 5, 2},
248 {124, 5, 2},
249 {132, 5, 2},
250 {137, 5, 2},
251 {141, 5, 2},
252 {149, 5, 2},
253 {151, 5, 2},
254 {159, 5, 2},
255 {166, 5, 2},
256 {167, 5, 2},
257 {172, 5, 2},
258 {189, 5, 2},
259 {191, 5, 2},
260 {194, 5, 2},
261 {206, 5, 2},
262 {208, 5, 2},
263 {83, 3, 3},
264 {88, 3, 3},
265 {109, 3, 3},
266 {112, 3, 3},
267 {103, 4, 3},
268 {105, 4, 3},
269 {161, 4, 3},
270 {112, 5, 3},
271 {115, 5, 3},
272 {121, 5, 3},
273 {127, 5, 3},
274 {134, 5, 3},
275 {137, 5, 3},
276 {148, 5, 3},
277 {157, 5, 3},
278 {169, 5, 3},
279 {172, 5, 3},
280 {182, 5, 3},
281 {191, 5, 3},
282 {195, 5, 3},
283 {209, 5, 3},
284 {142, 4, 4},
285 {146, 4, 4},
286 {161, 4, 4},
287 {141, 5, 4},
288 {150, 5, 4},
289 {165, 5, 4},
290 {176, 5, 4}
291}; 99};
292 100
293/* according to VIA Technologies these values are based on experiment */ 101/* according to VIA Technologies these values are based on experiment */
@@ -1633,17 +1441,34 @@ static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll)
1633 return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift; 1441 return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift;
1634} 1442}
1635 1443
1636static struct pll_config get_pll_config(struct pll_config *config, int size, 1444static struct pll_config get_pll_config(struct pll_limit *limits, int size,
1637 int clk) 1445 int clk)
1638{ 1446{
1639 struct pll_config best = config[0]; 1447 struct pll_config cur, up, down, best = {0, 1, 0};
1640 const u32 f0 = 14318180; /* X1 frequency */ 1448 const u32 f0 = 14318180; /* X1 frequency */
1641 int i; 1449 int i, f;
1642 1450
1643 for (i = 1; i < size; i++) { 1451 for (i = 0; i < size; i++) {
1644 if (abs(get_pll_output_frequency(f0, config[i]) - clk) 1452 cur.rshift = limits[i].rshift;
1645 < abs(get_pll_output_frequency(f0, best) - clk)) 1453 cur.divisor = limits[i].divisor;
1646 best = config[i]; 1454 cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift);
1455 f = abs(get_pll_output_frequency(f0, cur) - clk);
1456 up = down = cur;
1457 up.multiplier++;
1458 down.multiplier--;
1459 if (abs(get_pll_output_frequency(f0, up) - clk) < f)
1460 cur = up;
1461 else if (abs(get_pll_output_frequency(f0, down) - clk) < f)
1462 cur = down;
1463
1464 if (cur.multiplier < limits[i].multiplier_min)
1465 cur.multiplier = limits[i].multiplier_min;
1466 else if (cur.multiplier > limits[i].multiplier_max)
1467 cur.multiplier = limits[i].multiplier_max;
1468
1469 f = abs(get_pll_output_frequency(f0, cur) - clk);
1470 if (f < abs(get_pll_output_frequency(f0, best) - clk))
1471 best = cur;
1647 } 1472 }
1648 1473
1649 return best; 1474 return best;
@@ -1656,14 +1481,14 @@ u32 viafb_get_clk_value(int clk)
1656 switch (viaparinfo->chip_info->gfx_chip_name) { 1481 switch (viaparinfo->chip_info->gfx_chip_name) {
1657 case UNICHROME_CLE266: 1482 case UNICHROME_CLE266:
1658 case UNICHROME_K400: 1483 case UNICHROME_K400:
1659 value = cle266_encode_pll(get_pll_config(cle266_pll_config, 1484 value = cle266_encode_pll(get_pll_config(cle266_pll_limits,
1660 ARRAY_SIZE(cle266_pll_config), clk)); 1485 ARRAY_SIZE(cle266_pll_limits), clk));
1661 break; 1486 break;
1662 case UNICHROME_K800: 1487 case UNICHROME_K800:
1663 case UNICHROME_PM800: 1488 case UNICHROME_PM800:
1664 case UNICHROME_CN700: 1489 case UNICHROME_CN700:
1665 value = k800_encode_pll(get_pll_config(k800_pll_config, 1490 value = k800_encode_pll(get_pll_config(k800_pll_limits,
1666 ARRAY_SIZE(k800_pll_config), clk)); 1491 ARRAY_SIZE(k800_pll_limits), clk));
1667 break; 1492 break;
1668 case UNICHROME_CX700: 1493 case UNICHROME_CX700:
1669 case UNICHROME_CN750: 1494 case UNICHROME_CN750:
@@ -1671,13 +1496,13 @@ u32 viafb_get_clk_value(int clk)
1671 case UNICHROME_P4M890: 1496 case UNICHROME_P4M890:
1672 case UNICHROME_P4M900: 1497 case UNICHROME_P4M900:
1673 case UNICHROME_VX800: 1498 case UNICHROME_VX800:
1674 value = k800_encode_pll(get_pll_config(cx700_pll_config, 1499 value = k800_encode_pll(get_pll_config(cx700_pll_limits,
1675 ARRAY_SIZE(cx700_pll_config), clk)); 1500 ARRAY_SIZE(cx700_pll_limits), clk));
1676 break; 1501 break;
1677 case UNICHROME_VX855: 1502 case UNICHROME_VX855:
1678 case UNICHROME_VX900: 1503 case UNICHROME_VX900:
1679 value = vx855_encode_pll(get_pll_config(vx855_pll_config, 1504 value = vx855_encode_pll(get_pll_config(vx855_pll_limits,
1680 ARRAY_SIZE(vx855_pll_config), clk)); 1505 ARRAY_SIZE(vx855_pll_limits), clk));
1681 break; 1506 break;
1682 } 1507 }
1683 1508
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 8858593405aa..63d8d37e157c 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -738,12 +738,11 @@ struct pll_config {
738 u8 rshift; 738 u8 rshift;
739}; 739};
740 740
741struct pll_map { 741struct pll_limit {
742 u32 clk; 742 u16 multiplier_min;
743 struct pll_config cle266_pll; 743 u16 multiplier_max;
744 struct pll_config k800_pll; 744 u8 divisor;
745 struct pll_config cx700_pll; 745 u8 rshift;
746 struct pll_config vx855_pll;
747}; 746};
748 747
749struct rgbLUT { 748struct rgbLUT {