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

📄 radeon_pm.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	crtc_more_cntl 	= INREG( CRTC_MORE_CNTL);	fp_gen_cntl 	= INREG( FP_GEN_CNTL);	fp2_gen_cntl 	= INREG( FP2_GEN_CNTL); 	OUTREG( CRTC_MORE_CNTL, 0);	OUTREG( FP_GEN_CNTL, 0);	OUTREG( FP2_GEN_CNTL,0); 	OUTREG( CRTC_GEN_CNTL,  (crtcGenCntl | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B) );	OUTREG( CRTC2_GEN_CNTL, (crtcGenCntl2 | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B) );  	/* This is the code for the Aluminium PowerBooks M10 / iBooks M11 */	if (rinfo->family == CHIP_FAMILY_RV350) {		u32 sdram_mode_reg = rinfo->save_regs[35];		static const u32 default_mrtable[] =			{ 0x21320032,			  0x21321000, 0xa1321000, 0x21321000, 0xffffffff,			  0x21320032, 0xa1320032, 0x21320032, 0xffffffff,			  0x21321002, 0xa1321002, 0x21321002, 0xffffffff,			  0x21320132, 0xa1320132, 0x21320132, 0xffffffff,			  0x21320032, 0xa1320032, 0x21320032, 0xffffffff,			  0x31320032 };		const u32 *mrtable = default_mrtable;		int i, mrtable_size = ARRAY_SIZE(default_mrtable);		mdelay(30);		/* Disable refresh */		memRefreshCntl 	= INREG( MEM_REFRESH_CNTL)			& ~MEM_REFRESH_CNTL__MEM_REFRESH_DIS;		OUTREG( MEM_REFRESH_CNTL, memRefreshCntl			| MEM_REFRESH_CNTL__MEM_REFRESH_DIS);		/* Configure and enable M & SPLLs */       		radeon_pm_enable_dll_m10(rinfo);		radeon_pm_yclk_mclk_sync_m10(rinfo);#ifdef CONFIG_PPC_OF		if (rinfo->of_node != NULL) {			int size;			mrtable = of_get_property(rinfo->of_node, "ATY,MRT", &size);			if (mrtable)				mrtable_size = size >> 2;			else				mrtable = default_mrtable;		}#endif /* CONFIG_PPC_OF */		/* Program the SDRAM */		sdram_mode_reg = mrtable[0];		OUTREG(MEM_SDRAM_MODE_REG, sdram_mode_reg);		for (i = 0; i < mrtable_size; i++) {			if (mrtable[i] == 0xffffffffu)				radeon_pm_m10_program_mode_wait(rinfo);			else {				sdram_mode_reg &= ~(MEM_SDRAM_MODE_REG__MEM_MODE_REG_MASK						    | MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE						    | MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET);				sdram_mode_reg |= mrtable[i];				OUTREG(MEM_SDRAM_MODE_REG, sdram_mode_reg);				mdelay(1);			}		}		/* Restore memory refresh */		OUTREG(MEM_REFRESH_CNTL, memRefreshCntl);		mdelay(30);	}	/* Here come the desktop RV200 "QW" card */	else if (!rinfo->is_mobility && rinfo->family == CHIP_FAMILY_RV200) {		/* Disable refresh */		memRefreshCntl 	= INREG( MEM_REFRESH_CNTL)			& ~MEM_REFRESH_CNTL__MEM_REFRESH_DIS;		OUTREG(MEM_REFRESH_CNTL, memRefreshCntl		       | MEM_REFRESH_CNTL__MEM_REFRESH_DIS);		mdelay(30);		/* Reset memory */		OUTREG(MEM_SDRAM_MODE_REG,		       INREG( MEM_SDRAM_MODE_REG) & ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);		radeon_pm_program_mode_reg(rinfo, 0x2002, 2);		radeon_pm_program_mode_reg(rinfo, 0x0132, 2);		radeon_pm_program_mode_reg(rinfo, 0x0032, 2);		OUTREG(MEM_SDRAM_MODE_REG,		       INREG(MEM_SDRAM_MODE_REG) | MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);		OUTREG( MEM_REFRESH_CNTL, 	memRefreshCntl);	}	/* The M6 */	else if (rinfo->is_mobility && rinfo->family == CHIP_FAMILY_RV100) {		/* Disable refresh */		memRefreshCntl = INREG(EXT_MEM_CNTL) & ~(1 << 20);		OUTREG( EXT_MEM_CNTL, memRefreshCntl | (1 << 20)); 		/* Reset memory */		OUTREG( MEM_SDRAM_MODE_REG,			INREG( MEM_SDRAM_MODE_REG)			& ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);		/* DLL */		radeon_pm_enable_dll(rinfo);		/* MLCK / YCLK sync */		radeon_pm_yclk_mclk_sync(rinfo);		/* Program Mode Register */		radeon_pm_program_mode_reg(rinfo, 0x2000, 1);   		radeon_pm_program_mode_reg(rinfo, 0x2001, 1);   		radeon_pm_program_mode_reg(rinfo, 0x2002, 1);   		radeon_pm_program_mode_reg(rinfo, 0x0132, 1);   		radeon_pm_program_mode_reg(rinfo, 0x0032, 1); 		/* Complete & re-enable refresh */		OUTREG( MEM_SDRAM_MODE_REG,			INREG( MEM_SDRAM_MODE_REG) | MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);		OUTREG(EXT_MEM_CNTL, memRefreshCntl);	}	/* And finally, the M7..M9 models, including M9+ (RV280) */	else if (rinfo->is_mobility) {		/* Disable refresh */		memRefreshCntl 	= INREG( MEM_REFRESH_CNTL)			& ~MEM_REFRESH_CNTL__MEM_REFRESH_DIS;		OUTREG( MEM_REFRESH_CNTL, memRefreshCntl			| MEM_REFRESH_CNTL__MEM_REFRESH_DIS);		/* Reset memory */		OUTREG( MEM_SDRAM_MODE_REG,			INREG( MEM_SDRAM_MODE_REG)			& ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);		/* DLL */		radeon_pm_enable_dll(rinfo);		/* MLCK / YCLK sync */		radeon_pm_yclk_mclk_sync(rinfo);		/* M6, M7 and M9 so far ... */		if (rinfo->family <= CHIP_FAMILY_RV250) {			radeon_pm_program_mode_reg(rinfo, 0x2000, 1);			radeon_pm_program_mode_reg(rinfo, 0x2001, 1);			radeon_pm_program_mode_reg(rinfo, 0x2002, 1);			radeon_pm_program_mode_reg(rinfo, 0x0132, 1);			radeon_pm_program_mode_reg(rinfo, 0x0032, 1);		}		/* M9+ (iBook G4) */		else if (rinfo->family == CHIP_FAMILY_RV280) {			radeon_pm_program_mode_reg(rinfo, 0x2000, 1);			radeon_pm_program_mode_reg(rinfo, 0x0132, 1);			radeon_pm_program_mode_reg(rinfo, 0x0032, 1);		}		/* Complete & re-enable refresh */		OUTREG( MEM_SDRAM_MODE_REG,			INREG( MEM_SDRAM_MODE_REG) | MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);		OUTREG( MEM_REFRESH_CNTL, 	memRefreshCntl);	}	OUTREG( CRTC_GEN_CNTL, 		crtcGenCntl);	OUTREG( CRTC2_GEN_CNTL, 	crtcGenCntl2);	OUTREG( FP_GEN_CNTL, 		fp_gen_cntl);	OUTREG( FP2_GEN_CNTL, 		fp2_gen_cntl);	OUTREG( CRTC_MORE_CNTL, 	crtc_more_cntl);	mdelay( 15);}static void radeon_pm_reset_pad_ctlr_strength(struct radeonfb_info *rinfo){	u32 tmp, tmp2;	int i,j;	/* Reset the PAD_CTLR_STRENGTH & wait for it to be stable */	INREG(PAD_CTLR_STRENGTH);	OUTREG(PAD_CTLR_STRENGTH, INREG(PAD_CTLR_STRENGTH) & ~PAD_MANUAL_OVERRIDE);	tmp = INREG(PAD_CTLR_STRENGTH);	for (i = j = 0; i < 65; ++i) {		mdelay(1);		tmp2 = INREG(PAD_CTLR_STRENGTH);		if (tmp != tmp2) {			tmp = tmp2;			i = 0;			j++;			if (j > 10) {				printk(KERN_WARNING "radeon: PAD_CTLR_STRENGTH doesn't "				       "stabilize !\n");				break;			}		}	}}static void radeon_pm_all_ppls_off(struct radeonfb_info *rinfo){	u32 tmp;	tmp = INPLL(pllPPLL_CNTL);	OUTPLL(pllPPLL_CNTL, tmp | 0x3);	tmp = INPLL(pllP2PLL_CNTL);	OUTPLL(pllP2PLL_CNTL, tmp | 0x3);	tmp = INPLL(pllSPLL_CNTL);	OUTPLL(pllSPLL_CNTL, tmp | 0x3);	tmp = INPLL(pllMPLL_CNTL);	OUTPLL(pllMPLL_CNTL, tmp | 0x3);}static void radeon_pm_start_mclk_sclk(struct radeonfb_info *rinfo){	u32 tmp;	/* Switch SPLL to PCI source */	tmp = INPLL(pllSCLK_CNTL);	OUTPLL(pllSCLK_CNTL, tmp & ~SCLK_CNTL__SCLK_SRC_SEL_MASK);	/* Reconfigure SPLL charge pump, VCO gain, duty cycle */	tmp = INPLL(pllSPLL_CNTL);	OUTREG8(CLOCK_CNTL_INDEX, pllSPLL_CNTL + PLL_WR_EN);	radeon_pll_errata_after_index(rinfo);	OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);	radeon_pll_errata_after_data(rinfo);	/* Set SPLL feedback divider */	tmp = INPLL(pllM_SPLL_REF_FB_DIV);	tmp = (tmp & 0xff00fffful) | (rinfo->save_regs[77] & 0x00ff0000ul);	OUTPLL(pllM_SPLL_REF_FB_DIV, tmp);	/* Power up SPLL */	tmp = INPLL(pllSPLL_CNTL);	OUTPLL(pllSPLL_CNTL, tmp & ~1);	(void)INPLL(pllSPLL_CNTL);	mdelay(10);	/* Release SPLL reset */	tmp = INPLL(pllSPLL_CNTL);	OUTPLL(pllSPLL_CNTL, tmp & ~0x2);	(void)INPLL(pllSPLL_CNTL);	mdelay(10);	/* Select SCLK source  */	tmp = INPLL(pllSCLK_CNTL);	tmp &= ~SCLK_CNTL__SCLK_SRC_SEL_MASK;	tmp |= rinfo->save_regs[3] & SCLK_CNTL__SCLK_SRC_SEL_MASK;	OUTPLL(pllSCLK_CNTL, tmp);	(void)INPLL(pllSCLK_CNTL);	mdelay(10);	/* Reconfigure MPLL charge pump, VCO gain, duty cycle */	tmp = INPLL(pllMPLL_CNTL);	OUTREG8(CLOCK_CNTL_INDEX, pllMPLL_CNTL + PLL_WR_EN);	radeon_pll_errata_after_index(rinfo);	OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);	radeon_pll_errata_after_data(rinfo);	/* Set MPLL feedback divider */	tmp = INPLL(pllM_SPLL_REF_FB_DIV);	tmp = (tmp & 0xffff00fful) | (rinfo->save_regs[77] & 0x0000ff00ul);	OUTPLL(pllM_SPLL_REF_FB_DIV, tmp);	/* Power up MPLL */	tmp = INPLL(pllMPLL_CNTL);	OUTPLL(pllMPLL_CNTL, tmp & ~0x2);	(void)INPLL(pllMPLL_CNTL);	mdelay(10);	/* Un-reset MPLL */	tmp = INPLL(pllMPLL_CNTL);	OUTPLL(pllMPLL_CNTL, tmp & ~0x1);	(void)INPLL(pllMPLL_CNTL);	mdelay(10);	/* Select source for MCLK */	tmp = INPLL(pllMCLK_CNTL);	tmp |= rinfo->save_regs[2] & 0xffff;	OUTPLL(pllMCLK_CNTL, tmp);	(void)INPLL(pllMCLK_CNTL);	mdelay(10);}static void radeon_pm_m10_disable_spread_spectrum(struct radeonfb_info *rinfo){	u32 r2ec;	/* GACK ! I though we didn't have a DDA on Radeon's anymore	 * here we rewrite with the same value, ... I suppose we clear	 * some bits that are already clear ? Or maybe this 0x2ec	 * register is something new ?	 */	mdelay(20);	r2ec = INREG(VGA_DDA_ON_OFF);	OUTREG(VGA_DDA_ON_OFF, r2ec);	mdelay(1);	/* Spread spectrum PLLL off */	OUTPLL(pllSSPLL_CNTL, 0xbf03);	/* Spread spectrum disabled */	OUTPLL(pllSS_INT_CNTL, rinfo->save_regs[90] & ~3);	/* The trace shows read & rewrite of LVDS_PLL_CNTL here with same	 * value, not sure what for...	 */	r2ec |= 0x3f0;	OUTREG(VGA_DDA_ON_OFF, r2ec);	mdelay(1);}static void radeon_pm_m10_enable_lvds_spread_spectrum(struct radeonfb_info *rinfo){	u32 r2ec, tmp;	/* GACK (bis) ! I though we didn't have a DDA on Radeon's anymore	 * here we rewrite with the same value, ... I suppose we clear/set	 * some bits that are already clear/set ?	 */	r2ec = INREG(VGA_DDA_ON_OFF);	OUTREG(VGA_DDA_ON_OFF, r2ec);	mdelay(1);	/* Enable spread spectrum */	OUTPLL(pllSSPLL_CNTL, rinfo->save_regs[43] | 3);	mdelay(3);	OUTPLL(pllSSPLL_REF_DIV, rinfo->save_regs[44]);	OUTPLL(pllSSPLL_DIV_0, rinfo->save_regs[45]);	tmp = INPLL(pllSSPLL_CNTL);	OUTPLL(pllSSPLL_CNTL, tmp & ~0x2);	mdelay(6);	tmp = INPLL(pllSSPLL_CNTL);	OUTPLL(pllSSPLL_CNTL, tmp & ~0x1);	mdelay(5);       	OUTPLL(pllSS_INT_CNTL, rinfo->save_regs[90]);	r2ec |= 8;	OUTREG(VGA_DDA_ON_OFF, r2ec);	mdelay(20);	/* Enable LVDS interface */	tmp = INREG(LVDS_GEN_CNTL);	OUTREG(LVDS_GEN_CNTL, tmp | LVDS_EN);	/* Enable LVDS_PLL */	tmp = INREG(LVDS_PLL_CNTL);	tmp &= ~0x30000;	tmp |= 0x10000;	OUTREG(LVDS_PLL_CNTL, tmp);	OUTPLL(pllSCLK_MORE_CNTL, rinfo->save_regs[34]);	OUTPLL(pllSS_TST_CNTL, rinfo->save_regs[91]);	/* The trace reads that one here, waiting for something to settle down ? */	INREG(RBBM_STATUS);	/* Ugh ? SS_TST_DEC is supposed to be a read register in the	 * R300 register spec at least...	 */	tmp = INPLL(pllSS_TST_CNTL);	tmp |= 0x00400000;	OUTPLL(pllSS_TST_CNTL, tmp);}static void radeon_pm_restore_pixel_pll(struct radeonfb_info *rinfo){	u32 tmp;	OUTREG8(CLOCK_CNTL_INDEX, pllHTOTAL_CNTL + PLL_WR_EN);	radeon_pll_errata_after_index(rinfo);	OUTREG8(CLOCK_CNTL_DATA, 0);	radeon_pll_errata_after_data(rinfo);	tmp = INPLL(pllVCLK_ECP_CNTL);	OUTPLL(pllVCLK_ECP_CNTL, tmp | 0x80);	mdelay(5);	tmp = INPLL(pllPPLL_REF_DIV);	tmp = (tmp & ~PPLL_REF_DIV_MASK) | rinfo->pll.ref_div;	OUTPLL(pllPPLL_REF_DIV, tmp);	INPLL(pllPPLL_REF_DIV);	/* Reconfigure SPLL charge pump, VCO gain, duty cycle,	 * probably useless since we already did it ...	 */	tmp = INPLL(pllPPLL_CNTL);	OUTREG8(CLOCK_CNTL_INDEX, pllSPLL_CNTL + PLL_WR_EN);	radeon_pll_errata_after_index(rinfo);	OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);	radeon_pll_errata_after_data(rinfo);	/* Restore our "reference" PPLL divider set by firmware	 * according to proper spread spectrum calculations	 */	OUTPLL(pllPPLL_DIV_0, rinfo->save_regs[92]);	tmp = INPLL(pllPPLL_CNTL);	OUTPLL(pllPPLL_CNTL, tmp & ~0x2);	mdelay(5);

⌨️ 快捷键说明

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