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