aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via/lcd.c
diff options
context:
space:
mode:
authorJoseph Chan <JosephChan@via.com.tw>2008-10-16 01:03:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-16 14:21:41 -0400
commitac6c97e20f1befecd791feed57170ec6735dcce7 (patch)
tree3e63e1e5c0eec798d479d8eb093f8b960e404843 /drivers/video/via/lcd.c
parentc91b557ad0a4d4803874f8b908aa9732152b0f0b (diff)
viafb: lcd.c, lcd.h, lcdtbl.h
lcd.c, lcd.h: LVDS generic process. lcdtbl.h: patch register for simultaneous case. Signed-off-by: Joseph Chan <josephchan@via.com.tw> Cc: Krzysztof Helt <krzysztof.h1@poczta.fm> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/via/lcd.c')
-rw-r--r--drivers/video/via/lcd.c1821
1 files changed, 1821 insertions, 0 deletions
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
new file mode 100644
index 000000000000..6c7290a6a447
--- /dev/null
+++ b/drivers/video/via/lcd.c
@@ -0,0 +1,1821 @@
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 "global.h"
23#include "lcdtbl.h"
24
25static struct iga2_shadow_crtc_timing iga2_shadow_crtc_reg = {
26 /* IGA2 Shadow Horizontal Total */
27 {IGA2_SHADOW_HOR_TOTAL_REG_NUM, {{CR6D, 0, 7}, {CR71, 3, 3} } },
28 /* IGA2 Shadow Horizontal Blank End */
29 {IGA2_SHADOW_HOR_BLANK_END_REG_NUM, {{CR6E, 0, 7} } },
30 /* IGA2 Shadow Vertical Total */
31 {IGA2_SHADOW_VER_TOTAL_REG_NUM, {{CR6F, 0, 7}, {CR71, 0, 2} } },
32 /* IGA2 Shadow Vertical Addressable Video */
33 {IGA2_SHADOW_VER_ADDR_REG_NUM, {{CR70, 0, 7}, {CR71, 4, 6} } },
34 /* IGA2 Shadow Vertical Blank Start */
35 {IGA2_SHADOW_VER_BLANK_START_REG_NUM,
36 {{CR72, 0, 7}, {CR74, 4, 6} } },
37 /* IGA2 Shadow Vertical Blank End */
38 {IGA2_SHADOW_VER_BLANK_END_REG_NUM, {{CR73, 0, 7}, {CR74, 0, 2} } },
39 /* IGA2 Shadow Vertical Sync Start */
40 {IGA2_SHADOW_VER_SYNC_START_REG_NUM, {{CR75, 0, 7}, {CR76, 4, 6} } },
41 /* IGA2 Shadow Vertical Sync End */
42 {IGA2_SHADOW_VER_SYNC_END_REG_NUM, {{CR76, 0, 3} } }
43};
44
45static struct _lcd_scaling_factor lcd_scaling_factor = {
46 /* LCD Horizontal Scaling Factor Register */
47 {LCD_HOR_SCALING_FACTOR_REG_NUM,
48 {{CR9F, 0, 1}, {CR77, 0, 7}, {CR79, 4, 5} } },
49 /* LCD Vertical Scaling Factor Register */
50 {LCD_VER_SCALING_FACTOR_REG_NUM,
51 {{CR79, 3, 3}, {CR78, 0, 7}, {CR79, 6, 7} } }
52};
53static struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
54 /* LCD Horizontal Scaling Factor Register */
55 {LCD_HOR_SCALING_FACTOR_REG_NUM_CLE, {{CR77, 0, 7}, {CR79, 4, 5} } },
56 /* LCD Vertical Scaling Factor Register */
57 {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } }
58};
59
60static int check_lvds_chip(int device_id_subaddr, int device_id);
61static bool lvds_identify_integratedlvds(void);
62static int fp_id_to_vindex(int panel_id);
63static int lvds_register_read(int index);
64static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
65 int panel_vres);
66static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
67 int panel_id);
68static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
69 int panel_id);
70static void load_lcd_patch_regs(int set_hres, int set_vres,
71 int panel_id, int set_iga);
72static void via_pitch_alignment_patch_lcd(
73 struct lvds_setting_information *plvds_setting_info,
74 struct lvds_chip_information
75 *plvds_chip_info);
76static void lcd_patch_skew_dvp0(struct lvds_setting_information
77 *plvds_setting_info,
78 struct lvds_chip_information *plvds_chip_info);
79static void lcd_patch_skew_dvp1(struct lvds_setting_information
80 *plvds_setting_info,
81 struct lvds_chip_information *plvds_chip_info);
82static void lcd_patch_skew(struct lvds_setting_information
83 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
84
85static void integrated_lvds_disable(struct lvds_setting_information
86 *plvds_setting_info,
87 struct lvds_chip_information *plvds_chip_info);
88static void integrated_lvds_enable(struct lvds_setting_information
89 *plvds_setting_info,
90 struct lvds_chip_information *plvds_chip_info);
91static void lcd_powersequence_off(void);
92static void lcd_powersequence_on(void);
93static void fill_lcd_format(void);
94static void check_diport_of_integrated_lvds(
95 struct lvds_chip_information *plvds_chip_info,
96 struct lvds_setting_information
97 *plvds_setting_info);
98static struct display_timing lcd_centering_timging(struct display_timing
99 mode_crt_reg,
100 struct display_timing panel_crt_reg);
101static void load_crtc_shadow_timing(struct display_timing mode_timing,
102 struct display_timing panel_timing);
103static void viafb_load_scaling_factor_for_p4m900(int set_hres,
104 int set_vres, int panel_hres, int panel_vres);
105
106static int check_lvds_chip(int device_id_subaddr, int device_id)
107{
108 if (lvds_register_read(device_id_subaddr) == device_id)
109 return OK;
110 else
111 return FAIL;
112}
113
114void viafb_init_lcd_size(void)
115{
116 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
117 DEBUG_MSG(KERN_INFO
118 "viaparinfo->lvds_setting_info->get_lcd_size_method %d\n",
119 viaparinfo->lvds_setting_info->get_lcd_size_method);
120
121 switch (viaparinfo->lvds_setting_info->get_lcd_size_method) {
122 case GET_LCD_SIZE_BY_SYSTEM_BIOS:
123 break;
124 case GET_LCD_SZIE_BY_HW_STRAPPING:
125 break;
126 case GET_LCD_SIZE_BY_VGA_BIOS:
127 DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n");
128 viaparinfo->lvds_setting_info->lcd_panel_size =
129 fp_id_to_vindex(viafb_lcd_panel_id);
130 DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
131 viaparinfo->lvds_setting_info->lcd_panel_id);
132 DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n",
133 viaparinfo->lvds_setting_info->lcd_panel_size);
134 break;
135 case GET_LCD_SIZE_BY_USER_SETTING:
136 DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n");
137 viaparinfo->lvds_setting_info->lcd_panel_size =
138 fp_id_to_vindex(viafb_lcd_panel_id);
139 DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
140 viaparinfo->lvds_setting_info->lcd_panel_id);
141 DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n",
142 viaparinfo->lvds_setting_info->lcd_panel_size);
143 break;
144 default:
145 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n");
146 viaparinfo->lvds_setting_info->lcd_panel_id =
147 LCD_PANEL_ID1_800X600;
148 viaparinfo->lvds_setting_info->lcd_panel_size =
149 fp_id_to_vindex(LCD_PANEL_ID1_800X600);
150 }
151 viaparinfo->lvds_setting_info2->lcd_panel_id =
152 viaparinfo->lvds_setting_info->lcd_panel_id;
153 viaparinfo->lvds_setting_info2->lcd_panel_size =
154 viaparinfo->lvds_setting_info->lcd_panel_size;
155 viaparinfo->lvds_setting_info2->lcd_panel_hres =
156 viaparinfo->lvds_setting_info->lcd_panel_hres;
157 viaparinfo->lvds_setting_info2->lcd_panel_vres =
158 viaparinfo->lvds_setting_info->lcd_panel_vres;
159 viaparinfo->lvds_setting_info2->device_lcd_dualedge =
160 viaparinfo->lvds_setting_info->device_lcd_dualedge;
161 viaparinfo->lvds_setting_info2->LCDDithering =
162 viaparinfo->lvds_setting_info->LCDDithering;
163}
164
165static bool lvds_identify_integratedlvds(void)
166{
167 if (viafb_display_hardware_layout == HW_LAYOUT_LCD_EXTERNAL_LCD2) {
168 /* Two dual channel LCD (Internal LVDS + External LVDS): */
169 /* If we have an external LVDS, such as VT1636, we should
170 have its chip ID already. */
171 if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
172 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
173 INTEGRATED_LVDS;
174 DEBUG_MSG(KERN_INFO "Support two dual channel LVDS!\
175 (Internal LVDS + External LVDS)\n");
176 } else {
177 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
178 INTEGRATED_LVDS;
179 DEBUG_MSG(KERN_INFO "Not found external LVDS,\
180 so can't support two dual channel LVDS!\n");
181 }
182 } else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) {
183 /* Two single channel LCD (Internal LVDS + Internal LVDS): */
184 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
185 INTEGRATED_LVDS;
186 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
187 INTEGRATED_LVDS;
188 DEBUG_MSG(KERN_INFO "Support two single channel LVDS!\
189 (Internal LVDS + Internal LVDS)\n");
190 } else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) {
191 /* If we have found external LVDS, just use it,
192 otherwise, we will use internal LVDS as default. */
193 if (!viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
194 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
195 INTEGRATED_LVDS;
196 DEBUG_MSG(KERN_INFO "Found Integrated LVDS!\n");
197 }
198 } else {
199 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
200 NON_LVDS_TRANSMITTER;
201 DEBUG_MSG(KERN_INFO "Do not support LVDS!\n");
202 return false;
203 }
204
205 return true;
206}
207
208int viafb_lvds_trasmitter_identify(void)
209{
210 viaparinfo->i2c_stuff.i2c_port = I2CPORTINDEX;
211 if (viafb_lvds_identify_vt1636()) {
212 viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX;
213 DEBUG_MSG(KERN_INFO
214 "Found VIA VT1636 LVDS on port i2c 0x31 \n");
215 } else {
216 viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX;
217 if (viafb_lvds_identify_vt1636()) {
218 viaparinfo->chip_info->lvds_chip_info.i2c_port =
219 GPIOPORTINDEX;
220 DEBUG_MSG(KERN_INFO
221 "Found VIA VT1636 LVDS on port gpio 0x2c \n");
222 }
223 }
224
225 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
226 lvds_identify_integratedlvds();
227
228 if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
229 return true;
230 /* Check for VT1631: */
231 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = VT1631_LVDS;
232 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
233 VT1631_LVDS_I2C_ADDR;
234
235 if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID) != FAIL) {
236 DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n");
237 DEBUG_MSG(KERN_INFO "\n %2d",
238 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
239 DEBUG_MSG(KERN_INFO "\n %2d",
240 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
241 return OK;
242 }
243
244 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
245 NON_LVDS_TRANSMITTER;
246 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
247 VT1631_LVDS_I2C_ADDR;
248 return FAIL;
249}
250
251static int fp_id_to_vindex(int panel_id)
252{
253 DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
254
255 if (panel_id > LCD_PANEL_ID_MAXIMUM)
256 viafb_lcd_panel_id = panel_id =
257 viafb_read_reg(VIACR, CR3F) & 0x0F;
258
259 switch (panel_id) {
260 case 0x0:
261 viaparinfo->lvds_setting_info->lcd_panel_hres = 640;
262 viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
263 viaparinfo->lvds_setting_info->lcd_panel_id =
264 LCD_PANEL_ID0_640X480;
265 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
266 viaparinfo->lvds_setting_info->LCDDithering = 1;
267 return VIA_RES_640X480;
268 break;
269 case 0x1:
270 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
271 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
272 viaparinfo->lvds_setting_info->lcd_panel_id =
273 LCD_PANEL_ID1_800X600;
274 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
275 viaparinfo->lvds_setting_info->LCDDithering = 1;
276 return VIA_RES_800X600;
277 break;
278 case 0x2:
279 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
280 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
281 viaparinfo->lvds_setting_info->lcd_panel_id =
282 LCD_PANEL_ID2_1024X768;
283 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
284 viaparinfo->lvds_setting_info->LCDDithering = 1;
285 return VIA_RES_1024X768;
286 break;
287 case 0x3:
288 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
289 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
290 viaparinfo->lvds_setting_info->lcd_panel_id =
291 LCD_PANEL_ID3_1280X768;
292 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
293 viaparinfo->lvds_setting_info->LCDDithering = 1;
294 return VIA_RES_1280X768;
295 break;
296 case 0x4:
297 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
298 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
299 viaparinfo->lvds_setting_info->lcd_panel_id =
300 LCD_PANEL_ID4_1280X1024;
301 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
302 viaparinfo->lvds_setting_info->LCDDithering = 1;
303 return VIA_RES_1280X1024;
304 break;
305 case 0x5:
306 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
307 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
308 viaparinfo->lvds_setting_info->lcd_panel_id =
309 LCD_PANEL_ID5_1400X1050;
310 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
311 viaparinfo->lvds_setting_info->LCDDithering = 1;
312 return VIA_RES_1400X1050;
313 break;
314 case 0x6:
315 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
316 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
317 viaparinfo->lvds_setting_info->lcd_panel_id =
318 LCD_PANEL_ID6_1600X1200;
319 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
320 viaparinfo->lvds_setting_info->LCDDithering = 1;
321 return VIA_RES_1600X1200;
322 break;
323 case 0x8:
324 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
325 viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
326 viaparinfo->lvds_setting_info->lcd_panel_id =
327 LCD_PANEL_IDA_800X480;
328 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
329 viaparinfo->lvds_setting_info->LCDDithering = 1;
330 return VIA_RES_800X480;
331 break;
332 case 0x9:
333 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
334 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
335 viaparinfo->lvds_setting_info->lcd_panel_id =
336 LCD_PANEL_ID2_1024X768;
337 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
338 viaparinfo->lvds_setting_info->LCDDithering = 1;
339 return VIA_RES_1024X768;
340 break;
341 case 0xA:
342 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
343 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
344 viaparinfo->lvds_setting_info->lcd_panel_id =
345 LCD_PANEL_ID2_1024X768;
346 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
347 viaparinfo->lvds_setting_info->LCDDithering = 0;
348 return VIA_RES_1024X768;
349 break;
350 case 0xB:
351 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
352 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
353 viaparinfo->lvds_setting_info->lcd_panel_id =
354 LCD_PANEL_ID2_1024X768;
355 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
356 viaparinfo->lvds_setting_info->LCDDithering = 0;
357 return VIA_RES_1024X768;
358 break;
359 case 0xC:
360 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
361 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
362 viaparinfo->lvds_setting_info->lcd_panel_id =
363 LCD_PANEL_ID3_1280X768;
364 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
365 viaparinfo->lvds_setting_info->LCDDithering = 0;
366 return VIA_RES_1280X768;
367 break;
368 case 0xD:
369 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
370 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
371 viaparinfo->lvds_setting_info->lcd_panel_id =
372 LCD_PANEL_ID4_1280X1024;
373 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
374 viaparinfo->lvds_setting_info->LCDDithering = 0;
375 return VIA_RES_1280X1024;
376 break;
377 case 0xE:
378 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
379 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
380 viaparinfo->lvds_setting_info->lcd_panel_id =
381 LCD_PANEL_ID5_1400X1050;
382 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
383 viaparinfo->lvds_setting_info->LCDDithering = 0;
384 return VIA_RES_1400X1050;
385 break;
386 case 0xF:
387 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
388 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
389 viaparinfo->lvds_setting_info->lcd_panel_id =
390 LCD_PANEL_ID6_1600X1200;
391 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
392 viaparinfo->lvds_setting_info->LCDDithering = 0;
393 return VIA_RES_1600X1200;
394 break;
395 case 0x10:
396 viaparinfo->lvds_setting_info->lcd_panel_hres = 1366;
397 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
398 viaparinfo->lvds_setting_info->lcd_panel_id =
399 LCD_PANEL_ID7_1366X768;
400 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
401 viaparinfo->lvds_setting_info->LCDDithering = 0;
402 return VIA_RES_1368X768;
403 break;
404 case 0x11:
405 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
406 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
407 viaparinfo->lvds_setting_info->lcd_panel_id =
408 LCD_PANEL_ID8_1024X600;
409 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
410 viaparinfo->lvds_setting_info->LCDDithering = 1;
411 return VIA_RES_1024X600;
412 break;
413 case 0x12:
414 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
415 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
416 viaparinfo->lvds_setting_info->lcd_panel_id =
417 LCD_PANEL_ID3_1280X768;
418 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
419 viaparinfo->lvds_setting_info->LCDDithering = 1;
420 return VIA_RES_1280X768;
421 break;
422 case 0x13:
423 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
424 viaparinfo->lvds_setting_info->lcd_panel_vres = 800;
425 viaparinfo->lvds_setting_info->lcd_panel_id =
426 LCD_PANEL_ID9_1280X800;
427 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
428 viaparinfo->lvds_setting_info->LCDDithering = 1;
429 return VIA_RES_1280X800;
430 break;
431 case 0x14:
432 viaparinfo->lvds_setting_info->lcd_panel_hres = 1360;
433 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
434 viaparinfo->lvds_setting_info->lcd_panel_id =
435 LCD_PANEL_IDB_1360X768;
436 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
437 viaparinfo->lvds_setting_info->LCDDithering = 0;
438 return VIA_RES_1360X768;
439 break;
440 case 0x15:
441 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
442 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
443 viaparinfo->lvds_setting_info->lcd_panel_id =
444 LCD_PANEL_ID3_1280X768;
445 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
446 viaparinfo->lvds_setting_info->LCDDithering = 0;
447 return VIA_RES_1280X768;
448 break;
449 case 0x16:
450 viaparinfo->lvds_setting_info->lcd_panel_hres = 480;
451 viaparinfo->lvds_setting_info->lcd_panel_vres = 640;
452 viaparinfo->lvds_setting_info->lcd_panel_id =
453 LCD_PANEL_IDC_480X640;
454 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
455 viaparinfo->lvds_setting_info->LCDDithering = 1;
456 return VIA_RES_480X640;
457 break;
458 default:
459 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
460 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
461 viaparinfo->lvds_setting_info->lcd_panel_id =
462 LCD_PANEL_ID1_800X600;
463 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
464 viaparinfo->lvds_setting_info->LCDDithering = 1;
465 return VIA_RES_800X600;
466 }
467}
468
469static int lvds_register_read(int index)
470{
471 u8 data;
472
473 viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX;
474 viafb_i2c_readbyte((u8) viaparinfo->chip_info->
475 lvds_chip_info.lvds_chip_slave_addr,
476 (u8) index, &data);
477 return data;
478}
479
480static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
481 int panel_vres)
482{
483 int reg_value = 0;
484 int viafb_load_reg_num;
485 struct io_register *reg = NULL;
486
487 DEBUG_MSG(KERN_INFO "load_lcd_scaling()!!\n");
488
489 /* LCD Scaling Enable */
490 viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2);
491 if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
492 viafb_load_scaling_factor_for_p4m900(set_hres, set_vres,
493 panel_hres, panel_vres);
494 return;
495 }
496
497 /* Check if expansion for horizontal */
498 if (set_hres != panel_hres) {
499 /* Load Horizontal Scaling Factor */
500 switch (viaparinfo->chip_info->gfx_chip_name) {
501 case UNICHROME_CLE266:
502 case UNICHROME_K400:
503 reg_value =
504 CLE266_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
505 viafb_load_reg_num =
506 lcd_scaling_factor_CLE.lcd_hor_scaling_factor.
507 reg_num;
508 reg = lcd_scaling_factor_CLE.lcd_hor_scaling_factor.reg;
509 viafb_load_reg(reg_value,
510 viafb_load_reg_num, reg, VIACR);
511 break;
512 case UNICHROME_K800:
513 case UNICHROME_PM800:
514 case UNICHROME_CN700:
515 case UNICHROME_CX700:
516 case UNICHROME_K8M890:
517 case UNICHROME_P4M890:
518 reg_value =
519 K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
520 /* Horizontal scaling enabled */
521 viafb_write_reg_mask(CRA2, VIACR, 0xC0, BIT7 + BIT6);
522 viafb_load_reg_num =
523 lcd_scaling_factor.lcd_hor_scaling_factor.reg_num;
524 reg = lcd_scaling_factor.lcd_hor_scaling_factor.reg;
525 viafb_load_reg(reg_value,
526 viafb_load_reg_num, reg, VIACR);
527 break;
528 }
529
530 DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d", reg_value);
531 } else {
532 /* Horizontal scaling disabled */
533 viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT7);
534 }
535
536 /* Check if expansion for vertical */
537 if (set_vres != panel_vres) {
538 /* Load Vertical Scaling Factor */
539 switch (viaparinfo->chip_info->gfx_chip_name) {
540 case UNICHROME_CLE266:
541 case UNICHROME_K400:
542 reg_value =
543 CLE266_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
544 viafb_load_reg_num =
545 lcd_scaling_factor_CLE.lcd_ver_scaling_factor.
546 reg_num;
547 reg = lcd_scaling_factor_CLE.lcd_ver_scaling_factor.reg;
548 viafb_load_reg(reg_value,
549 viafb_load_reg_num, reg, VIACR);
550 break;
551 case UNICHROME_K800:
552 case UNICHROME_PM800:
553 case UNICHROME_CN700:
554 case UNICHROME_CX700:
555 case UNICHROME_K8M890:
556 case UNICHROME_P4M890:
557 reg_value =
558 K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
559 /* Vertical scaling enabled */
560 viafb_write_reg_mask(CRA2, VIACR, 0x08, BIT3);
561 viafb_load_reg_num =
562 lcd_scaling_factor.lcd_ver_scaling_factor.reg_num;
563 reg = lcd_scaling_factor.lcd_ver_scaling_factor.reg;
564 viafb_load_reg(reg_value,
565 viafb_load_reg_num, reg, VIACR);
566 break;
567 }
568
569 DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d", reg_value);
570 } else {
571 /* Vertical scaling disabled */
572 viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT3);
573 }
574}
575
576static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
577 int panel_id)
578{
579 int vmode_index;
580 int reg_num = 0;
581 struct io_reg *lcd_patch_reg = NULL;
582
583 if (viaparinfo->lvds_setting_info->iga_path == IGA2)
584 vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
585 else
586 vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
587 switch (panel_id) {
588 /* LCD 800x600 */
589 case LCD_PANEL_ID1_800X600:
590 switch (vmode_index) {
591 case VIA_RES_640X400:
592 case VIA_RES_640X480:
593 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_8X6;
594 lcd_patch_reg = K400_LCD_RES_6X4_8X6;
595 break;
596 case VIA_RES_720X480:
597 case VIA_RES_720X576:
598 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_8X6;
599 lcd_patch_reg = K400_LCD_RES_7X4_8X6;
600 break;
601 }
602 break;
603
604 /* LCD 1024x768 */
605 case LCD_PANEL_ID2_1024X768:
606 switch (vmode_index) {
607 case VIA_RES_640X400:
608 case VIA_RES_640X480:
609 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_10X7;
610 lcd_patch_reg = K400_LCD_RES_6X4_10X7;
611 break;
612 case VIA_RES_720X480:
613 case VIA_RES_720X576:
614 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_10X7;
615 lcd_patch_reg = K400_LCD_RES_7X4_10X7;
616 break;
617 case VIA_RES_800X600:
618 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_10X7;
619 lcd_patch_reg = K400_LCD_RES_8X6_10X7;
620 break;
621 }
622 break;
623
624 /* LCD 1280x1024 */
625 case LCD_PANEL_ID4_1280X1024:
626 switch (vmode_index) {
627 case VIA_RES_640X400:
628 case VIA_RES_640X480:
629 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_12X10;
630 lcd_patch_reg = K400_LCD_RES_6X4_12X10;
631 break;
632 case VIA_RES_720X480:
633 case VIA_RES_720X576:
634 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_12X10;
635 lcd_patch_reg = K400_LCD_RES_7X4_12X10;
636 break;
637 case VIA_RES_800X600:
638 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_12X10;
639 lcd_patch_reg = K400_LCD_RES_8X6_12X10;
640 break;
641 case VIA_RES_1024X768:
642 reg_num = NUM_TOTAL_K400_LCD_RES_10X7_12X10;
643 lcd_patch_reg = K400_LCD_RES_10X7_12X10;
644 break;
645
646 }
647 break;
648
649 /* LCD 1400x1050 */
650 case LCD_PANEL_ID5_1400X1050:
651 switch (vmode_index) {
652 case VIA_RES_640X480:
653 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_14X10;
654 lcd_patch_reg = K400_LCD_RES_6X4_14X10;
655 break;
656 case VIA_RES_800X600:
657 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_14X10;
658 lcd_patch_reg = K400_LCD_RES_8X6_14X10;
659 break;
660 case VIA_RES_1024X768:
661 reg_num = NUM_TOTAL_K400_LCD_RES_10X7_14X10;
662 lcd_patch_reg = K400_LCD_RES_10X7_14X10;
663 break;
664 case VIA_RES_1280X768:
665 case VIA_RES_1280X800:
666 case VIA_RES_1280X960:
667 case VIA_RES_1280X1024:
668 reg_num = NUM_TOTAL_K400_LCD_RES_12X10_14X10;
669 lcd_patch_reg = K400_LCD_RES_12X10_14X10;
670 break;
671 }
672 break;
673
674 /* LCD 1600x1200 */
675 case LCD_PANEL_ID6_1600X1200:
676 switch (vmode_index) {
677 case VIA_RES_640X400:
678 case VIA_RES_640X480:
679 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_16X12;
680 lcd_patch_reg = K400_LCD_RES_6X4_16X12;
681 break;
682 case VIA_RES_720X480:
683 case VIA_RES_720X576:
684 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_16X12;
685 lcd_patch_reg = K400_LCD_RES_7X4_16X12;
686 break;
687 case VIA_RES_800X600:
688 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_16X12;
689 lcd_patch_reg = K400_LCD_RES_8X6_16X12;
690 break;
691 case VIA_RES_1024X768:
692 reg_num = NUM_TOTAL_K400_LCD_RES_10X7_16X12;
693 lcd_patch_reg = K400_LCD_RES_10X7_16X12;
694 break;
695 case VIA_RES_1280X768:
696 case VIA_RES_1280X800:
697 case VIA_RES_1280X960:
698 case VIA_RES_1280X1024:
699 reg_num = NUM_TOTAL_K400_LCD_RES_12X10_16X12;
700 lcd_patch_reg = K400_LCD_RES_12X10_16X12;
701 break;
702 }
703 break;
704
705 /* LCD 1366x768 */
706 case LCD_PANEL_ID7_1366X768:
707 switch (vmode_index) {
708 case VIA_RES_640X480:
709 reg_num = NUM_TOTAL_K400_LCD_RES_6X4_1366X7;
710 lcd_patch_reg = K400_LCD_RES_6X4_1366X7;
711 break;
712 case VIA_RES_720X480:
713 case VIA_RES_720X576:
714 reg_num = NUM_TOTAL_K400_LCD_RES_7X4_1366X7;
715 lcd_patch_reg = K400_LCD_RES_7X4_1366X7;
716 break;
717 case VIA_RES_800X600:
718 reg_num = NUM_TOTAL_K400_LCD_RES_8X6_1366X7;
719 lcd_patch_reg = K400_LCD_RES_8X6_1366X7;
720 break;
721 case VIA_RES_1024X768:
722 reg_num = NUM_TOTAL_K400_LCD_RES_10X7_1366X7;
723 lcd_patch_reg = K400_LCD_RES_10X7_1366X7;
724 break;
725 case VIA_RES_1280X768:
726 case VIA_RES_1280X800:
727 case VIA_RES_1280X960:
728 case VIA_RES_1280X1024:
729 reg_num = NUM_TOTAL_K400_LCD_RES_12X10_1366X7;
730 lcd_patch_reg = K400_LCD_RES_12X10_1366X7;
731 break;
732 }
733 break;
734
735 /* LCD 1360x768 */
736 case LCD_PANEL_IDB_1360X768:
737 break;
738 }
739 if (reg_num != 0) {
740 /* H.W. Reset : ON */
741 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
742
743 viafb_write_regx(lcd_patch_reg, reg_num);
744
745 /* H.W. Reset : OFF */
746 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
747
748 /* Reset PLL */
749 viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
750 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
751
752 /* Fire! */
753 outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc);
754 }
755}
756
757static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
758 int panel_id)
759{
760 int vmode_index;
761 int reg_num = 0;
762 struct io_reg *lcd_patch_reg = NULL;
763
764 if (viaparinfo->lvds_setting_info->iga_path == IGA2)
765 vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
766 else
767 vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
768
769 switch (panel_id) {
770 case LCD_PANEL_ID5_1400X1050:
771 switch (vmode_index) {
772 case VIA_RES_640X480:
773 reg_num = NUM_TOTAL_P880_LCD_RES_6X4_14X10;
774 lcd_patch_reg = P880_LCD_RES_6X4_14X10;
775 break;
776 case VIA_RES_800X600:
777 reg_num = NUM_TOTAL_P880_LCD_RES_8X6_14X10;
778 lcd_patch_reg = P880_LCD_RES_8X6_14X10;
779 break;
780 }
781 break;
782 case LCD_PANEL_ID6_1600X1200:
783 switch (vmode_index) {
784 case VIA_RES_640X400:
785 case VIA_RES_640X480:
786 reg_num = NUM_TOTAL_P880_LCD_RES_6X4_16X12;
787 lcd_patch_reg = P880_LCD_RES_6X4_16X12;
788 break;
789 case VIA_RES_720X480:
790 case VIA_RES_720X576:
791 reg_num = NUM_TOTAL_P880_LCD_RES_7X4_16X12;
792 lcd_patch_reg = P880_LCD_RES_7X4_16X12;
793 break;
794 case VIA_RES_800X600:
795 reg_num = NUM_TOTAL_P880_LCD_RES_8X6_16X12;
796 lcd_patch_reg = P880_LCD_RES_8X6_16X12;
797 break;
798 case VIA_RES_1024X768:
799 reg_num = NUM_TOTAL_P880_LCD_RES_10X7_16X12;
800 lcd_patch_reg = P880_LCD_RES_10X7_16X12;
801 break;
802 case VIA_RES_1280X768:
803 case VIA_RES_1280X960:
804 case VIA_RES_1280X1024:
805 reg_num = NUM_TOTAL_P880_LCD_RES_12X10_16X12;
806 lcd_patch_reg = P880_LCD_RES_12X10_16X12;
807 break;
808 }
809 break;
810
811 }
812 if (reg_num != 0) {
813 /* H.W. Reset : ON */
814 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
815
816 viafb_write_regx(lcd_patch_reg, reg_num);
817
818 /* H.W. Reset : OFF */
819 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
820
821 /* Reset PLL */
822 viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
823 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
824
825 /* Fire! */
826 outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc);
827 }
828}
829
830static void load_lcd_patch_regs(int set_hres, int set_vres,
831 int panel_id, int set_iga)
832{
833 int vmode_index;
834
835 if (viaparinfo->lvds_setting_info->iga_path == IGA2)
836 vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
837 else
838 vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
839
840 viafb_unlock_crt();
841
842 /* Patch for simultaneous & Expansion */
843 if ((set_iga == IGA1_IGA2) &&
844 (viaparinfo->lvds_setting_info->display_method ==
845 LCD_EXPANDSION)) {
846 switch (viaparinfo->chip_info->gfx_chip_name) {
847 case UNICHROME_CLE266:
848 case UNICHROME_K400:
849 load_lcd_k400_patch_tbl(set_hres, set_vres, panel_id);
850 break;
851 case UNICHROME_K800:
852 break;
853 case UNICHROME_PM800:
854 case UNICHROME_CN700:
855 case UNICHROME_CX700:
856 load_lcd_p880_patch_tbl(set_hres, set_vres, panel_id);
857 }
858 }
859
860 viafb_lock_crt();
861}
862
863static void via_pitch_alignment_patch_lcd(
864 struct lvds_setting_information *plvds_setting_info,
865 struct lvds_chip_information
866 *plvds_chip_info)
867{
868 unsigned char cr13, cr35, cr65, cr66, cr67;
869 unsigned long dwScreenPitch = 0;
870 unsigned long dwPitch;
871
872 dwPitch = plvds_setting_info->h_active * (plvds_setting_info->bpp >> 3);
873 if (dwPitch & 0x1F) {
874 dwScreenPitch = ((dwPitch + 31) & ~31) >> 3;
875 if (plvds_setting_info->iga_path == IGA2) {
876 if (plvds_setting_info->bpp > 8) {
877 cr66 = (unsigned char)(dwScreenPitch & 0xFF);
878 viafb_write_reg(CR66, VIACR, cr66);
879 cr67 = viafb_read_reg(VIACR, CR67) & 0xFC;
880 cr67 |=
881 (unsigned
882 char)((dwScreenPitch & 0x300) >> 8);
883 viafb_write_reg(CR67, VIACR, cr67);
884 }
885
886 /* Fetch Count */
887 cr67 = viafb_read_reg(VIACR, CR67) & 0xF3;
888 cr67 |= (unsigned char)((dwScreenPitch & 0x600) >> 7);
889 viafb_write_reg(CR67, VIACR, cr67);
890 cr65 = (unsigned char)((dwScreenPitch >> 1) & 0xFF);
891 cr65 += 2;
892 viafb_write_reg(CR65, VIACR, cr65);
893 } else {
894 if (plvds_setting_info->bpp > 8) {
895 cr13 = (unsigned char)(dwScreenPitch & 0xFF);
896 viafb_write_reg(CR13, VIACR, cr13);
897 cr35 = viafb_read_reg(VIACR, CR35) & 0x1F;
898 cr35 |=
899 (unsigned
900 char)((dwScreenPitch & 0x700) >> 3);
901 viafb_write_reg(CR35, VIACR, cr35);
902 }
903 }
904 }
905}
906static void lcd_patch_skew_dvp0(struct lvds_setting_information
907 *plvds_setting_info,
908 struct lvds_chip_information *plvds_chip_info)
909{
910 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
911 switch (viaparinfo->chip_info->gfx_chip_name) {
912 case UNICHROME_P4M900:
913 viafb_vt1636_patch_skew_on_vt3364(plvds_setting_info,
914 plvds_chip_info);
915 break;
916 case UNICHROME_P4M890:
917 viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info,
918 plvds_chip_info);
919 break;
920 }
921 }
922}
923static void lcd_patch_skew_dvp1(struct lvds_setting_information
924 *plvds_setting_info,
925 struct lvds_chip_information *plvds_chip_info)
926{
927 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
928 switch (viaparinfo->chip_info->gfx_chip_name) {
929 case UNICHROME_CX700:
930 viafb_vt1636_patch_skew_on_vt3324(plvds_setting_info,
931 plvds_chip_info);
932 break;
933 }
934 }
935}
936static void lcd_patch_skew(struct lvds_setting_information
937 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
938{
939 DEBUG_MSG(KERN_INFO "lcd_patch_skew\n");
940 switch (plvds_chip_info->output_interface) {
941 case INTERFACE_DVP0:
942 lcd_patch_skew_dvp0(plvds_setting_info, plvds_chip_info);
943 break;
944 case INTERFACE_DVP1:
945 lcd_patch_skew_dvp1(plvds_setting_info, plvds_chip_info);
946 break;
947 case INTERFACE_DFP_LOW:
948 if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
949 viafb_write_reg_mask(CR99, VIACR, 0x08,
950 BIT0 + BIT1 + BIT2 + BIT3);
951 }
952 break;
953 }
954}
955
956/* LCD Set Mode */
957void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
958 struct lvds_setting_information *plvds_setting_info,
959 struct lvds_chip_information *plvds_chip_info)
960{
961 int video_index = plvds_setting_info->lcd_panel_size;
962 int set_iga = plvds_setting_info->iga_path;
963 int mode_bpp = plvds_setting_info->bpp;
964 int viafb_load_reg_num = 0;
965 int reg_value = 0;
966 int set_hres, set_vres;
967 int panel_hres, panel_vres;
968 u32 pll_D_N;
969 int offset;
970 struct io_register *reg = NULL;
971 struct display_timing mode_crt_reg, panel_crt_reg;
972 struct crt_mode_table *panel_crt_table = NULL;
973 struct VideoModeTable *vmode_tbl = NULL;
974
975 DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n");
976 /* Get mode table */
977 mode_crt_reg = mode_crt_table->crtc;
978 /* Get panel table Pointer */
979 vmode_tbl = viafb_get_modetbl_pointer(video_index);
980 panel_crt_table = vmode_tbl->crtc;
981 panel_crt_reg = panel_crt_table->crtc;
982 DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
983 set_hres = plvds_setting_info->h_active;
984 set_vres = plvds_setting_info->v_active;
985 panel_hres = plvds_setting_info->lcd_panel_hres;
986 panel_vres = plvds_setting_info->lcd_panel_vres;
987 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
988 viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info);
989 plvds_setting_info->vclk = panel_crt_table->clk;
990 if (set_iga == IGA1) {
991 /* IGA1 doesn't have LCD scaling, so set it as centering. */
992 viafb_load_crtc_timing(lcd_centering_timging
993 (mode_crt_reg, panel_crt_reg), IGA1);
994 } else {
995 /* Expansion */
996 if ((plvds_setting_info->display_method ==
997 LCD_EXPANDSION) & ((set_hres != panel_hres)
998 || (set_vres != panel_vres))) {
999 /* expansion timing IGA2 loaded panel set timing*/
1000 viafb_load_crtc_timing(panel_crt_reg, IGA2);
1001 DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n");
1002 load_lcd_scaling(set_hres, set_vres, panel_hres,
1003 panel_vres);
1004 DEBUG_MSG(KERN_INFO "load_lcd_scaling!!\n");
1005 } else { /* Centering */
1006 /* centering timing IGA2 always loaded panel
1007 and mode releative timing */
1008 viafb_load_crtc_timing(lcd_centering_timging
1009 (mode_crt_reg, panel_crt_reg), IGA2);
1010 viafb_write_reg_mask(CR79, VIACR, 0x00,
1011 BIT0 + BIT1 + BIT2);
1012 /* LCD scaling disabled */
1013 }
1014 }
1015
1016 if (set_iga == IGA1_IGA2) {
1017 load_crtc_shadow_timing(mode_crt_reg, panel_crt_reg);
1018 /* Fill shadow registers */
1019
1020 switch (plvds_setting_info->lcd_panel_id) {
1021 case LCD_PANEL_ID0_640X480:
1022 offset = 80;
1023 break;
1024 case LCD_PANEL_ID1_800X600:
1025 case LCD_PANEL_IDA_800X480:
1026 offset = 110;
1027 break;
1028 case LCD_PANEL_ID2_1024X768:
1029 offset = 150;
1030 break;
1031 case LCD_PANEL_ID3_1280X768:
1032 case LCD_PANEL_ID4_1280X1024:
1033 case LCD_PANEL_ID5_1400X1050:
1034 case LCD_PANEL_ID9_1280X800:
1035 offset = 190;
1036 break;
1037 case LCD_PANEL_ID6_1600X1200:
1038 offset = 250;
1039 break;
1040 case LCD_PANEL_ID7_1366X768:
1041 case LCD_PANEL_IDB_1360X768:
1042 offset = 212;
1043 break;
1044 default:
1045 offset = 140;
1046 break;
1047 }
1048
1049 /* Offset for simultaneous */
1050 reg_value = offset;
1051 viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num;
1052 reg = offset_reg.iga2_offset_reg.reg;
1053 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1054 DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n");
1055 viafb_load_fetch_count_reg(set_hres, 4, IGA2);
1056 /* Fetch count for simultaneous */
1057 } else { /* SAMM */
1058 /* Offset for IGA2 only */
1059 viafb_load_offset_reg(set_hres, mode_bpp / 8, set_iga);
1060 /* Fetch count for IGA2 only */
1061 viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
1062
1063 if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
1064 && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
1065 viafb_load_FIFO_reg(set_iga, set_hres, set_vres);
1066
1067 viafb_set_color_depth(mode_bpp / 8, set_iga);
1068 }
1069
1070 fill_lcd_format();
1071
1072 pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk);
1073 DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N);
1074 viafb_set_vclock(pll_D_N, set_iga);
1075
1076 viafb_set_output_path(DEVICE_LCD, set_iga,
1077 plvds_chip_info->output_interface);
1078 lcd_patch_skew(plvds_setting_info, plvds_chip_info);
1079
1080 /* If K8M800, enable LCD Prefetch Mode. */
1081 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
1082 || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name))
1083 viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0);
1084
1085 load_lcd_patch_regs(set_hres, set_vres,
1086 plvds_setting_info->lcd_panel_id, set_iga);
1087
1088 DEBUG_MSG(KERN_INFO "load_lcd_patch_regs!!\n");
1089
1090 /* Patch for non 32bit alignment mode */
1091 via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info);
1092}
1093
1094static void integrated_lvds_disable(struct lvds_setting_information
1095 *plvds_setting_info,
1096 struct lvds_chip_information *plvds_chip_info)
1097{
1098 bool turn_off_first_powersequence = false;
1099 bool turn_off_second_powersequence = false;
1100 if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface)
1101 turn_off_first_powersequence = true;
1102 if (INTERFACE_LVDS0 == plvds_chip_info->output_interface)
1103 turn_off_first_powersequence = true;
1104 if (INTERFACE_LVDS1 == plvds_chip_info->output_interface)
1105 turn_off_second_powersequence = true;
1106 if (turn_off_second_powersequence) {
1107 /* Use second power sequence control: */
1108
1109 /* Turn off power sequence. */
1110 viafb_write_reg_mask(CRD4, VIACR, 0, BIT1);
1111
1112 /* Turn off back light. */
1113 viafb_write_reg_mask(CRD3, VIACR, 0xC0, BIT6 + BIT7);
1114 }
1115 if (turn_off_first_powersequence) {
1116 /* Use first power sequence control: */
1117
1118 /* Turn off power sequence. */
1119 viafb_write_reg_mask(CR6A, VIACR, 0, BIT3);
1120
1121 /* Turn off back light. */
1122 viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7);
1123 }
1124
1125 /* Turn DFP High/Low Pad off. */
1126 viafb_write_reg_mask(SR2A, VIASR, 0, BIT0 + BIT1 + BIT2 + BIT3);
1127
1128 /* Power off LVDS channel. */
1129 switch (plvds_chip_info->output_interface) {
1130 case INTERFACE_LVDS0:
1131 {
1132 viafb_write_reg_mask(CRD2, VIACR, 0x80, BIT7);
1133 break;
1134 }
1135
1136 case INTERFACE_LVDS1:
1137 {
1138 viafb_write_reg_mask(CRD2, VIACR, 0x40, BIT6);
1139 break;
1140 }
1141
1142 case INTERFACE_LVDS0LVDS1:
1143 {
1144 viafb_write_reg_mask(CRD2, VIACR, 0xC0, BIT6 + BIT7);
1145 break;
1146 }
1147 }
1148}
1149
1150static void integrated_lvds_enable(struct lvds_setting_information
1151 *plvds_setting_info,
1152 struct lvds_chip_information *plvds_chip_info)
1153{
1154 bool turn_on_first_powersequence = false;
1155 bool turn_on_second_powersequence = false;
1156
1157 DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n",
1158 plvds_chip_info->output_interface);
1159 if (plvds_setting_info->lcd_mode == LCD_SPWG)
1160 viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT0 + BIT1);
1161 else
1162 viafb_write_reg_mask(CRD2, VIACR, 0x03, BIT0 + BIT1);
1163 if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface)
1164 turn_on_first_powersequence = true;
1165 if (INTERFACE_LVDS0 == plvds_chip_info->output_interface)
1166 turn_on_first_powersequence = true;
1167 if (INTERFACE_LVDS1 == plvds_chip_info->output_interface)
1168 turn_on_second_powersequence = true;
1169
1170 if (turn_on_second_powersequence) {
1171 /* Use second power sequence control: */
1172
1173 /* Use hardware control power sequence. */
1174 viafb_write_reg_mask(CRD3, VIACR, 0, BIT0);
1175
1176 /* Turn on back light. */
1177 viafb_write_reg_mask(CRD3, VIACR, 0, BIT6 + BIT7);
1178
1179 /* Turn on hardware power sequence. */
1180 viafb_write_reg_mask(CRD4, VIACR, 0x02, BIT1);
1181 }
1182 if (turn_on_first_powersequence) {
1183 /* Use first power sequence control: */
1184
1185 /* Use hardware control power sequence. */
1186 viafb_write_reg_mask(CR91, VIACR, 0, BIT0);
1187
1188 /* Turn on back light. */
1189 viafb_write_reg_mask(CR91, VIACR, 0, BIT6 + BIT7);
1190
1191 /* Turn on hardware power sequence. */
1192 viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
1193 }
1194
1195 /* Turn DFP High/Low pad on. */
1196 viafb_write_reg_mask(SR2A, VIASR, 0x0F, BIT0 + BIT1 + BIT2 + BIT3);
1197
1198 /* Power on LVDS channel. */
1199 switch (plvds_chip_info->output_interface) {
1200 case INTERFACE_LVDS0:
1201 {
1202 viafb_write_reg_mask(CRD2, VIACR, 0, BIT7);
1203 break;
1204 }
1205
1206 case INTERFACE_LVDS1:
1207 {
1208 viafb_write_reg_mask(CRD2, VIACR, 0, BIT6);
1209 break;
1210 }
1211
1212 case INTERFACE_LVDS0LVDS1:
1213 {
1214 viafb_write_reg_mask(CRD2, VIACR, 0, BIT6 + BIT7);
1215 break;
1216 }
1217 }
1218}
1219
1220void viafb_lcd_disable(void)
1221{
1222
1223 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
1224 lcd_powersequence_off();
1225 /* DI1 pad off */
1226 viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
1227 } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1228 if (viafb_LCD2_ON
1229 && (INTEGRATED_LVDS ==
1230 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
1231 integrated_lvds_disable(viaparinfo->lvds_setting_info,
1232 &viaparinfo->chip_info->lvds_chip_info2);
1233 if (INTEGRATED_LVDS ==
1234 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
1235 integrated_lvds_disable(viaparinfo->lvds_setting_info,
1236 &viaparinfo->chip_info->lvds_chip_info);
1237 if (VT1636_LVDS == viaparinfo->chip_info->
1238 lvds_chip_info.lvds_chip_name)
1239 viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
1240 &viaparinfo->chip_info->lvds_chip_info);
1241 } else if (VT1636_LVDS ==
1242 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
1243 viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
1244 &viaparinfo->chip_info->lvds_chip_info);
1245 } else {
1246 /* DFP-HL pad off */
1247 viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0F);
1248 /* Backlight off */
1249 viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20);
1250 /* 24 bit DI data paht off */
1251 viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80);
1252 /* Simultaneout disabled */
1253 viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
1254 }
1255
1256 /* Disable expansion bit */
1257 viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01);
1258 /* CRT path set to IGA1 */
1259 viafb_write_reg_mask(SR16, VIASR, 0x00, 0x40);
1260 /* Simultaneout disabled */
1261 viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
1262 /* IGA2 path disabled */
1263 viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80);
1264
1265}
1266
1267void viafb_lcd_enable(void)
1268{
1269 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
1270 /* DI1 pad on */
1271 viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
1272 lcd_powersequence_on();
1273 } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1274 if (viafb_LCD2_ON && (INTEGRATED_LVDS ==
1275 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
1276 integrated_lvds_enable(viaparinfo->lvds_setting_info2, \
1277 &viaparinfo->chip_info->lvds_chip_info2);
1278 if (INTEGRATED_LVDS ==
1279 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
1280 integrated_lvds_enable(viaparinfo->lvds_setting_info,
1281 &viaparinfo->chip_info->lvds_chip_info);
1282 if (VT1636_LVDS == viaparinfo->chip_info->
1283 lvds_chip_info.lvds_chip_name)
1284 viafb_enable_lvds_vt1636(viaparinfo->
1285 lvds_setting_info, &viaparinfo->chip_info->
1286 lvds_chip_info);
1287 } else if (VT1636_LVDS ==
1288 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
1289 viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info,
1290 &viaparinfo->chip_info->lvds_chip_info);
1291 } else {
1292 /* DFP-HL pad on */
1293 viafb_write_reg_mask(SR2A, VIASR, 0x0F, 0x0F);
1294 /* Backlight on */
1295 viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20);
1296 /* 24 bit DI data paht on */
1297 viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80);
1298
1299 /* Set data source selection bit by iga path */
1300 if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
1301 /* DFP-H set to IGA1 */
1302 viafb_write_reg_mask(CR97, VIACR, 0x00, 0x10);
1303 /* DFP-L set to IGA1 */
1304 viafb_write_reg_mask(CR99, VIACR, 0x00, 0x10);
1305 } else {
1306 /* DFP-H set to IGA2 */
1307 viafb_write_reg_mask(CR97, VIACR, 0x10, 0x10);
1308 /* DFP-L set to IGA2 */
1309 viafb_write_reg_mask(CR99, VIACR, 0x10, 0x10);
1310 }
1311 /* LCD enabled */
1312 viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48);
1313 }
1314
1315 if ((viaparinfo->lvds_setting_info->iga_path == IGA1)
1316 || (viaparinfo->lvds_setting_info->iga_path == IGA1_IGA2)) {
1317 /* CRT path set to IGA2 */
1318 viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40);
1319 /* IGA2 path disabled */
1320 viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80);
1321 /* IGA2 path enabled */
1322 } else { /* IGA2 */
1323 viafb_write_reg_mask(CR6A, VIACR, 0x80, 0x80);
1324 }
1325
1326}
1327
1328static void lcd_powersequence_off(void)
1329{
1330 int i, mask, data;
1331
1332 /* Software control power sequence */
1333 viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
1334
1335 for (i = 0; i < 3; i++) {
1336 mask = PowerSequenceOff[0][i];
1337 data = PowerSequenceOff[1][i] & mask;
1338 viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
1339 udelay(PowerSequenceOff[2][i]);
1340 }
1341
1342 /* Disable LCD */
1343 viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x08);
1344}
1345
1346static void lcd_powersequence_on(void)
1347{
1348 int i, mask, data;
1349
1350 /* Software control power sequence */
1351 viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
1352
1353 /* Enable LCD */
1354 viafb_write_reg_mask(CR6A, VIACR, 0x08, 0x08);
1355
1356 for (i = 0; i < 3; i++) {
1357 mask = PowerSequenceOn[0][i];
1358 data = PowerSequenceOn[1][i] & mask;
1359 viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
1360 udelay(PowerSequenceOn[2][i]);
1361 }
1362
1363 udelay(1);
1364}
1365
1366static void fill_lcd_format(void)
1367{
1368 u8 bdithering = 0, bdual = 0;
1369
1370 if (viaparinfo->lvds_setting_info->device_lcd_dualedge)
1371 bdual = BIT4;
1372 if (viaparinfo->lvds_setting_info->LCDDithering)
1373 bdithering = BIT0;
1374 /* Dual & Dithering */
1375 viafb_write_reg_mask(CR88, VIACR, (bdithering | bdual), BIT4 + BIT0);
1376}
1377
1378static void check_diport_of_integrated_lvds(
1379 struct lvds_chip_information *plvds_chip_info,
1380 struct lvds_setting_information
1381 *plvds_setting_info)
1382{
1383 /* Determine LCD DI Port by hardware layout. */
1384 switch (viafb_display_hardware_layout) {
1385 case HW_LAYOUT_LCD_ONLY:
1386 {
1387 if (plvds_setting_info->device_lcd_dualedge) {
1388 plvds_chip_info->output_interface =
1389 INTERFACE_LVDS0LVDS1;
1390 } else {
1391 plvds_chip_info->output_interface =
1392 INTERFACE_LVDS0;
1393 }
1394
1395 break;
1396 }
1397
1398 case HW_LAYOUT_DVI_ONLY:
1399 {
1400 plvds_chip_info->output_interface = INTERFACE_NONE;
1401 break;
1402 }
1403
1404 case HW_LAYOUT_LCD1_LCD2:
1405 case HW_LAYOUT_LCD_EXTERNAL_LCD2:
1406 {
1407 plvds_chip_info->output_interface =
1408 INTERFACE_LVDS0LVDS1;
1409 break;
1410 }
1411
1412 case HW_LAYOUT_LCD_DVI:
1413 {
1414 plvds_chip_info->output_interface = INTERFACE_LVDS1;
1415 break;
1416 }
1417
1418 default:
1419 {
1420 plvds_chip_info->output_interface = INTERFACE_LVDS1;
1421 break;
1422 }
1423 }
1424
1425 DEBUG_MSG(KERN_INFO
1426 "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n",
1427 viafb_display_hardware_layout,
1428 plvds_chip_info->output_interface);
1429}
1430
1431void viafb_init_lvds_output_interface(struct lvds_chip_information
1432 *plvds_chip_info,
1433 struct lvds_setting_information
1434 *plvds_setting_info)
1435{
1436 if (INTERFACE_NONE != plvds_chip_info->output_interface) {
1437 /*Do nothing, lcd port is specified by module parameter */
1438 return;
1439 }
1440
1441 switch (plvds_chip_info->lvds_chip_name) {
1442
1443 case VT1636_LVDS:
1444 switch (viaparinfo->chip_info->gfx_chip_name) {
1445 case UNICHROME_CX700:
1446 plvds_chip_info->output_interface = INTERFACE_DVP1;
1447 break;
1448 case UNICHROME_CN700:
1449 plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
1450 break;
1451 default:
1452 plvds_chip_info->output_interface = INTERFACE_DVP0;
1453 break;
1454 }
1455 break;
1456
1457 case INTEGRATED_LVDS:
1458 check_diport_of_integrated_lvds(plvds_chip_info,
1459 plvds_setting_info);
1460 break;
1461
1462 default:
1463 switch (viaparinfo->chip_info->gfx_chip_name) {
1464 case UNICHROME_K8M890:
1465 case UNICHROME_P4M900:
1466 case UNICHROME_P4M890:
1467 plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
1468 break;
1469 default:
1470 plvds_chip_info->output_interface = INTERFACE_DFP;
1471 break;
1472 }
1473 break;
1474 }
1475}
1476
1477static struct display_timing lcd_centering_timging(struct display_timing
1478 mode_crt_reg,
1479 struct display_timing panel_crt_reg)
1480{
1481 struct display_timing crt_reg;
1482
1483 crt_reg.hor_total = panel_crt_reg.hor_total;
1484 crt_reg.hor_addr = mode_crt_reg.hor_addr;
1485 crt_reg.hor_blank_start =
1486 (panel_crt_reg.hor_addr - mode_crt_reg.hor_addr) / 2 +
1487 crt_reg.hor_addr;
1488 crt_reg.hor_blank_end = panel_crt_reg.hor_blank_end;
1489 crt_reg.hor_sync_start =
1490 (panel_crt_reg.hor_sync_start -
1491 panel_crt_reg.hor_blank_start) + crt_reg.hor_blank_start;
1492 crt_reg.hor_sync_end = panel_crt_reg.hor_sync_end;
1493
1494 crt_reg.ver_total = panel_crt_reg.ver_total;
1495 crt_reg.ver_addr = mode_crt_reg.ver_addr;
1496 crt_reg.ver_blank_start =
1497 (panel_crt_reg.ver_addr - mode_crt_reg.ver_addr) / 2 +
1498 crt_reg.ver_addr;
1499 crt_reg.ver_blank_end = panel_crt_reg.ver_blank_end;
1500 crt_reg.ver_sync_start =
1501 (panel_crt_reg.ver_sync_start -
1502 panel_crt_reg.ver_blank_start) + crt_reg.ver_blank_start;
1503 crt_reg.ver_sync_end = panel_crt_reg.ver_sync_end;
1504
1505 return crt_reg;
1506}
1507
1508static void load_crtc_shadow_timing(struct display_timing mode_timing,
1509 struct display_timing panel_timing)
1510{
1511 struct io_register *reg = NULL;
1512 int i;
1513 int viafb_load_reg_Num = 0;
1514 int reg_value = 0;
1515
1516 if (viaparinfo->lvds_setting_info->display_method == LCD_EXPANDSION) {
1517 /* Expansion */
1518 for (i = 12; i < 20; i++) {
1519 switch (i) {
1520 case H_TOTAL_SHADOW_INDEX:
1521 reg_value =
1522 IGA2_HOR_TOTAL_SHADOW_FORMULA
1523 (panel_timing.hor_total);
1524 viafb_load_reg_Num =
1525 iga2_shadow_crtc_reg.hor_total_shadow.
1526 reg_num;
1527 reg = iga2_shadow_crtc_reg.hor_total_shadow.reg;
1528 break;
1529 case H_BLANK_END_SHADOW_INDEX:
1530 reg_value =
1531 IGA2_HOR_BLANK_END_SHADOW_FORMULA
1532 (panel_timing.hor_blank_start,
1533 panel_timing.hor_blank_end);
1534 viafb_load_reg_Num =
1535 iga2_shadow_crtc_reg.
1536 hor_blank_end_shadow.reg_num;
1537 reg =
1538 iga2_shadow_crtc_reg.
1539 hor_blank_end_shadow.reg;
1540 break;
1541 case V_TOTAL_SHADOW_INDEX:
1542 reg_value =
1543 IGA2_VER_TOTAL_SHADOW_FORMULA
1544 (panel_timing.ver_total);
1545 viafb_load_reg_Num =
1546 iga2_shadow_crtc_reg.ver_total_shadow.
1547 reg_num;
1548 reg = iga2_shadow_crtc_reg.ver_total_shadow.reg;
1549 break;
1550 case V_ADDR_SHADOW_INDEX:
1551 reg_value =
1552 IGA2_VER_ADDR_SHADOW_FORMULA
1553 (panel_timing.ver_addr);
1554 viafb_load_reg_Num =
1555 iga2_shadow_crtc_reg.ver_addr_shadow.
1556 reg_num;
1557 reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg;
1558 break;
1559 case V_BLANK_SATRT_SHADOW_INDEX:
1560 reg_value =
1561 IGA2_VER_BLANK_START_SHADOW_FORMULA
1562 (panel_timing.ver_blank_start);
1563 viafb_load_reg_Num =
1564 iga2_shadow_crtc_reg.
1565 ver_blank_start_shadow.reg_num;
1566 reg =
1567 iga2_shadow_crtc_reg.
1568 ver_blank_start_shadow.reg;
1569 break;
1570 case V_BLANK_END_SHADOW_INDEX:
1571 reg_value =
1572 IGA2_VER_BLANK_END_SHADOW_FORMULA
1573 (panel_timing.ver_blank_start,
1574 panel_timing.ver_blank_end);
1575 viafb_load_reg_Num =
1576 iga2_shadow_crtc_reg.
1577 ver_blank_end_shadow.reg_num;
1578 reg =
1579 iga2_shadow_crtc_reg.
1580 ver_blank_end_shadow.reg;
1581 break;
1582 case V_SYNC_SATRT_SHADOW_INDEX:
1583 reg_value =
1584 IGA2_VER_SYNC_START_SHADOW_FORMULA
1585 (panel_timing.ver_sync_start);
1586 viafb_load_reg_Num =
1587 iga2_shadow_crtc_reg.
1588 ver_sync_start_shadow.reg_num;
1589 reg =
1590 iga2_shadow_crtc_reg.
1591 ver_sync_start_shadow.reg;
1592 break;
1593 case V_SYNC_END_SHADOW_INDEX:
1594 reg_value =
1595 IGA2_VER_SYNC_END_SHADOW_FORMULA
1596 (panel_timing.ver_sync_start,
1597 panel_timing.ver_sync_end);
1598 viafb_load_reg_Num =
1599 iga2_shadow_crtc_reg.
1600 ver_sync_end_shadow.reg_num;
1601 reg =
1602 iga2_shadow_crtc_reg.
1603 ver_sync_end_shadow.reg;
1604 break;
1605 }
1606 viafb_load_reg(reg_value,
1607 viafb_load_reg_Num, reg, VIACR);
1608 }
1609 } else { /* Centering */
1610 for (i = 12; i < 20; i++) {
1611 switch (i) {
1612 case H_TOTAL_SHADOW_INDEX:
1613 reg_value =
1614 IGA2_HOR_TOTAL_SHADOW_FORMULA
1615 (panel_timing.hor_total);
1616 viafb_load_reg_Num =
1617 iga2_shadow_crtc_reg.hor_total_shadow.
1618 reg_num;
1619 reg = iga2_shadow_crtc_reg.hor_total_shadow.reg;
1620 break;
1621 case H_BLANK_END_SHADOW_INDEX:
1622 reg_value =
1623 IGA2_HOR_BLANK_END_SHADOW_FORMULA
1624 (panel_timing.hor_blank_start,
1625 panel_timing.hor_blank_end);
1626 viafb_load_reg_Num =
1627 iga2_shadow_crtc_reg.
1628 hor_blank_end_shadow.reg_num;
1629 reg =
1630 iga2_shadow_crtc_reg.
1631 hor_blank_end_shadow.reg;
1632 break;
1633 case V_TOTAL_SHADOW_INDEX:
1634 reg_value =
1635 IGA2_VER_TOTAL_SHADOW_FORMULA
1636 (panel_timing.ver_total);
1637 viafb_load_reg_Num =
1638 iga2_shadow_crtc_reg.ver_total_shadow.
1639 reg_num;
1640 reg = iga2_shadow_crtc_reg.ver_total_shadow.reg;
1641 break;
1642 case V_ADDR_SHADOW_INDEX:
1643 reg_value =
1644 IGA2_VER_ADDR_SHADOW_FORMULA
1645 (mode_timing.ver_addr);
1646 viafb_load_reg_Num =
1647 iga2_shadow_crtc_reg.ver_addr_shadow.
1648 reg_num;
1649 reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg;
1650 break;
1651 case V_BLANK_SATRT_SHADOW_INDEX:
1652 reg_value =
1653 IGA2_VER_BLANK_START_SHADOW_FORMULA
1654 (mode_timing.ver_blank_start);
1655 viafb_load_reg_Num =
1656 iga2_shadow_crtc_reg.
1657 ver_blank_start_shadow.reg_num;
1658 reg =
1659 iga2_shadow_crtc_reg.
1660 ver_blank_start_shadow.reg;
1661 break;
1662 case V_BLANK_END_SHADOW_INDEX:
1663 reg_value =
1664 IGA2_VER_BLANK_END_SHADOW_FORMULA
1665 (panel_timing.ver_blank_start,
1666 panel_timing.ver_blank_end);
1667 viafb_load_reg_Num =
1668 iga2_shadow_crtc_reg.
1669 ver_blank_end_shadow.reg_num;
1670 reg =
1671 iga2_shadow_crtc_reg.
1672 ver_blank_end_shadow.reg;
1673 break;
1674 case V_SYNC_SATRT_SHADOW_INDEX:
1675 reg_value =
1676 IGA2_VER_SYNC_START_SHADOW_FORMULA(
1677 (panel_timing.ver_sync_start -
1678 panel_timing.ver_blank_start) +
1679 (panel_timing.ver_addr -
1680 mode_timing.ver_addr) / 2 +
1681 mode_timing.ver_addr);
1682 viafb_load_reg_Num =
1683 iga2_shadow_crtc_reg.ver_sync_start_shadow.
1684 reg_num;
1685 reg =
1686 iga2_shadow_crtc_reg.ver_sync_start_shadow.
1687 reg;
1688 break;
1689 case V_SYNC_END_SHADOW_INDEX:
1690 reg_value =
1691 IGA2_VER_SYNC_END_SHADOW_FORMULA(
1692 (panel_timing.ver_sync_start -
1693 panel_timing.ver_blank_start) +
1694 (panel_timing.ver_addr -
1695 mode_timing.ver_addr) / 2 +
1696 mode_timing.ver_addr,
1697 panel_timing.ver_sync_end);
1698 viafb_load_reg_Num =
1699 iga2_shadow_crtc_reg.ver_sync_end_shadow.
1700 reg_num;
1701 reg =
1702 iga2_shadow_crtc_reg.ver_sync_end_shadow.
1703 reg;
1704 break;
1705 }
1706 viafb_load_reg(reg_value,
1707 viafb_load_reg_Num, reg, VIACR);
1708 }
1709 }
1710}
1711
1712bool viafb_lcd_get_mobile_state(bool *mobile)
1713{
1714 unsigned char *romptr, *tableptr;
1715 u8 core_base;
1716 unsigned char *biosptr;
1717 /* Rom address */
1718 u32 romaddr = 0x000C0000;
1719 u16 start_pattern = 0;
1720
1721 biosptr = ioremap(romaddr, 0x10000);
1722
1723 memcpy(&start_pattern, biosptr, 2);
1724 /* Compare pattern */
1725 if (start_pattern == 0xAA55) {
1726 /* Get the start of Table */
1727 /* 0x1B means BIOS offset position */
1728 romptr = biosptr + 0x1B;
1729 tableptr = biosptr + *((u16 *) romptr);
1730
1731 /* Get the start of biosver structure */
1732 /* 18 means BIOS version position. */
1733 romptr = tableptr + 18;
1734 romptr = biosptr + *((u16 *) romptr);
1735
1736 /* The offset should be 44, but the
1737 actual image is less three char. */
1738 /* pRom += 44; */
1739 romptr += 41;
1740
1741 core_base = *romptr++;
1742
1743 if (core_base & 0x8)
1744 *mobile = false;
1745 else
1746 *mobile = true;
1747 /* release memory */
1748 iounmap(biosptr);
1749
1750 return true;
1751 } else {
1752 iounmap(biosptr);
1753 return false;
1754 }
1755}
1756
1757static void viafb_load_scaling_factor_for_p4m900(int set_hres,
1758 int set_vres, int panel_hres, int panel_vres)
1759{
1760 int h_scaling_factor;
1761 int v_scaling_factor;
1762 u8 cra2 = 0;
1763 u8 cr77 = 0;
1764 u8 cr78 = 0;
1765 u8 cr79 = 0;
1766 u8 cr9f = 0;
1767 /* Check if expansion for horizontal */
1768 if (set_hres < panel_hres) {
1769 /* Load Horizontal Scaling Factor */
1770
1771 /* For VIA_K8M800 or later chipsets. */
1772 h_scaling_factor =
1773 K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
1774 /* HSCaleFactor[1:0] at CR9F[1:0] */
1775 cr9f = h_scaling_factor & 0x0003;
1776 /* HSCaleFactor[9:2] at CR77[7:0] */
1777 cr77 = (h_scaling_factor & 0x03FC) >> 2;
1778 /* HSCaleFactor[11:10] at CR79[5:4] */
1779 cr79 = (h_scaling_factor & 0x0C00) >> 10;
1780 cr79 <<= 4;
1781
1782 /* Horizontal scaling enabled */
1783 cra2 = 0xC0;
1784
1785 DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d\n",
1786 h_scaling_factor);
1787 } else {
1788 /* Horizontal scaling disabled */
1789 cra2 = 0x00;
1790 }
1791
1792 /* Check if expansion for vertical */
1793 if (set_vres < panel_vres) {
1794 /* Load Vertical Scaling Factor */
1795
1796 /* For VIA_K8M800 or later chipsets. */
1797 v_scaling_factor =
1798 K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
1799
1800 /* Vertical scaling enabled */
1801 cra2 |= 0x08;
1802 /* VSCaleFactor[0] at CR79[3] */
1803 cr79 |= ((v_scaling_factor & 0x0001) << 3);
1804 /* VSCaleFactor[8:1] at CR78[7:0] */
1805 cr78 |= (v_scaling_factor & 0x01FE) >> 1;
1806 /* VSCaleFactor[10:9] at CR79[7:6] */
1807 cr79 |= ((v_scaling_factor & 0x0600) >> 9) << 6;
1808
1809 DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d\n",
1810 v_scaling_factor);
1811 } else {
1812 /* Vertical scaling disabled */
1813 cra2 |= 0x00;
1814 }
1815
1816 viafb_write_reg_mask(CRA2, VIACR, cra2, BIT3 + BIT6 + BIT7);
1817 viafb_write_reg_mask(CR77, VIACR, cr77, 0xFF);
1818 viafb_write_reg_mask(CR78, VIACR, cr78, 0xFF);
1819 viafb_write_reg_mask(CR79, VIACR, cr79, 0xF8);
1820 viafb_write_reg_mask(CR9F, VIACR, cr9f, BIT0 + BIT1);
1821}