--- ../ati.orig/radeon_driver.c	2003-02-24 22:50:15.000000000 -0500
+++ radeon_driver.c	2003-04-14 23:04:18.000000000 -0400
@@ -116,6 +116,11 @@
 					    int PowerManagementMode,
 					    int flags);
 
+/* power management functions */
+static void RADEONPMDisableDynamicMode(ScrnInfoPtr pScrn);
+static void RADEONPMEnableDynamicMode(ScrnInfoPtr pScrn);
+
+
 typedef enum {
     OPTION_NOACCEL,
     OPTION_SW_CURSOR,
@@ -141,7 +146,8 @@
     OPTION_CLONE_HSYNC,
     OPTION_CLONE_VREFRESH,
     OPTION_FBDEV,
-    OPTION_VIDEO_KEY
+    OPTION_VIDEO_KEY,
+    OPTION_DYN_PM
 } RADEONOpts;
 
 const OptionInfoRec RADEONOptions[] = {
@@ -170,6 +176,7 @@
     { OPTION_CLONE_VREFRESH, "CloneVRefresh",    OPTV_ANYSTR,  {0}, FALSE },
     { OPTION_FBDEV,          "UseFBDev",         OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_VIDEO_KEY,      "VideoKey",         OPTV_INTEGER, {0}, FALSE },
+    { OPTION_DYN_PM,	     "DynamicPM",	 OPTV_BOOLEAN, {0}, FALSE },
     { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
 };
 
@@ -4073,6 +4080,13 @@
     info->BlockHandler = pScreen->BlockHandler;
     pScreen->BlockHandler = RADEONBlockHandler;
 
+/* power management stuff */
+    info->PMActive = FALSE;
+    xf86GetOptValBool(info->Options, OPTION_DYN_PM, &info->PMActive);
+    if (info->PMActive) {
+	RADEONPMEnableDynamicMode(pScrn);
+    }
+
     return TRUE;
 }
 
@@ -5837,6 +5851,10 @@
 
     xf86ClearPrimInitDone(pScrn->entityList[0]);
 
+/* turn off power management */
+    if (info->PMActive)
+	RADEONPMDisableDynamicMode(pScrn);
+
     pScreen->BlockHandler = info->BlockHandler;
     pScreen->CloseScreen = info->CloseScreen;
     return (*pScreen->CloseScreen)(scrnIndex, pScreen);
@@ -5942,3 +5960,175 @@
     if (info->CPStarted) DRIUnlock(pScrn->pScreen);
 #endif
 }
+
+static void RADEONPMDisableDynamicMode(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr  info   = RADEONPTR(pScrn); 
+    unsigned char *RADEONMMIO = info->MMIO;
+    unsigned long sclk_cntl;
+    unsigned long mclk_cntl;
+    unsigned long sclk_more_cntl;
+    unsigned long vclk_ecp_cntl;
+    unsigned long pixclks_cntl;
+
+    /* Mobility chips only */
+    if ((info->ChipFamily != CHIP_FAMILY_M6) && 
+	(info->ChipFamily != CHIP_FAMILY_M7) && 
+	(info->ChipFamily != CHIP_FAMILY_M9))
+		return;
+	
+    /* Force Core Clocks */
+    sclk_cntl = INPLL(pScrn, RADEON_SCLK_CNTL);
+    sclk_cntl |= 	SCLK_CNTL_M6__FORCE_CP|
+			SCLK_CNTL_M6__FORCE_HDP|
+			SCLK_CNTL_M6__FORCE_DISP1|
+			SCLK_CNTL_M6__FORCE_DISP2|
+			SCLK_CNTL_M6__FORCE_TOP|
+			SCLK_CNTL_M6__FORCE_E2|
+			SCLK_CNTL_M6__FORCE_SE|
+			SCLK_CNTL_M6__FORCE_IDCT|
+			SCLK_CNTL_M6__FORCE_VIP|
+			SCLK_CNTL_M6__FORCE_RE|
+			SCLK_CNTL_M6__FORCE_PB|
+			SCLK_CNTL_M6__FORCE_TAM|
+			SCLK_CNTL_M6__FORCE_TDM|
+			SCLK_CNTL_M6__FORCE_RB|
+			SCLK_CNTL_M6__FORCE_TV_SCLK|
+			SCLK_CNTL_M6__FORCE_SUBPIC|
+			SCLK_CNTL_M6__FORCE_OV0;
+    OUTPLL(RADEON_SCLK_CNTL, sclk_cntl);
+	
+	
+	
+    sclk_more_cntl = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
+    sclk_more_cntl |= 	        SCLK_MORE_CNTL__FORCE_DISPREGS|
+				SCLK_MORE_CNTL__FORCE_MC_GUI|
+				SCLK_MORE_CNTL__FORCE_MC_HOST;	
+    OUTPLL(RADEON_SCLK_MORE_CNTL, sclk_more_cntl);
+	
+    /* Force Display clocks	*/
+    vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+    vclk_ecp_cntl &= ~(	VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
+			 	VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
+ 
+    OUTPLL(RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl);
+	
+    pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_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(RADEON_PIXCLKS_CNTL, pixclks_cntl);
+
+    /* Force Memory Clocks */
+    mclk_cntl  = INPLL(pScrn, RADEON_MCLK_CNTL);
+    mclk_cntl |= 	MCLK_CNTL_M6__FORCE_MCLKA|  
+			MCLK_CNTL_M6__FORCE_MCLKB|	
+			MCLK_CNTL_M6__FORCE_YCLKA|
+			MCLK_CNTL_M6__FORCE_YCLKB;
+			
+    OUTPLL(RADEON_MCLK_CNTL, mclk_cntl);
+}
+
+static void RADEONPMEnableDynamicMode(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr  info   = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    unsigned long clk_pwrmgt_cntl;
+    unsigned long sclk_cntl;
+    unsigned long sclk_more_cntl;
+    unsigned long clk_pin_cntl;
+    unsigned long pixclks_cntl;
+    unsigned long vclk_ecp_cntl;
+    unsigned long mclk_cntl;
+    unsigned long mclk_misc;
+
+    /* Mobility chips only */
+    if ((info->ChipFamily != CHIP_FAMILY_M6) &&
+	(info->ChipFamily != CHIP_FAMILY_M7) &&
+        (info->ChipFamily != CHIP_FAMILY_M9))
+                return;
+	
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Power Management Enabled\n");
+
+    /* Set Latencies */
+    clk_pwrmgt_cntl = INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL_M6);
+	
+    clk_pwrmgt_cntl &= ~(	 CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE_MASK|
+				 CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
+				 CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT_MASK|
+				 CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE_MASK);
+    /* Mode 1 */
+    clk_pwrmgt_cntl = 	        CLK_PWRMGT_CNTL_M6__MC_CH_MODE|
+				CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE | 
+				(1<<CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT__SHIFT) |
+				(0<<CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT__SHIFT)|
+				(0<<CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE__SHIFT);
+
+    OUTPLL(RADEON_CLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
+						
+
+    clk_pin_cntl = INPLL(pScrn, RADEON_CLK_PIN_CNTL);
+    clk_pin_cntl |= CLK_PIN_CNTL__SCLK_DYN_START_CNTL;
+	 
+    OUTPLL(RADEON_CLK_PIN_CNTL, clk_pin_cntl);
+
+    /* Enable Dyanmic mode for SCLK */
+
+    sclk_cntl = INPLL(pScrn, RADEON_SCLK_CNTL);	
+    sclk_cntl &= SCLK_CNTL_M6__SCLK_SRC_SEL_MASK;
+    sclk_cntl |= SCLK_CNTL_M6__FORCE_VIP;		
+
+    OUTPLL(RADEON_SCLK_CNTL, sclk_cntl);
+
+
+    sclk_more_cntl = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
+    sclk_more_cntl &= ~(SCLK_MORE_CNTL__FORCE_DISPREGS);
+				                    
+    OUTPLL(RADEON_SCLK_MORE_CNTL, sclk_more_cntl);
+
+	
+    /* Enable Dynamic mode for PIXCLK & PIX2CLK */
+
+    pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+	
+    pixclks_cntl|=      PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb | 
+			PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb|
+			PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
+			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(RADEON_PIXCLKS_CNTL, pixclks_cntl);
+		
+		
+    vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+	
+    vclk_ecp_cntl|=  VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb | 
+			 VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb;
+
+    OUTPLL(RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl);
+
+
+    /* Enable Dynamic mode for MCLK	*/
+    mclk_cntl = INPLL(pScrn, RADEON_MCLK_CNTL);
+    mclk_cntl &= ~(	MCLK_CNTL_M6__FORCE_MCLKA |  
+			MCLK_CNTL_M6__FORCE_MCLKB |
+			MCLK_CNTL_M6__FORCE_YCLKA |
+			MCLK_CNTL_M6__FORCE_YCLKB );
+    OUTPLL(RADEON_MCLK_CNTL, mclk_cntl);
+
+    mclk_misc = INPLL(pScrn, RADEON_MCLK_MISC);
+    mclk_misc |= 	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(RADEON_MCLK_MISC, mclk_misc);
+}
+
--- ../ati.orig/radeon.h	2003-02-23 18:28:48.000000000 -0500
+++ radeon.h	2003-04-14 23:33:45.000000000 -0400
@@ -530,6 +530,10 @@
 #ifdef XFree86LOADER
     XF86ModReqInfo    xaaReq;
 #endif
+
+/* Power management support */
+    Bool PMActive;
+
 } RADEONInfoRec, *RADEONInfoPtr;
 
 #define RADEONWaitForFifo(pScrn, entries)				\
--- ../ati.orig/radeon_reg.h	2003-02-07 13:08:59.000000000 -0500
+++ radeon_reg.h	2003-04-14 22:32:30.000000000 -0400
@@ -1995,4 +1995,66 @@
 #define RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR    51
 #define RADEON_SS_SHININESS                      60
 
+/* dynamic power management */
+#define RADEON_CLK_PWRMGT_CNTL_M6                       0x0014
+#define RADEON_MCLK_MISC                                0x001F
+
+#define	CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT__SHIFT         0x0000000d
+#define	CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT__SHIFT       0x0000000f
+#define	CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE__SHIFT           0x00000015
+
+#define PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb                   0x00000040L
+#define PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb               0x00000080L
+#define PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb              0x00000800L
+#define PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb                 0x00001000L
+#define PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb           0x00002000L
+#define PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb               0x00004000L
+#define PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb               0x00008000L
+
+#define SCLK_CNTL_M6__SCLK_SRC_SEL_MASK                    0x00000007L
+#define SCLK_CNTL_M6__FORCE_DISP2                          0x00008000L
+#define SCLK_CNTL_M6__FORCE_CP                             0x00010000L
+#define SCLK_CNTL_M6__FORCE_HDP                            0x00020000L
+#define SCLK_CNTL_M6__FORCE_DISP1                          0x00040000L
+#define SCLK_CNTL_M6__FORCE_TOP                            0x00080000L
+#define SCLK_CNTL_M6__FORCE_E2                             0x00100000L
+#define SCLK_CNTL_M6__FORCE_SE                             0x00200000L
+#define SCLK_CNTL_M6__FORCE_IDCT                           0x00400000L
+#define SCLK_CNTL_M6__FORCE_VIP                            0x00800000L
+#define SCLK_CNTL_M6__FORCE_RE                             0x01000000L
+#define SCLK_CNTL_M6__FORCE_PB                             0x02000000L
+#define SCLK_CNTL_M6__FORCE_TV_SCLK                        0x20000000L
+#define SCLK_CNTL_M6__FORCE_SUBPIC                         0x40000000L
+#define SCLK_CNTL_M6__FORCE_OV0                            0x80000000L
+#define SCLK_CNTL_M6__FORCE_TAM                            0x04000000L
+#define SCLK_CNTL_M6__FORCE_TDM                            0x08000000L
+#define SCLK_CNTL_M6__FORCE_RB                             0x10000000L
+
+#define SCLK_MORE_CNTL__FORCE_DISPREGS                     0x00000100L
+#define SCLK_MORE_CNTL__FORCE_MC_GUI                       0x00000200L
+#define SCLK_MORE_CNTL__FORCE_MC_HOST                      0x00000400L
+
+#define MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT                0x00001000L
+#define MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT                0x00002000L
+#define MCLK_MISC__MC_MCLK_DYN_ENABLE                      0x00004000L
+#define MCLK_MISC__IO_MCLK_DYN_ENABLE                      0x00008000L
+
+#define VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb                   0x00000040L
+#define VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb               0x00000080L
+
+#define CLK_PWRMGT_CNTL_M6__MC_CH_MODE                     0x00000100L
+#define CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE_MASK        0x00001000L
+#define CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE             0x00001000L
+#define CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK           0x00006000L
+#define CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT_MASK         0x00008000L
+#define CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE_MASK             0x00e00000L
+
+#define MCLK_CNTL_M6__FORCE_MCLKA                          0x00010000L
+#define MCLK_CNTL_M6__FORCE_MCLKB                          0x00020000L
+#define MCLK_CNTL_M6__FORCE_YCLKA                          0x00040000L
+#define MCLK_CNTL_M6__FORCE_YCLKB                          0x00080000L
+
+#define CLK_PIN_CNTL__SCLK_DYN_START_CNTL                  0x00008000L
+/* dymanic power managment */
+
 #endif
