18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
48c2ecf20Sopenharmony_ci * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#include <linux/via-core.h>
88c2ecf20Sopenharmony_ci#include <linux/via_i2c.h>
98c2ecf20Sopenharmony_ci#include "global.h"
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#define viafb_compact_res(x, y) (((x)<<16)|(y))
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci/* CLE266 Software Power Sequence */
148c2ecf20Sopenharmony_ci/* {Mask}, {Data}, {Delay} */
158c2ecf20Sopenharmony_cistatic const int PowerSequenceOn[3][3] = {
168c2ecf20Sopenharmony_ci	{0x10, 0x08, 0x06}, {0x10, 0x08, 0x06},	{0x19, 0x1FE, 0x01}
178c2ecf20Sopenharmony_ci};
188c2ecf20Sopenharmony_cistatic const int PowerSequenceOff[3][3] = {
198c2ecf20Sopenharmony_ci	{0x06, 0x08, 0x10}, {0x00, 0x00, 0x00},	{0xD2, 0x19, 0x01}
208c2ecf20Sopenharmony_ci};
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistatic struct _lcd_scaling_factor lcd_scaling_factor = {
238c2ecf20Sopenharmony_ci	/* LCD Horizontal Scaling Factor Register */
248c2ecf20Sopenharmony_ci	{LCD_HOR_SCALING_FACTOR_REG_NUM,
258c2ecf20Sopenharmony_ci	 {{CR9F, 0, 1}, {CR77, 0, 7}, {CR79, 4, 5} } },
268c2ecf20Sopenharmony_ci	/* LCD Vertical Scaling Factor Register */
278c2ecf20Sopenharmony_ci	{LCD_VER_SCALING_FACTOR_REG_NUM,
288c2ecf20Sopenharmony_ci	 {{CR79, 3, 3}, {CR78, 0, 7}, {CR79, 6, 7} } }
298c2ecf20Sopenharmony_ci};
308c2ecf20Sopenharmony_cistatic struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
318c2ecf20Sopenharmony_ci	/* LCD Horizontal Scaling Factor Register */
328c2ecf20Sopenharmony_ci	{LCD_HOR_SCALING_FACTOR_REG_NUM_CLE, {{CR77, 0, 7}, {CR79, 4, 5} } },
338c2ecf20Sopenharmony_ci	/* LCD Vertical Scaling Factor Register */
348c2ecf20Sopenharmony_ci	{LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } }
358c2ecf20Sopenharmony_ci};
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_cistatic bool lvds_identify_integratedlvds(void);
388c2ecf20Sopenharmony_cistatic void fp_id_to_vindex(int panel_id);
398c2ecf20Sopenharmony_cistatic int lvds_register_read(int index);
408c2ecf20Sopenharmony_cistatic void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
418c2ecf20Sopenharmony_ci		      int panel_vres);
428c2ecf20Sopenharmony_cistatic void lcd_patch_skew_dvp0(struct lvds_setting_information
438c2ecf20Sopenharmony_ci			 *plvds_setting_info,
448c2ecf20Sopenharmony_ci			 struct lvds_chip_information *plvds_chip_info);
458c2ecf20Sopenharmony_cistatic void lcd_patch_skew_dvp1(struct lvds_setting_information
468c2ecf20Sopenharmony_ci			 *plvds_setting_info,
478c2ecf20Sopenharmony_ci			 struct lvds_chip_information *plvds_chip_info);
488c2ecf20Sopenharmony_cistatic void lcd_patch_skew(struct lvds_setting_information
498c2ecf20Sopenharmony_ci	*plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_cistatic void integrated_lvds_disable(struct lvds_setting_information
528c2ecf20Sopenharmony_ci			     *plvds_setting_info,
538c2ecf20Sopenharmony_ci			     struct lvds_chip_information *plvds_chip_info);
548c2ecf20Sopenharmony_cistatic void integrated_lvds_enable(struct lvds_setting_information
558c2ecf20Sopenharmony_ci			    *plvds_setting_info,
568c2ecf20Sopenharmony_ci			    struct lvds_chip_information *plvds_chip_info);
578c2ecf20Sopenharmony_cistatic void lcd_powersequence_off(void);
588c2ecf20Sopenharmony_cistatic void lcd_powersequence_on(void);
598c2ecf20Sopenharmony_cistatic void fill_lcd_format(void);
608c2ecf20Sopenharmony_cistatic void check_diport_of_integrated_lvds(
618c2ecf20Sopenharmony_ci	struct lvds_chip_information *plvds_chip_info,
628c2ecf20Sopenharmony_ci				     struct lvds_setting_information
638c2ecf20Sopenharmony_ci				     *plvds_setting_info);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_cistatic inline bool check_lvds_chip(int device_id_subaddr, int device_id)
668c2ecf20Sopenharmony_ci{
678c2ecf20Sopenharmony_ci	return lvds_register_read(device_id_subaddr) == device_id;
688c2ecf20Sopenharmony_ci}
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_civoid viafb_init_lcd_size(void)
718c2ecf20Sopenharmony_ci{
728c2ecf20Sopenharmony_ci	DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	fp_id_to_vindex(viafb_lcd_panel_id);
758c2ecf20Sopenharmony_ci	viaparinfo->lvds_setting_info2->lcd_panel_hres =
768c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres;
778c2ecf20Sopenharmony_ci	viaparinfo->lvds_setting_info2->lcd_panel_vres =
788c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres;
798c2ecf20Sopenharmony_ci	viaparinfo->lvds_setting_info2->device_lcd_dualedge =
808c2ecf20Sopenharmony_ci	    viaparinfo->lvds_setting_info->device_lcd_dualedge;
818c2ecf20Sopenharmony_ci	viaparinfo->lvds_setting_info2->LCDDithering =
828c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering;
838c2ecf20Sopenharmony_ci}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_cistatic bool lvds_identify_integratedlvds(void)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	if (viafb_display_hardware_layout == HW_LAYOUT_LCD_EXTERNAL_LCD2) {
888c2ecf20Sopenharmony_ci		/* Two dual channel LCD (Internal LVDS + External LVDS): */
898c2ecf20Sopenharmony_ci		/* If we have an external LVDS, such as VT1636, we should
908c2ecf20Sopenharmony_ci		   have its chip ID already. */
918c2ecf20Sopenharmony_ci		if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
928c2ecf20Sopenharmony_ci			viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
938c2ecf20Sopenharmony_ci			    INTEGRATED_LVDS;
948c2ecf20Sopenharmony_ci			DEBUG_MSG(KERN_INFO "Support two dual channel LVDS! "
958c2ecf20Sopenharmony_ci				  "(Internal LVDS + External LVDS)\n");
968c2ecf20Sopenharmony_ci		} else {
978c2ecf20Sopenharmony_ci			viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
988c2ecf20Sopenharmony_ci			    INTEGRATED_LVDS;
998c2ecf20Sopenharmony_ci			DEBUG_MSG(KERN_INFO "Not found external LVDS, "
1008c2ecf20Sopenharmony_ci				  "so can't support two dual channel LVDS!\n");
1018c2ecf20Sopenharmony_ci		}
1028c2ecf20Sopenharmony_ci	} else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) {
1038c2ecf20Sopenharmony_ci		/* Two single channel LCD (Internal LVDS + Internal LVDS): */
1048c2ecf20Sopenharmony_ci		viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
1058c2ecf20Sopenharmony_ci		INTEGRATED_LVDS;
1068c2ecf20Sopenharmony_ci		viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
1078c2ecf20Sopenharmony_ci			INTEGRATED_LVDS;
1088c2ecf20Sopenharmony_ci		DEBUG_MSG(KERN_INFO "Support two single channel LVDS! "
1098c2ecf20Sopenharmony_ci			  "(Internal LVDS + Internal LVDS)\n");
1108c2ecf20Sopenharmony_ci	} else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) {
1118c2ecf20Sopenharmony_ci		/* If we have found external LVDS, just use it,
1128c2ecf20Sopenharmony_ci		   otherwise, we will use internal LVDS as default. */
1138c2ecf20Sopenharmony_ci		if (!viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
1148c2ecf20Sopenharmony_ci			viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
1158c2ecf20Sopenharmony_ci			    INTEGRATED_LVDS;
1168c2ecf20Sopenharmony_ci			DEBUG_MSG(KERN_INFO "Found Integrated LVDS!\n");
1178c2ecf20Sopenharmony_ci		}
1188c2ecf20Sopenharmony_ci	} else {
1198c2ecf20Sopenharmony_ci		viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
1208c2ecf20Sopenharmony_ci			NON_LVDS_TRANSMITTER;
1218c2ecf20Sopenharmony_ci		DEBUG_MSG(KERN_INFO "Do not support LVDS!\n");
1228c2ecf20Sopenharmony_ci		return false;
1238c2ecf20Sopenharmony_ci	}
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	return true;
1268c2ecf20Sopenharmony_ci}
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_cibool viafb_lvds_trasmitter_identify(void)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	if (viafb_lvds_identify_vt1636(VIA_PORT_31)) {
1318c2ecf20Sopenharmony_ci		viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31;
1328c2ecf20Sopenharmony_ci		DEBUG_MSG(KERN_INFO
1338c2ecf20Sopenharmony_ci			  "Found VIA VT1636 LVDS on port i2c 0x31\n");
1348c2ecf20Sopenharmony_ci	} else {
1358c2ecf20Sopenharmony_ci		if (viafb_lvds_identify_vt1636(VIA_PORT_2C)) {
1368c2ecf20Sopenharmony_ci			viaparinfo->chip_info->lvds_chip_info.i2c_port =
1378c2ecf20Sopenharmony_ci				VIA_PORT_2C;
1388c2ecf20Sopenharmony_ci			DEBUG_MSG(KERN_INFO
1398c2ecf20Sopenharmony_ci				  "Found VIA VT1636 LVDS on port gpio 0x2c\n");
1408c2ecf20Sopenharmony_ci		}
1418c2ecf20Sopenharmony_ci	}
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
1448c2ecf20Sopenharmony_ci		lvds_identify_integratedlvds();
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci	if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
1478c2ecf20Sopenharmony_ci		return true;
1488c2ecf20Sopenharmony_ci	/* Check for VT1631: */
1498c2ecf20Sopenharmony_ci	viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = VT1631_LVDS;
1508c2ecf20Sopenharmony_ci	viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
1518c2ecf20Sopenharmony_ci		VT1631_LVDS_I2C_ADDR;
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID)) {
1548c2ecf20Sopenharmony_ci		DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n");
1558c2ecf20Sopenharmony_ci		DEBUG_MSG(KERN_INFO "\n %2d",
1568c2ecf20Sopenharmony_ci			  viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
1578c2ecf20Sopenharmony_ci		DEBUG_MSG(KERN_INFO "\n %2d",
1588c2ecf20Sopenharmony_ci			  viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
1598c2ecf20Sopenharmony_ci		return true;
1608c2ecf20Sopenharmony_ci	}
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
1638c2ecf20Sopenharmony_ci		NON_LVDS_TRANSMITTER;
1648c2ecf20Sopenharmony_ci	viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
1658c2ecf20Sopenharmony_ci		VT1631_LVDS_I2C_ADDR;
1668c2ecf20Sopenharmony_ci	return false;
1678c2ecf20Sopenharmony_ci}
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_cistatic void fp_id_to_vindex(int panel_id)
1708c2ecf20Sopenharmony_ci{
1718c2ecf20Sopenharmony_ci	DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci	if (panel_id > LCD_PANEL_ID_MAXIMUM)
1748c2ecf20Sopenharmony_ci		viafb_lcd_panel_id = panel_id =
1758c2ecf20Sopenharmony_ci		viafb_read_reg(VIACR, CR3F) & 0x0F;
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci	switch (panel_id) {
1788c2ecf20Sopenharmony_ci	case 0x0:
1798c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 640;
1808c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
1818c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
1828c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
1838c2ecf20Sopenharmony_ci		break;
1848c2ecf20Sopenharmony_ci	case 0x1:
1858c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
1868c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
1878c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
1888c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
1898c2ecf20Sopenharmony_ci		break;
1908c2ecf20Sopenharmony_ci	case 0x2:
1918c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
1928c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
1938c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
1948c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
1958c2ecf20Sopenharmony_ci		break;
1968c2ecf20Sopenharmony_ci	case 0x3:
1978c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
1988c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
1998c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
2008c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
2018c2ecf20Sopenharmony_ci		break;
2028c2ecf20Sopenharmony_ci	case 0x4:
2038c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
2048c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
2058c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
2068c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
2078c2ecf20Sopenharmony_ci		break;
2088c2ecf20Sopenharmony_ci	case 0x5:
2098c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
2108c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
2118c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
2128c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
2138c2ecf20Sopenharmony_ci		break;
2148c2ecf20Sopenharmony_ci	case 0x6:
2158c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
2168c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
2178c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
2188c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
2198c2ecf20Sopenharmony_ci		break;
2208c2ecf20Sopenharmony_ci	case 0x8:
2218c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
2228c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
2238c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
2248c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
2258c2ecf20Sopenharmony_ci		break;
2268c2ecf20Sopenharmony_ci	case 0x9:
2278c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
2288c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
2298c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
2308c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
2318c2ecf20Sopenharmony_ci		break;
2328c2ecf20Sopenharmony_ci	case 0xA:
2338c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
2348c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
2358c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
2368c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 0;
2378c2ecf20Sopenharmony_ci		break;
2388c2ecf20Sopenharmony_ci	case 0xB:
2398c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
2408c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
2418c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
2428c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 0;
2438c2ecf20Sopenharmony_ci		break;
2448c2ecf20Sopenharmony_ci	case 0xC:
2458c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
2468c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
2478c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
2488c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 0;
2498c2ecf20Sopenharmony_ci		break;
2508c2ecf20Sopenharmony_ci	case 0xD:
2518c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
2528c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
2538c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
2548c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 0;
2558c2ecf20Sopenharmony_ci		break;
2568c2ecf20Sopenharmony_ci	case 0xE:
2578c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
2588c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
2598c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
2608c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 0;
2618c2ecf20Sopenharmony_ci		break;
2628c2ecf20Sopenharmony_ci	case 0xF:
2638c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
2648c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
2658c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
2668c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 0;
2678c2ecf20Sopenharmony_ci		break;
2688c2ecf20Sopenharmony_ci	case 0x10:
2698c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1366;
2708c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
2718c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
2728c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 0;
2738c2ecf20Sopenharmony_ci		break;
2748c2ecf20Sopenharmony_ci	case 0x11:
2758c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
2768c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
2778c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
2788c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
2798c2ecf20Sopenharmony_ci		break;
2808c2ecf20Sopenharmony_ci	case 0x12:
2818c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
2828c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
2838c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
2848c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
2858c2ecf20Sopenharmony_ci		break;
2868c2ecf20Sopenharmony_ci	case 0x13:
2878c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
2888c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 800;
2898c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
2908c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
2918c2ecf20Sopenharmony_ci		break;
2928c2ecf20Sopenharmony_ci	case 0x14:
2938c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1360;
2948c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
2958c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
2968c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 0;
2978c2ecf20Sopenharmony_ci		break;
2988c2ecf20Sopenharmony_ci	case 0x15:
2998c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
3008c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
3018c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
3028c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 0;
3038c2ecf20Sopenharmony_ci		break;
3048c2ecf20Sopenharmony_ci	case 0x16:
3058c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 480;
3068c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 640;
3078c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
3088c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
3098c2ecf20Sopenharmony_ci		break;
3108c2ecf20Sopenharmony_ci	case 0x17:
3118c2ecf20Sopenharmony_ci		/* OLPC XO-1.5 panel */
3128c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 1200;
3138c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 900;
3148c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
3158c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 0;
3168c2ecf20Sopenharmony_ci		break;
3178c2ecf20Sopenharmony_ci	default:
3188c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
3198c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
3208c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
3218c2ecf20Sopenharmony_ci		viaparinfo->lvds_setting_info->LCDDithering = 1;
3228c2ecf20Sopenharmony_ci	}
3238c2ecf20Sopenharmony_ci}
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_cistatic int lvds_register_read(int index)
3268c2ecf20Sopenharmony_ci{
3278c2ecf20Sopenharmony_ci	u8 data;
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci	viafb_i2c_readbyte(VIA_PORT_2C,
3308c2ecf20Sopenharmony_ci			(u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
3318c2ecf20Sopenharmony_ci			(u8) index, &data);
3328c2ecf20Sopenharmony_ci	return data;
3338c2ecf20Sopenharmony_ci}
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_cistatic void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
3368c2ecf20Sopenharmony_ci		      int panel_vres)
3378c2ecf20Sopenharmony_ci{
3388c2ecf20Sopenharmony_ci	int reg_value = 0;
3398c2ecf20Sopenharmony_ci	int viafb_load_reg_num;
3408c2ecf20Sopenharmony_ci	struct io_register *reg = NULL;
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci	DEBUG_MSG(KERN_INFO "load_lcd_scaling()!!\n");
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci	/* LCD Scaling Enable */
3458c2ecf20Sopenharmony_ci	viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2);
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci	/* Check if expansion for horizontal */
3488c2ecf20Sopenharmony_ci	if (set_hres < panel_hres) {
3498c2ecf20Sopenharmony_ci		/* Load Horizontal Scaling Factor */
3508c2ecf20Sopenharmony_ci		switch (viaparinfo->chip_info->gfx_chip_name) {
3518c2ecf20Sopenharmony_ci		case UNICHROME_CLE266:
3528c2ecf20Sopenharmony_ci		case UNICHROME_K400:
3538c2ecf20Sopenharmony_ci			reg_value =
3548c2ecf20Sopenharmony_ci			    CLE266_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
3558c2ecf20Sopenharmony_ci			viafb_load_reg_num =
3568c2ecf20Sopenharmony_ci			    lcd_scaling_factor_CLE.lcd_hor_scaling_factor.
3578c2ecf20Sopenharmony_ci			    reg_num;
3588c2ecf20Sopenharmony_ci			reg = lcd_scaling_factor_CLE.lcd_hor_scaling_factor.reg;
3598c2ecf20Sopenharmony_ci			viafb_load_reg(reg_value,
3608c2ecf20Sopenharmony_ci				viafb_load_reg_num, reg, VIACR);
3618c2ecf20Sopenharmony_ci			break;
3628c2ecf20Sopenharmony_ci		case UNICHROME_K800:
3638c2ecf20Sopenharmony_ci		case UNICHROME_PM800:
3648c2ecf20Sopenharmony_ci		case UNICHROME_CN700:
3658c2ecf20Sopenharmony_ci		case UNICHROME_CX700:
3668c2ecf20Sopenharmony_ci		case UNICHROME_K8M890:
3678c2ecf20Sopenharmony_ci		case UNICHROME_P4M890:
3688c2ecf20Sopenharmony_ci		case UNICHROME_P4M900:
3698c2ecf20Sopenharmony_ci		case UNICHROME_CN750:
3708c2ecf20Sopenharmony_ci		case UNICHROME_VX800:
3718c2ecf20Sopenharmony_ci		case UNICHROME_VX855:
3728c2ecf20Sopenharmony_ci		case UNICHROME_VX900:
3738c2ecf20Sopenharmony_ci			reg_value =
3748c2ecf20Sopenharmony_ci			    K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
3758c2ecf20Sopenharmony_ci			/* Horizontal scaling enabled */
3768c2ecf20Sopenharmony_ci			viafb_write_reg_mask(CRA2, VIACR, 0xC0, BIT7 + BIT6);
3778c2ecf20Sopenharmony_ci			viafb_load_reg_num =
3788c2ecf20Sopenharmony_ci			    lcd_scaling_factor.lcd_hor_scaling_factor.reg_num;
3798c2ecf20Sopenharmony_ci			reg = lcd_scaling_factor.lcd_hor_scaling_factor.reg;
3808c2ecf20Sopenharmony_ci			viafb_load_reg(reg_value,
3818c2ecf20Sopenharmony_ci				viafb_load_reg_num, reg, VIACR);
3828c2ecf20Sopenharmony_ci			break;
3838c2ecf20Sopenharmony_ci		}
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ci		DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d", reg_value);
3868c2ecf20Sopenharmony_ci	} else {
3878c2ecf20Sopenharmony_ci		/* Horizontal scaling disabled */
3888c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT7);
3898c2ecf20Sopenharmony_ci	}
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_ci	/* Check if expansion for vertical */
3928c2ecf20Sopenharmony_ci	if (set_vres < panel_vres) {
3938c2ecf20Sopenharmony_ci		/* Load Vertical Scaling Factor */
3948c2ecf20Sopenharmony_ci		switch (viaparinfo->chip_info->gfx_chip_name) {
3958c2ecf20Sopenharmony_ci		case UNICHROME_CLE266:
3968c2ecf20Sopenharmony_ci		case UNICHROME_K400:
3978c2ecf20Sopenharmony_ci			reg_value =
3988c2ecf20Sopenharmony_ci			    CLE266_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
3998c2ecf20Sopenharmony_ci			viafb_load_reg_num =
4008c2ecf20Sopenharmony_ci			    lcd_scaling_factor_CLE.lcd_ver_scaling_factor.
4018c2ecf20Sopenharmony_ci			    reg_num;
4028c2ecf20Sopenharmony_ci			reg = lcd_scaling_factor_CLE.lcd_ver_scaling_factor.reg;
4038c2ecf20Sopenharmony_ci			viafb_load_reg(reg_value,
4048c2ecf20Sopenharmony_ci				viafb_load_reg_num, reg, VIACR);
4058c2ecf20Sopenharmony_ci			break;
4068c2ecf20Sopenharmony_ci		case UNICHROME_K800:
4078c2ecf20Sopenharmony_ci		case UNICHROME_PM800:
4088c2ecf20Sopenharmony_ci		case UNICHROME_CN700:
4098c2ecf20Sopenharmony_ci		case UNICHROME_CX700:
4108c2ecf20Sopenharmony_ci		case UNICHROME_K8M890:
4118c2ecf20Sopenharmony_ci		case UNICHROME_P4M890:
4128c2ecf20Sopenharmony_ci		case UNICHROME_P4M900:
4138c2ecf20Sopenharmony_ci		case UNICHROME_CN750:
4148c2ecf20Sopenharmony_ci		case UNICHROME_VX800:
4158c2ecf20Sopenharmony_ci		case UNICHROME_VX855:
4168c2ecf20Sopenharmony_ci		case UNICHROME_VX900:
4178c2ecf20Sopenharmony_ci			reg_value =
4188c2ecf20Sopenharmony_ci			    K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
4198c2ecf20Sopenharmony_ci			/* Vertical scaling enabled */
4208c2ecf20Sopenharmony_ci			viafb_write_reg_mask(CRA2, VIACR, 0x08, BIT3);
4218c2ecf20Sopenharmony_ci			viafb_load_reg_num =
4228c2ecf20Sopenharmony_ci			    lcd_scaling_factor.lcd_ver_scaling_factor.reg_num;
4238c2ecf20Sopenharmony_ci			reg = lcd_scaling_factor.lcd_ver_scaling_factor.reg;
4248c2ecf20Sopenharmony_ci			viafb_load_reg(reg_value,
4258c2ecf20Sopenharmony_ci				viafb_load_reg_num, reg, VIACR);
4268c2ecf20Sopenharmony_ci			break;
4278c2ecf20Sopenharmony_ci		}
4288c2ecf20Sopenharmony_ci
4298c2ecf20Sopenharmony_ci		DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d", reg_value);
4308c2ecf20Sopenharmony_ci	} else {
4318c2ecf20Sopenharmony_ci		/* Vertical scaling disabled */
4328c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT3);
4338c2ecf20Sopenharmony_ci	}
4348c2ecf20Sopenharmony_ci}
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_cistatic void via_pitch_alignment_patch_lcd(int iga_path, int hres, int bpp)
4378c2ecf20Sopenharmony_ci{
4388c2ecf20Sopenharmony_ci	unsigned char cr13, cr35, cr65, cr66, cr67;
4398c2ecf20Sopenharmony_ci	unsigned long dwScreenPitch = 0;
4408c2ecf20Sopenharmony_ci	unsigned long dwPitch;
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci	dwPitch = hres * (bpp >> 3);
4438c2ecf20Sopenharmony_ci	if (dwPitch & 0x1F) {
4448c2ecf20Sopenharmony_ci		dwScreenPitch = ((dwPitch + 31) & ~31) >> 3;
4458c2ecf20Sopenharmony_ci		if (iga_path == IGA2) {
4468c2ecf20Sopenharmony_ci			if (bpp > 8) {
4478c2ecf20Sopenharmony_ci				cr66 = (unsigned char)(dwScreenPitch & 0xFF);
4488c2ecf20Sopenharmony_ci				viafb_write_reg(CR66, VIACR, cr66);
4498c2ecf20Sopenharmony_ci				cr67 = viafb_read_reg(VIACR, CR67) & 0xFC;
4508c2ecf20Sopenharmony_ci				cr67 |=
4518c2ecf20Sopenharmony_ci				    (unsigned
4528c2ecf20Sopenharmony_ci				     char)((dwScreenPitch & 0x300) >> 8);
4538c2ecf20Sopenharmony_ci				viafb_write_reg(CR67, VIACR, cr67);
4548c2ecf20Sopenharmony_ci			}
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci			/* Fetch Count */
4578c2ecf20Sopenharmony_ci			cr67 = viafb_read_reg(VIACR, CR67) & 0xF3;
4588c2ecf20Sopenharmony_ci			cr67 |= (unsigned char)((dwScreenPitch & 0x600) >> 7);
4598c2ecf20Sopenharmony_ci			viafb_write_reg(CR67, VIACR, cr67);
4608c2ecf20Sopenharmony_ci			cr65 = (unsigned char)((dwScreenPitch >> 1) & 0xFF);
4618c2ecf20Sopenharmony_ci			cr65 += 2;
4628c2ecf20Sopenharmony_ci			viafb_write_reg(CR65, VIACR, cr65);
4638c2ecf20Sopenharmony_ci		} else {
4648c2ecf20Sopenharmony_ci			if (bpp > 8) {
4658c2ecf20Sopenharmony_ci				cr13 = (unsigned char)(dwScreenPitch & 0xFF);
4668c2ecf20Sopenharmony_ci				viafb_write_reg(CR13, VIACR, cr13);
4678c2ecf20Sopenharmony_ci				cr35 = viafb_read_reg(VIACR, CR35) & 0x1F;
4688c2ecf20Sopenharmony_ci				cr35 |=
4698c2ecf20Sopenharmony_ci				    (unsigned
4708c2ecf20Sopenharmony_ci				     char)((dwScreenPitch & 0x700) >> 3);
4718c2ecf20Sopenharmony_ci				viafb_write_reg(CR35, VIACR, cr35);
4728c2ecf20Sopenharmony_ci			}
4738c2ecf20Sopenharmony_ci		}
4748c2ecf20Sopenharmony_ci	}
4758c2ecf20Sopenharmony_ci}
4768c2ecf20Sopenharmony_cistatic void lcd_patch_skew_dvp0(struct lvds_setting_information
4778c2ecf20Sopenharmony_ci			 *plvds_setting_info,
4788c2ecf20Sopenharmony_ci			 struct lvds_chip_information *plvds_chip_info)
4798c2ecf20Sopenharmony_ci{
4808c2ecf20Sopenharmony_ci	if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
4818c2ecf20Sopenharmony_ci		switch (viaparinfo->chip_info->gfx_chip_name) {
4828c2ecf20Sopenharmony_ci		case UNICHROME_P4M900:
4838c2ecf20Sopenharmony_ci			viafb_vt1636_patch_skew_on_vt3364(plvds_setting_info,
4848c2ecf20Sopenharmony_ci						    plvds_chip_info);
4858c2ecf20Sopenharmony_ci			break;
4868c2ecf20Sopenharmony_ci		case UNICHROME_P4M890:
4878c2ecf20Sopenharmony_ci			viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info,
4888c2ecf20Sopenharmony_ci						    plvds_chip_info);
4898c2ecf20Sopenharmony_ci			break;
4908c2ecf20Sopenharmony_ci		}
4918c2ecf20Sopenharmony_ci	}
4928c2ecf20Sopenharmony_ci}
4938c2ecf20Sopenharmony_cistatic void lcd_patch_skew_dvp1(struct lvds_setting_information
4948c2ecf20Sopenharmony_ci			 *plvds_setting_info,
4958c2ecf20Sopenharmony_ci			 struct lvds_chip_information *plvds_chip_info)
4968c2ecf20Sopenharmony_ci{
4978c2ecf20Sopenharmony_ci	if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
4988c2ecf20Sopenharmony_ci		switch (viaparinfo->chip_info->gfx_chip_name) {
4998c2ecf20Sopenharmony_ci		case UNICHROME_CX700:
5008c2ecf20Sopenharmony_ci			viafb_vt1636_patch_skew_on_vt3324(plvds_setting_info,
5018c2ecf20Sopenharmony_ci						    plvds_chip_info);
5028c2ecf20Sopenharmony_ci			break;
5038c2ecf20Sopenharmony_ci		}
5048c2ecf20Sopenharmony_ci	}
5058c2ecf20Sopenharmony_ci}
5068c2ecf20Sopenharmony_cistatic void lcd_patch_skew(struct lvds_setting_information
5078c2ecf20Sopenharmony_ci	*plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
5088c2ecf20Sopenharmony_ci{
5098c2ecf20Sopenharmony_ci	DEBUG_MSG(KERN_INFO "lcd_patch_skew\n");
5108c2ecf20Sopenharmony_ci	switch (plvds_chip_info->output_interface) {
5118c2ecf20Sopenharmony_ci	case INTERFACE_DVP0:
5128c2ecf20Sopenharmony_ci		lcd_patch_skew_dvp0(plvds_setting_info, plvds_chip_info);
5138c2ecf20Sopenharmony_ci		break;
5148c2ecf20Sopenharmony_ci	case INTERFACE_DVP1:
5158c2ecf20Sopenharmony_ci		lcd_patch_skew_dvp1(plvds_setting_info, plvds_chip_info);
5168c2ecf20Sopenharmony_ci		break;
5178c2ecf20Sopenharmony_ci	case INTERFACE_DFP_LOW:
5188c2ecf20Sopenharmony_ci		if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
5198c2ecf20Sopenharmony_ci			viafb_write_reg_mask(CR99, VIACR, 0x08,
5208c2ecf20Sopenharmony_ci				       BIT0 + BIT1 + BIT2 + BIT3);
5218c2ecf20Sopenharmony_ci		}
5228c2ecf20Sopenharmony_ci		break;
5238c2ecf20Sopenharmony_ci	}
5248c2ecf20Sopenharmony_ci}
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_ci/* LCD Set Mode */
5278c2ecf20Sopenharmony_civoid viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres,
5288c2ecf20Sopenharmony_ci	u16 cyres, struct lvds_setting_information *plvds_setting_info,
5298c2ecf20Sopenharmony_ci	struct lvds_chip_information *plvds_chip_info)
5308c2ecf20Sopenharmony_ci{
5318c2ecf20Sopenharmony_ci	int set_iga = plvds_setting_info->iga_path;
5328c2ecf20Sopenharmony_ci	int mode_bpp = var->bits_per_pixel;
5338c2ecf20Sopenharmony_ci	int set_hres = cxres ? cxres : var->xres;
5348c2ecf20Sopenharmony_ci	int set_vres = cyres ? cyres : var->yres;
5358c2ecf20Sopenharmony_ci	int panel_hres = plvds_setting_info->lcd_panel_hres;
5368c2ecf20Sopenharmony_ci	int panel_vres = plvds_setting_info->lcd_panel_vres;
5378c2ecf20Sopenharmony_ci	u32 clock;
5388c2ecf20Sopenharmony_ci	struct via_display_timing timing;
5398c2ecf20Sopenharmony_ci	struct fb_var_screeninfo panel_var;
5408c2ecf20Sopenharmony_ci	const struct fb_videomode *mode_crt_table, *panel_crt_table;
5418c2ecf20Sopenharmony_ci
5428c2ecf20Sopenharmony_ci	DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n");
5438c2ecf20Sopenharmony_ci	/* Get mode table */
5448c2ecf20Sopenharmony_ci	mode_crt_table = viafb_get_best_mode(set_hres, set_vres, 60);
5458c2ecf20Sopenharmony_ci	/* Get panel table Pointer */
5468c2ecf20Sopenharmony_ci	panel_crt_table = viafb_get_best_mode(panel_hres, panel_vres, 60);
5478c2ecf20Sopenharmony_ci	viafb_fill_var_timing_info(&panel_var, panel_crt_table);
5488c2ecf20Sopenharmony_ci	DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
5498c2ecf20Sopenharmony_ci	if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
5508c2ecf20Sopenharmony_ci		viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info);
5518c2ecf20Sopenharmony_ci	clock = PICOS2KHZ(panel_crt_table->pixclock) * 1000;
5528c2ecf20Sopenharmony_ci	plvds_setting_info->vclk = clock;
5538c2ecf20Sopenharmony_ci
5548c2ecf20Sopenharmony_ci	if (set_iga == IGA2 && (set_hres < panel_hres || set_vres < panel_vres)
5558c2ecf20Sopenharmony_ci		&& plvds_setting_info->display_method == LCD_EXPANDSION) {
5568c2ecf20Sopenharmony_ci		timing = var_to_timing(&panel_var, panel_hres, panel_vres);
5578c2ecf20Sopenharmony_ci		load_lcd_scaling(set_hres, set_vres, panel_hres, panel_vres);
5588c2ecf20Sopenharmony_ci	} else {
5598c2ecf20Sopenharmony_ci		timing = var_to_timing(&panel_var, set_hres, set_vres);
5608c2ecf20Sopenharmony_ci		if (set_iga == IGA2)
5618c2ecf20Sopenharmony_ci			/* disable scaling */
5628c2ecf20Sopenharmony_ci			via_write_reg_mask(VIACR, 0x79, 0x00,
5638c2ecf20Sopenharmony_ci				BIT0 + BIT1 + BIT2);
5648c2ecf20Sopenharmony_ci	}
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_ci	if (set_iga == IGA1)
5678c2ecf20Sopenharmony_ci		via_set_primary_timing(&timing);
5688c2ecf20Sopenharmony_ci	else if (set_iga == IGA2)
5698c2ecf20Sopenharmony_ci		via_set_secondary_timing(&timing);
5708c2ecf20Sopenharmony_ci
5718c2ecf20Sopenharmony_ci	/* Fetch count for IGA2 only */
5728c2ecf20Sopenharmony_ci	viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_ci	if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
5758c2ecf20Sopenharmony_ci		&& (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
5768c2ecf20Sopenharmony_ci		viafb_load_FIFO_reg(set_iga, set_hres, set_vres);
5778c2ecf20Sopenharmony_ci
5788c2ecf20Sopenharmony_ci	fill_lcd_format();
5798c2ecf20Sopenharmony_ci	viafb_set_vclock(clock, set_iga);
5808c2ecf20Sopenharmony_ci	lcd_patch_skew(plvds_setting_info, plvds_chip_info);
5818c2ecf20Sopenharmony_ci
5828c2ecf20Sopenharmony_ci	/* If K8M800, enable LCD Prefetch Mode. */
5838c2ecf20Sopenharmony_ci	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
5848c2ecf20Sopenharmony_ci	    || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name))
5858c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0);
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ci	/* Patch for non 32bit alignment mode */
5888c2ecf20Sopenharmony_ci	via_pitch_alignment_patch_lcd(plvds_setting_info->iga_path, set_hres,
5898c2ecf20Sopenharmony_ci		var->bits_per_pixel);
5908c2ecf20Sopenharmony_ci}
5918c2ecf20Sopenharmony_ci
5928c2ecf20Sopenharmony_cistatic void integrated_lvds_disable(struct lvds_setting_information
5938c2ecf20Sopenharmony_ci			     *plvds_setting_info,
5948c2ecf20Sopenharmony_ci			     struct lvds_chip_information *plvds_chip_info)
5958c2ecf20Sopenharmony_ci{
5968c2ecf20Sopenharmony_ci	bool turn_off_first_powersequence = false;
5978c2ecf20Sopenharmony_ci	bool turn_off_second_powersequence = false;
5988c2ecf20Sopenharmony_ci	if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface)
5998c2ecf20Sopenharmony_ci		turn_off_first_powersequence = true;
6008c2ecf20Sopenharmony_ci	if (INTERFACE_LVDS0 == plvds_chip_info->output_interface)
6018c2ecf20Sopenharmony_ci		turn_off_first_powersequence = true;
6028c2ecf20Sopenharmony_ci	if (INTERFACE_LVDS1 == plvds_chip_info->output_interface)
6038c2ecf20Sopenharmony_ci		turn_off_second_powersequence = true;
6048c2ecf20Sopenharmony_ci	if (turn_off_second_powersequence) {
6058c2ecf20Sopenharmony_ci		/* Use second power sequence control: */
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_ci		/* Turn off power sequence. */
6088c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CRD4, VIACR, 0, BIT1);
6098c2ecf20Sopenharmony_ci
6108c2ecf20Sopenharmony_ci		/* Turn off back light. */
6118c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CRD3, VIACR, 0xC0, BIT6 + BIT7);
6128c2ecf20Sopenharmony_ci	}
6138c2ecf20Sopenharmony_ci	if (turn_off_first_powersequence) {
6148c2ecf20Sopenharmony_ci		/* Use first power sequence control: */
6158c2ecf20Sopenharmony_ci
6168c2ecf20Sopenharmony_ci		/* Turn off power sequence. */
6178c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CR6A, VIACR, 0, BIT3);
6188c2ecf20Sopenharmony_ci
6198c2ecf20Sopenharmony_ci		/* Turn off back light. */
6208c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7);
6218c2ecf20Sopenharmony_ci	}
6228c2ecf20Sopenharmony_ci
6238c2ecf20Sopenharmony_ci	/* Power off LVDS channel. */
6248c2ecf20Sopenharmony_ci	switch (plvds_chip_info->output_interface) {
6258c2ecf20Sopenharmony_ci	case INTERFACE_LVDS0:
6268c2ecf20Sopenharmony_ci		{
6278c2ecf20Sopenharmony_ci			viafb_write_reg_mask(CRD2, VIACR, 0x80, BIT7);
6288c2ecf20Sopenharmony_ci			break;
6298c2ecf20Sopenharmony_ci		}
6308c2ecf20Sopenharmony_ci
6318c2ecf20Sopenharmony_ci	case INTERFACE_LVDS1:
6328c2ecf20Sopenharmony_ci		{
6338c2ecf20Sopenharmony_ci			viafb_write_reg_mask(CRD2, VIACR, 0x40, BIT6);
6348c2ecf20Sopenharmony_ci			break;
6358c2ecf20Sopenharmony_ci		}
6368c2ecf20Sopenharmony_ci
6378c2ecf20Sopenharmony_ci	case INTERFACE_LVDS0LVDS1:
6388c2ecf20Sopenharmony_ci		{
6398c2ecf20Sopenharmony_ci			viafb_write_reg_mask(CRD2, VIACR, 0xC0, BIT6 + BIT7);
6408c2ecf20Sopenharmony_ci			break;
6418c2ecf20Sopenharmony_ci		}
6428c2ecf20Sopenharmony_ci	}
6438c2ecf20Sopenharmony_ci}
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_cistatic void integrated_lvds_enable(struct lvds_setting_information
6468c2ecf20Sopenharmony_ci			    *plvds_setting_info,
6478c2ecf20Sopenharmony_ci			    struct lvds_chip_information *plvds_chip_info)
6488c2ecf20Sopenharmony_ci{
6498c2ecf20Sopenharmony_ci	DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n",
6508c2ecf20Sopenharmony_ci		  plvds_chip_info->output_interface);
6518c2ecf20Sopenharmony_ci	if (plvds_setting_info->lcd_mode == LCD_SPWG)
6528c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT0 + BIT1);
6538c2ecf20Sopenharmony_ci	else
6548c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CRD2, VIACR, 0x03, BIT0 + BIT1);
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_ci	switch (plvds_chip_info->output_interface) {
6578c2ecf20Sopenharmony_ci	case INTERFACE_LVDS0LVDS1:
6588c2ecf20Sopenharmony_ci	case INTERFACE_LVDS0:
6598c2ecf20Sopenharmony_ci		/* Use first power sequence control: */
6608c2ecf20Sopenharmony_ci		/* Use hardware control power sequence. */
6618c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CR91, VIACR, 0, BIT0);
6628c2ecf20Sopenharmony_ci		/* Turn on back light. */
6638c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CR91, VIACR, 0, BIT6 + BIT7);
6648c2ecf20Sopenharmony_ci		/* Turn on hardware power sequence. */
6658c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
6668c2ecf20Sopenharmony_ci		break;
6678c2ecf20Sopenharmony_ci	case INTERFACE_LVDS1:
6688c2ecf20Sopenharmony_ci		/* Use second power sequence control: */
6698c2ecf20Sopenharmony_ci		/* Use hardware control power sequence. */
6708c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CRD3, VIACR, 0, BIT0);
6718c2ecf20Sopenharmony_ci		/* Turn on back light. */
6728c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CRD3, VIACR, 0, BIT6 + BIT7);
6738c2ecf20Sopenharmony_ci		/* Turn on hardware power sequence. */
6748c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CRD4, VIACR, 0x02, BIT1);
6758c2ecf20Sopenharmony_ci		break;
6768c2ecf20Sopenharmony_ci	}
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_ci	/* Power on LVDS channel. */
6798c2ecf20Sopenharmony_ci	switch (plvds_chip_info->output_interface) {
6808c2ecf20Sopenharmony_ci	case INTERFACE_LVDS0:
6818c2ecf20Sopenharmony_ci		{
6828c2ecf20Sopenharmony_ci			viafb_write_reg_mask(CRD2, VIACR, 0, BIT7);
6838c2ecf20Sopenharmony_ci			break;
6848c2ecf20Sopenharmony_ci		}
6858c2ecf20Sopenharmony_ci
6868c2ecf20Sopenharmony_ci	case INTERFACE_LVDS1:
6878c2ecf20Sopenharmony_ci		{
6888c2ecf20Sopenharmony_ci			viafb_write_reg_mask(CRD2, VIACR, 0, BIT6);
6898c2ecf20Sopenharmony_ci			break;
6908c2ecf20Sopenharmony_ci		}
6918c2ecf20Sopenharmony_ci
6928c2ecf20Sopenharmony_ci	case INTERFACE_LVDS0LVDS1:
6938c2ecf20Sopenharmony_ci		{
6948c2ecf20Sopenharmony_ci			viafb_write_reg_mask(CRD2, VIACR, 0, BIT6 + BIT7);
6958c2ecf20Sopenharmony_ci			break;
6968c2ecf20Sopenharmony_ci		}
6978c2ecf20Sopenharmony_ci	}
6988c2ecf20Sopenharmony_ci}
6998c2ecf20Sopenharmony_ci
7008c2ecf20Sopenharmony_civoid viafb_lcd_disable(void)
7018c2ecf20Sopenharmony_ci{
7028c2ecf20Sopenharmony_ci
7038c2ecf20Sopenharmony_ci	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
7048c2ecf20Sopenharmony_ci		lcd_powersequence_off();
7058c2ecf20Sopenharmony_ci		/* DI1 pad off */
7068c2ecf20Sopenharmony_ci		viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
7078c2ecf20Sopenharmony_ci	} else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
7088c2ecf20Sopenharmony_ci		if (viafb_LCD2_ON
7098c2ecf20Sopenharmony_ci		    && (INTEGRATED_LVDS ==
7108c2ecf20Sopenharmony_ci			viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
7118c2ecf20Sopenharmony_ci			integrated_lvds_disable(viaparinfo->lvds_setting_info,
7128c2ecf20Sopenharmony_ci				&viaparinfo->chip_info->lvds_chip_info2);
7138c2ecf20Sopenharmony_ci		if (INTEGRATED_LVDS ==
7148c2ecf20Sopenharmony_ci			viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
7158c2ecf20Sopenharmony_ci			integrated_lvds_disable(viaparinfo->lvds_setting_info,
7168c2ecf20Sopenharmony_ci				&viaparinfo->chip_info->lvds_chip_info);
7178c2ecf20Sopenharmony_ci		if (VT1636_LVDS == viaparinfo->chip_info->
7188c2ecf20Sopenharmony_ci			lvds_chip_info.lvds_chip_name)
7198c2ecf20Sopenharmony_ci			viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
7208c2ecf20Sopenharmony_ci				&viaparinfo->chip_info->lvds_chip_info);
7218c2ecf20Sopenharmony_ci	} else if (VT1636_LVDS ==
7228c2ecf20Sopenharmony_ci	viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
7238c2ecf20Sopenharmony_ci		viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
7248c2ecf20Sopenharmony_ci				    &viaparinfo->chip_info->lvds_chip_info);
7258c2ecf20Sopenharmony_ci	} else {
7268c2ecf20Sopenharmony_ci		/* Backlight off           */
7278c2ecf20Sopenharmony_ci		viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20);
7288c2ecf20Sopenharmony_ci		/* 24 bit DI data paht off */
7298c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80);
7308c2ecf20Sopenharmony_ci	}
7318c2ecf20Sopenharmony_ci
7328c2ecf20Sopenharmony_ci	/* Disable expansion bit   */
7338c2ecf20Sopenharmony_ci	viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01);
7348c2ecf20Sopenharmony_ci	/* Simultaneout disabled   */
7358c2ecf20Sopenharmony_ci	viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
7368c2ecf20Sopenharmony_ci}
7378c2ecf20Sopenharmony_ci
7388c2ecf20Sopenharmony_cistatic void set_lcd_output_path(int set_iga, int output_interface)
7398c2ecf20Sopenharmony_ci{
7408c2ecf20Sopenharmony_ci	switch (output_interface) {
7418c2ecf20Sopenharmony_ci	case INTERFACE_DFP:
7428c2ecf20Sopenharmony_ci		if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)
7438c2ecf20Sopenharmony_ci		    || (UNICHROME_P4M890 ==
7448c2ecf20Sopenharmony_ci		    viaparinfo->chip_info->gfx_chip_name))
7458c2ecf20Sopenharmony_ci			viafb_write_reg_mask(CR97, VIACR, 0x84,
7468c2ecf20Sopenharmony_ci				       BIT7 + BIT2 + BIT1 + BIT0);
7478c2ecf20Sopenharmony_ci		fallthrough;
7488c2ecf20Sopenharmony_ci	case INTERFACE_DVP0:
7498c2ecf20Sopenharmony_ci	case INTERFACE_DVP1:
7508c2ecf20Sopenharmony_ci	case INTERFACE_DFP_HIGH:
7518c2ecf20Sopenharmony_ci	case INTERFACE_DFP_LOW:
7528c2ecf20Sopenharmony_ci		if (set_iga == IGA2)
7538c2ecf20Sopenharmony_ci			viafb_write_reg(CR91, VIACR, 0x00);
7548c2ecf20Sopenharmony_ci		break;
7558c2ecf20Sopenharmony_ci	}
7568c2ecf20Sopenharmony_ci}
7578c2ecf20Sopenharmony_ci
7588c2ecf20Sopenharmony_civoid viafb_lcd_enable(void)
7598c2ecf20Sopenharmony_ci{
7608c2ecf20Sopenharmony_ci	viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
7618c2ecf20Sopenharmony_ci	viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
7628c2ecf20Sopenharmony_ci	set_lcd_output_path(viaparinfo->lvds_setting_info->iga_path,
7638c2ecf20Sopenharmony_ci		viaparinfo->chip_info->lvds_chip_info.output_interface);
7648c2ecf20Sopenharmony_ci	if (viafb_LCD2_ON)
7658c2ecf20Sopenharmony_ci		set_lcd_output_path(viaparinfo->lvds_setting_info2->iga_path,
7668c2ecf20Sopenharmony_ci			viaparinfo->chip_info->
7678c2ecf20Sopenharmony_ci			lvds_chip_info2.output_interface);
7688c2ecf20Sopenharmony_ci
7698c2ecf20Sopenharmony_ci	if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
7708c2ecf20Sopenharmony_ci		/* DI1 pad on */
7718c2ecf20Sopenharmony_ci		viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
7728c2ecf20Sopenharmony_ci		lcd_powersequence_on();
7738c2ecf20Sopenharmony_ci	} else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
7748c2ecf20Sopenharmony_ci		if (viafb_LCD2_ON && (INTEGRATED_LVDS ==
7758c2ecf20Sopenharmony_ci			viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
7768c2ecf20Sopenharmony_ci			integrated_lvds_enable(viaparinfo->lvds_setting_info2, \
7778c2ecf20Sopenharmony_ci				&viaparinfo->chip_info->lvds_chip_info2);
7788c2ecf20Sopenharmony_ci		if (INTEGRATED_LVDS ==
7798c2ecf20Sopenharmony_ci			viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
7808c2ecf20Sopenharmony_ci			integrated_lvds_enable(viaparinfo->lvds_setting_info,
7818c2ecf20Sopenharmony_ci				&viaparinfo->chip_info->lvds_chip_info);
7828c2ecf20Sopenharmony_ci		if (VT1636_LVDS == viaparinfo->chip_info->
7838c2ecf20Sopenharmony_ci			lvds_chip_info.lvds_chip_name)
7848c2ecf20Sopenharmony_ci			viafb_enable_lvds_vt1636(viaparinfo->
7858c2ecf20Sopenharmony_ci			lvds_setting_info, &viaparinfo->chip_info->
7868c2ecf20Sopenharmony_ci			lvds_chip_info);
7878c2ecf20Sopenharmony_ci	} else if (VT1636_LVDS ==
7888c2ecf20Sopenharmony_ci	viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
7898c2ecf20Sopenharmony_ci		viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info,
7908c2ecf20Sopenharmony_ci				   &viaparinfo->chip_info->lvds_chip_info);
7918c2ecf20Sopenharmony_ci	} else {
7928c2ecf20Sopenharmony_ci		/* Backlight on            */
7938c2ecf20Sopenharmony_ci		viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20);
7948c2ecf20Sopenharmony_ci		/* 24 bit DI data paht on  */
7958c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80);
7968c2ecf20Sopenharmony_ci		/* LCD enabled             */
7978c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48);
7988c2ecf20Sopenharmony_ci	}
7998c2ecf20Sopenharmony_ci}
8008c2ecf20Sopenharmony_ci
8018c2ecf20Sopenharmony_cistatic void lcd_powersequence_off(void)
8028c2ecf20Sopenharmony_ci{
8038c2ecf20Sopenharmony_ci	int i, mask, data;
8048c2ecf20Sopenharmony_ci
8058c2ecf20Sopenharmony_ci	/* Software control power sequence */
8068c2ecf20Sopenharmony_ci	viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
8078c2ecf20Sopenharmony_ci
8088c2ecf20Sopenharmony_ci	for (i = 0; i < 3; i++) {
8098c2ecf20Sopenharmony_ci		mask = PowerSequenceOff[0][i];
8108c2ecf20Sopenharmony_ci		data = PowerSequenceOff[1][i] & mask;
8118c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
8128c2ecf20Sopenharmony_ci		udelay(PowerSequenceOff[2][i]);
8138c2ecf20Sopenharmony_ci	}
8148c2ecf20Sopenharmony_ci
8158c2ecf20Sopenharmony_ci	/* Disable LCD */
8168c2ecf20Sopenharmony_ci	viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x08);
8178c2ecf20Sopenharmony_ci}
8188c2ecf20Sopenharmony_ci
8198c2ecf20Sopenharmony_cistatic void lcd_powersequence_on(void)
8208c2ecf20Sopenharmony_ci{
8218c2ecf20Sopenharmony_ci	int i, mask, data;
8228c2ecf20Sopenharmony_ci
8238c2ecf20Sopenharmony_ci	/* Software control power sequence */
8248c2ecf20Sopenharmony_ci	viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
8258c2ecf20Sopenharmony_ci
8268c2ecf20Sopenharmony_ci	/* Enable LCD */
8278c2ecf20Sopenharmony_ci	viafb_write_reg_mask(CR6A, VIACR, 0x08, 0x08);
8288c2ecf20Sopenharmony_ci
8298c2ecf20Sopenharmony_ci	for (i = 0; i < 3; i++) {
8308c2ecf20Sopenharmony_ci		mask = PowerSequenceOn[0][i];
8318c2ecf20Sopenharmony_ci		data = PowerSequenceOn[1][i] & mask;
8328c2ecf20Sopenharmony_ci		viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
8338c2ecf20Sopenharmony_ci		udelay(PowerSequenceOn[2][i]);
8348c2ecf20Sopenharmony_ci	}
8358c2ecf20Sopenharmony_ci
8368c2ecf20Sopenharmony_ci	udelay(1);
8378c2ecf20Sopenharmony_ci}
8388c2ecf20Sopenharmony_ci
8398c2ecf20Sopenharmony_cistatic void fill_lcd_format(void)
8408c2ecf20Sopenharmony_ci{
8418c2ecf20Sopenharmony_ci	u8 bdithering = 0, bdual = 0;
8428c2ecf20Sopenharmony_ci
8438c2ecf20Sopenharmony_ci	if (viaparinfo->lvds_setting_info->device_lcd_dualedge)
8448c2ecf20Sopenharmony_ci		bdual = BIT4;
8458c2ecf20Sopenharmony_ci	if (viaparinfo->lvds_setting_info->LCDDithering)
8468c2ecf20Sopenharmony_ci		bdithering = BIT0;
8478c2ecf20Sopenharmony_ci	/* Dual & Dithering */
8488c2ecf20Sopenharmony_ci	viafb_write_reg_mask(CR88, VIACR, (bdithering | bdual), BIT4 + BIT0);
8498c2ecf20Sopenharmony_ci}
8508c2ecf20Sopenharmony_ci
8518c2ecf20Sopenharmony_cistatic void check_diport_of_integrated_lvds(
8528c2ecf20Sopenharmony_ci	struct lvds_chip_information *plvds_chip_info,
8538c2ecf20Sopenharmony_ci				     struct lvds_setting_information
8548c2ecf20Sopenharmony_ci				     *plvds_setting_info)
8558c2ecf20Sopenharmony_ci{
8568c2ecf20Sopenharmony_ci	/* Determine LCD DI Port by hardware layout. */
8578c2ecf20Sopenharmony_ci	switch (viafb_display_hardware_layout) {
8588c2ecf20Sopenharmony_ci	case HW_LAYOUT_LCD_ONLY:
8598c2ecf20Sopenharmony_ci		{
8608c2ecf20Sopenharmony_ci			if (plvds_setting_info->device_lcd_dualedge) {
8618c2ecf20Sopenharmony_ci				plvds_chip_info->output_interface =
8628c2ecf20Sopenharmony_ci				    INTERFACE_LVDS0LVDS1;
8638c2ecf20Sopenharmony_ci			} else {
8648c2ecf20Sopenharmony_ci				plvds_chip_info->output_interface =
8658c2ecf20Sopenharmony_ci				    INTERFACE_LVDS0;
8668c2ecf20Sopenharmony_ci			}
8678c2ecf20Sopenharmony_ci
8688c2ecf20Sopenharmony_ci			break;
8698c2ecf20Sopenharmony_ci		}
8708c2ecf20Sopenharmony_ci
8718c2ecf20Sopenharmony_ci	case HW_LAYOUT_DVI_ONLY:
8728c2ecf20Sopenharmony_ci		{
8738c2ecf20Sopenharmony_ci			plvds_chip_info->output_interface = INTERFACE_NONE;
8748c2ecf20Sopenharmony_ci			break;
8758c2ecf20Sopenharmony_ci		}
8768c2ecf20Sopenharmony_ci
8778c2ecf20Sopenharmony_ci	case HW_LAYOUT_LCD1_LCD2:
8788c2ecf20Sopenharmony_ci	case HW_LAYOUT_LCD_EXTERNAL_LCD2:
8798c2ecf20Sopenharmony_ci		{
8808c2ecf20Sopenharmony_ci			plvds_chip_info->output_interface =
8818c2ecf20Sopenharmony_ci			    INTERFACE_LVDS0LVDS1;
8828c2ecf20Sopenharmony_ci			break;
8838c2ecf20Sopenharmony_ci		}
8848c2ecf20Sopenharmony_ci
8858c2ecf20Sopenharmony_ci	case HW_LAYOUT_LCD_DVI:
8868c2ecf20Sopenharmony_ci		{
8878c2ecf20Sopenharmony_ci			plvds_chip_info->output_interface = INTERFACE_LVDS1;
8888c2ecf20Sopenharmony_ci			break;
8898c2ecf20Sopenharmony_ci		}
8908c2ecf20Sopenharmony_ci
8918c2ecf20Sopenharmony_ci	default:
8928c2ecf20Sopenharmony_ci		{
8938c2ecf20Sopenharmony_ci			plvds_chip_info->output_interface = INTERFACE_LVDS1;
8948c2ecf20Sopenharmony_ci			break;
8958c2ecf20Sopenharmony_ci		}
8968c2ecf20Sopenharmony_ci	}
8978c2ecf20Sopenharmony_ci
8988c2ecf20Sopenharmony_ci	DEBUG_MSG(KERN_INFO
8998c2ecf20Sopenharmony_ci		  "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n",
9008c2ecf20Sopenharmony_ci		  viafb_display_hardware_layout,
9018c2ecf20Sopenharmony_ci		  plvds_chip_info->output_interface);
9028c2ecf20Sopenharmony_ci}
9038c2ecf20Sopenharmony_ci
9048c2ecf20Sopenharmony_civoid viafb_init_lvds_output_interface(struct lvds_chip_information
9058c2ecf20Sopenharmony_ci				*plvds_chip_info,
9068c2ecf20Sopenharmony_ci				struct lvds_setting_information
9078c2ecf20Sopenharmony_ci				*plvds_setting_info)
9088c2ecf20Sopenharmony_ci{
9098c2ecf20Sopenharmony_ci	if (INTERFACE_NONE != plvds_chip_info->output_interface) {
9108c2ecf20Sopenharmony_ci		/*Do nothing, lcd port is specified by module parameter */
9118c2ecf20Sopenharmony_ci		return;
9128c2ecf20Sopenharmony_ci	}
9138c2ecf20Sopenharmony_ci
9148c2ecf20Sopenharmony_ci	switch (plvds_chip_info->lvds_chip_name) {
9158c2ecf20Sopenharmony_ci
9168c2ecf20Sopenharmony_ci	case VT1636_LVDS:
9178c2ecf20Sopenharmony_ci		switch (viaparinfo->chip_info->gfx_chip_name) {
9188c2ecf20Sopenharmony_ci		case UNICHROME_CX700:
9198c2ecf20Sopenharmony_ci			plvds_chip_info->output_interface = INTERFACE_DVP1;
9208c2ecf20Sopenharmony_ci			break;
9218c2ecf20Sopenharmony_ci		case UNICHROME_CN700:
9228c2ecf20Sopenharmony_ci			plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
9238c2ecf20Sopenharmony_ci			break;
9248c2ecf20Sopenharmony_ci		default:
9258c2ecf20Sopenharmony_ci			plvds_chip_info->output_interface = INTERFACE_DVP0;
9268c2ecf20Sopenharmony_ci			break;
9278c2ecf20Sopenharmony_ci		}
9288c2ecf20Sopenharmony_ci		break;
9298c2ecf20Sopenharmony_ci
9308c2ecf20Sopenharmony_ci	case INTEGRATED_LVDS:
9318c2ecf20Sopenharmony_ci		check_diport_of_integrated_lvds(plvds_chip_info,
9328c2ecf20Sopenharmony_ci						plvds_setting_info);
9338c2ecf20Sopenharmony_ci		break;
9348c2ecf20Sopenharmony_ci
9358c2ecf20Sopenharmony_ci	default:
9368c2ecf20Sopenharmony_ci		switch (viaparinfo->chip_info->gfx_chip_name) {
9378c2ecf20Sopenharmony_ci		case UNICHROME_K8M890:
9388c2ecf20Sopenharmony_ci		case UNICHROME_P4M900:
9398c2ecf20Sopenharmony_ci		case UNICHROME_P4M890:
9408c2ecf20Sopenharmony_ci			plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
9418c2ecf20Sopenharmony_ci			break;
9428c2ecf20Sopenharmony_ci		default:
9438c2ecf20Sopenharmony_ci			plvds_chip_info->output_interface = INTERFACE_DFP;
9448c2ecf20Sopenharmony_ci			break;
9458c2ecf20Sopenharmony_ci		}
9468c2ecf20Sopenharmony_ci		break;
9478c2ecf20Sopenharmony_ci	}
9488c2ecf20Sopenharmony_ci}
9498c2ecf20Sopenharmony_ci
9508c2ecf20Sopenharmony_cibool viafb_lcd_get_mobile_state(bool *mobile)
9518c2ecf20Sopenharmony_ci{
9528c2ecf20Sopenharmony_ci	unsigned char __iomem *romptr, *tableptr, *biosptr;
9538c2ecf20Sopenharmony_ci	u8 core_base;
9548c2ecf20Sopenharmony_ci	/* Rom address */
9558c2ecf20Sopenharmony_ci	const u32 romaddr = 0x000C0000;
9568c2ecf20Sopenharmony_ci	u16 start_pattern;
9578c2ecf20Sopenharmony_ci
9588c2ecf20Sopenharmony_ci	biosptr = ioremap(romaddr, 0x10000);
9598c2ecf20Sopenharmony_ci	start_pattern = readw(biosptr);
9608c2ecf20Sopenharmony_ci
9618c2ecf20Sopenharmony_ci	/* Compare pattern */
9628c2ecf20Sopenharmony_ci	if (start_pattern == 0xAA55) {
9638c2ecf20Sopenharmony_ci		/* Get the start of Table */
9648c2ecf20Sopenharmony_ci		/* 0x1B means BIOS offset position */
9658c2ecf20Sopenharmony_ci		romptr = biosptr + 0x1B;
9668c2ecf20Sopenharmony_ci		tableptr = biosptr + readw(romptr);
9678c2ecf20Sopenharmony_ci
9688c2ecf20Sopenharmony_ci		/* Get the start of biosver structure */
9698c2ecf20Sopenharmony_ci		/* 18 means BIOS version position. */
9708c2ecf20Sopenharmony_ci		romptr = tableptr + 18;
9718c2ecf20Sopenharmony_ci		romptr = biosptr + readw(romptr);
9728c2ecf20Sopenharmony_ci
9738c2ecf20Sopenharmony_ci		/* The offset should be 44, but the
9748c2ecf20Sopenharmony_ci		   actual image is less three char. */
9758c2ecf20Sopenharmony_ci		/* pRom += 44; */
9768c2ecf20Sopenharmony_ci		romptr += 41;
9778c2ecf20Sopenharmony_ci
9788c2ecf20Sopenharmony_ci		core_base = readb(romptr);
9798c2ecf20Sopenharmony_ci
9808c2ecf20Sopenharmony_ci		if (core_base & 0x8)
9818c2ecf20Sopenharmony_ci			*mobile = false;
9828c2ecf20Sopenharmony_ci		else
9838c2ecf20Sopenharmony_ci			*mobile = true;
9848c2ecf20Sopenharmony_ci		/* release memory */
9858c2ecf20Sopenharmony_ci		iounmap(biosptr);
9868c2ecf20Sopenharmony_ci
9878c2ecf20Sopenharmony_ci		return true;
9888c2ecf20Sopenharmony_ci	} else {
9898c2ecf20Sopenharmony_ci		iounmap(biosptr);
9908c2ecf20Sopenharmony_ci		return false;
9918c2ecf20Sopenharmony_ci	}
9928c2ecf20Sopenharmony_ci}
993