[go: nahoru, domu]

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