1
2
3
4
5
6
7#include "gem/i915_gem_pm.h"
8#include "gt/intel_gt.h"
9#include "gt/intel_gt_pm.h"
10#include "gt/intel_gt_requests.h"
11
12#include "i915_drv.h"
13
14#if defined(CONFIG_X86)
15#include <asm/smp.h>
16#else
17#define wbinvd_on_all_cpus() \
18 pr_warn(DRIVER_NAME ": Missing cache flush in %s\n", __func__)
19#endif
20
21void i915_gem_suspend(struct drm_i915_private *i915)
22{
23 GEM_TRACE("%s\n", dev_name(i915->drm.dev));
24
25 intel_wakeref_auto(&i915->ggtt.userfault_wakeref, 0);
26 flush_workqueue(i915->wq);
27
28
29
30
31
32
33
34
35
36
37 intel_gt_suspend_prepare(&i915->gt);
38
39 i915_gem_drain_freed_objects(i915);
40}
41
42void i915_gem_suspend_late(struct drm_i915_private *i915)
43{
44 struct drm_i915_gem_object *obj;
45 struct list_head *phases[] = {
46 &i915->mm.shrink_list,
47 &i915->mm.purge_list,
48 NULL
49 }, **phase;
50 unsigned long flags;
51 bool flush = false;
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 intel_gt_suspend_late(&i915->gt);
74
75 spin_lock_irqsave(&i915->mm.obj_lock, flags);
76 for (phase = phases; *phase; phase++) {
77 list_for_each_entry(obj, *phase, mm.link) {
78 if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ))
79 flush |= (obj->read_domains & I915_GEM_DOMAIN_CPU) == 0;
80 __start_cpu_write(obj);
81 }
82 }
83 spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
84 if (flush)
85 wbinvd_on_all_cpus();
86}
87
88int i915_gem_freeze(struct drm_i915_private *i915)
89{
90
91
92
93 i915_gem_shrink_all(i915);
94
95 return 0;
96}
97
98int i915_gem_freeze_late(struct drm_i915_private *i915)
99{
100 struct drm_i915_gem_object *obj;
101 intel_wakeref_t wakeref;
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118 with_intel_runtime_pm(&i915->runtime_pm, wakeref)
119 i915_gem_shrink(NULL, i915, -1UL, NULL, ~0);
120 i915_gem_drain_freed_objects(i915);
121
122 wbinvd_on_all_cpus();
123 list_for_each_entry(obj, &i915->mm.shrink_list, mm.link)
124 __start_cpu_write(obj);
125
126 return 0;
127}
128
129void i915_gem_resume(struct drm_i915_private *i915)
130{
131 GEM_TRACE("%s\n", dev_name(i915->drm.dev));
132
133
134
135
136
137
138 intel_gt_resume(&i915->gt);
139}
140