2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
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.
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
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
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 static 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} } }
45 static 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} } }
53 static 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} } }
60 static int check_lvds_chip(int device_id_subaddr
, int device_id
);
61 static bool lvds_identify_integratedlvds(void);
62 static int fp_id_to_vindex(int panel_id
);
63 static int lvds_register_read(int index
);
64 static void load_lcd_scaling(int set_hres
, int set_vres
, int panel_hres
,
66 static void load_lcd_k400_patch_tbl(int set_hres
, int set_vres
,
68 static void load_lcd_p880_patch_tbl(int set_hres
, int set_vres
,
70 static void load_lcd_patch_regs(int set_hres
, int set_vres
,
71 int panel_id
, int set_iga
);
72 static void via_pitch_alignment_patch_lcd(
73 struct lvds_setting_information
*plvds_setting_info
,
74 struct lvds_chip_information
76 static void lcd_patch_skew_dvp0(struct lvds_setting_information
78 struct lvds_chip_information
*plvds_chip_info
);
79 static void lcd_patch_skew_dvp1(struct lvds_setting_information
81 struct lvds_chip_information
*plvds_chip_info
);
82 static void lcd_patch_skew(struct lvds_setting_information
83 *plvds_setting_info
, struct lvds_chip_information
*plvds_chip_info
);
85 static void integrated_lvds_disable(struct lvds_setting_information
87 struct lvds_chip_information
*plvds_chip_info
);
88 static void integrated_lvds_enable(struct lvds_setting_information
90 struct lvds_chip_information
*plvds_chip_info
);
91 static void lcd_powersequence_off(void);
92 static void lcd_powersequence_on(void);
93 static void fill_lcd_format(void);
94 static void check_diport_of_integrated_lvds(
95 struct lvds_chip_information
*plvds_chip_info
,
96 struct lvds_setting_information
98 static struct display_timing
lcd_centering_timging(struct display_timing
100 struct display_timing panel_crt_reg
);
101 static void load_crtc_shadow_timing(struct display_timing mode_timing
,
102 struct display_timing panel_timing
);
103 static void viafb_load_scaling_factor_for_p4m900(int set_hres
,
104 int set_vres
, int panel_hres
, int panel_vres
);
106 static int check_lvds_chip(int device_id_subaddr
, int device_id
)
108 if (lvds_register_read(device_id_subaddr
) == device_id
)
114 void viafb_init_lcd_size(void)
116 DEBUG_MSG(KERN_INFO
"viafb_init_lcd_size()\n");
118 "viaparinfo->lvds_setting_info->get_lcd_size_method %d\n",
119 viaparinfo
->lvds_setting_info
->get_lcd_size_method
);
121 switch (viaparinfo
->lvds_setting_info
->get_lcd_size_method
) {
122 case GET_LCD_SIZE_BY_SYSTEM_BIOS
:
124 case GET_LCD_SZIE_BY_HW_STRAPPING
:
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
);
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
);
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
);
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
;
165 static bool lvds_identify_integratedlvds(void)
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
=
174 DEBUG_MSG(KERN_INFO
"Support two dual channel LVDS!\
175 (Internal LVDS + External LVDS)\n");
177 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
=
179 DEBUG_MSG(KERN_INFO
"Not found external LVDS,\
180 so can't support two dual channel LVDS!\n");
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
=
186 viaparinfo
->chip_info
->lvds_chip_info2
.lvds_chip_name
=
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
=
196 DEBUG_MSG(KERN_INFO
"Found Integrated LVDS!\n");
199 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
=
200 NON_LVDS_TRANSMITTER
;
201 DEBUG_MSG(KERN_INFO
"Do not support LVDS!\n");
208 int viafb_lvds_trasmitter_identify(void)
210 viaparinfo
->i2c_stuff
.i2c_port
= I2CPORTINDEX
;
211 if (viafb_lvds_identify_vt1636()) {
212 viaparinfo
->chip_info
->lvds_chip_info
.i2c_port
= I2CPORTINDEX
;
214 "Found VIA VT1636 LVDS on port i2c 0x31 \n");
216 viaparinfo
->i2c_stuff
.i2c_port
= GPIOPORTINDEX
;
217 if (viafb_lvds_identify_vt1636()) {
218 viaparinfo
->chip_info
->lvds_chip_info
.i2c_port
=
221 "Found VIA VT1636 LVDS on port gpio 0x2c \n");
225 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
)
226 lvds_identify_integratedlvds();
228 if (viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
)
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
;
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
);
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
;
251 static int fp_id_to_vindex(int panel_id
)
253 DEBUG_MSG(KERN_INFO
"fp_get_panel_id()\n");
255 if (panel_id
> LCD_PANEL_ID_MAXIMUM
)
256 viafb_lcd_panel_id
= panel_id
=
257 viafb_read_reg(VIACR
, CR3F
) & 0x0F;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
469 static int lvds_register_read(int index
)
473 viaparinfo
->i2c_stuff
.i2c_port
= GPIOPORTINDEX
;
474 viafb_i2c_readbyte((u8
) viaparinfo
->chip_info
->
475 lvds_chip_info
.lvds_chip_slave_addr
,
480 static void load_lcd_scaling(int set_hres
, int set_vres
, int panel_hres
,
484 int viafb_load_reg_num
;
485 struct io_register
*reg
= NULL
;
487 DEBUG_MSG(KERN_INFO
"load_lcd_scaling()!!\n");
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
);
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
:
504 CLE266_LCD_HOR_SCF_FORMULA(set_hres
, panel_hres
);
506 lcd_scaling_factor_CLE
.lcd_hor_scaling_factor
.
508 reg
= lcd_scaling_factor_CLE
.lcd_hor_scaling_factor
.reg
;
509 viafb_load_reg(reg_value
,
510 viafb_load_reg_num
, reg
, VIACR
);
513 case UNICHROME_PM800
:
514 case UNICHROME_CN700
:
515 case UNICHROME_CX700
:
516 case UNICHROME_K8M890
:
517 case UNICHROME_P4M890
:
519 K800_LCD_HOR_SCF_FORMULA(set_hres
, panel_hres
);
520 /* Horizontal scaling enabled */
521 viafb_write_reg_mask(CRA2
, VIACR
, 0xC0, BIT7
+ BIT6
);
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
);
530 DEBUG_MSG(KERN_INFO
"Horizontal Scaling value = %d", reg_value
);
532 /* Horizontal scaling disabled */
533 viafb_write_reg_mask(CRA2
, VIACR
, 0x00, BIT7
);
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
:
543 CLE266_LCD_VER_SCF_FORMULA(set_vres
, panel_vres
);
545 lcd_scaling_factor_CLE
.lcd_ver_scaling_factor
.
547 reg
= lcd_scaling_factor_CLE
.lcd_ver_scaling_factor
.reg
;
548 viafb_load_reg(reg_value
,
549 viafb_load_reg_num
, reg
, VIACR
);
552 case UNICHROME_PM800
:
553 case UNICHROME_CN700
:
554 case UNICHROME_CX700
:
555 case UNICHROME_K8M890
:
556 case UNICHROME_P4M890
:
558 K800_LCD_VER_SCF_FORMULA(set_vres
, panel_vres
);
559 /* Vertical scaling enabled */
560 viafb_write_reg_mask(CRA2
, VIACR
, 0x08, BIT3
);
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
);
569 DEBUG_MSG(KERN_INFO
"Vertical Scaling value = %d", reg_value
);
571 /* Vertical scaling disabled */
572 viafb_write_reg_mask(CRA2
, VIACR
, 0x00, BIT3
);
576 static void load_lcd_k400_patch_tbl(int set_hres
, int set_vres
,
581 struct io_reg
*lcd_patch_reg
= NULL
;
583 if (viaparinfo
->lvds_setting_info
->iga_path
== IGA2
)
584 vmode_index
= viafb_get_mode_index(set_hres
, set_vres
, 1);
586 vmode_index
= viafb_get_mode_index(set_hres
, set_vres
, 0);
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
;
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
;
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
;
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
;
617 case VIA_RES_800X600
:
618 reg_num
= NUM_TOTAL_K400_LCD_RES_8X6_10X7
;
619 lcd_patch_reg
= K400_LCD_RES_8X6_10X7
;
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
;
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
;
637 case VIA_RES_800X600
:
638 reg_num
= NUM_TOTAL_K400_LCD_RES_8X6_12X10
;
639 lcd_patch_reg
= K400_LCD_RES_8X6_12X10
;
641 case VIA_RES_1024X768
:
642 reg_num
= NUM_TOTAL_K400_LCD_RES_10X7_12X10
;
643 lcd_patch_reg
= K400_LCD_RES_10X7_12X10
;
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
;
656 case VIA_RES_800X600
:
657 reg_num
= NUM_TOTAL_K400_LCD_RES_8X6_14X10
;
658 lcd_patch_reg
= K400_LCD_RES_8X6_14X10
;
660 case VIA_RES_1024X768
:
661 reg_num
= NUM_TOTAL_K400_LCD_RES_10X7_14X10
;
662 lcd_patch_reg
= K400_LCD_RES_10X7_14X10
;
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
;
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
;
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
;
687 case VIA_RES_800X600
:
688 reg_num
= NUM_TOTAL_K400_LCD_RES_8X6_16X12
;
689 lcd_patch_reg
= K400_LCD_RES_8X6_16X12
;
691 case VIA_RES_1024X768
:
692 reg_num
= NUM_TOTAL_K400_LCD_RES_10X7_16X12
;
693 lcd_patch_reg
= K400_LCD_RES_10X7_16X12
;
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
;
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
;
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
;
717 case VIA_RES_800X600
:
718 reg_num
= NUM_TOTAL_K400_LCD_RES_8X6_1366X7
;
719 lcd_patch_reg
= K400_LCD_RES_8X6_1366X7
;
721 case VIA_RES_1024X768
:
722 reg_num
= NUM_TOTAL_K400_LCD_RES_10X7_1366X7
;
723 lcd_patch_reg
= K400_LCD_RES_10X7_1366X7
;
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
;
736 case LCD_PANEL_IDB_1360X768
:
740 /* H.W. Reset : ON */
741 viafb_write_reg_mask(CR17
, VIACR
, 0x00, BIT7
);
743 viafb_write_regx(lcd_patch_reg
, reg_num
);
745 /* H.W. Reset : OFF */
746 viafb_write_reg_mask(CR17
, VIACR
, 0x80, BIT7
);
749 viafb_write_reg_mask(SR40
, VIASR
, 0x02, BIT1
);
750 viafb_write_reg_mask(SR40
, VIASR
, 0x00, BIT1
);
753 outb(inb(VIARMisc
) | (BIT2
+ BIT3
), VIAWMisc
);
757 static void load_lcd_p880_patch_tbl(int set_hres
, int set_vres
,
762 struct io_reg
*lcd_patch_reg
= NULL
;
764 if (viaparinfo
->lvds_setting_info
->iga_path
== IGA2
)
765 vmode_index
= viafb_get_mode_index(set_hres
, set_vres
, 1);
767 vmode_index
= viafb_get_mode_index(set_hres
, set_vres
, 0);
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
;
776 case VIA_RES_800X600
:
777 reg_num
= NUM_TOTAL_P880_LCD_RES_8X6_14X10
;
778 lcd_patch_reg
= P880_LCD_RES_8X6_14X10
;
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
;
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
;
794 case VIA_RES_800X600
:
795 reg_num
= NUM_TOTAL_P880_LCD_RES_8X6_16X12
;
796 lcd_patch_reg
= P880_LCD_RES_8X6_16X12
;
798 case VIA_RES_1024X768
:
799 reg_num
= NUM_TOTAL_P880_LCD_RES_10X7_16X12
;
800 lcd_patch_reg
= P880_LCD_RES_10X7_16X12
;
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
;
813 /* H.W. Reset : ON */
814 viafb_write_reg_mask(CR17
, VIACR
, 0x00, BIT7
);
816 viafb_write_regx(lcd_patch_reg
, reg_num
);
818 /* H.W. Reset : OFF */
819 viafb_write_reg_mask(CR17
, VIACR
, 0x80, BIT7
);
822 viafb_write_reg_mask(SR40
, VIASR
, 0x02, BIT1
);
823 viafb_write_reg_mask(SR40
, VIASR
, 0x00, BIT1
);
826 outb(inb(VIARMisc
) | (BIT2
+ BIT3
), VIAWMisc
);
830 static void load_lcd_patch_regs(int set_hres
, int set_vres
,
831 int panel_id
, int set_iga
)
835 if (viaparinfo
->lvds_setting_info
->iga_path
== IGA2
)
836 vmode_index
= viafb_get_mode_index(set_hres
, set_vres
, 1);
838 vmode_index
= viafb_get_mode_index(set_hres
, set_vres
, 0);
842 /* Patch for simultaneous & Expansion */
843 if ((set_iga
== IGA1_IGA2
) &&
844 (viaparinfo
->lvds_setting_info
->display_method
==
846 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
847 case UNICHROME_CLE266
:
849 load_lcd_k400_patch_tbl(set_hres
, set_vres
, panel_id
);
853 case UNICHROME_PM800
:
854 case UNICHROME_CN700
:
855 case UNICHROME_CX700
:
856 load_lcd_p880_patch_tbl(set_hres
, set_vres
, panel_id
);
863 static void via_pitch_alignment_patch_lcd(
864 struct lvds_setting_information
*plvds_setting_info
,
865 struct lvds_chip_information
868 unsigned char cr13
, cr35
, cr65
, cr66
, cr67
;
869 unsigned long dwScreenPitch
= 0;
870 unsigned long dwPitch
;
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;
882 char)((dwScreenPitch
& 0x300) >> 8);
883 viafb_write_reg(CR67
, VIACR
, cr67
);
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);
892 viafb_write_reg(CR65
, VIACR
, cr65
);
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;
900 char)((dwScreenPitch
& 0x700) >> 3);
901 viafb_write_reg(CR35
, VIACR
, cr35
);
906 static void lcd_patch_skew_dvp0(struct lvds_setting_information
908 struct lvds_chip_information
*plvds_chip_info
)
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
,
916 case UNICHROME_P4M890
:
917 viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info
,
923 static void lcd_patch_skew_dvp1(struct lvds_setting_information
925 struct lvds_chip_information
*plvds_chip_info
)
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
,
936 static void lcd_patch_skew(struct lvds_setting_information
937 *plvds_setting_info
, struct lvds_chip_information
*plvds_chip_info
)
939 DEBUG_MSG(KERN_INFO
"lcd_patch_skew\n");
940 switch (plvds_chip_info
->output_interface
) {
942 lcd_patch_skew_dvp0(plvds_setting_info
, plvds_chip_info
);
945 lcd_patch_skew_dvp1(plvds_setting_info
, plvds_chip_info
);
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
);
957 void 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
)
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;
966 int set_hres
, set_vres
;
967 int panel_hres
, panel_vres
;
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
;
975 DEBUG_MSG(KERN_INFO
"viafb_lcd_set_mode!!\n");
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
);
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
,
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 */
1016 if (set_iga
== IGA1_IGA2
) {
1017 load_crtc_shadow_timing(mode_crt_reg
, panel_crt_reg
);
1018 /* Fill shadow registers */
1020 switch (plvds_setting_info
->lcd_panel_id
) {
1021 case LCD_PANEL_ID0_640X480
:
1024 case LCD_PANEL_ID1_800X600
:
1025 case LCD_PANEL_IDA_800X480
:
1028 case LCD_PANEL_ID2_1024X768
:
1031 case LCD_PANEL_ID3_1280X768
:
1032 case LCD_PANEL_ID4_1280X1024
:
1033 case LCD_PANEL_ID5_1400X1050
:
1034 case LCD_PANEL_ID9_1280X800
:
1037 case LCD_PANEL_ID6_1600X1200
:
1040 case LCD_PANEL_ID7_1366X768
:
1041 case LCD_PANEL_IDB_1360X768
:
1049 /* Offset for simultaneous */
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 */
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
);
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
);
1067 viafb_set_color_depth(mode_bpp
/ 8, set_iga
);
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
);
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
);
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
);
1085 load_lcd_patch_regs(set_hres
, set_vres
,
1086 plvds_setting_info
->lcd_panel_id
, set_iga
);
1088 DEBUG_MSG(KERN_INFO
"load_lcd_patch_regs!!\n");
1090 /* Patch for non 32bit alignment mode */
1091 via_pitch_alignment_patch_lcd(plvds_setting_info
, plvds_chip_info
);
1094 static void integrated_lvds_disable(struct lvds_setting_information
1095 *plvds_setting_info
,
1096 struct lvds_chip_information
*plvds_chip_info
)
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: */
1109 /* Turn off power sequence. */
1110 viafb_write_reg_mask(CRD4
, VIACR
, 0, BIT1
);
1112 /* Turn off back light. */
1113 viafb_write_reg_mask(CRD3
, VIACR
, 0xC0, BIT6
+ BIT7
);
1115 if (turn_off_first_powersequence
) {
1116 /* Use first power sequence control: */
1118 /* Turn off power sequence. */
1119 viafb_write_reg_mask(CR6A
, VIACR
, 0, BIT3
);
1121 /* Turn off back light. */
1122 viafb_write_reg_mask(CR91
, VIACR
, 0xC0, BIT6
+ BIT7
);
1125 /* Turn DFP High/Low Pad off. */
1126 viafb_write_reg_mask(SR2A
, VIASR
, 0, BIT0
+ BIT1
+ BIT2
+ BIT3
);
1128 /* Power off LVDS channel. */
1129 switch (plvds_chip_info
->output_interface
) {
1130 case INTERFACE_LVDS0
:
1132 viafb_write_reg_mask(CRD2
, VIACR
, 0x80, BIT7
);
1136 case INTERFACE_LVDS1
:
1138 viafb_write_reg_mask(CRD2
, VIACR
, 0x40, BIT6
);
1142 case INTERFACE_LVDS0LVDS1
:
1144 viafb_write_reg_mask(CRD2
, VIACR
, 0xC0, BIT6
+ BIT7
);
1150 static void integrated_lvds_enable(struct lvds_setting_information
1151 *plvds_setting_info
,
1152 struct lvds_chip_information
*plvds_chip_info
)
1154 bool turn_on_first_powersequence
= false;
1155 bool turn_on_second_powersequence
= false;
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
);
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;
1170 if (turn_on_second_powersequence
) {
1171 /* Use second power sequence control: */
1173 /* Use hardware control power sequence. */
1174 viafb_write_reg_mask(CRD3
, VIACR
, 0, BIT0
);
1176 /* Turn on back light. */
1177 viafb_write_reg_mask(CRD3
, VIACR
, 0, BIT6
+ BIT7
);
1179 /* Turn on hardware power sequence. */
1180 viafb_write_reg_mask(CRD4
, VIACR
, 0x02, BIT1
);
1182 if (turn_on_first_powersequence
) {
1183 /* Use first power sequence control: */
1185 /* Use hardware control power sequence. */
1186 viafb_write_reg_mask(CR91
, VIACR
, 0, BIT0
);
1188 /* Turn on back light. */
1189 viafb_write_reg_mask(CR91
, VIACR
, 0, BIT6
+ BIT7
);
1191 /* Turn on hardware power sequence. */
1192 viafb_write_reg_mask(CR6A
, VIACR
, 0x08, BIT3
);
1195 /* Turn DFP High/Low pad on. */
1196 viafb_write_reg_mask(SR2A
, VIASR
, 0x0F, BIT0
+ BIT1
+ BIT2
+ BIT3
);
1198 /* Power on LVDS channel. */
1199 switch (plvds_chip_info
->output_interface
) {
1200 case INTERFACE_LVDS0
:
1202 viafb_write_reg_mask(CRD2
, VIACR
, 0, BIT7
);
1206 case INTERFACE_LVDS1
:
1208 viafb_write_reg_mask(CRD2
, VIACR
, 0, BIT6
);
1212 case INTERFACE_LVDS0LVDS1
:
1214 viafb_write_reg_mask(CRD2
, VIACR
, 0, BIT6
+ BIT7
);
1220 void viafb_lcd_disable(void)
1223 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
) {
1224 lcd_powersequence_off();
1226 viafb_write_reg_mask(SR1E
, VIASR
, 0x00, 0x30);
1227 } else if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
) {
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
);
1246 /* DFP-HL pad off */
1247 viafb_write_reg_mask(SR2A
, VIASR
, 0x00, 0x0F);
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);
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);
1267 void viafb_lcd_enable(void)
1269 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
) {
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
->
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
);
1293 viafb_write_reg_mask(SR2A
, VIASR
, 0x0F, 0x0F);
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);
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);
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);
1312 viafb_write_reg_mask(CR6A
, VIACR
, 0x48, 0x48);
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 */
1323 viafb_write_reg_mask(CR6A
, VIACR
, 0x80, 0x80);
1328 static void lcd_powersequence_off(void)
1332 /* Software control power sequence */
1333 viafb_write_reg_mask(CR91
, VIACR
, 0x11, 0x11);
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
]);
1343 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, 0x08);
1346 static void lcd_powersequence_on(void)
1350 /* Software control power sequence */
1351 viafb_write_reg_mask(CR91
, VIACR
, 0x11, 0x11);
1354 viafb_write_reg_mask(CR6A
, VIACR
, 0x08, 0x08);
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
]);
1366 static void fill_lcd_format(void)
1368 u8 bdithering
= 0, bdual
= 0;
1370 if (viaparinfo
->lvds_setting_info
->device_lcd_dualedge
)
1372 if (viaparinfo
->lvds_setting_info
->LCDDithering
)
1374 /* Dual & Dithering */
1375 viafb_write_reg_mask(CR88
, VIACR
, (bdithering
| bdual
), BIT4
+ BIT0
);
1378 static void check_diport_of_integrated_lvds(
1379 struct lvds_chip_information
*plvds_chip_info
,
1380 struct lvds_setting_information
1381 *plvds_setting_info
)
1383 /* Determine LCD DI Port by hardware layout. */
1384 switch (viafb_display_hardware_layout
) {
1385 case HW_LAYOUT_LCD_ONLY
:
1387 if (plvds_setting_info
->device_lcd_dualedge
) {
1388 plvds_chip_info
->output_interface
=
1389 INTERFACE_LVDS0LVDS1
;
1391 plvds_chip_info
->output_interface
=
1398 case HW_LAYOUT_DVI_ONLY
:
1400 plvds_chip_info
->output_interface
= INTERFACE_NONE
;
1404 case HW_LAYOUT_LCD1_LCD2
:
1405 case HW_LAYOUT_LCD_EXTERNAL_LCD2
:
1407 plvds_chip_info
->output_interface
=
1408 INTERFACE_LVDS0LVDS1
;
1412 case HW_LAYOUT_LCD_DVI
:
1414 plvds_chip_info
->output_interface
= INTERFACE_LVDS1
;
1420 plvds_chip_info
->output_interface
= INTERFACE_LVDS1
;
1426 "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n",
1427 viafb_display_hardware_layout
,
1428 plvds_chip_info
->output_interface
);
1431 void viafb_init_lvds_output_interface(struct lvds_chip_information
1433 struct lvds_setting_information
1434 *plvds_setting_info
)
1436 if (INTERFACE_NONE
!= plvds_chip_info
->output_interface
) {
1437 /*Do nothing, lcd port is specified by module parameter */
1441 switch (plvds_chip_info
->lvds_chip_name
) {
1444 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
1445 case UNICHROME_CX700
:
1446 plvds_chip_info
->output_interface
= INTERFACE_DVP1
;
1448 case UNICHROME_CN700
:
1449 plvds_chip_info
->output_interface
= INTERFACE_DFP_LOW
;
1452 plvds_chip_info
->output_interface
= INTERFACE_DVP0
;
1457 case INTEGRATED_LVDS
:
1458 check_diport_of_integrated_lvds(plvds_chip_info
,
1459 plvds_setting_info
);
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
;
1470 plvds_chip_info
->output_interface
= INTERFACE_DFP
;
1477 static struct display_timing
lcd_centering_timging(struct display_timing
1479 struct display_timing panel_crt_reg
)
1481 struct display_timing crt_reg
;
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 +
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
;
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 +
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
;
1508 static void load_crtc_shadow_timing(struct display_timing mode_timing
,
1509 struct display_timing panel_timing
)
1511 struct io_register
*reg
= NULL
;
1513 int viafb_load_reg_Num
= 0;
1516 if (viaparinfo
->lvds_setting_info
->display_method
== LCD_EXPANDSION
) {
1518 for (i
= 12; i
< 20; i
++) {
1520 case H_TOTAL_SHADOW_INDEX
:
1522 IGA2_HOR_TOTAL_SHADOW_FORMULA
1523 (panel_timing
.hor_total
);
1524 viafb_load_reg_Num
=
1525 iga2_shadow_crtc_reg
.hor_total_shadow
.
1527 reg
= iga2_shadow_crtc_reg
.hor_total_shadow
.reg
;
1529 case H_BLANK_END_SHADOW_INDEX
:
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
;
1538 iga2_shadow_crtc_reg
.
1539 hor_blank_end_shadow
.reg
;
1541 case V_TOTAL_SHADOW_INDEX
:
1543 IGA2_VER_TOTAL_SHADOW_FORMULA
1544 (panel_timing
.ver_total
);
1545 viafb_load_reg_Num
=
1546 iga2_shadow_crtc_reg
.ver_total_shadow
.
1548 reg
= iga2_shadow_crtc_reg
.ver_total_shadow
.reg
;
1550 case V_ADDR_SHADOW_INDEX
:
1552 IGA2_VER_ADDR_SHADOW_FORMULA
1553 (panel_timing
.ver_addr
);
1554 viafb_load_reg_Num
=
1555 iga2_shadow_crtc_reg
.ver_addr_shadow
.
1557 reg
= iga2_shadow_crtc_reg
.ver_addr_shadow
.reg
;
1559 case V_BLANK_SATRT_SHADOW_INDEX
:
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
;
1567 iga2_shadow_crtc_reg
.
1568 ver_blank_start_shadow
.reg
;
1570 case V_BLANK_END_SHADOW_INDEX
:
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
;
1579 iga2_shadow_crtc_reg
.
1580 ver_blank_end_shadow
.reg
;
1582 case V_SYNC_SATRT_SHADOW_INDEX
:
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
;
1590 iga2_shadow_crtc_reg
.
1591 ver_sync_start_shadow
.reg
;
1593 case V_SYNC_END_SHADOW_INDEX
:
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
;
1602 iga2_shadow_crtc_reg
.
1603 ver_sync_end_shadow
.reg
;
1606 viafb_load_reg(reg_value
,
1607 viafb_load_reg_Num
, reg
, VIACR
);
1609 } else { /* Centering */
1610 for (i
= 12; i
< 20; i
++) {
1612 case H_TOTAL_SHADOW_INDEX
:
1614 IGA2_HOR_TOTAL_SHADOW_FORMULA
1615 (panel_timing
.hor_total
);
1616 viafb_load_reg_Num
=
1617 iga2_shadow_crtc_reg
.hor_total_shadow
.
1619 reg
= iga2_shadow_crtc_reg
.hor_total_shadow
.reg
;
1621 case H_BLANK_END_SHADOW_INDEX
:
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
;
1630 iga2_shadow_crtc_reg
.
1631 hor_blank_end_shadow
.reg
;
1633 case V_TOTAL_SHADOW_INDEX
:
1635 IGA2_VER_TOTAL_SHADOW_FORMULA
1636 (panel_timing
.ver_total
);
1637 viafb_load_reg_Num
=
1638 iga2_shadow_crtc_reg
.ver_total_shadow
.
1640 reg
= iga2_shadow_crtc_reg
.ver_total_shadow
.reg
;
1642 case V_ADDR_SHADOW_INDEX
:
1644 IGA2_VER_ADDR_SHADOW_FORMULA
1645 (mode_timing
.ver_addr
);
1646 viafb_load_reg_Num
=
1647 iga2_shadow_crtc_reg
.ver_addr_shadow
.
1649 reg
= iga2_shadow_crtc_reg
.ver_addr_shadow
.reg
;
1651 case V_BLANK_SATRT_SHADOW_INDEX
:
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
;
1659 iga2_shadow_crtc_reg
.
1660 ver_blank_start_shadow
.reg
;
1662 case V_BLANK_END_SHADOW_INDEX
:
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
;
1671 iga2_shadow_crtc_reg
.
1672 ver_blank_end_shadow
.reg
;
1674 case V_SYNC_SATRT_SHADOW_INDEX
:
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
.
1686 iga2_shadow_crtc_reg
.ver_sync_start_shadow
.
1689 case V_SYNC_END_SHADOW_INDEX
:
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
.
1702 iga2_shadow_crtc_reg
.ver_sync_end_shadow
.
1706 viafb_load_reg(reg_value
,
1707 viafb_load_reg_Num
, reg
, VIACR
);
1712 bool viafb_lcd_get_mobile_state(bool *mobile
)
1714 unsigned char *romptr
, *tableptr
;
1716 unsigned char *biosptr
;
1718 u32 romaddr
= 0x000C0000;
1719 u16 start_pattern
= 0;
1721 biosptr
= ioremap(romaddr
, 0x10000);
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
);
1731 /* Get the start of biosver structure */
1732 /* 18 means BIOS version position. */
1733 romptr
= tableptr
+ 18;
1734 romptr
= biosptr
+ *((u16
*) romptr
);
1736 /* The offset should be 44, but the
1737 actual image is less three char. */
1741 core_base
= *romptr
++;
1743 if (core_base
& 0x8)
1747 /* release memory */
1757 static void viafb_load_scaling_factor_for_p4m900(int set_hres
,
1758 int set_vres
, int panel_hres
, int panel_vres
)
1760 int h_scaling_factor
;
1761 int v_scaling_factor
;
1767 /* Check if expansion for horizontal */
1768 if (set_hres
< panel_hres
) {
1769 /* Load Horizontal Scaling Factor */
1771 /* For VIA_K8M800 or later chipsets. */
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;
1782 /* Horizontal scaling enabled */
1785 DEBUG_MSG(KERN_INFO
"Horizontal Scaling value = %d\n",
1788 /* Horizontal scaling disabled */
1792 /* Check if expansion for vertical */
1793 if (set_vres
< panel_vres
) {
1794 /* Load Vertical Scaling Factor */
1796 /* For VIA_K8M800 or later chipsets. */
1798 K800_LCD_VER_SCF_FORMULA(set_vres
, panel_vres
);
1800 /* Vertical scaling enabled */
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;
1809 DEBUG_MSG(KERN_INFO
"Vertical Scaling value = %d\n",
1812 /* Vertical scaling disabled */
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
);