All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matt Roper <matthew.d.roper@intel.com>
To: Thierry Reding <thierry.reding@gmail.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v5 2/3] drm/atomic-helper: Implement subsystem-level suspend/resume
Date: Wed, 2 Dec 2015 16:06:34 -0800	[thread overview]
Message-ID: <20151203000634.GF13669@intel.com> (raw)
In-Reply-To: <1449075005-13937-2-git-send-email-thierry.reding@gmail.com>

On Wed, Dec 02, 2015 at 05:50:04PM +0100, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> Provide subsystem-level suspend and resume helpers that can be used to
> implement suspend/resume on atomic mode-setting enabled drivers.
> 
> v2: simplify locking, enhance kerneldoc comments
> v3: pass lock acquisition context by parameter, improve kerneldoc
> v4: - remove redundant code (already provided by atomic helpers)
>       (Maarten Lankhorst)
>     - move backoff dance from drm_modeset_lock_all_ctx() into suspend
>       helper (Daniel Vetter)
> v5: handle potential EDEADLK from drm_atomic_helper_duplicate_state()
>     and drm_atomic_helper_disable_all() (Daniel Vetter)
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/gpu/drm/drm_atomic_helper.c | 162 +++++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/drm_crtc_helper.c   |   6 ++
>  include/drm/drm_atomic_helper.h     |   6 ++
>  3 files changed, 173 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 3731a26979bc..ce2cfef08742 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -1818,6 +1818,161 @@ commit:
>  }
>  
>  /**
> + * drm_atomic_helper_disable_all - disable all currently active outputs
> + * @dev: DRM device
> + * @ctx: lock acquisition context
> + *
> + * Loops through all connectors, finding those that aren't turned off and then
> + * turns them off by setting their DPMS mode to OFF and deactivating the CRTC
> + * that they are connected to.
> + *
> + * This is used for example in suspend/resume to disable all currently active
> + * functions when suspending.
> + *
> + * Note that if callers haven't already acquired all modeset locks this might
> + * return -EDEADLK, which must be handled by calling drm_modeset_backoff().
> + *
> + * Returns:
> + * 0 on success or a negative error code on failure.
> + *
> + * See also:
> + * drm_atomic_helper_suspend(), drm_atomic_helper_resume()
> + */
> +int drm_atomic_helper_disable_all(struct drm_device *dev,
> +				  struct drm_modeset_acquire_ctx *ctx)
> +{
> +	struct drm_atomic_state *state;
> +	struct drm_connector *conn;
> +	int err;
> +
> +	state = drm_atomic_state_alloc(dev);
> +	if (!state)
> +		return -ENOMEM;
> +
> +	state->acquire_ctx = ctx;
> +
> +	drm_for_each_connector(conn, dev) {

This iterator will raise a WARN() if the caller isn't already holding
either mode_config->mutex or mode_config->connection_mutex.  Should a
note about that be added to the kerneldoc above where you're talking
about locks?  Ditto for the iterator in
drm_atomic_helper_duplicate_state().


Matt

> +		struct drm_crtc *crtc = conn->state->crtc;
> +		struct drm_crtc_state *crtc_state;
> +
> +		if (!crtc || conn->dpms != DRM_MODE_DPMS_ON)
> +			continue;
> +
> +		crtc_state = drm_atomic_get_crtc_state(state, crtc);
> +		if (IS_ERR(crtc_state)) {
> +			err = PTR_ERR(crtc_state);
> +			goto free;
> +		}
> +
> +		crtc_state->active = false;
> +	}
> +
> +	err = drm_atomic_commit(state);
> +
> +free:
> +	if (err < 0)
> +		drm_atomic_state_free(state);
> +
> +	return err;
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_disable_all);
> +
> +/**
> + * drm_atomic_helper_suspend - subsystem-level suspend helper
> + * @dev: DRM device
> + *
> + * Duplicates the current atomic state, disables all active outputs and then
> + * returns a pointer to the original atomic state to the caller. Drivers can
> + * pass this pointer to the drm_atomic_helper_resume() helper upon resume to
> + * restore the output configuration that was active at the time the system
> + * entered suspend.
> + *
> + * Note that it is potentially unsafe to use this. The atomic state object
> + * returned by this function is assumed to be persistent. Drivers must ensure
> + * that this holds true. Before calling this function, drivers must make sure
> + * to suspend fbdev emulation so that nothing can be using the device.
> + *
> + * Returns:
> + * A pointer to a copy of the state before suspend on success or an ERR_PTR()-
> + * encoded error code on failure. Drivers should store the returned atomic
> + * state object and pass it to the drm_atomic_helper_resume() helper upon
> + * resume.
> + *
> + * See also:
> + * drm_atomic_helper_duplicate_state(), drm_atomic_helper_disable_all(),
> + * drm_atomic_helper_resume()
> + */
> +struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)
> +{
> +	struct drm_modeset_acquire_ctx ctx;
> +	struct drm_atomic_state *state;
> +	int err;
> +
> +	drm_modeset_acquire_init(&ctx, 0);
> +
> +retry:
> +	err = drm_modeset_lock_all_ctx(dev, &ctx);
> +	if (err < 0) {
> +		state = ERR_PTR(err);
> +		goto unlock;
> +	}
> +
> +	state = drm_atomic_helper_duplicate_state(dev, &ctx);
> +	if (IS_ERR(state))
> +		goto unlock;
> +
> +	err = drm_atomic_helper_disable_all(dev, &ctx);
> +	if (err < 0) {
> +		drm_atomic_state_free(state);
> +		state = ERR_PTR(err);
> +		goto unlock;
> +	}
> +
> +unlock:
> +	if (PTR_ERR(state) == -EDEADLK) {
> +		drm_modeset_backoff(&ctx);
> +		goto retry;
> +	}
> +
> +	drm_modeset_drop_locks(&ctx);
> +	drm_modeset_acquire_fini(&ctx);
> +	return state;
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_suspend);
> +
> +/**
> + * drm_atomic_helper_resume - subsystem-level resume helper
> + * @dev: DRM device
> + * @state: atomic state to resume to
> + *
> + * Calls drm_mode_config_reset() to synchronize hardware and software states,
> + * grabs all modeset locks and commits the atomic state object. This can be
> + * used in conjunction with the drm_atomic_helper_suspend() helper to
> + * implement suspend/resume for drivers that support atomic mode-setting.
> + *
> + * Returns:
> + * 0 on success or a negative error code on failure.
> + *
> + * See also:
> + * drm_atomic_helper_suspend()
> + */
> +int drm_atomic_helper_resume(struct drm_device *dev,
> +			     struct drm_atomic_state *state)
> +{
> +	struct drm_mode_config *config = &dev->mode_config;
> +	int err;
> +
> +	drm_mode_config_reset(dev);
> +	drm_modeset_lock_all(dev);
> +	state->acquire_ctx = config->acquire_ctx;
> +	err = drm_atomic_commit(state);
> +	drm_modeset_unlock_all(dev);
> +
> +	return err;
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_resume);
> +
> +/**
>   * drm_atomic_helper_crtc_set_property - helper for crtc properties
>   * @crtc: DRM crtc
>   * @property: DRM property
> @@ -2429,7 +2584,9 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
>   * @ctx: lock acquisition context
>   *
>   * Makes a copy of the current atomic state by looping over all objects and
> - * duplicating their respective states.
> + * duplicating their respective states. This is used for example by suspend/
> + * resume support code to save the state prior to suspend such that it can
> + * be restored upon resume.
>   *
>   * Note that this treats atomic state as persistent between save and restore.
>   * Drivers must make sure that this is possible and won't result in confusion
> @@ -2441,6 +2598,9 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
>   * Returns:
>   * A pointer to the copy of the atomic state object on success or an
>   * ERR_PTR()-encoded error code on failure.
> + *
> + * See also:
> + * drm_atomic_helper_suspend(), drm_atomic_helper_resume()
>   */
>  struct drm_atomic_state *
>  drm_atomic_helper_duplicate_state(struct drm_device *dev,
> diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
> index 6b4cf25fed12..10d0989db273 100644
> --- a/drivers/gpu/drm/drm_crtc_helper.c
> +++ b/drivers/gpu/drm/drm_crtc_helper.c
> @@ -855,6 +855,12 @@ EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
>   * due to slight differences in allocating shared resources when the
>   * configuration is restored in a different order than when userspace set it up)
>   * need to use their own restore logic.
> + *
> + * This function is deprecated. New drivers should implement atomic mode-
> + * setting and use the atomic suspend/resume helpers.
> + *
> + * See also:
> + * drm_atomic_helper_suspend(), drm_atomic_helper_resume()
>   */
>  void drm_helper_resume_force_mode(struct drm_device *dev)
>  {
> diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> index 8cba54a2a0a0..8045cdea8cc9 100644
> --- a/include/drm/drm_atomic_helper.h
> +++ b/include/drm/drm_atomic_helper.h
> @@ -81,6 +81,12 @@ int drm_atomic_helper_set_config(struct drm_mode_set *set);
>  int __drm_atomic_helper_set_config(struct drm_mode_set *set,
>  		struct drm_atomic_state *state);
>  
> +int drm_atomic_helper_disable_all(struct drm_device *dev,
> +				  struct drm_modeset_acquire_ctx *ctx);
> +struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev);
> +int drm_atomic_helper_resume(struct drm_device *dev,
> +			     struct drm_atomic_state *state);
> +
>  int drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
>  					struct drm_property *property,
>  					uint64_t val);
> -- 
> 2.5.0
> 

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2015-12-03  0:06 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-02 16:50 [PATCH v5 1/3] drm: Implement drm_modeset_lock_all_ctx() Thierry Reding
2015-12-02 16:50 ` [PATCH v5 2/3] drm/atomic-helper: Implement subsystem-level suspend/resume Thierry Reding
2015-12-02 22:12   ` Daniel Vetter
2015-12-03  0:06   ` Matt Roper [this message]
2015-12-02 16:50 ` [PATCH v5 3/3] drm/tegra: " Thierry Reding

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=20151203000634.GF13669@intel.com \
    --to=matthew.d.roper@intel.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=thierry.reding@gmail.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 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.