From patchwork Thu May 16 21:56:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniele Ceraolo Spurio X-Patchwork-Id: 10947073 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0A5B51398 for ; Thu, 16 May 2019 21:57:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EDD2228ADE for ; Thu, 16 May 2019 21:57:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E255628C8D; Thu, 16 May 2019 21:57:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A807E28ADE for ; Thu, 16 May 2019 21:57:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B443C897EF; Thu, 16 May 2019 21:57:22 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9523A897E7 for ; Thu, 16 May 2019 21:57:20 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 May 2019 14:57:20 -0700 X-ExtLoop1: 1 Received: from dceraolo-linux.fm.intel.com ([10.1.27.145]) by orsmga001.jf.intel.com with ESMTP; 16 May 2019 14:57:20 -0700 From: Daniele Ceraolo Spurio To: intel-gfx@lists.freedesktop.org Date: Thu, 16 May 2019 14:56:31 -0700 Message-Id: <20190516215634.16675-5-daniele.ceraolospurio@intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190516215634.16675-1-daniele.ceraolospurio@intel.com> References: <20190516215634.16675-1-daniele.ceraolospurio@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC 4/7] drm/i915: move and rename i915_runtime_pm X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Asserts aside, all the code working on this structure is in intel_runtime_pm.c and uses the intel_ prefix, so move the structure to intel_runtime_pm.h and adopt the same prefix. Since all the asserts are now working on the runtime_pm structure, bring them across as well. Signed-off-by: Daniele Ceraolo Spurio --- drivers/gpu/drm/i915/i915_debugfs.c | 4 +- drivers/gpu/drm/i915/i915_drv.c | 4 +- drivers/gpu/drm/i915/i915_drv.h | 52 +-------- drivers/gpu/drm/i915/intel_drv.h | 97 ---------------- drivers/gpu/drm/i915/intel_runtime_pm.c | 58 +++++----- drivers/gpu/drm/i915/intel_runtime_pm.h | 147 ++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_uncore.h | 4 +- 7 files changed, 183 insertions(+), 183 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 072464a18050..227a1cdf4f02 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2636,7 +2636,7 @@ static int i915_energy_uJ(struct seq_file *m, void *data) return 0; } -static int i915_runtime_pm_status(struct seq_file *m, void *unused) +static int intel_runtime_pm_status(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); struct pci_dev *pdev = dev_priv->drm.pdev; @@ -4600,7 +4600,7 @@ static const struct drm_info_list i915_debugfs_list[] = { {"i915_llc", i915_llc, 0}, {"i915_edp_psr_status", i915_edp_psr_status, 0}, {"i915_energy_uJ", i915_energy_uJ, 0}, - {"i915_runtime_pm_status", i915_runtime_pm_status, 0}, + {"intel_runtime_pm_status", intel_runtime_pm_status, 0}, {"i915_power_domain_info", i915_power_domain_info, 0}, {"i915_dmc_info", i915_dmc_info, 0}, {"i915_display_info", i915_display_info, 0}, diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 8b9e5b042e70..7938906f5b1d 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2873,7 +2873,7 @@ static int intel_runtime_suspend(struct device *kdev) struct pci_dev *pdev = to_pci_dev(kdev); struct drm_device *dev = pci_get_drvdata(pdev); struct drm_i915_private *dev_priv = to_i915(dev); - struct i915_runtime_pm *rpm = &dev_priv->runtime_pm; + struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; int ret; if (WARN_ON_ONCE(!(dev_priv->gt_pm.rc6.enabled && HAS_RC6(dev_priv)))) @@ -2972,7 +2972,7 @@ static int intel_runtime_resume(struct device *kdev) struct pci_dev *pdev = to_pci_dev(kdev); struct drm_device *dev = pci_get_drvdata(pdev); struct drm_i915_private *dev_priv = to_i915(dev); - struct i915_runtime_pm *rpm = &dev_priv->runtime_pm; + struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; int ret = 0; if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv))) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 474074c7f395..195ba437835f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1152,56 +1152,6 @@ struct skl_wm_params { u32 dbuf_block_size; }; -/* - * This struct helps tracking the state needed for runtime PM, which puts the - * device in PCI D3 state. Notice that when this happens, nothing on the - * graphics device works, even register access, so we don't get interrupts nor - * anything else. - * - * Every piece of our code that needs to actually touch the hardware needs to - * either call intel_runtime_pm_get or call intel_display_power_get with the - * appropriate power domain. - * - * Our driver uses the autosuspend delay feature, which means we'll only really - * suspend if we stay with zero refcount for a certain amount of time. The - * default value is currently very conservative (see intel_runtime_pm_enable), but - * it can be changed with the standard runtime PM files from sysfs. - * - * The irqs_disabled variable becomes true exactly after we disable the IRQs and - * goes back to false exactly before we reenable the IRQs. We use this variable - * to check if someone is trying to enable/disable IRQs while they're supposed - * to be disabled. This shouldn't happen and we'll print some error messages in - * case it happens. - * - * For more, read the Documentation/power/runtime_pm.txt. - */ -struct i915_runtime_pm { - atomic_t wakeref_count; - struct device *kdev; - bool available; - bool suspended; - bool irqs_enabled; - -#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) - /* - * To aide detection of wakeref leaks and general misuse, we - * track all wakeref holders. With manual markup (i.e. returning - * a cookie to each rpm_get caller which they then supply to their - * paired rpm_put) we can remove corresponding pairs of and keep - * the array trimmed to active wakerefs. - */ - struct intel_runtime_pm_debug { - spinlock_t lock; - - depot_stack_handle_t last_acquire; - depot_stack_handle_t last_release; - - depot_stack_handle_t *owners; - unsigned long count; - } debug; -#endif -}; - enum intel_pipe_crc_source { INTEL_PIPE_CRC_SOURCE_NONE, INTEL_PIPE_CRC_SOURCE_PLANE1, @@ -1843,7 +1793,7 @@ struct drm_i915_private { } type; } dram_info; - struct i915_runtime_pm runtime_pm; + struct intel_runtime_pm runtime_pm; struct { bool initialized; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 6976d92b0bd8..178f1d123a13 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1619,101 +1619,4 @@ unsigned int i9xx_plane_max_stride(struct intel_plane *plane, unsigned int rotation); int bdw_get_pipemisc_bpp(struct intel_crtc *crtc); -/* intel_runtime_pm.c */ -#define BITS_PER_WAKEREF \ - BITS_PER_TYPE(struct_member(struct i915_runtime_pm, wakeref_count)) -#define INTEL_RPM_WAKELOCK_SHIFT (BITS_PER_WAKEREF / 2) -#define INTEL_RPM_WAKELOCK_BIAS (1 << INTEL_RPM_WAKELOCK_SHIFT) -#define INTEL_RPM_RAW_WAKEREF_MASK (INTEL_RPM_WAKELOCK_BIAS - 1) - -static inline int -intel_rpm_raw_wakeref_count(int wakeref_count) -{ - return wakeref_count & INTEL_RPM_RAW_WAKEREF_MASK; -} - -static inline int -intel_rpm_wakelock_count(int wakeref_count) -{ - return wakeref_count >> INTEL_RPM_WAKELOCK_SHIFT; -} - -static inline void -assert_rpm_device_not_suspended(struct i915_runtime_pm *rpm) -{ - WARN_ONCE(rpm->suspended, - "Device suspended during HW access\n"); -} - -static inline void -__assert_rpm_raw_wakeref_held(struct i915_runtime_pm *rpm, int wakeref_count) -{ - assert_rpm_device_not_suspended(rpm); - WARN_ONCE(!intel_rpm_raw_wakeref_count(wakeref_count), - "RPM raw-wakeref not held\n"); -} - -static inline void -__assert_rpm_wakelock_held(struct i915_runtime_pm *rpm, int wakeref_count) -{ - __assert_rpm_raw_wakeref_held(rpm, wakeref_count); - WARN_ONCE(!intel_rpm_wakelock_count(wakeref_count), - "RPM wakelock ref not held during HW access\n"); -} - -static inline void -assert_rpm_raw_wakeref_held(struct i915_runtime_pm *rpm) -{ - __assert_rpm_raw_wakeref_held(rpm, atomic_read(&rpm->wakeref_count)); -} - -static inline void -assert_rpm_wakelock_held(struct i915_runtime_pm *rpm) -{ - __assert_rpm_wakelock_held(rpm, atomic_read(&rpm->wakeref_count)); -} - -/** - * disable_rpm_wakeref_asserts - disable the RPM assert checks - * @rpm: the i915_runtime_pm structure - * - * This function disable asserts that check if we hold an RPM wakelock - * reference, while keeping the device-not-suspended checks still enabled. - * It's meant to be used only in special circumstances where our rule about - * the wakelock refcount wrt. the device power state doesn't hold. According - * to this rule at any point where we access the HW or want to keep the HW in - * an active state we must hold an RPM wakelock reference acquired via one of - * the intel_runtime_pm_get() helpers. Currently there are a few special spots - * where this rule doesn't hold: the IRQ and suspend/resume handlers, the - * forcewake release timer, and the GPU RPS and hangcheck works. All other - * users should avoid using this function. - * - * Any calls to this function must have a symmetric call to - * enable_rpm_wakeref_asserts(). - */ -static inline void -disable_rpm_wakeref_asserts(struct i915_runtime_pm *rpm) -{ - atomic_add(INTEL_RPM_WAKELOCK_BIAS + 1, - &rpm->wakeref_count); -} - -/** - * enable_rpm_wakeref_asserts - re-enable the RPM assert checks - * @rpm: the i915_runtime_pm structure - * - * This function re-enables the RPM assert checks after disabling them with - * disable_rpm_wakeref_asserts. It's meant to be used only in special - * circumstances otherwise its use should be avoided. - * - * Any calls to this function must have a symmetric call to - * disable_rpm_wakeref_asserts(). - */ -static inline void -enable_rpm_wakeref_asserts(struct i915_runtime_pm *rpm) -{ - atomic_sub(INTEL_RPM_WAKELOCK_BIAS + 1, - &rpm->wakeref_count); -} - #endif /* __INTEL_DRV_H__ */ diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 271153fd3a33..f669688c32c9 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -60,16 +60,16 @@ * present for a given platform. */ -static intel_wakeref_t intel_runtime_pm_get_raw(struct i915_runtime_pm *rpm); +static intel_wakeref_t intel_runtime_pm_get_raw(struct intel_runtime_pm *rpm); static void -__intel_runtime_pm_put(struct i915_runtime_pm *rpm, intel_wakeref_t wref, +__intel_runtime_pm_put(struct intel_runtime_pm *rpm, intel_wakeref_t wref, bool wakelock); #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) static void -intel_runtime_pm_put_raw(struct i915_runtime_pm *rpm, intel_wakeref_t wref); +intel_runtime_pm_put_raw(struct intel_runtime_pm *rpm, intel_wakeref_t wref); #else -static inline void intel_runtime_pm_put_raw(struct i915_runtime_pm *rpm, +static inline void intel_runtime_pm_put_raw(struct intel_runtime_pm *rpm, intel_wakeref_t wref) { __intel_runtime_pm_put(rpm, -1, false); @@ -112,13 +112,13 @@ static void __print_depot_stack(depot_stack_handle_t stack, snprint_stack_trace(buf, sz, &trace, indent); } -static void init_intel_runtime_pm_wakeref(struct i915_runtime_pm *rpm) +static void init_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm) { spin_lock_init(&rpm->debug.lock); } static noinline depot_stack_handle_t -track_intel_runtime_pm_wakeref(struct i915_runtime_pm *rpm) +track_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm) { depot_stack_handle_t stack, *stacks; unsigned long flags; @@ -150,7 +150,7 @@ track_intel_runtime_pm_wakeref(struct i915_runtime_pm *rpm) return stack; } -static void untrack_intel_runtime_pm_wakeref(struct i915_runtime_pm *rpm, +static void untrack_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm, depot_stack_handle_t stack) { unsigned long flags, n; @@ -270,7 +270,7 @@ dump_and_free_wakeref_tracking(struct intel_runtime_pm_debug *debug) } static noinline void -__intel_wakeref_dec_and_check_tracking(struct i915_runtime_pm *rpm) +__intel_wakeref_dec_and_check_tracking(struct intel_runtime_pm *rpm) { struct intel_runtime_pm_debug dbg = {}; unsigned long flags; @@ -287,7 +287,7 @@ __intel_wakeref_dec_and_check_tracking(struct i915_runtime_pm *rpm) } static noinline void -untrack_all_intel_runtime_pm_wakerefs(struct i915_runtime_pm *rpm) +untrack_all_intel_runtime_pm_wakerefs(struct intel_runtime_pm *rpm) { struct intel_runtime_pm_debug dbg = {}; unsigned long flags; @@ -305,7 +305,7 @@ void print_intel_runtime_pm_wakeref(struct drm_i915_private *i915, struct intel_runtime_pm_debug dbg = {}; do { - struct i915_runtime_pm *rpm = &i915->runtime_pm; + struct intel_runtime_pm *rpm = &i915->runtime_pm; unsigned long alloc = dbg.count; depot_stack_handle_t *s; @@ -339,36 +339,36 @@ void print_intel_runtime_pm_wakeref(struct drm_i915_private *i915, #else -static void init_intel_runtime_pm_wakeref(struct i915_runtime_pm *rpm) +static void init_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm) { } static depot_stack_handle_t -track_intel_runtime_pm_wakeref(struct i915_runtime_pm *rpm) +track_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm) { return -1; } -static void untrack_intel_runtime_pm_wakeref(struct i915_runtime_pm *rpm, +static void untrack_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm, intel_wakeref_t wref) { } static void -__intel_wakeref_dec_and_check_tracking(struct i915_runtime_pm *rpm) +__intel_wakeref_dec_and_check_tracking(struct intel_runtime_pm *rpm) { atomic_dec(&rpm->wakeref_count); } static void -untrack_all_intel_runtime_pm_wakerefs(struct i915_runtime_pm *rpm) +untrack_all_intel_runtime_pm_wakerefs(struct intel_runtime_pm *rpm) { } #endif static void -intel_runtime_pm_acquire(struct i915_runtime_pm *rpm, bool wakelock) +intel_runtime_pm_acquire(struct intel_runtime_pm *rpm, bool wakelock) { if (wakelock) { atomic_add(1 + INTEL_RPM_WAKELOCK_BIAS, &rpm->wakeref_count); @@ -380,7 +380,7 @@ intel_runtime_pm_acquire(struct i915_runtime_pm *rpm, bool wakelock) } static void -intel_runtime_pm_release(struct i915_runtime_pm *rpm, int wakelock) +intel_runtime_pm_release(struct intel_runtime_pm *rpm, int wakelock) { if (wakelock) { assert_rpm_wakelock_held(rpm); @@ -2209,7 +2209,7 @@ intel_display_power_put_async_work(struct work_struct *work) container_of(work, struct drm_i915_private, power_domains.async_put_work.work); struct i915_power_domains *power_domains = &dev_priv->power_domains; - struct i915_runtime_pm *rpm = &dev_priv->runtime_pm; + struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; intel_wakeref_t new_work_wakeref = intel_runtime_pm_get_raw(rpm); intel_wakeref_t old_work_wakeref = 0; @@ -2260,7 +2260,7 @@ void __intel_display_power_put_async(struct drm_i915_private *i915, intel_wakeref_t wakeref) { struct i915_power_domains *power_domains = &i915->power_domains; - struct i915_runtime_pm *rpm = &i915->runtime_pm; + struct intel_runtime_pm *rpm = &i915->runtime_pm; intel_wakeref_t work_wakeref = intel_runtime_pm_get_raw(rpm); mutex_lock(&power_domains->lock); @@ -4988,7 +4988,7 @@ static void intel_power_domains_verify_state(struct drm_i915_private *i915) #endif -static intel_wakeref_t __intel_runtime_pm_get(struct i915_runtime_pm *rpm, +static intel_wakeref_t __intel_runtime_pm_get(struct intel_runtime_pm *rpm, bool wakelock) { int ret; @@ -5001,7 +5001,7 @@ static intel_wakeref_t __intel_runtime_pm_get(struct i915_runtime_pm *rpm, return track_intel_runtime_pm_wakeref(rpm); } -static intel_wakeref_t intel_runtime_pm_get_raw(struct i915_runtime_pm *rpm) +static intel_wakeref_t intel_runtime_pm_get_raw(struct intel_runtime_pm *rpm) { return __intel_runtime_pm_get(rpm, false); } @@ -5039,7 +5039,7 @@ intel_wakeref_t intel_runtime_pm_get(struct drm_i915_private *i915) */ intel_wakeref_t intel_runtime_pm_get_if_in_use(struct drm_i915_private *i915) { - struct i915_runtime_pm *rpm = &i915->runtime_pm; + struct intel_runtime_pm *rpm = &i915->runtime_pm; if (IS_ENABLED(CONFIG_PM)) { /* @@ -5078,7 +5078,7 @@ intel_wakeref_t intel_runtime_pm_get_if_in_use(struct drm_i915_private *i915) */ intel_wakeref_t intel_runtime_pm_get_noresume(struct drm_i915_private *i915) { - struct i915_runtime_pm *rpm = &i915->runtime_pm; + struct intel_runtime_pm *rpm = &i915->runtime_pm; assert_rpm_wakelock_held(rpm); pm_runtime_get_noresume(rpm->kdev); @@ -5088,7 +5088,7 @@ intel_wakeref_t intel_runtime_pm_get_noresume(struct drm_i915_private *i915) return track_intel_runtime_pm_wakeref(rpm); } -static void __intel_runtime_pm_put(struct i915_runtime_pm *rpm, +static void __intel_runtime_pm_put(struct intel_runtime_pm *rpm, intel_wakeref_t wref, bool wakelock) { @@ -5104,7 +5104,7 @@ static void __intel_runtime_pm_put(struct i915_runtime_pm *rpm, #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) static void -intel_runtime_pm_put_raw(struct i915_runtime_pm *rpm, intel_wakeref_t wref) +intel_runtime_pm_put_raw(struct intel_runtime_pm *rpm, intel_wakeref_t wref) { __intel_runtime_pm_put(rpm, wref, false); } @@ -5155,7 +5155,7 @@ void intel_runtime_pm_put(struct drm_i915_private *i915, intel_wakeref_t wref) */ void intel_runtime_pm_enable(struct drm_i915_private *i915) { - struct i915_runtime_pm *rpm = &i915->runtime_pm; + struct intel_runtime_pm *rpm = &i915->runtime_pm; struct device *kdev = rpm->kdev; /* @@ -5197,7 +5197,7 @@ void intel_runtime_pm_enable(struct drm_i915_private *i915) void intel_runtime_pm_disable(struct drm_i915_private *i915) { - struct i915_runtime_pm *rpm = &i915->runtime_pm; + struct intel_runtime_pm *rpm = &i915->runtime_pm; struct device *kdev = rpm->kdev; /* Transfer rpm ownership back to core */ @@ -5212,7 +5212,7 @@ void intel_runtime_pm_disable(struct drm_i915_private *i915) void intel_runtime_pm_cleanup(struct drm_i915_private *i915) { - struct i915_runtime_pm *rpm = &i915->runtime_pm; + struct intel_runtime_pm *rpm = &i915->runtime_pm; int count = atomic_read(&rpm->wakeref_count); WARN(count, @@ -5225,7 +5225,7 @@ void intel_runtime_pm_cleanup(struct drm_i915_private *i915) void intel_runtime_pm_init_early(struct drm_i915_private *i915) { - struct i915_runtime_pm *rpm = &i915->runtime_pm; + struct intel_runtime_pm *rpm = &i915->runtime_pm; struct pci_dev *pdev = i915->drm.pdev; struct device *kdev = &pdev->dev; diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.h b/drivers/gpu/drm/i915/intel_runtime_pm.h index b964ca7af9c8..0e3817f9785e 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.h +++ b/drivers/gpu/drm/i915/intel_runtime_pm.h @@ -6,6 +6,7 @@ #ifndef __INTEL_RUNTIME_PM_H__ #define __INTEL_RUNTIME_PM_H__ +#include #include #include @@ -19,6 +20,152 @@ enum i915_drm_suspend_mode { I915_DRM_SUSPEND_HIBERNATE, }; +/* + * This struct helps tracking the state needed for runtime PM, which puts the + * device in PCI D3 state. Notice that when this happens, nothing on the + * graphics device works, even register access, so we don't get interrupts nor + * anything else. + * + * Every piece of our code that needs to actually touch the hardware needs to + * either call intel_runtime_pm_get or call intel_display_power_get with the + * appropriate power domain. + * + * Our driver uses the autosuspend delay feature, which means we'll only really + * suspend if we stay with zero refcount for a certain amount of time. The + * default value is currently very conservative (see intel_runtime_pm_enable), but + * it can be changed with the standard runtime PM files from sysfs. + * + * The irqs_disabled variable becomes true exactly after we disable the IRQs and + * goes back to false exactly before we reenable the IRQs. We use this variable + * to check if someone is trying to enable/disable IRQs while they're supposed + * to be disabled. This shouldn't happen and we'll print some error messages in + * case it happens. + * + * For more, read the Documentation/power/runtime_pm.txt. + */ +struct intel_runtime_pm { + atomic_t wakeref_count; + struct device *kdev; + bool available; + bool suspended; + bool irqs_enabled; + +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) + /* + * To aide detection of wakeref leaks and general misuse, we + * track all wakeref holders. With manual markup (i.e. returning + * a cookie to each rpm_get caller which they then supply to their + * paired rpm_put) we can remove corresponding pairs of and keep + * the array trimmed to active wakerefs. + */ + struct intel_runtime_pm_debug { + spinlock_t lock; + + depot_stack_handle_t last_acquire; + depot_stack_handle_t last_release; + + depot_stack_handle_t *owners; + unsigned long count; + } debug; +#endif +}; + +#define BITS_PER_WAKEREF \ + BITS_PER_TYPE(struct_member(struct intel_runtime_pm, wakeref_count)) +#define INTEL_RPM_WAKELOCK_SHIFT (BITS_PER_WAKEREF / 2) +#define INTEL_RPM_WAKELOCK_BIAS (1 << INTEL_RPM_WAKELOCK_SHIFT) +#define INTEL_RPM_RAW_WAKEREF_MASK (INTEL_RPM_WAKELOCK_BIAS - 1) + +static inline int +intel_rpm_raw_wakeref_count(int wakeref_count) +{ + return wakeref_count & INTEL_RPM_RAW_WAKEREF_MASK; +} + +static inline int +intel_rpm_wakelock_count(int wakeref_count) +{ + return wakeref_count >> INTEL_RPM_WAKELOCK_SHIFT; +} + +static inline void +assert_rpm_device_not_suspended(struct intel_runtime_pm *rpm) +{ + WARN_ONCE(rpm->suspended, + "Device suspended during HW access\n"); +} + +static inline void +__assert_rpm_raw_wakeref_held(struct intel_runtime_pm *rpm, int wakeref_count) +{ + assert_rpm_device_not_suspended(rpm); + WARN_ONCE(!intel_rpm_raw_wakeref_count(wakeref_count), + "RPM raw-wakeref not held\n"); +} + +static inline void +__assert_rpm_wakelock_held(struct intel_runtime_pm *rpm, int wakeref_count) +{ + __assert_rpm_raw_wakeref_held(rpm, wakeref_count); + WARN_ONCE(!intel_rpm_wakelock_count(wakeref_count), + "RPM wakelock ref not held during HW access\n"); +} + +static inline void +assert_rpm_raw_wakeref_held(struct intel_runtime_pm *rpm) +{ + __assert_rpm_raw_wakeref_held(rpm, atomic_read(&rpm->wakeref_count)); +} + +static inline void +assert_rpm_wakelock_held(struct intel_runtime_pm *rpm) +{ + __assert_rpm_wakelock_held(rpm, atomic_read(&rpm->wakeref_count)); +} + +/** + * disable_rpm_wakeref_asserts - disable the RPM assert checks + * @rpm: the intel_runtime_pm structure + * + * This function disable asserts that check if we hold an RPM wakelock + * reference, while keeping the device-not-suspended checks still enabled. + * It's meant to be used only in special circumstances where our rule about + * the wakelock refcount wrt. the device power state doesn't hold. According + * to this rule at any point where we access the HW or want to keep the HW in + * an active state we must hold an RPM wakelock reference acquired via one of + * the intel_runtime_pm_get() helpers. Currently there are a few special spots + * where this rule doesn't hold: the IRQ and suspend/resume handlers, the + * forcewake release timer, and the GPU RPS and hangcheck works. All other + * users should avoid using this function. + * + * Any calls to this function must have a symmetric call to + * enable_rpm_wakeref_asserts(). + */ +static inline void +disable_rpm_wakeref_asserts(struct intel_runtime_pm *rpm) +{ + atomic_add(INTEL_RPM_WAKELOCK_BIAS + 1, + &rpm->wakeref_count); +} + +/** + * enable_rpm_wakeref_asserts - re-enable the RPM assert checks + * @rpm: the intel_runtime_pm structure + * + * This function re-enables the RPM assert checks after disabling them with + * disable_rpm_wakeref_asserts. It's meant to be used only in special + * circumstances otherwise its use should be avoided. + * + * Any calls to this function must have a symmetric call to + * disable_rpm_wakeref_asserts(). + */ +static inline void +enable_rpm_wakeref_asserts(struct intel_runtime_pm *rpm) +{ + atomic_sub(INTEL_RPM_WAKELOCK_BIAS + 1, + &rpm->wakeref_count); +} + void skl_enable_dc6(struct drm_i915_private *dev_priv); void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv); void bxt_enable_dc9(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index d6af3de70121..804a0faacc91 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -33,7 +33,7 @@ #include "i915_reg.h" struct drm_i915_private; -struct i915_runtime_pm; +struct intel_runtime_pm; struct intel_uncore; enum forcewake_domain_id { @@ -97,7 +97,7 @@ struct intel_forcewake_range { struct intel_uncore { void __iomem *regs; - struct i915_runtime_pm *rpm; + struct intel_runtime_pm *rpm; spinlock_t lock; /** lock is also taken in irq contexts. */