xref: /linux/drivers/gpu/drm/i915/gem/i915_gem_lmem.c (revision 2c1ed907520c50326b8f604907a8478b27881a2e)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2019 Intel Corporation
4  */
5 
6 #include <uapi/drm/i915_drm.h>
7 
8 #include "intel_memory_region.h"
9 #include "gem/i915_gem_region.h"
10 #include "gem/i915_gem_lmem.h"
11 #include "i915_drv.h"
12 
13 void __iomem *
i915_gem_object_lmem_io_map(struct drm_i915_gem_object * obj,unsigned long n,unsigned long size)14 i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
15 			    unsigned long n,
16 			    unsigned long size)
17 {
18 	resource_size_t offset;
19 
20 	GEM_BUG_ON(!i915_gem_object_is_contiguous(obj));
21 
22 	offset = i915_gem_object_get_dma_address(obj, n);
23 	offset -= obj->mm.region->region.start;
24 
25 	return io_mapping_map_wc(&obj->mm.region->iomap, offset, size);
26 }
27 
28 /**
29  * i915_gem_object_is_lmem - Whether the object is resident in
30  * lmem
31  * @obj: The object to check.
32  *
33  * Even if an object is allowed to migrate and change memory region,
34  * this function checks whether it will always be present in lmem when
35  * valid *or* if that's not the case, whether it's currently resident in lmem.
36  * For migratable and evictable objects, the latter only makes sense when
37  * the object is locked.
38  *
39  * Return: Whether the object migratable but resident in lmem, or not
40  * migratable and will be present in lmem when valid.
41  */
i915_gem_object_is_lmem(struct drm_i915_gem_object * obj)42 bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj)
43 {
44 	struct intel_memory_region *mr = READ_ONCE(obj->mm.region);
45 
46 #ifdef CONFIG_LOCKDEP
47 	if (i915_gem_object_migratable(obj) &&
48 	    i915_gem_object_evictable(obj))
49 		assert_object_held(obj);
50 #endif
51 	return mr && (mr->type == INTEL_MEMORY_LOCAL ||
52 		      mr->type == INTEL_MEMORY_STOLEN_LOCAL);
53 }
54 
55 /**
56  * __i915_gem_object_create_lmem_with_ps - Create lmem object and force the
57  * minimum page size for the backing pages.
58  * @i915: The i915 instance.
59  * @size: The size in bytes for the object. Note that we need to round the size
60  * up depending on the @page_size. The final object size can be fished out from
61  * the drm GEM object.
62  * @page_size: The requested minimum page size in bytes for this object. This is
63  * useful if we need something bigger than the regions min_page_size due to some
64  * hw restriction, or in some very specialised cases where it needs to be
65  * smaller, where the internal fragmentation cost is too great when rounding up
66  * the object size.
67  * @flags: The optional BO allocation flags.
68  *
69  * Note that this interface assumes you know what you are doing when forcing the
70  * @page_size. If this is smaller than the regions min_page_size then it can
71  * never be inserted into any GTT, otherwise it might lead to undefined
72  * behaviour.
73  *
74  * Return: The object pointer, which might be an ERR_PTR in the case of failure.
75  */
76 struct drm_i915_gem_object *
__i915_gem_object_create_lmem_with_ps(struct drm_i915_private * i915,resource_size_t size,resource_size_t page_size,unsigned int flags)77 __i915_gem_object_create_lmem_with_ps(struct drm_i915_private *i915,
78 				      resource_size_t size,
79 				      resource_size_t page_size,
80 				      unsigned int flags)
81 {
82 	return i915_gem_object_create_region(i915->mm.regions[INTEL_REGION_LMEM_0],
83 					     size, page_size, flags);
84 }
85 
86 struct drm_i915_gem_object *
i915_gem_object_create_lmem_from_data(struct drm_i915_private * i915,const void * data,size_t size)87 i915_gem_object_create_lmem_from_data(struct drm_i915_private *i915,
88 				      const void *data, size_t size)
89 {
90 	struct drm_i915_gem_object *obj;
91 	void *map;
92 
93 	obj = i915_gem_object_create_lmem(i915,
94 					  round_up(size, PAGE_SIZE),
95 					  I915_BO_ALLOC_CONTIGUOUS);
96 	if (IS_ERR(obj))
97 		return obj;
98 
99 	map = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
100 	if (IS_ERR(map)) {
101 		i915_gem_object_put(obj);
102 		return map;
103 	}
104 
105 	memcpy(map, data, size);
106 
107 	i915_gem_object_flush_map(obj);
108 	__i915_gem_object_release_map(obj);
109 
110 	return obj;
111 }
112 
113 struct drm_i915_gem_object *
i915_gem_object_create_lmem(struct drm_i915_private * i915,resource_size_t size,unsigned int flags)114 i915_gem_object_create_lmem(struct drm_i915_private *i915,
115 			    resource_size_t size,
116 			    unsigned int flags)
117 {
118 	return i915_gem_object_create_region(i915->mm.regions[INTEL_REGION_LMEM_0],
119 					     size, 0, flags);
120 }
121