summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/radeon.h5
-rw-r--r--src/radeon_atombios.c4
-rw-r--r--src/radeon_atombios.h4
-rw-r--r--src/radeon_driver.c401
-rw-r--r--src/radeon_pm.c416
6 files changed, 434 insertions, 398 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7cc2a6fb..1864f96e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -92,7 +92,7 @@ radeon_drv_la_SOURCES = \
radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
radeon_vip.c radeon_misc.c radeon_probe.c \
legacy_crtc.c legacy_output.c \
- radeon_textured_video.c \
+ radeon_textured_video.c radeon_pm.c \
radeon_crtc.c radeon_output.c radeon_modes.c radeon_tv.c \
$(RADEON_ATOMBIOS_SOURCES) radeon_atombios.c radeon_atomwrapper.c \
$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) atombios_output.c atombios_crtc.c
diff --git a/src/radeon.h b/src/radeon.h
index d56d94df..60d56db2 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -186,7 +186,7 @@ typedef enum {
OPTION_SUBPIXEL_ORDER,
#endif
OPTION_SHOWCACHE,
- OPTION_DYNAMIC_CLOCKS,
+ OPTION_CLOCK_GATING,
OPTION_BIOS_HOTKEYS,
OPTION_VGA_ACCESS,
OPTION_REVERSE_DDC,
@@ -1068,6 +1068,9 @@ extern void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
extern void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
RADEONSavePtr restore);
+/* radeon_pm.c */
+extern void RADEONSetClockGating(ScrnInfoPtr pScrn, Bool enable);
+
#ifdef USE_EXA
/* radeon_exa.c */
extern Bool RADEONSetupMemEXA(ScreenPtr pScreen);
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index a657fac7..e32f7ba4 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -524,7 +524,7 @@ rhdAtomASICInit(atomBiosHandlePtr handle)
}
int
-atombios_dyn_clk_setup(ScrnInfoPtr pScrn, int enable)
+atombios_clk_gating_setup(ScrnInfoPtr pScrn, Bool enable)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
DYNAMIC_CLOCK_GATING_PS_ALLOCATION dynclk_data;
@@ -548,7 +548,7 @@ atombios_dyn_clk_setup(ScrnInfoPtr pScrn, int enable)
}
int
-atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, int enable)
+atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, Bool enable)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION pwrmgt_data;
diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h
index b9a5398c..806df303 100644
--- a/src/radeon_atombios.h
+++ b/src/radeon_atombios.h
@@ -117,10 +117,10 @@ extern Bool
RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn);
extern int
-atombios_dyn_clk_setup(ScrnInfoPtr pScrn, int enable);
+atombios_clk_gating_setup(ScrnInfoPtr pScrn, Bool enable);
extern int
-atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, int enable);
+atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, Bool enable);
extern Bool
RADEONGetATOMTVInfo(xf86OutputPtr output);
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index f1991e89..fe00dd79 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -118,8 +118,6 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen);
static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode);
static void RADEONSave(ScrnInfoPtr pScrn);
-static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode);
-static void RADEONForceSomeClocks(ScrnInfoPtr pScrn);
static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
static void
@@ -176,7 +174,7 @@ static const OptionInfoRec RADEONOptions[] = {
{ OPTION_SUBPIXEL_ORDER, "SubPixelOrder", OPTV_ANYSTR, {0}, FALSE },
#endif
{ OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_DYNAMIC_CLOCKS, "DynamicClocks", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_CLOCK_GATING, "ClockGating", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_VGA_ACCESS, "VGAAccess", OPTV_BOOLEAN, {0}, TRUE },
{ OPTION_REVERSE_DDC, "ReverseDDC", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_LVDS_PROBE_PLL, "LVDSProbePLL", OPTV_BOOLEAN, {0}, FALSE },
@@ -3330,21 +3328,10 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
/* blank the outputs/crtcs */
RADEONBlank(pScrn);
- if (info->IsMobility && !IS_AVIVO_VARIANT) {
- if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
- RADEONSetDynamicClock(pScrn, 1);
- } else {
- RADEONSetDynamicClock(pScrn, 0);
- }
- } else if (IS_AVIVO_VARIANT) {
- if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
- atombios_static_pwrmgt_setup(pScrn, 1);
- atombios_dyn_clk_setup(pScrn, 1);
- }
- }
-
- if (IS_R300_VARIANT || IS_RV100_VARIANT)
- RADEONForceSomeClocks(pScrn);
+ if (xf86ReturnOptValBool(info->Options, OPTION_CLOCK_GATING, FALSE))
+ RADEONSetClockGating(pScrn, TRUE);
+ else
+ RADEONSetClockGating(pScrn, FALSE);
if (info->allowColorTiling && (pScrn->virtualX > info->MaxSurfaceWidth)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -5601,21 +5588,10 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
/* Makes sure the engine is idle before doing anything */
RADEONWaitForIdleMMIO(pScrn);
- if (info->IsMobility && !IS_AVIVO_VARIANT) {
- if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
- RADEONSetDynamicClock(pScrn, 1);
- } else {
- RADEONSetDynamicClock(pScrn, 0);
- }
- } else if (IS_AVIVO_VARIANT) {
- if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
- atombios_static_pwrmgt_setup(pScrn, 1);
- atombios_dyn_clk_setup(pScrn, 1);
- }
- }
-
- if (IS_R300_VARIANT || IS_RV100_VARIANT)
- RADEONForceSomeClocks(pScrn);
+ if (xf86ReturnOptValBool(info->Options, OPTION_CLOCK_GATING, FALSE))
+ RADEONSetClockGating(pScrn, TRUE);
+ else
+ RADEONSetClockGating(pScrn, FALSE);
for (i = 0; i < config->num_crtc; i++)
radeon_crtc_modeset_ioctl(config->crtc[i], TRUE);
@@ -5874,362 +5850,3 @@ void RADEONFreeScreen(int scrnIndex, int flags)
#endif
RADEONFreeRec(pScrn);
}
-
-static void RADEONForceSomeClocks(ScrnInfoPtr pScrn)
-{
- /* It appears from r300 and rv100 may need some clocks forced-on */
- uint32_t tmp;
-
- tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
- tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP;
- OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
-}
-
-static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- uint32_t tmp;
- switch(mode) {
- case 0: /* Turn everything OFF (ForceON to everything)*/
- if ( !pRADEONEnt->HasCRTC2 ) {
- tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
- tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP |
- RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP |
- RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE |
- RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP |
- RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB |
- RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM |
- RADEON_SCLK_FORCE_RB);
- OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
- } else if (info->ChipFamily == CHIP_FAMILY_RV350) {
- /* for RV350/M10, no delays are required. */
- tmp = INPLL(pScrn, R300_SCLK_CNTL2);
- tmp |= (R300_SCLK_FORCE_TCL |
- R300_SCLK_FORCE_GA |
- R300_SCLK_FORCE_CBA);
- OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
-
- tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
- tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
- RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
- RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
- R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
- RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
- R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
- R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
- R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
- OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
-
- tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
- tmp |= RADEON_SCLK_MORE_FORCEON;
- OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
-
- tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
- tmp |= (RADEON_FORCEON_MCLKA |
- RADEON_FORCEON_MCLKB |
- RADEON_FORCEON_YCLKA |
- RADEON_FORCEON_YCLKB |
- RADEON_FORCEON_MC);
- OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp);
-
- tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
- tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
- RADEON_PIXCLK_DAC_ALWAYS_ONb |
- R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF);
- OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
-
- tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
- tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
- RADEON_PIX2CLK_DAC_ALWAYS_ONb |
- RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
- R300_DVOCLK_ALWAYS_ONb |
- RADEON_PIXCLK_BLEND_ALWAYS_ONb |
- RADEON_PIXCLK_GV_ALWAYS_ONb |
- R300_PIXCLK_DVO_ALWAYS_ONb |
- RADEON_PIXCLK_LVDS_ALWAYS_ONb |
- RADEON_PIXCLK_TMDS_ALWAYS_ONb |
- R300_PIXCLK_TRANS_ALWAYS_ONb |
- R300_PIXCLK_TVO_ALWAYS_ONb |
- R300_P2G2CLK_ALWAYS_ONb |
- R300_P2G2CLK_ALWAYS_ONb |
- R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
- } else {
- tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
- tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2);
- tmp |= RADEON_SCLK_FORCE_SE;
-
- if ( !pRADEONEnt->HasCRTC2 ) {
- tmp |= ( RADEON_SCLK_FORCE_RB |
- RADEON_SCLK_FORCE_TDM |
- RADEON_SCLK_FORCE_TAM |
- RADEON_SCLK_FORCE_PB |
- RADEON_SCLK_FORCE_RE |
- RADEON_SCLK_FORCE_VIP |
- RADEON_SCLK_FORCE_IDCT |
- RADEON_SCLK_FORCE_TOP |
- RADEON_SCLK_FORCE_DISP1 |
- RADEON_SCLK_FORCE_DISP2 |
- RADEON_SCLK_FORCE_HDP );
- } else if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350)) {
- tmp |= ( RADEON_SCLK_FORCE_HDP |
- RADEON_SCLK_FORCE_DISP1 |
- RADEON_SCLK_FORCE_DISP2 |
- RADEON_SCLK_FORCE_TOP |
- RADEON_SCLK_FORCE_IDCT |
- RADEON_SCLK_FORCE_VIP);
- }
- OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
-
- usleep(16000);
-
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350)) {
- tmp = INPLL(pScrn, R300_SCLK_CNTL2);
- tmp |= ( R300_SCLK_FORCE_TCL |
- R300_SCLK_FORCE_GA |
- R300_SCLK_FORCE_CBA);
- OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
- usleep(16000);
- }
-
- if (info->IsIGP) {
- tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
- tmp &= ~(RADEON_FORCEON_MCLKA |
- RADEON_FORCEON_YCLKA);
- OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp);
- usleep(16000);
- }
-
- if ((info->ChipFamily == CHIP_FAMILY_RV200) ||
- (info->ChipFamily == CHIP_FAMILY_RV250) ||
- (info->ChipFamily == CHIP_FAMILY_RV280)) {
- tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
- tmp |= RADEON_SCLK_MORE_FORCEON;
- OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
- usleep(16000);
- }
-
- tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
- tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
- RADEON_PIX2CLK_DAC_ALWAYS_ONb |
- RADEON_PIXCLK_BLEND_ALWAYS_ONb |
- RADEON_PIXCLK_GV_ALWAYS_ONb |
- RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
- RADEON_PIXCLK_LVDS_ALWAYS_ONb |
- RADEON_PIXCLK_TMDS_ALWAYS_ONb);
-
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
- usleep(16000);
-
- tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
- tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
- RADEON_PIXCLK_DAC_ALWAYS_ONb);
- OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Clock Scaling Disabled\n");
- break;
- case 1:
- if (!pRADEONEnt->HasCRTC2) {
- tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
- if ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) >
- RADEON_CFG_ATI_REV_A13) {
- tmp &= ~(RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_RB);
- }
- tmp &= ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
- RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE |
- RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE |
- RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM |
- RADEON_SCLK_FORCE_TDM);
- OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
- } else if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350) ||
- (info->ChipFamily == CHIP_FAMILY_RV350)) {
- if (info->ChipFamily == CHIP_FAMILY_RV350) {
- tmp = INPLL(pScrn, R300_SCLK_CNTL2);
- tmp &= ~(R300_SCLK_FORCE_TCL |
- R300_SCLK_FORCE_GA |
- R300_SCLK_FORCE_CBA);
- tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT |
- R300_SCLK_GA_MAX_DYN_STOP_LAT |
- R300_SCLK_CBA_MAX_DYN_STOP_LAT);
- OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
-
- tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
- tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
- RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
- RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
- R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
- RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
- R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
- R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
- R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
- tmp |= RADEON_DYN_STOP_LAT_MASK;
- OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
-
- tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
- tmp &= ~RADEON_SCLK_MORE_FORCEON;
- tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
- OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
-
- tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
- tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
- RADEON_PIXCLK_DAC_ALWAYS_ONb);
- OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
-
- tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
- tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
- RADEON_PIX2CLK_DAC_ALWAYS_ONb |
- RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
- R300_DVOCLK_ALWAYS_ONb |
- RADEON_PIXCLK_BLEND_ALWAYS_ONb |
- RADEON_PIXCLK_GV_ALWAYS_ONb |
- R300_PIXCLK_DVO_ALWAYS_ONb |
- RADEON_PIXCLK_LVDS_ALWAYS_ONb |
- RADEON_PIXCLK_TMDS_ALWAYS_ONb |
- R300_PIXCLK_TRANS_ALWAYS_ONb |
- R300_PIXCLK_TVO_ALWAYS_ONb |
- R300_P2G2CLK_ALWAYS_ONb |
- R300_P2G2CLK_ALWAYS_ONb);
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
-
- tmp = INPLL(pScrn, RADEON_MCLK_MISC);
- tmp |= (RADEON_MC_MCLK_DYN_ENABLE |
- RADEON_IO_MCLK_DYN_ENABLE);
- OUTPLL(pScrn, RADEON_MCLK_MISC, tmp);
-
- tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
- tmp |= (RADEON_FORCEON_MCLKA |
- RADEON_FORCEON_MCLKB);
-
- tmp &= ~(RADEON_FORCEON_YCLKA |
- RADEON_FORCEON_YCLKB |
- RADEON_FORCEON_MC);
-
- /* Some releases of vbios have set DISABLE_MC_MCLKA
- and DISABLE_MC_MCLKB bits in the vbios table. Setting these
- bits will cause H/W hang when reading video memory with dynamic clocking
- enabled. */
- if ((tmp & R300_DISABLE_MC_MCLKA) &&
- (tmp & R300_DISABLE_MC_MCLKB)) {
- /* If both bits are set, then check the active channels */
- tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
- if (info->RamWidth == 64) {
- if (INREG(RADEON_MEM_CNTL) & R300_MEM_USE_CD_CH_ONLY)
- tmp &= ~R300_DISABLE_MC_MCLKB;
- else
- tmp &= ~R300_DISABLE_MC_MCLKA;
- } else {
- tmp &= ~(R300_DISABLE_MC_MCLKA |
- R300_DISABLE_MC_MCLKB);
- }
- }
-
- OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp);
- } else {
- tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
- tmp &= ~(R300_SCLK_FORCE_VAP);
- tmp |= RADEON_SCLK_FORCE_CP;
- OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
- usleep(15000);
-
- tmp = INPLL(pScrn, R300_SCLK_CNTL2);
- tmp &= ~(R300_SCLK_FORCE_TCL |
- R300_SCLK_FORCE_GA |
- R300_SCLK_FORCE_CBA);
- OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
- }
- } else {
- tmp = INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL);
-
- tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK |
- RADEON_DISP_DYN_STOP_LAT_MASK |
- RADEON_DYN_STOP_MODE_MASK);
-
- tmp |= (RADEON_ENGIN_DYNCLK_MODE |
- (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
- OUTPLL(pScrn, RADEON_CLK_PWRMGT_CNTL, tmp);
- usleep(15000);
-
- tmp = INPLL(pScrn, RADEON_CLK_PIN_CNTL);
- tmp |= RADEON_SCLK_DYN_START_CNTL;
- OUTPLL(pScrn, RADEON_CLK_PIN_CNTL, tmp);
- usleep(15000);
-
- /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
- to lockup randomly, leave them as set by BIOS.
- */
- tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
- /*tmp &= RADEON_SCLK_SRC_SEL_MASK;*/
- tmp &= ~RADEON_SCLK_FORCEON_MASK;
-
- /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/
- if (((info->ChipFamily == CHIP_FAMILY_RV250) &&
- ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <
- RADEON_CFG_ATI_REV_A13)) ||
- ((info->ChipFamily == CHIP_FAMILY_RV100) &&
- ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <=
- RADEON_CFG_ATI_REV_A13))){
- tmp |= RADEON_SCLK_FORCE_CP;
- tmp |= RADEON_SCLK_FORCE_VIP;
- }
-
- OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
-
- if ((info->ChipFamily == CHIP_FAMILY_RV200) ||
- (info->ChipFamily == CHIP_FAMILY_RV250) ||
- (info->ChipFamily == CHIP_FAMILY_RV280)) {
- tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
- tmp &= ~RADEON_SCLK_MORE_FORCEON;
-
- /* RV200::A11 A12 RV250::A11 A12 */
- if (((info->ChipFamily == CHIP_FAMILY_RV200) ||
- (info->ChipFamily == CHIP_FAMILY_RV250)) &&
- ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <
- RADEON_CFG_ATI_REV_A13)) {
- tmp |= RADEON_SCLK_MORE_FORCEON;
- }
- OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
- usleep(15000);
- }
-
- /* RV200::A11 A12, RV250::A11 A12 */
- if (((info->ChipFamily == CHIP_FAMILY_RV200) ||
- (info->ChipFamily == CHIP_FAMILY_RV250)) &&
- ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <
- RADEON_CFG_ATI_REV_A13)) {
- tmp = INPLL(pScrn, RADEON_PLL_PWRMGT_CNTL);
- tmp |= RADEON_TCL_BYPASS_DISABLE;
- OUTPLL(pScrn, RADEON_PLL_PWRMGT_CNTL, tmp);
- }
- usleep(15000);
-
- /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK)*/
- tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
- tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
- RADEON_PIX2CLK_DAC_ALWAYS_ONb |
- RADEON_PIXCLK_BLEND_ALWAYS_ONb |
- RADEON_PIXCLK_GV_ALWAYS_ONb |
- RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
- RADEON_PIXCLK_LVDS_ALWAYS_ONb |
- RADEON_PIXCLK_TMDS_ALWAYS_ONb);
-
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
- usleep(15000);
-
- tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
- tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
- RADEON_PIXCLK_DAC_ALWAYS_ONb);
-
- OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
- usleep(15000);
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Clock Scaling Enabled\n");
- break;
- default:
- break;
- }
-}
diff --git a/src/radeon_pm.c b/src/radeon_pm.c
new file mode 100644
index 00000000..4f3f4c7a
--- /dev/null
+++ b/src/radeon_pm.c
@@ -0,0 +1,416 @@
+/*
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR
+ * AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Alex Deucher <alexander.deucher@amd.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+ /* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_atombios.h"
+
+static void LegacySetClockGating(ScrnInfoPtr pScrn, Bool enable)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ uint32_t tmp;
+
+ if (enable) {
+ if (!pRADEONEnt->HasCRTC2) {
+ tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
+ if ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) >
+ RADEON_CFG_ATI_REV_A13) {
+ tmp &= ~(RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_RB);
+ }
+ tmp &= ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
+ RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE |
+ RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE |
+ RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM |
+ RADEON_SCLK_FORCE_TDM);
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
+ } else if (IS_R300_VARIANT) {
+ if (info->ChipFamily >= CHIP_FAMILY_RV350) {
+ tmp = INPLL(pScrn, R300_SCLK_CNTL2);
+ tmp &= ~(R300_SCLK_FORCE_TCL |
+ R300_SCLK_FORCE_GA |
+ R300_SCLK_FORCE_CBA);
+ tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT |
+ R300_SCLK_GA_MAX_DYN_STOP_LAT |
+ R300_SCLK_CBA_MAX_DYN_STOP_LAT);
+ OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
+
+ tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
+ tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
+ RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
+ RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
+ R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
+ RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
+ R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
+ R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
+ R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
+ tmp |= RADEON_DYN_STOP_LAT_MASK;
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
+
+ tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
+ tmp &= ~RADEON_SCLK_MORE_FORCEON;
+ tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
+ OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
+
+ tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+ tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
+ RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
+
+ tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+ tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
+ RADEON_PIX2CLK_DAC_ALWAYS_ONb |
+ RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
+ R300_DVOCLK_ALWAYS_ONb |
+ RADEON_PIXCLK_BLEND_ALWAYS_ONb |
+ RADEON_PIXCLK_GV_ALWAYS_ONb |
+ R300_PIXCLK_DVO_ALWAYS_ONb |
+ RADEON_PIXCLK_LVDS_ALWAYS_ONb |
+ RADEON_PIXCLK_TMDS_ALWAYS_ONb |
+ R300_PIXCLK_TRANS_ALWAYS_ONb |
+ R300_PIXCLK_TVO_ALWAYS_ONb |
+ R300_P2G2CLK_ALWAYS_ONb |
+ R300_P2G2CLK_ALWAYS_ONb);
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
+
+ tmp = INPLL(pScrn, RADEON_MCLK_MISC);
+ tmp |= (RADEON_MC_MCLK_DYN_ENABLE |
+ RADEON_IO_MCLK_DYN_ENABLE);
+ OUTPLL(pScrn, RADEON_MCLK_MISC, tmp);
+
+ tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
+ tmp |= (RADEON_FORCEON_MCLKA |
+ RADEON_FORCEON_MCLKB);
+
+ tmp &= ~(RADEON_FORCEON_YCLKA |
+ RADEON_FORCEON_YCLKB |
+ RADEON_FORCEON_MC);
+
+ /* Some releases of vbios have set DISABLE_MC_MCLKA
+ and DISABLE_MC_MCLKB bits in the vbios table. Setting these
+ bits will cause H/W hang when reading video memory with dynamic clocking
+ enabled. */
+ if ((tmp & R300_DISABLE_MC_MCLKA) &&
+ (tmp & R300_DISABLE_MC_MCLKB)) {
+ /* If both bits are set, then check the active channels */
+ tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
+ if (info->RamWidth == 64) {
+ if (INREG(RADEON_MEM_CNTL) & R300_MEM_USE_CD_CH_ONLY)
+ tmp &= ~R300_DISABLE_MC_MCLKB;
+ else
+ tmp &= ~R300_DISABLE_MC_MCLKA;
+ } else {
+ tmp &= ~(R300_DISABLE_MC_MCLKA |
+ R300_DISABLE_MC_MCLKB);
+ }
+ }
+
+ OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp);
+ } else {
+ tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
+ tmp &= ~(R300_SCLK_FORCE_VAP);
+ tmp |= RADEON_SCLK_FORCE_CP;
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
+ usleep(15000);
+
+ tmp = INPLL(pScrn, R300_SCLK_CNTL2);
+ tmp &= ~(R300_SCLK_FORCE_TCL |
+ R300_SCLK_FORCE_GA |
+ R300_SCLK_FORCE_CBA);
+ OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
+ }
+ } else {
+ tmp = INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL);
+
+ tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK |
+ RADEON_DISP_DYN_STOP_LAT_MASK |
+ RADEON_DYN_STOP_MODE_MASK);
+
+ tmp |= (RADEON_ENGIN_DYNCLK_MODE |
+ (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
+ OUTPLL(pScrn, RADEON_CLK_PWRMGT_CNTL, tmp);
+ usleep(15000);
+
+ tmp = INPLL(pScrn, RADEON_CLK_PIN_CNTL);
+ tmp |= RADEON_SCLK_DYN_START_CNTL;
+ OUTPLL(pScrn, RADEON_CLK_PIN_CNTL, tmp);
+ usleep(15000);
+
+ /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
+ to lockup randomly, leave them as set by BIOS.
+ */
+ tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
+ /*tmp &= RADEON_SCLK_SRC_SEL_MASK;*/
+ tmp &= ~RADEON_SCLK_FORCEON_MASK;
+
+ /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/
+ if (((info->ChipFamily == CHIP_FAMILY_RV250) &&
+ ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <
+ RADEON_CFG_ATI_REV_A13)) ||
+ ((info->ChipFamily == CHIP_FAMILY_RV100) &&
+ ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <=
+ RADEON_CFG_ATI_REV_A13))) {
+ tmp |= RADEON_SCLK_FORCE_CP;
+ tmp |= RADEON_SCLK_FORCE_VIP;
+ }
+
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
+
+ if ((info->ChipFamily == CHIP_FAMILY_RV200) ||
+ (info->ChipFamily == CHIP_FAMILY_RV250) ||
+ (info->ChipFamily == CHIP_FAMILY_RV280)) {
+ tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
+ tmp &= ~RADEON_SCLK_MORE_FORCEON;
+
+ /* RV200::A11 A12 RV250::A11 A12 */
+ if (((info->ChipFamily == CHIP_FAMILY_RV200) ||
+ (info->ChipFamily == CHIP_FAMILY_RV250)) &&
+ ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <
+ RADEON_CFG_ATI_REV_A13)) {
+ tmp |= RADEON_SCLK_MORE_FORCEON;
+ }
+ OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
+ usleep(15000);
+ }
+
+ /* RV200::A11 A12, RV250::A11 A12 */
+ if (((info->ChipFamily == CHIP_FAMILY_RV200) ||
+ (info->ChipFamily == CHIP_FAMILY_RV250)) &&
+ ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <
+ RADEON_CFG_ATI_REV_A13)) {
+ tmp = INPLL(pScrn, RADEON_PLL_PWRMGT_CNTL);
+ tmp |= RADEON_TCL_BYPASS_DISABLE;
+ OUTPLL(pScrn, RADEON_PLL_PWRMGT_CNTL, tmp);
+ }
+ usleep(15000);
+
+ /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK)*/
+ tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+ tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
+ RADEON_PIX2CLK_DAC_ALWAYS_ONb |
+ RADEON_PIXCLK_BLEND_ALWAYS_ONb |
+ RADEON_PIXCLK_GV_ALWAYS_ONb |
+ RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
+ RADEON_PIXCLK_LVDS_ALWAYS_ONb |
+ RADEON_PIXCLK_TMDS_ALWAYS_ONb);
+
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
+ usleep(15000);
+
+ tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+ tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
+ RADEON_PIXCLK_DAC_ALWAYS_ONb);
+
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
+ usleep(15000);
+ }
+ } else {
+ /* Turn everything OFF (ForceON to everything)*/
+ if ( !pRADEONEnt->HasCRTC2 ) {
+ tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
+ tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP |
+ RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP |
+ RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE |
+ RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP |
+ RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB |
+ RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM |
+ RADEON_SCLK_FORCE_RB);
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
+ } else if (info->ChipFamily >= CHIP_FAMILY_RV350) {
+ /* for RV350/M10, no delays are required. */
+ tmp = INPLL(pScrn, R300_SCLK_CNTL2);
+ tmp |= (R300_SCLK_FORCE_TCL |
+ R300_SCLK_FORCE_GA |
+ R300_SCLK_FORCE_CBA);
+ OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
+
+ tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
+ tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
+ RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
+ RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
+ R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
+ RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
+ R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
+ R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
+ R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
+
+ tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
+ tmp |= RADEON_SCLK_MORE_FORCEON;
+ OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
+
+ tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
+ tmp |= (RADEON_FORCEON_MCLKA |
+ RADEON_FORCEON_MCLKB |
+ RADEON_FORCEON_YCLKA |
+ RADEON_FORCEON_YCLKB |
+ RADEON_FORCEON_MC);
+ OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp);
+
+ tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+ tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
+ RADEON_PIXCLK_DAC_ALWAYS_ONb |
+ R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF);
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
+
+ tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+ tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
+ RADEON_PIX2CLK_DAC_ALWAYS_ONb |
+ RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
+ R300_DVOCLK_ALWAYS_ONb |
+ RADEON_PIXCLK_BLEND_ALWAYS_ONb |
+ RADEON_PIXCLK_GV_ALWAYS_ONb |
+ R300_PIXCLK_DVO_ALWAYS_ONb |
+ RADEON_PIXCLK_LVDS_ALWAYS_ONb |
+ RADEON_PIXCLK_TMDS_ALWAYS_ONb |
+ R300_PIXCLK_TRANS_ALWAYS_ONb |
+ R300_PIXCLK_TVO_ALWAYS_ONb |
+ R300_P2G2CLK_ALWAYS_ONb |
+ R300_P2G2CLK_ALWAYS_ONb |
+ R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
+ } else {
+ tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
+ tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2);
+ tmp |= RADEON_SCLK_FORCE_SE;
+
+ if ( !pRADEONEnt->HasCRTC2 ) {
+ tmp |= ( RADEON_SCLK_FORCE_RB |
+ RADEON_SCLK_FORCE_TDM |
+ RADEON_SCLK_FORCE_TAM |
+ RADEON_SCLK_FORCE_PB |
+ RADEON_SCLK_FORCE_RE |
+ RADEON_SCLK_FORCE_VIP |
+ RADEON_SCLK_FORCE_IDCT |
+ RADEON_SCLK_FORCE_TOP |
+ RADEON_SCLK_FORCE_DISP1 |
+ RADEON_SCLK_FORCE_DISP2 |
+ RADEON_SCLK_FORCE_HDP );
+ } else if ((info->ChipFamily == CHIP_FAMILY_R300) ||
+ (info->ChipFamily == CHIP_FAMILY_R350)) {
+ tmp |= ( RADEON_SCLK_FORCE_HDP |
+ RADEON_SCLK_FORCE_DISP1 |
+ RADEON_SCLK_FORCE_DISP2 |
+ RADEON_SCLK_FORCE_TOP |
+ RADEON_SCLK_FORCE_IDCT |
+ RADEON_SCLK_FORCE_VIP);
+ }
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
+
+ usleep(16000);
+
+ if ((info->ChipFamily == CHIP_FAMILY_R300) ||
+ (info->ChipFamily == CHIP_FAMILY_R350)) {
+ tmp = INPLL(pScrn, R300_SCLK_CNTL2);
+ tmp |= ( R300_SCLK_FORCE_TCL |
+ R300_SCLK_FORCE_GA |
+ R300_SCLK_FORCE_CBA);
+ OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
+ usleep(16000);
+ }
+
+ if (info->IsIGP) {
+ tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
+ tmp &= ~(RADEON_FORCEON_MCLKA |
+ RADEON_FORCEON_YCLKA);
+ OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp);
+ usleep(16000);
+ }
+
+ if ((info->ChipFamily == CHIP_FAMILY_RV200) ||
+ (info->ChipFamily == CHIP_FAMILY_RV250) ||
+ (info->ChipFamily == CHIP_FAMILY_RV280)) {
+ tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
+ tmp |= RADEON_SCLK_MORE_FORCEON;
+ OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
+ usleep(16000);
+ }
+
+ tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+ tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
+ RADEON_PIX2CLK_DAC_ALWAYS_ONb |
+ RADEON_PIXCLK_BLEND_ALWAYS_ONb |
+ RADEON_PIXCLK_GV_ALWAYS_ONb |
+ RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
+ RADEON_PIXCLK_LVDS_ALWAYS_ONb |
+ RADEON_PIXCLK_TMDS_ALWAYS_ONb);
+
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
+ usleep(16000);
+
+ tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+ tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
+ RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
+ }
+ }
+}
+
+void RADEONForceSomeClocks(ScrnInfoPtr pScrn)
+{
+ /* It appears from r300 and rv100 may need some clocks forced-on */
+ uint32_t tmp;
+
+ tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
+ tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP;
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
+}
+
+void
+RADEONSetClockGating(ScrnInfoPtr pScrn, Bool enable)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ RADEONWaitForIdleMMIO(pScrn);
+
+ if (info->ChipFamily >= CHIP_FAMILY_R600)
+ atombios_static_pwrmgt_setup(pScrn, enable);
+ else {
+ if (info->IsAtomBios) {
+ atombios_static_pwrmgt_setup(pScrn, enable);
+ atombios_clk_gating_setup(pScrn, enable);
+ } else if (info->IsMobility)
+ LegacySetClockGating(pScrn, enable);
+
+ if (IS_R300_VARIANT || IS_RV100_VARIANT)
+ RADEONForceSomeClocks(pScrn);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Clock Gating %sabled\n",
+ enable ? "En" : "Dis");
+}
+