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 11 #include "gem/i915_gem_internal.h" 12 #include "gem/i915_gem_object_frontbuffer.h" 13 #include "gem/i915_gem_pm.h" 14 15 #include "gt/intel_gpu_commands.h" 16 #include "gt/intel_ring.h" 17 18 #include "i915_drv.h" 19 #include "i915_overlay.h" 20 #include "i915_reg.h" 21 #include "intel_pci_config.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_gem_object *new_bo = to_intel_bo(obj); 358 struct i915_gem_ww_ctx ww; 359 struct i915_vma *vma; 360 int ret; 361 362 i915_gem_ww_ctx_init(&ww, true); 363 retry: 364 ret = i915_gem_object_lock(new_bo, &ww); 365 if (!ret) { 366 vma = i915_gem_object_pin_to_display_plane(new_bo, &ww, 0, 0, 367 NULL, PIN_MAPPABLE); 368 ret = PTR_ERR_OR_ZERO(vma); 369 } 370 if (ret == -EDEADLK) { 371 ret = i915_gem_ww_ctx_backoff(&ww); 372 if (!ret) 373 goto retry; 374 } 375 i915_gem_ww_ctx_fini(&ww); 376 if (ret) 377 return ERR_PTR(ret); 378 379 *offset = i915_ggtt_offset(vma); 380 381 return vma; 382 } 383 384 static void i915_overlay_unpin_fb(struct drm_device *drm, 385 struct i915_vma *vma) 386 { 387 i915_vma_unpin(vma); 388 } 389 390 static struct drm_gem_object * 391 i915_overlay_obj_lookup(struct drm_device *drm, 392 struct drm_file *file_priv, 393 u32 handle) 394 { 395 struct drm_i915_gem_object *bo; 396 397 bo = i915_gem_object_lookup(file_priv, handle); 398 if (!bo) 399 return ERR_PTR(-ENOENT); 400 401 if (i915_gem_object_is_tiled(bo)) { 402 drm_dbg(drm, "buffer used for overlay image can not be tiled\n"); 403 i915_gem_object_put(bo); 404 return ERR_PTR(-EINVAL); 405 } 406 407 return intel_bo_to_drm_bo(bo); 408 } 409 410 static int get_registers(struct i915_overlay *overlay, bool use_phys) 411 { 412 struct drm_i915_private *i915 = overlay->i915; 413 struct drm_i915_gem_object *obj; 414 struct i915_vma *vma; 415 int err; 416 417 obj = i915_gem_object_create_stolen(i915, PAGE_SIZE); 418 if (IS_ERR(obj)) 419 obj = i915_gem_object_create_internal(i915, PAGE_SIZE); 420 if (IS_ERR(obj)) 421 return PTR_ERR(obj); 422 423 vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE); 424 if (IS_ERR(vma)) { 425 err = PTR_ERR(vma); 426 goto err_put_bo; 427 } 428 429 if (use_phys) 430 overlay->flip_addr = sg_dma_address(obj->mm.pages->sgl); 431 else 432 overlay->flip_addr = i915_ggtt_offset(vma); 433 overlay->regs = i915_vma_pin_iomap(vma); 434 i915_vma_unpin(vma); 435 436 if (IS_ERR(overlay->regs)) { 437 err = PTR_ERR(overlay->regs); 438 goto err_put_bo; 439 } 440 441 overlay->reg_bo = obj; 442 return 0; 443 444 err_put_bo: 445 i915_gem_object_put(obj); 446 return err; 447 } 448 449 static void __iomem *i915_overlay_setup(struct drm_device *drm, 450 bool needs_physical) 451 { 452 struct drm_i915_private *i915 = to_i915(drm); 453 struct intel_engine_cs *engine; 454 struct i915_overlay *overlay; 455 int ret; 456 457 engine = to_gt(i915)->engine[RCS0]; 458 if (!engine || !engine->kernel_context) 459 return ERR_PTR(-ENOENT); 460 461 overlay = kzalloc_obj(*overlay); 462 if (!overlay) 463 return ERR_PTR(-ENOMEM); 464 465 overlay->i915 = i915; 466 overlay->context = engine->kernel_context; 467 468 i915_active_init(&overlay->last_flip, 469 NULL, i915_overlay_last_flip_retire, 0); 470 471 ret = get_registers(overlay, needs_physical); 472 if (ret) { 473 kfree(overlay); 474 return ERR_PTR(ret); 475 } 476 477 i915->overlay = overlay; 478 479 return overlay->regs; 480 } 481 482 static void i915_overlay_cleanup(struct drm_device *drm) 483 { 484 struct drm_i915_private *i915 = to_i915(drm); 485 struct i915_overlay *overlay = i915->overlay; 486 487 if (!overlay) 488 return; 489 490 /* 491 * The bo's should be free'd by the generic code already. 492 * Furthermore modesetting teardown happens beforehand so the 493 * hardware should be off already. 494 */ 495 drm_WARN_ON(drm, i915_overlay_is_active(drm)); 496 497 i915_gem_object_put(overlay->reg_bo); 498 i915_active_fini(&overlay->last_flip); 499 500 kfree(overlay); 501 i915->overlay = NULL; 502 } 503 504 const struct intel_display_overlay_interface i915_display_overlay_interface = { 505 .is_active = i915_overlay_is_active, 506 .overlay_on = i915_overlay_on, 507 .overlay_continue = i915_overlay_continue, 508 .overlay_off = i915_overlay_off, 509 .recover_from_interrupt = i915_overlay_recover_from_interrupt, 510 .release_old_vid = i915_overlay_release_old_vid, 511 .reset = i915_overlay_reset, 512 .obj_lookup = i915_overlay_obj_lookup, 513 .pin_fb = i915_overlay_pin_fb, 514 .unpin_fb = i915_overlay_unpin_fb, 515 .setup = i915_overlay_setup, 516 .cleanup = i915_overlay_cleanup, 517 }; 518