aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via/hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/via/hw.c')
-rw-r--r--drivers/video/via/hw.c1463
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
27static 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
58static 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
25static struct pll_map pll_value[] = { 77static 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} }, 92static 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}, 104static 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}, 121static 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
363static struct fifo_depth_select display_fifo_depth_reg = { 157static 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
721static void set_crt_output_path(int set_iga); 515static struct via_device_mapping device_mapping[] = {
722static void dvi_patch_skew_dvp0(void); 516 {VIA_LDVP0, "LDVP0"},
723static void dvi_patch_skew_dvp1(void); 517 {VIA_LDVP1, "LDVP1"},
724static void dvi_patch_skew_dvp_low(void); 518 {VIA_DVP0, "DVP0"},
725static void set_dvi_output_path(int set_iga, int output_interface); 519 {VIA_CRT, "CRT"},
726static 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 */
526static struct via_clock clock;
527
727static void load_fix_bit_crtc_reg(void); 528static void load_fix_bit_crtc_reg(void);
728static void init_gfx_chip_info(int chip_type); 529static void __devinit init_gfx_chip_info(int chip_type);
729static void init_tmds_chip_info(void); 530static void __devinit init_tmds_chip_info(void);
730static void init_lvds_chip_info(void); 531static void __devinit init_lvds_chip_info(void);
731static void device_screen_off(void); 532static void device_screen_off(void);
732static void device_screen_on(void); 533static void device_screen_on(void);
733static void set_display_channel(void); 534static 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
750void write_dac_reg(u8 index, u8 r, u8 g, u8 b) 551static 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
559static 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
590static 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*/
759void viafb_set_iga_path(void) 620void 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
826static void set_color_register(u8 index, u8 red, u8 green, u8 blue) 733static 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
847void viafb_set_output_path(int device, int set_iga, int output_interface) 754static 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
862static void set_crt_output_path(int set_iga) 773static 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
877static void dvi_patch_skew_dvp0(void) 792static 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: 797static 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: 802static inline void set_dvp0_source(u8 iga)
907 { 803{
908 break; 804 set_source_common(0x96, 4, iga);
909 }
910 }
911} 805}
912 806
913static void dvi_patch_skew_dvp1(void) 807static 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: 812static inline void set_lvds1_source(u8 iga)
922 { 813{
923 break; 814 set_source_common(0x99, 4, iga);
924 }
925 }
926} 815}
927 816
928static void dvi_patch_skew_dvp_low(void) 817static 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: 822void 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: 840static 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
958static void set_dvi_output_path(int set_iga, int output_interface) 864static 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); 882static 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) { 900static 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
1043static void set_lcd_output_path(int set_iga, int output_interface) 918static 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: 936void 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: 955void 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: 973u32 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; 999void 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
1138static void load_fix_bit_crtc_reg(void) 1016static 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
1561static u32 cle266_encode_pll(struct pll_config pll) 1449static 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++) {
1568static 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
1575static 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
1582u32 viafb_get_clk_value(int clk) 1482static 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*/
1624void viafb_set_vclock(u32 clk, int set_iga) 1518void 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
2007void viafb_init_chip_info(int chip_type) 1829void __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
2027void viafb_update_device_setting(int hres, int vres, 1847void 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
2074static void init_gfx_chip_info(int chip_type) 1879static 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
2126static void init_tmds_chip_info(void) 1932static 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
2171static void init_lvds_chip_info(void) 1977static 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
2205void viafb_init_dac(int set_iga) 2011void __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
2084static 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
2278int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, 2095int 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,
2493int viafb_get_pixclock(int hres, int vres, int vmode_refresh) 2351int 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
2507int viafb_get_refresh(int hres, int vres, u32 long_refresh) 2371int 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
2527static void device_off(void) 2397static 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
2534static void device_on(void) 2403static 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
2544void viafb_crt_disable(void)
2545{
2546 viafb_write_reg_mask(CR36, VIACR, BIT5 + BIT4, BIT5 + BIT4);
2547}
2548
2549void viafb_crt_enable(void)
2550{
2551 viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4);
2552}
2553
2554static void enable_second_display_channel(void) 2411static 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
2571void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ 2427void 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}