1 /*
2  * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3  * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public
7  * License as published by the Free Software Foundation;
8  * either version 2, or (at your option) any later version.
9 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12  * the implied warranty of MERCHANTABILITY or FITNESS FOR
13  * A PARTICULAR PURPOSE.See the GNU General Public License
14  * for more details.
15 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc.,
19  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #include <linux/via-core.h>
23 #include "global.h"
24 
25 static struct pll_config cle266_pll_config[] = {
26 	{19, 4, 0},
27 	{26, 5, 0},
28 	{28, 5, 0},
29 	{31, 5, 0},
30 	{33, 5, 0},
31 	{55, 5, 0},
32 	{102, 5, 0},
33 	{53, 6, 0},
34 	{92, 6, 0},
35 	{98, 6, 0},
36 	{112, 6, 0},
37 	{41, 7, 0},
38 	{60, 7, 0},
39 	{99, 7, 0},
40 	{100, 7, 0},
41 	{83, 8, 0},
42 	{86, 8, 0},
43 	{108, 8, 0},
44 	{87, 9, 0},
45 	{118, 9, 0},
46 	{95, 12, 0},
47 	{115, 12, 0},
48 	{108, 13, 0},
49 	{83, 17, 0},
50 	{67, 20, 0},
51 	{86, 20, 0},
52 	{98, 20, 0},
53 	{121, 24, 0},
54 	{99, 29, 0},
55 	{33, 3, 1},
56 	{15, 4, 1},
57 	{23, 4, 1},
58 	{37, 5, 1},
59 	{83, 5, 1},
60 	{85, 5, 1},
61 	{94, 5, 1},
62 	{103, 5, 1},
63 	{109, 5, 1},
64 	{113, 5, 1},
65 	{121, 5, 1},
66 	{82, 6, 1},
67 	{31, 7, 1},
68 	{55, 7, 1},
69 	{84, 7, 1},
70 	{83, 8, 1},
71 	{76, 9, 1},
72 	{127, 9, 1},
73 	{33, 4, 2},
74 	{75, 4, 2},
75 	{119, 4, 2},
76 	{121, 4, 2},
77 	{91, 5, 2},
78 	{118, 5, 2},
79 	{83, 6, 2},
80 	{109, 6, 2},
81 	{90, 7, 2},
82 	{93, 2, 3},
83 	{53, 3, 3},
84 	{73, 4, 3},
85 	{89, 4, 3},
86 	{105, 4, 3},
87 	{117, 4, 3},
88 	{101, 5, 3},
89 	{121, 5, 3},
90 	{127, 5, 3},
91 	{99, 7, 3}
92 };
93 
94 static struct pll_config k800_pll_config[] = {
95 	{22, 2, 0},
96 	{28, 3, 0},
97 	{81, 3, 1},
98 	{85, 3, 1},
99 	{98, 3, 1},
100 	{112, 3, 1},
101 	{86, 4, 1},
102 	{166, 4, 1},
103 	{109, 5, 1},
104 	{113, 5, 1},
105 	{121, 5, 1},
106 	{131, 5, 1},
107 	{143, 5, 1},
108 	{153, 5, 1},
109 	{66, 3, 2},
110 	{68, 3, 2},
111 	{95, 3, 2},
112 	{106, 3, 2},
113 	{116, 3, 2},
114 	{93, 4, 2},
115 	{119, 4, 2},
116 	{121, 4, 2},
117 	{133, 4, 2},
118 	{137, 4, 2},
119 	{117, 5, 2},
120 	{118, 5, 2},
121 	{120, 5, 2},
122 	{124, 5, 2},
123 	{132, 5, 2},
124 	{137, 5, 2},
125 	{141, 5, 2},
126 	{166, 5, 2},
127 	{170, 5, 2},
128 	{191, 5, 2},
129 	{206, 5, 2},
130 	{208, 5, 2},
131 	{30, 2, 3},
132 	{69, 3, 3},
133 	{82, 3, 3},
134 	{83, 3, 3},
135 	{109, 3, 3},
136 	{114, 3, 3},
137 	{125, 3, 3},
138 	{89, 4, 3},
139 	{103, 4, 3},
140 	{117, 4, 3},
141 	{126, 4, 3},
142 	{150, 4, 3},
143 	{161, 4, 3},
144 	{121, 5, 3},
145 	{127, 5, 3},
146 	{131, 5, 3},
147 	{134, 5, 3},
148 	{148, 5, 3},
149 	{169, 5, 3},
150 	{172, 5, 3},
151 	{182, 5, 3},
152 	{195, 5, 3},
153 	{196, 5, 3},
154 	{208, 5, 3},
155 	{66, 2, 4},
156 	{85, 3, 4},
157 	{141, 4, 4},
158 	{146, 4, 4},
159 	{161, 4, 4},
160 	{177, 5, 4}
161 };
162 
163 static struct pll_config cx700_pll_config[] = {
164 	{98, 3, 1},
165 	{86, 4, 1},
166 	{109, 5, 1},
167 	{110, 5, 1},
168 	{113, 5, 1},
169 	{121, 5, 1},
170 	{131, 5, 1},
171 	{135, 5, 1},
172 	{142, 5, 1},
173 	{143, 5, 1},
174 	{153, 5, 1},
175 	{187, 5, 1},
176 	{208, 5, 1},
177 	{68, 2, 2},
178 	{95, 3, 2},
179 	{116, 3, 2},
180 	{93, 4, 2},
181 	{119, 4, 2},
182 	{133, 4, 2},
183 	{137, 4, 2},
184 	{151, 4, 2},
185 	{166, 4, 2},
186 	{110, 5, 2},
187 	{112, 5, 2},
188 	{117, 5, 2},
189 	{118, 5, 2},
190 	{120, 5, 2},
191 	{132, 5, 2},
192 	{137, 5, 2},
193 	{141, 5, 2},
194 	{151, 5, 2},
195 	{166, 5, 2},
196 	{175, 5, 2},
197 	{191, 5, 2},
198 	{206, 5, 2},
199 	{174, 7, 2},
200 	{82, 3, 3},
201 	{109, 3, 3},
202 	{117, 4, 3},
203 	{150, 4, 3},
204 	{161, 4, 3},
205 	{112, 5, 3},
206 	{115, 5, 3},
207 	{121, 5, 3},
208 	{127, 5, 3},
209 	{129, 5, 3},
210 	{131, 5, 3},
211 	{134, 5, 3},
212 	{138, 5, 3},
213 	{148, 5, 3},
214 	{157, 5, 3},
215 	{169, 5, 3},
216 	{172, 5, 3},
217 	{190, 5, 3},
218 	{195, 5, 3},
219 	{196, 5, 3},
220 	{208, 5, 3},
221 	{141, 5, 4},
222 	{150, 5, 4},
223 	{166, 5, 4},
224 	{176, 5, 4},
225 	{177, 5, 4},
226 	{183, 5, 4},
227 	{202, 5, 4}
228 };
229 
230 static struct pll_config vx855_pll_config[] = {
231 	{86, 4, 1},
232 	{108, 5, 1},
233 	{110, 5, 1},
234 	{113, 5, 1},
235 	{121, 5, 1},
236 	{131, 5, 1},
237 	{135, 5, 1},
238 	{142, 5, 1},
239 	{143, 5, 1},
240 	{153, 5, 1},
241 	{164, 5, 1},
242 	{187, 5, 1},
243 	{208, 5, 1},
244 	{110, 5, 2},
245 	{112, 5, 2},
246 	{117, 5, 2},
247 	{118, 5, 2},
248 	{124, 5, 2},
249 	{132, 5, 2},
250 	{137, 5, 2},
251 	{141, 5, 2},
252 	{149, 5, 2},
253 	{151, 5, 2},
254 	{159, 5, 2},
255 	{166, 5, 2},
256 	{167, 5, 2},
257 	{172, 5, 2},
258 	{189, 5, 2},
259 	{191, 5, 2},
260 	{194, 5, 2},
261 	{206, 5, 2},
262 	{208, 5, 2},
263 	{83, 3, 3},
264 	{88, 3, 3},
265 	{109, 3, 3},
266 	{112, 3, 3},
267 	{103, 4, 3},
268 	{105, 4, 3},
269 	{161, 4, 3},
270 	{112, 5, 3},
271 	{115, 5, 3},
272 	{121, 5, 3},
273 	{127, 5, 3},
274 	{134, 5, 3},
275 	{137, 5, 3},
276 	{148, 5, 3},
277 	{157, 5, 3},
278 	{169, 5, 3},
279 	{172, 5, 3},
280 	{182, 5, 3},
281 	{191, 5, 3},
282 	{195, 5, 3},
283 	{209, 5, 3},
284 	{142, 4, 4},
285 	{146, 4, 4},
286 	{161, 4, 4},
287 	{141, 5, 4},
288 	{150, 5, 4},
289 	{165, 5, 4},
290 	{176, 5, 4}
291 };
292 
293 /* according to VIA Technologies these values are based on experiment */
294 static struct io_reg scaling_parameters[] = {
295 	{VIACR, CR7A, 0xFF, 0x01},	/* LCD Scaling Parameter 1 */
296 	{VIACR, CR7B, 0xFF, 0x02},	/* LCD Scaling Parameter 2 */
297 	{VIACR, CR7C, 0xFF, 0x03},	/* LCD Scaling Parameter 3 */
298 	{VIACR, CR7D, 0xFF, 0x04},	/* LCD Scaling Parameter 4 */
299 	{VIACR, CR7E, 0xFF, 0x07},	/* LCD Scaling Parameter 5 */
300 	{VIACR, CR7F, 0xFF, 0x0A},	/* LCD Scaling Parameter 6 */
301 	{VIACR, CR80, 0xFF, 0x0D},	/* LCD Scaling Parameter 7 */
302 	{VIACR, CR81, 0xFF, 0x13},	/* LCD Scaling Parameter 8 */
303 	{VIACR, CR82, 0xFF, 0x16},	/* LCD Scaling Parameter 9 */
304 	{VIACR, CR83, 0xFF, 0x19},	/* LCD Scaling Parameter 10 */
305 	{VIACR, CR84, 0xFF, 0x1C},	/* LCD Scaling Parameter 11 */
306 	{VIACR, CR85, 0xFF, 0x1D},	/* LCD Scaling Parameter 12 */
307 	{VIACR, CR86, 0xFF, 0x1E},	/* LCD Scaling Parameter 13 */
308 	{VIACR, CR87, 0xFF, 0x1F},	/* LCD Scaling Parameter 14 */
309 };
310 
311 static struct fifo_depth_select display_fifo_depth_reg = {
312 	/* IGA1 FIFO Depth_Select */
313 	{IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } },
314 	/* IGA2 FIFO Depth_Select */
315 	{IGA2_FIFO_DEPTH_SELECT_REG_NUM,
316 	 {{CR68, 4, 7}, {CR94, 7, 7}, {CR95, 7, 7} } }
317 };
318 
319 static struct fifo_threshold_select fifo_threshold_select_reg = {
320 	/* IGA1 FIFO Threshold Select */
321 	{IGA1_FIFO_THRESHOLD_REG_NUM, {{SR16, 0, 5}, {SR16, 7, 7} } },
322 	/* IGA2 FIFO Threshold Select */
323 	{IGA2_FIFO_THRESHOLD_REG_NUM, {{CR68, 0, 3}, {CR95, 4, 6} } }
324 };
325 
326 static struct fifo_high_threshold_select fifo_high_threshold_select_reg = {
327 	/* IGA1 FIFO High Threshold Select */
328 	{IGA1_FIFO_HIGH_THRESHOLD_REG_NUM, {{SR18, 0, 5}, {SR18, 7, 7} } },
329 	/* IGA2 FIFO High Threshold Select */
330 	{IGA2_FIFO_HIGH_THRESHOLD_REG_NUM, {{CR92, 0, 3}, {CR95, 0, 2} } }
331 };
332 
333 static struct display_queue_expire_num display_queue_expire_num_reg = {
334 	/* IGA1 Display Queue Expire Num */
335 	{IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{SR22, 0, 4} } },
336 	/* IGA2 Display Queue Expire Num */
337 	{IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{CR94, 0, 6} } }
338 };
339 
340 /* Definition Fetch Count Registers*/
341 static struct fetch_count fetch_count_reg = {
342 	/* IGA1 Fetch Count Register */
343 	{IGA1_FETCH_COUNT_REG_NUM, {{SR1C, 0, 7}, {SR1D, 0, 1} } },
344 	/* IGA2 Fetch Count Register */
345 	{IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } }
346 };
347 
348 static struct iga1_crtc_timing iga1_crtc_reg = {
349 	/* IGA1 Horizontal Total */
350 	{IGA1_HOR_TOTAL_REG_NUM, {{CR00, 0, 7}, {CR36, 3, 3} } },
351 	/* IGA1 Horizontal Addressable Video */
352 	{IGA1_HOR_ADDR_REG_NUM, {{CR01, 0, 7} } },
353 	/* IGA1 Horizontal Blank Start */
354 	{IGA1_HOR_BLANK_START_REG_NUM, {{CR02, 0, 7} } },
355 	/* IGA1 Horizontal Blank End */
356 	{IGA1_HOR_BLANK_END_REG_NUM,
357 	 {{CR03, 0, 4}, {CR05, 7, 7}, {CR33, 5, 5} } },
358 	/* IGA1 Horizontal Sync Start */
359 	{IGA1_HOR_SYNC_START_REG_NUM, {{CR04, 0, 7}, {CR33, 4, 4} } },
360 	/* IGA1 Horizontal Sync End */
361 	{IGA1_HOR_SYNC_END_REG_NUM, {{CR05, 0, 4} } },
362 	/* IGA1 Vertical Total */
363 	{IGA1_VER_TOTAL_REG_NUM,
364 	 {{CR06, 0, 7}, {CR07, 0, 0}, {CR07, 5, 5}, {CR35, 0, 0} } },
365 	/* IGA1 Vertical Addressable Video */
366 	{IGA1_VER_ADDR_REG_NUM,
367 	 {{CR12, 0, 7}, {CR07, 1, 1}, {CR07, 6, 6}, {CR35, 2, 2} } },
368 	/* IGA1 Vertical Blank Start */
369 	{IGA1_VER_BLANK_START_REG_NUM,
370 	 {{CR15, 0, 7}, {CR07, 3, 3}, {CR09, 5, 5}, {CR35, 3, 3} } },
371 	/* IGA1 Vertical Blank End */
372 	{IGA1_VER_BLANK_END_REG_NUM, {{CR16, 0, 7} } },
373 	/* IGA1 Vertical Sync Start */
374 	{IGA1_VER_SYNC_START_REG_NUM,
375 	 {{CR10, 0, 7}, {CR07, 2, 2}, {CR07, 7, 7}, {CR35, 1, 1} } },
376 	/* IGA1 Vertical Sync End */
377 	{IGA1_VER_SYNC_END_REG_NUM, {{CR11, 0, 3} } }
378 };
379 
380 static struct iga2_crtc_timing iga2_crtc_reg = {
381 	/* IGA2 Horizontal Total */
382 	{IGA2_HOR_TOTAL_REG_NUM, {{CR50, 0, 7}, {CR55, 0, 3} } },
383 	/* IGA2 Horizontal Addressable Video */
384 	{IGA2_HOR_ADDR_REG_NUM, {{CR51, 0, 7}, {CR55, 4, 6} } },
385 	/* IGA2 Horizontal Blank Start */
386 	{IGA2_HOR_BLANK_START_REG_NUM, {{CR52, 0, 7}, {CR54, 0, 2} } },
387 	/* IGA2 Horizontal Blank End */
388 	{IGA2_HOR_BLANK_END_REG_NUM,
389 	 {{CR53, 0, 7}, {CR54, 3, 5}, {CR5D, 6, 6} } },
390 	/* IGA2 Horizontal Sync Start */
391 	{IGA2_HOR_SYNC_START_REG_NUM,
392 	 {{CR56, 0, 7}, {CR54, 6, 7}, {CR5C, 7, 7}, {CR5D, 7, 7} } },
393 	/* IGA2 Horizontal Sync End */
394 	{IGA2_HOR_SYNC_END_REG_NUM, {{CR57, 0, 7}, {CR5C, 6, 6} } },
395 	/* IGA2 Vertical Total */
396 	{IGA2_VER_TOTAL_REG_NUM, {{CR58, 0, 7}, {CR5D, 0, 2} } },
397 	/* IGA2 Vertical Addressable Video */
398 	{IGA2_VER_ADDR_REG_NUM, {{CR59, 0, 7}, {CR5D, 3, 5} } },
399 	/* IGA2 Vertical Blank Start */
400 	{IGA2_VER_BLANK_START_REG_NUM, {{CR5A, 0, 7}, {CR5C, 0, 2} } },
401 	/* IGA2 Vertical Blank End */
402 	{IGA2_VER_BLANK_END_REG_NUM, {{CR5B, 0, 7}, {CR5C, 3, 5} } },
403 	/* IGA2 Vertical Sync Start */
404 	{IGA2_VER_SYNC_START_REG_NUM, {{CR5E, 0, 7}, {CR5F, 5, 7} } },
405 	/* IGA2 Vertical Sync End */
406 	{IGA2_VER_SYNC_END_REG_NUM, {{CR5F, 0, 4} } }
407 };
408 
409 static struct rgbLUT palLUT_table[] = {
410 	/* {R,G,B} */
411 	/* Index 0x00~0x03 */
412 	{0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00,
413 								     0x2A,
414 								     0x2A},
415 	/* Index 0x04~0x07 */
416 	{0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A,
417 								     0x2A,
418 								     0x2A},
419 	/* Index 0x08~0x0B */
420 	{0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15,
421 								     0x3F,
422 								     0x3F},
423 	/* Index 0x0C~0x0F */
424 	{0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F,
425 								     0x3F,
426 								     0x3F},
427 	/* Index 0x10~0x13 */
428 	{0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B,
429 								     0x0B,
430 								     0x0B},
431 	/* Index 0x14~0x17 */
432 	{0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18,
433 								     0x18,
434 								     0x18},
435 	/* Index 0x18~0x1B */
436 	{0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28,
437 								     0x28,
438 								     0x28},
439 	/* Index 0x1C~0x1F */
440 	{0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F,
441 								     0x3F,
442 								     0x3F},
443 	/* Index 0x20~0x23 */
444 	{0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F,
445 								     0x00,
446 								     0x3F},
447 	/* Index 0x24~0x27 */
448 	{0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F,
449 								     0x00,
450 								     0x10},
451 	/* Index 0x28~0x2B */
452 	{0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F,
453 								     0x2F,
454 								     0x00},
455 	/* Index 0x2C~0x2F */
456 	{0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10,
457 								     0x3F,
458 								     0x00},
459 	/* Index 0x30~0x33 */
460 	{0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00,
461 								     0x3F,
462 								     0x2F},
463 	/* Index 0x34~0x37 */
464 	{0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00,
465 								     0x10,
466 								     0x3F},
467 	/* Index 0x38~0x3B */
468 	{0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37,
469 								     0x1F,
470 								     0x3F},
471 	/* Index 0x3C~0x3F */
472 	{0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F,
473 								     0x1F,
474 								     0x27},
475 	/* Index 0x40~0x43 */
476 	{0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F,
477 								     0x3F,
478 								     0x1F},
479 	/* Index 0x44~0x47 */
480 	{0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27,
481 								     0x3F,
482 								     0x1F},
483 	/* Index 0x48~0x4B */
484 	{0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F,
485 								     0x3F,
486 								     0x37},
487 	/* Index 0x4C~0x4F */
488 	{0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F,
489 								     0x27,
490 								     0x3F},
491 	/* Index 0x50~0x53 */
492 	{0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A,
493 								     0x2D,
494 								     0x3F},
495 	/* Index 0x54~0x57 */
496 	{0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F,
497 								     0x2D,
498 								     0x31},
499 	/* Index 0x58~0x5B */
500 	{0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F,
501 								     0x3A,
502 								     0x2D},
503 	/* Index 0x5C~0x5F */
504 	{0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31,
505 								     0x3F,
506 								     0x2D},
507 	/* Index 0x60~0x63 */
508 	{0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D,
509 								     0x3F,
510 								     0x3A},
511 	/* Index 0x64~0x67 */
512 	{0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D,
513 								     0x31,
514 								     0x3F},
515 	/* Index 0x68~0x6B */
516 	{0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15,
517 								     0x00,
518 								     0x1C},
519 	/* Index 0x6C~0x6F */
520 	{0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C,
521 								     0x00,
522 								     0x07},
523 	/* Index 0x70~0x73 */
524 	{0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C,
525 								     0x15,
526 								     0x00},
527 	/* Index 0x74~0x77 */
528 	{0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07,
529 								     0x1C,
530 								     0x00},
531 	/* Index 0x78~0x7B */
532 	{0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00,
533 								     0x1C,
534 								     0x15},
535 	/* Index 0x7C~0x7F */
536 	{0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00,
537 								     0x07,
538 								     0x1C},
539 	/* Index 0x80~0x83 */
540 	{0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18,
541 								     0x0E,
542 								     0x1C},
543 	/* Index 0x84~0x87 */
544 	{0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C,
545 								     0x0E,
546 								     0x11},
547 	/* Index 0x88~0x8B */
548 	{0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C,
549 								     0x18,
550 								     0x0E},
551 	/* Index 0x8C~0x8F */
552 	{0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11,
553 								     0x1C,
554 								     0x0E},
555 	/* Index 0x90~0x93 */
556 	{0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E,
557 								     0x1C,
558 								     0x18},
559 	/* Index 0x94~0x97 */
560 	{0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E,
561 								     0x11,
562 								     0x1C},
563 	/* Index 0x98~0x9B */
564 	{0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A,
565 								     0x14,
566 								     0x1C},
567 	/* Index 0x9C~0x9F */
568 	{0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C,
569 								     0x14,
570 								     0x16},
571 	/* Index 0xA0~0xA3 */
572 	{0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C,
573 								     0x1A,
574 								     0x14},
575 	/* Index 0xA4~0xA7 */
576 	{0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16,
577 								     0x1C,
578 								     0x14},
579 	/* Index 0xA8~0xAB */
580 	{0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14,
581 								     0x1C,
582 								     0x1A},
583 	/* Index 0xAC~0xAF */
584 	{0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14,
585 								     0x16,
586 								     0x1C},
587 	/* Index 0xB0~0xB3 */
588 	{0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C,
589 								     0x00,
590 								     0x10},
591 	/* Index 0xB4~0xB7 */
592 	{0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10,
593 								     0x00,
594 								     0x04},
595 	/* Index 0xB8~0xBB */
596 	{0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10,
597 								     0x0C,
598 								     0x00},
599 	/* Index 0xBC~0xBF */
600 	{0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04,
601 								     0x10,
602 								     0x00},
603 	/* Index 0xC0~0xC3 */
604 	{0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00,
605 								     0x10,
606 								     0x0C},
607 	/* Index 0xC4~0xC7 */
608 	{0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00,
609 								     0x04,
610 								     0x10},
611 	/* Index 0xC8~0xCB */
612 	{0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E,
613 								     0x08,
614 								     0x10},
615 	/* Index 0xCC~0xCF */
616 	{0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10,
617 								     0x08,
618 								     0x0A},
619 	/* Index 0xD0~0xD3 */
620 	{0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10,
621 								     0x0E,
622 								     0x08},
623 	/* Index 0xD4~0xD7 */
624 	{0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A,
625 								     0x10,
626 								     0x08},
627 	/* Index 0xD8~0xDB */
628 	{0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08,
629 								     0x10,
630 								     0x0E},
631 	/* Index 0xDC~0xDF */
632 	{0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08,
633 								     0x0A,
634 								     0x10},
635 	/* Index 0xE0~0xE3 */
636 	{0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F,
637 								     0x0B,
638 								     0x10},
639 	/* Index 0xE4~0xE7 */
640 	{0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10,
641 								     0x0B,
642 								     0x0C},
643 	/* Index 0xE8~0xEB */
644 	{0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10,
645 								     0x0F,
646 								     0x0B},
647 	/* Index 0xEC~0xEF */
648 	{0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C,
649 								     0x10,
650 								     0x0B},
651 	/* Index 0xF0~0xF3 */
652 	{0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B,
653 								     0x10,
654 								     0x0F},
655 	/* Index 0xF4~0xF7 */
656 	{0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B,
657 								     0x0C,
658 								     0x10},
659 	/* Index 0xF8~0xFB */
660 	{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
661 								     0x00,
662 								     0x00},
663 	/* Index 0xFC~0xFF */
664 	{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
665 								     0x00,
666 								     0x00}
667 };
668 
669 static struct via_device_mapping device_mapping[] = {
670 	{VIA_LDVP0, "LDVP0"},
671 	{VIA_LDVP1, "LDVP1"},
672 	{VIA_DVP0, "DVP0"},
673 	{VIA_CRT, "CRT"},
674 	{VIA_DVP1, "DVP1"},
675 	{VIA_LVDS1, "LVDS1"},
676 	{VIA_LVDS2, "LVDS2"}
677 };
678 
679 static void load_fix_bit_crtc_reg(void);
680 static void __devinit init_gfx_chip_info(int chip_type);
681 static void __devinit init_tmds_chip_info(void);
682 static void __devinit init_lvds_chip_info(void);
683 static void device_screen_off(void);
684 static void device_screen_on(void);
685 static void set_display_channel(void);
686 static void device_off(void);
687 static void device_on(void);
688 static void enable_second_display_channel(void);
689 static void disable_second_display_channel(void);
690 
viafb_lock_crt(void)691 void viafb_lock_crt(void)
692 {
693 	viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7);
694 }
695 
viafb_unlock_crt(void)696 void viafb_unlock_crt(void)
697 {
698 	viafb_write_reg_mask(CR11, VIACR, 0, BIT7);
699 	viafb_write_reg_mask(CR47, VIACR, 0, BIT0);
700 }
701 
write_dac_reg(u8 index,u8 r,u8 g,u8 b)702 static void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
703 {
704 	outb(index, LUT_INDEX_WRITE);
705 	outb(r, LUT_DATA);
706 	outb(g, LUT_DATA);
707 	outb(b, LUT_DATA);
708 }
709 
get_dvi_devices(int output_interface)710 static u32 get_dvi_devices(int output_interface)
711 {
712 	switch (output_interface) {
713 	case INTERFACE_DVP0:
714 		return VIA_DVP0 | VIA_LDVP0;
715 
716 	case INTERFACE_DVP1:
717 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
718 			return VIA_LDVP1;
719 		else
720 			return VIA_DVP1;
721 
722 	case INTERFACE_DFP_HIGH:
723 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
724 			return 0;
725 		else
726 			return VIA_LVDS2 | VIA_DVP0;
727 
728 	case INTERFACE_DFP_LOW:
729 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
730 			return 0;
731 		else
732 			return VIA_DVP1 | VIA_LVDS1;
733 
734 	case INTERFACE_TMDS:
735 		return VIA_LVDS1;
736 	}
737 
738 	return 0;
739 }
740 
get_lcd_devices(int output_interface)741 static u32 get_lcd_devices(int output_interface)
742 {
743 	switch (output_interface) {
744 	case INTERFACE_DVP0:
745 		return VIA_DVP0;
746 
747 	case INTERFACE_DVP1:
748 		return VIA_DVP1;
749 
750 	case INTERFACE_DFP_HIGH:
751 		return VIA_LVDS2 | VIA_DVP0;
752 
753 	case INTERFACE_DFP_LOW:
754 		return VIA_LVDS1 | VIA_DVP1;
755 
756 	case INTERFACE_DFP:
757 		return VIA_LVDS1 | VIA_LVDS2;
758 
759 	case INTERFACE_LVDS0:
760 	case INTERFACE_LVDS0LVDS1:
761 		return VIA_LVDS1;
762 
763 	case INTERFACE_LVDS1:
764 		return VIA_LVDS2;
765 	}
766 
767 	return 0;
768 }
769 
770 /*Set IGA path for each device*/
viafb_set_iga_path(void)771 void viafb_set_iga_path(void)
772 {
773 
774 	if (viafb_SAMM_ON == 1) {
775 		if (viafb_CRT_ON) {
776 			if (viafb_primary_dev == CRT_Device)
777 				viaparinfo->crt_setting_info->iga_path = IGA1;
778 			else
779 				viaparinfo->crt_setting_info->iga_path = IGA2;
780 		}
781 
782 		if (viafb_DVI_ON) {
783 			if (viafb_primary_dev == DVI_Device)
784 				viaparinfo->tmds_setting_info->iga_path = IGA1;
785 			else
786 				viaparinfo->tmds_setting_info->iga_path = IGA2;
787 		}
788 
789 		if (viafb_LCD_ON) {
790 			if (viafb_primary_dev == LCD_Device) {
791 				if (viafb_dual_fb &&
792 					(viaparinfo->chip_info->gfx_chip_name ==
793 					UNICHROME_CLE266)) {
794 					viaparinfo->
795 					lvds_setting_info->iga_path = IGA2;
796 					viaparinfo->
797 					crt_setting_info->iga_path = IGA1;
798 					viaparinfo->
799 					tmds_setting_info->iga_path = IGA1;
800 				} else
801 					viaparinfo->
802 					lvds_setting_info->iga_path = IGA1;
803 			} else {
804 				viaparinfo->lvds_setting_info->iga_path = IGA2;
805 			}
806 		}
807 		if (viafb_LCD2_ON) {
808 			if (LCD2_Device == viafb_primary_dev)
809 				viaparinfo->lvds_setting_info2->iga_path = IGA1;
810 			else
811 				viaparinfo->lvds_setting_info2->iga_path = IGA2;
812 		}
813 	} else {
814 		viafb_SAMM_ON = 0;
815 
816 		if (viafb_CRT_ON && viafb_LCD_ON) {
817 			viaparinfo->crt_setting_info->iga_path = IGA1;
818 			viaparinfo->lvds_setting_info->iga_path = IGA2;
819 		} else if (viafb_CRT_ON && viafb_DVI_ON) {
820 			viaparinfo->crt_setting_info->iga_path = IGA1;
821 			viaparinfo->tmds_setting_info->iga_path = IGA2;
822 		} else if (viafb_LCD_ON && viafb_DVI_ON) {
823 			viaparinfo->tmds_setting_info->iga_path = IGA1;
824 			viaparinfo->lvds_setting_info->iga_path = IGA2;
825 		} else if (viafb_LCD_ON && viafb_LCD2_ON) {
826 			viaparinfo->lvds_setting_info->iga_path = IGA2;
827 			viaparinfo->lvds_setting_info2->iga_path = IGA2;
828 		} else if (viafb_CRT_ON) {
829 			viaparinfo->crt_setting_info->iga_path = IGA1;
830 		} else if (viafb_LCD_ON) {
831 			viaparinfo->lvds_setting_info->iga_path = IGA2;
832 		} else if (viafb_DVI_ON) {
833 			viaparinfo->tmds_setting_info->iga_path = IGA1;
834 		}
835 	}
836 
837 	viaparinfo->shared->iga1_devices = 0;
838 	viaparinfo->shared->iga2_devices = 0;
839 	if (viafb_CRT_ON) {
840 		if (viaparinfo->crt_setting_info->iga_path == IGA1)
841 			viaparinfo->shared->iga1_devices |= VIA_CRT;
842 		else
843 			viaparinfo->shared->iga2_devices |= VIA_CRT;
844 	}
845 
846 	if (viafb_DVI_ON) {
847 		if (viaparinfo->tmds_setting_info->iga_path == IGA1)
848 			viaparinfo->shared->iga1_devices |= get_dvi_devices(
849 				viaparinfo->chip_info->
850 				tmds_chip_info.output_interface);
851 		else
852 			viaparinfo->shared->iga2_devices |= get_dvi_devices(
853 				viaparinfo->chip_info->
854 				tmds_chip_info.output_interface);
855 	}
856 
857 	if (viafb_LCD_ON) {
858 		if (viaparinfo->lvds_setting_info->iga_path == IGA1)
859 			viaparinfo->shared->iga1_devices |= get_lcd_devices(
860 				viaparinfo->chip_info->
861 				lvds_chip_info.output_interface);
862 		else
863 			viaparinfo->shared->iga2_devices |= get_lcd_devices(
864 				viaparinfo->chip_info->
865 				lvds_chip_info.output_interface);
866 	}
867 
868 	if (viafb_LCD2_ON) {
869 		if (viaparinfo->lvds_setting_info2->iga_path == IGA1)
870 			viaparinfo->shared->iga1_devices |= get_lcd_devices(
871 				viaparinfo->chip_info->
872 				lvds_chip_info2.output_interface);
873 		else
874 			viaparinfo->shared->iga2_devices |= get_lcd_devices(
875 				viaparinfo->chip_info->
876 				lvds_chip_info2.output_interface);
877 	}
878 }
879 
set_color_register(u8 index,u8 red,u8 green,u8 blue)880 static void set_color_register(u8 index, u8 red, u8 green, u8 blue)
881 {
882 	outb(0xFF, 0x3C6); /* bit mask of palette */
883 	outb(index, 0x3C8);
884 	outb(red, 0x3C9);
885 	outb(green, 0x3C9);
886 	outb(blue, 0x3C9);
887 }
888 
viafb_set_primary_color_register(u8 index,u8 red,u8 green,u8 blue)889 void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue)
890 {
891 	viafb_write_reg_mask(0x1A, VIASR, 0x00, 0x01);
892 	set_color_register(index, red, green, blue);
893 }
894 
viafb_set_secondary_color_register(u8 index,u8 red,u8 green,u8 blue)895 void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue)
896 {
897 	viafb_write_reg_mask(0x1A, VIASR, 0x01, 0x01);
898 	set_color_register(index, red, green, blue);
899 }
900 
set_source_common(u8 index,u8 offset,u8 iga)901 static void set_source_common(u8 index, u8 offset, u8 iga)
902 {
903 	u8 value, mask = 1 << offset;
904 
905 	switch (iga) {
906 	case IGA1:
907 		value = 0x00;
908 		break;
909 	case IGA2:
910 		value = mask;
911 		break;
912 	default:
913 		printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
914 		return;
915 	}
916 
917 	via_write_reg_mask(VIACR, index, value, mask);
918 }
919 
set_crt_source(u8 iga)920 static void set_crt_source(u8 iga)
921 {
922 	u8 value;
923 
924 	switch (iga) {
925 	case IGA1:
926 		value = 0x00;
927 		break;
928 	case IGA2:
929 		value = 0x40;
930 		break;
931 	default:
932 		printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
933 		return;
934 	}
935 
936 	via_write_reg_mask(VIASR, 0x16, value, 0x40);
937 }
938 
set_ldvp0_source(u8 iga)939 static inline void set_ldvp0_source(u8 iga)
940 {
941 	set_source_common(0x6C, 7, iga);
942 }
943 
set_ldvp1_source(u8 iga)944 static inline void set_ldvp1_source(u8 iga)
945 {
946 	set_source_common(0x93, 7, iga);
947 }
948 
set_dvp0_source(u8 iga)949 static inline void set_dvp0_source(u8 iga)
950 {
951 	set_source_common(0x96, 4, iga);
952 }
953 
set_dvp1_source(u8 iga)954 static inline void set_dvp1_source(u8 iga)
955 {
956 	set_source_common(0x9B, 4, iga);
957 }
958 
set_lvds1_source(u8 iga)959 static inline void set_lvds1_source(u8 iga)
960 {
961 	set_source_common(0x99, 4, iga);
962 }
963 
set_lvds2_source(u8 iga)964 static inline void set_lvds2_source(u8 iga)
965 {
966 	set_source_common(0x97, 4, iga);
967 }
968 
via_set_source(u32 devices,u8 iga)969 void via_set_source(u32 devices, u8 iga)
970 {
971 	if (devices & VIA_LDVP0)
972 		set_ldvp0_source(iga);
973 	if (devices & VIA_LDVP1)
974 		set_ldvp1_source(iga);
975 	if (devices & VIA_DVP0)
976 		set_dvp0_source(iga);
977 	if (devices & VIA_CRT)
978 		set_crt_source(iga);
979 	if (devices & VIA_DVP1)
980 		set_dvp1_source(iga);
981 	if (devices & VIA_LVDS1)
982 		set_lvds1_source(iga);
983 	if (devices & VIA_LVDS2)
984 		set_lvds2_source(iga);
985 }
986 
set_crt_state(u8 state)987 static void set_crt_state(u8 state)
988 {
989 	u8 value;
990 
991 	switch (state) {
992 	case VIA_STATE_ON:
993 		value = 0x00;
994 		break;
995 	case VIA_STATE_STANDBY:
996 		value = 0x10;
997 		break;
998 	case VIA_STATE_SUSPEND:
999 		value = 0x20;
1000 		break;
1001 	case VIA_STATE_OFF:
1002 		value = 0x30;
1003 		break;
1004 	default:
1005 		return;
1006 	}
1007 
1008 	via_write_reg_mask(VIACR, 0x36, value, 0x30);
1009 }
1010 
set_dvp0_state(u8 state)1011 static void set_dvp0_state(u8 state)
1012 {
1013 	u8 value;
1014 
1015 	switch (state) {
1016 	case VIA_STATE_ON:
1017 		value = 0xC0;
1018 		break;
1019 	case VIA_STATE_OFF:
1020 		value = 0x00;
1021 		break;
1022 	default:
1023 		return;
1024 	}
1025 
1026 	via_write_reg_mask(VIASR, 0x1E, value, 0xC0);
1027 }
1028 
set_dvp1_state(u8 state)1029 static void set_dvp1_state(u8 state)
1030 {
1031 	u8 value;
1032 
1033 	switch (state) {
1034 	case VIA_STATE_ON:
1035 		value = 0x30;
1036 		break;
1037 	case VIA_STATE_OFF:
1038 		value = 0x00;
1039 		break;
1040 	default:
1041 		return;
1042 	}
1043 
1044 	via_write_reg_mask(VIASR, 0x1E, value, 0x30);
1045 }
1046 
set_lvds1_state(u8 state)1047 static void set_lvds1_state(u8 state)
1048 {
1049 	u8 value;
1050 
1051 	switch (state) {
1052 	case VIA_STATE_ON:
1053 		value = 0x03;
1054 		break;
1055 	case VIA_STATE_OFF:
1056 		value = 0x00;
1057 		break;
1058 	default:
1059 		return;
1060 	}
1061 
1062 	via_write_reg_mask(VIASR, 0x2A, value, 0x03);
1063 }
1064 
set_lvds2_state(u8 state)1065 static void set_lvds2_state(u8 state)
1066 {
1067 	u8 value;
1068 
1069 	switch (state) {
1070 	case VIA_STATE_ON:
1071 		value = 0x0C;
1072 		break;
1073 	case VIA_STATE_OFF:
1074 		value = 0x00;
1075 		break;
1076 	default:
1077 		return;
1078 	}
1079 
1080 	via_write_reg_mask(VIASR, 0x2A, value, 0x0C);
1081 }
1082 
via_set_state(u32 devices,u8 state)1083 void via_set_state(u32 devices, u8 state)
1084 {
1085 	/*
1086 	TODO: Can we enable/disable these devices? How?
1087 	if (devices & VIA_LDVP0)
1088 	if (devices & VIA_LDVP1)
1089 	*/
1090 	if (devices & VIA_DVP0)
1091 		set_dvp0_state(state);
1092 	if (devices & VIA_CRT)
1093 		set_crt_state(state);
1094 	if (devices & VIA_DVP1)
1095 		set_dvp1_state(state);
1096 	if (devices & VIA_LVDS1)
1097 		set_lvds1_state(state);
1098 	if (devices & VIA_LVDS2)
1099 		set_lvds2_state(state);
1100 }
1101 
via_set_sync_polarity(u32 devices,u8 polarity)1102 void via_set_sync_polarity(u32 devices, u8 polarity)
1103 {
1104 	if (polarity & ~(VIA_HSYNC_NEGATIVE | VIA_VSYNC_NEGATIVE)) {
1105 		printk(KERN_WARNING "viafb: Unsupported polarity: %d\n",
1106 			polarity);
1107 		return;
1108 	}
1109 
1110 	if (devices & VIA_CRT)
1111 		via_write_misc_reg_mask(polarity << 6, 0xC0);
1112 	if (devices & VIA_DVP1)
1113 		via_write_reg_mask(VIACR, 0x9B, polarity << 5, 0x60);
1114 	if (devices & VIA_LVDS1)
1115 		via_write_reg_mask(VIACR, 0x99, polarity << 5, 0x60);
1116 	if (devices & VIA_LVDS2)
1117 		via_write_reg_mask(VIACR, 0x97, polarity << 5, 0x60);
1118 }
1119 
via_parse_odev(char * input,char ** end)1120 u32 via_parse_odev(char *input, char **end)
1121 {
1122 	char *ptr = input;
1123 	u32 odev = 0;
1124 	bool next = true;
1125 	int i, len;
1126 
1127 	while (next) {
1128 		next = false;
1129 		for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {
1130 			len = strlen(device_mapping[i].name);
1131 			if (!strncmp(ptr, device_mapping[i].name, len)) {
1132 				odev |= device_mapping[i].device;
1133 				ptr += len;
1134 				if (*ptr == ',') {
1135 					ptr++;
1136 					next = true;
1137 				}
1138 			}
1139 		}
1140 	}
1141 
1142 	*end = ptr;
1143 	return odev;
1144 }
1145 
via_odev_to_seq(struct seq_file * m,u32 odev)1146 void via_odev_to_seq(struct seq_file *m, u32 odev)
1147 {
1148 	int i, count = 0;
1149 
1150 	for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {
1151 		if (odev & device_mapping[i].device) {
1152 			if (count > 0)
1153 				seq_putc(m, ',');
1154 
1155 			seq_puts(m, device_mapping[i].name);
1156 			count++;
1157 		}
1158 	}
1159 
1160 	seq_putc(m, '\n');
1161 }
1162 
load_fix_bit_crtc_reg(void)1163 static void load_fix_bit_crtc_reg(void)
1164 {
1165 	/* always set to 1 */
1166 	viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);
1167 	/* line compare should set all bits = 1 (extend modes) */
1168 	viafb_write_reg(CR18, VIACR, 0xff);
1169 	/* line compare should set all bits = 1 (extend modes) */
1170 	viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4);
1171 	/* line compare should set all bits = 1 (extend modes) */
1172 	viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6);
1173 	/* line compare should set all bits = 1 (extend modes) */
1174 	viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);
1175 	/* line compare should set all bits = 1 (extend modes) */
1176 	viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);
1177 	/*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
1178 	/* extend mode always set to e3h */
1179 	viafb_write_reg(CR17, VIACR, 0xe3);
1180 	/* extend mode always set to 0h */
1181 	viafb_write_reg(CR08, VIACR, 0x00);
1182 	/* extend mode always set to 0h */
1183 	viafb_write_reg(CR14, VIACR, 0x00);
1184 
1185 	/* If K8M800, enable Prefetch Mode. */
1186 	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
1187 		|| (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890))
1188 		viafb_write_reg_mask(CR33, VIACR, 0x08, BIT3);
1189 	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
1190 	    && (viaparinfo->chip_info->gfx_chip_revision == CLE266_REVISION_AX))
1191 		viafb_write_reg_mask(SR1A, VIASR, 0x02, BIT1);
1192 
1193 }
1194 
viafb_load_reg(int timing_value,int viafb_load_reg_num,struct io_register * reg,int io_type)1195 void viafb_load_reg(int timing_value, int viafb_load_reg_num,
1196 	struct io_register *reg,
1197 	      int io_type)
1198 {
1199 	int reg_mask;
1200 	int bit_num = 0;
1201 	int data;
1202 	int i, j;
1203 	int shift_next_reg;
1204 	int start_index, end_index, cr_index;
1205 	u16 get_bit;
1206 
1207 	for (i = 0; i < viafb_load_reg_num; i++) {
1208 		reg_mask = 0;
1209 		data = 0;
1210 		start_index = reg[i].start_bit;
1211 		end_index = reg[i].end_bit;
1212 		cr_index = reg[i].io_addr;
1213 
1214 		shift_next_reg = bit_num;
1215 		for (j = start_index; j <= end_index; j++) {
1216 			/*if (bit_num==8) timing_value = timing_value >>8; */
1217 			reg_mask = reg_mask | (BIT0 << j);
1218 			get_bit = (timing_value & (BIT0 << bit_num));
1219 			data =
1220 			    data | ((get_bit >> shift_next_reg) << start_index);
1221 			bit_num++;
1222 		}
1223 		if (io_type == VIACR)
1224 			viafb_write_reg_mask(cr_index, VIACR, data, reg_mask);
1225 		else
1226 			viafb_write_reg_mask(cr_index, VIASR, data, reg_mask);
1227 	}
1228 
1229 }
1230 
1231 /* Write Registers */
viafb_write_regx(struct io_reg RegTable[],int ItemNum)1232 void viafb_write_regx(struct io_reg RegTable[], int ItemNum)
1233 {
1234 	int i;
1235 
1236 	/*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */
1237 
1238 	for (i = 0; i < ItemNum; i++)
1239 		via_write_reg_mask(RegTable[i].port, RegTable[i].index,
1240 			RegTable[i].value, RegTable[i].mask);
1241 }
1242 
viafb_load_fetch_count_reg(int h_addr,int bpp_byte,int set_iga)1243 void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
1244 {
1245 	int reg_value;
1246 	int viafb_load_reg_num;
1247 	struct io_register *reg = NULL;
1248 
1249 	switch (set_iga) {
1250 	case IGA1:
1251 		reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
1252 		viafb_load_reg_num = fetch_count_reg.
1253 			iga1_fetch_count_reg.reg_num;
1254 		reg = fetch_count_reg.iga1_fetch_count_reg.reg;
1255 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1256 		break;
1257 	case IGA2:
1258 		reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
1259 		viafb_load_reg_num = fetch_count_reg.
1260 			iga2_fetch_count_reg.reg_num;
1261 		reg = fetch_count_reg.iga2_fetch_count_reg.reg;
1262 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1263 		break;
1264 	}
1265 
1266 }
1267 
viafb_load_FIFO_reg(int set_iga,int hor_active,int ver_active)1268 void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
1269 {
1270 	int reg_value;
1271 	int viafb_load_reg_num;
1272 	struct io_register *reg = NULL;
1273 	int iga1_fifo_max_depth = 0, iga1_fifo_threshold =
1274 	    0, iga1_fifo_high_threshold = 0, iga1_display_queue_expire_num = 0;
1275 	int iga2_fifo_max_depth = 0, iga2_fifo_threshold =
1276 	    0, iga2_fifo_high_threshold = 0, iga2_display_queue_expire_num = 0;
1277 
1278 	if (set_iga == IGA1) {
1279 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1280 			iga1_fifo_max_depth = K800_IGA1_FIFO_MAX_DEPTH;
1281 			iga1_fifo_threshold = K800_IGA1_FIFO_THRESHOLD;
1282 			iga1_fifo_high_threshold =
1283 			    K800_IGA1_FIFO_HIGH_THRESHOLD;
1284 			/* If resolution > 1280x1024, expire length = 64, else
1285 			   expire length = 128 */
1286 			if ((hor_active > 1280) && (ver_active > 1024))
1287 				iga1_display_queue_expire_num = 16;
1288 			else
1289 				iga1_display_queue_expire_num =
1290 				    K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1291 
1292 		}
1293 
1294 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
1295 			iga1_fifo_max_depth = P880_IGA1_FIFO_MAX_DEPTH;
1296 			iga1_fifo_threshold = P880_IGA1_FIFO_THRESHOLD;
1297 			iga1_fifo_high_threshold =
1298 			    P880_IGA1_FIFO_HIGH_THRESHOLD;
1299 			iga1_display_queue_expire_num =
1300 			    P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1301 
1302 			/* If resolution > 1280x1024, expire length = 64, else
1303 			   expire length = 128 */
1304 			if ((hor_active > 1280) && (ver_active > 1024))
1305 				iga1_display_queue_expire_num = 16;
1306 			else
1307 				iga1_display_queue_expire_num =
1308 				    P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1309 		}
1310 
1311 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
1312 			iga1_fifo_max_depth = CN700_IGA1_FIFO_MAX_DEPTH;
1313 			iga1_fifo_threshold = CN700_IGA1_FIFO_THRESHOLD;
1314 			iga1_fifo_high_threshold =
1315 			    CN700_IGA1_FIFO_HIGH_THRESHOLD;
1316 
1317 			/* If resolution > 1280x1024, expire length = 64,
1318 			   else expire length = 128 */
1319 			if ((hor_active > 1280) && (ver_active > 1024))
1320 				iga1_display_queue_expire_num = 16;
1321 			else
1322 				iga1_display_queue_expire_num =
1323 				    CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1324 		}
1325 
1326 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1327 			iga1_fifo_max_depth = CX700_IGA1_FIFO_MAX_DEPTH;
1328 			iga1_fifo_threshold = CX700_IGA1_FIFO_THRESHOLD;
1329 			iga1_fifo_high_threshold =
1330 			    CX700_IGA1_FIFO_HIGH_THRESHOLD;
1331 			iga1_display_queue_expire_num =
1332 			    CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1333 		}
1334 
1335 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
1336 			iga1_fifo_max_depth = K8M890_IGA1_FIFO_MAX_DEPTH;
1337 			iga1_fifo_threshold = K8M890_IGA1_FIFO_THRESHOLD;
1338 			iga1_fifo_high_threshold =
1339 			    K8M890_IGA1_FIFO_HIGH_THRESHOLD;
1340 			iga1_display_queue_expire_num =
1341 			    K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1342 		}
1343 
1344 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
1345 			iga1_fifo_max_depth = P4M890_IGA1_FIFO_MAX_DEPTH;
1346 			iga1_fifo_threshold = P4M890_IGA1_FIFO_THRESHOLD;
1347 			iga1_fifo_high_threshold =
1348 			    P4M890_IGA1_FIFO_HIGH_THRESHOLD;
1349 			iga1_display_queue_expire_num =
1350 			    P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1351 		}
1352 
1353 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
1354 			iga1_fifo_max_depth = P4M900_IGA1_FIFO_MAX_DEPTH;
1355 			iga1_fifo_threshold = P4M900_IGA1_FIFO_THRESHOLD;
1356 			iga1_fifo_high_threshold =
1357 			    P4M900_IGA1_FIFO_HIGH_THRESHOLD;
1358 			iga1_display_queue_expire_num =
1359 			    P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1360 		}
1361 
1362 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
1363 			iga1_fifo_max_depth = VX800_IGA1_FIFO_MAX_DEPTH;
1364 			iga1_fifo_threshold = VX800_IGA1_FIFO_THRESHOLD;
1365 			iga1_fifo_high_threshold =
1366 			    VX800_IGA1_FIFO_HIGH_THRESHOLD;
1367 			iga1_display_queue_expire_num =
1368 			    VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1369 		}
1370 
1371 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
1372 			iga1_fifo_max_depth = VX855_IGA1_FIFO_MAX_DEPTH;
1373 			iga1_fifo_threshold = VX855_IGA1_FIFO_THRESHOLD;
1374 			iga1_fifo_high_threshold =
1375 			    VX855_IGA1_FIFO_HIGH_THRESHOLD;
1376 			iga1_display_queue_expire_num =
1377 			    VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1378 		}
1379 
1380 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {
1381 			iga1_fifo_max_depth = VX900_IGA1_FIFO_MAX_DEPTH;
1382 			iga1_fifo_threshold = VX900_IGA1_FIFO_THRESHOLD;
1383 			iga1_fifo_high_threshold =
1384 			    VX900_IGA1_FIFO_HIGH_THRESHOLD;
1385 			iga1_display_queue_expire_num =
1386 			    VX900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1387 		}
1388 
1389 		/* Set Display FIFO Depath Select */
1390 		reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);
1391 		viafb_load_reg_num =
1392 		    display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg_num;
1393 		reg = display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg;
1394 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1395 
1396 		/* Set Display FIFO Threshold Select */
1397 		reg_value = IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold);
1398 		viafb_load_reg_num =
1399 		    fifo_threshold_select_reg.
1400 		    iga1_fifo_threshold_select_reg.reg_num;
1401 		reg =
1402 		    fifo_threshold_select_reg.
1403 		    iga1_fifo_threshold_select_reg.reg;
1404 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1405 
1406 		/* Set FIFO High Threshold Select */
1407 		reg_value =
1408 		    IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold);
1409 		viafb_load_reg_num =
1410 		    fifo_high_threshold_select_reg.
1411 		    iga1_fifo_high_threshold_select_reg.reg_num;
1412 		reg =
1413 		    fifo_high_threshold_select_reg.
1414 		    iga1_fifo_high_threshold_select_reg.reg;
1415 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1416 
1417 		/* Set Display Queue Expire Num */
1418 		reg_value =
1419 		    IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1420 		    (iga1_display_queue_expire_num);
1421 		viafb_load_reg_num =
1422 		    display_queue_expire_num_reg.
1423 		    iga1_display_queue_expire_num_reg.reg_num;
1424 		reg =
1425 		    display_queue_expire_num_reg.
1426 		    iga1_display_queue_expire_num_reg.reg;
1427 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1428 
1429 	} else {
1430 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1431 			iga2_fifo_max_depth = K800_IGA2_FIFO_MAX_DEPTH;
1432 			iga2_fifo_threshold = K800_IGA2_FIFO_THRESHOLD;
1433 			iga2_fifo_high_threshold =
1434 			    K800_IGA2_FIFO_HIGH_THRESHOLD;
1435 
1436 			/* If resolution > 1280x1024, expire length = 64,
1437 			   else  expire length = 128 */
1438 			if ((hor_active > 1280) && (ver_active > 1024))
1439 				iga2_display_queue_expire_num = 16;
1440 			else
1441 				iga2_display_queue_expire_num =
1442 				    K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1443 		}
1444 
1445 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
1446 			iga2_fifo_max_depth = P880_IGA2_FIFO_MAX_DEPTH;
1447 			iga2_fifo_threshold = P880_IGA2_FIFO_THRESHOLD;
1448 			iga2_fifo_high_threshold =
1449 			    P880_IGA2_FIFO_HIGH_THRESHOLD;
1450 
1451 			/* If resolution > 1280x1024, expire length = 64,
1452 			   else  expire length = 128 */
1453 			if ((hor_active > 1280) && (ver_active > 1024))
1454 				iga2_display_queue_expire_num = 16;
1455 			else
1456 				iga2_display_queue_expire_num =
1457 				    P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1458 		}
1459 
1460 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
1461 			iga2_fifo_max_depth = CN700_IGA2_FIFO_MAX_DEPTH;
1462 			iga2_fifo_threshold = CN700_IGA2_FIFO_THRESHOLD;
1463 			iga2_fifo_high_threshold =
1464 			    CN700_IGA2_FIFO_HIGH_THRESHOLD;
1465 
1466 			/* If resolution > 1280x1024, expire length = 64,
1467 			   else expire length = 128 */
1468 			if ((hor_active > 1280) && (ver_active > 1024))
1469 				iga2_display_queue_expire_num = 16;
1470 			else
1471 				iga2_display_queue_expire_num =
1472 				    CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1473 		}
1474 
1475 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1476 			iga2_fifo_max_depth = CX700_IGA2_FIFO_MAX_DEPTH;
1477 			iga2_fifo_threshold = CX700_IGA2_FIFO_THRESHOLD;
1478 			iga2_fifo_high_threshold =
1479 			    CX700_IGA2_FIFO_HIGH_THRESHOLD;
1480 			iga2_display_queue_expire_num =
1481 			    CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1482 		}
1483 
1484 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
1485 			iga2_fifo_max_depth = K8M890_IGA2_FIFO_MAX_DEPTH;
1486 			iga2_fifo_threshold = K8M890_IGA2_FIFO_THRESHOLD;
1487 			iga2_fifo_high_threshold =
1488 			    K8M890_IGA2_FIFO_HIGH_THRESHOLD;
1489 			iga2_display_queue_expire_num =
1490 			    K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1491 		}
1492 
1493 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
1494 			iga2_fifo_max_depth = P4M890_IGA2_FIFO_MAX_DEPTH;
1495 			iga2_fifo_threshold = P4M890_IGA2_FIFO_THRESHOLD;
1496 			iga2_fifo_high_threshold =
1497 			    P4M890_IGA2_FIFO_HIGH_THRESHOLD;
1498 			iga2_display_queue_expire_num =
1499 			    P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1500 		}
1501 
1502 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
1503 			iga2_fifo_max_depth = P4M900_IGA2_FIFO_MAX_DEPTH;
1504 			iga2_fifo_threshold = P4M900_IGA2_FIFO_THRESHOLD;
1505 			iga2_fifo_high_threshold =
1506 			    P4M900_IGA2_FIFO_HIGH_THRESHOLD;
1507 			iga2_display_queue_expire_num =
1508 			    P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1509 		}
1510 
1511 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
1512 			iga2_fifo_max_depth = VX800_IGA2_FIFO_MAX_DEPTH;
1513 			iga2_fifo_threshold = VX800_IGA2_FIFO_THRESHOLD;
1514 			iga2_fifo_high_threshold =
1515 			    VX800_IGA2_FIFO_HIGH_THRESHOLD;
1516 			iga2_display_queue_expire_num =
1517 			    VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1518 		}
1519 
1520 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
1521 			iga2_fifo_max_depth = VX855_IGA2_FIFO_MAX_DEPTH;
1522 			iga2_fifo_threshold = VX855_IGA2_FIFO_THRESHOLD;
1523 			iga2_fifo_high_threshold =
1524 			    VX855_IGA2_FIFO_HIGH_THRESHOLD;
1525 			iga2_display_queue_expire_num =
1526 			    VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1527 		}
1528 
1529 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {
1530 			iga2_fifo_max_depth = VX900_IGA2_FIFO_MAX_DEPTH;
1531 			iga2_fifo_threshold = VX900_IGA2_FIFO_THRESHOLD;
1532 			iga2_fifo_high_threshold =
1533 			    VX900_IGA2_FIFO_HIGH_THRESHOLD;
1534 			iga2_display_queue_expire_num =
1535 			    VX900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1536 		}
1537 
1538 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1539 			/* Set Display FIFO Depath Select */
1540 			reg_value =
1541 			    IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth)
1542 			    - 1;
1543 			/* Patch LCD in IGA2 case */
1544 			viafb_load_reg_num =
1545 			    display_fifo_depth_reg.
1546 			    iga2_fifo_depth_select_reg.reg_num;
1547 			reg =
1548 			    display_fifo_depth_reg.
1549 			    iga2_fifo_depth_select_reg.reg;
1550 			viafb_load_reg(reg_value,
1551 				viafb_load_reg_num, reg, VIACR);
1552 		} else {
1553 
1554 			/* Set Display FIFO Depath Select */
1555 			reg_value =
1556 			    IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth);
1557 			viafb_load_reg_num =
1558 			    display_fifo_depth_reg.
1559 			    iga2_fifo_depth_select_reg.reg_num;
1560 			reg =
1561 			    display_fifo_depth_reg.
1562 			    iga2_fifo_depth_select_reg.reg;
1563 			viafb_load_reg(reg_value,
1564 				viafb_load_reg_num, reg, VIACR);
1565 		}
1566 
1567 		/* Set Display FIFO Threshold Select */
1568 		reg_value = IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold);
1569 		viafb_load_reg_num =
1570 		    fifo_threshold_select_reg.
1571 		    iga2_fifo_threshold_select_reg.reg_num;
1572 		reg =
1573 		    fifo_threshold_select_reg.
1574 		    iga2_fifo_threshold_select_reg.reg;
1575 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1576 
1577 		/* Set FIFO High Threshold Select */
1578 		reg_value =
1579 		    IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold);
1580 		viafb_load_reg_num =
1581 		    fifo_high_threshold_select_reg.
1582 		    iga2_fifo_high_threshold_select_reg.reg_num;
1583 		reg =
1584 		    fifo_high_threshold_select_reg.
1585 		    iga2_fifo_high_threshold_select_reg.reg;
1586 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1587 
1588 		/* Set Display Queue Expire Num */
1589 		reg_value =
1590 		    IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1591 		    (iga2_display_queue_expire_num);
1592 		viafb_load_reg_num =
1593 		    display_queue_expire_num_reg.
1594 		    iga2_display_queue_expire_num_reg.reg_num;
1595 		reg =
1596 		    display_queue_expire_num_reg.
1597 		    iga2_display_queue_expire_num_reg.reg;
1598 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1599 
1600 	}
1601 
1602 }
1603 
cle266_encode_pll(struct pll_config pll)1604 static u32 cle266_encode_pll(struct pll_config pll)
1605 {
1606 	return (pll.multiplier << 8)
1607 		| (pll.rshift << 6)
1608 		| pll.divisor;
1609 }
1610 
k800_encode_pll(struct pll_config pll)1611 static u32 k800_encode_pll(struct pll_config pll)
1612 {
1613 	return ((pll.divisor - 2) << 16)
1614 		| (pll.rshift << 10)
1615 		| (pll.multiplier - 2);
1616 }
1617 
vx855_encode_pll(struct pll_config pll)1618 static u32 vx855_encode_pll(struct pll_config pll)
1619 {
1620 	return (pll.divisor << 16)
1621 		| (pll.rshift << 10)
1622 		| pll.multiplier;
1623 }
1624 
get_pll_internal_frequency(u32 ref_freq,struct pll_config pll)1625 static inline u32 get_pll_internal_frequency(u32 ref_freq,
1626 	struct pll_config pll)
1627 {
1628 	return ref_freq / pll.divisor * pll.multiplier;
1629 }
1630 
get_pll_output_frequency(u32 ref_freq,struct pll_config pll)1631 static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll)
1632 {
1633 	return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift;
1634 }
1635 
get_pll_config(struct pll_config * config,int size,int clk)1636 static struct pll_config get_pll_config(struct pll_config *config, int size,
1637 	int clk)
1638 {
1639 	struct pll_config best = config[0];
1640 	const u32 f0 = 14318180; /* X1 frequency */
1641 	int i;
1642 
1643 	for (i = 1; i < size; i++) {
1644 		if (abs(get_pll_output_frequency(f0, config[i]) - clk)
1645 			< abs(get_pll_output_frequency(f0, best) - clk))
1646 			best = config[i];
1647 	}
1648 
1649 	return best;
1650 }
1651 
viafb_get_clk_value(int clk)1652 u32 viafb_get_clk_value(int clk)
1653 {
1654 	u32 value = 0;
1655 
1656 	switch (viaparinfo->chip_info->gfx_chip_name) {
1657 	case UNICHROME_CLE266:
1658 	case UNICHROME_K400:
1659 		value = cle266_encode_pll(get_pll_config(cle266_pll_config,
1660 			ARRAY_SIZE(cle266_pll_config), clk));
1661 		break;
1662 	case UNICHROME_K800:
1663 	case UNICHROME_PM800:
1664 	case UNICHROME_CN700:
1665 		value = k800_encode_pll(get_pll_config(k800_pll_config,
1666 			ARRAY_SIZE(k800_pll_config), clk));
1667 		break;
1668 	case UNICHROME_CX700:
1669 	case UNICHROME_CN750:
1670 	case UNICHROME_K8M890:
1671 	case UNICHROME_P4M890:
1672 	case UNICHROME_P4M900:
1673 	case UNICHROME_VX800:
1674 		value = k800_encode_pll(get_pll_config(cx700_pll_config,
1675 			ARRAY_SIZE(cx700_pll_config), clk));
1676 		break;
1677 	case UNICHROME_VX855:
1678 	case UNICHROME_VX900:
1679 		value = vx855_encode_pll(get_pll_config(vx855_pll_config,
1680 			ARRAY_SIZE(vx855_pll_config), clk));
1681 		break;
1682 	}
1683 
1684 	return value;
1685 }
1686 
1687 /* Set VCLK*/
viafb_set_vclock(u32 clk,int set_iga)1688 void viafb_set_vclock(u32 clk, int set_iga)
1689 {
1690 	/* H.W. Reset : ON */
1691 	viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
1692 
1693 	if (set_iga == IGA1) {
1694 		/* Change D,N FOR VCLK */
1695 		switch (viaparinfo->chip_info->gfx_chip_name) {
1696 		case UNICHROME_CLE266:
1697 		case UNICHROME_K400:
1698 			via_write_reg(VIASR, SR46, (clk & 0x00FF));
1699 			via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8);
1700 			break;
1701 
1702 		case UNICHROME_K800:
1703 		case UNICHROME_PM800:
1704 		case UNICHROME_CN700:
1705 		case UNICHROME_CX700:
1706 		case UNICHROME_CN750:
1707 		case UNICHROME_K8M890:
1708 		case UNICHROME_P4M890:
1709 		case UNICHROME_P4M900:
1710 		case UNICHROME_VX800:
1711 		case UNICHROME_VX855:
1712 		case UNICHROME_VX900:
1713 			via_write_reg(VIASR, SR44, (clk & 0x0000FF));
1714 			via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8);
1715 			via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16);
1716 			break;
1717 		}
1718 	}
1719 
1720 	if (set_iga == IGA2) {
1721 		/* Change D,N FOR LCK */
1722 		switch (viaparinfo->chip_info->gfx_chip_name) {
1723 		case UNICHROME_CLE266:
1724 		case UNICHROME_K400:
1725 			via_write_reg(VIASR, SR44, (clk & 0x00FF));
1726 			via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8);
1727 			break;
1728 
1729 		case UNICHROME_K800:
1730 		case UNICHROME_PM800:
1731 		case UNICHROME_CN700:
1732 		case UNICHROME_CX700:
1733 		case UNICHROME_CN750:
1734 		case UNICHROME_K8M890:
1735 		case UNICHROME_P4M890:
1736 		case UNICHROME_P4M900:
1737 		case UNICHROME_VX800:
1738 		case UNICHROME_VX855:
1739 		case UNICHROME_VX900:
1740 			via_write_reg(VIASR, SR4A, (clk & 0x0000FF));
1741 			via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8);
1742 			via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16);
1743 			break;
1744 		}
1745 	}
1746 
1747 	/* H.W. Reset : OFF */
1748 	viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
1749 
1750 	/* Reset PLL */
1751 	if (set_iga == IGA1) {
1752 		viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
1753 		viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
1754 	}
1755 
1756 	if (set_iga == IGA2) {
1757 		viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2);
1758 		viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2);
1759 	}
1760 
1761 	/* Fire! */
1762 	via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
1763 }
1764 
viafb_load_crtc_timing(struct display_timing device_timing,int set_iga)1765 void viafb_load_crtc_timing(struct display_timing device_timing,
1766 	int set_iga)
1767 {
1768 	int i;
1769 	int viafb_load_reg_num = 0;
1770 	int reg_value = 0;
1771 	struct io_register *reg = NULL;
1772 
1773 	viafb_unlock_crt();
1774 
1775 	for (i = 0; i < 12; i++) {
1776 		if (set_iga == IGA1) {
1777 			switch (i) {
1778 			case H_TOTAL_INDEX:
1779 				reg_value =
1780 				    IGA1_HOR_TOTAL_FORMULA(device_timing.
1781 							   hor_total);
1782 				viafb_load_reg_num =
1783 					iga1_crtc_reg.hor_total.reg_num;
1784 				reg = iga1_crtc_reg.hor_total.reg;
1785 				break;
1786 			case H_ADDR_INDEX:
1787 				reg_value =
1788 				    IGA1_HOR_ADDR_FORMULA(device_timing.
1789 							  hor_addr);
1790 				viafb_load_reg_num =
1791 					iga1_crtc_reg.hor_addr.reg_num;
1792 				reg = iga1_crtc_reg.hor_addr.reg;
1793 				break;
1794 			case H_BLANK_START_INDEX:
1795 				reg_value =
1796 				    IGA1_HOR_BLANK_START_FORMULA
1797 				    (device_timing.hor_blank_start);
1798 				viafb_load_reg_num =
1799 				    iga1_crtc_reg.hor_blank_start.reg_num;
1800 				reg = iga1_crtc_reg.hor_blank_start.reg;
1801 				break;
1802 			case H_BLANK_END_INDEX:
1803 				reg_value =
1804 				    IGA1_HOR_BLANK_END_FORMULA
1805 				    (device_timing.hor_blank_start,
1806 				     device_timing.hor_blank_end);
1807 				viafb_load_reg_num =
1808 				    iga1_crtc_reg.hor_blank_end.reg_num;
1809 				reg = iga1_crtc_reg.hor_blank_end.reg;
1810 				break;
1811 			case H_SYNC_START_INDEX:
1812 				reg_value =
1813 				    IGA1_HOR_SYNC_START_FORMULA
1814 				    (device_timing.hor_sync_start);
1815 				viafb_load_reg_num =
1816 				    iga1_crtc_reg.hor_sync_start.reg_num;
1817 				reg = iga1_crtc_reg.hor_sync_start.reg;
1818 				break;
1819 			case H_SYNC_END_INDEX:
1820 				reg_value =
1821 				    IGA1_HOR_SYNC_END_FORMULA
1822 				    (device_timing.hor_sync_start,
1823 				     device_timing.hor_sync_end);
1824 				viafb_load_reg_num =
1825 				    iga1_crtc_reg.hor_sync_end.reg_num;
1826 				reg = iga1_crtc_reg.hor_sync_end.reg;
1827 				break;
1828 			case V_TOTAL_INDEX:
1829 				reg_value =
1830 				    IGA1_VER_TOTAL_FORMULA(device_timing.
1831 							   ver_total);
1832 				viafb_load_reg_num =
1833 					iga1_crtc_reg.ver_total.reg_num;
1834 				reg = iga1_crtc_reg.ver_total.reg;
1835 				break;
1836 			case V_ADDR_INDEX:
1837 				reg_value =
1838 				    IGA1_VER_ADDR_FORMULA(device_timing.
1839 							  ver_addr);
1840 				viafb_load_reg_num =
1841 					iga1_crtc_reg.ver_addr.reg_num;
1842 				reg = iga1_crtc_reg.ver_addr.reg;
1843 				break;
1844 			case V_BLANK_START_INDEX:
1845 				reg_value =
1846 				    IGA1_VER_BLANK_START_FORMULA
1847 				    (device_timing.ver_blank_start);
1848 				viafb_load_reg_num =
1849 				    iga1_crtc_reg.ver_blank_start.reg_num;
1850 				reg = iga1_crtc_reg.ver_blank_start.reg;
1851 				break;
1852 			case V_BLANK_END_INDEX:
1853 				reg_value =
1854 				    IGA1_VER_BLANK_END_FORMULA
1855 				    (device_timing.ver_blank_start,
1856 				     device_timing.ver_blank_end);
1857 				viafb_load_reg_num =
1858 				    iga1_crtc_reg.ver_blank_end.reg_num;
1859 				reg = iga1_crtc_reg.ver_blank_end.reg;
1860 				break;
1861 			case V_SYNC_START_INDEX:
1862 				reg_value =
1863 				    IGA1_VER_SYNC_START_FORMULA
1864 				    (device_timing.ver_sync_start);
1865 				viafb_load_reg_num =
1866 				    iga1_crtc_reg.ver_sync_start.reg_num;
1867 				reg = iga1_crtc_reg.ver_sync_start.reg;
1868 				break;
1869 			case V_SYNC_END_INDEX:
1870 				reg_value =
1871 				    IGA1_VER_SYNC_END_FORMULA
1872 				    (device_timing.ver_sync_start,
1873 				     device_timing.ver_sync_end);
1874 				viafb_load_reg_num =
1875 				    iga1_crtc_reg.ver_sync_end.reg_num;
1876 				reg = iga1_crtc_reg.ver_sync_end.reg;
1877 				break;
1878 
1879 			}
1880 		}
1881 
1882 		if (set_iga == IGA2) {
1883 			switch (i) {
1884 			case H_TOTAL_INDEX:
1885 				reg_value =
1886 				    IGA2_HOR_TOTAL_FORMULA(device_timing.
1887 							   hor_total);
1888 				viafb_load_reg_num =
1889 					iga2_crtc_reg.hor_total.reg_num;
1890 				reg = iga2_crtc_reg.hor_total.reg;
1891 				break;
1892 			case H_ADDR_INDEX:
1893 				reg_value =
1894 				    IGA2_HOR_ADDR_FORMULA(device_timing.
1895 							  hor_addr);
1896 				viafb_load_reg_num =
1897 					iga2_crtc_reg.hor_addr.reg_num;
1898 				reg = iga2_crtc_reg.hor_addr.reg;
1899 				break;
1900 			case H_BLANK_START_INDEX:
1901 				reg_value =
1902 				    IGA2_HOR_BLANK_START_FORMULA
1903 				    (device_timing.hor_blank_start);
1904 				viafb_load_reg_num =
1905 				    iga2_crtc_reg.hor_blank_start.reg_num;
1906 				reg = iga2_crtc_reg.hor_blank_start.reg;
1907 				break;
1908 			case H_BLANK_END_INDEX:
1909 				reg_value =
1910 				    IGA2_HOR_BLANK_END_FORMULA
1911 				    (device_timing.hor_blank_start,
1912 				     device_timing.hor_blank_end);
1913 				viafb_load_reg_num =
1914 				    iga2_crtc_reg.hor_blank_end.reg_num;
1915 				reg = iga2_crtc_reg.hor_blank_end.reg;
1916 				break;
1917 			case H_SYNC_START_INDEX:
1918 				reg_value =
1919 				    IGA2_HOR_SYNC_START_FORMULA
1920 				    (device_timing.hor_sync_start);
1921 				if (UNICHROME_CN700 <=
1922 					viaparinfo->chip_info->gfx_chip_name)
1923 					viafb_load_reg_num =
1924 					    iga2_crtc_reg.hor_sync_start.
1925 					    reg_num;
1926 				else
1927 					viafb_load_reg_num = 3;
1928 				reg = iga2_crtc_reg.hor_sync_start.reg;
1929 				break;
1930 			case H_SYNC_END_INDEX:
1931 				reg_value =
1932 				    IGA2_HOR_SYNC_END_FORMULA
1933 				    (device_timing.hor_sync_start,
1934 				     device_timing.hor_sync_end);
1935 				viafb_load_reg_num =
1936 				    iga2_crtc_reg.hor_sync_end.reg_num;
1937 				reg = iga2_crtc_reg.hor_sync_end.reg;
1938 				break;
1939 			case V_TOTAL_INDEX:
1940 				reg_value =
1941 				    IGA2_VER_TOTAL_FORMULA(device_timing.
1942 							   ver_total);
1943 				viafb_load_reg_num =
1944 					iga2_crtc_reg.ver_total.reg_num;
1945 				reg = iga2_crtc_reg.ver_total.reg;
1946 				break;
1947 			case V_ADDR_INDEX:
1948 				reg_value =
1949 				    IGA2_VER_ADDR_FORMULA(device_timing.
1950 							  ver_addr);
1951 				viafb_load_reg_num =
1952 					iga2_crtc_reg.ver_addr.reg_num;
1953 				reg = iga2_crtc_reg.ver_addr.reg;
1954 				break;
1955 			case V_BLANK_START_INDEX:
1956 				reg_value =
1957 				    IGA2_VER_BLANK_START_FORMULA
1958 				    (device_timing.ver_blank_start);
1959 				viafb_load_reg_num =
1960 				    iga2_crtc_reg.ver_blank_start.reg_num;
1961 				reg = iga2_crtc_reg.ver_blank_start.reg;
1962 				break;
1963 			case V_BLANK_END_INDEX:
1964 				reg_value =
1965 				    IGA2_VER_BLANK_END_FORMULA
1966 				    (device_timing.ver_blank_start,
1967 				     device_timing.ver_blank_end);
1968 				viafb_load_reg_num =
1969 				    iga2_crtc_reg.ver_blank_end.reg_num;
1970 				reg = iga2_crtc_reg.ver_blank_end.reg;
1971 				break;
1972 			case V_SYNC_START_INDEX:
1973 				reg_value =
1974 				    IGA2_VER_SYNC_START_FORMULA
1975 				    (device_timing.ver_sync_start);
1976 				viafb_load_reg_num =
1977 				    iga2_crtc_reg.ver_sync_start.reg_num;
1978 				reg = iga2_crtc_reg.ver_sync_start.reg;
1979 				break;
1980 			case V_SYNC_END_INDEX:
1981 				reg_value =
1982 				    IGA2_VER_SYNC_END_FORMULA
1983 				    (device_timing.ver_sync_start,
1984 				     device_timing.ver_sync_end);
1985 				viafb_load_reg_num =
1986 				    iga2_crtc_reg.ver_sync_end.reg_num;
1987 				reg = iga2_crtc_reg.ver_sync_end.reg;
1988 				break;
1989 
1990 			}
1991 		}
1992 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1993 	}
1994 
1995 	viafb_lock_crt();
1996 }
1997 
viafb_fill_crtc_timing(struct crt_mode_table * crt_table,struct VideoModeTable * video_mode,int bpp_byte,int set_iga)1998 void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
1999 	struct VideoModeTable *video_mode, int bpp_byte, int set_iga)
2000 {
2001 	struct display_timing crt_reg;
2002 	int i;
2003 	int index = 0;
2004 	int h_addr, v_addr;
2005 	u32 pll_D_N, clock, refresh = viafb_refresh;
2006 
2007 	if (viafb_SAMM_ON && set_iga == IGA2)
2008 		refresh = viafb_refresh1;
2009 
2010 	for (i = 0; i < video_mode->mode_array; i++) {
2011 		index = i;
2012 
2013 		if (crt_table[i].refresh_rate == refresh)
2014 			break;
2015 	}
2016 
2017 	crt_reg = crt_table[index].crtc;
2018 
2019 	/* Mode 640x480 has border, but LCD/DFP didn't have border. */
2020 	/* So we would delete border. */
2021 	if ((viafb_LCD_ON | viafb_DVI_ON)
2022 	    && video_mode->crtc[0].crtc.hor_addr == 640
2023 	    && video_mode->crtc[0].crtc.ver_addr == 480
2024 	    && refresh == 60) {
2025 		/* The border is 8 pixels. */
2026 		crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8;
2027 
2028 		/* Blanking time should add left and right borders. */
2029 		crt_reg.hor_blank_end = crt_reg.hor_blank_end + 16;
2030 	}
2031 
2032 	h_addr = crt_reg.hor_addr;
2033 	v_addr = crt_reg.ver_addr;
2034 	if (set_iga == IGA1) {
2035 		viafb_unlock_crt();
2036 		viafb_write_reg(CR09, VIACR, 0x00);	/*initial CR09=0 */
2037 		viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6);
2038 		viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
2039 	}
2040 
2041 	switch (set_iga) {
2042 	case IGA1:
2043 		viafb_load_crtc_timing(crt_reg, IGA1);
2044 		break;
2045 	case IGA2:
2046 		viafb_load_crtc_timing(crt_reg, IGA2);
2047 		break;
2048 	}
2049 
2050 	load_fix_bit_crtc_reg();
2051 	viafb_lock_crt();
2052 	viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
2053 	viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga);
2054 
2055 	/* load FIFO */
2056 	if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
2057 	    && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
2058 		viafb_load_FIFO_reg(set_iga, h_addr, v_addr);
2059 
2060 	clock = crt_reg.hor_total * crt_reg.ver_total
2061 		* crt_table[index].refresh_rate;
2062 	pll_D_N = viafb_get_clk_value(clock);
2063 	DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N);
2064 	viafb_set_vclock(pll_D_N, set_iga);
2065 
2066 }
2067 
viafb_init_chip_info(int chip_type)2068 void __devinit viafb_init_chip_info(int chip_type)
2069 {
2070 	init_gfx_chip_info(chip_type);
2071 	init_tmds_chip_info();
2072 	init_lvds_chip_info();
2073 
2074 	viaparinfo->crt_setting_info->iga_path = IGA1;
2075 
2076 	/*Set IGA path for each device */
2077 	viafb_set_iga_path();
2078 
2079 	viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method;
2080 	viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode;
2081 	viaparinfo->lvds_setting_info2->display_method =
2082 		viaparinfo->lvds_setting_info->display_method;
2083 	viaparinfo->lvds_setting_info2->lcd_mode =
2084 		viaparinfo->lvds_setting_info->lcd_mode;
2085 }
2086 
viafb_update_device_setting(int hres,int vres,int bpp,int flag)2087 void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
2088 {
2089 	if (flag == 0) {
2090 		viaparinfo->tmds_setting_info->h_active = hres;
2091 		viaparinfo->tmds_setting_info->v_active = vres;
2092 
2093 		viaparinfo->lvds_setting_info->h_active = hres;
2094 		viaparinfo->lvds_setting_info->v_active = vres;
2095 		viaparinfo->lvds_setting_info->bpp = bpp;
2096 		viaparinfo->lvds_setting_info2->h_active = hres;
2097 		viaparinfo->lvds_setting_info2->v_active = vres;
2098 		viaparinfo->lvds_setting_info2->bpp = bpp;
2099 	} else {
2100 
2101 		if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
2102 			viaparinfo->tmds_setting_info->h_active = hres;
2103 			viaparinfo->tmds_setting_info->v_active = vres;
2104 		}
2105 
2106 		if (viaparinfo->lvds_setting_info->iga_path == IGA2) {
2107 			viaparinfo->lvds_setting_info->h_active = hres;
2108 			viaparinfo->lvds_setting_info->v_active = vres;
2109 			viaparinfo->lvds_setting_info->bpp = bpp;
2110 		}
2111 		if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) {
2112 			viaparinfo->lvds_setting_info2->h_active = hres;
2113 			viaparinfo->lvds_setting_info2->v_active = vres;
2114 			viaparinfo->lvds_setting_info2->bpp = bpp;
2115 		}
2116 	}
2117 }
2118 
init_gfx_chip_info(int chip_type)2119 static void __devinit init_gfx_chip_info(int chip_type)
2120 {
2121 	u8 tmp;
2122 
2123 	viaparinfo->chip_info->gfx_chip_name = chip_type;
2124 
2125 	/* Check revision of CLE266 Chip */
2126 	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
2127 		/* CR4F only define in CLE266.CX chip */
2128 		tmp = viafb_read_reg(VIACR, CR4F);
2129 		viafb_write_reg(CR4F, VIACR, 0x55);
2130 		if (viafb_read_reg(VIACR, CR4F) != 0x55)
2131 			viaparinfo->chip_info->gfx_chip_revision =
2132 			CLE266_REVISION_AX;
2133 		else
2134 			viaparinfo->chip_info->gfx_chip_revision =
2135 			CLE266_REVISION_CX;
2136 		/* restore orignal CR4F value */
2137 		viafb_write_reg(CR4F, VIACR, tmp);
2138 	}
2139 
2140 	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
2141 		tmp = viafb_read_reg(VIASR, SR43);
2142 		DEBUG_MSG(KERN_INFO "SR43:%X\n", tmp);
2143 		if (tmp & 0x02) {
2144 			viaparinfo->chip_info->gfx_chip_revision =
2145 				CX700_REVISION_700M2;
2146 		} else if (tmp & 0x40) {
2147 			viaparinfo->chip_info->gfx_chip_revision =
2148 				CX700_REVISION_700M;
2149 		} else {
2150 			viaparinfo->chip_info->gfx_chip_revision =
2151 				CX700_REVISION_700;
2152 		}
2153 	}
2154 
2155 	/* Determine which 2D engine we have */
2156 	switch (viaparinfo->chip_info->gfx_chip_name) {
2157 	case UNICHROME_VX800:
2158 	case UNICHROME_VX855:
2159 	case UNICHROME_VX900:
2160 		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1;
2161 		break;
2162 	case UNICHROME_K8M890:
2163 	case UNICHROME_P4M900:
2164 		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H5;
2165 		break;
2166 	default:
2167 		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H2;
2168 		break;
2169 	}
2170 }
2171 
init_tmds_chip_info(void)2172 static void __devinit init_tmds_chip_info(void)
2173 {
2174 	viafb_tmds_trasmitter_identify();
2175 
2176 	if (INTERFACE_NONE == viaparinfo->chip_info->tmds_chip_info.
2177 		output_interface) {
2178 		switch (viaparinfo->chip_info->gfx_chip_name) {
2179 		case UNICHROME_CX700:
2180 			{
2181 				/* we should check support by hardware layout.*/
2182 				if ((viafb_display_hardware_layout ==
2183 				     HW_LAYOUT_DVI_ONLY)
2184 				    || (viafb_display_hardware_layout ==
2185 					HW_LAYOUT_LCD_DVI)) {
2186 					viaparinfo->chip_info->tmds_chip_info.
2187 					    output_interface = INTERFACE_TMDS;
2188 				} else {
2189 					viaparinfo->chip_info->tmds_chip_info.
2190 						output_interface =
2191 						INTERFACE_NONE;
2192 				}
2193 				break;
2194 			}
2195 		case UNICHROME_K8M890:
2196 		case UNICHROME_P4M900:
2197 		case UNICHROME_P4M890:
2198 			/* TMDS on PCIE, we set DFPLOW as default. */
2199 			viaparinfo->chip_info->tmds_chip_info.output_interface =
2200 			    INTERFACE_DFP_LOW;
2201 			break;
2202 		default:
2203 			{
2204 				/* set DVP1 default for DVI */
2205 				viaparinfo->chip_info->tmds_chip_info
2206 				.output_interface = INTERFACE_DVP1;
2207 			}
2208 		}
2209 	}
2210 
2211 	DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n",
2212 		  viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
2213 	viafb_init_dvi_size(&viaparinfo->shared->chip_info.tmds_chip_info,
2214 		&viaparinfo->shared->tmds_setting_info);
2215 }
2216 
init_lvds_chip_info(void)2217 static void __devinit init_lvds_chip_info(void)
2218 {
2219 	viafb_lvds_trasmitter_identify();
2220 	viafb_init_lcd_size();
2221 	viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info,
2222 				   viaparinfo->lvds_setting_info);
2223 	if (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
2224 		viafb_init_lvds_output_interface(&viaparinfo->chip_info->
2225 			lvds_chip_info2, viaparinfo->lvds_setting_info2);
2226 	}
2227 	/*If CX700,two singel LCD, we need to reassign
2228 	   LCD interface to different LVDS port */
2229 	if ((UNICHROME_CX700 == viaparinfo->chip_info->gfx_chip_name)
2230 	    && (HW_LAYOUT_LCD1_LCD2 == viafb_display_hardware_layout)) {
2231 		if ((INTEGRATED_LVDS == viaparinfo->chip_info->lvds_chip_info.
2232 			lvds_chip_name) && (INTEGRATED_LVDS ==
2233 			viaparinfo->chip_info->
2234 			lvds_chip_info2.lvds_chip_name)) {
2235 			viaparinfo->chip_info->lvds_chip_info.output_interface =
2236 				INTERFACE_LVDS0;
2237 			viaparinfo->chip_info->lvds_chip_info2.
2238 				output_interface =
2239 			    INTERFACE_LVDS1;
2240 		}
2241 	}
2242 
2243 	DEBUG_MSG(KERN_INFO "LVDS Chip = %d\n",
2244 		  viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
2245 	DEBUG_MSG(KERN_INFO "LVDS1 output_interface = %d\n",
2246 		  viaparinfo->chip_info->lvds_chip_info.output_interface);
2247 	DEBUG_MSG(KERN_INFO "LVDS2 output_interface = %d\n",
2248 		  viaparinfo->chip_info->lvds_chip_info.output_interface);
2249 }
2250 
viafb_init_dac(int set_iga)2251 void __devinit viafb_init_dac(int set_iga)
2252 {
2253 	int i;
2254 	u8 tmp;
2255 
2256 	if (set_iga == IGA1) {
2257 		/* access Primary Display's LUT */
2258 		viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
2259 		/* turn off LCK */
2260 		viafb_write_reg_mask(SR1B, VIASR, 0x00, BIT7 + BIT6);
2261 		for (i = 0; i < 256; i++) {
2262 			write_dac_reg(i, palLUT_table[i].red,
2263 				      palLUT_table[i].green,
2264 				      palLUT_table[i].blue);
2265 		}
2266 		/* turn on LCK */
2267 		viafb_write_reg_mask(SR1B, VIASR, 0xC0, BIT7 + BIT6);
2268 	} else {
2269 		tmp = viafb_read_reg(VIACR, CR6A);
2270 		/* access Secondary Display's LUT */
2271 		viafb_write_reg_mask(CR6A, VIACR, 0x40, BIT6);
2272 		viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
2273 		for (i = 0; i < 256; i++) {
2274 			write_dac_reg(i, palLUT_table[i].red,
2275 				      palLUT_table[i].green,
2276 				      palLUT_table[i].blue);
2277 		}
2278 		/* set IGA1 DAC for default */
2279 		viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
2280 		viafb_write_reg(CR6A, VIACR, tmp);
2281 	}
2282 }
2283 
device_screen_off(void)2284 static void device_screen_off(void)
2285 {
2286 	/* turn off CRT screen (IGA1) */
2287 	viafb_write_reg_mask(SR01, VIASR, 0x20, BIT5);
2288 }
2289 
device_screen_on(void)2290 static void device_screen_on(void)
2291 {
2292 	/* turn on CRT screen (IGA1) */
2293 	viafb_write_reg_mask(SR01, VIASR, 0x00, BIT5);
2294 }
2295 
set_display_channel(void)2296 static void set_display_channel(void)
2297 {
2298 	/*If viafb_LCD2_ON, on cx700, internal lvds's information
2299 	is keeped on lvds_setting_info2 */
2300 	if (viafb_LCD2_ON &&
2301 		viaparinfo->lvds_setting_info2->device_lcd_dualedge) {
2302 		/* For dual channel LCD: */
2303 		/* Set to Dual LVDS channel. */
2304 		viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
2305 	} else if (viafb_LCD_ON && viafb_DVI_ON) {
2306 		/* For LCD+DFP: */
2307 		/* Set to LVDS1 + TMDS channel. */
2308 		viafb_write_reg_mask(CRD2, VIACR, 0x10, BIT4 + BIT5);
2309 	} else if (viafb_DVI_ON) {
2310 		/* Set to single TMDS channel. */
2311 		viafb_write_reg_mask(CRD2, VIACR, 0x30, BIT4 + BIT5);
2312 	} else if (viafb_LCD_ON) {
2313 		if (viaparinfo->lvds_setting_info->device_lcd_dualedge) {
2314 			/* For dual channel LCD: */
2315 			/* Set to Dual LVDS channel. */
2316 			viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
2317 		} else {
2318 			/* Set to LVDS0 + LVDS1 channel. */
2319 			viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT4 + BIT5);
2320 		}
2321 	}
2322 }
2323 
get_sync(struct fb_info * info)2324 static u8 get_sync(struct fb_info *info)
2325 {
2326 	u8 polarity = 0;
2327 
2328 	if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
2329 		polarity |= VIA_HSYNC_NEGATIVE;
2330 	if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
2331 		polarity |= VIA_VSYNC_NEGATIVE;
2332 	return polarity;
2333 }
2334 
viafb_setmode(struct VideoModeTable * vmode_tbl,int video_bpp,struct VideoModeTable * vmode_tbl1,int video_bpp1)2335 int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2336 	struct VideoModeTable *vmode_tbl1, int video_bpp1)
2337 {
2338 	int i, j;
2339 	int port;
2340 	u32 devices = viaparinfo->shared->iga1_devices
2341 		| viaparinfo->shared->iga2_devices;
2342 	u8 value, index, mask;
2343 	struct crt_mode_table *crt_timing;
2344 	struct crt_mode_table *crt_timing1 = NULL;
2345 
2346 	device_screen_off();
2347 	crt_timing = vmode_tbl->crtc;
2348 
2349 	if (viafb_SAMM_ON == 1) {
2350 		crt_timing1 = vmode_tbl1->crtc;
2351 	}
2352 
2353 	inb(VIAStatus);
2354 	outb(0x00, VIAAR);
2355 
2356 	/* Write Common Setting for Video Mode */
2357 	switch (viaparinfo->chip_info->gfx_chip_name) {
2358 	case UNICHROME_CLE266:
2359 		viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs);
2360 		break;
2361 
2362 	case UNICHROME_K400:
2363 		viafb_write_regx(KM400_ModeXregs, NUM_TOTAL_KM400_ModeXregs);
2364 		break;
2365 
2366 	case UNICHROME_K800:
2367 	case UNICHROME_PM800:
2368 		viafb_write_regx(CN400_ModeXregs, NUM_TOTAL_CN400_ModeXregs);
2369 		break;
2370 
2371 	case UNICHROME_CN700:
2372 	case UNICHROME_K8M890:
2373 	case UNICHROME_P4M890:
2374 	case UNICHROME_P4M900:
2375 		viafb_write_regx(CN700_ModeXregs, NUM_TOTAL_CN700_ModeXregs);
2376 		break;
2377 
2378 	case UNICHROME_CX700:
2379 	case UNICHROME_VX800:
2380 		viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
2381 		break;
2382 
2383 	case UNICHROME_VX855:
2384 	case UNICHROME_VX900:
2385 		viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs);
2386 		break;
2387 	}
2388 
2389 	viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters));
2390 	device_off();
2391 	via_set_state(devices, VIA_STATE_OFF);
2392 
2393 	/* Fill VPIT Parameters */
2394 	/* Write Misc Register */
2395 	outb(VPIT.Misc, VIA_MISC_REG_WRITE);
2396 
2397 	/* Write Sequencer */
2398 	for (i = 1; i <= StdSR; i++)
2399 		via_write_reg(VIASR, i, VPIT.SR[i - 1]);
2400 
2401 	viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);
2402 
2403 	/* Write CRTC */
2404 	viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1);
2405 
2406 	/* Write Graphic Controller */
2407 	for (i = 0; i < StdGR; i++)
2408 		via_write_reg(VIAGR, i, VPIT.GR[i]);
2409 
2410 	/* Write Attribute Controller */
2411 	for (i = 0; i < StdAR; i++) {
2412 		inb(VIAStatus);
2413 		outb(i, VIAAR);
2414 		outb(VPIT.AR[i], VIAAR);
2415 	}
2416 
2417 	inb(VIAStatus);
2418 	outb(0x20, VIAAR);
2419 
2420 	/* Update Patch Register */
2421 
2422 	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266
2423 	    || viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)
2424 	    && vmode_tbl->crtc[0].crtc.hor_addr == 1024
2425 	    && vmode_tbl->crtc[0].crtc.ver_addr == 768) {
2426 		for (j = 0; j < res_patch_table[0].table_length; j++) {
2427 			index = res_patch_table[0].io_reg_table[j].index;
2428 			port = res_patch_table[0].io_reg_table[j].port;
2429 			value = res_patch_table[0].io_reg_table[j].value;
2430 			mask = res_patch_table[0].io_reg_table[j].mask;
2431 			viafb_write_reg_mask(index, port, value, mask);
2432 		}
2433 	}
2434 
2435 	via_set_primary_pitch(viafbinfo->fix.line_length);
2436 	via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
2437 		: viafbinfo->fix.line_length);
2438 	via_set_primary_color_depth(viaparinfo->depth);
2439 	via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth
2440 		: viaparinfo->depth);
2441 	via_set_source(viaparinfo->shared->iga1_devices, IGA1);
2442 	via_set_source(viaparinfo->shared->iga2_devices, IGA2);
2443 	if (viaparinfo->shared->iga2_devices)
2444 		enable_second_display_channel();
2445 	else
2446 		disable_second_display_channel();
2447 
2448 	/* Update Refresh Rate Setting */
2449 
2450 	/* Clear On Screen */
2451 
2452 	/* CRT set mode */
2453 	if (viafb_CRT_ON) {
2454 		if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path ==
2455 			IGA2)) {
2456 			viafb_fill_crtc_timing(crt_timing1, vmode_tbl1,
2457 				video_bpp1 / 8,
2458 				viaparinfo->crt_setting_info->iga_path);
2459 		} else {
2460 			viafb_fill_crtc_timing(crt_timing, vmode_tbl,
2461 				video_bpp / 8,
2462 				viaparinfo->crt_setting_info->iga_path);
2463 		}
2464 
2465 		/* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
2466 		to 8 alignment (1368),there is several pixels (2 pixels)
2467 		on right side of screen. */
2468 		if (vmode_tbl->crtc[0].crtc.hor_addr % 8) {
2469 			viafb_unlock_crt();
2470 			viafb_write_reg(CR02, VIACR,
2471 				viafb_read_reg(VIACR, CR02) - 1);
2472 			viafb_lock_crt();
2473 		}
2474 	}
2475 
2476 	if (viafb_DVI_ON) {
2477 		if (viafb_SAMM_ON &&
2478 			(viaparinfo->tmds_setting_info->iga_path == IGA2)) {
2479 			viafb_dvi_set_mode(viafb_get_mode
2480 				     (viaparinfo->tmds_setting_info->h_active,
2481 				      viaparinfo->tmds_setting_info->
2482 				      v_active),
2483 				     video_bpp1, viaparinfo->
2484 				     tmds_setting_info->iga_path);
2485 		} else {
2486 			viafb_dvi_set_mode(viafb_get_mode
2487 				     (viaparinfo->tmds_setting_info->h_active,
2488 				      viaparinfo->
2489 				      tmds_setting_info->v_active),
2490 				     video_bpp, viaparinfo->
2491 				     tmds_setting_info->iga_path);
2492 		}
2493 	}
2494 
2495 	if (viafb_LCD_ON) {
2496 		if (viafb_SAMM_ON &&
2497 			(viaparinfo->lvds_setting_info->iga_path == IGA2)) {
2498 			viaparinfo->lvds_setting_info->bpp = video_bpp1;
2499 			viafb_lcd_set_mode(crt_timing1, viaparinfo->
2500 				lvds_setting_info,
2501 				     &viaparinfo->chip_info->lvds_chip_info);
2502 		} else {
2503 			/* IGA1 doesn't have LCD scaling, so set it center. */
2504 			if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
2505 				viaparinfo->lvds_setting_info->display_method =
2506 				    LCD_CENTERING;
2507 			}
2508 			viaparinfo->lvds_setting_info->bpp = video_bpp;
2509 			viafb_lcd_set_mode(crt_timing, viaparinfo->
2510 				lvds_setting_info,
2511 				     &viaparinfo->chip_info->lvds_chip_info);
2512 		}
2513 	}
2514 	if (viafb_LCD2_ON) {
2515 		if (viafb_SAMM_ON &&
2516 			(viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
2517 			viaparinfo->lvds_setting_info2->bpp = video_bpp1;
2518 			viafb_lcd_set_mode(crt_timing1, viaparinfo->
2519 				lvds_setting_info2,
2520 				     &viaparinfo->chip_info->lvds_chip_info2);
2521 		} else {
2522 			/* IGA1 doesn't have LCD scaling, so set it center. */
2523 			if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
2524 				viaparinfo->lvds_setting_info2->display_method =
2525 				    LCD_CENTERING;
2526 			}
2527 			viaparinfo->lvds_setting_info2->bpp = video_bpp;
2528 			viafb_lcd_set_mode(crt_timing, viaparinfo->
2529 				lvds_setting_info2,
2530 				     &viaparinfo->chip_info->lvds_chip_info2);
2531 		}
2532 	}
2533 
2534 	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
2535 	    && (viafb_LCD_ON || viafb_DVI_ON))
2536 		set_display_channel();
2537 
2538 	/* If set mode normally, save resolution information for hot-plug . */
2539 	if (!viafb_hotplug) {
2540 		viafb_hotplug_Xres = vmode_tbl->crtc[0].crtc.hor_addr;
2541 		viafb_hotplug_Yres = vmode_tbl->crtc[0].crtc.ver_addr;
2542 		viafb_hotplug_bpp = video_bpp;
2543 		viafb_hotplug_refresh = viafb_refresh;
2544 
2545 		if (viafb_DVI_ON)
2546 			viafb_DeviceStatus = DVI_Device;
2547 		else
2548 			viafb_DeviceStatus = CRT_Device;
2549 	}
2550 	device_on();
2551 	if (!viafb_dual_fb)
2552 		via_set_sync_polarity(devices, get_sync(viafbinfo));
2553 	else {
2554 		via_set_sync_polarity(viaparinfo->shared->iga1_devices,
2555 			get_sync(viafbinfo));
2556 		via_set_sync_polarity(viaparinfo->shared->iga2_devices,
2557 			get_sync(viafbinfo1));
2558 	}
2559 
2560 	via_set_state(devices, VIA_STATE_ON);
2561 	device_screen_on();
2562 	return 1;
2563 }
2564 
viafb_get_pixclock(int hres,int vres,int vmode_refresh)2565 int viafb_get_pixclock(int hres, int vres, int vmode_refresh)
2566 {
2567 	int i;
2568 	struct crt_mode_table *best;
2569 	struct VideoModeTable *vmode = viafb_get_mode(hres, vres);
2570 
2571 	if (!vmode)
2572 		return RES_640X480_60HZ_PIXCLOCK;
2573 
2574 	best = &vmode->crtc[0];
2575 	for (i = 1; i < vmode->mode_array; i++) {
2576 		if (abs(vmode->crtc[i].refresh_rate - vmode_refresh)
2577 			< abs(best->refresh_rate - vmode_refresh))
2578 			best = &vmode->crtc[i];
2579 	}
2580 
2581 	return 1000000000 / (best->crtc.hor_total * best->crtc.ver_total)
2582 		* 1000 / best->refresh_rate;
2583 }
2584 
viafb_get_refresh(int hres,int vres,u32 long_refresh)2585 int viafb_get_refresh(int hres, int vres, u32 long_refresh)
2586 {
2587 	int i;
2588 	struct crt_mode_table *best;
2589 	struct VideoModeTable *vmode = viafb_get_mode(hres, vres);
2590 
2591 	if (!vmode)
2592 		return 60;
2593 
2594 	best = &vmode->crtc[0];
2595 	for (i = 1; i < vmode->mode_array; i++) {
2596 		if (abs(vmode->crtc[i].refresh_rate - long_refresh)
2597 			< abs(best->refresh_rate - long_refresh))
2598 			best = &vmode->crtc[i];
2599 	}
2600 
2601 	if (abs(best->refresh_rate - long_refresh) > 3)
2602 		return 60;
2603 
2604 	return best->refresh_rate;
2605 }
2606 
device_off(void)2607 static void device_off(void)
2608 {
2609 	viafb_dvi_disable();
2610 	viafb_lcd_disable();
2611 }
2612 
device_on(void)2613 static void device_on(void)
2614 {
2615 	if (viafb_DVI_ON == 1)
2616 		viafb_dvi_enable();
2617 	if (viafb_LCD_ON == 1)
2618 		viafb_lcd_enable();
2619 }
2620 
enable_second_display_channel(void)2621 static void enable_second_display_channel(void)
2622 {
2623 	/* to enable second display channel. */
2624 	viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
2625 	viafb_write_reg_mask(CR6A, VIACR, BIT7, BIT7);
2626 	viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2627 }
2628 
disable_second_display_channel(void)2629 static void disable_second_display_channel(void)
2630 {
2631 	/* to disable second display channel. */
2632 	viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
2633 	viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7);
2634 	viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2635 }
2636 
viafb_set_dpa_gfx(int output_interface,struct GFX_DPA_SETTING * p_gfx_dpa_setting)2637 void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
2638 					*p_gfx_dpa_setting)
2639 {
2640 	switch (output_interface) {
2641 	case INTERFACE_DVP0:
2642 		{
2643 			/* DVP0 Clock Polarity and Adjust: */
2644 			viafb_write_reg_mask(CR96, VIACR,
2645 				       p_gfx_dpa_setting->DVP0, 0x0F);
2646 
2647 			/* DVP0 Clock and Data Pads Driving: */
2648 			viafb_write_reg_mask(SR1E, VIASR,
2649 				       p_gfx_dpa_setting->DVP0ClockDri_S, BIT2);
2650 			viafb_write_reg_mask(SR2A, VIASR,
2651 				       p_gfx_dpa_setting->DVP0ClockDri_S1,
2652 				       BIT4);
2653 			viafb_write_reg_mask(SR1B, VIASR,
2654 				       p_gfx_dpa_setting->DVP0DataDri_S, BIT1);
2655 			viafb_write_reg_mask(SR2A, VIASR,
2656 				       p_gfx_dpa_setting->DVP0DataDri_S1, BIT5);
2657 			break;
2658 		}
2659 
2660 	case INTERFACE_DVP1:
2661 		{
2662 			/* DVP1 Clock Polarity and Adjust: */
2663 			viafb_write_reg_mask(CR9B, VIACR,
2664 				       p_gfx_dpa_setting->DVP1, 0x0F);
2665 
2666 			/* DVP1 Clock and Data Pads Driving: */
2667 			viafb_write_reg_mask(SR65, VIASR,
2668 				       p_gfx_dpa_setting->DVP1Driving, 0x0F);
2669 			break;
2670 		}
2671 
2672 	case INTERFACE_DFP_HIGH:
2673 		{
2674 			viafb_write_reg_mask(CR97, VIACR,
2675 				       p_gfx_dpa_setting->DFPHigh, 0x0F);
2676 			break;
2677 		}
2678 
2679 	case INTERFACE_DFP_LOW:
2680 		{
2681 			viafb_write_reg_mask(CR99, VIACR,
2682 				       p_gfx_dpa_setting->DFPLow, 0x0F);
2683 			break;
2684 		}
2685 
2686 	case INTERFACE_DFP:
2687 		{
2688 			viafb_write_reg_mask(CR97, VIACR,
2689 				       p_gfx_dpa_setting->DFPHigh, 0x0F);
2690 			viafb_write_reg_mask(CR99, VIACR,
2691 				       p_gfx_dpa_setting->DFPLow, 0x0F);
2692 			break;
2693 		}
2694 	}
2695 }
2696 
2697 /*According var's xres, yres fill var's other timing information*/
viafb_fill_var_timing_info(struct fb_var_screeninfo * var,int refresh,struct VideoModeTable * vmode_tbl)2698 void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
2699 	struct VideoModeTable *vmode_tbl)
2700 {
2701 	struct crt_mode_table *crt_timing = NULL;
2702 	struct display_timing crt_reg;
2703 	int i = 0, index = 0;
2704 	crt_timing = vmode_tbl->crtc;
2705 	for (i = 0; i < vmode_tbl->mode_array; i++) {
2706 		index = i;
2707 		if (crt_timing[i].refresh_rate == refresh)
2708 			break;
2709 	}
2710 
2711 	crt_reg = crt_timing[index].crtc;
2712 	var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh);
2713 	var->left_margin =
2714 	    crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
2715 	var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr;
2716 	var->hsync_len = crt_reg.hor_sync_end;
2717 	var->upper_margin =
2718 	    crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end);
2719 	var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr;
2720 	var->vsync_len = crt_reg.ver_sync_end;
2721 	var->sync = 0;
2722 	if (crt_timing[index].h_sync_polarity == POSITIVE)
2723 		var->sync |= FB_SYNC_HOR_HIGH_ACT;
2724 	if (crt_timing[index].v_sync_polarity == POSITIVE)
2725 		var->sync |= FB_SYNC_VERT_HIGH_ACT;
2726 }
2727