Commit | Line | Data |
---|---|---|
232a6eba MA |
1 | // SPDX-License-Identifier: MIT |
2 | /* | |
d1487389 | 3 | * Copyright © 2019-2021 Intel Corporation |
232a6eba MA |
4 | */ |
5 | ||
d53ec322 | 6 | #include <drm/ttm/ttm_placement.h> |
d1487389 TH |
7 | #include <linux/scatterlist.h> |
8 | ||
232a6eba MA |
9 | #include "gem/i915_gem_region.h" |
10 | #include "intel_memory_region.h" | |
d1487389 | 11 | #include "intel_region_ttm.h" |
232a6eba MA |
12 | |
13 | #include "mock_region.h" | |
14 | ||
d1487389 TH |
15 | static void mock_region_put_pages(struct drm_i915_gem_object *obj, |
16 | struct sg_table *pages) | |
17 | { | |
cad7109a TH |
18 | i915_refct_sgt_put(obj->mm.rsgt); |
19 | obj->mm.rsgt = NULL; | |
687c7d0f | 20 | intel_region_ttm_resource_free(obj->mm.region, obj->mm.res); |
d1487389 TH |
21 | } |
22 | ||
23 | static int mock_region_get_pages(struct drm_i915_gem_object *obj) | |
24 | { | |
d1487389 | 25 | struct sg_table *pages; |
d53ec322 | 26 | int err; |
d1487389 | 27 | |
687c7d0f | 28 | obj->mm.res = intel_region_ttm_resource_alloc(obj->mm.region, |
ecbf2060 | 29 | obj->bo_offset, |
687c7d0f | 30 | obj->base.size, |
30b9d1b3 | 31 | obj->flags); |
687c7d0f MA |
32 | if (IS_ERR(obj->mm.res)) |
33 | return PTR_ERR(obj->mm.res); | |
d1487389 | 34 | |
cad7109a | 35 | obj->mm.rsgt = intel_region_ttm_resource_to_rsgt(obj->mm.region, |
bc99f120 MA |
36 | obj->mm.res, |
37 | obj->mm.region->min_page_size); | |
cad7109a TH |
38 | if (IS_ERR(obj->mm.rsgt)) { |
39 | err = PTR_ERR(obj->mm.rsgt); | |
d53ec322 | 40 | goto err_free_resource; |
d1487389 TH |
41 | } |
42 | ||
cad7109a | 43 | pages = &obj->mm.rsgt->table; |
8c949515 | 44 | __i915_gem_object_set_pages(obj, pages); |
d1487389 TH |
45 | |
46 | return 0; | |
d53ec322 MA |
47 | |
48 | err_free_resource: | |
49 | intel_region_ttm_resource_free(obj->mm.region, obj->mm.res); | |
50 | return err; | |
d1487389 TH |
51 | } |
52 | ||
232a6eba | 53 | static const struct drm_i915_gem_object_ops mock_region_obj_ops = { |
7d192daa | 54 | .name = "mock-region", |
d1487389 TH |
55 | .get_pages = mock_region_get_pages, |
56 | .put_pages = mock_region_put_pages, | |
232a6eba MA |
57 | .release = i915_gem_object_release_memory_region, |
58 | }; | |
59 | ||
97d55396 MA |
60 | static int mock_object_init(struct intel_memory_region *mem, |
61 | struct drm_i915_gem_object *obj, | |
9b78b5da | 62 | resource_size_t offset, |
97d55396 | 63 | resource_size_t size, |
d22632c8 | 64 | resource_size_t page_size, |
97d55396 | 65 | unsigned int flags) |
232a6eba | 66 | { |
7867d709 | 67 | static struct lock_class_key lock_class; |
232a6eba | 68 | struct drm_i915_private *i915 = mem->i915; |
232a6eba | 69 | |
d1487389 | 70 | if (size > resource_size(&mem->region)) |
97d55396 | 71 | return -E2BIG; |
232a6eba MA |
72 | |
73 | drm_gem_private_object_init(&i915->drm, &obj->base, size); | |
c471748d | 74 | i915_gem_object_init(obj, &mock_region_obj_ops, &lock_class, flags); |
232a6eba | 75 | |
ecbf2060 MA |
76 | obj->bo_offset = offset; |
77 | ||
232a6eba MA |
78 | obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT; |
79 | ||
80 | i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE); | |
81 | ||
c471748d | 82 | i915_gem_object_init_memory_region(obj, mem); |
232a6eba | 83 | |
97d55396 | 84 | return 0; |
232a6eba MA |
85 | } |
86 | ||
8b1f7f92 | 87 | static int mock_region_fini(struct intel_memory_region *mem) |
d1487389 TH |
88 | { |
89 | struct drm_i915_private *i915 = mem->i915; | |
90 | int instance = mem->instance; | |
8b1f7f92 | 91 | int ret; |
d1487389 | 92 | |
8b1f7f92 | 93 | ret = intel_region_ttm_fini(mem); |
d1487389 | 94 | ida_free(&i915->selftest.mock_region_instances, instance); |
8b1f7f92 TH |
95 | |
96 | return ret; | |
d1487389 TH |
97 | } |
98 | ||
232a6eba | 99 | static const struct intel_memory_region_ops mock_region_ops = { |
d1487389 TH |
100 | .init = intel_region_ttm_init, |
101 | .release = mock_region_fini, | |
97d55396 | 102 | .init_object = mock_object_init, |
232a6eba MA |
103 | }; |
104 | ||
105 | struct intel_memory_region * | |
106 | mock_region_create(struct drm_i915_private *i915, | |
107 | resource_size_t start, | |
108 | resource_size_t size, | |
109 | resource_size_t min_page_size, | |
235582ca MA |
110 | resource_size_t io_start, |
111 | resource_size_t io_size) | |
232a6eba | 112 | { |
d1487389 TH |
113 | int instance = ida_alloc_max(&i915->selftest.mock_region_instances, |
114 | TTM_NUM_MEM_TYPES - TTM_PL_PRIV - 1, | |
115 | GFP_KERNEL); | |
116 | ||
117 | if (instance < 0) | |
118 | return ERR_PTR(instance); | |
119 | ||
232a6eba | 120 | return intel_memory_region_create(i915, start, size, min_page_size, |
235582ca MA |
121 | io_start, io_size, |
122 | INTEL_MEMORY_MOCK, instance, | |
d1487389 | 123 | &mock_region_ops); |
232a6eba | 124 | } |