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 "gt/intel_gt.h"
29 #include "gt/intel_gt_requests.h"
30 #include "gt/mock_engine.h"
31 #include "intel_memory_region.h"
33 #include "mock_request.h"
34 #include "mock_gem_device.h"
36 #include "mock_uncore.h"
37 #include "mock_region.h"
39 #include "gem/selftests/mock_context.h"
40 #include "gem/selftests/mock_gem_object.h"
42 void mock_device_flush(struct drm_i915_private
*i915
)
44 struct intel_gt
*gt
= &i915
->gt
;
45 struct intel_engine_cs
*engine
;
46 enum intel_engine_id id
;
49 for_each_engine(engine
, gt
, id
)
50 mock_engine_flush(engine
);
51 } while (intel_gt_retire_requests_timeout(gt
, MAX_SCHEDULE_TIMEOUT
));
54 static void mock_device_release(struct drm_device
*dev
)
56 struct drm_i915_private
*i915
= to_i915(dev
);
58 mock_device_flush(i915
);
59 intel_gt_driver_remove(&i915
->gt
);
61 i915_gem_driver_release__contexts(i915
);
63 i915_gem_drain_workqueue(i915
);
64 i915_gem_drain_freed_objects(i915
);
66 mock_fini_ggtt(&i915
->ggtt
);
67 destroy_workqueue(i915
->wq
);
69 intel_gt_driver_late_release(&i915
->gt
);
70 intel_memory_regions_driver_release(i915
);
72 drm_mode_config_cleanup(&i915
->drm
);
74 drm_dev_fini(&i915
->drm
);
75 put_device(&i915
->drm
.pdev
->dev
);
78 static struct drm_driver mock_driver
= {
80 .driver_features
= DRIVER_GEM
,
81 .release
= mock_device_release
,
83 .gem_close_object
= i915_gem_close_object
,
84 .gem_free_object_unlocked
= i915_gem_free_object
,
87 static void release_dev(struct device
*dev
)
89 struct pci_dev
*pdev
= to_pci_dev(dev
);
94 static int pm_domain_resume(struct device
*dev
)
96 return pm_generic_runtime_resume(dev
);
99 static int pm_domain_suspend(struct device
*dev
)
101 return pm_generic_runtime_suspend(dev
);
104 static struct dev_pm_domain pm_domain
= {
106 .runtime_suspend
= pm_domain_suspend
,
107 .runtime_resume
= pm_domain_resume
,
111 struct drm_i915_private
*mock_gem_device(void)
113 struct drm_i915_private
*i915
;
114 struct pci_dev
*pdev
;
117 pdev
= kzalloc(sizeof(*pdev
) + sizeof(*i915
), GFP_KERNEL
);
121 device_initialize(&pdev
->dev
);
122 pdev
->class = PCI_BASE_CLASS_DISPLAY
<< 16;
123 pdev
->dev
.release
= release_dev
;
124 dev_set_name(&pdev
->dev
, "mock");
125 dma_coerce_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(64));
127 #if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU)
128 /* hack to disable iommu for the fake device; force identity mapping */
129 pdev
->dev
.archdata
.iommu
= (void *)-1;
132 i915
= (struct drm_i915_private
*)(pdev
+ 1);
133 pci_set_drvdata(pdev
, i915
);
135 dev_pm_domain_set(&pdev
->dev
, &pm_domain
);
136 pm_runtime_enable(&pdev
->dev
);
137 pm_runtime_dont_use_autosuspend(&pdev
->dev
);
138 if (pm_runtime_enabled(&pdev
->dev
))
139 WARN_ON(pm_runtime_get_sync(&pdev
->dev
));
141 err
= drm_dev_init(&i915
->drm
, &mock_driver
, &pdev
->dev
);
143 pr_err("Failed to initialise mock GEM device: err=%d\n", err
);
146 i915
->drm
.pdev
= pdev
;
147 i915
->drm
.dev_private
= i915
;
149 intel_runtime_pm_init_early(&i915
->runtime_pm
);
151 /* Using the global GTT may ask questions about KMS users, so prepare */
152 drm_mode_config_init(&i915
->drm
);
154 mkwrite_device_info(i915
)->gen
= -1;
156 mkwrite_device_info(i915
)->page_sizes
=
157 I915_GTT_PAGE_SIZE_4K
|
158 I915_GTT_PAGE_SIZE_64K
|
159 I915_GTT_PAGE_SIZE_2M
;
161 mkwrite_device_info(i915
)->memory_regions
= REGION_SMEM
;
162 intel_memory_regions_hw_probe(i915
);
164 mock_uncore_init(&i915
->uncore
, i915
);
166 i915_gem_init__mm(i915
);
167 intel_gt_init_early(&i915
->gt
, i915
);
168 atomic_inc(&i915
->gt
.wakeref
.count
); /* disable; no hw support */
169 i915
->gt
.awake
= -ENODEV
;
171 i915
->wq
= alloc_ordered_workqueue("mock", 0);
175 mock_init_contexts(i915
);
177 mock_init_ggtt(i915
, &i915
->ggtt
);
178 i915
->gt
.vm
= i915_vm_get(&i915
->ggtt
.vm
);
180 mkwrite_device_info(i915
)->engine_mask
= BIT(0);
182 i915
->engine
[RCS0
] = mock_engine(i915
, "mock", RCS0
);
183 if (!i915
->engine
[RCS0
])
186 if (mock_engine_init(i915
->engine
[RCS0
]))
189 __clear_bit(I915_WEDGED
, &i915
->gt
.reset
.flags
);
190 intel_engines_driver_register(i915
);
195 intel_gt_driver_remove(&i915
->gt
);
197 destroy_workqueue(i915
->wq
);
199 intel_gt_driver_late_release(&i915
->gt
);
200 intel_memory_regions_driver_release(i915
);
201 drm_mode_config_cleanup(&i915
->drm
);
202 drm_dev_fini(&i915
->drm
);
204 put_device(&pdev
->dev
);