drm/vram: Add kmap ref-counting to GEM VRAM objects
[linux-2.6-block.git] / drivers / gpu / drm / drm_gem_vram_helper.c
CommitLineData
85438a8d
TZ
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3#include <drm/drm_gem_vram_helper.h>
59f5989a 4#include <drm/drm_device.h>
fed1eec0 5#include <drm/drm_mode.h>
1f460b49 6#include <drm/drm_prime.h>
5c9dcacf 7#include <drm/drm_vram_mm_helper.h>
85438a8d
TZ
8#include <drm/ttm/ttm_page_alloc.h>
9
31070a87
TZ
10static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
11
85438a8d
TZ
12/**
13 * DOC: overview
14 *
15 * This library provides a GEM buffer object that is backed by video RAM
16 * (VRAM). It can be used for framebuffer devices with dedicated memory.
17 */
18
19/*
20 * Buffer-objects helpers
21 */
22
23static void drm_gem_vram_cleanup(struct drm_gem_vram_object *gbo)
24{
25 /* We got here via ttm_bo_put(), which means that the
26 * TTM buffer object in 'bo' has already been cleaned
27 * up; only release the GEM object.
28 */
37a48adf
TZ
29
30 WARN_ON(gbo->kmap_use_count);
31
0e580c6d 32 drm_gem_object_release(&gbo->bo.base);
85438a8d
TZ
33}
34
35static void drm_gem_vram_destroy(struct drm_gem_vram_object *gbo)
36{
37 drm_gem_vram_cleanup(gbo);
38 kfree(gbo);
39}
40
41static void ttm_buffer_object_destroy(struct ttm_buffer_object *bo)
42{
43 struct drm_gem_vram_object *gbo = drm_gem_vram_of_bo(bo);
44
45 drm_gem_vram_destroy(gbo);
46}
47
48static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo,
49 unsigned long pl_flag)
50{
51 unsigned int i;
52 unsigned int c = 0;
53
54 gbo->placement.placement = gbo->placements;
55 gbo->placement.busy_placement = gbo->placements;
56
57 if (pl_flag & TTM_PL_FLAG_VRAM)
58 gbo->placements[c++].flags = TTM_PL_FLAG_WC |
59 TTM_PL_FLAG_UNCACHED |
60 TTM_PL_FLAG_VRAM;
61
62 if (pl_flag & TTM_PL_FLAG_SYSTEM)
63 gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
64 TTM_PL_FLAG_SYSTEM;
65
66 if (!c)
67 gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
68 TTM_PL_FLAG_SYSTEM;
69
70 gbo->placement.num_placement = c;
71 gbo->placement.num_busy_placement = c;
72
73 for (i = 0; i < c; ++i) {
74 gbo->placements[i].fpfn = 0;
75 gbo->placements[i].lpfn = 0;
76 }
77}
78
79static int drm_gem_vram_init(struct drm_device *dev,
80 struct ttm_bo_device *bdev,
81 struct drm_gem_vram_object *gbo,
82 size_t size, unsigned long pg_align,
83 bool interruptible)
84{
85 int ret;
86 size_t acc_size;
87
0e580c6d
GH
88 if (!gbo->bo.base.funcs)
89 gbo->bo.base.funcs = &drm_gem_vram_object_funcs;
31070a87 90
0e580c6d 91 ret = drm_gem_object_init(dev, &gbo->bo.base, size);
85438a8d
TZ
92 if (ret)
93 return ret;
94
95 acc_size = ttm_bo_dma_acc_size(bdev, size, sizeof(*gbo));
96
97 gbo->bo.bdev = bdev;
98 drm_gem_vram_placement(gbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
99
100 ret = ttm_bo_init(bdev, &gbo->bo, size, ttm_bo_type_device,
101 &gbo->placement, pg_align, interruptible, acc_size,
102 NULL, NULL, ttm_buffer_object_destroy);
103 if (ret)
104 goto err_drm_gem_object_release;
105
106 return 0;
107
108err_drm_gem_object_release:
0e580c6d 109 drm_gem_object_release(&gbo->bo.base);
85438a8d
TZ
110 return ret;
111}
112
113/**
114 * drm_gem_vram_create() - Creates a VRAM-backed GEM object
115 * @dev: the DRM device
116 * @bdev: the TTM BO device backing the object
117 * @size: the buffer size in bytes
118 * @pg_align: the buffer's alignment in multiples of the page size
119 * @interruptible: sleep interruptible if waiting for memory
120 *
121 * Returns:
122 * A new instance of &struct drm_gem_vram_object on success, or
123 * an ERR_PTR()-encoded error code otherwise.
124 */
125struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev,
126 struct ttm_bo_device *bdev,
127 size_t size,
128 unsigned long pg_align,
129 bool interruptible)
130{
131 struct drm_gem_vram_object *gbo;
132 int ret;
133
134 gbo = kzalloc(sizeof(*gbo), GFP_KERNEL);
135 if (!gbo)
136 return ERR_PTR(-ENOMEM);
137
138 ret = drm_gem_vram_init(dev, bdev, gbo, size, pg_align, interruptible);
139 if (ret < 0)
140 goto err_kfree;
141
142 return gbo;
143
144err_kfree:
145 kfree(gbo);
146 return ERR_PTR(ret);
147}
148EXPORT_SYMBOL(drm_gem_vram_create);
149
150/**
151 * drm_gem_vram_put() - Releases a reference to a VRAM-backed GEM object
152 * @gbo: the GEM VRAM object
153 *
154 * See ttm_bo_put() for more information.
155 */
156void drm_gem_vram_put(struct drm_gem_vram_object *gbo)
157{
158 ttm_bo_put(&gbo->bo);
159}
160EXPORT_SYMBOL(drm_gem_vram_put);
161
85438a8d
TZ
162/**
163 * drm_gem_vram_mmap_offset() - Returns a GEM VRAM object's mmap offset
164 * @gbo: the GEM VRAM object
165 *
166 * See drm_vma_node_offset_addr() for more information.
167 *
168 * Returns:
169 * The buffer object's offset for userspace mappings on success, or
170 * 0 if no offset is allocated.
171 */
172u64 drm_gem_vram_mmap_offset(struct drm_gem_vram_object *gbo)
173{
b96f3e7c 174 return drm_vma_node_offset_addr(&gbo->bo.base.vma_node);
85438a8d
TZ
175}
176EXPORT_SYMBOL(drm_gem_vram_mmap_offset);
177
178/**
179 * drm_gem_vram_offset() - \
180 Returns a GEM VRAM object's offset in video memory
181 * @gbo: the GEM VRAM object
182 *
183 * This function returns the buffer object's offset in the device's video
184 * memory. The buffer object has to be pinned to %TTM_PL_VRAM.
185 *
186 * Returns:
187 * The buffer object's offset in video memory on success, or
188 * a negative errno code otherwise.
189 */
190s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo)
191{
192 if (WARN_ON_ONCE(!gbo->pin_count))
193 return (s64)-ENODEV;
194 return gbo->bo.offset;
195}
196EXPORT_SYMBOL(drm_gem_vram_offset);
197
198/**
199 * drm_gem_vram_pin() - Pins a GEM VRAM object in a region.
200 * @gbo: the GEM VRAM object
201 * @pl_flag: a bitmask of possible memory regions
202 *
203 * Pinning a buffer object ensures that it is not evicted from
204 * a memory region. A pinned buffer object has to be unpinned before
a6c3464f
TZ
205 * it can be pinned to another region. If the pl_flag argument is 0,
206 * the buffer is pinned at its current location (video RAM or system
207 * memory).
85438a8d
TZ
208 *
209 * Returns:
210 * 0 on success, or
211 * a negative error code otherwise.
212 */
213int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag)
214{
215 int i, ret;
216 struct ttm_operation_ctx ctx = { false, false };
217
5b24f715
TZ
218 ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
219 if (ret < 0)
220 return ret;
221
222 if (gbo->pin_count)
223 goto out;
85438a8d 224
a6c3464f
TZ
225 if (pl_flag)
226 drm_gem_vram_placement(gbo, pl_flag);
227
85438a8d
TZ
228 for (i = 0; i < gbo->placement.num_placement; ++i)
229 gbo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
230
231 ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
232 if (ret < 0)
5b24f715 233 goto err_ttm_bo_unreserve;
85438a8d 234
5b24f715
TZ
235out:
236 ++gbo->pin_count;
237 ttm_bo_unreserve(&gbo->bo);
85438a8d
TZ
238
239 return 0;
5b24f715
TZ
240
241err_ttm_bo_unreserve:
242 ttm_bo_unreserve(&gbo->bo);
243 return ret;
85438a8d
TZ
244}
245EXPORT_SYMBOL(drm_gem_vram_pin);
246
247/**
248 * drm_gem_vram_unpin() - Unpins a GEM VRAM object
249 * @gbo: the GEM VRAM object
250 *
251 * Returns:
252 * 0 on success, or
253 * a negative error code otherwise.
254 */
255int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo)
256{
257 int i, ret;
258 struct ttm_operation_ctx ctx = { false, false };
259
5b24f715
TZ
260 ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
261 if (ret < 0)
262 return ret;
263
85438a8d 264 if (WARN_ON_ONCE(!gbo->pin_count))
5b24f715 265 goto out;
85438a8d
TZ
266
267 --gbo->pin_count;
268 if (gbo->pin_count)
5b24f715 269 goto out;
85438a8d
TZ
270
271 for (i = 0; i < gbo->placement.num_placement ; ++i)
272 gbo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
273
274 ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
275 if (ret < 0)
5b24f715
TZ
276 goto err_ttm_bo_unreserve;
277
278out:
279 ttm_bo_unreserve(&gbo->bo);
85438a8d
TZ
280
281 return 0;
5b24f715
TZ
282
283err_ttm_bo_unreserve:
284 ttm_bo_unreserve(&gbo->bo);
285 return ret;
85438a8d
TZ
286}
287EXPORT_SYMBOL(drm_gem_vram_unpin);
288
37a48adf
TZ
289static void *drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo,
290 bool map, bool *is_iomem)
291{
292 int ret;
293 struct ttm_bo_kmap_obj *kmap = &gbo->kmap;
294
295 if (gbo->kmap_use_count > 0)
296 goto out;
297
298 if (kmap->virtual || !map)
299 goto out;
300
301 ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, kmap);
302 if (ret)
303 return ERR_PTR(ret);
304
305out:
306 if (!kmap->virtual) {
307 if (is_iomem)
308 *is_iomem = false;
309 return NULL; /* not mapped; don't increment ref */
310 }
311 ++gbo->kmap_use_count;
312 if (is_iomem)
313 return ttm_kmap_obj_virtual(kmap, is_iomem);
314 return kmap->virtual;
315}
316
85438a8d 317/**
92172173 318 * drm_gem_vram_kmap() - Maps a GEM VRAM object into kernel address space
85438a8d
TZ
319 * @gbo: the GEM VRAM object
320 * @map: establish a mapping if necessary
321 * @is_iomem: returns true if the mapped memory is I/O memory, or false \
322 otherwise; can be NULL
85438a8d
TZ
323 *
324 * This function maps the buffer object into the kernel's address space
325 * or returns the current mapping. If the parameter map is false, the
326 * function only queries the current mapping, but does not establish a
327 * new one.
328 *
329 * Returns:
330 * The buffers virtual address if mapped, or
331 * NULL if not mapped, or
332 * an ERR_PTR()-encoded error code otherwise.
333 */
92172173
TZ
334void *drm_gem_vram_kmap(struct drm_gem_vram_object *gbo, bool map,
335 bool *is_iomem)
85438a8d
TZ
336{
337 int ret;
37a48adf 338 void *virtual;
85438a8d 339
37a48adf 340 ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
85438a8d
TZ
341 if (ret)
342 return ERR_PTR(ret);
37a48adf
TZ
343 virtual = drm_gem_vram_kmap_locked(gbo, map, is_iomem);
344 ttm_bo_unreserve(&gbo->bo);
85438a8d 345
37a48adf 346 return virtual;
85438a8d 347}
85438a8d
TZ
348EXPORT_SYMBOL(drm_gem_vram_kmap);
349
37a48adf 350static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo)
85438a8d 351{
92172173
TZ
352 struct ttm_bo_kmap_obj *kmap = &gbo->kmap;
353
37a48adf
TZ
354 if (WARN_ON_ONCE(!gbo->kmap_use_count))
355 return;
356 if (--gbo->kmap_use_count > 0)
357 return;
358
85438a8d
TZ
359 if (!kmap->virtual)
360 return;
361
362 ttm_bo_kunmap(kmap);
363 kmap->virtual = NULL;
364}
37a48adf
TZ
365
366/**
367 * drm_gem_vram_kunmap() - Unmaps a GEM VRAM object
368 * @gbo: the GEM VRAM object
369 */
370void drm_gem_vram_kunmap(struct drm_gem_vram_object *gbo)
371{
372 int ret;
373
374 ret = ttm_bo_reserve(&gbo->bo, false, false, NULL);
375 if (WARN_ONCE(ret, "ttm_bo_reserve_failed(): ret=%d\n", ret))
376 return;
377 drm_gem_vram_kunmap_locked(gbo);
378 ttm_bo_unreserve(&gbo->bo);
379}
85438a8d 380EXPORT_SYMBOL(drm_gem_vram_kunmap);
6c812bc5 381
fed1eec0
TZ
382/**
383 * drm_gem_vram_fill_create_dumb() - \
384 Helper for implementing &struct drm_driver.dumb_create
385 * @file: the DRM file
386 * @dev: the DRM device
387 * @bdev: the TTM BO device managing the buffer object
388 * @pg_align: the buffer's alignment in multiples of the page size
389 * @interruptible: sleep interruptible if waiting for memory
390 * @args: the arguments as provided to \
391 &struct drm_driver.dumb_create
392 *
393 * This helper function fills &struct drm_mode_create_dumb, which is used
394 * by &struct drm_driver.dumb_create. Implementations of this interface
395 * should forwards their arguments to this helper, plus the driver-specific
396 * parameters.
397 *
398 * Returns:
399 * 0 on success, or
400 * a negative error code otherwise.
401 */
402int drm_gem_vram_fill_create_dumb(struct drm_file *file,
403 struct drm_device *dev,
404 struct ttm_bo_device *bdev,
405 unsigned long pg_align,
406 bool interruptible,
407 struct drm_mode_create_dumb *args)
408{
409 size_t pitch, size;
410 struct drm_gem_vram_object *gbo;
411 int ret;
412 u32 handle;
413
414 pitch = args->width * ((args->bpp + 7) / 8);
415 size = pitch * args->height;
416
417 size = roundup(size, PAGE_SIZE);
418 if (!size)
419 return -EINVAL;
420
421 gbo = drm_gem_vram_create(dev, bdev, size, pg_align, interruptible);
422 if (IS_ERR(gbo))
423 return PTR_ERR(gbo);
424
0e580c6d 425 ret = drm_gem_handle_create(file, &gbo->bo.base, &handle);
fed1eec0
TZ
426 if (ret)
427 goto err_drm_gem_object_put_unlocked;
428
0e580c6d 429 drm_gem_object_put_unlocked(&gbo->bo.base);
fed1eec0
TZ
430
431 args->pitch = pitch;
432 args->size = size;
433 args->handle = handle;
434
435 return 0;
436
437err_drm_gem_object_put_unlocked:
0e580c6d 438 drm_gem_object_put_unlocked(&gbo->bo.base);
fed1eec0
TZ
439 return ret;
440}
441EXPORT_SYMBOL(drm_gem_vram_fill_create_dumb);
442
6c812bc5
TZ
443/*
444 * Helpers for struct ttm_bo_driver
445 */
446
447static bool drm_is_gem_vram(struct ttm_buffer_object *bo)
448{
449 return (bo->destroy == ttm_buffer_object_destroy);
450}
451
452/**
453 * drm_gem_vram_bo_driver_evict_flags() - \
454 Implements &struct ttm_bo_driver.evict_flags
455 * @bo: TTM buffer object. Refers to &struct drm_gem_vram_object.bo
456 * @pl: TTM placement information.
457 */
458void drm_gem_vram_bo_driver_evict_flags(struct ttm_buffer_object *bo,
459 struct ttm_placement *pl)
460{
461 struct drm_gem_vram_object *gbo;
462
463 /* TTM may pass BOs that are not GEM VRAM BOs. */
464 if (!drm_is_gem_vram(bo))
465 return;
466
467 gbo = drm_gem_vram_of_bo(bo);
468 drm_gem_vram_placement(gbo, TTM_PL_FLAG_SYSTEM);
469 *pl = gbo->placement;
470}
471EXPORT_SYMBOL(drm_gem_vram_bo_driver_evict_flags);
472
473/**
474 * drm_gem_vram_bo_driver_verify_access() - \
475 Implements &struct ttm_bo_driver.verify_access
476 * @bo: TTM buffer object. Refers to &struct drm_gem_vram_object.bo
477 * @filp: File pointer.
478 *
479 * Returns:
480 * 0 on success, or
481 * a negative errno code otherwise.
482 */
483int drm_gem_vram_bo_driver_verify_access(struct ttm_buffer_object *bo,
484 struct file *filp)
485{
486 struct drm_gem_vram_object *gbo = drm_gem_vram_of_bo(bo);
487
0e580c6d 488 return drm_vma_node_verify_access(&gbo->bo.base.vma_node,
6c812bc5
TZ
489 filp->private_data);
490}
491EXPORT_SYMBOL(drm_gem_vram_bo_driver_verify_access);
737000fd 492
1a1e5c0f 493/*
5c9dcacf
TZ
494 * drm_gem_vram_mm_funcs - Functions for &struct drm_vram_mm
495 *
496 * Most users of @struct drm_gem_vram_object will also use
497 * @struct drm_vram_mm. This instance of &struct drm_vram_mm_funcs
498 * can be used to connect both.
499 */
500const struct drm_vram_mm_funcs drm_gem_vram_mm_funcs = {
501 .evict_flags = drm_gem_vram_bo_driver_evict_flags,
502 .verify_access = drm_gem_vram_bo_driver_verify_access
503};
504EXPORT_SYMBOL(drm_gem_vram_mm_funcs);
505
737000fd 506/*
0ccf52ba 507 * Helpers for struct drm_gem_object_funcs
737000fd
TZ
508 */
509
510/**
0ccf52ba
TZ
511 * drm_gem_vram_object_free() - \
512 Implements &struct drm_gem_object_funcs.free
513 * @gem: GEM object. Refers to &struct drm_gem_vram_object.gem
737000fd 514 */
0ccf52ba 515static void drm_gem_vram_object_free(struct drm_gem_object *gem)
737000fd
TZ
516{
517 struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
518
519 drm_gem_vram_put(gbo);
520}
0ccf52ba
TZ
521
522/*
523 * Helpers for dump buffers
524 */
737000fd 525
59f5989a
TZ
526/**
527 * drm_gem_vram_driver_create_dumb() - \
528 Implements &struct drm_driver.dumb_create
529 * @file: the DRM file
530 * @dev: the DRM device
531 * @args: the arguments as provided to \
532 &struct drm_driver.dumb_create
533 *
534 * This function requires the driver to use @drm_device.vram_mm for its
535 * instance of VRAM MM.
536 *
537 * Returns:
538 * 0 on success, or
539 * a negative error code otherwise.
540 */
541int drm_gem_vram_driver_dumb_create(struct drm_file *file,
542 struct drm_device *dev,
543 struct drm_mode_create_dumb *args)
544{
545 if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized"))
546 return -EINVAL;
547
548 return drm_gem_vram_fill_create_dumb(file, dev, &dev->vram_mm->bdev, 0,
549 false, args);
550}
551EXPORT_SYMBOL(drm_gem_vram_driver_dumb_create);
552
737000fd
TZ
553/**
554 * drm_gem_vram_driver_dumb_mmap_offset() - \
555 Implements &struct drm_driver.dumb_mmap_offset
556 * @file: DRM file pointer.
557 * @dev: DRM device.
558 * @handle: GEM handle
559 * @offset: Returns the mapping's memory offset on success
560 *
561 * Returns:
562 * 0 on success, or
563 * a negative errno code otherwise.
564 */
565int drm_gem_vram_driver_dumb_mmap_offset(struct drm_file *file,
566 struct drm_device *dev,
567 uint32_t handle, uint64_t *offset)
568{
569 struct drm_gem_object *gem;
570 struct drm_gem_vram_object *gbo;
571
572 gem = drm_gem_object_lookup(file, handle);
573 if (!gem)
574 return -ENOENT;
575
576 gbo = drm_gem_vram_of_gem(gem);
577 *offset = drm_gem_vram_mmap_offset(gbo);
578
579 drm_gem_object_put_unlocked(gem);
580
581 return 0;
582}
583EXPORT_SYMBOL(drm_gem_vram_driver_dumb_mmap_offset);
1f460b49
TZ
584
585/*
0ccf52ba 586 * PRIME helpers
1f460b49
TZ
587 */
588
589/**
0ccf52ba
TZ
590 * drm_gem_vram_object_pin() - \
591 Implements &struct drm_gem_object_funcs.pin
1f460b49
TZ
592 * @gem: The GEM object to pin
593 *
594 * Returns:
595 * 0 on success, or
596 * a negative errno code otherwise.
597 */
0ccf52ba 598static int drm_gem_vram_object_pin(struct drm_gem_object *gem)
1f460b49
TZ
599{
600 struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
601
a6c3464f
TZ
602 /* Fbdev console emulation is the use case of these PRIME
603 * helpers. This may involve updating a hardware buffer from
604 * a shadow FB. We pin the buffer to it's current location
605 * (either video RAM or system memory) to prevent it from
606 * being relocated during the update operation. If you require
607 * the buffer to be pinned to VRAM, implement a callback that
608 * sets the flags accordingly.
609 */
610 return drm_gem_vram_pin(gbo, 0);
1f460b49 611}
1f460b49
TZ
612
613/**
0ccf52ba
TZ
614 * drm_gem_vram_object_unpin() - \
615 Implements &struct drm_gem_object_funcs.unpin
1f460b49
TZ
616 * @gem: The GEM object to unpin
617 */
0ccf52ba 618static void drm_gem_vram_object_unpin(struct drm_gem_object *gem)
1f460b49
TZ
619{
620 struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
621
622 drm_gem_vram_unpin(gbo);
623}
1f460b49
TZ
624
625/**
0ccf52ba
TZ
626 * drm_gem_vram_object_vmap() - \
627 Implements &struct drm_gem_object_funcs.vmap
1f460b49
TZ
628 * @gem: The GEM object to map
629 *
630 * Returns:
631 * The buffers virtual address on success, or
632 * NULL otherwise.
633 */
0ccf52ba 634static void *drm_gem_vram_object_vmap(struct drm_gem_object *gem)
1f460b49
TZ
635{
636 struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
637 int ret;
638 void *base;
639
a6c3464f 640 ret = drm_gem_vram_pin(gbo, 0);
1f460b49
TZ
641 if (ret)
642 return NULL;
643 base = drm_gem_vram_kmap(gbo, true, NULL);
644 if (IS_ERR(base)) {
645 drm_gem_vram_unpin(gbo);
646 return NULL;
647 }
648 return base;
649}
1f460b49
TZ
650
651/**
0ccf52ba
TZ
652 * drm_gem_vram_object_vunmap() - \
653 Implements &struct drm_gem_object_funcs.vunmap
1f460b49
TZ
654 * @gem: The GEM object to unmap
655 * @vaddr: The mapping's base address
656 */
0ccf52ba
TZ
657static void drm_gem_vram_object_vunmap(struct drm_gem_object *gem,
658 void *vaddr)
1f460b49
TZ
659{
660 struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
661
662 drm_gem_vram_kunmap(gbo);
663 drm_gem_vram_unpin(gbo);
664}
31070a87
TZ
665
666/*
667 * GEM object funcs
668 */
669
670static const struct drm_gem_object_funcs drm_gem_vram_object_funcs = {
0ccf52ba
TZ
671 .free = drm_gem_vram_object_free,
672 .pin = drm_gem_vram_object_pin,
673 .unpin = drm_gem_vram_object_unpin,
674 .vmap = drm_gem_vram_object_vmap,
675 .vunmap = drm_gem_vram_object_vunmap
31070a87 676};