Commit c09c782f3e7d38e1f3842822209bb6faff4a2b1b

Authored by Joseph Chan
Committed by Linus Torvalds
1 parent ae35e8106a

viafb: dvi.c, dvi.h, global.c and global.h

dvi.c, dvi.h: TMDS generic process and setting.
global.c, global.h: define global variabls.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Joseph Chan <josephchan@via.com.tw>
Cc: Krzysztof Helt <krzysztof.h1@poczta.fm>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 4 changed files with 896 additions and 0 deletions Side-by-side Diff

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 int check_reduce_blanking_mode(int mode_index,
  27 + int refresh_rate);
  28 +static int dvi_get_panel_size_from_DDCv1(void);
  29 +static int dvi_get_panel_size_from_DDCv2(void);
  30 +static unsigned char dvi_get_panel_info(void);
  31 +static int viafb_dvi_query_EDID(void);
  32 +
  33 +static int check_tmds_chip(int device_id_subaddr, int device_id)
  34 +{
  35 + if (tmds_register_read(device_id_subaddr) == device_id)
  36 + return OK;
  37 + else
  38 + return FAIL;
  39 +}
  40 +
  41 +void viafb_init_dvi_size(void)
  42 +{
  43 + DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
  44 + DEBUG_MSG(KERN_INFO
  45 + "viaparinfo->tmds_setting_info->get_dvi_size_method %d\n",
  46 + viaparinfo->tmds_setting_info->get_dvi_size_method);
  47 +
  48 + switch (viaparinfo->tmds_setting_info->get_dvi_size_method) {
  49 + case GET_DVI_SIZE_BY_SYSTEM_BIOS:
  50 + break;
  51 + case GET_DVI_SZIE_BY_HW_STRAPPING:
  52 + break;
  53 + case GET_DVI_SIZE_BY_VGA_BIOS:
  54 + default:
  55 + dvi_get_panel_info();
  56 + break;
  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->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->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->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 +static int check_reduce_blanking_mode(int mode_index,
  193 + int refresh_rate)
  194 +{
  195 + if (refresh_rate != 60)
  196 + return false;
  197 +
  198 + switch (mode_index) {
  199 + /* Following modes have reduce blanking mode. */
  200 + case VIA_RES_1360X768:
  201 + case VIA_RES_1400X1050:
  202 + case VIA_RES_1440X900:
  203 + case VIA_RES_1600X900:
  204 + case VIA_RES_1680X1050:
  205 + case VIA_RES_1920X1080:
  206 + case VIA_RES_1920X1200:
  207 + break;
  208 +
  209 + default:
  210 + DEBUG_MSG(KERN_INFO
  211 + "This dvi mode %d have no reduce blanking mode!\n",
  212 + mode_index);
  213 + return false;
  214 + }
  215 +
  216 + return true;
  217 +}
  218 +
  219 +/* DVI Set Mode */
  220 +void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga)
  221 +{
  222 + struct VideoModeTable *videoMode = NULL;
  223 + struct crt_mode_table *pDviTiming;
  224 + unsigned long desirePixelClock, maxPixelClock;
  225 + int status = 0;
  226 + videoMode = viafb_get_modetbl_pointer(video_index);
  227 + pDviTiming = videoMode->crtc;
  228 + desirePixelClock = pDviTiming->clk / 1000000;
  229 + maxPixelClock = (unsigned long)viaparinfo->
  230 + tmds_setting_info->max_pixel_clock;
  231 +
  232 + DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
  233 +
  234 + if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
  235 + /*Check if reduce-blanking mode is exist */
  236 + status =
  237 + check_reduce_blanking_mode(video_index,
  238 + pDviTiming->refresh_rate);
  239 + if (status) {
  240 + video_index += 100; /*Use reduce-blanking mode */
  241 + videoMode = viafb_get_modetbl_pointer(video_index);
  242 + pDviTiming = videoMode->crtc;
  243 + DEBUG_MSG(KERN_INFO
  244 + "DVI use reduce blanking mode %d!!\n",
  245 + video_index);
  246 + }
  247 + }
  248 + viafb_fill_crtc_timing(pDviTiming, video_index, mode_bpp / 8, set_iga);
  249 + viafb_set_output_path(DEVICE_DVI, set_iga,
  250 + viaparinfo->chip_info->tmds_chip_info.output_interface);
  251 +}
  252 +
  253 +/* Sense DVI Connector */
  254 +int viafb_dvi_sense(void)
  255 +{
  256 + u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0,
  257 + RegCR93 = 0, RegCR9B = 0, data;
  258 + int ret = false;
  259 +
  260 + DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n");
  261 +
  262 + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
  263 + /* DI1 Pad on */
  264 + RegSR1E = viafb_read_reg(VIASR, SR1E);
  265 + viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30);
  266 +
  267 + /* CR6B[0]VCK Input Selection: 1 = External clock. */
  268 + RegCR6B = viafb_read_reg(VIACR, CR6B);
  269 + viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08);
  270 +
  271 + /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
  272 + [0] Software Control Power Sequence */
  273 + RegCR91 = viafb_read_reg(VIACR, CR91);
  274 + viafb_write_reg(CR91, VIACR, 0x1D);
  275 +
  276 + /* CR93[7] DI1 Data Source Selection: 1 = DSP2.
  277 + CR93[5] DI1 Clock Source: 1 = internal.
  278 + CR93[4] DI1 Clock Polarity.
  279 + CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */
  280 + RegCR93 = viafb_read_reg(VIACR, CR93);
  281 + viafb_write_reg(CR93, VIACR, 0x01);
  282 + } else {
  283 + /* DVP0/DVP1 Pad on */
  284 + RegSR1E = viafb_read_reg(VIASR, SR1E);
  285 + viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0);
  286 +
  287 + /* SR3E[1]Multi-function selection:
  288 + 0 = Emulate I2C and DDC bus by GPIO2/3/4. */
  289 + RegSR3E = viafb_read_reg(VIASR, SR3E);
  290 + viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20));
  291 +
  292 + /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
  293 + [0] Software Control Power Sequence */
  294 + RegCR91 = viafb_read_reg(VIACR, CR91);
  295 + viafb_write_reg(CR91, VIACR, 0x1D);
  296 +
  297 + /*CR9B[4] DVP1 Data Source Selection: 1 = From secondary
  298 + display.CR9B[2:0] DVP1 Clock Adjust */
  299 + RegCR9B = viafb_read_reg(VIACR, CR9B);
  300 + viafb_write_reg(CR9B, VIACR, 0x01);
  301 + }
  302 +
  303 + data = (u8) tmds_register_read(0x09);
  304 + if (data & 0x04)
  305 + ret = true;
  306 +
  307 + if (ret == false) {
  308 + if (viafb_dvi_query_EDID())
  309 + ret = true;
  310 + }
  311 +
  312 + /* Restore status */
  313 + viafb_write_reg(SR1E, VIASR, RegSR1E);
  314 + viafb_write_reg(CR91, VIACR, RegCR91);
  315 + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
  316 + viafb_write_reg(CR6B, VIACR, RegCR6B);
  317 + viafb_write_reg(CR93, VIACR, RegCR93);
  318 + } else {
  319 + viafb_write_reg(SR3E, VIASR, RegSR3E);
  320 + viafb_write_reg(CR9B, VIACR, RegCR9B);
  321 + }
  322 +
  323 + return ret;
  324 +}
  325 +
  326 +/* Query Flat Panel's EDID Table Version Through DVI Connector */
  327 +static int viafb_dvi_query_EDID(void)
  328 +{
  329 + u8 data0, data1;
  330 + int restore;
  331 +
  332 + DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n");
  333 +
  334 + restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
  335 + viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
  336 +
  337 + data0 = (u8) tmds_register_read(0x00);
  338 + data1 = (u8) tmds_register_read(0x01);
  339 + if ((data0 == 0) && (data1 == 0xFF)) {
  340 + viaparinfo->chip_info->
  341 + tmds_chip_info.tmds_chip_slave_addr = restore;
  342 + return EDID_VERSION_1; /* Found EDID1 Table */
  343 + }
  344 +
  345 + data0 = (u8) tmds_register_read(0x00);
  346 + viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
  347 + if (data0 == 0x20)
  348 + return EDID_VERSION_2; /* Found EDID2 Table */
  349 + else
  350 + return false;
  351 +}
  352 +
  353 +/*
  354 + *
  355 + * int dvi_get_panel_size_from_DDCv1(void)
  356 + *
  357 + * - Get Panel Size Using EDID1 Table
  358 + *
  359 + * Return Type: int
  360 + *
  361 + */
  362 +static int dvi_get_panel_size_from_DDCv1(void)
  363 +{
  364 + int i, max_h = 0, max_v = 0, tmp, restore;
  365 + unsigned char rData;
  366 + unsigned char EDID_DATA[18];
  367 +
  368 + DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
  369 +
  370 + restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
  371 + viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
  372 +
  373 + rData = tmds_register_read(0x23);
  374 + if (rData & 0x3C)
  375 + max_h = 640;
  376 + if (rData & 0xC0)
  377 + max_h = 720;
  378 + if (rData & 0x03)
  379 + max_h = 800;
  380 +
  381 + rData = tmds_register_read(0x24);
  382 + if (rData & 0xC0)
  383 + max_h = 800;
  384 + if (rData & 0x1E)
  385 + max_h = 1024;
  386 + if (rData & 0x01)
  387 + max_h = 1280;
  388 +
  389 + for (i = 0x25; i < 0x6D; i++) {
  390 + switch (i) {
  391 + case 0x26:
  392 + case 0x28:
  393 + case 0x2A:
  394 + case 0x2C:
  395 + case 0x2E:
  396 + case 0x30:
  397 + case 0x32:
  398 + case 0x34:
  399 + rData = tmds_register_read(i);
  400 + if (rData == 1)
  401 + break;
  402 + /* data = (data + 31) * 8 */
  403 + tmp = (rData + 31) << 3;
  404 + if (tmp > max_h)
  405 + max_h = tmp;
  406 + break;
  407 +
  408 + case 0x36:
  409 + case 0x48:
  410 + case 0x5A:
  411 + case 0x6C:
  412 + tmds_register_read_bytes(i, EDID_DATA, 10);
  413 + if (!(EDID_DATA[0] || EDID_DATA[1])) {
  414 + /* The first two byte must be zero. */
  415 + if (EDID_DATA[3] == 0xFD) {
  416 + /* To get max pixel clock. */
  417 + viaparinfo->tmds_setting_info->
  418 + max_pixel_clock = EDID_DATA[9] * 10;
  419 + }
  420 + }
  421 + break;
  422 +
  423 + default:
  424 + break;
  425 + }
  426 + }
  427 +
  428 + switch (max_h) {
  429 + case 640:
  430 + viaparinfo->tmds_setting_info->dvi_panel_size =
  431 + VIA_RES_640X480;
  432 + break;
  433 + case 800:
  434 + viaparinfo->tmds_setting_info->dvi_panel_size =
  435 + VIA_RES_800X600;
  436 + break;
  437 + case 1024:
  438 + viaparinfo->tmds_setting_info->dvi_panel_size =
  439 + VIA_RES_1024X768;
  440 + break;
  441 + case 1280:
  442 + viaparinfo->tmds_setting_info->dvi_panel_size =
  443 + VIA_RES_1280X1024;
  444 + break;
  445 + case 1400:
  446 + viaparinfo->tmds_setting_info->dvi_panel_size =
  447 + VIA_RES_1400X1050;
  448 + break;
  449 + case 1440:
  450 + viaparinfo->tmds_setting_info->dvi_panel_size =
  451 + VIA_RES_1440X1050;
  452 + break;
  453 + case 1600:
  454 + viaparinfo->tmds_setting_info->dvi_panel_size =
  455 + VIA_RES_1600X1200;
  456 + break;
  457 + case 1920:
  458 + if (max_v == 1200) {
  459 + viaparinfo->tmds_setting_info->dvi_panel_size =
  460 + VIA_RES_1920X1200;
  461 + } else {
  462 + viaparinfo->tmds_setting_info->dvi_panel_size =
  463 + VIA_RES_1920X1080;
  464 + }
  465 +
  466 + break;
  467 + default:
  468 + viaparinfo->tmds_setting_info->dvi_panel_size =
  469 + VIA_RES_1024X768;
  470 + DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d !\
  471 + set default panel size.\n", max_h);
  472 + break;
  473 + }
  474 +
  475 + DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
  476 + viaparinfo->tmds_setting_info->max_pixel_clock);
  477 + viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
  478 + return viaparinfo->tmds_setting_info->dvi_panel_size;
  479 +}
  480 +
  481 +/*
  482 + *
  483 + * int dvi_get_panel_size_from_DDCv2(void)
  484 + *
  485 + * - Get Panel Size Using EDID2 Table
  486 + *
  487 + * Return Type: int
  488 + *
  489 + */
  490 +static int dvi_get_panel_size_from_DDCv2(void)
  491 +{
  492 + int HSize = 0, restore;
  493 + unsigned char R_Buffer[2];
  494 +
  495 + DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
  496 +
  497 + restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
  498 + viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
  499 +
  500 + /* Horizontal: 0x76, 0x77 */
  501 + tmds_register_read_bytes(0x76, R_Buffer, 2);
  502 + HSize = R_Buffer[0];
  503 + HSize += R_Buffer[1] << 8;
  504 +
  505 + switch (HSize) {
  506 + case 640:
  507 + viaparinfo->tmds_setting_info->dvi_panel_size =
  508 + VIA_RES_640X480;
  509 + break;
  510 + case 800:
  511 + viaparinfo->tmds_setting_info->dvi_panel_size =
  512 + VIA_RES_800X600;
  513 + break;
  514 + case 1024:
  515 + viaparinfo->tmds_setting_info->dvi_panel_size =
  516 + VIA_RES_1024X768;
  517 + break;
  518 + case 1280:
  519 + viaparinfo->tmds_setting_info->dvi_panel_size =
  520 + VIA_RES_1280X1024;
  521 + break;
  522 + case 1400:
  523 + viaparinfo->tmds_setting_info->dvi_panel_size =
  524 + VIA_RES_1400X1050;
  525 + break;
  526 + case 1440:
  527 + viaparinfo->tmds_setting_info->dvi_panel_size =
  528 + VIA_RES_1440X1050;
  529 + break;
  530 + case 1600:
  531 + viaparinfo->tmds_setting_info->dvi_panel_size =
  532 + VIA_RES_1600X1200;
  533 + break;
  534 + default:
  535 + viaparinfo->tmds_setting_info->dvi_panel_size =
  536 + VIA_RES_1024X768;
  537 + DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d!\
  538 + set default panel size.\n", HSize);
  539 + break;
  540 + }
  541 +
  542 + viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
  543 + return viaparinfo->tmds_setting_info->dvi_panel_size;
  544 +}
  545 +
  546 +/*
  547 + *
  548 + * unsigned char dvi_get_panel_info(void)
  549 + *
  550 + * - Get Panel Size
  551 + *
  552 + * Return Type: unsigned char
  553 + */
  554 +static unsigned char dvi_get_panel_info(void)
  555 +{
  556 + unsigned char dvipanelsize;
  557 + DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
  558 +
  559 + viafb_dvi_sense();
  560 + switch (viafb_dvi_query_EDID()) {
  561 + case 1:
  562 + dvi_get_panel_size_from_DDCv1();
  563 + break;
  564 + case 2:
  565 + dvi_get_panel_size_from_DDCv2();
  566 + break;
  567 + default:
  568 + break;
  569 + }
  570 +
  571 + DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n",
  572 + viaparinfo->tmds_setting_info->dvi_panel_size);
  573 + dvipanelsize = (unsigned char)(viaparinfo->
  574 + tmds_setting_info->dvi_panel_size);
  575 + return dvipanelsize;
  576 +}
  577 +
  578 +/* If Disable DVI, turn off pad */
  579 +void viafb_dvi_disable(void)
  580 +{
  581 + if (viaparinfo->chip_info->
  582 + tmds_chip_info.output_interface == INTERFACE_DVP0)
  583 + viafb_write_reg(SR1E, VIASR,
  584 + viafb_read_reg(VIASR, SR1E) & (~0xC0));
  585 +
  586 + if (viaparinfo->chip_info->
  587 + tmds_chip_info.output_interface == INTERFACE_DVP1)
  588 + viafb_write_reg(SR1E, VIASR,
  589 + viafb_read_reg(VIASR, SR1E) & (~0x30));
  590 +
  591 + if (viaparinfo->chip_info->
  592 + tmds_chip_info.output_interface == INTERFACE_DFP_HIGH)
  593 + viafb_write_reg(SR2A, VIASR,
  594 + viafb_read_reg(VIASR, SR2A) & (~0x0C));
  595 +
  596 + if (viaparinfo->chip_info->
  597 + tmds_chip_info.output_interface == INTERFACE_DFP_LOW)
  598 + viafb_write_reg(SR2A, VIASR,
  599 + viafb_read_reg(VIASR, SR2A) & (~0x03));
  600 +
  601 + if (viaparinfo->chip_info->
  602 + tmds_chip_info.output_interface == INTERFACE_TMDS)
  603 + /* Turn off TMDS power. */
  604 + viafb_write_reg(CRD2, VIACR,
  605 + viafb_read_reg(VIACR, CRD2) | 0x08);
  606 +}
  607 +
  608 +/* If Enable DVI, turn off pad */
  609 +void viafb_dvi_enable(void)
  610 +{
  611 + u8 data;
  612 +
  613 + if (viaparinfo->chip_info->
  614 + tmds_chip_info.output_interface == INTERFACE_DVP0) {
  615 + viafb_write_reg(SR1E, VIASR,
  616 + viafb_read_reg(VIASR, SR1E) | 0xC0);
  617 + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
  618 + tmds_register_write(0x88, 0x3b);
  619 + else
  620 + /*clear CR91[5] to direct on display period
  621 + in the secondary diplay path */
  622 + viafb_write_reg(CR91, VIACR,
  623 + viafb_read_reg(VIACR, CR91) & 0xDF);
  624 + }
  625 +
  626 + if (viaparinfo->chip_info->
  627 + tmds_chip_info.output_interface == INTERFACE_DVP1) {
  628 + viafb_write_reg(SR1E, VIASR,
  629 + viafb_read_reg(VIASR, SR1E) | 0x30);
  630 +
  631 + /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
  632 + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
  633 + tmds_register_write(0x88, 0x3b);
  634 + } else {
  635 + /*clear CR91[5] to direct on display period
  636 + in the secondary diplay path */
  637 + viafb_write_reg(CR91, VIACR,
  638 + viafb_read_reg(VIACR, CR91) & 0xDF);
  639 + }
  640 +
  641 + /*fix DVI cannot enable on EPIA-M board */
  642 + if (viafb_platform_epia_dvi == 1) {
  643 + viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f);
  644 + viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0);
  645 + if (viafb_bus_width == 24) {
  646 + if (viafb_device_lcd_dualedge == 1)
  647 + data = 0x3F;
  648 + else
  649 + data = 0x37;
  650 + viafb_i2c_writebyte(viaparinfo->chip_info->
  651 + tmds_chip_info.
  652 + tmds_chip_slave_addr,
  653 + 0x08, data);
  654 + }
  655 + }
  656 + }
  657 +
  658 + if (viaparinfo->chip_info->
  659 + tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) {
  660 + viafb_write_reg(SR2A, VIASR,
  661 + viafb_read_reg(VIASR, SR2A) | 0x0C);
  662 + viafb_write_reg(CR91, VIACR,
  663 + viafb_read_reg(VIACR, CR91) & 0xDF);
  664 + }
  665 +
  666 + if (viaparinfo->chip_info->
  667 + tmds_chip_info.output_interface == INTERFACE_DFP_LOW) {
  668 + viafb_write_reg(SR2A, VIASR,
  669 + viafb_read_reg(VIASR, SR2A) | 0x03);
  670 + viafb_write_reg(CR91, VIACR,
  671 + viafb_read_reg(VIACR, CR91) & 0xDF);
  672 + }
  673 + if (viaparinfo->chip_info->
  674 + tmds_chip_info.output_interface == INTERFACE_TMDS) {
  675 + /* Turn on Display period in the panel path. */
  676 + viafb_write_reg_mask(CR91, VIACR, 0, BIT7);
  677 +
  678 + /* Turn on TMDS power. */
  679 + viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);
  680 + }
  681 +}
drivers/video/via/dvi.h
  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 +
  22 +#ifndef __DVI_H__
  23 +#define __DVI_H__
  24 +
  25 +/*Definition TMDS Device ID register*/
  26 +#define VT1632_DEVICE_ID_REG 0x02
  27 +#define VT1632_DEVICE_ID 0x92
  28 +
  29 +#define GET_DVI_SIZE_BY_SYSTEM_BIOS 0x01
  30 +#define GET_DVI_SIZE_BY_VGA_BIOS 0x02
  31 +#define GET_DVI_SZIE_BY_HW_STRAPPING 0x03
  32 +
  33 +/* Definition DVI Panel ID*/
  34 +/* Resolution: 640x480, Channel: single, Dithering: Enable */
  35 +#define DVI_PANEL_ID0_640X480 0x00
  36 +/* Resolution: 800x600, Channel: single, Dithering: Enable */
  37 +#define DVI_PANEL_ID1_800x600 0x01
  38 +/* Resolution: 1024x768, Channel: single, Dithering: Enable */
  39 +#define DVI_PANEL_ID1_1024x768 0x02
  40 +/* Resolution: 1280x768, Channel: single, Dithering: Enable */
  41 +#define DVI_PANEL_ID1_1280x768 0x03
  42 +/* Resolution: 1280x1024, Channel: dual, Dithering: Enable */
  43 +#define DVI_PANEL_ID1_1280x1024 0x04
  44 +/* Resolution: 1400x1050, Channel: dual, Dithering: Enable */
  45 +#define DVI_PANEL_ID1_1400x1050 0x05
  46 +/* Resolution: 1600x1200, Channel: dual, Dithering: Enable */
  47 +#define DVI_PANEL_ID1_1600x1200 0x06
  48 +
  49 +/* Define the version of EDID*/
  50 +#define EDID_VERSION_1 1
  51 +#define EDID_VERSION_2 2
  52 +
  53 +#define DEV_CONNECT_DVI 0x01
  54 +#define DEV_CONNECT_HDMI 0x02
  55 +
  56 +struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index);
  57 +int viafb_dvi_sense(void);
  58 +void viafb_dvi_disable(void);
  59 +void viafb_dvi_enable(void);
  60 +int viafb_tmds_trasmitter_identify(void);
  61 +void viafb_init_dvi_size(void);
  62 +void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga);
  63 +
  64 +#endif /* __DVI_H__ */
drivers/video/via/global.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 +int viafb_platform_epia_dvi = STATE_OFF;
  23 +int viafb_device_lcd_dualedge = STATE_OFF;
  24 +int viafb_bus_width = 12;
  25 +int viafb_display_hardware_layout = HW_LAYOUT_LCD_DVI;
  26 +int viafb_memsize;
  27 +int viafb_DeviceStatus = CRT_Device;
  28 +int viafb_hotplug;
  29 +int viafb_refresh = 60;
  30 +int viafb_refresh1 = 60;
  31 +int viafb_lcd_dsp_method = LCD_EXPANDSION;
  32 +int viafb_lcd_mode = LCD_OPENLDI;
  33 +int viafb_bpp = 32;
  34 +int viafb_bpp1 = 32;
  35 +int viafb_accel = 1;
  36 +int viafb_CRT_ON = 1;
  37 +int viafb_DVI_ON;
  38 +int viafb_LCD_ON ;
  39 +int viafb_LCD2_ON;
  40 +int viafb_SAMM_ON;
  41 +int viafb_dual_fb;
  42 +int viafb_hotplug_Xres = 640;
  43 +int viafb_hotplug_Yres = 480;
  44 +int viafb_hotplug_bpp = 32;
  45 +int viafb_hotplug_refresh = 60;
  46 +unsigned int viafb_second_offset;
  47 +int viafb_second_size;
  48 +int viafb_primary_dev = None_Device;
  49 +void __iomem *viafb_FB_MM;
  50 +unsigned int viafb_second_xres = 640;
  51 +unsigned int viafb_second_yres = 480;
  52 +unsigned int viafb_second_virtual_xres;
  53 +unsigned int viafb_second_virtual_yres;
  54 +int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1;
  55 +struct fb_cursor viacursor;
  56 +struct fb_info *viafbinfo;
  57 +struct fb_info *viafbinfo1;
  58 +struct viafb_par *viaparinfo;
  59 +struct viafb_par *viaparinfo1;
drivers/video/via/global.h
  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 +
  22 +#ifndef __GLOBAL_H__
  23 +#define __GLOBAL_H__
  24 +
  25 +#include <linux/fb.h>
  26 +#include <linux/delay.h>
  27 +#include <linux/ioport.h>
  28 +#include <linux/pci.h>
  29 +#include <linux/io.h>
  30 +#include <linux/uaccess.h>
  31 +#include <linux/init.h>
  32 +#include <linux/proc_fs.h>
  33 +#include <linux/console.h>
  34 +#include <linux/timer.h>
  35 +
  36 +#include "debug.h"
  37 +
  38 +#include "iface.h"
  39 +#include "viafbdev.h"
  40 +#include "chip.h"
  41 +#include "debug.h"
  42 +#include "accel.h"
  43 +#include "share.h"
  44 +#include "dvi.h"
  45 +#include "viamode.h"
  46 +#include "via_i2c.h"
  47 +#include "hw.h"
  48 +
  49 +#include "lcd.h"
  50 +#include "ioctl.h"
  51 +#include "viamode.h"
  52 +#include "via_utility.h"
  53 +#include "vt1636.h"
  54 +#include "tblDPASetting.h"
  55 +#include "tbl1636.h"
  56 +#include "viafbdev.h"
  57 +
  58 +/* External struct*/
  59 +
  60 +extern int viafb_platform_epia_dvi;
  61 +extern int viafb_device_lcd_dualedge;
  62 +extern int viafb_bus_width;
  63 +extern int viafb_display_hardware_layout;
  64 +extern struct offset offset_reg;
  65 +extern struct viafb_par *viaparinfo;
  66 +extern struct viafb_par *viaparinfo1;
  67 +extern struct fb_info *viafbinfo;
  68 +extern struct fb_info *viafbinfo1;
  69 +extern int viafb_DeviceStatus;
  70 +extern int viafb_refresh;
  71 +extern int viafb_refresh1;
  72 +extern int viafb_lcd_dsp_method;
  73 +extern int viafb_lcd_mode;
  74 +extern int viafb_bpp;
  75 +extern int viafb_bpp1;
  76 +
  77 +extern int viafb_CRT_ON;
  78 +extern int viafb_hotplug_Xres;
  79 +extern int viafb_hotplug_Yres;
  80 +extern int viafb_hotplug_bpp;
  81 +extern int viafb_hotplug_refresh;
  82 +extern int viafb_primary_dev;
  83 +extern void __iomem *viafb_FB_MM;
  84 +extern struct fb_cursor viacursor;
  85 +
  86 +extern unsigned int viafb_second_xres;
  87 +extern unsigned int viafb_second_yres;
  88 +extern int viafb_lcd_panel_id;
  89 +
  90 +#endif /* __GLOBAL_H__ */