intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: Ville Syrjala <ville.syrjala@linux.intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: Drew Davenport <ddavenport@chromium.org>
Subject: [Intel-gfx] [PATCH 5/6] drm/i915: Disable DC states for all commits
Date: Mon, 20 Mar 2023 11:54:37 +0200	[thread overview]
Message-ID: <20230320095438.17328-6-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <20230320095438.17328-1-ville.syrjala@linux.intel.com>

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Keeping DC states enabled is incompatible with the _noarm()/_arm()
split we use for writing pipe/plane registers. When DC5 and PSR
are enabled, all pipe/plane registers effectively become self-arming
on account of DC5 exit arming the update, and PSR exit latching it.

What probably saves us most of the time is that (with PIPE_MISC[21]=0)
all pipe register writes themselves trigger PSR exit, and then
we don't re-enter PSR until the idle frame count has elapsed.
So it may be that the PSR exit happens alreday before we're
update the state too much.

Also the PSR1 panel (at least on this KBL) seems to discard the first
frame we trasmit, presumably still scanning out from its internal
framebuffer at that point. So only the second frame we transmit is
actually visible. But I suppose that could also be panel specific
behaviour. I haven't checked out how other PSR panels behave, nor
did I bother to check what the eDP spec has to say about this.

And since this really is all about DC states, let's switch from
the MODESET domain to the DC_OFF domain. Functionally they are
100% identical. We should probably remove the MODESET domain...

And for good measure let's toss in an assert to the place where
we do the _noarm() register writes to make sure DC states are
in fact off.

Cc: Manasi Navare <navaremanasi@google.com>
Cc: Drew Davenport <ddavenport@chromium.org>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Jouni Högander <jouni.hogander@intel.com>
Fixes: d13dde449580 ("drm/i915: Split pipe+output CSC programming to noarm+arm pair")
Fixes: f8a005eb8972 ("drm/i915: Optimize icl+ universal plane programming")
Fixes: 890b6ec4a522 ("drm/i915: Split skl+ plane update into noarm+arm pair")
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  | 28 +++++++++++++++++--
 .../drm/i915/display/intel_display_power.c    | 15 ++++++++++
 .../drm/i915/display/intel_display_power.h    |  1 +
 3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 5146d6cc7400..074b6a53ea19 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6989,6 +6989,8 @@ static void intel_update_crtc(struct intel_atomic_state *state,
 
 	intel_fbc_update(state, crtc);
 
+	intel_display_power_assert_dc_off(i915);
+
 	if (!modeset &&
 	    intel_crtc_needs_color_update(new_crtc_state))
 		intel_color_commit_noarm(new_crtc_state);
@@ -7356,8 +7358,28 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 	drm_atomic_helper_wait_for_dependencies(&state->base);
 	drm_dp_mst_atomic_wait_for_dependencies(&state->base);
 
-	if (state->modeset)
-		wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET);
+	/*
+	 * During full modesets we write a lot of registers, wait
+	 * for PLLs, etc. Doing that while DC states are enabled
+	 * is not a good idea.
+	 *
+	 * During fastsets and other updates we also need to
+	 * disable DC states due to the following scenario:
+	 * 1. DC5 exit and PSR exit happen
+	 * 2. Some or all _noarm() registers are written
+	 * 3. Due to some long delay PSR is re-entered
+	 * 4. DC5 entry -> DMC saves the already written new
+	 *    _noarm() registers and the old not yet written
+	 *    _arm() registers
+	 * 5. DC5 exit -> DMC restores a mixture of old and
+	 *    new register values and arms the update
+	 * 6. PSR exit -> hardware latches a mixture of old and
+	 *    new register values -> corrupted frame, or worse
+	 * 7. New _arm() registers are finally written
+	 * 8. Hardware finally latches a complete set of new
+	 *    register values, and subsequent frames will be OK again
+	 */
+	wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DC_OFF);
 
 	intel_atomic_prepare_plane_clear_colors(state);
 
@@ -7506,8 +7528,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		 * the culprit.
 		 */
 		intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore);
-		intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET, wakeref);
 	}
+	intel_display_power_put(dev_priv, POWER_DOMAIN_DC_OFF, wakeref);
 	intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref);
 
 	/*
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index f86060195987..f2c9f88e7aef 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -2502,3 +2502,18 @@ intel_display_power_tbt_aux_domain(struct drm_i915_private *i915, enum aux_ch au
 
 	return domains->aux_tbt + (int)(aux_ch - domains->aux_ch_start);
 }
+
+void intel_display_power_assert_dc_off(struct drm_i915_private *i915)
+{
+	struct i915_power_domains *power_domains = &i915->display.power.domains;
+	struct i915_power_well *power_well;
+
+	mutex_lock(&power_domains->lock);
+
+	power_well = lookup_power_well(i915, SKL_DISP_DC_OFF);
+
+	drm_WARN_ON(&i915->drm, power_well &&
+		    !intel_power_well_is_enabled(i915, power_well));
+
+	mutex_unlock(&power_domains->lock);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
index 8e96be8e6330..9ca48e233185 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -182,6 +182,7 @@ void intel_display_power_suspend(struct drm_i915_private *i915);
 void intel_display_power_resume(struct drm_i915_private *i915);
 void intel_display_power_set_target_dc_state(struct drm_i915_private *dev_priv,
 					     u32 state);
+void intel_display_power_assert_dc_off(struct drm_i915_private *dev_priv);
 
 const char *
 intel_display_power_domain_str(enum intel_display_power_domain domain);
-- 
2.39.2


  parent reply	other threads:[~2023-03-20  9:55 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-20  9:54 [Intel-gfx] [PATCH 0/6] drm/i915: Fix various issues with noarm register writes Ville Syrjala
2023-03-20  9:54 ` [Intel-gfx] [PATCH 1/6] drm/i915: Split icl_color_commit_noarm() from skl_color_commit_noarm() Ville Syrjala
2023-03-20  9:54 ` [Intel-gfx] [PATCH 2/6] drm/i915: Move CSC load back into .color_commit_arm() when PSR is enabled on skl/glk Ville Syrjala
2023-03-20  9:54 ` [Intel-gfx] [PATCH 3/6] drm/i915: Add a .color_post_update() hook Ville Syrjala
2023-03-20  9:54 ` [Intel-gfx] [PATCH 4/6] drm/i915: Workaround ICL CSC_MODE sticky arming Ville Syrjala
2023-03-20  9:54 ` Ville Syrjala [this message]
2023-03-20 11:51   ` [Intel-gfx] [PATCH 5/6] drm/i915: Disable DC states for all commits Imre Deak
2023-03-20 18:24     ` Ville Syrjälä
2023-03-20 18:35   ` [Intel-gfx] [PATCH v2 " Ville Syrjala
2023-03-20  9:54 ` [Intel-gfx] [PATCH 6/6] drm/i915/psr: Define more PSR mask bits Ville Syrjala
2023-03-20 12:05   ` Imre Deak
2023-03-20 12:23     ` Ville Syrjälä
2023-03-21 20:45   ` Ville Syrjälä
2023-03-20 18:01 ` [Intel-gfx] ✗ Fi.CI.BUILD: warning for drm/i915: Fix various issues with noarm register writes Patchwork
2023-03-20 18:02 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: " Patchwork
2023-03-20 18:02 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2023-03-20 18:02 ` [Intel-gfx] ✗ Fi.CI.DOCS: " Patchwork
2023-03-20 18:23 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2023-03-21  6:07 ` [Intel-gfx] ✗ Fi.CI.BUILD: warning for drm/i915: Fix various issues with noarm register writes (rev2) Patchwork
2023-03-21  6:07 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: " Patchwork
2023-03-21  6:07 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2023-03-21  6:33 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2023-03-21  9:59 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230320095438.17328-6-ville.syrjala@linux.intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=ddavenport@chromium.org \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).