⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvi.c

📁 via framebuffer driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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){	u8 tmp;	tmp = viaparinfo->chip_info->chip_on_slot;	switch (viaparinfo->chip_info->tmds_chip_info.i2c_port) {	case I2CPORTINDEX:		viaparinfo->chip_info->chip_on_slot = PORT_ON_AMR;		break;	case GPIOPORTINDEX:	default:		viaparinfo->chip_info->chip_on_slot = PORT_ON_AGP;		break;	}	viafb_i2cWriteByte(viaparinfo->chip_info->tmds_chip_info.		tmds_chip_slave_addr, index,		     data);	viaparinfo->chip_info->chip_on_slot = tmp;}static int tmds_register_read(int index){	u8 data;	int status;	u8 tmp;	tmp = viaparinfo->chip_info->chip_on_slot;	switch (viaparinfo->chip_info->tmds_chip_info.i2c_port) {	case I2CPORTINDEX:		viaparinfo->chip_info->chip_on_slot = PORT_ON_AMR;		break;	case GPIOPORTINDEX:	default:		viaparinfo->chip_info->chip_on_slot = PORT_ON_AGP;		break;	}	status =	    viafb_i2cReadByte((u8) viaparinfo->chip_info->	    tmds_chip_info.tmds_chip_slave_addr,			(u8) index, &data);	viaparinfo->chip_info->chip_on_slot = tmp;	return (data);}static int tmds_register_read_bytes(int index, u8 *buff, int buff_len){	int status;	u8 tmp;	tmp = viaparinfo->chip_info->chip_on_slot;	switch (viaparinfo->chip_info->tmds_chip_info.i2c_port) {	case I2CPORTINDEX:		viaparinfo->chip_info->chip_on_slot = PORT_ON_AMR;		break;	case GPIOPORTINDEX:	default:		viaparinfo->chip_info->chip_on_slot = PORT_ON_AGP;		break;	}	status =	    viafb_i2cReadBytes((u8) viaparinfo->chip_info->tmds_chip_info.			 tmds_chip_slave_addr, (u8) index, buff, buff_len);	viaparinfo->chip_info->chip_on_slot = tmp;	return (status);}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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -