aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2015-12-15 13:10:37 -0500
committerImre Deak <imre.deak@intel.com>2015-12-17 09:37:43 -0500
commit2b19efebf175bb2120c5ae00b8e79febe73d225a (patch)
treea5bab2bec86f9d34521c9094027ee82141a11d43
parent542db3cd345c38936bb9e4bb2c8d1971e6ac6619 (diff)
drm/i915: add support for checking RPM atomic sections
In some cases we want to check whether we hold an RPM wakelock reference for the whole duration of a sequence. To achieve this add a new RPM atomic sequence counter that we increment any time the wakelock refcount drops to zero. Check whether the sequence number stays the same during the atomic section and that we hold the wakelock at the beginning of the section. Motivated by Chris. v2-v3: - unchanged v4: - swap the order of atomic_read() and assert_rpm_wakelock_held() in assert_rpm_atomic_begin() to avoid race Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> (v3) Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1450203038-5150-10-git-send-email-imre.deak@intel.com
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h17
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c1
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c3
4 files changed, 21 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 74f1d78cbe2e..1943b8f0e684 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1606,6 +1606,7 @@ struct skl_wm_level {
1606 */ 1606 */
1607struct i915_runtime_pm { 1607struct i915_runtime_pm {
1608 atomic_t wakeref_count; 1608 atomic_t wakeref_count;
1609 atomic_t atomic_seq;
1609 bool suspended; 1610 bool suspended;
1610 bool irqs_enabled; 1611 bool irqs_enabled;
1611}; 1612};
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index eff7d2e7d71b..d523ebb2f89d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1446,6 +1446,23 @@ assert_rpm_wakelock_held(struct drm_i915_private *dev_priv)
1446 "RPM wakelock ref not held during HW access"); 1446 "RPM wakelock ref not held during HW access");
1447} 1447}
1448 1448
1449static inline int
1450assert_rpm_atomic_begin(struct drm_i915_private *dev_priv)
1451{
1452 int seq = atomic_read(&dev_priv->pm.atomic_seq);
1453
1454 assert_rpm_wakelock_held(dev_priv);
1455
1456 return seq;
1457}
1458
1459static inline void
1460assert_rpm_atomic_end(struct drm_i915_private *dev_priv, int begin_seq)
1461{
1462 WARN_ONCE(atomic_read(&dev_priv->pm.atomic_seq) != begin_seq,
1463 "HW access outside of RPM atomic section\n");
1464}
1465
1449/** 1466/**
1450 * disable_rpm_wakeref_asserts - disable the RPM assert checks 1467 * disable_rpm_wakeref_asserts - disable the RPM assert checks
1451 * @dev_priv: i915 device instance 1468 * @dev_priv: i915 device instance
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 3232305301ca..8d0d6f59a72b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7247,4 +7247,5 @@ void intel_pm_setup(struct drm_device *dev)
7247 7247
7248 dev_priv->pm.suspended = false; 7248 dev_priv->pm.suspended = false;
7249 atomic_set(&dev_priv->pm.wakeref_count, 0); 7249 atomic_set(&dev_priv->pm.wakeref_count, 0);
7250 atomic_set(&dev_priv->pm.atomic_seq, 0);
7250} 7251}
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 4c80d2adac70..a0b9eaf77fe9 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -2287,7 +2287,8 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv)
2287 struct device *device = &dev->pdev->dev; 2287 struct device *device = &dev->pdev->dev;
2288 2288
2289 assert_rpm_wakelock_held(dev_priv); 2289 assert_rpm_wakelock_held(dev_priv);
2290 atomic_dec(&dev_priv->pm.wakeref_count); 2290 if (atomic_dec_and_test(&dev_priv->pm.wakeref_count))
2291 atomic_inc(&dev_priv->pm.atomic_seq);
2291 2292
2292 pm_runtime_mark_last_busy(device); 2293 pm_runtime_mark_last_busy(device);
2293 pm_runtime_put_autosuspend(device); 2294 pm_runtime_put_autosuspend(device);