diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 85f3eb74d2b7..5fb305840db8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -4913,22 +4913,19 @@ static void i9xx_get_pfit_config(struct intel_crtc *crtc, | |||
4913 | uint32_t tmp; | 4913 | uint32_t tmp; |
4914 | 4914 | ||
4915 | tmp = I915_READ(PFIT_CONTROL); | 4915 | tmp = I915_READ(PFIT_CONTROL); |
4916 | if (!(tmp & PFIT_ENABLE)) | ||
4917 | return; | ||
4916 | 4918 | ||
4919 | /* Check whether the pfit is attached to our pipe. */ | ||
4917 | if (INTEL_INFO(dev)->gen < 4) { | 4920 | if (INTEL_INFO(dev)->gen < 4) { |
4918 | if (crtc->pipe != PIPE_B) | 4921 | if (crtc->pipe != PIPE_B) |
4919 | return; | 4922 | return; |
4920 | |||
4921 | /* gen2/3 store dither state in pfit control, needs to match */ | ||
4922 | pipe_config->gmch_pfit.control = tmp & PANEL_8TO6_DITHER_ENABLE; | ||
4923 | } else { | 4923 | } else { |
4924 | if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT)) | 4924 | if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT)) |
4925 | return; | 4925 | return; |
4926 | } | 4926 | } |
4927 | 4927 | ||
4928 | if (!(tmp & PFIT_ENABLE)) | 4928 | pipe_config->gmch_pfit.control = tmp; |
4929 | return; | ||
4930 | |||
4931 | pipe_config->gmch_pfit.control = I915_READ(PFIT_CONTROL); | ||
4932 | pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS); | 4929 | pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS); |
4933 | if (INTEL_INFO(dev)->gen < 5) | 4930 | if (INTEL_INFO(dev)->gen < 5) |
4934 | pipe_config->gmch_pfit.lvds_border_bits = | 4931 | pipe_config->gmch_pfit.lvds_border_bits = |
@@ -8317,6 +8314,8 @@ check_shared_dpll_state(struct drm_device *dev) | |||
8317 | pll->active, pll->refcount); | 8314 | pll->active, pll->refcount); |
8318 | WARN(pll->active && !pll->on, | 8315 | WARN(pll->active && !pll->on, |
8319 | "pll in active use but not on in sw tracking\n"); | 8316 | "pll in active use but not on in sw tracking\n"); |
8317 | WARN(pll->on && !pll->active, | ||
8318 | "pll in on but not on in use in sw tracking\n"); | ||
8320 | WARN(pll->on != active, | 8319 | WARN(pll->on != active, |
8321 | "pll on state mismatch (expected %i, found %i)\n", | 8320 | "pll on state mismatch (expected %i, found %i)\n", |
8322 | pll->on, active); | 8321 | pll->on, active); |
@@ -8541,15 +8540,20 @@ static void intel_set_config_restore_state(struct drm_device *dev, | |||
8541 | } | 8540 | } |
8542 | 8541 | ||
8543 | static bool | 8542 | static bool |
8544 | is_crtc_connector_off(struct drm_crtc *crtc, struct drm_connector *connectors, | 8543 | is_crtc_connector_off(struct drm_mode_set *set) |
8545 | int num_connectors) | ||
8546 | { | 8544 | { |
8547 | int i; | 8545 | int i; |
8548 | 8546 | ||
8549 | for (i = 0; i < num_connectors; i++) | 8547 | if (set->num_connectors == 0) |
8550 | if (connectors[i].encoder && | 8548 | return false; |
8551 | connectors[i].encoder->crtc == crtc && | 8549 | |
8552 | connectors[i].dpms != DRM_MODE_DPMS_ON) | 8550 | if (WARN_ON(set->connectors == NULL)) |
8551 | return false; | ||
8552 | |||
8553 | for (i = 0; i < set->num_connectors; i++) | ||
8554 | if (set->connectors[i]->encoder && | ||
8555 | set->connectors[i]->encoder->crtc == set->crtc && | ||
8556 | set->connectors[i]->dpms != DRM_MODE_DPMS_ON) | ||
8553 | return true; | 8557 | return true; |
8554 | 8558 | ||
8555 | return false; | 8559 | return false; |
@@ -8562,10 +8566,8 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set, | |||
8562 | 8566 | ||
8563 | /* We should be able to check here if the fb has the same properties | 8567 | /* We should be able to check here if the fb has the same properties |
8564 | * and then just flip_or_move it */ | 8568 | * and then just flip_or_move it */ |
8565 | if (set->connectors != NULL && | 8569 | if (is_crtc_connector_off(set)) { |
8566 | is_crtc_connector_off(set->crtc, *set->connectors, | 8570 | config->mode_changed = true; |
8567 | set->num_connectors)) { | ||
8568 | config->mode_changed = true; | ||
8569 | } else if (set->crtc->fb != set->fb) { | 8571 | } else if (set->crtc->fb != set->fb) { |
8570 | /* If we have no fb then treat it as a full mode set */ | 8572 | /* If we have no fb then treat it as a full mode set */ |
8571 | if (set->crtc->fb == NULL) { | 8573 | if (set->crtc->fb == NULL) { |
@@ -9398,6 +9400,17 @@ static void quirk_invert_brightness(struct drm_device *dev) | |||
9398 | DRM_INFO("applying inverted panel brightness quirk\n"); | 9400 | DRM_INFO("applying inverted panel brightness quirk\n"); |
9399 | } | 9401 | } |
9400 | 9402 | ||
9403 | /* | ||
9404 | * Some machines (Dell XPS13) suffer broken backlight controls if | ||
9405 | * BLM_PCH_PWM_ENABLE is set. | ||
9406 | */ | ||
9407 | static void quirk_no_pcm_pwm_enable(struct drm_device *dev) | ||
9408 | { | ||
9409 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9410 | dev_priv->quirks |= QUIRK_NO_PCH_PWM_ENABLE; | ||
9411 | DRM_INFO("applying no-PCH_PWM_ENABLE quirk\n"); | ||
9412 | } | ||
9413 | |||
9401 | struct intel_quirk { | 9414 | struct intel_quirk { |
9402 | int device; | 9415 | int device; |
9403 | int subsystem_vendor; | 9416 | int subsystem_vendor; |
@@ -9467,6 +9480,11 @@ static struct intel_quirk intel_quirks[] = { | |||
9467 | 9480 | ||
9468 | /* Acer Aspire 4736Z */ | 9481 | /* Acer Aspire 4736Z */ |
9469 | { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness }, | 9482 | { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness }, |
9483 | |||
9484 | /* Dell XPS13 HD Sandy Bridge */ | ||
9485 | { 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable }, | ||
9486 | /* Dell XPS13 HD and XPS13 FHD Ivy Bridge */ | ||
9487 | { 0x0166, 0x1028, 0x058b, quirk_no_pcm_pwm_enable }, | ||
9470 | }; | 9488 | }; |
9471 | 9489 | ||
9472 | static void intel_init_quirks(struct drm_device *dev) | 9490 | static void intel_init_quirks(struct drm_device *dev) |
@@ -9817,8 +9835,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) | |||
9817 | } | 9835 | } |
9818 | pll->refcount = pll->active; | 9836 | pll->refcount = pll->active; |
9819 | 9837 | ||
9820 | DRM_DEBUG_KMS("%s hw state readout: refcount %i\n", | 9838 | DRM_DEBUG_KMS("%s hw state readout: refcount %i, on %i\n", |
9821 | pll->name, pll->refcount); | 9839 | pll->name, pll->refcount, pll->on); |
9822 | } | 9840 | } |
9823 | 9841 | ||
9824 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | 9842 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
@@ -9869,6 +9887,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, | |||
9869 | struct drm_plane *plane; | 9887 | struct drm_plane *plane; |
9870 | struct intel_crtc *crtc; | 9888 | struct intel_crtc *crtc; |
9871 | struct intel_encoder *encoder; | 9889 | struct intel_encoder *encoder; |
9890 | int i; | ||
9872 | 9891 | ||
9873 | intel_modeset_readout_hw_state(dev); | 9892 | intel_modeset_readout_hw_state(dev); |
9874 | 9893 | ||
@@ -9884,6 +9903,18 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, | |||
9884 | intel_dump_pipe_config(crtc, &crtc->config, "[setup_hw_state]"); | 9903 | intel_dump_pipe_config(crtc, &crtc->config, "[setup_hw_state]"); |
9885 | } | 9904 | } |
9886 | 9905 | ||
9906 | for (i = 0; i < dev_priv->num_shared_dpll; i++) { | ||
9907 | struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; | ||
9908 | |||
9909 | if (!pll->on || pll->active) | ||
9910 | continue; | ||
9911 | |||
9912 | DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name); | ||
9913 | |||
9914 | pll->disable(dev_priv, pll); | ||
9915 | pll->on = false; | ||
9916 | } | ||
9917 | |||
9887 | if (force_restore) { | 9918 | if (force_restore) { |
9888 | /* | 9919 | /* |
9889 | * We need to use raw interfaces for restoring state to avoid | 9920 | * We need to use raw interfaces for restoring state to avoid |