diff options
Diffstat (limited to 'drivers/video/via/hw.c')
-rw-r--r-- | drivers/video/via/hw.c | 1463 |
1 files changed, 662 insertions, 801 deletions
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 7dcb4d5bb9c3..47b13535ed2b 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c | |||
@@ -20,344 +20,138 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/via-core.h> | 22 | #include <linux/via-core.h> |
23 | #include <asm/olpc.h> | ||
23 | #include "global.h" | 24 | #include "global.h" |
25 | #include "via_clock.h" | ||
26 | |||
27 | static struct pll_limit cle266_pll_limits[] = { | ||
28 | {19, 19, 4, 0}, | ||
29 | {26, 102, 5, 0}, | ||
30 | {53, 112, 6, 0}, | ||
31 | {41, 100, 7, 0}, | ||
32 | {83, 108, 8, 0}, | ||
33 | {87, 118, 9, 0}, | ||
34 | {95, 115, 12, 0}, | ||
35 | {108, 108, 13, 0}, | ||
36 | {83, 83, 17, 0}, | ||
37 | {67, 98, 20, 0}, | ||
38 | {121, 121, 24, 0}, | ||
39 | {99, 99, 29, 0}, | ||
40 | {33, 33, 3, 1}, | ||
41 | {15, 23, 4, 1}, | ||
42 | {37, 121, 5, 1}, | ||
43 | {82, 82, 6, 1}, | ||
44 | {31, 84, 7, 1}, | ||
45 | {83, 83, 8, 1}, | ||
46 | {76, 127, 9, 1}, | ||
47 | {33, 121, 4, 2}, | ||
48 | {91, 118, 5, 2}, | ||
49 | {83, 109, 6, 2}, | ||
50 | {90, 90, 7, 2}, | ||
51 | {93, 93, 2, 3}, | ||
52 | {53, 53, 3, 3}, | ||
53 | {73, 117, 4, 3}, | ||
54 | {101, 127, 5, 3}, | ||
55 | {99, 99, 7, 3} | ||
56 | }; | ||
57 | |||
58 | static struct pll_limit k800_pll_limits[] = { | ||
59 | {22, 22, 2, 0}, | ||
60 | {28, 28, 3, 0}, | ||
61 | {81, 112, 3, 1}, | ||
62 | {86, 166, 4, 1}, | ||
63 | {109, 153, 5, 1}, | ||
64 | {66, 116, 3, 2}, | ||
65 | {93, 137, 4, 2}, | ||
66 | {117, 208, 5, 2}, | ||
67 | {30, 30, 2, 3}, | ||
68 | {69, 125, 3, 3}, | ||
69 | {89, 161, 4, 3}, | ||
70 | {121, 208, 5, 3}, | ||
71 | {66, 66, 2, 4}, | ||
72 | {85, 85, 3, 4}, | ||
73 | {141, 161, 4, 4}, | ||
74 | {177, 177, 5, 4} | ||
75 | }; | ||
24 | 76 | ||
25 | static struct pll_map pll_value[] = { | 77 | static struct pll_limit cx700_pll_limits[] = { |
26 | {25175000, | 78 | {98, 98, 3, 1}, |
27 | {99, 7, 3}, | 79 | {86, 86, 4, 1}, |
28 | {85, 3, 4}, /* ignoring bit difference: 0x00008000 */ | 80 | {109, 208, 5, 1}, |
29 | {141, 5, 4}, | 81 | {68, 68, 2, 2}, |
30 | {141, 5, 4} }, | 82 | {95, 116, 3, 2}, |
31 | {29581000, | 83 | {93, 166, 4, 2}, |
32 | {33, 4, 2}, | 84 | {110, 206, 5, 2}, |
33 | {66, 2, 4}, /* ignoring bit difference: 0x00808000 */ | 85 | {174, 174, 7, 2}, |
34 | {166, 5, 4}, /* ignoring bit difference: 0x00008000 */ | 86 | {82, 109, 3, 3}, |
35 | {165, 5, 4} }, | 87 | {117, 161, 4, 3}, |
36 | {26880000, | 88 | {112, 208, 5, 3}, |
37 | {15, 4, 1}, | 89 | {141, 202, 5, 4} |
38 | {30, 2, 3}, /* ignoring bit difference: 0x00808000 */ | 90 | }; |
39 | {150, 5, 4}, | 91 | |
40 | {150, 5, 4} }, | 92 | static struct pll_limit vx855_pll_limits[] = { |
41 | {31500000, | 93 | {86, 86, 4, 1}, |
42 | {53, 3, 3}, /* ignoring bit difference: 0x00008000 */ | 94 | {108, 208, 5, 1}, |
43 | {141, 4, 4}, /* ignoring bit difference: 0x00008000 */ | 95 | {110, 208, 5, 2}, |
44 | {176, 5, 4}, | 96 | {83, 112, 3, 3}, |
45 | {176, 5, 4} }, | 97 | {103, 161, 4, 3}, |
46 | {31728000, | 98 | {112, 209, 5, 3}, |
47 | {31, 7, 1}, | 99 | {142, 161, 4, 4}, |
48 | {177, 5, 4}, /* ignoring bit difference: 0x00008000 */ | 100 | {141, 176, 5, 4} |
49 | {177, 5, 4}, | 101 | }; |
50 | {142, 4, 4} }, | 102 | |
51 | {32688000, | 103 | /* according to VIA Technologies these values are based on experiment */ |
52 | {73, 4, 3}, | 104 | static struct io_reg scaling_parameters[] = { |
53 | {146, 4, 4}, /* ignoring bit difference: 0x00008000 */ | 105 | {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */ |
54 | {183, 5, 4}, | 106 | {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */ |
55 | {146, 4, 4} }, | 107 | {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */ |
56 | {36000000, | 108 | {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */ |
57 | {101, 5, 3}, /* ignoring bit difference: 0x00008000 */ | 109 | {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */ |
58 | {161, 4, 4}, /* ignoring bit difference: 0x00008000 */ | 110 | {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */ |
59 | {202, 5, 4}, | 111 | {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */ |
60 | {161, 4, 4} }, | 112 | {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */ |
61 | {40000000, | 113 | {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */ |
62 | {89, 4, 3}, | 114 | {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */ |
63 | {89, 4, 3}, /* ignoring bit difference: 0x00008000 */ | 115 | {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */ |
64 | {112, 5, 3}, | 116 | {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */ |
65 | {112, 5, 3} }, | 117 | {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */ |
66 | {41291000, | 118 | {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ |
67 | {23, 4, 1}, | 119 | }; |
68 | {69, 3, 3}, /* ignoring bit difference: 0x00008000 */ | 120 | |
69 | {115, 5, 3}, | 121 | static struct io_reg common_vga[] = { |
70 | {115, 5, 3} }, | 122 | {VIACR, CR07, 0x10, 0x10}, /* [0] vertical total (bit 8) |
71 | {43163000, | 123 | [1] vertical display end (bit 8) |
72 | {121, 5, 3}, | 124 | [2] vertical retrace start (bit 8) |
73 | {121, 5, 3}, /* ignoring bit difference: 0x00008000 */ | 125 | [3] start vertical blanking (bit 8) |
74 | {121, 5, 3}, | 126 | [4] line compare (bit 8) |
75 | {121, 5, 3} }, | 127 | [5] vertical total (bit 9) |
76 | {45250000, | 128 | [6] vertical display end (bit 9) |
77 | {127, 5, 3}, | 129 | [7] vertical retrace start (bit 9) */ |
78 | {127, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 130 | {VIACR, CR08, 0xFF, 0x00}, /* [0-4] preset row scan |
79 | {127, 5, 3}, | 131 | [5-6] byte panning */ |
80 | {127, 5, 3} }, | 132 | {VIACR, CR09, 0xDF, 0x40}, /* [0-4] max scan line |
81 | {46000000, | 133 | [5] start vertical blanking (bit 9) |
82 | {90, 7, 2}, | 134 | [6] line compare (bit 9) |
83 | {103, 4, 3}, /* ignoring bit difference: 0x00008000 */ | 135 | [7] scan doubling */ |
84 | {129, 5, 3}, | 136 | {VIACR, CR0A, 0xFF, 0x1E}, /* [0-4] cursor start |
85 | {103, 4, 3} }, | 137 | [5] cursor disable */ |
86 | {46996000, | 138 | {VIACR, CR0B, 0xFF, 0x00}, /* [0-4] cursor end |
87 | {105, 4, 3}, /* ignoring bit difference: 0x00008000 */ | 139 | [5-6] cursor skew */ |
88 | {131, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 140 | {VIACR, CR0E, 0xFF, 0x00}, /* [0-7] cursor location (high) */ |
89 | {131, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 141 | {VIACR, CR0F, 0xFF, 0x00}, /* [0-7] cursor location (low) */ |
90 | {105, 4, 3} }, | 142 | {VIACR, CR11, 0xF0, 0x80}, /* [0-3] vertical retrace end |
91 | {48000000, | 143 | [6] memory refresh bandwidth |
92 | {67, 20, 0}, | 144 | [7] CRTC register protect enable */ |
93 | {134, 5, 3}, /* ignoring bit difference: 0x00808000 */ | 145 | {VIACR, CR14, 0xFF, 0x00}, /* [0-4] underline location |
94 | {134, 5, 3}, | 146 | [5] divide memory address clock by 4 |
95 | {134, 5, 3} }, | 147 | [6] double word addressing */ |
96 | {48875000, | 148 | {VIACR, CR17, 0xFF, 0x63}, /* [0-1] mapping of display address 13-14 |
97 | {99, 29, 0}, | 149 | [2] divide scan line clock by 2 |
98 | {82, 3, 3}, /* ignoring bit difference: 0x00808000 */ | 150 | [3] divide memory address clock by 2 |
99 | {82, 3, 3}, /* ignoring bit difference: 0x00808000 */ | 151 | [5] address wrap |
100 | {137, 5, 3} }, | 152 | [6] byte mode select |
101 | {49500000, | 153 | [7] sync enable */ |
102 | {83, 6, 2}, | 154 | {VIACR, CR18, 0xFF, 0xFF}, /* [0-7] line compare */ |
103 | {83, 3, 3}, /* ignoring bit difference: 0x00008000 */ | ||
104 | {138, 5, 3}, | ||
105 | {83, 3, 3} }, | ||
106 | {52406000, | ||
107 | {117, 4, 3}, | ||
108 | {117, 4, 3}, /* ignoring bit difference: 0x00008000 */ | ||
109 | {117, 4, 3}, | ||
110 | {88, 3, 3} }, | ||
111 | {52977000, | ||
112 | {37, 5, 1}, | ||
113 | {148, 5, 3}, /* ignoring bit difference: 0x00808000 */ | ||
114 | {148, 5, 3}, | ||
115 | {148, 5, 3} }, | ||
116 | {56250000, | ||
117 | {55, 7, 1}, /* ignoring bit difference: 0x00008000 */ | ||
118 | {126, 4, 3}, /* ignoring bit difference: 0x00008000 */ | ||
119 | {157, 5, 3}, | ||
120 | {157, 5, 3} }, | ||
121 | {57275000, | ||
122 | {0, 0, 0}, | ||
123 | {2, 2, 0}, | ||
124 | {2, 2, 0}, | ||
125 | {157, 5, 3} }, /* ignoring bit difference: 0x00808000 */ | ||
126 | {60466000, | ||
127 | {76, 9, 1}, | ||
128 | {169, 5, 3}, /* ignoring bit difference: 0x00808000 */ | ||
129 | {169, 5, 3}, /* FIXED: old = {72, 2, 3} */ | ||
130 | {169, 5, 3} }, | ||
131 | {61500000, | ||
132 | {86, 20, 0}, | ||
133 | {172, 5, 3}, /* ignoring bit difference: 0x00808000 */ | ||
134 | {172, 5, 3}, | ||
135 | {172, 5, 3} }, | ||
136 | {65000000, | ||
137 | {109, 6, 2}, /* ignoring bit difference: 0x00008000 */ | ||
138 | {109, 3, 3}, /* ignoring bit difference: 0x00008000 */ | ||
139 | {109, 3, 3}, | ||
140 | {109, 3, 3} }, | ||
141 | {65178000, | ||
142 | {91, 5, 2}, | ||
143 | {182, 5, 3}, /* ignoring bit difference: 0x00808000 */ | ||
144 | {109, 3, 3}, | ||
145 | {182, 5, 3} }, | ||
146 | {66750000, | ||
147 | {75, 4, 2}, | ||
148 | {150, 4, 3}, /* ignoring bit difference: 0x00808000 */ | ||
149 | {150, 4, 3}, | ||
150 | {112, 3, 3} }, | ||
151 | {68179000, | ||
152 | {19, 4, 0}, | ||
153 | {114, 3, 3}, /* ignoring bit difference: 0x00008000 */ | ||
154 | {190, 5, 3}, | ||
155 | {191, 5, 3} }, | ||
156 | {69924000, | ||
157 | {83, 17, 0}, | ||
158 | {195, 5, 3}, /* ignoring bit difference: 0x00808000 */ | ||
159 | {195, 5, 3}, | ||
160 | {195, 5, 3} }, | ||
161 | {70159000, | ||
162 | {98, 20, 0}, | ||
163 | {196, 5, 3}, /* ignoring bit difference: 0x00808000 */ | ||
164 | {196, 5, 3}, | ||
165 | {195, 5, 3} }, | ||
166 | {72000000, | ||
167 | {121, 24, 0}, | ||
168 | {161, 4, 3}, /* ignoring bit difference: 0x00808000 */ | ||
169 | {161, 4, 3}, | ||
170 | {161, 4, 3} }, | ||
171 | {78750000, | ||
172 | {33, 3, 1}, | ||
173 | {66, 3, 2}, /* ignoring bit difference: 0x00008000 */ | ||
174 | {110, 5, 2}, | ||
175 | {110, 5, 2} }, | ||
176 | {80136000, | ||
177 | {28, 5, 0}, | ||
178 | {68, 3, 2}, /* ignoring bit difference: 0x00008000 */ | ||
179 | {112, 5, 2}, | ||
180 | {112, 5, 2} }, | ||
181 | {83375000, | ||
182 | {93, 2, 3}, | ||
183 | {93, 4, 2}, /* ignoring bit difference: 0x00800000 */ | ||
184 | {93, 4, 2}, /* ignoring bit difference: 0x00800000 */ | ||
185 | {117, 5, 2} }, | ||
186 | {83950000, | ||
187 | {41, 7, 0}, | ||
188 | {117, 5, 2}, /* ignoring bit difference: 0x00008000 */ | ||
189 | {117, 5, 2}, | ||
190 | {117, 5, 2} }, | ||
191 | {84750000, | ||
192 | {118, 5, 2}, | ||
193 | {118, 5, 2}, /* ignoring bit difference: 0x00808000 */ | ||
194 | {118, 5, 2}, | ||
195 | {118, 5, 2} }, | ||
196 | {85860000, | ||
197 | {84, 7, 1}, | ||
198 | {120, 5, 2}, /* ignoring bit difference: 0x00808000 */ | ||
199 | {120, 5, 2}, | ||
200 | {118, 5, 2} }, | ||
201 | {88750000, | ||
202 | {31, 5, 0}, | ||
203 | {124, 5, 2}, /* ignoring bit difference: 0x00808000 */ | ||
204 | {174, 7, 2}, /* ignoring bit difference: 0x00808000 */ | ||
205 | {124, 5, 2} }, | ||
206 | {94500000, | ||
207 | {33, 5, 0}, | ||
208 | {132, 5, 2}, /* ignoring bit difference: 0x00008000 */ | ||
209 | {132, 5, 2}, | ||
210 | {132, 5, 2} }, | ||
211 | {97750000, | ||
212 | {82, 6, 1}, | ||
213 | {137, 5, 2}, /* ignoring bit difference: 0x00808000 */ | ||
214 | {137, 5, 2}, | ||
215 | {137, 5, 2} }, | ||
216 | {101000000, | ||
217 | {127, 9, 1}, | ||
218 | {141, 5, 2}, /* ignoring bit difference: 0x00808000 */ | ||
219 | {141, 5, 2}, | ||
220 | {141, 5, 2} }, | ||
221 | {106500000, | ||
222 | {119, 4, 2}, | ||
223 | {119, 4, 2}, /* ignoring bit difference: 0x00808000 */ | ||
224 | {119, 4, 2}, | ||
225 | {149, 5, 2} }, | ||
226 | {108000000, | ||
227 | {121, 4, 2}, | ||
228 | {121, 4, 2}, /* ignoring bit difference: 0x00808000 */ | ||
229 | {151, 5, 2}, | ||
230 | {151, 5, 2} }, | ||
231 | {113309000, | ||
232 | {95, 12, 0}, | ||
233 | {95, 3, 2}, /* ignoring bit difference: 0x00808000 */ | ||
234 | {95, 3, 2}, | ||
235 | {159, 5, 2} }, | ||
236 | {118840000, | ||
237 | {83, 5, 1}, | ||
238 | {166, 5, 2}, /* ignoring bit difference: 0x00808000 */ | ||
239 | {166, 5, 2}, | ||
240 | {166, 5, 2} }, | ||
241 | {119000000, | ||
242 | {108, 13, 0}, | ||
243 | {133, 4, 2}, /* ignoring bit difference: 0x00808000 */ | ||
244 | {133, 4, 2}, | ||
245 | {167, 5, 2} }, | ||
246 | {121750000, | ||
247 | {85, 5, 1}, | ||
248 | {170, 5, 2}, /* ignoring bit difference: 0x00808000 */ | ||
249 | {68, 2, 2}, | ||
250 | {0, 0, 0} }, | ||
251 | {125104000, | ||
252 | {53, 6, 0}, /* ignoring bit difference: 0x00008000 */ | ||
253 | {106, 3, 2}, /* ignoring bit difference: 0x00008000 */ | ||
254 | {175, 5, 2}, | ||
255 | {0, 0, 0} }, | ||
256 | {135000000, | ||
257 | {94, 5, 1}, | ||
258 | {28, 3, 0}, /* ignoring bit difference: 0x00804000 */ | ||
259 | {151, 4, 2}, | ||
260 | {189, 5, 2} }, | ||
261 | {136700000, | ||
262 | {115, 12, 0}, | ||
263 | {191, 5, 2}, /* ignoring bit difference: 0x00808000 */ | ||
264 | {191, 5, 2}, | ||
265 | {191, 5, 2} }, | ||
266 | {138400000, | ||
267 | {87, 9, 0}, | ||
268 | {116, 3, 2}, /* ignoring bit difference: 0x00808000 */ | ||
269 | {116, 3, 2}, | ||
270 | {194, 5, 2} }, | ||
271 | {146760000, | ||
272 | {103, 5, 1}, | ||
273 | {206, 5, 2}, /* ignoring bit difference: 0x00808000 */ | ||
274 | {206, 5, 2}, | ||
275 | {206, 5, 2} }, | ||
276 | {153920000, | ||
277 | {86, 8, 0}, | ||
278 | {86, 4, 1}, /* ignoring bit difference: 0x00808000 */ | ||
279 | {86, 4, 1}, | ||
280 | {86, 4, 1} }, /* FIXED: old = {84, 2, 1} */ | ||
281 | {156000000, | ||
282 | {109, 5, 1}, | ||
283 | {109, 5, 1}, /* ignoring bit difference: 0x00808000 */ | ||
284 | {109, 5, 1}, | ||
285 | {108, 5, 1} }, | ||
286 | {157500000, | ||
287 | {55, 5, 0}, /* ignoring bit difference: 0x00008000 */ | ||
288 | {22, 2, 0}, /* ignoring bit difference: 0x00802000 */ | ||
289 | {110, 5, 1}, | ||
290 | {110, 5, 1} }, | ||
291 | {162000000, | ||
292 | {113, 5, 1}, | ||
293 | {113, 5, 1}, /* ignoring bit difference: 0x00808000 */ | ||
294 | {113, 5, 1}, | ||
295 | {113, 5, 1} }, | ||
296 | {187000000, | ||
297 | {118, 9, 0}, | ||
298 | {131, 5, 1}, /* ignoring bit difference: 0x00808000 */ | ||
299 | {131, 5, 1}, | ||
300 | {131, 5, 1} }, | ||
301 | {193295000, | ||
302 | {108, 8, 0}, | ||
303 | {81, 3, 1}, /* ignoring bit difference: 0x00808000 */ | ||
304 | {135, 5, 1}, | ||
305 | {135, 5, 1} }, | ||
306 | {202500000, | ||
307 | {99, 7, 0}, | ||
308 | {85, 3, 1}, /* ignoring bit difference: 0x00808000 */ | ||
309 | {142, 5, 1}, | ||
310 | {142, 5, 1} }, | ||
311 | {204000000, | ||
312 | {100, 7, 0}, | ||
313 | {143, 5, 1}, /* ignoring bit difference: 0x00808000 */ | ||
314 | {143, 5, 1}, | ||
315 | {143, 5, 1} }, | ||
316 | {218500000, | ||
317 | {92, 6, 0}, | ||
318 | {153, 5, 1}, /* ignoring bit difference: 0x00808000 */ | ||
319 | {153, 5, 1}, | ||
320 | {153, 5, 1} }, | ||
321 | {234000000, | ||
322 | {98, 6, 0}, | ||
323 | {98, 3, 1}, /* ignoring bit difference: 0x00008000 */ | ||
324 | {98, 3, 1}, | ||
325 | {164, 5, 1} }, | ||
326 | {267250000, | ||
327 | {112, 6, 0}, | ||
328 | {112, 3, 1}, /* ignoring bit difference: 0x00808000 */ | ||
329 | {187, 5, 1}, | ||
330 | {187, 5, 1} }, | ||
331 | {297500000, | ||
332 | {102, 5, 0}, /* ignoring bit difference: 0x00008000 */ | ||
333 | {166, 4, 1}, /* ignoring bit difference: 0x00008000 */ | ||
334 | {208, 5, 1}, | ||
335 | {208, 5, 1} }, | ||
336 | {74481000, | ||
337 | {26, 5, 0}, | ||
338 | {125, 3, 3}, /* ignoring bit difference: 0x00808000 */ | ||
339 | {208, 5, 3}, | ||
340 | {209, 5, 3} }, | ||
341 | {172798000, | ||
342 | {121, 5, 1}, | ||
343 | {121, 5, 1}, /* ignoring bit difference: 0x00808000 */ | ||
344 | {121, 5, 1}, | ||
345 | {121, 5, 1} }, | ||
346 | {122614000, | ||
347 | {60, 7, 0}, | ||
348 | {137, 4, 2}, /* ignoring bit difference: 0x00808000 */ | ||
349 | {137, 4, 2}, | ||
350 | {172, 5, 2} }, | ||
351 | {74270000, | ||
352 | {83, 8, 1}, | ||
353 | {208, 5, 3}, | ||
354 | {208, 5, 3}, | ||
355 | {0, 0, 0} }, | ||
356 | {148500000, | ||
357 | {83, 8, 0}, | ||
358 | {208, 5, 2}, | ||
359 | {166, 4, 2}, | ||
360 | {208, 5, 2} } | ||
361 | }; | 155 | }; |
362 | 156 | ||
363 | static struct fifo_depth_select display_fifo_depth_reg = { | 157 | static struct fifo_depth_select display_fifo_depth_reg = { |
@@ -718,16 +512,23 @@ static struct rgbLUT palLUT_table[] = { | |||
718 | 0x00} | 512 | 0x00} |
719 | }; | 513 | }; |
720 | 514 | ||
721 | static void set_crt_output_path(int set_iga); | 515 | static struct via_device_mapping device_mapping[] = { |
722 | static void dvi_patch_skew_dvp0(void); | 516 | {VIA_LDVP0, "LDVP0"}, |
723 | static void dvi_patch_skew_dvp1(void); | 517 | {VIA_LDVP1, "LDVP1"}, |
724 | static void dvi_patch_skew_dvp_low(void); | 518 | {VIA_DVP0, "DVP0"}, |
725 | static void set_dvi_output_path(int set_iga, int output_interface); | 519 | {VIA_CRT, "CRT"}, |
726 | static void set_lcd_output_path(int set_iga, int output_interface); | 520 | {VIA_DVP1, "DVP1"}, |
521 | {VIA_LVDS1, "LVDS1"}, | ||
522 | {VIA_LVDS2, "LVDS2"} | ||
523 | }; | ||
524 | |||
525 | /* structure with function pointers to support clock control */ | ||
526 | static struct via_clock clock; | ||
527 | |||
727 | static void load_fix_bit_crtc_reg(void); | 528 | static void load_fix_bit_crtc_reg(void); |
728 | static void init_gfx_chip_info(int chip_type); | 529 | static void __devinit init_gfx_chip_info(int chip_type); |
729 | static void init_tmds_chip_info(void); | 530 | static void __devinit init_tmds_chip_info(void); |
730 | static void init_lvds_chip_info(void); | 531 | static void __devinit init_lvds_chip_info(void); |
731 | static void device_screen_off(void); | 532 | static void device_screen_off(void); |
732 | static void device_screen_on(void); | 533 | static void device_screen_on(void); |
733 | static void set_display_channel(void); | 534 | static void set_display_channel(void); |
@@ -747,7 +548,7 @@ void viafb_unlock_crt(void) | |||
747 | viafb_write_reg_mask(CR47, VIACR, 0, BIT0); | 548 | viafb_write_reg_mask(CR47, VIACR, 0, BIT0); |
748 | } | 549 | } |
749 | 550 | ||
750 | void write_dac_reg(u8 index, u8 r, u8 g, u8 b) | 551 | static void write_dac_reg(u8 index, u8 r, u8 g, u8 b) |
751 | { | 552 | { |
752 | outb(index, LUT_INDEX_WRITE); | 553 | outb(index, LUT_INDEX_WRITE); |
753 | outb(r, LUT_DATA); | 554 | outb(r, LUT_DATA); |
@@ -755,16 +556,77 @@ void write_dac_reg(u8 index, u8 r, u8 g, u8 b) | |||
755 | outb(b, LUT_DATA); | 556 | outb(b, LUT_DATA); |
756 | } | 557 | } |
757 | 558 | ||
559 | static u32 get_dvi_devices(int output_interface) | ||
560 | { | ||
561 | switch (output_interface) { | ||
562 | case INTERFACE_DVP0: | ||
563 | return VIA_DVP0 | VIA_LDVP0; | ||
564 | |||
565 | case INTERFACE_DVP1: | ||
566 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) | ||
567 | return VIA_LDVP1; | ||
568 | else | ||
569 | return VIA_DVP1; | ||
570 | |||
571 | case INTERFACE_DFP_HIGH: | ||
572 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) | ||
573 | return 0; | ||
574 | else | ||
575 | return VIA_LVDS2 | VIA_DVP0; | ||
576 | |||
577 | case INTERFACE_DFP_LOW: | ||
578 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) | ||
579 | return 0; | ||
580 | else | ||
581 | return VIA_DVP1 | VIA_LVDS1; | ||
582 | |||
583 | case INTERFACE_TMDS: | ||
584 | return VIA_LVDS1; | ||
585 | } | ||
586 | |||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | static u32 get_lcd_devices(int output_interface) | ||
591 | { | ||
592 | switch (output_interface) { | ||
593 | case INTERFACE_DVP0: | ||
594 | return VIA_DVP0; | ||
595 | |||
596 | case INTERFACE_DVP1: | ||
597 | return VIA_DVP1; | ||
598 | |||
599 | case INTERFACE_DFP_HIGH: | ||
600 | return VIA_LVDS2 | VIA_DVP0; | ||
601 | |||
602 | case INTERFACE_DFP_LOW: | ||
603 | return VIA_LVDS1 | VIA_DVP1; | ||
604 | |||
605 | case INTERFACE_DFP: | ||
606 | return VIA_LVDS1 | VIA_LVDS2; | ||
607 | |||
608 | case INTERFACE_LVDS0: | ||
609 | case INTERFACE_LVDS0LVDS1: | ||
610 | return VIA_LVDS1; | ||
611 | |||
612 | case INTERFACE_LVDS1: | ||
613 | return VIA_LVDS2; | ||
614 | } | ||
615 | |||
616 | return 0; | ||
617 | } | ||
618 | |||
758 | /*Set IGA path for each device*/ | 619 | /*Set IGA path for each device*/ |
759 | void viafb_set_iga_path(void) | 620 | void viafb_set_iga_path(void) |
760 | { | 621 | { |
622 | int crt_iga_path = 0; | ||
761 | 623 | ||
762 | if (viafb_SAMM_ON == 1) { | 624 | if (viafb_SAMM_ON == 1) { |
763 | if (viafb_CRT_ON) { | 625 | if (viafb_CRT_ON) { |
764 | if (viafb_primary_dev == CRT_Device) | 626 | if (viafb_primary_dev == CRT_Device) |
765 | viaparinfo->crt_setting_info->iga_path = IGA1; | 627 | crt_iga_path = IGA1; |
766 | else | 628 | else |
767 | viaparinfo->crt_setting_info->iga_path = IGA2; | 629 | crt_iga_path = IGA2; |
768 | } | 630 | } |
769 | 631 | ||
770 | if (viafb_DVI_ON) { | 632 | if (viafb_DVI_ON) { |
@@ -781,8 +643,7 @@ void viafb_set_iga_path(void) | |||
781 | UNICHROME_CLE266)) { | 643 | UNICHROME_CLE266)) { |
782 | viaparinfo-> | 644 | viaparinfo-> |
783 | lvds_setting_info->iga_path = IGA2; | 645 | lvds_setting_info->iga_path = IGA2; |
784 | viaparinfo-> | 646 | crt_iga_path = IGA1; |
785 | crt_setting_info->iga_path = IGA1; | ||
786 | viaparinfo-> | 647 | viaparinfo-> |
787 | tmds_setting_info->iga_path = IGA1; | 648 | tmds_setting_info->iga_path = IGA1; |
788 | } else | 649 | } else |
@@ -802,10 +663,10 @@ void viafb_set_iga_path(void) | |||
802 | viafb_SAMM_ON = 0; | 663 | viafb_SAMM_ON = 0; |
803 | 664 | ||
804 | if (viafb_CRT_ON && viafb_LCD_ON) { | 665 | if (viafb_CRT_ON && viafb_LCD_ON) { |
805 | viaparinfo->crt_setting_info->iga_path = IGA1; | 666 | crt_iga_path = IGA1; |
806 | viaparinfo->lvds_setting_info->iga_path = IGA2; | 667 | viaparinfo->lvds_setting_info->iga_path = IGA2; |
807 | } else if (viafb_CRT_ON && viafb_DVI_ON) { | 668 | } else if (viafb_CRT_ON && viafb_DVI_ON) { |
808 | viaparinfo->crt_setting_info->iga_path = IGA1; | 669 | crt_iga_path = IGA1; |
809 | viaparinfo->tmds_setting_info->iga_path = IGA2; | 670 | viaparinfo->tmds_setting_info->iga_path = IGA2; |
810 | } else if (viafb_LCD_ON && viafb_DVI_ON) { | 671 | } else if (viafb_LCD_ON && viafb_DVI_ON) { |
811 | viaparinfo->tmds_setting_info->iga_path = IGA1; | 672 | viaparinfo->tmds_setting_info->iga_path = IGA1; |
@@ -814,13 +675,59 @@ void viafb_set_iga_path(void) | |||
814 | viaparinfo->lvds_setting_info->iga_path = IGA2; | 675 | viaparinfo->lvds_setting_info->iga_path = IGA2; |
815 | viaparinfo->lvds_setting_info2->iga_path = IGA2; | 676 | viaparinfo->lvds_setting_info2->iga_path = IGA2; |
816 | } else if (viafb_CRT_ON) { | 677 | } else if (viafb_CRT_ON) { |
817 | viaparinfo->crt_setting_info->iga_path = IGA1; | 678 | crt_iga_path = IGA1; |
818 | } else if (viafb_LCD_ON) { | 679 | } else if (viafb_LCD_ON) { |
819 | viaparinfo->lvds_setting_info->iga_path = IGA2; | 680 | viaparinfo->lvds_setting_info->iga_path = IGA2; |
820 | } else if (viafb_DVI_ON) { | 681 | } else if (viafb_DVI_ON) { |
821 | viaparinfo->tmds_setting_info->iga_path = IGA1; | 682 | viaparinfo->tmds_setting_info->iga_path = IGA1; |
822 | } | 683 | } |
823 | } | 684 | } |
685 | |||
686 | viaparinfo->shared->iga1_devices = 0; | ||
687 | viaparinfo->shared->iga2_devices = 0; | ||
688 | if (viafb_CRT_ON) { | ||
689 | if (crt_iga_path == IGA1) | ||
690 | viaparinfo->shared->iga1_devices |= VIA_CRT; | ||
691 | else | ||
692 | viaparinfo->shared->iga2_devices |= VIA_CRT; | ||
693 | } | ||
694 | |||
695 | if (viafb_DVI_ON) { | ||
696 | if (viaparinfo->tmds_setting_info->iga_path == IGA1) | ||
697 | viaparinfo->shared->iga1_devices |= get_dvi_devices( | ||
698 | viaparinfo->chip_info-> | ||
699 | tmds_chip_info.output_interface); | ||
700 | else | ||
701 | viaparinfo->shared->iga2_devices |= get_dvi_devices( | ||
702 | viaparinfo->chip_info-> | ||
703 | tmds_chip_info.output_interface); | ||
704 | } | ||
705 | |||
706 | if (viafb_LCD_ON) { | ||
707 | if (viaparinfo->lvds_setting_info->iga_path == IGA1) | ||
708 | viaparinfo->shared->iga1_devices |= get_lcd_devices( | ||
709 | viaparinfo->chip_info-> | ||
710 | lvds_chip_info.output_interface); | ||
711 | else | ||
712 | viaparinfo->shared->iga2_devices |= get_lcd_devices( | ||
713 | viaparinfo->chip_info-> | ||
714 | lvds_chip_info.output_interface); | ||
715 | } | ||
716 | |||
717 | if (viafb_LCD2_ON) { | ||
718 | if (viaparinfo->lvds_setting_info2->iga_path == IGA1) | ||
719 | viaparinfo->shared->iga1_devices |= get_lcd_devices( | ||
720 | viaparinfo->chip_info-> | ||
721 | lvds_chip_info2.output_interface); | ||
722 | else | ||
723 | viaparinfo->shared->iga2_devices |= get_lcd_devices( | ||
724 | viaparinfo->chip_info-> | ||
725 | lvds_chip_info2.output_interface); | ||
726 | } | ||
727 | |||
728 | /* looks like the OLPC has its display wired to DVP1 and LVDS2 */ | ||
729 | if (machine_is_olpc()) | ||
730 | viaparinfo->shared->iga2_devices = VIA_DVP1 | VIA_LVDS2; | ||
824 | } | 731 | } |
825 | 732 | ||
826 | static void set_color_register(u8 index, u8 red, u8 green, u8 blue) | 733 | static void set_color_register(u8 index, u8 red, u8 green, u8 blue) |
@@ -844,318 +751,281 @@ void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue) | |||
844 | set_color_register(index, red, green, blue); | 751 | set_color_register(index, red, green, blue); |
845 | } | 752 | } |
846 | 753 | ||
847 | void viafb_set_output_path(int device, int set_iga, int output_interface) | 754 | static void set_source_common(u8 index, u8 offset, u8 iga) |
848 | { | 755 | { |
849 | switch (device) { | 756 | u8 value, mask = 1 << offset; |
850 | case DEVICE_CRT: | 757 | |
851 | set_crt_output_path(set_iga); | 758 | switch (iga) { |
852 | break; | 759 | case IGA1: |
853 | case DEVICE_DVI: | 760 | value = 0x00; |
854 | set_dvi_output_path(set_iga, output_interface); | ||
855 | break; | 761 | break; |
856 | case DEVICE_LCD: | 762 | case IGA2: |
857 | set_lcd_output_path(set_iga, output_interface); | 763 | value = mask; |
858 | break; | 764 | break; |
765 | default: | ||
766 | printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga); | ||
767 | return; | ||
859 | } | 768 | } |
769 | |||
770 | via_write_reg_mask(VIACR, index, value, mask); | ||
860 | } | 771 | } |
861 | 772 | ||
862 | static void set_crt_output_path(int set_iga) | 773 | static void set_crt_source(u8 iga) |
863 | { | 774 | { |
864 | viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5); | 775 | u8 value; |
865 | 776 | ||
866 | switch (set_iga) { | 777 | switch (iga) { |
867 | case IGA1: | 778 | case IGA1: |
868 | viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6); | 779 | value = 0x00; |
869 | break; | 780 | break; |
870 | case IGA2: | 781 | case IGA2: |
871 | viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7); | 782 | value = 0x40; |
872 | viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6); | ||
873 | break; | 783 | break; |
784 | default: | ||
785 | printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga); | ||
786 | return; | ||
874 | } | 787 | } |
788 | |||
789 | via_write_reg_mask(VIASR, 0x16, value, 0x40); | ||
875 | } | 790 | } |
876 | 791 | ||
877 | static void dvi_patch_skew_dvp0(void) | 792 | static inline void set_ldvp0_source(u8 iga) |
878 | { | 793 | { |
879 | /* Reset data driving first: */ | 794 | set_source_common(0x6C, 7, iga); |
880 | viafb_write_reg_mask(SR1B, VIASR, 0, BIT1); | 795 | } |
881 | viafb_write_reg_mask(SR2A, VIASR, 0, BIT4); | ||
882 | |||
883 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
884 | case UNICHROME_P4M890: | ||
885 | { | ||
886 | if ((viaparinfo->tmds_setting_info->h_active == 1600) && | ||
887 | (viaparinfo->tmds_setting_info->v_active == | ||
888 | 1200)) | ||
889 | viafb_write_reg_mask(CR96, VIACR, 0x03, | ||
890 | BIT0 + BIT1 + BIT2); | ||
891 | else | ||
892 | viafb_write_reg_mask(CR96, VIACR, 0x07, | ||
893 | BIT0 + BIT1 + BIT2); | ||
894 | break; | ||
895 | } | ||
896 | 796 | ||
897 | case UNICHROME_P4M900: | 797 | static inline void set_ldvp1_source(u8 iga) |
898 | { | 798 | { |
899 | viafb_write_reg_mask(CR96, VIACR, 0x07, | 799 | set_source_common(0x93, 7, iga); |
900 | BIT0 + BIT1 + BIT2 + BIT3); | 800 | } |
901 | viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1); | ||
902 | viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4); | ||
903 | break; | ||
904 | } | ||
905 | 801 | ||
906 | default: | 802 | static inline void set_dvp0_source(u8 iga) |
907 | { | 803 | { |
908 | break; | 804 | set_source_common(0x96, 4, iga); |
909 | } | ||
910 | } | ||
911 | } | 805 | } |
912 | 806 | ||
913 | static void dvi_patch_skew_dvp1(void) | 807 | static inline void set_dvp1_source(u8 iga) |
914 | { | 808 | { |
915 | switch (viaparinfo->chip_info->gfx_chip_name) { | 809 | set_source_common(0x9B, 4, iga); |
916 | case UNICHROME_CX700: | 810 | } |
917 | { | ||
918 | break; | ||
919 | } | ||
920 | 811 | ||
921 | default: | 812 | static inline void set_lvds1_source(u8 iga) |
922 | { | 813 | { |
923 | break; | 814 | set_source_common(0x99, 4, iga); |
924 | } | ||
925 | } | ||
926 | } | 815 | } |
927 | 816 | ||
928 | static void dvi_patch_skew_dvp_low(void) | 817 | static inline void set_lvds2_source(u8 iga) |
929 | { | 818 | { |
930 | switch (viaparinfo->chip_info->gfx_chip_name) { | 819 | set_source_common(0x97, 4, iga); |
931 | case UNICHROME_K8M890: | 820 | } |
932 | { | ||
933 | viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1); | ||
934 | break; | ||
935 | } | ||
936 | 821 | ||
937 | case UNICHROME_P4M900: | 822 | void via_set_source(u32 devices, u8 iga) |
938 | { | 823 | { |
939 | viafb_write_reg_mask(CR99, VIACR, 0x08, | 824 | if (devices & VIA_LDVP0) |
940 | BIT0 + BIT1 + BIT2 + BIT3); | 825 | set_ldvp0_source(iga); |
941 | break; | 826 | if (devices & VIA_LDVP1) |
942 | } | 827 | set_ldvp1_source(iga); |
828 | if (devices & VIA_DVP0) | ||
829 | set_dvp0_source(iga); | ||
830 | if (devices & VIA_CRT) | ||
831 | set_crt_source(iga); | ||
832 | if (devices & VIA_DVP1) | ||
833 | set_dvp1_source(iga); | ||
834 | if (devices & VIA_LVDS1) | ||
835 | set_lvds1_source(iga); | ||
836 | if (devices & VIA_LVDS2) | ||
837 | set_lvds2_source(iga); | ||
838 | } | ||
943 | 839 | ||
944 | case UNICHROME_P4M890: | 840 | static void set_crt_state(u8 state) |
945 | { | 841 | { |
946 | viafb_write_reg_mask(CR99, VIACR, 0x0F, | 842 | u8 value; |
947 | BIT0 + BIT1 + BIT2 + BIT3); | ||
948 | break; | ||
949 | } | ||
950 | 843 | ||
844 | switch (state) { | ||
845 | case VIA_STATE_ON: | ||
846 | value = 0x00; | ||
847 | break; | ||
848 | case VIA_STATE_STANDBY: | ||
849 | value = 0x10; | ||
850 | break; | ||
851 | case VIA_STATE_SUSPEND: | ||
852 | value = 0x20; | ||
853 | break; | ||
854 | case VIA_STATE_OFF: | ||
855 | value = 0x30; | ||
856 | break; | ||
951 | default: | 857 | default: |
952 | { | 858 | return; |
953 | break; | ||
954 | } | ||
955 | } | 859 | } |
860 | |||
861 | via_write_reg_mask(VIACR, 0x36, value, 0x30); | ||
956 | } | 862 | } |
957 | 863 | ||
958 | static void set_dvi_output_path(int set_iga, int output_interface) | 864 | static void set_dvp0_state(u8 state) |
959 | { | 865 | { |
960 | switch (output_interface) { | 866 | u8 value; |
961 | case INTERFACE_DVP0: | ||
962 | viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0); | ||
963 | |||
964 | if (set_iga == IGA1) { | ||
965 | viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4); | ||
966 | viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + | ||
967 | BIT5 + BIT7); | ||
968 | } else { | ||
969 | viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); | ||
970 | viafb_write_reg_mask(CR6C, VIACR, 0xA1, BIT0 + | ||
971 | BIT5 + BIT7); | ||
972 | } | ||
973 | |||
974 | viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6); | ||
975 | 867 | ||
976 | dvi_patch_skew_dvp0(); | 868 | switch (state) { |
869 | case VIA_STATE_ON: | ||
870 | value = 0xC0; | ||
871 | break; | ||
872 | case VIA_STATE_OFF: | ||
873 | value = 0x00; | ||
977 | break; | 874 | break; |
875 | default: | ||
876 | return; | ||
877 | } | ||
978 | 878 | ||
979 | case INTERFACE_DVP1: | 879 | via_write_reg_mask(VIASR, 0x1E, value, 0xC0); |
980 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { | 880 | } |
981 | if (set_iga == IGA1) | ||
982 | viafb_write_reg_mask(CR93, VIACR, 0x21, | ||
983 | BIT0 + BIT5 + BIT7); | ||
984 | else | ||
985 | viafb_write_reg_mask(CR93, VIACR, 0xA1, | ||
986 | BIT0 + BIT5 + BIT7); | ||
987 | } else { | ||
988 | if (set_iga == IGA1) | ||
989 | viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4); | ||
990 | else | ||
991 | viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4); | ||
992 | } | ||
993 | 881 | ||
994 | viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5); | 882 | static void set_dvp1_state(u8 state) |
995 | dvi_patch_skew_dvp1(); | 883 | { |
884 | u8 value; | ||
885 | |||
886 | switch (state) { | ||
887 | case VIA_STATE_ON: | ||
888 | value = 0x30; | ||
996 | break; | 889 | break; |
997 | case INTERFACE_DFP_HIGH: | 890 | case VIA_STATE_OFF: |
998 | if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) { | 891 | value = 0x00; |
999 | if (set_iga == IGA1) { | ||
1000 | viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4); | ||
1001 | viafb_write_reg_mask(CR97, VIACR, 0x03, | ||
1002 | BIT0 + BIT1 + BIT4); | ||
1003 | } else { | ||
1004 | viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); | ||
1005 | viafb_write_reg_mask(CR97, VIACR, 0x13, | ||
1006 | BIT0 + BIT1 + BIT4); | ||
1007 | } | ||
1008 | } | ||
1009 | viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3); | ||
1010 | break; | 892 | break; |
893 | default: | ||
894 | return; | ||
895 | } | ||
1011 | 896 | ||
1012 | case INTERFACE_DFP_LOW: | 897 | via_write_reg_mask(VIASR, 0x1E, value, 0x30); |
1013 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) | 898 | } |
1014 | break; | ||
1015 | 899 | ||
1016 | if (set_iga == IGA1) { | 900 | static void set_lvds1_state(u8 state) |
1017 | viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); | 901 | { |
1018 | viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4); | 902 | u8 value; |
1019 | } else { | ||
1020 | viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); | ||
1021 | viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4); | ||
1022 | } | ||
1023 | 903 | ||
1024 | viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); | 904 | switch (state) { |
1025 | dvi_patch_skew_dvp_low(); | 905 | case VIA_STATE_ON: |
906 | value = 0x03; | ||
1026 | break; | 907 | break; |
1027 | 908 | case VIA_STATE_OFF: | |
1028 | case INTERFACE_TMDS: | 909 | value = 0x00; |
1029 | if (set_iga == IGA1) | ||
1030 | viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); | ||
1031 | else | ||
1032 | viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); | ||
1033 | break; | 910 | break; |
911 | default: | ||
912 | return; | ||
1034 | } | 913 | } |
1035 | 914 | ||
1036 | if (set_iga == IGA2) { | 915 | via_write_reg_mask(VIASR, 0x2A, value, 0x03); |
1037 | enable_second_display_channel(); | ||
1038 | /* Disable LCD Scaling */ | ||
1039 | viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0); | ||
1040 | } | ||
1041 | } | 916 | } |
1042 | 917 | ||
1043 | static void set_lcd_output_path(int set_iga, int output_interface) | 918 | static void set_lvds2_state(u8 state) |
1044 | { | 919 | { |
1045 | DEBUG_MSG(KERN_INFO | 920 | u8 value; |
1046 | "set_lcd_output_path, iga:%d,out_interface:%d\n", | ||
1047 | set_iga, output_interface); | ||
1048 | switch (set_iga) { | ||
1049 | case IGA1: | ||
1050 | viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); | ||
1051 | viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); | ||
1052 | 921 | ||
1053 | disable_second_display_channel(); | 922 | switch (state) { |
923 | case VIA_STATE_ON: | ||
924 | value = 0x0C; | ||
1054 | break; | 925 | break; |
1055 | 926 | case VIA_STATE_OFF: | |
1056 | case IGA2: | 927 | value = 0x00; |
1057 | viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); | ||
1058 | viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); | ||
1059 | |||
1060 | enable_second_display_channel(); | ||
1061 | break; | 928 | break; |
929 | default: | ||
930 | return; | ||
1062 | } | 931 | } |
1063 | 932 | ||
1064 | switch (output_interface) { | 933 | via_write_reg_mask(VIASR, 0x2A, value, 0x0C); |
1065 | case INTERFACE_DVP0: | 934 | } |
1066 | if (set_iga == IGA1) { | ||
1067 | viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4); | ||
1068 | } else { | ||
1069 | viafb_write_reg(CR91, VIACR, 0x00); | ||
1070 | viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); | ||
1071 | } | ||
1072 | break; | ||
1073 | |||
1074 | case INTERFACE_DVP1: | ||
1075 | if (set_iga == IGA1) | ||
1076 | viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4); | ||
1077 | else { | ||
1078 | viafb_write_reg(CR91, VIACR, 0x00); | ||
1079 | viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4); | ||
1080 | } | ||
1081 | break; | ||
1082 | 935 | ||
1083 | case INTERFACE_DFP_HIGH: | 936 | void via_set_state(u32 devices, u8 state) |
1084 | if (set_iga == IGA1) | 937 | { |
1085 | viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4); | 938 | /* |
1086 | else { | 939 | TODO: Can we enable/disable these devices? How? |
1087 | viafb_write_reg(CR91, VIACR, 0x00); | 940 | if (devices & VIA_LDVP0) |
1088 | viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4); | 941 | if (devices & VIA_LDVP1) |
1089 | viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); | 942 | */ |
1090 | } | 943 | if (devices & VIA_DVP0) |
1091 | break; | 944 | set_dvp0_state(state); |
945 | if (devices & VIA_CRT) | ||
946 | set_crt_state(state); | ||
947 | if (devices & VIA_DVP1) | ||
948 | set_dvp1_state(state); | ||
949 | if (devices & VIA_LVDS1) | ||
950 | set_lvds1_state(state); | ||
951 | if (devices & VIA_LVDS2) | ||
952 | set_lvds2_state(state); | ||
953 | } | ||
1092 | 954 | ||
1093 | case INTERFACE_DFP_LOW: | 955 | void via_set_sync_polarity(u32 devices, u8 polarity) |
1094 | if (set_iga == IGA1) | 956 | { |
1095 | viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); | 957 | if (polarity & ~(VIA_HSYNC_NEGATIVE | VIA_VSYNC_NEGATIVE)) { |
1096 | else { | 958 | printk(KERN_WARNING "viafb: Unsupported polarity: %d\n", |
1097 | viafb_write_reg(CR91, VIACR, 0x00); | 959 | polarity); |
1098 | viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); | 960 | return; |
1099 | viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4); | 961 | } |
1100 | } | ||
1101 | 962 | ||
1102 | break; | 963 | if (devices & VIA_CRT) |
964 | via_write_misc_reg_mask(polarity << 6, 0xC0); | ||
965 | if (devices & VIA_DVP1) | ||
966 | via_write_reg_mask(VIACR, 0x9B, polarity << 5, 0x60); | ||
967 | if (devices & VIA_LVDS1) | ||
968 | via_write_reg_mask(VIACR, 0x99, polarity << 5, 0x60); | ||
969 | if (devices & VIA_LVDS2) | ||
970 | via_write_reg_mask(VIACR, 0x97, polarity << 5, 0x60); | ||
971 | } | ||
1103 | 972 | ||
1104 | case INTERFACE_DFP: | 973 | u32 via_parse_odev(char *input, char **end) |
1105 | if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name) | 974 | { |
1106 | || (UNICHROME_P4M890 == | 975 | char *ptr = input; |
1107 | viaparinfo->chip_info->gfx_chip_name)) | 976 | u32 odev = 0; |
1108 | viafb_write_reg_mask(CR97, VIACR, 0x84, | 977 | bool next = true; |
1109 | BIT7 + BIT2 + BIT1 + BIT0); | 978 | int i, len; |
1110 | if (set_iga == IGA1) { | 979 | |
1111 | viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4); | 980 | while (next) { |
1112 | viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); | 981 | next = false; |
1113 | } else { | 982 | for (i = 0; i < ARRAY_SIZE(device_mapping); i++) { |
1114 | viafb_write_reg(CR91, VIACR, 0x00); | 983 | len = strlen(device_mapping[i].name); |
1115 | viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4); | 984 | if (!strncmp(ptr, device_mapping[i].name, len)) { |
1116 | viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); | 985 | odev |= device_mapping[i].device; |
986 | ptr += len; | ||
987 | if (*ptr == ',') { | ||
988 | ptr++; | ||
989 | next = true; | ||
990 | } | ||
991 | } | ||
1117 | } | 992 | } |
1118 | break; | 993 | } |
1119 | 994 | ||
1120 | case INTERFACE_LVDS0: | 995 | *end = ptr; |
1121 | case INTERFACE_LVDS0LVDS1: | 996 | return odev; |
1122 | if (set_iga == IGA1) | 997 | } |
1123 | viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); | ||
1124 | else | ||
1125 | viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); | ||
1126 | 998 | ||
1127 | break; | 999 | void via_odev_to_seq(struct seq_file *m, u32 odev) |
1000 | { | ||
1001 | int i, count = 0; | ||
1128 | 1002 | ||
1129 | case INTERFACE_LVDS1: | 1003 | for (i = 0; i < ARRAY_SIZE(device_mapping); i++) { |
1130 | if (set_iga == IGA1) | 1004 | if (odev & device_mapping[i].device) { |
1131 | viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4); | 1005 | if (count > 0) |
1132 | else | 1006 | seq_putc(m, ','); |
1133 | viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4); | 1007 | |
1134 | break; | 1008 | seq_puts(m, device_mapping[i].name); |
1009 | count++; | ||
1010 | } | ||
1135 | } | 1011 | } |
1012 | |||
1013 | seq_putc(m, '\n'); | ||
1136 | } | 1014 | } |
1137 | 1015 | ||
1138 | static void load_fix_bit_crtc_reg(void) | 1016 | static void load_fix_bit_crtc_reg(void) |
1139 | { | 1017 | { |
1018 | viafb_unlock_crt(); | ||
1019 | |||
1140 | /* always set to 1 */ | 1020 | /* always set to 1 */ |
1141 | viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7); | 1021 | viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7); |
1142 | /* line compare should set all bits = 1 (extend modes) */ | 1022 | /* line compare should set all bits = 1 (extend modes) */ |
1143 | viafb_write_reg(CR18, VIACR, 0xff); | ||
1144 | /* line compare should set all bits = 1 (extend modes) */ | ||
1145 | viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4); | ||
1146 | /* line compare should set all bits = 1 (extend modes) */ | ||
1147 | viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6); | ||
1148 | /* line compare should set all bits = 1 (extend modes) */ | ||
1149 | viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4); | 1023 | viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4); |
1150 | /* line compare should set all bits = 1 (extend modes) */ | 1024 | /* line compare should set all bits = 1 (extend modes) */ |
1151 | viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2); | 1025 | viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2); |
1152 | /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */ | 1026 | /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */ |
1153 | /* extend mode always set to e3h */ | 1027 | |
1154 | viafb_write_reg(CR17, VIACR, 0xe3); | 1028 | viafb_lock_crt(); |
1155 | /* extend mode always set to 0h */ | ||
1156 | viafb_write_reg(CR08, VIACR, 0x00); | ||
1157 | /* extend mode always set to 0h */ | ||
1158 | viafb_write_reg(CR14, VIACR, 0x00); | ||
1159 | 1029 | ||
1160 | /* If K8M800, enable Prefetch Mode. */ | 1030 | /* If K8M800, enable Prefetch Mode. */ |
1161 | if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) | 1031 | if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) |
@@ -1352,6 +1222,15 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) | |||
1352 | VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | 1222 | VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; |
1353 | } | 1223 | } |
1354 | 1224 | ||
1225 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) { | ||
1226 | iga1_fifo_max_depth = VX900_IGA1_FIFO_MAX_DEPTH; | ||
1227 | iga1_fifo_threshold = VX900_IGA1_FIFO_THRESHOLD; | ||
1228 | iga1_fifo_high_threshold = | ||
1229 | VX900_IGA1_FIFO_HIGH_THRESHOLD; | ||
1230 | iga1_display_queue_expire_num = | ||
1231 | VX900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1232 | } | ||
1233 | |||
1355 | /* Set Display FIFO Depath Select */ | 1234 | /* Set Display FIFO Depath Select */ |
1356 | reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth); | 1235 | reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth); |
1357 | viafb_load_reg_num = | 1236 | viafb_load_reg_num = |
@@ -1492,6 +1371,15 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) | |||
1492 | VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; | 1371 | VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; |
1493 | } | 1372 | } |
1494 | 1373 | ||
1374 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) { | ||
1375 | iga2_fifo_max_depth = VX900_IGA2_FIFO_MAX_DEPTH; | ||
1376 | iga2_fifo_threshold = VX900_IGA2_FIFO_THRESHOLD; | ||
1377 | iga2_fifo_high_threshold = | ||
1378 | VX900_IGA2_FIFO_HIGH_THRESHOLD; | ||
1379 | iga2_display_queue_expire_num = | ||
1380 | VX900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; | ||
1381 | } | ||
1382 | |||
1495 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) { | 1383 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) { |
1496 | /* Set Display FIFO Depath Select */ | 1384 | /* Set Display FIFO Depath Select */ |
1497 | reg_value = | 1385 | reg_value = |
@@ -1558,139 +1446,83 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) | |||
1558 | 1446 | ||
1559 | } | 1447 | } |
1560 | 1448 | ||
1561 | static u32 cle266_encode_pll(struct pll_config pll) | 1449 | static struct via_pll_config get_pll_config(struct pll_limit *limits, int size, |
1450 | int clk) | ||
1562 | { | 1451 | { |
1563 | return (pll.multiplier << 8) | 1452 | struct via_pll_config cur, up, down, best = {0, 1, 0}; |
1564 | | (pll.rshift << 6) | 1453 | const u32 f0 = 14318180; /* X1 frequency */ |
1565 | | pll.divisor; | 1454 | int i, f; |
1566 | } | 1455 | |
1567 | 1456 | for (i = 0; i < size; i++) { | |
1568 | static u32 k800_encode_pll(struct pll_config pll) | 1457 | cur.rshift = limits[i].rshift; |
1569 | { | 1458 | cur.divisor = limits[i].divisor; |
1570 | return ((pll.divisor - 2) << 16) | 1459 | cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift); |
1571 | | (pll.rshift << 10) | 1460 | f = abs(get_pll_output_frequency(f0, cur) - clk); |
1572 | | (pll.multiplier - 2); | 1461 | up = down = cur; |
1573 | } | 1462 | up.multiplier++; |
1463 | down.multiplier--; | ||
1464 | if (abs(get_pll_output_frequency(f0, up) - clk) < f) | ||
1465 | cur = up; | ||
1466 | else if (abs(get_pll_output_frequency(f0, down) - clk) < f) | ||
1467 | cur = down; | ||
1468 | |||
1469 | if (cur.multiplier < limits[i].multiplier_min) | ||
1470 | cur.multiplier = limits[i].multiplier_min; | ||
1471 | else if (cur.multiplier > limits[i].multiplier_max) | ||
1472 | cur.multiplier = limits[i].multiplier_max; | ||
1473 | |||
1474 | f = abs(get_pll_output_frequency(f0, cur) - clk); | ||
1475 | if (f < abs(get_pll_output_frequency(f0, best) - clk)) | ||
1476 | best = cur; | ||
1477 | } | ||
1574 | 1478 | ||
1575 | static u32 vx855_encode_pll(struct pll_config pll) | 1479 | return best; |
1576 | { | ||
1577 | return (pll.divisor << 16) | ||
1578 | | (pll.rshift << 10) | ||
1579 | | pll.multiplier; | ||
1580 | } | 1480 | } |
1581 | 1481 | ||
1582 | u32 viafb_get_clk_value(int clk) | 1482 | static struct via_pll_config get_best_pll_config(int clk) |
1583 | { | 1483 | { |
1584 | u32 value = 0; | 1484 | struct via_pll_config config; |
1585 | int i = 0; | ||
1586 | |||
1587 | while (i < NUM_TOTAL_PLL_TABLE && clk != pll_value[i].clk) | ||
1588 | i++; | ||
1589 | |||
1590 | if (i == NUM_TOTAL_PLL_TABLE) { | ||
1591 | printk(KERN_WARNING "viafb_get_clk_value: PLL lookup failed!"); | ||
1592 | } else { | ||
1593 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
1594 | case UNICHROME_CLE266: | ||
1595 | case UNICHROME_K400: | ||
1596 | value = cle266_encode_pll(pll_value[i].cle266_pll); | ||
1597 | break; | ||
1598 | 1485 | ||
1599 | case UNICHROME_K800: | 1486 | switch (viaparinfo->chip_info->gfx_chip_name) { |
1600 | case UNICHROME_PM800: | 1487 | case UNICHROME_CLE266: |
1601 | case UNICHROME_CN700: | 1488 | case UNICHROME_K400: |
1602 | value = k800_encode_pll(pll_value[i].k800_pll); | 1489 | config = get_pll_config(cle266_pll_limits, |
1603 | break; | 1490 | ARRAY_SIZE(cle266_pll_limits), clk); |
1604 | 1491 | break; | |
1605 | case UNICHROME_CX700: | 1492 | case UNICHROME_K800: |
1606 | case UNICHROME_CN750: | 1493 | case UNICHROME_PM800: |
1607 | case UNICHROME_K8M890: | 1494 | case UNICHROME_CN700: |
1608 | case UNICHROME_P4M890: | 1495 | config = get_pll_config(k800_pll_limits, |
1609 | case UNICHROME_P4M900: | 1496 | ARRAY_SIZE(k800_pll_limits), clk); |
1610 | case UNICHROME_VX800: | 1497 | break; |
1611 | value = k800_encode_pll(pll_value[i].cx700_pll); | 1498 | case UNICHROME_CX700: |
1612 | break; | 1499 | case UNICHROME_CN750: |
1613 | 1500 | case UNICHROME_K8M890: | |
1614 | case UNICHROME_VX855: | 1501 | case UNICHROME_P4M890: |
1615 | value = vx855_encode_pll(pll_value[i].vx855_pll); | 1502 | case UNICHROME_P4M900: |
1616 | break; | 1503 | case UNICHROME_VX800: |
1617 | } | 1504 | config = get_pll_config(cx700_pll_limits, |
1505 | ARRAY_SIZE(cx700_pll_limits), clk); | ||
1506 | break; | ||
1507 | case UNICHROME_VX855: | ||
1508 | case UNICHROME_VX900: | ||
1509 | config = get_pll_config(vx855_pll_limits, | ||
1510 | ARRAY_SIZE(vx855_pll_limits), clk); | ||
1511 | break; | ||
1618 | } | 1512 | } |
1619 | 1513 | ||
1620 | return value; | 1514 | return config; |
1621 | } | 1515 | } |
1622 | 1516 | ||
1623 | /* Set VCLK*/ | 1517 | /* Set VCLK*/ |
1624 | void viafb_set_vclock(u32 clk, int set_iga) | 1518 | void viafb_set_vclock(u32 clk, int set_iga) |
1625 | { | 1519 | { |
1626 | /* H.W. Reset : ON */ | 1520 | struct via_pll_config config = get_best_pll_config(clk); |
1627 | viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); | ||
1628 | |||
1629 | if (set_iga == IGA1) { | ||
1630 | /* Change D,N FOR VCLK */ | ||
1631 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
1632 | case UNICHROME_CLE266: | ||
1633 | case UNICHROME_K400: | ||
1634 | via_write_reg(VIASR, SR46, (clk & 0x00FF)); | ||
1635 | via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8); | ||
1636 | break; | ||
1637 | |||
1638 | case UNICHROME_K800: | ||
1639 | case UNICHROME_PM800: | ||
1640 | case UNICHROME_CN700: | ||
1641 | case UNICHROME_CX700: | ||
1642 | case UNICHROME_CN750: | ||
1643 | case UNICHROME_K8M890: | ||
1644 | case UNICHROME_P4M890: | ||
1645 | case UNICHROME_P4M900: | ||
1646 | case UNICHROME_VX800: | ||
1647 | case UNICHROME_VX855: | ||
1648 | via_write_reg(VIASR, SR44, (clk & 0x0000FF)); | ||
1649 | via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8); | ||
1650 | via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16); | ||
1651 | break; | ||
1652 | } | ||
1653 | } | ||
1654 | |||
1655 | if (set_iga == IGA2) { | ||
1656 | /* Change D,N FOR LCK */ | ||
1657 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
1658 | case UNICHROME_CLE266: | ||
1659 | case UNICHROME_K400: | ||
1660 | via_write_reg(VIASR, SR44, (clk & 0x00FF)); | ||
1661 | via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8); | ||
1662 | break; | ||
1663 | |||
1664 | case UNICHROME_K800: | ||
1665 | case UNICHROME_PM800: | ||
1666 | case UNICHROME_CN700: | ||
1667 | case UNICHROME_CX700: | ||
1668 | case UNICHROME_CN750: | ||
1669 | case UNICHROME_K8M890: | ||
1670 | case UNICHROME_P4M890: | ||
1671 | case UNICHROME_P4M900: | ||
1672 | case UNICHROME_VX800: | ||
1673 | case UNICHROME_VX855: | ||
1674 | via_write_reg(VIASR, SR4A, (clk & 0x0000FF)); | ||
1675 | via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8); | ||
1676 | via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16); | ||
1677 | break; | ||
1678 | } | ||
1679 | } | ||
1680 | 1521 | ||
1681 | /* H.W. Reset : OFF */ | 1522 | if (set_iga == IGA1) |
1682 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); | 1523 | clock.set_primary_pll(config); |
1683 | 1524 | if (set_iga == IGA2) | |
1684 | /* Reset PLL */ | 1525 | clock.set_secondary_pll(config); |
1685 | if (set_iga == IGA1) { | ||
1686 | viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); | ||
1687 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); | ||
1688 | } | ||
1689 | |||
1690 | if (set_iga == IGA2) { | ||
1691 | viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0); | ||
1692 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0); | ||
1693 | } | ||
1694 | 1526 | ||
1695 | /* Fire! */ | 1527 | /* Fire! */ |
1696 | via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ | 1528 | via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ |
@@ -1936,14 +1768,15 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | |||
1936 | int i; | 1768 | int i; |
1937 | int index = 0; | 1769 | int index = 0; |
1938 | int h_addr, v_addr; | 1770 | int h_addr, v_addr; |
1939 | u32 pll_D_N; | 1771 | u32 clock, refresh = viafb_refresh; |
1940 | u8 polarity = 0; | 1772 | |
1773 | if (viafb_SAMM_ON && set_iga == IGA2) | ||
1774 | refresh = viafb_refresh1; | ||
1941 | 1775 | ||
1942 | for (i = 0; i < video_mode->mode_array; i++) { | 1776 | for (i = 0; i < video_mode->mode_array; i++) { |
1943 | index = i; | 1777 | index = i; |
1944 | 1778 | ||
1945 | if (crt_table[i].refresh_rate == viaparinfo-> | 1779 | if (crt_table[i].refresh_rate == refresh) |
1946 | crt_setting_info->refresh_rate) | ||
1947 | break; | 1780 | break; |
1948 | } | 1781 | } |
1949 | 1782 | ||
@@ -1954,7 +1787,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | |||
1954 | if ((viafb_LCD_ON | viafb_DVI_ON) | 1787 | if ((viafb_LCD_ON | viafb_DVI_ON) |
1955 | && video_mode->crtc[0].crtc.hor_addr == 640 | 1788 | && video_mode->crtc[0].crtc.hor_addr == 640 |
1956 | && video_mode->crtc[0].crtc.ver_addr == 480 | 1789 | && video_mode->crtc[0].crtc.ver_addr == 480 |
1957 | && viaparinfo->crt_setting_info->refresh_rate == 60) { | 1790 | && refresh == 60) { |
1958 | /* The border is 8 pixels. */ | 1791 | /* The border is 8 pixels. */ |
1959 | crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8; | 1792 | crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8; |
1960 | 1793 | ||
@@ -1964,18 +1797,8 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | |||
1964 | 1797 | ||
1965 | h_addr = crt_reg.hor_addr; | 1798 | h_addr = crt_reg.hor_addr; |
1966 | v_addr = crt_reg.ver_addr; | 1799 | v_addr = crt_reg.ver_addr; |
1967 | |||
1968 | /* update polarity for CRT timing */ | ||
1969 | if (crt_table[index].h_sync_polarity == NEGATIVE) | ||
1970 | polarity |= BIT6; | ||
1971 | if (crt_table[index].v_sync_polarity == NEGATIVE) | ||
1972 | polarity |= BIT7; | ||
1973 | via_write_misc_reg_mask(polarity, BIT6 | BIT7); | ||
1974 | |||
1975 | if (set_iga == IGA1) { | 1800 | if (set_iga == IGA1) { |
1976 | viafb_unlock_crt(); | 1801 | viafb_unlock_crt(); |
1977 | viafb_write_reg(CR09, VIACR, 0x00); /*initial CR09=0 */ | ||
1978 | viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6); | ||
1979 | viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); | 1802 | viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); |
1980 | } | 1803 | } |
1981 | 1804 | ||
@@ -1988,7 +1811,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | |||
1988 | break; | 1811 | break; |
1989 | } | 1812 | } |
1990 | 1813 | ||
1991 | load_fix_bit_crtc_reg(); | ||
1992 | viafb_lock_crt(); | 1814 | viafb_lock_crt(); |
1993 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); | 1815 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); |
1994 | viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); | 1816 | viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); |
@@ -1998,21 +1820,19 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | |||
1998 | && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) | 1820 | && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) |
1999 | viafb_load_FIFO_reg(set_iga, h_addr, v_addr); | 1821 | viafb_load_FIFO_reg(set_iga, h_addr, v_addr); |
2000 | 1822 | ||
2001 | pll_D_N = viafb_get_clk_value(crt_table[index].clk); | 1823 | clock = crt_reg.hor_total * crt_reg.ver_total |
2002 | DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); | 1824 | * crt_table[index].refresh_rate; |
2003 | viafb_set_vclock(pll_D_N, set_iga); | 1825 | viafb_set_vclock(clock, set_iga); |
2004 | 1826 | ||
2005 | } | 1827 | } |
2006 | 1828 | ||
2007 | void viafb_init_chip_info(int chip_type) | 1829 | void __devinit viafb_init_chip_info(int chip_type) |
2008 | { | 1830 | { |
1831 | via_clock_init(&clock, chip_type); | ||
2009 | init_gfx_chip_info(chip_type); | 1832 | init_gfx_chip_info(chip_type); |
2010 | init_tmds_chip_info(); | 1833 | init_tmds_chip_info(); |
2011 | init_lvds_chip_info(); | 1834 | init_lvds_chip_info(); |
2012 | 1835 | ||
2013 | viaparinfo->crt_setting_info->iga_path = IGA1; | ||
2014 | viaparinfo->crt_setting_info->refresh_rate = viafb_refresh; | ||
2015 | |||
2016 | /*Set IGA path for each device */ | 1836 | /*Set IGA path for each device */ |
2017 | viafb_set_iga_path(); | 1837 | viafb_set_iga_path(); |
2018 | 1838 | ||
@@ -2024,29 +1844,18 @@ void viafb_init_chip_info(int chip_type) | |||
2024 | viaparinfo->lvds_setting_info->lcd_mode; | 1844 | viaparinfo->lvds_setting_info->lcd_mode; |
2025 | } | 1845 | } |
2026 | 1846 | ||
2027 | void viafb_update_device_setting(int hres, int vres, | 1847 | void viafb_update_device_setting(int hres, int vres, int bpp, int flag) |
2028 | int bpp, int vmode_refresh, int flag) | ||
2029 | { | 1848 | { |
2030 | if (flag == 0) { | 1849 | if (flag == 0) { |
2031 | viaparinfo->crt_setting_info->h_active = hres; | ||
2032 | viaparinfo->crt_setting_info->v_active = vres; | ||
2033 | viaparinfo->crt_setting_info->bpp = bpp; | ||
2034 | viaparinfo->crt_setting_info->refresh_rate = | ||
2035 | vmode_refresh; | ||
2036 | |||
2037 | viaparinfo->tmds_setting_info->h_active = hres; | 1850 | viaparinfo->tmds_setting_info->h_active = hres; |
2038 | viaparinfo->tmds_setting_info->v_active = vres; | 1851 | viaparinfo->tmds_setting_info->v_active = vres; |
2039 | 1852 | ||
2040 | viaparinfo->lvds_setting_info->h_active = hres; | 1853 | viaparinfo->lvds_setting_info->h_active = hres; |
2041 | viaparinfo->lvds_setting_info->v_active = vres; | 1854 | viaparinfo->lvds_setting_info->v_active = vres; |
2042 | viaparinfo->lvds_setting_info->bpp = bpp; | 1855 | viaparinfo->lvds_setting_info->bpp = bpp; |
2043 | viaparinfo->lvds_setting_info->refresh_rate = | ||
2044 | vmode_refresh; | ||
2045 | viaparinfo->lvds_setting_info2->h_active = hres; | 1856 | viaparinfo->lvds_setting_info2->h_active = hres; |
2046 | viaparinfo->lvds_setting_info2->v_active = vres; | 1857 | viaparinfo->lvds_setting_info2->v_active = vres; |
2047 | viaparinfo->lvds_setting_info2->bpp = bpp; | 1858 | viaparinfo->lvds_setting_info2->bpp = bpp; |
2048 | viaparinfo->lvds_setting_info2->refresh_rate = | ||
2049 | vmode_refresh; | ||
2050 | } else { | 1859 | } else { |
2051 | 1860 | ||
2052 | if (viaparinfo->tmds_setting_info->iga_path == IGA2) { | 1861 | if (viaparinfo->tmds_setting_info->iga_path == IGA2) { |
@@ -2058,20 +1867,16 @@ void viafb_update_device_setting(int hres, int vres, | |||
2058 | viaparinfo->lvds_setting_info->h_active = hres; | 1867 | viaparinfo->lvds_setting_info->h_active = hres; |
2059 | viaparinfo->lvds_setting_info->v_active = vres; | 1868 | viaparinfo->lvds_setting_info->v_active = vres; |
2060 | viaparinfo->lvds_setting_info->bpp = bpp; | 1869 | viaparinfo->lvds_setting_info->bpp = bpp; |
2061 | viaparinfo->lvds_setting_info->refresh_rate = | ||
2062 | vmode_refresh; | ||
2063 | } | 1870 | } |
2064 | if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) { | 1871 | if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) { |
2065 | viaparinfo->lvds_setting_info2->h_active = hres; | 1872 | viaparinfo->lvds_setting_info2->h_active = hres; |
2066 | viaparinfo->lvds_setting_info2->v_active = vres; | 1873 | viaparinfo->lvds_setting_info2->v_active = vres; |
2067 | viaparinfo->lvds_setting_info2->bpp = bpp; | 1874 | viaparinfo->lvds_setting_info2->bpp = bpp; |
2068 | viaparinfo->lvds_setting_info2->refresh_rate = | ||
2069 | vmode_refresh; | ||
2070 | } | 1875 | } |
2071 | } | 1876 | } |
2072 | } | 1877 | } |
2073 | 1878 | ||
2074 | static void init_gfx_chip_info(int chip_type) | 1879 | static void __devinit init_gfx_chip_info(int chip_type) |
2075 | { | 1880 | { |
2076 | u8 tmp; | 1881 | u8 tmp; |
2077 | 1882 | ||
@@ -2111,6 +1916,7 @@ static void init_gfx_chip_info(int chip_type) | |||
2111 | switch (viaparinfo->chip_info->gfx_chip_name) { | 1916 | switch (viaparinfo->chip_info->gfx_chip_name) { |
2112 | case UNICHROME_VX800: | 1917 | case UNICHROME_VX800: |
2113 | case UNICHROME_VX855: | 1918 | case UNICHROME_VX855: |
1919 | case UNICHROME_VX900: | ||
2114 | viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1; | 1920 | viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1; |
2115 | break; | 1921 | break; |
2116 | case UNICHROME_K8M890: | 1922 | case UNICHROME_K8M890: |
@@ -2123,7 +1929,7 @@ static void init_gfx_chip_info(int chip_type) | |||
2123 | } | 1929 | } |
2124 | } | 1930 | } |
2125 | 1931 | ||
2126 | static void init_tmds_chip_info(void) | 1932 | static void __devinit init_tmds_chip_info(void) |
2127 | { | 1933 | { |
2128 | viafb_tmds_trasmitter_identify(); | 1934 | viafb_tmds_trasmitter_identify(); |
2129 | 1935 | ||
@@ -2168,7 +1974,7 @@ static void init_tmds_chip_info(void) | |||
2168 | &viaparinfo->shared->tmds_setting_info); | 1974 | &viaparinfo->shared->tmds_setting_info); |
2169 | } | 1975 | } |
2170 | 1976 | ||
2171 | static void init_lvds_chip_info(void) | 1977 | static void __devinit init_lvds_chip_info(void) |
2172 | { | 1978 | { |
2173 | viafb_lvds_trasmitter_identify(); | 1979 | viafb_lvds_trasmitter_identify(); |
2174 | viafb_init_lcd_size(); | 1980 | viafb_init_lcd_size(); |
@@ -2202,7 +2008,7 @@ static void init_lvds_chip_info(void) | |||
2202 | viaparinfo->chip_info->lvds_chip_info.output_interface); | 2008 | viaparinfo->chip_info->lvds_chip_info.output_interface); |
2203 | } | 2009 | } |
2204 | 2010 | ||
2205 | void viafb_init_dac(int set_iga) | 2011 | void __devinit viafb_init_dac(int set_iga) |
2206 | { | 2012 | { |
2207 | int i; | 2013 | int i; |
2208 | u8 tmp; | 2014 | u8 tmp; |
@@ -2275,11 +2081,24 @@ static void set_display_channel(void) | |||
2275 | } | 2081 | } |
2276 | } | 2082 | } |
2277 | 2083 | ||
2084 | static u8 get_sync(struct fb_info *info) | ||
2085 | { | ||
2086 | u8 polarity = 0; | ||
2087 | |||
2088 | if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT)) | ||
2089 | polarity |= VIA_HSYNC_NEGATIVE; | ||
2090 | if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT)) | ||
2091 | polarity |= VIA_VSYNC_NEGATIVE; | ||
2092 | return polarity; | ||
2093 | } | ||
2094 | |||
2278 | int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, | 2095 | int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, |
2279 | struct VideoModeTable *vmode_tbl1, int video_bpp1) | 2096 | struct VideoModeTable *vmode_tbl1, int video_bpp1) |
2280 | { | 2097 | { |
2281 | int i, j; | 2098 | int i, j; |
2282 | int port; | 2099 | int port; |
2100 | u32 devices = viaparinfo->shared->iga1_devices | ||
2101 | | viaparinfo->shared->iga2_devices; | ||
2283 | u8 value, index, mask; | 2102 | u8 value, index, mask; |
2284 | struct crt_mode_table *crt_timing; | 2103 | struct crt_mode_table *crt_timing; |
2285 | struct crt_mode_table *crt_timing1 = NULL; | 2104 | struct crt_mode_table *crt_timing1 = NULL; |
@@ -2295,6 +2114,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, | |||
2295 | outb(0x00, VIAAR); | 2114 | outb(0x00, VIAAR); |
2296 | 2115 | ||
2297 | /* Write Common Setting for Video Mode */ | 2116 | /* Write Common Setting for Video Mode */ |
2117 | viafb_write_regx(common_vga, ARRAY_SIZE(common_vga)); | ||
2298 | switch (viaparinfo->chip_info->gfx_chip_name) { | 2118 | switch (viaparinfo->chip_info->gfx_chip_name) { |
2299 | case UNICHROME_CLE266: | 2119 | case UNICHROME_CLE266: |
2300 | viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs); | 2120 | viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs); |
@@ -2322,11 +2142,14 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, | |||
2322 | break; | 2142 | break; |
2323 | 2143 | ||
2324 | case UNICHROME_VX855: | 2144 | case UNICHROME_VX855: |
2145 | case UNICHROME_VX900: | ||
2325 | viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs); | 2146 | viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs); |
2326 | break; | 2147 | break; |
2327 | } | 2148 | } |
2328 | 2149 | ||
2150 | viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters)); | ||
2329 | device_off(); | 2151 | device_off(); |
2152 | via_set_state(devices, VIA_STATE_OFF); | ||
2330 | 2153 | ||
2331 | /* Fill VPIT Parameters */ | 2154 | /* Fill VPIT Parameters */ |
2332 | /* Write Misc Register */ | 2155 | /* Write Misc Register */ |
@@ -2337,10 +2160,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, | |||
2337 | via_write_reg(VIASR, i, VPIT.SR[i - 1]); | 2160 | via_write_reg(VIASR, i, VPIT.SR[i - 1]); |
2338 | 2161 | ||
2339 | viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2); | 2162 | viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2); |
2340 | viafb_set_iga_path(); | ||
2341 | |||
2342 | /* Write CRTC */ | ||
2343 | viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1); | ||
2344 | 2163 | ||
2345 | /* Write Graphic Controller */ | 2164 | /* Write Graphic Controller */ |
2346 | for (i = 0; i < StdGR; i++) | 2165 | for (i = 0; i < StdGR; i++) |
@@ -2371,31 +2190,37 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, | |||
2371 | } | 2190 | } |
2372 | } | 2191 | } |
2373 | 2192 | ||
2193 | load_fix_bit_crtc_reg(); | ||
2374 | via_set_primary_pitch(viafbinfo->fix.line_length); | 2194 | via_set_primary_pitch(viafbinfo->fix.line_length); |
2375 | via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length | 2195 | via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length |
2376 | : viafbinfo->fix.line_length); | 2196 | : viafbinfo->fix.line_length); |
2377 | via_set_primary_color_depth(viaparinfo->depth); | 2197 | via_set_primary_color_depth(viaparinfo->depth); |
2378 | via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth | 2198 | via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth |
2379 | : viaparinfo->depth); | 2199 | : viaparinfo->depth); |
2200 | via_set_source(viaparinfo->shared->iga1_devices, IGA1); | ||
2201 | via_set_source(viaparinfo->shared->iga2_devices, IGA2); | ||
2202 | if (viaparinfo->shared->iga2_devices) | ||
2203 | enable_second_display_channel(); | ||
2204 | else | ||
2205 | disable_second_display_channel(); | ||
2206 | |||
2380 | /* Update Refresh Rate Setting */ | 2207 | /* Update Refresh Rate Setting */ |
2381 | 2208 | ||
2382 | /* Clear On Screen */ | 2209 | /* Clear On Screen */ |
2383 | 2210 | ||
2384 | /* CRT set mode */ | 2211 | /* CRT set mode */ |
2385 | if (viafb_CRT_ON) { | 2212 | if (viafb_CRT_ON) { |
2386 | if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path == | 2213 | if (viafb_SAMM_ON && |
2387 | IGA2)) { | 2214 | viaparinfo->shared->iga2_devices & VIA_CRT) { |
2388 | viafb_fill_crtc_timing(crt_timing1, vmode_tbl1, | 2215 | viafb_fill_crtc_timing(crt_timing1, vmode_tbl1, |
2389 | video_bpp1 / 8, | 2216 | video_bpp1 / 8, IGA2); |
2390 | viaparinfo->crt_setting_info->iga_path); | ||
2391 | } else { | 2217 | } else { |
2392 | viafb_fill_crtc_timing(crt_timing, vmode_tbl, | 2218 | viafb_fill_crtc_timing(crt_timing, vmode_tbl, |
2393 | video_bpp / 8, | 2219 | video_bpp / 8, |
2394 | viaparinfo->crt_setting_info->iga_path); | 2220 | (viaparinfo->shared->iga1_devices & VIA_CRT) |
2221 | ? IGA1 : IGA2); | ||
2395 | } | 2222 | } |
2396 | 2223 | ||
2397 | set_crt_output_path(viaparinfo->crt_setting_info->iga_path); | ||
2398 | |||
2399 | /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode | 2224 | /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode |
2400 | to 8 alignment (1368),there is several pixels (2 pixels) | 2225 | to 8 alignment (1368),there is several pixels (2 pixels) |
2401 | on right side of screen. */ | 2226 | on right side of screen. */ |
@@ -2482,10 +2307,43 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, | |||
2482 | viafb_DeviceStatus = CRT_Device; | 2307 | viafb_DeviceStatus = CRT_Device; |
2483 | } | 2308 | } |
2484 | device_on(); | 2309 | device_on(); |
2310 | if (!viafb_dual_fb) | ||
2311 | via_set_sync_polarity(devices, get_sync(viafbinfo)); | ||
2312 | else { | ||
2313 | via_set_sync_polarity(viaparinfo->shared->iga1_devices, | ||
2314 | get_sync(viafbinfo)); | ||
2315 | via_set_sync_polarity(viaparinfo->shared->iga2_devices, | ||
2316 | get_sync(viafbinfo1)); | ||
2317 | } | ||
2485 | 2318 | ||
2486 | if (viafb_SAMM_ON == 1) | 2319 | clock.set_engine_pll_state(VIA_STATE_ON); |
2487 | viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7); | 2320 | clock.set_primary_clock_source(VIA_CLKSRC_X1, true); |
2321 | clock.set_secondary_clock_source(VIA_CLKSRC_X1, true); | ||
2322 | |||
2323 | #ifdef CONFIG_FB_VIA_X_COMPATIBILITY | ||
2324 | clock.set_primary_pll_state(VIA_STATE_ON); | ||
2325 | clock.set_primary_clock_state(VIA_STATE_ON); | ||
2326 | clock.set_secondary_pll_state(VIA_STATE_ON); | ||
2327 | clock.set_secondary_clock_state(VIA_STATE_ON); | ||
2328 | #else | ||
2329 | if (viaparinfo->shared->iga1_devices) { | ||
2330 | clock.set_primary_pll_state(VIA_STATE_ON); | ||
2331 | clock.set_primary_clock_state(VIA_STATE_ON); | ||
2332 | } else { | ||
2333 | clock.set_primary_pll_state(VIA_STATE_OFF); | ||
2334 | clock.set_primary_clock_state(VIA_STATE_OFF); | ||
2335 | } | ||
2336 | |||
2337 | if (viaparinfo->shared->iga2_devices) { | ||
2338 | clock.set_secondary_pll_state(VIA_STATE_ON); | ||
2339 | clock.set_secondary_clock_state(VIA_STATE_ON); | ||
2340 | } else { | ||
2341 | clock.set_secondary_pll_state(VIA_STATE_OFF); | ||
2342 | clock.set_secondary_clock_state(VIA_STATE_OFF); | ||
2343 | } | ||
2344 | #endif /*CONFIG_FB_VIA_X_COMPATIBILITY*/ | ||
2488 | 2345 | ||
2346 | via_set_state(devices, VIA_STATE_ON); | ||
2489 | device_screen_on(); | 2347 | device_screen_on(); |
2490 | return 1; | 2348 | return 1; |
2491 | } | 2349 | } |
@@ -2493,64 +2351,63 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, | |||
2493 | int viafb_get_pixclock(int hres, int vres, int vmode_refresh) | 2351 | int viafb_get_pixclock(int hres, int vres, int vmode_refresh) |
2494 | { | 2352 | { |
2495 | int i; | 2353 | int i; |
2354 | struct crt_mode_table *best; | ||
2355 | struct VideoModeTable *vmode = viafb_get_mode(hres, vres); | ||
2356 | |||
2357 | if (!vmode) | ||
2358 | return RES_640X480_60HZ_PIXCLOCK; | ||
2496 | 2359 | ||
2497 | for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) { | 2360 | best = &vmode->crtc[0]; |
2498 | if ((hres == res_map_refresh_tbl[i].hres) | 2361 | for (i = 1; i < vmode->mode_array; i++) { |
2499 | && (vres == res_map_refresh_tbl[i].vres) | 2362 | if (abs(vmode->crtc[i].refresh_rate - vmode_refresh) |
2500 | && (vmode_refresh == res_map_refresh_tbl[i].vmode_refresh)) | 2363 | < abs(best->refresh_rate - vmode_refresh)) |
2501 | return res_map_refresh_tbl[i].pixclock; | 2364 | best = &vmode->crtc[i]; |
2502 | } | 2365 | } |
2503 | return RES_640X480_60HZ_PIXCLOCK; | ||
2504 | 2366 | ||
2367 | return 1000000000 / (best->crtc.hor_total * best->crtc.ver_total) | ||
2368 | * 1000 / best->refresh_rate; | ||
2505 | } | 2369 | } |
2506 | 2370 | ||
2507 | int viafb_get_refresh(int hres, int vres, u32 long_refresh) | 2371 | int viafb_get_refresh(int hres, int vres, u32 long_refresh) |
2508 | { | 2372 | { |
2509 | #define REFRESH_TOLERANCE 3 | 2373 | int i; |
2510 | int i, nearest = -1, diff = REFRESH_TOLERANCE; | 2374 | struct crt_mode_table *best; |
2511 | for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) { | 2375 | struct VideoModeTable *vmode = viafb_get_mode(hres, vres); |
2512 | if ((hres == res_map_refresh_tbl[i].hres) | 2376 | |
2513 | && (vres == res_map_refresh_tbl[i].vres) | 2377 | if (!vmode) |
2514 | && (diff > (abs(long_refresh - | 2378 | return 60; |
2515 | res_map_refresh_tbl[i].vmode_refresh)))) { | 2379 | |
2516 | diff = abs(long_refresh - res_map_refresh_tbl[i]. | 2380 | best = &vmode->crtc[0]; |
2517 | vmode_refresh); | 2381 | for (i = 1; i < vmode->mode_array; i++) { |
2518 | nearest = i; | 2382 | if (abs(vmode->crtc[i].refresh_rate - long_refresh) |
2519 | } | 2383 | < abs(best->refresh_rate - long_refresh)) |
2384 | best = &vmode->crtc[i]; | ||
2520 | } | 2385 | } |
2521 | #undef REFRESH_TOLERANCE | 2386 | |
2522 | if (nearest > 0) | 2387 | if (abs(best->refresh_rate - long_refresh) > 3) { |
2523 | return res_map_refresh_tbl[nearest].vmode_refresh; | 2388 | if (hres == 1200 && vres == 900) |
2524 | return 60; | 2389 | return 49; /* OLPC DCON only supports 50 Hz */ |
2390 | else | ||
2391 | return 60; | ||
2392 | } | ||
2393 | |||
2394 | return best->refresh_rate; | ||
2525 | } | 2395 | } |
2526 | 2396 | ||
2527 | static void device_off(void) | 2397 | static void device_off(void) |
2528 | { | 2398 | { |
2529 | viafb_crt_disable(); | ||
2530 | viafb_dvi_disable(); | 2399 | viafb_dvi_disable(); |
2531 | viafb_lcd_disable(); | 2400 | viafb_lcd_disable(); |
2532 | } | 2401 | } |
2533 | 2402 | ||
2534 | static void device_on(void) | 2403 | static void device_on(void) |
2535 | { | 2404 | { |
2536 | if (viafb_CRT_ON == 1) | ||
2537 | viafb_crt_enable(); | ||
2538 | if (viafb_DVI_ON == 1) | 2405 | if (viafb_DVI_ON == 1) |
2539 | viafb_dvi_enable(); | 2406 | viafb_dvi_enable(); |
2540 | if (viafb_LCD_ON == 1) | 2407 | if (viafb_LCD_ON == 1) |
2541 | viafb_lcd_enable(); | 2408 | viafb_lcd_enable(); |
2542 | } | 2409 | } |
2543 | 2410 | ||
2544 | void viafb_crt_disable(void) | ||
2545 | { | ||
2546 | viafb_write_reg_mask(CR36, VIACR, BIT5 + BIT4, BIT5 + BIT4); | ||
2547 | } | ||
2548 | |||
2549 | void viafb_crt_enable(void) | ||
2550 | { | ||
2551 | viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4); | ||
2552 | } | ||
2553 | |||
2554 | static void enable_second_display_channel(void) | 2411 | static void enable_second_display_channel(void) |
2555 | { | 2412 | { |
2556 | /* to enable second display channel. */ | 2413 | /* to enable second display channel. */ |
@@ -2567,7 +2424,6 @@ static void disable_second_display_channel(void) | |||
2567 | viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); | 2424 | viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); |
2568 | } | 2425 | } |
2569 | 2426 | ||
2570 | |||
2571 | void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ | 2427 | void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ |
2572 | *p_gfx_dpa_setting) | 2428 | *p_gfx_dpa_setting) |
2573 | { | 2429 | { |
@@ -2652,4 +2508,9 @@ void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, | |||
2652 | crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end); | 2508 | crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end); |
2653 | var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr; | 2509 | var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr; |
2654 | var->vsync_len = crt_reg.ver_sync_end; | 2510 | var->vsync_len = crt_reg.ver_sync_end; |
2511 | var->sync = 0; | ||
2512 | if (crt_timing[index].h_sync_polarity == POSITIVE) | ||
2513 | var->sync |= FB_SYNC_HOR_HIGH_ACT; | ||
2514 | if (crt_timing[index].v_sync_polarity == POSITIVE) | ||
2515 | var->sync |= FB_SYNC_VERT_HIGH_ACT; | ||
2655 | } | 2516 | } |