dvi.c revision 277d32a36cba0b42c9c6836ff07f9b978566e95c
1c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan/* 2c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 3c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 4c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 5c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * This program is free software; you can redistribute it and/or 6c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * modify it under the terms of the GNU General Public 7c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * License as published by the Free Software Foundation; 8c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * either version 2, or (at your option) any later version. 9c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 10c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * This program is distributed in the hope that it will be useful, 11c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even 12c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * the implied warranty of MERCHANTABILITY or FITNESS FOR 13c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * A PARTICULAR PURPOSE.See the GNU General Public License 14c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * for more details. 15c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 16c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * You should have received a copy of the GNU General Public License 17c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * along with this program; if not, write to the Free Software 18c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * Foundation, Inc., 19c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan */ 21c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan#include "global.h" 22c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 23c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic void tmds_register_write(int index, u8 data); 24c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int tmds_register_read(int index); 25c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int tmds_register_read_bytes(int index, u8 *buff, int buff_len); 26c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinatstatic void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information 27c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat *tmds_chip, struct tmds_setting_information *tmds_setting); 28c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinatstatic void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information 29c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat *tmds_chip, struct tmds_setting_information *tmds_setting); 30c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int viafb_dvi_query_EDID(void); 31c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 32c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int check_tmds_chip(int device_id_subaddr, int device_id) 33c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 34c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (tmds_register_read(device_id_subaddr) == device_id) 35c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return OK; 36c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan else 37c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return FAIL; 38c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 39c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 40c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinatvoid viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, 41c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat struct tmds_setting_information *tmds_setting) 42c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 43c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n"); 44c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 45c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat viafb_dvi_sense(); 46c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat switch (viafb_dvi_query_EDID()) { 47c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat case 1: 48c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat dvi_get_panel_size_from_DDCv1(tmds_chip, tmds_setting); 49c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 50c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat case 2: 51c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat dvi_get_panel_size_from_DDCv2(tmds_chip, tmds_setting); 52c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 53c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan default: 54c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat printk(KERN_WARNING "viafb_init_dvi_size: DVI panel size undetected!\n"); 55c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 56c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 57c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat 58c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return; 59c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 60c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 61c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanint viafb_tmds_trasmitter_identify(void) 62c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 63c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan unsigned char sr2a = 0, sr1e = 0, sr3e = 0; 64c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 65c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Turn on ouputting pad */ 66c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan switch (viaparinfo->chip_info->gfx_chip_name) { 67c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case UNICHROME_K8M890: 68c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /*=* DFP Low Pad on *=*/ 69c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan sr2a = viafb_read_reg(VIASR, SR2A); 70c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); 71c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 72c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 73c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case UNICHROME_P4M900: 74c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case UNICHROME_P4M890: 75c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* DFP Low Pad on */ 76c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan sr2a = viafb_read_reg(VIASR, SR2A); 77c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); 78c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* DVP0 Pad on */ 79c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan sr1e = viafb_read_reg(VIASR, SR1E); 80c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7); 81c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 82c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 83c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan default: 84c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* DVP0/DVP1 Pad on */ 85c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan sr1e = viafb_read_reg(VIASR, SR1E); 86c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(SR1E, VIASR, 0xF0, BIT4 + 87c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan BIT5 + BIT6 + BIT7); 88c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* SR3E[1]Multi-function selection: 89c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 0 = Emulate I2C and DDC bus by GPIO2/3/4. */ 90c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan sr3e = viafb_read_reg(VIASR, SR3E); 91c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(SR3E, VIASR, 0x0, BIT5); 92c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 93c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 94c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 95c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Check for VT1632: */ 96c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS; 97c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info-> 98c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; 99277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_31; 100c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { 101c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* 102c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * Currently only support 12bits,dual edge,add 24bits mode later 103c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan */ 104c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_register_write(0x08, 0x3b); 105c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 106c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n"); 107c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n %2d", 108c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info.tmds_chip_name); 109c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n %2d", 110c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info.i2c_port); 111c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return OK; 112c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } else { 113277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_2C; 114c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) 115c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan != FAIL) { 116c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_register_write(0x08, 0x3b); 117c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n"); 118c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n %2d", 119c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info-> 120c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.tmds_chip_name); 121c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n %2d", 122c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info-> 123c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.i2c_port); 124c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return OK; 125c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 126c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 127c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 128c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS; 129c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 130c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) && 131c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) || 132c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) { 133c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n"); 134c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return OK; 135c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 136c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 137c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan switch (viaparinfo->chip_info->gfx_chip_name) { 138c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case UNICHROME_K8M890: 139c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR2A, VIASR, sr2a); 140c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 141c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 142c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case UNICHROME_P4M900: 143c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case UNICHROME_P4M890: 144c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR2A, VIASR, sr2a); 145c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, sr1e); 146c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 147c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 148c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan default: 149c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, sr1e); 150c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR3E, VIASR, sr3e); 151c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 152c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 153c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 154c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info-> 155c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER; 156c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info. 157c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; 158c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return FAIL; 159c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 160c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 161c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic void tmds_register_write(int index, u8 data) 162c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 163277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.i2c_port, 164277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, 165277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte index, data); 166c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 167c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 168c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int tmds_register_read(int index) 169c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 170c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan u8 data; 171c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 172277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte viafb_i2c_readbyte(viaparinfo->chip_info->tmds_chip_info.i2c_port, 173277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, 174277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte (u8) index, &data); 175c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return data; 176c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 177c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 178c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int tmds_register_read_bytes(int index, u8 *buff, int buff_len) 179c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 180277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte viafb_i2c_readbytes(viaparinfo->chip_info->tmds_chip_info.i2c_port, 181277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, 182277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte (u8) index, buff, buff_len); 183c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return 0; 184c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 185c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 186c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan/* DVI Set Mode */ 187dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinatvoid viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp, 188dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat int set_iga) 189c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 190dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat struct VideoModeTable *rb_mode; 191c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan struct crt_mode_table *pDviTiming; 192c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan unsigned long desirePixelClock, maxPixelClock; 193dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat pDviTiming = mode->crtc; 194c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan desirePixelClock = pDviTiming->clk / 1000000; 195c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan maxPixelClock = (unsigned long)viaparinfo-> 196c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_setting_info->max_pixel_clock; 197c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 198c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n"); 199c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 200c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) { 201dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat rb_mode = viafb_get_rb_mode(mode->crtc[0].crtc.hor_addr, 202dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat mode->crtc[0].crtc.ver_addr); 203dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat if (rb_mode) { 204dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat mode = rb_mode; 205dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat pDviTiming = rb_mode->crtc; 206c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 207c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 208dd73d6868b9ecb4841def0c6ff0a25da27db33baFlorian Tobias Schandinat viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga); 209c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_set_output_path(DEVICE_DVI, set_iga, 210c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info.output_interface); 211c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 212c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 213c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan/* Sense DVI Connector */ 214c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanint viafb_dvi_sense(void) 215c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 216c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0, 217c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegCR93 = 0, RegCR9B = 0, data; 218c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan int ret = false; 219c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 220c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n"); 221c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 222c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { 223c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* DI1 Pad on */ 224c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegSR1E = viafb_read_reg(VIASR, SR1E); 225c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30); 226c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 227c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* CR6B[0]VCK Input Selection: 1 = External clock. */ 228c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegCR6B = viafb_read_reg(VIACR, CR6B); 229c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08); 230c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 231c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off 232c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan [0] Software Control Power Sequence */ 233c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegCR91 = viafb_read_reg(VIACR, CR91); 234c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR91, VIACR, 0x1D); 235c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 236c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* CR93[7] DI1 Data Source Selection: 1 = DSP2. 237c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan CR93[5] DI1 Clock Source: 1 = internal. 238c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan CR93[4] DI1 Clock Polarity. 239c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */ 240c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegCR93 = viafb_read_reg(VIACR, CR93); 241c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR93, VIACR, 0x01); 242c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } else { 243c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* DVP0/DVP1 Pad on */ 244c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegSR1E = viafb_read_reg(VIASR, SR1E); 245c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0); 246c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 247c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* SR3E[1]Multi-function selection: 248c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 0 = Emulate I2C and DDC bus by GPIO2/3/4. */ 249c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegSR3E = viafb_read_reg(VIASR, SR3E); 250c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20)); 251c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 252c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off 253c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan [0] Software Control Power Sequence */ 254c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegCR91 = viafb_read_reg(VIACR, CR91); 255c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR91, VIACR, 0x1D); 256c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 257c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /*CR9B[4] DVP1 Data Source Selection: 1 = From secondary 258c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan display.CR9B[2:0] DVP1 Clock Adjust */ 259c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegCR9B = viafb_read_reg(VIACR, CR9B); 260c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR9B, VIACR, 0x01); 261c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 262c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 263c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan data = (u8) tmds_register_read(0x09); 264c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (data & 0x04) 265c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan ret = true; 266c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 267c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (ret == false) { 268c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viafb_dvi_query_EDID()) 269c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan ret = true; 270c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 271c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 272c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Restore status */ 273c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, RegSR1E); 274c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR91, VIACR, RegCR91); 275c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { 276c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR6B, VIACR, RegCR6B); 277c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR93, VIACR, RegCR93); 278c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } else { 279c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR3E, VIASR, RegSR3E); 280c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR9B, VIACR, RegCR9B); 281c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 282c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 283c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return ret; 284c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 285c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 286c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan/* Query Flat Panel's EDID Table Version Through DVI Connector */ 287c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int viafb_dvi_query_EDID(void) 288c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 289c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan u8 data0, data1; 290c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan int restore; 291c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 292c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n"); 293c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 294c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr; 295c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0; 296c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 297c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan data0 = (u8) tmds_register_read(0x00); 298c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan data1 = (u8) tmds_register_read(0x01); 299c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if ((data0 == 0) && (data1 == 0xFF)) { 300c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info-> 301c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.tmds_chip_slave_addr = restore; 302c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return EDID_VERSION_1; /* Found EDID1 Table */ 303c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 304c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 305c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan data0 = (u8) tmds_register_read(0x00); 306c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore; 307c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (data0 == 0x20) 308c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return EDID_VERSION_2; /* Found EDID2 Table */ 309c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan else 310c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return false; 311c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 312c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 313c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat/* Get Panel Size Using EDID1 Table */ 314c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinatstatic void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information 315c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat *tmds_chip, struct tmds_setting_information *tmds_setting) 316c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 3179b24b00c364bb3bfa717ba2ead258a527b20cc5fFlorian Tobias Schandinat int i, max_h = 0, tmp, restore; 318c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan unsigned char rData; 319c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan unsigned char EDID_DATA[18]; 320c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 321c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n"); 322c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 323c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat restore = tmds_chip->tmds_chip_slave_addr; 324c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_chip->tmds_chip_slave_addr = 0xA0; 325c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 326c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan rData = tmds_register_read(0x23); 327c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (rData & 0x3C) 328c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan max_h = 640; 329c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (rData & 0xC0) 330c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan max_h = 720; 331c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (rData & 0x03) 332c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan max_h = 800; 333c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 334c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan rData = tmds_register_read(0x24); 335c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (rData & 0xC0) 336c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan max_h = 800; 337c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (rData & 0x1E) 338c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan max_h = 1024; 339c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (rData & 0x01) 340c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan max_h = 1280; 341c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 342c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan for (i = 0x25; i < 0x6D; i++) { 343c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan switch (i) { 344c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x26: 345c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x28: 346c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x2A: 347c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x2C: 348c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x2E: 349c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x30: 350c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x32: 351c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x34: 352c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan rData = tmds_register_read(i); 353c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (rData == 1) 354c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 355c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* data = (data + 31) * 8 */ 356c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmp = (rData + 31) << 3; 357c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (tmp > max_h) 358c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan max_h = tmp; 359c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 360c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 361c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x36: 362c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x48: 363c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x5A: 364c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x6C: 365c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_register_read_bytes(i, EDID_DATA, 10); 366c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (!(EDID_DATA[0] || EDID_DATA[1])) { 367c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* The first two byte must be zero. */ 368c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (EDID_DATA[3] == 0xFD) { 369c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* To get max pixel clock. */ 370c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_pixel_clock = 371c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat EDID_DATA[9] * 10; 372c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 373c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 374c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 375c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 376c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan default: 377c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 378c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 379c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 380c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 381c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_hres = max_h; 382c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan switch (max_h) { 383c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 640: 384c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 480; 385c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 386c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 800: 387c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 600; 388c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 389c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 1024: 390c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 768; 391c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 392c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 1280: 393c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 1024; 394c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 395c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 1400: 396c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 1050; 397c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 398c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 1440: 399c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 1050; 400c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 401c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 1600: 402c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 1200; 403c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 404c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 1920: 405c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 1080; 406c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 407c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan default: 4082c0e0c88422033c9b6162bf7875aecdd095130b7Joe Perches DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d ! " 4092c0e0c88422033c9b6162bf7875aecdd095130b7Joe Perches "set default panel size.\n", max_h); 410c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 411c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 412c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 413c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n", 414c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_pixel_clock); 415c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_chip->tmds_chip_slave_addr = restore; 416c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 417c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 418c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat/* Get Panel Size Using EDID2 Table */ 419c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinatstatic void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information 420c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat *tmds_chip, struct tmds_setting_information *tmds_setting) 421c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 422c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat int restore; 423c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan unsigned char R_Buffer[2]; 424c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 425c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n"); 426c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 427c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat restore = tmds_chip->tmds_chip_slave_addr; 428c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_chip->tmds_chip_slave_addr = 0xA2; 429c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 430c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Horizontal: 0x76, 0x77 */ 431c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_register_read_bytes(0x76, R_Buffer, 2); 432c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_hres = R_Buffer[0] + (R_Buffer[1] << 8); 433c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 434c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat switch (tmds_setting->max_hres) { 435c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 640: 436c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 480; 437c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 438c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 800: 439c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 600; 440c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 441c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 1024: 442c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 768; 443c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 444c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 1280: 445c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 1024; 446c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 447c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 1400: 448c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 1050; 449c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 450c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 1440: 451c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 1050; 452c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 453c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 1600: 454c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_vres = 1200; 455c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 456c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan default: 4572c0e0c88422033c9b6162bf7875aecdd095130b7Joe Perches DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d! " 4582c0e0c88422033c9b6162bf7875aecdd095130b7Joe Perches "set default panel size.\n", tmds_setting->max_hres); 459c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 460c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 461c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 462c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_chip->tmds_chip_slave_addr = restore; 463c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 464c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 465c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan/* If Disable DVI, turn off pad */ 466c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanvoid viafb_dvi_disable(void) 467c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 468c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info-> 469c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.output_interface == INTERFACE_DVP0) 470c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, 471c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIASR, SR1E) & (~0xC0)); 472c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 473c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info-> 474c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.output_interface == INTERFACE_DVP1) 475c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, 476c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIASR, SR1E) & (~0x30)); 477c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 478c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info-> 479c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) 480c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR2A, VIASR, 481c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIASR, SR2A) & (~0x0C)); 482c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 483c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info-> 484c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.output_interface == INTERFACE_DFP_LOW) 485c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR2A, VIASR, 486c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIASR, SR2A) & (~0x03)); 487c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 488c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info-> 489c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.output_interface == INTERFACE_TMDS) 490c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Turn off TMDS power. */ 491c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CRD2, VIACR, 492c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIACR, CRD2) | 0x08); 493c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 494c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 495c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan/* If Enable DVI, turn off pad */ 496c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanvoid viafb_dvi_enable(void) 497c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 498c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan u8 data; 499c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 500c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info-> 501c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.output_interface == INTERFACE_DVP0) { 502c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, 503c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIASR, SR1E) | 0xC0); 504c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) 505c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_register_write(0x88, 0x3b); 506c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan else 507c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /*clear CR91[5] to direct on display period 508c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan in the secondary diplay path */ 509c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR91, VIACR, 510c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIACR, CR91) & 0xDF); 511c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 512c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 513c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info-> 514c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.output_interface == INTERFACE_DVP1) { 515c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, 516c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIASR, SR1E) | 0x30); 517c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 518c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */ 519c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { 520c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_register_write(0x88, 0x3b); 521c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } else { 522c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /*clear CR91[5] to direct on display period 523c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan in the secondary diplay path */ 524c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR91, VIACR, 525c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIACR, CR91) & 0xDF); 526c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 527c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 528c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /*fix DVI cannot enable on EPIA-M board */ 529c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viafb_platform_epia_dvi == 1) { 530c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f); 531c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0); 532c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viafb_bus_width == 24) { 533c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viafb_device_lcd_dualedge == 1) 534c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan data = 0x3F; 535c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan else 536c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan data = 0x37; 537c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_i2c_writebyte(viaparinfo->chip_info-> 538277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte tmds_chip_info.i2c_port, 539277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte viaparinfo->chip_info-> 540277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte tmds_chip_info.tmds_chip_slave_addr, 541277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte 0x08, data); 542c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 543c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 544c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 545c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 546c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info-> 547c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) { 548c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR2A, VIASR, 549c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIASR, SR2A) | 0x0C); 550c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR91, VIACR, 551c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIACR, CR91) & 0xDF); 552c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 553c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 554c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info-> 555c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.output_interface == INTERFACE_DFP_LOW) { 556c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR2A, VIASR, 557c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIASR, SR2A) | 0x03); 558c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR91, VIACR, 559c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIACR, CR91) & 0xDF); 560c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 561c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info-> 562c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.output_interface == INTERFACE_TMDS) { 563c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Turn on Display period in the panel path. */ 564c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(CR91, VIACR, 0, BIT7); 565c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 566c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Turn on TMDS power. */ 567c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(CRD2, VIACR, 0, BIT3); 568c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 569c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 570c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 571