]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/gpu/drm/i915/intel_lvds.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / gpu / drm / i915 / intel_lvds.c
index 25bcedf386fd5e07f93b2c2f77d78dd8dc905170..bcdba7bd5cfafb26efa1b8f150530836d8cc5c71 100644 (file)
@@ -106,7 +106,7 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds)
        I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
        POSTING_READ(lvds_reg);
 
-       intel_panel_set_backlight(dev, dev_priv->backlight_level);
+       intel_panel_enable_backlight(dev);
 }
 
 static void intel_lvds_disable(struct intel_lvds *intel_lvds)
@@ -123,8 +123,7 @@ static void intel_lvds_disable(struct intel_lvds *intel_lvds)
                lvds_reg = LVDS;
        }
 
-       dev_priv->backlight_level = intel_panel_get_backlight(dev);
-       intel_panel_set_backlight(dev, 0);
+       intel_panel_disable_backlight(dev);
 
        I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
 
@@ -262,12 +261,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
                return true;
        }
 
-       /* Make sure pre-965s set dither correctly */
-       if (INTEL_INFO(dev)->gen < 4) {
-               if (dev_priv->lvds_dither)
-                       pfit_control |= PANEL_8TO6_DITHER_ENABLE;
-       }
-
        /* Native modes don't need fitting */
        if (adjusted_mode->hdisplay == mode->hdisplay &&
            adjusted_mode->vdisplay == mode->vdisplay)
@@ -304,14 +297,13 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
                        u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay;
                        u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay;
 
-                       pfit_control |= PFIT_ENABLE;
                        /* 965+ is easy, it does everything in hw */
                        if (scaled_width > scaled_height)
-                               pfit_control |= PFIT_SCALING_PILLAR;
+                               pfit_control |= PFIT_ENABLE | PFIT_SCALING_PILLAR;
                        else if (scaled_width < scaled_height)
-                               pfit_control |= PFIT_SCALING_LETTER;
-                       else
-                               pfit_control |= PFIT_SCALING_AUTO;
+                               pfit_control |= PFIT_ENABLE | PFIT_SCALING_LETTER;
+                       else if (adjusted_mode->hdisplay != mode->hdisplay)
+                               pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
                } else {
                        u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay;
                        u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay;
@@ -358,13 +350,17 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
                 * Full scaling, even if it changes the aspect ratio.
                 * Fortunately this is all done for us in hw.
                 */
-               pfit_control |= PFIT_ENABLE;
-               if (INTEL_INFO(dev)->gen >= 4)
-                       pfit_control |= PFIT_SCALING_AUTO;
-               else
-                       pfit_control |= (VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
-                                        VERT_INTERP_BILINEAR |
-                                        HORIZ_INTERP_BILINEAR);
+               if (mode->vdisplay != adjusted_mode->vdisplay ||
+                   mode->hdisplay != adjusted_mode->hdisplay) {
+                       pfit_control |= PFIT_ENABLE;
+                       if (INTEL_INFO(dev)->gen >= 4)
+                               pfit_control |= PFIT_SCALING_AUTO;
+                       else
+                               pfit_control |= (VERT_AUTO_SCALE |
+                                                VERT_INTERP_BILINEAR |
+                                                HORIZ_AUTO_SCALE |
+                                                HORIZ_INTERP_BILINEAR);
+               }
                break;
 
        default:
@@ -372,6 +368,16 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
        }
 
 out:
+       /* If not enabling scaling, be consistent and always use 0. */
+       if ((pfit_control & PFIT_ENABLE) == 0) {
+               pfit_control = 0;
+               pfit_pgm_ratios = 0;
+       }
+
+       /* Make sure pre-965 set dither correctly */
+       if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither)
+               pfit_control |= PANEL_8TO6_DITHER_ENABLE;
+
        if (pfit_control != intel_lvds->pfit_control ||
            pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) {
                intel_lvds->pfit_control = pfit_control;
@@ -395,8 +401,6 @@ static void intel_lvds_prepare(struct drm_encoder *encoder)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
 
-       dev_priv->backlight_level = intel_panel_get_backlight(dev);
-
        /* We try to do the minimum that is necessary in order to unlock
         * the registers for mode setting.
         *
@@ -427,9 +431,6 @@ static void intel_lvds_commit(struct drm_encoder *encoder)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
 
-       if (dev_priv->backlight_level == 0)
-               dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
-
        /* Undo any unlocking done in prepare to prevent accidental
         * adjustment of the registers.
         */
@@ -701,6 +702,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"),
                },
        },
+       {
+               .callback = intel_no_lvds_dmi_callback,
+               .ident = "AOpen i915GMm-HFS",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
+                       DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
+               },
+       },
        {
                .callback = intel_no_lvds_dmi_callback,
                .ident = "Aopen i945GTt-VFA",
@@ -914,6 +923,8 @@ bool intel_lvds_init(struct drm_device *dev)
 
        intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
        intel_encoder->crtc_mask = (1 << 1);
+       if (INTEL_INFO(dev)->gen >= 5)
+               intel_encoder->crtc_mask |= (1 << 0);
        drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
        drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
@@ -1019,10 +1030,18 @@ bool intel_lvds_init(struct drm_device *dev)
 out:
        if (HAS_PCH_SPLIT(dev)) {
                u32 pwm;
-               /* make sure PWM is enabled */
+
+               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);
-               pwm |= (PWM_ENABLE | PWM_PIPE_B);
-               I915_WRITE(BLC_PWM_CPU_CTL2, pwm);
+               if (pipe == 0 && (pwm & PWM_PIPE_B))
+                       I915_WRITE(BLC_PWM_CPU_CTL2, pwm & ~PWM_ENABLE);
+               if (pipe)
+                       pwm |= PWM_PIPE_B;
+               else
+                       pwm &= ~PWM_PIPE_B;
+               I915_WRITE(BLC_PWM_CPU_CTL2, pwm | PWM_ENABLE);
 
                pwm = I915_READ(BLC_PWM_PCH_CTL1);
                pwm |= PWM_PCH_ENABLE;