📄 lcd.c
字号:
/* * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE.See the GNU General Public License * for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "global.h"#include "lcdtbl.h"struct iga2_shadow_crtc_timing iga2_shadow_crtc_reg = { /* IGA2 Shadow Horizontal Total */ {IGA2_SHADOW_HOR_TOTAL_REG_NUM, {{CR6D, 0, 7}, {CR71, 3, 3} } }, /* IGA2 Shadow Horizontal Blank End */ {IGA2_SHADOW_HOR_BLANK_END_REG_NUM, {{CR6E, 0, 7} } }, /* IGA2 Shadow Vertical Total */ {IGA2_SHADOW_VER_TOTAL_REG_NUM, {{CR6F, 0, 7}, {CR71, 0, 2} } }, /* IGA2 Shadow Vertical Addressable Video */ {IGA2_SHADOW_VER_ADDR_REG_NUM, {{CR70, 0, 7}, {CR71, 4, 6} } }, /* IGA2 Shadow Vertical Blank Start */ {IGA2_SHADOW_VER_BLANK_START_REG_NUM, {{CR72, 0, 7}, {CR74, 4, 6} } }, /* IGA2 Shadow Vertical Blank End */ {IGA2_SHADOW_VER_BLANK_END_REG_NUM, {{CR73, 0, 7}, {CR74, 0, 2} } }, /* IGA2 Shadow Vertical Sync Start */ {IGA2_SHADOW_VER_SYNC_START_REG_NUM, {{CR75, 0, 7}, {CR76, 4, 6} } }, /* IGA2 Shadow Vertical Sync End */ {IGA2_SHADOW_VER_SYNC_END_REG_NUM, {{CR76, 0, 3} } }};struct _lcd_scaling_factor lcd_scaling_factor = { /* LCD Horizontal Scaling Factor Register */ {LCD_HOR_SCALING_FACTOR_REG_NUM, {{CR9F, 0, 1}, {CR77, 0, 7}, {CR79, 4, 5} } }, /* LCD Vertical Scaling Factor Register */ {LCD_VER_SCALING_FACTOR_REG_NUM, {{CR79, 3, 3}, {CR78, 0, 7}, {CR79, 6, 7} } }};struct _lcd_scaling_factor lcd_scaling_factor_CLE = { /* LCD Horizontal Scaling Factor Register */ {LCD_HOR_SCALING_FACTOR_REG_NUM_CLE, {{CR77, 0, 7}, {CR79, 4, 5} } }, /* LCD Vertical Scaling Factor Register */ {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } }};static int check_lvds_chip(int device_id_subaddr, int device_id);static bool lvds_identify_integratedlvds(void);static int fp_id_to_vindex(int panel_id);static int lvds_register_read(int index);static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, int panel_vres);static void load_lcd_k400_patch_tbl(int set_hres, int set_vres, int panel_id);static void load_lcd_p880_patch_tbl(int set_hres, int set_vres, int panel_id);static void load_lcd_patch_regs(int set_hres, int set_vres, int panel_id, int set_iga);static void via_pitch_alignment_patch_lcd( struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);static void lcd_patch_skew_dvp0(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);static void lcd_patch_skew_dvp1(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);static void lcd_patch_skew(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);static void integrated_lvds_disable(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);static void integrated_lvds_enable(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);static void lcd_powersequence_off(void);static void lcd_powersequence_on(void);static void fill_lcd_format(void);static void check_diport_of_integrated_lvds( struct lvds_chip_information *plvds_chip_info, struct lvds_setting_information *plvds_setting_info);static struct display_timing lcd_centering_timging(struct display_timing mode_crt_reg, struct display_timing panel_crt_reg);static void load_crtc_shadow_timing(struct display_timing mode_timing, struct display_timing panel_timing);static void viafb_load_scaling_factor_for_p4m900(int set_hres, int set_vres, int panel_hres, int panel_vres);static int check_lvds_chip(int device_id_subaddr, int device_id){ if (lvds_register_read(device_id_subaddr) == device_id) return (OK); else return (FAIL);}void viafb_init_lcd_size(void){ DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n"); DEBUG_MSG(KERN_INFO "viaparinfo->lvds_setting_info->get_lcd_size_method %d\n", viaparinfo->lvds_setting_info->get_lcd_size_method); switch (viaparinfo->lvds_setting_info->get_lcd_size_method) { case GET_LCD_SIZE_BY_SYSTEM_BIOS: break; case GET_LCD_SZIE_BY_HW_STRAPPING: break; case GET_LCD_SIZE_BY_VGA_BIOS: DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n"); viaparinfo->lvds_setting_info->lcd_panel_size = fp_id_to_vindex(viafb_lcd_panel_id); DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n", viaparinfo->lvds_setting_info->lcd_panel_id); DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n", viaparinfo->lvds_setting_info->lcd_panel_size); break; case GET_LCD_SIZE_BY_USER_SETTING: DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n"); viaparinfo->lvds_setting_info->lcd_panel_size = fp_id_to_vindex(viafb_lcd_panel_id); DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n", viaparinfo->lvds_setting_info->lcd_panel_id); DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n", viaparinfo->lvds_setting_info->lcd_panel_size); break; default: DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n"); viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID1_800X600; viaparinfo->lvds_setting_info->lcd_panel_size = fp_id_to_vindex(LCD_PANEL_ID1_800X600); } viaparinfo->lvds_setting_info2->lcd_panel_id = viaparinfo->lvds_setting_info->lcd_panel_id; viaparinfo->lvds_setting_info2->lcd_panel_size = viaparinfo->lvds_setting_info->lcd_panel_size; viaparinfo->lvds_setting_info2->lcd_panel_hres = viaparinfo->lvds_setting_info->lcd_panel_hres; viaparinfo->lvds_setting_info2->lcd_panel_vres = viaparinfo->lvds_setting_info->lcd_panel_vres; viaparinfo->lvds_setting_info2->device_lcd_dualedge = viaparinfo->lvds_setting_info->device_lcd_dualedge; viaparinfo->lvds_setting_info2->LCDDithering = viaparinfo->lvds_setting_info->LCDDithering;}static bool lvds_identify_integratedlvds(void){ if (viafb_display_hardware_layout == HW_LAYOUT_LCD_EXTERNAL_LCD2) { /* Two dual channel LCD (Internal LVDS + External LVDS): */ /* If we have an external LVDS, such as VT1636, we should have its chip ID already. */ if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name = INTEGRATED_LVDS; DEBUG_MSG(KERN_INFO "Support two dual channel LVDS!\ (Internal LVDS + External LVDS)\n"); } else { viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = INTEGRATED_LVDS; DEBUG_MSG(KERN_INFO "Not found external LVDS,\ so can't support two dual channel LVDS!\n"); } } else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) { /* Two single channel LCD (Internal LVDS + Internal LVDS): */ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = INTEGRATED_LVDS; viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name = INTEGRATED_LVDS; DEBUG_MSG(KERN_INFO "Support two single channel LVDS!\ (Internal LVDS + Internal LVDS)\n"); } else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) { /* If we have found external LVDS, just use it, otherwise, we will use internal LVDS as default. */ if (!viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = INTEGRATED_LVDS; DEBUG_MSG(KERN_INFO "Found Integrated LVDS!\n"); } } else { viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = NON_LVDS_TRANSMITTER; DEBUG_MSG(KERN_INFO "Do not support LVDS!\n"); return FALSE; } return TRUE;}int viafb_lvds_trasmitter_identify(void){ u8 tmp; tmp = viaparinfo->chip_info->chip_on_slot; viaparinfo->chip_info->chip_on_slot = PORT_ON_AMR; if (viafb_lvds_identify_vt1636()) { viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX; DEBUG_MSG(KERN_INFO "Found VIA VT1636 LVDS on port i2c 0x31 \n"); } else { viaparinfo->chip_info->chip_on_slot = PORT_ON_AGP; if (viafb_lvds_identify_vt1636()) { viaparinfo->chip_info->lvds_chip_info.i2c_port = GPIOPORTINDEX; DEBUG_MSG(KERN_INFO "Found VIA VT1636 LVDS on port gpio 0x2c \n"); } } viaparinfo->chip_info->chip_on_slot = tmp; if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) lvds_identify_integratedlvds(); if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) return TRUE; /* Check for VT1631: */ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = VT1631_LVDS; viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = VT1631_LVDS_I2C_ADDR; if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID) != FAIL) { DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n"); DEBUG_MSG(KERN_INFO "\n %2d", viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); DEBUG_MSG(KERN_INFO "\n %2d", viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); return (OK); } viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = NON_LVDS_TRANSMITTER; viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = VT1631_LVDS_I2C_ADDR; return (FAIL);}static int fp_id_to_vindex(int panel_id){ DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n"); if (panel_id > LCD_PANEL_ID_MAXIMUM) viafb_lcd_panel_id = panel_id = viafb_read_reg(VIACR, CR3F) & 0x0F; switch (panel_id) { case 0x0: viaparinfo->lvds_setting_info->lcd_panel_hres = 640; viaparinfo->lvds_setting_info->lcd_panel_vres = 480; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID0_640X480; viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_640X480); break; case 0x1: viaparinfo->lvds_setting_info->lcd_panel_hres = 800; viaparinfo->lvds_setting_info->lcd_panel_vres = 600; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID1_800X600; viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_800X600); break; case 0x2: viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; viaparinfo->lvds_setting_info->lcd_panel_vres = 768; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID2_1024X768; viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_1024X768); break; case 0x3: viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; viaparinfo->lvds_setting_info->lcd_panel_vres = 768; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID3_1280X768; viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_1280X768); break; case 0x4: viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID4_1280X1024; viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_1280X1024); break; case 0x5: viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID5_1400X1050; viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_1400X1050); break; case 0x6: viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID6_1600X1200; viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_1600X1200); break; case 0x8: viaparinfo->lvds_setting_info->lcd_panel_hres = 800; viaparinfo->lvds_setting_info->lcd_panel_vres = 480; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_IDA_800X480; viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_800X480); break; case 0x9: viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; viaparinfo->lvds_setting_info->lcd_panel_vres = 768; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID2_1024X768; viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_1024X768); break; case 0xA: viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; viaparinfo->lvds_setting_info->lcd_panel_vres = 768; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID2_1024X768; viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 0; return (VIA_RES_1024X768); break; case 0xB: viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; viaparinfo->lvds_setting_info->lcd_panel_vres = 768; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID2_1024X768; viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; viaparinfo->lvds_setting_info->LCDDithering = 0; return (VIA_RES_1024X768); break; case 0xC: viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; viaparinfo->lvds_setting_info->lcd_panel_vres = 768; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID3_1280X768; viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 0; return (VIA_RES_1280X768); break; case 0xD: viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; viaparinfo->lvds_setting_info->lcd_panel_vres = 1024; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID4_1280X1024; viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; viaparinfo->lvds_setting_info->LCDDithering = 0; return (VIA_RES_1280X1024); break; case 0xE: viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; viaparinfo->lvds_setting_info->lcd_panel_vres = 1050; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID5_1400X1050; viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; viaparinfo->lvds_setting_info->LCDDithering = 0; return (VIA_RES_1400X1050); break; case 0xF: viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; viaparinfo->lvds_setting_info->lcd_panel_vres = 1200; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID6_1600X1200; viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; viaparinfo->lvds_setting_info->LCDDithering = 0; return (VIA_RES_1600X1200); break; case 0x10: viaparinfo->lvds_setting_info->lcd_panel_hres = 1366; viaparinfo->lvds_setting_info->lcd_panel_vres = 768; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID7_1366X768; viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 0; return (VIA_RES_1368X768); break; case 0x11: viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; viaparinfo->lvds_setting_info->lcd_panel_vres = 600; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID8_1024X600; viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_1024X600); break; case 0x12: viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; viaparinfo->lvds_setting_info->lcd_panel_vres = 768; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID3_1280X768; viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_1280X768); break; case 0x13: viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; viaparinfo->lvds_setting_info->lcd_panel_vres = 800; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID9_1280X800; viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_1280X800); break; case 0x14: viaparinfo->lvds_setting_info->lcd_panel_hres = 1360; viaparinfo->lvds_setting_info->lcd_panel_vres = 768; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_IDB_1360X768; viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 0; return (VIA_RES_1360X768); break; case 0x15: viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; viaparinfo->lvds_setting_info->lcd_panel_vres = 768; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_ID3_1280X768; viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; viaparinfo->lvds_setting_info->LCDDithering = 0; return (VIA_RES_1280X768); break; case 0x16: viaparinfo->lvds_setting_info->lcd_panel_hres = 480; viaparinfo->lvds_setting_info->lcd_panel_vres = 640; viaparinfo->lvds_setting_info->lcd_panel_id = LCD_PANEL_IDC_480X640; viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 1; return (VIA_RES_480X640);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -