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

📄 radeon_pm.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* Force Core Clocks */	sclk_cntl = INPLL( pllSCLK_CNTL);	sclk_cntl |= 	SCLK_CNTL__IDCT_MAX_DYN_STOP_LAT|			SCLK_CNTL__VIP_MAX_DYN_STOP_LAT|			SCLK_CNTL__RE_MAX_DYN_STOP_LAT|			SCLK_CNTL__PB_MAX_DYN_STOP_LAT|			SCLK_CNTL__TAM_MAX_DYN_STOP_LAT|			SCLK_CNTL__TDM_MAX_DYN_STOP_LAT|			SCLK_CNTL__RB_MAX_DYN_STOP_LAT|						SCLK_CNTL__FORCE_DISP2|			SCLK_CNTL__FORCE_CP|			SCLK_CNTL__FORCE_HDP|			SCLK_CNTL__FORCE_DISP1|			SCLK_CNTL__FORCE_TOP|			SCLK_CNTL__FORCE_E2|			SCLK_CNTL__FORCE_SE|			SCLK_CNTL__FORCE_IDCT|			SCLK_CNTL__FORCE_VIP|						SCLK_CNTL__FORCE_PB|			SCLK_CNTL__FORCE_TAM|			SCLK_CNTL__FORCE_TDM|			SCLK_CNTL__FORCE_RB|			SCLK_CNTL__FORCE_TV_SCLK|			SCLK_CNTL__FORCE_SUBPIC|			SCLK_CNTL__FORCE_OV0;	if (rinfo->family <= CHIP_FAMILY_RV280)		sclk_cntl |= SCLK_CNTL__FORCE_RE;	else		sclk_cntl |= SCLK_CNTL__SE_MAX_DYN_STOP_LAT |			SCLK_CNTL__E2_MAX_DYN_STOP_LAT |			SCLK_CNTL__TV_MAX_DYN_STOP_LAT |			SCLK_CNTL__HDP_MAX_DYN_STOP_LAT |			SCLK_CNTL__CP_MAX_DYN_STOP_LAT;	OUTPLL( pllSCLK_CNTL, sclk_cntl);	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);	sclk_more_cntl |= 	SCLK_MORE_CNTL__FORCE_DISPREGS |				SCLK_MORE_CNTL__FORCE_MC_GUI |				SCLK_MORE_CNTL__FORCE_MC_HOST;	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);				mclk_cntl = INPLL( pllMCLK_CNTL);	mclk_cntl &= ~(	MCLK_CNTL__FORCE_MCLKA |			MCLK_CNTL__FORCE_MCLKB |			MCLK_CNTL__FORCE_YCLKA |			MCLK_CNTL__FORCE_YCLKB |			MCLK_CNTL__FORCE_MC		      );	    	OUTPLL( pllMCLK_CNTL, mclk_cntl);		/* Force Display clocks	*/	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);	vclk_ecp_cntl &= ~(VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb			   | VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);	vclk_ecp_cntl |= VCLK_ECP_CNTL__ECP_FORCE_ON;	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);			pixclks_cntl = INPLL( pllPIXCLKS_CNTL);	pixclks_cntl &= ~(	PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb | 				PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|				PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |				PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|				PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|				PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|				PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);						 	OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);	/* Switch off LVDS interface */	OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) &	       ~(LVDS_BLON | LVDS_EN | LVDS_ON | LVDS_DIGON));	/* Enable System power management */	pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL);		pll_pwrmgt_cntl |= 	PLL_PWRMGT_CNTL__SPLL_TURNOFF |				PLL_PWRMGT_CNTL__MPLL_TURNOFF|				PLL_PWRMGT_CNTL__PPLL_TURNOFF|				PLL_PWRMGT_CNTL__P2PLL_TURNOFF|				PLL_PWRMGT_CNTL__TVPLL_TURNOFF;							OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);		clk_pwrmgt_cntl	 = INPLL( pllCLK_PWRMGT_CNTL);		clk_pwrmgt_cntl &= ~(	CLK_PWRMGT_CNTL__MPLL_PWRMGT_OFF|				CLK_PWRMGT_CNTL__SPLL_PWRMGT_OFF|				CLK_PWRMGT_CNTL__PPLL_PWRMGT_OFF|				CLK_PWRMGT_CNTL__P2PLL_PWRMGT_OFF|				CLK_PWRMGT_CNTL__MCLK_TURNOFF|				CLK_PWRMGT_CNTL__SCLK_TURNOFF|				CLK_PWRMGT_CNTL__PCLK_TURNOFF|				CLK_PWRMGT_CNTL__P2CLK_TURNOFF|				CLK_PWRMGT_CNTL__TVPLL_PWRMGT_OFF|				CLK_PWRMGT_CNTL__GLOBAL_PMAN_EN|				CLK_PWRMGT_CNTL__ENGINE_DYNCLK_MODE|				CLK_PWRMGT_CNTL__ACTIVE_HILO_LAT_MASK|				CLK_PWRMGT_CNTL__CG_NO1_DEBUG_MASK			);							clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL__GLOBAL_PMAN_EN		| CLK_PWRMGT_CNTL__DISP_PM;		OUTPLL( pllCLK_PWRMGT_CNTL, clk_pwrmgt_cntl);		clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);		clk_pin_cntl &= ~CLK_PIN_CNTL__ACCESS_REGS_IN_SUSPEND;	/* because both INPLL and OUTPLL take the same lock, that's why. */	tmp = INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND;	OUTPLL( pllMCLK_MISC, tmp);	/* BUS_CNTL1__MOBILE_PLATORM_SEL setting is northbridge chipset	 * and radeon chip dependent. Thus we only enable it on Mac for	 * now (until we get more info on how to compute the correct	 * value for various X86 bridges).	 */#ifdef CONFIG_PPC_PMAC	if (machine_is(powermac)) {		/* AGP PLL control */		if (rinfo->family <= CHIP_FAMILY_RV280) {			OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) |  BUS_CNTL1__AGPCLK_VALID);			OUTREG(BUS_CNTL1,			       (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)			       | (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT));	// 440BX		} else {			OUTREG(BUS_CNTL1, INREG(BUS_CNTL1));			OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000);		}	}#endif	OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL)				  & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN));		clk_pin_cntl &= ~CLK_PIN_CNTL__CG_CLK_TO_OUTPIN;	clk_pin_cntl |= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;		OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);	/* Solano2M */	OUTREG(AGP_CNTL,		(INREG(AGP_CNTL) & ~(AGP_CNTL__MAX_IDLE_CLK_MASK))		| (0x20<<AGP_CNTL__MAX_IDLE_CLK__SHIFT));	/* ACPI mode */	/* because both INPLL and OUTPLL take the same lock, that's why. */	tmp = INPLL( pllPLL_PWRMGT_CNTL) & ~PLL_PWRMGT_CNTL__PM_MODE_SEL;	OUTPLL( pllPLL_PWRMGT_CNTL, tmp);	disp_mis_cntl = INREG(DISP_MISC_CNTL);		disp_mis_cntl &= ~(	DISP_MISC_CNTL__SOFT_RESET_GRPH_PP | 				DISP_MISC_CNTL__SOFT_RESET_SUBPIC_PP | 				DISP_MISC_CNTL__SOFT_RESET_OV0_PP |				DISP_MISC_CNTL__SOFT_RESET_GRPH_SCLK|				DISP_MISC_CNTL__SOFT_RESET_SUBPIC_SCLK|				DISP_MISC_CNTL__SOFT_RESET_OV0_SCLK|				DISP_MISC_CNTL__SOFT_RESET_GRPH2_PP|				DISP_MISC_CNTL__SOFT_RESET_GRPH2_SCLK|				DISP_MISC_CNTL__SOFT_RESET_LVDS|				DISP_MISC_CNTL__SOFT_RESET_TMDS|				DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS|				DISP_MISC_CNTL__SOFT_RESET_TV);		OUTREG(DISP_MISC_CNTL, disp_mis_cntl);							disp_pwr_man = INREG(DISP_PWR_MAN);		disp_pwr_man &= ~(	DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN	| 				DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN |				DISP_PWR_MAN__DISP_PWR_MAN_DPMS_MASK|				DISP_PWR_MAN__DISP_D3_RST|				DISP_PWR_MAN__DISP_D3_REG_RST				);		disp_pwr_man |= DISP_PWR_MAN__DISP_D3_GRPH_RST|					DISP_PWR_MAN__DISP_D3_SUBPIC_RST|					DISP_PWR_MAN__DISP_D3_OV0_RST|					DISP_PWR_MAN__DISP_D1D2_GRPH_RST|					DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST|					DISP_PWR_MAN__DISP_D1D2_OV0_RST|					DISP_PWR_MAN__DIG_TMDS_ENABLE_RST|					DISP_PWR_MAN__TV_ENABLE_RST| //					DISP_PWR_MAN__AUTO_PWRUP_EN|					0;		OUTREG(DISP_PWR_MAN, disp_pwr_man);													clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL);	pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL) ;	clk_pin_cntl 	= INPLL( pllCLK_PIN_CNTL);	disp_pwr_man	= INREG(DISP_PWR_MAN);				/* D2 */	clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL__DISP_PM;	pll_pwrmgt_cntl |= PLL_PWRMGT_CNTL__MOBILE_SU | PLL_PWRMGT_CNTL__SU_SCLK_USE_BCLK;	clk_pin_cntl	|= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;	disp_pwr_man 	&= ~(DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN_MASK			     | DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN_MASK);	OUTPLL( pllCLK_PWRMGT_CNTL, clk_pwrmgt_cntl);	OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);	OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);	OUTREG(DISP_PWR_MAN, disp_pwr_man);	/* disable display request & disable display */	OUTREG( CRTC_GEN_CNTL, (INREG( CRTC_GEN_CNTL) & ~CRTC_GEN_CNTL__CRTC_EN)		| CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B);	OUTREG( CRTC2_GEN_CNTL, (INREG( CRTC2_GEN_CNTL) & ~CRTC2_GEN_CNTL__CRTC2_EN)		| CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B);	mdelay(17);				   }static void radeon_pm_yclk_mclk_sync(struct radeonfb_info *rinfo){	u32 mc_chp_io_cntl_a1, mc_chp_io_cntl_b1;	mc_chp_io_cntl_a1 = INMC( rinfo, ixMC_CHP_IO_CNTL_A1)		& ~MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA_MASK;	mc_chp_io_cntl_b1 = INMC( rinfo, ixMC_CHP_IO_CNTL_B1)		& ~MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB_MASK;	OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1	       | (1<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT));	OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1	       | (1<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT));	OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1);	OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1);	mdelay( 1);}static void radeon_pm_yclk_mclk_sync_m10(struct radeonfb_info *rinfo){	u32 mc_chp_io_cntl_a1, mc_chp_io_cntl_b1;	mc_chp_io_cntl_a1 = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_A1)		& ~MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA_MASK;	mc_chp_io_cntl_b1 = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_B1)		& ~MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB_MASK;	OUTMC( rinfo, ixR300_MC_CHP_IO_CNTL_A1,	       mc_chp_io_cntl_a1 | (1<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT));	OUTMC( rinfo, ixR300_MC_CHP_IO_CNTL_B1,	       mc_chp_io_cntl_b1 | (1<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT));	OUTMC( rinfo, ixR300_MC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1);	OUTMC( rinfo, ixR300_MC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1);	mdelay( 1);}static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value,				       u8 delay_required){  	u32 mem_sdram_mode;	mem_sdram_mode  = INREG( MEM_SDRAM_MODE_REG);	mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_MODE_REG_MASK;	mem_sdram_mode |= (value<<MEM_SDRAM_MODE_REG__MEM_MODE_REG__SHIFT)		| MEM_SDRAM_MODE_REG__MEM_CFG_TYPE;	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);	if (delay_required >= 2)		mdelay(1);	mem_sdram_mode |=  MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);	if (delay_required >= 2)		mdelay(1);	mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);	if (delay_required >= 2)		mdelay(1);	if (delay_required) {		do {			if (delay_required >= 2)				mdelay(1);		} while ((INREG(MC_STATUS)			  & (MC_STATUS__MEM_PWRUP_COMPL_A |			     MC_STATUS__MEM_PWRUP_COMPL_B)) == 0);	}}static void radeon_pm_m10_program_mode_wait(struct radeonfb_info *rinfo){	int cnt;	for (cnt = 0; cnt < 100; ++cnt) {		mdelay(1);		if (INREG(MC_STATUS) & (MC_STATUS__MEM_PWRUP_COMPL_A					| MC_STATUS__MEM_PWRUP_COMPL_B))			break;	}}static void radeon_pm_enable_dll(struct radeonfb_info *rinfo){  #define DLL_RESET_DELAY 	5#define DLL_SLEEP_DELAY		1	u32 cko = INPLL(pllMDLL_CKO)   | MDLL_CKO__MCKOA_SLEEP		| MDLL_CKO__MCKOA_RESET;	u32 cka = INPLL(pllMDLL_RDCKA) | MDLL_RDCKA__MRDCKA0_SLEEP		| MDLL_RDCKA__MRDCKA1_SLEEP | MDLL_RDCKA__MRDCKA0_RESET		| MDLL_RDCKA__MRDCKA1_RESET;	u32 ckb = INPLL(pllMDLL_RDCKB) | MDLL_RDCKB__MRDCKB0_SLEEP		| MDLL_RDCKB__MRDCKB1_SLEEP | MDLL_RDCKB__MRDCKB0_RESET		| MDLL_RDCKB__MRDCKB1_RESET;	/* Setting up the DLL range for write */	OUTPLL(pllMDLL_CKO,   	cko);	OUTPLL(pllMDLL_RDCKA,  	cka);	OUTPLL(pllMDLL_RDCKB,	ckb);	mdelay(DLL_RESET_DELAY*2);	cko &= ~(MDLL_CKO__MCKOA_SLEEP | MDLL_CKO__MCKOB_SLEEP);	OUTPLL(pllMDLL_CKO, cko);	mdelay(DLL_SLEEP_DELAY);	cko &= ~(MDLL_CKO__MCKOA_RESET | MDLL_CKO__MCKOB_RESET);	OUTPLL(pllMDLL_CKO, cko);	mdelay(DLL_RESET_DELAY);	cka &= ~(MDLL_RDCKA__MRDCKA0_SLEEP | MDLL_RDCKA__MRDCKA1_SLEEP);	OUTPLL(pllMDLL_RDCKA, cka);	mdelay(DLL_SLEEP_DELAY);	cka &= ~(MDLL_RDCKA__MRDCKA0_RESET | MDLL_RDCKA__MRDCKA1_RESET);	OUTPLL(pllMDLL_RDCKA, cka);	mdelay(DLL_RESET_DELAY);	ckb &= ~(MDLL_RDCKB__MRDCKB0_SLEEP | MDLL_RDCKB__MRDCKB1_SLEEP);	OUTPLL(pllMDLL_RDCKB, ckb);	mdelay(DLL_SLEEP_DELAY);	ckb &= ~(MDLL_RDCKB__MRDCKB0_RESET | MDLL_RDCKB__MRDCKB1_RESET);	OUTPLL(pllMDLL_RDCKB, ckb);	mdelay(DLL_RESET_DELAY);#undef DLL_RESET_DELAY#undef DLL_SLEEP_DELAY}static void radeon_pm_enable_dll_m10(struct radeonfb_info *rinfo){	u32 dll_value;	u32 dll_sleep_mask = 0;	u32 dll_reset_mask = 0;	u32 mc;#define DLL_RESET_DELAY 	5#define DLL_SLEEP_DELAY		1	OUTMC(rinfo, ixR300_MC_DLL_CNTL, rinfo->save_regs[70]);	mc = INREG(MC_CNTL);	/* Check which channels are enabled */	switch (mc & 0x3) {	case 1:		if (mc & 0x4)			break;	case 2:		dll_sleep_mask |= MDLL_R300_RDCK__MRDCKB_SLEEP;		dll_reset_mask |= MDLL_R300_RDCK__MRDCKB_RESET;	case 0:		dll_sleep_mask |= MDLL_R300_RDCK__MRDCKA_SLEEP;		dll_reset_mask |= MDLL_R300_RDCK__MRDCKA_RESET;	}	switch (mc & 0x3) {	case 1:		if (!(mc & 0x4))			break;	case 2:		dll_sleep_mask |= MDLL_R300_RDCK__MRDCKD_SLEEP;		dll_reset_mask |= MDLL_R300_RDCK__MRDCKD_RESET;		dll_sleep_mask |= MDLL_R300_RDCK__MRDCKC_SLEEP;		dll_reset_mask |= MDLL_R300_RDCK__MRDCKC_RESET;	}	dll_value = INPLL(pllMDLL_RDCKA);	/* Power Up */	dll_value &= ~(dll_sleep_mask);	OUTPLL(pllMDLL_RDCKA, dll_value);	mdelay( DLL_SLEEP_DELAY);  			dll_value &= ~(dll_reset_mask);	OUTPLL(pllMDLL_RDCKA, dll_value);	mdelay( DLL_RESET_DELAY);  		#undef DLL_RESET_DELAY #undef DLL_SLEEP_DELAY}static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo){	u32 crtcGenCntl, crtcGenCntl2, memRefreshCntl, crtc_more_cntl,		fp_gen_cntl, fp2_gen_cntl; 	crtcGenCntl  = INREG( CRTC_GEN_CNTL);	crtcGenCntl2 = INREG( CRTC2_GEN_CNTL);

⌨️ 快捷键说明

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