All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Cc: Jani Nikula <jani.nikula@intel.com>
Subject: Re: [PATCH 17/21] drm/i915: Track the wakeref used to initialise display power domains
Date: Fri, 11 Jan 2019 15:09:17 +0200	[thread overview]
Message-ID: <87wonbz6gy.fsf@gaia.fi.intel.com> (raw)
In-Reply-To: <20190110101152.15651-18-chris@chris-wilson.co.uk>

Chris Wilson <chris@chris-wilson.co.uk> writes:

> On module load and unload, we grab the POWER_DOMAIN_INIT powerwells and
> transfer them to the runtime-pm code. We can use our wakeref tracking to
> verify that the wakeref is indeed passed from init to enable, and
> disable to fini; and across suspend.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c     |   3 +
>  drivers/gpu/drm/i915/i915_drv.h         |   2 +
>  drivers/gpu/drm/i915/intel_runtime_pm.c | 151 +++++++++++++-----------
>  3 files changed, 88 insertions(+), 68 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index b7dcacf2a5d3..96717a23b32f 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -2699,6 +2699,9 @@ static int i915_runtime_pm_status(struct seq_file *m, void *unused)
>  	if (!HAS_RUNTIME_PM(dev_priv))
>  		seq_puts(m, "Runtime power management not supported\n");
>  
> +	seq_printf(m, "Runtime power management: %s\n",
> +		   enableddisabled(!dev_priv->power_domains.wakeref));
> +
>  	seq_printf(m, "GPU idle: %s (epoch %u)\n",
>  		   yesno(!dev_priv->gt.awake), dev_priv->gt.epoch);
>  	seq_printf(m, "IRQs disabled: %s\n",
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 44c1b21febba..259b91b62ff2 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -822,6 +822,8 @@ struct i915_power_domains {
>  	bool display_core_suspended;
>  	int power_well_count;
>  
> +	intel_wakeref_t wakeref;
> +
>  	struct mutex lock;
>  	int domain_use_count[POWER_DOMAIN_NUM];
>  	struct i915_power_well *power_wells;
> diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
> index fd2fc10dd1e4..8d38f3e7fad1 100644
> --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> @@ -4009,7 +4009,7 @@ static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv);
>  
>  /**
>   * intel_power_domains_init_hw - initialize hardware power domain state
> - * @dev_priv: i915 device instance
> + * @i915: i915 device instance
>   * @resume: Called from resume code paths or not
>   *
>   * This function initializes the hardware power domain state and enables all
> @@ -4023,30 +4023,31 @@ static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv);
>   * intel_power_domains_enable()) and must be paired with
>   * intel_power_domains_fini_hw().
>   */
> -void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume)
> +void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume)
>  {
> -	struct i915_power_domains *power_domains = &dev_priv->power_domains;
> +	struct i915_power_domains *power_domains = &i915->power_domains;
>  
>  	power_domains->initializing = true;
>  
> -	if (IS_ICELAKE(dev_priv)) {
> -		icl_display_core_init(dev_priv, resume);
> -	} else if (IS_CANNONLAKE(dev_priv)) {
> -		cnl_display_core_init(dev_priv, resume);
> -	} else if (IS_GEN9_BC(dev_priv)) {
> -		skl_display_core_init(dev_priv, resume);
> -	} else if (IS_GEN9_LP(dev_priv)) {
> -		bxt_display_core_init(dev_priv, resume);
> -	} else if (IS_CHERRYVIEW(dev_priv)) {
> +	if (IS_ICELAKE(i915)) {
> +		icl_display_core_init(i915, resume);
> +	} else if (IS_CANNONLAKE(i915)) {
> +		cnl_display_core_init(i915, resume);
> +	} else if (IS_GEN9_BC(i915)) {
> +		skl_display_core_init(i915, resume);
> +	} else if (IS_GEN9_LP(i915)) {
> +		bxt_display_core_init(i915, resume);
> +	} else if (IS_CHERRYVIEW(i915)) {
>  		mutex_lock(&power_domains->lock);
> -		chv_phy_control_init(dev_priv);
> +		chv_phy_control_init(i915);
>  		mutex_unlock(&power_domains->lock);
> -	} else if (IS_VALLEYVIEW(dev_priv)) {
> +	} else if (IS_VALLEYVIEW(i915)) {
>  		mutex_lock(&power_domains->lock);
> -		vlv_cmnlane_wa(dev_priv);
> +		vlv_cmnlane_wa(i915);
>  		mutex_unlock(&power_domains->lock);
> -	} else if (IS_IVYBRIDGE(dev_priv) || INTEL_GEN(dev_priv) >= 7)
> -		intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv));
> +	} else if (IS_IVYBRIDGE(i915) || INTEL_GEN(i915) >= 7) {
> +		intel_pch_reset_handshake(i915, !HAS_PCH_NOP(i915));
> +	}
>  
>  	/*
>  	 * Keep all power wells enabled for any dependent HW access during
> @@ -4054,18 +4055,20 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume)
>  	 * resources powered until display HW readout is complete. We drop
>  	 * this reference in intel_power_domains_enable().
>  	 */
> -	intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
> +	power_domains->wakeref =
> +		intel_display_power_get(i915, POWER_DOMAIN_INIT);
> +
>  	/* Disable power support if the user asked so. */
>  	if (!i915_modparams.disable_power_well)
> -		intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);

For the uninitiated, the comment vs the conditional did raise
heart rate.

Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>


> -	intel_power_domains_sync_hw(dev_priv);
> +		intel_display_power_get(i915, POWER_DOMAIN_INIT);
> +	intel_power_domains_sync_hw(i915);
>  
>  	power_domains->initializing = false;
>  }
>  
>  /**
>   * intel_power_domains_fini_hw - deinitialize hw power domain state
> - * @dev_priv: i915 device instance
> + * @i915: i915 device instance
>   *
>   * De-initializes the display power domain HW state. It also ensures that the
>   * device stays powered up so that the driver can be reloaded.
> @@ -4074,21 +4077,24 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume)
>   * intel_power_domains_disable()) and must be paired with
>   * intel_power_domains_init_hw().
>   */
> -void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv)
> +void intel_power_domains_fini_hw(struct drm_i915_private *i915)
>  {
> -	/* Keep the power well enabled, but cancel its rpm wakeref. */
> -	intel_runtime_pm_put_unchecked(dev_priv);
> +	intel_wakeref_t wakeref __maybe_unused =
> +		fetch_and_zero(&i915->power_domains.wakeref);
>  
>  	/* Remove the refcount we took to keep power well support disabled. */
>  	if (!i915_modparams.disable_power_well)
> -		intel_display_power_put_unchecked(dev_priv, POWER_DOMAIN_INIT);
> +		intel_display_power_put_unchecked(i915, POWER_DOMAIN_INIT);
> +
> +	intel_power_domains_verify_state(i915);
>  
> -	intel_power_domains_verify_state(dev_priv);
> +	/* Keep the power well enabled, but cancel its rpm wakeref. */
> +	intel_runtime_pm_put(i915, wakeref);
>  }
>  
>  /**
>   * intel_power_domains_enable - enable toggling of display power wells
> - * @dev_priv: i915 device instance
> + * @i915: i915 device instance
>   *
>   * Enable the ondemand enabling/disabling of the display power wells. Note that
>   * power wells not belonging to POWER_DOMAIN_INIT are allowed to be toggled
> @@ -4098,30 +4104,36 @@ void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv)
>   * of display HW readout (which will acquire the power references reflecting
>   * the current HW state).
>   */
> -void intel_power_domains_enable(struct drm_i915_private *dev_priv)
> +void intel_power_domains_enable(struct drm_i915_private *i915)
>  {
> -	intel_display_power_put_unchecked(dev_priv, POWER_DOMAIN_INIT);
> +	intel_wakeref_t wakeref __maybe_unused =
> +		fetch_and_zero(&i915->power_domains.wakeref);
>  
> -	intel_power_domains_verify_state(dev_priv);
> +	intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref);
> +	intel_power_domains_verify_state(i915);
>  }
>  
>  /**
>   * intel_power_domains_disable - disable toggling of display power wells
> - * @dev_priv: i915 device instance
> + * @i915: i915 device instance
>   *
>   * Disable the ondemand enabling/disabling of the display power wells. See
>   * intel_power_domains_enable() for which power wells this call controls.
>   */
> -void intel_power_domains_disable(struct drm_i915_private *dev_priv)
> +void intel_power_domains_disable(struct drm_i915_private *i915)
>  {
> -	intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
> +	struct i915_power_domains *power_domains = &i915->power_domains;
>  
> -	intel_power_domains_verify_state(dev_priv);
> +	WARN_ON(power_domains->wakeref);
> +	power_domains->wakeref =
> +		intel_display_power_get(i915, POWER_DOMAIN_INIT);
> +
> +	intel_power_domains_verify_state(i915);
>  }
>  
>  /**
>   * intel_power_domains_suspend - suspend power domain state
> - * @dev_priv: i915 device instance
> + * @i915: i915 device instance
>   * @suspend_mode: specifies the target suspend state (idle, mem, hibernation)
>   *
>   * This function prepares the hardware power domain state before entering
> @@ -4130,12 +4142,14 @@ void intel_power_domains_disable(struct drm_i915_private *dev_priv)
>   * It must be called with power domains already disabled (after a call to
>   * intel_power_domains_disable()) and paired with intel_power_domains_resume().
>   */
> -void intel_power_domains_suspend(struct drm_i915_private *dev_priv,
> +void intel_power_domains_suspend(struct drm_i915_private *i915,
>  				 enum i915_drm_suspend_mode suspend_mode)
>  {
> -	struct i915_power_domains *power_domains = &dev_priv->power_domains;
> +	struct i915_power_domains *power_domains = &i915->power_domains;
> +	intel_wakeref_t wakeref __maybe_unused =
> +		fetch_and_zero(&power_domains->wakeref);
>  
> -	intel_display_power_put_unchecked(dev_priv, POWER_DOMAIN_INIT);
> +	intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref);
>  
>  	/*
>  	 * In case of suspend-to-idle (aka S0ix) on a DMC platform without DC9
> @@ -4144,10 +4158,10 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv,
>  	 * resources as required and also enable deeper system power states
>  	 * that would be blocked if the firmware was inactive.
>  	 */
> -	if (!(dev_priv->csr.allowed_dc_mask & DC_STATE_EN_DC9) &&
> +	if (!(i915->csr.allowed_dc_mask & DC_STATE_EN_DC9) &&
>  	    suspend_mode == I915_DRM_SUSPEND_IDLE &&
> -	    dev_priv->csr.dmc_payload != NULL) {
> -		intel_power_domains_verify_state(dev_priv);
> +	    i915->csr.dmc_payload) {
> +		intel_power_domains_verify_state(i915);
>  		return;
>  	}
>  
> @@ -4156,25 +4170,25 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv,
>  	 * power wells if power domains must be deinitialized for suspend.
>  	 */
>  	if (!i915_modparams.disable_power_well) {
> -		intel_display_power_put_unchecked(dev_priv, POWER_DOMAIN_INIT);
> -		intel_power_domains_verify_state(dev_priv);
> +		intel_display_power_put_unchecked(i915, POWER_DOMAIN_INIT);
> +		intel_power_domains_verify_state(i915);
>  	}
>  
> -	if (IS_ICELAKE(dev_priv))
> -		icl_display_core_uninit(dev_priv);
> -	else if (IS_CANNONLAKE(dev_priv))
> -		cnl_display_core_uninit(dev_priv);
> -	else if (IS_GEN9_BC(dev_priv))
> -		skl_display_core_uninit(dev_priv);
> -	else if (IS_GEN9_LP(dev_priv))
> -		bxt_display_core_uninit(dev_priv);
> +	if (IS_ICELAKE(i915))
> +		icl_display_core_uninit(i915);
> +	else if (IS_CANNONLAKE(i915))
> +		cnl_display_core_uninit(i915);
> +	else if (IS_GEN9_BC(i915))
> +		skl_display_core_uninit(i915);
> +	else if (IS_GEN9_LP(i915))
> +		bxt_display_core_uninit(i915);
>  
>  	power_domains->display_core_suspended = true;
>  }
>  
>  /**
>   * intel_power_domains_resume - resume power domain state
> - * @dev_priv: i915 device instance
> + * @i915: i915 device instance
>   *
>   * This function resume the hardware power domain state during system resume.
>   *
> @@ -4182,28 +4196,30 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv,
>   * intel_power_domains_enable()) and must be paired with
>   * intel_power_domains_suspend().
>   */
> -void intel_power_domains_resume(struct drm_i915_private *dev_priv)
> +void intel_power_domains_resume(struct drm_i915_private *i915)
>  {
> -	struct i915_power_domains *power_domains = &dev_priv->power_domains;
> +	struct i915_power_domains *power_domains = &i915->power_domains;
>  
>  	if (power_domains->display_core_suspended) {
> -		intel_power_domains_init_hw(dev_priv, true);
> +		intel_power_domains_init_hw(i915, true);
>  		power_domains->display_core_suspended = false;
>  	} else {
> -		intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
> +		WARN_ON(power_domains->wakeref);
> +		power_domains->wakeref =
> +			intel_display_power_get(i915, POWER_DOMAIN_INIT);
>  	}
>  
> -	intel_power_domains_verify_state(dev_priv);
> +	intel_power_domains_verify_state(i915);
>  }
>  
>  #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
>  
> -static void intel_power_domains_dump_info(struct drm_i915_private *dev_priv)
> +static void intel_power_domains_dump_info(struct drm_i915_private *i915)
>  {
> -	struct i915_power_domains *power_domains = &dev_priv->power_domains;
> +	struct i915_power_domains *power_domains = &i915->power_domains;
>  	struct i915_power_well *power_well;
>  
> -	for_each_power_well(dev_priv, power_well) {
> +	for_each_power_well(i915, power_well) {
>  		enum intel_display_power_domain domain;
>  
>  		DRM_DEBUG_DRIVER("%-25s %d\n",
> @@ -4218,7 +4234,7 @@ static void intel_power_domains_dump_info(struct drm_i915_private *dev_priv)
>  
>  /**
>   * intel_power_domains_verify_state - verify the HW/SW state for all power wells
> - * @dev_priv: i915 device instance
> + * @i915: i915 device instance
>   *
>   * Verify if the reference count of each power well matches its HW enabled
>   * state and the total refcount of the domains it belongs to. This must be
> @@ -4226,22 +4242,21 @@ static void intel_power_domains_dump_info(struct drm_i915_private *dev_priv)
>   * acquiring reference counts for any power wells in use and disabling the
>   * ones left on by BIOS but not required by any active output.
>   */
> -static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv)
> +static void intel_power_domains_verify_state(struct drm_i915_private *i915)
>  {
> -	struct i915_power_domains *power_domains = &dev_priv->power_domains;
> +	struct i915_power_domains *power_domains = &i915->power_domains;
>  	struct i915_power_well *power_well;
>  	bool dump_domain_info;
>  
>  	mutex_lock(&power_domains->lock);
>  
>  	dump_domain_info = false;
> -	for_each_power_well(dev_priv, power_well) {
> +	for_each_power_well(i915, power_well) {
>  		enum intel_display_power_domain domain;
>  		int domains_count;
>  		bool enabled;
>  
> -		enabled = power_well->desc->ops->is_enabled(dev_priv,
> -							    power_well);
> +		enabled = power_well->desc->ops->is_enabled(i915, power_well);
>  		if ((power_well->count || power_well->desc->always_on) !=
>  		    enabled)
>  			DRM_ERROR("power well %s state mismatch (refcount %d/enabled %d)",
> @@ -4265,7 +4280,7 @@ static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv)
>  		static bool dumped;
>  
>  		if (!dumped) {
> -			intel_power_domains_dump_info(dev_priv);
> +			intel_power_domains_dump_info(i915);
>  			dumped = true;
>  		}
>  	}
> @@ -4275,7 +4290,7 @@ static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv)
>  
>  #else
>  
> -static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv)
> +static void intel_power_domains_verify_state(struct drm_i915_private *i915)
>  {
>  }
>  
> -- 
> 2.20.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2019-01-11 13:10 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-10 10:11 Track rpm wakerefs to fix bugs Chris Wilson
2019-01-10 10:11 ` [PATCH 01/21] drm/i915: Track all held rpm wakerefs Chris Wilson
2019-01-10 10:11 ` [PATCH 02/21] drm/i915: Markup paired operations on wakerefs Chris Wilson
2019-01-10 10:20   ` Mika Kuoppala
2019-01-10 10:11 ` [PATCH 03/21] drm/i915: Track GT wakeref Chris Wilson
2019-01-10 10:11 ` [PATCH 04/21] drm/i915: Track the rpm wakerefs for error handling Chris Wilson
2019-01-10 10:11 ` [PATCH 05/21] drm/i915: Mark up sysfs with rpm wakeref tracking Chris Wilson
2019-01-10 10:11 ` [PATCH 06/21] drm/i915: Mark up debugfs " Chris Wilson
2019-01-10 10:11 ` [PATCH 07/21] drm/i915/perf: Track the rpm wakeref Chris Wilson
2019-01-10 10:11 ` [PATCH 08/21] drm/i915/pmu: Track " Chris Wilson
2019-01-10 10:11 ` [PATCH 09/21] drm/i915/guc: Track the " Chris Wilson
2019-01-10 10:11 ` [PATCH 10/21] drm/i915/gem: Track the rpm wakerefs Chris Wilson
2019-01-10 10:11 ` [PATCH 11/21] drm/i915/fb: Track " Chris Wilson
2019-01-10 10:11 ` [PATCH 12/21] drm/i915/hotplug: Track temporary rpm wakeref Chris Wilson
2019-01-10 10:11 ` [PATCH 13/21] drm/i915/panel: " Chris Wilson
2019-01-10 10:11 ` [PATCH 14/21] drm/i915/selftests: Mark up rpm wakerefs Chris Wilson
2019-01-10 10:11 ` [PATCH 15/21] drm/i915: Syntatic sugar for using intel_runtime_pm Chris Wilson
2019-01-10 10:11 ` [PATCH 16/21] drm/i915: Markup paired operations on display power domains Chris Wilson
2019-01-10 15:51   ` Mika Kuoppala
2019-01-10 16:21     ` Chris Wilson
2019-01-10 16:49       ` Mika Kuoppala
2019-01-10 10:11 ` [PATCH 17/21] drm/i915: Track the wakeref used to initialise " Chris Wilson
2019-01-10 23:15   ` John Harrison
2019-01-10 23:21     ` Chris Wilson
2019-01-11 13:09   ` Mika Kuoppala [this message]
2019-01-10 10:11 ` [PATCH 18/21] drm/i915: Combined gt.awake/gt.power wakerefs Chris Wilson
2019-01-14 14:20   ` Mika Kuoppala
2019-01-10 10:11 ` [PATCH 19/21] drm/i915/dp: Markup pps lock power well Chris Wilson
2019-01-11  0:16   ` John Harrison
2019-01-11  1:19     ` Chris Wilson
2019-01-10 10:11 ` [PATCH 20/21] drm/i915: Complain if hsw_get_pipe_config acquires the same power well twice Chris Wilson
2019-01-11 13:47   ` Mika Kuoppala
2019-01-10 10:11 ` [PATCH 21/21] drm/i915: Mark up Ironlake ips with rpm wakerefs Chris Wilson
2019-01-11 21:05   ` John Harrison
2019-01-14 15:01   ` Mika Kuoppala
2019-01-14 16:57     ` Chris Wilson
2019-01-10 11:47 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/21] drm/i915: Track all held " Patchwork
2019-01-10 11:54 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-01-10 12:31 ` ✗ Fi.CI.BAT: failure " 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=87wonbz6gy.fsf@gaia.fi.intel.com \
    --to=mika.kuoppala@linux.intel.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jani.nikula@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 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.