1 /* SPDX-License-Identifier: MIT */ 2 /* 3 * Copyright © 2021 Intel Corporation 4 */ 5 6 #include <drm/drm_modeset_helper.h> 7 #include <drm/ttm/ttm_bo.h> 8 9 #include "intel_display_types.h" 10 #include "intel_fb_bo.h" 11 #include "xe_bo.h" 12 13 void intel_fb_bo_framebuffer_fini(struct xe_bo *bo) 14 { 15 if (bo->flags & XE_BO_FLAG_PINNED) { 16 /* Unpin our kernel fb first */ 17 xe_bo_lock(bo, false); 18 xe_bo_unpin(bo); 19 xe_bo_unlock(bo); 20 } 21 xe_bo_put(bo); 22 } 23 24 int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, 25 struct xe_bo *bo, 26 struct drm_mode_fb_cmd2 *mode_cmd) 27 { 28 struct xe_device *xe = to_xe_device(bo->ttm.base.dev); 29 int ret; 30 31 xe_bo_get(bo); 32 33 ret = ttm_bo_reserve(&bo->ttm, true, false, NULL); 34 if (ret) 35 goto err; 36 37 if (!(bo->flags & XE_BO_FLAG_SCANOUT)) { 38 /* 39 * XE_BO_FLAG_SCANOUT should ideally be set at creation, or is 40 * automatically set when creating FB. We cannot change caching 41 * mode when the boect is VM_BINDed, so we can only set 42 * coherency with display when unbound. 43 */ 44 if (XE_IOCTL_DBG(xe, !list_empty(&bo->ttm.base.gpuva.list))) { 45 ttm_bo_unreserve(&bo->ttm); 46 ret = -EINVAL; 47 goto err; 48 } 49 bo->flags |= XE_BO_FLAG_SCANOUT; 50 } 51 ttm_bo_unreserve(&bo->ttm); 52 return 0; 53 54 err: 55 xe_bo_put(bo); 56 return ret; 57 } 58 59 struct xe_bo *intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, 60 struct drm_file *filp, 61 const struct drm_mode_fb_cmd2 *mode_cmd) 62 { 63 struct drm_i915_gem_object *bo; 64 struct drm_gem_object *gem = drm_gem_object_lookup(filp, mode_cmd->handles[0]); 65 66 if (!gem) 67 return ERR_PTR(-ENOENT); 68 69 bo = gem_to_xe_bo(gem); 70 /* Require vram placement or dma-buf import */ 71 if (IS_DGFX(i915) && 72 !xe_bo_can_migrate(gem_to_xe_bo(gem), XE_PL_VRAM0) && 73 bo->ttm.type != ttm_bo_type_sg) { 74 drm_gem_object_put(gem); 75 return ERR_PTR(-EREMOTE); 76 } 77 78 return bo; 79 } 80