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