📄 radeon_pm.c
字号:
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);}#ifdef CONFIG_PPC_OFstatic 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); tmp = INPLL(pllPPLL_CNTL); OUTPLL(pllPPLL_CNTL, tmp & ~0x1); mdelay(5); tmp = INPLL(pllVCLK_ECP_CNTL); OUTPLL(pllVCLK_ECP_CNTL, tmp | 3); mdelay(5); tmp = INPLL(pllVCLK_ECP_CNTL); OUTPLL(pllVCLK_ECP_CNTL, tmp | 3); mdelay(5); /* Switch pixel clock to firmware default div 0 */ OUTREG8(CLOCK_CNTL_INDEX+1, 0); radeon_pll_errata_after_index(rinfo); radeon_pll_errata_after_data(rinfo);}static void radeon_pm_m10_reconfigure_mc(struct radeonfb_info *rinfo){ OUTREG(MC_CNTL, rinfo->save_regs[46]); OUTREG(MC_INIT_GFX_LAT_TIMER, rinfo->save_regs[47]); OUTREG(MC_INIT_MISC_LAT_TIMER, rinfo->save_regs[48]); OUTREG(MEM_SDRAM_MODE_REG, rinfo->save_regs[35] & ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); OUTREG(MC_TIMING_CNTL, rinfo->save_regs[49]); OUTREG(MEM_REFRESH_CNTL, rinfo->save_regs[42]); OUTREG(MC_READ_CNTL_AB, rinfo->save_regs[50]); OUTREG(MC_CHIP_IO_OE_CNTL_AB, rinfo->save_regs[52]); OUTREG(MC_IOPAD_CNTL, rinfo->save_regs[51]); OUTREG(MC_DEBUG, rinfo->save_regs[53]); OUTMC(rinfo, ixR300_MC_MC_INIT_WR_LAT_TIMER, rinfo->save_regs[58]); OUTMC(rinfo, ixR300_MC_IMP_CNTL, rinfo->save_regs[59]); OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_C0, rinfo->save_regs[60]); OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_C1, rinfo->save_regs[61]); OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_D0, rinfo->save_regs[62]); OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_D1, rinfo->save_regs[63]); OUTMC(rinfo, ixR300_MC_BIST_CNTL_3, rinfo->save_regs[64]); OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_A0, rinfo->save_regs[65]); OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_A1, rinfo->save_regs[66]); OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_B0, rinfo->save_regs[67]); OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_B1, rinfo->save_regs[68]); OUTMC(rinfo, ixR300_MC_DEBUG_CNTL, rinfo->save_regs[69]); OUTMC(rinfo, ixR300_MC_DLL_CNTL, rinfo->save_regs[70]); OUTMC(rinfo, ixR300_MC_IMP_CNTL_0, rinfo->save_regs[71]); OUTMC(rinfo, ixR300_MC_ELPIDA_CNTL, rinfo->save_regs[72]); OUTMC(rinfo, ixR300_MC_READ_CNTL_CD, rinfo->save_regs[96]); OUTREG(MC_IND_INDEX, 0);}static void radeon_reinitialize_M10(struct radeonfb_info *rinfo){ u32 tmp, i; /* Restore a bunch of registers first */ OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]); OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]); OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]); OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]); OUTREG(OV0_BASE_ADDR, rinfo->save_regs[80]); OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); OUTREG(BUS_CNTL, rinfo->save_regs[36]); OUTREG(BUS_CNTL1, rinfo->save_regs[14]); OUTREG(MPP_TB_CONFIG, rinfo->save_regs[37]); OUTREG(FCP_CNTL, rinfo->save_regs[38]); OUTREG(RBBM_CNTL, rinfo->save_regs[39]); OUTREG(DAC_CNTL, rinfo->save_regs[40]); OUTREG(DAC_MACRO_CNTL, (INREG(DAC_MACRO_CNTL) & ~0x6) | 8); OUTREG(DAC_MACRO_CNTL, (INREG(DAC_MACRO_CNTL) & ~0x6) | 8); /* Hrm... */ OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) | DAC2_EXPAND_MODE); /* Reset the PAD CTLR */ radeon_pm_reset_pad_ctlr_strength(rinfo); /* Some PLLs are Read & written identically in the trace here... * I suppose it's actually to switch them all off & reset, * let's assume off is what we want. I'm just doing that for all major PLLs now. */ radeon_pm_all_ppls_off(rinfo); /* Clear tiling, reset swappers */ INREG(SURFACE_CNTL); OUTREG(SURFACE_CNTL, 0); /* Some black magic with TV_DAC_CNTL, we should restore those from backups * rather than hard coding... */ tmp = INREG(TV_DAC_CNTL) & ~TV_DAC_CNTL_BGADJ_MASK; tmp |= 8 << TV_DAC_CNTL_BGADJ__SHIFT; OUTREG(TV_DAC_CNTL, tmp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -