aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/Kconfig.debug3
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c6
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c8
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h20
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h44
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c285
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gem_device.c8
7 files changed, 324 insertions, 50 deletions
diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug
index 9e36ffb5eb7c..ad4d71161dda 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -21,11 +21,11 @@ config DRM_I915_DEBUG
21 select DEBUG_FS 21 select DEBUG_FS
22 select PREEMPT_COUNT 22 select PREEMPT_COUNT
23 select I2C_CHARDEV 23 select I2C_CHARDEV
24 select STACKDEPOT
24 select DRM_DP_AUX_CHARDEV 25 select DRM_DP_AUX_CHARDEV
25 select X86_MSR # used by igt/pm_rpm 26 select X86_MSR # used by igt/pm_rpm
26 select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks) 27 select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
27 select DRM_DEBUG_MM if DRM=y 28 select DRM_DEBUG_MM if DRM=y
28 select STACKDEPOT if DRM=y # for DRM_DEBUG_MM
29 select DRM_DEBUG_SELFTEST 29 select DRM_DEBUG_SELFTEST
30 select SW_SYNC # signaling validation framework (igt/syncobj*) 30 select SW_SYNC # signaling validation framework (igt/syncobj*)
31 select DRM_I915_SW_FENCE_DEBUG_OBJECTS 31 select DRM_I915_SW_FENCE_DEBUG_OBJECTS
@@ -173,6 +173,7 @@ config DRM_I915_DEBUG_RUNTIME_PM
173 bool "Enable extra state checking for runtime PM" 173 bool "Enable extra state checking for runtime PM"
174 depends on DRM_I915 174 depends on DRM_I915
175 default n 175 default n
176 select STACKDEPOT
176 help 177 help
177 Choose this option to turn on extra state checking for the 178 Choose this option to turn on extra state checking for the
178 runtime PM functionality. This may introduce overhead during 179 runtime PM functionality. This may introduce overhead during
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 95813e21ae02..050cf8abd426 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2702,6 +2702,12 @@ static int i915_runtime_pm_status(struct seq_file *m, void *unused)
2702 pci_power_name(pdev->current_state), 2702 pci_power_name(pdev->current_state),
2703 pdev->current_state); 2703 pdev->current_state);
2704 2704
2705 if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)) {
2706 struct drm_printer p = drm_seq_file_printer(m);
2707
2708 print_intel_runtime_pm_wakeref(dev_priv, &p);
2709 }
2710
2705 return 0; 2711 return 0;
2706} 2712}
2707 2713
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 75652dc1e24c..5731f992cf44 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -905,6 +905,7 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv)
905 mutex_init(&dev_priv->pps_mutex); 905 mutex_init(&dev_priv->pps_mutex);
906 906
907 i915_memcpy_init_early(dev_priv); 907 i915_memcpy_init_early(dev_priv);
908 intel_runtime_pm_init_early(dev_priv);
908 909
909 ret = i915_workqueues_init(dev_priv); 910 ret = i915_workqueues_init(dev_priv);
910 if (ret < 0) 911 if (ret < 0)
@@ -1807,8 +1808,7 @@ void i915_driver_unload(struct drm_device *dev)
1807 i915_driver_cleanup_mmio(dev_priv); 1808 i915_driver_cleanup_mmio(dev_priv);
1808 1809
1809 enable_rpm_wakeref_asserts(dev_priv); 1810 enable_rpm_wakeref_asserts(dev_priv);
1810 1811 intel_runtime_pm_cleanup(dev_priv);
1811 WARN_ON(atomic_read(&dev_priv->runtime_pm.wakeref_count));
1812} 1812}
1813 1813
1814static void i915_driver_release(struct drm_device *dev) 1814static void i915_driver_release(struct drm_device *dev)
@@ -2010,6 +2010,8 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
2010 2010
2011out: 2011out:
2012 enable_rpm_wakeref_asserts(dev_priv); 2012 enable_rpm_wakeref_asserts(dev_priv);
2013 if (!dev_priv->uncore.user_forcewake.count)
2014 intel_runtime_pm_cleanup(dev_priv);
2013 2015
2014 return ret; 2016 return ret;
2015} 2017}
@@ -2965,7 +2967,7 @@ static int intel_runtime_suspend(struct device *kdev)
2965 } 2967 }
2966 2968
2967 enable_rpm_wakeref_asserts(dev_priv); 2969 enable_rpm_wakeref_asserts(dev_priv);
2968 WARN_ON_ONCE(atomic_read(&dev_priv->runtime_pm.wakeref_count)); 2970 intel_runtime_pm_cleanup(dev_priv);
2969 2971
2970 if (intel_uncore_arm_unclaimed_mmio_detection(dev_priv)) 2972 if (intel_uncore_arm_unclaimed_mmio_detection(dev_priv))
2971 DRM_ERROR("Unclaimed access detected prior to suspending\n"); 2973 DRM_ERROR("Unclaimed access detected prior to suspending\n");
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5df26ccda8a4..7e3566a0ba72 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -45,6 +45,7 @@
45#include <linux/pm_qos.h> 45#include <linux/pm_qos.h>
46#include <linux/reservation.h> 46#include <linux/reservation.h>
47#include <linux/shmem_fs.h> 47#include <linux/shmem_fs.h>
48#include <linux/stackdepot.h>
48 49
49#include <drm/intel-gtt.h> 50#include <drm/intel-gtt.h>
50#include <drm/drm_legacy.h> /* for struct drm_dma_handle */ 51#include <drm/drm_legacy.h> /* for struct drm_dma_handle */
@@ -1156,6 +1157,25 @@ struct i915_runtime_pm {
1156 atomic_t wakeref_count; 1157 atomic_t wakeref_count;
1157 bool suspended; 1158 bool suspended;
1158 bool irqs_enabled; 1159 bool irqs_enabled;
1160
1161#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
1162 /*
1163 * To aide detection of wakeref leaks and general misuse, we
1164 * track all wakeref holders. With manual markup (i.e. returning
1165 * a cookie to each rpm_get caller which they then supply to their
1166 * paired rpm_put) we can remove corresponding pairs of and keep
1167 * the array trimmed to active wakerefs.
1168 */
1169 struct intel_runtime_pm_debug {
1170 spinlock_t lock;
1171
1172 depot_stack_handle_t last_acquire;
1173 depot_stack_handle_t last_release;
1174
1175 depot_stack_handle_t *owners;
1176 unsigned long count;
1177 } debug;
1178#endif
1159}; 1179};
1160 1180
1161enum intel_pipe_crc_source { 1181enum intel_pipe_crc_source {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1a11c2beb7f3..ac513fd70315 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -41,6 +41,8 @@
41#include <drm/drm_atomic.h> 41#include <drm/drm_atomic.h>
42#include <media/cec-notifier.h> 42#include <media/cec-notifier.h>
43 43
44struct drm_printer;
45
44/** 46/**
45 * __wait_for - magic wait macro 47 * __wait_for - magic wait macro
46 * 48 *
@@ -2084,6 +2086,7 @@ bool intel_psr_enabled(struct intel_dp *intel_dp);
2084void intel_init_quirks(struct drm_i915_private *dev_priv); 2086void intel_init_quirks(struct drm_i915_private *dev_priv);
2085 2087
2086/* intel_runtime_pm.c */ 2088/* intel_runtime_pm.c */
2089void intel_runtime_pm_init_early(struct drm_i915_private *dev_priv);
2087int intel_power_domains_init(struct drm_i915_private *); 2090int intel_power_domains_init(struct drm_i915_private *);
2088void intel_power_domains_cleanup(struct drm_i915_private *dev_priv); 2091void intel_power_domains_cleanup(struct drm_i915_private *dev_priv);
2089void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume); 2092void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume);
@@ -2106,6 +2109,7 @@ void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume);
2106void bxt_display_core_uninit(struct drm_i915_private *dev_priv); 2109void bxt_display_core_uninit(struct drm_i915_private *dev_priv);
2107void intel_runtime_pm_enable(struct drm_i915_private *dev_priv); 2110void intel_runtime_pm_enable(struct drm_i915_private *dev_priv);
2108void intel_runtime_pm_disable(struct drm_i915_private *dev_priv); 2111void intel_runtime_pm_disable(struct drm_i915_private *dev_priv);
2112void intel_runtime_pm_cleanup(struct drm_i915_private *dev_priv);
2109const char * 2113const char *
2110intel_display_power_domain_str(enum intel_display_power_domain domain); 2114intel_display_power_domain_str(enum intel_display_power_domain domain);
2111 2115
@@ -2123,23 +2127,23 @@ void icl_dbuf_slices_update(struct drm_i915_private *dev_priv,
2123 u8 req_slices); 2127 u8 req_slices);
2124 2128
2125static inline void 2129static inline void
2126assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv) 2130assert_rpm_device_not_suspended(struct drm_i915_private *i915)
2127{ 2131{
2128 WARN_ONCE(dev_priv->runtime_pm.suspended, 2132 WARN_ONCE(i915->runtime_pm.suspended,
2129 "Device suspended during HW access\n"); 2133 "Device suspended during HW access\n");
2130} 2134}
2131 2135
2132static inline void 2136static inline void
2133assert_rpm_wakelock_held(struct drm_i915_private *dev_priv) 2137assert_rpm_wakelock_held(struct drm_i915_private *i915)
2134{ 2138{
2135 assert_rpm_device_not_suspended(dev_priv); 2139 assert_rpm_device_not_suspended(i915);
2136 WARN_ONCE(!atomic_read(&dev_priv->runtime_pm.wakeref_count), 2140 WARN_ONCE(!atomic_read(&i915->runtime_pm.wakeref_count),
2137 "RPM wakelock ref not held during HW access"); 2141 "RPM wakelock ref not held during HW access");
2138} 2142}
2139 2143
2140/** 2144/**
2141 * disable_rpm_wakeref_asserts - disable the RPM assert checks 2145 * disable_rpm_wakeref_asserts - disable the RPM assert checks
2142 * @dev_priv: i915 device instance 2146 * @i915: i915 device instance
2143 * 2147 *
2144 * This function disable asserts that check if we hold an RPM wakelock 2148 * This function disable asserts that check if we hold an RPM wakelock
2145 * reference, while keeping the device-not-suspended checks still enabled. 2149 * reference, while keeping the device-not-suspended checks still enabled.
@@ -2156,14 +2160,14 @@ assert_rpm_wakelock_held(struct drm_i915_private *dev_priv)
2156 * enable_rpm_wakeref_asserts(). 2160 * enable_rpm_wakeref_asserts().
2157 */ 2161 */
2158static inline void 2162static inline void
2159disable_rpm_wakeref_asserts(struct drm_i915_private *dev_priv) 2163disable_rpm_wakeref_asserts(struct drm_i915_private *i915)
2160{ 2164{
2161 atomic_inc(&dev_priv->runtime_pm.wakeref_count); 2165 atomic_inc(&i915->runtime_pm.wakeref_count);
2162} 2166}
2163 2167
2164/** 2168/**
2165 * enable_rpm_wakeref_asserts - re-enable the RPM assert checks 2169 * enable_rpm_wakeref_asserts - re-enable the RPM assert checks
2166 * @dev_priv: i915 device instance 2170 * @i915: i915 device instance
2167 * 2171 *
2168 * This function re-enables the RPM assert checks after disabling them with 2172 * This function re-enables the RPM assert checks after disabling them with
2169 * disable_rpm_wakeref_asserts. It's meant to be used only in special 2173 * disable_rpm_wakeref_asserts. It's meant to be used only in special
@@ -2173,15 +2177,25 @@ disable_rpm_wakeref_asserts(struct drm_i915_private *dev_priv)
2173 * disable_rpm_wakeref_asserts(). 2177 * disable_rpm_wakeref_asserts().
2174 */ 2178 */
2175static inline void 2179static inline void
2176enable_rpm_wakeref_asserts(struct drm_i915_private *dev_priv) 2180enable_rpm_wakeref_asserts(struct drm_i915_private *i915)
2177{ 2181{
2178 atomic_dec(&dev_priv->runtime_pm.wakeref_count); 2182 atomic_dec(&i915->runtime_pm.wakeref_count);
2179} 2183}
2180 2184
2181void intel_runtime_pm_get(struct drm_i915_private *dev_priv); 2185void intel_runtime_pm_get(struct drm_i915_private *i915);
2182bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv); 2186bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *i915);
2183void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv); 2187void intel_runtime_pm_get_noresume(struct drm_i915_private *i915);
2184void intel_runtime_pm_put(struct drm_i915_private *dev_priv); 2188void intel_runtime_pm_put(struct drm_i915_private *i915);
2189
2190#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
2191void print_intel_runtime_pm_wakeref(struct drm_i915_private *i915,
2192 struct drm_printer *p);
2193#else
2194static inline void print_intel_runtime_pm_wakeref(struct drm_i915_private *i915,
2195 struct drm_printer *p)
2196{
2197}
2198#endif
2185 2199
2186void chv_phy_powergate_lanes(struct intel_encoder *encoder, 2200void chv_phy_powergate_lanes(struct intel_encoder *encoder,
2187 bool override, unsigned int mask); 2201 bool override, unsigned int mask);
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 9e9501f82f06..08f809371bbd 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -29,6 +29,8 @@
29#include <linux/pm_runtime.h> 29#include <linux/pm_runtime.h>
30#include <linux/vgaarb.h> 30#include <linux/vgaarb.h>
31 31
32#include <drm/drm_print.h>
33
32#include "i915_drv.h" 34#include "i915_drv.h"
33#include "intel_drv.h" 35#include "intel_drv.h"
34 36
@@ -49,6 +51,218 @@
49 * present for a given platform. 51 * present for a given platform.
50 */ 52 */
51 53
54#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
55
56#include <linux/sort.h>
57
58#define STACKDEPTH 8
59
60static noinline depot_stack_handle_t __save_depot_stack(void)
61{
62 unsigned long entries[STACKDEPTH];
63 struct stack_trace trace = {
64 .entries = entries,
65 .max_entries = ARRAY_SIZE(entries),
66 .skip = 1,
67 };
68
69 save_stack_trace(&trace);
70 if (trace.nr_entries &&
71 trace.entries[trace.nr_entries - 1] == ULONG_MAX)
72 trace.nr_entries--;
73
74 return depot_save_stack(&trace, GFP_NOWAIT | __GFP_NOWARN);
75}
76
77static void __print_depot_stack(depot_stack_handle_t stack,
78 char *buf, int sz, int indent)
79{
80 unsigned long entries[STACKDEPTH];
81 struct stack_trace trace = {
82 .entries = entries,
83 .max_entries = ARRAY_SIZE(entries),
84 };
85
86 depot_fetch_stack(stack, &trace);
87 snprint_stack_trace(buf, sz, &trace, indent);
88}
89
90static void init_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
91{
92 struct i915_runtime_pm *rpm = &i915->runtime_pm;
93
94 spin_lock_init(&rpm->debug.lock);
95}
96
97static noinline void
98track_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
99{
100 struct i915_runtime_pm *rpm = &i915->runtime_pm;
101 depot_stack_handle_t stack, *stacks;
102 unsigned long flags;
103
104 atomic_inc(&rpm->wakeref_count);
105 assert_rpm_wakelock_held(i915);
106
107 if (!HAS_RUNTIME_PM(i915))
108 return;
109
110 stack = __save_depot_stack();
111 if (!stack)
112 return;
113
114 spin_lock_irqsave(&rpm->debug.lock, flags);
115
116 if (!rpm->debug.count)
117 rpm->debug.last_acquire = stack;
118
119 stacks = krealloc(rpm->debug.owners,
120 (rpm->debug.count + 1) * sizeof(*stacks),
121 GFP_NOWAIT | __GFP_NOWARN);
122 if (stacks) {
123 stacks[rpm->debug.count++] = stack;
124 rpm->debug.owners = stacks;
125 }
126
127 spin_unlock_irqrestore(&rpm->debug.lock, flags);
128}
129
130static int cmphandle(const void *_a, const void *_b)
131{
132 const depot_stack_handle_t * const a = _a, * const b = _b;
133
134 if (*a < *b)
135 return -1;
136 else if (*a > *b)
137 return 1;
138 else
139 return 0;
140}
141
142static void
143__print_intel_runtime_pm_wakeref(struct drm_printer *p,
144 const struct intel_runtime_pm_debug *dbg)
145{
146 unsigned long i;
147 char *buf;
148
149 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
150 if (!buf)
151 return;
152
153 if (dbg->last_acquire) {
154 __print_depot_stack(dbg->last_acquire, buf, PAGE_SIZE, 2);
155 drm_printf(p, "Wakeref last acquired:\n%s", buf);
156 }
157
158 if (dbg->last_release) {
159 __print_depot_stack(dbg->last_release, buf, PAGE_SIZE, 2);
160 drm_printf(p, "Wakeref last released:\n%s", buf);
161 }
162
163 drm_printf(p, "Wakeref count: %lu\n", dbg->count);
164
165 sort(dbg->owners, dbg->count, sizeof(*dbg->owners), cmphandle, NULL);
166
167 for (i = 0; i < dbg->count; i++) {
168 depot_stack_handle_t stack = dbg->owners[i];
169 unsigned long rep;
170
171 rep = 1;
172 while (i + 1 < dbg->count && dbg->owners[i + 1] == stack)
173 rep++, i++;
174 __print_depot_stack(stack, buf, PAGE_SIZE, 2);
175 drm_printf(p, "Wakeref x%lu taken at:\n%s", rep, buf);
176 }
177
178 kfree(buf);
179}
180
181static noinline void
182untrack_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
183{
184 struct i915_runtime_pm *rpm = &i915->runtime_pm;
185 struct intel_runtime_pm_debug dbg = {};
186 struct drm_printer p;
187 unsigned long flags;
188
189 assert_rpm_wakelock_held(i915);
190 if (atomic_dec_and_lock_irqsave(&rpm->wakeref_count,
191 &rpm->debug.lock,
192 flags)) {
193 dbg = rpm->debug;
194
195 rpm->debug.owners = NULL;
196 rpm->debug.count = 0;
197 rpm->debug.last_release = __save_depot_stack();
198
199 spin_unlock_irqrestore(&rpm->debug.lock, flags);
200 }
201 if (!dbg.count)
202 return;
203
204 p = drm_debug_printer("i915");
205 __print_intel_runtime_pm_wakeref(&p, &dbg);
206
207 kfree(dbg.owners);
208}
209
210void print_intel_runtime_pm_wakeref(struct drm_i915_private *i915,
211 struct drm_printer *p)
212{
213 struct intel_runtime_pm_debug dbg = {};
214
215 do {
216 struct i915_runtime_pm *rpm = &i915->runtime_pm;
217 unsigned long alloc = dbg.count;
218 depot_stack_handle_t *s;
219
220 spin_lock_irq(&rpm->debug.lock);
221 dbg.count = rpm->debug.count;
222 if (dbg.count <= alloc) {
223 memcpy(dbg.owners,
224 rpm->debug.owners,
225 dbg.count * sizeof(*s));
226 }
227 dbg.last_acquire = rpm->debug.last_acquire;
228 dbg.last_release = rpm->debug.last_release;
229 spin_unlock_irq(&rpm->debug.lock);
230 if (dbg.count <= alloc)
231 break;
232
233 s = krealloc(dbg.owners, dbg.count * sizeof(*s), GFP_KERNEL);
234 if (!s)
235 goto out;
236
237 dbg.owners = s;
238 } while (1);
239
240 __print_intel_runtime_pm_wakeref(p, &dbg);
241
242out:
243 kfree(dbg.owners);
244}
245
246#else
247
248static void init_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
249{
250}
251
252static void track_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
253{
254 atomic_inc(&i915->runtime_pm.wakeref_count);
255 assert_rpm_wakelock_held(i915);
256}
257
258static void untrack_intel_runtime_pm_wakeref(struct drm_i915_private *i915)
259{
260 assert_rpm_wakelock_held(i915);
261 atomic_dec(&i915->runtime_pm.wakeref_count);
262}
263
264#endif
265
52bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, 266bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
53 enum i915_power_well_id power_well_id); 267 enum i915_power_well_id power_well_id);
54 268
@@ -3986,7 +4200,7 @@ static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv)
3986 4200
3987/** 4201/**
3988 * intel_runtime_pm_get - grab a runtime pm reference 4202 * intel_runtime_pm_get - grab a runtime pm reference
3989 * @dev_priv: i915 device instance 4203 * @i915: i915 device instance
3990 * 4204 *
3991 * This function grabs a device-level runtime pm reference (mostly used for GEM 4205 * This function grabs a device-level runtime pm reference (mostly used for GEM
3992 * code to ensure the GTT or GT is on) and ensures that it is powered up. 4206 * code to ensure the GTT or GT is on) and ensures that it is powered up.
@@ -3994,22 +4208,21 @@ static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv)
3994 * Any runtime pm reference obtained by this function must have a symmetric 4208 * Any runtime pm reference obtained by this function must have a symmetric
3995 * call to intel_runtime_pm_put() to release the reference again. 4209 * call to intel_runtime_pm_put() to release the reference again.
3996 */ 4210 */
3997void intel_runtime_pm_get(struct drm_i915_private *dev_priv) 4211void intel_runtime_pm_get(struct drm_i915_private *i915)
3998{ 4212{
3999 struct pci_dev *pdev = dev_priv->drm.pdev; 4213 struct pci_dev *pdev = i915->drm.pdev;
4000 struct device *kdev = &pdev->dev; 4214 struct device *kdev = &pdev->dev;
4001 int ret; 4215 int ret;
4002 4216
4003 ret = pm_runtime_get_sync(kdev); 4217 ret = pm_runtime_get_sync(kdev);
4004 WARN_ONCE(ret < 0, "pm_runtime_get_sync() failed: %d\n", ret); 4218 WARN_ONCE(ret < 0, "pm_runtime_get_sync() failed: %d\n", ret);
4005 4219
4006 atomic_inc(&dev_priv->runtime_pm.wakeref_count); 4220 track_intel_runtime_pm_wakeref(i915);
4007 assert_rpm_wakelock_held(dev_priv);
4008} 4221}
4009 4222
4010/** 4223/**
4011 * intel_runtime_pm_get_if_in_use - grab a runtime pm reference if device in use 4224 * intel_runtime_pm_get_if_in_use - grab a runtime pm reference if device in use
4012 * @dev_priv: i915 device instance 4225 * @i915: i915 device instance
4013 * 4226 *
4014 * This function grabs a device-level runtime pm reference if the device is 4227 * This function grabs a device-level runtime pm reference if the device is
4015 * already in use and ensures that it is powered up. It is illegal to try 4228 * already in use and ensures that it is powered up. It is illegal to try
@@ -4020,10 +4233,10 @@ void intel_runtime_pm_get(struct drm_i915_private *dev_priv)
4020 * 4233 *
4021 * Returns: True if the wakeref was acquired, or False otherwise. 4234 * Returns: True if the wakeref was acquired, or False otherwise.
4022 */ 4235 */
4023bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv) 4236bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *i915)
4024{ 4237{
4025 if (IS_ENABLED(CONFIG_PM)) { 4238 if (IS_ENABLED(CONFIG_PM)) {
4026 struct pci_dev *pdev = dev_priv->drm.pdev; 4239 struct pci_dev *pdev = i915->drm.pdev;
4027 struct device *kdev = &pdev->dev; 4240 struct device *kdev = &pdev->dev;
4028 4241
4029 /* 4242 /*
@@ -4036,15 +4249,14 @@ bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv)
4036 return false; 4249 return false;
4037 } 4250 }
4038 4251
4039 atomic_inc(&dev_priv->runtime_pm.wakeref_count); 4252 track_intel_runtime_pm_wakeref(i915);
4040 assert_rpm_wakelock_held(dev_priv);
4041 4253
4042 return true; 4254 return true;
4043} 4255}
4044 4256
4045/** 4257/**
4046 * intel_runtime_pm_get_noresume - grab a runtime pm reference 4258 * intel_runtime_pm_get_noresume - grab a runtime pm reference
4047 * @dev_priv: i915 device instance 4259 * @i915: i915 device instance
4048 * 4260 *
4049 * This function grabs a device-level runtime pm reference (mostly used for GEM 4261 * This function grabs a device-level runtime pm reference (mostly used for GEM
4050 * code to ensure the GTT or GT is on). 4262 * code to ensure the GTT or GT is on).
@@ -4059,32 +4271,31 @@ bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv)
4059 * Any runtime pm reference obtained by this function must have a symmetric 4271 * Any runtime pm reference obtained by this function must have a symmetric
4060 * call to intel_runtime_pm_put() to release the reference again. 4272 * call to intel_runtime_pm_put() to release the reference again.
4061 */ 4273 */
4062void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv) 4274void intel_runtime_pm_get_noresume(struct drm_i915_private *i915)
4063{ 4275{
4064 struct pci_dev *pdev = dev_priv->drm.pdev; 4276 struct pci_dev *pdev = i915->drm.pdev;
4065 struct device *kdev = &pdev->dev; 4277 struct device *kdev = &pdev->dev;
4066 4278
4067 assert_rpm_wakelock_held(dev_priv); 4279 assert_rpm_wakelock_held(i915);
4068 pm_runtime_get_noresume(kdev); 4280 pm_runtime_get_noresume(kdev);
4069 4281
4070 atomic_inc(&dev_priv->runtime_pm.wakeref_count); 4282 track_intel_runtime_pm_wakeref(i915);
4071} 4283}
4072 4284
4073/** 4285/**
4074 * intel_runtime_pm_put - release a runtime pm reference 4286 * intel_runtime_pm_put - release a runtime pm reference
4075 * @dev_priv: i915 device instance 4287 * @i915: i915 device instance
4076 * 4288 *
4077 * This function drops the device-level runtime pm reference obtained by 4289 * This function drops the device-level runtime pm reference obtained by
4078 * intel_runtime_pm_get() and might power down the corresponding 4290 * intel_runtime_pm_get() and might power down the corresponding
4079 * hardware block right away if this is the last reference. 4291 * hardware block right away if this is the last reference.
4080 */ 4292 */
4081void intel_runtime_pm_put(struct drm_i915_private *dev_priv) 4293void intel_runtime_pm_put(struct drm_i915_private *i915)
4082{ 4294{
4083 struct pci_dev *pdev = dev_priv->drm.pdev; 4295 struct pci_dev *pdev = i915->drm.pdev;
4084 struct device *kdev = &pdev->dev; 4296 struct device *kdev = &pdev->dev;
4085 4297
4086 assert_rpm_wakelock_held(dev_priv); 4298 untrack_intel_runtime_pm_wakeref(i915);
4087 atomic_dec(&dev_priv->runtime_pm.wakeref_count);
4088 4299
4089 pm_runtime_mark_last_busy(kdev); 4300 pm_runtime_mark_last_busy(kdev);
4090 pm_runtime_put_autosuspend(kdev); 4301 pm_runtime_put_autosuspend(kdev);
@@ -4092,7 +4303,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv)
4092 4303
4093/** 4304/**
4094 * intel_runtime_pm_enable - enable runtime pm 4305 * intel_runtime_pm_enable - enable runtime pm
4095 * @dev_priv: i915 device instance 4306 * @i915: i915 device instance
4096 * 4307 *
4097 * This function enables runtime pm at the end of the driver load sequence. 4308 * This function enables runtime pm at the end of the driver load sequence.
4098 * 4309 *
@@ -4100,9 +4311,9 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv)
4100 * subordinate display power domains. That is done by 4311 * subordinate display power domains. That is done by
4101 * intel_power_domains_enable(). 4312 * intel_power_domains_enable().
4102 */ 4313 */
4103void intel_runtime_pm_enable(struct drm_i915_private *dev_priv) 4314void intel_runtime_pm_enable(struct drm_i915_private *i915)
4104{ 4315{
4105 struct pci_dev *pdev = dev_priv->drm.pdev; 4316 struct pci_dev *pdev = i915->drm.pdev;
4106 struct device *kdev = &pdev->dev; 4317 struct device *kdev = &pdev->dev;
4107 4318
4108 /* 4319 /*
@@ -4124,7 +4335,7 @@ void intel_runtime_pm_enable(struct drm_i915_private *dev_priv)
4124 * so the driver's own RPM reference tracking asserts also work on 4335 * so the driver's own RPM reference tracking asserts also work on
4125 * platforms without RPM support. 4336 * platforms without RPM support.
4126 */ 4337 */
4127 if (!HAS_RUNTIME_PM(dev_priv)) { 4338 if (!HAS_RUNTIME_PM(i915)) {
4128 int ret; 4339 int ret;
4129 4340
4130 pm_runtime_dont_use_autosuspend(kdev); 4341 pm_runtime_dont_use_autosuspend(kdev);
@@ -4142,17 +4353,35 @@ void intel_runtime_pm_enable(struct drm_i915_private *dev_priv)
4142 pm_runtime_put_autosuspend(kdev); 4353 pm_runtime_put_autosuspend(kdev);
4143} 4354}
4144 4355
4145void intel_runtime_pm_disable(struct drm_i915_private *dev_priv) 4356void intel_runtime_pm_disable(struct drm_i915_private *i915)
4146{ 4357{
4147 struct pci_dev *pdev = dev_priv->drm.pdev; 4358 struct pci_dev *pdev = i915->drm.pdev;
4148 struct device *kdev = &pdev->dev; 4359 struct device *kdev = &pdev->dev;
4149 4360
4150 /* Transfer rpm ownership back to core */ 4361 /* Transfer rpm ownership back to core */
4151 WARN(pm_runtime_get_sync(&dev_priv->drm.pdev->dev) < 0, 4362 WARN(pm_runtime_get_sync(kdev) < 0,
4152 "Failed to pass rpm ownership back to core\n"); 4363 "Failed to pass rpm ownership back to core\n");
4153 4364
4154 pm_runtime_dont_use_autosuspend(kdev); 4365 pm_runtime_dont_use_autosuspend(kdev);
4155 4366
4156 if (!HAS_RUNTIME_PM(dev_priv)) 4367 if (!HAS_RUNTIME_PM(i915))
4157 pm_runtime_put(kdev); 4368 pm_runtime_put(kdev);
4158} 4369}
4370
4371void intel_runtime_pm_cleanup(struct drm_i915_private *i915)
4372{
4373 struct i915_runtime_pm *rpm = &i915->runtime_pm;
4374 int count;
4375
4376 count = atomic_fetch_inc(&rpm->wakeref_count); /* balance untrack */
4377 WARN(count,
4378 "i915->runtime_pm.wakeref_count=%d on cleanup\n",
4379 count);
4380
4381 untrack_intel_runtime_pm_wakeref(i915);
4382}
4383
4384void intel_runtime_pm_init_early(struct drm_i915_private *i915)
4385{
4386 init_intel_runtime_pm_wakeref(i915);
4387}
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index baa3c38919de..082809569681 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -154,15 +154,17 @@ struct drm_i915_private *mock_gem_device(void)
154 pdev->dev.archdata.iommu = (void *)-1; 154 pdev->dev.archdata.iommu = (void *)-1;
155#endif 155#endif
156 156
157 i915 = (struct drm_i915_private *)(pdev + 1);
158 pci_set_drvdata(pdev, i915);
159
160 intel_runtime_pm_init_early(i915);
161
157 dev_pm_domain_set(&pdev->dev, &pm_domain); 162 dev_pm_domain_set(&pdev->dev, &pm_domain);
158 pm_runtime_enable(&pdev->dev); 163 pm_runtime_enable(&pdev->dev);
159 pm_runtime_dont_use_autosuspend(&pdev->dev); 164 pm_runtime_dont_use_autosuspend(&pdev->dev);
160 if (pm_runtime_enabled(&pdev->dev)) 165 if (pm_runtime_enabled(&pdev->dev))
161 WARN_ON(pm_runtime_get_sync(&pdev->dev)); 166 WARN_ON(pm_runtime_get_sync(&pdev->dev));
162 167
163 i915 = (struct drm_i915_private *)(pdev + 1);
164 pci_set_drvdata(pdev, i915);
165
166 err = drm_dev_init(&i915->drm, &mock_driver, &pdev->dev); 168 err = drm_dev_init(&i915->drm, &mock_driver, &pdev->dev);
167 if (err) { 169 if (err) {
168 pr_err("Failed to initialise mock GEM device: err=%d\n", err); 170 pr_err("Failed to initialise mock GEM device: err=%d\n", err);