[go: nahoru, domu]

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