Lines Matching +full:long +full:- +full:ram +full:- +full:code

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 #include <linux/iosys-map.h>
29 * buffer object that is backed by video RAM (VRAM). It can be used for
38 * graphics buffers, such as an on-screen framebuffer. GEM does not provide
42 * library. Each active buffer object is stored in video RAM. Active
53 * .. code-block:: c
69 * unsigned long vram_size;
84 * manages an area of video RAM with VRAM MM and provides GEM VRAM objects
89 * clean-up handler to run during the DRM device's release.
92 * in video RAM. Call drm_gem_vram_pin() with &DRM_GEM_VRAM_PL_FLAG_VRAM or
93 * &DRM_GEM_VRAM_PL_FLAG_SYSTEM to pin a buffer object in video RAM or system
96 * A buffer object that is pinned in video RAM has a fixed address within that
109 * Buffer-objects helpers
119 WARN_ON(gbo->vmap_use_count); in drm_gem_vram_cleanup()
120 WARN_ON(iosys_map_is_set(&gbo->map)); in drm_gem_vram_cleanup()
122 drm_gem_object_release(&gbo->bo.base); in drm_gem_vram_cleanup()
139 unsigned long pl_flag) in drm_gem_vram_placement()
148 gbo->placement.placement = gbo->placements; in drm_gem_vram_placement()
151 gbo->placements[c].mem_type = TTM_PL_VRAM; in drm_gem_vram_placement()
152 gbo->placements[c++].flags = invariant_flags; in drm_gem_vram_placement()
156 gbo->placements[c].mem_type = TTM_PL_SYSTEM; in drm_gem_vram_placement()
157 gbo->placements[c++].flags = invariant_flags; in drm_gem_vram_placement()
160 gbo->placement.num_placement = c; in drm_gem_vram_placement()
163 gbo->placements[i].fpfn = 0; in drm_gem_vram_placement()
164 gbo->placements[i].lpfn = 0; in drm_gem_vram_placement()
169 * drm_gem_vram_create() - Creates a VRAM-backed GEM object
182 * an ERR_PTR()-encoded error code otherwise.
186 unsigned long pg_align) in drm_gem_vram_create()
190 struct drm_vram_mm *vmm = dev->vram_mm; in drm_gem_vram_create()
195 return ERR_PTR(-EINVAL); in drm_gem_vram_create()
197 if (dev->driver->gem_create_object) { in drm_gem_vram_create()
198 gem = dev->driver->gem_create_object(dev, size); in drm_gem_vram_create()
205 return ERR_PTR(-ENOMEM); in drm_gem_vram_create()
206 gem = &gbo->bo.base; in drm_gem_vram_create()
209 if (!gem->funcs) in drm_gem_vram_create()
210 gem->funcs = &drm_gem_vram_object_funcs; in drm_gem_vram_create()
218 bdev = &vmm->bdev; in drm_gem_vram_create()
220 gbo->bo.bdev = bdev; in drm_gem_vram_create()
225 * to release gbo->bo.base and kfree gbo. in drm_gem_vram_create()
227 ret = ttm_bo_init_validate(bdev, &gbo->bo, ttm_bo_type_device, in drm_gem_vram_create()
228 &gbo->placement, pg_align, false, NULL, NULL, in drm_gem_vram_create()
238 * drm_gem_vram_put() - Releases a reference to a VRAM-backed GEM object
245 ttm_bo_put(&gbo->bo); in drm_gem_vram_put()
252 if (WARN_ON_ONCE(!gbo->bo.resource || in drm_gem_vram_pg_offset()
253 gbo->bo.resource->mem_type == TTM_PL_SYSTEM)) in drm_gem_vram_pg_offset()
256 return gbo->bo.resource->start; in drm_gem_vram_pg_offset()
260 * drm_gem_vram_offset() - Returns a GEM VRAM object's offset in video memory
268 * a negative errno code otherwise.
272 if (WARN_ON_ONCE(!gbo->bo.pin_count)) in drm_gem_vram_offset()
273 return (s64)-ENODEV; in drm_gem_vram_offset()
279 unsigned long pl_flag) in drm_gem_vram_pin_locked()
284 dma_resv_assert_held(gbo->bo.base.resv); in drm_gem_vram_pin_locked()
286 if (gbo->bo.pin_count) in drm_gem_vram_pin_locked()
292 ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx); in drm_gem_vram_pin_locked()
297 ttm_bo_pin(&gbo->bo); in drm_gem_vram_pin_locked()
303 * drm_gem_vram_pin() - Pins a GEM VRAM object in a region.
310 * the buffer is pinned at its current location (video RAM or system
314 * fragmentation if they are pinned in the middle of video RAM. This
316 * video RAM. Fragmentation can prevent the primary framebuffer from
323 * a negative error code otherwise.
325 int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag) in drm_gem_vram_pin()
329 ret = ttm_bo_reserve(&gbo->bo, true, false, NULL); in drm_gem_vram_pin()
333 ttm_bo_unreserve(&gbo->bo); in drm_gem_vram_pin()
341 dma_resv_assert_held(gbo->bo.base.resv); in drm_gem_vram_unpin_locked()
343 ttm_bo_unpin(&gbo->bo); in drm_gem_vram_unpin_locked()
347 * drm_gem_vram_unpin() - Unpins a GEM VRAM object
352 * a negative error code otherwise.
358 ret = ttm_bo_reserve(&gbo->bo, true, false, NULL); in drm_gem_vram_unpin()
363 ttm_bo_unreserve(&gbo->bo); in drm_gem_vram_unpin()
370 * drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address
383 * 0 on success, or a negative error code otherwise.
389 dma_resv_assert_held(gbo->bo.base.resv); in drm_gem_vram_vmap()
391 if (gbo->vmap_use_count > 0) in drm_gem_vram_vmap()
399 if (iosys_map_is_null(&gbo->map)) { in drm_gem_vram_vmap()
400 ret = ttm_bo_vmap(&gbo->bo, &gbo->map); in drm_gem_vram_vmap()
406 ++gbo->vmap_use_count; in drm_gem_vram_vmap()
407 *map = gbo->map; in drm_gem_vram_vmap()
414 * drm_gem_vram_vunmap() - Unmaps and unpins a GEM VRAM object
424 struct drm_device *dev = gbo->bo.base.dev; in drm_gem_vram_vunmap()
426 dma_resv_assert_held(gbo->bo.base.resv); in drm_gem_vram_vunmap()
428 if (drm_WARN_ON_ONCE(dev, !gbo->vmap_use_count)) in drm_gem_vram_vunmap()
431 if (drm_WARN_ON_ONCE(dev, !iosys_map_is_equal(&gbo->map, map))) in drm_gem_vram_vunmap()
434 if (--gbo->vmap_use_count > 0) in drm_gem_vram_vunmap()
447 * drm_gem_vram_fill_create_dumb() - Helper for implementing
459 * should forwards their arguments to this helper, plus the driver-specific
464 * a negative error code otherwise.
468 unsigned long pg_align, in drm_gem_vram_fill_create_dumb()
469 unsigned long pitch_align, in drm_gem_vram_fill_create_dumb()
477 pitch = args->width * DIV_ROUND_UP(args->bpp, 8); in drm_gem_vram_fill_create_dumb()
480 return -EINVAL; in drm_gem_vram_fill_create_dumb()
483 size = pitch * args->height; in drm_gem_vram_fill_create_dumb()
487 return -EINVAL; in drm_gem_vram_fill_create_dumb()
493 ret = drm_gem_handle_create(file, &gbo->bo.base, &handle); in drm_gem_vram_fill_create_dumb()
497 drm_gem_object_put(&gbo->bo.base); in drm_gem_vram_fill_create_dumb()
499 args->pitch = pitch; in drm_gem_vram_fill_create_dumb()
500 args->size = size; in drm_gem_vram_fill_create_dumb()
501 args->handle = handle; in drm_gem_vram_fill_create_dumb()
506 drm_gem_object_put(&gbo->bo.base); in drm_gem_vram_fill_create_dumb()
517 return (bo->destroy == ttm_buffer_object_destroy); in drm_is_gem_vram()
524 *pl = gbo->placement; in drm_gem_vram_bo_driver_evict_flags()
529 struct ttm_buffer_object *bo = &gbo->bo; in drm_gem_vram_bo_driver_move_notify()
530 struct drm_device *dev = bo->base.dev; in drm_gem_vram_bo_driver_move_notify()
532 if (drm_WARN_ON_ONCE(dev, gbo->vmap_use_count)) in drm_gem_vram_bo_driver_move_notify()
535 ttm_bo_vunmap(bo, &gbo->map); in drm_gem_vram_bo_driver_move_notify()
536 iosys_map_clear(&gbo->map); /* explicitly clear mapping for next vmap call */ in drm_gem_vram_bo_driver_move_notify()
545 return ttm_bo_move_memcpy(&gbo->bo, ctx, new_mem); in drm_gem_vram_bo_driver_move()
553 * drm_gem_vram_object_free() - Implements &struct drm_gem_object_funcs.free
568 * drm_gem_vram_driver_dumb_create() - Implements &struct drm_driver.dumb_create
579 * a negative error code otherwise.
585 if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized")) in drm_gem_vram_driver_dumb_create()
586 return -EINVAL; in drm_gem_vram_driver_dumb_create()
602 struct drm_framebuffer *fb = state->fb; in __drm_gem_vram_plane_helper_cleanup_fb()
605 --num_planes; in __drm_gem_vram_plane_helper_cleanup_fb()
615 * drm_gem_vram_plane_helper_prepare_fb() - Implements &struct
626 * a negative errno code otherwise.
632 struct drm_framebuffer *fb = new_state->fb; in drm_gem_vram_plane_helper_prepare_fb()
641 for (i = 0; i < fb->format->num_planes; ++i) { in drm_gem_vram_plane_helper_prepare_fb()
644 ret = -EINVAL; in drm_gem_vram_plane_helper_prepare_fb()
666 * drm_gem_vram_plane_helper_cleanup_fb() - Implements &struct
679 struct drm_framebuffer *fb = old_state->fb; in drm_gem_vram_plane_helper_cleanup_fb()
684 __drm_gem_vram_plane_helper_cleanup_fb(plane, old_state, fb->format->num_planes); in drm_gem_vram_plane_helper_cleanup_fb()
693 * drm_gem_vram_object_pin() - Implements &struct drm_gem_object_funcs.pin
698 * a negative errno code otherwise.
708 * (either video RAM or system memory) to prevent it from in drm_gem_vram_object_pin()
717 * drm_gem_vram_object_unpin() - Implements &struct drm_gem_object_funcs.unpin
728 * drm_gem_vram_object_vmap() -
735 * 0 on success, or a negative error code otherwise.
746 * drm_gem_vram_object_vunmap() -
847 if (!bo->resource) { in bo_driver_move()
848 if (new_mem->mem_type != TTM_PL_SYSTEM) { in bo_driver_move()
849 hop->mem_type = TTM_PL_SYSTEM; in bo_driver_move()
850 hop->flags = TTM_PL_FLAG_TEMPORARY; in bo_driver_move()
851 return -EMULTIHOP; in bo_driver_move()
868 switch (mem->mem_type) { in bo_driver_io_mem_reserve()
872 mem->bus.offset = (mem->start << PAGE_SHIFT) + vmm->vram_base; in bo_driver_io_mem_reserve()
873 mem->bus.is_iomem = true; in bo_driver_io_mem_reserve()
874 mem->bus.caching = ttm_write_combined; in bo_driver_io_mem_reserve()
877 return -EINVAL; in bo_driver_io_mem_reserve()
899 struct drm_debugfs_entry *entry = m->private; in drm_vram_mm_debugfs()
900 struct drm_vram_mm *vmm = entry->dev->vram_mm; in drm_vram_mm_debugfs()
901 struct ttm_resource_manager *man = ttm_manager_type(&vmm->bdev, TTM_PL_VRAM); in drm_vram_mm_debugfs()
909 { "vram-mm", drm_vram_mm_debugfs, 0, NULL },
913 * drm_vram_mm_debugfs_init() - Register VRAM MM debugfs file.
920 drm_debugfs_add_files(minor->dev, drm_vram_mm_debugfs_list, in drm_vram_mm_debugfs_init()
930 vmm->vram_base = vram_base; in drm_vram_mm_init()
931 vmm->vram_size = vram_size; in drm_vram_mm_init()
933 ret = ttm_device_init(&vmm->bdev, &bo_driver, dev->dev, in drm_vram_mm_init()
934 dev->anon_inode->i_mapping, in drm_vram_mm_init()
935 dev->vma_offset_manager, in drm_vram_mm_init()
940 ret = ttm_range_man_init(&vmm->bdev, TTM_PL_VRAM, in drm_vram_mm_init()
950 ttm_range_man_fini(&vmm->bdev, TTM_PL_VRAM); in drm_vram_mm_cleanup()
951 ttm_device_fini(&vmm->bdev); in drm_vram_mm_cleanup()
963 if (WARN_ON(dev->vram_mm)) in drm_vram_helper_alloc_mm()
964 return dev->vram_mm; in drm_vram_helper_alloc_mm()
966 dev->vram_mm = kzalloc(sizeof(*dev->vram_mm), GFP_KERNEL); in drm_vram_helper_alloc_mm()
967 if (!dev->vram_mm) in drm_vram_helper_alloc_mm()
968 return ERR_PTR(-ENOMEM); in drm_vram_helper_alloc_mm()
970 ret = drm_vram_mm_init(dev->vram_mm, dev, vram_base, vram_size); in drm_vram_helper_alloc_mm()
974 return dev->vram_mm; in drm_vram_helper_alloc_mm()
977 kfree(dev->vram_mm); in drm_vram_helper_alloc_mm()
978 dev->vram_mm = NULL; in drm_vram_helper_alloc_mm()
984 if (!dev->vram_mm) in drm_vram_helper_release_mm()
987 drm_vram_mm_cleanup(dev->vram_mm); in drm_vram_helper_release_mm()
988 kfree(dev->vram_mm); in drm_vram_helper_release_mm()
989 dev->vram_mm = NULL; in drm_vram_helper_release_mm()
998 * drmm_vram_helper_init - Initializes a device's instance of
1005 * struct &drm_device.vram_mm. The instance is auto-managed and cleaned
1010 * 0 on success, or a negative errno code otherwise.
1017 if (drm_WARN_ON_ONCE(dev, dev->vram_mm)) in drmm_vram_helper_init()
1028 * Mode-config helpers
1034 unsigned long max_bpp) in drm_vram_helper_mode_valid_internal()
1036 struct drm_vram_mm *vmm = dev->vram_mm; in drm_vram_helper_mode_valid_internal()
1037 unsigned long fbsize, fbpages, max_fbpages; in drm_vram_helper_mode_valid_internal()
1039 if (WARN_ON(!dev->vram_mm)) in drm_vram_helper_mode_valid_internal()
1042 max_fbpages = (vmm->vram_size / 2) >> PAGE_SHIFT; in drm_vram_helper_mode_valid_internal()
1044 fbsize = mode->hdisplay * mode->vdisplay * max_bpp; in drm_vram_helper_mode_valid_internal()
1054 * drm_vram_helper_mode_valid - Tests if a display mode's
1065 * have 32-bit color depth.
1071 * 32-bit fits all current use case. A more flexible test can be added
1075 * MODE_OK if the display mode is supported, or an error code of type
1082 static const unsigned long max_bpp = 4; /* DRM_FORMAT_XRGB8888 */ in drm_vram_helper_mode_valid()
1088 MODULE_DESCRIPTION("DRM VRAM memory-management helpers");