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 */ 21ec66841e495b9ab4f92bdf91efe8cf56e1471fbdJonathan Corbet#include <linux/via-core.h> 22ec66841e495b9ab4f92bdf91efe8cf56e1471fbdJonathan Corbet#include <linux/via_i2c.h> 23c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan#include "global.h" 24c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 25c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic void tmds_register_write(int index, u8 data); 26c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int tmds_register_read(int index); 27c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int tmds_register_read_bytes(int index, u8 *buff, int buff_len); 2848c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic void dvi_get_panel_size_from_DDCv1( 29f4ab2f7a21338ae0f59ad925c23545e790cd51e3Florian Tobias Schandinat struct tmds_chip_information *tmds_chip, 30f4ab2f7a21338ae0f59ad925c23545e790cd51e3Florian Tobias Schandinat struct tmds_setting_information *tmds_setting); 31c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int viafb_dvi_query_EDID(void); 32c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 33cd00b1154d3c7d711e83c3c17b831aafe6377532Florian Tobias Schandinatstatic inline bool check_tmds_chip(int device_id_subaddr, int device_id) 34c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 35cd00b1154d3c7d711e83c3c17b831aafe6377532Florian Tobias Schandinat return tmds_register_read(device_id_subaddr) == device_id; 36c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 37c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 3848c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanvoid viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, 3948c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartman struct tmds_setting_information *tmds_setting) 40c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 41c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n"); 42c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 43c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat viafb_dvi_sense(); 44c91faa61697a60ee5cc653db9b6fd3c7049890a6Florian Tobias Schandinat if (viafb_dvi_query_EDID() == 1) 45c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat dvi_get_panel_size_from_DDCv1(tmds_chip, tmds_setting); 46c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat 47c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return; 48c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 49c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 5048c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanbool viafb_tmds_trasmitter_identify(void) 51c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 52c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan unsigned char sr2a = 0, sr1e = 0, sr3e = 0; 53c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 54c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Turn on ouputting pad */ 55c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan switch (viaparinfo->chip_info->gfx_chip_name) { 56c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case UNICHROME_K8M890: 57c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /*=* DFP Low Pad on *=*/ 58c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan sr2a = viafb_read_reg(VIASR, SR2A); 59c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); 60c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 61c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 62c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case UNICHROME_P4M900: 63c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case UNICHROME_P4M890: 64c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* DFP Low Pad on */ 65c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan sr2a = viafb_read_reg(VIASR, SR2A); 66c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); 67c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* DVP0 Pad on */ 68c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan sr1e = viafb_read_reg(VIASR, SR1E); 69c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7); 70c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 71c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 72c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan default: 73c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* DVP0/DVP1 Pad on */ 74c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan sr1e = viafb_read_reg(VIASR, SR1E); 75c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(SR1E, VIASR, 0xF0, BIT4 + 76c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan BIT5 + BIT6 + BIT7); 77c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* SR3E[1]Multi-function selection: 78c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 0 = Emulate I2C and DDC bus by GPIO2/3/4. */ 79c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan sr3e = viafb_read_reg(VIASR, SR3E); 80c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(SR3E, VIASR, 0x0, BIT5); 81c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 82c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 83c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 84c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Check for VT1632: */ 85c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS; 86c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info-> 87c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; 88f045f77bc0bf238a871b10bea9e425329a8e4abcJonathan Corbet viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31; 89cd00b1154d3c7d711e83c3c17b831aafe6377532Florian Tobias Schandinat if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) { 90c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* 91c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan * Currently only support 12bits,dual edge,add 24bits mode later 92c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan */ 93c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_register_write(0x08, 0x3b); 94c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 95c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n"); 96c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n %2d", 97c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info.tmds_chip_name); 98c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n %2d", 99c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info.i2c_port); 100cd00b1154d3c7d711e83c3c17b831aafe6377532Florian Tobias Schandinat return true; 101c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } else { 102f045f77bc0bf238a871b10bea9e425329a8e4abcJonathan Corbet viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_2C; 103cd00b1154d3c7d711e83c3c17b831aafe6377532Florian Tobias Schandinat if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) { 104c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_register_write(0x08, 0x3b); 105c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n"); 106c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n %2d", 107c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info-> 108c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.tmds_chip_name); 109c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n %2d", 110c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info-> 111c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.i2c_port); 112cd00b1154d3c7d711e83c3c17b831aafe6377532Florian Tobias Schandinat return true; 113c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 114c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 115c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 116c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS; 117c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 118c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) && 119c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) || 120c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) { 121c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n"); 122cd00b1154d3c7d711e83c3c17b831aafe6377532Florian Tobias Schandinat return true; 123c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 124c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 125c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan switch (viaparinfo->chip_info->gfx_chip_name) { 126c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case UNICHROME_K8M890: 127c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR2A, VIASR, sr2a); 128c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 129c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 130c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case UNICHROME_P4M900: 131c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case UNICHROME_P4M890: 132c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR2A, VIASR, sr2a); 133c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, sr1e); 134c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 135c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 136c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan default: 137c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, sr1e); 138c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR3E, VIASR, sr3e); 139c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 140c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 141c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 142c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info-> 143c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER; 144c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info. 145c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; 146cd00b1154d3c7d711e83c3c17b831aafe6377532Florian Tobias Schandinat return false; 147c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 148c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 149c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic void tmds_register_write(int index, u8 data) 150c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 151277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.i2c_port, 152277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, 153277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte index, data); 154c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 155c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 156c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int tmds_register_read(int index) 157c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 158c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan u8 data; 159c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 160277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte viafb_i2c_readbyte(viaparinfo->chip_info->tmds_chip_info.i2c_port, 161277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, 162277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte (u8) index, &data); 163c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return data; 164c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 165c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 166c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int tmds_register_read_bytes(int index, u8 *buff, int buff_len) 167c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 168277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte viafb_i2c_readbytes(viaparinfo->chip_info->tmds_chip_info.i2c_port, 169277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, 170277d32a36cba0b42c9c6836ff07f9b978566e95cHarald Welte (u8) index, buff, buff_len); 171c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return 0; 172c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 173c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 174c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan/* DVI Set Mode */ 175532f9169db21fbffd07cc44075c7ea1859c07806Florian Tobias Schandinatvoid viafb_dvi_set_mode(const struct fb_var_screeninfo *var, 176532f9169db21fbffd07cc44075c7ea1859c07806Florian Tobias Schandinat u16 cxres, u16 cyres, int iga) 177c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 178ebb29fb47e198787b8b47a74cb10334cd9647a9dFlorian Tobias Schandinat struct fb_var_screeninfo dvi_var = *var; 1799864ca20c50c2fcaba63767a336e16c88b46d7adFlorian Tobias Schandinat const struct fb_videomode *rb_mode; 180ebb29fb47e198787b8b47a74cb10334cd9647a9dFlorian Tobias Schandinat int maxPixelClock; 181ebb29fb47e198787b8b47a74cb10334cd9647a9dFlorian Tobias Schandinat 182ebb29fb47e198787b8b47a74cb10334cd9647a9dFlorian Tobias Schandinat maxPixelClock = viaparinfo->shared->tmds_setting_info.max_pixel_clock; 183ebb29fb47e198787b8b47a74cb10334cd9647a9dFlorian Tobias Schandinat if (maxPixelClock && PICOS2KHZ(var->pixclock) / 1000 > maxPixelClock) { 184ebb29fb47e198787b8b47a74cb10334cd9647a9dFlorian Tobias Schandinat rb_mode = viafb_get_best_rb_mode(var->xres, var->yres, 60); 18592746c3c82135b13d7fb1bbdebbabb0faedd8433Florian Tobias Schandinat if (rb_mode) 186ebb29fb47e198787b8b47a74cb10334cd9647a9dFlorian Tobias Schandinat viafb_fill_var_timing_info(&dvi_var, rb_mode); 187c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 188ebb29fb47e198787b8b47a74cb10334cd9647a9dFlorian Tobias Schandinat 189532f9169db21fbffd07cc44075c7ea1859c07806Florian Tobias Schandinat viafb_fill_crtc_timing(&dvi_var, cxres, cyres, iga); 190c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 191c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 192c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan/* Sense DVI Connector */ 193c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanint viafb_dvi_sense(void) 194c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 195c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0, 196c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegCR93 = 0, RegCR9B = 0, data; 197c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan int ret = false; 198c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 199c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n"); 200c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 201c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { 202c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* DI1 Pad on */ 203c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegSR1E = viafb_read_reg(VIASR, SR1E); 204c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30); 205c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 206c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* CR6B[0]VCK Input Selection: 1 = External clock. */ 207c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegCR6B = viafb_read_reg(VIACR, CR6B); 208c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08); 209c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 210c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off 211c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan [0] Software Control Power Sequence */ 212c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegCR91 = viafb_read_reg(VIACR, CR91); 213c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR91, VIACR, 0x1D); 214c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 215c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* CR93[7] DI1 Data Source Selection: 1 = DSP2. 216c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan CR93[5] DI1 Clock Source: 1 = internal. 217c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan CR93[4] DI1 Clock Polarity. 218c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */ 219c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegCR93 = viafb_read_reg(VIACR, CR93); 220c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR93, VIACR, 0x01); 221c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } else { 222c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* DVP0/DVP1 Pad on */ 223c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegSR1E = viafb_read_reg(VIASR, SR1E); 224c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0); 225c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 226c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* SR3E[1]Multi-function selection: 227c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 0 = Emulate I2C and DDC bus by GPIO2/3/4. */ 228c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegSR3E = viafb_read_reg(VIASR, SR3E); 229c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20)); 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 /*CR9B[4] DVP1 Data Source Selection: 1 = From secondary 237c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan display.CR9B[2:0] DVP1 Clock Adjust */ 238c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan RegCR9B = viafb_read_reg(VIACR, CR9B); 239c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR9B, VIACR, 0x01); 240c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 241c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 242c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan data = (u8) tmds_register_read(0x09); 243c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (data & 0x04) 244c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan ret = true; 245c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 246c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (ret == false) { 247c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viafb_dvi_query_EDID()) 248c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan ret = true; 249c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 250c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 251c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Restore status */ 252c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR1E, VIASR, RegSR1E); 253c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR91, VIACR, RegCR91); 254c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { 255c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR6B, VIACR, RegCR6B); 256c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR93, VIACR, RegCR93); 257c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } else { 258c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(SR3E, VIASR, RegSR3E); 259c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CR9B, VIACR, RegCR9B); 260c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 261c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 262c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return ret; 263c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 264c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 265c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan/* Query Flat Panel's EDID Table Version Through DVI Connector */ 266c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanstatic int viafb_dvi_query_EDID(void) 267c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 268c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan u8 data0, data1; 269c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan int restore; 270c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 271c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n"); 272c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 273c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr; 274c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0; 275c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 276c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan data0 = (u8) tmds_register_read(0x00); 277c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan data1 = (u8) tmds_register_read(0x01); 278c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if ((data0 == 0) && (data1 == 0xFF)) { 279c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viaparinfo->chip_info-> 280c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.tmds_chip_slave_addr = restore; 281c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan return EDID_VERSION_1; /* Found EDID1 Table */ 282c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 283c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 284c91faa61697a60ee5cc653db9b6fd3c7049890a6Florian Tobias Schandinat return false; 285c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 286c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 287c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat/* Get Panel Size Using EDID1 Table */ 28848c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic void dvi_get_panel_size_from_DDCv1( 289f4ab2f7a21338ae0f59ad925c23545e790cd51e3Florian Tobias Schandinat struct tmds_chip_information *tmds_chip, 290f4ab2f7a21338ae0f59ad925c23545e790cd51e3Florian Tobias Schandinat struct tmds_setting_information *tmds_setting) 291c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 292c91faa61697a60ee5cc653db9b6fd3c7049890a6Florian Tobias Schandinat int i, restore; 293c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan unsigned char EDID_DATA[18]; 294c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 295c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n"); 296c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 297c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat restore = tmds_chip->tmds_chip_slave_addr; 298c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_chip->tmds_chip_slave_addr = 0xA0; 299c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan for (i = 0x25; i < 0x6D; i++) { 300c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan switch (i) { 301c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x36: 302c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x48: 303c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x5A: 304c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan case 0x6C: 305c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_register_read_bytes(i, EDID_DATA, 10); 306c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (!(EDID_DATA[0] || EDID_DATA[1])) { 307c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* The first two byte must be zero. */ 308c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (EDID_DATA[3] == 0xFD) { 309c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* To get max pixel clock. */ 310c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_pixel_clock = 311c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat EDID_DATA[9] * 10; 312c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 313c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 314c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 315c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 316c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan default: 317c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan break; 318c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 319c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 320c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 321c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n", 322c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_setting->max_pixel_clock); 323c5f06f5cddd6681b978ffdb53755e28eefccb1bbFlorian Tobias Schandinat tmds_chip->tmds_chip_slave_addr = restore; 324c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 325c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 326c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan/* If Disable DVI, turn off pad */ 327c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanvoid viafb_dvi_disable(void) 328c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 329c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info-> 330c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_chip_info.output_interface == INTERFACE_TMDS) 331c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Turn off TMDS power. */ 332c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg(CRD2, VIACR, 333c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_read_reg(VIACR, CRD2) | 0x08); 334c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan} 335c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 336cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinatstatic void dvi_patch_skew_dvp0(void) 337cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat{ 338cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat /* Reset data driving first: */ 339cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(SR1B, VIASR, 0, BIT1); 340cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(SR2A, VIASR, 0, BIT4); 341cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat 342cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat switch (viaparinfo->chip_info->gfx_chip_name) { 343cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat case UNICHROME_P4M890: 344cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat { 345cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat if ((viaparinfo->tmds_setting_info->h_active == 1600) && 346cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat (viaparinfo->tmds_setting_info->v_active == 347cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat 1200)) 348cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(CR96, VIACR, 0x03, 349cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat BIT0 + BIT1 + BIT2); 350cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat else 351cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(CR96, VIACR, 0x07, 352cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat BIT0 + BIT1 + BIT2); 353cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 354cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat } 355cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat 356cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat case UNICHROME_P4M900: 357cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat { 358cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(CR96, VIACR, 0x07, 359cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat BIT0 + BIT1 + BIT2 + BIT3); 360cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1); 361cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4); 362cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 363cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat } 364cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat 365cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat default: 366cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat { 367cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 368cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat } 369cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat } 370cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat} 371cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat 372cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinatstatic void dvi_patch_skew_dvp_low(void) 373cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat{ 374cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat switch (viaparinfo->chip_info->gfx_chip_name) { 375cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat case UNICHROME_K8M890: 376cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat { 377cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1); 378cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 379cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat } 380cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat 381cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat case UNICHROME_P4M900: 382cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat { 383cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(CR99, VIACR, 0x08, 384cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat BIT0 + BIT1 + BIT2 + BIT3); 385cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 386cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat } 387cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat 388cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat case UNICHROME_P4M890: 389cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat { 390cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(CR99, VIACR, 0x0F, 391cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat BIT0 + BIT1 + BIT2 + BIT3); 392cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 393cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat } 394cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat 395cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat default: 396cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat { 397cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 398cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat } 399cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat } 400cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat} 401cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat 402c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan/* If Enable DVI, turn off pad */ 403c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chanvoid viafb_dvi_enable(void) 404c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan{ 405c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan u8 data; 406c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 407cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat switch (viaparinfo->chip_info->tmds_chip_info.output_interface) { 408cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat case INTERFACE_DVP0: 409cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0); 410cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + BIT5); 411cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat dvi_patch_skew_dvp0(); 412c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) 413c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_register_write(0x88, 0x3b); 414c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan else 415c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /*clear CR91[5] to direct on display period 416c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan in the secondary diplay path */ 417cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); 418cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 419c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 420cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat case INTERFACE_DVP1: 421cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) 422cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(CR93, VIACR, 0x21, BIT0 + BIT5); 423c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 424c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */ 425cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) 426c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan tmds_register_write(0x88, 0x3b); 427cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat else 428c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /*clear CR91[5] to direct on display period 429c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan in the secondary diplay path */ 430cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); 431c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 432c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /*fix DVI cannot enable on EPIA-M board */ 433c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viafb_platform_epia_dvi == 1) { 434c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f); 435c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0); 436c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viafb_bus_width == 24) { 437c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan if (viafb_device_lcd_dualedge == 1) 438c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan data = 0x3F; 439c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan else 440c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan data = 0x37; 441c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_i2c_writebyte(viaparinfo->chip_info-> 442cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat tmds_chip_info.i2c_port, 443cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viaparinfo->chip_info-> 444cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat tmds_chip_info.tmds_chip_slave_addr, 445cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat 0x08, data); 446c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 447c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 448cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 449c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 450cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat case INTERFACE_DFP_HIGH: 451cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) 452cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat via_write_reg_mask(VIACR, CR97, 0x03, 0x03); 453c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 454cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); 455cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 456cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat 457cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat case INTERFACE_DFP_LOW: 458cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) 459cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 4606f9422d4e407bd63a9bd665ea09e57c1e3800c47Florian Tobias Schandinat 461cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat dvi_patch_skew_dvp_low(); 462cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); 463cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 464cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat 465cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat case INTERFACE_TMDS: 466c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Turn on Display period in the panel path. */ 467c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(CR91, VIACR, 0, BIT7); 468c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 469c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan /* Turn on TMDS power. */ 470c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan viafb_write_reg_mask(CRD2, VIACR, 0, BIT3); 471cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat break; 472c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan } 473c09c782f3e7d38e1f3842822209bb6faff4a2b1bJoseph Chan 474cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat if (viaparinfo->tmds_setting_info->iga_path == IGA2) { 475cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat /* Disable LCD Scaling */ 476cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0); 477cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat } 478cd7e9103e983ff0f518ac0e85cee265027ccbfa4Florian Tobias Schandinat} 479