1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2021 Intel Corporation 4 */ 5 6 /** 7 * DOC: display pinning helpers 8 */ 9 10 #include <drm/drm_print.h> 11 12 #include "gem/i915_gem_domain.h" 13 #include "gem/i915_gem_object.h" 14 15 #include "i915_drv.h" 16 #include "i915_vma.h" 17 #include "intel_display_core.h" 18 #include "intel_display_rpm.h" 19 #include "intel_display_types.h" 20 #include "i915_dpt.h" 21 #include "intel_fb.h" 22 #include "intel_fb_pin.h" 23 #include "intel_plane.h" 24 25 static struct i915_vma * 26 intel_fb_pin_to_dpt(const struct drm_framebuffer *fb, 27 const struct i915_gtt_view *view, 28 unsigned int alignment, 29 unsigned long *out_flags, 30 struct intel_dpt *dpt) 31 { 32 struct drm_device *dev = fb->dev; 33 struct intel_display *display = to_intel_display(dev); 34 struct drm_i915_private *dev_priv = to_i915(dev); 35 struct drm_gem_object *_obj = intel_fb_bo(fb); 36 struct drm_i915_gem_object *obj = to_intel_bo(_obj); 37 struct i915_address_space *vm = i915_dpt_to_vm(dpt); 38 struct i915_gem_ww_ctx ww; 39 struct i915_vma *vma; 40 int ret; 41 42 /* 43 * We are not syncing against the binding (and potential migrations) 44 * below, so this vm must never be async. 45 */ 46 if (drm_WARN_ON(&dev_priv->drm, vm->bind_async_flags)) 47 return ERR_PTR(-EINVAL); 48 49 if (WARN_ON(!i915_gem_object_is_framebuffer(obj))) 50 return ERR_PTR(-EINVAL); 51 52 atomic_inc(&display->restore.pending_fb_pin); 53 54 for_i915_gem_ww(&ww, ret, true) { 55 ret = i915_gem_object_lock(obj, &ww); 56 if (ret) 57 continue; 58 59 if (HAS_LMEM(dev_priv)) { 60 unsigned int flags = obj->flags; 61 62 /* 63 * For this type of buffer we need to able to read from the CPU 64 * the clear color value found in the buffer, hence we need to 65 * ensure it is always in the mappable part of lmem, if this is 66 * a small-bar device. 67 */ 68 if (intel_fb_rc_ccs_cc_plane(fb) >= 0) 69 flags &= ~I915_BO_ALLOC_GPU_ONLY; 70 ret = __i915_gem_object_migrate(obj, &ww, INTEL_REGION_LMEM_0, 71 flags); 72 if (ret) 73 continue; 74 } 75 76 ret = i915_gem_object_set_cache_level(obj, I915_CACHE_NONE); 77 if (ret) 78 continue; 79 80 vma = i915_vma_instance(obj, vm, view); 81 if (IS_ERR(vma)) { 82 ret = PTR_ERR(vma); 83 continue; 84 } 85 86 if (i915_vma_misplaced(vma, 0, alignment, 0)) { 87 ret = i915_vma_unbind(vma); 88 if (ret) 89 continue; 90 } 91 92 ret = i915_vma_pin_ww(vma, &ww, 0, alignment, PIN_GLOBAL); 93 if (ret) 94 continue; 95 } 96 if (ret) { 97 vma = ERR_PTR(ret); 98 goto err; 99 } 100 101 vma->display_alignment = max(vma->display_alignment, alignment); 102 103 i915_gem_object_flush_if_display(obj); 104 105 i915_vma_get(vma); 106 err: 107 atomic_dec(&display->restore.pending_fb_pin); 108 109 return vma; 110 } 111 112 struct i915_vma * 113 intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, 114 const struct i915_gtt_view *view, 115 unsigned int alignment, 116 unsigned int phys_alignment, 117 unsigned int vtd_guard, 118 bool uses_fence, 119 unsigned long *out_flags) 120 { 121 struct drm_device *dev = fb->dev; 122 struct intel_display *display = to_intel_display(dev); 123 struct drm_i915_private *dev_priv = to_i915(dev); 124 struct drm_gem_object *_obj = intel_fb_bo(fb); 125 struct drm_i915_gem_object *obj = to_intel_bo(_obj); 126 struct ref_tracker *wakeref; 127 struct i915_gem_ww_ctx ww; 128 struct i915_vma *vma; 129 unsigned int pinctl; 130 int ret; 131 132 if (drm_WARN_ON(dev, !i915_gem_object_is_framebuffer(obj))) 133 return ERR_PTR(-EINVAL); 134 135 if (drm_WARN_ON(dev, alignment && !is_power_of_2(alignment))) 136 return ERR_PTR(-EINVAL); 137 138 /* 139 * Global gtt pte registers are special registers which actually forward 140 * writes to a chunk of system memory. Which means that there is no risk 141 * that the register values disappear as soon as we call 142 * intel_runtime_pm_put(), so it is correct to wrap only the 143 * pin/unpin/fence and not more. 144 */ 145 wakeref = intel_display_rpm_get(display); 146 147 atomic_inc(&display->restore.pending_fb_pin); 148 149 /* 150 * Valleyview is definitely limited to scanning out the first 151 * 512MiB. Lets presume this behaviour was inherited from the 152 * g4x display engine and that all earlier gen are similarly 153 * limited. Testing suggests that it is a little more 154 * complicated than this. For example, Cherryview appears quite 155 * happy to scanout from anywhere within its global aperture. 156 */ 157 pinctl = 0; 158 if (HAS_GMCH(display)) 159 pinctl |= PIN_MAPPABLE; 160 161 i915_gem_ww_ctx_init(&ww, true); 162 retry: 163 ret = i915_gem_object_lock(obj, &ww); 164 if (!ret && phys_alignment) 165 ret = i915_gem_object_attach_phys(obj, phys_alignment); 166 else if (!ret && HAS_LMEM(dev_priv)) 167 ret = i915_gem_object_migrate(obj, &ww, INTEL_REGION_LMEM_0); 168 if (!ret) 169 ret = i915_gem_object_pin_pages(obj); 170 if (ret) 171 goto err; 172 173 vma = i915_gem_object_pin_to_display_plane(obj, &ww, alignment, 174 vtd_guard, view, pinctl); 175 if (IS_ERR(vma)) { 176 ret = PTR_ERR(vma); 177 goto err_unpin; 178 } 179 180 if (uses_fence && i915_vma_is_map_and_fenceable(vma)) { 181 /* 182 * Install a fence for tiled scan-out. Pre-i965 always needs a 183 * fence, whereas 965+ only requires a fence if using 184 * framebuffer compression. For simplicity, we always, when 185 * possible, install a fence as the cost is not that onerous. 186 * 187 * If we fail to fence the tiled scanout, then either the 188 * modeset will reject the change (which is highly unlikely as 189 * the affected systems, all but one, do not have unmappable 190 * space) or we will not be able to enable full powersaving 191 * techniques (also likely not to apply due to various limits 192 * FBC and the like impose on the size of the buffer, which 193 * presumably we violated anyway with this unmappable buffer). 194 * Anyway, it is presumably better to stumble onwards with 195 * something and try to run the system in a "less than optimal" 196 * mode that matches the user configuration. 197 */ 198 ret = i915_vma_pin_fence(vma); 199 if (ret != 0 && DISPLAY_VER(display) < 4) { 200 i915_vma_unpin(vma); 201 goto err_unpin; 202 } 203 ret = 0; 204 205 if (vma->fence) 206 *out_flags |= PLANE_HAS_FENCE; 207 } 208 209 i915_vma_get(vma); 210 211 err_unpin: 212 i915_gem_object_unpin_pages(obj); 213 err: 214 if (ret == -EDEADLK) { 215 ret = i915_gem_ww_ctx_backoff(&ww); 216 if (!ret) 217 goto retry; 218 } 219 i915_gem_ww_ctx_fini(&ww); 220 if (ret) 221 vma = ERR_PTR(ret); 222 223 atomic_dec(&display->restore.pending_fb_pin); 224 intel_display_rpm_put(display, wakeref); 225 return vma; 226 } 227 228 void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags) 229 { 230 if (flags & PLANE_HAS_FENCE) 231 i915_vma_unpin_fence(vma); 232 i915_vma_unpin(vma); 233 i915_vma_put(vma); 234 } 235 236 static unsigned int 237 intel_plane_fb_min_alignment(const struct intel_plane_state *plane_state) 238 { 239 const struct intel_framebuffer *fb = to_intel_framebuffer(plane_state->hw.fb); 240 241 return fb->min_alignment; 242 } 243 244 static unsigned int 245 intel_plane_fb_min_phys_alignment(const struct intel_plane_state *plane_state) 246 { 247 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 248 const struct drm_framebuffer *fb = plane_state->hw.fb; 249 250 if (!intel_plane_needs_physical(plane)) 251 return 0; 252 253 return plane->min_alignment(plane, fb, 0); 254 } 255 256 static unsigned int 257 intel_plane_fb_vtd_guard(const struct intel_plane_state *plane_state) 258 { 259 return intel_fb_view_vtd_guard(plane_state->hw.fb, 260 &plane_state->view, 261 plane_state->hw.rotation); 262 } 263 264 int intel_plane_pin_fb(struct intel_plane_state *plane_state, 265 const struct intel_plane_state *old_plane_state) 266 { 267 struct intel_display *display = to_intel_display(plane_state); 268 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 269 const struct intel_framebuffer *fb = 270 to_intel_framebuffer(plane_state->hw.fb); 271 struct i915_vma *vma; 272 273 if (!intel_fb_uses_dpt(&fb->base)) { 274 vma = intel_fb_pin_to_ggtt(&fb->base, &plane_state->view.gtt, 275 intel_plane_fb_min_alignment(plane_state), 276 intel_plane_fb_min_phys_alignment(plane_state), 277 intel_plane_fb_vtd_guard(plane_state), 278 intel_plane_uses_fence(plane_state), 279 &plane_state->flags); 280 if (IS_ERR(vma)) 281 return PTR_ERR(vma); 282 283 plane_state->ggtt_vma = vma; 284 285 } else { 286 unsigned int alignment = intel_plane_fb_min_alignment(plane_state); 287 288 vma = i915_dpt_pin_to_ggtt(fb->dpt, alignment / 512); 289 if (IS_ERR(vma)) 290 return PTR_ERR(vma); 291 292 plane_state->ggtt_vma = vma; 293 294 vma = intel_fb_pin_to_dpt(&fb->base, &plane_state->view.gtt, 295 alignment, &plane_state->flags, 296 fb->dpt); 297 if (IS_ERR(vma)) { 298 i915_dpt_unpin_from_ggtt(fb->dpt); 299 plane_state->ggtt_vma = NULL; 300 return PTR_ERR(vma); 301 } 302 303 plane_state->dpt_vma = vma; 304 305 WARN_ON(plane_state->ggtt_vma == plane_state->dpt_vma); 306 307 /* 308 * The DPT object contains only one vma, and there is no VT-d 309 * guard, so the VMA's offset within the DPT is always 0. 310 */ 311 drm_WARN_ON(display->drm, i915_dpt_offset(plane_state->dpt_vma)); 312 } 313 314 /* 315 * Pre-populate the dma address before we enter the vblank 316 * evade critical section as i915_gem_object_get_dma_address() 317 * will trigger might_sleep() even if it won't actually sleep, 318 * which is the case when the fb has already been pinned. 319 */ 320 if (intel_plane_needs_physical(plane)) { 321 struct drm_i915_gem_object *obj = to_intel_bo(intel_fb_bo(&fb->base)); 322 323 plane_state->surf = i915_gem_object_get_dma_address(obj, 0) + 324 plane->surf_offset(plane_state); 325 } else { 326 plane_state->surf = i915_ggtt_offset(plane_state->ggtt_vma) + 327 plane->surf_offset(plane_state); 328 } 329 330 return 0; 331 } 332 333 void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) 334 { 335 const struct intel_framebuffer *fb = 336 to_intel_framebuffer(old_plane_state->hw.fb); 337 struct i915_vma *vma; 338 339 if (!intel_fb_uses_dpt(&fb->base)) { 340 vma = fetch_and_zero(&old_plane_state->ggtt_vma); 341 if (vma) 342 intel_fb_unpin_vma(vma, old_plane_state->flags); 343 } else { 344 vma = fetch_and_zero(&old_plane_state->dpt_vma); 345 if (vma) 346 intel_fb_unpin_vma(vma, old_plane_state->flags); 347 348 vma = fetch_and_zero(&old_plane_state->ggtt_vma); 349 if (vma) 350 i915_dpt_unpin_from_ggtt(fb->dpt); 351 } 352 } 353 354 void intel_fb_get_map(struct i915_vma *vma, struct iosys_map *map) 355 { 356 iosys_map_set_vaddr_iomem(map, i915_vma_get_iomap(vma)); 357 } 358