2 * Copyright © 2016 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 #include <linux/pm_domain.h>
26 #include <linux/pm_runtime.h>
28 #include "mock_engine.h"
29 #include "mock_context.h"
30 #include "mock_request.h"
31 #include "mock_gem_device.h"
32 #include "mock_gem_object.h"
34 #include "mock_uncore.h"
36 void mock_device_flush(struct drm_i915_private
*i915
)
38 struct intel_engine_cs
*engine
;
39 enum intel_engine_id id
;
41 lockdep_assert_held(&i915
->drm
.struct_mutex
);
43 for_each_engine(engine
, i915
, id
)
44 mock_engine_flush(engine
);
46 i915_gem_retire_requests(i915
);
49 static void mock_device_release(struct drm_device
*dev
)
51 struct drm_i915_private
*i915
= to_i915(dev
);
52 struct intel_engine_cs
*engine
;
53 enum intel_engine_id id
;
55 mutex_lock(&i915
->drm
.struct_mutex
);
56 mock_device_flush(i915
);
57 i915_gem_contexts_lost(i915
);
58 mutex_unlock(&i915
->drm
.struct_mutex
);
60 cancel_delayed_work_sync(&i915
->gt
.retire_work
);
61 cancel_delayed_work_sync(&i915
->gt
.idle_work
);
62 i915_gem_drain_workqueue(i915
);
64 mutex_lock(&i915
->drm
.struct_mutex
);
65 for_each_engine(engine
, i915
, id
)
66 mock_engine_free(engine
);
67 i915_gem_contexts_fini(i915
);
68 mutex_unlock(&i915
->drm
.struct_mutex
);
70 drain_workqueue(i915
->wq
);
71 i915_gem_drain_freed_objects(i915
);
73 mutex_lock(&i915
->drm
.struct_mutex
);
75 i915_gem_timeline_fini(&i915
->gt
.global_timeline
);
76 mutex_unlock(&i915
->drm
.struct_mutex
);
78 destroy_workqueue(i915
->wq
);
80 kmem_cache_destroy(i915
->priorities
);
81 kmem_cache_destroy(i915
->dependencies
);
82 kmem_cache_destroy(i915
->requests
);
83 kmem_cache_destroy(i915
->vmas
);
84 kmem_cache_destroy(i915
->objects
);
86 i915_gemfs_fini(i915
);
88 drm_mode_config_cleanup(&i915
->drm
);
90 drm_dev_fini(&i915
->drm
);
91 put_device(&i915
->drm
.pdev
->dev
);
94 static struct drm_driver mock_driver
= {
96 .driver_features
= DRIVER_GEM
,
97 .release
= mock_device_release
,
99 .gem_close_object
= i915_gem_close_object
,
100 .gem_free_object_unlocked
= i915_gem_free_object
,
103 static void release_dev(struct device
*dev
)
105 struct pci_dev
*pdev
= to_pci_dev(dev
);
110 static void mock_retire_work_handler(struct work_struct
*work
)
114 static void mock_idle_work_handler(struct work_struct
*work
)
118 static int pm_domain_resume(struct device
*dev
)
120 return pm_generic_runtime_resume(dev
);
123 static int pm_domain_suspend(struct device
*dev
)
125 return pm_generic_runtime_suspend(dev
);
128 static struct dev_pm_domain pm_domain
= {
130 .runtime_suspend
= pm_domain_suspend
,
131 .runtime_resume
= pm_domain_resume
,
135 struct drm_i915_private
*mock_gem_device(void)
137 struct drm_i915_private
*i915
;
138 struct intel_engine_cs
*engine
;
139 enum intel_engine_id id
;
140 struct pci_dev
*pdev
;
143 pdev
= kzalloc(sizeof(*pdev
) + sizeof(*i915
), GFP_KERNEL
);
147 device_initialize(&pdev
->dev
);
148 pdev
->class = PCI_BASE_CLASS_DISPLAY
<< 16;
149 pdev
->dev
.release
= release_dev
;
150 dev_set_name(&pdev
->dev
, "mock");
151 dma_coerce_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(32));
153 #if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU)
154 /* hack to disable iommu for the fake device; force identity mapping */
155 pdev
->dev
.archdata
.iommu
= (void *)-1;
158 dev_pm_domain_set(&pdev
->dev
, &pm_domain
);
159 pm_runtime_enable(&pdev
->dev
);
160 pm_runtime_dont_use_autosuspend(&pdev
->dev
);
161 WARN_ON(pm_runtime_get_sync(&pdev
->dev
));
163 i915
= (struct drm_i915_private
*)(pdev
+ 1);
164 pci_set_drvdata(pdev
, i915
);
166 err
= drm_dev_init(&i915
->drm
, &mock_driver
, &pdev
->dev
);
168 pr_err("Failed to initialise mock GEM device: err=%d\n", err
);
171 i915
->drm
.pdev
= pdev
;
172 i915
->drm
.dev_private
= i915
;
174 /* Using the global GTT may ask questions about KMS users, so prepare */
175 drm_mode_config_init(&i915
->drm
);
177 mkwrite_device_info(i915
)->gen
= -1;
179 mkwrite_device_info(i915
)->page_sizes
=
180 I915_GTT_PAGE_SIZE_4K
|
181 I915_GTT_PAGE_SIZE_64K
|
182 I915_GTT_PAGE_SIZE_2M
;
184 mock_uncore_init(i915
);
185 i915_gem_init__mm(i915
);
187 init_waitqueue_head(&i915
->gpu_error
.wait_queue
);
188 init_waitqueue_head(&i915
->gpu_error
.reset_queue
);
190 i915
->wq
= alloc_ordered_workqueue("mock", 0);
194 mock_init_contexts(i915
);
196 INIT_DELAYED_WORK(&i915
->gt
.retire_work
, mock_retire_work_handler
);
197 INIT_DELAYED_WORK(&i915
->gt
.idle_work
, mock_idle_work_handler
);
199 i915
->gt
.awake
= true;
201 i915
->objects
= KMEM_CACHE(mock_object
, SLAB_HWCACHE_ALIGN
);
205 i915
->vmas
= KMEM_CACHE(i915_vma
, SLAB_HWCACHE_ALIGN
);
209 i915
->requests
= KMEM_CACHE(mock_request
,
211 SLAB_RECLAIM_ACCOUNT
|
212 SLAB_TYPESAFE_BY_RCU
);
216 i915
->dependencies
= KMEM_CACHE(i915_dependency
,
218 SLAB_RECLAIM_ACCOUNT
);
219 if (!i915
->dependencies
)
222 i915
->priorities
= KMEM_CACHE(i915_priolist
, SLAB_HWCACHE_ALIGN
);
223 if (!i915
->priorities
)
224 goto err_dependencies
;
226 mutex_lock(&i915
->drm
.struct_mutex
);
227 INIT_LIST_HEAD(&i915
->gt
.timelines
);
228 err
= i915_gem_timeline_init__global(i915
);
230 mutex_unlock(&i915
->drm
.struct_mutex
);
234 mock_init_ggtt(i915
);
235 mutex_unlock(&i915
->drm
.struct_mutex
);
237 mkwrite_device_info(i915
)->ring_mask
= BIT(0);
238 i915
->engine
[RCS
] = mock_engine(i915
, "mock", RCS
);
239 if (!i915
->engine
[RCS
])
242 i915
->kernel_context
= mock_context(i915
, NULL
);
243 if (!i915
->kernel_context
)
246 i915
->preempt_context
= mock_context(i915
, NULL
);
247 if (!i915
->preempt_context
)
248 goto err_kernel_context
;
250 WARN_ON(i915_gemfs_init(i915
));
255 i915_gem_context_put(i915
->kernel_context
);
257 for_each_engine(engine
, i915
, id
)
258 mock_engine_free(engine
);
260 kmem_cache_destroy(i915
->priorities
);
262 kmem_cache_destroy(i915
->dependencies
);
264 kmem_cache_destroy(i915
->requests
);
266 kmem_cache_destroy(i915
->vmas
);
268 kmem_cache_destroy(i915
->objects
);
270 destroy_workqueue(i915
->wq
);
272 drm_mode_config_cleanup(&i915
->drm
);
273 drm_dev_fini(&i915
->drm
);
275 put_device(&pdev
->dev
);