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 #define viafb_compact_res(x, y) (((x)<<16)|(y))
27 static struct _lcd_scaling_factor lcd_scaling_factor
= {
28 /* LCD Horizontal Scaling Factor Register */
29 {LCD_HOR_SCALING_FACTOR_REG_NUM
,
30 {{CR9F
, 0, 1}, {CR77
, 0, 7}, {CR79
, 4, 5} } },
31 /* LCD Vertical Scaling Factor Register */
32 {LCD_VER_SCALING_FACTOR_REG_NUM
,
33 {{CR79
, 3, 3}, {CR78
, 0, 7}, {CR79
, 6, 7} } }
35 static struct _lcd_scaling_factor lcd_scaling_factor_CLE
= {
36 /* LCD Horizontal Scaling Factor Register */
37 {LCD_HOR_SCALING_FACTOR_REG_NUM_CLE
, {{CR77
, 0, 7}, {CR79
, 4, 5} } },
38 /* LCD Vertical Scaling Factor Register */
39 {LCD_VER_SCALING_FACTOR_REG_NUM_CLE
, {{CR78
, 0, 7}, {CR79
, 6, 7} } }
42 static int check_lvds_chip(int device_id_subaddr
, int device_id
);
43 static bool lvds_identify_integratedlvds(void);
44 static void fp_id_to_vindex(int panel_id
);
45 static int lvds_register_read(int index
);
46 static void load_lcd_scaling(int set_hres
, int set_vres
, int panel_hres
,
48 static void via_pitch_alignment_patch_lcd(
49 struct lvds_setting_information
*plvds_setting_info
,
50 struct lvds_chip_information
52 static void lcd_patch_skew_dvp0(struct lvds_setting_information
54 struct lvds_chip_information
*plvds_chip_info
);
55 static void lcd_patch_skew_dvp1(struct lvds_setting_information
57 struct lvds_chip_information
*plvds_chip_info
);
58 static void lcd_patch_skew(struct lvds_setting_information
59 *plvds_setting_info
, struct lvds_chip_information
*plvds_chip_info
);
61 static void integrated_lvds_disable(struct lvds_setting_information
63 struct lvds_chip_information
*plvds_chip_info
);
64 static void integrated_lvds_enable(struct lvds_setting_information
66 struct lvds_chip_information
*plvds_chip_info
);
67 static void lcd_powersequence_off(void);
68 static void lcd_powersequence_on(void);
69 static void fill_lcd_format(void);
70 static void check_diport_of_integrated_lvds(
71 struct lvds_chip_information
*plvds_chip_info
,
72 struct lvds_setting_information
74 static struct display_timing
lcd_centering_timging(struct display_timing
76 struct display_timing panel_crt_reg
);
77 static void viafb_load_scaling_factor_for_p4m900(int set_hres
,
78 int set_vres
, int panel_hres
, int panel_vres
);
80 static int check_lvds_chip(int device_id_subaddr
, int device_id
)
82 if (lvds_register_read(device_id_subaddr
) == device_id
)
88 void viafb_init_lcd_size(void)
90 DEBUG_MSG(KERN_INFO
"viafb_init_lcd_size()\n");
92 "viaparinfo->lvds_setting_info->get_lcd_size_method %d\n",
93 viaparinfo
->lvds_setting_info
->get_lcd_size_method
);
95 switch (viaparinfo
->lvds_setting_info
->get_lcd_size_method
) {
96 case GET_LCD_SIZE_BY_SYSTEM_BIOS
:
98 case GET_LCD_SZIE_BY_HW_STRAPPING
:
100 case GET_LCD_SIZE_BY_VGA_BIOS
:
101 DEBUG_MSG(KERN_INFO
"Get LCD Size method by VGA BIOS !!\n");
102 fp_id_to_vindex(viafb_lcd_panel_id
);
103 DEBUG_MSG(KERN_INFO
"LCD Panel_ID = %d\n",
104 viaparinfo
->lvds_setting_info
->lcd_panel_id
);
106 case GET_LCD_SIZE_BY_USER_SETTING
:
107 DEBUG_MSG(KERN_INFO
"Get LCD Size method by user setting !!\n");
108 fp_id_to_vindex(viafb_lcd_panel_id
);
109 DEBUG_MSG(KERN_INFO
"LCD Panel_ID = %d\n",
110 viaparinfo
->lvds_setting_info
->lcd_panel_id
);
113 DEBUG_MSG(KERN_INFO
"viafb_init_lcd_size fail\n");
114 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
115 LCD_PANEL_ID1_800X600
;
116 fp_id_to_vindex(LCD_PANEL_ID1_800X600
);
118 viaparinfo
->lvds_setting_info2
->lcd_panel_id
=
119 viaparinfo
->lvds_setting_info
->lcd_panel_id
;
120 viaparinfo
->lvds_setting_info2
->lcd_panel_hres
=
121 viaparinfo
->lvds_setting_info
->lcd_panel_hres
;
122 viaparinfo
->lvds_setting_info2
->lcd_panel_vres
=
123 viaparinfo
->lvds_setting_info
->lcd_panel_vres
;
124 viaparinfo
->lvds_setting_info2
->device_lcd_dualedge
=
125 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
;
126 viaparinfo
->lvds_setting_info2
->LCDDithering
=
127 viaparinfo
->lvds_setting_info
->LCDDithering
;
130 static bool lvds_identify_integratedlvds(void)
132 if (viafb_display_hardware_layout
== HW_LAYOUT_LCD_EXTERNAL_LCD2
) {
133 /* Two dual channel LCD (Internal LVDS + External LVDS): */
134 /* If we have an external LVDS, such as VT1636, we should
135 have its chip ID already. */
136 if (viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
) {
137 viaparinfo
->chip_info
->lvds_chip_info2
.lvds_chip_name
=
139 DEBUG_MSG(KERN_INFO
"Support two dual channel LVDS! "
140 "(Internal LVDS + External LVDS)\n");
142 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
=
144 DEBUG_MSG(KERN_INFO
"Not found external LVDS, "
145 "so can't support two dual channel LVDS!\n");
147 } else if (viafb_display_hardware_layout
== HW_LAYOUT_LCD1_LCD2
) {
148 /* Two single channel LCD (Internal LVDS + Internal LVDS): */
149 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
=
151 viaparinfo
->chip_info
->lvds_chip_info2
.lvds_chip_name
=
153 DEBUG_MSG(KERN_INFO
"Support two single channel LVDS! "
154 "(Internal LVDS + Internal LVDS)\n");
155 } else if (viafb_display_hardware_layout
!= HW_LAYOUT_DVI_ONLY
) {
156 /* If we have found external LVDS, just use it,
157 otherwise, we will use internal LVDS as default. */
158 if (!viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
) {
159 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
=
161 DEBUG_MSG(KERN_INFO
"Found Integrated LVDS!\n");
164 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
=
165 NON_LVDS_TRANSMITTER
;
166 DEBUG_MSG(KERN_INFO
"Do not support LVDS!\n");
173 int viafb_lvds_trasmitter_identify(void)
175 viaparinfo
->shared
->i2c_stuff
.i2c_port
= I2CPORTINDEX
;
176 if (viafb_lvds_identify_vt1636()) {
177 viaparinfo
->chip_info
->lvds_chip_info
.i2c_port
= I2CPORTINDEX
;
179 "Found VIA VT1636 LVDS on port i2c 0x31 \n");
181 viaparinfo
->shared
->i2c_stuff
.i2c_port
= GPIOPORTINDEX
;
182 if (viafb_lvds_identify_vt1636()) {
183 viaparinfo
->chip_info
->lvds_chip_info
.i2c_port
=
186 "Found VIA VT1636 LVDS on port gpio 0x2c \n");
190 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
)
191 lvds_identify_integratedlvds();
193 if (viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
)
195 /* Check for VT1631: */
196 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
= VT1631_LVDS
;
197 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_slave_addr
=
198 VT1631_LVDS_I2C_ADDR
;
200 if (check_lvds_chip(VT1631_DEVICE_ID_REG
, VT1631_DEVICE_ID
) != FAIL
) {
201 DEBUG_MSG(KERN_INFO
"\n VT1631 LVDS ! \n");
202 DEBUG_MSG(KERN_INFO
"\n %2d",
203 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
);
204 DEBUG_MSG(KERN_INFO
"\n %2d",
205 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
);
209 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
=
210 NON_LVDS_TRANSMITTER
;
211 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_slave_addr
=
212 VT1631_LVDS_I2C_ADDR
;
216 static void fp_id_to_vindex(int panel_id
)
218 DEBUG_MSG(KERN_INFO
"fp_get_panel_id()\n");
220 if (panel_id
> LCD_PANEL_ID_MAXIMUM
)
221 viafb_lcd_panel_id
= panel_id
=
222 viafb_read_reg(VIACR
, CR3F
) & 0x0F;
226 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 640;
227 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 480;
228 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
229 LCD_PANEL_ID0_640X480
;
230 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
231 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
234 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 800;
235 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 600;
236 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
237 LCD_PANEL_ID1_800X600
;
238 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
239 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
242 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1024;
243 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 768;
244 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
245 LCD_PANEL_ID2_1024X768
;
246 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
247 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
250 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1280;
251 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 768;
252 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
253 LCD_PANEL_ID3_1280X768
;
254 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
255 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
258 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1280;
259 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 1024;
260 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
261 LCD_PANEL_ID4_1280X1024
;
262 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 1;
263 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
266 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1400;
267 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 1050;
268 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
269 LCD_PANEL_ID5_1400X1050
;
270 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 1;
271 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
274 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1600;
275 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 1200;
276 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
277 LCD_PANEL_ID6_1600X1200
;
278 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 1;
279 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
282 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 800;
283 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 480;
284 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
285 LCD_PANEL_IDA_800X480
;
286 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
287 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
290 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1024;
291 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 768;
292 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
293 LCD_PANEL_ID2_1024X768
;
294 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 1;
295 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
298 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1024;
299 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 768;
300 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
301 LCD_PANEL_ID2_1024X768
;
302 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
303 viaparinfo
->lvds_setting_info
->LCDDithering
= 0;
306 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1024;
307 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 768;
308 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
309 LCD_PANEL_ID2_1024X768
;
310 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 1;
311 viaparinfo
->lvds_setting_info
->LCDDithering
= 0;
314 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1280;
315 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 768;
316 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
317 LCD_PANEL_ID3_1280X768
;
318 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
319 viaparinfo
->lvds_setting_info
->LCDDithering
= 0;
322 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1280;
323 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 1024;
324 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
325 LCD_PANEL_ID4_1280X1024
;
326 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 1;
327 viaparinfo
->lvds_setting_info
->LCDDithering
= 0;
330 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1400;
331 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 1050;
332 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
333 LCD_PANEL_ID5_1400X1050
;
334 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 1;
335 viaparinfo
->lvds_setting_info
->LCDDithering
= 0;
338 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1600;
339 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 1200;
340 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
341 LCD_PANEL_ID6_1600X1200
;
342 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 1;
343 viaparinfo
->lvds_setting_info
->LCDDithering
= 0;
346 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1366;
347 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 768;
348 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
349 LCD_PANEL_ID7_1366X768
;
350 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
351 viaparinfo
->lvds_setting_info
->LCDDithering
= 0;
354 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1024;
355 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 600;
356 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
357 LCD_PANEL_ID8_1024X600
;
358 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
359 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
362 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1280;
363 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 768;
364 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
365 LCD_PANEL_ID3_1280X768
;
366 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 1;
367 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
370 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1280;
371 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 800;
372 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
373 LCD_PANEL_ID9_1280X800
;
374 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
375 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
378 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1360;
379 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 768;
380 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
381 LCD_PANEL_IDB_1360X768
;
382 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
383 viaparinfo
->lvds_setting_info
->LCDDithering
= 0;
386 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 1280;
387 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 768;
388 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
389 LCD_PANEL_ID3_1280X768
;
390 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 1;
391 viaparinfo
->lvds_setting_info
->LCDDithering
= 0;
394 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 480;
395 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 640;
396 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
397 LCD_PANEL_IDC_480X640
;
398 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
399 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
402 viaparinfo
->lvds_setting_info
->lcd_panel_hres
= 800;
403 viaparinfo
->lvds_setting_info
->lcd_panel_vres
= 600;
404 viaparinfo
->lvds_setting_info
->lcd_panel_id
=
405 LCD_PANEL_ID1_800X600
;
406 viaparinfo
->lvds_setting_info
->device_lcd_dualedge
= 0;
407 viaparinfo
->lvds_setting_info
->LCDDithering
= 1;
411 static int lvds_register_read(int index
)
415 viaparinfo
->shared
->i2c_stuff
.i2c_port
= GPIOPORTINDEX
;
416 viafb_i2c_readbyte((u8
) viaparinfo
->chip_info
->
417 lvds_chip_info
.lvds_chip_slave_addr
,
422 static void load_lcd_scaling(int set_hres
, int set_vres
, int panel_hres
,
426 int viafb_load_reg_num
;
427 struct io_register
*reg
= NULL
;
429 DEBUG_MSG(KERN_INFO
"load_lcd_scaling()!!\n");
431 /* LCD Scaling Enable */
432 viafb_write_reg_mask(CR79
, VIACR
, 0x07, BIT0
+ BIT1
+ BIT2
);
433 if (UNICHROME_P4M900
== viaparinfo
->chip_info
->gfx_chip_name
) {
434 viafb_load_scaling_factor_for_p4m900(set_hres
, set_vres
,
435 panel_hres
, panel_vres
);
439 /* Check if expansion for horizontal */
440 if (set_hres
!= panel_hres
) {
441 /* Load Horizontal Scaling Factor */
442 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
443 case UNICHROME_CLE266
:
446 CLE266_LCD_HOR_SCF_FORMULA(set_hres
, panel_hres
);
448 lcd_scaling_factor_CLE
.lcd_hor_scaling_factor
.
450 reg
= lcd_scaling_factor_CLE
.lcd_hor_scaling_factor
.reg
;
451 viafb_load_reg(reg_value
,
452 viafb_load_reg_num
, reg
, VIACR
);
455 case UNICHROME_PM800
:
456 case UNICHROME_CN700
:
457 case UNICHROME_CX700
:
458 case UNICHROME_K8M890
:
459 case UNICHROME_P4M890
:
461 K800_LCD_HOR_SCF_FORMULA(set_hres
, panel_hres
);
462 /* Horizontal scaling enabled */
463 viafb_write_reg_mask(CRA2
, VIACR
, 0xC0, BIT7
+ BIT6
);
465 lcd_scaling_factor
.lcd_hor_scaling_factor
.reg_num
;
466 reg
= lcd_scaling_factor
.lcd_hor_scaling_factor
.reg
;
467 viafb_load_reg(reg_value
,
468 viafb_load_reg_num
, reg
, VIACR
);
472 DEBUG_MSG(KERN_INFO
"Horizontal Scaling value = %d", reg_value
);
474 /* Horizontal scaling disabled */
475 viafb_write_reg_mask(CRA2
, VIACR
, 0x00, BIT7
);
478 /* Check if expansion for vertical */
479 if (set_vres
!= panel_vres
) {
480 /* Load Vertical Scaling Factor */
481 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
482 case UNICHROME_CLE266
:
485 CLE266_LCD_VER_SCF_FORMULA(set_vres
, panel_vres
);
487 lcd_scaling_factor_CLE
.lcd_ver_scaling_factor
.
489 reg
= lcd_scaling_factor_CLE
.lcd_ver_scaling_factor
.reg
;
490 viafb_load_reg(reg_value
,
491 viafb_load_reg_num
, reg
, VIACR
);
494 case UNICHROME_PM800
:
495 case UNICHROME_CN700
:
496 case UNICHROME_CX700
:
497 case UNICHROME_K8M890
:
498 case UNICHROME_P4M890
:
500 K800_LCD_VER_SCF_FORMULA(set_vres
, panel_vres
);
501 /* Vertical scaling enabled */
502 viafb_write_reg_mask(CRA2
, VIACR
, 0x08, BIT3
);
504 lcd_scaling_factor
.lcd_ver_scaling_factor
.reg_num
;
505 reg
= lcd_scaling_factor
.lcd_ver_scaling_factor
.reg
;
506 viafb_load_reg(reg_value
,
507 viafb_load_reg_num
, reg
, VIACR
);
511 DEBUG_MSG(KERN_INFO
"Vertical Scaling value = %d", reg_value
);
513 /* Vertical scaling disabled */
514 viafb_write_reg_mask(CRA2
, VIACR
, 0x00, BIT3
);
518 static void via_pitch_alignment_patch_lcd(
519 struct lvds_setting_information
*plvds_setting_info
,
520 struct lvds_chip_information
523 unsigned char cr13
, cr35
, cr65
, cr66
, cr67
;
524 unsigned long dwScreenPitch
= 0;
525 unsigned long dwPitch
;
527 dwPitch
= plvds_setting_info
->h_active
* (plvds_setting_info
->bpp
>> 3);
528 if (dwPitch
& 0x1F) {
529 dwScreenPitch
= ((dwPitch
+ 31) & ~31) >> 3;
530 if (plvds_setting_info
->iga_path
== IGA2
) {
531 if (plvds_setting_info
->bpp
> 8) {
532 cr66
= (unsigned char)(dwScreenPitch
& 0xFF);
533 viafb_write_reg(CR66
, VIACR
, cr66
);
534 cr67
= viafb_read_reg(VIACR
, CR67
) & 0xFC;
537 char)((dwScreenPitch
& 0x300) >> 8);
538 viafb_write_reg(CR67
, VIACR
, cr67
);
542 cr67
= viafb_read_reg(VIACR
, CR67
) & 0xF3;
543 cr67
|= (unsigned char)((dwScreenPitch
& 0x600) >> 7);
544 viafb_write_reg(CR67
, VIACR
, cr67
);
545 cr65
= (unsigned char)((dwScreenPitch
>> 1) & 0xFF);
547 viafb_write_reg(CR65
, VIACR
, cr65
);
549 if (plvds_setting_info
->bpp
> 8) {
550 cr13
= (unsigned char)(dwScreenPitch
& 0xFF);
551 viafb_write_reg(CR13
, VIACR
, cr13
);
552 cr35
= viafb_read_reg(VIACR
, CR35
) & 0x1F;
555 char)((dwScreenPitch
& 0x700) >> 3);
556 viafb_write_reg(CR35
, VIACR
, cr35
);
561 static void lcd_patch_skew_dvp0(struct lvds_setting_information
563 struct lvds_chip_information
*plvds_chip_info
)
565 if (VT1636_LVDS
== plvds_chip_info
->lvds_chip_name
) {
566 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
567 case UNICHROME_P4M900
:
568 viafb_vt1636_patch_skew_on_vt3364(plvds_setting_info
,
571 case UNICHROME_P4M890
:
572 viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info
,
578 static void lcd_patch_skew_dvp1(struct lvds_setting_information
580 struct lvds_chip_information
*plvds_chip_info
)
582 if (VT1636_LVDS
== plvds_chip_info
->lvds_chip_name
) {
583 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
584 case UNICHROME_CX700
:
585 viafb_vt1636_patch_skew_on_vt3324(plvds_setting_info
,
591 static void lcd_patch_skew(struct lvds_setting_information
592 *plvds_setting_info
, struct lvds_chip_information
*plvds_chip_info
)
594 DEBUG_MSG(KERN_INFO
"lcd_patch_skew\n");
595 switch (plvds_chip_info
->output_interface
) {
597 lcd_patch_skew_dvp0(plvds_setting_info
, plvds_chip_info
);
600 lcd_patch_skew_dvp1(plvds_setting_info
, plvds_chip_info
);
602 case INTERFACE_DFP_LOW
:
603 if (UNICHROME_P4M900
== viaparinfo
->chip_info
->gfx_chip_name
) {
604 viafb_write_reg_mask(CR99
, VIACR
, 0x08,
605 BIT0
+ BIT1
+ BIT2
+ BIT3
);
612 void viafb_lcd_set_mode(struct crt_mode_table
*mode_crt_table
,
613 struct lvds_setting_information
*plvds_setting_info
,
614 struct lvds_chip_information
*plvds_chip_info
)
616 int set_iga
= plvds_setting_info
->iga_path
;
617 int mode_bpp
= plvds_setting_info
->bpp
;
618 int set_hres
= plvds_setting_info
->h_active
;
619 int set_vres
= plvds_setting_info
->v_active
;
620 int panel_hres
= plvds_setting_info
->lcd_panel_hres
;
621 int panel_vres
= plvds_setting_info
->lcd_panel_vres
;
623 struct display_timing mode_crt_reg
, panel_crt_reg
;
624 struct crt_mode_table
*panel_crt_table
= NULL
;
625 struct VideoModeTable
*vmode_tbl
= viafb_get_mode(panel_hres
,
628 DEBUG_MSG(KERN_INFO
"viafb_lcd_set_mode!!\n");
630 mode_crt_reg
= mode_crt_table
->crtc
;
631 /* Get panel table Pointer */
632 panel_crt_table
= vmode_tbl
->crtc
;
633 panel_crt_reg
= panel_crt_table
->crtc
;
634 DEBUG_MSG(KERN_INFO
"bellow viafb_lcd_set_mode!!\n");
635 if (VT1636_LVDS
== plvds_chip_info
->lvds_chip_name
)
636 viafb_init_lvds_vt1636(plvds_setting_info
, plvds_chip_info
);
637 plvds_setting_info
->vclk
= panel_crt_table
->clk
;
638 if (set_iga
== IGA1
) {
639 /* IGA1 doesn't have LCD scaling, so set it as centering. */
640 viafb_load_crtc_timing(lcd_centering_timging
641 (mode_crt_reg
, panel_crt_reg
), IGA1
);
644 if ((plvds_setting_info
->display_method
==
645 LCD_EXPANDSION
) & ((set_hres
!= panel_hres
)
646 || (set_vres
!= panel_vres
))) {
647 /* expansion timing IGA2 loaded panel set timing*/
648 viafb_load_crtc_timing(panel_crt_reg
, IGA2
);
649 DEBUG_MSG(KERN_INFO
"viafb_load_crtc_timing!!\n");
650 load_lcd_scaling(set_hres
, set_vres
, panel_hres
,
652 DEBUG_MSG(KERN_INFO
"load_lcd_scaling!!\n");
653 } else { /* Centering */
654 /* centering timing IGA2 always loaded panel
655 and mode releative timing */
656 viafb_load_crtc_timing(lcd_centering_timging
657 (mode_crt_reg
, panel_crt_reg
), IGA2
);
658 viafb_write_reg_mask(CR79
, VIACR
, 0x00,
660 /* LCD scaling disabled */
664 /* Fetch count for IGA2 only */
665 viafb_load_fetch_count_reg(set_hres
, mode_bpp
/ 8, set_iga
);
667 if ((viaparinfo
->chip_info
->gfx_chip_name
!= UNICHROME_CLE266
)
668 && (viaparinfo
->chip_info
->gfx_chip_name
!= UNICHROME_K400
))
669 viafb_load_FIFO_reg(set_iga
, set_hres
, set_vres
);
673 pll_D_N
= viafb_get_clk_value(panel_crt_table
[0].clk
);
674 DEBUG_MSG(KERN_INFO
"PLL=0x%x", pll_D_N
);
675 viafb_set_vclock(pll_D_N
, set_iga
);
677 viafb_set_output_path(DEVICE_LCD
, set_iga
,
678 plvds_chip_info
->output_interface
);
679 lcd_patch_skew(plvds_setting_info
, plvds_chip_info
);
681 /* If K8M800, enable LCD Prefetch Mode. */
682 if ((viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_K800
)
683 || (UNICHROME_K8M890
== viaparinfo
->chip_info
->gfx_chip_name
))
684 viafb_write_reg_mask(CR6A
, VIACR
, 0x01, BIT0
);
686 /* Patch for non 32bit alignment mode */
687 via_pitch_alignment_patch_lcd(plvds_setting_info
, plvds_chip_info
);
690 static void integrated_lvds_disable(struct lvds_setting_information
692 struct lvds_chip_information
*plvds_chip_info
)
694 bool turn_off_first_powersequence
= false;
695 bool turn_off_second_powersequence
= false;
696 if (INTERFACE_LVDS0LVDS1
== plvds_chip_info
->output_interface
)
697 turn_off_first_powersequence
= true;
698 if (INTERFACE_LVDS0
== plvds_chip_info
->output_interface
)
699 turn_off_first_powersequence
= true;
700 if (INTERFACE_LVDS1
== plvds_chip_info
->output_interface
)
701 turn_off_second_powersequence
= true;
702 if (turn_off_second_powersequence
) {
703 /* Use second power sequence control: */
705 /* Turn off power sequence. */
706 viafb_write_reg_mask(CRD4
, VIACR
, 0, BIT1
);
708 /* Turn off back light. */
709 viafb_write_reg_mask(CRD3
, VIACR
, 0xC0, BIT6
+ BIT7
);
711 if (turn_off_first_powersequence
) {
712 /* Use first power sequence control: */
714 /* Turn off power sequence. */
715 viafb_write_reg_mask(CR6A
, VIACR
, 0, BIT3
);
717 /* Turn off back light. */
718 viafb_write_reg_mask(CR91
, VIACR
, 0xC0, BIT6
+ BIT7
);
721 /* Turn DFP High/Low Pad off. */
722 viafb_write_reg_mask(SR2A
, VIASR
, 0, BIT0
+ BIT1
+ BIT2
+ BIT3
);
724 /* Power off LVDS channel. */
725 switch (plvds_chip_info
->output_interface
) {
726 case INTERFACE_LVDS0
:
728 viafb_write_reg_mask(CRD2
, VIACR
, 0x80, BIT7
);
732 case INTERFACE_LVDS1
:
734 viafb_write_reg_mask(CRD2
, VIACR
, 0x40, BIT6
);
738 case INTERFACE_LVDS0LVDS1
:
740 viafb_write_reg_mask(CRD2
, VIACR
, 0xC0, BIT6
+ BIT7
);
746 static void integrated_lvds_enable(struct lvds_setting_information
748 struct lvds_chip_information
*plvds_chip_info
)
750 DEBUG_MSG(KERN_INFO
"integrated_lvds_enable, out_interface:%d\n",
751 plvds_chip_info
->output_interface
);
752 if (plvds_setting_info
->lcd_mode
== LCD_SPWG
)
753 viafb_write_reg_mask(CRD2
, VIACR
, 0x00, BIT0
+ BIT1
);
755 viafb_write_reg_mask(CRD2
, VIACR
, 0x03, BIT0
+ BIT1
);
757 switch (plvds_chip_info
->output_interface
) {
758 case INTERFACE_LVDS0LVDS1
:
759 case INTERFACE_LVDS0
:
760 /* Use first power sequence control: */
761 /* Use hardware control power sequence. */
762 viafb_write_reg_mask(CR91
, VIACR
, 0, BIT0
);
763 /* Turn on back light. */
764 viafb_write_reg_mask(CR91
, VIACR
, 0, BIT6
+ BIT7
);
765 /* Turn on hardware power sequence. */
766 viafb_write_reg_mask(CR6A
, VIACR
, 0x08, BIT3
);
768 case INTERFACE_LVDS1
:
769 /* Use second power sequence control: */
770 /* Use hardware control power sequence. */
771 viafb_write_reg_mask(CRD3
, VIACR
, 0, BIT0
);
772 /* Turn on back light. */
773 viafb_write_reg_mask(CRD3
, VIACR
, 0, BIT6
+ BIT7
);
774 /* Turn on hardware power sequence. */
775 viafb_write_reg_mask(CRD4
, VIACR
, 0x02, BIT1
);
779 /* Turn DFP High/Low pad on. */
780 viafb_write_reg_mask(SR2A
, VIASR
, 0x0F, BIT0
+ BIT1
+ BIT2
+ BIT3
);
782 /* Power on LVDS channel. */
783 switch (plvds_chip_info
->output_interface
) {
784 case INTERFACE_LVDS0
:
786 viafb_write_reg_mask(CRD2
, VIACR
, 0, BIT7
);
790 case INTERFACE_LVDS1
:
792 viafb_write_reg_mask(CRD2
, VIACR
, 0, BIT6
);
796 case INTERFACE_LVDS0LVDS1
:
798 viafb_write_reg_mask(CRD2
, VIACR
, 0, BIT6
+ BIT7
);
804 void viafb_lcd_disable(void)
807 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
) {
808 lcd_powersequence_off();
810 viafb_write_reg_mask(SR1E
, VIASR
, 0x00, 0x30);
811 } else if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
) {
813 && (INTEGRATED_LVDS
==
814 viaparinfo
->chip_info
->lvds_chip_info2
.lvds_chip_name
))
815 integrated_lvds_disable(viaparinfo
->lvds_setting_info
,
816 &viaparinfo
->chip_info
->lvds_chip_info2
);
817 if (INTEGRATED_LVDS
==
818 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
)
819 integrated_lvds_disable(viaparinfo
->lvds_setting_info
,
820 &viaparinfo
->chip_info
->lvds_chip_info
);
821 if (VT1636_LVDS
== viaparinfo
->chip_info
->
822 lvds_chip_info
.lvds_chip_name
)
823 viafb_disable_lvds_vt1636(viaparinfo
->lvds_setting_info
,
824 &viaparinfo
->chip_info
->lvds_chip_info
);
825 } else if (VT1636_LVDS
==
826 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
) {
827 viafb_disable_lvds_vt1636(viaparinfo
->lvds_setting_info
,
828 &viaparinfo
->chip_info
->lvds_chip_info
);
831 viafb_write_reg_mask(SR2A
, VIASR
, 0x00, 0x0F);
833 viafb_write_reg_mask(SR3D
, VIASR
, 0x00, 0x20);
834 /* 24 bit DI data paht off */
835 viafb_write_reg_mask(CR91
, VIACR
, 0x80, 0x80);
836 /* Simultaneout disabled */
837 viafb_write_reg_mask(CR6B
, VIACR
, 0x00, 0x08);
840 /* Disable expansion bit */
841 viafb_write_reg_mask(CR79
, VIACR
, 0x00, 0x01);
842 /* CRT path set to IGA1 */
843 viafb_write_reg_mask(SR16
, VIASR
, 0x00, 0x40);
844 /* Simultaneout disabled */
845 viafb_write_reg_mask(CR6B
, VIACR
, 0x00, 0x08);
846 /* IGA2 path disabled */
847 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, 0x80);
851 void viafb_lcd_enable(void)
853 if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CLE266
) {
855 viafb_write_reg_mask(SR1E
, VIASR
, 0x30, 0x30);
856 lcd_powersequence_on();
857 } else if (viaparinfo
->chip_info
->gfx_chip_name
== UNICHROME_CX700
) {
858 if (viafb_LCD2_ON
&& (INTEGRATED_LVDS
==
859 viaparinfo
->chip_info
->lvds_chip_info2
.lvds_chip_name
))
860 integrated_lvds_enable(viaparinfo
->lvds_setting_info2
, \
861 &viaparinfo
->chip_info
->lvds_chip_info2
);
862 if (INTEGRATED_LVDS
==
863 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
)
864 integrated_lvds_enable(viaparinfo
->lvds_setting_info
,
865 &viaparinfo
->chip_info
->lvds_chip_info
);
866 if (VT1636_LVDS
== viaparinfo
->chip_info
->
867 lvds_chip_info
.lvds_chip_name
)
868 viafb_enable_lvds_vt1636(viaparinfo
->
869 lvds_setting_info
, &viaparinfo
->chip_info
->
871 } else if (VT1636_LVDS
==
872 viaparinfo
->chip_info
->lvds_chip_info
.lvds_chip_name
) {
873 viafb_enable_lvds_vt1636(viaparinfo
->lvds_setting_info
,
874 &viaparinfo
->chip_info
->lvds_chip_info
);
877 viafb_write_reg_mask(SR2A
, VIASR
, 0x0F, 0x0F);
879 viafb_write_reg_mask(SR3D
, VIASR
, 0x20, 0x20);
880 /* 24 bit DI data paht on */
881 viafb_write_reg_mask(CR91
, VIACR
, 0x00, 0x80);
883 /* Set data source selection bit by iga path */
884 if (viaparinfo
->lvds_setting_info
->iga_path
== IGA1
) {
885 /* DFP-H set to IGA1 */
886 viafb_write_reg_mask(CR97
, VIACR
, 0x00, 0x10);
887 /* DFP-L set to IGA1 */
888 viafb_write_reg_mask(CR99
, VIACR
, 0x00, 0x10);
890 /* DFP-H set to IGA2 */
891 viafb_write_reg_mask(CR97
, VIACR
, 0x10, 0x10);
892 /* DFP-L set to IGA2 */
893 viafb_write_reg_mask(CR99
, VIACR
, 0x10, 0x10);
896 viafb_write_reg_mask(CR6A
, VIACR
, 0x48, 0x48);
899 if (viaparinfo
->lvds_setting_info
->iga_path
== IGA1
) {
900 /* CRT path set to IGA2 */
901 viafb_write_reg_mask(SR16
, VIASR
, 0x40, 0x40);
902 /* IGA2 path disabled */
903 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, 0x80);
904 /* IGA2 path enabled */
906 viafb_write_reg_mask(CR6A
, VIACR
, 0x80, 0x80);
911 static void lcd_powersequence_off(void)
915 /* Software control power sequence */
916 viafb_write_reg_mask(CR91
, VIACR
, 0x11, 0x11);
918 for (i
= 0; i
< 3; i
++) {
919 mask
= PowerSequenceOff
[0][i
];
920 data
= PowerSequenceOff
[1][i
] & mask
;
921 viafb_write_reg_mask(CR91
, VIACR
, (u8
) data
, (u8
) mask
);
922 udelay(PowerSequenceOff
[2][i
]);
926 viafb_write_reg_mask(CR6A
, VIACR
, 0x00, 0x08);
929 static void lcd_powersequence_on(void)
933 /* Software control power sequence */
934 viafb_write_reg_mask(CR91
, VIACR
, 0x11, 0x11);
937 viafb_write_reg_mask(CR6A
, VIACR
, 0x08, 0x08);
939 for (i
= 0; i
< 3; i
++) {
940 mask
= PowerSequenceOn
[0][i
];
941 data
= PowerSequenceOn
[1][i
] & mask
;
942 viafb_write_reg_mask(CR91
, VIACR
, (u8
) data
, (u8
) mask
);
943 udelay(PowerSequenceOn
[2][i
]);
949 static void fill_lcd_format(void)
951 u8 bdithering
= 0, bdual
= 0;
953 if (viaparinfo
->lvds_setting_info
->device_lcd_dualedge
)
955 if (viaparinfo
->lvds_setting_info
->LCDDithering
)
957 /* Dual & Dithering */
958 viafb_write_reg_mask(CR88
, VIACR
, (bdithering
| bdual
), BIT4
+ BIT0
);
961 static void check_diport_of_integrated_lvds(
962 struct lvds_chip_information
*plvds_chip_info
,
963 struct lvds_setting_information
966 /* Determine LCD DI Port by hardware layout. */
967 switch (viafb_display_hardware_layout
) {
968 case HW_LAYOUT_LCD_ONLY
:
970 if (plvds_setting_info
->device_lcd_dualedge
) {
971 plvds_chip_info
->output_interface
=
972 INTERFACE_LVDS0LVDS1
;
974 plvds_chip_info
->output_interface
=
981 case HW_LAYOUT_DVI_ONLY
:
983 plvds_chip_info
->output_interface
= INTERFACE_NONE
;
987 case HW_LAYOUT_LCD1_LCD2
:
988 case HW_LAYOUT_LCD_EXTERNAL_LCD2
:
990 plvds_chip_info
->output_interface
=
991 INTERFACE_LVDS0LVDS1
;
995 case HW_LAYOUT_LCD_DVI
:
997 plvds_chip_info
->output_interface
= INTERFACE_LVDS1
;
1003 plvds_chip_info
->output_interface
= INTERFACE_LVDS1
;
1009 "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n",
1010 viafb_display_hardware_layout
,
1011 plvds_chip_info
->output_interface
);
1014 void viafb_init_lvds_output_interface(struct lvds_chip_information
1016 struct lvds_setting_information
1017 *plvds_setting_info
)
1019 if (INTERFACE_NONE
!= plvds_chip_info
->output_interface
) {
1020 /*Do nothing, lcd port is specified by module parameter */
1024 switch (plvds_chip_info
->lvds_chip_name
) {
1027 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
1028 case UNICHROME_CX700
:
1029 plvds_chip_info
->output_interface
= INTERFACE_DVP1
;
1031 case UNICHROME_CN700
:
1032 plvds_chip_info
->output_interface
= INTERFACE_DFP_LOW
;
1035 plvds_chip_info
->output_interface
= INTERFACE_DVP0
;
1040 case INTEGRATED_LVDS
:
1041 check_diport_of_integrated_lvds(plvds_chip_info
,
1042 plvds_setting_info
);
1046 switch (viaparinfo
->chip_info
->gfx_chip_name
) {
1047 case UNICHROME_K8M890
:
1048 case UNICHROME_P4M900
:
1049 case UNICHROME_P4M890
:
1050 plvds_chip_info
->output_interface
= INTERFACE_DFP_LOW
;
1053 plvds_chip_info
->output_interface
= INTERFACE_DFP
;
1060 static struct display_timing
lcd_centering_timging(struct display_timing
1062 struct display_timing panel_crt_reg
)
1064 struct display_timing crt_reg
;
1066 crt_reg
.hor_total
= panel_crt_reg
.hor_total
;
1067 crt_reg
.hor_addr
= mode_crt_reg
.hor_addr
;
1068 crt_reg
.hor_blank_start
=
1069 (panel_crt_reg
.hor_addr
- mode_crt_reg
.hor_addr
) / 2 +
1071 crt_reg
.hor_blank_end
= panel_crt_reg
.hor_blank_end
;
1072 crt_reg
.hor_sync_start
=
1073 (panel_crt_reg
.hor_sync_start
-
1074 panel_crt_reg
.hor_blank_start
) + crt_reg
.hor_blank_start
;
1075 crt_reg
.hor_sync_end
= panel_crt_reg
.hor_sync_end
;
1077 crt_reg
.ver_total
= panel_crt_reg
.ver_total
;
1078 crt_reg
.ver_addr
= mode_crt_reg
.ver_addr
;
1079 crt_reg
.ver_blank_start
=
1080 (panel_crt_reg
.ver_addr
- mode_crt_reg
.ver_addr
) / 2 +
1082 crt_reg
.ver_blank_end
= panel_crt_reg
.ver_blank_end
;
1083 crt_reg
.ver_sync_start
=
1084 (panel_crt_reg
.ver_sync_start
-
1085 panel_crt_reg
.ver_blank_start
) + crt_reg
.ver_blank_start
;
1086 crt_reg
.ver_sync_end
= panel_crt_reg
.ver_sync_end
;
1091 bool viafb_lcd_get_mobile_state(bool *mobile
)
1093 unsigned char *romptr
, *tableptr
;
1095 unsigned char *biosptr
;
1097 u32 romaddr
= 0x000C0000;
1098 u16 start_pattern
= 0;
1100 biosptr
= ioremap(romaddr
, 0x10000);
1102 memcpy(&start_pattern
, biosptr
, 2);
1103 /* Compare pattern */
1104 if (start_pattern
== 0xAA55) {
1105 /* Get the start of Table */
1106 /* 0x1B means BIOS offset position */
1107 romptr
= biosptr
+ 0x1B;
1108 tableptr
= biosptr
+ *((u16
*) romptr
);
1110 /* Get the start of biosver structure */
1111 /* 18 means BIOS version position. */
1112 romptr
= tableptr
+ 18;
1113 romptr
= biosptr
+ *((u16
*) romptr
);
1115 /* The offset should be 44, but the
1116 actual image is less three char. */
1120 core_base
= *romptr
++;
1122 if (core_base
& 0x8)
1126 /* release memory */
1136 static void viafb_load_scaling_factor_for_p4m900(int set_hres
,
1137 int set_vres
, int panel_hres
, int panel_vres
)
1139 int h_scaling_factor
;
1140 int v_scaling_factor
;
1146 /* Check if expansion for horizontal */
1147 if (set_hres
< panel_hres
) {
1148 /* Load Horizontal Scaling Factor */
1150 /* For VIA_K8M800 or later chipsets. */
1152 K800_LCD_HOR_SCF_FORMULA(set_hres
, panel_hres
);
1153 /* HSCaleFactor[1:0] at CR9F[1:0] */
1154 cr9f
= h_scaling_factor
& 0x0003;
1155 /* HSCaleFactor[9:2] at CR77[7:0] */
1156 cr77
= (h_scaling_factor
& 0x03FC) >> 2;
1157 /* HSCaleFactor[11:10] at CR79[5:4] */
1158 cr79
= (h_scaling_factor
& 0x0C00) >> 10;
1161 /* Horizontal scaling enabled */
1164 DEBUG_MSG(KERN_INFO
"Horizontal Scaling value = %d\n",
1167 /* Horizontal scaling disabled */
1171 /* Check if expansion for vertical */
1172 if (set_vres
< panel_vres
) {
1173 /* Load Vertical Scaling Factor */
1175 /* For VIA_K8M800 or later chipsets. */
1177 K800_LCD_VER_SCF_FORMULA(set_vres
, panel_vres
);
1179 /* Vertical scaling enabled */
1181 /* VSCaleFactor[0] at CR79[3] */
1182 cr79
|= ((v_scaling_factor
& 0x0001) << 3);
1183 /* VSCaleFactor[8:1] at CR78[7:0] */
1184 cr78
|= (v_scaling_factor
& 0x01FE) >> 1;
1185 /* VSCaleFactor[10:9] at CR79[7:6] */
1186 cr79
|= ((v_scaling_factor
& 0x0600) >> 9) << 6;
1188 DEBUG_MSG(KERN_INFO
"Vertical Scaling value = %d\n",
1191 /* Vertical scaling disabled */
1195 viafb_write_reg_mask(CRA2
, VIACR
, cra2
, BIT3
+ BIT6
+ BIT7
);
1196 viafb_write_reg_mask(CR77
, VIACR
, cr77
, 0xFF);
1197 viafb_write_reg_mask(CR78
, VIACR
, cr78
, 0xFF);
1198 viafb_write_reg_mask(CR79
, VIACR
, cr79
, 0xF8);
1199 viafb_write_reg_mask(CR9F
, VIACR
, cr9f
, BIT0
+ BIT1
);