1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright 2026, Intel Corporation. 4 */ 5 6 #include <drm/drm_print.h> 7 8 #include <drm/intel/display_parent_interface.h> 9 #include <drm/intel/intel_gmd_interrupt_regs.h> 10 #include <drm/intel/pci_config.h> 11 12 #include "gem/i915_gem_internal.h" 13 #include "gem/i915_gem_object_frontbuffer.h" 14 #include "gem/i915_gem_pm.h" 15 16 #include "gt/intel_gpu_commands.h" 17 #include "gt/intel_ring.h" 18 19 #include "i915_drv.h" 20 #include "i915_overlay.h" 21 #include "i915_reg.h" 22 23 #include "display/intel_frontbuffer.h" 24 25 /* overlay flip addr flag */ 26 #define OFC_UPDATE 0x1 27 28 struct i915_overlay { 29 struct drm_i915_private *i915; 30 struct intel_context *context; 31 struct i915_vma *vma; 32 struct i915_vma *old_vma; 33 struct i915_frontbuffer *frontbuffer; 34 /* register access */ 35 struct drm_i915_gem_object *reg_bo; 36 void __iomem *regs; 37 u32 flip_addr; 38 u32 frontbuffer_bits; 39 /* flip handling */ 40 struct i915_active last_flip; 41 void (*flip_complete)(struct i915_overlay *overlay); 42 }; 43 44 static void i830_overlay_clock_gating(struct drm_i915_private *i915, 45 bool enable) 46 { 47 struct pci_dev *pdev = to_pci_dev(i915->drm.dev); 48 u8 val; 49 50 /* 51 * WA_OVERLAY_CLKGATE:alm 52 * 53 * FIXME should perhaps be done on the display side? 54 */ 55 if (enable) 56 intel_uncore_write(&i915->uncore, DSPCLK_GATE_D, 0); 57 else 58 intel_uncore_write(&i915->uncore, DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); 59 60 /* WA_DISABLE_L2CACHE_CLOCK_GATING:alm */ 61 pci_bus_read_config_byte(pdev->bus, 62 PCI_DEVFN(0, 0), I830_CLOCK_GATE, &val); 63 if (enable) 64 val &= ~I830_L2_CACHE_CLOCK_GATE_DISABLE; 65 else 66 val |= I830_L2_CACHE_CLOCK_GATE_DISABLE; 67 pci_bus_write_config_byte(pdev->bus, 68 PCI_DEVFN(0, 0), I830_CLOCK_GATE, val); 69 } 70 71 static struct i915_request * 72 alloc_request(struct i915_overlay *overlay, void (*fn)(struct i915_overlay *)) 73 { 74 struct i915_request *rq; 75 int err; 76 77 overlay->flip_complete = fn; 78 79 rq = i915_request_create(overlay->context); 80 if (IS_ERR(rq)) 81 return rq; 82 83 err = i915_active_add_request(&overlay->last_flip, rq); 84 if (err) { 85 i915_request_add(rq); 86 return ERR_PTR(err); 87 } 88 89 return rq; 90 } 91 92 static bool i915_overlay_is_active(struct drm_device *drm) 93 { 94 struct drm_i915_private *i915 = to_i915(drm); 95 struct i915_overlay *overlay = i915->overlay; 96 97 return overlay->frontbuffer_bits; 98 } 99 100 /* overlay needs to be disable in OCMD reg */ 101 static int i915_overlay_on(struct drm_device *drm, 102 u32 frontbuffer_bits) 103 { 104 struct drm_i915_private *i915 = to_i915(drm); 105 struct i915_overlay *overlay = i915->overlay; 106 struct i915_request *rq; 107 u32 *cs; 108 109 drm_WARN_ON(drm, i915_overlay_is_active(drm)); 110 111 rq = alloc_request(overlay, NULL); 112 if (IS_ERR(rq)) 113 return PTR_ERR(rq); 114 115 cs = intel_ring_begin(rq, 4); 116 if (IS_ERR(cs)) { 117 i915_request_add(rq); 118 return PTR_ERR(cs); 119 } 120 121 overlay->frontbuffer_bits = frontbuffer_bits; 122 123 if (IS_I830(i915)) 124 i830_overlay_clock_gating(i915, false); 125 126 *cs++ = MI_OVERLAY_FLIP | MI_OVERLAY_ON; 127 *cs++ = overlay->flip_addr | OFC_UPDATE; 128 *cs++ = MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP; 129 *cs++ = MI_NOOP; 130 intel_ring_advance(rq, cs); 131 132 i915_request_add(rq); 133 134 return i915_active_wait(&overlay->last_flip); 135 } 136 137 static void i915_overlay_flip_prepare(struct i915_overlay *overlay, 138 struct i915_vma *vma) 139 { 140 struct drm_i915_private *i915 = overlay->i915; 141 struct i915_frontbuffer *frontbuffer = NULL; 142 143 drm_WARN_ON(&i915->drm, overlay->old_vma); 144 145 if (vma) 146 frontbuffer = i915_gem_object_frontbuffer_get(vma->obj); 147 148 i915_gem_object_frontbuffer_track(overlay->frontbuffer, frontbuffer, 149 overlay->frontbuffer_bits); 150 151 if (overlay->frontbuffer) 152 i915_gem_object_frontbuffer_put(overlay->frontbuffer); 153 overlay->frontbuffer = frontbuffer; 154 155 overlay->old_vma = overlay->vma; 156 if (vma) 157 overlay->vma = i915_vma_get(vma); 158 else 159 overlay->vma = NULL; 160 } 161 162 /* overlay needs to be enabled in OCMD reg */ 163 static int i915_overlay_continue(struct drm_device *drm, 164 struct i915_vma *vma, 165 bool load_polyphase_filter) 166 { 167 struct drm_i915_private *i915 = to_i915(drm); 168 struct i915_overlay *overlay = i915->overlay; 169 struct i915_request *rq; 170 u32 flip_addr = overlay->flip_addr; 171 u32 *cs; 172 173 drm_WARN_ON(drm, !i915_overlay_is_active(drm)); 174 175 if (load_polyphase_filter) 176 flip_addr |= OFC_UPDATE; 177 178 rq = alloc_request(overlay, NULL); 179 if (IS_ERR(rq)) 180 return PTR_ERR(rq); 181 182 cs = intel_ring_begin(rq, 2); 183 if (IS_ERR(cs)) { 184 i915_request_add(rq); 185 return PTR_ERR(cs); 186 } 187 188 *cs++ = MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE; 189 *cs++ = flip_addr; 190 intel_ring_advance(rq, cs); 191 192 i915_overlay_flip_prepare(overlay, vma); 193 i915_request_add(rq); 194 195 return 0; 196 } 197 198 static void i915_overlay_release_old_vma(struct i915_overlay *overlay) 199 { 200 struct drm_i915_private *i915 = overlay->i915; 201 struct intel_display *display = i915->display; 202 struct i915_vma *vma; 203 204 vma = fetch_and_zero(&overlay->old_vma); 205 if (drm_WARN_ON(&i915->drm, !vma)) 206 return; 207 208 intel_frontbuffer_flip(display, overlay->frontbuffer_bits); 209 210 i915_vma_unpin(vma); 211 i915_vma_put(vma); 212 } 213 214 static void 215 i915_overlay_release_old_vid_tail(struct i915_overlay *overlay) 216 { 217 i915_overlay_release_old_vma(overlay); 218 } 219 220 static void i915_overlay_off_tail(struct i915_overlay *overlay) 221 { 222 struct drm_i915_private *i915 = overlay->i915; 223 224 i915_overlay_release_old_vma(overlay); 225 226 overlay->frontbuffer_bits = 0; 227 228 if (IS_I830(i915)) 229 i830_overlay_clock_gating(i915, true); 230 } 231 232 static void i915_overlay_last_flip_retire(struct i915_active *active) 233 { 234 struct i915_overlay *overlay = 235 container_of(active, typeof(*overlay), last_flip); 236 237 if (overlay->flip_complete) 238 overlay->flip_complete(overlay); 239 } 240 241 /* overlay needs to be disabled in OCMD reg */ 242 static int i915_overlay_off(struct drm_device *drm) 243 { 244 struct drm_i915_private *i915 = to_i915(drm); 245 struct i915_overlay *overlay = i915->overlay; 246 struct i915_request *rq; 247 u32 *cs, flip_addr = overlay->flip_addr; 248 249 drm_WARN_ON(drm, !i915_overlay_is_active(drm)); 250 251 /* 252 * According to intel docs the overlay hw may hang (when switching 253 * off) without loading the filter coeffs. It is however unclear whether 254 * this applies to the disabling of the overlay or to the switching off 255 * of the hw. Do it in both cases. 256 */ 257 flip_addr |= OFC_UPDATE; 258 259 rq = alloc_request(overlay, i915_overlay_off_tail); 260 if (IS_ERR(rq)) 261 return PTR_ERR(rq); 262 263 cs = intel_ring_begin(rq, 6); 264 if (IS_ERR(cs)) { 265 i915_request_add(rq); 266 return PTR_ERR(cs); 267 } 268 269 /* wait for overlay to go idle */ 270 *cs++ = MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE; 271 *cs++ = flip_addr; 272 *cs++ = MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP; 273 274 /* turn overlay off */ 275 *cs++ = MI_OVERLAY_FLIP | MI_OVERLAY_OFF; 276 *cs++ = flip_addr; 277 *cs++ = MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP; 278 279 intel_ring_advance(rq, cs); 280 281 i915_overlay_flip_prepare(overlay, NULL); 282 i915_request_add(rq); 283 284 return i915_active_wait(&overlay->last_flip); 285 } 286 287 /* 288 * Recover from an interruption due to a signal. 289 * We have to be careful not to repeat work forever an make forward progress. 290 */ 291 static int i915_overlay_recover_from_interrupt(struct drm_device *drm) 292 { 293 struct drm_i915_private *i915 = to_i915(drm); 294 struct i915_overlay *overlay = i915->overlay; 295 296 return i915_active_wait(&overlay->last_flip); 297 } 298 299 /* 300 * Wait for pending overlay flip and release old frame. 301 * Needs to be called before the overlay register are changed 302 * via intel_overlay_(un)map_regs. 303 */ 304 static int i915_overlay_release_old_vid(struct drm_device *drm) 305 { 306 struct drm_i915_private *i915 = to_i915(drm); 307 struct i915_overlay *overlay = i915->overlay; 308 struct i915_request *rq; 309 u32 *cs; 310 311 /* 312 * Only wait if there is actually an old frame to release to 313 * guarantee forward progress. 314 */ 315 if (!overlay->old_vma) 316 return 0; 317 318 if (!(intel_uncore_read(&i915->uncore, GEN2_ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT)) { 319 i915_overlay_release_old_vid_tail(overlay); 320 return 0; 321 } 322 323 rq = alloc_request(overlay, i915_overlay_release_old_vid_tail); 324 if (IS_ERR(rq)) 325 return PTR_ERR(rq); 326 327 cs = intel_ring_begin(rq, 2); 328 if (IS_ERR(cs)) { 329 i915_request_add(rq); 330 return PTR_ERR(cs); 331 } 332 333 *cs++ = MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP; 334 *cs++ = MI_NOOP; 335 intel_ring_advance(rq, cs); 336 337 i915_request_add(rq); 338 339 return i915_active_wait(&overlay->last_flip); 340 } 341 342 static void i915_overlay_reset(struct drm_device *drm) 343 { 344 struct drm_i915_private *i915 = to_i915(drm); 345 struct i915_overlay *overlay = i915->overlay; 346 347 if (!overlay) 348 return; 349 350 overlay->frontbuffer_bits = 0; 351 } 352 353 static struct i915_vma *i915_overlay_pin_fb(struct drm_device *drm, 354 struct drm_gem_object *obj, 355 u32 *offset) 356 { 357 struct drm_i915_private *i915 = to_i915(drm); 358 struct drm_i915_gem_object *new_bo = to_intel_bo(obj); 359 struct i915_gem_ww_ctx ww; 360 struct i915_vma *vma; 361 int ret; 362 363 atomic_inc(&i915->pending_fb_pin); 364 365 i915_gem_ww_ctx_init(&ww, true); 366 retry: 367 ret = i915_gem_object_lock(new_bo, &ww); 368 if (!ret) { 369 vma = i915_gem_object_pin_to_display_plane(new_bo, &ww, 0, 0, 370 NULL, PIN_MAPPABLE); 371 ret = PTR_ERR_OR_ZERO(vma); 372 } 373 if (ret == -EDEADLK) { 374 ret = i915_gem_ww_ctx_backoff(&ww); 375 if (!ret) 376 goto retry; 377 } 378 i915_gem_ww_ctx_fini(&ww); 379 380 atomic_dec(&i915->pending_fb_pin); 381 382 if (ret) 383 return ERR_PTR(ret); 384 385 *offset = i915_ggtt_offset(vma); 386 387 return vma; 388 } 389 390 static void i915_overlay_unpin_fb(struct drm_device *drm, 391 struct i915_vma *vma) 392 { 393 i915_vma_unpin(vma); 394 } 395 396 static struct drm_gem_object * 397 i915_overlay_obj_lookup(struct drm_device *drm, 398 struct drm_file *file_priv, 399 u32 handle) 400 { 401 struct drm_i915_gem_object *bo; 402 403 bo = i915_gem_object_lookup(file_priv, handle); 404 if (!bo) 405 return ERR_PTR(-ENOENT); 406 407 if (i915_gem_object_is_tiled(bo)) { 408 drm_dbg(drm, "buffer used for overlay image can not be tiled\n"); 409 i915_gem_object_put(bo); 410 return ERR_PTR(-EINVAL); 411 } 412 413 return intel_bo_to_drm_bo(bo); 414 } 415 416 static int get_registers(struct i915_overlay *overlay, bool use_phys) 417 { 418 struct drm_i915_private *i915 = overlay->i915; 419 struct drm_i915_gem_object *obj; 420 struct i915_vma *vma; 421 int err; 422 423 obj = i915_gem_object_create_stolen(i915, PAGE_SIZE); 424 if (IS_ERR(obj)) 425 obj = i915_gem_object_create_internal(i915, PAGE_SIZE); 426 if (IS_ERR(obj)) 427 return PTR_ERR(obj); 428 429 vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE); 430 if (IS_ERR(vma)) { 431 err = PTR_ERR(vma); 432 goto err_put_bo; 433 } 434 435 if (use_phys) 436 overlay->flip_addr = sg_dma_address(obj->mm.pages->sgl); 437 else 438 overlay->flip_addr = i915_ggtt_offset(vma); 439 overlay->regs = i915_vma_pin_iomap(vma); 440 i915_vma_unpin(vma); 441 442 if (IS_ERR(overlay->regs)) { 443 err = PTR_ERR(overlay->regs); 444 goto err_put_bo; 445 } 446 447 overlay->reg_bo = obj; 448 return 0; 449 450 err_put_bo: 451 i915_gem_object_put(obj); 452 return err; 453 } 454 455 static void __iomem *i915_overlay_setup(struct drm_device *drm, 456 bool needs_physical) 457 { 458 struct drm_i915_private *i915 = to_i915(drm); 459 struct intel_engine_cs *engine; 460 struct i915_overlay *overlay; 461 int ret; 462 463 engine = to_gt(i915)->engine[RCS0]; 464 if (!engine || !engine->kernel_context) 465 return ERR_PTR(-ENOENT); 466 467 overlay = kzalloc_obj(*overlay); 468 if (!overlay) 469 return ERR_PTR(-ENOMEM); 470 471 overlay->i915 = i915; 472 overlay->context = engine->kernel_context; 473 474 i915_active_init(&overlay->last_flip, 475 NULL, i915_overlay_last_flip_retire, 0); 476 477 ret = get_registers(overlay, needs_physical); 478 if (ret) { 479 kfree(overlay); 480 return ERR_PTR(ret); 481 } 482 483 i915->overlay = overlay; 484 485 return overlay->regs; 486 } 487 488 static void i915_overlay_cleanup(struct drm_device *drm) 489 { 490 struct drm_i915_private *i915 = to_i915(drm); 491 struct i915_overlay *overlay = i915->overlay; 492 493 if (!overlay) 494 return; 495 496 /* 497 * The bo's should be free'd by the generic code already. 498 * Furthermore modesetting teardown happens beforehand so the 499 * hardware should be off already. 500 */ 501 drm_WARN_ON(drm, i915_overlay_is_active(drm)); 502 503 i915_gem_object_put(overlay->reg_bo); 504 i915_active_fini(&overlay->last_flip); 505 506 kfree(overlay); 507 i915->overlay = NULL; 508 } 509 510 const struct intel_display_overlay_interface i915_display_overlay_interface = { 511 .is_active = i915_overlay_is_active, 512 .overlay_on = i915_overlay_on, 513 .overlay_continue = i915_overlay_continue, 514 .overlay_off = i915_overlay_off, 515 .recover_from_interrupt = i915_overlay_recover_from_interrupt, 516 .release_old_vid = i915_overlay_release_old_vid, 517 .reset = i915_overlay_reset, 518 .obj_lookup = i915_overlay_obj_lookup, 519 .pin_fb = i915_overlay_pin_fb, 520 .unpin_fb = i915_overlay_unpin_fb, 521 .setup = i915_overlay_setup, 522 .cleanup = i915_overlay_cleanup, 523 }; 524