Lines Matching +full:use +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
42 * contains dedicated video memory, the DRM driver can use the VRAM helper
43 * library. Each active buffer object is stored in video RAM. Active
50 * in &struct drm_device.vram_mm . Use &DRM_GEM_VRAM_DRIVER to initialize
54 * .. code-block:: c
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
100 * the cursor overlay's image for a mouse cursor, or use it as input to the
105 * space and returns the memory address. Use drm_gem_vram_vunmap() to
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()
149 gbo->placement.placement = gbo->placements; in drm_gem_vram_placement()
150 gbo->placement.busy_placement = gbo->placements; in drm_gem_vram_placement()
153 gbo->placements[c].mem_type = TTM_PL_VRAM; in drm_gem_vram_placement()
154 gbo->placements[c++].flags = invariant_flags; in drm_gem_vram_placement()
158 gbo->placements[c].mem_type = TTM_PL_SYSTEM; in drm_gem_vram_placement()
159 gbo->placements[c++].flags = invariant_flags; in drm_gem_vram_placement()
162 gbo->placement.num_placement = c; in drm_gem_vram_placement()
163 gbo->placement.num_busy_placement = c; in drm_gem_vram_placement()
166 gbo->placements[i].fpfn = 0; in drm_gem_vram_placement()
167 gbo->placements[i].lpfn = 0; in drm_gem_vram_placement()
172 * drm_gem_vram_create() - Creates a VRAM-backed GEM object
180 * are set, the new GEM object will use the default functions from GEM VRAM
185 * an ERR_PTR()-encoded error code otherwise.
193 struct drm_vram_mm *vmm = dev->vram_mm; in drm_gem_vram_create()
198 return ERR_PTR(-EINVAL); in drm_gem_vram_create()
200 if (dev->driver->gem_create_object) { in drm_gem_vram_create()
201 gem = dev->driver->gem_create_object(dev, size); in drm_gem_vram_create()
208 return ERR_PTR(-ENOMEM); in drm_gem_vram_create()
209 gem = &gbo->bo.base; in drm_gem_vram_create()
212 if (!gem->funcs) in drm_gem_vram_create()
213 gem->funcs = &drm_gem_vram_object_funcs; in drm_gem_vram_create()
221 bdev = &vmm->bdev; in drm_gem_vram_create()
223 gbo->bo.bdev = bdev; in drm_gem_vram_create()
228 * to release gbo->bo.base and kfree gbo. in drm_gem_vram_create()
230 ret = ttm_bo_init_validate(bdev, &gbo->bo, ttm_bo_type_device, in drm_gem_vram_create()
231 &gbo->placement, pg_align, false, NULL, NULL, in drm_gem_vram_create()
241 * drm_gem_vram_put() - Releases a reference to a VRAM-backed GEM object
248 ttm_bo_put(&gbo->bo); in drm_gem_vram_put()
255 if (WARN_ON_ONCE(!gbo->bo.resource || in drm_gem_vram_pg_offset()
256 gbo->bo.resource->mem_type == TTM_PL_SYSTEM)) in drm_gem_vram_pg_offset()
259 return gbo->bo.resource->start; in drm_gem_vram_pg_offset()
263 * drm_gem_vram_offset() - \
272 * a negative errno code otherwise.
276 if (WARN_ON_ONCE(!gbo->bo.pin_count)) in drm_gem_vram_offset()
277 return (s64)-ENODEV; in drm_gem_vram_offset()
288 if (gbo->bo.pin_count) in drm_gem_vram_pin_locked()
294 ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx); in drm_gem_vram_pin_locked()
299 ttm_bo_pin(&gbo->bo); in drm_gem_vram_pin_locked()
305 * drm_gem_vram_pin() - Pins a GEM VRAM object in a region.
312 * the buffer is pinned at its current location (video RAM or system
316 * fragmentation if they are pinned in the middle of video RAM. This
318 * video RAM. Fragmentation can prevent the primary framebuffer from
325 * a negative error code otherwise.
331 ret = ttm_bo_reserve(&gbo->bo, true, false, NULL); in drm_gem_vram_pin()
335 ttm_bo_unreserve(&gbo->bo); in drm_gem_vram_pin()
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()
374 if (gbo->vmap_use_count > 0) in drm_gem_vram_kmap_locked()
382 if (iosys_map_is_null(&gbo->map)) { in drm_gem_vram_kmap_locked()
383 ret = ttm_bo_vmap(&gbo->bo, &gbo->map); in drm_gem_vram_kmap_locked()
389 ++gbo->vmap_use_count; in drm_gem_vram_kmap_locked()
390 *map = gbo->map; in drm_gem_vram_kmap_locked()
398 struct drm_device *dev = gbo->bo.base.dev; in drm_gem_vram_kunmap_locked()
400 if (drm_WARN_ON_ONCE(dev, !gbo->vmap_use_count)) in drm_gem_vram_kunmap_locked()
403 if (drm_WARN_ON_ONCE(dev, !iosys_map_is_equal(&gbo->map, map))) in drm_gem_vram_kunmap_locked()
406 if (--gbo->vmap_use_count > 0) in drm_gem_vram_kunmap_locked()
418 * drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address
431 * 0 on success, or a negative error code otherwise.
437 dma_resv_assert_held(gbo->bo.base.resv); in drm_gem_vram_vmap()
455 * drm_gem_vram_vunmap() - Unmaps and unpins a GEM VRAM object
465 dma_resv_assert_held(gbo->bo.base.resv); in drm_gem_vram_vunmap()
473 * drm_gem_vram_fill_create_dumb() - \
484 * should forwards their arguments to this helper, plus the driver-specific
489 * a negative error code otherwise.
502 pitch = args->width * DIV_ROUND_UP(args->bpp, 8); in drm_gem_vram_fill_create_dumb()
505 return -EINVAL; in drm_gem_vram_fill_create_dumb()
508 size = pitch * args->height; in drm_gem_vram_fill_create_dumb()
512 return -EINVAL; in drm_gem_vram_fill_create_dumb()
518 ret = drm_gem_handle_create(file, &gbo->bo.base, &handle); in drm_gem_vram_fill_create_dumb()
522 drm_gem_object_put(&gbo->bo.base); in drm_gem_vram_fill_create_dumb()
524 args->pitch = pitch; in drm_gem_vram_fill_create_dumb()
525 args->size = size; in drm_gem_vram_fill_create_dumb()
526 args->handle = handle; in drm_gem_vram_fill_create_dumb()
531 drm_gem_object_put(&gbo->bo.base); in drm_gem_vram_fill_create_dumb()
542 return (bo->destroy == ttm_buffer_object_destroy); in drm_is_gem_vram()
549 *pl = gbo->placement; in drm_gem_vram_bo_driver_evict_flags()
554 struct ttm_buffer_object *bo = &gbo->bo; in drm_gem_vram_bo_driver_move_notify()
555 struct drm_device *dev = bo->base.dev; in drm_gem_vram_bo_driver_move_notify()
557 if (drm_WARN_ON_ONCE(dev, gbo->vmap_use_count)) in drm_gem_vram_bo_driver_move_notify()
560 ttm_bo_vunmap(bo, &gbo->map); in drm_gem_vram_bo_driver_move_notify()
561 iosys_map_clear(&gbo->map); /* explicitly clear mapping for next vmap call */ in drm_gem_vram_bo_driver_move_notify()
570 return ttm_bo_move_memcpy(&gbo->bo, ctx, new_mem); in drm_gem_vram_bo_driver_move()
578 * drm_gem_vram_object_free() - \
594 * drm_gem_vram_driver_dumb_create() - \
601 * This function requires the driver to use @drm_device.vram_mm for its
606 * a negative error code otherwise.
612 if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized")) in drm_gem_vram_driver_dumb_create()
613 return -EINVAL; in drm_gem_vram_driver_dumb_create()
629 struct drm_framebuffer *fb = state->fb; in __drm_gem_vram_plane_helper_cleanup_fb()
632 --num_planes; in __drm_gem_vram_plane_helper_cleanup_fb()
642 * drm_gem_vram_plane_helper_prepare_fb() - \
653 * a negative errno code otherwise.
659 struct drm_framebuffer *fb = new_state->fb; in drm_gem_vram_plane_helper_prepare_fb()
668 for (i = 0; i < fb->format->num_planes; ++i) { in drm_gem_vram_plane_helper_prepare_fb()
671 ret = -EINVAL; in drm_gem_vram_plane_helper_prepare_fb()
693 * drm_gem_vram_plane_helper_cleanup_fb() - \
706 struct drm_framebuffer *fb = old_state->fb; in drm_gem_vram_plane_helper_cleanup_fb()
711 __drm_gem_vram_plane_helper_cleanup_fb(plane, old_state, fb->format->num_planes); in drm_gem_vram_plane_helper_cleanup_fb()
720 * drm_gem_vram_simple_display_pipe_prepare_fb() - \
731 * a negative errno code otherwise.
737 return drm_gem_vram_plane_helper_prepare_fb(&pipe->plane, new_state); in drm_gem_vram_simple_display_pipe_prepare_fb()
742 * drm_gem_vram_simple_display_pipe_cleanup_fb() - \
755 drm_gem_vram_plane_helper_cleanup_fb(&pipe->plane, old_state); in drm_gem_vram_simple_display_pipe_cleanup_fb()
764 * drm_gem_vram_object_pin() - \
770 * a negative errno code otherwise.
776 /* Fbdev console emulation is the use case of these PRIME in drm_gem_vram_object_pin()
779 * (either video RAM or system memory) to prevent it from in drm_gem_vram_object_pin()
788 * drm_gem_vram_object_unpin() - \
800 * drm_gem_vram_object_vmap() -
807 * 0 on success, or a negative error code otherwise.
818 * drm_gem_vram_object_vunmap() -
919 if (!bo->resource) { in bo_driver_move()
920 if (new_mem->mem_type != TTM_PL_SYSTEM) { in bo_driver_move()
921 hop->mem_type = TTM_PL_SYSTEM; in bo_driver_move()
922 hop->flags = TTM_PL_FLAG_TEMPORARY; in bo_driver_move()
923 return -EMULTIHOP; in bo_driver_move()
940 switch (mem->mem_type) { in bo_driver_io_mem_reserve()
944 mem->bus.offset = (mem->start << PAGE_SHIFT) + vmm->vram_base; in bo_driver_io_mem_reserve()
945 mem->bus.is_iomem = true; in bo_driver_io_mem_reserve()
946 mem->bus.caching = ttm_write_combined; in bo_driver_io_mem_reserve()
949 return -EINVAL; in bo_driver_io_mem_reserve()
971 struct drm_debugfs_entry *entry = m->private; in drm_vram_mm_debugfs()
972 struct drm_vram_mm *vmm = entry->dev->vram_mm; in drm_vram_mm_debugfs()
973 struct ttm_resource_manager *man = ttm_manager_type(&vmm->bdev, TTM_PL_VRAM); in drm_vram_mm_debugfs()
981 { "vram-mm", drm_vram_mm_debugfs, 0, NULL },
985 * drm_vram_mm_debugfs_init() - Register VRAM MM debugfs file.
992 drm_debugfs_add_files(minor->dev, drm_vram_mm_debugfs_list, in drm_vram_mm_debugfs_init()
1002 vmm->vram_base = vram_base; in drm_vram_mm_init()
1003 vmm->vram_size = vram_size; in drm_vram_mm_init()
1005 ret = ttm_device_init(&vmm->bdev, &bo_driver, dev->dev, in drm_vram_mm_init()
1006 dev->anon_inode->i_mapping, in drm_vram_mm_init()
1007 dev->vma_offset_manager, in drm_vram_mm_init()
1012 ret = ttm_range_man_init(&vmm->bdev, TTM_PL_VRAM, in drm_vram_mm_init()
1022 ttm_range_man_fini(&vmm->bdev, TTM_PL_VRAM); in drm_vram_mm_cleanup()
1023 ttm_device_fini(&vmm->bdev); in drm_vram_mm_cleanup()
1035 if (WARN_ON(dev->vram_mm)) in drm_vram_helper_alloc_mm()
1036 return dev->vram_mm; in drm_vram_helper_alloc_mm()
1038 dev->vram_mm = kzalloc(sizeof(*dev->vram_mm), GFP_KERNEL); in drm_vram_helper_alloc_mm()
1039 if (!dev->vram_mm) in drm_vram_helper_alloc_mm()
1040 return ERR_PTR(-ENOMEM); in drm_vram_helper_alloc_mm()
1042 ret = drm_vram_mm_init(dev->vram_mm, dev, vram_base, vram_size); in drm_vram_helper_alloc_mm()
1046 return dev->vram_mm; in drm_vram_helper_alloc_mm()
1049 kfree(dev->vram_mm); in drm_vram_helper_alloc_mm()
1050 dev->vram_mm = NULL; in drm_vram_helper_alloc_mm()
1056 if (!dev->vram_mm) in drm_vram_helper_release_mm()
1059 drm_vram_mm_cleanup(dev->vram_mm); in drm_vram_helper_release_mm()
1060 kfree(dev->vram_mm); in drm_vram_helper_release_mm()
1061 dev->vram_mm = NULL; in drm_vram_helper_release_mm()
1070 * drmm_vram_helper_init - Initializes a device's instance of
1077 * struct &drm_device.vram_mm. The instance is auto-managed and cleaned
1082 * 0 on success, or a negative errno code otherwise.
1089 if (drm_WARN_ON_ONCE(dev, dev->vram_mm)) in drmm_vram_helper_init()
1100 * Mode-config helpers
1108 struct drm_vram_mm *vmm = dev->vram_mm; in drm_vram_helper_mode_valid_internal()
1111 if (WARN_ON(!dev->vram_mm)) in drm_vram_helper_mode_valid_internal()
1114 max_fbpages = (vmm->vram_size / 2) >> PAGE_SHIFT; in drm_vram_helper_mode_valid_internal()
1116 fbsize = mode->hdisplay * mode->vdisplay * max_bpp; in drm_vram_helper_mode_valid_internal()
1126 * drm_vram_helper_mode_valid - Tests if a display mode's
1137 * have 32-bit color depth.
1143 * 32-bit fits all current use case. A more flexible test can be added
1147 * MODE_OK if the display mode is supported, or an error code of type
1160 MODULE_DESCRIPTION("DRM VRAM memory-management helpers");