diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.h')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_runtime_pm.h | 68 |
1 files changed, 41 insertions, 27 deletions
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.h b/drivers/gpu/drm/i915/intel_runtime_pm.h index 183ea2b187fe..ed6c43b17f9a 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.h +++ b/drivers/gpu/drm/i915/intel_runtime_pm.h @@ -6,23 +6,15 @@ #ifndef __INTEL_RUNTIME_PM_H__ #define __INTEL_RUNTIME_PM_H__ +#include <linux/pm_runtime.h> #include <linux/types.h> -#include "display/intel_display.h" - #include "intel_wakeref.h" -#include "i915_utils.h" - struct device; struct drm_i915_private; struct drm_printer; - -enum i915_drm_suspend_mode { - I915_DRM_SUSPEND_IDLE, - I915_DRM_SUSPEND_MEM, - I915_DRM_SUSPEND_HIBERNATE, -}; +struct intel_display_rpm_interface; /* * This struct helps tracking the state needed for runtime PM, which puts the @@ -40,7 +32,7 @@ enum i915_drm_suspend_mode { * 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 + * goes back to false exactly before we re-enable 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. @@ -51,8 +43,29 @@ struct intel_runtime_pm { atomic_t wakeref_count; struct device *kdev; /* points to i915->drm.dev */ bool available; - bool suspended; - bool irqs_enabled; + bool no_wakeref_tracking; + + /* + * Protects access to lmem usefault list. + * It is required, if we are outside of the runtime suspend path, + * access to @lmem_userfault_list requires always first grabbing the + * runtime pm, to ensure we can't race against runtime suspend. + * Once we have that we also need to grab @lmem_userfault_lock, + * at which point we have exclusive access. + * The runtime suspend path is special since it doesn't really hold any locks, + * but instead has exclusive access by virtue of all other accesses requiring + * holding the runtime pm wakeref. + */ + spinlock_t lmem_userfault_lock; + + /* + * Keep list of userfaulted gem obj, which require to release their + * mmap mappings at runtime suspend path. + */ + struct list_head lmem_userfault_list; + + /* Manual runtime pm autosuspend delay for user GGTT/lmem mmaps */ + struct intel_wakeref_auto userfault_wakeref; #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) /* @@ -62,20 +75,12 @@ struct intel_runtime_pm { * 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; + struct ref_tracker_dir debug; #endif }; #define BITS_PER_WAKEREF \ - BITS_PER_TYPE(struct_member(struct intel_runtime_pm, wakeref_count)) + BITS_PER_TYPE(typeof_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) @@ -92,10 +97,16 @@ intel_rpm_wakelock_count(int wakeref_count) return wakeref_count >> INTEL_RPM_WAKELOCK_SHIFT; } +static inline bool +intel_runtime_pm_suspended(struct intel_runtime_pm *rpm) +{ + return pm_runtime_suspended(rpm->kdev); +} + static inline void assert_rpm_device_not_suspended(struct intel_runtime_pm *rpm) { - WARN_ONCE(rpm->suspended, + WARN_ONCE(intel_runtime_pm_suspended(rpm), "Device suspended during HW access\n"); } @@ -174,6 +185,7 @@ void intel_runtime_pm_init_early(struct intel_runtime_pm *rpm); void intel_runtime_pm_enable(struct intel_runtime_pm *rpm); void intel_runtime_pm_disable(struct intel_runtime_pm *rpm); void intel_runtime_pm_driver_release(struct intel_runtime_pm *rpm); +void intel_runtime_pm_driver_last_release(struct intel_runtime_pm *rpm); intel_wakeref_t intel_runtime_pm_get(struct intel_runtime_pm *rpm); intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm); @@ -183,15 +195,15 @@ intel_wakeref_t intel_runtime_pm_get_raw(struct intel_runtime_pm *rpm); #define with_intel_runtime_pm(rpm, wf) \ for ((wf) = intel_runtime_pm_get(rpm); (wf); \ - intel_runtime_pm_put((rpm), (wf)), (wf) = 0) + intel_runtime_pm_put((rpm), (wf)), (wf) = NULL) #define with_intel_runtime_pm_if_in_use(rpm, wf) \ for ((wf) = intel_runtime_pm_get_if_in_use(rpm); (wf); \ - intel_runtime_pm_put((rpm), (wf)), (wf) = 0) + intel_runtime_pm_put((rpm), (wf)), (wf) = NULL) #define with_intel_runtime_pm_if_active(rpm, wf) \ for ((wf) = intel_runtime_pm_get_if_active(rpm); (wf); \ - intel_runtime_pm_put((rpm), (wf)), (wf) = 0) + intel_runtime_pm_put((rpm), (wf)), (wf) = NULL) void intel_runtime_pm_put_unchecked(struct intel_runtime_pm *rpm); #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) @@ -215,4 +227,6 @@ static inline void print_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm, } #endif +extern const struct intel_display_rpm_interface i915_display_rpm_interface; + #endif /* __INTEL_RUNTIME_PM_H__ */ |
