lcd.c revision 1606f87e98f83512762da6dbc992103ae690ff11
1ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan/*
2ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
5ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * This program is free software; you can redistribute it and/or
6ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * modify it under the terms of the GNU General Public
7ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * License as published by the Free Software Foundation;
8ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * either version 2, or (at your option) any later version.
9ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
10ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * This program is distributed in the hope that it will be useful,
11ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * the implied warranty of MERCHANTABILITY or FITNESS FOR
13ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * A PARTICULAR PURPOSE.See the GNU General Public License
14ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * for more details.
15ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
16ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * You should have received a copy of the GNU General Public License
17ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * along with this program; if not, write to the Free Software
18ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * Foundation, Inc.,
19ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan */
21ec66841e495b9ab4f92bdf91efe8cf56e1471fbdJonathan Corbet#include <linux/via-core.h>
22ec66841e495b9ab4f92bdf91efe8cf56e1471fbdJonathan Corbet#include <linux/via_i2c.h>
23ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan#include "global.h"
24ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
25dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat#define viafb_compact_res(x, y) (((x)<<16)|(y))
26dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat
2791336712ce579dd8e83bc07bf0a45b7c6963eed2Florian Tobias Schandinat/* CLE266 Software Power Sequence */
2891336712ce579dd8e83bc07bf0a45b7c6963eed2Florian Tobias Schandinat/* {Mask}, {Data}, {Delay} */
2923e5abd5555b86fd56af6383e7a832b0cf2a2d95Stephen Hemmingerstatic const int PowerSequenceOn[3][3] = {
3023e5abd5555b86fd56af6383e7a832b0cf2a2d95Stephen Hemminger	{0x10, 0x08, 0x06}, {0x10, 0x08, 0x06},	{0x19, 0x1FE, 0x01}
3123e5abd5555b86fd56af6383e7a832b0cf2a2d95Stephen Hemminger};
3223e5abd5555b86fd56af6383e7a832b0cf2a2d95Stephen Hemmingerstatic const int PowerSequenceOff[3][3] = {
3323e5abd5555b86fd56af6383e7a832b0cf2a2d95Stephen Hemminger	{0x06, 0x08, 0x10}, {0x00, 0x00, 0x00},	{0xD2, 0x19, 0x01}
3423e5abd5555b86fd56af6383e7a832b0cf2a2d95Stephen Hemminger};
3591336712ce579dd8e83bc07bf0a45b7c6963eed2Florian Tobias Schandinat
36ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic struct _lcd_scaling_factor lcd_scaling_factor = {
37ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* LCD Horizontal Scaling Factor Register */
38ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	{LCD_HOR_SCALING_FACTOR_REG_NUM,
39ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	 {{CR9F, 0, 1}, {CR77, 0, 7}, {CR79, 4, 5} } },
40ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* LCD Vertical Scaling Factor Register */
41ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	{LCD_VER_SCALING_FACTOR_REG_NUM,
42ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	 {{CR79, 3, 3}, {CR78, 0, 7}, {CR79, 6, 7} } }
43ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan};
44ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
45ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* LCD Horizontal Scaling Factor Register */
46ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	{LCD_HOR_SCALING_FACTOR_REG_NUM_CLE, {{CR77, 0, 7}, {CR79, 4, 5} } },
47ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* LCD Vertical Scaling Factor Register */
48ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	{LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } }
49ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan};
50ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
51ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic int check_lvds_chip(int device_id_subaddr, int device_id);
52ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic bool lvds_identify_integratedlvds(void);
53f4ab2f7a21338ae0f59ad925c23545e790cd51e3Florian Tobias Schandinatstatic void __devinit fp_id_to_vindex(int panel_id);
54ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic int lvds_register_read(int index);
55ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
56ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		      int panel_vres);
57ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void via_pitch_alignment_patch_lcd(
58ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	struct lvds_setting_information *plvds_setting_info,
59ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				   struct lvds_chip_information
60ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				   *plvds_chip_info);
61ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void lcd_patch_skew_dvp0(struct lvds_setting_information
62ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			 *plvds_setting_info,
63ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			 struct lvds_chip_information *plvds_chip_info);
64ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void lcd_patch_skew_dvp1(struct lvds_setting_information
65ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			 *plvds_setting_info,
66ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			 struct lvds_chip_information *plvds_chip_info);
67ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void lcd_patch_skew(struct lvds_setting_information
68ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	*plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
69ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
70ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void integrated_lvds_disable(struct lvds_setting_information
71ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			     *plvds_setting_info,
72ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			     struct lvds_chip_information *plvds_chip_info);
73ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void integrated_lvds_enable(struct lvds_setting_information
74ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    *plvds_setting_info,
75ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    struct lvds_chip_information *plvds_chip_info);
76ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void lcd_powersequence_off(void);
77ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void lcd_powersequence_on(void);
78ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void fill_lcd_format(void);
79ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void check_diport_of_integrated_lvds(
80ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	struct lvds_chip_information *plvds_chip_info,
81ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				     struct lvds_setting_information
82ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				     *plvds_setting_info);
83ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic struct display_timing lcd_centering_timging(struct display_timing
84ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan					    mode_crt_reg,
85ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan					   struct display_timing panel_crt_reg);
86ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
87ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic int check_lvds_chip(int device_id_subaddr, int device_id)
88ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
89ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (lvds_register_read(device_id_subaddr) == device_id)
90ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		return OK;
91ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	else
92ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		return FAIL;
93ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
94ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
95f4ab2f7a21338ae0f59ad925c23545e790cd51e3Florian Tobias Schandinatvoid __devinit viafb_init_lcd_size(void)
96ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
97ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
98ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
99cc3fd679a344468e892a109b8de3e2948ce14e0fFlorian Tobias Schandinat	fp_id_to_vindex(viafb_lcd_panel_id);
100ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viaparinfo->lvds_setting_info2->lcd_panel_hres =
101ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres;
102ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viaparinfo->lvds_setting_info2->lcd_panel_vres =
103ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres;
104ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viaparinfo->lvds_setting_info2->device_lcd_dualedge =
105ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	    viaparinfo->lvds_setting_info->device_lcd_dualedge;
106ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viaparinfo->lvds_setting_info2->LCDDithering =
107ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering;
108ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
109ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
110ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic bool lvds_identify_integratedlvds(void)
111ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
112ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (viafb_display_hardware_layout == HW_LAYOUT_LCD_EXTERNAL_LCD2) {
113ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Two dual channel LCD (Internal LVDS + External LVDS): */
114ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* If we have an external LVDS, such as VT1636, we should
115ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		   have its chip ID already. */
116ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
117ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
118ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    INTEGRATED_LVDS;
1192c0e0c88422033c9b6162bf7875aecdd095130b7Joe Perches			DEBUG_MSG(KERN_INFO "Support two dual channel LVDS! "
1202c0e0c88422033c9b6162bf7875aecdd095130b7Joe Perches				  "(Internal LVDS + External LVDS)\n");
121ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		} else {
122ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
123ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    INTEGRATED_LVDS;
1242c0e0c88422033c9b6162bf7875aecdd095130b7Joe Perches			DEBUG_MSG(KERN_INFO "Not found external LVDS, "
1252c0e0c88422033c9b6162bf7875aecdd095130b7Joe Perches				  "so can't support two dual channel LVDS!\n");
126ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
127ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) {
128ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Two single channel LCD (Internal LVDS + Internal LVDS): */
129ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
130ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		INTEGRATED_LVDS;
131ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
132ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			INTEGRATED_LVDS;
1332c0e0c88422033c9b6162bf7875aecdd095130b7Joe Perches		DEBUG_MSG(KERN_INFO "Support two single channel LVDS! "
1342c0e0c88422033c9b6162bf7875aecdd095130b7Joe Perches			  "(Internal LVDS + Internal LVDS)\n");
135ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) {
136ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* If we have found external LVDS, just use it,
137ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		   otherwise, we will use internal LVDS as default. */
138ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		if (!viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
139ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
140ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    INTEGRATED_LVDS;
141ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			DEBUG_MSG(KERN_INFO "Found Integrated LVDS!\n");
142ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
143ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else {
144ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
145ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			NON_LVDS_TRANSMITTER;
146ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		DEBUG_MSG(KERN_INFO "Do not support LVDS!\n");
147ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		return false;
148ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
149ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
150ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	return true;
151ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
152ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
153f4ab2f7a21338ae0f59ad925c23545e790cd51e3Florian Tobias Schandinatint __devinit viafb_lvds_trasmitter_identify(void)
154ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
155f045f77bc0bf238a871b10bea9e425329a8e4abcJonathan Corbet	if (viafb_lvds_identify_vt1636(VIA_PORT_31)) {
156f045f77bc0bf238a871b10bea9e425329a8e4abcJonathan Corbet		viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31;
157ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		DEBUG_MSG(KERN_INFO
158277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte			  "Found VIA VT1636 LVDS on port i2c 0x31\n");
159ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else {
160f045f77bc0bf238a871b10bea9e425329a8e4abcJonathan Corbet		if (viafb_lvds_identify_vt1636(VIA_PORT_2C)) {
161ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viaparinfo->chip_info->lvds_chip_info.i2c_port =
162f045f77bc0bf238a871b10bea9e425329a8e4abcJonathan Corbet				VIA_PORT_2C;
163ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			DEBUG_MSG(KERN_INFO
164277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte				  "Found VIA VT1636 LVDS on port gpio 0x2c\n");
165ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
166ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
167ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
168ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
169ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		lvds_identify_integratedlvds();
170ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
171ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
172ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		return true;
173ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Check for VT1631: */
174ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = VT1631_LVDS;
175ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
176ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		VT1631_LVDS_I2C_ADDR;
177ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
178ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID) != FAIL) {
179ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n");
180ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		DEBUG_MSG(KERN_INFO "\n %2d",
181ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			  viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
182ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		DEBUG_MSG(KERN_INFO "\n %2d",
183ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			  viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
184ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		return OK;
185ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
186ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
187ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
188ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		NON_LVDS_TRANSMITTER;
189ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
190ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		VT1631_LVDS_I2C_ADDR;
191ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	return FAIL;
192ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
193ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
194f4ab2f7a21338ae0f59ad925c23545e790cd51e3Florian Tobias Schandinatstatic void __devinit fp_id_to_vindex(int panel_id)
195ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
196ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
197ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
198ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (panel_id > LCD_PANEL_ID_MAXIMUM)
199ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_lcd_panel_id = panel_id =
200ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_read_reg(VIACR, CR3F) & 0x0F;
201ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
202ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	switch (panel_id) {
203ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x0:
204ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 640;
205ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
206ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
207ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
208ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
209ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x1:
210ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
211ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
212ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
213ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
214ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
215ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x2:
216ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
217ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
218ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
219ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
220ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
221ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x3:
222ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
223ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
224ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
225ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
226ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
227ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x4:
228ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
229ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
230ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
231ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
232ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
233ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x5:
234ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
235ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
236ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
237ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
238ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
239ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x6:
240ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
241ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
242ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
243ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
244ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
245ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x8:
246ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
247ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
248ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
249ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
250ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
251ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x9:
252ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
253ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
254ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
255ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
256ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
257ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0xA:
258ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
259ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
260ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
261ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 0;
262ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
263ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0xB:
264ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
265ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
266ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
267ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 0;
268ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
269ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0xC:
270ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
271ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
272ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
273ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 0;
274ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
275ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0xD:
276ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
277ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
278ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
279ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 0;
280ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
281ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0xE:
282ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
283ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
284ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
285ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 0;
286ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
287ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0xF:
288ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
289ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
290ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
291ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 0;
292ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
293ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x10:
294ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1366;
295ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
296ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
297ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 0;
298ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
299ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x11:
300ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
301ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
302ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
303ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
304ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
305ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x12:
306ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
307ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
308ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
309ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
310ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
311ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x13:
312ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
313ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 800;
314ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
315ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
316ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
317ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x14:
318ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1360;
319ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
320ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
321ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 0;
322ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
323ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x15:
324ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
325ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
326ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
327ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 0;
328ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
329ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case 0x16:
330ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 480;
331ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 640;
332ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
333ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
334ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
335c205d932530719d2a6ddb9152650e5bbe80c9400Chris Ball	case 0x17:
336c205d932530719d2a6ddb9152650e5bbe80c9400Chris Ball		/* OLPC XO-1.5 panel */
337c205d932530719d2a6ddb9152650e5bbe80c9400Chris Ball		viaparinfo->lvds_setting_info->lcd_panel_hres = 1200;
338c205d932530719d2a6ddb9152650e5bbe80c9400Chris Ball		viaparinfo->lvds_setting_info->lcd_panel_vres = 900;
339c205d932530719d2a6ddb9152650e5bbe80c9400Chris Ball		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
340c205d932530719d2a6ddb9152650e5bbe80c9400Chris Ball		viaparinfo->lvds_setting_info->LCDDithering = 0;
341c205d932530719d2a6ddb9152650e5bbe80c9400Chris Ball		break;
342ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	default:
343ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
344ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
345ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
346ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viaparinfo->lvds_setting_info->LCDDithering = 1;
347ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
348ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
349ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
350ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic int lvds_register_read(int index)
351ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
352ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	u8 data;
353ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
354f045f77bc0bf238a871b10bea9e425329a8e4abcJonathan Corbet	viafb_i2c_readbyte(VIA_PORT_2C,
355277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte			(u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
356ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			(u8) index, &data);
357ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	return data;
358ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
359ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
360ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
361ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		      int panel_vres)
362ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
363ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	int reg_value = 0;
364ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	int viafb_load_reg_num;
365ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	struct io_register *reg = NULL;
366ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
367ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	DEBUG_MSG(KERN_INFO "load_lcd_scaling()!!\n");
368ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
369ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* LCD Scaling Enable */
370ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2);
371ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
372ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Check if expansion for horizontal */
373119b953a80d28821a56567d84dab860b0edc7940Florian Tobias Schandinat	if (set_hres < panel_hres) {
374ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Load Horizontal Scaling Factor */
375ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		switch (viaparinfo->chip_info->gfx_chip_name) {
376ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_CLE266:
377ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_K400:
378ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			reg_value =
379ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    CLE266_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
380ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_load_reg_num =
381ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    lcd_scaling_factor_CLE.lcd_hor_scaling_factor.
382ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    reg_num;
383ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			reg = lcd_scaling_factor_CLE.lcd_hor_scaling_factor.reg;
384ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_load_reg(reg_value,
385ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				viafb_load_reg_num, reg, VIACR);
386ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
387ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_K800:
388ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_PM800:
389ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_CN700:
390ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_CX700:
391ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_K8M890:
392ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_P4M890:
3934a73d70ebe890fb71dcdd1cfcb788e1432ed0034Florian Tobias Schandinat		case UNICHROME_P4M900:
394f1ad752a096aca76f93cd7f86815af8093366fdcFlorian Tobias Schandinat		case UNICHROME_CN750:
395f1ad752a096aca76f93cd7f86815af8093366fdcFlorian Tobias Schandinat		case UNICHROME_VX800:
396f1ad752a096aca76f93cd7f86815af8093366fdcFlorian Tobias Schandinat		case UNICHROME_VX855:
39751f4332bb5fef869e8a89895a7bac6b4c03b4946Florian Tobias Schandinat		case UNICHROME_VX900:
398ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			reg_value =
399ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
400ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			/* Horizontal scaling enabled */
401ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_write_reg_mask(CRA2, VIACR, 0xC0, BIT7 + BIT6);
402ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_load_reg_num =
403ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    lcd_scaling_factor.lcd_hor_scaling_factor.reg_num;
404ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			reg = lcd_scaling_factor.lcd_hor_scaling_factor.reg;
405ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_load_reg(reg_value,
406ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				viafb_load_reg_num, reg, VIACR);
407ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
408ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
409ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
410ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d", reg_value);
411ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else {
412ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Horizontal scaling disabled */
413ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT7);
414ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
415ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
416ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Check if expansion for vertical */
417119b953a80d28821a56567d84dab860b0edc7940Florian Tobias Schandinat	if (set_vres < panel_vres) {
418ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Load Vertical Scaling Factor */
419ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		switch (viaparinfo->chip_info->gfx_chip_name) {
420ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_CLE266:
421ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_K400:
422ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			reg_value =
423ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    CLE266_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
424ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_load_reg_num =
425ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    lcd_scaling_factor_CLE.lcd_ver_scaling_factor.
426ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    reg_num;
427ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			reg = lcd_scaling_factor_CLE.lcd_ver_scaling_factor.reg;
428ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_load_reg(reg_value,
429ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				viafb_load_reg_num, reg, VIACR);
430ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
431ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_K800:
432ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_PM800:
433ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_CN700:
434ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_CX700:
435ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_K8M890:
436ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_P4M890:
4374a73d70ebe890fb71dcdd1cfcb788e1432ed0034Florian Tobias Schandinat		case UNICHROME_P4M900:
438f1ad752a096aca76f93cd7f86815af8093366fdcFlorian Tobias Schandinat		case UNICHROME_CN750:
439f1ad752a096aca76f93cd7f86815af8093366fdcFlorian Tobias Schandinat		case UNICHROME_VX800:
440f1ad752a096aca76f93cd7f86815af8093366fdcFlorian Tobias Schandinat		case UNICHROME_VX855:
44151f4332bb5fef869e8a89895a7bac6b4c03b4946Florian Tobias Schandinat		case UNICHROME_VX900:
442ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			reg_value =
443ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
444ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			/* Vertical scaling enabled */
445ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_write_reg_mask(CRA2, VIACR, 0x08, BIT3);
446ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_load_reg_num =
447ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    lcd_scaling_factor.lcd_ver_scaling_factor.reg_num;
448ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			reg = lcd_scaling_factor.lcd_ver_scaling_factor.reg;
449ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_load_reg(reg_value,
450ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				viafb_load_reg_num, reg, VIACR);
451ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
452ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
453ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
454ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d", reg_value);
455ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else {
456ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Vertical scaling disabled */
457ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT3);
458ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
459ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
460ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
461ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void via_pitch_alignment_patch_lcd(
462ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	struct lvds_setting_information *plvds_setting_info,
463ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				   struct lvds_chip_information
464ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				   *plvds_chip_info)
465ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
466ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	unsigned char cr13, cr35, cr65, cr66, cr67;
467ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	unsigned long dwScreenPitch = 0;
468ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	unsigned long dwPitch;
469ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
470ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	dwPitch = plvds_setting_info->h_active * (plvds_setting_info->bpp >> 3);
471ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (dwPitch & 0x1F) {
472ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		dwScreenPitch = ((dwPitch + 31) & ~31) >> 3;
473ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		if (plvds_setting_info->iga_path == IGA2) {
474ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			if (plvds_setting_info->bpp > 8) {
475ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				cr66 = (unsigned char)(dwScreenPitch & 0xFF);
476ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				viafb_write_reg(CR66, VIACR, cr66);
477ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				cr67 = viafb_read_reg(VIACR, CR67) & 0xFC;
478ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				cr67 |=
479ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				    (unsigned
480ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				     char)((dwScreenPitch & 0x300) >> 8);
481ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				viafb_write_reg(CR67, VIACR, cr67);
482ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			}
483ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
484ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			/* Fetch Count */
485ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			cr67 = viafb_read_reg(VIACR, CR67) & 0xF3;
486ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			cr67 |= (unsigned char)((dwScreenPitch & 0x600) >> 7);
487ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_write_reg(CR67, VIACR, cr67);
488ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			cr65 = (unsigned char)((dwScreenPitch >> 1) & 0xFF);
489ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			cr65 += 2;
490ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_write_reg(CR65, VIACR, cr65);
491ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		} else {
492ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			if (plvds_setting_info->bpp > 8) {
493ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				cr13 = (unsigned char)(dwScreenPitch & 0xFF);
494ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				viafb_write_reg(CR13, VIACR, cr13);
495ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				cr35 = viafb_read_reg(VIACR, CR35) & 0x1F;
496ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				cr35 |=
497ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				    (unsigned
498ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				     char)((dwScreenPitch & 0x700) >> 3);
499ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				viafb_write_reg(CR35, VIACR, cr35);
500ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			}
501ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
502ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
503ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
504ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void lcd_patch_skew_dvp0(struct lvds_setting_information
505ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			 *plvds_setting_info,
506ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			 struct lvds_chip_information *plvds_chip_info)
507ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
508ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
509ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		switch (viaparinfo->chip_info->gfx_chip_name) {
510ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_P4M900:
511ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_vt1636_patch_skew_on_vt3364(plvds_setting_info,
512ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan						    plvds_chip_info);
513ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
514ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_P4M890:
515ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info,
516ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan						    plvds_chip_info);
517ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
518ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
519ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
520ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
521ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void lcd_patch_skew_dvp1(struct lvds_setting_information
522ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			 *plvds_setting_info,
523ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			 struct lvds_chip_information *plvds_chip_info)
524ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
525ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
526ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		switch (viaparinfo->chip_info->gfx_chip_name) {
527ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_CX700:
528ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_vt1636_patch_skew_on_vt3324(plvds_setting_info,
529ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan						    plvds_chip_info);
530ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
531ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
532ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
533ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
534ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void lcd_patch_skew(struct lvds_setting_information
535ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	*plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
536ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
537ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	DEBUG_MSG(KERN_INFO "lcd_patch_skew\n");
538ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	switch (plvds_chip_info->output_interface) {
539ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case INTERFACE_DVP0:
540ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		lcd_patch_skew_dvp0(plvds_setting_info, plvds_chip_info);
541ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
542ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case INTERFACE_DVP1:
543ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		lcd_patch_skew_dvp1(plvds_setting_info, plvds_chip_info);
544ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
545ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case INTERFACE_DFP_LOW:
546ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
547ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_write_reg_mask(CR99, VIACR, 0x08,
548ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				       BIT0 + BIT1 + BIT2 + BIT3);
549ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
550ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
551ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
552ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
553ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
554ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan/* LCD Set Mode */
555ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanvoid viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
556ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		  struct lvds_setting_information *plvds_setting_info,
557ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		  struct lvds_chip_information *plvds_chip_info)
558ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
559ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	int set_iga = plvds_setting_info->iga_path;
560ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	int mode_bpp = plvds_setting_info->bpp;
561dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat	int set_hres = plvds_setting_info->h_active;
562dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat	int set_vres = plvds_setting_info->v_active;
563dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat	int panel_hres = plvds_setting_info->lcd_panel_hres;
564dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat	int panel_vres = plvds_setting_info->lcd_panel_vres;
5651606f87e98f83512762da6dbc992103ae690ff11Florian Tobias Schandinat	u32 clock;
566ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	struct display_timing mode_crt_reg, panel_crt_reg;
567ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	struct crt_mode_table *panel_crt_table = NULL;
568dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat	struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres,
569dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat		panel_vres);
570ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
571ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n");
572ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Get mode table */
573ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	mode_crt_reg = mode_crt_table->crtc;
574ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Get panel table Pointer */
575ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	panel_crt_table = vmode_tbl->crtc;
576ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	panel_crt_reg = panel_crt_table->crtc;
577ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
578ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
579ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info);
580fd3cc69848b7e1873e5f12bbcdd572b20277ecf3Florian Tobias Schandinat	clock = panel_crt_reg.hor_total * panel_crt_reg.ver_total
581fd3cc69848b7e1873e5f12bbcdd572b20277ecf3Florian Tobias Schandinat		* panel_crt_table->refresh_rate;
582fd3cc69848b7e1873e5f12bbcdd572b20277ecf3Florian Tobias Schandinat	plvds_setting_info->vclk = clock;
583ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (set_iga == IGA1) {
584ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* IGA1 doesn't have LCD scaling, so set it as centering. */
585ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_load_crtc_timing(lcd_centering_timging
586ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				 (mode_crt_reg, panel_crt_reg), IGA1);
587ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else {
588ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Expansion */
589119b953a80d28821a56567d84dab860b0edc7940Florian Tobias Schandinat		if (plvds_setting_info->display_method == LCD_EXPANDSION
590119b953a80d28821a56567d84dab860b0edc7940Florian Tobias Schandinat			&& (set_hres < panel_hres || set_vres < panel_vres)) {
591ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			/* expansion timing IGA2 loaded panel set timing*/
592ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_load_crtc_timing(panel_crt_reg, IGA2);
593ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n");
594ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			load_lcd_scaling(set_hres, set_vres, panel_hres,
595ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan					 panel_vres);
596ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			DEBUG_MSG(KERN_INFO "load_lcd_scaling!!\n");
597ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		} else {	/* Centering */
598ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			/* centering timing IGA2 always loaded panel
599ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			   and mode releative timing */
600ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_load_crtc_timing(lcd_centering_timging
601ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan					 (mode_crt_reg, panel_crt_reg), IGA2);
602ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_write_reg_mask(CR79, VIACR, 0x00,
603ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				BIT0 + BIT1 + BIT2);
604ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			/* LCD scaling disabled */
605ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
606ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
607ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
6084bbac05f8c0ab40dcc52ed6dff44e1b0d80fa6e3Florian Tobias Schandinat	/* Fetch count for IGA2 only */
6094bbac05f8c0ab40dcc52ed6dff44e1b0d80fa6e3Florian Tobias Schandinat	viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
610ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
6114bbac05f8c0ab40dcc52ed6dff44e1b0d80fa6e3Florian Tobias Schandinat	if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
6124bbac05f8c0ab40dcc52ed6dff44e1b0d80fa6e3Florian Tobias Schandinat		&& (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
6134bbac05f8c0ab40dcc52ed6dff44e1b0d80fa6e3Florian Tobias Schandinat		viafb_load_FIFO_reg(set_iga, set_hres, set_vres);
614ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
615ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	fill_lcd_format();
6161606f87e98f83512762da6dbc992103ae690ff11Florian Tobias Schandinat	viafb_set_vclock(clock, set_iga);
617ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	lcd_patch_skew(plvds_setting_info, plvds_chip_info);
618ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
619ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* If K8M800, enable LCD Prefetch Mode. */
620ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
621ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	    || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name))
622ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0);
623ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
624ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Patch for non 32bit alignment mode */
625ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info);
626ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
627ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
628ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void integrated_lvds_disable(struct lvds_setting_information
629ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			     *plvds_setting_info,
630ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			     struct lvds_chip_information *plvds_chip_info)
631ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
632ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	bool turn_off_first_powersequence = false;
633ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	bool turn_off_second_powersequence = false;
634ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface)
635ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		turn_off_first_powersequence = true;
636ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (INTERFACE_LVDS0 == plvds_chip_info->output_interface)
637ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		turn_off_first_powersequence = true;
638ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (INTERFACE_LVDS1 == plvds_chip_info->output_interface)
639ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		turn_off_second_powersequence = true;
640ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (turn_off_second_powersequence) {
641ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Use second power sequence control: */
642ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
643ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Turn off power sequence. */
644ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CRD4, VIACR, 0, BIT1);
645ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
646ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Turn off back light. */
647ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CRD3, VIACR, 0xC0, BIT6 + BIT7);
648ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
649ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (turn_off_first_powersequence) {
650ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Use first power sequence control: */
651ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
652ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Turn off power sequence. */
653ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CR6A, VIACR, 0, BIT3);
654ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
655ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Turn off back light. */
656ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7);
657ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
658ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
659ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Power off LVDS channel. */
660ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	switch (plvds_chip_info->output_interface) {
661ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case INTERFACE_LVDS0:
662ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		{
663ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_write_reg_mask(CRD2, VIACR, 0x80, BIT7);
664ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
665ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
666ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
667ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case INTERFACE_LVDS1:
668ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		{
669ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_write_reg_mask(CRD2, VIACR, 0x40, BIT6);
670ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
671ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
672ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
673ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case INTERFACE_LVDS0LVDS1:
674ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		{
675ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_write_reg_mask(CRD2, VIACR, 0xC0, BIT6 + BIT7);
676ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
677ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
678ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
679ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
680ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
681ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void integrated_lvds_enable(struct lvds_setting_information
682ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    *plvds_setting_info,
683ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    struct lvds_chip_information *plvds_chip_info)
684ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
685ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n",
686ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		  plvds_chip_info->output_interface);
687ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (plvds_setting_info->lcd_mode == LCD_SPWG)
688ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT0 + BIT1);
689e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte	else
690ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CRD2, VIACR, 0x03, BIT0 + BIT1);
691ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
692e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte	switch (plvds_chip_info->output_interface) {
693e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte	case INTERFACE_LVDS0LVDS1:
694e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte	case INTERFACE_LVDS0:
695ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Use first power sequence control: */
696ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Use hardware control power sequence. */
697ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CR91, VIACR, 0, BIT0);
698ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Turn on back light. */
699ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CR91, VIACR, 0, BIT6 + BIT7);
700ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Turn on hardware power sequence. */
701ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
702e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte		break;
703e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte	case INTERFACE_LVDS1:
704e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte		/* Use second power sequence control: */
705e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte		/* Use hardware control power sequence. */
706e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte		viafb_write_reg_mask(CRD3, VIACR, 0, BIT0);
707e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte		/* Turn on back light. */
708e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte		viafb_write_reg_mask(CRD3, VIACR, 0, BIT6 + BIT7);
709e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte		/* Turn on hardware power sequence. */
710e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte		viafb_write_reg_mask(CRD4, VIACR, 0x02, BIT1);
711e6bf0d2c9a7f1b9b0ac77698017f8f06f9cc0317Harald Welte		break;
712ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
713ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
714ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Power on LVDS channel. */
715ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	switch (plvds_chip_info->output_interface) {
716ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case INTERFACE_LVDS0:
717ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		{
718ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_write_reg_mask(CRD2, VIACR, 0, BIT7);
719ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
720ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
721ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
722ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case INTERFACE_LVDS1:
723ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		{
724ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_write_reg_mask(CRD2, VIACR, 0, BIT6);
725ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
726ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
727ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
728ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case INTERFACE_LVDS0LVDS1:
729ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		{
730ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_write_reg_mask(CRD2, VIACR, 0, BIT6 + BIT7);
731ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
732ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
733ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
734ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
735ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
736ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanvoid viafb_lcd_disable(void)
737ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
738ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
739ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
740ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		lcd_powersequence_off();
741ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* DI1 pad off */
742ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
743ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
744ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		if (viafb_LCD2_ON
745ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		    && (INTEGRATED_LVDS ==
746ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
747ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			integrated_lvds_disable(viaparinfo->lvds_setting_info,
748ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				&viaparinfo->chip_info->lvds_chip_info2);
749ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		if (INTEGRATED_LVDS ==
750ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
751ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			integrated_lvds_disable(viaparinfo->lvds_setting_info,
752ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				&viaparinfo->chip_info->lvds_chip_info);
753ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		if (VT1636_LVDS == viaparinfo->chip_info->
754ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			lvds_chip_info.lvds_chip_name)
755ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
756ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				&viaparinfo->chip_info->lvds_chip_info);
757ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else if (VT1636_LVDS ==
758ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
759ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
760ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				    &viaparinfo->chip_info->lvds_chip_info);
761ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else {
762ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Backlight off           */
763ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20);
764ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* 24 bit DI data paht off */
765ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80);
766ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
767ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
768ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Disable expansion bit   */
769ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01);
770ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Simultaneout disabled   */
771ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
772ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
773ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
774cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinatstatic void set_lcd_output_path(int set_iga, int output_interface)
775cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat{
776cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat	switch (output_interface) {
777cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat	case INTERFACE_DFP:
778cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat		if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)
779cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat		    || (UNICHROME_P4M890 ==
780cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat		    viaparinfo->chip_info->gfx_chip_name))
781cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat			viafb_write_reg_mask(CR97, VIACR, 0x84,
782cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat				       BIT7 + BIT2 + BIT1 + BIT0);
783cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat	case INTERFACE_DVP0:
784cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat	case INTERFACE_DVP1:
785cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat	case INTERFACE_DFP_HIGH:
786cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat	case INTERFACE_DFP_LOW:
787cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat		if (set_iga == IGA2)
788cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat			viafb_write_reg(CR91, VIACR, 0x00);
789cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat		break;
790cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat	}
791cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat}
792cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat
793ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanvoid viafb_lcd_enable(void)
794ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
795cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat	viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
796cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat	viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
797cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat	set_lcd_output_path(viaparinfo->lvds_setting_info->iga_path,
798cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat		viaparinfo->chip_info->lvds_chip_info.output_interface);
799cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat	if (viafb_LCD2_ON)
800cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat		set_lcd_output_path(viaparinfo->lvds_setting_info2->iga_path,
801cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat			viaparinfo->chip_info->
802cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat			lvds_chip_info2.output_interface);
803cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat
804ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
805ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* DI1 pad on */
806ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
807ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		lcd_powersequence_on();
808ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
809ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		if (viafb_LCD2_ON && (INTEGRATED_LVDS ==
810ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
811ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			integrated_lvds_enable(viaparinfo->lvds_setting_info2, \
812ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				&viaparinfo->chip_info->lvds_chip_info2);
813ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		if (INTEGRATED_LVDS ==
814ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
815ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			integrated_lvds_enable(viaparinfo->lvds_setting_info,
816ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				&viaparinfo->chip_info->lvds_chip_info);
817ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		if (VT1636_LVDS == viaparinfo->chip_info->
818ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			lvds_chip_info.lvds_chip_name)
819ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			viafb_enable_lvds_vt1636(viaparinfo->
820ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			lvds_setting_info, &viaparinfo->chip_info->
821ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			lvds_chip_info);
822ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else if (VT1636_LVDS ==
823ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
824ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info,
825ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				   &viaparinfo->chip_info->lvds_chip_info);
826ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else {
827ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Backlight on            */
828ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20);
829ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* 24 bit DI data paht on  */
830ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80);
831ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* LCD enabled             */
832ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48);
833ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
834ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
835ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
836ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void lcd_powersequence_off(void)
837ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
838ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	int i, mask, data;
839ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
840ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Software control power sequence */
841ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
842ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
843ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	for (i = 0; i < 3; i++) {
844ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		mask = PowerSequenceOff[0][i];
845ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		data = PowerSequenceOff[1][i] & mask;
846ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
847ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		udelay(PowerSequenceOff[2][i]);
848ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
849ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
850ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Disable LCD */
851ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x08);
852ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
853ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
854ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void lcd_powersequence_on(void)
855ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
856ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	int i, mask, data;
857ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
858ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Software control power sequence */
859ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
860ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
861ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Enable LCD */
862ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viafb_write_reg_mask(CR6A, VIACR, 0x08, 0x08);
863ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
864ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	for (i = 0; i < 3; i++) {
865ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		mask = PowerSequenceOn[0][i];
866ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		data = PowerSequenceOn[1][i] & mask;
867ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
868ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		udelay(PowerSequenceOn[2][i]);
869ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
870ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
871ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	udelay(1);
872ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
873ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
874ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void fill_lcd_format(void)
875ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
876ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	u8 bdithering = 0, bdual = 0;
877ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
878ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (viaparinfo->lvds_setting_info->device_lcd_dualedge)
879ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		bdual = BIT4;
880ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (viaparinfo->lvds_setting_info->LCDDithering)
881ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		bdithering = BIT0;
882ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Dual & Dithering */
883ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	viafb_write_reg_mask(CR88, VIACR, (bdithering | bdual), BIT4 + BIT0);
884ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
885ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
886ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic void check_diport_of_integrated_lvds(
887ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	struct lvds_chip_information *plvds_chip_info,
888ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				     struct lvds_setting_information
889ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				     *plvds_setting_info)
890ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
891ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Determine LCD DI Port by hardware layout. */
892ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	switch (viafb_display_hardware_layout) {
893ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case HW_LAYOUT_LCD_ONLY:
894ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		{
895ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			if (plvds_setting_info->device_lcd_dualedge) {
896ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				plvds_chip_info->output_interface =
897ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				    INTERFACE_LVDS0LVDS1;
898ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			} else {
899ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				plvds_chip_info->output_interface =
900ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				    INTERFACE_LVDS0;
901ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			}
902ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
903ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
904ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
905ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
906ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case HW_LAYOUT_DVI_ONLY:
907ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		{
908ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			plvds_chip_info->output_interface = INTERFACE_NONE;
909ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
910ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
911ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
912ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case HW_LAYOUT_LCD1_LCD2:
913ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case HW_LAYOUT_LCD_EXTERNAL_LCD2:
914ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		{
915ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			plvds_chip_info->output_interface =
916ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			    INTERFACE_LVDS0LVDS1;
917ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
918ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
919ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
920ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case HW_LAYOUT_LCD_DVI:
921ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		{
922ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			plvds_chip_info->output_interface = INTERFACE_LVDS1;
923ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
924ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
925ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
926ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	default:
927ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		{
928ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			plvds_chip_info->output_interface = INTERFACE_LVDS1;
929ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
930ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
931ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
932ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
933ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	DEBUG_MSG(KERN_INFO
934ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		  "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n",
935ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		  viafb_display_hardware_layout,
936ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		  plvds_chip_info->output_interface);
937ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
938ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
939f4ab2f7a21338ae0f59ad925c23545e790cd51e3Florian Tobias Schandinatvoid __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
940ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				*plvds_chip_info,
941ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				struct lvds_setting_information
942ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan				*plvds_setting_info)
943ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
944ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (INTERFACE_NONE != plvds_chip_info->output_interface) {
945ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/*Do nothing, lcd port is specified by module parameter */
946ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		return;
947ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
948ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
949ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	switch (plvds_chip_info->lvds_chip_name) {
950ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
951ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case VT1636_LVDS:
952ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		switch (viaparinfo->chip_info->gfx_chip_name) {
953ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_CX700:
954ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			plvds_chip_info->output_interface = INTERFACE_DVP1;
955ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
956ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_CN700:
957ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
958ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
959ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		default:
960ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			plvds_chip_info->output_interface = INTERFACE_DVP0;
961ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
962ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
963ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
964ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
965ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	case INTEGRATED_LVDS:
966ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		check_diport_of_integrated_lvds(plvds_chip_info,
967ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan						plvds_setting_info);
968ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
969ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
970ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	default:
971ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		switch (viaparinfo->chip_info->gfx_chip_name) {
972ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_K8M890:
973ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_P4M900:
974ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		case UNICHROME_P4M890:
975ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
976ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
977ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		default:
978ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			plvds_chip_info->output_interface = INTERFACE_DFP;
979ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			break;
980ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		}
981ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		break;
982ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
983ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
984ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
985ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanstatic struct display_timing lcd_centering_timging(struct display_timing
986ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan					    mode_crt_reg,
987ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan					    struct display_timing panel_crt_reg)
988ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
989ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	struct display_timing crt_reg;
990ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
991ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	crt_reg.hor_total = panel_crt_reg.hor_total;
992ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	crt_reg.hor_addr = mode_crt_reg.hor_addr;
993ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	crt_reg.hor_blank_start =
994ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	    (panel_crt_reg.hor_addr - mode_crt_reg.hor_addr) / 2 +
995ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	    crt_reg.hor_addr;
996ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	crt_reg.hor_blank_end = panel_crt_reg.hor_blank_end;
997ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	crt_reg.hor_sync_start =
998ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	    (panel_crt_reg.hor_sync_start -
999ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	     panel_crt_reg.hor_blank_start) + crt_reg.hor_blank_start;
1000ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	crt_reg.hor_sync_end = panel_crt_reg.hor_sync_end;
1001ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
1002ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	crt_reg.ver_total = panel_crt_reg.ver_total;
1003ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	crt_reg.ver_addr = mode_crt_reg.ver_addr;
1004ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	crt_reg.ver_blank_start =
1005ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	    (panel_crt_reg.ver_addr - mode_crt_reg.ver_addr) / 2 +
1006ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	    crt_reg.ver_addr;
1007ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	crt_reg.ver_blank_end = panel_crt_reg.ver_blank_end;
1008ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	crt_reg.ver_sync_start =
1009ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	    (panel_crt_reg.ver_sync_start -
1010ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	     panel_crt_reg.ver_blank_start) + crt_reg.ver_blank_start;
1011ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	crt_reg.ver_sync_end = panel_crt_reg.ver_sync_end;
1012ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
1013ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	return crt_reg;
1014ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
1015ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
1016ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chanbool viafb_lcd_get_mobile_state(bool *mobile)
1017ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan{
1018b65d6040e3a7cd75d9287f7ddfd115e85fde4b44Stephen Hemminger	unsigned char __iomem *romptr, *tableptr, *biosptr;
1019ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	u8 core_base;
1020ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Rom address */
1021b65d6040e3a7cd75d9287f7ddfd115e85fde4b44Stephen Hemminger	const u32 romaddr = 0x000C0000;
1022b65d6040e3a7cd75d9287f7ddfd115e85fde4b44Stephen Hemminger	u16 start_pattern;
1023ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
1024ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	biosptr = ioremap(romaddr, 0x10000);
1025b65d6040e3a7cd75d9287f7ddfd115e85fde4b44Stephen Hemminger	start_pattern = readw(biosptr);
1026ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
1027ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	/* Compare pattern */
1028ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	if (start_pattern == 0xAA55) {
1029ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Get the start of Table */
1030ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* 0x1B means BIOS offset position */
1031ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		romptr = biosptr + 0x1B;
1032b65d6040e3a7cd75d9287f7ddfd115e85fde4b44Stephen Hemminger		tableptr = biosptr + readw(romptr);
1033ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
1034ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* Get the start of biosver structure */
1035ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* 18 means BIOS version position. */
1036ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		romptr = tableptr + 18;
1037b65d6040e3a7cd75d9287f7ddfd115e85fde4b44Stephen Hemminger		romptr = biosptr + readw(romptr);
1038ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
1039ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* The offset should be 44, but the
1040ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		   actual image is less three char. */
1041ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* pRom += 44; */
1042ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		romptr += 41;
1043ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
1044b65d6040e3a7cd75d9287f7ddfd115e85fde4b44Stephen Hemminger		core_base = readb(romptr);
1045ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
1046ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		if (core_base & 0x8)
1047ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			*mobile = false;
1048ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		else
1049ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan			*mobile = true;
1050ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		/* release memory */
1051ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		iounmap(biosptr);
1052ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan
1053ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		return true;
1054ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	} else {
1055ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		iounmap(biosptr);
1056ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan		return false;
1057ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan	}
1058ac6c97e20f1befecd791feed57170ec6735dcce7Joseph Chan}
1059