From: Ville Syrjälä Date: Wed, 12 Jun 2019 17:24:23 +0000 (+0300) Subject: drm/i915: Don't clobber M/N values during fastset check X-Git-Tag: Ubuntu-5.13.0-19.19~8107^2~16^2~15 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=f0521558a2a89d58a08745e225025d338572e60a;p=mirror_ubuntu-jammy-kernel.git drm/i915: Don't clobber M/N values during fastset check We're now calling intel_pipe_config_compare(..., true) uncoditionally which means we're always going clobber the calculated M/N values with the old values if the fuzzy M/N check passes. That causes problems because the fuzzy check allows for a huge difference in the values. I'm actually tempted to just make the M/N checks exact, but that might prevent fastboot from kicking in when people want it. So for now let's overwrite the computed values with the old values only if decide to skip the modeset. v2: Copy has_drrs along with M/N M2/N2 values Cc: stable@vger.kernel.org Cc: Blubberbub@protonmail.com Cc: Maarten Lankhorst Cc: Hans de Goede Tested-by: Blubberbub@protonmail.com Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=110782 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=110675 Fixes: d19f958db23c ("drm/i915: Enable fastset for non-boot modesets.") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190612172423.25231-1-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ad5cccf4413d..853f2a37e8db 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -12300,9 +12300,6 @@ intel_compare_link_m_n(const struct intel_link_m_n *m_n, m2_n2->gmch_m, m2_n2->gmch_n, !adjust) && intel_compare_m_n(m_n->link_m, m_n->link_n, m2_n2->link_m, m2_n2->link_n, !adjust)) { - if (adjust) - *m2_n2 = *m_n; - return true; } @@ -13434,6 +13431,33 @@ static int calc_watermark_data(struct intel_atomic_state *state) return 0; } +static void intel_crtc_check_fastset(struct intel_crtc_state *old_crtc_state, + struct intel_crtc_state *new_crtc_state) +{ + struct drm_i915_private *dev_priv = + to_i915(new_crtc_state->base.crtc->dev); + + if (!intel_pipe_config_compare(dev_priv, old_crtc_state, + new_crtc_state, true)) + return; + + new_crtc_state->base.mode_changed = false; + new_crtc_state->update_pipe = true; + + /* + * If we're not doing the full modeset we want to + * keep the current M/N values as they may be + * sufficiently different to the computed values + * to cause problems. + * + * FIXME: should really copy more fuzzy state here + */ + new_crtc_state->fdi_m_n = old_crtc_state->fdi_m_n; + new_crtc_state->dp_m_n = old_crtc_state->dp_m_n; + new_crtc_state->dp_m2_n2 = old_crtc_state->dp_m2_n2; + new_crtc_state->has_drrs = old_crtc_state->has_drrs; +} + /** * intel_atomic_check - validate state object * @dev: drm device @@ -13475,11 +13499,7 @@ static int intel_atomic_check(struct drm_device *dev, if (ret) goto fail; - if (intel_pipe_config_compare(dev_priv, old_crtc_state, - new_crtc_state, true)) { - new_crtc_state->base.mode_changed = false; - new_crtc_state->update_pipe = true; - } + intel_crtc_check_fastset(old_crtc_state, new_crtc_state); if (needs_modeset(&new_crtc_state->base)) any_ms = true;