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

📄 monitor_detection.c

📁 ati driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	Copyright (c) 2002,03 Thomas Kurschel		Part of Radeon accelerant			Monitor detection*/#include "radeon_accelerant.h"#include "../shared/mmio.h"#include "../regs/crtc_regs.h"#include "../regs/dac_regs.h"#include "../regs/pll_regs.h"#include "../regs/tv_out_regs.h"#include "../regs/config_regs.h"#include "../regs/ddc_regs.h"#include "../regs/gpiopad_regs.h"#include "../shared/pll_access.h"#include "../regs/theatre_regs.h"#include "set_mode.h"#include "ddc.h"#include <malloc.h>typedef struct {	accelerator_info *ai;	uint32 port;} ddc_port_info;// get I2C signalsstatic status_t get_signals( void *cookie, int *clk, int *data ){	ddc_port_info *info = (ddc_port_info *)cookie;	vuint8 *regs = info->ai->regs;	uint32 value;		value = INREG( regs, info->port );		*clk = (value >> RADEON_GPIO_Y_SHIFT_1) & 1;	*data = (value >> RADEON_GPIO_Y_SHIFT_0) & 1;		return B_OK;}// set I2C signalsstatic status_t set_signals( void *cookie, int clk, int data ){	ddc_port_info *info = (ddc_port_info *)cookie;	vuint8 *regs = info->ai->regs;	uint32 value;	value = INREG( regs, info->port );	value &= ~(RADEON_GPIO_A_1 | RADEON_GPIO_A_0);	value &= ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);			value |= ((1-clk) << RADEON_GPIO_EN_SHIFT_1) | ((1-data) << RADEON_GPIO_EN_SHIFT_0);	OUTREG( regs, info->port, value );		return B_OK;}// read EDID information from monitor// ddc_port - register to use for DDC2 communicationbool Radeon_ReadEDID( accelerator_info *ai, uint32 ddc_port, edid1_info *edid ){	i2c_bus bus;	ddc_port_info info;	void *vdif;	size_t vdif_len;	status_t res;		info.ai = ai;	info.port = ddc_port;		bus.cookie = &info;	bus.set_signals = &set_signals;	bus.get_signals = &get_signals;	res = ddc2_read_edid1( &bus, edid, &vdif, &vdif_len );	if( res != B_OK )		return false;			SHOW_FLOW( 2, "Found DDC-capable monitor @0x%04x", ddc_port );	if( vdif != NULL )		free( vdif );			return true;}// search for display connect to CRT DAC// colour - true, if only a colour monitor is to be acceptedstatic bool Radeon_DetectCRTInt( accelerator_info *ai, bool colour ){	vuint8 *regs = ai->regs;	uint32 old_crtc_ext_cntl, old_dac_ext_cntl, old_dac_cntl, tmp;	bool found;	// makes sure there is a signal		old_crtc_ext_cntl = INREG( regs, RADEON_CRTC_EXT_CNTL );	tmp = old_crtc_ext_cntl | RADEON_CRTC_CRT_ON;	OUTREG( regs, RADEON_CRTC_EXT_CNTL, tmp );	// force DAC to output constant voltage	// for colour monitors, RGB is tested, for B/W only G		old_dac_ext_cntl = INREG( regs, RADEON_DAC_EXT_CNTL );		tmp = 		RADEON_DAC_FORCE_BLANK_OFF_EN |		RADEON_DAC_FORCE_DATA_EN |		(colour ? RADEON_DAC_FORCE_DATA_SEL_RGB : RADEON_DAC_FORCE_DATA_SEL_G) |		(0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);	OUTREG( regs, RADEON_DAC_EXT_CNTL, tmp );		// enable DAC and tell is to use VGA signals	old_dac_cntl = INREG( regs, RADEON_DAC_CNTL );		tmp = old_dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN);	tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;	OUTREG( regs, RADEON_DAC_CNTL, tmp );	// specs says that we should wait 1µs before checking but sample	// code uses 2 ms; we use long delay to be on safe side	// (though we don't want to make it too long as the monitor 	// gets no sync signal now)		snooze( 2000 );	// let's see whether there is some		found = (INREG( regs, RADEON_DAC_CNTL ) & RADEON_DAC_CMP_OUTPUT) != 0;		if( found )		SHOW_INFO( 2, "Found %s CRT connected to CRT-DAC", colour ? "colour" : "b/w" );		OUTREG( regs, RADEON_DAC_CNTL, old_dac_cntl );	OUTREG( regs, RADEON_DAC_EXT_CNTL, old_dac_ext_cntl );	OUTREG( regs, RADEON_CRTC_EXT_CNTL, old_crtc_ext_cntl );		return found;}// check whethere there is a CRT connected to CRT DACstatic bool Radeon_DetectCRT( accelerator_info *ai ){	vuint32 old_vclk_ecp_cntl, tmp;	bool found;	// enforce clock so the DAC gets activated		old_vclk_ecp_cntl = Radeon_INPLL( ai->regs, ai->si->asic, RADEON_VCLK_ECP_CNTL );		tmp = old_vclk_ecp_cntl &		~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb);	Radeon_OUTPLL( ai->regs, ai->si->asic, RADEON_VCLK_ECP_CNTL, tmp );	// search first for colour, then for B/W monitor	found = Radeon_DetectCRTInt( ai, true ) || Radeon_DetectCRTInt( ai, false );		Radeon_OUTPLL( ai->regs, ai->si->asic, RADEON_VCLK_ECP_CNTL, old_vclk_ecp_cntl );		return found;}// CRT on TV-DAC detection for rv200 and below// checked for rv200static bool Radeon_DetectTVCRT_RV200( accelerator_info *ai ){	vuint8 *regs = ai->regs;	uint32 old_crtc2_gen_cntl, old_tv_dac_cntl, old_dac_cntl2, tmp;	bool found;	// enable CRTC2, setting 8 bpp (we just pick any valid value)	old_crtc2_gen_cntl = INREG( regs, RADEON_CRTC2_GEN_CNTL );		tmp = old_crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;	tmp |= 		RADEON_CRTC2_CRT2_ON |		(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);	OUTREG( regs, RADEON_CRTC2_GEN_CNTL, tmp );		// enable TV-DAC, choosing VGA signal level	old_tv_dac_cntl = INREG( regs, RADEON_TV_DAC_CNTL );		tmp = 		RADEON_TV_DAC_CNTL_NBLANK |		RADEON_TV_DAC_CNTL_NHOLD |		RADEON_TV_DAC_CNTL_DETECT |		RADEON_TV_DAC_CNTL_STD_PS2;	OUTREG( regs, RADEON_TV_DAC_CNTL, tmp );		// enforce constant DAC output voltage on RGB	tmp =		RADEON_DAC2_FORCE_BLANK_OFF_EN |		RADEON_DAC2_FORCE_DATA_EN |		RADEON_DAC_FORCE_DATA_SEL_RGB |		(0x180 << RADEON_DAC_FORCE_DATA_SHIFT);	OUTREG( regs, RADEON_DAC_EXT_CNTL, tmp );		old_dac_cntl2 = INREG( regs, RADEON_DAC_CNTL2 );		// set DAC in CRT mode and enable detection	// TODO: make sure we really use CRTC2 - this is ASIC dependant	tmp = old_dac_cntl2 | RADEON_DAC2_CLK_SEL_CRT | RADEON_DAC2_CMP_EN;	OUTREG( regs, RADEON_DAC_CNTL2, tmp );		snooze( 10000 );	// let's see what we've got!		found = (INREG( regs, RADEON_DAC_CNTL2 ) & RADEON_DAC2_CMP_OUTPUT) != 0;		if( found )		SHOW_INFO0( 2, "Found CRT connected to TV-DAC, i.e. DVI port" );		OUTREG( regs, RADEON_DAC_CNTL2, old_dac_cntl2 );	OUTREG( regs, RADEON_DAC_EXT_CNTL, 0 );	OUTREG( regs, RADEON_TV_DAC_CNTL, old_tv_dac_cntl );	OUTREG( regs, RADEON_CRTC2_GEN_CNTL, old_crtc2_gen_cntl );		return found;}// CRT on TV-DAC detection for r300// checked for r300static bool Radeon_DetectTVCRT_R300( accelerator_info *ai ){	vuint8 *regs = ai->regs;	uint32 old_crtc2_gen_cntl, old_tv_dac_cntl, old_dac_cntl2, tmp;	uint32 old_radeon_gpiopad_a;	bool found;		old_radeon_gpiopad_a = INREG( regs, RADEON_GPIOPAD_A );	// whatever these flags mean - let's pray they won't get changed	OUTREGP( regs, RADEON_GPIOPAD_EN, 1, ~1 );	OUTREGP( regs, RADEON_GPIOPAD_MASK, 1, ~1 );	OUTREGP( regs, RADEON_GPIOPAD_A, 1, ~1 );	old_crtc2_gen_cntl = INREG( regs, RADEON_CRTC2_GEN_CNTL );	// enable DAC, choose valid pixel format and enable DPMS	// as usual, the code doesn't take into account whether the TV-DAC	// does really use CRTC2		tmp = old_crtc2_gen_cntl;	tmp &= ~RADEON_CRTC2_PIX_WIDTH_MASK;	tmp |= 		(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT) |		RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT;			OUTREG( regs, RADEON_CRTC2_GEN_CNTL, tmp );		old_tv_dac_cntl = INREG( regs, RADEON_TV_DAC_CNTL );		// enable TV-DAC	OUTREG( regs, RADEON_TV_DAC_CNTL, 		RADEON_TV_DAC_CNTL_NBLANK | RADEON_TV_DAC_CNTL_NHOLD |		RADEON_TV_DAC_CNTL_DETECT |		RADEON_TV_DAC_CNTL_STD_PS2 );			// force constant voltage output of DAC for impedance test	OUTREG( regs, RADEON_DAC_EXT_CNTL, 		RADEON_DAC2_FORCE_BLANK_OFF_EN | RADEON_DAC2_FORCE_DATA_EN |    	RADEON_DAC_FORCE_DATA_SEL_RGB |    	(0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT ));    	    old_dac_cntl2 = INREG( regs, RADEON_DAC_CNTL2 );	// enable CRT mode of TV-DAC and enable comparator        tmp = old_dac_cntl2 | RADEON_DAC2_CLK_SEL_CRT | RADEON_DAC2_CMP_EN;        OUTREG( regs, RADEON_DAC_CNTL2, tmp );        snooze( 10000 );        // check connection of blue data signal to see whether there is a CRT	found = (INREG( regs, RADEON_DAC_CNTL2 ) & RADEON_DAC2_CMP_OUT_B) != 0;        // clean up the mess	OUTREG( regs, RADEON_DAC_CNTL2, old_dac_cntl2 );	OUTREG( regs, RADEON_DAC_EXT_CNTL, 0 );	OUTREG( regs, RADEON_TV_DAC_CNTL, old_tv_dac_cntl );	OUTREG( regs, RADEON_CRTC2_GEN_CNTL, old_crtc2_gen_cntl );	OUTREGP( regs, RADEON_GPIOPAD_A, old_radeon_gpiopad_a, ~1 );        return found;}// check whether there is a CRT connected to TV-DACstatic bool Radeon_DetectTVCRT( accelerator_info *ai ){	switch( ai->si->asic ) {	case rt_r100:	case rt_m6:	case rt_m7:	case rt_m9:	case rt_m9plus:	case rt_m10:		// original Radeons have pure DVI only and mobility chips		// have no DVI connector		// TBD: can they have a docking station for CRT on TV-DAC?		return dd_none;			case rt_ve:	case rt_rv200:	case rt_rv250:	case rt_rv280:	// IGP is guessed	case rt_rs100:	case rt_rs200:		return Radeon_DetectTVCRT_RV200( ai );			case rt_r300:	case rt_r300_4p:	case rt_rv350:	case rt_rv360:	case rt_r350:	case rt_r360:		return Radeon_DetectTVCRT_R300( ai );			case rt_r200:		// r200 has no built-in TV-out and thus no TV-DAC to use for		// second CRT		return dd_none;	}				return dd_none;}// TV detection for rv200 and below// should work for M6 and RV200static display_device_e Radeon_DetectTV_RV200( accelerator_info *ai, bool tv_crt_found ){	vuint8 *regs = ai->regs;	uint32 		tmp, old_dac_cntl2, old_crtc_ext_cntl, old_crtc2_gen_cntl, old_tv_master_cntl, 		old_tv_dac_cntl, old_pre_dac_mux_cntl, config_cntl;	display_device_e displays = dd_none;		// give up if there is a CRT connected to TV-DAC	if( tv_crt_found )		return dd_none;	// enable TV mode	old_dac_cntl2 = INREG( regs, RADEON_DAC_CNTL2 );	tmp = old_dac_cntl2 & ~RADEON_DAC2_CLK_SEL_CRT;	OUTREG( regs, RADEON_DAC_CNTL2, tmp );		old_crtc_ext_cntl = INREG( regs, RADEON_CRTC_EXT_CNTL );	old_crtc2_gen_cntl = INREG( regs, RADEON_CRTC2_GEN_CNTL );	old_tv_master_cntl = INREG( regs, RADEON_TV_MASTER_CNTL );		// enable TV output	tmp = old_tv_master_cntl | RADEON_TV_MASTER_CNTL_TV_ON;	tmp &= ~(		RADEON_TV_MASTER_CNTL_TV_ASYNC_RST | 		RADEON_TV_MASTER_CNTL_RESTART_PHASE_FIX | 		RADEON_TV_MASTER_CNTL_CRT_FIFO_CE_EN | 		RADEON_TV_MASTER_CNTL_TV_FIFO_CE_EN | 		RADEON_TV_MASTER_CNTL_RE_SYNC_NOW_SEL_MASK);	tmp |= 		RADEON_TV_MASTER_CNTL_TV_FIFO_ASYNC_RST | 		RADEON_TV_MASTER_CNTL_CRT_ASYNC_RST;	OUTREG( regs, RADEON_TV_MASTER_CNTL, tmp );	old_tv_dac_cntl = INREG( regs, RADEON_TV_DAC_CNTL );			config_cntl = INREG( regs, RADEON_CONFIG_CNTL );	// unlock TV DAC		tmp = 		RADEON_TV_DAC_CNTL_NBLANK | RADEON_TV_DAC_CNTL_NHOLD | 		RADEON_TV_DAC_CNTL_DETECT | RADEON_TV_DAC_CNTL_STD_NTSC | 		(8 << RADEON_TV_DAC_CNTL_BGADJ_SHIFT) | 		((((config_cntl & RADEON_CFG_ATI_REV_ID_MASK) == 0) ? 8 : 4) << RADEON_TV_DAC_CNTL_DACADJ_SHIFT);	OUTREG( regs, RADEON_TV_DAC_CNTL, tmp );		old_pre_dac_mux_cntl = INREG( regs, RADEON_TV_PRE_DAC_MUX_CNTL );		// force constant DAC output voltage	tmp = 		RADEON_TV_PRE_DAC_MUX_CNTL_C_GRN_EN | RADEON_TV_PRE_DAC_MUX_CNTL_CMP_BLU_EN | 		(RADEON_TV_MUX_FORCE_DAC_DATA << RADEON_TV_PRE_DAC_MUX_CNTL_RED_MX_SHIFT) |		(RADEON_TV_MUX_FORCE_DAC_DATA << RADEON_TV_PRE_DAC_MUX_CNTL_GRN_MX_SHIFT) |		(RADEON_TV_MUX_FORCE_DAC_DATA << RADEON_TV_PRE_DAC_MUX_CNTL_BLU_MX_SHIFT) |		(0x109 << RADEON_TV_PRE_DAC_MUX_CNTL_FORCE_DAC_DATA_SHIFT);	OUTREG( regs, RADEON_TV_PRE_DAC_MUX_CNTL, tmp );		// let things settle a bit	snooze( 3000 );		// now see which wires are connected	tmp = INREG( regs, RADEON_TV_DAC_CNTL );	if( (tmp & RADEON_TV_DAC_CNTL_GDACDET) != 0 ) {		displays |= dd_stv;		SHOW_INFO0( 2, "S-Video TV-Out is connected" );	}		if( (tmp & RADEON_TV_DAC_CNTL_BDACDET) != 0 ) {		displays |= dd_ctv;		SHOW_INFO0( 2, "Composite TV-Out is connected" );	}			OUTREG( regs, RADEON_TV_PRE_DAC_MUX_CNTL, old_pre_dac_mux_cntl );	OUTREG( regs, RADEON_TV_DAC_CNTL, old_tv_dac_cntl );	OUTREG( regs, RADEON_TV_MASTER_CNTL, old_tv_master_cntl );	OUTREG( regs, RADEON_CRTC2_GEN_CNTL, old_crtc2_gen_cntl );	OUTREG( regs, RADEON_CRTC_EXT_CNTL, old_crtc_ext_cntl );	OUTREG( regs, RADEON_DAC_CNTL2, old_dac_cntl2 );		return displays;}// TV detection for r300 series// should work for R300static display_device_e Radeon_DetectTV_R300( accelerator_info *ai ){	vuint8 *regs = ai->regs;	display_device_e displays = dd_none;	uint32 tmp, old_dac_cntl2, old_crtc2_gen_cntl, old_dac_ext_cntl, old_tv_dac_cntl;	uint32 old_radeon_gpiopad_a;		old_radeon_gpiopad_a = INREG( regs, RADEON_GPIOPAD_A );	// whatever these flags mean - let's pray they won't get changed	OUTREGP( regs, RADEON_GPIOPAD_EN, 1, ~1 );	OUTREGP( regs, RADEON_GPIOPAD_MASK, 1, ~1 );	OUTREGP( regs, RADEON_GPIOPAD_A, 0, ~1 );		old_dac_cntl2 = INREG( regs, RADEON_DAC_CNTL2 );		// set CRT mode (!) of TV-DAC	OUTREG( regs, RADEON_DAC_CNTL2, RADEON_DAC2_CLK_SEL_CRT );		old_crtc2_gen_cntl = INREG( regs, RADEON_CRTC2_GEN_CNTL );		// enable TV-Out output, but set DPMS mode 	// (this seems to be not correct if TV-Out is connected to CRTC1,	//  but it doesn't really hurt having wrong DPMS mode)	OUTREG( regs, RADEON_CRTC2_GEN_CNTL, 		RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT );		old_dac_ext_cntl = INREG( regs, RADEON_DAC_EXT_CNTL );		// force constant voltage output of DAC for impedance test	OUTREG( regs, RADEON_DAC_EXT_CNTL, 		RADEON_DAC2_FORCE_BLANK_OFF_EN | RADEON_DAC2_FORCE_DATA_EN |    	RADEON_DAC_FORCE_DATA_SEL_RGB |    	(0xec << RADEON_DAC_FORCE_DATA_SHIFT ));	old_tv_dac_cntl = INREG( regs, RADEON_TV_DAC_CNTL );	// get TV-DAC running (or something...)		OUTREG( regs, RADEON_TV_DAC_CNTL, 		RADEON_TV_DAC_CNTL_STD_NTSC |		(8 << RADEON_TV_DAC_CNTL_BGADJ_SHIFT) |		(6 << RADEON_TV_DAC_CNTL_DACADJ_SHIFT ));			(void)INREG( regs, RADEON_TV_DAC_CNTL );	

⌨️ 快捷键说明

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