extern u32 intel_panel_get_backlight(struct drm_device *dev);
 extern void intel_panel_set_backlight(struct drm_device *dev, u32 level);
 extern int intel_panel_setup_backlight(struct drm_device *dev);
-extern void intel_panel_enable_backlight(struct drm_device *dev);
+extern void intel_panel_enable_backlight(struct drm_device *dev,
+                                        enum pipe pipe);
 extern void intel_panel_disable_backlight(struct drm_device *dev);
 extern void intel_panel_destroy_backlight(struct drm_device *dev);
 extern enum drm_connector_status intel_panel_detect(struct drm_device *dev);
 
 static void intel_lvds_enable(struct intel_lvds *intel_lvds)
 {
        struct drm_device *dev = intel_lvds->base.base.dev;
+       struct intel_crtc *intel_crtc = to_intel_crtc(intel_lvds->base.base.crtc);
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 ctl_reg, lvds_reg, stat_reg;
 
        if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000))
                DRM_ERROR("timed out waiting for panel to power on\n");
 
-       intel_panel_enable_backlight(dev);
+       intel_panel_enable_backlight(dev, intel_crtc->pipe);
 }
 
 static void intel_lvds_disable(struct intel_lvds *intel_lvds)
                goto failed;
 
 out:
+       /*
+        * Unlock registers and just
+        * leave them unlocked
+        */
        if (HAS_PCH_SPLIT(dev)) {
-               u32 pwm;
-
-               pipe = (I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT) ? 1 : 0;
-
-               /* make sure PWM is enabled and locked to the LVDS pipe */
-               pwm = I915_READ(BLC_PWM_CPU_CTL2);
-               if (pipe == 0 && (pwm & BLM_PIPE_B))
-                       I915_WRITE(BLC_PWM_CPU_CTL2, pwm & ~BLM_PWM_ENABLE);
-               if (pipe)
-                       pwm |= BLM_PIPE_B;
-               else
-                       pwm &= ~BLM_PIPE_B;
-               I915_WRITE(BLC_PWM_CPU_CTL2, pwm | BLM_PWM_ENABLE);
-
-               pwm = I915_READ(BLC_PWM_PCH_CTL1);
-               pwm |= BLM_PCH_PWM_ENABLE;
-               I915_WRITE(BLC_PWM_PCH_CTL1, pwm);
-               /*
-                * Unlock registers and just
-                * leave them unlocked
-                */
                I915_WRITE(PCH_PP_CONTROL,
                           I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS);
        } else {
-               /*
-                * Unlock registers and just
-                * leave them unlocked
-                */
                I915_WRITE(PP_CONTROL,
                           I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS);
        }
 
 
        dev_priv->backlight_enabled = false;
        intel_panel_actually_set_backlight(dev, 0);
+
+       if (INTEL_INFO(dev)->gen >= 4) {
+               uint32_t reg;
+
+               reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2;
+
+               I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE);
+       }
 }
 
-void intel_panel_enable_backlight(struct drm_device *dev)
+void intel_panel_enable_backlight(struct drm_device *dev,
+                                 enum pipe pipe)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
 
        dev_priv->backlight_enabled = true;
        intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
+
+       if (INTEL_INFO(dev)->gen >= 4) {
+               uint32_t reg, tmp;
+
+               reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2;
+
+
+               tmp = I915_READ(reg);
+
+               /* Note that this can also get called through dpms changes. And
+                * we don't track the backlight dpms state, hence check whether
+                * we have to do anything first. */
+               if (tmp & BLM_PWM_ENABLE)
+                       return;
+
+               if (dev_priv->num_pipe == 3)
+                       tmp &= ~BLM_PIPE_SELECT_IVB;
+               else
+                       tmp &= ~BLM_PIPE_SELECT;
+
+               tmp |= BLM_PIPE(pipe);
+               tmp &= ~BLM_PWM_ENABLE;
+
+               I915_WRITE(reg, tmp);
+               POSTING_READ(reg);
+               I915_WRITE(reg, tmp | BLM_PWM_ENABLE);
+       }
 }
 
 static void intel_panel_init_backlight(struct drm_device *dev)