Merge branch 'akpm' (patches from Andrew)
[linux/fpc-iii.git] / drivers / gpu / drm / drm_gem_vram_helper.c
bloba4863326061a49f802a95b051d80b3d0fc425314
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 #include <drm/drm_debugfs.h>
4 #include <drm/drm_device.h>
5 #include <drm/drm_drv.h>
6 #include <drm/drm_file.h>
7 #include <drm/drm_framebuffer.h>
8 #include <drm/drm_gem_ttm_helper.h>
9 #include <drm/drm_gem_vram_helper.h>
10 #include <drm/drm_mode.h>
11 #include <drm/drm_plane.h>
12 #include <drm/drm_prime.h>
13 #include <drm/drm_simple_kms_helper.h>
14 #include <drm/ttm/ttm_page_alloc.h>
16 static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
18 /**
19 * DOC: overview
21 * This library provides a GEM buffer object that is backed by video RAM
22 * (VRAM). It can be used for framebuffer devices with dedicated memory.
24 * The data structure &struct drm_vram_mm and its helpers implement a memory
25 * manager for simple framebuffer devices with dedicated video memory. Buffer
26 * objects are either placed in video RAM or evicted to system memory. The rsp.
27 * buffer object is provided by &struct drm_gem_vram_object.
31 * Buffer-objects helpers
34 static void drm_gem_vram_cleanup(struct drm_gem_vram_object *gbo)
36 /* We got here via ttm_bo_put(), which means that the
37 * TTM buffer object in 'bo' has already been cleaned
38 * up; only release the GEM object.
41 WARN_ON(gbo->kmap_use_count);
42 WARN_ON(gbo->kmap.virtual);
44 drm_gem_object_release(&gbo->bo.base);
47 static void drm_gem_vram_destroy(struct drm_gem_vram_object *gbo)
49 drm_gem_vram_cleanup(gbo);
50 kfree(gbo);
53 static void ttm_buffer_object_destroy(struct ttm_buffer_object *bo)
55 struct drm_gem_vram_object *gbo = drm_gem_vram_of_bo(bo);
57 drm_gem_vram_destroy(gbo);
60 static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo,
61 unsigned long pl_flag)
63 unsigned int i;
64 unsigned int c = 0;
65 u32 invariant_flags = pl_flag & TTM_PL_FLAG_TOPDOWN;
67 gbo->placement.placement = gbo->placements;
68 gbo->placement.busy_placement = gbo->placements;
70 if (pl_flag & TTM_PL_FLAG_VRAM)
71 gbo->placements[c++].flags = TTM_PL_FLAG_WC |
72 TTM_PL_FLAG_UNCACHED |
73 TTM_PL_FLAG_VRAM |
74 invariant_flags;
76 if (pl_flag & TTM_PL_FLAG_SYSTEM)
77 gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
78 TTM_PL_FLAG_SYSTEM |
79 invariant_flags;
81 if (!c)
82 gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
83 TTM_PL_FLAG_SYSTEM |
84 invariant_flags;
86 gbo->placement.num_placement = c;
87 gbo->placement.num_busy_placement = c;
89 for (i = 0; i < c; ++i) {
90 gbo->placements[i].fpfn = 0;
91 gbo->placements[i].lpfn = 0;
95 static int drm_gem_vram_init(struct drm_device *dev,
96 struct drm_gem_vram_object *gbo,
97 size_t size, unsigned long pg_align)
99 struct drm_vram_mm *vmm = dev->vram_mm;
100 struct ttm_bo_device *bdev;
101 int ret;
102 size_t acc_size;
104 if (WARN_ONCE(!vmm, "VRAM MM not initialized"))
105 return -EINVAL;
106 bdev = &vmm->bdev;
108 gbo->bo.base.funcs = &drm_gem_vram_object_funcs;
110 ret = drm_gem_object_init(dev, &gbo->bo.base, size);
111 if (ret)
112 return ret;
114 acc_size = ttm_bo_dma_acc_size(bdev, size, sizeof(*gbo));
116 gbo->bo.bdev = bdev;
117 drm_gem_vram_placement(gbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
119 ret = ttm_bo_init(bdev, &gbo->bo, size, ttm_bo_type_device,
120 &gbo->placement, pg_align, false, acc_size,
121 NULL, NULL, ttm_buffer_object_destroy);
122 if (ret)
123 goto err_drm_gem_object_release;
125 return 0;
127 err_drm_gem_object_release:
128 drm_gem_object_release(&gbo->bo.base);
129 return ret;
133 * drm_gem_vram_create() - Creates a VRAM-backed GEM object
134 * @dev: the DRM device
135 * @size: the buffer size in bytes
136 * @pg_align: the buffer's alignment in multiples of the page size
138 * Returns:
139 * A new instance of &struct drm_gem_vram_object on success, or
140 * an ERR_PTR()-encoded error code otherwise.
142 struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev,
143 size_t size,
144 unsigned long pg_align)
146 struct drm_gem_vram_object *gbo;
147 int ret;
149 if (dev->driver->gem_create_object) {
150 struct drm_gem_object *gem =
151 dev->driver->gem_create_object(dev, size);
152 if (!gem)
153 return ERR_PTR(-ENOMEM);
154 gbo = drm_gem_vram_of_gem(gem);
155 } else {
156 gbo = kzalloc(sizeof(*gbo), GFP_KERNEL);
157 if (!gbo)
158 return ERR_PTR(-ENOMEM);
161 ret = drm_gem_vram_init(dev, gbo, size, pg_align);
162 if (ret < 0)
163 goto err_kfree;
165 return gbo;
167 err_kfree:
168 kfree(gbo);
169 return ERR_PTR(ret);
171 EXPORT_SYMBOL(drm_gem_vram_create);
174 * drm_gem_vram_put() - Releases a reference to a VRAM-backed GEM object
175 * @gbo: the GEM VRAM object
177 * See ttm_bo_put() for more information.
179 void drm_gem_vram_put(struct drm_gem_vram_object *gbo)
181 ttm_bo_put(&gbo->bo);
183 EXPORT_SYMBOL(drm_gem_vram_put);
186 * drm_gem_vram_mmap_offset() - Returns a GEM VRAM object's mmap offset
187 * @gbo: the GEM VRAM object
189 * See drm_vma_node_offset_addr() for more information.
191 * Returns:
192 * The buffer object's offset for userspace mappings on success, or
193 * 0 if no offset is allocated.
195 u64 drm_gem_vram_mmap_offset(struct drm_gem_vram_object *gbo)
197 return drm_vma_node_offset_addr(&gbo->bo.base.vma_node);
199 EXPORT_SYMBOL(drm_gem_vram_mmap_offset);
202 * drm_gem_vram_offset() - \
203 Returns a GEM VRAM object's offset in video memory
204 * @gbo: the GEM VRAM object
206 * This function returns the buffer object's offset in the device's video
207 * memory. The buffer object has to be pinned to %TTM_PL_VRAM.
209 * Returns:
210 * The buffer object's offset in video memory on success, or
211 * a negative errno code otherwise.
213 s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo)
215 if (WARN_ON_ONCE(!gbo->pin_count))
216 return (s64)-ENODEV;
217 return gbo->bo.offset;
219 EXPORT_SYMBOL(drm_gem_vram_offset);
221 static int drm_gem_vram_pin_locked(struct drm_gem_vram_object *gbo,
222 unsigned long pl_flag)
224 int i, ret;
225 struct ttm_operation_ctx ctx = { false, false };
227 if (gbo->pin_count)
228 goto out;
230 if (pl_flag)
231 drm_gem_vram_placement(gbo, pl_flag);
233 for (i = 0; i < gbo->placement.num_placement; ++i)
234 gbo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
236 ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
237 if (ret < 0)
238 return ret;
240 out:
241 ++gbo->pin_count;
243 return 0;
247 * drm_gem_vram_pin() - Pins a GEM VRAM object in a region.
248 * @gbo: the GEM VRAM object
249 * @pl_flag: a bitmask of possible memory regions
251 * Pinning a buffer object ensures that it is not evicted from
252 * a memory region. A pinned buffer object has to be unpinned before
253 * it can be pinned to another region. If the pl_flag argument is 0,
254 * the buffer is pinned at its current location (video RAM or system
255 * memory).
257 * Small buffer objects, such as cursor images, can lead to memory
258 * fragmentation if they are pinned in the middle of video RAM. This
259 * is especially a problem on devices with only a small amount of
260 * video RAM. Fragmentation can prevent the primary framebuffer from
261 * fitting in, even though there's enough memory overall. The modifier
262 * DRM_GEM_VRAM_PL_FLAG_TOPDOWN marks the buffer object to be pinned
263 * at the high end of the memory region to avoid fragmentation.
265 * Returns:
266 * 0 on success, or
267 * a negative error code otherwise.
269 int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag)
271 int ret;
273 ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
274 if (ret)
275 return ret;
276 ret = drm_gem_vram_pin_locked(gbo, pl_flag);
277 ttm_bo_unreserve(&gbo->bo);
279 return ret;
281 EXPORT_SYMBOL(drm_gem_vram_pin);
283 static int drm_gem_vram_unpin_locked(struct drm_gem_vram_object *gbo)
285 int i, ret;
286 struct ttm_operation_ctx ctx = { false, false };
288 if (WARN_ON_ONCE(!gbo->pin_count))
289 return 0;
291 --gbo->pin_count;
292 if (gbo->pin_count)
293 return 0;
295 for (i = 0; i < gbo->placement.num_placement ; ++i)
296 gbo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
298 ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
299 if (ret < 0)
300 return ret;
302 return 0;
306 * drm_gem_vram_unpin() - Unpins a GEM VRAM object
307 * @gbo: the GEM VRAM object
309 * Returns:
310 * 0 on success, or
311 * a negative error code otherwise.
313 int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo)
315 int ret;
317 ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
318 if (ret)
319 return ret;
320 ret = drm_gem_vram_unpin_locked(gbo);
321 ttm_bo_unreserve(&gbo->bo);
323 return ret;
325 EXPORT_SYMBOL(drm_gem_vram_unpin);
327 static void *drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo,
328 bool map, bool *is_iomem)
330 int ret;
331 struct ttm_bo_kmap_obj *kmap = &gbo->kmap;
333 if (gbo->kmap_use_count > 0)
334 goto out;
336 if (kmap->virtual || !map)
337 goto out;
339 ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, kmap);
340 if (ret)
341 return ERR_PTR(ret);
343 out:
344 if (!kmap->virtual) {
345 if (is_iomem)
346 *is_iomem = false;
347 return NULL; /* not mapped; don't increment ref */
349 ++gbo->kmap_use_count;
350 if (is_iomem)
351 return ttm_kmap_obj_virtual(kmap, is_iomem);
352 return kmap->virtual;
356 * drm_gem_vram_kmap() - Maps a GEM VRAM object into kernel address space
357 * @gbo: the GEM VRAM object
358 * @map: establish a mapping if necessary
359 * @is_iomem: returns true if the mapped memory is I/O memory, or false \
360 otherwise; can be NULL
362 * This function maps the buffer object into the kernel's address space
363 * or returns the current mapping. If the parameter map is false, the
364 * function only queries the current mapping, but does not establish a
365 * new one.
367 * Returns:
368 * The buffers virtual address if mapped, or
369 * NULL if not mapped, or
370 * an ERR_PTR()-encoded error code otherwise.
372 void *drm_gem_vram_kmap(struct drm_gem_vram_object *gbo, bool map,
373 bool *is_iomem)
375 int ret;
376 void *virtual;
378 ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
379 if (ret)
380 return ERR_PTR(ret);
381 virtual = drm_gem_vram_kmap_locked(gbo, map, is_iomem);
382 ttm_bo_unreserve(&gbo->bo);
384 return virtual;
386 EXPORT_SYMBOL(drm_gem_vram_kmap);
388 static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo)
390 if (WARN_ON_ONCE(!gbo->kmap_use_count))
391 return;
392 if (--gbo->kmap_use_count > 0)
393 return;
396 * Permanently mapping and unmapping buffers adds overhead from
397 * updating the page tables and creates debugging output. Therefore,
398 * we delay the actual unmap operation until the BO gets evicted
399 * from memory. See drm_gem_vram_bo_driver_move_notify().
404 * drm_gem_vram_kunmap() - Unmaps a GEM VRAM object
405 * @gbo: the GEM VRAM object
407 void drm_gem_vram_kunmap(struct drm_gem_vram_object *gbo)
409 int ret;
411 ret = ttm_bo_reserve(&gbo->bo, false, false, NULL);
412 if (WARN_ONCE(ret, "ttm_bo_reserve_failed(): ret=%d\n", ret))
413 return;
414 drm_gem_vram_kunmap_locked(gbo);
415 ttm_bo_unreserve(&gbo->bo);
417 EXPORT_SYMBOL(drm_gem_vram_kunmap);
420 * drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address
421 * space
422 * @gbo: The GEM VRAM object to map
424 * The vmap function pins a GEM VRAM object to its current location, either
425 * system or video memory, and maps its buffer into kernel address space.
426 * As pinned object cannot be relocated, you should avoid pinning objects
427 * permanently. Call drm_gem_vram_vunmap() with the returned address to
428 * unmap and unpin the GEM VRAM object.
430 * If you have special requirements for the pinning or mapping operations,
431 * call drm_gem_vram_pin() and drm_gem_vram_kmap() directly.
433 * Returns:
434 * The buffer's virtual address on success, or
435 * an ERR_PTR()-encoded error code otherwise.
437 void *drm_gem_vram_vmap(struct drm_gem_vram_object *gbo)
439 int ret;
440 void *base;
442 ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
443 if (ret)
444 return ERR_PTR(ret);
446 ret = drm_gem_vram_pin_locked(gbo, 0);
447 if (ret)
448 goto err_ttm_bo_unreserve;
449 base = drm_gem_vram_kmap_locked(gbo, true, NULL);
450 if (IS_ERR(base)) {
451 ret = PTR_ERR(base);
452 goto err_drm_gem_vram_unpin_locked;
455 ttm_bo_unreserve(&gbo->bo);
457 return base;
459 err_drm_gem_vram_unpin_locked:
460 drm_gem_vram_unpin_locked(gbo);
461 err_ttm_bo_unreserve:
462 ttm_bo_unreserve(&gbo->bo);
463 return ERR_PTR(ret);
465 EXPORT_SYMBOL(drm_gem_vram_vmap);
468 * drm_gem_vram_vunmap() - Unmaps and unpins a GEM VRAM object
469 * @gbo: The GEM VRAM object to unmap
470 * @vaddr: The mapping's base address as returned by drm_gem_vram_vmap()
472 * A call to drm_gem_vram_vunmap() unmaps and unpins a GEM VRAM buffer. See
473 * the documentation for drm_gem_vram_vmap() for more information.
475 void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo, void *vaddr)
477 int ret;
479 ret = ttm_bo_reserve(&gbo->bo, false, false, NULL);
480 if (WARN_ONCE(ret, "ttm_bo_reserve_failed(): ret=%d\n", ret))
481 return;
483 drm_gem_vram_kunmap_locked(gbo);
484 drm_gem_vram_unpin_locked(gbo);
486 ttm_bo_unreserve(&gbo->bo);
488 EXPORT_SYMBOL(drm_gem_vram_vunmap);
491 * drm_gem_vram_fill_create_dumb() - \
492 Helper for implementing &struct drm_driver.dumb_create
493 * @file: the DRM file
494 * @dev: the DRM device
495 * @pg_align: the buffer's alignment in multiples of the page size
496 * @pitch_align: the scanline's alignment in powers of 2
497 * @args: the arguments as provided to \
498 &struct drm_driver.dumb_create
500 * This helper function fills &struct drm_mode_create_dumb, which is used
501 * by &struct drm_driver.dumb_create. Implementations of this interface
502 * should forwards their arguments to this helper, plus the driver-specific
503 * parameters.
505 * Returns:
506 * 0 on success, or
507 * a negative error code otherwise.
509 int drm_gem_vram_fill_create_dumb(struct drm_file *file,
510 struct drm_device *dev,
511 unsigned long pg_align,
512 unsigned long pitch_align,
513 struct drm_mode_create_dumb *args)
515 size_t pitch, size;
516 struct drm_gem_vram_object *gbo;
517 int ret;
518 u32 handle;
520 pitch = args->width * DIV_ROUND_UP(args->bpp, 8);
521 if (pitch_align) {
522 if (WARN_ON_ONCE(!is_power_of_2(pitch_align)))
523 return -EINVAL;
524 pitch = ALIGN(pitch, pitch_align);
526 size = pitch * args->height;
528 size = roundup(size, PAGE_SIZE);
529 if (!size)
530 return -EINVAL;
532 gbo = drm_gem_vram_create(dev, size, pg_align);
533 if (IS_ERR(gbo))
534 return PTR_ERR(gbo);
536 ret = drm_gem_handle_create(file, &gbo->bo.base, &handle);
537 if (ret)
538 goto err_drm_gem_object_put_unlocked;
540 drm_gem_object_put_unlocked(&gbo->bo.base);
542 args->pitch = pitch;
543 args->size = size;
544 args->handle = handle;
546 return 0;
548 err_drm_gem_object_put_unlocked:
549 drm_gem_object_put_unlocked(&gbo->bo.base);
550 return ret;
552 EXPORT_SYMBOL(drm_gem_vram_fill_create_dumb);
555 * Helpers for struct ttm_bo_driver
558 static bool drm_is_gem_vram(struct ttm_buffer_object *bo)
560 return (bo->destroy == ttm_buffer_object_destroy);
563 static void drm_gem_vram_bo_driver_evict_flags(struct drm_gem_vram_object *gbo,
564 struct ttm_placement *pl)
566 drm_gem_vram_placement(gbo, TTM_PL_FLAG_SYSTEM);
567 *pl = gbo->placement;
570 static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo,
571 bool evict,
572 struct ttm_mem_reg *new_mem)
574 struct ttm_bo_kmap_obj *kmap = &gbo->kmap;
576 if (WARN_ON_ONCE(gbo->kmap_use_count))
577 return;
579 if (!kmap->virtual)
580 return;
581 ttm_bo_kunmap(kmap);
582 kmap->virtual = NULL;
586 * Helpers for struct drm_gem_object_funcs
590 * drm_gem_vram_object_free() - \
591 Implements &struct drm_gem_object_funcs.free
592 * @gem: GEM object. Refers to &struct drm_gem_vram_object.gem
594 static void drm_gem_vram_object_free(struct drm_gem_object *gem)
596 struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
598 drm_gem_vram_put(gbo);
602 * Helpers for dump buffers
606 * drm_gem_vram_driver_create_dumb() - \
607 Implements &struct drm_driver.dumb_create
608 * @file: the DRM file
609 * @dev: the DRM device
610 * @args: the arguments as provided to \
611 &struct drm_driver.dumb_create
613 * This function requires the driver to use @drm_device.vram_mm for its
614 * instance of VRAM MM.
616 * Returns:
617 * 0 on success, or
618 * a negative error code otherwise.
620 int drm_gem_vram_driver_dumb_create(struct drm_file *file,
621 struct drm_device *dev,
622 struct drm_mode_create_dumb *args)
624 if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized"))
625 return -EINVAL;
627 return drm_gem_vram_fill_create_dumb(file, dev, 0, 0, args);
629 EXPORT_SYMBOL(drm_gem_vram_driver_dumb_create);
632 * drm_gem_vram_driver_dumb_mmap_offset() - \
633 Implements &struct drm_driver.dumb_mmap_offset
634 * @file: DRM file pointer.
635 * @dev: DRM device.
636 * @handle: GEM handle
637 * @offset: Returns the mapping's memory offset on success
639 * Returns:
640 * 0 on success, or
641 * a negative errno code otherwise.
643 int drm_gem_vram_driver_dumb_mmap_offset(struct drm_file *file,
644 struct drm_device *dev,
645 uint32_t handle, uint64_t *offset)
647 struct drm_gem_object *gem;
648 struct drm_gem_vram_object *gbo;
650 gem = drm_gem_object_lookup(file, handle);
651 if (!gem)
652 return -ENOENT;
654 gbo = drm_gem_vram_of_gem(gem);
655 *offset = drm_gem_vram_mmap_offset(gbo);
657 drm_gem_object_put_unlocked(gem);
659 return 0;
661 EXPORT_SYMBOL(drm_gem_vram_driver_dumb_mmap_offset);
664 * Helpers for struct drm_plane_helper_funcs
668 * drm_gem_vram_plane_helper_prepare_fb() - \
669 * Implements &struct drm_plane_helper_funcs.prepare_fb
670 * @plane: a DRM plane
671 * @new_state: the plane's new state
673 * During plane updates, this function pins the GEM VRAM
674 * objects of the plane's new framebuffer to VRAM. Call
675 * drm_gem_vram_plane_helper_cleanup_fb() to unpin them.
677 * Returns:
678 * 0 on success, or
679 * a negative errno code otherwise.
682 drm_gem_vram_plane_helper_prepare_fb(struct drm_plane *plane,
683 struct drm_plane_state *new_state)
685 size_t i;
686 struct drm_gem_vram_object *gbo;
687 int ret;
689 if (!new_state->fb)
690 return 0;
692 for (i = 0; i < ARRAY_SIZE(new_state->fb->obj); ++i) {
693 if (!new_state->fb->obj[i])
694 continue;
695 gbo = drm_gem_vram_of_gem(new_state->fb->obj[i]);
696 ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
697 if (ret)
698 goto err_drm_gem_vram_unpin;
701 return 0;
703 err_drm_gem_vram_unpin:
704 while (i) {
705 --i;
706 gbo = drm_gem_vram_of_gem(new_state->fb->obj[i]);
707 drm_gem_vram_unpin(gbo);
709 return ret;
711 EXPORT_SYMBOL(drm_gem_vram_plane_helper_prepare_fb);
714 * drm_gem_vram_plane_helper_cleanup_fb() - \
715 * Implements &struct drm_plane_helper_funcs.cleanup_fb
716 * @plane: a DRM plane
717 * @old_state: the plane's old state
719 * During plane updates, this function unpins the GEM VRAM
720 * objects of the plane's old framebuffer from VRAM. Complements
721 * drm_gem_vram_plane_helper_prepare_fb().
723 void
724 drm_gem_vram_plane_helper_cleanup_fb(struct drm_plane *plane,
725 struct drm_plane_state *old_state)
727 size_t i;
728 struct drm_gem_vram_object *gbo;
730 if (!old_state->fb)
731 return;
733 for (i = 0; i < ARRAY_SIZE(old_state->fb->obj); ++i) {
734 if (!old_state->fb->obj[i])
735 continue;
736 gbo = drm_gem_vram_of_gem(old_state->fb->obj[i]);
737 drm_gem_vram_unpin(gbo);
740 EXPORT_SYMBOL(drm_gem_vram_plane_helper_cleanup_fb);
743 * Helpers for struct drm_simple_display_pipe_funcs
747 * drm_gem_vram_simple_display_pipe_prepare_fb() - \
748 * Implements &struct drm_simple_display_pipe_funcs.prepare_fb
749 * @pipe: a simple display pipe
750 * @new_state: the plane's new state
752 * During plane updates, this function pins the GEM VRAM
753 * objects of the plane's new framebuffer to VRAM. Call
754 * drm_gem_vram_simple_display_pipe_cleanup_fb() to unpin them.
756 * Returns:
757 * 0 on success, or
758 * a negative errno code otherwise.
760 int drm_gem_vram_simple_display_pipe_prepare_fb(
761 struct drm_simple_display_pipe *pipe,
762 struct drm_plane_state *new_state)
764 return drm_gem_vram_plane_helper_prepare_fb(&pipe->plane, new_state);
766 EXPORT_SYMBOL(drm_gem_vram_simple_display_pipe_prepare_fb);
769 * drm_gem_vram_simple_display_pipe_cleanup_fb() - \
770 * Implements &struct drm_simple_display_pipe_funcs.cleanup_fb
771 * @pipe: a simple display pipe
772 * @old_state: the plane's old state
774 * During plane updates, this function unpins the GEM VRAM
775 * objects of the plane's old framebuffer from VRAM. Complements
776 * drm_gem_vram_simple_display_pipe_prepare_fb().
778 void drm_gem_vram_simple_display_pipe_cleanup_fb(
779 struct drm_simple_display_pipe *pipe,
780 struct drm_plane_state *old_state)
782 drm_gem_vram_plane_helper_cleanup_fb(&pipe->plane, old_state);
784 EXPORT_SYMBOL(drm_gem_vram_simple_display_pipe_cleanup_fb);
787 * PRIME helpers
791 * drm_gem_vram_object_pin() - \
792 Implements &struct drm_gem_object_funcs.pin
793 * @gem: The GEM object to pin
795 * Returns:
796 * 0 on success, or
797 * a negative errno code otherwise.
799 static int drm_gem_vram_object_pin(struct drm_gem_object *gem)
801 struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
803 /* Fbdev console emulation is the use case of these PRIME
804 * helpers. This may involve updating a hardware buffer from
805 * a shadow FB. We pin the buffer to it's current location
806 * (either video RAM or system memory) to prevent it from
807 * being relocated during the update operation. If you require
808 * the buffer to be pinned to VRAM, implement a callback that
809 * sets the flags accordingly.
811 return drm_gem_vram_pin(gbo, 0);
815 * drm_gem_vram_object_unpin() - \
816 Implements &struct drm_gem_object_funcs.unpin
817 * @gem: The GEM object to unpin
819 static void drm_gem_vram_object_unpin(struct drm_gem_object *gem)
821 struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
823 drm_gem_vram_unpin(gbo);
827 * drm_gem_vram_object_vmap() - \
828 Implements &struct drm_gem_object_funcs.vmap
829 * @gem: The GEM object to map
831 * Returns:
832 * The buffers virtual address on success, or
833 * NULL otherwise.
835 static void *drm_gem_vram_object_vmap(struct drm_gem_object *gem)
837 struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
838 void *base;
840 base = drm_gem_vram_vmap(gbo);
841 if (IS_ERR(base))
842 return NULL;
843 return base;
847 * drm_gem_vram_object_vunmap() - \
848 Implements &struct drm_gem_object_funcs.vunmap
849 * @gem: The GEM object to unmap
850 * @vaddr: The mapping's base address
852 static void drm_gem_vram_object_vunmap(struct drm_gem_object *gem,
853 void *vaddr)
855 struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
857 drm_gem_vram_vunmap(gbo, vaddr);
861 * GEM object funcs
864 static const struct drm_gem_object_funcs drm_gem_vram_object_funcs = {
865 .free = drm_gem_vram_object_free,
866 .pin = drm_gem_vram_object_pin,
867 .unpin = drm_gem_vram_object_unpin,
868 .vmap = drm_gem_vram_object_vmap,
869 .vunmap = drm_gem_vram_object_vunmap,
870 .mmap = drm_gem_ttm_mmap,
871 .print_info = drm_gem_ttm_print_info,
875 * VRAM memory manager
879 * TTM TT
882 static void backend_func_destroy(struct ttm_tt *tt)
884 ttm_tt_fini(tt);
885 kfree(tt);
888 static struct ttm_backend_func backend_func = {
889 .destroy = backend_func_destroy
893 * TTM BO device
896 static struct ttm_tt *bo_driver_ttm_tt_create(struct ttm_buffer_object *bo,
897 uint32_t page_flags)
899 struct ttm_tt *tt;
900 int ret;
902 tt = kzalloc(sizeof(*tt), GFP_KERNEL);
903 if (!tt)
904 return NULL;
906 tt->func = &backend_func;
908 ret = ttm_tt_init(tt, bo, page_flags);
909 if (ret < 0)
910 goto err_ttm_tt_init;
912 return tt;
914 err_ttm_tt_init:
915 kfree(tt);
916 return NULL;
919 static int bo_driver_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
920 struct ttm_mem_type_manager *man)
922 switch (type) {
923 case TTM_PL_SYSTEM:
924 man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
925 man->available_caching = TTM_PL_MASK_CACHING;
926 man->default_caching = TTM_PL_FLAG_CACHED;
927 break;
928 case TTM_PL_VRAM:
929 man->func = &ttm_bo_manager_func;
930 man->flags = TTM_MEMTYPE_FLAG_FIXED |
931 TTM_MEMTYPE_FLAG_MAPPABLE;
932 man->available_caching = TTM_PL_FLAG_UNCACHED |
933 TTM_PL_FLAG_WC;
934 man->default_caching = TTM_PL_FLAG_WC;
935 break;
936 default:
937 return -EINVAL;
939 return 0;
942 static void bo_driver_evict_flags(struct ttm_buffer_object *bo,
943 struct ttm_placement *placement)
945 struct drm_gem_vram_object *gbo;
947 /* TTM may pass BOs that are not GEM VRAM BOs. */
948 if (!drm_is_gem_vram(bo))
949 return;
951 gbo = drm_gem_vram_of_bo(bo);
953 drm_gem_vram_bo_driver_evict_flags(gbo, placement);
956 static void bo_driver_move_notify(struct ttm_buffer_object *bo,
957 bool evict,
958 struct ttm_mem_reg *new_mem)
960 struct drm_gem_vram_object *gbo;
962 /* TTM may pass BOs that are not GEM VRAM BOs. */
963 if (!drm_is_gem_vram(bo))
964 return;
966 gbo = drm_gem_vram_of_bo(bo);
968 drm_gem_vram_bo_driver_move_notify(gbo, evict, new_mem);
971 static int bo_driver_io_mem_reserve(struct ttm_bo_device *bdev,
972 struct ttm_mem_reg *mem)
974 struct ttm_mem_type_manager *man = bdev->man + mem->mem_type;
975 struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bdev);
977 if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
978 return -EINVAL;
980 mem->bus.addr = NULL;
981 mem->bus.size = mem->num_pages << PAGE_SHIFT;
983 switch (mem->mem_type) {
984 case TTM_PL_SYSTEM: /* nothing to do */
985 mem->bus.offset = 0;
986 mem->bus.base = 0;
987 mem->bus.is_iomem = false;
988 break;
989 case TTM_PL_VRAM:
990 mem->bus.offset = mem->start << PAGE_SHIFT;
991 mem->bus.base = vmm->vram_base;
992 mem->bus.is_iomem = true;
993 break;
994 default:
995 return -EINVAL;
998 return 0;
1001 static void bo_driver_io_mem_free(struct ttm_bo_device *bdev,
1002 struct ttm_mem_reg *mem)
1005 static struct ttm_bo_driver bo_driver = {
1006 .ttm_tt_create = bo_driver_ttm_tt_create,
1007 .ttm_tt_populate = ttm_pool_populate,
1008 .ttm_tt_unpopulate = ttm_pool_unpopulate,
1009 .init_mem_type = bo_driver_init_mem_type,
1010 .eviction_valuable = ttm_bo_eviction_valuable,
1011 .evict_flags = bo_driver_evict_flags,
1012 .move_notify = bo_driver_move_notify,
1013 .io_mem_reserve = bo_driver_io_mem_reserve,
1014 .io_mem_free = bo_driver_io_mem_free,
1018 * struct drm_vram_mm
1021 #if defined(CONFIG_DEBUG_FS)
1022 static int drm_vram_mm_debugfs(struct seq_file *m, void *data)
1024 struct drm_info_node *node = (struct drm_info_node *) m->private;
1025 struct drm_vram_mm *vmm = node->minor->dev->vram_mm;
1026 struct drm_mm *mm = vmm->bdev.man[TTM_PL_VRAM].priv;
1027 struct drm_printer p = drm_seq_file_printer(m);
1029 spin_lock(&ttm_bo_glob.lru_lock);
1030 drm_mm_print(mm, &p);
1031 spin_unlock(&ttm_bo_glob.lru_lock);
1032 return 0;
1035 static const struct drm_info_list drm_vram_mm_debugfs_list[] = {
1036 { "vram-mm", drm_vram_mm_debugfs, 0, NULL },
1038 #endif
1041 * drm_vram_mm_debugfs_init() - Register VRAM MM debugfs file.
1043 * @minor: drm minor device.
1045 * Returns:
1046 * 0 on success, or
1047 * a negative error code otherwise.
1049 int drm_vram_mm_debugfs_init(struct drm_minor *minor)
1051 int ret = 0;
1053 #if defined(CONFIG_DEBUG_FS)
1054 ret = drm_debugfs_create_files(drm_vram_mm_debugfs_list,
1055 ARRAY_SIZE(drm_vram_mm_debugfs_list),
1056 minor->debugfs_root, minor);
1057 #endif
1058 return ret;
1060 EXPORT_SYMBOL(drm_vram_mm_debugfs_init);
1062 static int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev,
1063 uint64_t vram_base, size_t vram_size)
1065 int ret;
1067 vmm->vram_base = vram_base;
1068 vmm->vram_size = vram_size;
1070 ret = ttm_bo_device_init(&vmm->bdev, &bo_driver,
1071 dev->anon_inode->i_mapping,
1072 dev->vma_offset_manager,
1073 true);
1074 if (ret)
1075 return ret;
1077 ret = ttm_bo_init_mm(&vmm->bdev, TTM_PL_VRAM, vram_size >> PAGE_SHIFT);
1078 if (ret)
1079 return ret;
1081 return 0;
1084 static void drm_vram_mm_cleanup(struct drm_vram_mm *vmm)
1086 ttm_bo_device_release(&vmm->bdev);
1090 * Helpers for integration with struct drm_device
1094 * drm_vram_helper_alloc_mm - Allocates a device's instance of \
1095 &struct drm_vram_mm
1096 * @dev: the DRM device
1097 * @vram_base: the base address of the video memory
1098 * @vram_size: the size of the video memory in bytes
1100 * Returns:
1101 * The new instance of &struct drm_vram_mm on success, or
1102 * an ERR_PTR()-encoded errno code otherwise.
1104 struct drm_vram_mm *drm_vram_helper_alloc_mm(
1105 struct drm_device *dev, uint64_t vram_base, size_t vram_size)
1107 int ret;
1109 if (WARN_ON(dev->vram_mm))
1110 return dev->vram_mm;
1112 dev->vram_mm = kzalloc(sizeof(*dev->vram_mm), GFP_KERNEL);
1113 if (!dev->vram_mm)
1114 return ERR_PTR(-ENOMEM);
1116 ret = drm_vram_mm_init(dev->vram_mm, dev, vram_base, vram_size);
1117 if (ret)
1118 goto err_kfree;
1120 return dev->vram_mm;
1122 err_kfree:
1123 kfree(dev->vram_mm);
1124 dev->vram_mm = NULL;
1125 return ERR_PTR(ret);
1127 EXPORT_SYMBOL(drm_vram_helper_alloc_mm);
1130 * drm_vram_helper_release_mm - Releases a device's instance of \
1131 &struct drm_vram_mm
1132 * @dev: the DRM device
1134 void drm_vram_helper_release_mm(struct drm_device *dev)
1136 if (!dev->vram_mm)
1137 return;
1139 drm_vram_mm_cleanup(dev->vram_mm);
1140 kfree(dev->vram_mm);
1141 dev->vram_mm = NULL;
1143 EXPORT_SYMBOL(drm_vram_helper_release_mm);