1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2021 Intel Corporation 4 */ 5 6 #include "i915_drv.h" 7 #include "intel_atomic_plane.h" 8 #include "intel_display.h" 9 #include "intel_display_types.h" 10 #include "intel_fb.h" 11 #include "intel_plane_initial.h" 12 13 static bool 14 intel_reuse_initial_plane_obj(struct drm_i915_private *i915, 15 const struct intel_initial_plane_config *plane_config, 16 struct drm_framebuffer **fb, 17 struct i915_vma **vma) 18 { 19 struct intel_crtc *crtc; 20 21 for_each_intel_crtc(&i915->drm, crtc) { 22 struct intel_crtc_state *crtc_state = 23 to_intel_crtc_state(crtc->base.state); 24 struct intel_plane *plane = 25 to_intel_plane(crtc->base.primary); 26 struct intel_plane_state *plane_state = 27 to_intel_plane_state(plane->base.state); 28 29 if (!crtc_state->uapi.active) 30 continue; 31 32 if (!plane_state->ggtt_vma) 33 continue; 34 35 if (intel_plane_ggtt_offset(plane_state) == plane_config->base) { 36 *fb = plane_state->hw.fb; 37 *vma = plane_state->ggtt_vma; 38 return true; 39 } 40 } 41 42 return false; 43 } 44 45 static struct i915_vma * 46 initial_plane_vma(struct drm_i915_private *i915, 47 struct intel_initial_plane_config *plane_config) 48 { 49 struct drm_i915_gem_object *obj; 50 struct i915_vma *vma; 51 u32 base, size; 52 53 if (plane_config->size == 0) 54 return NULL; 55 56 base = round_down(plane_config->base, 57 I915_GTT_MIN_ALIGNMENT); 58 size = round_up(plane_config->base + plane_config->size, 59 I915_GTT_MIN_ALIGNMENT); 60 size -= base; 61 62 /* 63 * If the FB is too big, just don't use it since fbdev is not very 64 * important and we should probably use that space with FBC or other 65 * features. 66 */ 67 if (IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) && 68 size * 2 > i915->stolen_usable_size) 69 return NULL; 70 71 obj = i915_gem_object_create_stolen_for_preallocated(i915, base, size); 72 if (IS_ERR(obj)) 73 return NULL; 74 75 /* 76 * Mark it WT ahead of time to avoid changing the 77 * cache_level during fbdev initialization. The 78 * unbind there would get stuck waiting for rcu. 79 */ 80 i915_gem_object_set_cache_coherency(obj, HAS_WT(i915) ? 81 I915_CACHE_WT : I915_CACHE_NONE); 82 83 switch (plane_config->tiling) { 84 case I915_TILING_NONE: 85 break; 86 case I915_TILING_X: 87 case I915_TILING_Y: 88 obj->tiling_and_stride = 89 plane_config->fb->base.pitches[0] | 90 plane_config->tiling; 91 break; 92 default: 93 MISSING_CASE(plane_config->tiling); 94 goto err_obj; 95 } 96 97 vma = i915_vma_instance(obj, &i915->ggtt.vm, NULL); 98 if (IS_ERR(vma)) 99 goto err_obj; 100 101 if (i915_ggtt_pin(vma, NULL, 0, PIN_MAPPABLE | PIN_OFFSET_FIXED | base)) 102 goto err_obj; 103 104 if (i915_gem_object_is_tiled(obj) && 105 !i915_vma_is_map_and_fenceable(vma)) 106 goto err_obj; 107 108 return vma; 109 110 err_obj: 111 i915_gem_object_put(obj); 112 return NULL; 113 } 114 115 static bool 116 intel_alloc_initial_plane_obj(struct intel_crtc *crtc, 117 struct intel_initial_plane_config *plane_config) 118 { 119 struct drm_device *dev = crtc->base.dev; 120 struct drm_i915_private *dev_priv = to_i915(dev); 121 struct drm_mode_fb_cmd2 mode_cmd = { 0 }; 122 struct drm_framebuffer *fb = &plane_config->fb->base; 123 struct i915_vma *vma; 124 125 switch (fb->modifier) { 126 case DRM_FORMAT_MOD_LINEAR: 127 case I915_FORMAT_MOD_X_TILED: 128 case I915_FORMAT_MOD_Y_TILED: 129 break; 130 default: 131 drm_dbg(&dev_priv->drm, 132 "Unsupported modifier for initial FB: 0x%llx\n", 133 fb->modifier); 134 return false; 135 } 136 137 vma = initial_plane_vma(dev_priv, plane_config); 138 if (!vma) 139 return false; 140 141 mode_cmd.pixel_format = fb->format->format; 142 mode_cmd.width = fb->width; 143 mode_cmd.height = fb->height; 144 mode_cmd.pitches[0] = fb->pitches[0]; 145 mode_cmd.modifier[0] = fb->modifier; 146 mode_cmd.flags = DRM_MODE_FB_MODIFIERS; 147 148 if (intel_framebuffer_init(to_intel_framebuffer(fb), 149 vma->obj, &mode_cmd)) { 150 drm_dbg_kms(&dev_priv->drm, "intel fb init failed\n"); 151 goto err_vma; 152 } 153 154 plane_config->vma = vma; 155 return true; 156 157 err_vma: 158 i915_vma_put(vma); 159 return false; 160 } 161 162 static void 163 intel_find_initial_plane_obj(struct intel_crtc *crtc, 164 struct intel_initial_plane_config *plane_config) 165 { 166 struct drm_device *dev = crtc->base.dev; 167 struct drm_i915_private *dev_priv = to_i915(dev); 168 struct intel_crtc_state *crtc_state = 169 to_intel_crtc_state(crtc->base.state); 170 struct intel_plane *plane = 171 to_intel_plane(crtc->base.primary); 172 struct intel_plane_state *plane_state = 173 to_intel_plane_state(plane->base.state); 174 struct drm_framebuffer *fb; 175 struct i915_vma *vma; 176 177 /* 178 * TODO: 179 * Disable planes if get_initial_plane_config() failed. 180 * Make sure things work if the surface base is not page aligned. 181 */ 182 if (!plane_config->fb) 183 return; 184 185 if (intel_alloc_initial_plane_obj(crtc, plane_config)) { 186 fb = &plane_config->fb->base; 187 vma = plane_config->vma; 188 goto valid_fb; 189 } 190 191 /* 192 * Failed to alloc the obj, check to see if we should share 193 * an fb with another CRTC instead 194 */ 195 if (intel_reuse_initial_plane_obj(dev_priv, plane_config, &fb, &vma)) 196 goto valid_fb; 197 198 /* 199 * We've failed to reconstruct the BIOS FB. Current display state 200 * indicates that the primary plane is visible, but has a NULL FB, 201 * which will lead to problems later if we don't fix it up. The 202 * simplest solution is to just disable the primary plane now and 203 * pretend the BIOS never had it enabled. 204 */ 205 intel_plane_disable_noatomic(crtc, plane); 206 if (crtc_state->bigjoiner) { 207 struct intel_crtc *slave = 208 crtc_state->bigjoiner_linked_crtc; 209 intel_plane_disable_noatomic(slave, to_intel_plane(slave->base.primary)); 210 } 211 212 return; 213 214 valid_fb: 215 plane_state->uapi.rotation = plane_config->rotation; 216 intel_fb_fill_view(to_intel_framebuffer(fb), 217 plane_state->uapi.rotation, &plane_state->view); 218 219 __i915_vma_pin(vma); 220 plane_state->ggtt_vma = i915_vma_get(vma); 221 if (intel_plane_uses_fence(plane_state) && 222 i915_vma_pin_fence(vma) == 0 && vma->fence) 223 plane_state->flags |= PLANE_HAS_FENCE; 224 225 plane_state->uapi.src_x = 0; 226 plane_state->uapi.src_y = 0; 227 plane_state->uapi.src_w = fb->width << 16; 228 plane_state->uapi.src_h = fb->height << 16; 229 230 plane_state->uapi.crtc_x = 0; 231 plane_state->uapi.crtc_y = 0; 232 plane_state->uapi.crtc_w = fb->width; 233 plane_state->uapi.crtc_h = fb->height; 234 235 if (plane_config->tiling) 236 dev_priv->preserve_bios_swizzle = true; 237 238 plane_state->uapi.fb = fb; 239 drm_framebuffer_get(fb); 240 241 plane_state->uapi.crtc = &crtc->base; 242 intel_plane_copy_uapi_to_hw_state(plane_state, plane_state, crtc); 243 244 atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits); 245 } 246 247 static void plane_config_fini(struct intel_initial_plane_config *plane_config) 248 { 249 if (plane_config->fb) { 250 struct drm_framebuffer *fb = &plane_config->fb->base; 251 252 /* We may only have the stub and not a full framebuffer */ 253 if (drm_framebuffer_read_refcount(fb)) 254 drm_framebuffer_put(fb); 255 else 256 kfree(fb); 257 } 258 259 if (plane_config->vma) 260 i915_vma_put(plane_config->vma); 261 } 262 263 void intel_crtc_initial_plane_config(struct intel_crtc *crtc) 264 { 265 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 266 struct intel_initial_plane_config plane_config = {}; 267 268 /* 269 * Note that reserving the BIOS fb up front prevents us 270 * from stuffing other stolen allocations like the ring 271 * on top. This prevents some ugliness at boot time, and 272 * can even allow for smooth boot transitions if the BIOS 273 * fb is large enough for the active pipe configuration. 274 */ 275 dev_priv->display->get_initial_plane_config(crtc, &plane_config); 276 277 /* 278 * If the fb is shared between multiple heads, we'll 279 * just get the first one. 280 */ 281 intel_find_initial_plane_obj(crtc, &plane_config); 282 283 plane_config_fini(&plane_config); 284 } 285