1 /* SPDX-License-Identifier: MIT */ 2 /* 3 * Copyright © 2021 Intel Corporation 4 */ 5 6 #include <drm/drm_framebuffer.h> 7 8 #include "gem/i915_gem_object.h" 9 10 #include "i915_drv.h" 11 #include "intel_fb.h" 12 #include "intel_fb_bo.h" 13 14 int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb, 15 struct drm_i915_gem_object *obj, 16 struct drm_mode_fb_cmd2 *mode_cmd) 17 { 18 struct drm_i915_private *i915 = to_i915(obj->base.dev); 19 unsigned int tiling, stride; 20 21 i915_gem_object_lock(obj, NULL); 22 tiling = i915_gem_object_get_tiling(obj); 23 stride = i915_gem_object_get_stride(obj); 24 i915_gem_object_unlock(obj); 25 26 if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) { 27 /* 28 * If there's a fence, enforce that 29 * the fb modifier and tiling mode match. 30 */ 31 if (tiling != I915_TILING_NONE && 32 tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) { 33 drm_dbg_kms(&i915->drm, 34 "tiling_mode doesn't match fb modifier\n"); 35 return -EINVAL; 36 } 37 } else { 38 if (tiling == I915_TILING_X) { 39 mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED; 40 } else if (tiling == I915_TILING_Y) { 41 drm_dbg_kms(&i915->drm, 42 "No Y tiling for legacy addfb\n"); 43 return -EINVAL; 44 } 45 } 46 47 /* 48 * gen2/3 display engine uses the fence if present, 49 * so the tiling mode must match the fb modifier exactly. 50 */ 51 if (DISPLAY_VER(i915) < 4 && 52 tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) { 53 drm_dbg_kms(&i915->drm, 54 "tiling_mode must match fb modifier exactly on gen2/3\n"); 55 return -EINVAL; 56 } 57 58 /* 59 * If there's a fence, enforce that 60 * the fb pitch and fence stride match. 61 */ 62 if (tiling != I915_TILING_NONE && mode_cmd->pitches[0] != stride) { 63 drm_dbg_kms(&i915->drm, 64 "pitch (%d) must match tiling stride (%d)\n", 65 mode_cmd->pitches[0], stride); 66 return -EINVAL; 67 } 68 69 return 0; 70 } 71 72 struct drm_i915_gem_object * 73 intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915, 74 struct drm_file *filp, 75 const struct drm_mode_fb_cmd2 *mode_cmd) 76 { 77 struct drm_i915_gem_object *obj; 78 79 obj = i915_gem_object_lookup(filp, mode_cmd->handles[0]); 80 if (!obj) 81 return ERR_PTR(-ENOENT); 82 83 /* object is backed with LMEM for discrete */ 84 if (HAS_LMEM(i915) && !i915_gem_object_can_migrate(obj, INTEL_REGION_LMEM_0)) { 85 /* object is "remote", not in local memory */ 86 i915_gem_object_put(obj); 87 drm_dbg_kms(&i915->drm, "framebuffer must reside in local memory\n"); 88 return ERR_PTR(-EREMOTE); 89 } 90 91 return obj; 92 } 93