Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[linux-2.6] / 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 check_reduce_blanking_mode(int mode_index,
27         int refresh_rate);
28 static int dvi_get_panel_size_from_DDCv1(void);
29 static int dvi_get_panel_size_from_DDCv2(void);
30 static unsigned char dvi_get_panel_info(void);
31 static int viafb_dvi_query_EDID(void);
32
33 static int check_tmds_chip(int device_id_subaddr, int device_id)
34 {
35         if (tmds_register_read(device_id_subaddr) == device_id)
36                 return OK;
37         else
38                 return FAIL;
39 }
40
41 void viafb_init_dvi_size(void)
42 {
43         DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
44         DEBUG_MSG(KERN_INFO
45                 "viaparinfo->tmds_setting_info->get_dvi_size_method %d\n",
46                   viaparinfo->tmds_setting_info->get_dvi_size_method);
47
48         switch (viaparinfo->tmds_setting_info->get_dvi_size_method) {
49         case GET_DVI_SIZE_BY_SYSTEM_BIOS:
50                 break;
51         case GET_DVI_SZIE_BY_HW_STRAPPING:
52                 break;
53         case GET_DVI_SIZE_BY_VGA_BIOS:
54         default:
55                 dvi_get_panel_info();
56                 break;
57         }
58         return;
59 }
60
61 int viafb_tmds_trasmitter_identify(void)
62 {
63         unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
64
65         /* Turn on ouputting pad */
66         switch (viaparinfo->chip_info->gfx_chip_name) {
67         case UNICHROME_K8M890:
68             /*=* DFP Low Pad on *=*/
69                 sr2a = viafb_read_reg(VIASR, SR2A);
70                 viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
71                 break;
72
73         case UNICHROME_P4M900:
74         case UNICHROME_P4M890:
75                 /* DFP Low Pad on */
76                 sr2a = viafb_read_reg(VIASR, SR2A);
77                 viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
78                 /* DVP0 Pad on */
79                 sr1e = viafb_read_reg(VIASR, SR1E);
80                 viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7);
81                 break;
82
83         default:
84             /* DVP0/DVP1 Pad on */
85                 sr1e = viafb_read_reg(VIASR, SR1E);
86                 viafb_write_reg_mask(SR1E, VIASR, 0xF0, BIT4 +
87                         BIT5 + BIT6 + BIT7);
88             /* SR3E[1]Multi-function selection:
89             0 = Emulate I2C and DDC bus by GPIO2/3/4. */
90                 sr3e = viafb_read_reg(VIASR, SR3E);
91                 viafb_write_reg_mask(SR3E, VIASR, 0x0, BIT5);
92                 break;
93         }
94
95         /* Check for VT1632: */
96         viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
97         viaparinfo->chip_info->
98                 tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
99         viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX;
100         if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) {
101                 /*
102                  * Currently only support 12bits,dual edge,add 24bits mode later
103                  */
104                 tmds_register_write(0x08, 0x3b);
105
106                 DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
107                 DEBUG_MSG(KERN_INFO "\n %2d",
108                           viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
109                 DEBUG_MSG(KERN_INFO "\n %2d",
110                           viaparinfo->chip_info->tmds_chip_info.i2c_port);
111                 return OK;
112         } else {
113                 viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX;
114                 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)
115                     != FAIL) {
116                         tmds_register_write(0x08, 0x3b);
117                         DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
118                         DEBUG_MSG(KERN_INFO "\n %2d",
119                                   viaparinfo->chip_info->
120                                   tmds_chip_info.tmds_chip_name);
121                         DEBUG_MSG(KERN_INFO "\n %2d",
122                                   viaparinfo->chip_info->
123                                   tmds_chip_info.i2c_port);
124                         return OK;
125                 }
126         }
127
128         viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS;
129
130         if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) &&
131             ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) ||
132              (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) {
133                 DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n");
134                 return OK;
135         }
136
137         switch (viaparinfo->chip_info->gfx_chip_name) {
138         case UNICHROME_K8M890:
139                 viafb_write_reg(SR2A, VIASR, sr2a);
140                 break;
141
142         case UNICHROME_P4M900:
143         case UNICHROME_P4M890:
144                 viafb_write_reg(SR2A, VIASR, sr2a);
145                 viafb_write_reg(SR1E, VIASR, sr1e);
146                 break;
147
148         default:
149                 viafb_write_reg(SR1E, VIASR, sr1e);
150                 viafb_write_reg(SR3E, VIASR, sr3e);
151                 break;
152         }
153
154         viaparinfo->chip_info->
155                 tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
156         viaparinfo->chip_info->tmds_chip_info.
157                 tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
158         return FAIL;
159 }
160
161 static void tmds_register_write(int index, u8 data)
162 {
163         viaparinfo->i2c_stuff.i2c_port =
164                 viaparinfo->chip_info->tmds_chip_info.i2c_port;
165
166         viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.
167                 tmds_chip_slave_addr, index,
168                      data);
169 }
170
171 static int tmds_register_read(int index)
172 {
173         u8 data;
174
175         viaparinfo->i2c_stuff.i2c_port =
176                 viaparinfo->chip_info->tmds_chip_info.i2c_port;
177         viafb_i2c_readbyte((u8) viaparinfo->chip_info->
178             tmds_chip_info.tmds_chip_slave_addr,
179                         (u8) index, &data);
180         return data;
181 }
182
183 static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
184 {
185         viaparinfo->i2c_stuff.i2c_port =
186                 viaparinfo->chip_info->tmds_chip_info.i2c_port;
187         viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info.
188                          tmds_chip_slave_addr, (u8) index, buff, buff_len);
189         return 0;
190 }
191
192 static int check_reduce_blanking_mode(int mode_index,
193         int refresh_rate)
194 {
195         if (refresh_rate != 60)
196                 return false;
197
198         switch (mode_index) {
199                 /* Following modes have reduce blanking mode. */
200         case VIA_RES_1360X768:
201         case VIA_RES_1400X1050:
202         case VIA_RES_1440X900:
203         case VIA_RES_1600X900:
204         case VIA_RES_1680X1050:
205         case VIA_RES_1920X1080:
206         case VIA_RES_1920X1200:
207                 break;
208
209         default:
210                 DEBUG_MSG(KERN_INFO
211                           "This dvi mode %d have no reduce blanking mode!\n",
212                           mode_index);
213                 return false;
214         }
215
216         return true;
217 }
218
219 /* DVI Set Mode */
220 void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga)
221 {
222         struct VideoModeTable *videoMode = NULL;
223         struct crt_mode_table *pDviTiming;
224         unsigned long desirePixelClock, maxPixelClock;
225         int status = 0;
226         videoMode = viafb_get_modetbl_pointer(video_index);
227         pDviTiming = videoMode->crtc;
228         desirePixelClock = pDviTiming->clk / 1000000;
229         maxPixelClock = (unsigned long)viaparinfo->
230                 tmds_setting_info->max_pixel_clock;
231
232         DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
233
234         if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
235                 /*Check if reduce-blanking mode is exist */
236                 status =
237                     check_reduce_blanking_mode(video_index,
238                                                pDviTiming->refresh_rate);
239                 if (status) {
240                         video_index += 100;     /*Use reduce-blanking mode */
241                         videoMode = viafb_get_modetbl_pointer(video_index);
242                         pDviTiming = videoMode->crtc;
243                         DEBUG_MSG(KERN_INFO
244                                   "DVI use reduce blanking mode %d!!\n",
245                                   video_index);
246                 }
247         }
248         viafb_fill_crtc_timing(pDviTiming, video_index, mode_bpp / 8, set_iga);
249         viafb_set_output_path(DEVICE_DVI, set_iga,
250                         viaparinfo->chip_info->tmds_chip_info.output_interface);
251 }
252
253 /* Sense DVI Connector */
254 int viafb_dvi_sense(void)
255 {
256         u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0,
257                 RegCR93 = 0, RegCR9B = 0, data;
258         int ret = false;
259
260         DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n");
261
262         if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
263                 /* DI1 Pad on */
264                 RegSR1E = viafb_read_reg(VIASR, SR1E);
265                 viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30);
266
267                 /* CR6B[0]VCK Input Selection: 1 = External clock. */
268                 RegCR6B = viafb_read_reg(VIACR, CR6B);
269                 viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08);
270
271                 /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
272                    [0] Software Control Power Sequence */
273                 RegCR91 = viafb_read_reg(VIACR, CR91);
274                 viafb_write_reg(CR91, VIACR, 0x1D);
275
276                 /* CR93[7] DI1 Data Source Selection: 1 = DSP2.
277                    CR93[5] DI1 Clock Source: 1 = internal.
278                    CR93[4] DI1 Clock Polarity.
279                    CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */
280                 RegCR93 = viafb_read_reg(VIACR, CR93);
281                 viafb_write_reg(CR93, VIACR, 0x01);
282         } else {
283                 /* DVP0/DVP1 Pad on */
284                 RegSR1E = viafb_read_reg(VIASR, SR1E);
285                 viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0);
286
287                 /* SR3E[1]Multi-function selection:
288                    0 = Emulate I2C and DDC bus by GPIO2/3/4. */
289                 RegSR3E = viafb_read_reg(VIASR, SR3E);
290                 viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20));
291
292                 /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
293                    [0] Software Control Power Sequence */
294                 RegCR91 = viafb_read_reg(VIACR, CR91);
295                 viafb_write_reg(CR91, VIACR, 0x1D);
296
297                 /*CR9B[4] DVP1 Data Source Selection: 1 = From secondary
298                 display.CR9B[2:0] DVP1 Clock Adjust */
299                 RegCR9B = viafb_read_reg(VIACR, CR9B);
300                 viafb_write_reg(CR9B, VIACR, 0x01);
301         }
302
303         data = (u8) tmds_register_read(0x09);
304         if (data & 0x04)
305                 ret = true;
306
307         if (ret == false) {
308                 if (viafb_dvi_query_EDID())
309                         ret = true;
310         }
311
312         /* Restore status */
313         viafb_write_reg(SR1E, VIASR, RegSR1E);
314         viafb_write_reg(CR91, VIACR, RegCR91);
315         if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
316                 viafb_write_reg(CR6B, VIACR, RegCR6B);
317                 viafb_write_reg(CR93, VIACR, RegCR93);
318         } else {
319                 viafb_write_reg(SR3E, VIASR, RegSR3E);
320                 viafb_write_reg(CR9B, VIACR, RegCR9B);
321         }
322
323         return ret;
324 }
325
326 /* Query Flat Panel's EDID Table Version Through DVI Connector */
327 static int viafb_dvi_query_EDID(void)
328 {
329         u8 data0, data1;
330         int restore;
331
332         DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\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         data0 = (u8) tmds_register_read(0x00);
338         data1 = (u8) tmds_register_read(0x01);
339         if ((data0 == 0) && (data1 == 0xFF)) {
340                 viaparinfo->chip_info->
341                         tmds_chip_info.tmds_chip_slave_addr = restore;
342                 return EDID_VERSION_1;  /* Found EDID1 Table */
343         }
344
345         data0 = (u8) tmds_register_read(0x00);
346         viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
347         if (data0 == 0x20)
348                 return EDID_VERSION_2;  /* Found EDID2 Table */
349         else
350                 return false;
351 }
352
353 /*
354  *
355  * int dvi_get_panel_size_from_DDCv1(void)
356  *
357  *     - Get Panel Size Using EDID1 Table
358  *
359  * Return Type:    int
360  *
361  */
362 static int dvi_get_panel_size_from_DDCv1(void)
363 {
364         int i, max_h = 0, max_v = 0, tmp, restore;
365         unsigned char rData;
366         unsigned char EDID_DATA[18];
367
368         DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
369
370         restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
371         viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
372
373         rData = tmds_register_read(0x23);
374         if (rData & 0x3C)
375                 max_h = 640;
376         if (rData & 0xC0)
377                 max_h = 720;
378         if (rData & 0x03)
379                 max_h = 800;
380
381         rData = tmds_register_read(0x24);
382         if (rData & 0xC0)
383                 max_h = 800;
384         if (rData & 0x1E)
385                 max_h = 1024;
386         if (rData & 0x01)
387                 max_h = 1280;
388
389         for (i = 0x25; i < 0x6D; i++) {
390                 switch (i) {
391                 case 0x26:
392                 case 0x28:
393                 case 0x2A:
394                 case 0x2C:
395                 case 0x2E:
396                 case 0x30:
397                 case 0x32:
398                 case 0x34:
399                         rData = tmds_register_read(i);
400                         if (rData == 1)
401                                 break;
402                         /* data = (data + 31) * 8 */
403                         tmp = (rData + 31) << 3;
404                         if (tmp > max_h)
405                                 max_h = tmp;
406                         break;
407
408                 case 0x36:
409                 case 0x48:
410                 case 0x5A:
411                 case 0x6C:
412                         tmds_register_read_bytes(i, EDID_DATA, 10);
413                         if (!(EDID_DATA[0] || EDID_DATA[1])) {
414                                 /* The first two byte must be zero. */
415                                 if (EDID_DATA[3] == 0xFD) {
416                                         /* To get max pixel clock. */
417                                         viaparinfo->tmds_setting_info->
418                                         max_pixel_clock = EDID_DATA[9] * 10;
419                                 }
420                         }
421                         break;
422
423                 default:
424                         break;
425                 }
426         }
427
428         switch (max_h) {
429         case 640:
430                 viaparinfo->tmds_setting_info->dvi_panel_size =
431                         VIA_RES_640X480;
432                 break;
433         case 800:
434                 viaparinfo->tmds_setting_info->dvi_panel_size =
435                         VIA_RES_800X600;
436                 break;
437         case 1024:
438                 viaparinfo->tmds_setting_info->dvi_panel_size =
439                         VIA_RES_1024X768;
440                 break;
441         case 1280:
442                 viaparinfo->tmds_setting_info->dvi_panel_size =
443                         VIA_RES_1280X1024;
444                 break;
445         case 1400:
446                 viaparinfo->tmds_setting_info->dvi_panel_size =
447                         VIA_RES_1400X1050;
448                 break;
449         case 1440:
450                 viaparinfo->tmds_setting_info->dvi_panel_size =
451                         VIA_RES_1440X1050;
452                 break;
453         case 1600:
454                 viaparinfo->tmds_setting_info->dvi_panel_size =
455                         VIA_RES_1600X1200;
456                 break;
457         case 1920:
458                 if (max_v == 1200) {
459                         viaparinfo->tmds_setting_info->dvi_panel_size =
460                                 VIA_RES_1920X1200;
461                 } else {
462                         viaparinfo->tmds_setting_info->dvi_panel_size =
463                                 VIA_RES_1920X1080;
464                 }
465
466                 break;
467         default:
468                 viaparinfo->tmds_setting_info->dvi_panel_size =
469                         VIA_RES_1024X768;
470                 DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d !\
471                                          set default panel size.\n", max_h);
472                 break;
473         }
474
475         DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
476                   viaparinfo->tmds_setting_info->max_pixel_clock);
477         viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
478         return viaparinfo->tmds_setting_info->dvi_panel_size;
479 }
480
481 /*
482  *
483  * int dvi_get_panel_size_from_DDCv2(void)
484  *
485  *     - Get Panel Size Using EDID2 Table
486  *
487  * Return Type:    int
488  *
489  */
490 static int dvi_get_panel_size_from_DDCv2(void)
491 {
492         int HSize = 0, restore;
493         unsigned char R_Buffer[2];
494
495         DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
496
497         restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
498         viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
499
500         /* Horizontal: 0x76, 0x77 */
501         tmds_register_read_bytes(0x76, R_Buffer, 2);
502         HSize = R_Buffer[0];
503         HSize += R_Buffer[1] << 8;
504
505         switch (HSize) {
506         case 640:
507                 viaparinfo->tmds_setting_info->dvi_panel_size =
508                         VIA_RES_640X480;
509                 break;
510         case 800:
511                 viaparinfo->tmds_setting_info->dvi_panel_size =
512                         VIA_RES_800X600;
513                 break;
514         case 1024:
515                 viaparinfo->tmds_setting_info->dvi_panel_size =
516                         VIA_RES_1024X768;
517                 break;
518         case 1280:
519                 viaparinfo->tmds_setting_info->dvi_panel_size =
520                         VIA_RES_1280X1024;
521                 break;
522         case 1400:
523                 viaparinfo->tmds_setting_info->dvi_panel_size =
524                         VIA_RES_1400X1050;
525                 break;
526         case 1440:
527                 viaparinfo->tmds_setting_info->dvi_panel_size =
528                         VIA_RES_1440X1050;
529                 break;
530         case 1600:
531                 viaparinfo->tmds_setting_info->dvi_panel_size =
532                         VIA_RES_1600X1200;
533                 break;
534         default:
535                 viaparinfo->tmds_setting_info->dvi_panel_size =
536                         VIA_RES_1024X768;
537                 DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d!\
538                                         set default panel size.\n", HSize);
539                 break;
540         }
541
542         viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
543         return viaparinfo->tmds_setting_info->dvi_panel_size;
544 }
545
546 /*
547  *
548  * unsigned char dvi_get_panel_info(void)
549  *
550  *     - Get Panel Size
551  *
552  * Return Type:    unsigned char
553  */
554 static unsigned char dvi_get_panel_info(void)
555 {
556         unsigned char dvipanelsize;
557         DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
558
559         viafb_dvi_sense();
560         switch (viafb_dvi_query_EDID()) {
561         case 1:
562                 dvi_get_panel_size_from_DDCv1();
563                 break;
564         case 2:
565                 dvi_get_panel_size_from_DDCv2();
566                 break;
567         default:
568                 break;
569         }
570
571         DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n",
572                   viaparinfo->tmds_setting_info->dvi_panel_size);
573         dvipanelsize = (unsigned char)(viaparinfo->
574                 tmds_setting_info->dvi_panel_size);
575         return dvipanelsize;
576 }
577
578 /* If Disable DVI, turn off pad */
579 void viafb_dvi_disable(void)
580 {
581         if (viaparinfo->chip_info->
582                 tmds_chip_info.output_interface == INTERFACE_DVP0)
583                 viafb_write_reg(SR1E, VIASR,
584                 viafb_read_reg(VIASR, SR1E) & (~0xC0));
585
586         if (viaparinfo->chip_info->
587                 tmds_chip_info.output_interface == INTERFACE_DVP1)
588                 viafb_write_reg(SR1E, VIASR,
589                 viafb_read_reg(VIASR, SR1E) & (~0x30));
590
591         if (viaparinfo->chip_info->
592                 tmds_chip_info.output_interface == INTERFACE_DFP_HIGH)
593                 viafb_write_reg(SR2A, VIASR,
594                 viafb_read_reg(VIASR, SR2A) & (~0x0C));
595
596         if (viaparinfo->chip_info->
597                 tmds_chip_info.output_interface == INTERFACE_DFP_LOW)
598                 viafb_write_reg(SR2A, VIASR,
599                 viafb_read_reg(VIASR, SR2A) & (~0x03));
600
601         if (viaparinfo->chip_info->
602                 tmds_chip_info.output_interface == INTERFACE_TMDS)
603                 /* Turn off TMDS power. */
604                 viafb_write_reg(CRD2, VIACR,
605                 viafb_read_reg(VIACR, CRD2) | 0x08);
606 }
607
608 /* If Enable DVI, turn off pad */
609 void viafb_dvi_enable(void)
610 {
611         u8 data;
612
613         if (viaparinfo->chip_info->
614                 tmds_chip_info.output_interface == INTERFACE_DVP0) {
615                 viafb_write_reg(SR1E, VIASR,
616                         viafb_read_reg(VIASR, SR1E) | 0xC0);
617                 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
618                         tmds_register_write(0x88, 0x3b);
619                 else
620                         /*clear CR91[5] to direct on display period
621                            in the secondary diplay path */
622                         viafb_write_reg(CR91, VIACR,
623                         viafb_read_reg(VIACR, CR91) & 0xDF);
624         }
625
626         if (viaparinfo->chip_info->
627                 tmds_chip_info.output_interface == INTERFACE_DVP1) {
628                 viafb_write_reg(SR1E, VIASR,
629                         viafb_read_reg(VIASR, SR1E) | 0x30);
630
631                 /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
632                 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
633                         tmds_register_write(0x88, 0x3b);
634                 } else {
635                         /*clear CR91[5] to direct on display period
636                           in the secondary diplay path */
637                         viafb_write_reg(CR91, VIACR,
638                         viafb_read_reg(VIACR, CR91) & 0xDF);
639                 }
640
641                 /*fix DVI cannot enable on EPIA-M board */
642                 if (viafb_platform_epia_dvi == 1) {
643                         viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f);
644                         viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0);
645                         if (viafb_bus_width == 24) {
646                                 if (viafb_device_lcd_dualedge == 1)
647                                         data = 0x3F;
648                                 else
649                                         data = 0x37;
650                                 viafb_i2c_writebyte(viaparinfo->chip_info->
651                                              tmds_chip_info.
652                                              tmds_chip_slave_addr,
653                                              0x08, data);
654                         }
655                 }
656         }
657
658         if (viaparinfo->chip_info->
659                 tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) {
660                 viafb_write_reg(SR2A, VIASR,
661                         viafb_read_reg(VIASR, SR2A) | 0x0C);
662                 viafb_write_reg(CR91, VIACR,
663                         viafb_read_reg(VIACR, CR91) & 0xDF);
664         }
665
666         if (viaparinfo->chip_info->
667                 tmds_chip_info.output_interface == INTERFACE_DFP_LOW) {
668                 viafb_write_reg(SR2A, VIASR,
669                         viafb_read_reg(VIASR, SR2A) | 0x03);
670                 viafb_write_reg(CR91, VIACR,
671                         viafb_read_reg(VIACR, CR91) & 0xDF);
672         }
673         if (viaparinfo->chip_info->
674                 tmds_chip_info.output_interface == INTERFACE_TMDS) {
675                 /* Turn on Display period in the panel path. */
676                 viafb_write_reg_mask(CR91, VIACR, 0, BIT7);
677
678                 /* Turn on TMDS power. */
679                 viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);
680         }
681 }
682