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>
30 * buffer object that is backed by video RAM (VRAM). It can be used for
39 * graphics buffers, such as an on-screen framebuffer. GEM does not provide
43 * library. Each active buffer object is stored in video RAM. Active
54 * .. code-block:: c
70 * unsigned long vram_size;
85 * manages an area of video RAM with VRAM MM and provides GEM VRAM objects
90 * clean-up handler to run during the DRM device's release.
93 * in video RAM. Call drm_gem_vram_pin() with &DRM_GEM_VRAM_PL_FLAG_VRAM or
94 * &DRM_GEM_VRAM_PL_FLAG_SYSTEM to pin a buffer object in video RAM or system
97 * A buffer object that is pinned in video RAM has a fixed address within that
110 * Buffer-objects helpers
120 WARN_ON(gbo->vmap_use_count); in drm_gem_vram_cleanup()
121 WARN_ON(iosys_map_is_set(&gbo->map)); in drm_gem_vram_cleanup()
123 drm_gem_object_release(&gbo->bo.base); in drm_gem_vram_cleanup()
140 unsigned long pl_flag) in drm_gem_vram_placement()
149 gbo->placement.placement = gbo->placements; in drm_gem_vram_placement()
152 gbo->placements[c].mem_type = TTM_PL_VRAM; in drm_gem_vram_placement()
153 gbo->placements[c++].flags = invariant_flags; in drm_gem_vram_placement()
157 gbo->placements[c].mem_type = TTM_PL_SYSTEM; in drm_gem_vram_placement()
158 gbo->placements[c++].flags = invariant_flags; in drm_gem_vram_placement()
161 gbo->placement.num_placement = c; in drm_gem_vram_placement()
164 gbo->placements[i].fpfn = 0; in drm_gem_vram_placement()
165 gbo->placements[i].lpfn = 0; in drm_gem_vram_placement()
170 * drm_gem_vram_create() - Creates a VRAM-backed GEM object
183 * an ERR_PTR()-encoded error code otherwise.
187 unsigned long pg_align) in drm_gem_vram_create()
191 struct drm_vram_mm *vmm = dev->vram_mm; in drm_gem_vram_create()
196 return ERR_PTR(-EINVAL); in drm_gem_vram_create()
198 if (dev->driver->gem_create_object) { in drm_gem_vram_create()
199 gem = dev->driver->gem_create_object(dev, size); in drm_gem_vram_create()
206 return ERR_PTR(-ENOMEM); in drm_gem_vram_create()
207 gem = &gbo->bo.base; in drm_gem_vram_create()
210 if (!gem->funcs) in drm_gem_vram_create()
211 gem->funcs = &drm_gem_vram_object_funcs; in drm_gem_vram_create()
219 bdev = &vmm->bdev; in drm_gem_vram_create()
221 gbo->bo.bdev = bdev; in drm_gem_vram_create()
226 * to release gbo->bo.base and kfree gbo. in drm_gem_vram_create()
228 ret = ttm_bo_init_validate(bdev, &gbo->bo, ttm_bo_type_device, in drm_gem_vram_create()
229 &gbo->placement, pg_align, false, NULL, NULL, in drm_gem_vram_create()
239 * drm_gem_vram_put() - Releases a reference to a VRAM-backed GEM object
246 ttm_bo_put(&gbo->bo); in drm_gem_vram_put()
253 if (WARN_ON_ONCE(!gbo->bo.resource || in drm_gem_vram_pg_offset()
254 gbo->bo.resource->mem_type == TTM_PL_SYSTEM)) in drm_gem_vram_pg_offset()
257 return gbo->bo.resource->start; in drm_gem_vram_pg_offset()
261 * drm_gem_vram_offset() - Returns a GEM VRAM object's offset in video memory
269 * a negative errno code otherwise.
273 if (WARN_ON_ONCE(!gbo->bo.pin_count)) in drm_gem_vram_offset()
274 return (s64)-ENODEV; in drm_gem_vram_offset()
280 unsigned long pl_flag) in drm_gem_vram_pin_locked()
285 dma_resv_assert_held(gbo->bo.base.resv); in drm_gem_vram_pin_locked()
287 if (gbo->bo.pin_count) in drm_gem_vram_pin_locked()
293 ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx); in drm_gem_vram_pin_locked()
298 ttm_bo_pin(&gbo->bo); in drm_gem_vram_pin_locked()
304 * drm_gem_vram_pin() - Pins a GEM VRAM object in a region.
311 * the buffer is pinned at its current location (video RAM or system
315 * fragmentation if they are pinned in the middle of video RAM. This
317 * video RAM. Fragmentation can prevent the primary framebuffer from
324 * a negative error code otherwise.
326 int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag) in drm_gem_vram_pin()
330 ret = ttm_bo_reserve(&gbo->bo, true, false, NULL); in drm_gem_vram_pin()
334 ttm_bo_unreserve(&gbo->bo); in drm_gem_vram_pin()
342 dma_resv_assert_held(gbo->bo.base.resv); in drm_gem_vram_unpin_locked()
344 ttm_bo_unpin(&gbo->bo); in drm_gem_vram_unpin_locked()
348 * drm_gem_vram_unpin() - Unpins a GEM VRAM object
353 * a negative error code otherwise.
359 ret = ttm_bo_reserve(&gbo->bo, true, false, NULL); in drm_gem_vram_unpin()
364 ttm_bo_unreserve(&gbo->bo); in drm_gem_vram_unpin()
371 * drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address
384 * 0 on success, or a negative error code otherwise.
390 dma_resv_assert_held(gbo->bo.base.resv); in drm_gem_vram_vmap()
392 if (gbo->vmap_use_count > 0) in drm_gem_vram_vmap()
400 if (iosys_map_is_null(&gbo->map)) { in drm_gem_vram_vmap()
401 ret = ttm_bo_vmap(&gbo->bo, &gbo->map); in drm_gem_vram_vmap()
407 ++gbo->vmap_use_count; in drm_gem_vram_vmap()
408 *map = gbo->map; in drm_gem_vram_vmap()
415 * drm_gem_vram_vunmap() - Unmaps and unpins a GEM VRAM object
425 struct drm_device *dev = gbo->bo.base.dev; in drm_gem_vram_vunmap()
427 dma_resv_assert_held(gbo->bo.base.resv); in drm_gem_vram_vunmap()
429 if (drm_WARN_ON_ONCE(dev, !gbo->vmap_use_count)) in drm_gem_vram_vunmap()
432 if (drm_WARN_ON_ONCE(dev, !iosys_map_is_equal(&gbo->map, map))) in drm_gem_vram_vunmap()
435 if (--gbo->vmap_use_count > 0) in drm_gem_vram_vunmap()
448 * drm_gem_vram_fill_create_dumb() - Helper for implementing
460 * should forwards their arguments to this helper, plus the driver-specific
465 * a negative error code otherwise.
469 unsigned long pg_align, in drm_gem_vram_fill_create_dumb()
470 unsigned long pitch_align, in drm_gem_vram_fill_create_dumb()
478 pitch = args->width * DIV_ROUND_UP(args->bpp, 8); in drm_gem_vram_fill_create_dumb()
481 return -EINVAL; in drm_gem_vram_fill_create_dumb()
484 size = pitch * args->height; in drm_gem_vram_fill_create_dumb()
488 return -EINVAL; in drm_gem_vram_fill_create_dumb()
494 ret = drm_gem_handle_create(file, &gbo->bo.base, &handle); in drm_gem_vram_fill_create_dumb()
498 drm_gem_object_put(&gbo->bo.base); in drm_gem_vram_fill_create_dumb()
500 args->pitch = pitch; in drm_gem_vram_fill_create_dumb()
501 args->size = size; in drm_gem_vram_fill_create_dumb()
502 args->handle = handle; in drm_gem_vram_fill_create_dumb()
507 drm_gem_object_put(&gbo->bo.base); in drm_gem_vram_fill_create_dumb()
518 return (bo->destroy == ttm_buffer_object_destroy); in drm_is_gem_vram()
525 *pl = gbo->placement; in drm_gem_vram_bo_driver_evict_flags()
530 struct ttm_buffer_object *bo = &gbo->bo; in drm_gem_vram_bo_driver_move_notify()
531 struct drm_device *dev = bo->base.dev; in drm_gem_vram_bo_driver_move_notify()
533 if (drm_WARN_ON_ONCE(dev, gbo->vmap_use_count)) in drm_gem_vram_bo_driver_move_notify()
536 ttm_bo_vunmap(bo, &gbo->map); in drm_gem_vram_bo_driver_move_notify()
537 iosys_map_clear(&gbo->map); /* explicitly clear mapping for next vmap call */ in drm_gem_vram_bo_driver_move_notify()
546 return ttm_bo_move_memcpy(&gbo->bo, ctx, new_mem); in drm_gem_vram_bo_driver_move()
554 * drm_gem_vram_object_free() - Implements &struct drm_gem_object_funcs.free
569 * drm_gem_vram_driver_dumb_create() - Implements &struct drm_driver.dumb_create
580 * a negative error code otherwise.
586 if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized")) in drm_gem_vram_driver_dumb_create()
587 return -EINVAL; in drm_gem_vram_driver_dumb_create()
603 struct drm_framebuffer *fb = state->fb; in __drm_gem_vram_plane_helper_cleanup_fb()
606 --num_planes; in __drm_gem_vram_plane_helper_cleanup_fb()
616 * drm_gem_vram_plane_helper_prepare_fb() - Implements &struct
627 * a negative errno code otherwise.
633 struct drm_framebuffer *fb = new_state->fb; in drm_gem_vram_plane_helper_prepare_fb()
642 for (i = 0; i < fb->format->num_planes; ++i) { in drm_gem_vram_plane_helper_prepare_fb()
645 ret = -EINVAL; in drm_gem_vram_plane_helper_prepare_fb()
667 * drm_gem_vram_plane_helper_cleanup_fb() - Implements &struct
680 struct drm_framebuffer *fb = old_state->fb; in drm_gem_vram_plane_helper_cleanup_fb()
685 __drm_gem_vram_plane_helper_cleanup_fb(plane, old_state, fb->format->num_planes); in drm_gem_vram_plane_helper_cleanup_fb()
694 * drm_gem_vram_simple_display_pipe_prepare_fb() - Implements &struct
705 * a negative errno code otherwise.
711 return drm_gem_vram_plane_helper_prepare_fb(&pipe->plane, new_state); in drm_gem_vram_simple_display_pipe_prepare_fb()
716 * drm_gem_vram_simple_display_pipe_cleanup_fb() - Implements &struct
729 drm_gem_vram_plane_helper_cleanup_fb(&pipe->plane, old_state); in drm_gem_vram_simple_display_pipe_cleanup_fb()
738 * drm_gem_vram_object_pin() - Implements &struct drm_gem_object_funcs.pin
743 * a negative errno code otherwise.
753 * (either video RAM or system memory) to prevent it from in drm_gem_vram_object_pin()
762 * drm_gem_vram_object_unpin() - Implements &struct drm_gem_object_funcs.unpin
773 * drm_gem_vram_object_vmap() -
780 * 0 on success, or a negative error code otherwise.
791 * drm_gem_vram_object_vunmap() -
892 if (!bo->resource) { in bo_driver_move()
893 if (new_mem->mem_type != TTM_PL_SYSTEM) { in bo_driver_move()
894 hop->mem_type = TTM_PL_SYSTEM; in bo_driver_move()
895 hop->flags = TTM_PL_FLAG_TEMPORARY; in bo_driver_move()
896 return -EMULTIHOP; in bo_driver_move()
913 switch (mem->mem_type) { in bo_driver_io_mem_reserve()
917 mem->bus.offset = (mem->start << PAGE_SHIFT) + vmm->vram_base; in bo_driver_io_mem_reserve()
918 mem->bus.is_iomem = true; in bo_driver_io_mem_reserve()
919 mem->bus.caching = ttm_write_combined; in bo_driver_io_mem_reserve()
922 return -EINVAL; in bo_driver_io_mem_reserve()
944 struct drm_debugfs_entry *entry = m->private; in drm_vram_mm_debugfs()
945 struct drm_vram_mm *vmm = entry->dev->vram_mm; in drm_vram_mm_debugfs()
946 struct ttm_resource_manager *man = ttm_manager_type(&vmm->bdev, TTM_PL_VRAM); in drm_vram_mm_debugfs()
954 { "vram-mm", drm_vram_mm_debugfs, 0, NULL },
958 * drm_vram_mm_debugfs_init() - Register VRAM MM debugfs file.
965 drm_debugfs_add_files(minor->dev, drm_vram_mm_debugfs_list, in drm_vram_mm_debugfs_init()
975 vmm->vram_base = vram_base; in drm_vram_mm_init()
976 vmm->vram_size = vram_size; in drm_vram_mm_init()
978 ret = ttm_device_init(&vmm->bdev, &bo_driver, dev->dev, in drm_vram_mm_init()
979 dev->anon_inode->i_mapping, in drm_vram_mm_init()
980 dev->vma_offset_manager, in drm_vram_mm_init()
985 ret = ttm_range_man_init(&vmm->bdev, TTM_PL_VRAM, in drm_vram_mm_init()
995 ttm_range_man_fini(&vmm->bdev, TTM_PL_VRAM); in drm_vram_mm_cleanup()
996 ttm_device_fini(&vmm->bdev); in drm_vram_mm_cleanup()
1008 if (WARN_ON(dev->vram_mm)) in drm_vram_helper_alloc_mm()
1009 return dev->vram_mm; in drm_vram_helper_alloc_mm()
1011 dev->vram_mm = kzalloc(sizeof(*dev->vram_mm), GFP_KERNEL); in drm_vram_helper_alloc_mm()
1012 if (!dev->vram_mm) in drm_vram_helper_alloc_mm()
1013 return ERR_PTR(-ENOMEM); in drm_vram_helper_alloc_mm()
1015 ret = drm_vram_mm_init(dev->vram_mm, dev, vram_base, vram_size); in drm_vram_helper_alloc_mm()
1019 return dev->vram_mm; in drm_vram_helper_alloc_mm()
1022 kfree(dev->vram_mm); in drm_vram_helper_alloc_mm()
1023 dev->vram_mm = NULL; in drm_vram_helper_alloc_mm()
1029 if (!dev->vram_mm) in drm_vram_helper_release_mm()
1032 drm_vram_mm_cleanup(dev->vram_mm); in drm_vram_helper_release_mm()
1033 kfree(dev->vram_mm); in drm_vram_helper_release_mm()
1034 dev->vram_mm = NULL; in drm_vram_helper_release_mm()
1043 * drmm_vram_helper_init - Initializes a device's instance of
1050 * struct &drm_device.vram_mm. The instance is auto-managed and cleaned
1055 * 0 on success, or a negative errno code otherwise.
1062 if (drm_WARN_ON_ONCE(dev, dev->vram_mm)) in drmm_vram_helper_init()
1073 * Mode-config helpers
1079 unsigned long max_bpp) in drm_vram_helper_mode_valid_internal()
1081 struct drm_vram_mm *vmm = dev->vram_mm; in drm_vram_helper_mode_valid_internal()
1082 unsigned long fbsize, fbpages, max_fbpages; in drm_vram_helper_mode_valid_internal()
1084 if (WARN_ON(!dev->vram_mm)) in drm_vram_helper_mode_valid_internal()
1087 max_fbpages = (vmm->vram_size / 2) >> PAGE_SHIFT; in drm_vram_helper_mode_valid_internal()
1089 fbsize = mode->hdisplay * mode->vdisplay * max_bpp; in drm_vram_helper_mode_valid_internal()
1099 * drm_vram_helper_mode_valid - Tests if a display mode's
1110 * have 32-bit color depth.
1116 * 32-bit fits all current use case. A more flexible test can be added
1120 * MODE_OK if the display mode is supported, or an error code of type
1127 static const unsigned long max_bpp = 4; /* DRM_FORMAT_XRGB8888 */ in drm_vram_helper_mode_valid()
1133 MODULE_DESCRIPTION("DRM VRAM memory-management helpers");