c4df5489e4
This patch introduces viafb_shared and is the beginning of a smooth transition to use it. viafb_shared should contain all general, non-surface specific data that should be shared along all viafb framebuffers while viafb_par should only contain things that are specific to each surface or in other words extend fb_info. This change is intended to clean the dual/multi framebuffer handling up. This removes the annoyance that viafbinfo1->par points to a different structure than viaparinfo1. As the last change is fundamental it is difficult to ensure that all parts of the driver do not depend on the previous brokenness but the chance of regressions is very low. Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> Cc: Scott Fang <ScottFang@viatech.com.cn> Cc: Joseph Chan <JosephChan@via.com.tw> Cc: Harald Welte <laforge@gnumonks.org> Cc: Jonathan Corbet <corbet@lwn.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
683 lines
18 KiB
C
683 lines
18 KiB
C
/*
|
|
* Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
|
|
* Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public
|
|
* License as published by the Free Software Foundation;
|
|
* either version 2, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
|
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
* A PARTICULAR PURPOSE.See the GNU General Public License
|
|
* for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc.,
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
#include "global.h"
|
|
|
|
static void tmds_register_write(int index, u8 data);
|
|
static int tmds_register_read(int index);
|
|
static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
|
|
static int check_reduce_blanking_mode(int mode_index,
|
|
int refresh_rate);
|
|
static int dvi_get_panel_size_from_DDCv1(void);
|
|
static int dvi_get_panel_size_from_DDCv2(void);
|
|
static unsigned char dvi_get_panel_info(void);
|
|
static int viafb_dvi_query_EDID(void);
|
|
|
|
static int check_tmds_chip(int device_id_subaddr, int device_id)
|
|
{
|
|
if (tmds_register_read(device_id_subaddr) == device_id)
|
|
return OK;
|
|
else
|
|
return FAIL;
|
|
}
|
|
|
|
void viafb_init_dvi_size(void)
|
|
{
|
|
DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
|
|
DEBUG_MSG(KERN_INFO
|
|
"viaparinfo->tmds_setting_info->get_dvi_size_method %d\n",
|
|
viaparinfo->tmds_setting_info->get_dvi_size_method);
|
|
|
|
switch (viaparinfo->tmds_setting_info->get_dvi_size_method) {
|
|
case GET_DVI_SIZE_BY_SYSTEM_BIOS:
|
|
break;
|
|
case GET_DVI_SZIE_BY_HW_STRAPPING:
|
|
break;
|
|
case GET_DVI_SIZE_BY_VGA_BIOS:
|
|
default:
|
|
dvi_get_panel_info();
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
int viafb_tmds_trasmitter_identify(void)
|
|
{
|
|
unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
|
|
|
|
/* Turn on ouputting pad */
|
|
switch (viaparinfo->chip_info->gfx_chip_name) {
|
|
case UNICHROME_K8M890:
|
|
/*=* DFP Low Pad on *=*/
|
|
sr2a = viafb_read_reg(VIASR, SR2A);
|
|
viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
|
|
break;
|
|
|
|
case UNICHROME_P4M900:
|
|
case UNICHROME_P4M890:
|
|
/* DFP Low Pad on */
|
|
sr2a = viafb_read_reg(VIASR, SR2A);
|
|
viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
|
|
/* DVP0 Pad on */
|
|
sr1e = viafb_read_reg(VIASR, SR1E);
|
|
viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7);
|
|
break;
|
|
|
|
default:
|
|
/* DVP0/DVP1 Pad on */
|
|
sr1e = viafb_read_reg(VIASR, SR1E);
|
|
viafb_write_reg_mask(SR1E, VIASR, 0xF0, BIT4 +
|
|
BIT5 + BIT6 + BIT7);
|
|
/* SR3E[1]Multi-function selection:
|
|
0 = Emulate I2C and DDC bus by GPIO2/3/4. */
|
|
sr3e = viafb_read_reg(VIASR, SR3E);
|
|
viafb_write_reg_mask(SR3E, VIASR, 0x0, BIT5);
|
|
break;
|
|
}
|
|
|
|
/* Check for VT1632: */
|
|
viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
|
|
viaparinfo->chip_info->
|
|
tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
|
|
viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX;
|
|
if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) {
|
|
/*
|
|
* Currently only support 12bits,dual edge,add 24bits mode later
|
|
*/
|
|
tmds_register_write(0x08, 0x3b);
|
|
|
|
DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
|
|
DEBUG_MSG(KERN_INFO "\n %2d",
|
|
viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
|
|
DEBUG_MSG(KERN_INFO "\n %2d",
|
|
viaparinfo->chip_info->tmds_chip_info.i2c_port);
|
|
return OK;
|
|
} else {
|
|
viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX;
|
|
if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)
|
|
!= FAIL) {
|
|
tmds_register_write(0x08, 0x3b);
|
|
DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
|
|
DEBUG_MSG(KERN_INFO "\n %2d",
|
|
viaparinfo->chip_info->
|
|
tmds_chip_info.tmds_chip_name);
|
|
DEBUG_MSG(KERN_INFO "\n %2d",
|
|
viaparinfo->chip_info->
|
|
tmds_chip_info.i2c_port);
|
|
return OK;
|
|
}
|
|
}
|
|
|
|
viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS;
|
|
|
|
if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) &&
|
|
((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) ||
|
|
(viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) {
|
|
DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n");
|
|
return OK;
|
|
}
|
|
|
|
switch (viaparinfo->chip_info->gfx_chip_name) {
|
|
case UNICHROME_K8M890:
|
|
viafb_write_reg(SR2A, VIASR, sr2a);
|
|
break;
|
|
|
|
case UNICHROME_P4M900:
|
|
case UNICHROME_P4M890:
|
|
viafb_write_reg(SR2A, VIASR, sr2a);
|
|
viafb_write_reg(SR1E, VIASR, sr1e);
|
|
break;
|
|
|
|
default:
|
|
viafb_write_reg(SR1E, VIASR, sr1e);
|
|
viafb_write_reg(SR3E, VIASR, sr3e);
|
|
break;
|
|
}
|
|
|
|
viaparinfo->chip_info->
|
|
tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
|
|
viaparinfo->chip_info->tmds_chip_info.
|
|
tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
|
|
return FAIL;
|
|
}
|
|
|
|
static void tmds_register_write(int index, u8 data)
|
|
{
|
|
viaparinfo->shared->i2c_stuff.i2c_port =
|
|
viaparinfo->chip_info->tmds_chip_info.i2c_port;
|
|
|
|
viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.
|
|
tmds_chip_slave_addr, index,
|
|
data);
|
|
}
|
|
|
|
static int tmds_register_read(int index)
|
|
{
|
|
u8 data;
|
|
|
|
viaparinfo->shared->i2c_stuff.i2c_port =
|
|
viaparinfo->chip_info->tmds_chip_info.i2c_port;
|
|
viafb_i2c_readbyte((u8) viaparinfo->chip_info->
|
|
tmds_chip_info.tmds_chip_slave_addr,
|
|
(u8) index, &data);
|
|
return data;
|
|
}
|
|
|
|
static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
|
|
{
|
|
viaparinfo->shared->i2c_stuff.i2c_port =
|
|
viaparinfo->chip_info->tmds_chip_info.i2c_port;
|
|
viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info.
|
|
tmds_chip_slave_addr, (u8) index, buff, buff_len);
|
|
return 0;
|
|
}
|
|
|
|
static int check_reduce_blanking_mode(int mode_index,
|
|
int refresh_rate)
|
|
{
|
|
if (refresh_rate != 60)
|
|
return false;
|
|
|
|
switch (mode_index) {
|
|
/* Following modes have reduce blanking mode. */
|
|
case VIA_RES_1360X768:
|
|
case VIA_RES_1400X1050:
|
|
case VIA_RES_1440X900:
|
|
case VIA_RES_1600X900:
|
|
case VIA_RES_1680X1050:
|
|
case VIA_RES_1920X1080:
|
|
case VIA_RES_1920X1200:
|
|
break;
|
|
|
|
default:
|
|
DEBUG_MSG(KERN_INFO
|
|
"This dvi mode %d have no reduce blanking mode!\n",
|
|
mode_index);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* DVI Set Mode */
|
|
void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga)
|
|
{
|
|
struct VideoModeTable *videoMode = NULL;
|
|
struct crt_mode_table *pDviTiming;
|
|
unsigned long desirePixelClock, maxPixelClock;
|
|
int status = 0;
|
|
videoMode = viafb_get_modetbl_pointer(video_index);
|
|
pDviTiming = videoMode->crtc;
|
|
desirePixelClock = pDviTiming->clk / 1000000;
|
|
maxPixelClock = (unsigned long)viaparinfo->
|
|
tmds_setting_info->max_pixel_clock;
|
|
|
|
DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
|
|
|
|
if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
|
|
/*Check if reduce-blanking mode is exist */
|
|
status =
|
|
check_reduce_blanking_mode(video_index,
|
|
pDviTiming->refresh_rate);
|
|
if (status) {
|
|
video_index += 100; /*Use reduce-blanking mode */
|
|
videoMode = viafb_get_modetbl_pointer(video_index);
|
|
pDviTiming = videoMode->crtc;
|
|
DEBUG_MSG(KERN_INFO
|
|
"DVI use reduce blanking mode %d!!\n",
|
|
video_index);
|
|
}
|
|
}
|
|
viafb_fill_crtc_timing(pDviTiming, video_index, mode_bpp / 8, set_iga);
|
|
viafb_set_output_path(DEVICE_DVI, set_iga,
|
|
viaparinfo->chip_info->tmds_chip_info.output_interface);
|
|
}
|
|
|
|
/* Sense DVI Connector */
|
|
int viafb_dvi_sense(void)
|
|
{
|
|
u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0,
|
|
RegCR93 = 0, RegCR9B = 0, data;
|
|
int ret = false;
|
|
|
|
DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n");
|
|
|
|
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
|
|
/* DI1 Pad on */
|
|
RegSR1E = viafb_read_reg(VIASR, SR1E);
|
|
viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30);
|
|
|
|
/* CR6B[0]VCK Input Selection: 1 = External clock. */
|
|
RegCR6B = viafb_read_reg(VIACR, CR6B);
|
|
viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08);
|
|
|
|
/* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
|
|
[0] Software Control Power Sequence */
|
|
RegCR91 = viafb_read_reg(VIACR, CR91);
|
|
viafb_write_reg(CR91, VIACR, 0x1D);
|
|
|
|
/* CR93[7] DI1 Data Source Selection: 1 = DSP2.
|
|
CR93[5] DI1 Clock Source: 1 = internal.
|
|
CR93[4] DI1 Clock Polarity.
|
|
CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */
|
|
RegCR93 = viafb_read_reg(VIACR, CR93);
|
|
viafb_write_reg(CR93, VIACR, 0x01);
|
|
} else {
|
|
/* DVP0/DVP1 Pad on */
|
|
RegSR1E = viafb_read_reg(VIASR, SR1E);
|
|
viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0);
|
|
|
|
/* SR3E[1]Multi-function selection:
|
|
0 = Emulate I2C and DDC bus by GPIO2/3/4. */
|
|
RegSR3E = viafb_read_reg(VIASR, SR3E);
|
|
viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20));
|
|
|
|
/* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
|
|
[0] Software Control Power Sequence */
|
|
RegCR91 = viafb_read_reg(VIACR, CR91);
|
|
viafb_write_reg(CR91, VIACR, 0x1D);
|
|
|
|
/*CR9B[4] DVP1 Data Source Selection: 1 = From secondary
|
|
display.CR9B[2:0] DVP1 Clock Adjust */
|
|
RegCR9B = viafb_read_reg(VIACR, CR9B);
|
|
viafb_write_reg(CR9B, VIACR, 0x01);
|
|
}
|
|
|
|
data = (u8) tmds_register_read(0x09);
|
|
if (data & 0x04)
|
|
ret = true;
|
|
|
|
if (ret == false) {
|
|
if (viafb_dvi_query_EDID())
|
|
ret = true;
|
|
}
|
|
|
|
/* Restore status */
|
|
viafb_write_reg(SR1E, VIASR, RegSR1E);
|
|
viafb_write_reg(CR91, VIACR, RegCR91);
|
|
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
|
|
viafb_write_reg(CR6B, VIACR, RegCR6B);
|
|
viafb_write_reg(CR93, VIACR, RegCR93);
|
|
} else {
|
|
viafb_write_reg(SR3E, VIASR, RegSR3E);
|
|
viafb_write_reg(CR9B, VIACR, RegCR9B);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* Query Flat Panel's EDID Table Version Through DVI Connector */
|
|
static int viafb_dvi_query_EDID(void)
|
|
{
|
|
u8 data0, data1;
|
|
int restore;
|
|
|
|
DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n");
|
|
|
|
restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
|
|
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
|
|
|
|
data0 = (u8) tmds_register_read(0x00);
|
|
data1 = (u8) tmds_register_read(0x01);
|
|
if ((data0 == 0) && (data1 == 0xFF)) {
|
|
viaparinfo->chip_info->
|
|
tmds_chip_info.tmds_chip_slave_addr = restore;
|
|
return EDID_VERSION_1; /* Found EDID1 Table */
|
|
}
|
|
|
|
data0 = (u8) tmds_register_read(0x00);
|
|
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
|
|
if (data0 == 0x20)
|
|
return EDID_VERSION_2; /* Found EDID2 Table */
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
*
|
|
* int dvi_get_panel_size_from_DDCv1(void)
|
|
*
|
|
* - Get Panel Size Using EDID1 Table
|
|
*
|
|
* Return Type: int
|
|
*
|
|
*/
|
|
static int dvi_get_panel_size_from_DDCv1(void)
|
|
{
|
|
int i, max_h = 0, max_v = 0, tmp, restore;
|
|
unsigned char rData;
|
|
unsigned char EDID_DATA[18];
|
|
|
|
DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
|
|
|
|
restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
|
|
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
|
|
|
|
rData = tmds_register_read(0x23);
|
|
if (rData & 0x3C)
|
|
max_h = 640;
|
|
if (rData & 0xC0)
|
|
max_h = 720;
|
|
if (rData & 0x03)
|
|
max_h = 800;
|
|
|
|
rData = tmds_register_read(0x24);
|
|
if (rData & 0xC0)
|
|
max_h = 800;
|
|
if (rData & 0x1E)
|
|
max_h = 1024;
|
|
if (rData & 0x01)
|
|
max_h = 1280;
|
|
|
|
for (i = 0x25; i < 0x6D; i++) {
|
|
switch (i) {
|
|
case 0x26:
|
|
case 0x28:
|
|
case 0x2A:
|
|
case 0x2C:
|
|
case 0x2E:
|
|
case 0x30:
|
|
case 0x32:
|
|
case 0x34:
|
|
rData = tmds_register_read(i);
|
|
if (rData == 1)
|
|
break;
|
|
/* data = (data + 31) * 8 */
|
|
tmp = (rData + 31) << 3;
|
|
if (tmp > max_h)
|
|
max_h = tmp;
|
|
break;
|
|
|
|
case 0x36:
|
|
case 0x48:
|
|
case 0x5A:
|
|
case 0x6C:
|
|
tmds_register_read_bytes(i, EDID_DATA, 10);
|
|
if (!(EDID_DATA[0] || EDID_DATA[1])) {
|
|
/* The first two byte must be zero. */
|
|
if (EDID_DATA[3] == 0xFD) {
|
|
/* To get max pixel clock. */
|
|
viaparinfo->tmds_setting_info->
|
|
max_pixel_clock = EDID_DATA[9] * 10;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (max_h) {
|
|
case 640:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_640X480;
|
|
break;
|
|
case 800:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_800X600;
|
|
break;
|
|
case 1024:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1024X768;
|
|
break;
|
|
case 1280:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1280X1024;
|
|
break;
|
|
case 1400:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1400X1050;
|
|
break;
|
|
case 1440:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1440X1050;
|
|
break;
|
|
case 1600:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1600X1200;
|
|
break;
|
|
case 1920:
|
|
if (max_v == 1200) {
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1920X1200;
|
|
} else {
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1920X1080;
|
|
}
|
|
|
|
break;
|
|
default:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1024X768;
|
|
DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d !\
|
|
set default panel size.\n", max_h);
|
|
break;
|
|
}
|
|
|
|
DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
|
|
viaparinfo->tmds_setting_info->max_pixel_clock);
|
|
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
|
|
return viaparinfo->tmds_setting_info->dvi_panel_size;
|
|
}
|
|
|
|
/*
|
|
*
|
|
* int dvi_get_panel_size_from_DDCv2(void)
|
|
*
|
|
* - Get Panel Size Using EDID2 Table
|
|
*
|
|
* Return Type: int
|
|
*
|
|
*/
|
|
static int dvi_get_panel_size_from_DDCv2(void)
|
|
{
|
|
int HSize = 0, restore;
|
|
unsigned char R_Buffer[2];
|
|
|
|
DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
|
|
|
|
restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
|
|
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
|
|
|
|
/* Horizontal: 0x76, 0x77 */
|
|
tmds_register_read_bytes(0x76, R_Buffer, 2);
|
|
HSize = R_Buffer[0];
|
|
HSize += R_Buffer[1] << 8;
|
|
|
|
switch (HSize) {
|
|
case 640:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_640X480;
|
|
break;
|
|
case 800:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_800X600;
|
|
break;
|
|
case 1024:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1024X768;
|
|
break;
|
|
case 1280:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1280X1024;
|
|
break;
|
|
case 1400:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1400X1050;
|
|
break;
|
|
case 1440:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1440X1050;
|
|
break;
|
|
case 1600:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1600X1200;
|
|
break;
|
|
default:
|
|
viaparinfo->tmds_setting_info->dvi_panel_size =
|
|
VIA_RES_1024X768;
|
|
DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d!\
|
|
set default panel size.\n", HSize);
|
|
break;
|
|
}
|
|
|
|
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
|
|
return viaparinfo->tmds_setting_info->dvi_panel_size;
|
|
}
|
|
|
|
/*
|
|
*
|
|
* unsigned char dvi_get_panel_info(void)
|
|
*
|
|
* - Get Panel Size
|
|
*
|
|
* Return Type: unsigned char
|
|
*/
|
|
static unsigned char dvi_get_panel_info(void)
|
|
{
|
|
unsigned char dvipanelsize;
|
|
DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
|
|
|
|
viafb_dvi_sense();
|
|
switch (viafb_dvi_query_EDID()) {
|
|
case 1:
|
|
dvi_get_panel_size_from_DDCv1();
|
|
break;
|
|
case 2:
|
|
dvi_get_panel_size_from_DDCv2();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n",
|
|
viaparinfo->tmds_setting_info->dvi_panel_size);
|
|
dvipanelsize = (unsigned char)(viaparinfo->
|
|
tmds_setting_info->dvi_panel_size);
|
|
return dvipanelsize;
|
|
}
|
|
|
|
/* If Disable DVI, turn off pad */
|
|
void viafb_dvi_disable(void)
|
|
{
|
|
if (viaparinfo->chip_info->
|
|
tmds_chip_info.output_interface == INTERFACE_DVP0)
|
|
viafb_write_reg(SR1E, VIASR,
|
|
viafb_read_reg(VIASR, SR1E) & (~0xC0));
|
|
|
|
if (viaparinfo->chip_info->
|
|
tmds_chip_info.output_interface == INTERFACE_DVP1)
|
|
viafb_write_reg(SR1E, VIASR,
|
|
viafb_read_reg(VIASR, SR1E) & (~0x30));
|
|
|
|
if (viaparinfo->chip_info->
|
|
tmds_chip_info.output_interface == INTERFACE_DFP_HIGH)
|
|
viafb_write_reg(SR2A, VIASR,
|
|
viafb_read_reg(VIASR, SR2A) & (~0x0C));
|
|
|
|
if (viaparinfo->chip_info->
|
|
tmds_chip_info.output_interface == INTERFACE_DFP_LOW)
|
|
viafb_write_reg(SR2A, VIASR,
|
|
viafb_read_reg(VIASR, SR2A) & (~0x03));
|
|
|
|
if (viaparinfo->chip_info->
|
|
tmds_chip_info.output_interface == INTERFACE_TMDS)
|
|
/* Turn off TMDS power. */
|
|
viafb_write_reg(CRD2, VIACR,
|
|
viafb_read_reg(VIACR, CRD2) | 0x08);
|
|
}
|
|
|
|
/* If Enable DVI, turn off pad */
|
|
void viafb_dvi_enable(void)
|
|
{
|
|
u8 data;
|
|
|
|
if (viaparinfo->chip_info->
|
|
tmds_chip_info.output_interface == INTERFACE_DVP0) {
|
|
viafb_write_reg(SR1E, VIASR,
|
|
viafb_read_reg(VIASR, SR1E) | 0xC0);
|
|
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
|
|
tmds_register_write(0x88, 0x3b);
|
|
else
|
|
/*clear CR91[5] to direct on display period
|
|
in the secondary diplay path */
|
|
viafb_write_reg(CR91, VIACR,
|
|
viafb_read_reg(VIACR, CR91) & 0xDF);
|
|
}
|
|
|
|
if (viaparinfo->chip_info->
|
|
tmds_chip_info.output_interface == INTERFACE_DVP1) {
|
|
viafb_write_reg(SR1E, VIASR,
|
|
viafb_read_reg(VIASR, SR1E) | 0x30);
|
|
|
|
/*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
|
|
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
|
|
tmds_register_write(0x88, 0x3b);
|
|
} else {
|
|
/*clear CR91[5] to direct on display period
|
|
in the secondary diplay path */
|
|
viafb_write_reg(CR91, VIACR,
|
|
viafb_read_reg(VIACR, CR91) & 0xDF);
|
|
}
|
|
|
|
/*fix DVI cannot enable on EPIA-M board */
|
|
if (viafb_platform_epia_dvi == 1) {
|
|
viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f);
|
|
viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0);
|
|
if (viafb_bus_width == 24) {
|
|
if (viafb_device_lcd_dualedge == 1)
|
|
data = 0x3F;
|
|
else
|
|
data = 0x37;
|
|
viafb_i2c_writebyte(viaparinfo->chip_info->
|
|
tmds_chip_info.
|
|
tmds_chip_slave_addr,
|
|
0x08, data);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (viaparinfo->chip_info->
|
|
tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) {
|
|
viafb_write_reg(SR2A, VIASR,
|
|
viafb_read_reg(VIASR, SR2A) | 0x0C);
|
|
viafb_write_reg(CR91, VIACR,
|
|
viafb_read_reg(VIACR, CR91) & 0xDF);
|
|
}
|
|
|
|
if (viaparinfo->chip_info->
|
|
tmds_chip_info.output_interface == INTERFACE_DFP_LOW) {
|
|
viafb_write_reg(SR2A, VIASR,
|
|
viafb_read_reg(VIASR, SR2A) | 0x03);
|
|
viafb_write_reg(CR91, VIACR,
|
|
viafb_read_reg(VIACR, CR91) & 0xDF);
|
|
}
|
|
if (viaparinfo->chip_info->
|
|
tmds_chip_info.output_interface == INTERFACE_TMDS) {
|
|
/* Turn on Display period in the panel path. */
|
|
viafb_write_reg_mask(CR91, VIACR, 0, BIT7);
|
|
|
|
/* Turn on TMDS power. */
|
|
viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);
|
|
}
|
|
}
|
|
|