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