blob: 9cb261ce6e355bdfe4e2ee8bc5421c2752f3f634 [file] [log] [blame]
Joseph Chanc09c7822008-10-15 22:03:23 -07001/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
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.
9
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
14 * for more details.
15
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
18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21#include "global.h"
22
23static void tmds_register_write(int index, u8 data);
24static int tmds_register_read(int index);
25static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
Florian Tobias Schandinat9b24b002010-03-10 15:21:29 -080026static void dvi_get_panel_size_from_DDCv1(void);
27static void dvi_get_panel_size_from_DDCv2(void);
28static void dvi_get_panel_info(void);
Joseph Chanc09c7822008-10-15 22:03:23 -070029static int viafb_dvi_query_EDID(void);
30
31static int check_tmds_chip(int device_id_subaddr, int device_id)
32{
33 if (tmds_register_read(device_id_subaddr) == device_id)
34 return OK;
35 else
36 return FAIL;
37}
38
39void viafb_init_dvi_size(void)
40{
41 DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
42 DEBUG_MSG(KERN_INFO
43 "viaparinfo->tmds_setting_info->get_dvi_size_method %d\n",
44 viaparinfo->tmds_setting_info->get_dvi_size_method);
45
46 switch (viaparinfo->tmds_setting_info->get_dvi_size_method) {
47 case GET_DVI_SIZE_BY_SYSTEM_BIOS:
48 break;
49 case GET_DVI_SZIE_BY_HW_STRAPPING:
50 break;
51 case GET_DVI_SIZE_BY_VGA_BIOS:
52 default:
53 dvi_get_panel_info();
54 break;
55 }
56 return;
57}
58
59int viafb_tmds_trasmitter_identify(void)
60{
61 unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
62
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);
69 break;
70
71 case UNICHROME_P4M900:
72 case UNICHROME_P4M890:
73 /* DFP Low Pad on */
74 sr2a = viafb_read_reg(VIASR, SR2A);
75 viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
76 /* DVP0 Pad on */
77 sr1e = viafb_read_reg(VIASR, SR1E);
78 viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7);
79 break;
80
81 default:
82 /* DVP0/DVP1 Pad on */
83 sr1e = viafb_read_reg(VIASR, SR1E);
84 viafb_write_reg_mask(SR1E, VIASR, 0xF0, BIT4 +
85 BIT5 + BIT6 + BIT7);
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);
90 break;
91 }
92
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) {
99 /*
100 * Currently only support 12bits,dual edge,add 24bits mode later
101 */
102 tmds_register_write(0x08, 0x3b);
103
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);
109 return OK;
110 } else {
111 viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX;
112 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)
113 != FAIL) {
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);
122 return OK;
123 }
124 }
125
126 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS;
127
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");
132 return OK;
133 }
134
135 switch (viaparinfo->chip_info->gfx_chip_name) {
136 case UNICHROME_K8M890:
137 viafb_write_reg(SR2A, VIASR, sr2a);
138 break;
139
140 case UNICHROME_P4M900:
141 case UNICHROME_P4M890:
142 viafb_write_reg(SR2A, VIASR, sr2a);
143 viafb_write_reg(SR1E, VIASR, sr1e);
144 break;
145
146 default:
147 viafb_write_reg(SR1E, VIASR, sr1e);
148 viafb_write_reg(SR3E, VIASR, sr3e);
149 break;
150 }
151
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;
156 return FAIL;
157}
158
159static void tmds_register_write(int index, u8 data)
160{
Florian Tobias Schandinatc4df5482009-09-22 16:47:24 -0700161 viaparinfo->shared->i2c_stuff.i2c_port =
Joseph Chanc09c7822008-10-15 22:03:23 -0700162 viaparinfo->chip_info->tmds_chip_info.i2c_port;
163
164 viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.
165 tmds_chip_slave_addr, index,
166 data);
167}
168
169static int tmds_register_read(int index)
170{
171 u8 data;
172
Florian Tobias Schandinatc4df5482009-09-22 16:47:24 -0700173 viaparinfo->shared->i2c_stuff.i2c_port =
Joseph Chanc09c7822008-10-15 22:03:23 -0700174 viaparinfo->chip_info->tmds_chip_info.i2c_port;
175 viafb_i2c_readbyte((u8) viaparinfo->chip_info->
176 tmds_chip_info.tmds_chip_slave_addr,
177 (u8) index, &data);
178 return data;
179}
180
181static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
182{
Florian Tobias Schandinatc4df5482009-09-22 16:47:24 -0700183 viaparinfo->shared->i2c_stuff.i2c_port =
Joseph Chanc09c7822008-10-15 22:03:23 -0700184 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);
187 return 0;
188}
189
Joseph Chanc09c7822008-10-15 22:03:23 -0700190/* DVI Set Mode */
Florian Tobias Schandinatdd73d6862010-03-10 15:21:28 -0800191void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp,
192 int set_iga)
Joseph Chanc09c7822008-10-15 22:03:23 -0700193{
Florian Tobias Schandinatdd73d6862010-03-10 15:21:28 -0800194 struct VideoModeTable *rb_mode;
Joseph Chanc09c7822008-10-15 22:03:23 -0700195 struct crt_mode_table *pDviTiming;
196 unsigned long desirePixelClock, maxPixelClock;
Florian Tobias Schandinatdd73d6862010-03-10 15:21:28 -0800197 pDviTiming = mode->crtc;
Joseph Chanc09c7822008-10-15 22:03:23 -0700198 desirePixelClock = pDviTiming->clk / 1000000;
199 maxPixelClock = (unsigned long)viaparinfo->
200 tmds_setting_info->max_pixel_clock;
201
202 DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
203
204 if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
Florian Tobias Schandinatdd73d6862010-03-10 15:21:28 -0800205 rb_mode = viafb_get_rb_mode(mode->crtc[0].crtc.hor_addr,
206 mode->crtc[0].crtc.ver_addr);
207 if (rb_mode) {
208 mode = rb_mode;
209 pDviTiming = rb_mode->crtc;
Joseph Chanc09c7822008-10-15 22:03:23 -0700210 }
211 }
Florian Tobias Schandinatdd73d6862010-03-10 15:21:28 -0800212 viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga);
Joseph Chanc09c7822008-10-15 22:03:23 -0700213 viafb_set_output_path(DEVICE_DVI, set_iga,
214 viaparinfo->chip_info->tmds_chip_info.output_interface);
215}
216
217/* Sense DVI Connector */
218int viafb_dvi_sense(void)
219{
220 u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0,
221 RegCR93 = 0, RegCR9B = 0, data;
222 int ret = false;
223
224 DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n");
225
226 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
227 /* DI1 Pad on */
228 RegSR1E = viafb_read_reg(VIASR, SR1E);
229 viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30);
230
231 /* CR6B[0]VCK Input Selection: 1 = External clock. */
232 RegCR6B = viafb_read_reg(VIACR, CR6B);
233 viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08);
234
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);
239
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);
246 } else {
247 /* DVP0/DVP1 Pad on */
248 RegSR1E = viafb_read_reg(VIASR, SR1E);
249 viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0);
250
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));
255
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);
260
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);
265 }
266
267 data = (u8) tmds_register_read(0x09);
268 if (data & 0x04)
269 ret = true;
270
271 if (ret == false) {
272 if (viafb_dvi_query_EDID())
273 ret = true;
274 }
275
276 /* Restore status */
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);
282 } else {
283 viafb_write_reg(SR3E, VIASR, RegSR3E);
284 viafb_write_reg(CR9B, VIACR, RegCR9B);
285 }
286
287 return ret;
288}
289
290/* Query Flat Panel's EDID Table Version Through DVI Connector */
291static int viafb_dvi_query_EDID(void)
292{
293 u8 data0, data1;
294 int restore;
295
296 DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n");
297
298 restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
299 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
300
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 */
307 }
308
309 data0 = (u8) tmds_register_read(0x00);
310 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
311 if (data0 == 0x20)
312 return EDID_VERSION_2; /* Found EDID2 Table */
313 else
314 return false;
315}
316
Florian Tobias Schandinat9b24b002010-03-10 15:21:29 -0800317/* void dvi_get_panel_size_from_DDCv1(void)
Joseph Chanc09c7822008-10-15 22:03:23 -0700318 *
319 * - Get Panel Size Using EDID1 Table
Joseph Chanc09c7822008-10-15 22:03:23 -0700320 */
Florian Tobias Schandinat9b24b002010-03-10 15:21:29 -0800321static void dvi_get_panel_size_from_DDCv1(void)
Joseph Chanc09c7822008-10-15 22:03:23 -0700322{
Florian Tobias Schandinat9b24b002010-03-10 15:21:29 -0800323 int i, max_h = 0, tmp, restore;
Joseph Chanc09c7822008-10-15 22:03:23 -0700324 unsigned char rData;
325 unsigned char EDID_DATA[18];
326
327 DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
328
329 restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
330 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
331
332 rData = tmds_register_read(0x23);
333 if (rData & 0x3C)
334 max_h = 640;
335 if (rData & 0xC0)
336 max_h = 720;
337 if (rData & 0x03)
338 max_h = 800;
339
340 rData = tmds_register_read(0x24);
341 if (rData & 0xC0)
342 max_h = 800;
343 if (rData & 0x1E)
344 max_h = 1024;
345 if (rData & 0x01)
346 max_h = 1280;
347
348 for (i = 0x25; i < 0x6D; i++) {
349 switch (i) {
350 case 0x26:
351 case 0x28:
352 case 0x2A:
353 case 0x2C:
354 case 0x2E:
355 case 0x30:
356 case 0x32:
357 case 0x34:
358 rData = tmds_register_read(i);
359 if (rData == 1)
360 break;
361 /* data = (data + 31) * 8 */
362 tmp = (rData + 31) << 3;
363 if (tmp > max_h)
364 max_h = tmp;
365 break;
366
367 case 0x36:
368 case 0x48:
369 case 0x5A:
370 case 0x6C:
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;
378 }
379 }
380 break;
381
382 default:
383 break;
384 }
385 }
386
387 switch (max_h) {
388 case 640:
Joseph Chanc09c7822008-10-15 22:03:23 -0700389 break;
390 case 800:
Joseph Chanc09c7822008-10-15 22:03:23 -0700391 break;
392 case 1024:
Joseph Chanc09c7822008-10-15 22:03:23 -0700393 break;
394 case 1280:
Joseph Chanc09c7822008-10-15 22:03:23 -0700395 break;
396 case 1400:
Joseph Chanc09c7822008-10-15 22:03:23 -0700397 break;
398 case 1440:
Joseph Chanc09c7822008-10-15 22:03:23 -0700399 break;
400 case 1600:
Joseph Chanc09c7822008-10-15 22:03:23 -0700401 break;
402 case 1920:
Joseph Chanc09c7822008-10-15 22:03:23 -0700403
404 break;
405 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -0200406 DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d !\
Joseph Chanc09c7822008-10-15 22:03:23 -0700407 set default panel size.\n", max_h);
408 break;
409 }
410
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;
Joseph Chanc09c7822008-10-15 22:03:23 -0700414}
415
Florian Tobias Schandinat9b24b002010-03-10 15:21:29 -0800416/* void dvi_get_panel_size_from_DDCv2(void)
Joseph Chanc09c7822008-10-15 22:03:23 -0700417 *
418 * - Get Panel Size Using EDID2 Table
Joseph Chanc09c7822008-10-15 22:03:23 -0700419 */
Florian Tobias Schandinat9b24b002010-03-10 15:21:29 -0800420static void dvi_get_panel_size_from_DDCv2(void)
Joseph Chanc09c7822008-10-15 22:03:23 -0700421{
422 int HSize = 0, restore;
423 unsigned char R_Buffer[2];
424
425 DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
426
427 restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
428 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
429
430 /* Horizontal: 0x76, 0x77 */
431 tmds_register_read_bytes(0x76, R_Buffer, 2);
432 HSize = R_Buffer[0];
433 HSize += R_Buffer[1] << 8;
434
435 switch (HSize) {
436 case 640:
Joseph Chanc09c7822008-10-15 22:03:23 -0700437 break;
438 case 800:
Joseph Chanc09c7822008-10-15 22:03:23 -0700439 break;
440 case 1024:
Joseph Chanc09c7822008-10-15 22:03:23 -0700441 break;
442 case 1280:
Joseph Chanc09c7822008-10-15 22:03:23 -0700443 break;
444 case 1400:
Joseph Chanc09c7822008-10-15 22:03:23 -0700445 break;
446 case 1440:
Joseph Chanc09c7822008-10-15 22:03:23 -0700447 break;
448 case 1600:
Joseph Chanc09c7822008-10-15 22:03:23 -0700449 break;
450 default:
André Goddard Rosaaf901ca2009-11-14 13:09:05 -0200451 DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d!\
Joseph Chanc09c7822008-10-15 22:03:23 -0700452 set default panel size.\n", HSize);
453 break;
454 }
455
456 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
Joseph Chanc09c7822008-10-15 22:03:23 -0700457}
458
Florian Tobias Schandinat9b24b002010-03-10 15:21:29 -0800459/* unsigned char dvi_get_panel_info(void)
Joseph Chanc09c7822008-10-15 22:03:23 -0700460 *
461 * - Get Panel Size
Joseph Chanc09c7822008-10-15 22:03:23 -0700462 */
Florian Tobias Schandinat9b24b002010-03-10 15:21:29 -0800463static void dvi_get_panel_info(void)
Joseph Chanc09c7822008-10-15 22:03:23 -0700464{
Joseph Chanc09c7822008-10-15 22:03:23 -0700465 DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
466
467 viafb_dvi_sense();
468 switch (viafb_dvi_query_EDID()) {
469 case 1:
470 dvi_get_panel_size_from_DDCv1();
471 break;
472 case 2:
473 dvi_get_panel_size_from_DDCv2();
474 break;
475 default:
476 break;
477 }
Joseph Chanc09c7822008-10-15 22:03:23 -0700478}
479
480/* If Disable DVI, turn off pad */
481void viafb_dvi_disable(void)
482{
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));
487
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));
492
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));
497
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));
502
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);
508}
509
510/* If Enable DVI, turn off pad */
511void viafb_dvi_enable(void)
512{
513 u8 data;
514
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);
521 else
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);
526 }
527
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);
532
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);
536 } else {
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);
541 }
542
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)
549 data = 0x3F;
550 else
551 data = 0x37;
552 viafb_i2c_writebyte(viaparinfo->chip_info->
553 tmds_chip_info.
554 tmds_chip_slave_addr,
555 0x08, data);
556 }
557 }
558 }
559
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);
566 }
567
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);
574 }
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);
579
580 /* Turn on TMDS power. */
581 viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);
582 }
583}
584