xref: /linux/drivers/video/fbdev/via/hw.c (revision 0be3ff0c)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
4  * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
5 
6  */
7 
8 #include <linux/via-core.h>
9 #include "global.h"
10 #include "via_clock.h"
11 
12 static struct pll_limit cle266_pll_limits[] = {
13 	{19, 19, 4, 0},
14 	{26, 102, 5, 0},
15 	{53, 112, 6, 0},
16 	{41, 100, 7, 0},
17 	{83, 108, 8, 0},
18 	{87, 118, 9, 0},
19 	{95, 115, 12, 0},
20 	{108, 108, 13, 0},
21 	{83, 83, 17, 0},
22 	{67, 98, 20, 0},
23 	{121, 121, 24, 0},
24 	{99, 99, 29, 0},
25 	{33, 33, 3, 1},
26 	{15, 23, 4, 1},
27 	{37, 121, 5, 1},
28 	{82, 82, 6, 1},
29 	{31, 84, 7, 1},
30 	{83, 83, 8, 1},
31 	{76, 127, 9, 1},
32 	{33, 121, 4, 2},
33 	{91, 118, 5, 2},
34 	{83, 109, 6, 2},
35 	{90, 90, 7, 2},
36 	{93, 93, 2, 3},
37 	{53, 53, 3, 3},
38 	{73, 117, 4, 3},
39 	{101, 127, 5, 3},
40 	{99, 99, 7, 3}
41 };
42 
43 static struct pll_limit k800_pll_limits[] = {
44 	{22, 22, 2, 0},
45 	{28, 28, 3, 0},
46 	{81, 112, 3, 1},
47 	{86, 166, 4, 1},
48 	{109, 153, 5, 1},
49 	{66, 116, 3, 2},
50 	{93, 137, 4, 2},
51 	{117, 208, 5, 2},
52 	{30, 30, 2, 3},
53 	{69, 125, 3, 3},
54 	{89, 161, 4, 3},
55 	{121, 208, 5, 3},
56 	{66, 66, 2, 4},
57 	{85, 85, 3, 4},
58 	{141, 161, 4, 4},
59 	{177, 177, 5, 4}
60 };
61 
62 static struct pll_limit cx700_pll_limits[] = {
63 	{98, 98, 3, 1},
64 	{86, 86, 4, 1},
65 	{109, 208, 5, 1},
66 	{68, 68, 2, 2},
67 	{95, 116, 3, 2},
68 	{93, 166, 4, 2},
69 	{110, 206, 5, 2},
70 	{174, 174, 7, 2},
71 	{82, 109, 3, 3},
72 	{117, 161, 4, 3},
73 	{112, 208, 5, 3},
74 	{141, 202, 5, 4}
75 };
76 
77 static struct pll_limit vx855_pll_limits[] = {
78 	{86, 86, 4, 1},
79 	{108, 208, 5, 1},
80 	{110, 208, 5, 2},
81 	{83, 112, 3, 3},
82 	{103, 161, 4, 3},
83 	{112, 209, 5, 3},
84 	{142, 161, 4, 4},
85 	{141, 176, 5, 4}
86 };
87 
88 /* according to VIA Technologies these values are based on experiment */
89 static struct io_reg scaling_parameters[] = {
90 	{VIACR, CR7A, 0xFF, 0x01},	/* LCD Scaling Parameter 1 */
91 	{VIACR, CR7B, 0xFF, 0x02},	/* LCD Scaling Parameter 2 */
92 	{VIACR, CR7C, 0xFF, 0x03},	/* LCD Scaling Parameter 3 */
93 	{VIACR, CR7D, 0xFF, 0x04},	/* LCD Scaling Parameter 4 */
94 	{VIACR, CR7E, 0xFF, 0x07},	/* LCD Scaling Parameter 5 */
95 	{VIACR, CR7F, 0xFF, 0x0A},	/* LCD Scaling Parameter 6 */
96 	{VIACR, CR80, 0xFF, 0x0D},	/* LCD Scaling Parameter 7 */
97 	{VIACR, CR81, 0xFF, 0x13},	/* LCD Scaling Parameter 8 */
98 	{VIACR, CR82, 0xFF, 0x16},	/* LCD Scaling Parameter 9 */
99 	{VIACR, CR83, 0xFF, 0x19},	/* LCD Scaling Parameter 10 */
100 	{VIACR, CR84, 0xFF, 0x1C},	/* LCD Scaling Parameter 11 */
101 	{VIACR, CR85, 0xFF, 0x1D},	/* LCD Scaling Parameter 12 */
102 	{VIACR, CR86, 0xFF, 0x1E},	/* LCD Scaling Parameter 13 */
103 	{VIACR, CR87, 0xFF, 0x1F},	/* LCD Scaling Parameter 14 */
104 };
105 
106 static struct io_reg common_vga[] = {
107 	{VIACR, CR07, 0x10, 0x10}, /* [0] vertical total (bit 8)
108 					[1] vertical display end (bit 8)
109 					[2] vertical retrace start (bit 8)
110 					[3] start vertical blanking (bit 8)
111 					[4] line compare (bit 8)
112 					[5] vertical total (bit 9)
113 					[6] vertical display end (bit 9)
114 					[7] vertical retrace start (bit 9) */
115 	{VIACR, CR08, 0xFF, 0x00}, /* [0-4] preset row scan
116 					[5-6] byte panning */
117 	{VIACR, CR09, 0xDF, 0x40}, /* [0-4] max scan line
118 					[5] start vertical blanking (bit 9)
119 					[6] line compare (bit 9)
120 					[7] scan doubling */
121 	{VIACR, CR0A, 0xFF, 0x1E}, /* [0-4] cursor start
122 					[5] cursor disable */
123 	{VIACR, CR0B, 0xFF, 0x00}, /* [0-4] cursor end
124 					[5-6] cursor skew */
125 	{VIACR, CR0E, 0xFF, 0x00}, /* [0-7] cursor location (high) */
126 	{VIACR, CR0F, 0xFF, 0x00}, /* [0-7] cursor location (low) */
127 	{VIACR, CR11, 0xF0, 0x80}, /* [0-3] vertical retrace end
128 					[6] memory refresh bandwidth
129 					[7] CRTC register protect enable */
130 	{VIACR, CR14, 0xFF, 0x00}, /* [0-4] underline location
131 					[5] divide memory address clock by 4
132 					[6] double word addressing */
133 	{VIACR, CR17, 0xFF, 0x63}, /* [0-1] mapping of display address 13-14
134 					[2] divide scan line clock by 2
135 					[3] divide memory address clock by 2
136 					[5] address wrap
137 					[6] byte mode select
138 					[7] sync enable */
139 	{VIACR, CR18, 0xFF, 0xFF}, /* [0-7] line compare */
140 };
141 
142 static struct fifo_depth_select display_fifo_depth_reg = {
143 	/* IGA1 FIFO Depth_Select */
144 	{IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } },
145 	/* IGA2 FIFO Depth_Select */
146 	{IGA2_FIFO_DEPTH_SELECT_REG_NUM,
147 	 {{CR68, 4, 7}, {CR94, 7, 7}, {CR95, 7, 7} } }
148 };
149 
150 static struct fifo_threshold_select fifo_threshold_select_reg = {
151 	/* IGA1 FIFO Threshold Select */
152 	{IGA1_FIFO_THRESHOLD_REG_NUM, {{SR16, 0, 5}, {SR16, 7, 7} } },
153 	/* IGA2 FIFO Threshold Select */
154 	{IGA2_FIFO_THRESHOLD_REG_NUM, {{CR68, 0, 3}, {CR95, 4, 6} } }
155 };
156 
157 static struct fifo_high_threshold_select fifo_high_threshold_select_reg = {
158 	/* IGA1 FIFO High Threshold Select */
159 	{IGA1_FIFO_HIGH_THRESHOLD_REG_NUM, {{SR18, 0, 5}, {SR18, 7, 7} } },
160 	/* IGA2 FIFO High Threshold Select */
161 	{IGA2_FIFO_HIGH_THRESHOLD_REG_NUM, {{CR92, 0, 3}, {CR95, 0, 2} } }
162 };
163 
164 static struct display_queue_expire_num display_queue_expire_num_reg = {
165 	/* IGA1 Display Queue Expire Num */
166 	{IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{SR22, 0, 4} } },
167 	/* IGA2 Display Queue Expire Num */
168 	{IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{CR94, 0, 6} } }
169 };
170 
171 /* Definition Fetch Count Registers*/
172 static struct fetch_count fetch_count_reg = {
173 	/* IGA1 Fetch Count Register */
174 	{IGA1_FETCH_COUNT_REG_NUM, {{SR1C, 0, 7}, {SR1D, 0, 1} } },
175 	/* IGA2 Fetch Count Register */
176 	{IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } }
177 };
178 
179 static struct rgbLUT palLUT_table[] = {
180 	/* {R,G,B} */
181 	/* Index 0x00~0x03 */
182 	{0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00,
183 								     0x2A,
184 								     0x2A},
185 	/* Index 0x04~0x07 */
186 	{0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A,
187 								     0x2A,
188 								     0x2A},
189 	/* Index 0x08~0x0B */
190 	{0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15,
191 								     0x3F,
192 								     0x3F},
193 	/* Index 0x0C~0x0F */
194 	{0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F,
195 								     0x3F,
196 								     0x3F},
197 	/* Index 0x10~0x13 */
198 	{0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B,
199 								     0x0B,
200 								     0x0B},
201 	/* Index 0x14~0x17 */
202 	{0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18,
203 								     0x18,
204 								     0x18},
205 	/* Index 0x18~0x1B */
206 	{0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28,
207 								     0x28,
208 								     0x28},
209 	/* Index 0x1C~0x1F */
210 	{0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F,
211 								     0x3F,
212 								     0x3F},
213 	/* Index 0x20~0x23 */
214 	{0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F,
215 								     0x00,
216 								     0x3F},
217 	/* Index 0x24~0x27 */
218 	{0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F,
219 								     0x00,
220 								     0x10},
221 	/* Index 0x28~0x2B */
222 	{0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F,
223 								     0x2F,
224 								     0x00},
225 	/* Index 0x2C~0x2F */
226 	{0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10,
227 								     0x3F,
228 								     0x00},
229 	/* Index 0x30~0x33 */
230 	{0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00,
231 								     0x3F,
232 								     0x2F},
233 	/* Index 0x34~0x37 */
234 	{0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00,
235 								     0x10,
236 								     0x3F},
237 	/* Index 0x38~0x3B */
238 	{0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37,
239 								     0x1F,
240 								     0x3F},
241 	/* Index 0x3C~0x3F */
242 	{0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F,
243 								     0x1F,
244 								     0x27},
245 	/* Index 0x40~0x43 */
246 	{0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F,
247 								     0x3F,
248 								     0x1F},
249 	/* Index 0x44~0x47 */
250 	{0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27,
251 								     0x3F,
252 								     0x1F},
253 	/* Index 0x48~0x4B */
254 	{0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F,
255 								     0x3F,
256 								     0x37},
257 	/* Index 0x4C~0x4F */
258 	{0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F,
259 								     0x27,
260 								     0x3F},
261 	/* Index 0x50~0x53 */
262 	{0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A,
263 								     0x2D,
264 								     0x3F},
265 	/* Index 0x54~0x57 */
266 	{0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F,
267 								     0x2D,
268 								     0x31},
269 	/* Index 0x58~0x5B */
270 	{0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F,
271 								     0x3A,
272 								     0x2D},
273 	/* Index 0x5C~0x5F */
274 	{0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31,
275 								     0x3F,
276 								     0x2D},
277 	/* Index 0x60~0x63 */
278 	{0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D,
279 								     0x3F,
280 								     0x3A},
281 	/* Index 0x64~0x67 */
282 	{0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D,
283 								     0x31,
284 								     0x3F},
285 	/* Index 0x68~0x6B */
286 	{0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15,
287 								     0x00,
288 								     0x1C},
289 	/* Index 0x6C~0x6F */
290 	{0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C,
291 								     0x00,
292 								     0x07},
293 	/* Index 0x70~0x73 */
294 	{0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C,
295 								     0x15,
296 								     0x00},
297 	/* Index 0x74~0x77 */
298 	{0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07,
299 								     0x1C,
300 								     0x00},
301 	/* Index 0x78~0x7B */
302 	{0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00,
303 								     0x1C,
304 								     0x15},
305 	/* Index 0x7C~0x7F */
306 	{0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00,
307 								     0x07,
308 								     0x1C},
309 	/* Index 0x80~0x83 */
310 	{0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18,
311 								     0x0E,
312 								     0x1C},
313 	/* Index 0x84~0x87 */
314 	{0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C,
315 								     0x0E,
316 								     0x11},
317 	/* Index 0x88~0x8B */
318 	{0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C,
319 								     0x18,
320 								     0x0E},
321 	/* Index 0x8C~0x8F */
322 	{0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11,
323 								     0x1C,
324 								     0x0E},
325 	/* Index 0x90~0x93 */
326 	{0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E,
327 								     0x1C,
328 								     0x18},
329 	/* Index 0x94~0x97 */
330 	{0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E,
331 								     0x11,
332 								     0x1C},
333 	/* Index 0x98~0x9B */
334 	{0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A,
335 								     0x14,
336 								     0x1C},
337 	/* Index 0x9C~0x9F */
338 	{0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C,
339 								     0x14,
340 								     0x16},
341 	/* Index 0xA0~0xA3 */
342 	{0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C,
343 								     0x1A,
344 								     0x14},
345 	/* Index 0xA4~0xA7 */
346 	{0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16,
347 								     0x1C,
348 								     0x14},
349 	/* Index 0xA8~0xAB */
350 	{0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14,
351 								     0x1C,
352 								     0x1A},
353 	/* Index 0xAC~0xAF */
354 	{0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14,
355 								     0x16,
356 								     0x1C},
357 	/* Index 0xB0~0xB3 */
358 	{0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C,
359 								     0x00,
360 								     0x10},
361 	/* Index 0xB4~0xB7 */
362 	{0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10,
363 								     0x00,
364 								     0x04},
365 	/* Index 0xB8~0xBB */
366 	{0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10,
367 								     0x0C,
368 								     0x00},
369 	/* Index 0xBC~0xBF */
370 	{0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04,
371 								     0x10,
372 								     0x00},
373 	/* Index 0xC0~0xC3 */
374 	{0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00,
375 								     0x10,
376 								     0x0C},
377 	/* Index 0xC4~0xC7 */
378 	{0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00,
379 								     0x04,
380 								     0x10},
381 	/* Index 0xC8~0xCB */
382 	{0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E,
383 								     0x08,
384 								     0x10},
385 	/* Index 0xCC~0xCF */
386 	{0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10,
387 								     0x08,
388 								     0x0A},
389 	/* Index 0xD0~0xD3 */
390 	{0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10,
391 								     0x0E,
392 								     0x08},
393 	/* Index 0xD4~0xD7 */
394 	{0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A,
395 								     0x10,
396 								     0x08},
397 	/* Index 0xD8~0xDB */
398 	{0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08,
399 								     0x10,
400 								     0x0E},
401 	/* Index 0xDC~0xDF */
402 	{0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08,
403 								     0x0A,
404 								     0x10},
405 	/* Index 0xE0~0xE3 */
406 	{0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F,
407 								     0x0B,
408 								     0x10},
409 	/* Index 0xE4~0xE7 */
410 	{0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10,
411 								     0x0B,
412 								     0x0C},
413 	/* Index 0xE8~0xEB */
414 	{0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10,
415 								     0x0F,
416 								     0x0B},
417 	/* Index 0xEC~0xEF */
418 	{0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C,
419 								     0x10,
420 								     0x0B},
421 	/* Index 0xF0~0xF3 */
422 	{0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B,
423 								     0x10,
424 								     0x0F},
425 	/* Index 0xF4~0xF7 */
426 	{0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B,
427 								     0x0C,
428 								     0x10},
429 	/* Index 0xF8~0xFB */
430 	{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
431 								     0x00,
432 								     0x00},
433 	/* Index 0xFC~0xFF */
434 	{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
435 								     0x00,
436 								     0x00}
437 };
438 
439 static struct via_device_mapping device_mapping[] = {
440 	{VIA_LDVP0, "LDVP0"},
441 	{VIA_LDVP1, "LDVP1"},
442 	{VIA_DVP0, "DVP0"},
443 	{VIA_CRT, "CRT"},
444 	{VIA_DVP1, "DVP1"},
445 	{VIA_LVDS1, "LVDS1"},
446 	{VIA_LVDS2, "LVDS2"}
447 };
448 
449 /* structure with function pointers to support clock control */
450 static struct via_clock clock;
451 
452 static void load_fix_bit_crtc_reg(void);
453 static void init_gfx_chip_info(int chip_type);
454 static void init_tmds_chip_info(void);
455 static void init_lvds_chip_info(void);
456 static void device_screen_off(void);
457 static void device_screen_on(void);
458 static void set_display_channel(void);
459 static void device_off(void);
460 static void device_on(void);
461 static void enable_second_display_channel(void);
462 static void disable_second_display_channel(void);
463 
464 void viafb_lock_crt(void)
465 {
466 	viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7);
467 }
468 
469 void viafb_unlock_crt(void)
470 {
471 	viafb_write_reg_mask(CR11, VIACR, 0, BIT7);
472 	viafb_write_reg_mask(CR47, VIACR, 0, BIT0);
473 }
474 
475 static void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
476 {
477 	outb(index, LUT_INDEX_WRITE);
478 	outb(r, LUT_DATA);
479 	outb(g, LUT_DATA);
480 	outb(b, LUT_DATA);
481 }
482 
483 static u32 get_dvi_devices(int output_interface)
484 {
485 	switch (output_interface) {
486 	case INTERFACE_DVP0:
487 		return VIA_DVP0 | VIA_LDVP0;
488 
489 	case INTERFACE_DVP1:
490 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
491 			return VIA_LDVP1;
492 		else
493 			return VIA_DVP1;
494 
495 	case INTERFACE_DFP_HIGH:
496 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
497 			return 0;
498 		else
499 			return VIA_LVDS2 | VIA_DVP0;
500 
501 	case INTERFACE_DFP_LOW:
502 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
503 			return 0;
504 		else
505 			return VIA_DVP1 | VIA_LVDS1;
506 
507 	case INTERFACE_TMDS:
508 		return VIA_LVDS1;
509 	}
510 
511 	return 0;
512 }
513 
514 static u32 get_lcd_devices(int output_interface)
515 {
516 	switch (output_interface) {
517 	case INTERFACE_DVP0:
518 		return VIA_DVP0;
519 
520 	case INTERFACE_DVP1:
521 		return VIA_DVP1;
522 
523 	case INTERFACE_DFP_HIGH:
524 		return VIA_LVDS2 | VIA_DVP0;
525 
526 	case INTERFACE_DFP_LOW:
527 		return VIA_LVDS1 | VIA_DVP1;
528 
529 	case INTERFACE_DFP:
530 		return VIA_LVDS1 | VIA_LVDS2;
531 
532 	case INTERFACE_LVDS0:
533 	case INTERFACE_LVDS0LVDS1:
534 		return VIA_LVDS1;
535 
536 	case INTERFACE_LVDS1:
537 		return VIA_LVDS2;
538 	}
539 
540 	return 0;
541 }
542 
543 /*Set IGA path for each device*/
544 void viafb_set_iga_path(void)
545 {
546 	int crt_iga_path = 0;
547 
548 	if (viafb_SAMM_ON == 1) {
549 		if (viafb_CRT_ON) {
550 			if (viafb_primary_dev == CRT_Device)
551 				crt_iga_path = IGA1;
552 			else
553 				crt_iga_path = IGA2;
554 		}
555 
556 		if (viafb_DVI_ON) {
557 			if (viafb_primary_dev == DVI_Device)
558 				viaparinfo->tmds_setting_info->iga_path = IGA1;
559 			else
560 				viaparinfo->tmds_setting_info->iga_path = IGA2;
561 		}
562 
563 		if (viafb_LCD_ON) {
564 			if (viafb_primary_dev == LCD_Device) {
565 				if (viafb_dual_fb &&
566 					(viaparinfo->chip_info->gfx_chip_name ==
567 					UNICHROME_CLE266)) {
568 					viaparinfo->
569 					lvds_setting_info->iga_path = IGA2;
570 					crt_iga_path = IGA1;
571 					viaparinfo->
572 					tmds_setting_info->iga_path = IGA1;
573 				} else
574 					viaparinfo->
575 					lvds_setting_info->iga_path = IGA1;
576 			} else {
577 				viaparinfo->lvds_setting_info->iga_path = IGA2;
578 			}
579 		}
580 		if (viafb_LCD2_ON) {
581 			if (LCD2_Device == viafb_primary_dev)
582 				viaparinfo->lvds_setting_info2->iga_path = IGA1;
583 			else
584 				viaparinfo->lvds_setting_info2->iga_path = IGA2;
585 		}
586 	} else {
587 		viafb_SAMM_ON = 0;
588 
589 		if (viafb_CRT_ON && viafb_LCD_ON) {
590 			crt_iga_path = IGA1;
591 			viaparinfo->lvds_setting_info->iga_path = IGA2;
592 		} else if (viafb_CRT_ON && viafb_DVI_ON) {
593 			crt_iga_path = IGA1;
594 			viaparinfo->tmds_setting_info->iga_path = IGA2;
595 		} else if (viafb_LCD_ON && viafb_DVI_ON) {
596 			viaparinfo->tmds_setting_info->iga_path = IGA1;
597 			viaparinfo->lvds_setting_info->iga_path = IGA2;
598 		} else if (viafb_LCD_ON && viafb_LCD2_ON) {
599 			viaparinfo->lvds_setting_info->iga_path = IGA2;
600 			viaparinfo->lvds_setting_info2->iga_path = IGA2;
601 		} else if (viafb_CRT_ON) {
602 			crt_iga_path = IGA1;
603 		} else if (viafb_LCD_ON) {
604 			viaparinfo->lvds_setting_info->iga_path = IGA2;
605 		} else if (viafb_DVI_ON) {
606 			viaparinfo->tmds_setting_info->iga_path = IGA1;
607 		}
608 	}
609 
610 	viaparinfo->shared->iga1_devices = 0;
611 	viaparinfo->shared->iga2_devices = 0;
612 	if (viafb_CRT_ON) {
613 		if (crt_iga_path == IGA1)
614 			viaparinfo->shared->iga1_devices |= VIA_CRT;
615 		else
616 			viaparinfo->shared->iga2_devices |= VIA_CRT;
617 	}
618 
619 	if (viafb_DVI_ON) {
620 		if (viaparinfo->tmds_setting_info->iga_path == IGA1)
621 			viaparinfo->shared->iga1_devices |= get_dvi_devices(
622 				viaparinfo->chip_info->
623 				tmds_chip_info.output_interface);
624 		else
625 			viaparinfo->shared->iga2_devices |= get_dvi_devices(
626 				viaparinfo->chip_info->
627 				tmds_chip_info.output_interface);
628 	}
629 
630 	if (viafb_LCD_ON) {
631 		if (viaparinfo->lvds_setting_info->iga_path == IGA1)
632 			viaparinfo->shared->iga1_devices |= get_lcd_devices(
633 				viaparinfo->chip_info->
634 				lvds_chip_info.output_interface);
635 		else
636 			viaparinfo->shared->iga2_devices |= get_lcd_devices(
637 				viaparinfo->chip_info->
638 				lvds_chip_info.output_interface);
639 	}
640 
641 	if (viafb_LCD2_ON) {
642 		if (viaparinfo->lvds_setting_info2->iga_path == IGA1)
643 			viaparinfo->shared->iga1_devices |= get_lcd_devices(
644 				viaparinfo->chip_info->
645 				lvds_chip_info2.output_interface);
646 		else
647 			viaparinfo->shared->iga2_devices |= get_lcd_devices(
648 				viaparinfo->chip_info->
649 				lvds_chip_info2.output_interface);
650 	}
651 
652 	/* looks like the OLPC has its display wired to DVP1 and LVDS2 */
653 	if (machine_is_olpc())
654 		viaparinfo->shared->iga2_devices = VIA_DVP1 | VIA_LVDS2;
655 }
656 
657 static void set_color_register(u8 index, u8 red, u8 green, u8 blue)
658 {
659 	outb(0xFF, 0x3C6); /* bit mask of palette */
660 	outb(index, 0x3C8);
661 	outb(red, 0x3C9);
662 	outb(green, 0x3C9);
663 	outb(blue, 0x3C9);
664 }
665 
666 void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue)
667 {
668 	viafb_write_reg_mask(0x1A, VIASR, 0x00, 0x01);
669 	set_color_register(index, red, green, blue);
670 }
671 
672 void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue)
673 {
674 	viafb_write_reg_mask(0x1A, VIASR, 0x01, 0x01);
675 	set_color_register(index, red, green, blue);
676 }
677 
678 static void set_source_common(u8 index, u8 offset, u8 iga)
679 {
680 	u8 value, mask = 1 << offset;
681 
682 	switch (iga) {
683 	case IGA1:
684 		value = 0x00;
685 		break;
686 	case IGA2:
687 		value = mask;
688 		break;
689 	default:
690 		printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
691 		return;
692 	}
693 
694 	via_write_reg_mask(VIACR, index, value, mask);
695 }
696 
697 static void set_crt_source(u8 iga)
698 {
699 	u8 value;
700 
701 	switch (iga) {
702 	case IGA1:
703 		value = 0x00;
704 		break;
705 	case IGA2:
706 		value = 0x40;
707 		break;
708 	default:
709 		printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
710 		return;
711 	}
712 
713 	via_write_reg_mask(VIASR, 0x16, value, 0x40);
714 }
715 
716 static inline void set_ldvp0_source(u8 iga)
717 {
718 	set_source_common(0x6C, 7, iga);
719 }
720 
721 static inline void set_ldvp1_source(u8 iga)
722 {
723 	set_source_common(0x93, 7, iga);
724 }
725 
726 static inline void set_dvp0_source(u8 iga)
727 {
728 	set_source_common(0x96, 4, iga);
729 }
730 
731 static inline void set_dvp1_source(u8 iga)
732 {
733 	set_source_common(0x9B, 4, iga);
734 }
735 
736 static inline void set_lvds1_source(u8 iga)
737 {
738 	set_source_common(0x99, 4, iga);
739 }
740 
741 static inline void set_lvds2_source(u8 iga)
742 {
743 	set_source_common(0x97, 4, iga);
744 }
745 
746 void via_set_source(u32 devices, u8 iga)
747 {
748 	if (devices & VIA_LDVP0)
749 		set_ldvp0_source(iga);
750 	if (devices & VIA_LDVP1)
751 		set_ldvp1_source(iga);
752 	if (devices & VIA_DVP0)
753 		set_dvp0_source(iga);
754 	if (devices & VIA_CRT)
755 		set_crt_source(iga);
756 	if (devices & VIA_DVP1)
757 		set_dvp1_source(iga);
758 	if (devices & VIA_LVDS1)
759 		set_lvds1_source(iga);
760 	if (devices & VIA_LVDS2)
761 		set_lvds2_source(iga);
762 }
763 
764 static void set_crt_state(u8 state)
765 {
766 	u8 value;
767 
768 	switch (state) {
769 	case VIA_STATE_ON:
770 		value = 0x00;
771 		break;
772 	case VIA_STATE_STANDBY:
773 		value = 0x10;
774 		break;
775 	case VIA_STATE_SUSPEND:
776 		value = 0x20;
777 		break;
778 	case VIA_STATE_OFF:
779 		value = 0x30;
780 		break;
781 	default:
782 		return;
783 	}
784 
785 	via_write_reg_mask(VIACR, 0x36, value, 0x30);
786 }
787 
788 static void set_dvp0_state(u8 state)
789 {
790 	u8 value;
791 
792 	switch (state) {
793 	case VIA_STATE_ON:
794 		value = 0xC0;
795 		break;
796 	case VIA_STATE_OFF:
797 		value = 0x00;
798 		break;
799 	default:
800 		return;
801 	}
802 
803 	via_write_reg_mask(VIASR, 0x1E, value, 0xC0);
804 }
805 
806 static void set_dvp1_state(u8 state)
807 {
808 	u8 value;
809 
810 	switch (state) {
811 	case VIA_STATE_ON:
812 		value = 0x30;
813 		break;
814 	case VIA_STATE_OFF:
815 		value = 0x00;
816 		break;
817 	default:
818 		return;
819 	}
820 
821 	via_write_reg_mask(VIASR, 0x1E, value, 0x30);
822 }
823 
824 static void set_lvds1_state(u8 state)
825 {
826 	u8 value;
827 
828 	switch (state) {
829 	case VIA_STATE_ON:
830 		value = 0x03;
831 		break;
832 	case VIA_STATE_OFF:
833 		value = 0x00;
834 		break;
835 	default:
836 		return;
837 	}
838 
839 	via_write_reg_mask(VIASR, 0x2A, value, 0x03);
840 }
841 
842 static void set_lvds2_state(u8 state)
843 {
844 	u8 value;
845 
846 	switch (state) {
847 	case VIA_STATE_ON:
848 		value = 0x0C;
849 		break;
850 	case VIA_STATE_OFF:
851 		value = 0x00;
852 		break;
853 	default:
854 		return;
855 	}
856 
857 	via_write_reg_mask(VIASR, 0x2A, value, 0x0C);
858 }
859 
860 void via_set_state(u32 devices, u8 state)
861 {
862 	/*
863 	TODO: Can we enable/disable these devices? How?
864 	if (devices & VIA_LDVP0)
865 	if (devices & VIA_LDVP1)
866 	*/
867 	if (devices & VIA_DVP0)
868 		set_dvp0_state(state);
869 	if (devices & VIA_CRT)
870 		set_crt_state(state);
871 	if (devices & VIA_DVP1)
872 		set_dvp1_state(state);
873 	if (devices & VIA_LVDS1)
874 		set_lvds1_state(state);
875 	if (devices & VIA_LVDS2)
876 		set_lvds2_state(state);
877 }
878 
879 void via_set_sync_polarity(u32 devices, u8 polarity)
880 {
881 	if (polarity & ~(VIA_HSYNC_NEGATIVE | VIA_VSYNC_NEGATIVE)) {
882 		printk(KERN_WARNING "viafb: Unsupported polarity: %d\n",
883 			polarity);
884 		return;
885 	}
886 
887 	if (devices & VIA_CRT)
888 		via_write_misc_reg_mask(polarity << 6, 0xC0);
889 	if (devices & VIA_DVP1)
890 		via_write_reg_mask(VIACR, 0x9B, polarity << 5, 0x60);
891 	if (devices & VIA_LVDS1)
892 		via_write_reg_mask(VIACR, 0x99, polarity << 5, 0x60);
893 	if (devices & VIA_LVDS2)
894 		via_write_reg_mask(VIACR, 0x97, polarity << 5, 0x60);
895 }
896 
897 u32 via_parse_odev(char *input, char **end)
898 {
899 	char *ptr = input;
900 	u32 odev = 0;
901 	bool next = true;
902 	int i, len;
903 
904 	while (next) {
905 		next = false;
906 		for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {
907 			len = strlen(device_mapping[i].name);
908 			if (!strncmp(ptr, device_mapping[i].name, len)) {
909 				odev |= device_mapping[i].device;
910 				ptr += len;
911 				if (*ptr == ',') {
912 					ptr++;
913 					next = true;
914 				}
915 			}
916 		}
917 	}
918 
919 	*end = ptr;
920 	return odev;
921 }
922 
923 void via_odev_to_seq(struct seq_file *m, u32 odev)
924 {
925 	int i, count = 0;
926 
927 	for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {
928 		if (odev & device_mapping[i].device) {
929 			if (count > 0)
930 				seq_putc(m, ',');
931 
932 			seq_puts(m, device_mapping[i].name);
933 			count++;
934 		}
935 	}
936 
937 	seq_putc(m, '\n');
938 }
939 
940 static void load_fix_bit_crtc_reg(void)
941 {
942 	viafb_unlock_crt();
943 
944 	/* always set to 1 */
945 	viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);
946 	/* line compare should set all bits = 1 (extend modes) */
947 	viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);
948 	/* line compare should set all bits = 1 (extend modes) */
949 	viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);
950 	/*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
951 
952 	viafb_lock_crt();
953 
954 	/* If K8M800, enable Prefetch Mode. */
955 	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
956 		|| (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890))
957 		viafb_write_reg_mask(CR33, VIACR, 0x08, BIT3);
958 	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
959 	    && (viaparinfo->chip_info->gfx_chip_revision == CLE266_REVISION_AX))
960 		viafb_write_reg_mask(SR1A, VIASR, 0x02, BIT1);
961 
962 }
963 
964 void viafb_load_reg(int timing_value, int viafb_load_reg_num,
965 	struct io_register *reg,
966 	      int io_type)
967 {
968 	int reg_mask;
969 	int bit_num = 0;
970 	int data;
971 	int i, j;
972 	int shift_next_reg;
973 	int start_index, end_index, cr_index;
974 	u16 get_bit;
975 
976 	for (i = 0; i < viafb_load_reg_num; i++) {
977 		reg_mask = 0;
978 		data = 0;
979 		start_index = reg[i].start_bit;
980 		end_index = reg[i].end_bit;
981 		cr_index = reg[i].io_addr;
982 
983 		shift_next_reg = bit_num;
984 		for (j = start_index; j <= end_index; j++) {
985 			/*if (bit_num==8) timing_value = timing_value >>8; */
986 			reg_mask = reg_mask | (BIT0 << j);
987 			get_bit = (timing_value & (BIT0 << bit_num));
988 			data =
989 			    data | ((get_bit >> shift_next_reg) << start_index);
990 			bit_num++;
991 		}
992 		if (io_type == VIACR)
993 			viafb_write_reg_mask(cr_index, VIACR, data, reg_mask);
994 		else
995 			viafb_write_reg_mask(cr_index, VIASR, data, reg_mask);
996 	}
997 
998 }
999 
1000 /* Write Registers */
1001 void viafb_write_regx(struct io_reg RegTable[], int ItemNum)
1002 {
1003 	int i;
1004 
1005 	/*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */
1006 
1007 	for (i = 0; i < ItemNum; i++)
1008 		via_write_reg_mask(RegTable[i].port, RegTable[i].index,
1009 			RegTable[i].value, RegTable[i].mask);
1010 }
1011 
1012 void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
1013 {
1014 	int reg_value;
1015 	int viafb_load_reg_num;
1016 	struct io_register *reg = NULL;
1017 
1018 	switch (set_iga) {
1019 	case IGA1:
1020 		reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
1021 		viafb_load_reg_num = fetch_count_reg.
1022 			iga1_fetch_count_reg.reg_num;
1023 		reg = fetch_count_reg.iga1_fetch_count_reg.reg;
1024 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1025 		break;
1026 	case IGA2:
1027 		reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
1028 		viafb_load_reg_num = fetch_count_reg.
1029 			iga2_fetch_count_reg.reg_num;
1030 		reg = fetch_count_reg.iga2_fetch_count_reg.reg;
1031 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1032 		break;
1033 	}
1034 
1035 }
1036 
1037 void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
1038 {
1039 	int reg_value;
1040 	int viafb_load_reg_num;
1041 	struct io_register *reg = NULL;
1042 	int iga1_fifo_max_depth = 0, iga1_fifo_threshold =
1043 	    0, iga1_fifo_high_threshold = 0, iga1_display_queue_expire_num = 0;
1044 	int iga2_fifo_max_depth = 0, iga2_fifo_threshold =
1045 	    0, iga2_fifo_high_threshold = 0, iga2_display_queue_expire_num = 0;
1046 
1047 	if (set_iga == IGA1) {
1048 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1049 			iga1_fifo_max_depth = K800_IGA1_FIFO_MAX_DEPTH;
1050 			iga1_fifo_threshold = K800_IGA1_FIFO_THRESHOLD;
1051 			iga1_fifo_high_threshold =
1052 			    K800_IGA1_FIFO_HIGH_THRESHOLD;
1053 			/* If resolution > 1280x1024, expire length = 64, else
1054 			   expire length = 128 */
1055 			if ((hor_active > 1280) && (ver_active > 1024))
1056 				iga1_display_queue_expire_num = 16;
1057 			else
1058 				iga1_display_queue_expire_num =
1059 				    K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1060 
1061 		}
1062 
1063 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
1064 			iga1_fifo_max_depth = P880_IGA1_FIFO_MAX_DEPTH;
1065 			iga1_fifo_threshold = P880_IGA1_FIFO_THRESHOLD;
1066 			iga1_fifo_high_threshold =
1067 			    P880_IGA1_FIFO_HIGH_THRESHOLD;
1068 			iga1_display_queue_expire_num =
1069 			    P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1070 
1071 			/* If resolution > 1280x1024, expire length = 64, else
1072 			   expire length = 128 */
1073 			if ((hor_active > 1280) && (ver_active > 1024))
1074 				iga1_display_queue_expire_num = 16;
1075 			else
1076 				iga1_display_queue_expire_num =
1077 				    P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1078 		}
1079 
1080 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
1081 			iga1_fifo_max_depth = CN700_IGA1_FIFO_MAX_DEPTH;
1082 			iga1_fifo_threshold = CN700_IGA1_FIFO_THRESHOLD;
1083 			iga1_fifo_high_threshold =
1084 			    CN700_IGA1_FIFO_HIGH_THRESHOLD;
1085 
1086 			/* If resolution > 1280x1024, expire length = 64,
1087 			   else expire length = 128 */
1088 			if ((hor_active > 1280) && (ver_active > 1024))
1089 				iga1_display_queue_expire_num = 16;
1090 			else
1091 				iga1_display_queue_expire_num =
1092 				    CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1093 		}
1094 
1095 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1096 			iga1_fifo_max_depth = CX700_IGA1_FIFO_MAX_DEPTH;
1097 			iga1_fifo_threshold = CX700_IGA1_FIFO_THRESHOLD;
1098 			iga1_fifo_high_threshold =
1099 			    CX700_IGA1_FIFO_HIGH_THRESHOLD;
1100 			iga1_display_queue_expire_num =
1101 			    CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1102 		}
1103 
1104 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
1105 			iga1_fifo_max_depth = K8M890_IGA1_FIFO_MAX_DEPTH;
1106 			iga1_fifo_threshold = K8M890_IGA1_FIFO_THRESHOLD;
1107 			iga1_fifo_high_threshold =
1108 			    K8M890_IGA1_FIFO_HIGH_THRESHOLD;
1109 			iga1_display_queue_expire_num =
1110 			    K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1111 		}
1112 
1113 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
1114 			iga1_fifo_max_depth = P4M890_IGA1_FIFO_MAX_DEPTH;
1115 			iga1_fifo_threshold = P4M890_IGA1_FIFO_THRESHOLD;
1116 			iga1_fifo_high_threshold =
1117 			    P4M890_IGA1_FIFO_HIGH_THRESHOLD;
1118 			iga1_display_queue_expire_num =
1119 			    P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1120 		}
1121 
1122 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
1123 			iga1_fifo_max_depth = P4M900_IGA1_FIFO_MAX_DEPTH;
1124 			iga1_fifo_threshold = P4M900_IGA1_FIFO_THRESHOLD;
1125 			iga1_fifo_high_threshold =
1126 			    P4M900_IGA1_FIFO_HIGH_THRESHOLD;
1127 			iga1_display_queue_expire_num =
1128 			    P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1129 		}
1130 
1131 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
1132 			iga1_fifo_max_depth = VX800_IGA1_FIFO_MAX_DEPTH;
1133 			iga1_fifo_threshold = VX800_IGA1_FIFO_THRESHOLD;
1134 			iga1_fifo_high_threshold =
1135 			    VX800_IGA1_FIFO_HIGH_THRESHOLD;
1136 			iga1_display_queue_expire_num =
1137 			    VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1138 		}
1139 
1140 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
1141 			iga1_fifo_max_depth = VX855_IGA1_FIFO_MAX_DEPTH;
1142 			iga1_fifo_threshold = VX855_IGA1_FIFO_THRESHOLD;
1143 			iga1_fifo_high_threshold =
1144 			    VX855_IGA1_FIFO_HIGH_THRESHOLD;
1145 			iga1_display_queue_expire_num =
1146 			    VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1147 		}
1148 
1149 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {
1150 			iga1_fifo_max_depth = VX900_IGA1_FIFO_MAX_DEPTH;
1151 			iga1_fifo_threshold = VX900_IGA1_FIFO_THRESHOLD;
1152 			iga1_fifo_high_threshold =
1153 			    VX900_IGA1_FIFO_HIGH_THRESHOLD;
1154 			iga1_display_queue_expire_num =
1155 			    VX900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1156 		}
1157 
1158 		/* Set Display FIFO Depath Select */
1159 		reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);
1160 		viafb_load_reg_num =
1161 		    display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg_num;
1162 		reg = display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg;
1163 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1164 
1165 		/* Set Display FIFO Threshold Select */
1166 		reg_value = IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold);
1167 		viafb_load_reg_num =
1168 		    fifo_threshold_select_reg.
1169 		    iga1_fifo_threshold_select_reg.reg_num;
1170 		reg =
1171 		    fifo_threshold_select_reg.
1172 		    iga1_fifo_threshold_select_reg.reg;
1173 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1174 
1175 		/* Set FIFO High Threshold Select */
1176 		reg_value =
1177 		    IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold);
1178 		viafb_load_reg_num =
1179 		    fifo_high_threshold_select_reg.
1180 		    iga1_fifo_high_threshold_select_reg.reg_num;
1181 		reg =
1182 		    fifo_high_threshold_select_reg.
1183 		    iga1_fifo_high_threshold_select_reg.reg;
1184 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1185 
1186 		/* Set Display Queue Expire Num */
1187 		reg_value =
1188 		    IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1189 		    (iga1_display_queue_expire_num);
1190 		viafb_load_reg_num =
1191 		    display_queue_expire_num_reg.
1192 		    iga1_display_queue_expire_num_reg.reg_num;
1193 		reg =
1194 		    display_queue_expire_num_reg.
1195 		    iga1_display_queue_expire_num_reg.reg;
1196 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1197 
1198 	} else {
1199 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1200 			iga2_fifo_max_depth = K800_IGA2_FIFO_MAX_DEPTH;
1201 			iga2_fifo_threshold = K800_IGA2_FIFO_THRESHOLD;
1202 			iga2_fifo_high_threshold =
1203 			    K800_IGA2_FIFO_HIGH_THRESHOLD;
1204 
1205 			/* If resolution > 1280x1024, expire length = 64,
1206 			   else  expire length = 128 */
1207 			if ((hor_active > 1280) && (ver_active > 1024))
1208 				iga2_display_queue_expire_num = 16;
1209 			else
1210 				iga2_display_queue_expire_num =
1211 				    K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1212 		}
1213 
1214 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
1215 			iga2_fifo_max_depth = P880_IGA2_FIFO_MAX_DEPTH;
1216 			iga2_fifo_threshold = P880_IGA2_FIFO_THRESHOLD;
1217 			iga2_fifo_high_threshold =
1218 			    P880_IGA2_FIFO_HIGH_THRESHOLD;
1219 
1220 			/* If resolution > 1280x1024, expire length = 64,
1221 			   else  expire length = 128 */
1222 			if ((hor_active > 1280) && (ver_active > 1024))
1223 				iga2_display_queue_expire_num = 16;
1224 			else
1225 				iga2_display_queue_expire_num =
1226 				    P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1227 		}
1228 
1229 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
1230 			iga2_fifo_max_depth = CN700_IGA2_FIFO_MAX_DEPTH;
1231 			iga2_fifo_threshold = CN700_IGA2_FIFO_THRESHOLD;
1232 			iga2_fifo_high_threshold =
1233 			    CN700_IGA2_FIFO_HIGH_THRESHOLD;
1234 
1235 			/* If resolution > 1280x1024, expire length = 64,
1236 			   else expire length = 128 */
1237 			if ((hor_active > 1280) && (ver_active > 1024))
1238 				iga2_display_queue_expire_num = 16;
1239 			else
1240 				iga2_display_queue_expire_num =
1241 				    CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1242 		}
1243 
1244 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1245 			iga2_fifo_max_depth = CX700_IGA2_FIFO_MAX_DEPTH;
1246 			iga2_fifo_threshold = CX700_IGA2_FIFO_THRESHOLD;
1247 			iga2_fifo_high_threshold =
1248 			    CX700_IGA2_FIFO_HIGH_THRESHOLD;
1249 			iga2_display_queue_expire_num =
1250 			    CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1251 		}
1252 
1253 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
1254 			iga2_fifo_max_depth = K8M890_IGA2_FIFO_MAX_DEPTH;
1255 			iga2_fifo_threshold = K8M890_IGA2_FIFO_THRESHOLD;
1256 			iga2_fifo_high_threshold =
1257 			    K8M890_IGA2_FIFO_HIGH_THRESHOLD;
1258 			iga2_display_queue_expire_num =
1259 			    K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1260 		}
1261 
1262 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
1263 			iga2_fifo_max_depth = P4M890_IGA2_FIFO_MAX_DEPTH;
1264 			iga2_fifo_threshold = P4M890_IGA2_FIFO_THRESHOLD;
1265 			iga2_fifo_high_threshold =
1266 			    P4M890_IGA2_FIFO_HIGH_THRESHOLD;
1267 			iga2_display_queue_expire_num =
1268 			    P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1269 		}
1270 
1271 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
1272 			iga2_fifo_max_depth = P4M900_IGA2_FIFO_MAX_DEPTH;
1273 			iga2_fifo_threshold = P4M900_IGA2_FIFO_THRESHOLD;
1274 			iga2_fifo_high_threshold =
1275 			    P4M900_IGA2_FIFO_HIGH_THRESHOLD;
1276 			iga2_display_queue_expire_num =
1277 			    P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1278 		}
1279 
1280 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
1281 			iga2_fifo_max_depth = VX800_IGA2_FIFO_MAX_DEPTH;
1282 			iga2_fifo_threshold = VX800_IGA2_FIFO_THRESHOLD;
1283 			iga2_fifo_high_threshold =
1284 			    VX800_IGA2_FIFO_HIGH_THRESHOLD;
1285 			iga2_display_queue_expire_num =
1286 			    VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1287 		}
1288 
1289 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
1290 			iga2_fifo_max_depth = VX855_IGA2_FIFO_MAX_DEPTH;
1291 			iga2_fifo_threshold = VX855_IGA2_FIFO_THRESHOLD;
1292 			iga2_fifo_high_threshold =
1293 			    VX855_IGA2_FIFO_HIGH_THRESHOLD;
1294 			iga2_display_queue_expire_num =
1295 			    VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1296 		}
1297 
1298 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {
1299 			iga2_fifo_max_depth = VX900_IGA2_FIFO_MAX_DEPTH;
1300 			iga2_fifo_threshold = VX900_IGA2_FIFO_THRESHOLD;
1301 			iga2_fifo_high_threshold =
1302 			    VX900_IGA2_FIFO_HIGH_THRESHOLD;
1303 			iga2_display_queue_expire_num =
1304 			    VX900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1305 		}
1306 
1307 		if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1308 			/* Set Display FIFO Depath Select */
1309 			reg_value =
1310 			    IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth)
1311 			    - 1;
1312 			/* Patch LCD in IGA2 case */
1313 			viafb_load_reg_num =
1314 			    display_fifo_depth_reg.
1315 			    iga2_fifo_depth_select_reg.reg_num;
1316 			reg =
1317 			    display_fifo_depth_reg.
1318 			    iga2_fifo_depth_select_reg.reg;
1319 			viafb_load_reg(reg_value,
1320 				viafb_load_reg_num, reg, VIACR);
1321 		} else {
1322 
1323 			/* Set Display FIFO Depath Select */
1324 			reg_value =
1325 			    IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth);
1326 			viafb_load_reg_num =
1327 			    display_fifo_depth_reg.
1328 			    iga2_fifo_depth_select_reg.reg_num;
1329 			reg =
1330 			    display_fifo_depth_reg.
1331 			    iga2_fifo_depth_select_reg.reg;
1332 			viafb_load_reg(reg_value,
1333 				viafb_load_reg_num, reg, VIACR);
1334 		}
1335 
1336 		/* Set Display FIFO Threshold Select */
1337 		reg_value = IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold);
1338 		viafb_load_reg_num =
1339 		    fifo_threshold_select_reg.
1340 		    iga2_fifo_threshold_select_reg.reg_num;
1341 		reg =
1342 		    fifo_threshold_select_reg.
1343 		    iga2_fifo_threshold_select_reg.reg;
1344 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1345 
1346 		/* Set FIFO High Threshold Select */
1347 		reg_value =
1348 		    IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold);
1349 		viafb_load_reg_num =
1350 		    fifo_high_threshold_select_reg.
1351 		    iga2_fifo_high_threshold_select_reg.reg_num;
1352 		reg =
1353 		    fifo_high_threshold_select_reg.
1354 		    iga2_fifo_high_threshold_select_reg.reg;
1355 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1356 
1357 		/* Set Display Queue Expire Num */
1358 		reg_value =
1359 		    IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1360 		    (iga2_display_queue_expire_num);
1361 		viafb_load_reg_num =
1362 		    display_queue_expire_num_reg.
1363 		    iga2_display_queue_expire_num_reg.reg_num;
1364 		reg =
1365 		    display_queue_expire_num_reg.
1366 		    iga2_display_queue_expire_num_reg.reg;
1367 		viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1368 
1369 	}
1370 
1371 }
1372 
1373 static struct via_pll_config get_pll_config(struct pll_limit *limits, int size,
1374 	int clk)
1375 {
1376 	struct via_pll_config cur, up, down, best = {0, 1, 0};
1377 	const u32 f0 = 14318180; /* X1 frequency */
1378 	int i, f;
1379 
1380 	for (i = 0; i < size; i++) {
1381 		cur.rshift = limits[i].rshift;
1382 		cur.divisor = limits[i].divisor;
1383 		cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift);
1384 		f = abs(get_pll_output_frequency(f0, cur) - clk);
1385 		up = down = cur;
1386 		up.multiplier++;
1387 		down.multiplier--;
1388 		if (abs(get_pll_output_frequency(f0, up) - clk) < f)
1389 			cur = up;
1390 		else if (abs(get_pll_output_frequency(f0, down) - clk) < f)
1391 			cur = down;
1392 
1393 		if (cur.multiplier < limits[i].multiplier_min)
1394 			cur.multiplier = limits[i].multiplier_min;
1395 		else if (cur.multiplier > limits[i].multiplier_max)
1396 			cur.multiplier = limits[i].multiplier_max;
1397 
1398 		f = abs(get_pll_output_frequency(f0, cur) - clk);
1399 		if (f < abs(get_pll_output_frequency(f0, best) - clk))
1400 			best = cur;
1401 	}
1402 
1403 	return best;
1404 }
1405 
1406 static struct via_pll_config get_best_pll_config(int clk)
1407 {
1408 	struct via_pll_config config;
1409 
1410 	switch (viaparinfo->chip_info->gfx_chip_name) {
1411 	case UNICHROME_CLE266:
1412 	case UNICHROME_K400:
1413 		config = get_pll_config(cle266_pll_limits,
1414 			ARRAY_SIZE(cle266_pll_limits), clk);
1415 		break;
1416 	case UNICHROME_K800:
1417 	case UNICHROME_PM800:
1418 	case UNICHROME_CN700:
1419 		config = get_pll_config(k800_pll_limits,
1420 			ARRAY_SIZE(k800_pll_limits), clk);
1421 		break;
1422 	case UNICHROME_CX700:
1423 	case UNICHROME_CN750:
1424 	case UNICHROME_K8M890:
1425 	case UNICHROME_P4M890:
1426 	case UNICHROME_P4M900:
1427 	case UNICHROME_VX800:
1428 		config = get_pll_config(cx700_pll_limits,
1429 			ARRAY_SIZE(cx700_pll_limits), clk);
1430 		break;
1431 	case UNICHROME_VX855:
1432 	case UNICHROME_VX900:
1433 		config = get_pll_config(vx855_pll_limits,
1434 			ARRAY_SIZE(vx855_pll_limits), clk);
1435 		break;
1436 	}
1437 
1438 	return config;
1439 }
1440 
1441 /* Set VCLK*/
1442 void viafb_set_vclock(u32 clk, int set_iga)
1443 {
1444 	struct via_pll_config config = get_best_pll_config(clk);
1445 
1446 	if (set_iga == IGA1)
1447 		clock.set_primary_pll(config);
1448 	if (set_iga == IGA2)
1449 		clock.set_secondary_pll(config);
1450 
1451 	/* Fire! */
1452 	via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
1453 }
1454 
1455 struct via_display_timing var_to_timing(const struct fb_var_screeninfo *var,
1456 	u16 cxres, u16 cyres)
1457 {
1458 	struct via_display_timing timing;
1459 	u16 dx = (var->xres - cxres) / 2, dy = (var->yres - cyres) / 2;
1460 
1461 	timing.hor_addr = cxres;
1462 	timing.hor_sync_start = timing.hor_addr + var->right_margin + dx;
1463 	timing.hor_sync_end = timing.hor_sync_start + var->hsync_len;
1464 	timing.hor_total = timing.hor_sync_end + var->left_margin + dx;
1465 	timing.hor_blank_start = timing.hor_addr + dx;
1466 	timing.hor_blank_end = timing.hor_total - dx;
1467 	timing.ver_addr = cyres;
1468 	timing.ver_sync_start = timing.ver_addr + var->lower_margin + dy;
1469 	timing.ver_sync_end = timing.ver_sync_start + var->vsync_len;
1470 	timing.ver_total = timing.ver_sync_end + var->upper_margin + dy;
1471 	timing.ver_blank_start = timing.ver_addr + dy;
1472 	timing.ver_blank_end = timing.ver_total - dy;
1473 	return timing;
1474 }
1475 
1476 void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
1477 	u16 cxres, u16 cyres, int iga)
1478 {
1479 	struct via_display_timing crt_reg = var_to_timing(var,
1480 		cxres ? cxres : var->xres, cyres ? cyres : var->yres);
1481 
1482 	if (iga == IGA1)
1483 		via_set_primary_timing(&crt_reg);
1484 	else if (iga == IGA2)
1485 		via_set_secondary_timing(&crt_reg);
1486 
1487 	viafb_load_fetch_count_reg(var->xres, var->bits_per_pixel / 8, iga);
1488 	if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266
1489 		&& viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)
1490 		viafb_load_FIFO_reg(iga, var->xres, var->yres);
1491 
1492 	viafb_set_vclock(PICOS2KHZ(var->pixclock) * 1000, iga);
1493 }
1494 
1495 void viafb_init_chip_info(int chip_type)
1496 {
1497 	via_clock_init(&clock, chip_type);
1498 	init_gfx_chip_info(chip_type);
1499 	init_tmds_chip_info();
1500 	init_lvds_chip_info();
1501 
1502 	/*Set IGA path for each device */
1503 	viafb_set_iga_path();
1504 
1505 	viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method;
1506 	viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode;
1507 	viaparinfo->lvds_setting_info2->display_method =
1508 		viaparinfo->lvds_setting_info->display_method;
1509 	viaparinfo->lvds_setting_info2->lcd_mode =
1510 		viaparinfo->lvds_setting_info->lcd_mode;
1511 }
1512 
1513 void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
1514 {
1515 	if (flag == 0) {
1516 		viaparinfo->tmds_setting_info->h_active = hres;
1517 		viaparinfo->tmds_setting_info->v_active = vres;
1518 	} else {
1519 
1520 		if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
1521 			viaparinfo->tmds_setting_info->h_active = hres;
1522 			viaparinfo->tmds_setting_info->v_active = vres;
1523 		}
1524 
1525 	}
1526 }
1527 
1528 static void init_gfx_chip_info(int chip_type)
1529 {
1530 	u8 tmp;
1531 
1532 	viaparinfo->chip_info->gfx_chip_name = chip_type;
1533 
1534 	/* Check revision of CLE266 Chip */
1535 	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
1536 		/* CR4F only define in CLE266.CX chip */
1537 		tmp = viafb_read_reg(VIACR, CR4F);
1538 		viafb_write_reg(CR4F, VIACR, 0x55);
1539 		if (viafb_read_reg(VIACR, CR4F) != 0x55)
1540 			viaparinfo->chip_info->gfx_chip_revision =
1541 			CLE266_REVISION_AX;
1542 		else
1543 			viaparinfo->chip_info->gfx_chip_revision =
1544 			CLE266_REVISION_CX;
1545 		/* restore orignal CR4F value */
1546 		viafb_write_reg(CR4F, VIACR, tmp);
1547 	}
1548 
1549 	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1550 		tmp = viafb_read_reg(VIASR, SR43);
1551 		DEBUG_MSG(KERN_INFO "SR43:%X\n", tmp);
1552 		if (tmp & 0x02) {
1553 			viaparinfo->chip_info->gfx_chip_revision =
1554 				CX700_REVISION_700M2;
1555 		} else if (tmp & 0x40) {
1556 			viaparinfo->chip_info->gfx_chip_revision =
1557 				CX700_REVISION_700M;
1558 		} else {
1559 			viaparinfo->chip_info->gfx_chip_revision =
1560 				CX700_REVISION_700;
1561 		}
1562 	}
1563 
1564 	/* Determine which 2D engine we have */
1565 	switch (viaparinfo->chip_info->gfx_chip_name) {
1566 	case UNICHROME_VX800:
1567 	case UNICHROME_VX855:
1568 	case UNICHROME_VX900:
1569 		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1;
1570 		break;
1571 	case UNICHROME_K8M890:
1572 	case UNICHROME_P4M900:
1573 		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H5;
1574 		break;
1575 	default:
1576 		viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H2;
1577 		break;
1578 	}
1579 }
1580 
1581 static void init_tmds_chip_info(void)
1582 {
1583 	viafb_tmds_trasmitter_identify();
1584 
1585 	if (INTERFACE_NONE == viaparinfo->chip_info->tmds_chip_info.
1586 		output_interface) {
1587 		switch (viaparinfo->chip_info->gfx_chip_name) {
1588 		case UNICHROME_CX700:
1589 			{
1590 				/* we should check support by hardware layout.*/
1591 				if ((viafb_display_hardware_layout ==
1592 				     HW_LAYOUT_DVI_ONLY)
1593 				    || (viafb_display_hardware_layout ==
1594 					HW_LAYOUT_LCD_DVI)) {
1595 					viaparinfo->chip_info->tmds_chip_info.
1596 					    output_interface = INTERFACE_TMDS;
1597 				} else {
1598 					viaparinfo->chip_info->tmds_chip_info.
1599 						output_interface =
1600 						INTERFACE_NONE;
1601 				}
1602 				break;
1603 			}
1604 		case UNICHROME_K8M890:
1605 		case UNICHROME_P4M900:
1606 		case UNICHROME_P4M890:
1607 			/* TMDS on PCIE, we set DFPLOW as default. */
1608 			viaparinfo->chip_info->tmds_chip_info.output_interface =
1609 			    INTERFACE_DFP_LOW;
1610 			break;
1611 		default:
1612 			{
1613 				/* set DVP1 default for DVI */
1614 				viaparinfo->chip_info->tmds_chip_info
1615 				.output_interface = INTERFACE_DVP1;
1616 			}
1617 		}
1618 	}
1619 
1620 	DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n",
1621 		  viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
1622 	viafb_init_dvi_size(&viaparinfo->shared->chip_info.tmds_chip_info,
1623 		&viaparinfo->shared->tmds_setting_info);
1624 }
1625 
1626 static void init_lvds_chip_info(void)
1627 {
1628 	viafb_lvds_trasmitter_identify();
1629 	viafb_init_lcd_size();
1630 	viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info,
1631 				   viaparinfo->lvds_setting_info);
1632 	if (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
1633 		viafb_init_lvds_output_interface(&viaparinfo->chip_info->
1634 			lvds_chip_info2, viaparinfo->lvds_setting_info2);
1635 	}
1636 	/*If CX700,two singel LCD, we need to reassign
1637 	   LCD interface to different LVDS port */
1638 	if ((UNICHROME_CX700 == viaparinfo->chip_info->gfx_chip_name)
1639 	    && (HW_LAYOUT_LCD1_LCD2 == viafb_display_hardware_layout)) {
1640 		if ((INTEGRATED_LVDS == viaparinfo->chip_info->lvds_chip_info.
1641 			lvds_chip_name) && (INTEGRATED_LVDS ==
1642 			viaparinfo->chip_info->
1643 			lvds_chip_info2.lvds_chip_name)) {
1644 			viaparinfo->chip_info->lvds_chip_info.output_interface =
1645 				INTERFACE_LVDS0;
1646 			viaparinfo->chip_info->lvds_chip_info2.
1647 				output_interface =
1648 			    INTERFACE_LVDS1;
1649 		}
1650 	}
1651 
1652 	DEBUG_MSG(KERN_INFO "LVDS Chip = %d\n",
1653 		  viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
1654 	DEBUG_MSG(KERN_INFO "LVDS1 output_interface = %d\n",
1655 		  viaparinfo->chip_info->lvds_chip_info.output_interface);
1656 	DEBUG_MSG(KERN_INFO "LVDS2 output_interface = %d\n",
1657 		  viaparinfo->chip_info->lvds_chip_info.output_interface);
1658 }
1659 
1660 void viafb_init_dac(int set_iga)
1661 {
1662 	int i;
1663 	u8 tmp;
1664 
1665 	if (set_iga == IGA1) {
1666 		/* access Primary Display's LUT */
1667 		viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
1668 		/* turn off LCK */
1669 		viafb_write_reg_mask(SR1B, VIASR, 0x00, BIT7 + BIT6);
1670 		for (i = 0; i < 256; i++) {
1671 			write_dac_reg(i, palLUT_table[i].red,
1672 				      palLUT_table[i].green,
1673 				      palLUT_table[i].blue);
1674 		}
1675 		/* turn on LCK */
1676 		viafb_write_reg_mask(SR1B, VIASR, 0xC0, BIT7 + BIT6);
1677 	} else {
1678 		tmp = viafb_read_reg(VIACR, CR6A);
1679 		/* access Secondary Display's LUT */
1680 		viafb_write_reg_mask(CR6A, VIACR, 0x40, BIT6);
1681 		viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
1682 		for (i = 0; i < 256; i++) {
1683 			write_dac_reg(i, palLUT_table[i].red,
1684 				      palLUT_table[i].green,
1685 				      palLUT_table[i].blue);
1686 		}
1687 		/* set IGA1 DAC for default */
1688 		viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
1689 		viafb_write_reg(CR6A, VIACR, tmp);
1690 	}
1691 }
1692 
1693 static void device_screen_off(void)
1694 {
1695 	/* turn off CRT screen (IGA1) */
1696 	viafb_write_reg_mask(SR01, VIASR, 0x20, BIT5);
1697 }
1698 
1699 static void device_screen_on(void)
1700 {
1701 	/* turn on CRT screen (IGA1) */
1702 	viafb_write_reg_mask(SR01, VIASR, 0x00, BIT5);
1703 }
1704 
1705 static void set_display_channel(void)
1706 {
1707 	/*If viafb_LCD2_ON, on cx700, internal lvds's information
1708 	is keeped on lvds_setting_info2 */
1709 	if (viafb_LCD2_ON &&
1710 		viaparinfo->lvds_setting_info2->device_lcd_dualedge) {
1711 		/* For dual channel LCD: */
1712 		/* Set to Dual LVDS channel. */
1713 		viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
1714 	} else if (viafb_LCD_ON && viafb_DVI_ON) {
1715 		/* For LCD+DFP: */
1716 		/* Set to LVDS1 + TMDS channel. */
1717 		viafb_write_reg_mask(CRD2, VIACR, 0x10, BIT4 + BIT5);
1718 	} else if (viafb_DVI_ON) {
1719 		/* Set to single TMDS channel. */
1720 		viafb_write_reg_mask(CRD2, VIACR, 0x30, BIT4 + BIT5);
1721 	} else if (viafb_LCD_ON) {
1722 		if (viaparinfo->lvds_setting_info->device_lcd_dualedge) {
1723 			/* For dual channel LCD: */
1724 			/* Set to Dual LVDS channel. */
1725 			viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
1726 		} else {
1727 			/* Set to LVDS0 + LVDS1 channel. */
1728 			viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT4 + BIT5);
1729 		}
1730 	}
1731 }
1732 
1733 static u8 get_sync(struct fb_var_screeninfo *var)
1734 {
1735 	u8 polarity = 0;
1736 
1737 	if (!(var->sync & FB_SYNC_HOR_HIGH_ACT))
1738 		polarity |= VIA_HSYNC_NEGATIVE;
1739 	if (!(var->sync & FB_SYNC_VERT_HIGH_ACT))
1740 		polarity |= VIA_VSYNC_NEGATIVE;
1741 	return polarity;
1742 }
1743 
1744 static void hw_init(void)
1745 {
1746 	int i;
1747 
1748 	inb(VIAStatus);
1749 	outb(0x00, VIAAR);
1750 
1751 	/* Write Common Setting for Video Mode */
1752 	viafb_write_regx(common_vga, ARRAY_SIZE(common_vga));
1753 	switch (viaparinfo->chip_info->gfx_chip_name) {
1754 	case UNICHROME_CLE266:
1755 		viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs);
1756 		break;
1757 
1758 	case UNICHROME_K400:
1759 		viafb_write_regx(KM400_ModeXregs, NUM_TOTAL_KM400_ModeXregs);
1760 		break;
1761 
1762 	case UNICHROME_K800:
1763 	case UNICHROME_PM800:
1764 		viafb_write_regx(CN400_ModeXregs, NUM_TOTAL_CN400_ModeXregs);
1765 		break;
1766 
1767 	case UNICHROME_CN700:
1768 	case UNICHROME_K8M890:
1769 	case UNICHROME_P4M890:
1770 	case UNICHROME_P4M900:
1771 		viafb_write_regx(CN700_ModeXregs, NUM_TOTAL_CN700_ModeXregs);
1772 		break;
1773 
1774 	case UNICHROME_CX700:
1775 	case UNICHROME_VX800:
1776 		viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
1777 		break;
1778 
1779 	case UNICHROME_VX855:
1780 	case UNICHROME_VX900:
1781 		viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs);
1782 		break;
1783 	}
1784 
1785 	/* magic required on VX900 for correct modesetting on IGA1 */
1786 	via_write_reg_mask(VIACR, 0x45, 0x00, 0x01);
1787 
1788 	/* probably this should go to the scaling code one day */
1789 	via_write_reg_mask(VIACR, 0xFD, 0, 0x80); /* VX900 hw scale on IGA2 */
1790 	viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters));
1791 
1792 	/* Fill VPIT Parameters */
1793 	/* Write Misc Register */
1794 	outb(VPIT.Misc, VIA_MISC_REG_WRITE);
1795 
1796 	/* Write Sequencer */
1797 	for (i = 1; i <= StdSR; i++)
1798 		via_write_reg(VIASR, i, VPIT.SR[i - 1]);
1799 
1800 	viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);
1801 
1802 	/* Write Graphic Controller */
1803 	for (i = 0; i < StdGR; i++)
1804 		via_write_reg(VIAGR, i, VPIT.GR[i]);
1805 
1806 	/* Write Attribute Controller */
1807 	for (i = 0; i < StdAR; i++) {
1808 		inb(VIAStatus);
1809 		outb(i, VIAAR);
1810 		outb(VPIT.AR[i], VIAAR);
1811 	}
1812 
1813 	inb(VIAStatus);
1814 	outb(0x20, VIAAR);
1815 
1816 	load_fix_bit_crtc_reg();
1817 }
1818 
1819 int viafb_setmode(void)
1820 {
1821 	int j, cxres = 0, cyres = 0;
1822 	int port;
1823 	u32 devices = viaparinfo->shared->iga1_devices
1824 		| viaparinfo->shared->iga2_devices;
1825 	u8 value, index, mask;
1826 	struct fb_var_screeninfo var2;
1827 
1828 	device_screen_off();
1829 	device_off();
1830 	via_set_state(devices, VIA_STATE_OFF);
1831 
1832 	hw_init();
1833 
1834 	/* Update Patch Register */
1835 
1836 	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266
1837 		|| viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)
1838 		&& viafbinfo->var.xres == 1024 && viafbinfo->var.yres == 768) {
1839 		for (j = 0; j < res_patch_table[0].table_length; j++) {
1840 			index = res_patch_table[0].io_reg_table[j].index;
1841 			port = res_patch_table[0].io_reg_table[j].port;
1842 			value = res_patch_table[0].io_reg_table[j].value;
1843 			mask = res_patch_table[0].io_reg_table[j].mask;
1844 			viafb_write_reg_mask(index, port, value, mask);
1845 		}
1846 	}
1847 
1848 	via_set_primary_pitch(viafbinfo->fix.line_length);
1849 	via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
1850 		: viafbinfo->fix.line_length);
1851 	via_set_primary_color_depth(viaparinfo->depth);
1852 	via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth
1853 		: viaparinfo->depth);
1854 	via_set_source(viaparinfo->shared->iga1_devices, IGA1);
1855 	via_set_source(viaparinfo->shared->iga2_devices, IGA2);
1856 	if (viaparinfo->shared->iga2_devices)
1857 		enable_second_display_channel();
1858 	else
1859 		disable_second_display_channel();
1860 
1861 	/* Update Refresh Rate Setting */
1862 
1863 	/* Clear On Screen */
1864 
1865 	if (viafb_dual_fb) {
1866 		var2 = viafbinfo1->var;
1867 	} else if (viafb_SAMM_ON) {
1868 		viafb_fill_var_timing_info(&var2, viafb_get_best_mode(
1869 			viafb_second_xres, viafb_second_yres, viafb_refresh1));
1870 		cxres = viafbinfo->var.xres;
1871 		cyres = viafbinfo->var.yres;
1872 		var2.bits_per_pixel = viafbinfo->var.bits_per_pixel;
1873 	}
1874 
1875 	/* CRT set mode */
1876 	if (viafb_CRT_ON) {
1877 		if (viaparinfo->shared->iga2_devices & VIA_CRT
1878 			&& viafb_SAMM_ON)
1879 			viafb_fill_crtc_timing(&var2, cxres, cyres, IGA2);
1880 		else
1881 			viafb_fill_crtc_timing(&viafbinfo->var, 0, 0,
1882 				(viaparinfo->shared->iga1_devices & VIA_CRT)
1883 				? IGA1 : IGA2);
1884 
1885 		/* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
1886 		to 8 alignment (1368),there is several pixels (2 pixels)
1887 		on right side of screen. */
1888 		if (viafbinfo->var.xres % 8) {
1889 			viafb_unlock_crt();
1890 			viafb_write_reg(CR02, VIACR,
1891 				viafb_read_reg(VIACR, CR02) - 1);
1892 			viafb_lock_crt();
1893 		}
1894 	}
1895 
1896 	if (viafb_DVI_ON) {
1897 		if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2
1898 			&& viafb_SAMM_ON)
1899 			viafb_dvi_set_mode(&var2, cxres, cyres, IGA2);
1900 		else
1901 			viafb_dvi_set_mode(&viafbinfo->var, 0, 0,
1902 				viaparinfo->tmds_setting_info->iga_path);
1903 	}
1904 
1905 	if (viafb_LCD_ON) {
1906 		if (viafb_SAMM_ON &&
1907 			(viaparinfo->lvds_setting_info->iga_path == IGA2)) {
1908 			viafb_lcd_set_mode(&var2, cxres, cyres,
1909 				viaparinfo->lvds_setting_info,
1910 				&viaparinfo->chip_info->lvds_chip_info);
1911 		} else {
1912 			/* IGA1 doesn't have LCD scaling, so set it center. */
1913 			if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
1914 				viaparinfo->lvds_setting_info->display_method =
1915 				    LCD_CENTERING;
1916 			}
1917 			viafb_lcd_set_mode(&viafbinfo->var, 0, 0,
1918 				viaparinfo->lvds_setting_info,
1919 				&viaparinfo->chip_info->lvds_chip_info);
1920 		}
1921 	}
1922 	if (viafb_LCD2_ON) {
1923 		if (viafb_SAMM_ON &&
1924 			(viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
1925 			viafb_lcd_set_mode(&var2, cxres, cyres,
1926 				viaparinfo->lvds_setting_info2,
1927 				&viaparinfo->chip_info->lvds_chip_info2);
1928 		} else {
1929 			/* IGA1 doesn't have LCD scaling, so set it center. */
1930 			if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
1931 				viaparinfo->lvds_setting_info2->display_method =
1932 				    LCD_CENTERING;
1933 			}
1934 			viafb_lcd_set_mode(&viafbinfo->var, 0, 0,
1935 				viaparinfo->lvds_setting_info2,
1936 				&viaparinfo->chip_info->lvds_chip_info2);
1937 		}
1938 	}
1939 
1940 	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
1941 	    && (viafb_LCD_ON || viafb_DVI_ON))
1942 		set_display_channel();
1943 
1944 	/* If set mode normally, save resolution information for hot-plug . */
1945 	if (!viafb_hotplug) {
1946 		viafb_hotplug_Xres = viafbinfo->var.xres;
1947 		viafb_hotplug_Yres = viafbinfo->var.yres;
1948 		viafb_hotplug_bpp = viafbinfo->var.bits_per_pixel;
1949 		viafb_hotplug_refresh = viafb_refresh;
1950 
1951 		if (viafb_DVI_ON)
1952 			viafb_DeviceStatus = DVI_Device;
1953 		else
1954 			viafb_DeviceStatus = CRT_Device;
1955 	}
1956 	device_on();
1957 	if (!viafb_SAMM_ON)
1958 		via_set_sync_polarity(devices, get_sync(&viafbinfo->var));
1959 	else {
1960 		via_set_sync_polarity(viaparinfo->shared->iga1_devices,
1961 			get_sync(&viafbinfo->var));
1962 		via_set_sync_polarity(viaparinfo->shared->iga2_devices,
1963 			get_sync(&var2));
1964 	}
1965 
1966 	clock.set_engine_pll_state(VIA_STATE_ON);
1967 	clock.set_primary_clock_source(VIA_CLKSRC_X1, true);
1968 	clock.set_secondary_clock_source(VIA_CLKSRC_X1, true);
1969 
1970 #ifdef CONFIG_FB_VIA_X_COMPATIBILITY
1971 	clock.set_primary_pll_state(VIA_STATE_ON);
1972 	clock.set_primary_clock_state(VIA_STATE_ON);
1973 	clock.set_secondary_pll_state(VIA_STATE_ON);
1974 	clock.set_secondary_clock_state(VIA_STATE_ON);
1975 #else
1976 	if (viaparinfo->shared->iga1_devices) {
1977 		clock.set_primary_pll_state(VIA_STATE_ON);
1978 		clock.set_primary_clock_state(VIA_STATE_ON);
1979 	} else {
1980 		clock.set_primary_pll_state(VIA_STATE_OFF);
1981 		clock.set_primary_clock_state(VIA_STATE_OFF);
1982 	}
1983 
1984 	if (viaparinfo->shared->iga2_devices) {
1985 		clock.set_secondary_pll_state(VIA_STATE_ON);
1986 		clock.set_secondary_clock_state(VIA_STATE_ON);
1987 	} else {
1988 		clock.set_secondary_pll_state(VIA_STATE_OFF);
1989 		clock.set_secondary_clock_state(VIA_STATE_OFF);
1990 	}
1991 #endif /*CONFIG_FB_VIA_X_COMPATIBILITY*/
1992 
1993 	via_set_state(devices, VIA_STATE_ON);
1994 	device_screen_on();
1995 	return 1;
1996 }
1997 
1998 int viafb_get_refresh(int hres, int vres, u32 long_refresh)
1999 {
2000 	const struct fb_videomode *best;
2001 
2002 	best = viafb_get_best_mode(hres, vres, long_refresh);
2003 	if (!best)
2004 		return 60;
2005 
2006 	if (abs(best->refresh - long_refresh) > 3) {
2007 		if (hres == 1200 && vres == 900)
2008 			return 49; /* OLPC DCON only supports 50 Hz */
2009 		else
2010 			return 60;
2011 	}
2012 
2013 	return best->refresh;
2014 }
2015 
2016 static void device_off(void)
2017 {
2018 	viafb_dvi_disable();
2019 	viafb_lcd_disable();
2020 }
2021 
2022 static void device_on(void)
2023 {
2024 	if (viafb_DVI_ON == 1)
2025 		viafb_dvi_enable();
2026 	if (viafb_LCD_ON == 1)
2027 		viafb_lcd_enable();
2028 }
2029 
2030 static void enable_second_display_channel(void)
2031 {
2032 	/* to enable second display channel. */
2033 	viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
2034 	viafb_write_reg_mask(CR6A, VIACR, BIT7, BIT7);
2035 	viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2036 }
2037 
2038 static void disable_second_display_channel(void)
2039 {
2040 	/* to disable second display channel. */
2041 	viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
2042 	viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7);
2043 	viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2044 }
2045 
2046 void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
2047 					*p_gfx_dpa_setting)
2048 {
2049 	switch (output_interface) {
2050 	case INTERFACE_DVP0:
2051 		{
2052 			/* DVP0 Clock Polarity and Adjust: */
2053 			viafb_write_reg_mask(CR96, VIACR,
2054 				       p_gfx_dpa_setting->DVP0, 0x0F);
2055 
2056 			/* DVP0 Clock and Data Pads Driving: */
2057 			viafb_write_reg_mask(SR1E, VIASR,
2058 				       p_gfx_dpa_setting->DVP0ClockDri_S, BIT2);
2059 			viafb_write_reg_mask(SR2A, VIASR,
2060 				       p_gfx_dpa_setting->DVP0ClockDri_S1,
2061 				       BIT4);
2062 			viafb_write_reg_mask(SR1B, VIASR,
2063 				       p_gfx_dpa_setting->DVP0DataDri_S, BIT1);
2064 			viafb_write_reg_mask(SR2A, VIASR,
2065 				       p_gfx_dpa_setting->DVP0DataDri_S1, BIT5);
2066 			break;
2067 		}
2068 
2069 	case INTERFACE_DVP1:
2070 		{
2071 			/* DVP1 Clock Polarity and Adjust: */
2072 			viafb_write_reg_mask(CR9B, VIACR,
2073 				       p_gfx_dpa_setting->DVP1, 0x0F);
2074 
2075 			/* DVP1 Clock and Data Pads Driving: */
2076 			viafb_write_reg_mask(SR65, VIASR,
2077 				       p_gfx_dpa_setting->DVP1Driving, 0x0F);
2078 			break;
2079 		}
2080 
2081 	case INTERFACE_DFP_HIGH:
2082 		{
2083 			viafb_write_reg_mask(CR97, VIACR,
2084 				       p_gfx_dpa_setting->DFPHigh, 0x0F);
2085 			break;
2086 		}
2087 
2088 	case INTERFACE_DFP_LOW:
2089 		{
2090 			viafb_write_reg_mask(CR99, VIACR,
2091 				       p_gfx_dpa_setting->DFPLow, 0x0F);
2092 			break;
2093 		}
2094 
2095 	case INTERFACE_DFP:
2096 		{
2097 			viafb_write_reg_mask(CR97, VIACR,
2098 				       p_gfx_dpa_setting->DFPHigh, 0x0F);
2099 			viafb_write_reg_mask(CR99, VIACR,
2100 				       p_gfx_dpa_setting->DFPLow, 0x0F);
2101 			break;
2102 		}
2103 	}
2104 }
2105 
2106 void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
2107 	const struct fb_videomode *mode)
2108 {
2109 	var->pixclock = mode->pixclock;
2110 	var->xres = mode->xres;
2111 	var->yres = mode->yres;
2112 	var->left_margin = mode->left_margin;
2113 	var->right_margin = mode->right_margin;
2114 	var->hsync_len = mode->hsync_len;
2115 	var->upper_margin = mode->upper_margin;
2116 	var->lower_margin = mode->lower_margin;
2117 	var->vsync_len = mode->vsync_len;
2118 	var->sync = mode->sync;
2119 }
2120