[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#264037: xserver-xfree86: Adding powerplay support to radeon?



Package: xserver-xfree86
Version: 4.3.0.dfsg.1-4
Severity: wishlist
Tags: patch


Hi,

Alex Deucher produced a patch to enable PowerPlay on the radeon chipset:
the patch is at http://www.botchco.com/alex/radeon/dynamicPM/hy0/. I
simply adapted the that patch to the the Debian package and recompiled.

I've been running now with DynamicPM set to true on my radeon M9000 and
I get less fan activity and more battery power. I include the patch here
in the hope that it can make it into the Debian package.

thanks
graziano


-- Package-specific info:

-- System Information:
Debian Release: 3.1
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)
Kernel: Linux 2.6.7-mm7
Locale: LANG=C, LC_CTYPE=C

Versions of packages xserver-xfree86 depends on:
ii  debconf [debconf-2.0]     1.4.30         Debian configuration management sy
ii  libc6                     2.3.2.ds1-13   GNU C Library: Shared libraries an
ii  xserver-common            4.3.0.dfsg.1-4 files and utilities common to all 
ii  zlib1g                    1:1.2.1.1-5    compression library - runtime

-- debconf information excluded
--- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c	2003-11-16 22:57:41.000000000 -0500
+++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c	2003-11-16 23:15:35.000000000 -0500
@@ -174,6 +174,7 @@
     clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
     if (info->R300CGWorkaround) R300CGWorkaround(pScrn);
 
+#if 0 /* taken care of by new PM code */
     /* Some ASICs have bugs with dynamic-on feature, which are
      * ASIC-version dependent, so we force all blocks on for now
      */
@@ -190,8 +191,11 @@
 	    OUTPLL(RADEON_SCLK_MORE_CNTL, tmp | RADEON_SCLK_MORE_FORCEON);
 	}
     }
+#endif /* new PM code */
 
     mclk_cntl = INPLL(pScrn, RADEON_MCLK_CNTL);
+
+#if 0 /* handled by new PM code */
     OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl |
 			      RADEON_FORCEON_MCLKA |
 			      RADEON_FORCEON_MCLKB |
@@ -199,6 +203,7 @@
 			      RADEON_FORCEON_YCLKB |
 			      RADEON_FORCEON_MC |
 			      RADEON_FORCEON_AIC));
+#endif /* new PM code */
 
     /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some
      * unexpected behaviour on some machines.  Here we use
--- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2003-11-10 13:41:22.000000000 -0500
+++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2003-11-16 23:09:20.000000000 -0500
@@ -113,6 +113,7 @@
 					    int PowerManagementMode,
 					    int flags);
 static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
+static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode);
 
 typedef enum {
     OPTION_NOACCEL,
@@ -145,7 +146,8 @@
     OPTION_VIDEO_KEY,
     OPTION_DISP_PRIORITY,
     OPTION_PANEL_SIZE,
-    OPTION_MIN_DOTCLOCK
+    OPTION_MIN_DOTCLOCK,
+    OPTION_DYNAMIC_PM
 } RADEONOpts;
 
 const OptionInfoRec RADEONOptions[] = {
@@ -181,6 +183,7 @@
     { OPTION_DISP_PRIORITY,  "DisplayPriority",  OPTV_ANYSTR,  {0}, FALSE },
     { OPTION_PANEL_SIZE,     "PanelSize",        OPTV_ANYSTR,  {0}, FALSE },
     { OPTION_MIN_DOTCLOCK,   "ForceMinDotClock", OPTV_FREQ,    {0}, FALSE },
+    { OPTION_DYNAMIC_PM,     "DynamicPM",        OPTV_BOOLEAN, {0}, FALSE },
     { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
 };
 
@@ -4293,6 +4296,13 @@
     info->PaletteSavedOnVT = FALSE;
 
     RADEONSave(pScrn);
+
+    if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_PM, FALSE)) {
+	RADEONSetDynamicClock(pScrn, 1);
+    } else {
+	RADEONSetDynamicClock(pScrn, 0);
+    }
+
     if (info->FBDev) {
 	unsigned char *RADEONMMIO = info->MMIO;
 
@@ -7229,3 +7239,352 @@
     if (info->CPStarted) DRIUnlock(pScrn->pScreen);
 #endif
 }
+
+static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 tmp;
+    switch(mode) {
+        case 0: /* Turn everything OFF (ForceON to everything)*/
+            if ( !info->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(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(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(RADEON_SCLK_CNTL, tmp);
+
+                tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
+                tmp |= RADEON_SCLK_MORE_FORCEON;
+                OUTPLL(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(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(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(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 ( !info->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);
+		}
+                OUTREG(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(R300_SCLK_CNTL2, tmp);
+		    usleep(16000);
+		}
+
+                if (info->IsIGP) {
+                    tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
+                    tmp &= ~(RADEON_FORCEON_MCLKA |
+			     RADEON_FORCEON_YCLKA);
+                    OUTREG(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(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);
+
+		OUTREG(RADEON_PIXCLKS_CNTL, tmp);
+		usleep(16000);
+
+                tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+                tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb  |
+			 RADEON_PIXCLK_DAC_ALWAYS_ONb); 
+                OUTPLL(RADEON_VCLK_ECP_CNTL, tmp);
+	    }
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Power Management Disabled\n");
+            break;
+        case 1:
+            if (!info->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 (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(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(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(RADEON_SCLK_MORE_CNTL, tmp);
+
+		    tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+		    tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
+			    RADEON_PIXCLK_DAC_ALWAYS_ONb);   
+		    OUTPLL(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(RADEON_PIXCLKS_CNTL, tmp);
+
+		    tmp = INPLL(pScrn, RADEON_MCLK_MISC);
+		    tmp |= (RADEON_MC_MCLK_DYN_ENABLE |
+			    RADEON_IO_MCLK_DYN_ENABLE);
+		    OUTPLL(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(RADEON_MCLK_CNTL, tmp);
+		} else {
+		    tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
+		    tmp &= ~(R300_SCLK_FORCE_VAP);
+		    tmp |= RADEON_SCLK_FORCE_CP;
+		    OUTPLL(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(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(RADEON_CLK_PWRMGT_CNTL, tmp);
+		usleep(15000);
+
+                tmp = INPLL(pScrn, RADEON_CLK_PIN_CNTL);
+                tmp |= RADEON_SCLK_DYN_START_CNTL; 
+                OUTPLL(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(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(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;
+                    OUTREG(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(RADEON_PIXCLKS_CNTL, tmp);
+		usleep(15000);
+
+		tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+		tmp |= (RADEON_PIXCLK_ALWAYS_ONb  |
+		        RADEON_PIXCLK_DAC_ALWAYS_ONb); 
+
+                OUTPLL(RADEON_VCLK_ECP_CNTL, tmp);
+		usleep(15000);
+            }    
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Power Management Enabled\n");
+	    break;
+        default:
+	    break;
+    }
+}
+
--- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h	2003-11-10 13:41:23.000000000 -0500
+++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h	2003-10-23 23:50:34.000000000 -0400
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v 1.31 2003/11/10 18:41:23 tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v 1.30 2003/10/07 22:47:12 martin Exp $ */
 /*
  * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
  *                VA Linux Systems Inc., Fremont, California.
@@ -197,11 +197,20 @@
 #define RADEON_CAPABILITIES_ID              0x0f50 /* PCI */
 #define RADEON_CAPABILITIES_PTR             0x0f34 /* PCI */
 #define RADEON_CLK_PIN_CNTL                 0x0001 /* PLL */
+#       define RADEON_SCLK_DYN_START_CNTL   (1 << 15)
 #define RADEON_CLOCK_CNTL_DATA              0x000c
 #define RADEON_CLOCK_CNTL_INDEX             0x0008
 #       define RADEON_PLL_WR_EN             (1 << 7)
 #       define RADEON_PLL_DIV_SEL           (3 << 8)
 #       define RADEON_PLL2_DIV_SEL_MASK     ~(3 << 8)
+#define RADEON_CLK_PWRMGT_CNTL              0x0014
+#       define RADEON_ENGIN_DYNCLK_MODE     (1 << 12)
+#       define RADEON_ACTIVE_HILO_LAT_MASK  (3 << 13)
+#       define RADEON_ACTIVE_HILO_LAT_SHIFT 13
+#       define RADEON_DISP_DYN_STOP_LAT_MASK (1 << 12)
+#       define RADEON_DYN_STOP_MODE_MASK    (7 << 21)
+#define RADEON_PLL_PWRMGT_CNTL              0x0015
+#       define RADEON_TCL_BYPASS_DISABLE    (1 << 20)
 #define RADEON_CLR_CMP_CLR_3D               0x1a24
 #define RADEON_CLR_CMP_CLR_DST              0x15c8
 #define RADEON_CLR_CMP_CLR_SRC              0x15c4
@@ -297,8 +306,8 @@
 #       define RADEON_CRTC2_HSYNC_DIS       (1 << 28)
 #       define RADEON_CRTC2_VSYNC_DIS       (1 << 29)
 #define RADEON_CRTC_MORE_CNTL               0x27c
-#       define RADEON_CRTC_H_CUTOFF_ACTIVE_EN (1<<4)
-#       define RADEON_CRTC_V_CUTOFF_ACTIVE_EN (1<<5)
+#       define RADEON_CRTC_H_CUTOFF_ACTIVE_EN (1<<4)   
+#       define RADEON_CRTC_V_CUTOFF_ACTIVE_EN (1<<5)   
 #define RADEON_CRTC_GUI_TRIG_VLINE          0x0218
 #define RADEON_CRTC_H_SYNC_STRT_WID         0x0204
 #       define RADEON_CRTC_H_SYNC_STRT_PIX        (0x07  <<  0)
@@ -430,7 +439,7 @@
 #define RADEON_DEVICE_ID                    0x0f02 /* PCI */
 #define RADEON_DISP_MISC_CNTL               0x0d00
 #       define RADEON_SOFT_RESET_GRPH_PP    (1 << 0)
-#define RADEON_DISP_MERGE_CNTL		  0x0d60
+#define RADEON_DISP_MERGE_CNTL	          0x0d60
 #       define RADEON_DISP_ALPHA_MODE_MASK  0x03
 #       define RADEON_DISP_ALPHA_MODE_KEY   0
 #       define RADEON_DISP_ALPHA_MODE_PER_PIXEL 1
@@ -439,7 +448,7 @@
 #       define RADEON_DISP_GRPH_ALPHA_MASK  (0xff << 16)
 #       define RADEON_DISP_OV0_ALPHA_MASK   (0xff << 24)
 #	define RADEON_DISP_LIN_TRANS_BYPASS (0x01 << 9)
-#define RADEON_DISP2_MERGE_CNTL		    0x0d68
+#define RADEON_DISP2_MERGE_CNTL	            0x0d68
 #       define RADEON_DISP2_RGB_OFFSET_EN   (1<<8)
 #define RADEON_DISP_LIN_TRANS_GRPH_A        0x0d80
 #define RADEON_DISP_LIN_TRANS_GRPH_B        0x0d84
@@ -768,6 +777,13 @@
 #       define RADEON_FORCEON_YCLKB         (1 << 19)
 #       define RADEON_FORCEON_MC            (1 << 20)
 #       define RADEON_FORCEON_AIC           (1 << 21)
+#       define R300_DISABLE_MC_MCLKA        (1 << 21)
+#       define R300_DISABLE_MC_MCLKB        (1 << 21)
+#define RADEON_MCLK_MISC                    0x001f /* PLL */
+#       define RADEON_MC_MCLK_MAX_DYN_STOP_LAT (1<<12)
+#       define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1<<13)
+#       define RADEON_MC_MCLK_DYN_ENABLE    (1 << 14)
+#       define RADEON_IO_MCLK_DYN_ENABLE    (1 << 14)
 #define RADEON_MDGPIO_A_REG                 0x01ac
 #define RADEON_MDGPIO_EN_REG                0x01b0
 #define RADEON_MDGPIO_MASK                  0x0198
@@ -970,8 +986,19 @@
 #       define RADEON_PIX2CLK_ALWAYS_ONb       (1<<6)
 #       define RADEON_PIX2CLK_DAC_ALWAYS_ONb   (1<<7)
 #       define RADEON_PIXCLK_TV_SRC_SEL        (1 << 8)
+#       define RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb (1 << 9)
+#       define R300_DVOCLK_ALWAYS_ONb          (1 << 10)
+#       define RADEON_PIXCLK_BLEND_ALWAYS_ONb  (1 << 11)
+#       define RADEON_PIXCLK_GV_ALWAYS_ONb     (1 << 12)
+#       define RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb (1 << 13)
+#       define R300_PIXCLK_DVO_ALWAYS_ONb      (1 << 13)
 #       define RADEON_PIXCLK_LVDS_ALWAYS_ONb   (1 << 14)
 #       define RADEON_PIXCLK_TMDS_ALWAYS_ONb   (1 << 15)
+#       define R300_PIXCLK_TRANS_ALWAYS_ONb    (1 << 16)
+#       define R300_PIXCLK_TVO_ALWAYS_ONb      (1 << 17)
+#       define R300_P2G2CLK_ALWAYS_ONb         (1 << 18)
+#       define R300_P2G2CLK_DAC_ALWAYS_ONb     (1 << 19)
+#       define R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF (1 << 23)
 #define RADEON_PLANE_3D_MASK_C              0x1d44
 #define RADEON_PLL_TEST_CNTL                0x0013 /* PLL */
 #define RADEON_PMI_CAP_ID                   0x0f5c /* PCI */
@@ -1036,10 +1063,42 @@
 #       define RADEON_SC_SIGN_MASK_LO       0x8000
 #       define RADEON_SC_SIGN_MASK_HI       0x80000000
 #define RADEON_SCLK_CNTL                    0x000d /* PLL */
+#       define RADEON_SCLK_SRC_SEL_MASK     0x0007
 #       define RADEON_DYN_STOP_LAT_MASK     0x00007ff8
 #       define RADEON_CP_MAX_DYN_STOP_LAT   0x0008
 #       define RADEON_SCLK_FORCEON_MASK     0xffff8000
+#       define RADEON_SCLK_FORCE_DISP2      (1<<15)
+#       define RADEON_SCLK_FORCE_CP         (1<<16)
+#       define RADEON_SCLK_FORCE_HDP        (1<<17)
+#       define RADEON_SCLK_FORCE_DISP1      (1<<18)
+#       define RADEON_SCLK_FORCE_TOP        (1<<19)
+#       define RADEON_SCLK_FORCE_E2         (1<<20)
+#       define RADEON_SCLK_FORCE_SE         (1<<21)
+#       define RADEON_SCLK_FORCE_IDCT       (1<<22)
+#       define RADEON_SCLK_FORCE_VIP        (1<<23)
+#       define RADEON_SCLK_FORCE_RE         (1<<24)
+#       define RADEON_SCLK_FORCE_PB         (1<<25)
+#       define RADEON_SCLK_FORCE_TAM        (1<<26)
+#       define RADEON_SCLK_FORCE_TDM        (1<<27)
+#       define RADEON_SCLK_FORCE_RB         (1<<28)
+#       define RADEON_SCLK_FORCE_TV_SCLK    (1<<29)
+#       define RADEON_SCLK_FORCE_SUBPIC     (1<<30)
+#       define RADEON_SCLK_FORCE_OV0        (1<<31)
+#       define R300_SCLK_FORCE_VAP          (1<<21)
+#       define R300_SCLK_FORCE_SR           (1<<25)
+#       define R300_SCLK_FORCE_PX           (1<<26)
+#       define R300_SCLK_FORCE_TX           (1<<27)
+#       define R300_SCLK_FORCE_US           (1<<28)
+#       define R300_SCLK_FORCE_SU           (1<<30)
+#define R300_SCLK_CNTL2                     0x1e   /* PLL */
+#       define R300_SCLK_TCL_MAX_DYN_STOP_LAT (1<<10)
+#       define R300_SCLK_GA_MAX_DYN_STOP_LAT  (1<<11)
+#       define R300_SCLK_CBA_MAX_DYN_STOP_LAT (1<<12)
+#       define R300_SCLK_FORCE_TCL          (1<<13)
+#       define R300_SCLK_FORCE_CBA          (1<<14)
+#       define R300_SCLK_FORCE_GA           (1<<15)
 #define RADEON_SCLK_MORE_CNTL               0x0035 /* PLL */
+#       define RADEON_SCLK_MORE_MAX_DYN_STOP_LAT 0x0007
 #       define RADEON_SCLK_MORE_FORCEON     0x0700
 #define RADEON_SDRAM_MODE_REG               0x0158
 #define RADEON_SEQ8_DATA                    0x03c5 /* VGA */
@@ -1111,6 +1170,7 @@
 #       define RADEON_VCLK_SRC_SEL_PPLLCLK  0x03
 #       define RADEON_PIXCLK_ALWAYS_ONb     (1<<6)
 #       define RADEON_PIXCLK_DAC_ALWAYS_ONb (1<<7)
+#       define R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF (1<<23)
 
 #define RADEON_VENDOR_ID                    0x0f00 /* PCI */
 #define RADEON_VGA_DDA_CONFIG               0x02e8

Reply to: