diff options
Diffstat (limited to 'drivers/video/via/hw.c')
-rw-r--r-- | drivers/video/via/hw.c | 377 |
1 files changed, 101 insertions, 276 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 | ||
25 | static struct pll_config cle266_pll_config[] = { | 25 | static 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 | ||
94 | static struct pll_config k800_pll_config[] = { | 56 | static 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 | ||
163 | static struct pll_config cx700_pll_config[] = { | 75 | static 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 | ||
230 | static struct pll_config vx855_pll_config[] = { | 90 | static 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 | ||
1636 | static struct pll_config get_pll_config(struct pll_config *config, int size, | 1444 | static 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 | ||