diff --git a/src/i830.h b/src/i830.h
index 2a804ab..514437a 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -447,6 +447,12 @@ typedef struct _I830Rec {
 #endif
 #endif
 
+#ifdef DAMAGE
+   DamagePtr pPMDamage;
+   Bool idle;
+   TimeStamp idleTime;
+#endif
+
    Bool NeedRingBufferLow;
    Bool allowPageFlip;
    Bool TripleBuffer;
@@ -804,6 +810,7 @@ void i830_dvo_init(ScrnInfoPtr pScrn);
 
 /* i830_lvds.c */
 void i830_lvds_init(ScrnInfoPtr pScrn);
+void i830_lvds_reclock(I830Ptr pI830);
 
 extern void i830MarkSync(ScrnInfoPtr pScrn);
 extern void i830WaitSync(ScrnInfoPtr pScrn);
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 43a65cb..3df2779 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -172,6 +172,12 @@ i830_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
     I830CrtcPrivatePtr	intel_crtc = I830CrtcPrivate(crtc);
     uint32_t		temp;
 
+    if (pI830->idle) {
+	pI830->idle=0;
+	i830_lvds_reclock(pI830);
+	pI830->idleTime = currentTime;
+    }
+
     temp = 0;
     if (x < 0) {
 	temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
diff --git a/src/i830_display.c b/src/i830_display.c
index 56a718d..4abcfc3 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1083,7 +1083,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
     int i;
     int refclk;
     intel_clock_t clock;
-    uint32_t dpll = 0, fp = 0, dspcntr, pipeconf, lvds_bits = 0;
+    uint32_t dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf, lvds_bits = 0;
     Bool ok, is_sdvo = FALSE, is_dvo = FALSE;
     Bool is_crt = FALSE, is_lvds = FALSE, is_tv = FALSE;
 
@@ -1140,6 +1140,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
     }
 
     fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
+    fp2 = (((clock.n+2)*2)-2) << 16 | clock.m1 << 8 | clock.m2;
 
     dpll = DPLL_VGA_MODE_DIS;
     if (IS_I9XX(pI830)) {
@@ -1276,6 +1277,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
     if (dpll & DPLL_VCO_ENABLE)
     {
 	OUTREG(fp_reg, fp);
+	OUTREG(fp_reg+4, fp2);
 	OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
 	POSTING_READ(dpll_reg);
 	usleep(150);
@@ -1330,6 +1332,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
     }
 
     OUTREG(fp_reg, fp);
+    OUTREG(fp_reg+4, fp2);
     OUTREG(dpll_reg, dpll);
     POSTING_READ(dpll_reg);
     /* Wait for the clocks to stabilize. */
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 604665e..979a372 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -882,6 +882,11 @@ i830CreateScreenResources(ScreenPtr pScreen)
 
    i830_update_front_offset(pScrn);
 
+#ifdef DAMAGE
+   DamageRegister(&pScrn->pScreen->GetScreenPixmap(pScrn->pScreen)->drawable, 
+		  pI830->pPMDamage);
+#endif
+
    return TRUE;
 }
 
@@ -1090,6 +1095,65 @@ static const xf86CrtcConfigFuncsRec i830_xf86crtc_config_funcs = {
     i830_xf86crtc_resize
 };
 
+#define WAIT_MILLIS 10
+
+static void
+I830PMBlockHandler(void *closure,
+		struct timeval **wt,
+		void *selectmask)
+{
+    I830Ptr pI830 = closure;
+
+    if (pI830->idle)
+	    return;
+
+    if (pI830->pPMDamage)
+	    DamageEmpty(pI830->pPMDamage);
+
+    AdjustWaitForDelay(wt, WAIT_MILLIS);
+}
+
+static void
+I830WakeupHandler(void *closure,
+		  int rc,
+		  void *selectmask)
+{
+    I830Ptr pI830 = closure;    
+
+    if (pI830->idle)
+	    return;
+
+    if (currentTime.milliseconds - pI830->idleTime.milliseconds 
+	> WAIT_MILLIS) {
+	    pI830->idle = 1;
+	    i830_lvds_reclock(pI830);
+    } else {
+	    UpdateCurrentTime();
+    }
+}
+
+static void
+I830DamageReport(DamagePtr pDamage, RegionPtr pRegion, void *closure)
+{
+    I830Ptr pI830 = closure;
+    if (pI830->idle) {
+	    i830_lvds_reclock(pI830);
+	    pI830->idle=0;
+    }
+    pI830->idleTime = currentTime;
+}
+
+static void
+I830DamageDestroy(DamagePtr pDamage, void *closure)
+{	
+    I830Ptr pI830 = closure;
+    if (pI830->idle) {
+	    i830_lvds_reclock(pI830);
+	    pI830->idle=0;
+    }
+    pI830->idleTime = currentTime;
+}
+
 #define HOTKEY_BIOS_SWITCH	0
 #define HOTKEY_DRIVER_NOTIFY	1
 
@@ -1842,6 +1906,15 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
    }
 #endif
 
+#if defined(DAMAGE)
+   RegisterBlockAndWakeupHandlers(I830PMBlockHandler,
+				  I830WakeupHandler,
+				  pI830);
+   pI830->pPMDamage = DamageCreate(I830DamageReport, I830DamageDestroy,
+				   DamageReportNonEmpty, TRUE, pScrn->pScreen,
+				   pI830);
+#endif
+
    pI830->preinit = FALSE;
 
    return TRUE;
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index af82ee7..8c693e3 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -501,6 +501,23 @@ i830_lvds_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
     return MODE_OK;
 }
 
+void
+i830_lvds_reclock(I830Ptr pI830)
+{	
+    /* 965 has hardware level refresh adjustment */
+    if (!IS_MOBILE(pI830) || IS_I830(pI830) || IS_I965G(pI830))
+	    return;
+
+    OUTREG(PP_CONTROL, INREG(PP_CONTROL) | (0xabcd << 16));
+    /* We don't get damage events for the hardware overlay, so force high-speed
+       if we're using it */
+    if (pI830->idle && !*pI830->overlayOn)
+	    OUTREG(DPLL_B, INREG(DPLL_B) | DISPLAY_RATE_SELECT_FPA1);
+    else
+	    OUTREG(DPLL_B, INREG(DPLL_B) & ~DISPLAY_RATE_SELECT_FPA1);
+    OUTREG(PP_CONTROL, INREG(PP_CONTROL) & 0x3);
+}
+
 static Bool
 i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		     DisplayModePtr adjusted_mode)
@@ -1396,6 +1413,10 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 
     dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output);
 
+    /* Enable automatic refresh rate adjustment on 965 */
+    if (IS_I965G(pI830))
+	    OUTREG(PIPEBCONF, (INREG(PIPEBCONF) & 0xFFFCFFFF) | (1 << 16));
+
     /*
      * Default to filling the whole screen if the mode is less than the
      * native size. (Change default to origin FULL mode, i8xx can only work
diff --git a/src/i830_video.c b/src/i830_video.c
index 7b81b04..8a51676 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -449,6 +449,12 @@ i830_overlay_on(ScrnInfoPtr pScrn)
     if (*pI830->overlayOn)
 	return;
 
+    /* We won't get damage events while the overlay is enabled, so force the
+       screen to full refresh rate */
+
+    pI830->idle = 0;
+    i830_lvds_reclock(pI830);
+
     /*
      * On I830, if pipe A is off when the overlayis enabled, it will fail to
      * turn on and blank the entire screen or lock up the ring. Light up pipe
@@ -558,6 +564,9 @@ i830_overlay_off(ScrnInfoPtr pScrn)
     }
     *pI830->overlayOn = FALSE;
     OVERLAY_DEBUG("overlay_off\n");
+
+    pI830->idle=1;
+    i830_lvds_reclock(pI830);
 }
 
 void
