xref: /linux/drivers/gpu/drm/drm_gem_ttm_helper.c (revision 815e260a18a3af4dab59025ee99a7156c0e8b5e0)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 #include <linux/export.h>
4 #include <linux/module.h>
5 
6 #include <drm/drm_gem_ttm_helper.h>
7 #include <drm/drm_print.h>
8 #include <drm/ttm/ttm_placement.h>
9 #include <drm/ttm/ttm_tt.h>
10 
11 /**
12  * DOC: overview
13  *
14  * This library provides helper functions for gem objects backed by
15  * ttm.
16  */
17 
18 /**
19  * drm_gem_ttm_print_info() - Print &ttm_buffer_object info for debugfs
20  * @p: DRM printer
21  * @indent: Tab indentation level
22  * @gem: GEM object
23  *
24  * This function can be used as &drm_gem_object_funcs.print_info
25  * callback.
26  */
27 void drm_gem_ttm_print_info(struct drm_printer *p, unsigned int indent,
28 			    const struct drm_gem_object *gem)
29 {
30 	static const char * const plname[] = {
31 		[ TTM_PL_SYSTEM ] = "system",
32 		[ TTM_PL_TT     ] = "tt",
33 		[ TTM_PL_VRAM   ] = "vram",
34 		[ TTM_PL_PRIV   ] = "priv",
35 
36 		[ 16 ]            = "cached",
37 		[ 17 ]            = "uncached",
38 		[ 18 ]            = "wc",
39 		[ 19 ]            = "contig",
40 
41 		[ 21 ]            = "pinned", /* NO_EVICT */
42 		[ 22 ]            = "topdown",
43 	};
44 	const struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
45 
46 	drm_printf_indent(p, indent, "placement=");
47 	drm_print_bits(p, bo->resource->placement, plname, ARRAY_SIZE(plname));
48 	drm_printf(p, "\n");
49 
50 	if (bo->resource->bus.is_iomem)
51 		drm_printf_indent(p, indent, "bus.offset=%lx\n",
52 				  (unsigned long)bo->resource->bus.offset);
53 }
54 EXPORT_SYMBOL(drm_gem_ttm_print_info);
55 
56 /**
57  * drm_gem_ttm_vmap() - vmap &ttm_buffer_object
58  * @gem: GEM object.
59  * @map: [out] returns the dma-buf mapping.
60  *
61  * Maps a GEM object with ttm_bo_vmap(). This function can be used as
62  * &drm_gem_object_funcs.vmap callback.
63  *
64  * Returns:
65  * 0 on success, or a negative errno code otherwise.
66  */
67 int drm_gem_ttm_vmap(struct drm_gem_object *gem,
68 		     struct iosys_map *map)
69 {
70 	struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
71 
72 	return ttm_bo_vmap(bo, map);
73 }
74 EXPORT_SYMBOL(drm_gem_ttm_vmap);
75 
76 /**
77  * drm_gem_ttm_vunmap() - vunmap &ttm_buffer_object
78  * @gem: GEM object.
79  * @map: dma-buf mapping.
80  *
81  * Unmaps a GEM object with ttm_bo_vunmap(). This function can be used as
82  * &drm_gem_object_funcs.vmap callback.
83  */
84 void drm_gem_ttm_vunmap(struct drm_gem_object *gem,
85 			struct iosys_map *map)
86 {
87 	struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
88 
89 	ttm_bo_vunmap(bo, map);
90 }
91 EXPORT_SYMBOL(drm_gem_ttm_vunmap);
92 
93 /**
94  * drm_gem_ttm_mmap() - mmap &ttm_buffer_object
95  * @gem: GEM object.
96  * @vma: vm area.
97  *
98  * This function can be used as &drm_gem_object_funcs.mmap
99  * callback.
100  */
101 int drm_gem_ttm_mmap(struct drm_gem_object *gem,
102 		     struct vm_area_struct *vma)
103 {
104 	struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
105 	int ret;
106 
107 	ret = ttm_bo_mmap_obj(vma, bo);
108 	if (ret < 0)
109 		return ret;
110 
111 	/*
112 	 * ttm has its own object refcounting, so drop gem reference
113 	 * to avoid double accounting counting.
114 	 */
115 	drm_gem_object_put(gem);
116 
117 	return 0;
118 }
119 EXPORT_SYMBOL(drm_gem_ttm_mmap);
120 
121 /**
122  * drm_gem_ttm_dumb_map_offset() - Implements struct &drm_driver.dumb_map_offset
123  * @file:	DRM file pointer.
124  * @dev:	DRM device.
125  * @handle:	GEM handle
126  * @offset:	Returns the mapping's memory offset on success
127  *
128  * Provides an implementation of struct &drm_driver.dumb_map_offset for
129  * TTM-based GEM drivers. TTM allocates the offset internally and
130  * drm_gem_ttm_dumb_map_offset() returns it for dumb-buffer implementations.
131  *
132  * See struct &drm_driver.dumb_map_offset.
133  *
134  * Returns:
135  * 0 on success, or a negative errno code otherwise.
136  */
137 int drm_gem_ttm_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
138 				uint32_t handle, uint64_t *offset)
139 {
140 	struct drm_gem_object *gem;
141 
142 	gem = drm_gem_object_lookup(file, handle);
143 	if (!gem)
144 		return -ENOENT;
145 
146 	*offset = drm_vma_node_offset_addr(&gem->vma_node);
147 
148 	drm_gem_object_put(gem);
149 
150 	return 0;
151 }
152 EXPORT_SYMBOL(drm_gem_ttm_dumb_map_offset);
153 
154 MODULE_DESCRIPTION("DRM gem ttm helpers");
155 MODULE_LICENSE("GPL");
156