Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dvi.c
Go to the documentation of this file.
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 __devinit dvi_get_panel_size_from_DDCv1(
29  struct tmds_chip_information *tmds_chip,
30  struct tmds_setting_information *tmds_setting);
31 static int viafb_dvi_query_EDID(void);
32 
33 static inline bool check_tmds_chip(int device_id_subaddr, int device_id)
34 {
35  return tmds_register_read(device_id_subaddr) == device_id;
36 }
37 
39  struct tmds_setting_information *tmds_setting)
40 {
41  DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
42 
44  if (viafb_dvi_query_EDID() == 1)
45  dvi_get_panel_size_from_DDCv1(tmds_chip, tmds_setting);
46 
47  return;
48 }
49 
51 {
52  unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
53 
54  /* Turn on ouputting pad */
55  switch (viaparinfo->chip_info->gfx_chip_name) {
56  case UNICHROME_K8M890:
57  /*=* DFP Low Pad on *=*/
58  sr2a = viafb_read_reg(VIASR, SR2A);
60  break;
61 
62  case UNICHROME_P4M900:
63  case UNICHROME_P4M890:
64  /* DFP Low Pad on */
65  sr2a = viafb_read_reg(VIASR, SR2A);
67  /* DVP0 Pad on */
68  sr1e = viafb_read_reg(VIASR, SR1E);
70  break;
71 
72  default:
73  /* DVP0/DVP1 Pad on */
74  sr1e = viafb_read_reg(VIASR, SR1E);
76  BIT5 + BIT6 + BIT7);
77  /* SR3E[1]Multi-function selection:
78  0 = Emulate I2C and DDC bus by GPIO2/3/4. */
79  sr3e = viafb_read_reg(VIASR, SR3E);
81  break;
82  }
83 
84  /* Check for VT1632: */
85  viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
86  viaparinfo->chip_info->
87  tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
88  viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31;
89  if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) {
90  /*
91  * Currently only support 12bits,dual edge,add 24bits mode later
92  */
93  tmds_register_write(0x08, 0x3b);
94 
95  DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
96  DEBUG_MSG(KERN_INFO "\n %2d",
97  viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
98  DEBUG_MSG(KERN_INFO "\n %2d",
99  viaparinfo->chip_info->tmds_chip_info.i2c_port);
100  return true;
101  } else {
102  viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_2C;
103  if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) {
104  tmds_register_write(0x08, 0x3b);
105  DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
106  DEBUG_MSG(KERN_INFO "\n %2d",
107  viaparinfo->chip_info->
108  tmds_chip_info.tmds_chip_name);
109  DEBUG_MSG(KERN_INFO "\n %2d",
110  viaparinfo->chip_info->
111  tmds_chip_info.i2c_port);
112  return true;
113  }
114  }
115 
116  viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS;
117 
118  if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) &&
121  DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n");
122  return true;
123  }
124 
125  switch (viaparinfo->chip_info->gfx_chip_name) {
126  case UNICHROME_K8M890:
127  viafb_write_reg(SR2A, VIASR, sr2a);
128  break;
129 
130  case UNICHROME_P4M900:
131  case UNICHROME_P4M890:
132  viafb_write_reg(SR2A, VIASR, sr2a);
133  viafb_write_reg(SR1E, VIASR, sr1e);
134  break;
135 
136  default:
137  viafb_write_reg(SR1E, VIASR, sr1e);
138  viafb_write_reg(SR3E, VIASR, sr3e);
139  break;
140  }
141 
142  viaparinfo->chip_info->
143  tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
144  viaparinfo->chip_info->tmds_chip_info.
145  tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
146  return false;
147 }
148 
149 static void tmds_register_write(int index, u8 data)
150 {
151  viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.i2c_port,
152  viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
153  index, data);
154 }
155 
156 static int tmds_register_read(int index)
157 {
158  u8 data;
159 
160  viafb_i2c_readbyte(viaparinfo->chip_info->tmds_chip_info.i2c_port,
161  (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
162  (u8) index, &data);
163  return data;
164 }
165 
166 static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
167 {
168  viafb_i2c_readbytes(viaparinfo->chip_info->tmds_chip_info.i2c_port,
169  (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
170  (u8) index, buff, buff_len);
171  return 0;
172 }
173 
174 /* DVI Set Mode */
175 void viafb_dvi_set_mode(const struct fb_var_screeninfo *var,
176  u16 cxres, u16 cyres, int iga)
177 {
178  struct fb_var_screeninfo dvi_var = *var;
179  const struct fb_videomode *rb_mode;
180  int maxPixelClock;
181 
182  maxPixelClock = viaparinfo->shared->tmds_setting_info.max_pixel_clock;
183  if (maxPixelClock && PICOS2KHZ(var->pixclock) / 1000 > maxPixelClock) {
184  rb_mode = viafb_get_best_rb_mode(var->xres, var->yres, 60);
185  if (rb_mode)
186  viafb_fill_var_timing_info(&dvi_var, rb_mode);
187  }
188 
189  viafb_fill_crtc_timing(&dvi_var, cxres, cyres, iga);
190 }
191 
192 /* Sense DVI Connector */
194 {
195  u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0,
196  RegCR93 = 0, RegCR9B = 0, data;
197  int ret = false;
198 
199  DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n");
200 
201  if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
202  /* DI1 Pad on */
203  RegSR1E = viafb_read_reg(VIASR, SR1E);
204  viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30);
205 
206  /* CR6B[0]VCK Input Selection: 1 = External clock. */
207  RegCR6B = viafb_read_reg(VIACR, CR6B);
208  viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08);
209 
210  /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
211  [0] Software Control Power Sequence */
212  RegCR91 = viafb_read_reg(VIACR, CR91);
213  viafb_write_reg(CR91, VIACR, 0x1D);
214 
215  /* CR93[7] DI1 Data Source Selection: 1 = DSP2.
216  CR93[5] DI1 Clock Source: 1 = internal.
217  CR93[4] DI1 Clock Polarity.
218  CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */
219  RegCR93 = viafb_read_reg(VIACR, CR93);
220  viafb_write_reg(CR93, VIACR, 0x01);
221  } else {
222  /* DVP0/DVP1 Pad on */
223  RegSR1E = viafb_read_reg(VIASR, SR1E);
224  viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0);
225 
226  /* SR3E[1]Multi-function selection:
227  0 = Emulate I2C and DDC bus by GPIO2/3/4. */
228  RegSR3E = viafb_read_reg(VIASR, SR3E);
229  viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20));
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  /*CR9B[4] DVP1 Data Source Selection: 1 = From secondary
237  display.CR9B[2:0] DVP1 Clock Adjust */
238  RegCR9B = viafb_read_reg(VIACR, CR9B);
239  viafb_write_reg(CR9B, VIACR, 0x01);
240  }
241 
242  data = (u8) tmds_register_read(0x09);
243  if (data & 0x04)
244  ret = true;
245 
246  if (ret == false) {
247  if (viafb_dvi_query_EDID())
248  ret = true;
249  }
250 
251  /* Restore status */
252  viafb_write_reg(SR1E, VIASR, RegSR1E);
253  viafb_write_reg(CR91, VIACR, RegCR91);
254  if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
255  viafb_write_reg(CR6B, VIACR, RegCR6B);
256  viafb_write_reg(CR93, VIACR, RegCR93);
257  } else {
258  viafb_write_reg(SR3E, VIASR, RegSR3E);
259  viafb_write_reg(CR9B, VIACR, RegCR9B);
260  }
261 
262  return ret;
263 }
264 
265 /* Query Flat Panel's EDID Table Version Through DVI Connector */
266 static int viafb_dvi_query_EDID(void)
267 {
268  u8 data0, data1;
269  int restore;
270 
271  DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n");
272 
273  restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
274  viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
275 
276  data0 = (u8) tmds_register_read(0x00);
277  data1 = (u8) tmds_register_read(0x01);
278  if ((data0 == 0) && (data1 == 0xFF)) {
279  viaparinfo->chip_info->
280  tmds_chip_info.tmds_chip_slave_addr = restore;
281  return EDID_VERSION_1; /* Found EDID1 Table */
282  }
283 
284  return false;
285 }
286 
287 /* Get Panel Size Using EDID1 Table */
288 static void __devinit dvi_get_panel_size_from_DDCv1(
289  struct tmds_chip_information *tmds_chip,
290  struct tmds_setting_information *tmds_setting)
291 {
292  int i, restore;
293  unsigned char EDID_DATA[18];
294 
295  DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
296 
297  restore = tmds_chip->tmds_chip_slave_addr;
298  tmds_chip->tmds_chip_slave_addr = 0xA0;
299  for (i = 0x25; i < 0x6D; i++) {
300  switch (i) {
301  case 0x36:
302  case 0x48:
303  case 0x5A:
304  case 0x6C:
305  tmds_register_read_bytes(i, EDID_DATA, 10);
306  if (!(EDID_DATA[0] || EDID_DATA[1])) {
307  /* The first two byte must be zero. */
308  if (EDID_DATA[3] == 0xFD) {
309  /* To get max pixel clock. */
310  tmds_setting->max_pixel_clock =
311  EDID_DATA[9] * 10;
312  }
313  }
314  break;
315 
316  default:
317  break;
318  }
319  }
320 
321  DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
322  tmds_setting->max_pixel_clock);
323  tmds_chip->tmds_chip_slave_addr = restore;
324 }
325 
326 /* If Disable DVI, turn off pad */
328 {
329  if (viaparinfo->chip_info->
330  tmds_chip_info.output_interface == INTERFACE_TMDS)
331  /* Turn off TMDS power. */
333  viafb_read_reg(VIACR, CRD2) | 0x08);
334 }
335 
336 static void dvi_patch_skew_dvp0(void)
337 {
338  /* Reset data driving first: */
341 
342  switch (viaparinfo->chip_info->gfx_chip_name) {
343  case UNICHROME_P4M890:
344  {
345  if ((viaparinfo->tmds_setting_info->h_active == 1600) &&
346  (viaparinfo->tmds_setting_info->v_active ==
347  1200))
349  BIT0 + BIT1 + BIT2);
350  else
352  BIT0 + BIT1 + BIT2);
353  break;
354  }
355 
356  case UNICHROME_P4M900:
357  {
359  BIT0 + BIT1 + BIT2 + BIT3);
362  break;
363  }
364 
365  default:
366  {
367  break;
368  }
369  }
370 }
371 
372 static void dvi_patch_skew_dvp_low(void)
373 {
374  switch (viaparinfo->chip_info->gfx_chip_name) {
375  case UNICHROME_K8M890:
376  {
378  break;
379  }
380 
381  case UNICHROME_P4M900:
382  {
384  BIT0 + BIT1 + BIT2 + BIT3);
385  break;
386  }
387 
388  case UNICHROME_P4M890:
389  {
391  BIT0 + BIT1 + BIT2 + BIT3);
392  break;
393  }
394 
395  default:
396  {
397  break;
398  }
399  }
400 }
401 
402 /* If Enable DVI, turn off pad */
404 {
405  u8 data;
406 
407  switch (viaparinfo->chip_info->tmds_chip_info.output_interface) {
408  case INTERFACE_DVP0:
411  dvi_patch_skew_dvp0();
412  if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
413  tmds_register_write(0x88, 0x3b);
414  else
415  /*clear CR91[5] to direct on display period
416  in the secondary diplay path */
417  via_write_reg_mask(VIACR, 0x91, 0x00, 0x20);
418  break;
419 
420  case INTERFACE_DVP1:
421  if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
423 
424  /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
425  if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
426  tmds_register_write(0x88, 0x3b);
427  else
428  /*clear CR91[5] to direct on display period
429  in the secondary diplay path */
430  via_write_reg_mask(VIACR, 0x91, 0x00, 0x20);
431 
432  /*fix DVI cannot enable on EPIA-M board */
433  if (viafb_platform_epia_dvi == 1) {
434  viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f);
436  if (viafb_bus_width == 24) {
437  if (viafb_device_lcd_dualedge == 1)
438  data = 0x3F;
439  else
440  data = 0x37;
441  viafb_i2c_writebyte(viaparinfo->chip_info->
442  tmds_chip_info.i2c_port,
443  viaparinfo->chip_info->
444  tmds_chip_info.tmds_chip_slave_addr,
445  0x08, data);
446  }
447  }
448  break;
449 
450  case INTERFACE_DFP_HIGH:
451  if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
452  via_write_reg_mask(VIACR, CR97, 0x03, 0x03);
453 
454  via_write_reg_mask(VIACR, 0x91, 0x00, 0x20);
455  break;
456 
457  case INTERFACE_DFP_LOW:
458  if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
459  break;
460 
461  dvi_patch_skew_dvp_low();
462  via_write_reg_mask(VIACR, 0x91, 0x00, 0x20);
463  break;
464 
465  case INTERFACE_TMDS:
466  /* Turn on Display period in the panel path. */
468 
469  /* Turn on TMDS power. */
471  break;
472  }
473 
474  if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
475  /* Disable LCD Scaling */
477  }
478 }