Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <maarten.lankhorst@linux.intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
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ä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190612172423.25231-1-ville.syrjala@linux.intel.com
Reviewed-by: Imre Deak <imre.deak@intel.com>
(cherry picked from commit f0521558a2a89d58a08745e225025d338572e60a)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190619120929.4057-1-ville.syrjala@linux.intel.com

authored by

Ville Syrjälä and committed by
Jani Nikula
475df5d0 f5633efc

+29 -9
+29 -9
drivers/gpu/drm/i915/intel_display.c
··· 12005 12005 m2_n2->gmch_m, m2_n2->gmch_n, !adjust) && 12006 12006 intel_compare_m_n(m_n->link_m, m_n->link_n, 12007 12007 m2_n2->link_m, m2_n2->link_n, !adjust)) { 12008 - if (adjust) 12009 - *m2_n2 = *m_n; 12010 - 12011 12008 return true; 12012 12009 } 12013 12010 ··· 13146 13149 return 0; 13147 13150 } 13148 13151 13152 + static void intel_crtc_check_fastset(struct intel_crtc_state *old_crtc_state, 13153 + struct intel_crtc_state *new_crtc_state) 13154 + { 13155 + struct drm_i915_private *dev_priv = 13156 + to_i915(new_crtc_state->base.crtc->dev); 13157 + 13158 + if (!intel_pipe_config_compare(dev_priv, old_crtc_state, 13159 + new_crtc_state, true)) 13160 + return; 13161 + 13162 + new_crtc_state->base.mode_changed = false; 13163 + new_crtc_state->update_pipe = true; 13164 + 13165 + /* 13166 + * If we're not doing the full modeset we want to 13167 + * keep the current M/N values as they may be 13168 + * sufficiently different to the computed values 13169 + * to cause problems. 13170 + * 13171 + * FIXME: should really copy more fuzzy state here 13172 + */ 13173 + new_crtc_state->fdi_m_n = old_crtc_state->fdi_m_n; 13174 + new_crtc_state->dp_m_n = old_crtc_state->dp_m_n; 13175 + new_crtc_state->dp_m2_n2 = old_crtc_state->dp_m2_n2; 13176 + new_crtc_state->has_drrs = old_crtc_state->has_drrs; 13177 + } 13178 + 13149 13179 /** 13150 13180 * intel_atomic_check - validate state object 13151 13181 * @dev: drm device ··· 13221 13197 return ret; 13222 13198 } 13223 13199 13224 - if (intel_pipe_config_compare(dev_priv, 13225 - to_intel_crtc_state(old_crtc_state), 13226 - pipe_config, true)) { 13227 - crtc_state->mode_changed = false; 13228 - pipe_config->update_pipe = true; 13229 - } 13200 + intel_crtc_check_fastset(to_intel_crtc_state(old_crtc_state), 13201 + pipe_config); 13230 13202 13231 13203 if (needs_modeset(crtc_state)) 13232 13204 any_ms = true;