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 25static void tmds_register_write(int index, u8 data); 26static int tmds_register_read(int index); 27static int tmds_register_read_bytes(int index, u8 *buff, int buff_len); 28static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information 29 *tmds_chip, struct tmds_setting_information *tmds_setting); 30static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information 31 *tmds_chip, struct tmds_setting_information *tmds_setting); 32static int viafb_dvi_query_EDID(void); 33 34static 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 42void 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 63int 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 163static 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 170static 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 180static 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 */ 189void 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 */ 216int 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 */ 289static 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 */ 316static 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 */ 421static 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 */ 468void 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 */ 498void 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