📄 radeon_pm.c
字号:
tmp = INREG(TV_DAC_CNTL) & ~TV_DAC_CNTL_DACADJ_MASK; tmp |= 7 << TV_DAC_CNTL_DACADJ__SHIFT; OUTREG(TV_DAC_CNTL, tmp); /* More registers restored */ OUTREG(AGP_CNTL, rinfo->save_regs[16]); OUTREG(HOST_PATH_CNTL, rinfo->save_regs[41]); OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]); /* Hrmmm ... What is that ? */ tmp = rinfo->save_regs[1] & ~(CLK_PWRMGT_CNTL__ACTIVE_HILO_LAT_MASK | CLK_PWRMGT_CNTL__MC_BUSY); OUTPLL(pllCLK_PWRMGT_CNTL, tmp); OUTREG(PAD_CTLR_MISC, rinfo->save_regs[56]); OUTREG(FW_CNTL, rinfo->save_regs[57]); OUTREG(HDP_DEBUG, rinfo->save_regs[96]); OUTREG(PAMAC0_DLY_CNTL, rinfo->save_regs[54]); OUTREG(PAMAC1_DLY_CNTL, rinfo->save_regs[55]); OUTREG(PAMAC2_DLY_CNTL, rinfo->save_regs[79]); /* Restore Memory Controller configuration */ radeon_pm_m10_reconfigure_mc(rinfo); /* Make sure CRTC's dont touch memory */ OUTREG(CRTC_GEN_CNTL, INREG(CRTC_GEN_CNTL) | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B); OUTREG(CRTC2_GEN_CNTL, INREG(CRTC2_GEN_CNTL) | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B); mdelay(30); /* Disable SDRAM refresh */ OUTREG(MEM_REFRESH_CNTL, INREG(MEM_REFRESH_CNTL) | MEM_REFRESH_CNTL__MEM_REFRESH_DIS); /* Restore XTALIN routing (CLK_PIN_CNTL) */ OUTPLL(pllCLK_PIN_CNTL, rinfo->save_regs[4]); /* Switch MCLK, YCLK and SCLK PLLs to PCI source & force them ON */ tmp = rinfo->save_regs[2] & 0xff000000; tmp |= MCLK_CNTL__FORCE_MCLKA | MCLK_CNTL__FORCE_MCLKB | MCLK_CNTL__FORCE_YCLKA | MCLK_CNTL__FORCE_YCLKB | MCLK_CNTL__FORCE_MC; OUTPLL(pllMCLK_CNTL, tmp); /* Force all clocks on in SCLK */ tmp = INPLL(pllSCLK_CNTL); tmp |= 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; tmp |= SCLK_CNTL__CP_MAX_DYN_STOP_LAT | SCLK_CNTL__HDP_MAX_DYN_STOP_LAT | SCLK_CNTL__TV_MAX_DYN_STOP_LAT | SCLK_CNTL__E2_MAX_DYN_STOP_LAT | SCLK_CNTL__SE_MAX_DYN_STOP_LAT | 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; OUTPLL(pllSCLK_CNTL, tmp); OUTPLL(pllVCLK_ECP_CNTL, 0); OUTPLL(pllPIXCLKS_CNTL, 0); OUTPLL(pllMCLK_MISC, MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT | MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT); mdelay(5); /* Restore the M_SPLL_REF_FB_DIV, MPLL_AUX_CNTL and SPLL_AUX_CNTL values */ OUTPLL(pllM_SPLL_REF_FB_DIV, rinfo->save_regs[77]); OUTPLL(pllMPLL_AUX_CNTL, rinfo->save_regs[75]); OUTPLL(pllSPLL_AUX_CNTL, rinfo->save_regs[76]); /* Now restore the major PLLs settings, keeping them off & reset though */ OUTPLL(pllPPLL_CNTL, rinfo->save_regs[93] | 0x3); OUTPLL(pllP2PLL_CNTL, rinfo->save_regs[8] | 0x3); OUTPLL(pllMPLL_CNTL, rinfo->save_regs[73] | 0x03); OUTPLL(pllSPLL_CNTL, rinfo->save_regs[74] | 0x03); /* Restore MC DLL state and switch it off/reset too */ OUTMC(rinfo, ixR300_MC_DLL_CNTL, rinfo->save_regs[70]); /* Switch MDLL off & reset */ OUTPLL(pllMDLL_RDCKA, rinfo->save_regs[98] | 0xff); mdelay(5); /* Setup some black magic bits in PLL_PWRMGT_CNTL. Hrm... we saved * 0xa1100007... and MacOS writes 0xa1000007 .. */ OUTPLL(pllPLL_PWRMGT_CNTL, rinfo->save_regs[0]); /* Restore more stuffs */ OUTPLL(pllHTOTAL_CNTL, 0); OUTPLL(pllHTOTAL2_CNTL, 0); /* More PLL initial configuration */ tmp = INPLL(pllSCLK_CNTL2); /* What for ? */ OUTPLL(pllSCLK_CNTL2, tmp); tmp = INPLL(pllSCLK_MORE_CNTL); tmp |= SCLK_MORE_CNTL__FORCE_DISPREGS | /* a guess */ SCLK_MORE_CNTL__FORCE_MC_GUI | SCLK_MORE_CNTL__FORCE_MC_HOST; OUTPLL(pllSCLK_MORE_CNTL, tmp); /* Now we actually start MCLK and SCLK */ radeon_pm_start_mclk_sclk(rinfo); /* Full reset sdrams, this also re-inits the MDLL */ radeon_pm_full_reset_sdram(rinfo); /* Fill palettes */ OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) | 0x20); for (i=0; i<256; i++) OUTREG(PALETTE_30_DATA, 0x15555555); OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) & ~20); udelay(20); for (i=0; i<256; i++) OUTREG(PALETTE_30_DATA, 0x15555555); OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) & ~0x20); mdelay(3); /* Restore TMDS */ OUTREG(FP_GEN_CNTL, rinfo->save_regs[82]); OUTREG(FP2_GEN_CNTL, rinfo->save_regs[83]); /* Set LVDS registers but keep interface & pll down */ OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11] & ~(LVDS_EN | LVDS_ON | LVDS_DIGON | LVDS_BLON | LVDS_BL_MOD_EN)); OUTREG(LVDS_PLL_CNTL, (rinfo->save_regs[12] & ~0xf0000) | 0x20000); OUTREG(DISP_OUTPUT_CNTL, rinfo->save_regs[86]); /* Restore GPIOPAD state */ OUTREG(GPIOPAD_A, rinfo->save_regs[19]); OUTREG(GPIOPAD_EN, rinfo->save_regs[20]); OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]); /* write some stuff to the framebuffer... */ for (i = 0; i < 0x8000; ++i) writeb(0, rinfo->fb_base + i); mdelay(40); OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) | LVDS_DIGON | LVDS_ON); mdelay(40); /* Restore a few more things */ OUTREG(GRPH_BUFFER_CNTL, rinfo->save_regs[94]); OUTREG(GRPH2_BUFFER_CNTL, rinfo->save_regs[95]); /* Take care of spread spectrum & PPLLs now */ radeon_pm_m10_disable_spread_spectrum(rinfo); radeon_pm_restore_pixel_pll(rinfo); /* GRRRR... I can't figure out the proper LVDS power sequence, and the * code I have for blank/unblank doesn't quite work on some laptop models * it seems ... Hrm. What I have here works most of the time ... */ radeon_pm_m10_enable_lvds_spread_spectrum(rinfo);}static void radeon_pm_m9p_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(MC_READ_CNTL_AB, rinfo->save_regs[50]); OUTREG(MEM_REFRESH_CNTL, rinfo->save_regs[42]); OUTREG(MC_IOPAD_CNTL, rinfo->save_regs[51]); OUTREG(MC_DEBUG, rinfo->save_regs[53]); OUTREG(MC_CHIP_IO_OE_CNTL_AB, rinfo->save_regs[52]); OUTMC(rinfo, ixMC_IMP_CNTL, rinfo->save_regs[59] /*0x00f460d6*/); OUTMC(rinfo, ixMC_CHP_IO_CNTL_A0, rinfo->save_regs[65] /*0xfecfa666*/); OUTMC(rinfo, ixMC_CHP_IO_CNTL_A1, rinfo->save_regs[66] /*0x141555ff*/); OUTMC(rinfo, ixMC_CHP_IO_CNTL_B0, rinfo->save_regs[67] /*0xfecfa666*/); OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, rinfo->save_regs[68] /*0x141555ff*/); OUTMC(rinfo, ixMC_IMP_CNTL_0, rinfo->save_regs[71] /*0x00009249*/); OUTREG(MC_IND_INDEX, 0); OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); mdelay(20);}static void radeon_reinitialize_M9P(struct radeonfb_info *rinfo){ u32 tmp, i; /* Restore a bunch of registers first */ OUTREG(SURFACE_CNTL, rinfo->save_regs[29]); 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(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_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 |= 6 << TV_DAC_CNTL_BGADJ__SHIFT; OUTREG(TV_DAC_CNTL, tmp); tmp = INREG(TV_DAC_CNTL) & ~TV_DAC_CNTL_DACADJ_MASK; tmp |= 6 << TV_DAC_CNTL_DACADJ__SHIFT; OUTREG(TV_DAC_CNTL, tmp); OUTPLL(pllAGP_PLL_CNTL, rinfo->save_regs[78]); OUTREG(PAMAC0_DLY_CNTL, rinfo->save_regs[54]); OUTREG(PAMAC1_DLY_CNTL, rinfo->save_regs[55]); OUTREG(PAMAC2_DLY_CNTL, rinfo->save_regs[79]); OUTREG(AGP_CNTL, rinfo->save_regs[16]); OUTREG(HOST_PATH_CNTL, rinfo->save_regs[41]); /* MacOS sets that to 0 !!! */ OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]); tmp = rinfo->save_regs[1] & ~(CLK_PWRMGT_CNTL__ACTIVE_HILO_LAT_MASK | CLK_PWRMGT_CNTL__MC_BUSY); OUTPLL(pllCLK_PWRMGT_CNTL, tmp); OUTREG(FW_CNTL, rinfo->save_regs[57]); /* Disable SDRAM refresh */ OUTREG(MEM_REFRESH_CNTL, INREG(MEM_REFRESH_CNTL) | MEM_REFRESH_CNTL__MEM_REFRESH_DIS); /* Restore XTALIN routing (CLK_PIN_CNTL) */ OUTPLL(pllCLK_PIN_CNTL, rinfo->save_regs[4]); /* Force MCLK to be PCI sourced and forced ON */ tmp = rinfo->save_regs[2] & 0xff000000; tmp |= MCLK_CNTL__FORCE_MCLKA | MCLK_CNTL__FORCE_MCLKB | MCLK_CNTL__FORCE_YCLKA | MCLK_CNTL__FORCE_YCLKB | MCLK_CNTL__FORCE_MC | MCLK_CNTL__FORCE_AIC; OUTPLL(pllMCLK_CNTL, tmp); /* Force SCLK to be PCI sourced with a bunch forced */ tmp = 0 | 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_RE| SCLK_CNTL__FORCE_PB| SCLK_CNTL__FORCE_TAM| SCLK_CNTL__FORCE_TDM| SCLK_CNTL__FORCE_RB; OUTPLL(pllSCLK_CNTL, tmp); /* Clear VCLK_ECP_CNTL & PIXCLKS_CNTL */ OUTPLL(pllVCLK_ECP_CNTL, 0); OUTPLL(pllPIXCLKS_CNTL, 0); /* Setup MCLK_MISC, non dynamic mode */ OUTPLL(pllMCLK_MISC, MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT | MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT); mdelay(5); /* Set back the default clock dividers */ OUTPLL(pllM_SPLL_REF_FB_DIV, rinfo->save_regs[77]); OUTPLL(pllMPLL_AUX_CNTL, rinfo->save_regs[75]); OUTPLL(pllSPLL_AUX_CNTL, rinfo->save_regs[76]); /* PPLL and P2PLL default values & off */ OUTPLL(pllPPLL_CNTL, rinfo->save_regs[93] | 0x3); OUTPLL(pllP2PLL_CNTL, rinfo->save_regs[8] | 0x3); /* S and M PLLs are reset & off, configure them */ OUTPLL(pllMPLL_CNTL, rinfo->save_regs[73] | 0x03); OUTPLL(pllSPLL_CNTL, rinfo->save_regs[74] | 0x03); /* Default values for MDLL ... fixme */ OUTPLL(pllMDLL_CKO, 0x9c009c); OUTPLL(pllMDLL_RDCKA, 0x08830883); OUTPLL(pllMDLL_RDCKB, 0x08830883); mdelay(5); /* Restore PLL_PWRMGT_CNTL */ // XXXX tmp = rinfo->save_regs[0]; tmp &= ~PLL_PWRMGT_CNTL_SU_SCLK_USE_BCLK; tmp |= PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK; OUTPLL(PLL_PWRMGT_CNTL, tmp); /* Clear HTOTAL_CNTL & HTOTAL2_CNTL */ OUTPLL(pllHTOTAL_CNTL, 0); OUTPLL(pllHTOTAL2_CNTL, 0); /* All outputs off */ OUTREG(CRTC_GEN_CNTL, 0x04000000); OUTREG(CRTC2_GEN_CNTL, 0x04000000); OUTREG(FP_GEN_CNTL, 0x00004008); OUTREG(FP2_GEN_CNTL, 0x00000008); OUTREG(LVDS_GEN_CNTL, 0x08000008); /* Restore Memory Controller configuration */ radeon_pm_m9p_reconfigure_mc(rinfo); /* Now we actually start MCLK and SCLK */ radeon_pm_start_mclk_sclk(rinfo); /* Full reset sdrams, this also re-inits the MDLL */ radeon_pm_full_reset_sdram(rinfo); /* Fill palettes */ OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) | 0x20); for (i=0; i<256; i++) OUTREG(PALETTE_30_DATA, 0x15555555); OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) & ~20); udelay(20); for (i=0; i<256; i++) OUTREG(PALETTE_30_DATA, 0x15555555); OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) & ~0x20); mdelay(3); /* Restore TV stuff, make sure TV DAC is down */ OUTREG(TV_MASTER_CNTL, rinfo->save_regs[88]); OUTREG(TV_DAC_CNTL, rinfo->save_regs[13] | 0x07000000); /* Restore GPIOS. MacOS does some magic here with one of the GPIO bits, * possibly related to the weird PLL related workarounds and to the * fact that CLK_PIN_CNTL is tweaked in ways I don't fully understand, * but we keep things the simple way here */ OUTREG(GPIOPAD_A, rinfo->save_regs[19]); OUTREG(GPIOPAD_EN, rinfo->save_regs[20]); OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]); /* Now do things with SCLK_MORE_CNTL. Force bits are already set, copy * high bits from backup */ tmp = INPLL(pllSCLK_MORE_CNTL) & 0x0000ffff; tmp |= rinfo->save_regs[34] & 0xffff0000; tmp |= SCLK_MORE_CNTL__FORCE_DISPREGS; OUTPLL(pllSCLK_MORE_CNTL, tmp); tmp = INPLL(pllSCLK_MORE_CNTL) & 0x0000ffff; tmp |= rinfo->save_regs[34] & 0xffff0000; tmp |= SCLK_MORE_CNTL__FORCE_DISPREGS; OUTPLL(pllSCLK_MORE_CNTL, tmp); OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11] & ~(LVDS_EN | LVDS_ON | LVDS_DIGON | LVDS_BLON | LVDS_BL_MOD_EN)); OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) | LVDS_BLON); OUTREG(LVDS_PLL_CNTL, (rinfo->save_regs[12] & ~0xf0000) | 0x20000); mdelay(20); /* write some stuff to the framebuffer... */ for (i = 0; i < 0x8000; ++i) writeb(0, rinfo->fb_base + i); OUTREG(0x2ec, 0x6332a020); OUTPLL(pllSSPLL_REF_DIV, rinfo->save_regs[44] /*0x3f */); OUTPLL(pllSSPLL_DIV_0, rinfo->save_regs[45] /*0x000081bb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -