From: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
To: "José Roberto de Souza" <jose.souza@intel.com>,
intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v4] drm/i915/psr: Execute the default PSR code path when setting i915_edp_psr_debug
Date: Wed, 06 Feb 2019 18:56:06 -0800 [thread overview]
Message-ID: <741ea2a06b50e3d65b6d416d07bba58e0ec43087.camel@intel.com> (raw)
In-Reply-To: <20190206211845.5322-1-jose.souza@intel.com>
On Wed, 2019-02-06 at 13:18 -0800, José Roberto de Souza wrote:
> Changing the i915_edp_psr_debug was enabling, disabling or switching
> PSR version by directly calling intel_psr_disable_locked() and
> intel_psr_enable_locked(), what is not the default PSR path that will
> be executed by real users.
>
> So lets force a fastset in the PSR CRTC to trigger a pipe update and
> stress the default code path.
>
> Recently a bug was found when switching from PSR2 to PSR1 while
> enable_psr kernel parameter was set to the default parameter, this
> changes fix it and also fixes the bug linked bellow were DRRS was
> left enabled together with PSR when enabling PSR from debugfs.
>
> v2: Handling missing case: disabled to PSR1
>
> v3: Not duplicating the whole atomic state(Maarten)
>
> v4: Adding back the missing call to intel_psr_irq_control(Dhinakaran)
Reviewed-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108341
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 14 +--
> drivers/gpu/drm/i915/i915_drv.h | 2 +-
> drivers/gpu/drm/i915/intel_ddi.c | 2 +-
> drivers/gpu/drm/i915/intel_drv.h | 6 +-
> drivers/gpu/drm/i915/intel_psr.c | 182 ++++++++++++++++--------
> ----
> 5 files changed, 113 insertions(+), 93 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
> b/drivers/gpu/drm/i915/i915_debugfs.c
> index 0bd890c04fe4..20a49cc4a9a1 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -2607,7 +2607,6 @@ static int
> i915_edp_psr_debug_set(void *data, u64 val)
> {
> struct drm_i915_private *dev_priv = data;
> - struct drm_modeset_acquire_ctx ctx;
> intel_wakeref_t wakeref;
> int ret;
>
> @@ -2618,18 +2617,7 @@ i915_edp_psr_debug_set(void *data, u64 val)
>
> wakeref = intel_runtime_pm_get(dev_priv);
>
> - drm_modeset_acquire_init(&ctx,
> DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
> -
> -retry:
> - ret = intel_psr_set_debugfs_mode(dev_priv, &ctx, val);
> - if (ret == -EDEADLK) {
> - ret = drm_modeset_backoff(&ctx);
> - if (!ret)
> - goto retry;
> - }
> -
> - drm_modeset_drop_locks(&ctx);
> - drm_modeset_acquire_fini(&ctx);
> + ret = intel_psr_debug_set(dev_priv, val);
>
> intel_runtime_pm_put(dev_priv, wakeref);
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index a2293152cb6a..989d1ac72ec8 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -496,7 +496,7 @@ struct i915_psr {
>
> u32 debug;
> bool sink_support;
> - bool prepared, enabled;
> + bool enabled;
> struct intel_dp *dp;
> enum pipe pipe;
> bool active;
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> b/drivers/gpu/drm/i915/intel_ddi.c
> index ca705546a0ab..9211e4579489 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -3556,7 +3556,7 @@ static void intel_ddi_update_pipe_dp(struct
> intel_encoder *encoder,
> {
> struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>
> - intel_psr_enable(intel_dp, crtc_state);
> + intel_psr_update(intel_dp, crtc_state);
> intel_edp_drrs_enable(intel_dp, crtc_state);
>
> intel_panel_update_backlight(encoder, crtc_state, conn_state);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index 9ec3d00fbd19..3eba33a2f951 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -2077,9 +2077,9 @@ void intel_psr_enable(struct intel_dp
> *intel_dp,
> const struct intel_crtc_state *crtc_state);
> void intel_psr_disable(struct intel_dp *intel_dp,
> const struct intel_crtc_state *old_crtc_state);
> -int intel_psr_set_debugfs_mode(struct drm_i915_private *dev_priv,
> - struct drm_modeset_acquire_ctx *ctx,
> - u64 value);
> +void intel_psr_update(struct intel_dp *intel_dp,
> + const struct intel_crtc_state *crtc_state);
> +int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64
> value);
> void intel_psr_invalidate(struct drm_i915_private *dev_priv,
> unsigned frontbuffer_bits,
> enum fb_op_origin origin);
> diff --git a/drivers/gpu/drm/i915/intel_psr.c
> b/drivers/gpu/drm/i915/intel_psr.c
> index 84a0fb981561..75c1a5deebf5 100644
> --- a/drivers/gpu/drm/i915/intel_psr.c
> +++ b/drivers/gpu/drm/i915/intel_psr.c
> @@ -51,6 +51,8 @@
> * must be correctly synchronized/cancelled when shutting down the
> pipe."
> */
>
> +#include <drm/drmP.h>
> +#include <drm/drm_atomic_helper.h>
>
> #include "intel_drv.h"
> #include "i915_drv.h"
> @@ -718,8 +720,11 @@ static void intel_psr_enable_locked(struct
> drm_i915_private *dev_priv,
> {
> struct intel_dp *intel_dp = dev_priv->psr.dp;
>
> - if (dev_priv->psr.enabled)
> - return;
> + WARN_ON(dev_priv->psr.enabled);
> +
> + dev_priv->psr.psr2_enabled = intel_psr2_enabled(dev_priv,
> crtc_state);
> + dev_priv->psr.busy_frontbuffer_bits = 0;
> + dev_priv->psr.pipe = to_intel_crtc(crtc_state->base.crtc)-
> >pipe;
>
> DRM_DEBUG_KMS("Enabling PSR%s\n",
> dev_priv->psr.psr2_enabled ? "2" : "1");
> @@ -752,20 +757,13 @@ void intel_psr_enable(struct intel_dp
> *intel_dp,
> WARN_ON(dev_priv->drrs.dp);
>
> mutex_lock(&dev_priv->psr.lock);
> - if (dev_priv->psr.prepared) {
> - DRM_DEBUG_KMS("PSR already in use\n");
> +
> + if (!psr_global_enabled(dev_priv->psr.debug)) {
> + DRM_DEBUG_KMS("PSR disabled by flag\n");
> goto unlock;
> }
>
> - dev_priv->psr.psr2_enabled = intel_psr2_enabled(dev_priv,
> crtc_state);
> - dev_priv->psr.busy_frontbuffer_bits = 0;
> - dev_priv->psr.prepared = true;
> - dev_priv->psr.pipe = to_intel_crtc(crtc_state->base.crtc)-
> >pipe;
> -
> - if (psr_global_enabled(dev_priv->psr.debug))
> - intel_psr_enable_locked(dev_priv, crtc_state);
> - else
> - DRM_DEBUG_KMS("PSR disabled by flag\n");
> + intel_psr_enable_locked(dev_priv, crtc_state);
>
> unlock:
> mutex_unlock(&dev_priv->psr.lock);
> @@ -848,18 +846,54 @@ void intel_psr_disable(struct intel_dp
> *intel_dp,
> return;
>
> mutex_lock(&dev_priv->psr.lock);
> - if (!dev_priv->psr.prepared) {
> - mutex_unlock(&dev_priv->psr.lock);
> - return;
> - }
>
> intel_psr_disable_locked(intel_dp);
>
> - dev_priv->psr.prepared = false;
> mutex_unlock(&dev_priv->psr.lock);
> cancel_work_sync(&dev_priv->psr.work);
> }
>
> +/**
> + * intel_psr_update - Update PSR state
> + * @intel_dp: Intel DP
> + * @crtc_state: new CRTC state
> + *
> + * This functions will update PSR states, disabling, enabling or
> switching PSR
> + * version when executing fastsets. For full modeset,
> intel_psr_disable() and
> + * intel_psr_enable() should be called instead.
> + */
> +void intel_psr_update(struct intel_dp *intel_dp,
> + const struct intel_crtc_state *crtc_state)
> +{
> + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> + struct i915_psr *psr = &dev_priv->psr;
> + bool enable, psr2_enable;
> +
> + if (!CAN_PSR(dev_priv) || READ_ONCE(psr->dp) != intel_dp)
> + return;
> +
> + mutex_lock(&dev_priv->psr.lock);
> +
> + enable = crtc_state->has_psr && psr_global_enabled(psr->debug);
> + psr2_enable = intel_psr2_enabled(dev_priv, crtc_state);
> +
> + if (enable == psr->enabled && psr2_enable == psr->psr2_enabled)
> + goto unlock;
> +
> + if (psr->enabled) {
> + if (!enable || psr2_enable != psr->psr2_enabled)
> + intel_psr_disable_locked(intel_dp);
> + }
> +
> + if (enable) {
> + if (!psr->enabled || psr2_enable != psr->psr2_enabled)
> + intel_psr_enable_locked(dev_priv, crtc_state);
> + }
> +
> +unlock:
> + mutex_unlock(&dev_priv->psr.lock);
> +}
> +
> /**
> * intel_psr_wait_for_idle - wait for PSR1 to idle
> * @new_crtc_state: new CRTC state
> @@ -924,36 +958,64 @@ static bool __psr_wait_for_idle_locked(struct
> drm_i915_private *dev_priv)
> return err == 0 && dev_priv->psr.enabled;
> }
>
> -static bool switching_psr(struct drm_i915_private *dev_priv,
> - struct intel_crtc_state *crtc_state,
> - u32 mode)
> +static int intel_psr_fastset_force(struct drm_i915_private
> *dev_priv)
> {
> - /* Can't switch psr state anyway if PSR2 is not supported. */
> - if (!crtc_state || !crtc_state->has_psr2)
> - return false;
> + struct drm_device *dev = &dev_priv->drm;
> + struct drm_modeset_acquire_ctx ctx;
> + struct drm_atomic_state *state;
> + struct drm_crtc *crtc;
> + int err;
>
> - if (dev_priv->psr.psr2_enabled && mode ==
> I915_PSR_DEBUG_FORCE_PSR1)
> - return true;
> + state = drm_atomic_state_alloc(dev);
> + if (!state)
> + return -ENOMEM;
>
> - if (!dev_priv->psr.psr2_enabled && mode !=
> I915_PSR_DEBUG_FORCE_PSR1)
> - return true;
> + drm_modeset_acquire_init(&ctx,
> DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
> + state->acquire_ctx = &ctx;
> +
> +retry:
> + drm_for_each_crtc(crtc, dev) {
> + struct drm_crtc_state *crtc_state;
> + struct intel_crtc_state *intel_crtc_state;
> +
> + crtc_state = drm_atomic_get_crtc_state(state, crtc);
> + if (IS_ERR(crtc_state)) {
> + err = PTR_ERR(crtc_state);
> + goto error;
> + }
> +
> + intel_crtc_state = to_intel_crtc_state(crtc_state);
> +
> + if (intel_crtc_has_type(intel_crtc_state,
> INTEL_OUTPUT_EDP) &&
> + intel_crtc_state->has_psr) {
> + /* Mark mode as changed to trigger a pipe-
> >update() */
> + crtc_state->mode_changed = true;
> + break;
> + }
> + }
> +
> + err = drm_atomic_commit(state);
>
> - return false;
> +error:
> + if (err == -EDEADLK) {
> + drm_atomic_state_clear(state);
> + err = drm_modeset_backoff(&ctx);
> + if (!err)
> + goto retry;
> + }
> +
> + drm_modeset_drop_locks(&ctx);
> + drm_modeset_acquire_fini(&ctx);
> + drm_atomic_state_put(state);
> +
> + return err;
> }
>
> -int intel_psr_set_debugfs_mode(struct drm_i915_private *dev_priv,
> - struct drm_modeset_acquire_ctx *ctx,
> - u64 val)
> +int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val)
> {
> - struct drm_device *dev = &dev_priv->drm;
> - struct drm_connector_state *conn_state;
> - struct intel_crtc_state *crtc_state = NULL;
> - struct drm_crtc_commit *commit;
> - struct drm_crtc *crtc;
> - struct intel_dp *dp;
> + const u32 mode = val & I915_PSR_DEBUG_MODE_MASK;
> + u32 old_mode;
> int ret;
> - bool enable;
> - u32 mode = val & I915_PSR_DEBUG_MODE_MASK;
>
> if (val & ~(I915_PSR_DEBUG_IRQ | I915_PSR_DEBUG_MODE_MASK) ||
> mode > I915_PSR_DEBUG_FORCE_PSR1) {
> @@ -961,49 +1023,19 @@ int intel_psr_set_debugfs_mode(struct
> drm_i915_private *dev_priv,
> return -EINVAL;
> }
>
> - ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
> ctx);
> - if (ret)
> - return ret;
> -
> - /* dev_priv->psr.dp should be set once and then never touched
> again. */
> - dp = READ_ONCE(dev_priv->psr.dp);
> - conn_state = dp->attached_connector->base.state;
> - crtc = conn_state->crtc;
> - if (crtc) {
> - ret = drm_modeset_lock(&crtc->mutex, ctx);
> - if (ret)
> - return ret;
> -
> - crtc_state = to_intel_crtc_state(crtc->state);
> - commit = crtc_state->base.commit;
> - } else {
> - commit = conn_state->commit;
> - }
> - if (commit) {
> - ret = wait_for_completion_interruptible(&commit-
> >hw_done);
> - if (ret)
> - return ret;
> - }
> -
> ret = mutex_lock_interruptible(&dev_priv->psr.lock);
> if (ret)
> return ret;
>
> - enable = psr_global_enabled(val);
> -
> - if (!enable || switching_psr(dev_priv, crtc_state, mode))
> - intel_psr_disable_locked(dev_priv->psr.dp);
> -
> + old_mode = dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK;
> dev_priv->psr.debug = val;
> - if (crtc)
> - dev_priv->psr.psr2_enabled =
> intel_psr2_enabled(dev_priv, crtc_state);
> -
> intel_psr_irq_control(dev_priv, dev_priv->psr.debug);
>
> - if (dev_priv->psr.prepared && enable)
> - intel_psr_enable_locked(dev_priv, crtc_state);
> -
> mutex_unlock(&dev_priv->psr.lock);
> +
> + if (old_mode != mode)
> + ret = intel_psr_fastset_force(dev_priv);
> +
> return ret;
> }
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2019-02-07 2:56 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-06 21:18 [PATCH v4] drm/i915/psr: Execute the default PSR code path when setting i915_edp_psr_debug José Roberto de Souza
2019-02-06 22:02 ` ✓ Fi.CI.BAT: success for drm/i915/psr: Execute the default PSR code path when setting i915_edp_psr_debug (rev4) Patchwork
2019-02-07 2:29 ` ✓ Fi.CI.IGT: " Patchwork
2019-02-07 2:56 ` Dhinakaran Pandiyan [this message]
2019-02-07 22:00 ` [PATCH v4] drm/i915/psr: Execute the default PSR code path when setting i915_edp_psr_debug Souza, Jose
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=741ea2a06b50e3d65b6d416d07bba58e0ec43087.camel@intel.com \
--to=dhinakaran.pandiyan@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=jose.souza@intel.com \
/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