* [PATCH v7 1/2] drm/i915/psr: Lockless version of psr_wait_for_idle
@ 2018-06-27 19:31 Tarun Vyas
2018-06-27 19:31 ` [PATCH v7 2/2] drm/i915: Wait for PSR exit before checking for vblank evasion Tarun Vyas
2018-06-27 19:49 ` ✗ Fi.CI.BAT: failure for series starting with [v7,1/2] drm/i915/psr: Lockless version of psr_wait_for_idle Patchwork
0 siblings, 2 replies; 3+ messages in thread
From: Tarun Vyas @ 2018-06-27 19:31 UTC (permalink / raw)
To: intel-gfx; +Cc: dhinakaran.pandiyan, rodrigo.vivi
This is a lockless version of the exisiting psr_wait_for_idle().
We want to wait for PSR to idle out inside intel_pipe_update_start.
At the time of a pipe update, we should never race with any psr
enable or disable code, which is a part of crtc enable/disable.
The follow up patch will use this lockless wait inside pipe_update_
start to wait for PSR to idle out before checking for vblank evasion.
We need to keep the wait in pipe_update_start to as less as it can be.
So,we can live and flourish w/o taking any psr locks at all.
Even if psr is never enabled, psr2_enabled will be false and this
function will wait for PSR1 to idle out, which should just return
immediately, so a very short (~1-2 usec) wait for cases where PSR
is disabled.
v2: Add comment to explain the 25msec timeout (DK)
v3: Rename psr_wait_for_idle to __psr_wait_for_idle_locked to avoid
naming conflicts and propagate err (if any) to the caller (Chris)
v5: Form a series with the next patch
v7: Better explain the need for lockless wait and increase the max
timeout to handle refresh rates < 60 Hz (Daniel Vetter)
Signed-off-by: Tarun Vyas <tarun.vyas@intel.com>
---
drivers/gpu/drm/i915/intel_drv.h | 1 +
drivers/gpu/drm/i915/intel_psr.c | 36 ++++++++++++++++++++++++++++++++++--
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 578346b8d7e2..9cb2b8afdd3e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1920,6 +1920,7 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state);
void intel_psr_irq_control(struct drm_i915_private *dev_priv, bool debug);
void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir);
+int intel_psr_wait_for_idle(struct drm_i915_private *dev_priv);
/* intel_runtime_pm.c */
int intel_power_domains_init(struct drm_i915_private *);
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index aea81ace854b..d11fd8a01d98 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -757,7 +757,39 @@ void intel_psr_disable(struct intel_dp *intel_dp,
cancel_work_sync(&dev_priv->psr.work);
}
-static bool psr_wait_for_idle(struct drm_i915_private *dev_priv)
+int intel_psr_wait_for_idle(struct drm_i915_private *dev_priv)
+{
+ i915_reg_t reg;
+ u32 mask;
+
+ /*
+ * The sole user right now is intel_pipe_update_start(),
+ * which won't race with psr_enable/disable, which is
+ * where psr2_enabled is written to. So, we don't need
+ * to acquire the psr.lock. More importantly, we want the
+ * latency inside intel_pipe_update_start() to be as low
+ * as possible, so no need to acquire psr.lock when it is
+ * not needed and will induce latencies in the atomic
+ * update path.
+ */
+ if (dev_priv->psr.psr2_enabled) {
+ reg = EDP_PSR2_STATUS;
+ mask = EDP_PSR2_STATUS_STATE_MASK;
+ } else {
+ reg = EDP_PSR_STATUS;
+ mask = EDP_PSR_STATUS_STATE_MASK;
+ }
+
+ /*
+ * Max time for PSR to idle = Inverse of the refresh rate +
+ * 6 ms of exit training time + 1.5 ms of aux channel
+ * handshake. 50 msec is defesive enough to cover everything.
+ */
+ return intel_wait_for_register(dev_priv, reg, mask,
+ EDP_PSR_STATUS_STATE_IDLE, 50);
+}
+
+static bool __psr_wait_for_idle_locked(struct drm_i915_private *dev_priv)
{
struct intel_dp *intel_dp;
i915_reg_t reg;
@@ -803,7 +835,7 @@ static void intel_psr_work(struct work_struct *work)
* PSR might take some time to get fully disabled
* and be ready for re-enable.
*/
- if (!psr_wait_for_idle(dev_priv))
+ if (!__psr_wait_for_idle_locked(dev_priv))
goto unlock;
/*
--
2.13.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v7 2/2] drm/i915: Wait for PSR exit before checking for vblank evasion
2018-06-27 19:31 [PATCH v7 1/2] drm/i915/psr: Lockless version of psr_wait_for_idle Tarun Vyas
@ 2018-06-27 19:31 ` Tarun Vyas
2018-06-27 19:49 ` ✗ Fi.CI.BAT: failure for series starting with [v7,1/2] drm/i915/psr: Lockless version of psr_wait_for_idle Patchwork
1 sibling, 0 replies; 3+ messages in thread
From: Tarun Vyas @ 2018-06-27 19:31 UTC (permalink / raw)
To: intel-gfx; +Cc: dhinakaran.pandiyan, rodrigo.vivi
The PIPEDSL freezes on PSR entry and if PSR hasn't fully exited, then
the pipe_update_start call schedules itself out to check back later.
On ChromeOS-4.4 kernel, which is fairly up-to-date w.r.t drm/i915 but
lags w.r.t core kernel code, hot plugging an external display triggers
tons of "potential atomic update errors" in the dmesg, on *pipe A*. A
closer analysis reveals that we try to read the scanline 3 times and
eventually timeout, b/c PSR hasn't exited fully leading to a PIPEDSL
stuck @ 1599. This issue is not seen on upstream kernels, b/c for *some*
reason we loop inside intel_pipe_update start for ~2+ msec which in this
case is more than enough to exit PSR fully, hence an *unstuck* PIPEDSL
counter, hence no error. On the other hand, the ChromeOS kernel spends
~1.1 msec looping inside intel_pipe_update_start and hence errors out
b/c the source is still in PSR.
Regardless, we should wait for PSR exit (if PSR is disabled, we incur
a ~1-2 usec penalty) before reading the PIPEDSL, b/c if we haven't
fully exited PSR, then checking for vblank evasion isn't actually
applicable.
v4: Comment explaining psr_wait after enabling VBL interrupts (DK)
v5: CAN_PSR() to handle platforms that don't support PSR.
v6: Handle local_irq_disable on early return (Chris)
Signed-off-by: Tarun Vyas <tarun.vyas@intel.com>
---
drivers/gpu/drm/i915/intel_sprite.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 344c0e709b19..4990d6e84ddf 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -107,13 +107,21 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
VBLANK_EVASION_TIME_US);
max = vblank_start - 1;
- local_irq_disable();
-
if (min <= 0 || max <= 0)
- return;
+ goto irq_disable;
if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
- return;
+ goto irq_disable;
+
+ /*
+ * Wait for psr to idle out after enabling the VBL interrupts
+ * VBL interrupts will start the PSR exit and prevent a PSR
+ * re-entry as well.
+ */
+ if (CAN_PSR(dev_priv) && intel_psr_wait_for_idle(dev_priv))
+ DRM_ERROR("PSR idle timed out, atomic update may fail\n");
+
+ local_irq_disable();
crtc->debug.min_vbl = min;
crtc->debug.max_vbl = max;
@@ -171,6 +179,10 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
trace_i915_pipe_update_vblank_evaded(crtc);
+ return;
+
+irq_disable:
+ local_irq_disable();
}
/**
--
2.13.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 3+ messages in thread
* ✗ Fi.CI.BAT: failure for series starting with [v7,1/2] drm/i915/psr: Lockless version of psr_wait_for_idle
2018-06-27 19:31 [PATCH v7 1/2] drm/i915/psr: Lockless version of psr_wait_for_idle Tarun Vyas
2018-06-27 19:31 ` [PATCH v7 2/2] drm/i915: Wait for PSR exit before checking for vblank evasion Tarun Vyas
@ 2018-06-27 19:49 ` Patchwork
1 sibling, 0 replies; 3+ messages in thread
From: Patchwork @ 2018-06-27 19:49 UTC (permalink / raw)
To: Tarun Vyas; +Cc: intel-gfx
== Series Details ==
Series: series starting with [v7,1/2] drm/i915/psr: Lockless version of psr_wait_for_idle
URL : https://patchwork.freedesktop.org/series/45521/
State : failure
== Summary ==
Applying: drm/i915/psr: Lockless version of psr_wait_for_idle
Using index info to reconstruct a base tree...
M drivers/gpu/drm/i915/intel_drv.h
M drivers/gpu/drm/i915/intel_psr.c
Falling back to patching base and 3-way merge...
Auto-merging drivers/gpu/drm/i915/intel_psr.c
Auto-merging drivers/gpu/drm/i915/intel_drv.h
CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/intel_drv.h
error: Failed to merge in the changes.
Patch failed at 0001 drm/i915/psr: Lockless version of psr_wait_for_idle
Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-06-27 19:49 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-27 19:31 [PATCH v7 1/2] drm/i915/psr: Lockless version of psr_wait_for_idle Tarun Vyas
2018-06-27 19:31 ` [PATCH v7 2/2] drm/i915: Wait for PSR exit before checking for vblank evasion Tarun Vyas
2018-06-27 19:49 ` ✗ Fi.CI.BAT: failure for series starting with [v7,1/2] drm/i915/psr: Lockless version of psr_wait_for_idle Patchwork
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.