]> Pileus Git - ~andy/linux/blobdiff - drivers/gpu/drm/i915/intel_display.c
Merge commit 'Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux'
[~andy/linux] / drivers / gpu / drm / i915 / intel_display.c
index 32024dadcceef121c819ef280b554146039b3f49..baaefd70cc67c814226e5879c9b427af07bc67ea 100644 (file)
@@ -4947,22 +4947,19 @@ static void i9xx_get_pfit_config(struct intel_crtc *crtc,
        uint32_t tmp;
 
        tmp = I915_READ(PFIT_CONTROL);
+       if (!(tmp & PFIT_ENABLE))
+               return;
 
+       /* Check whether the pfit is attached to our pipe. */
        if (INTEL_INFO(dev)->gen < 4) {
                if (crtc->pipe != PIPE_B)
                        return;
-
-               /* gen2/3 store dither state in pfit control, needs to match */
-               pipe_config->gmch_pfit.control = tmp & PANEL_8TO6_DITHER_ENABLE;
        } else {
                if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT))
                        return;
        }
 
-       if (!(tmp & PFIT_ENABLE))
-               return;
-
-       pipe_config->gmch_pfit.control = I915_READ(PFIT_CONTROL);
+       pipe_config->gmch_pfit.control = tmp;
        pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS);
        if (INTEL_INFO(dev)->gen < 5)
                pipe_config->gmch_pfit.lvds_border_bits =
@@ -8600,6 +8597,8 @@ check_shared_dpll_state(struct drm_device *dev)
                     pll->active, pll->refcount);
                WARN(pll->active && !pll->on,
                     "pll in active use but not on in sw tracking\n");
+               WARN(pll->on && !pll->active,
+                    "pll in on but not on in use in sw tracking\n");
                WARN(pll->on != active,
                     "pll on state mismatch (expected %i, found %i)\n",
                     pll->on, active);
@@ -8824,15 +8823,20 @@ static void intel_set_config_restore_state(struct drm_device *dev,
 }
 
 static bool
-is_crtc_connector_off(struct drm_crtc *crtc, struct drm_connector *connectors,
-                     int num_connectors)
+is_crtc_connector_off(struct drm_mode_set *set)
 {
        int i;
 
-       for (i = 0; i < num_connectors; i++)
-               if (connectors[i].encoder &&
-                   connectors[i].encoder->crtc == crtc &&
-                   connectors[i].dpms != DRM_MODE_DPMS_ON)
+       if (set->num_connectors == 0)
+               return false;
+
+       if (WARN_ON(set->connectors == NULL))
+               return false;
+
+       for (i = 0; i < set->num_connectors; i++)
+               if (set->connectors[i]->encoder &&
+                   set->connectors[i]->encoder->crtc == set->crtc &&
+                   set->connectors[i]->dpms != DRM_MODE_DPMS_ON)
                        return true;
 
        return false;
@@ -8845,10 +8849,8 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
 
        /* We should be able to check here if the fb has the same properties
         * and then just flip_or_move it */
-       if (set->connectors != NULL &&
-           is_crtc_connector_off(set->crtc, *set->connectors,
-                                 set->num_connectors)) {
-                       config->mode_changed = true;
+       if (is_crtc_connector_off(set)) {
+               config->mode_changed = true;
        } else if (set->crtc->fb != set->fb) {
                /* If we have no fb then treat it as a full mode set */
                if (set->crtc->fb == NULL) {
@@ -9702,6 +9704,17 @@ static void quirk_invert_brightness(struct drm_device *dev)
        DRM_INFO("applying inverted panel brightness quirk\n");
 }
 
+/*
+ * Some machines (Dell XPS13) suffer broken backlight controls if
+ * BLM_PCH_PWM_ENABLE is set.
+ */
+static void quirk_no_pcm_pwm_enable(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       dev_priv->quirks |= QUIRK_NO_PCH_PWM_ENABLE;
+       DRM_INFO("applying no-PCH_PWM_ENABLE quirk\n");
+}
+
 struct intel_quirk {
        int device;
        int subsystem_vendor;
@@ -9771,6 +9784,11 @@ static struct intel_quirk intel_quirks[] = {
 
        /* Acer Aspire 4736Z */
        { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness },
+
+       /* Dell XPS13 HD Sandy Bridge */
+       { 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable },
+       /* Dell XPS13 HD and XPS13 FHD Ivy Bridge */
+       { 0x0166, 0x1028, 0x058b, quirk_no_pcm_pwm_enable },
 };
 
 static void intel_init_quirks(struct drm_device *dev)
@@ -10121,8 +10139,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                }
                pll->refcount = pll->active;
 
-               DRM_DEBUG_KMS("%s hw state readout: refcount %i\n",
-                             pll->name, pll->refcount);
+               DRM_DEBUG_KMS("%s hw state readout: refcount %i, on %i\n",
+                             pll->name, pll->refcount, pll->on);
        }
 
        list_for_each_entry(encoder, &dev->mode_config.encoder_list,
@@ -10182,6 +10200,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
        struct drm_plane *plane;
        struct intel_crtc *crtc;
        struct intel_encoder *encoder;
+       int i;
 
        intel_modeset_readout_hw_state(dev);
 
@@ -10213,6 +10232,18 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
                intel_dump_pipe_config(crtc, &crtc->config, "[setup_hw_state]");
        }
 
+       for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+               struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
+
+               if (!pll->on || pll->active)
+                       continue;
+
+               DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name);
+
+               pll->disable(dev_priv, pll);
+               pll->on = false;
+       }
+
        if (force_restore) {
                /*
                 * We need to use raw interfaces for restoring state to avoid