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 88c2ecf20Sopenharmony_ci#include <linux/via-core.h> 98c2ecf20Sopenharmony_ci#include <linux/via_i2c.h> 108c2ecf20Sopenharmony_ci#include "global.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cistatic const struct IODATA common_init_data[] = { 138c2ecf20Sopenharmony_ci/* Index, Mask, Value */ 148c2ecf20Sopenharmony_ci /* Set panel power sequence timing */ 158c2ecf20Sopenharmony_ci {0x10, 0xC0, 0x00}, 168c2ecf20Sopenharmony_ci /* T1: VDD on - Data on. Each increment is 1 ms. (50ms = 031h) */ 178c2ecf20Sopenharmony_ci {0x0B, 0xFF, 0x40}, 188c2ecf20Sopenharmony_ci /* T2: Data on - Backlight on. Each increment is 2 ms. (210ms = 068h) */ 198c2ecf20Sopenharmony_ci {0x0C, 0xFF, 0x31}, 208c2ecf20Sopenharmony_ci /* T3: Backlight off -Data off. Each increment is 2 ms. (210ms = 068h)*/ 218c2ecf20Sopenharmony_ci {0x0D, 0xFF, 0x31}, 228c2ecf20Sopenharmony_ci /* T4: Data off - VDD off. Each increment is 1 ms. (50ms = 031h) */ 238c2ecf20Sopenharmony_ci {0x0E, 0xFF, 0x68}, 248c2ecf20Sopenharmony_ci /* T5: VDD off - VDD on. Each increment is 100 ms. (500ms = 04h) */ 258c2ecf20Sopenharmony_ci {0x0F, 0xFF, 0x68}, 268c2ecf20Sopenharmony_ci /* LVDS output power up */ 278c2ecf20Sopenharmony_ci {0x09, 0xA0, 0xA0}, 288c2ecf20Sopenharmony_ci /* turn on back light */ 298c2ecf20Sopenharmony_ci {0x10, 0x33, 0x13} 308c2ecf20Sopenharmony_ci}; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* Index, Mask, Value */ 338c2ecf20Sopenharmony_cistatic const struct IODATA dual_channel_enable_data = {0x08, 0xF0, 0xE0}; 348c2ecf20Sopenharmony_cistatic const struct IODATA single_channel_enable_data = {0x08, 0xF0, 0x00}; 358c2ecf20Sopenharmony_cistatic const struct IODATA dithering_enable_data = {0x0A, 0x70, 0x50}; 368c2ecf20Sopenharmony_cistatic const struct IODATA dithering_disable_data = {0x0A, 0x70, 0x00}; 378c2ecf20Sopenharmony_cistatic const struct IODATA vdd_on_data = {0x10, 0x20, 0x20}; 388c2ecf20Sopenharmony_cistatic const struct IODATA vdd_off_data = {0x10, 0x20, 0x00}; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ciu8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information 418c2ecf20Sopenharmony_ci *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, 428c2ecf20Sopenharmony_ci u8 index) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci u8 data; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci viafb_i2c_readbyte(plvds_chip_info->i2c_port, 478c2ecf20Sopenharmony_ci plvds_chip_info->lvds_chip_slave_addr, index, &data); 488c2ecf20Sopenharmony_ci return data; 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_civoid viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information 528c2ecf20Sopenharmony_ci *plvds_setting_info, struct lvds_chip_information 538c2ecf20Sopenharmony_ci *plvds_chip_info, struct IODATA io_data) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci int index, data; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci index = io_data.Index; 588c2ecf20Sopenharmony_ci data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info, 598c2ecf20Sopenharmony_ci index); 608c2ecf20Sopenharmony_ci data = (data & (~io_data.Mask)) | io_data.Data; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci viafb_i2c_writebyte(plvds_chip_info->i2c_port, 638c2ecf20Sopenharmony_ci plvds_chip_info->lvds_chip_slave_addr, index, data); 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_civoid viafb_init_lvds_vt1636(struct lvds_setting_information 678c2ecf20Sopenharmony_ci *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci int reg_num, i; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci /* Common settings: */ 728c2ecf20Sopenharmony_ci reg_num = ARRAY_SIZE(common_init_data); 738c2ecf20Sopenharmony_ci for (i = 0; i < reg_num; i++) 748c2ecf20Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, 758c2ecf20Sopenharmony_ci plvds_chip_info, common_init_data[i]); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci /* Input Data Mode Select */ 788c2ecf20Sopenharmony_ci if (plvds_setting_info->device_lcd_dualedge) 798c2ecf20Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, 808c2ecf20Sopenharmony_ci plvds_chip_info, dual_channel_enable_data); 818c2ecf20Sopenharmony_ci else 828c2ecf20Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, 838c2ecf20Sopenharmony_ci plvds_chip_info, single_channel_enable_data); 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci if (plvds_setting_info->LCDDithering) 868c2ecf20Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, 878c2ecf20Sopenharmony_ci plvds_chip_info, dithering_enable_data); 888c2ecf20Sopenharmony_ci else 898c2ecf20Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, 908c2ecf20Sopenharmony_ci plvds_chip_info, dithering_disable_data); 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_civoid viafb_enable_lvds_vt1636(struct lvds_setting_information 948c2ecf20Sopenharmony_ci *plvds_setting_info, 958c2ecf20Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, 988c2ecf20Sopenharmony_ci vdd_on_data); 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_civoid viafb_disable_lvds_vt1636(struct lvds_setting_information 1028c2ecf20Sopenharmony_ci *plvds_setting_info, 1038c2ecf20Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 1048c2ecf20Sopenharmony_ci{ 1058c2ecf20Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, 1068c2ecf20Sopenharmony_ci vdd_off_data); 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cibool viafb_lvds_identify_vt1636(u8 i2c_adapter) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci u8 Buffer[2]; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n"); 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci /* Sense VT1636 LVDS Transmiter */ 1168c2ecf20Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = 1178c2ecf20Sopenharmony_ci VT1636_LVDS_I2C_ADDR; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci /* Check vendor ID first: */ 1208c2ecf20Sopenharmony_ci if (viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 1218c2ecf20Sopenharmony_ci 0x00, &Buffer[0])) 1228c2ecf20Sopenharmony_ci return false; 1238c2ecf20Sopenharmony_ci viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x01, &Buffer[1]); 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11))) 1268c2ecf20Sopenharmony_ci return false; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci /* Check Chip ID: */ 1298c2ecf20Sopenharmony_ci viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x02, &Buffer[0]); 1308c2ecf20Sopenharmony_ci viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x03, &Buffer[1]); 1318c2ecf20Sopenharmony_ci if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) { 1328c2ecf20Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 1338c2ecf20Sopenharmony_ci VT1636_LVDS; 1348c2ecf20Sopenharmony_ci return true; 1358c2ecf20Sopenharmony_ci } 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci return false; 1388c2ecf20Sopenharmony_ci} 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cistatic int get_clk_range_index(u32 Clk) 1418c2ecf20Sopenharmony_ci{ 1428c2ecf20Sopenharmony_ci if (Clk < DPA_CLK_30M) 1438c2ecf20Sopenharmony_ci return DPA_CLK_RANGE_30M; 1448c2ecf20Sopenharmony_ci else if (Clk < DPA_CLK_50M) 1458c2ecf20Sopenharmony_ci return DPA_CLK_RANGE_30_50M; 1468c2ecf20Sopenharmony_ci else if (Clk < DPA_CLK_70M) 1478c2ecf20Sopenharmony_ci return DPA_CLK_RANGE_50_70M; 1488c2ecf20Sopenharmony_ci else if (Clk < DPA_CLK_100M) 1498c2ecf20Sopenharmony_ci return DPA_CLK_RANGE_70_100M; 1508c2ecf20Sopenharmony_ci else if (Clk < DPA_CLK_150M) 1518c2ecf20Sopenharmony_ci return DPA_CLK_RANGE_100_150M; 1528c2ecf20Sopenharmony_ci else 1538c2ecf20Sopenharmony_ci return DPA_CLK_RANGE_150M; 1548c2ecf20Sopenharmony_ci} 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistatic void set_dpa_vt1636(struct lvds_setting_information 1578c2ecf20Sopenharmony_ci *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, 1588c2ecf20Sopenharmony_ci struct VT1636_DPA_SETTING *p_vt1636_dpa_setting) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci struct IODATA io_data; 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci io_data.Index = 0x09; 1638c2ecf20Sopenharmony_ci io_data.Mask = 0x1F; 1648c2ecf20Sopenharmony_ci io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1; 1658c2ecf20Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, 1668c2ecf20Sopenharmony_ci plvds_chip_info, io_data); 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci io_data.Index = 0x08; 1698c2ecf20Sopenharmony_ci io_data.Mask = 0x0F; 1708c2ecf20Sopenharmony_ci io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2; 1718c2ecf20Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, 1728c2ecf20Sopenharmony_ci io_data); 1738c2ecf20Sopenharmony_ci} 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_civoid viafb_vt1636_patch_skew_on_vt3324( 1768c2ecf20Sopenharmony_ci struct lvds_setting_information *plvds_setting_info, 1778c2ecf20Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci struct VT1636_DPA_SETTING dpa = {0x00, 0x00}, dpa_16x12 = {0x0B, 0x03}, 1808c2ecf20Sopenharmony_ci *pdpa; 1818c2ecf20Sopenharmony_ci int index; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n"); 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci /* Graphics DPA settings: */ 1868c2ecf20Sopenharmony_ci index = get_clk_range_index(plvds_setting_info->vclk); 1878c2ecf20Sopenharmony_ci viafb_set_dpa_gfx(plvds_chip_info->output_interface, 1888c2ecf20Sopenharmony_ci &GFX_DPA_SETTING_TBL_VT3324[index]); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci /* LVDS Transmitter DPA settings: */ 1918c2ecf20Sopenharmony_ci if (plvds_setting_info->lcd_panel_hres == 1600 && 1928c2ecf20Sopenharmony_ci plvds_setting_info->lcd_panel_vres == 1200) 1938c2ecf20Sopenharmony_ci pdpa = &dpa_16x12; 1948c2ecf20Sopenharmony_ci else 1958c2ecf20Sopenharmony_ci pdpa = &dpa; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci set_dpa_vt1636(plvds_setting_info, plvds_chip_info, pdpa); 1988c2ecf20Sopenharmony_ci} 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_civoid viafb_vt1636_patch_skew_on_vt3327( 2018c2ecf20Sopenharmony_ci struct lvds_setting_information *plvds_setting_info, 2028c2ecf20Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci struct VT1636_DPA_SETTING dpa = {0x00, 0x00}; 2058c2ecf20Sopenharmony_ci int index; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n"); 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci /* Graphics DPA settings: */ 2108c2ecf20Sopenharmony_ci index = get_clk_range_index(plvds_setting_info->vclk); 2118c2ecf20Sopenharmony_ci viafb_set_dpa_gfx(plvds_chip_info->output_interface, 2128c2ecf20Sopenharmony_ci &GFX_DPA_SETTING_TBL_VT3327[index]); 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci /* LVDS Transmitter DPA settings: */ 2158c2ecf20Sopenharmony_ci set_dpa_vt1636(plvds_setting_info, plvds_chip_info, &dpa); 2168c2ecf20Sopenharmony_ci} 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_civoid viafb_vt1636_patch_skew_on_vt3364( 2198c2ecf20Sopenharmony_ci struct lvds_setting_information *plvds_setting_info, 2208c2ecf20Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 2218c2ecf20Sopenharmony_ci{ 2228c2ecf20Sopenharmony_ci int index; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n"); 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci /* Graphics DPA settings: */ 2278c2ecf20Sopenharmony_ci index = get_clk_range_index(plvds_setting_info->vclk); 2288c2ecf20Sopenharmony_ci viafb_set_dpa_gfx(plvds_chip_info->output_interface, 2298c2ecf20Sopenharmony_ci &GFX_DPA_SETTING_TBL_VT3364[index]); 2308c2ecf20Sopenharmony_ci} 231