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

📄 monitor_routing.c

📁 ati driver
💻 C
📖 第 1 页 / 共 2 页
字号:
			values->disp_output_cntl |=				crtc_idx == 0 ? 0 : RADEON_DISP_TVDAC_SOURCE_CRTC2;			break;					case rt_r100:			break;		}	}		// choose clock source for (internal) TV-out unit	if( (total_devices & (dd_ctv | dd_stv)) != 0 ) {		int crtc_idx = (display_devices[1] & (dd_ctv | dd_stv)) != 0;				values->pixclks_cntl &= ~RADEON_PIXCLK_TV_SRC_SEL_MASK;		values->pixclks_cntl |= crtc_idx == 0 ?			RADEON_PIXCLK_TV_SRC_SEL_PIXCLK : RADEON_PIXCLK_TV_SRC_SEL_PIX2CLK;	}	// choose CRTC clock source;	// normally, CRTC1 uses PLL1 and CRTC2 uses PLL2, but if an external TV-Out	// chip is used, the clock is retrieved from this chip to stay in perfect sync	if( (display_devices[0] & (dd_ctv | dd_stv)) != 0		&& !IS_INTERNAL_TV_OUT( ai->si->tv_chip ))	{		// select BYTCLK input pin as pixel src		values->vclk_ecp_cntl &=			~(RADEON_VCLK_ECP_CNTL_BYTE_CLK_POST_DIV_MASK | RADEON_VCLK_SRC_SEL_MASK);				values->vclk_ecp_cntl |= RADEON_VCLK_SRC_BYTE_CLK;		values->vclk_ecp_cntl |= 0 << RADEON_VCLK_ECP_CNTL_BYTE_CLK_POST_DIV_SHIFT;				// disable clock if pixel format in CRTC_GEN_CNTL is zero;		// disable (DAC?) during blank		values->vclk_ecp_cntl |= RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb;	} else {		// select PLL as pixel clock		values->vclk_ecp_cntl &= ~RADEON_VCLK_SRC_SEL_MASK;		values->vclk_ecp_cntl |= RADEON_VCLK_SRC_PPLL_CLK;				// disable clock if pixel format in CRTC_GEN_CNTL is zero		values->vclk_ecp_cntl |= RADEON_PIXCLK_ALWAYS_ONb;	}	values->pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK;	if( (display_devices[1] & (dd_ctv | dd_stv)) != 0		&& !IS_INTERNAL_TV_OUT( ai->si->tv_chip ))	{		// r200 spec misses everything regarding second CRTC, so		// this is guessing		values->pixclks_cntl |= 2;	} else		values->pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLL_CLK;		// choose CRTC for flat panel	if( (total_devices & (dd_lvds | dd_dvi)) != 0 ) {		int crtc_idx = (display_devices[1] & (dd_lvds | dd_dvi)) != 0;				values->fp_gen_cntl &= ~RADEON_FP_SEL_CRTC2;		values->fp_gen_cntl |= crtc_idx == 0 ? 0 : RADEON_FP_SEL_CRTC2;	}	// enable/disable RMX for crtc1 if there is a flat panel	// (TODO: this doesn't seem to work)	// !!! makes trouble on Radeon 9200 Mobility !??	if( (display_devices[1] & (dd_lvds | dd_dvi)) != 0 ) {		values->disp_output_cntl &= ~RADEON_DISP_DAC_SOURCE_MASK;		values->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_RMX;	}		// choose CRTC for secondary flat panel	if( (total_devices & dd_dvi_ext) != 0 ) {		int crtc_idx = (display_devices[1] & (dd_dvi_ext)) != 0;		// TODO: this list looks a bit magic/wrong for me; I reckon ATI moved the		// bit starting with ASIC xxx, but I have no specs to verify that		switch( ai->si->asic ) {		case rt_r200:		case rt_r300:		case rt_r350:		case rt_rv350:			case rt_m10:			values->fp2_gen_cntl &= ~RADEON_FP2_SOURCE_SEL_CRTC2;		    values->fp2_gen_cntl |= 		    	crtc_idx == 0 ? 0 : RADEON_FP2_SOURCE_SEL_CRTC2;		    break;		    		default:			values->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2;			values->fp2_gen_cntl |= 				crtc_idx == 0 ? 0 : RADEON_FP2_SRC_SEL_CRTC2;		}	}}void Radeon_ProgramMonitorRouting( 	accelerator_info *ai, routing_regs *values ){	vuint8 *regs = ai->regs;		OUTREG( regs, RADEON_DAC_CNTL, values->dac_cntl );	OUTREG( regs, RADEON_DAC_CNTL2, values->dac_cntl2 );	OUTREGP( regs, RADEON_CRTC2_GEN_CNTL, values->crtc2_gen_cntl,		~RADEON_CRTC2_CRT2_ON );	OUTREG( regs, RADEON_DISP_OUTPUT_CNTL, values->disp_output_cntl );	switch( ai->si->asic ) {	case rt_ve:	case rt_m6:	case rt_rv200:		case rt_m7:	case rt_rv250:	case rt_m9:	case rt_rv280:	case rt_m9plus:	case rt_rs100:	case rt_rs200:		OUTREG( regs, RADEON_DISP_HW_DEBUG, values->disp_hw_debug );		break;			case rt_r200:		OUTREG( regs, RADEON_DISP_TV_OUT_CNTL, values->disp_tv_out_cntl );		break;	case rt_r300:	case rt_r300_4p:	case rt_rv350:	case rt_m10:	case rt_rv360:	case rt_r350:	case rt_r360:		OUTREGP( regs, RADEON_GPIOPAD_A, values->gpiopad_a, ~1 );		break;			case rt_r100:		break;	}	if( ai->si->asic > rt_r100 ) {		// register introduced after R100;		// only set it when necessary (more precisely: if TV-Out is used,		// this register is set by the TV-Out code)		if( !values->skip_tv_dac )			OUTREG( regs, RADEON_TV_DAC_CNTL, values->tv_dac_cntl );	}		if( IS_INTERNAL_TV_OUT( ai->si->tv_chip ))		OUTREG( regs, RADEON_TV_MASTER_CNTL, values->tv_master_cntl );		OUTREGP( regs, RADEON_FP_GEN_CNTL, values->fp_gen_cntl, ~(		RADEON_FP_SEL_CRTC2 |		RADEON_FP_RMX_HVSYNC_CONTROL_EN |		RADEON_FP_DFP_SYNC_SEL |			RADEON_FP_CRT_SYNC_SEL | 		RADEON_FP_CRTC_LOCK_8DOT |		RADEON_FP_USE_SHADOW_EN |		RADEON_FP_CRTC_USE_SHADOW_VEND |		RADEON_FP_CRT_SYNC_ALT |		RADEON_FP_CRTC_DONT_SHADOW_VPAR |		RADEON_FP_CRTC_DONT_SHADOW_HEND ));					OUTREGP( regs, RADEON_FP2_GEN_CNTL, values->fp2_gen_cntl, 		~(RADEON_FP2_SOURCE_SEL_CRTC2 | RADEON_FP2_SRC_SEL_CRTC2 ));	if( ai->vc->used_crtc[0] ) {		Radeon_OUTPLLP( ai->regs, ai->si->asic, 			RADEON_VCLK_ECP_CNTL, values->vclk_ecp_cntl, 			~RADEON_VCLK_SRC_SEL_MASK );	}		if( ai->vc->used_crtc[1] ) {		Radeon_OUTPLLP( ai->regs, ai->si->asic, 			RADEON_PIXCLKS_CNTL, values->pixclks_cntl, 			~RADEON_PIX2CLK_SRC_SEL_MASK );	}		Radeon_OUTPLLP( ai->regs, ai->si->asic, 		RADEON_PIXCLKS_CNTL, values->pixclks_cntl, 		~RADEON_PIXCLK_TV_SRC_SEL_MASK );	// enable/disable CRTC1	if( ai->vc->assigned_crtc[0] ) {		uint32 crtc_gen_cntl;				crtc_gen_cntl = INREG( regs, RADEON_CRTC_GEN_CNTL );				if( ai->vc->used_crtc[0] ) {			crtc_gen_cntl |= RADEON_CRTC_EN;		} else {			crtc_gen_cntl &= ~RADEON_CRTC_EN;			crtc_gen_cntl &= ~RADEON_CRTC_PIX_WIDTH_MASK;		}					OUTREGP( regs, RADEON_CRTC_GEN_CNTL, crtc_gen_cntl, 			~(RADEON_CRTC_PIX_WIDTH_MASK | RADEON_CRTC_EN) );	}	// enable/disable CRTC2	if( ai->vc->assigned_crtc[1] ) {		uint32 crtc2_gen_cntl;				crtc2_gen_cntl = INREG( regs, RADEON_CRTC2_GEN_CNTL );				if( ai->vc->used_crtc[1] ) {			crtc2_gen_cntl |= RADEON_CRTC2_EN;		} else {			crtc2_gen_cntl &= ~RADEON_CRTC2_EN;			crtc2_gen_cntl &= ~RADEON_CRTC2_PIX_WIDTH_MASK;		}					OUTREGP( regs, RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl, 			~(RADEON_CRTC2_PIX_WIDTH_MASK | RADEON_CRTC2_EN) );	}			// XFree says that crtc_ext_cntl must be restored after CRTC2 in dual-screen mode	OUTREGP( regs, RADEON_CRTC_EXT_CNTL, values->crtc_ext_cntl,		RADEON_CRTC_VSYNC_DIS |		RADEON_CRTC_HSYNC_DIS |		RADEON_CRTC_DISPLAY_DIS );}// internal version of SetupDefaultMonitorRouting;// input and output are written to local variablesvoid assignDefaultMonitorRoute( 	accelerator_info *ai,	display_device_e display_devices, int whished_num_heads, bool use_laptop_panel,	display_device_e *crtc1, display_device_e *crtc2 ){	virtual_card *vc = ai->vc;	display_device_e crtc1_displays = 0, crtc2_displays = 0;		SHOW_FLOW( 2, "display_devices=%x, whished_num_heads=%d", 		display_devices, whished_num_heads );		// restrict to allowed devices		display_devices &= ai->vc->controlled_displays;		// if CRTC1 is not ours, we cannot use flat panels	if( !ai->vc->assigned_crtc[0] ) {		display_devices &= ~(dd_lvds | dd_dvi);	}		SHOW_FLOW( 2, "after restriction: %x", display_devices );		// flat panels get always connected to CRTC1 because its RMX unit	if( (display_devices & dd_lvds) != 0 ) {		// if user requests it, laptop panels are always used		if( use_laptop_panel ) {			crtc1_displays |= dd_lvds;					} else {			// if he doesn't request it, we try to not use it			display_device_e tmp_crtc1, tmp_crtc2;			int effective_num_heads;						// determine routing with laptop panel ignored			assignDefaultMonitorRoute( ai, display_devices & ~dd_lvds, 				whished_num_heads, use_laptop_panel, &tmp_crtc1, &tmp_crtc2 );			effective_num_heads = (tmp_crtc1 != 0) + (tmp_crtc2 != 0);						// only use laptop panel if we cannot satisfy the requested 			// number of heads without it			if( effective_num_heads < whished_num_heads )				crtc1_displays |= dd_lvds;		}			} else if( (display_devices & dd_dvi) != 0 )		crtc1_displays |= dd_dvi;			// TV-Out gets always connected to crtc2...	if( (display_devices & dd_stv) != 0 )		crtc2_displays |= dd_stv;	else if( (display_devices & dd_ctv) != 0 )		crtc2_displays |= dd_ctv;			// ...but if there is no crtc2, they win on crtc1;	// if the user connects both a flat panel and a TV, he usually 	// wants to use the TV	if( !vc->assigned_crtc[1] && crtc2_displays != 0 ) {		crtc1_displays = crtc2_displays;		crtc2_displays = dd_none;	}			// if internal TV-Out is used, the DAC cannot drive a CRT at the same time	if( IS_INTERNAL_TV_OUT( ai->si->tv_chip ) && (display_devices & (dd_stv | dd_ctv)) != 0 )		display_devices &= ~dd_tv_crt;			// CRT on CRT-DAC gets any spare CRTC;	// if there is none, it can share CRTC with TV-Out;	// this sharing may be dangerous as TV-Out uses strange timings, so	// we should perhaps forbid sharing	if( (display_devices & dd_crt) != 0 ) {		if( crtc1_displays == 0 && vc->assigned_crtc[0] )			crtc1_displays |= dd_crt;		else if( ai->si->num_crtc > 1 && crtc2_displays == 0 && vc->assigned_crtc[1] )			crtc2_displays |= dd_crt;		else if( (crtc1_displays & ~(dd_stv | dd_ctv)) == 0 && vc->assigned_crtc[0] )			crtc1_displays |= dd_crt;		else if( ai->si->num_crtc > 1 && (crtc2_displays & ~(dd_stv | dd_ctv)) == 0 && vc->assigned_crtc[1] )			crtc2_displays |= dd_crt;	}		// same applies to CRT on TV-DAC;	// if we cannot find a CRTC, we could clone the content of the CRT-DAC,	// but I doubt that you really want two CRTs showing the same	if( (display_devices & dd_tv_crt) != 0 ) {		if( crtc1_displays == 0 && vc->assigned_crtc[0] )			crtc1_displays |= dd_tv_crt;		else if( ai->si->num_crtc > 1 && crtc2_displays == 0 && vc->assigned_crtc[1] )			crtc2_displays |= dd_tv_crt;		else if( (crtc1_displays & ~(dd_stv | dd_ctv)) == 0 && vc->assigned_crtc[0] )			crtc1_displays |= dd_tv_crt;		else if( ai->si->num_crtc > 1 && (crtc2_displays & ~(dd_stv | dd_ctv)) == 0 && vc->assigned_crtc[1] )			crtc2_displays |= dd_tv_crt;	}		SHOW_FLOW( 3, "CRTC1: 0x%x, CRTC2: 0x%x", crtc1_displays, crtc2_displays );		*crtc1 = crtc1_displays;	*crtc2 = crtc2_displays;}// Setup sensible default monitor routing// whished_num_heads - number of independant heads current display mode would need// use_laptop_panel - if true, always use laptop panelvoid Radeon_SetupDefaultMonitorRouting( 	accelerator_info *ai, int whished_num_heads, bool use_laptop_panel ){	virtual_card *vc = ai->vc;	shared_info *si = ai->si;	display_device_e display_devices = vc->connected_displays;		SHOW_FLOW( 2, "display_devices=%x, whished_num_heads=%d, use_laptop_panel=%d", 		display_devices, whished_num_heads, use_laptop_panel );			// ignore TV if standard is set to "off"	if( vc->tv_standard == ts_off )		display_devices &= ~(dd_ctv | dd_stv);		assignDefaultMonitorRoute( 		ai, display_devices, whished_num_heads, use_laptop_panel,		&si->crtc[0].chosen_displays, &si->crtc[1].chosen_displays );		/*	si->crtc[0].chosen_displays = dd_none;	si->crtc[1].chosen_displays = dd_tv_crt;*/			/*vc->used_crtc[0] = si->crtc[0].chosen_displays != dd_none;	vc->used_crtc[1] = si->crtc[1].chosen_displays != dd_none;*/			SHOW_FLOW( 2, "num_crtc: %d, CRTC1 (%s): 0x%x, CRTC2 (%s): 0x%x", 		si->num_crtc,		vc->assigned_crtc[0] ? "assigned" : "not assigned", si->crtc[0].chosen_displays, 		vc->assigned_crtc[0] ? "assigned" : "not assigned", si->crtc[1].chosen_displays );}

⌨️ 快捷键说明

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