From 72d0b1cf587ea10daaba53928d1849b25a1c3368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> Date: Fri, 6 Sep 2019 19:39:15 +0300 Subject: [PATCH] drm/i915: Allocate state checker crtc state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't clobber the old state with the results of the hardware readout. In particualr this clobbers old_crtc_state->commit which caused explosions once I hooked up vblank works. Not sure why this doesn't cause problems already? Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> --- drivers/gpu/drm/i915/display/intel_display.c | 77 +++++++++++--------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index def02b7f71e23..c5e8bcf31b77e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -14183,69 +14183,61 @@ verify_encoder_state(struct drm_i915_private *dev_priv, struct intel_atomic_stat static void verify_crtc_state(struct intel_crtc *crtc, - struct intel_crtc_state *old_crtc_state, - struct intel_crtc_state *new_crtc_state) + struct intel_crtc_state *hw_crtc_state, + const struct intel_crtc_state *sw_crtc_state) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *encoder; - struct intel_crtc_state *pipe_config = old_crtc_state; - struct drm_atomic_state *state = old_crtc_state->uapi.state; bool active; - __drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi); - intel_crtc_free_hw_state(old_crtc_state); - intel_crtc_state_reset(old_crtc_state, crtc); - old_crtc_state->uapi.state = state; - drm_dbg_kms(&dev_priv->drm, "[CRTC:%d:%s]\n", crtc->base.base.id, crtc->base.name); - active = dev_priv->display.get_pipe_config(crtc, pipe_config); + active = dev_priv->display.get_pipe_config(crtc, hw_crtc_state); /* we keep both pipes enabled on 830 */ if (IS_I830(dev_priv)) - active = new_crtc_state->hw.active; + active = sw_crtc_state->hw.active; - I915_STATE_WARN(new_crtc_state->hw.active != active, + I915_STATE_WARN(sw_crtc_state->hw.active != active, "crtc active state doesn't match with hw state " "(expected %i, found %i)\n", - new_crtc_state->hw.active, active); + sw_crtc_state->hw.active, active); - I915_STATE_WARN(crtc->active != new_crtc_state->hw.active, + I915_STATE_WARN(crtc->active != sw_crtc_state->hw.active, "transitional active state does not match atomic hw state " "(expected %i, found %i)\n", - new_crtc_state->hw.active, crtc->active); + sw_crtc_state->hw.active, crtc->active); for_each_encoder_on_crtc(dev, &crtc->base, encoder) { enum pipe pipe; active = encoder->get_hw_state(encoder, &pipe); - I915_STATE_WARN(active != new_crtc_state->hw.active, + I915_STATE_WARN(active != sw_crtc_state->hw.active, "[ENCODER:%i] active %i with crtc active %i\n", encoder->base.base.id, active, - new_crtc_state->hw.active); + sw_crtc_state->hw.active); I915_STATE_WARN(active && crtc->pipe != pipe, "Encoder connected to wrong pipe %c\n", pipe_name(pipe)); if (active) - encoder->get_config(encoder, pipe_config); + encoder->get_config(encoder, hw_crtc_state); } - intel_crtc_compute_pixel_rate(pipe_config); + intel_crtc_compute_pixel_rate(hw_crtc_state); - if (!new_crtc_state->hw.active) + if (!sw_crtc_state->hw.active) return; - intel_pipe_config_sanity_check(dev_priv, pipe_config); + intel_pipe_config_sanity_check(dev_priv, hw_crtc_state); - if (!intel_pipe_config_compare(new_crtc_state, - pipe_config, false)) { + if (!intel_pipe_config_compare(sw_crtc_state, hw_crtc_state, false)) { I915_STATE_WARN(1, "pipe state doesn't match!\n"); - intel_dump_pipe_config(pipe_config, NULL, "[hw state]"); - intel_dump_pipe_config(new_crtc_state, NULL, "[sw state]"); + intel_dump_pipe_config(hw_crtc_state, NULL, "[hw state]"); + intel_dump_pipe_config(sw_crtc_state, NULL, "[sw state]"); } } @@ -14319,18 +14311,18 @@ verify_single_dpll_state(struct drm_i915_private *dev_priv, static void verify_shared_dpll_state(struct intel_crtc *crtc, - struct intel_crtc_state *old_crtc_state, - struct intel_crtc_state *new_crtc_state) + struct intel_crtc_state *hw_crtc_state, + struct intel_crtc_state *sw_crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - if (new_crtc_state->shared_dpll) - verify_single_dpll_state(dev_priv, new_crtc_state->shared_dpll, crtc, new_crtc_state); + if (sw_crtc_state->shared_dpll) + verify_single_dpll_state(dev_priv, sw_crtc_state->shared_dpll, crtc, sw_crtc_state); - if (old_crtc_state->shared_dpll && - old_crtc_state->shared_dpll != new_crtc_state->shared_dpll) { + if (hw_crtc_state->shared_dpll && + hw_crtc_state->shared_dpll != sw_crtc_state->shared_dpll) { unsigned int crtc_mask = drm_crtc_mask(&crtc->base); - struct intel_shared_dpll *pll = old_crtc_state->shared_dpll; + struct intel_shared_dpll *pll = hw_crtc_state->shared_dpll; I915_STATE_WARN(pll->active_mask & crtc_mask, "pll active mismatch (didn't expect pipe %c in active mask)\n", @@ -14344,16 +14336,29 @@ verify_shared_dpll_state(struct intel_crtc *crtc, static void intel_modeset_verify_crtc(struct intel_crtc *crtc, struct intel_atomic_state *state, - struct intel_crtc_state *old_crtc_state, struct intel_crtc_state *new_crtc_state) { + struct intel_crtc_state *hw_crtc_state; + if (!needs_modeset(new_crtc_state) && !new_crtc_state->update_pipe) return; verify_wm_state(crtc, new_crtc_state); verify_connector_state(state, crtc); - verify_crtc_state(crtc, old_crtc_state, new_crtc_state); - verify_shared_dpll_state(crtc, old_crtc_state, new_crtc_state); + + hw_crtc_state = to_intel_crtc_state(intel_crtc_duplicate_state(&crtc->base)); + if (!hw_crtc_state) + return; + + __drm_atomic_helper_crtc_destroy_state(&hw_crtc_state->uapi); + intel_crtc_free_hw_state(hw_crtc_state); + intel_crtc_state_reset(hw_crtc_state, crtc); + hw_crtc_state->uapi.state = &state->base; + + verify_crtc_state(crtc, hw_crtc_state, new_crtc_state); + verify_shared_dpll_state(crtc, hw_crtc_state, new_crtc_state); + + intel_crtc_destroy_state(&crtc->base, &hw_crtc_state->uapi); } static void @@ -15631,7 +15636,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) if (new_crtc_state->put_domains) modeset_put_power_domains(dev_priv, new_crtc_state->put_domains); - intel_modeset_verify_crtc(crtc, state, old_crtc_state, new_crtc_state); + intel_modeset_verify_crtc(crtc, state, new_crtc_state); } /* Underruns don't always raise interrupts, so check manually */ -- GitLab