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