static void radeon_pm_setup_for_suspend()

in fbdev/aty/radeon_pm.c [822:1058]


static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
{

	u32 sclk_cntl, mclk_cntl, sclk_more_cntl;

	u32 pll_pwrmgt_cntl;
	u32 clk_pwrmgt_cntl;
	u32 clk_pin_cntl;
	u32 vclk_ecp_cntl; 
	u32 pixclks_cntl;
	u32 disp_mis_cntl;
	u32 disp_pwr_man;
	u32 tmp;
	
	/* 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);				   

}