viafb: split global index up
[linux-2.6.git] / drivers / video / via / dvi.c
1 /*
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
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 int dvi_get_panel_size_from_DDCv1(void);
27 static int dvi_get_panel_size_from_DDCv2(void);
28 static unsigned char dvi_get_panel_info(void);
29 static int viafb_dvi_query_EDID(void);
30
31 static 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
39 void 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
59 int 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
159 static void tmds_register_write(int index, u8 data)
160 {
161         viaparinfo->shared->i2c_stuff.i2c_port =
162                 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
169 static int tmds_register_read(int index)
170 {
171         u8 data;
172
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,
177                         (u8) index, &data);
178         return data;
179 }
180
181 static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
182 {
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);
187         return 0;
188 }
189
190 /* DVI Set Mode */
191 void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp,
192         int set_iga)
193 {
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;
201
202         DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
203
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);
207                 if (rb_mode) {
208                         mode = rb_mode;
209                         pDviTiming = rb_mode->crtc;
210                 }
211         }
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);
215 }
216
217 /* Sense DVI Connector */
218 int 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 */
291 static 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
317 /*
318  *
319  * int dvi_get_panel_size_from_DDCv1(void)
320  *
321  *     - Get Panel Size Using EDID1 Table
322  *
323  * Return Type:    int
324  *
325  */
326 static int dvi_get_panel_size_from_DDCv1(void)
327 {
328         int i, max_h = 0, max_v = 0, tmp, restore;
329         unsigned char rData;
330         unsigned char EDID_DATA[18];
331
332         DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
333
334         restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
335         viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
336
337         rData = tmds_register_read(0x23);
338         if (rData & 0x3C)
339                 max_h = 640;
340         if (rData & 0xC0)
341                 max_h = 720;
342         if (rData & 0x03)
343                 max_h = 800;
344
345         rData = tmds_register_read(0x24);
346         if (rData & 0xC0)
347                 max_h = 800;
348         if (rData & 0x1E)
349                 max_h = 1024;
350         if (rData & 0x01)
351                 max_h = 1280;
352
353         for (i = 0x25; i < 0x6D; i++) {
354                 switch (i) {
355                 case 0x26:
356                 case 0x28:
357                 case 0x2A:
358                 case 0x2C:
359                 case 0x2E:
360                 case 0x30:
361                 case 0x32:
362                 case 0x34:
363                         rData = tmds_register_read(i);
364                         if (rData == 1)
365                                 break;
366                         /* data = (data + 31) * 8 */
367                         tmp = (rData + 31) << 3;
368                         if (tmp > max_h)
369                                 max_h = tmp;
370                         break;
371
372                 case 0x36:
373                 case 0x48:
374                 case 0x5A:
375                 case 0x6C:
376                         tmds_register_read_bytes(i, EDID_DATA, 10);
377                         if (!(EDID_DATA[0] || EDID_DATA[1])) {
378                                 /* The first two byte must be zero. */
379                                 if (EDID_DATA[3] == 0xFD) {
380                                         /* To get max pixel clock. */
381                                         viaparinfo->tmds_setting_info->
382                                         max_pixel_clock = EDID_DATA[9] * 10;
383                                 }
384                         }
385                         break;
386
387                 default:
388                         break;
389                 }
390         }
391
392         switch (max_h) {
393         case 640:
394                 viaparinfo->tmds_setting_info->dvi_panel_size =
395                         VIA_RES_640X480;
396                 break;
397         case 800:
398                 viaparinfo->tmds_setting_info->dvi_panel_size =
399                         VIA_RES_800X600;
400                 break;
401         case 1024:
402                 viaparinfo->tmds_setting_info->dvi_panel_size =
403                         VIA_RES_1024X768;
404                 break;
405         case 1280:
406                 viaparinfo->tmds_setting_info->dvi_panel_size =
407                         VIA_RES_1280X1024;
408                 break;
409         case 1400:
410                 viaparinfo->tmds_setting_info->dvi_panel_size =
411                         VIA_RES_1400X1050;
412                 break;
413         case 1440:
414                 viaparinfo->tmds_setting_info->dvi_panel_size =
415                         VIA_RES_1440X1050;
416                 break;
417         case 1600:
418                 viaparinfo->tmds_setting_info->dvi_panel_size =
419                         VIA_RES_1600X1200;
420                 break;
421         case 1920:
422                 if (max_v == 1200) {
423                         viaparinfo->tmds_setting_info->dvi_panel_size =
424                                 VIA_RES_1920X1200;
425                 } else {
426                         viaparinfo->tmds_setting_info->dvi_panel_size =
427                                 VIA_RES_1920X1080;
428                 }
429
430                 break;
431         default:
432                 viaparinfo->tmds_setting_info->dvi_panel_size =
433                         VIA_RES_1024X768;
434                 DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d !\
435                                          set default panel size.\n", max_h);
436                 break;
437         }
438
439         DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
440                   viaparinfo->tmds_setting_info->max_pixel_clock);
441         viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
442         return viaparinfo->tmds_setting_info->dvi_panel_size;
443 }
444
445 /*
446  *
447  * int dvi_get_panel_size_from_DDCv2(void)
448  *
449  *     - Get Panel Size Using EDID2 Table
450  *
451  * Return Type:    int
452  *
453  */
454 static int dvi_get_panel_size_from_DDCv2(void)
455 {
456         int HSize = 0, restore;
457         unsigned char R_Buffer[2];
458
459         DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
460
461         restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
462         viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
463
464         /* Horizontal: 0x76, 0x77 */
465         tmds_register_read_bytes(0x76, R_Buffer, 2);
466         HSize = R_Buffer[0];
467         HSize += R_Buffer[1] << 8;
468
469         switch (HSize) {
470         case 640:
471                 viaparinfo->tmds_setting_info->dvi_panel_size =
472                         VIA_RES_640X480;
473                 break;
474         case 800:
475                 viaparinfo->tmds_setting_info->dvi_panel_size =
476                         VIA_RES_800X600;
477                 break;
478         case 1024:
479                 viaparinfo->tmds_setting_info->dvi_panel_size =
480                         VIA_RES_1024X768;
481                 break;
482         case 1280:
483                 viaparinfo->tmds_setting_info->dvi_panel_size =
484                         VIA_RES_1280X1024;
485                 break;
486         case 1400:
487                 viaparinfo->tmds_setting_info->dvi_panel_size =
488                         VIA_RES_1400X1050;
489                 break;
490         case 1440:
491                 viaparinfo->tmds_setting_info->dvi_panel_size =
492                         VIA_RES_1440X1050;
493                 break;
494         case 1600:
495                 viaparinfo->tmds_setting_info->dvi_panel_size =
496                         VIA_RES_1600X1200;
497                 break;
498         default:
499                 viaparinfo->tmds_setting_info->dvi_panel_size =
500                         VIA_RES_1024X768;
501                 DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d!\
502                                         set default panel size.\n", HSize);
503                 break;
504         }
505
506         viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
507         return viaparinfo->tmds_setting_info->dvi_panel_size;
508 }
509
510 /*
511  *
512  * unsigned char dvi_get_panel_info(void)
513  *
514  *     - Get Panel Size
515  *
516  * Return Type:    unsigned char
517  */
518 static unsigned char dvi_get_panel_info(void)
519 {
520         unsigned char dvipanelsize;
521         DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
522
523         viafb_dvi_sense();
524         switch (viafb_dvi_query_EDID()) {
525         case 1:
526                 dvi_get_panel_size_from_DDCv1();
527                 break;
528         case 2:
529                 dvi_get_panel_size_from_DDCv2();
530                 break;
531         default:
532                 break;
533         }
534
535         DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n",
536                   viaparinfo->tmds_setting_info->dvi_panel_size);
537         dvipanelsize = (unsigned char)(viaparinfo->
538                 tmds_setting_info->dvi_panel_size);
539         return dvipanelsize;
540 }
541
542 /* If Disable DVI, turn off pad */
543 void viafb_dvi_disable(void)
544 {
545         if (viaparinfo->chip_info->
546                 tmds_chip_info.output_interface == INTERFACE_DVP0)
547                 viafb_write_reg(SR1E, VIASR,
548                 viafb_read_reg(VIASR, SR1E) & (~0xC0));
549
550         if (viaparinfo->chip_info->
551                 tmds_chip_info.output_interface == INTERFACE_DVP1)
552                 viafb_write_reg(SR1E, VIASR,
553                 viafb_read_reg(VIASR, SR1E) & (~0x30));
554
555         if (viaparinfo->chip_info->
556                 tmds_chip_info.output_interface == INTERFACE_DFP_HIGH)
557                 viafb_write_reg(SR2A, VIASR,
558                 viafb_read_reg(VIASR, SR2A) & (~0x0C));
559
560         if (viaparinfo->chip_info->
561                 tmds_chip_info.output_interface == INTERFACE_DFP_LOW)
562                 viafb_write_reg(SR2A, VIASR,
563                 viafb_read_reg(VIASR, SR2A) & (~0x03));
564
565         if (viaparinfo->chip_info->
566                 tmds_chip_info.output_interface == INTERFACE_TMDS)
567                 /* Turn off TMDS power. */
568                 viafb_write_reg(CRD2, VIACR,
569                 viafb_read_reg(VIACR, CRD2) | 0x08);
570 }
571
572 /* If Enable DVI, turn off pad */
573 void viafb_dvi_enable(void)
574 {
575         u8 data;
576
577         if (viaparinfo->chip_info->
578                 tmds_chip_info.output_interface == INTERFACE_DVP0) {
579                 viafb_write_reg(SR1E, VIASR,
580                         viafb_read_reg(VIASR, SR1E) | 0xC0);
581                 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
582                         tmds_register_write(0x88, 0x3b);
583                 else
584                         /*clear CR91[5] to direct on display period
585                            in the secondary diplay path */
586                         viafb_write_reg(CR91, VIACR,
587                         viafb_read_reg(VIACR, CR91) & 0xDF);
588         }
589
590         if (viaparinfo->chip_info->
591                 tmds_chip_info.output_interface == INTERFACE_DVP1) {
592                 viafb_write_reg(SR1E, VIASR,
593                         viafb_read_reg(VIASR, SR1E) | 0x30);
594
595                 /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
596                 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
597                         tmds_register_write(0x88, 0x3b);
598                 } else {
599                         /*clear CR91[5] to direct on display period
600                           in the secondary diplay path */
601                         viafb_write_reg(CR91, VIACR,
602                         viafb_read_reg(VIACR, CR91) & 0xDF);
603                 }
604
605                 /*fix DVI cannot enable on EPIA-M board */
606                 if (viafb_platform_epia_dvi == 1) {
607                         viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f);
608                         viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0);
609                         if (viafb_bus_width == 24) {
610                                 if (viafb_device_lcd_dualedge == 1)
611                                         data = 0x3F;
612                                 else
613                                         data = 0x37;
614                                 viafb_i2c_writebyte(viaparinfo->chip_info->
615                                              tmds_chip_info.
616                                              tmds_chip_slave_addr,
617                                              0x08, data);
618                         }
619                 }
620         }
621
622         if (viaparinfo->chip_info->
623                 tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) {
624                 viafb_write_reg(SR2A, VIASR,
625                         viafb_read_reg(VIASR, SR2A) | 0x0C);
626                 viafb_write_reg(CR91, VIACR,
627                         viafb_read_reg(VIACR, CR91) & 0xDF);
628         }
629
630         if (viaparinfo->chip_info->
631                 tmds_chip_info.output_interface == INTERFACE_DFP_LOW) {
632                 viafb_write_reg(SR2A, VIASR,
633                         viafb_read_reg(VIASR, SR2A) | 0x03);
634                 viafb_write_reg(CR91, VIACR,
635                         viafb_read_reg(VIACR, CR91) & 0xDF);
636         }
637         if (viaparinfo->chip_info->
638                 tmds_chip_info.output_interface == INTERFACE_TMDS) {
639                 /* Turn on Display period in the panel path. */
640                 viafb_write_reg_mask(CR91, VIACR, 0, BIT7);
641
642                 /* Turn on TMDS power. */
643                 viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);
644         }
645 }
646