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