📄 radeon_pm.c
字号:
PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb| PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb| PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb| PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb; OUTPLL(pllPIXCLKS_CNTL, tmp); radeon_msleep(15); tmp = INPLL(pllVCLK_ECP_CNTL); tmp |= VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb | VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb; OUTPLL(pllVCLK_ECP_CNTL, tmp); /* X doesn't do that ... hrm, we do on mobility && Macs */#ifdef CONFIG_PPC_OF if (rinfo->is_mobility) { tmp = INPLL(pllMCLK_CNTL); tmp &= ~(MCLK_CNTL__FORCE_MCLKA | MCLK_CNTL__FORCE_MCLKB | MCLK_CNTL__FORCE_YCLKA | MCLK_CNTL__FORCE_YCLKB); OUTPLL(pllMCLK_CNTL, tmp); radeon_msleep(15); tmp = INPLL(pllMCLK_MISC); tmp |= MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT| MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT| MCLK_MISC__MC_MCLK_DYN_ENABLE| MCLK_MISC__IO_MCLK_DYN_ENABLE; OUTPLL(pllMCLK_MISC, tmp); radeon_msleep(15); }#endif /* CONFIG_PPC_OF */}#ifdef CONFIG_PMstatic void OUTMC( struct radeonfb_info *rinfo, u8 indx, u32 value){ OUTREG( MC_IND_INDEX, indx | MC_IND_INDEX__MC_IND_WR_EN); OUTREG( MC_IND_DATA, value); }static u32 INMC(struct radeonfb_info *rinfo, u8 indx){ OUTREG( MC_IND_INDEX, indx); return INREG( MC_IND_DATA);}static void radeon_pm_save_regs(struct radeonfb_info *rinfo, int saving_for_d3){ rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL); rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL); rinfo->save_regs[2] = INPLL(MCLK_CNTL); rinfo->save_regs[3] = INPLL(SCLK_CNTL); rinfo->save_regs[4] = INPLL(CLK_PIN_CNTL); rinfo->save_regs[5] = INPLL(VCLK_ECP_CNTL); rinfo->save_regs[6] = INPLL(PIXCLKS_CNTL); rinfo->save_regs[7] = INPLL(MCLK_MISC); rinfo->save_regs[8] = INPLL(P2PLL_CNTL); rinfo->save_regs[9] = INREG(DISP_MISC_CNTL); rinfo->save_regs[10] = INREG(DISP_PWR_MAN); rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL); rinfo->save_regs[13] = INREG(TV_DAC_CNTL); rinfo->save_regs[14] = INREG(BUS_CNTL1); rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL); rinfo->save_regs[16] = INREG(AGP_CNTL); rinfo->save_regs[17] = (INREG(CRTC_GEN_CNTL) & 0xfdffffff) | 0x04000000; rinfo->save_regs[18] = (INREG(CRTC2_GEN_CNTL) & 0xfdffffff) | 0x04000000; rinfo->save_regs[19] = INREG(GPIOPAD_A); rinfo->save_regs[20] = INREG(GPIOPAD_EN); rinfo->save_regs[21] = INREG(GPIOPAD_MASK); rinfo->save_regs[22] = INREG(ZV_LCDPAD_A); rinfo->save_regs[23] = INREG(ZV_LCDPAD_EN); rinfo->save_regs[24] = INREG(ZV_LCDPAD_MASK); rinfo->save_regs[25] = INREG(GPIO_VGA_DDC); rinfo->save_regs[26] = INREG(GPIO_DVI_DDC); rinfo->save_regs[27] = INREG(GPIO_MONID); rinfo->save_regs[28] = INREG(GPIO_CRT2_DDC); rinfo->save_regs[29] = INREG(SURFACE_CNTL); rinfo->save_regs[30] = INREG(MC_FB_LOCATION); rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR); rinfo->save_regs[32] = INREG(MC_AGP_LOCATION); rinfo->save_regs[33] = INREG(CRTC2_DISPLAY_BASE_ADDR); rinfo->save_regs[34] = INPLL(SCLK_MORE_CNTL); rinfo->save_regs[35] = INREG(MEM_SDRAM_MODE_REG); rinfo->save_regs[36] = INREG(BUS_CNTL); rinfo->save_regs[39] = INREG(RBBM_CNTL); rinfo->save_regs[40] = INREG(DAC_CNTL); rinfo->save_regs[41] = INREG(HOST_PATH_CNTL); rinfo->save_regs[37] = INREG(MPP_TB_CONFIG); rinfo->save_regs[38] = INREG(FCP_CNTL); if (rinfo->is_mobility) { rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL); rinfo->save_regs[43] = INPLL(pllSSPLL_CNTL); rinfo->save_regs[44] = INPLL(pllSSPLL_REF_DIV); rinfo->save_regs[45] = INPLL(pllSSPLL_DIV_0); rinfo->save_regs[90] = INPLL(pllSS_INT_CNTL); rinfo->save_regs[91] = INPLL(pllSS_TST_CNTL); rinfo->save_regs[81] = INREG(LVDS_GEN_CNTL); } if (rinfo->family >= CHIP_FAMILY_RV200) { rinfo->save_regs[42] = INREG(MEM_REFRESH_CNTL); rinfo->save_regs[46] = INREG(MC_CNTL); rinfo->save_regs[47] = INREG(MC_INIT_GFX_LAT_TIMER); rinfo->save_regs[48] = INREG(MC_INIT_MISC_LAT_TIMER); rinfo->save_regs[49] = INREG(MC_TIMING_CNTL); rinfo->save_regs[50] = INREG(MC_READ_CNTL_AB); rinfo->save_regs[51] = INREG(MC_IOPAD_CNTL); rinfo->save_regs[52] = INREG(MC_CHIP_IO_OE_CNTL_AB); rinfo->save_regs[53] = INREG(MC_DEBUG); } rinfo->save_regs[54] = INREG(PAMAC0_DLY_CNTL); rinfo->save_regs[55] = INREG(PAMAC1_DLY_CNTL); rinfo->save_regs[56] = INREG(PAD_CTLR_MISC); rinfo->save_regs[57] = INREG(FW_CNTL); if (rinfo->family >= CHIP_FAMILY_R300) { rinfo->save_regs[58] = INMC(rinfo, ixR300_MC_MC_INIT_WR_LAT_TIMER); rinfo->save_regs[59] = INMC(rinfo, ixR300_MC_IMP_CNTL); rinfo->save_regs[60] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_C0); rinfo->save_regs[61] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_C1); rinfo->save_regs[62] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_D0); rinfo->save_regs[63] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_D1); rinfo->save_regs[64] = INMC(rinfo, ixR300_MC_BIST_CNTL_3); rinfo->save_regs[65] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_A0); rinfo->save_regs[66] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_A1); rinfo->save_regs[67] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_B0); rinfo->save_regs[68] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_B1); rinfo->save_regs[69] = INMC(rinfo, ixR300_MC_DEBUG_CNTL); rinfo->save_regs[70] = INMC(rinfo, ixR300_MC_DLL_CNTL); rinfo->save_regs[71] = INMC(rinfo, ixR300_MC_IMP_CNTL_0); rinfo->save_regs[72] = INMC(rinfo, ixR300_MC_ELPIDA_CNTL); rinfo->save_regs[96] = INMC(rinfo, ixR300_MC_READ_CNTL_CD); } else { rinfo->save_regs[59] = INMC(rinfo, ixMC_IMP_CNTL); rinfo->save_regs[65] = INMC(rinfo, ixMC_CHP_IO_CNTL_A0); rinfo->save_regs[66] = INMC(rinfo, ixMC_CHP_IO_CNTL_A1); rinfo->save_regs[67] = INMC(rinfo, ixMC_CHP_IO_CNTL_B0); rinfo->save_regs[68] = INMC(rinfo, ixMC_CHP_IO_CNTL_B1); rinfo->save_regs[71] = INMC(rinfo, ixMC_IMP_CNTL_0); } rinfo->save_regs[73] = INPLL(pllMPLL_CNTL); rinfo->save_regs[74] = INPLL(pllSPLL_CNTL); rinfo->save_regs[75] = INPLL(pllMPLL_AUX_CNTL); rinfo->save_regs[76] = INPLL(pllSPLL_AUX_CNTL); rinfo->save_regs[77] = INPLL(pllM_SPLL_REF_FB_DIV); rinfo->save_regs[78] = INPLL(pllAGP_PLL_CNTL); rinfo->save_regs[79] = INREG(PAMAC2_DLY_CNTL); rinfo->save_regs[80] = INREG(OV0_BASE_ADDR); rinfo->save_regs[82] = INREG(FP_GEN_CNTL); rinfo->save_regs[83] = INREG(FP2_GEN_CNTL); rinfo->save_regs[84] = INREG(TMDS_CNTL); rinfo->save_regs[85] = INREG(TMDS_TRANSMITTER_CNTL); rinfo->save_regs[86] = INREG(DISP_OUTPUT_CNTL); rinfo->save_regs[87] = INREG(DISP_HW_DEBUG); rinfo->save_regs[88] = INREG(TV_MASTER_CNTL); rinfo->save_regs[89] = INPLL(pllP2PLL_REF_DIV); rinfo->save_regs[92] = INPLL(pllPPLL_DIV_0); rinfo->save_regs[93] = INPLL(pllPPLL_CNTL); rinfo->save_regs[94] = INREG(GRPH_BUFFER_CNTL); rinfo->save_regs[95] = INREG(GRPH2_BUFFER_CNTL); rinfo->save_regs[96] = INREG(HDP_DEBUG); rinfo->save_regs[97] = INPLL(pllMDLL_CKO); rinfo->save_regs[98] = INPLL(pllMDLL_RDCKA); rinfo->save_regs[99] = INPLL(pllMDLL_RDCKB);}static void radeon_pm_restore_regs(struct radeonfb_info *rinfo){ OUTPLL(P2PLL_CNTL, rinfo->save_regs[8] & 0xFFFFFFFE); /* First */ OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]); OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]); OUTPLL(MCLK_CNTL, rinfo->save_regs[2]); OUTPLL(SCLK_CNTL, rinfo->save_regs[3]); OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]); OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]); OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]); OUTPLL(MCLK_MISC, rinfo->save_regs[7]); if (rinfo->family == CHIP_FAMILY_RV350) OUTPLL(SCLK_MORE_CNTL, rinfo->save_regs[34]); OUTREG(SURFACE_CNTL, rinfo->save_regs[29]); OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]); OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]); OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]); OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]); OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]); OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]); OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11]); OUTREG(LVDS_PLL_CNTL,rinfo->save_regs[12]); OUTREG(TV_DAC_CNTL, rinfo->save_regs[13]); OUTREG(BUS_CNTL1, rinfo->save_regs[14]); OUTREG(CRTC_OFFSET_CNTL, rinfo->save_regs[15]); OUTREG(AGP_CNTL, rinfo->save_regs[16]); OUTREG(CRTC_GEN_CNTL, rinfo->save_regs[17]); OUTREG(CRTC2_GEN_CNTL, rinfo->save_regs[18]); OUTPLL(P2PLL_CNTL, rinfo->save_regs[8]); OUTREG(GPIOPAD_A, rinfo->save_regs[19]); OUTREG(GPIOPAD_EN, rinfo->save_regs[20]); OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]); OUTREG(ZV_LCDPAD_A, rinfo->save_regs[22]); OUTREG(ZV_LCDPAD_EN, rinfo->save_regs[23]); OUTREG(ZV_LCDPAD_MASK, rinfo->save_regs[24]); OUTREG(GPIO_VGA_DDC, rinfo->save_regs[25]); OUTREG(GPIO_DVI_DDC, rinfo->save_regs[26]); OUTREG(GPIO_MONID, rinfo->save_regs[27]); OUTREG(GPIO_CRT2_DDC, rinfo->save_regs[28]);}static void radeon_pm_disable_iopad(struct radeonfb_info *rinfo){ OUTREG(GPIOPAD_MASK, 0x0001ffff); OUTREG(GPIOPAD_EN, 0x00000400); OUTREG(GPIOPAD_A, 0x00000000); OUTREG(ZV_LCDPAD_MASK, 0x00000000); OUTREG(ZV_LCDPAD_EN, 0x00000000); OUTREG(ZV_LCDPAD_A, 0x00000000); OUTREG(GPIO_VGA_DDC, 0x00030000); OUTREG(GPIO_DVI_DDC, 0x00000000); OUTREG(GPIO_MONID, 0x00030000); OUTREG(GPIO_CRT2_DDC, 0x00000000);}static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo){ /* Set v2clk to 65MHz */ if (rinfo->family <= CHIP_FAMILY_RV280) { OUTPLL(pllPIXCLKS_CNTL, __INPLL(rinfo, pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK); OUTPLL(pllP2PLL_REF_DIV, 0x0000000c); OUTPLL(pllP2PLL_CNTL, 0x0000bf00); } else { OUTPLL(pllP2PLL_REF_DIV, 0x0000000c); INPLL(pllP2PLL_REF_DIV); OUTPLL(pllP2PLL_CNTL, 0x0000a700); } OUTPLL(pllP2PLL_DIV_0, 0x00020074 | P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W); OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_SLEEP); mdelay(1); OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_RESET); mdelay( 1); OUTPLL(pllPIXCLKS_CNTL, (INPLL(pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK) | (0x03 << PIXCLKS_CNTL__PIX2CLK_SRC_SEL__SHIFT)); mdelay( 1); }static void radeon_pm_low_current(struct radeonfb_info *rinfo){ u32 reg; reg = INREG(BUS_CNTL1); if (rinfo->family <= CHIP_FAMILY_RV280) { reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK; reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT); } else { reg |= 0x4080; } OUTREG(BUS_CNTL1, reg); reg = INPLL(PLL_PWRMGT_CNTL); reg |= PLL_PWRMGT_CNTL_SPLL_TURNOFF | PLL_PWRMGT_CNTL_PPLL_TURNOFF | PLL_PWRMGT_CNTL_P2PLL_TURNOFF | PLL_PWRMGT_CNTL_TVPLL_TURNOFF; reg &= ~PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK; reg &= ~PLL_PWRMGT_CNTL_MOBILE_SU; OUTPLL(PLL_PWRMGT_CNTL, reg); reg = INREG(TV_DAC_CNTL); reg &= ~(TV_DAC_CNTL_BGADJ_MASK |TV_DAC_CNTL_DACADJ_MASK); reg |=TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD | (8<<TV_DAC_CNTL_BGADJ__SHIFT) | (8<<TV_DAC_CNTL_DACADJ__SHIFT); OUTREG(TV_DAC_CNTL, reg); reg = INREG(TMDS_TRANSMITTER_CNTL); reg &= ~(TMDS_PLL_EN | TMDS_PLLRST); OUTREG(TMDS_TRANSMITTER_CNTL, reg); reg = INREG(DAC_CNTL); reg &= ~DAC_CMP_EN; OUTREG(DAC_CNTL, reg); reg = INREG(DAC_CNTL2); reg &= ~DAC2_CMP_EN; OUTREG(DAC_CNTL2, reg); reg = INREG(TV_DAC_CNTL); reg &= ~TV_DAC_CNTL_DETECT; OUTREG(TV_DAC_CNTL, reg);}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|
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -