2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 static void tmds_register_write(int index, u8 data);
24 static int tmds_register_read(int index);
25 static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
26 static void dvi_get_panel_size_from_DDCv1(void);
27 static void dvi_get_panel_size_from_DDCv2(void);
28 static void dvi_get_panel_info(void);
29 static int viafb_dvi_query_EDID(void);
31 static int check_tmds_chip(int device_id_subaddr, int device_id)
33 if (tmds_register_read(device_id_subaddr) == device_id)
39 void viafb_init_dvi_size(void)
41 DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
43 "viaparinfo->tmds_setting_info->get_dvi_size_method %d\n",
44 viaparinfo->tmds_setting_info->get_dvi_size_method);
46 switch (viaparinfo->tmds_setting_info->get_dvi_size_method) {
47 case GET_DVI_SIZE_BY_SYSTEM_BIOS:
49 case GET_DVI_SZIE_BY_HW_STRAPPING:
51 case GET_DVI_SIZE_BY_VGA_BIOS:
59 int viafb_tmds_trasmitter_identify(void)
61 unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
63 /* Turn on ouputting pad */
64 switch (viaparinfo->chip_info->gfx_chip_name) {
65 case UNICHROME_K8M890:
66 /*=* DFP Low Pad on *=*/
67 sr2a = viafb_read_reg(VIASR, SR2A);
68 viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
71 case UNICHROME_P4M900:
72 case UNICHROME_P4M890:
74 sr2a = viafb_read_reg(VIASR, SR2A);
75 viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
77 sr1e = viafb_read_reg(VIASR, SR1E);
78 viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7);
82 /* DVP0/DVP1 Pad on */
83 sr1e = viafb_read_reg(VIASR, SR1E);
84 viafb_write_reg_mask(SR1E, VIASR, 0xF0, BIT4 +
86 /* SR3E[1]Multi-function selection:
87 0 = Emulate I2C and DDC bus by GPIO2/3/4. */
88 sr3e = viafb_read_reg(VIASR, SR3E);
89 viafb_write_reg_mask(SR3E, VIASR, 0x0, BIT5);
93 /* Check for VT1632: */
94 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
95 viaparinfo->chip_info->
96 tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
97 viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX;
98 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) {
100 * Currently only support 12bits,dual edge,add 24bits mode later
102 tmds_register_write(0x08, 0x3b);
104 DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
105 DEBUG_MSG(KERN_INFO "\n %2d",
106 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
107 DEBUG_MSG(KERN_INFO "\n %2d",
108 viaparinfo->chip_info->tmds_chip_info.i2c_port);
111 viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX;
112 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)
114 tmds_register_write(0x08, 0x3b);
115 DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
116 DEBUG_MSG(KERN_INFO "\n %2d",
117 viaparinfo->chip_info->
118 tmds_chip_info.tmds_chip_name);
119 DEBUG_MSG(KERN_INFO "\n %2d",
120 viaparinfo->chip_info->
121 tmds_chip_info.i2c_port);
126 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS;
128 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) &&
129 ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) ||
130 (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) {
131 DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n");
135 switch (viaparinfo->chip_info->gfx_chip_name) {
136 case UNICHROME_K8M890:
137 viafb_write_reg(SR2A, VIASR, sr2a);
140 case UNICHROME_P4M900:
141 case UNICHROME_P4M890:
142 viafb_write_reg(SR2A, VIASR, sr2a);
143 viafb_write_reg(SR1E, VIASR, sr1e);
147 viafb_write_reg(SR1E, VIASR, sr1e);
148 viafb_write_reg(SR3E, VIASR, sr3e);
152 viaparinfo->chip_info->
153 tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
154 viaparinfo->chip_info->tmds_chip_info.
155 tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
159 static void tmds_register_write(int index, u8 data)
161 viaparinfo->shared->i2c_stuff.i2c_port =
162 viaparinfo->chip_info->tmds_chip_info.i2c_port;
164 viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.
165 tmds_chip_slave_addr, index,
169 static int tmds_register_read(int index)
173 viaparinfo->shared->i2c_stuff.i2c_port =
174 viaparinfo->chip_info->tmds_chip_info.i2c_port;
175 viafb_i2c_readbyte((u8) viaparinfo->chip_info->
176 tmds_chip_info.tmds_chip_slave_addr,
181 static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
183 viaparinfo->shared->i2c_stuff.i2c_port =
184 viaparinfo->chip_info->tmds_chip_info.i2c_port;
185 viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info.
186 tmds_chip_slave_addr, (u8) index, buff, buff_len);
191 void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp,
194 struct VideoModeTable *rb_mode;
195 struct crt_mode_table *pDviTiming;
196 unsigned long desirePixelClock, maxPixelClock;
197 pDviTiming = mode->crtc;
198 desirePixelClock = pDviTiming->clk / 1000000;
199 maxPixelClock = (unsigned long)viaparinfo->
200 tmds_setting_info->max_pixel_clock;
202 DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
204 if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
205 rb_mode = viafb_get_rb_mode(mode->crtc[0].crtc.hor_addr,
206 mode->crtc[0].crtc.ver_addr);
209 pDviTiming = rb_mode->crtc;
212 viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga);
213 viafb_set_output_path(DEVICE_DVI, set_iga,
214 viaparinfo->chip_info->tmds_chip_info.output_interface);
217 /* Sense DVI Connector */
218 int viafb_dvi_sense(void)
220 u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0,
221 RegCR93 = 0, RegCR9B = 0, data;
224 DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n");
226 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
228 RegSR1E = viafb_read_reg(VIASR, SR1E);
229 viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30);
231 /* CR6B[0]VCK Input Selection: 1 = External clock. */
232 RegCR6B = viafb_read_reg(VIACR, CR6B);
233 viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08);
235 /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
236 [0] Software Control Power Sequence */
237 RegCR91 = viafb_read_reg(VIACR, CR91);
238 viafb_write_reg(CR91, VIACR, 0x1D);
240 /* CR93[7] DI1 Data Source Selection: 1 = DSP2.
241 CR93[5] DI1 Clock Source: 1 = internal.
242 CR93[4] DI1 Clock Polarity.
243 CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */
244 RegCR93 = viafb_read_reg(VIACR, CR93);
245 viafb_write_reg(CR93, VIACR, 0x01);
247 /* DVP0/DVP1 Pad on */
248 RegSR1E = viafb_read_reg(VIASR, SR1E);
249 viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0);
251 /* SR3E[1]Multi-function selection:
252 0 = Emulate I2C and DDC bus by GPIO2/3/4. */
253 RegSR3E = viafb_read_reg(VIASR, SR3E);
254 viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20));
256 /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
257 [0] Software Control Power Sequence */
258 RegCR91 = viafb_read_reg(VIACR, CR91);
259 viafb_write_reg(CR91, VIACR, 0x1D);
261 /*CR9B[4] DVP1 Data Source Selection: 1 = From secondary
262 display.CR9B[2:0] DVP1 Clock Adjust */
263 RegCR9B = viafb_read_reg(VIACR, CR9B);
264 viafb_write_reg(CR9B, VIACR, 0x01);
267 data = (u8) tmds_register_read(0x09);
272 if (viafb_dvi_query_EDID())
277 viafb_write_reg(SR1E, VIASR, RegSR1E);
278 viafb_write_reg(CR91, VIACR, RegCR91);
279 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
280 viafb_write_reg(CR6B, VIACR, RegCR6B);
281 viafb_write_reg(CR93, VIACR, RegCR93);
283 viafb_write_reg(SR3E, VIASR, RegSR3E);
284 viafb_write_reg(CR9B, VIACR, RegCR9B);
290 /* Query Flat Panel's EDID Table Version Through DVI Connector */
291 static int viafb_dvi_query_EDID(void)
296 DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n");
298 restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
299 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
301 data0 = (u8) tmds_register_read(0x00);
302 data1 = (u8) tmds_register_read(0x01);
303 if ((data0 == 0) && (data1 == 0xFF)) {
304 viaparinfo->chip_info->
305 tmds_chip_info.tmds_chip_slave_addr = restore;
306 return EDID_VERSION_1; /* Found EDID1 Table */
309 data0 = (u8) tmds_register_read(0x00);
310 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
312 return EDID_VERSION_2; /* Found EDID2 Table */
317 /* void dvi_get_panel_size_from_DDCv1(void)
319 * - Get Panel Size Using EDID1 Table
321 static void dvi_get_panel_size_from_DDCv1(void)
323 int i, max_h = 0, tmp, restore;
325 unsigned char EDID_DATA[18];
327 DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
329 restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
330 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
332 rData = tmds_register_read(0x23);
340 rData = tmds_register_read(0x24);
348 for (i = 0x25; i < 0x6D; i++) {
358 rData = tmds_register_read(i);
361 /* data = (data + 31) * 8 */
362 tmp = (rData + 31) << 3;
371 tmds_register_read_bytes(i, EDID_DATA, 10);
372 if (!(EDID_DATA[0] || EDID_DATA[1])) {
373 /* The first two byte must be zero. */
374 if (EDID_DATA[3] == 0xFD) {
375 /* To get max pixel clock. */
376 viaparinfo->tmds_setting_info->
377 max_pixel_clock = EDID_DATA[9] * 10;
406 DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d !\
407 set default panel size.\n", max_h);
411 DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
412 viaparinfo->tmds_setting_info->max_pixel_clock);
413 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
416 /* void dvi_get_panel_size_from_DDCv2(void)
418 * - Get Panel Size Using EDID2 Table
420 static void dvi_get_panel_size_from_DDCv2(void)
422 int HSize = 0, restore;
423 unsigned char R_Buffer[2];
425 DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
427 restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
428 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
430 /* Horizontal: 0x76, 0x77 */
431 tmds_register_read_bytes(0x76, R_Buffer, 2);
433 HSize += R_Buffer[1] << 8;
451 DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d!\
452 set default panel size.\n", HSize);
456 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
459 /* unsigned char dvi_get_panel_info(void)
463 static void dvi_get_panel_info(void)
465 DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
468 switch (viafb_dvi_query_EDID()) {
470 dvi_get_panel_size_from_DDCv1();
473 dvi_get_panel_size_from_DDCv2();
480 /* If Disable DVI, turn off pad */
481 void viafb_dvi_disable(void)
483 if (viaparinfo->chip_info->
484 tmds_chip_info.output_interface == INTERFACE_DVP0)
485 viafb_write_reg(SR1E, VIASR,
486 viafb_read_reg(VIASR, SR1E) & (~0xC0));
488 if (viaparinfo->chip_info->
489 tmds_chip_info.output_interface == INTERFACE_DVP1)
490 viafb_write_reg(SR1E, VIASR,
491 viafb_read_reg(VIASR, SR1E) & (~0x30));
493 if (viaparinfo->chip_info->
494 tmds_chip_info.output_interface == INTERFACE_DFP_HIGH)
495 viafb_write_reg(SR2A, VIASR,
496 viafb_read_reg(VIASR, SR2A) & (~0x0C));
498 if (viaparinfo->chip_info->
499 tmds_chip_info.output_interface == INTERFACE_DFP_LOW)
500 viafb_write_reg(SR2A, VIASR,
501 viafb_read_reg(VIASR, SR2A) & (~0x03));
503 if (viaparinfo->chip_info->
504 tmds_chip_info.output_interface == INTERFACE_TMDS)
505 /* Turn off TMDS power. */
506 viafb_write_reg(CRD2, VIACR,
507 viafb_read_reg(VIACR, CRD2) | 0x08);
510 /* If Enable DVI, turn off pad */
511 void viafb_dvi_enable(void)
515 if (viaparinfo->chip_info->
516 tmds_chip_info.output_interface == INTERFACE_DVP0) {
517 viafb_write_reg(SR1E, VIASR,
518 viafb_read_reg(VIASR, SR1E) | 0xC0);
519 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
520 tmds_register_write(0x88, 0x3b);
522 /*clear CR91[5] to direct on display period
523 in the secondary diplay path */
524 viafb_write_reg(CR91, VIACR,
525 viafb_read_reg(VIACR, CR91) & 0xDF);
528 if (viaparinfo->chip_info->
529 tmds_chip_info.output_interface == INTERFACE_DVP1) {
530 viafb_write_reg(SR1E, VIASR,
531 viafb_read_reg(VIASR, SR1E) | 0x30);
533 /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
534 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
535 tmds_register_write(0x88, 0x3b);
537 /*clear CR91[5] to direct on display period
538 in the secondary diplay path */
539 viafb_write_reg(CR91, VIACR,
540 viafb_read_reg(VIACR, CR91) & 0xDF);
543 /*fix DVI cannot enable on EPIA-M board */
544 if (viafb_platform_epia_dvi == 1) {
545 viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f);
546 viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0);
547 if (viafb_bus_width == 24) {
548 if (viafb_device_lcd_dualedge == 1)
552 viafb_i2c_writebyte(viaparinfo->chip_info->
554 tmds_chip_slave_addr,
560 if (viaparinfo->chip_info->
561 tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) {
562 viafb_write_reg(SR2A, VIASR,
563 viafb_read_reg(VIASR, SR2A) | 0x0C);
564 viafb_write_reg(CR91, VIACR,
565 viafb_read_reg(VIACR, CR91) & 0xDF);
568 if (viaparinfo->chip_info->
569 tmds_chip_info.output_interface == INTERFACE_DFP_LOW) {
570 viafb_write_reg(SR2A, VIASR,
571 viafb_read_reg(VIASR, SR2A) | 0x03);
572 viafb_write_reg(CR91, VIACR,
573 viafb_read_reg(VIACR, CR91) & 0xDF);
575 if (viaparinfo->chip_info->
576 tmds_chip_info.output_interface == INTERFACE_TMDS) {
577 /* Turn on Display period in the panel path. */
578 viafb_write_reg_mask(CR91, VIACR, 0, BIT7);
580 /* Turn on TMDS power. */
581 viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);