intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: Imre Deak <imre.deak@intel.com>
To: Paulo Zanoni <przanoni@gmail.com>
Cc: intel-gfx@lists.freedesktop.org, Paulo Zanoni <paulo.r.zanoni@intel.com>
Subject: Re: [RFC 1/6] drm/i915: add initial Runtime PM functions
Date: Mon, 28 Oct 2013 15:21:28 +0200	[thread overview]
Message-ID: <1382966488.5775.72.camel@intelbox> (raw)
In-Reply-To: <1382470214-1597-2-git-send-email-przanoni@gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 10696 bytes --]

On Tue, 2013-10-22 at 17:30 -0200, Paulo Zanoni wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
> 
> This patch adds the initial infrastructure to allow a Runtime PM
> implementation that sets the device to its D3 state. The patch just
> adds the necessary callbacks and the initial infrastructure.
> 
> We still don't have any platform that actually uses this
> infrastructure, we still don't call get/put in all the places we need
> to, and we don't have any function to save/restore the state of the
> registers. This is not a problem since no platform uses the code added
> by this patch. We have a few people simultaneously working on runtime
> PM, so this initial code could help everybody make their plans.
> 
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_dma.c     | 38 +++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_drv.c     | 42 +++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_drv.h     |  7 +++++++
>  drivers/gpu/drm/i915/intel_drv.h    |  2 ++
>  drivers/gpu/drm/i915/intel_pm.c     | 26 +++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_uncore.c |  9 ++++++++
>  6 files changed, 124 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index fd848ef..6aa044e 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -42,6 +42,8 @@
>  #include <linux/vga_switcheroo.h>
>  #include <linux/slab.h>
>  #include <acpi/video.h>
> +#include <linux/pm.h>
> +#include <linux/pm_runtime.h>
>  
>  #define LP_RING(d) (&((struct drm_i915_private *)(d))->ring[RCS])
>  
> @@ -1449,6 +1451,38 @@ static void i915_dump_device_info(struct drm_i915_private *dev_priv)
>  #undef SEP_COMMA
>  }
>  
> +static void i915_init_runtime_pm(struct drm_i915_private *dev_priv)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +	struct device *device = &dev->pdev->dev;
> +
> +	dev_priv->pm.suspended = false;
> +
> +	if (!HAS_RUNTIME_PM(dev))
> +		return;
> +
> +	pm_runtime_set_active(device);
> +	pm_runtime_enable(device);
> +
> +	pm_runtime_set_autosuspend_delay(device, 10000); /* 10s */
> +	pm_runtime_mark_last_busy(device);
> +	pm_runtime_use_autosuspend(device);
> +	pm_runtime_allow(device);

This shouldn't be needed as we get here already with an allowed state.
It's not a problem as it's just a nop here, but imo it's confusing that
we don't have the corresponding pm_runtime_forbid() in
i915_fini_runtime_pm().

> +}
> +
> +static void i915_fini_runtime_pm(struct drm_i915_private *dev_priv)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +	struct device *device = &dev->pdev->dev;
> +
> +	if (!HAS_RUNTIME_PM(dev))
> +		return;
> +
> +	/* Make sure we're not suspended first. */
> +	pm_runtime_get_sync(device);
> +	pm_runtime_disable(device);
> +}
> +

Could we have the above functions in intel_pm.c?

>  /**
>   * i915_driver_load - setup chip and create an initial config
>   * @dev: DRM device
> @@ -1664,6 +1698,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
>  	if (IS_GEN5(dev))
>  		intel_gpu_ips_init(dev_priv);
>  
> +	i915_init_runtime_pm(dev_priv);
> +
>  	return 0;
>  
>  out_power_well:
> @@ -1704,6 +1740,8 @@ int i915_driver_unload(struct drm_device *dev)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	int ret;
>  
> +	i915_fini_runtime_pm(dev_priv);
> +
>  	intel_gpu_ips_teardown();
>  
>  	if (HAS_POWER_WELL(dev)) {
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 85ae0dc..08fc7ea 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -469,6 +469,8 @@ static int i915_drm_freeze(struct drm_device *dev)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_crtc *crtc;
>  
> +	intel_runtime_pm_get(dev_priv);
> +
>  	/* ignore lid events during suspend */
>  	mutex_lock(&dev_priv->modeset_restore_lock);
>  	dev_priv->modeset_restore = MODESET_SUSPENDED;
> @@ -653,6 +655,8 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
>  	mutex_lock(&dev_priv->modeset_restore_lock);
>  	dev_priv->modeset_restore = MODESET_DONE;
>  	mutex_unlock(&dev_priv->modeset_restore_lock);
> +
> +	intel_runtime_pm_put(dev_priv);
>  	return error;
>  }
>  
> @@ -880,6 +884,42 @@ static int i915_pm_poweroff(struct device *dev)
>  	return i915_drm_freeze(drm_dev);
>  }
>  
> +static int i915_runtime_suspend(struct device *device)
> +{
> +	struct pci_dev *pdev = to_pci_dev(device);
> +	struct drm_device *dev = pci_get_drvdata(pdev);
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +	WARN_ON(!HAS_RUNTIME_PM(dev));
> +
> +	DRM_DEBUG_KMS("Suspending device\n");
> +
> +	dev_priv->pm.suspended = true;
> +
> +	pci_save_state(pdev);
> +	pci_set_power_state(pdev, PCI_D3cold);
> +
> +	return 0;
> +}
> +
> +static int i915_runtime_resume(struct device *device)
> +{
> +	struct pci_dev *pdev = to_pci_dev(device);
> +	struct drm_device *dev = pci_get_drvdata(pdev);
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +	WARN_ON(!HAS_RUNTIME_PM(dev));
> +
> +	DRM_DEBUG_KMS("Resuming device\n");
> +
> +	pci_set_power_state(pdev, PCI_D0);
> +	pci_restore_state(pdev);
> +
> +	dev_priv->pm.suspended = false;
> +
> +	return 0;
> +}
> +
>  static const struct dev_pm_ops i915_pm_ops = {
>  	.suspend = i915_pm_suspend,
>  	.resume = i915_pm_resume,
> @@ -887,6 +927,8 @@ static const struct dev_pm_ops i915_pm_ops = {
>  	.thaw = i915_pm_thaw,
>  	.poweroff = i915_pm_poweroff,
>  	.restore = i915_pm_resume,
> +	.runtime_suspend = i915_runtime_suspend,
> +	.runtime_resume = i915_runtime_resume,
>  };
>  
>  static const struct vm_operations_struct i915_gem_vm_ops = {
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 80957ca..74f2b5d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1230,6 +1230,10 @@ struct i915_package_c8 {
>  	} regsave;
>  };
>  
> +struct i915_runtime_pm {
> +	bool suspended;
> +};
> +
>  enum intel_pipe_crc_source {
>  	INTEL_PIPE_CRC_SOURCE_NONE,
>  	INTEL_PIPE_CRC_SOURCE_PLANE1,
> @@ -1462,6 +1466,8 @@ typedef struct drm_i915_private {
>  
>  	struct i915_package_c8 pc8;
>  
> +	struct i915_runtime_pm pm;
> +
>  	/* Old dri1 support infrastructure, beware the dragons ya fools entering
>  	 * here! */
>  	struct i915_dri1_state dri1;
> @@ -1779,6 +1785,7 @@ struct drm_i915_file_private {
>  #define HAS_POWER_WELL(dev)	(IS_HASWELL(dev))
>  #define HAS_FPGA_DBG_UNCLAIMED(dev)	(INTEL_INFO(dev)->has_fpga_dbg)
>  #define HAS_PSR(dev)		(IS_HASWELL(dev))
> +#define HAS_RUNTIME_PM(dev)	false
>  
>  #define INTEL_PCH_DEVICE_ID_MASK		0xff00
>  #define INTEL_PCH_IBX_DEVICE_ID_TYPE		0x3b00
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index af1553c..80b5a80 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -840,6 +840,8 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv);
>  void gen6_rps_boost(struct drm_i915_private *dev_priv);
>  void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv);
>  void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv);
> +void intel_runtime_pm_get(struct drm_i915_private *dev_priv);
> +void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
>  void ilk_wm_get_hw_state(struct drm_device *dev);
>  
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 3e140ab..a973f35 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -31,6 +31,7 @@
>  #include "../../../platform/x86/intel_ips.h"
>  #include <linux/module.h>
>  #include <drm/i915_powerwell.h>
> +#include <linux/pm_runtime.h>
>  
>  /**
>   * RC6 is a special power stage which allows the GPU to enter an very
> @@ -5779,6 +5780,31 @@ void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv)
>  	hsw_enable_package_c8(dev_priv);
>  }
>  
> +void intel_runtime_pm_get(struct drm_i915_private *dev_priv)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +	struct device *device = &dev->pdev->dev;
> +
> +	if (!HAS_RUNTIME_PM(dev))
> +		return;
> +
> +	pm_runtime_mark_last_busy(device);

What's the point of calling this here? We call pm_runtime_get below,
which will prevent an auto suspend anyway and we call
pm_runtime_mark_last_busy() then intel_runtime_pm_put().

> +	pm_runtime_get(device);
> +	pm_runtime_barrier(device);

Why not using pm_runtime_get_sync() instead of the above 2 calls?

--Imre

> +}
> +
> +void intel_runtime_pm_put(struct drm_i915_private *dev_priv)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +	struct device *device = &dev->pdev->dev;
> +
> +	if (!HAS_RUNTIME_PM(dev))
> +		return;
> +
> +	pm_runtime_mark_last_busy(device);
> +	pm_runtime_put_autosuspend(device);
> +}
> +
>  /* Set up chip specific power management-related functions */
>  void intel_init_pm(struct drm_device *dev)
>  {
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index f6fae35..f5a2a6d 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -343,6 +343,13 @@ hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg)
>  	}
>  }
>  
> +static void
> +assert_device_not_suspended(struct drm_i915_private *dev_priv)
> +{
> +	WARN(HAS_RUNTIME_PM(dev_priv->dev) && dev_priv->pm.suspended,
> +	     "Device suspended\n");
> +}
> +
>  #define REG_READ_HEADER(x) \
>  	unsigned long irqflags; \
>  	u##x val = 0; \
> @@ -435,6 +442,7 @@ gen6_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace
>  	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
>  		__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
>  	} \
> +	assert_device_not_suspended(dev_priv); \
>  	__raw_i915_write##x(dev_priv, reg, val); \
>  	if (unlikely(__fifo_ret)) { \
>  		gen6_gt_check_fifodbg(dev_priv); \
> @@ -450,6 +458,7 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
>  	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
>  		__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
>  	} \
> +	assert_device_not_suspended(dev_priv); \
>  	hsw_unclaimed_reg_clear(dev_priv, reg); \
>  	__raw_i915_write##x(dev_priv, reg, val); \
>  	if (unlikely(__fifo_ret)) { \


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2013-10-28 13:21 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-22 19:30 [RFC 0/6] Haswell runtime PM support + D3 Paulo Zanoni
2013-10-22 19:30 ` [RFC 1/6] drm/i915: add initial Runtime PM functions Paulo Zanoni
2013-10-28 13:21   ` Imre Deak [this message]
2013-11-06 20:32     ` Paulo Zanoni
2013-11-07  9:38       ` Imre Deak
2013-11-07 11:36         ` Imre Deak
2013-11-07 18:13           ` Imre Deak
2013-10-22 19:30 ` [RFC 2/6] drm/i915: do adapter power state notification at runtime PM Paulo Zanoni
2013-10-22 19:30 ` [RFC 3/6] drm/i915: add enable_runtime_pm option Paulo Zanoni
2013-10-28 13:27   ` Imre Deak
2013-11-04 21:36     ` Ville Syrjälä
2013-11-06 20:04       ` Paulo Zanoni
2013-10-22 19:30 ` [RFC 4/6] drm/i915: add runtime put/get calls at the basic places Paulo Zanoni
2013-10-22 19:30 ` [RFC 5/6] drm/i915: add some runtime PM get/put calls Paulo Zanoni
2013-10-22 19:30 ` [RFC 6/6] drm/i915: add runtime PM support on Haswell Paulo Zanoni
2013-10-25 13:44 ` [RFC i-g-t] tests: add runtime_pm Paulo Zanoni
2013-10-27 13:37   ` Daniel Vetter
2013-10-28 12:20     ` Paulo Zanoni
2013-10-28 16:05       ` Daniel Vetter
2013-11-04 21:40       ` Ville Syrjälä
2013-11-08 18:19         ` Paulo Zanoni
2013-11-08 18:42           ` Daniel Vetter
2013-10-28 13:09 ` [RFC 0/6] Haswell runtime PM support + D3 Imre Deak
2013-10-28 16:10   ` Daniel Vetter
2013-10-28 20:02     ` Jesse Barnes

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=1382966488.5775.72.camel@intelbox \
    --to=imre.deak@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=paulo.r.zanoni@intel.com \
    --cc=przanoni@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 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).