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
->shared
->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
->shared
->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
->shared
->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 vmode_index
= viafb_get_mode_index(set_hres
, set_vres
);
586 case LCD_PANEL_ID1_800X600
:
587 switch (vmode_index
) {
588 case VIA_RES_640X400
:
589 case VIA_RES_640X480
:
590 reg_num
= NUM_TOTAL_K400_LCD_RES_6X4_8X6
;
591 lcd_patch_reg
= K400_LCD_RES_6X4_8X6
;
593 case VIA_RES_720X480
:
594 case VIA_RES_720X576
:
595 reg_num
= NUM_TOTAL_K400_LCD_RES_7X4_8X6
;
596 lcd_patch_reg
= K400_LCD_RES_7X4_8X6
;
602 case LCD_PANEL_ID2_1024X768
:
603 switch (vmode_index
) {
604 case VIA_RES_640X400
:
605 case VIA_RES_640X480
:
606 reg_num
= NUM_TOTAL_K400_LCD_RES_6X4_10X7
;
607 lcd_patch_reg
= K400_LCD_RES_6X4_10X7
;
609 case VIA_RES_720X480
:
610 case VIA_RES_720X576
:
611 reg_num
= NUM_TOTAL_K400_LCD_RES_7X4_10X7
;
612 lcd_patch_reg
= K400_LCD_RES_7X4_10X7
;
614 case VIA_RES_800X600
:
615 reg_num
= NUM_TOTAL_K400_LCD_RES_8X6_10X7
;
616 lcd_patch_reg
= K400_LCD_RES_8X6_10X7
;
622 case LCD_PANEL_ID4_1280X1024
:
623 switch (vmode_index
) {
624 case VIA_RES_640X400
:
625 case VIA_RES_640X480
:
626 reg_num
= NUM_TOTAL_K400_LCD_RES_6X4_12X10
;
627 lcd_patch_reg
= K400_LCD_RES_6X4_12X10
;
629 case VIA_RES_720X480
:
630 case VIA_RES_720X576
:
631 reg_num
= NUM_TOTAL_K400_LCD_RES_7X4_12X10
;
632 lcd_patch_reg
= K400_LCD_RES_7X4_12X10
;
634 case VIA_RES_800X600
:
635 reg_num
= NUM_TOTAL_K400_LCD_RES_8X6_12X10
;
636 lcd_patch_reg
= K400_LCD_RES_8X6_12X10
;
638 case VIA_RES_1024X768
:
639 reg_num
= NUM_TOTAL_K400_LCD_RES_10X7_12X10
;
640 lcd_patch_reg
= K400_LCD_RES_10X7_12X10
;
647 case LCD_PANEL_ID5_1400X1050
:
648 switch (vmode_index
) {
649 case VIA_RES_640X480
:
650 reg_num
= NUM_TOTAL_K400_LCD_RES_6X4_14X10
;
651 lcd_patch_reg
= K400_LCD_RES_6X4_14X10
;
653 case VIA_RES_800X600
:
654 reg_num
= NUM_TOTAL_K400_LCD_RES_8X6_14X10
;
655 lcd_patch_reg
= K400_LCD_RES_8X6_14X10
;
657 case VIA_RES_1024X768
:
658 reg_num
= NUM_TOTAL_K400_LCD_RES_10X7_14X10
;
659 lcd_patch_reg
= K400_LCD_RES_10X7_14X10
;
661 case VIA_RES_1280X768
:
662 case VIA_RES_1280X800
:
663 case VIA_RES_1280X960
:
664 case VIA_RES_1280X1024
:
665 reg_num
= NUM_TOTAL_K400_LCD_RES_12X10_14X10
;
666 lcd_patch_reg
= K400_LCD_RES_12X10_14X10
;
672 case LCD_PANEL_ID6_1600X1200
:
673 switch (vmode_index
) {
674 case VIA_RES_640X400
:
675 case VIA_RES_640X480
:
676 reg_num
= NUM_TOTAL_K400_LCD_RES_6X4_16X12
;
677 lcd_patch_reg
= K400_LCD_RES_6X4_16X12
;
679 case VIA_RES_720X480
:
680 case VIA_RES_720X576
:
681 reg_num
= NUM_TOTAL_K400_LCD_RES_7X4_16X12
;
682 lcd_patch_reg
= K400_LCD_RES_7X4_16X12
;
684 case VIA_RES_800X600
:
685 reg_num
= NUM_TOTAL_K400_LCD_RES_8X6_16X12
;
686 lcd_patch_reg
= K400_LCD_RES_8X6_16X12
;
688 case VIA_RES_1024X768
:
689 reg_num
= NUM_TOTAL_K400_LCD_RES_10X7_16X12
;
690 lcd_patch_reg
= K400_LCD_RES_10X7_16X12
;
692 case VIA_RES_1280X768
:
693 case VIA_RES_1280X800
:
694 case VIA_RES_1280X960
:
695 case VIA_RES_1280X1024
:
696 reg_num
= NUM_TOTAL_K400_LCD_RES_12X10_16X12
;
697 lcd_patch_reg
= K400_LCD_RES_12X10_16X12
;
703 case LCD_PANEL_ID7_1366X768
:
704 switch (vmode_index
) {
705 case VIA_RES_640X480
:
706 reg_num
= NUM_TOTAL_K400_LCD_RES_6X4_1366X7
;
707 lcd_patch_reg
= K400_LCD_RES_6X4_1366X7
;
709 case VIA_RES_720X480
:
710 case VIA_RES_720X576
:
711 reg_num
= NUM_TOTAL_K400_LCD_RES_7X4_1366X7
;
712 lcd_patch_reg
= K400_LCD_RES_7X4_1366X7
;
714 case VIA_RES_800X600
:
715 reg_num
= NUM_TOTAL_K400_LCD_RES_8X6_1366X7
;
716 lcd_patch_reg
= K400_LCD_RES_8X6_1366X7
;
718 case VIA_RES_1024X768
:
719 reg_num
= NUM_TOTAL_K400_LCD_RES_10X7_1366X7
;
720 lcd_patch_reg
= K400_LCD_RES_10X7_1366X7
;
722 case VIA_RES_1280X768
:
723 case VIA_RES_1280X800
:
724 case VIA_RES_1280X960
:
725 case VIA_RES_1280X1024
:
726 reg_num
= NUM_TOTAL_K400_LCD_RES_12X10_1366X7
;
727 lcd_patch_reg
= K400_LCD_RES_12X10_1366X7
;
733 case LCD_PANEL_IDB_1360X768
:
737 /* H.W. Reset : ON */
738 viafb_write_reg_mask(CR17
, VIACR
, 0x00, BIT7
);
740 viafb_write_regx(lcd_patch_reg
, reg_num
);
742 /* H.W. Reset : OFF */
743 viafb_write_reg_mask(CR17
, VIACR
, 0x80, BIT7
);
746 viafb_write_reg_mask(SR40
, VIASR
, 0x02, BIT1
);
747 viafb_write_reg_mask(SR40
, VIASR
, 0x00, BIT1
);
750 outb(inb(VIARMisc
) | (BIT2
+ BIT3
), VIAWMisc
);
754 static void load_lcd_p880_patch_tbl(int set_hres
, int set_vres
,
759 struct io_reg
*lcd_patch_reg
= NULL
;
761 vmode_index
= viafb_get_mode_index(set_hres
, set_vres
);
764 case LCD_PANEL_ID5_1400X1050
:
765 switch (vmode_index
) {
766 case VIA_RES_640X480
:
767 reg_num
= NUM_TOTAL_P880_LCD_RES_6X4_14X10
;
768 lcd_patch_reg
= P880_LCD_RES_6X4_14X10
;
770 case VIA_RES_800X600
:
771 reg_num
= NUM_TOTAL_P880_LCD_RES_8X6_14X10
;
772 lcd_patch_reg
= P880_LCD_RES_8X6_14X10
;
776 case LCD_PANEL_ID6_1600X1200
:
777 switch (vmode_index
) {
778 case VIA_RES_640X400
:
779 case VIA_RES_640X480
:
780 reg_num
= NUM_TOTAL_P880_LCD_RES_6X4_16X12
;
781 lcd_patch_reg
= P880_LCD_RES_6X4_16X12
;
783 case VIA_RES_720X480
:
784 case VIA_RES_720X576
:
785 reg_num
= NUM_TOTAL_P880_LCD_RES_7X4_16X12
;
786 lcd_patch_reg
= P880_LCD_RES_7X4_16X12
;
788 case VIA_RES_800X600
:
789 reg_num
= NUM_TOTAL_P880_LCD_RES_8X6_16X12
;
790 lcd_patch_reg
= P880_LCD_RES_8X6_16X12
;
792 case VIA_RES_1024X768
:
793 reg_num
= NUM_TOTAL_P880_LCD_RES_10X7_16X12
;
794 lcd_patch_reg
= P880_LCD_RES_10X7_16X12
;
796 case VIA_RES_1280X768
:
797 case VIA_RES_1280X960
:
798 case VIA_RES_1280X1024
:
799 reg_num
= NUM_TOTAL_P880_LCD_RES_12X10_16X12
;
800 lcd_patch_reg
= P880_LCD_RES_12X10_16X12
;
807 /* H.W. Reset : ON */
808 viafb_write_reg_mask(CR17
, VIACR
, 0x00, BIT7
);
810 viafb_write_regx(lcd_patch_reg
, reg_num
);
812 /* H.W. Reset : OFF */
813 viafb_write_reg_mask(CR17
, VIACR
, 0x80, BIT7
);
816 viafb_write_reg_mask(SR40
, VIASR
, 0x02, BIT1
);
817 viafb_write_reg_mask(SR40
, VIASR
, 0x00, BIT1
);
820 outb(inb(VIARMisc
) | (BIT2
+ BIT3
), VIAWMisc
);
824 static void load_lcd_patch_regs(int set_hres
, int set_vres
,
825 int panel_id
, int set_iga
)
829 vmode_index
= viafb_get_mode_index(set_hres
, set_vres
);
833 /* Patch for simultaneous & Expansion */
834 if ((set_iga
== IGA1_IGA2
) &&
835 (viaparinfo
->lvds_setting_info
->display_method
==
837 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
838 case UNICHROME_CLE266
:
840 load_lcd_k400_patch_tbl(set_hres
, set_vres
, panel_id
);
844 case UNICHROME_PM800
:
845 case UNICHROME_CN700
:
846 case UNICHROME_CX700
:
847 load_lcd_p880_patch_tbl(set_hres
, set_vres
, panel_id
);
854 static void via_pitch_alignment_patch_lcd(
855 struct lvds_setting_information
*plvds_setting_info
,
856 struct lvds_chip_information
859 unsigned char cr13
, cr35
, cr65
, cr66
, cr67
;
860 unsigned long dwScreenPitch
= 0;
861 unsigned long dwPitch
;
863 dwPitch
= plvds_setting_info
->h_active
* (plvds_setting_info
->bpp
>> 3);
864 if (dwPitch
& 0x1F) {
865 dwScreenPitch
= ((dwPitch
+ 31) & ~31) >> 3;
866 if (plvds_setting_info
->iga_path
== IGA2
) {
867 if (plvds_setting_info
->bpp
> 8) {
868 cr66
= (unsigned char)(dwScreenPitch
& 0xFF);
869 viafb_write_reg(CR66
, VIACR
, cr66
);
870 cr67
= viafb_read_reg(VIACR
, CR67
) & 0xFC;
873 char)((dwScreenPitch
& 0x300) >> 8);
874 viafb_write_reg(CR67
, VIACR
, cr67
);
878 cr67
= viafb_read_reg(VIACR
, CR67
) & 0xF3;
879 cr67
|= (unsigned char)((dwScreenPitch
& 0x600) >> 7);
880 viafb_write_reg(CR67
, VIACR
, cr67
);
881 cr65
= (unsigned char)((dwScreenPitch
>> 1) & 0xFF);
883 viafb_write_reg(CR65
, VIACR
, cr65
);
885 if (plvds_setting_info
->bpp
> 8) {
886 cr13
= (unsigned char)(dwScreenPitch
& 0xFF);
887 viafb_write_reg(CR13
, VIACR
, cr13
);
888 cr35
= viafb_read_reg(VIACR
, CR35
) & 0x1F;
891 char)((dwScreenPitch
& 0x700) >> 3);
892 viafb_write_reg(CR35
, VIACR
, cr35
);
897 static void lcd_patch_skew_dvp0(struct lvds_setting_information
899 struct lvds_chip_information
*plvds_chip_info
)
901 if (VT1636_LVDS
== plvds_chip_info
->lvds_chip_name
) {
902 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
903 case UNICHROME_P4M900
:
904 viafb_vt1636_patch_skew_on_vt3364(plvds_setting_info
,
907 case UNICHROME_P4M890
:
908 viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info
,
914 static void lcd_patch_skew_dvp1(struct lvds_setting_information
916 struct lvds_chip_information
*plvds_chip_info
)
918 if (VT1636_LVDS
== plvds_chip_info
->lvds_chip_name
) {
919 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
920 case UNICHROME_CX700
:
921 viafb_vt1636_patch_skew_on_vt3324(plvds_setting_info
,
927 static void lcd_patch_skew(struct lvds_setting_information
928 *plvds_setting_info
, struct lvds_chip_information
*plvds_chip_info
)
930 DEBUG_MSG(KERN_INFO
"lcd_patch_skew\n");
931 switch (plvds_chip_info
->output_interface
) {
933 lcd_patch_skew_dvp0(plvds_setting_info
, plvds_chip_info
);
936 lcd_patch_skew_dvp1(plvds_setting_info
, plvds_chip_info
);
938 case INTERFACE_DFP_LOW
:
939 if (UNICHROME_P4M900
== viaparinfo
->chip_info
->gfx_chip_name
) {
940 viafb_write_reg_mask(CR99
, VIACR
, 0x08,
941 BIT0
+ BIT1
+ BIT2
+ BIT3
);
948 void viafb_lcd_set_mode(struct crt_mode_table
*mode_crt_table
,
949 struct lvds_setting_information
*plvds_setting_info
,
950 struct lvds_chip_information
*plvds_chip_info
)
952 int video_index
= plvds_setting_info
->lcd_panel_size
;
953 int set_iga
= plvds_setting_info
->iga_path
;
954 int mode_bpp
= plvds_setting_info
->bpp
;
955 int set_hres
, set_vres
;
956 int panel_hres
, panel_vres
;
959 struct display_timing mode_crt_reg
, panel_crt_reg
;
960 struct crt_mode_table
*panel_crt_table
= NULL
;
961 struct VideoModeTable
*vmode_tbl
= NULL
;
963 DEBUG_MSG(KERN_INFO
"viafb_lcd_set_mode!!\n");
965 mode_crt_reg
= mode_crt_table
->crtc
;
966 /* Get panel table Pointer */
967 vmode_tbl
= viafb_get_modetbl_pointer(video_index
);
968 panel_crt_table
= vmode_tbl
->crtc
;
969 panel_crt_reg
= panel_crt_table
->crtc
;
970 DEBUG_MSG(KERN_INFO
"bellow viafb_lcd_set_mode!!\n");
971 set_hres
= plvds_setting_info
->h_active
;
972 set_vres
= plvds_setting_info
->v_active
;
973 panel_hres
= plvds_setting_info
->lcd_panel_hres
;
974 panel_vres
= plvds_setting_info
->lcd_panel_vres
;
975 if (VT1636_LVDS
== plvds_chip_info
->lvds_chip_name
)
976 viafb_init_lvds_vt1636(plvds_setting_info
, plvds_chip_info
);
977 plvds_setting_info
->vclk
= panel_crt_table
->clk
;
978 if (set_iga
== IGA1
) {
979 /* IGA1 doesn't have LCD scaling, so set it as centering. */
980 viafb_load_crtc_timing(lcd_centering_timging
981 (mode_crt_reg
, panel_crt_reg
), IGA1
);
984 if ((plvds_setting_info
->display_method
==
985 LCD_EXPANDSION
) & ((set_hres
!= panel_hres
)
986 || (set_vres
!= panel_vres
))) {
987 /* expansion timing IGA2 loaded panel set timing*/
988 viafb_load_crtc_timing(panel_crt_reg
, IGA2
);
989 DEBUG_MSG(KERN_INFO
"viafb_load_crtc_timing!!\n");
990 load_lcd_scaling(set_hres
, set_vres
, panel_hres
,
992 DEBUG_MSG(KERN_INFO
"load_lcd_scaling!!\n");
993 } else { /* Centering */
994 /* centering timing IGA2 always loaded panel
995 and mode releative timing */
996 viafb_load_crtc_timing(lcd_centering_timging
997 (mode_crt_reg
, panel_crt_reg
), IGA2
);
998 viafb_write_reg_mask(CR79
, VIACR
, 0x00,
1000 /* LCD scaling disabled */
1004 if (set_iga
== IGA1_IGA2
) {
1005 load_crtc_shadow_timing(mode_crt_reg
, panel_crt_reg
);
1006 /* Fill shadow registers */
1008 switch (plvds_setting_info
->lcd_panel_id
) {
1009 case LCD_PANEL_ID0_640X480
:
1012 case LCD_PANEL_ID1_800X600
:
1013 case LCD_PANEL_IDA_800X480
:
1016 case LCD_PANEL_ID2_1024X768
:
1019 case LCD_PANEL_ID3_1280X768
:
1020 case LCD_PANEL_ID4_1280X1024
:
1021 case LCD_PANEL_ID5_1400X1050
:
1022 case LCD_PANEL_ID9_1280X800
:
1025 case LCD_PANEL_ID6_1600X1200
:
1028 case LCD_PANEL_ID7_1366X768
:
1029 case LCD_PANEL_IDB_1360X768
:
1037 /* Offset for simultaneous */
1038 viafb_set_secondary_pitch(offset
<< 3);
1039 DEBUG_MSG(KERN_INFO
"viafb_load_reg!!\n");
1040 viafb_load_fetch_count_reg(set_hres
, 4, IGA2
);
1041 /* Fetch count for simultaneous */
1043 /* Fetch count for IGA2 only */
1044 viafb_load_fetch_count_reg(set_hres
, mode_bpp
/ 8, set_iga
);
1046 if ((viaparinfo
->chip_info
->gfx_chip_name
!= UNICHROME_CLE266
)
1047 && (viaparinfo
->chip_info
->gfx_chip_name
!= UNICHROME_K400
))
1048 viafb_load_FIFO_reg(set_iga
, set_hres
, set_vres
);
1050 viafb_set_color_depth(mode_bpp
/ 8, set_iga
);
1055 pll_D_N
= viafb_get_clk_value(panel_crt_table
[0].clk
);
1056 DEBUG_MSG(KERN_INFO
"PLL=0x%x", pll_D_N
);
1057 viafb_set_vclock(pll_D_N
, set_iga
);
1059 viafb_set_output_path(DEVICE_LCD
, set_iga
,
1060 plvds_chip_info
->output_interface
);
1061 lcd_patch_skew(plvds_setting_info
, plvds_chip_info
);
1063 /* If K8M800, enable LCD Prefetch Mode. */
1064 if ((viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K800
)
1065 || (UNICHROME_K8M890
== viaparinfo
->chip_info
->gfx_chip_name
))
1066 viafb_write_reg_mask(CR6A
, VIACR
, 0x01, BIT0
);
1068 load_lcd_patch_regs(set_hres
, set_vres
,
1069 plvds_setting_info
->lcd_panel_id
, set_iga
);
1071 DEBUG_MSG(KERN_INFO
"load_lcd_patch_regs!!\n");
1073 /* Patch for non 32bit alignment mode */
1074 via_pitch_alignment_patch_lcd(plvds_setting_info
, plvds_chip_info
);
1077 static void integrated_lvds_disable(struct lvds_setting_information
1078 *plvds_setting_info
,
1079 struct lvds_chip_information
*plvds_chip_info
)
1081 bool turn_off_first_powersequence
= false;
1082 bool turn_off_second_powersequence
= false;
1083 if (INTERFACE_LVDS0LVDS1
== plvds_chip_info
->output_interface
)
1084 turn_off_first_powersequence
= true;
1085 if (INTERFACE_LVDS0
== plvds_chip_info
->output_interface
)
1086 turn_off_first_powersequence
= true;
1087 if (INTERFACE_LVDS1
== plvds_chip_info
->output_interface
)
1088 turn_off_second_powersequence
= true;
1089 if (turn_off_second_powersequence
) {
1090 /* Use second power sequence control: */
1092 /* Turn off power sequence. */
1093 viafb_write_reg_mask(CRD4
, VIACR
, 0, BIT1
);
1095 /* Turn off back light. */
1096 viafb_write_reg_mask(CRD3
, VIACR
, 0xC0, BIT6
+ BIT7
);
1098 if (turn_off_first_powersequence
) {
1099 /* Use first power sequence control: */
1101 /* Turn off power sequence. */
1102 viafb_write_reg_mask(CR6A
, VIACR
, 0, BIT3
);
1104 /* Turn off back light. */
1105 viafb_write_reg_mask(CR91
, VIACR
, 0xC0, BIT6
+ BIT7
);
1108 /* Turn DFP High/Low Pad off. */
1109 viafb_write_reg_mask(SR2A
, VIASR
, 0, BIT0
+ BIT1
+ BIT2
+ BIT3
);
1111 /* Power off LVDS channel. */
1112 switch (plvds_chip_info
->output_interface
) {
1113 case INTERFACE_LVDS0
:
1115 viafb_write_reg_mask(CRD2
, VIACR
, 0x80, BIT7
);
1119 case INTERFACE_LVDS1
:
1121 viafb_write_reg_mask(CRD2
, VIACR
, 0x40, BIT6
);
1125 case INTERFACE_LVDS0LVDS1
:
1127 viafb_write_reg_mask(CRD2
, VIACR
, 0xC0, BIT6
+ BIT7
);
1133 static void integrated_lvds_enable(struct lvds_setting_information
1134 *plvds_setting_info
,
1135 struct lvds_chip_information
*plvds_chip_info
)
1137 bool turn_on_first_powersequence
= false;
1138 bool turn_on_second_powersequence
= false;
1140 DEBUG_MSG(KERN_INFO
"integrated_lvds_enable, out_interface:%d\n",
1141 plvds_chip_info
->output_interface
);
1142 if (plvds_setting_info
->lcd_mode
== LCD_SPWG
)
1143 viafb_write_reg_mask(CRD2
, VIACR
, 0x00, BIT0
+ BIT1
);
1145 viafb_write_reg_mask(CRD2
, VIACR
, 0x03, BIT0
+ BIT1
);
1146 if (INTERFACE_LVDS0LVDS1
== plvds_chip_info
->output_interface
)
1147 turn_on_first_powersequence
= true;
1148 if (INTERFACE_LVDS0
== plvds_chip_info
->output_interface
)
1149 turn_on_first_powersequence
= true;
1150 if (INTERFACE_LVDS1
== plvds_chip_info
->output_interface
)
1151 turn_on_second_powersequence
= true;
1153 if (turn_on_second_powersequence
) {
1154 /* Use second power sequence control: */
1156 /* Use hardware control power sequence. */
1157 viafb_write_reg_mask(CRD3
, VIACR
, 0, BIT0
);
1159 /* Turn on back light. */
1160 viafb_write_reg_mask(CRD3
, VIACR
, 0, BIT6
+ BIT7
);
1162 /* Turn on hardware power sequence. */
1163 viafb_write_reg_mask(CRD4
, VIACR
, 0x02, BIT1
);
1165 if (turn_on_first_powersequence
) {
1166 /* Use first power sequence control: */
1168 /* Use hardware control power sequence. */
1169 viafb_write_reg_mask(CR91
, VIACR
, 0, BIT0
);
1171 /* Turn on back light. */
1172 viafb_write_reg_mask(CR91
, VIACR
, 0, BIT6
+ BIT7
);
1174 /* Turn on hardware power sequence. */
1175 viafb_write_reg_mask(CR6A
, VIACR
, 0x08, BIT3
);
1178 /* Turn DFP High/Low pad on. */
1179 viafb_write_reg_mask(SR2A
, VIASR
, 0x0F, BIT0
+ BIT1
+ BIT2
+ BIT3
);
1181 /* Power on LVDS channel. */
1182 switch (plvds_chip_info
->output_interface
) {
1183 case INTERFACE_LVDS0
:
1185 viafb_write_reg_mask(CRD2
, VIACR
, 0, BIT7
);
1189 case INTERFACE_LVDS1
:
1191 viafb_write_reg_mask(CRD2
, VIACR
, 0, BIT6
);
1195 case INTERFACE_LVDS0LVDS1
:
1197 viafb_write_reg_mask(CRD2
, VIACR
, 0, BIT6
+ BIT7
);
1203 void viafb_lcd_disable(void)
1206 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
) {
1207 lcd_powersequence_off();
1209 viafb_write_reg_mask(SR1E
, VIASR
, 0x00, 0x30);
1210 } else if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
) {
1212 && (INTEGRATED_LVDS
==
1213 viaparinfo
->chip_info
->lvds_chip_info2
.lvds_chip_name
))
1214 integrated_lvds_disable(viaparinfo
->lvds_setting_info
,
1215 &viaparinfo
->chip_info
->lvds_chip_info2
);
1216 if (INTEGRATED_LVDS
==
1217 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
)
1218 integrated_lvds_disable(viaparinfo
->lvds_setting_info
,
1219 &viaparinfo
->chip_info
->lvds_chip_info
);
1220 if (VT1636_LVDS
== viaparinfo
->chip_info
->
1221 lvds_chip_info
.lvds_chip_name
)
1222 viafb_disable_lvds_vt1636(viaparinfo
->lvds_setting_info
,
1223 &viaparinfo
->chip_info
->lvds_chip_info
);
1224 } else if (VT1636_LVDS
==
1225 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
) {
1226 viafb_disable_lvds_vt1636(viaparinfo
->lvds_setting_info
,
1227 &viaparinfo
->chip_info
->lvds_chip_info
);
1229 /* DFP-HL pad off */
1230 viafb_write_reg_mask(SR2A
, VIASR
, 0x00, 0x0F);
1232 viafb_write_reg_mask(SR3D
, VIASR
, 0x00, 0x20);
1233 /* 24 bit DI data paht off */
1234 viafb_write_reg_mask(CR91
, VIACR
, 0x80, 0x80);
1235 /* Simultaneout disabled */
1236 viafb_write_reg_mask(CR6B
, VIACR
, 0x00, 0x08);
1239 /* Disable expansion bit */
1240 viafb_write_reg_mask(CR79
, VIACR
, 0x00, 0x01);
1241 /* CRT path set to IGA1 */
1242 viafb_write_reg_mask(SR16
, VIASR
, 0x00, 0x40);
1243 /* Simultaneout disabled */
1244 viafb_write_reg_mask(CR6B
, VIACR
, 0x00, 0x08);
1245 /* IGA2 path disabled */
1246 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, 0x80);
1250 void viafb_lcd_enable(void)
1252 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
) {
1254 viafb_write_reg_mask(SR1E
, VIASR
, 0x30, 0x30);
1255 lcd_powersequence_on();
1256 } else if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
) {
1257 if (viafb_LCD2_ON
&& (INTEGRATED_LVDS
==
1258 viaparinfo
->chip_info
->lvds_chip_info2
.lvds_chip_name
))
1259 integrated_lvds_enable(viaparinfo
->lvds_setting_info2
, \
1260 &viaparinfo
->chip_info
->lvds_chip_info2
);
1261 if (INTEGRATED_LVDS
==
1262 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
)
1263 integrated_lvds_enable(viaparinfo
->lvds_setting_info
,
1264 &viaparinfo
->chip_info
->lvds_chip_info
);
1265 if (VT1636_LVDS
== viaparinfo
->chip_info
->
1266 lvds_chip_info
.lvds_chip_name
)
1267 viafb_enable_lvds_vt1636(viaparinfo
->
1268 lvds_setting_info
, &viaparinfo
->chip_info
->
1270 } else if (VT1636_LVDS
==
1271 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
) {
1272 viafb_enable_lvds_vt1636(viaparinfo
->lvds_setting_info
,
1273 &viaparinfo
->chip_info
->lvds_chip_info
);
1276 viafb_write_reg_mask(SR2A
, VIASR
, 0x0F, 0x0F);
1278 viafb_write_reg_mask(SR3D
, VIASR
, 0x20, 0x20);
1279 /* 24 bit DI data paht on */
1280 viafb_write_reg_mask(CR91
, VIACR
, 0x00, 0x80);
1282 /* Set data source selection bit by iga path */
1283 if (viaparinfo
->lvds_setting_info
->iga_path
== IGA1
) {
1284 /* DFP-H set to IGA1 */
1285 viafb_write_reg_mask(CR97
, VIACR
, 0x00, 0x10);
1286 /* DFP-L set to IGA1 */
1287 viafb_write_reg_mask(CR99
, VIACR
, 0x00, 0x10);
1289 /* DFP-H set to IGA2 */
1290 viafb_write_reg_mask(CR97
, VIACR
, 0x10, 0x10);
1291 /* DFP-L set to IGA2 */
1292 viafb_write_reg_mask(CR99
, VIACR
, 0x10, 0x10);
1295 viafb_write_reg_mask(CR6A
, VIACR
, 0x48, 0x48);
1298 if ((viaparinfo
->lvds_setting_info
->iga_path
== IGA1
)
1299 || (viaparinfo
->lvds_setting_info
->iga_path
== IGA1_IGA2
)) {
1300 /* CRT path set to IGA2 */
1301 viafb_write_reg_mask(SR16
, VIASR
, 0x40, 0x40);
1302 /* IGA2 path disabled */
1303 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, 0x80);
1304 /* IGA2 path enabled */
1306 viafb_write_reg_mask(CR6A
, VIACR
, 0x80, 0x80);
1311 static void lcd_powersequence_off(void)
1315 /* Software control power sequence */
1316 viafb_write_reg_mask(CR91
, VIACR
, 0x11, 0x11);
1318 for (i
= 0; i
< 3; i
++) {
1319 mask
= PowerSequenceOff
[0][i
];
1320 data
= PowerSequenceOff
[1][i
] & mask
;
1321 viafb_write_reg_mask(CR91
, VIACR
, (u8
) data
, (u8
) mask
);
1322 udelay(PowerSequenceOff
[2][i
]);
1326 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, 0x08);
1329 static void lcd_powersequence_on(void)
1333 /* Software control power sequence */
1334 viafb_write_reg_mask(CR91
, VIACR
, 0x11, 0x11);
1337 viafb_write_reg_mask(CR6A
, VIACR
, 0x08, 0x08);
1339 for (i
= 0; i
< 3; i
++) {
1340 mask
= PowerSequenceOn
[0][i
];
1341 data
= PowerSequenceOn
[1][i
] & mask
;
1342 viafb_write_reg_mask(CR91
, VIACR
, (u8
) data
, (u8
) mask
);
1343 udelay(PowerSequenceOn
[2][i
]);
1349 static void fill_lcd_format(void)
1351 u8 bdithering
= 0, bdual
= 0;
1353 if (viaparinfo
->lvds_setting_info
->device_lcd_dualedge
)
1355 if (viaparinfo
->lvds_setting_info
->LCDDithering
)
1357 /* Dual & Dithering */
1358 viafb_write_reg_mask(CR88
, VIACR
, (bdithering
| bdual
), BIT4
+ BIT0
);
1361 static void check_diport_of_integrated_lvds(
1362 struct lvds_chip_information
*plvds_chip_info
,
1363 struct lvds_setting_information
1364 *plvds_setting_info
)
1366 /* Determine LCD DI Port by hardware layout. */
1367 switch (viafb_display_hardware_layout
) {
1368 case HW_LAYOUT_LCD_ONLY
:
1370 if (plvds_setting_info
->device_lcd_dualedge
) {
1371 plvds_chip_info
->output_interface
=
1372 INTERFACE_LVDS0LVDS1
;
1374 plvds_chip_info
->output_interface
=
1381 case HW_LAYOUT_DVI_ONLY
:
1383 plvds_chip_info
->output_interface
= INTERFACE_NONE
;
1387 case HW_LAYOUT_LCD1_LCD2
:
1388 case HW_LAYOUT_LCD_EXTERNAL_LCD2
:
1390 plvds_chip_info
->output_interface
=
1391 INTERFACE_LVDS0LVDS1
;
1395 case HW_LAYOUT_LCD_DVI
:
1397 plvds_chip_info
->output_interface
= INTERFACE_LVDS1
;
1403 plvds_chip_info
->output_interface
= INTERFACE_LVDS1
;
1409 "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n",
1410 viafb_display_hardware_layout
,
1411 plvds_chip_info
->output_interface
);
1414 void viafb_init_lvds_output_interface(struct lvds_chip_information
1416 struct lvds_setting_information
1417 *plvds_setting_info
)
1419 if (INTERFACE_NONE
!= plvds_chip_info
->output_interface
) {
1420 /*Do nothing, lcd port is specified by module parameter */
1424 switch (plvds_chip_info
->lvds_chip_name
) {
1427 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
1428 case UNICHROME_CX700
:
1429 plvds_chip_info
->output_interface
= INTERFACE_DVP1
;
1431 case UNICHROME_CN700
:
1432 plvds_chip_info
->output_interface
= INTERFACE_DFP_LOW
;
1435 plvds_chip_info
->output_interface
= INTERFACE_DVP0
;
1440 case INTEGRATED_LVDS
:
1441 check_diport_of_integrated_lvds(plvds_chip_info
,
1442 plvds_setting_info
);
1446 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
1447 case UNICHROME_K8M890
:
1448 case UNICHROME_P4M900
:
1449 case UNICHROME_P4M890
:
1450 plvds_chip_info
->output_interface
= INTERFACE_DFP_LOW
;
1453 plvds_chip_info
->output_interface
= INTERFACE_DFP
;
1460 static struct display_timing
lcd_centering_timging(struct display_timing
1462 struct display_timing panel_crt_reg
)
1464 struct display_timing crt_reg
;
1466 crt_reg
.hor_total
= panel_crt_reg
.hor_total
;
1467 crt_reg
.hor_addr
= mode_crt_reg
.hor_addr
;
1468 crt_reg
.hor_blank_start
=
1469 (panel_crt_reg
.hor_addr
- mode_crt_reg
.hor_addr
) / 2 +
1471 crt_reg
.hor_blank_end
= panel_crt_reg
.hor_blank_end
;
1472 crt_reg
.hor_sync_start
=
1473 (panel_crt_reg
.hor_sync_start
-
1474 panel_crt_reg
.hor_blank_start
) + crt_reg
.hor_blank_start
;
1475 crt_reg
.hor_sync_end
= panel_crt_reg
.hor_sync_end
;
1477 crt_reg
.ver_total
= panel_crt_reg
.ver_total
;
1478 crt_reg
.ver_addr
= mode_crt_reg
.ver_addr
;
1479 crt_reg
.ver_blank_start
=
1480 (panel_crt_reg
.ver_addr
- mode_crt_reg
.ver_addr
) / 2 +
1482 crt_reg
.ver_blank_end
= panel_crt_reg
.ver_blank_end
;
1483 crt_reg
.ver_sync_start
=
1484 (panel_crt_reg
.ver_sync_start
-
1485 panel_crt_reg
.ver_blank_start
) + crt_reg
.ver_blank_start
;
1486 crt_reg
.ver_sync_end
= panel_crt_reg
.ver_sync_end
;
1491 static void load_crtc_shadow_timing(struct display_timing mode_timing
,
1492 struct display_timing panel_timing
)
1494 struct io_register
*reg
= NULL
;
1496 int viafb_load_reg_Num
= 0;
1499 if (viaparinfo
->lvds_setting_info
->display_method
== LCD_EXPANDSION
) {
1501 for (i
= 12; i
< 20; i
++) {
1503 case H_TOTAL_SHADOW_INDEX
:
1505 IGA2_HOR_TOTAL_SHADOW_FORMULA
1506 (panel_timing
.hor_total
);
1507 viafb_load_reg_Num
=
1508 iga2_shadow_crtc_reg
.hor_total_shadow
.
1510 reg
= iga2_shadow_crtc_reg
.hor_total_shadow
.reg
;
1512 case H_BLANK_END_SHADOW_INDEX
:
1514 IGA2_HOR_BLANK_END_SHADOW_FORMULA
1515 (panel_timing
.hor_blank_start
,
1516 panel_timing
.hor_blank_end
);
1517 viafb_load_reg_Num
=
1518 iga2_shadow_crtc_reg
.
1519 hor_blank_end_shadow
.reg_num
;
1521 iga2_shadow_crtc_reg
.
1522 hor_blank_end_shadow
.reg
;
1524 case V_TOTAL_SHADOW_INDEX
:
1526 IGA2_VER_TOTAL_SHADOW_FORMULA
1527 (panel_timing
.ver_total
);
1528 viafb_load_reg_Num
=
1529 iga2_shadow_crtc_reg
.ver_total_shadow
.
1531 reg
= iga2_shadow_crtc_reg
.ver_total_shadow
.reg
;
1533 case V_ADDR_SHADOW_INDEX
:
1535 IGA2_VER_ADDR_SHADOW_FORMULA
1536 (panel_timing
.ver_addr
);
1537 viafb_load_reg_Num
=
1538 iga2_shadow_crtc_reg
.ver_addr_shadow
.
1540 reg
= iga2_shadow_crtc_reg
.ver_addr_shadow
.reg
;
1542 case V_BLANK_SATRT_SHADOW_INDEX
:
1544 IGA2_VER_BLANK_START_SHADOW_FORMULA
1545 (panel_timing
.ver_blank_start
);
1546 viafb_load_reg_Num
=
1547 iga2_shadow_crtc_reg
.
1548 ver_blank_start_shadow
.reg_num
;
1550 iga2_shadow_crtc_reg
.
1551 ver_blank_start_shadow
.reg
;
1553 case V_BLANK_END_SHADOW_INDEX
:
1555 IGA2_VER_BLANK_END_SHADOW_FORMULA
1556 (panel_timing
.ver_blank_start
,
1557 panel_timing
.ver_blank_end
);
1558 viafb_load_reg_Num
=
1559 iga2_shadow_crtc_reg
.
1560 ver_blank_end_shadow
.reg_num
;
1562 iga2_shadow_crtc_reg
.
1563 ver_blank_end_shadow
.reg
;
1565 case V_SYNC_SATRT_SHADOW_INDEX
:
1567 IGA2_VER_SYNC_START_SHADOW_FORMULA
1568 (panel_timing
.ver_sync_start
);
1569 viafb_load_reg_Num
=
1570 iga2_shadow_crtc_reg
.
1571 ver_sync_start_shadow
.reg_num
;
1573 iga2_shadow_crtc_reg
.
1574 ver_sync_start_shadow
.reg
;
1576 case V_SYNC_END_SHADOW_INDEX
:
1578 IGA2_VER_SYNC_END_SHADOW_FORMULA
1579 (panel_timing
.ver_sync_start
,
1580 panel_timing
.ver_sync_end
);
1581 viafb_load_reg_Num
=
1582 iga2_shadow_crtc_reg
.
1583 ver_sync_end_shadow
.reg_num
;
1585 iga2_shadow_crtc_reg
.
1586 ver_sync_end_shadow
.reg
;
1589 viafb_load_reg(reg_value
,
1590 viafb_load_reg_Num
, reg
, VIACR
);
1592 } else { /* Centering */
1593 for (i
= 12; i
< 20; i
++) {
1595 case H_TOTAL_SHADOW_INDEX
:
1597 IGA2_HOR_TOTAL_SHADOW_FORMULA
1598 (panel_timing
.hor_total
);
1599 viafb_load_reg_Num
=
1600 iga2_shadow_crtc_reg
.hor_total_shadow
.
1602 reg
= iga2_shadow_crtc_reg
.hor_total_shadow
.reg
;
1604 case H_BLANK_END_SHADOW_INDEX
:
1606 IGA2_HOR_BLANK_END_SHADOW_FORMULA
1607 (panel_timing
.hor_blank_start
,
1608 panel_timing
.hor_blank_end
);
1609 viafb_load_reg_Num
=
1610 iga2_shadow_crtc_reg
.
1611 hor_blank_end_shadow
.reg_num
;
1613 iga2_shadow_crtc_reg
.
1614 hor_blank_end_shadow
.reg
;
1616 case V_TOTAL_SHADOW_INDEX
:
1618 IGA2_VER_TOTAL_SHADOW_FORMULA
1619 (panel_timing
.ver_total
);
1620 viafb_load_reg_Num
=
1621 iga2_shadow_crtc_reg
.ver_total_shadow
.
1623 reg
= iga2_shadow_crtc_reg
.ver_total_shadow
.reg
;
1625 case V_ADDR_SHADOW_INDEX
:
1627 IGA2_VER_ADDR_SHADOW_FORMULA
1628 (mode_timing
.ver_addr
);
1629 viafb_load_reg_Num
=
1630 iga2_shadow_crtc_reg
.ver_addr_shadow
.
1632 reg
= iga2_shadow_crtc_reg
.ver_addr_shadow
.reg
;
1634 case V_BLANK_SATRT_SHADOW_INDEX
:
1636 IGA2_VER_BLANK_START_SHADOW_FORMULA
1637 (mode_timing
.ver_blank_start
);
1638 viafb_load_reg_Num
=
1639 iga2_shadow_crtc_reg
.
1640 ver_blank_start_shadow
.reg_num
;
1642 iga2_shadow_crtc_reg
.
1643 ver_blank_start_shadow
.reg
;
1645 case V_BLANK_END_SHADOW_INDEX
:
1647 IGA2_VER_BLANK_END_SHADOW_FORMULA
1648 (panel_timing
.ver_blank_start
,
1649 panel_timing
.ver_blank_end
);
1650 viafb_load_reg_Num
=
1651 iga2_shadow_crtc_reg
.
1652 ver_blank_end_shadow
.reg_num
;
1654 iga2_shadow_crtc_reg
.
1655 ver_blank_end_shadow
.reg
;
1657 case V_SYNC_SATRT_SHADOW_INDEX
:
1659 IGA2_VER_SYNC_START_SHADOW_FORMULA(
1660 (panel_timing
.ver_sync_start
-
1661 panel_timing
.ver_blank_start
) +
1662 (panel_timing
.ver_addr
-
1663 mode_timing
.ver_addr
) / 2 +
1664 mode_timing
.ver_addr
);
1665 viafb_load_reg_Num
=
1666 iga2_shadow_crtc_reg
.ver_sync_start_shadow
.
1669 iga2_shadow_crtc_reg
.ver_sync_start_shadow
.
1672 case V_SYNC_END_SHADOW_INDEX
:
1674 IGA2_VER_SYNC_END_SHADOW_FORMULA(
1675 (panel_timing
.ver_sync_start
-
1676 panel_timing
.ver_blank_start
) +
1677 (panel_timing
.ver_addr
-
1678 mode_timing
.ver_addr
) / 2 +
1679 mode_timing
.ver_addr
,
1680 panel_timing
.ver_sync_end
);
1681 viafb_load_reg_Num
=
1682 iga2_shadow_crtc_reg
.ver_sync_end_shadow
.
1685 iga2_shadow_crtc_reg
.ver_sync_end_shadow
.
1689 viafb_load_reg(reg_value
,
1690 viafb_load_reg_Num
, reg
, VIACR
);
1695 bool viafb_lcd_get_mobile_state(bool *mobile
)
1697 unsigned char *romptr
, *tableptr
;
1699 unsigned char *biosptr
;
1701 u32 romaddr
= 0x000C0000;
1702 u16 start_pattern
= 0;
1704 biosptr
= ioremap(romaddr
, 0x10000);
1706 memcpy(&start_pattern
, biosptr
, 2);
1707 /* Compare pattern */
1708 if (start_pattern
== 0xAA55) {
1709 /* Get the start of Table */
1710 /* 0x1B means BIOS offset position */
1711 romptr
= biosptr
+ 0x1B;
1712 tableptr
= biosptr
+ *((u16
*) romptr
);
1714 /* Get the start of biosver structure */
1715 /* 18 means BIOS version position. */
1716 romptr
= tableptr
+ 18;
1717 romptr
= biosptr
+ *((u16
*) romptr
);
1719 /* The offset should be 44, but the
1720 actual image is less three char. */
1724 core_base
= *romptr
++;
1726 if (core_base
& 0x8)
1730 /* release memory */
1740 static void viafb_load_scaling_factor_for_p4m900(int set_hres
,
1741 int set_vres
, int panel_hres
, int panel_vres
)
1743 int h_scaling_factor
;
1744 int v_scaling_factor
;
1750 /* Check if expansion for horizontal */
1751 if (set_hres
< panel_hres
) {
1752 /* Load Horizontal Scaling Factor */
1754 /* For VIA_K8M800 or later chipsets. */
1756 K800_LCD_HOR_SCF_FORMULA(set_hres
, panel_hres
);
1757 /* HSCaleFactor[1:0] at CR9F[1:0] */
1758 cr9f
= h_scaling_factor
& 0x0003;
1759 /* HSCaleFactor[9:2] at CR77[7:0] */
1760 cr77
= (h_scaling_factor
& 0x03FC) >> 2;
1761 /* HSCaleFactor[11:10] at CR79[5:4] */
1762 cr79
= (h_scaling_factor
& 0x0C00) >> 10;
1765 /* Horizontal scaling enabled */
1768 DEBUG_MSG(KERN_INFO
"Horizontal Scaling value = %d\n",
1771 /* Horizontal scaling disabled */
1775 /* Check if expansion for vertical */
1776 if (set_vres
< panel_vres
) {
1777 /* Load Vertical Scaling Factor */
1779 /* For VIA_K8M800 or later chipsets. */
1781 K800_LCD_VER_SCF_FORMULA(set_vres
, panel_vres
);
1783 /* Vertical scaling enabled */
1785 /* VSCaleFactor[0] at CR79[3] */
1786 cr79
|= ((v_scaling_factor
& 0x0001) << 3);
1787 /* VSCaleFactor[8:1] at CR78[7:0] */
1788 cr78
|= (v_scaling_factor
& 0x01FE) >> 1;
1789 /* VSCaleFactor[10:9] at CR79[7:6] */
1790 cr79
|= ((v_scaling_factor
& 0x0600) >> 9) << 6;
1792 DEBUG_MSG(KERN_INFO
"Vertical Scaling value = %d\n",
1795 /* Vertical scaling disabled */
1799 viafb_write_reg_mask(CRA2
, VIACR
, cra2
, BIT3
+ BIT6
+ BIT7
);
1800 viafb_write_reg_mask(CR77
, VIACR
, cr77
, 0xFF);
1801 viafb_write_reg_mask(CR78
, VIACR
, cr78
, 0xFF);
1802 viafb_write_reg_mask(CR79
, VIACR
, cr79
, 0xF8);
1803 viafb_write_reg_mask(CR9F
, VIACR
, cr9f
, BIT0
+ BIT1
);