From 7c3eb9f47533220888a67266448185fd0775d4da Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 15 May 2026 19:09:20 +0300 Subject: [PATCH 01/80] drm/xe/display: fix oops in suspend/shutdown without display The xe driver keeps track of whether to probe display, and whether display hardware is there, using xe->info.probe_display. It gets set to false if there's no display after intel_display_device_probe(). However, the display may also be disabled via fuses, detected at a later time in intel_display_device_info_runtime_init(). In this case, the xe driver does for_each_intel_crtc() on uninitialized mode config in xe_display_flush_cleanup_work(), leading to a NULL pointer dereference, and generally calls display code with display info cleared. Check for intel_display_device_present() after intel_display_device_info_runtime_init(), and reset xe->info.probe_display as necessary. Also do unset_display_features() for completeness, although display runtime init has already done that. This will need to be unified across all cases later. Move intel_display_device_info_runtime_init() call slightly earlier, similar to i915, to avoid a bunch of unnecessary setup for no display cases. Note #1: The xe driver has no business doing low level display plumbing like for_each_intel_crtc() to begin with. It all needs to happen in display code. Note #2: The actual bug is present already in commit 44e694958b95 ("drm/xe/display: Implement display support"), but the oops was likely introduced later at commit ddf6492e0e50 ("drm/xe/display: Make display suspend/resume work on discrete"). Fixes: 44e694958b95 ("drm/xe/display: Implement display support") Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/7904 Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/6150 Cc: stable@vger.kernel.org # v6.8+ Reviewed-by: Suraj Kandpal Link: https://patch.msgid.link/20260515160920.1082842-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/xe/display/xe_display.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index aa73023b7398..fc198236e9de 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -125,6 +125,15 @@ int xe_display_init_early(struct xe_device *xe) intel_display_driver_early_probe(display); + intel_display_device_info_runtime_init(display); + + /* Display may have been disabled at runtime init */ + if (!intel_display_device_present(display)) { + xe->info.probe_display = false; + unset_display_features(xe); + return 0; + } + /* Early display init.. */ intel_opregion_setup(display); @@ -138,8 +147,6 @@ int xe_display_init_early(struct xe_device *xe) intel_bw_init_hw(display); - intel_display_device_info_runtime_init(display); - err = intel_display_driver_probe_noirq(display); if (err) goto err_opregion; From b64614eddc4e9abd6023ca716aed4f6554f77627 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 19:13:24 +0300 Subject: [PATCH 02/80] drm/i915/irq: deduplicate dg1_de_irq_postinstall() and gen11_de_irq_postinstall() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dg1_de_irq_postinstall() and gen11_de_irq_postinstall() are exactly the same. Remove dg1_de_irq_postinstall() and call gen11_de_irq_postinstall() instead. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/bbbec68fe398175b1609049771810fb6a8b7b7e6.1778688699.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_irq.c | 9 --------- drivers/gpu/drm/i915/display/intel_display_irq.h | 1 - drivers/gpu/drm/i915/i915_irq.c | 2 +- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 27fb72e5cefb..a1dbf20c2e02 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -2449,15 +2449,6 @@ void gen11_de_irq_postinstall(struct intel_display *display) intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); } -void dg1_de_irq_postinstall(struct intel_display *display) -{ - if (!HAS_DISPLAY(display)) - return; - - gen8_de_irq_postinstall(display); - intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); -} - struct intel_display_irq_funcs { void (*reset)(struct intel_display *display); }; diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index b25d180254d7..e2b1674fae06 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -71,7 +71,6 @@ void vlv_display_irq_postinstall(struct intel_display *display); void ilk_de_irq_postinstall(struct intel_display *display); void gen8_de_irq_postinstall(struct intel_display *display); void gen11_de_irq_postinstall(struct intel_display *display); -void dg1_de_irq_postinstall(struct intel_display *display); u32 i915_pipestat_enable_mask(struct intel_display *display, enum pipe pipe); void i915_enable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d4d8dd0a4174..ef9eadf38a53 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -778,7 +778,7 @@ static void dg1_irq_postinstall(struct drm_i915_private *dev_priv) gen2_irq_init(uncore, GEN11_GU_MISC_IRQ_REGS, ~gu_misc_masked, gu_misc_masked); - dg1_de_irq_postinstall(display); + gen11_de_irq_postinstall(display); dg1_master_intr_enable(intel_uncore_regs(uncore)); intel_uncore_posting_read(uncore, DG1_MSTR_TILE_INTR); From 7b18938135fa9a95d1ec1d0ecb575be1c37b72b2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 19:13:25 +0300 Subject: [PATCH 03/80] drm/i915/irq: constify pipe stats parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pipe stat irq handling doesn't need to modify the pipe stats arrays. Make them const. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/3b7ad6be706ed757b53c6c4e06a3410f6f7520e0.1778688699.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_irq.c | 6 +++--- drivers/gpu/drm/i915/display/intel_display_irq.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index a1dbf20c2e02..c656d59c7571 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -597,7 +597,7 @@ void i9xx_pipestat_irq_ack(struct intel_display *display, } void i915_pipestat_irq_handler(struct intel_display *display, - u32 iir, u32 pipe_stats[I915_MAX_PIPES]) + u32 iir, const u32 pipe_stats[I915_MAX_PIPES]) { bool blc_event = false; enum pipe pipe; @@ -621,7 +621,7 @@ void i915_pipestat_irq_handler(struct intel_display *display, } void i965_pipestat_irq_handler(struct intel_display *display, - u32 iir, u32 pipe_stats[I915_MAX_PIPES]) + u32 iir, const u32 pipe_stats[I915_MAX_PIPES]) { bool blc_event = false; enum pipe pipe; @@ -648,7 +648,7 @@ void i965_pipestat_irq_handler(struct intel_display *display, } void valleyview_pipestat_irq_handler(struct intel_display *display, - u32 pipe_stats[I915_MAX_PIPES]) + const u32 pipe_stats[I915_MAX_PIPES]) { enum pipe pipe; diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index e2b1674fae06..d25b9ea4272b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -78,9 +78,9 @@ void i915_disable_pipestat(struct intel_display *display, enum pipe pipe, u32 st void i9xx_pipestat_irq_ack(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); -void i915_pipestat_irq_handler(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); -void i965_pipestat_irq_handler(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); -void valleyview_pipestat_irq_handler(struct intel_display *display, u32 pipe_stats[I915_MAX_PIPES]); +void i915_pipestat_irq_handler(struct intel_display *display, u32 iir, const u32 pipe_stats[I915_MAX_PIPES]); +void i965_pipestat_irq_handler(struct intel_display *display, u32 iir, const u32 pipe_stats[I915_MAX_PIPES]); +void valleyview_pipestat_irq_handler(struct intel_display *display, const u32 pipe_stats[I915_MAX_PIPES]); void vlv_display_error_irq_ack(struct intel_display *display, u32 *eir, u32 *dpinvgtt); void vlv_display_error_irq_handler(struct intel_display *display, u32 eir, u32 dpinvgtt); From 56f0919c4324a3d9c07e321b17d9e430094fb35d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 19:13:26 +0300 Subject: [PATCH 04/80] drm/i915/irq: add display irq funcs, start with intel_display_irq_reset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce display irq hooks with struct intel_display_irq_funcs, and add the ->reset hook as the first thing. Call the reset hooks from i915 and xe core via intel_display_irq_reset(). Relocate the gen8 and gen11 HAS_DISPLAY() check to intel_display_irq_reset(), as the funcs pointer won't be initialized for no display. Note: We're increasingly moving to the territory of not touching display at all if there's no display or it has been fused off. Which is good, but care must be taken to not have hardware setup required also for no display cases in display code. Also note that the line is fuzzy for older platforms, but there we also don't have fusing. v2: - make the structs static const (Sashiko) - relocate HAS_DISPLAY() (Sashiko) Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/f9d75e8af92b5550a9d07f29491be5313b7c866b.1778688699.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_core.h | 3 + .../gpu/drm/i915/display/intel_display_irq.c | 61 +++++++++++++++---- .../gpu/drm/i915/display/intel_display_irq.h | 6 +- drivers/gpu/drm/i915/i915_irq.c | 16 ++--- drivers/gpu/drm/xe/display/xe_display.c | 2 +- 5 files changed, 63 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 76745ce6a716..3dc5ac75a98b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -475,6 +475,9 @@ struct intel_display { } ips; struct { + /* internal display irq functions */ + const struct intel_display_irq_funcs *funcs; + /* protects the irq masks */ spinlock_t lock; diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index c656d59c7571..27599a303843 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1947,7 +1947,7 @@ static void _vlv_display_irq_reset(struct intel_display *display) display->irq.vlv_imr_mask = ~0u; } -void vlv_display_irq_reset(struct intel_display *display) +static void vlv_display_irq_reset(struct intel_display *display) { spin_lock_irq(&display->irq.lock); if (display->irq.vlv_display_irqs_enabled) @@ -1955,7 +1955,7 @@ void vlv_display_irq_reset(struct intel_display *display) spin_unlock_irq(&display->irq.lock); } -void i9xx_display_irq_reset(struct intel_display *display) +static void i9xx_display_irq_reset(struct intel_display *display) { if (HAS_HOTPLUG(display)) { i915_hotplug_interrupt_update(display, 0xffffffff, 0); @@ -2076,7 +2076,7 @@ static void ibx_display_irq_reset(struct intel_display *display) intel_de_write(display, SERR_INT, 0xffffffff); } -void ilk_display_irq_reset(struct intel_display *display) +static void ilk_display_irq_reset(struct intel_display *display) { irq_reset(display, DE_IRQ_REGS); display->irq.ilk_de_imr_mask = ~0u; @@ -2092,13 +2092,10 @@ void ilk_display_irq_reset(struct intel_display *display) ibx_display_irq_reset(display); } -void gen8_display_irq_reset(struct intel_display *display) +static void gen8_display_irq_reset(struct intel_display *display) { enum pipe pipe; - if (!HAS_DISPLAY(display)) - return; - intel_de_write(display, EDP_PSR_IMR, 0xffffffff); intel_de_write(display, EDP_PSR_IIR, 0xffffffff); @@ -2114,15 +2111,12 @@ void gen8_display_irq_reset(struct intel_display *display) ibx_display_irq_reset(display); } -void gen11_display_irq_reset(struct intel_display *display) +static void gen11_display_irq_reset(struct intel_display *display) { enum pipe pipe; u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D); - if (!HAS_DISPLAY(display)) - return; - intel_de_write(display, GEN11_DISPLAY_INT_CTL, 0); if (DISPLAY_VER(display) >= 12) { @@ -2453,6 +2447,38 @@ struct intel_display_irq_funcs { void (*reset)(struct intel_display *display); }; +static const struct intel_display_irq_funcs gen11_display_irq_funcs = { + .reset = gen11_display_irq_reset, +}; + +static const struct intel_display_irq_funcs gen8_display_irq_funcs = { + .reset = gen8_display_irq_reset, +}; + +static const struct intel_display_irq_funcs vlv_display_irq_funcs = { + .reset = vlv_display_irq_reset, +}; + +static const struct intel_display_irq_funcs ilk_display_irq_funcs = { + .reset = ilk_display_irq_reset, +}; + +static const struct intel_display_irq_funcs i965_display_irq_funcs = { + .reset = i9xx_display_irq_reset, +}; + +static const struct intel_display_irq_funcs i915_display_irq_funcs = { + .reset = i9xx_display_irq_reset, +}; + +void intel_display_irq_reset(struct intel_display *display) +{ + if (!HAS_DISPLAY(display)) + return; + + display->irq.funcs->reset(display); +} + void intel_display_irq_init(struct intel_display *display) { spin_lock_init(&display->irq.lock); @@ -2463,6 +2489,19 @@ void intel_display_irq_init(struct intel_display *display) INIT_WORK(&display->irq.vblank_notify_work, intel_display_vblank_notify_work); + + if (DISPLAY_VER(display) >= 11) + display->irq.funcs = &gen11_display_irq_funcs; + else if (display->platform.cherryview || display->platform.valleyview) + display->irq.funcs = &vlv_display_irq_funcs; + else if (DISPLAY_VER(display) >= 8) + display->irq.funcs = &gen8_display_irq_funcs; + else if (DISPLAY_VER(display) >= 5) + display->irq.funcs = &ilk_display_irq_funcs; + else if (DISPLAY_VER(display) == 4) + display->irq.funcs = &i965_display_irq_funcs; + else + display->irq.funcs = &i915_display_irq_funcs; } struct intel_display_irq_snapshot { diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index d25b9ea4272b..21b2145656cd 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -58,11 +58,7 @@ void gen11_display_irq_handler(struct intel_display *display); u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl); void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir); -void i9xx_display_irq_reset(struct intel_display *display); -void ilk_display_irq_reset(struct intel_display *display); -void vlv_display_irq_reset(struct intel_display *display); -void gen8_display_irq_reset(struct intel_display *display); -void gen11_display_irq_reset(struct intel_display *display); +void intel_display_irq_reset(struct intel_display *display); u32 i9xx_display_irq_enable_mask(struct intel_display *display); void i915_display_irq_postinstall(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ef9eadf38a53..c4f56a869910 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -640,7 +640,7 @@ static void ilk_irq_reset(struct drm_i915_private *dev_priv) struct intel_display *display = dev_priv->display; /* The master interrupt enable is in DEIER, reset display irq first */ - ilk_display_irq_reset(display); + intel_display_irq_reset(display); gen5_gt_irq_reset(to_gt(dev_priv)); } @@ -653,7 +653,7 @@ static void valleyview_irq_reset(struct drm_i915_private *dev_priv) gen5_gt_irq_reset(to_gt(dev_priv)); - vlv_display_irq_reset(display); + intel_display_irq_reset(display); } static void gen8_irq_reset(struct drm_i915_private *dev_priv) @@ -664,7 +664,7 @@ static void gen8_irq_reset(struct drm_i915_private *dev_priv) gen8_master_intr_disable(intel_uncore_regs(uncore)); gen8_gt_irq_reset(to_gt(dev_priv)); - gen8_display_irq_reset(display); + intel_display_irq_reset(display); gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS); } @@ -677,7 +677,7 @@ static void gen11_irq_reset(struct drm_i915_private *dev_priv) gen11_master_intr_disable(intel_uncore_regs(&dev_priv->uncore)); gen11_gt_irq_reset(gt); - gen11_display_irq_reset(display); + intel_display_irq_reset(display); gen2_irq_reset(uncore, GEN11_GU_MISC_IRQ_REGS); gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS); @@ -695,7 +695,7 @@ static void dg1_irq_reset(struct drm_i915_private *dev_priv) for_each_gt(gt, dev_priv, i) gen11_gt_irq_reset(gt); - gen11_display_irq_reset(display); + intel_display_irq_reset(display); gen2_irq_reset(uncore, GEN11_GU_MISC_IRQ_REGS); gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS); @@ -715,7 +715,7 @@ static void cherryview_irq_reset(struct drm_i915_private *dev_priv) gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS); - vlv_display_irq_reset(display); + intel_display_irq_reset(display); } static void ilk_irq_postinstall(struct drm_i915_private *dev_priv) @@ -864,7 +864,7 @@ static void i915_irq_reset(struct drm_i915_private *dev_priv) struct intel_display *display = dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; - i9xx_display_irq_reset(display); + intel_display_irq_reset(display); gen2_error_reset(uncore, GEN2_ERROR_REGS); gen2_irq_reset(uncore, GEN2_IRQ_REGS); @@ -951,7 +951,7 @@ static void i965_irq_reset(struct drm_i915_private *dev_priv) struct intel_display *display = dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; - i9xx_display_irq_reset(display); + intel_display_irq_reset(display); gen2_error_reset(uncore, GEN2_ERROR_REGS); gen2_irq_reset(uncore, GEN2_IRQ_REGS); diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index fc198236e9de..6ce8f37ddd44 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -243,7 +243,7 @@ void xe_display_irq_reset(struct xe_device *xe) if (!xe->info.probe_display) return; - gen11_display_irq_reset(display); + intel_display_irq_reset(display); } void xe_display_irq_postinstall(struct xe_device *xe) From 002a330f5b9815ad0698ca8e7ecd3c81478d4c98 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 19:13:27 +0300 Subject: [PATCH 05/80] drm/i915/irq: add intel_display_irq_postinstall() to irq funcs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call the platform specific display irq postinstall hooks via intel_display_irq_postinstall(). Relocate the gen11 HAS_DISPLAY() check to intel_display_irq_postinstall(), as the funcs pointer won't be initialized for no display. v2: - relocate HAS_DISPLAY() (Sashiko) Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/65f1ad73628fb6dbdf6e782493eaecb1d61abaf7.1778688699.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_irq.c | 30 +++++++++++++------ .../gpu/drm/i915/display/intel_display_irq.h | 7 +---- drivers/gpu/drm/i915/i915_irq.c | 16 +++++----- drivers/gpu/drm/xe/display/xe_display.c | 2 +- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 27599a303843..9d6596ad8b3b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1981,7 +1981,7 @@ u32 i9xx_display_irq_enable_mask(struct intel_display *display) return enable_mask; } -void i915_display_irq_postinstall(struct intel_display *display) +static void i915_display_irq_postinstall(struct intel_display *display) { /* * Interrupt setup is already guaranteed to be single-threaded, this is @@ -1995,7 +1995,7 @@ void i915_display_irq_postinstall(struct intel_display *display) i915_enable_asle_pipestat(display); } -void i965_display_irq_postinstall(struct intel_display *display) +static void i965_display_irq_postinstall(struct intel_display *display) { /* * Interrupt setup is already guaranteed to be single-threaded, this is @@ -2057,7 +2057,7 @@ static void _vlv_display_irq_postinstall(struct intel_display *display) irq_init(display, VLV_IRQ_REGS, display->irq.vlv_imr_mask, enable_mask); } -void vlv_display_irq_postinstall(struct intel_display *display) +static void vlv_display_irq_postinstall(struct intel_display *display) { spin_lock_irq(&display->irq.lock); if (display->irq.vlv_display_irqs_enabled) @@ -2262,7 +2262,7 @@ void valleyview_disable_display_irqs(struct intel_display *display) spin_unlock_irq(&display->irq.lock); } -void ilk_de_irq_postinstall(struct intel_display *display) +static void ilk_de_irq_postinstall(struct intel_display *display) { u32 display_mask, extra_mask; @@ -2306,7 +2306,7 @@ void ilk_de_irq_postinstall(struct intel_display *display) static void mtp_irq_postinstall(struct intel_display *display); static void icp_irq_postinstall(struct intel_display *display); -void gen8_de_irq_postinstall(struct intel_display *display) +static void gen8_de_irq_postinstall(struct intel_display *display) { u32 de_pipe_masked = gen8_de_pipe_fault_mask(display) | GEN8_PIPE_CDCLK_CRC_DONE; @@ -2433,11 +2433,8 @@ static void icp_irq_postinstall(struct intel_display *display) irq_init(display, SDE_IRQ_REGS, ~mask, 0xffffffff); } -void gen11_de_irq_postinstall(struct intel_display *display) +static void gen11_de_irq_postinstall(struct intel_display *display) { - if (!HAS_DISPLAY(display)) - return; - gen8_de_irq_postinstall(display); intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); @@ -2445,30 +2442,37 @@ void gen11_de_irq_postinstall(struct intel_display *display) struct intel_display_irq_funcs { void (*reset)(struct intel_display *display); + void (*postinstall)(struct intel_display *display); }; static const struct intel_display_irq_funcs gen11_display_irq_funcs = { .reset = gen11_display_irq_reset, + .postinstall = gen11_de_irq_postinstall, }; static const struct intel_display_irq_funcs gen8_display_irq_funcs = { .reset = gen8_display_irq_reset, + .postinstall = gen8_de_irq_postinstall, }; static const struct intel_display_irq_funcs vlv_display_irq_funcs = { .reset = vlv_display_irq_reset, + .postinstall = vlv_display_irq_postinstall, }; static const struct intel_display_irq_funcs ilk_display_irq_funcs = { .reset = ilk_display_irq_reset, + .postinstall = ilk_de_irq_postinstall, }; static const struct intel_display_irq_funcs i965_display_irq_funcs = { .reset = i9xx_display_irq_reset, + .postinstall = i965_display_irq_postinstall, }; static const struct intel_display_irq_funcs i915_display_irq_funcs = { .reset = i9xx_display_irq_reset, + .postinstall = i915_display_irq_postinstall, }; void intel_display_irq_reset(struct intel_display *display) @@ -2479,6 +2483,14 @@ void intel_display_irq_reset(struct intel_display *display) display->irq.funcs->reset(display); } +void intel_display_irq_postinstall(struct intel_display *display) +{ + if (!HAS_DISPLAY(display)) + return; + + display->irq.funcs->postinstall(display); +} + void intel_display_irq_init(struct intel_display *display) { spin_lock_init(&display->irq.lock); diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index 21b2145656cd..fd9873ce9755 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -59,14 +59,9 @@ u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl); void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir); void intel_display_irq_reset(struct intel_display *display); +void intel_display_irq_postinstall(struct intel_display *display); u32 i9xx_display_irq_enable_mask(struct intel_display *display); -void i915_display_irq_postinstall(struct intel_display *display); -void i965_display_irq_postinstall(struct intel_display *display); -void vlv_display_irq_postinstall(struct intel_display *display); -void ilk_de_irq_postinstall(struct intel_display *display); -void gen8_de_irq_postinstall(struct intel_display *display); -void gen11_de_irq_postinstall(struct intel_display *display); u32 i915_pipestat_enable_mask(struct intel_display *display, enum pipe pipe); void i915_enable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c4f56a869910..c21b289b8007 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -724,7 +724,7 @@ static void ilk_irq_postinstall(struct drm_i915_private *dev_priv) gen5_gt_irq_postinstall(to_gt(dev_priv)); - ilk_de_irq_postinstall(display); + intel_display_irq_postinstall(display); } static void valleyview_irq_postinstall(struct drm_i915_private *dev_priv) @@ -733,7 +733,7 @@ static void valleyview_irq_postinstall(struct drm_i915_private *dev_priv) gen5_gt_irq_postinstall(to_gt(dev_priv)); - vlv_display_irq_postinstall(display); + intel_display_irq_postinstall(display); intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); intel_uncore_posting_read(&dev_priv->uncore, VLV_MASTER_IER); @@ -744,7 +744,7 @@ static void gen8_irq_postinstall(struct drm_i915_private *dev_priv) struct intel_display *display = dev_priv->display; gen8_gt_irq_postinstall(to_gt(dev_priv)); - gen8_de_irq_postinstall(display); + intel_display_irq_postinstall(display); gen8_master_intr_enable(intel_uncore_regs(&dev_priv->uncore)); } @@ -757,7 +757,7 @@ static void gen11_irq_postinstall(struct drm_i915_private *dev_priv) u32 gu_misc_masked = GEN11_GU_MISC_GSE; gen11_gt_irq_postinstall(gt); - gen11_de_irq_postinstall(display); + intel_display_irq_postinstall(display); gen2_irq_init(uncore, GEN11_GU_MISC_IRQ_REGS, ~gu_misc_masked, gu_misc_masked); @@ -778,7 +778,7 @@ static void dg1_irq_postinstall(struct drm_i915_private *dev_priv) gen2_irq_init(uncore, GEN11_GU_MISC_IRQ_REGS, ~gu_misc_masked, gu_misc_masked); - gen11_de_irq_postinstall(display); + intel_display_irq_postinstall(display); dg1_master_intr_enable(intel_uncore_regs(uncore)); intel_uncore_posting_read(uncore, DG1_MSTR_TILE_INTR); @@ -790,7 +790,7 @@ static void cherryview_irq_postinstall(struct drm_i915_private *dev_priv) gen8_gt_irq_postinstall(to_gt(dev_priv)); - vlv_display_irq_postinstall(display); + intel_display_irq_postinstall(display); intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); intel_uncore_posting_read(&dev_priv->uncore, GEN8_MASTER_IRQ); @@ -888,7 +888,7 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv) gen2_irq_init(uncore, GEN2_IRQ_REGS, dev_priv->gen2_imr_mask, enable_mask); - i915_display_irq_postinstall(display); + intel_display_irq_postinstall(display); } static irqreturn_t i915_irq_handler(int irq, void *arg) @@ -997,7 +997,7 @@ static void i965_irq_postinstall(struct drm_i915_private *dev_priv) gen2_irq_init(uncore, GEN2_IRQ_REGS, dev_priv->gen2_imr_mask, enable_mask); - i965_display_irq_postinstall(display); + intel_display_irq_postinstall(display); } static irqreturn_t i965_irq_handler(int irq, void *arg) diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 6ce8f37ddd44..00820cce59ea 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -253,7 +253,7 @@ void xe_display_irq_postinstall(struct xe_device *xe) if (!xe->info.probe_display) return; - gen11_de_irq_postinstall(display); + intel_display_irq_postinstall(display); } static bool suspend_to_idle(void) From 7fa007588c175be9471da4f1c59d8b7270f6063e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 19:13:28 +0300 Subject: [PATCH 06/80] drm/i915/irq: add platform specific display irq ack functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add i9xx_display_irq_ack() and vlv_display_irq_ack() to group together the various irq ack parts for the platforms, to declutter the core i915 irq code from the details. Introduce struct intel_display_irq_state to group together all the data the ack functions need. In the follow-up, this state will be passed on to similar platform specific handler functions. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/30d2f1c0c6acd997b841f0dfc538f703e064998d.1778688699.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_irq.c | 45 +++++- .../gpu/drm/i915/display/intel_display_irq.h | 14 +- drivers/gpu/drm/i915/i915_irq.c | 144 ++++++------------ 3 files changed, 102 insertions(+), 101 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 9d6596ad8b3b..5eefb7e093c4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -23,6 +23,7 @@ #include "intel_fifo_underrun.h" #include "intel_gmbus.h" #include "intel_hotplug_irq.h" +#include "intel_lpe_audio.h" #include "intel_parent.h" #include "intel_pipe_crc_regs.h" #include "intel_plane.h" @@ -529,8 +530,8 @@ static void i9xx_pipestat_irq_reset(struct intel_display *display) } } -void i9xx_pipestat_irq_ack(struct intel_display *display, - u32 iir, u32 pipe_stats[I915_MAX_PIPES]) +static void i9xx_pipestat_irq_ack(struct intel_display *display, + u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { enum pipe pipe; @@ -1898,8 +1899,8 @@ static void vlv_page_table_error_irq_handler(struct intel_display *display, u32 } } -void vlv_display_error_irq_ack(struct intel_display *display, - u32 *eir, u32 *dpinvgtt) +static void vlv_display_error_irq_ack(struct intel_display *display, + u32 *eir, u32 *dpinvgtt) { u32 emr; @@ -2010,6 +2011,16 @@ static void i965_display_irq_postinstall(struct intel_display *display) i915_enable_asle_pipestat(display); } +void i9xx_display_irq_ack(struct intel_display *display, + struct intel_display_irq_state *state) +{ + if (state->iir & I915_DISPLAY_PORT_INTERRUPT) + state->hotplug_status = i9xx_hpd_irq_ack(display); + + /* Call regardless, as some status bits might not be signalled in IIR */ + i9xx_pipestat_irq_ack(display, state->iir, state->pipe_stats); +} + static u32 vlv_error_mask(void) { /* TODO enable other errors too? */ @@ -2065,6 +2076,32 @@ static void vlv_display_irq_postinstall(struct intel_display *display) spin_unlock_irq(&display->irq.lock); } +static u32 vlv_lpe_irq_mask(struct intel_display *display) +{ + if (display->platform.cherryview) + return I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT | + I915_LPE_PIPE_C_INTERRUPT; + else + return I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT; +} + +void vlv_display_irq_ack(struct intel_display *display, + struct intel_display_irq_state *state) +{ + if (state->iir & I915_DISPLAY_PORT_INTERRUPT) + state->hotplug_status = i9xx_hpd_irq_ack(display); + + if (state->iir & I915_MASTER_ERROR_INTERRUPT) + vlv_display_error_irq_ack(display, &state->eir, &state->dpinvgtt); + + /* Call regardless, as some status bits might not be signalled in IIR */ + i9xx_pipestat_irq_ack(display, state->iir, state->pipe_stats); + + /* The handler acks the irq, so need to call the handler here */ + if (state->iir & vlv_lpe_irq_mask(display)) + intel_lpe_audio_irq_handler(display); +} + static void ibx_display_irq_reset(struct intel_display *display) { if (HAS_PCH_NOP(display)) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index fd9873ce9755..8d4ea53bb9db 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -58,22 +58,30 @@ void gen11_display_irq_handler(struct intel_display *display); u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl); void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir); +struct intel_display_irq_state { + u32 iir; + u32 eir; + u32 hotplug_status; + u32 dpinvgtt; + u32 pipe_stats[I915_MAX_PIPES]; +}; + void intel_display_irq_reset(struct intel_display *display); void intel_display_irq_postinstall(struct intel_display *display); +void vlv_display_irq_ack(struct intel_display *display, struct intel_display_irq_state *state); +void i9xx_display_irq_ack(struct intel_display *display, struct intel_display_irq_state *state); + u32 i9xx_display_irq_enable_mask(struct intel_display *display); u32 i915_pipestat_enable_mask(struct intel_display *display, enum pipe pipe); void i915_enable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask); void i915_disable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask); -void i9xx_pipestat_irq_ack(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); - void i915_pipestat_irq_handler(struct intel_display *display, u32 iir, const u32 pipe_stats[I915_MAX_PIPES]); void i965_pipestat_irq_handler(struct intel_display *display, u32 iir, const u32 pipe_stats[I915_MAX_PIPES]); void valleyview_pipestat_irq_handler(struct intel_display *display, const u32 pipe_stats[I915_MAX_PIPES]); -void vlv_display_error_irq_ack(struct intel_display *display, u32 *eir, u32 *dpinvgtt); void vlv_display_error_irq_handler(struct intel_display *display, u32 eir, u32 dpinvgtt); void intel_display_irq_init(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c21b289b8007..9022e32156a5 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -39,7 +39,6 @@ #include "display/intel_display_irq.h" #include "display/intel_hotplug.h" #include "display/intel_hotplug_irq.h" -#include "display/intel_lpe_audio.h" #include "gt/intel_breadcrumbs.h" #include "gt/intel_gt.h" @@ -236,17 +235,15 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) disable_rpm_wakeref_asserts(&dev_priv->runtime_pm); do { - u32 iir, gt_iir, pm_iir; - u32 eir = 0, dpinvgtt = 0; - u32 pipe_stats[I915_MAX_PIPES] = {}; - u32 hotplug_status = 0; + struct intel_display_irq_state state = {}; + u32 gt_iir, pm_iir; u32 ier = 0; gt_iir = intel_uncore_read(&dev_priv->uncore, GTIIR); pm_iir = intel_uncore_read(&dev_priv->uncore, GEN6_PMIIR); - iir = intel_uncore_read(&dev_priv->uncore, VLV_IIR); + state.iir = intel_uncore_read(&dev_priv->uncore, VLV_IIR); - if (gt_iir == 0 && pm_iir == 0 && iir == 0) + if (gt_iir == 0 && pm_iir == 0 && state.iir == 0) break; ret = IRQ_HANDLED; @@ -272,26 +269,14 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) if (pm_iir) intel_uncore_write(&dev_priv->uncore, GEN6_PMIIR, pm_iir); - if (iir & I915_DISPLAY_PORT_INTERRUPT) - hotplug_status = i9xx_hpd_irq_ack(display); - - if (iir & I915_MASTER_ERROR_INTERRUPT) - vlv_display_error_irq_ack(display, &eir, &dpinvgtt); - - /* Call regardless, as some status bits might not be - * signalled in IIR */ - i9xx_pipestat_irq_ack(display, iir, pipe_stats); - - if (iir & (I915_LPE_PIPE_A_INTERRUPT | - I915_LPE_PIPE_B_INTERRUPT)) - intel_lpe_audio_irq_handler(display); + vlv_display_irq_ack(display, &state); /* * VLV_IIR is single buffered, and reflects the level * from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last. */ - if (iir) - intel_uncore_write(&dev_priv->uncore, VLV_IIR, iir); + if (state.iir) + intel_uncore_write(&dev_priv->uncore, VLV_IIR, state.iir); intel_uncore_write(&dev_priv->uncore, VLV_IER, ier); intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); @@ -301,13 +286,13 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) if (pm_iir) gen6_rps_irq_handler(&to_gt(dev_priv)->rps, pm_iir); - if (hotplug_status) - i9xx_hpd_irq_handler(display, hotplug_status); + if (state.hotplug_status) + i9xx_hpd_irq_handler(display, state.hotplug_status); - if (iir & I915_MASTER_ERROR_INTERRUPT) - vlv_display_error_irq_handler(display, eir, dpinvgtt); + if (state.iir & I915_MASTER_ERROR_INTERRUPT) + vlv_display_error_irq_handler(display, state.eir, state.dpinvgtt); - valleyview_pipestat_irq_handler(display, pipe_stats); + valleyview_pipestat_irq_handler(display, state.pipe_stats); } while (0); pmu_irq_stats(dev_priv, ret); @@ -330,16 +315,14 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) disable_rpm_wakeref_asserts(&dev_priv->runtime_pm); do { - u32 master_ctl, iir; - u32 eir = 0, dpinvgtt = 0; - u32 pipe_stats[I915_MAX_PIPES] = {}; - u32 hotplug_status = 0; + struct intel_display_irq_state state = {}; + u32 master_ctl; u32 ier = 0; master_ctl = intel_uncore_read(&dev_priv->uncore, GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL; - iir = intel_uncore_read(&dev_priv->uncore, VLV_IIR); + state.iir = intel_uncore_read(&dev_priv->uncore, VLV_IIR); - if (master_ctl == 0 && iir == 0) + if (master_ctl == 0 && state.iir == 0) break; ret = IRQ_HANDLED; @@ -362,38 +345,25 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) gen8_gt_irq_handler(to_gt(dev_priv), master_ctl); - if (iir & I915_DISPLAY_PORT_INTERRUPT) - hotplug_status = i9xx_hpd_irq_ack(display); - - if (iir & I915_MASTER_ERROR_INTERRUPT) - vlv_display_error_irq_ack(display, &eir, &dpinvgtt); - - /* Call regardless, as some status bits might not be - * signalled in IIR */ - i9xx_pipestat_irq_ack(display, iir, pipe_stats); - - if (iir & (I915_LPE_PIPE_A_INTERRUPT | - I915_LPE_PIPE_B_INTERRUPT | - I915_LPE_PIPE_C_INTERRUPT)) - intel_lpe_audio_irq_handler(display); + vlv_display_irq_ack(display, &state); /* * VLV_IIR is single buffered, and reflects the level * from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last. */ - if (iir) - intel_uncore_write(&dev_priv->uncore, VLV_IIR, iir); + if (state.iir) + intel_uncore_write(&dev_priv->uncore, VLV_IIR, state.iir); intel_uncore_write(&dev_priv->uncore, VLV_IER, ier); intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); - if (hotplug_status) - i9xx_hpd_irq_handler(display, hotplug_status); + if (state.hotplug_status) + i9xx_hpd_irq_handler(display, state.hotplug_status); - if (iir & I915_MASTER_ERROR_INTERRUPT) - vlv_display_error_irq_handler(display, eir, dpinvgtt); + if (state.iir & I915_MASTER_ERROR_INTERRUPT) + vlv_display_error_irq_handler(display, state.eir, state.dpinvgtt); - valleyview_pipestat_irq_handler(display, pipe_stats); + valleyview_pipestat_irq_handler(display, state.pipe_stats); } while (0); pmu_irq_stats(dev_priv, ret); @@ -904,39 +874,32 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) disable_rpm_wakeref_asserts(&dev_priv->runtime_pm); do { - u32 pipe_stats[I915_MAX_PIPES] = {}; + struct intel_display_irq_state state = {}; u32 eir = 0, eir_stuck = 0; - u32 hotplug_status = 0; - u32 iir; - iir = intel_uncore_read(&dev_priv->uncore, GEN2_IIR); - if (iir == 0) + state.iir = intel_uncore_read(&dev_priv->uncore, GEN2_IIR); + if (state.iir == 0) break; ret = IRQ_HANDLED; - if (iir & I915_DISPLAY_PORT_INTERRUPT) - hotplug_status = i9xx_hpd_irq_ack(display); + i9xx_display_irq_ack(display, &state); - /* Call regardless, as some status bits might not be - * signalled in IIR */ - i9xx_pipestat_irq_ack(display, iir, pipe_stats); - - if (iir & I915_MASTER_ERROR_INTERRUPT) + if (state.iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_ack(dev_priv, &eir, &eir_stuck); - intel_uncore_write(&dev_priv->uncore, GEN2_IIR, iir); + intel_uncore_write(&dev_priv->uncore, GEN2_IIR, state.iir); - if (iir & I915_USER_INTERRUPT) - intel_engine_cs_irq(to_gt(dev_priv)->engine[RCS0], iir); + if (state.iir & I915_USER_INTERRUPT) + intel_engine_cs_irq(to_gt(dev_priv)->engine[RCS0], state.iir); - if (iir & I915_MASTER_ERROR_INTERRUPT) + if (state.iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_handler(dev_priv, eir, eir_stuck); - if (hotplug_status) - i9xx_hpd_irq_handler(display, hotplug_status); + if (state.hotplug_status) + i9xx_hpd_irq_handler(display, state.hotplug_status); - i915_pipestat_irq_handler(display, iir, pipe_stats); + i915_pipestat_irq_handler(display, state.iir, state.pipe_stats); } while (0); pmu_irq_stats(dev_priv, ret); @@ -1013,44 +976,37 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) disable_rpm_wakeref_asserts(&dev_priv->runtime_pm); do { - u32 pipe_stats[I915_MAX_PIPES] = {}; + struct intel_display_irq_state state = {}; u32 eir = 0, eir_stuck = 0; - u32 hotplug_status = 0; - u32 iir; - iir = intel_uncore_read(&dev_priv->uncore, GEN2_IIR); - if (iir == 0) + state.iir = intel_uncore_read(&dev_priv->uncore, GEN2_IIR); + if (state.iir == 0) break; ret = IRQ_HANDLED; - if (iir & I915_DISPLAY_PORT_INTERRUPT) - hotplug_status = i9xx_hpd_irq_ack(display); + i9xx_display_irq_ack(display, &state); - /* Call regardless, as some status bits might not be - * signalled in IIR */ - i9xx_pipestat_irq_ack(display, iir, pipe_stats); - - if (iir & I915_MASTER_ERROR_INTERRUPT) + if (state.iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_ack(dev_priv, &eir, &eir_stuck); - intel_uncore_write(&dev_priv->uncore, GEN2_IIR, iir); + intel_uncore_write(&dev_priv->uncore, GEN2_IIR, state.iir); - if (iir & I915_USER_INTERRUPT) + if (state.iir & I915_USER_INTERRUPT) intel_engine_cs_irq(to_gt(dev_priv)->engine[RCS0], - iir); + state.iir); - if (iir & I915_BSD_USER_INTERRUPT) + if (state.iir & I915_BSD_USER_INTERRUPT) intel_engine_cs_irq(to_gt(dev_priv)->engine[VCS0], - iir >> 25); + state.iir >> 25); - if (iir & I915_MASTER_ERROR_INTERRUPT) + if (state.iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_handler(dev_priv, eir, eir_stuck); - if (hotplug_status) - i9xx_hpd_irq_handler(display, hotplug_status); + if (state.hotplug_status) + i9xx_hpd_irq_handler(display, state.hotplug_status); - i965_pipestat_irq_handler(display, iir, pipe_stats); + i965_pipestat_irq_handler(display, state.iir, state.pipe_stats); } while (0); pmu_irq_stats(dev_priv, IRQ_HANDLED); From c7ae1bdfcec9e48c2386cfaad1787d2812052b7a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 19:13:29 +0300 Subject: [PATCH 07/80] drm/i915/irq: add platform specific display irq handler functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a number of *_display_irq_handler() functions to group together the various display irq handler parts for the platforms, to declutter the core i915 irq code from the details. Add master_ctl to struct intel_display_irq_state, and pass the state pointer to the handlers where necessary. The handler function signatures are intentionally the same to allow for more refactoring. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/5088a9a658ce9a57049c999ee2ebababd7536b6c.1778688699.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_irq.c | 70 ++++++++++++++++--- .../gpu/drm/i915/display/intel_display_irq.h | 17 +++-- drivers/gpu/drm/i915/i915_irq.c | 38 +++------- drivers/gpu/drm/xe/display/xe_display.c | 2 +- 4 files changed, 79 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 5eefb7e093c4..672fd4f245ff 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -597,8 +597,8 @@ static void i9xx_pipestat_irq_ack(struct intel_display *display, spin_unlock(&display->irq.lock); } -void i915_pipestat_irq_handler(struct intel_display *display, - u32 iir, const u32 pipe_stats[I915_MAX_PIPES]) +static void i915_pipestat_irq_handler(struct intel_display *display, + u32 iir, const u32 pipe_stats[I915_MAX_PIPES]) { bool blc_event = false; enum pipe pipe; @@ -621,8 +621,8 @@ void i915_pipestat_irq_handler(struct intel_display *display, intel_opregion_asle_intr(display); } -void i965_pipestat_irq_handler(struct intel_display *display, - u32 iir, const u32 pipe_stats[I915_MAX_PIPES]) +static void i965_pipestat_irq_handler(struct intel_display *display, + u32 iir, const u32 pipe_stats[I915_MAX_PIPES]) { bool blc_event = false; enum pipe pipe; @@ -648,8 +648,8 @@ void i965_pipestat_irq_handler(struct intel_display *display, intel_gmbus_irq_handler(display); } -void valleyview_pipestat_irq_handler(struct intel_display *display, - const u32 pipe_stats[I915_MAX_PIPES]) +static void valleyview_pipestat_irq_handler(struct intel_display *display, + const u32 pipe_stats[I915_MAX_PIPES]) { enum pipe pipe; @@ -1021,7 +1021,8 @@ void ilk_display_irq_master_enable(struct intel_display *display, u32 de_ier, u3 intel_de_write_fw(display, SDEIER, sde_ier); } -bool ilk_display_irq_handler(struct intel_display *display) +bool ilk_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) { u32 de_iir; bool handled = false; @@ -1405,7 +1406,7 @@ static void gen8_read_and_ack_pch_irqs(struct intel_display *display, u32 *pch_i intel_de_write(display, PICAINTERRUPT_IER, pica_ier); } -void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl) +static void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl) { u32 iir; enum pipe pipe; @@ -1566,6 +1567,14 @@ void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl) } } +bool gen8_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) +{ + gen8_de_irq_handler(display, state->master_ctl); + + return true; +} + u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl) { u32 iir; @@ -1590,7 +1599,8 @@ void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir) intel_opregion_asle_intr(display); } -void gen11_display_irq_handler(struct intel_display *display) +bool gen11_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) { u32 disp_ctl; @@ -1606,6 +1616,8 @@ void gen11_display_irq_handler(struct intel_display *display) intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); intel_display_rpm_assert_unblock(display); + + return true; } static void i915gm_irq_cstate_wa_enable(struct intel_display *display) @@ -1921,8 +1933,8 @@ static void vlv_display_error_irq_ack(struct intel_display *display, intel_de_write(display, VLV_EMR, emr); } -void vlv_display_error_irq_handler(struct intel_display *display, - u32 eir, u32 dpinvgtt) +static void vlv_display_error_irq_handler(struct intel_display *display, + u32 eir, u32 dpinvgtt) { drm_dbg(display->drm, "Master Error, EIR 0x%08x\n", eir); @@ -2021,6 +2033,28 @@ void i9xx_display_irq_ack(struct intel_display *display, i9xx_pipestat_irq_ack(display, state->iir, state->pipe_stats); } +bool i965_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) +{ + if (state->hotplug_status) + i9xx_hpd_irq_handler(display, state->hotplug_status); + + i965_pipestat_irq_handler(display, state->iir, state->pipe_stats); + + return true; +} + +bool i915_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) +{ + if (state->hotplug_status) + i9xx_hpd_irq_handler(display, state->hotplug_status); + + i915_pipestat_irq_handler(display, state->iir, state->pipe_stats); + + return true; +} + static u32 vlv_error_mask(void) { /* TODO enable other errors too? */ @@ -2102,6 +2136,20 @@ void vlv_display_irq_ack(struct intel_display *display, intel_lpe_audio_irq_handler(display); } +bool vlv_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) +{ + if (state->hotplug_status) + i9xx_hpd_irq_handler(display, state->hotplug_status); + + if (state->iir & I915_MASTER_ERROR_INTERRUPT) + vlv_display_error_irq_handler(display, state->eir, state->dpinvgtt); + + valleyview_pipestat_irq_handler(display, state->pipe_stats); + + return true; +} + static void ibx_display_irq_reset(struct intel_display *display) { if (HAS_PCH_NOP(display)) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index 8d4ea53bb9db..59ec673ffc9b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -51,14 +51,12 @@ void bdw_disable_vblank(struct drm_crtc *crtc); void ilk_display_irq_master_disable(struct intel_display *display, u32 *de_ier, u32 *sde_ier); void ilk_display_irq_master_enable(struct intel_display *display, u32 de_ier, u32 sde_ier); -bool ilk_display_irq_handler(struct intel_display *display); -void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl); -void gen11_display_irq_handler(struct intel_display *display); u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl); void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir); struct intel_display_irq_state { + u32 master_ctl; u32 iir; u32 eir; u32 hotplug_status; @@ -72,18 +70,19 @@ void intel_display_irq_postinstall(struct intel_display *display); void vlv_display_irq_ack(struct intel_display *display, struct intel_display_irq_state *state); void i9xx_display_irq_ack(struct intel_display *display, struct intel_display_irq_state *state); +bool ilk_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); +bool gen8_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); +bool gen11_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); +bool i965_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); +bool i915_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); +bool vlv_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); + u32 i9xx_display_irq_enable_mask(struct intel_display *display); u32 i915_pipestat_enable_mask(struct intel_display *display, enum pipe pipe); void i915_enable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask); void i915_disable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask); -void i915_pipestat_irq_handler(struct intel_display *display, u32 iir, const u32 pipe_stats[I915_MAX_PIPES]); -void i965_pipestat_irq_handler(struct intel_display *display, u32 iir, const u32 pipe_stats[I915_MAX_PIPES]); -void valleyview_pipestat_irq_handler(struct intel_display *display, const u32 pipe_stats[I915_MAX_PIPES]); - -void vlv_display_error_irq_handler(struct intel_display *display, u32 eir, u32 dpinvgtt); - void intel_display_irq_init(struct intel_display *display); void i915gm_irq_cstate_wa(struct intel_display *display, bool enable); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9022e32156a5..0d0ee2c43f00 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -38,7 +38,6 @@ #include "display/intel_display_irq.h" #include "display/intel_hotplug.h" -#include "display/intel_hotplug_irq.h" #include "gt/intel_breadcrumbs.h" #include "gt/intel_gt.h" @@ -286,13 +285,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) if (pm_iir) gen6_rps_irq_handler(&to_gt(dev_priv)->rps, pm_iir); - if (state.hotplug_status) - i9xx_hpd_irq_handler(display, state.hotplug_status); - - if (state.iir & I915_MASTER_ERROR_INTERRUPT) - vlv_display_error_irq_handler(display, state.eir, state.dpinvgtt); - - valleyview_pipestat_irq_handler(display, state.pipe_stats); + vlv_display_irq_handler(display, &state); } while (0); pmu_irq_stats(dev_priv, ret); @@ -357,13 +350,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) intel_uncore_write(&dev_priv->uncore, VLV_IER, ier); intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); - if (state.hotplug_status) - i9xx_hpd_irq_handler(display, state.hotplug_status); - - if (state.iir & I915_MASTER_ERROR_INTERRUPT) - vlv_display_error_irq_handler(display, state.eir, state.dpinvgtt); - - valleyview_pipestat_irq_handler(display, state.pipe_stats); + vlv_display_irq_handler(display, &state); } while (0); pmu_irq_stats(dev_priv, ret); @@ -410,7 +397,7 @@ static irqreturn_t ilk_irq_handler(int irq, void *arg) ret = IRQ_HANDLED; } - if (ilk_display_irq_handler(display)) + if (ilk_display_irq_handler(display, NULL)) ret = IRQ_HANDLED; if (GRAPHICS_VER(i915) >= 6) { @@ -472,8 +459,11 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) /* IRQs are synced during runtime_suspend, we don't require a wakeref */ if (master_ctl & ~GEN8_GT_IRQS) { + const struct intel_display_irq_state state = { + .master_ctl = master_ctl, + }; disable_rpm_wakeref_asserts(&dev_priv->runtime_pm); - gen8_de_irq_handler(display, master_ctl); + gen8_display_irq_handler(display, &state); enable_rpm_wakeref_asserts(&dev_priv->runtime_pm); } @@ -525,7 +515,7 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg) /* IRQs are synced during runtime_suspend, we don't require a wakeref */ if (master_ctl & GEN11_DISPLAY_IRQ) - gen11_display_irq_handler(display); + gen11_display_irq_handler(display, NULL); gu_misc_iir = gen11_gu_misc_irq_ack(display, master_ctl); @@ -592,7 +582,7 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg) gen11_gt_irq_handler(gt, master_ctl); if (master_ctl & GEN11_DISPLAY_IRQ) - gen11_display_irq_handler(display); + gen11_display_irq_handler(display, NULL); gu_misc_iir = gen11_gu_misc_irq_ack(display, master_ctl); @@ -896,10 +886,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) if (state.iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_handler(dev_priv, eir, eir_stuck); - if (state.hotplug_status) - i9xx_hpd_irq_handler(display, state.hotplug_status); - - i915_pipestat_irq_handler(display, state.iir, state.pipe_stats); + i915_display_irq_handler(display, &state); } while (0); pmu_irq_stats(dev_priv, ret); @@ -1003,10 +990,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) if (state.iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_handler(dev_priv, eir, eir_stuck); - if (state.hotplug_status) - i9xx_hpd_irq_handler(display, state.hotplug_status); - - i965_pipestat_irq_handler(display, state.iir, state.pipe_stats); + i965_display_irq_handler(display, &state); } while (0); pmu_irq_stats(dev_priv, IRQ_HANDLED); diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 00820cce59ea..9bd871a8d545 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -222,7 +222,7 @@ void xe_display_irq_handler(struct xe_device *xe, u32 master_ctl) return; if (master_ctl & DISPLAY_IRQ) - gen11_display_irq_handler(display); + gen11_display_irq_handler(display, NULL); } void xe_display_irq_enable(struct xe_device *xe, u32 gu_misc_iir) From 13dccf09e8cfaa731606532ad6246aea8e547cb7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 19:13:30 +0300 Subject: [PATCH 08/80] drm/i915/irq: add intel_display_irq_ack() to irq funcs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call the platform specific display irq ack hooks, if any, via intel_display_irq_ack(). Check for HAS_DISPLAY() in intel_display_irq_ack() for completeness even though fusing is not possible on the platforms in question. v3: - Pure vfunc change (Ville) v2: - Include LPE audio in the ack part - Check for HAS_DISPLAY() Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/a72974d66f7696ca35380b44f13f938b2d4d690d.1778688699.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_irq.c | 21 +++++++++++++++---- .../gpu/drm/i915/display/intel_display_irq.h | 4 +--- drivers/gpu/drm/i915/i915_irq.c | 8 +++---- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 672fd4f245ff..c777b7f249c8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -2023,8 +2023,8 @@ static void i965_display_irq_postinstall(struct intel_display *display) i915_enable_asle_pipestat(display); } -void i9xx_display_irq_ack(struct intel_display *display, - struct intel_display_irq_state *state) +static void i9xx_display_irq_ack(struct intel_display *display, + struct intel_display_irq_state *state) { if (state->iir & I915_DISPLAY_PORT_INTERRUPT) state->hotplug_status = i9xx_hpd_irq_ack(display); @@ -2119,8 +2119,8 @@ static u32 vlv_lpe_irq_mask(struct intel_display *display) return I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT; } -void vlv_display_irq_ack(struct intel_display *display, - struct intel_display_irq_state *state) +static void vlv_display_irq_ack(struct intel_display *display, + struct intel_display_irq_state *state) { if (state->iir & I915_DISPLAY_PORT_INTERRUPT) state->hotplug_status = i9xx_hpd_irq_ack(display); @@ -2528,6 +2528,7 @@ static void gen11_de_irq_postinstall(struct intel_display *display) struct intel_display_irq_funcs { void (*reset)(struct intel_display *display); void (*postinstall)(struct intel_display *display); + void (*ack)(struct intel_display *display, struct intel_display_irq_state *state); }; static const struct intel_display_irq_funcs gen11_display_irq_funcs = { @@ -2543,6 +2544,7 @@ static const struct intel_display_irq_funcs gen8_display_irq_funcs = { static const struct intel_display_irq_funcs vlv_display_irq_funcs = { .reset = vlv_display_irq_reset, .postinstall = vlv_display_irq_postinstall, + .ack = vlv_display_irq_ack, }; static const struct intel_display_irq_funcs ilk_display_irq_funcs = { @@ -2553,11 +2555,13 @@ static const struct intel_display_irq_funcs ilk_display_irq_funcs = { static const struct intel_display_irq_funcs i965_display_irq_funcs = { .reset = i9xx_display_irq_reset, .postinstall = i965_display_irq_postinstall, + .ack = i9xx_display_irq_ack, }; static const struct intel_display_irq_funcs i915_display_irq_funcs = { .reset = i9xx_display_irq_reset, .postinstall = i915_display_irq_postinstall, + .ack = i9xx_display_irq_ack, }; void intel_display_irq_reset(struct intel_display *display) @@ -2576,6 +2580,15 @@ void intel_display_irq_postinstall(struct intel_display *display) display->irq.funcs->postinstall(display); } +void intel_display_irq_ack(struct intel_display *display, + struct intel_display_irq_state *state) +{ + if (!HAS_DISPLAY(display) || !display->irq.funcs->ack) + return; + + display->irq.funcs->ack(display, state); +} + void intel_display_irq_init(struct intel_display *display) { spin_lock_init(&display->irq.lock); diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index 59ec673ffc9b..876ee171d74a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -66,9 +66,7 @@ struct intel_display_irq_state { void intel_display_irq_reset(struct intel_display *display); void intel_display_irq_postinstall(struct intel_display *display); - -void vlv_display_irq_ack(struct intel_display *display, struct intel_display_irq_state *state); -void i9xx_display_irq_ack(struct intel_display *display, struct intel_display_irq_state *state); +void intel_display_irq_ack(struct intel_display *display, struct intel_display_irq_state *state); bool ilk_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); bool gen8_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0d0ee2c43f00..321dc1e573cc 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -268,7 +268,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) if (pm_iir) intel_uncore_write(&dev_priv->uncore, GEN6_PMIIR, pm_iir); - vlv_display_irq_ack(display, &state); + intel_display_irq_ack(display, &state); /* * VLV_IIR is single buffered, and reflects the level @@ -338,7 +338,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) gen8_gt_irq_handler(to_gt(dev_priv), master_ctl); - vlv_display_irq_ack(display, &state); + intel_display_irq_ack(display, &state); /* * VLV_IIR is single buffered, and reflects the level @@ -873,7 +873,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) ret = IRQ_HANDLED; - i9xx_display_irq_ack(display, &state); + intel_display_irq_ack(display, &state); if (state.iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_ack(dev_priv, &eir, &eir_stuck); @@ -972,7 +972,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) ret = IRQ_HANDLED; - i9xx_display_irq_ack(display, &state); + intel_display_irq_ack(display, &state); if (state.iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_ack(dev_priv, &eir, &eir_stuck); From bbba23373bcca2133d945fbb8893c8cb1d377365 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 19:13:31 +0300 Subject: [PATCH 09/80] drm/i915/irq: add intel_display_irq_handler() to irq funcs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call the platform specific display irq handler hooks via intel_display_irq_handler(). v3: Pure vfunc change (Ville) v2: Rebase, handle LPE audio in ack (Ville) Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/d728f04a47532898c278ef208692ea173b446106.1778688699.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../gpu/drm/i915/display/intel_display_irq.c | 40 +++++++++++++------ .../gpu/drm/i915/display/intel_display_irq.h | 8 +--- drivers/gpu/drm/i915/i915_irq.c | 16 ++++---- drivers/gpu/drm/xe/display/xe_display.c | 2 +- 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index c777b7f249c8..899a38c0a7b7 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1021,8 +1021,8 @@ void ilk_display_irq_master_enable(struct intel_display *display, u32 de_ier, u3 intel_de_write_fw(display, SDEIER, sde_ier); } -bool ilk_display_irq_handler(struct intel_display *display, - const struct intel_display_irq_state *state) +static bool ilk_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) { u32 de_iir; bool handled = false; @@ -1567,8 +1567,8 @@ static void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl) } } -bool gen8_display_irq_handler(struct intel_display *display, - const struct intel_display_irq_state *state) +static bool gen8_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) { gen8_de_irq_handler(display, state->master_ctl); @@ -1599,8 +1599,8 @@ void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir) intel_opregion_asle_intr(display); } -bool gen11_display_irq_handler(struct intel_display *display, - const struct intel_display_irq_state *state) +static bool gen11_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) { u32 disp_ctl; @@ -2033,8 +2033,8 @@ static void i9xx_display_irq_ack(struct intel_display *display, i9xx_pipestat_irq_ack(display, state->iir, state->pipe_stats); } -bool i965_display_irq_handler(struct intel_display *display, - const struct intel_display_irq_state *state) +static bool i965_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) { if (state->hotplug_status) i9xx_hpd_irq_handler(display, state->hotplug_status); @@ -2044,8 +2044,8 @@ bool i965_display_irq_handler(struct intel_display *display, return true; } -bool i915_display_irq_handler(struct intel_display *display, - const struct intel_display_irq_state *state) +static bool i915_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) { if (state->hotplug_status) i9xx_hpd_irq_handler(display, state->hotplug_status); @@ -2136,8 +2136,8 @@ static void vlv_display_irq_ack(struct intel_display *display, intel_lpe_audio_irq_handler(display); } -bool vlv_display_irq_handler(struct intel_display *display, - const struct intel_display_irq_state *state) +static bool vlv_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) { if (state->hotplug_status) i9xx_hpd_irq_handler(display, state->hotplug_status); @@ -2529,39 +2529,46 @@ struct intel_display_irq_funcs { void (*reset)(struct intel_display *display); void (*postinstall)(struct intel_display *display); void (*ack)(struct intel_display *display, struct intel_display_irq_state *state); + bool (*handler)(struct intel_display *display, const struct intel_display_irq_state *state); }; static const struct intel_display_irq_funcs gen11_display_irq_funcs = { .reset = gen11_display_irq_reset, .postinstall = gen11_de_irq_postinstall, + .handler = gen11_display_irq_handler, }; static const struct intel_display_irq_funcs gen8_display_irq_funcs = { .reset = gen8_display_irq_reset, .postinstall = gen8_de_irq_postinstall, + .handler = gen8_display_irq_handler, }; static const struct intel_display_irq_funcs vlv_display_irq_funcs = { .reset = vlv_display_irq_reset, .postinstall = vlv_display_irq_postinstall, .ack = vlv_display_irq_ack, + .handler = vlv_display_irq_handler, }; static const struct intel_display_irq_funcs ilk_display_irq_funcs = { .reset = ilk_display_irq_reset, .postinstall = ilk_de_irq_postinstall, + .handler = ilk_display_irq_handler, }; static const struct intel_display_irq_funcs i965_display_irq_funcs = { .reset = i9xx_display_irq_reset, .postinstall = i965_display_irq_postinstall, .ack = i9xx_display_irq_ack, + .handler = i965_display_irq_handler, }; static const struct intel_display_irq_funcs i915_display_irq_funcs = { .reset = i9xx_display_irq_reset, .postinstall = i915_display_irq_postinstall, .ack = i9xx_display_irq_ack, + .handler = i915_display_irq_handler, }; void intel_display_irq_reset(struct intel_display *display) @@ -2589,6 +2596,15 @@ void intel_display_irq_ack(struct intel_display *display, display->irq.funcs->ack(display, state); } +bool intel_display_irq_handler(struct intel_display *display, + const struct intel_display_irq_state *state) +{ + if (!HAS_DISPLAY(display) || !display->irq.funcs->handler) + return true; + + return display->irq.funcs->handler(display, state); +} + void intel_display_irq_init(struct intel_display *display) { spin_lock_init(&display->irq.lock); diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index 876ee171d74a..a1227cee885a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -67,13 +67,7 @@ struct intel_display_irq_state { void intel_display_irq_reset(struct intel_display *display); void intel_display_irq_postinstall(struct intel_display *display); void intel_display_irq_ack(struct intel_display *display, struct intel_display_irq_state *state); - -bool ilk_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); -bool gen8_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); -bool gen11_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); -bool i965_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); -bool i915_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); -bool vlv_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); +bool intel_display_irq_handler(struct intel_display *display, const struct intel_display_irq_state *state); u32 i9xx_display_irq_enable_mask(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 321dc1e573cc..30ce462e92ab 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -285,7 +285,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) if (pm_iir) gen6_rps_irq_handler(&to_gt(dev_priv)->rps, pm_iir); - vlv_display_irq_handler(display, &state); + intel_display_irq_handler(display, &state); } while (0); pmu_irq_stats(dev_priv, ret); @@ -350,7 +350,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) intel_uncore_write(&dev_priv->uncore, VLV_IER, ier); intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); - vlv_display_irq_handler(display, &state); + intel_display_irq_handler(display, &state); } while (0); pmu_irq_stats(dev_priv, ret); @@ -397,7 +397,7 @@ static irqreturn_t ilk_irq_handler(int irq, void *arg) ret = IRQ_HANDLED; } - if (ilk_display_irq_handler(display, NULL)) + if (intel_display_irq_handler(display, NULL)) ret = IRQ_HANDLED; if (GRAPHICS_VER(i915) >= 6) { @@ -463,7 +463,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) .master_ctl = master_ctl, }; disable_rpm_wakeref_asserts(&dev_priv->runtime_pm); - gen8_display_irq_handler(display, &state); + intel_display_irq_handler(display, &state); enable_rpm_wakeref_asserts(&dev_priv->runtime_pm); } @@ -515,7 +515,7 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg) /* IRQs are synced during runtime_suspend, we don't require a wakeref */ if (master_ctl & GEN11_DISPLAY_IRQ) - gen11_display_irq_handler(display, NULL); + intel_display_irq_handler(display, NULL); gu_misc_iir = gen11_gu_misc_irq_ack(display, master_ctl); @@ -582,7 +582,7 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg) gen11_gt_irq_handler(gt, master_ctl); if (master_ctl & GEN11_DISPLAY_IRQ) - gen11_display_irq_handler(display, NULL); + intel_display_irq_handler(display, NULL); gu_misc_iir = gen11_gu_misc_irq_ack(display, master_ctl); @@ -886,7 +886,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) if (state.iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_handler(dev_priv, eir, eir_stuck); - i915_display_irq_handler(display, &state); + intel_display_irq_handler(display, &state); } while (0); pmu_irq_stats(dev_priv, ret); @@ -990,7 +990,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) if (state.iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_handler(dev_priv, eir, eir_stuck); - i965_display_irq_handler(display, &state); + intel_display_irq_handler(display, &state); } while (0); pmu_irq_stats(dev_priv, IRQ_HANDLED); diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 9bd871a8d545..75324aa82631 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -222,7 +222,7 @@ void xe_display_irq_handler(struct xe_device *xe, u32 master_ctl) return; if (master_ctl & DISPLAY_IRQ) - gen11_display_irq_handler(display, NULL); + intel_display_irq_handler(display, NULL); } void xe_display_irq_enable(struct xe_device *xe, u32 gu_misc_iir) From f7abc4af2b19240a145a221461dfe756cc01d74a Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 11 May 2026 18:02:15 +0530 Subject: [PATCH 10/80] drm/i915/dp: Fix readback for target_rr in Adaptive Sync SDP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correct the bit-shift logic to properly readback the 10 bit target_rr from DB3 and DB4. v2: Align the style with readback for vtotal. (Ville) Fixes: 12ea89291603 ("drm/i915/dp: Add Read/Write support for Adaptive Sync SDP") Cc: Mitul Golani Cc: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260511123218.1589830-2-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 61ccaf0a46b6..f01a6eed3839 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5376,7 +5376,7 @@ int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp, as_sdp->length = sdp->sdp_header.HB3 & DP_AS_SDP_LENGTH_MASK; as_sdp->mode = sdp->db[0] & DP_AS_SDP_OPERATION_MODE_MASK; as_sdp->vtotal = (sdp->db[2] << 8) | sdp->db[1]; - as_sdp->target_rr = (u64)sdp->db[3] | ((u64)sdp->db[4] & 0x3); + as_sdp->target_rr = ((sdp->db[4] & 0x3) << 8) | sdp->db[3]; as_sdp->target_rr_divider = sdp->db[4] & 0x20 ? true : false; return 0; From 563daf057863e06f35b90d072434c848ce280261 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 11 May 2026 18:02:16 +0530 Subject: [PATCH 11/80] drm/i915/dp: Use revision field of AS SDP data structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the revision field of struct drm_dp_as_sdp instead of current hardcoding for the AS SDP revisions. Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260511123218.1589830-3-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 3 ++- drivers/gpu/drm/i915/display/intel_dp.c | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9094ab4a9b6c..1e10163bdc36 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4881,7 +4881,8 @@ static bool intel_compare_dp_as_sdp(const struct drm_dp_as_sdp *a, const struct drm_dp_as_sdp *b) { - return a->vtotal == b->vtotal && + return a->revision == b->revision && + a->vtotal == b->vtotal && a->target_rr == b->target_rr && a->duration_incr_ms == b->duration_incr_ms && a->duration_decr_ms == b->duration_decr_ms && diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index f01a6eed3839..b30b1e773eee 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3204,6 +3204,7 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC; as_sdp->length = 0x9; as_sdp->duration_incr_ms = 0; + as_sdp->revision = 0x2; as_sdp->vtotal = intel_vrr_vmin_vtotal(crtc_state); if (crtc_state->cmrr.enable) { @@ -5180,7 +5181,7 @@ static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp, /* Prepare AS (Adaptive Sync) SDP Header */ sdp->sdp_header.HB0 = 0; sdp->sdp_header.HB1 = as_sdp->sdp_type; - sdp->sdp_header.HB2 = 0x02; + sdp->sdp_header.HB2 = as_sdp->revision; sdp->sdp_header.HB3 = as_sdp->length; /* Fill AS (Adaptive Sync) SDP Payload */ @@ -5367,13 +5368,11 @@ int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp, if (sdp->sdp_header.HB1 != DP_SDP_ADAPTIVE_SYNC) return -EINVAL; - if (sdp->sdp_header.HB2 != 0x02) - return -EINVAL; - if ((sdp->sdp_header.HB3 & 0x3F) != 9) return -EINVAL; as_sdp->length = sdp->sdp_header.HB3 & DP_AS_SDP_LENGTH_MASK; + as_sdp->revision = sdp->sdp_header.HB2; as_sdp->mode = sdp->db[0] & DP_AS_SDP_OPERATION_MODE_MASK; as_sdp->vtotal = (sdp->db[2] << 8) | sdp->db[1]; as_sdp->target_rr = ((sdp->db[4] & 0x3) << 8) | sdp->db[3]; From 801b3544b9a46050e4928362b23ef4ac3886c241 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 11 May 2026 18:02:17 +0530 Subject: [PATCH 12/80] drm/i915/dp: Set sdp_type in AS SDP unpack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add sdp_type in AS SDP unpack. Since the field sdp_type is not compared in intel_compare_dp_as_sdp() it doesn't throw up any mismatch error yet. In the subsequent change this field will be added along with other missing fields for comparison. Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260511123218.1589830-4-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index b30b1e773eee..1920d2f02666 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5371,6 +5371,7 @@ int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp, if ((sdp->sdp_header.HB3 & 0x3F) != 9) return -EINVAL; + as_sdp->sdp_type = sdp->sdp_header.HB1; as_sdp->length = sdp->sdp_header.HB3 & DP_AS_SDP_LENGTH_MASK; as_sdp->revision = sdp->sdp_header.HB2; as_sdp->mode = sdp->db[0] & DP_AS_SDP_OPERATION_MODE_MASK; From 51d34dd8accce8523ff3f039826096e53f9c04d1 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 11 May 2026 18:02:18 +0530 Subject: [PATCH 13/80] drm/i915/dp: Include all relevant AS SDP fields in comparison MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add missing drm_dp_as_sdp header fields to intel_compare_dp_as_sdp() comparison. Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260511123218.1589830-5-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 1e10163bdc36..757a78c75bbf 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4881,11 +4881,14 @@ static bool intel_compare_dp_as_sdp(const struct drm_dp_as_sdp *a, const struct drm_dp_as_sdp *b) { - return a->revision == b->revision && + return a->sdp_type == b->sdp_type && + a->revision == b->revision && + a->length == b->length && a->vtotal == b->vtotal && a->target_rr == b->target_rr && a->duration_incr_ms == b->duration_incr_ms && a->duration_decr_ms == b->duration_decr_ms && + a->target_rr_divider == b->target_rr_divider && a->mode == b->mode; } From 1da1c9294825f08f622c473480d185680c2a3b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 15 May 2026 12:57:53 +0300 Subject: [PATCH 14/80] drm/i915/psr: Add defininitions for INTEL_WA_REGISTER_CAPS DPCD register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EDP specification says: "If either VSC SDP is unable to be transmitted 100 ns before the SU region, the Source device may optionally transmit the VSC SDP during the prior video scan line’s HBlank period There is a Intel specific drm dp register currently containing bits related how TCON can support PSR2 with SDP on prior line." Unfortunately many panels are having problems in implementing this. So there is a custom Intel specific DPCD register (INTEL_WA_REGISTER_CAPS) to figure out if this is properly implemented on a panel or if panel doesn't require that 100 ns delay before the SU region. Here are the definitions in this custom DPCD address: 0 = Panel doesn't support SDP on prior line 1 = Panel supports SDP on prior line 2 = Panel doesn't have 100ns requirement 3 = Reserved Add definitions for this new register and it's values into new header intel_dpcd.h. v2: add INTEL_DPCD_ prefix to definitions Bspec: 74741 Signed-off-by: Jouni Högander Reviewed-by: Suraj Kandpal Link: https://patch.msgid.link/20260515095756.2799483-2-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_dpcd.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 drivers/gpu/drm/i915/display/intel_dpcd.h diff --git a/drivers/gpu/drm/i915/display/intel_dpcd.h b/drivers/gpu/drm/i915/display/intel_dpcd.h new file mode 100644 index 000000000000..4aea5326f2ed --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_dpcd.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2026 Intel Corporation + */ + +#ifndef __INTEL_DPCD_H__ +#define __INTEL_DPCD_H__ + +#define INTEL_DPCD_INTEL_WA_REGISTER_CAPS 0x3f0 +# define INTEL_DPCD_INTEL_WA_REGISTER_CAPS_PSR2_EARLYSCANLINE_SDP_SUPPORT_MASK REG_GENMASK(1, 0) +# define INTEL_DPCD_INTEL_WA_REGISTER_CAPS_FALL_BACK_TO_PSR1 0 +# define INTEL_DPCD_INTEL_WA_REGISTER_CAPS_PSR2_WITH_EARLY_SCANLINE 1 +# define INTEL_DPCD_INTEL_WA_REGISTER_CAPS_PSR2_WITHOUT_EARLY_SCANLINE 2 + +#endif /* __INTEL_DPCD_H__ */ From c48ff24d0f4ab7ad696b2d35ad64ce7e049c668c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 15 May 2026 12:57:54 +0300 Subject: [PATCH 15/80] drm/i915/psr: Read Intel DPCD workaround register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Read Intel DPCD workaround register and store it into intel_connector->dp.psr_caps. psr_caps was chosen as currently it contains only PSR workaround for PSR2 SDP on prior scanline implementation. Signed-off-by: Jouni Högander Reviewed-by: Suraj Kandpal Link: https://patch.msgid.link/20260515095756.2799483-3-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_psr.c | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index b7bcf8fefa3e..f44be5c689ae 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -584,6 +584,7 @@ struct intel_connector { struct { u8 dpcd[EDP_PSR_RECEIVER_CAP_SIZE]; + u8 intel_wa_dpcd; bool support; bool su_support; diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 892d209dce1b..03a2377c315c 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -44,6 +44,7 @@ #include "intel_display_wa.h" #include "intel_dmc.h" #include "intel_dp.h" +#include "intel_dpcd.h" #include "intel_dp_aux.h" #include "intel_dp_tunnel.h" #include "intel_dsb.h" @@ -720,8 +721,14 @@ static void _psr_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *co connector->dp.psr_caps.su_support ? "" : "not "); } - if (connector->dp.psr_caps.su_support) + if (connector->dp.psr_caps.su_support) { + ret = drm_dp_dpcd_read_byte(&intel_dp->aux, + INTEL_DPCD_INTEL_WA_REGISTER_CAPS, + &connector->dp.psr_caps.intel_wa_dpcd); + if (ret < 0) + return; _psr_compute_su_granularity(intel_dp, connector); + } } void intel_psr_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector) From c3fe899fbeac86ea4a5ca9dd845b2cbc0da46249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 15 May 2026 12:57:55 +0300 Subject: [PATCH 16/80] drm/i915/psr: Apply Intel DPCD workaround when SDP on prior line used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is Intel specific workaround DPCD address containing workaround for case where SDP is on prior line. Apply this workaround according to values in the offset. Fixes: 61e887329e33 ("drm/i915/xelpd: Handle PSR2 SDP indication in the prior scanline") Cc: # v5.15+ Signed-off-by: Jouni Högander Reviewed-by: Suraj Kandpal Link: https://patch.msgid.link/20260515095756.2799483-4-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 35 +++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 03a2377c315c..bb1c0252837e 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1389,9 +1389,35 @@ static bool psr2_granularity_check(struct intel_crtc_state *crtc_state, return true; } -static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_dp *intel_dp, - struct intel_crtc_state *crtc_state) +static bool apply_scanline_indication_wa(struct intel_crtc_state *crtc_state, + struct intel_connector *connector) { + struct intel_dp *intel_dp = intel_attached_dp(connector); + u8 early_scanline_support = connector->dp.psr_caps.intel_wa_dpcd & + INTEL_DPCD_INTEL_WA_REGISTER_CAPS_PSR2_EARLYSCANLINE_SDP_SUPPORT_MASK; + + if (intel_dp->edp_dpcd[0] >= DP_EDP_15) + return true; + + switch (early_scanline_support) { + case INTEL_DPCD_INTEL_WA_REGISTER_CAPS_FALL_BACK_TO_PSR1: + crtc_state->req_psr2_sdp_prior_scanline = false; + return false; + case INTEL_DPCD_INTEL_WA_REGISTER_CAPS_PSR2_WITH_EARLY_SCANLINE: + return true; + case INTEL_DPCD_INTEL_WA_REGISTER_CAPS_PSR2_WITHOUT_EARLY_SCANLINE: + crtc_state->req_psr2_sdp_prior_scanline = false; + return true; + default: + MISSING_CASE(early_scanline_support); + return false; + } +} + +static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_crtc_state *crtc_state, + struct intel_connector *connector) +{ + struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_display *display = to_intel_display(intel_dp); const struct drm_display_mode *adjusted_mode = &crtc_state->uapi.adjusted_mode; u32 hblank_total, hblank_ns, req_ns; @@ -1410,7 +1436,8 @@ static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_dp *intel_d return false; crtc_state->req_psr2_sdp_prior_scanline = true; - return true; + + return apply_scanline_indication_wa(crtc_state, connector); } static int intel_psr_entry_setup_frames(struct intel_dp *intel_dp, @@ -1691,7 +1718,7 @@ static bool intel_sel_update_config_valid(struct intel_crtc_state *crtc_state, conn_state)) goto unsupported; - if (!_compute_psr2_sdp_prior_scanline_indication(intel_dp, crtc_state)) { + if (!_compute_psr2_sdp_prior_scanline_indication(crtc_state, connector)) { drm_dbg_kms(display->drm, "Selective update not enabled, SDP indication do not fit in hblank\n"); goto unsupported; From fed4921503a8a346ea4e6826eee7658f480341ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 15 May 2026 12:57:56 +0300 Subject: [PATCH 17/80] drm/i915/psr: Apply SDP on prior scanline workaround for Xe3p MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Xe3p there is an HW optimization done. When there is an SU triggered in Capture state, Link will be kept ON post Capture CRC SDP. Before valid SU pixels Intel source will transmit dummy pixels. Some TCONS are improperly considering these dummy pixels as a valid pixel data. Prior Xe3p link was was turned off even if there was SU triggered in capture state and no dummy pixels were transmitted. These dummy pixels are problem only if SDP on prior scanline is used and Early Transport is not in use. The workaround is to start SU area always at scanline 0. v2: use intel_display_wa Bspec: 74741, 79482 Signed-off-by: Jouni Högander Reviewed-by: Suraj Kandpal Link: https://patch.msgid.link/20260515095756.2799483-5-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_display_wa.c | 2 ++ drivers/gpu/drm/i915/display/intel_display_wa.h | 1 + drivers/gpu/drm/i915/display/intel_psr.c | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.c b/drivers/gpu/drm/i915/display/intel_display_wa.c index 7d3d63a59882..2094eda09c91 100644 --- a/drivers/gpu/drm/i915/display/intel_display_wa.c +++ b/drivers/gpu/drm/i915/display/intel_display_wa.c @@ -136,6 +136,8 @@ bool __intel_display_wa(struct intel_display *display, enum intel_display_wa wa, return DISPLAY_VER(display) == 20 && IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0); + case INTEL_DISPLAY_WA_16029024088: + return DISPLAY_VER(display) >= 35; case INTEL_DISPLAY_WA_18034343758: return DISPLAY_VER(display) == 20 || (display->platform.pantherlake && diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.h b/drivers/gpu/drm/i915/display/intel_display_wa.h index 15fec843f15e..9cdd148ea4fa 100644 --- a/drivers/gpu/drm/i915/display/intel_display_wa.h +++ b/drivers/gpu/drm/i915/display/intel_display_wa.h @@ -52,6 +52,7 @@ enum intel_display_wa { INTEL_DISPLAY_WA_16023588340, INTEL_DISPLAY_WA_16025573575, INTEL_DISPLAY_WA_16025596647, + INTEL_DISPLAY_WA_16029024088, INTEL_DISPLAY_WA_18034343758, INTEL_DISPLAY_WA_22010178259, INTEL_DISPLAY_WA_22010947358, diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index bb1c0252837e..b0414bd1dc6b 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2913,6 +2913,11 @@ intel_psr_apply_su_area_workarounds(struct intel_crtc_state *crtc_state) crtc_state->splitter.enable) crtc_state->psr2_su_area.y1 = 0; + if (intel_display_wa(display, INTEL_DISPLAY_WA_16029024088) && + crtc_state->req_psr2_sdp_prior_scanline && + !crtc_state->enable_psr2_su_region_et) + crtc_state->psr2_su_area.y1 = 0; + /* Wa 14019834836 */ if (DISPLAY_VER(display) == 30) intel_psr_apply_pr_link_on_su_wa(crtc_state); From 05e0550b65cd1604bd515fbc65f522bce4c10a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grzelak?= Date: Thu, 16 Apr 2026 18:37:44 +0200 Subject: [PATCH 18/80] drm/i915/aux: use polling when irqs are unavailable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PTL with physically disconnected display was observed to have 40s longer execution time when testing xe_fault_injection@xe_guc_mmio_send_recv. The issue has not been seen when reverting commit 40a9f77a28fa ("Revert "drm/i915/dp: change aux_ctl reg read to polling read""). Apparently the configuration suffers from not having AUX enabled when using interrupts. One probable cause can be xe enabling interrupts too late: interrupts need memory allocations which currently can't be done before the display FB takeover is done. As for now, use polling for AUX in case interrupts are unavailable. Fixes: 40a9f77a28fa ("Revert "drm/i915/dp: change aux_ctl reg read to polling read"") Suggested-by: Ville Syrjälä Signed-off-by: Michał Grzelak Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260416163744.288107-1-michal.grzelak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_aux.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c index ef33ecd81f28..3cb07b0a901c 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c @@ -12,6 +12,7 @@ #include "intel_dp.h" #include "intel_dp_aux.h" #include "intel_dp_aux_regs.h" +#include "intel_parent.h" #include "intel_pps.h" #include "intel_quirks.h" #include "intel_tc.h" @@ -60,18 +61,29 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp) struct intel_display *display = to_intel_display(intel_dp); intel_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp); const unsigned int timeout_ms = 10; + bool done = true; u32 status; - bool done; + int ret; + if (intel_parent_irq_enabled(display)) { #define C (((status = intel_de_read_notrace(display, ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0) - done = wait_event_timeout(display->gmbus.wait_queue, C, - msecs_to_jiffies_timeout(timeout_ms)); + done = wait_event_timeout(display->gmbus.wait_queue, C, + msecs_to_jiffies_timeout(timeout_ms)); + +#undef C + } else { + ret = intel_de_wait_ms(display, ch_ctl, + DP_AUX_CH_CTL_SEND_BUSY, 0, + timeout_ms, &status); + + if (ret == -ETIMEDOUT) + done = false; + } if (!done) drm_err(display->drm, "%s: did not complete or timeout within %ums (status 0x%08x)\n", intel_dp->aux.name, timeout_ms, status); -#undef C return status; } From 2c0e9814b427abe382ac4d7bc444fcd03f4e7610 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Mon, 18 May 2026 13:14:00 -0300 Subject: [PATCH 19/80] drm/i915/bw: Don't call intel_dram_info() too early If we end-up bailing early from intel_bw_init_hw() due to !HAS_DISPLAY(display), the call to intel_dram_info() to initialize dram_info will be meaningless. Move the call to be done after that check. Reviewed-by: Jani Nikula Link: https://patch.msgid.link/20260518-separate-platform-from-diplay-ip-specific-bw-params-v4-1-918528006549@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_bw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 9c3a9bbb49f6..7eef693b51ad 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -791,11 +791,13 @@ static unsigned int icl_qgv_bw(struct intel_display *display, void intel_bw_init_hw(struct intel_display *display) { - const struct dram_info *dram_info = intel_dram_info(display); + const struct dram_info *dram_info; if (!HAS_DISPLAY(display)) return; + dram_info = intel_dram_info(display); + /* * Starting with Xe3p_LPD, the hardware tells us whether memory has ECC * enabled that would impact display bandwidth. However, so far there From 71aedf795c3ae0c77fdf1144bfd43f5c5bebef09 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Mon, 18 May 2026 13:14:01 -0300 Subject: [PATCH 20/80] drm/i915/bw: Extract platform-specific parameters We got confirmation from the hardware team that the bandwidth parameters deprogbwlimit and derating are platform-specific and not tied to the display IP. As such, let's make sure that we use platform checks for those. The rest of the members of struct intel_sa_info are tied to the display IP and we will deal with them as a follow-up. v2: - Use good old if-ladder instead of weird-looking pattern "assign ret, check platform, then return ret". (Jani, Matt) - Have a single call site for get_platform_bw_params() and pass the result as parameter to the *_get_bw_info() functions. (Jani) - Avoid using "plat" as abbreviation for "platform". (Jani) - s/_plat_bw_params/_bw_params/, since all of the instances are prefixed with platform names. (Jani) - s/struct intel_platform_bw_params/struct intel_soc_bw_params/. (Matt) - Do not return a default value; prefer to return NULL and intentionally cause a NULL pointer dereference if a platform is missing. (Gustavo) v3: - Call get_soc_bw_params() only after the check on HAS_DISPLAY(display). (Jani) - Combine if-ladder branches for adl_s_bw_params into a single one. (Matt) - Flatten if-ladder by checking for WCL before PTL (as opposed to checking for WCL inside the brace for PTL). (Matt) - Bail out of intel_bw_init_hw() if display version is below 11. (Gustavo) v4: - Drop drm_WARN() when no platform was matched to avoid special-casing DG2 and any other platform that doesn't use SoC-specific parameters. (Jani) - Pass dram_info to get_soc_bw_params() to keep a single call to intel_dram_info(). (Jani) - Don't use 2 separate if-ladders (one for client and another for discrete platforms) and keep a single one for simplicity. (Gustavo) Cc: Jani Nikula Cc: Rodrigo Vivi Reviewed-by: Matt Roper Link: https://patch.msgid.link/20260518-separate-platform-from-diplay-ip-specific-bw-params-v4-2-918528006549@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_bw.c | 151 ++++++++++++++++-------- 1 file changed, 103 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 7eef693b51ad..f5a0a3e009c1 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -372,81 +372,136 @@ static int icl_sagv_max_dclk(const struct intel_qgv_info *qi) return dclk; } +struct intel_soc_bw_params { + u8 deprogbwlimit; + u8 derating; +}; + +static const struct intel_soc_bw_params icl_bw_params = { + .deprogbwlimit = 25, + .derating = 10, +}; + +static const struct intel_soc_bw_params tgl_bw_params = { + .deprogbwlimit = 34, + .derating = 10, +}; + +static const struct intel_soc_bw_params rkl_bw_params = { + .deprogbwlimit = 20, + .derating = 10, +}; + +static const struct intel_soc_bw_params adl_s_bw_params = { + .deprogbwlimit = 38, + .derating = 10, +}; + +static const struct intel_soc_bw_params adl_p_bw_params = { + .deprogbwlimit = 38, + .derating = 20, +}; + +static const struct intel_soc_bw_params bmg_bw_params = { + .deprogbwlimit = 53, + .derating = 30, +}; + +static const struct intel_soc_bw_params bmg_ecc_bw_params = { + .deprogbwlimit = 53, + .derating = 45, +}; + +static const struct intel_soc_bw_params ptl_bw_params = { + .deprogbwlimit = 65, + .derating = 10, +}; + +static const struct intel_soc_bw_params wcl_bw_params = { + .deprogbwlimit = 22, + .derating = 10, +}; + +static const struct intel_soc_bw_params *get_soc_bw_params(struct intel_display *display, + const struct dram_info *dram_info) +{ + if (display->platform.icelake || + display->platform.jasperlake || + display->platform.elkhartlake) + return &icl_bw_params; + else if (display->platform.tigerlake || + display->platform.dg1) + return &tgl_bw_params; + else if (display->platform.rocketlake) + return &rkl_bw_params; + else if (display->platform.alderlake_s || + display->platform.meteorlake || + display->platform.lunarlake) + return &adl_s_bw_params; + else if (display->platform.alderlake_p) + return &adl_p_bw_params; + else if (display->platform.battlemage && + dram_info->type == INTEL_DRAM_GDDR_ECC) + return &bmg_ecc_bw_params; + else if (display->platform.battlemage) + return &bmg_bw_params; + else if (display->platform.pantherlake_wildcatlake) + return &wcl_bw_params; + else if (display->platform.pantherlake || + display->platform.novalake) + return &ptl_bw_params; + + return NULL; +} + struct intel_sa_info { u16 displayrtids; - u8 deburst, deprogbwlimit, derating; + u8 deburst; }; static const struct intel_sa_info icl_sa_info = { .deburst = 8, - .deprogbwlimit = 25, /* GB/s */ .displayrtids = 128, - .derating = 10, }; static const struct intel_sa_info tgl_sa_info = { .deburst = 16, - .deprogbwlimit = 34, /* GB/s */ .displayrtids = 256, - .derating = 10, }; static const struct intel_sa_info rkl_sa_info = { .deburst = 8, - .deprogbwlimit = 20, /* GB/s */ .displayrtids = 128, - .derating = 10, }; static const struct intel_sa_info adls_sa_info = { .deburst = 16, - .deprogbwlimit = 38, /* GB/s */ .displayrtids = 256, - .derating = 10, }; static const struct intel_sa_info adlp_sa_info = { .deburst = 16, - .deprogbwlimit = 38, /* GB/s */ .displayrtids = 256, - .derating = 20, }; static const struct intel_sa_info mtl_sa_info = { .deburst = 32, - .deprogbwlimit = 38, /* GB/s */ .displayrtids = 256, - .derating = 10, -}; - -static const struct intel_sa_info xe2_hpd_sa_info = { - .derating = 30, - .deprogbwlimit = 53, - /* Other values not used by simplified algorithm */ -}; - -static const struct intel_sa_info xe2_hpd_ecc_sa_info = { - .derating = 45, - .deprogbwlimit = 53, - /* Other values not used by simplified algorithm */ }; static const struct intel_sa_info xe3lpd_sa_info = { .deburst = 32, - .deprogbwlimit = 65, /* GB/s */ .displayrtids = 256, - .derating = 10, }; static const struct intel_sa_info xe3lpd_3002_sa_info = { .deburst = 32, - .deprogbwlimit = 22, /* GB/s */ .displayrtids = 256, - .derating = 10, }; static int icl_get_bw_info(struct intel_display *display, const struct dram_info *dram_info, + const struct intel_soc_bw_params *soc_bw_params, const struct intel_sa_info *sa) { struct intel_qgv_info qi = {}; @@ -466,7 +521,7 @@ static int icl_get_bw_info(struct intel_display *display, } dclk_max = icl_sagv_max_dclk(&qi); - maxdebw = min(sa->deprogbwlimit * 1000, dclk_max * 16 * 6 / 10); + maxdebw = min(soc_bw_params->deprogbwlimit * 1000, dclk_max * 16 * 6 / 10); ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels); qi.deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); @@ -496,7 +551,7 @@ static int icl_get_bw_info(struct intel_display *display, bw = DIV_ROUND_UP(sp->dclk * clpchgroup * 32 * num_channels, ct); bi->deratedbw[j] = min(maxdebw, - bw * (100 - sa->derating) / 100); + bw * (100 - soc_bw_params->derating) / 100); drm_dbg_kms(display->drm, "BW%d / QGV %d: num_planes=%d deratedbw=%u\n", @@ -518,6 +573,7 @@ static int icl_get_bw_info(struct intel_display *display, static int tgl_get_bw_info(struct intel_display *display, const struct dram_info *dram_info, + const struct intel_soc_bw_params *soc_bw_params, const struct intel_sa_info *sa) { struct intel_qgv_info qi = {}; @@ -554,7 +610,7 @@ static int tgl_get_bw_info(struct intel_display *display, dclk_max = icl_sagv_max_dclk(&qi); peakbw = num_channels * DIV_ROUND_UP(qi.channel_width, 8) * dclk_max; - maxdebw = min(sa->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100); + maxdebw = min(soc_bw_params->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100); ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels); /* @@ -599,7 +655,7 @@ static int tgl_get_bw_info(struct intel_display *display, bw = DIV_ROUND_UP(sp->dclk * clpchgroup * 32 * num_channels, ct); bi->deratedbw[j] = min(maxdebw, - bw * (100 - sa->derating) / 100); + bw * (100 - soc_bw_params->derating) / 100); bi->peakbw[j] = DIV_ROUND_CLOSEST(sp->dclk * num_channels * qi.channel_width, 8); @@ -661,7 +717,7 @@ static void dg2_get_bw_info(struct intel_display *display) static int xe2_hpd_get_bw_info(struct intel_display *display, const struct dram_info *dram_info, - const struct intel_sa_info *sa) + const struct intel_soc_bw_params *soc_bw_params) { struct intel_qgv_info qi = {}; int num_channels = dram_info->num_channels; @@ -676,14 +732,14 @@ static int xe2_hpd_get_bw_info(struct intel_display *display, } peakbw = num_channels * qi.channel_width / 8 * icl_sagv_max_dclk(&qi); - maxdebw = min(sa->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 10); + maxdebw = min(soc_bw_params->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 10); for (i = 0; i < qi.num_points; i++) { const struct intel_qgv_point *point = &qi.points[i]; int bw = num_channels * (qi.channel_width / 8) * point->dclk; display->bw.max[0].deratedbw[i] = - min(maxdebw, (100 - sa->derating) * bw / 100); + min(maxdebw, (100 - soc_bw_params->derating) * bw / 100); display->bw.max[0].peakbw[i] = bw; drm_dbg_kms(display->drm, "QGV %d: deratedbw=%u peakbw: %u\n", @@ -792,11 +848,13 @@ static unsigned int icl_qgv_bw(struct intel_display *display, void intel_bw_init_hw(struct intel_display *display) { const struct dram_info *dram_info; + const struct intel_soc_bw_params *soc_bw_params; if (!HAS_DISPLAY(display)) return; dram_info = intel_dram_info(display); + soc_bw_params = get_soc_bw_params(display, dram_info); /* * Starting with Xe3p_LPD, the hardware tells us whether memory has ECC @@ -809,28 +867,25 @@ void intel_bw_init_hw(struct intel_display *display) if (DISPLAY_VER(display) >= 30) { if (DISPLAY_VERx100(display) == 3002) - tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info); + tgl_get_bw_info(display, dram_info, soc_bw_params, &xe3lpd_3002_sa_info); else - tgl_get_bw_info(display, dram_info, &xe3lpd_sa_info); + tgl_get_bw_info(display, dram_info, soc_bw_params, &xe3lpd_sa_info); } else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx) { - if (dram_info->type == INTEL_DRAM_GDDR_ECC) - xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_ecc_sa_info); - else - xe2_hpd_get_bw_info(display, dram_info, &xe2_hpd_sa_info); + xe2_hpd_get_bw_info(display, dram_info, soc_bw_params); } else if (DISPLAY_VER(display) >= 14) { - tgl_get_bw_info(display, dram_info, &mtl_sa_info); + tgl_get_bw_info(display, dram_info, soc_bw_params, &mtl_sa_info); } else if (display->platform.dg2) { dg2_get_bw_info(display); } else if (display->platform.alderlake_p) { - tgl_get_bw_info(display, dram_info, &adlp_sa_info); + tgl_get_bw_info(display, dram_info, soc_bw_params, &adlp_sa_info); } else if (display->platform.alderlake_s) { - tgl_get_bw_info(display, dram_info, &adls_sa_info); + tgl_get_bw_info(display, dram_info, soc_bw_params, &adls_sa_info); } else if (display->platform.rocketlake) { - tgl_get_bw_info(display, dram_info, &rkl_sa_info); + tgl_get_bw_info(display, dram_info, soc_bw_params, &rkl_sa_info); } else if (DISPLAY_VER(display) == 12) { - tgl_get_bw_info(display, dram_info, &tgl_sa_info); + tgl_get_bw_info(display, dram_info, soc_bw_params, &tgl_sa_info); } else if (DISPLAY_VER(display) == 11) { - icl_get_bw_info(display, dram_info, &icl_sa_info); + icl_get_bw_info(display, dram_info, soc_bw_params, &icl_sa_info); } } From 6906c382b5c691ccbce9c10e42a31d7ab2837fef Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Mon, 18 May 2026 13:14:02 -0300 Subject: [PATCH 21/80] drm/i915/bw: Deduplicate intel_sa_info instances Now that intel_sa_info contains bandwidth parameters specific to the display IP, we can drop many duplicates and reuse from previous releases. Let's do that and also simplify intel_bw_init_hw() while at it. v2: - Drop rkl_sa_info and reuse icl_sa_info. (Matt) - Add comment explaining RKL's display's peculiarity on using ICL's parameters. (Matt) - Don't rename xelpdp_sa_info to mtl_sa_info. Renaming of instances to use IP names will be done in upcoming changes. Reviewed-by: Matt Roper Link: https://patch.msgid.link/20260518-separate-platform-from-diplay-ip-specific-bw-params-v4-3-918528006549@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_bw.c | 51 ++++++------------------- 1 file changed, 12 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index f5a0a3e009c1..5f2f2b08b92f 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -469,36 +469,11 @@ static const struct intel_sa_info tgl_sa_info = { .displayrtids = 256, }; -static const struct intel_sa_info rkl_sa_info = { - .deburst = 8, - .displayrtids = 128, -}; - -static const struct intel_sa_info adls_sa_info = { - .deburst = 16, - .displayrtids = 256, -}; - -static const struct intel_sa_info adlp_sa_info = { - .deburst = 16, - .displayrtids = 256, -}; - static const struct intel_sa_info mtl_sa_info = { .deburst = 32, .displayrtids = 256, }; -static const struct intel_sa_info xe3lpd_sa_info = { - .deburst = 32, - .displayrtids = 256, -}; - -static const struct intel_sa_info xe3lpd_3002_sa_info = { - .deburst = 32, - .displayrtids = 256, -}; - static int icl_get_bw_info(struct intel_display *display, const struct dram_info *dram_info, const struct intel_soc_bw_params *soc_bw_params, @@ -865,25 +840,23 @@ void intel_bw_init_hw(struct intel_display *display) if (DISPLAY_VER(display) >= 35) drm_WARN_ON(display->drm, dram_info->ecc_impacting_de_bw); - if (DISPLAY_VER(display) >= 30) { - if (DISPLAY_VERx100(display) == 3002) - tgl_get_bw_info(display, dram_info, soc_bw_params, &xe3lpd_3002_sa_info); - else - tgl_get_bw_info(display, dram_info, soc_bw_params, &xe3lpd_sa_info); - } else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx) { + if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx) { xe2_hpd_get_bw_info(display, dram_info, soc_bw_params); } else if (DISPLAY_VER(display) >= 14) { tgl_get_bw_info(display, dram_info, soc_bw_params, &mtl_sa_info); } else if (display->platform.dg2) { dg2_get_bw_info(display); - } else if (display->platform.alderlake_p) { - tgl_get_bw_info(display, dram_info, soc_bw_params, &adlp_sa_info); - } else if (display->platform.alderlake_s) { - tgl_get_bw_info(display, dram_info, soc_bw_params, &adls_sa_info); - } else if (display->platform.rocketlake) { - tgl_get_bw_info(display, dram_info, soc_bw_params, &rkl_sa_info); - } else if (DISPLAY_VER(display) == 12) { - tgl_get_bw_info(display, dram_info, soc_bw_params, &tgl_sa_info); + } else if (DISPLAY_VER(display) >= 12) { + /* + * RKL's SoC was based on ICL and the display, even though being + * gen12, had changes to the memory interface to match gen11's, + * consequently inheriting gen11's display-specific bandwidth + * parameters. + */ + if (display->platform.rocketlake) + tgl_get_bw_info(display, dram_info, soc_bw_params, &icl_sa_info); + else + tgl_get_bw_info(display, dram_info, soc_bw_params, &tgl_sa_info); } else if (DISPLAY_VER(display) == 11) { icl_get_bw_info(display, dram_info, soc_bw_params, &icl_sa_info); } From b0938f96cf483a452286294bef802aca6dc4ff37 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Mon, 18 May 2026 13:14:03 -0300 Subject: [PATCH 22/80] drm/i915/bw: Rename struct intel_sa_info to intel_display_bw_params To align with struct intel_platform_bw_params, rename struct intel_sa_info to intel_display_bw_params. Also add comments to contrast their purposes. v2: - Use gen11 and gen12 as prefixes for ICL's and TGL's display-specific parameters variables. (Matt) - Prefer to use "display" instead of "disp" in variable names. (Jani) - Drop the redundant "disp" from the variable names. Cc: Jani Nikula Reviewed-by: Matt Roper Link: https://patch.msgid.link/20260518-separate-platform-from-diplay-ip-specific-bw-params-v4-4-918528006549@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_bw.c | 36 +++++++++++++++---------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 5f2f2b08b92f..26b294544d10 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -372,6 +372,10 @@ static int icl_sagv_max_dclk(const struct intel_qgv_info *qi) return dclk; } +/* + * Bandwidth parameters that are tied to the SoC (as opposed to struct + * intel_display_bw_params). + */ struct intel_soc_bw_params { u8 deprogbwlimit; u8 derating; @@ -454,22 +458,26 @@ static const struct intel_soc_bw_params *get_soc_bw_params(struct intel_display return NULL; } -struct intel_sa_info { +/* + * Bandwidth parameters that are tied to the display IP (as opposed to struct + * intel_soc_bw_params). + */ +struct intel_display_bw_params { u16 displayrtids; u8 deburst; }; -static const struct intel_sa_info icl_sa_info = { +static const struct intel_display_bw_params gen11_bw_params = { .deburst = 8, .displayrtids = 128, }; -static const struct intel_sa_info tgl_sa_info = { +static const struct intel_display_bw_params gen12_bw_params = { .deburst = 16, .displayrtids = 256, }; -static const struct intel_sa_info mtl_sa_info = { +static const struct intel_display_bw_params xelpdp_bw_params = { .deburst = 32, .displayrtids = 256, }; @@ -477,7 +485,7 @@ static const struct intel_sa_info mtl_sa_info = { static int icl_get_bw_info(struct intel_display *display, const struct dram_info *dram_info, const struct intel_soc_bw_params *soc_bw_params, - const struct intel_sa_info *sa) + const struct intel_display_bw_params *display_bw_params) { struct intel_qgv_info qi = {}; bool is_y_tile = true; /* assume y tile may be used */ @@ -497,7 +505,7 @@ static int icl_get_bw_info(struct intel_display *display, dclk_max = icl_sagv_max_dclk(&qi); maxdebw = min(soc_bw_params->deprogbwlimit * 1000, dclk_max * 16 * 6 / 10); - ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels); + ipqdepth = min(ipqdepthpch, display_bw_params->displayrtids / num_channels); qi.deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); for (i = 0; i < num_groups; i++) { @@ -505,7 +513,7 @@ static int icl_get_bw_info(struct intel_display *display, int clpchgroup; int j; - clpchgroup = (sa->deburst * qi.deinterleave / num_channels) << i; + clpchgroup = (display_bw_params->deburst * qi.deinterleave / num_channels) << i; bi->num_planes = (ipqdepth - clpchgroup) / clpchgroup + 1; bi->num_qgv_points = qi.num_points; @@ -549,7 +557,7 @@ static int icl_get_bw_info(struct intel_display *display, static int tgl_get_bw_info(struct intel_display *display, const struct dram_info *dram_info, const struct intel_soc_bw_params *soc_bw_params, - const struct intel_sa_info *sa) + const struct intel_display_bw_params *display_bw_params) { struct intel_qgv_info qi = {}; bool is_y_tile = true; /* assume y tile may be used */ @@ -587,7 +595,7 @@ static int tgl_get_bw_info(struct intel_display *display, peakbw = num_channels * DIV_ROUND_UP(qi.channel_width, 8) * dclk_max; maxdebw = min(soc_bw_params->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100); - ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels); + ipqdepth = min(ipqdepthpch, display_bw_params->displayrtids / num_channels); /* * clperchgroup = 4kpagespermempage * clperchperblock, * clperchperblock = 8 / num_channels * interleave @@ -600,7 +608,7 @@ static int tgl_get_bw_info(struct intel_display *display, int clpchgroup; int j; - clpchgroup = (sa->deburst * qi.deinterleave / num_channels) << i; + clpchgroup = (display_bw_params->deburst * qi.deinterleave / num_channels) << i; if (i < num_groups - 1) { bi_next = &display->bw.max[i + 1]; @@ -843,7 +851,7 @@ void intel_bw_init_hw(struct intel_display *display) if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx) { xe2_hpd_get_bw_info(display, dram_info, soc_bw_params); } else if (DISPLAY_VER(display) >= 14) { - tgl_get_bw_info(display, dram_info, soc_bw_params, &mtl_sa_info); + tgl_get_bw_info(display, dram_info, soc_bw_params, &xelpdp_bw_params); } else if (display->platform.dg2) { dg2_get_bw_info(display); } else if (DISPLAY_VER(display) >= 12) { @@ -854,11 +862,11 @@ void intel_bw_init_hw(struct intel_display *display) * parameters. */ if (display->platform.rocketlake) - tgl_get_bw_info(display, dram_info, soc_bw_params, &icl_sa_info); + tgl_get_bw_info(display, dram_info, soc_bw_params, &gen11_bw_params); else - tgl_get_bw_info(display, dram_info, soc_bw_params, &tgl_sa_info); + tgl_get_bw_info(display, dram_info, soc_bw_params, &gen12_bw_params); } else if (DISPLAY_VER(display) == 11) { - icl_get_bw_info(display, dram_info, soc_bw_params, &icl_sa_info); + icl_get_bw_info(display, dram_info, soc_bw_params, &gen11_bw_params); } } From 4b478c8bad54d38aecf7bc0ccfb30d4ae2cd33e3 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Mon, 18 May 2026 13:14:04 -0300 Subject: [PATCH 23/80] drm/i915/bw: Extract get_display_bw_params() Just like it is done for the platform-specific bandwidth parameters, use a separate function named get_display_bw_params() to return the display IP-specific parameters. This simplifies intel_bw_init_hw() by having just one call for each of the *_get_bw_info() functions. v2: - Prefer to call get_display_bw_params() only once in intel_bw_init_hw() instead of having multiple calls in each of the affected *_get_bw_info() functions. (Jani) v3: - Call get_display_bw_params() only after the check on HAS_DISPLAY(display). (Jani) - Return &gen11_bw_params only if display version is 11. (Matt) v4: - Like done with get_soc_bw_params(), drop drm_WARN() when no display IP is matched. Cc: Jani Nikula Reviewed-by: Matt Roper Link: https://patch.msgid.link/20260518-separate-platform-from-diplay-ip-specific-bw-params-v4-5-918528006549@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_bw.c | 39 ++++++++++++++++--------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 26b294544d10..d7b2bc80f8e3 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -482,6 +482,28 @@ static const struct intel_display_bw_params xelpdp_bw_params = { .displayrtids = 256, }; +static const struct intel_display_bw_params *get_display_bw_params(struct intel_display *display) +{ + if (DISPLAY_VER(display) >= 14) { + return &xelpdp_bw_params; + } else if (DISPLAY_VER(display) >= 12) { + /* + * RKL's SoC was based on ICL and the display, even though being + * gen12, had changes to the memory interface to match gen11's, + * consequently inheriting gen11's display-specific bandwidth + * parameters. + */ + if (display->platform.rocketlake) + return &gen11_bw_params; + else + return &gen12_bw_params; + } else if (DISPLAY_VER(display) == 11) { + return &gen11_bw_params; + } + + return NULL; +} + static int icl_get_bw_info(struct intel_display *display, const struct dram_info *dram_info, const struct intel_soc_bw_params *soc_bw_params, @@ -832,12 +854,14 @@ void intel_bw_init_hw(struct intel_display *display) { const struct dram_info *dram_info; const struct intel_soc_bw_params *soc_bw_params; + const struct intel_display_bw_params *display_bw_params; if (!HAS_DISPLAY(display)) return; dram_info = intel_dram_info(display); soc_bw_params = get_soc_bw_params(display, dram_info); + display_bw_params = get_display_bw_params(display); /* * Starting with Xe3p_LPD, the hardware tells us whether memory has ECC @@ -850,23 +874,12 @@ void intel_bw_init_hw(struct intel_display *display) if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx) { xe2_hpd_get_bw_info(display, dram_info, soc_bw_params); - } else if (DISPLAY_VER(display) >= 14) { - tgl_get_bw_info(display, dram_info, soc_bw_params, &xelpdp_bw_params); } else if (display->platform.dg2) { dg2_get_bw_info(display); } else if (DISPLAY_VER(display) >= 12) { - /* - * RKL's SoC was based on ICL and the display, even though being - * gen12, had changes to the memory interface to match gen11's, - * consequently inheriting gen11's display-specific bandwidth - * parameters. - */ - if (display->platform.rocketlake) - tgl_get_bw_info(display, dram_info, soc_bw_params, &gen11_bw_params); - else - tgl_get_bw_info(display, dram_info, soc_bw_params, &gen12_bw_params); + tgl_get_bw_info(display, dram_info, soc_bw_params, display_bw_params); } else if (DISPLAY_VER(display) == 11) { - icl_get_bw_info(display, dram_info, soc_bw_params, &gen11_bw_params); + icl_get_bw_info(display, dram_info, soc_bw_params, display_bw_params); } } From bd3d6a0b6e7859b90d9741aba08b87a49a531bd1 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Wed, 29 Apr 2026 11:26:56 -0300 Subject: [PATCH 24/80] drm/i915/dmc_wl: Remove macro HAS_DMC_WAKELOCK() The macro HAS_DMC_WAKELOCK() is currently only used inside intel_dmc_wl.c and doesn't need to be exposed to the rest of the driver. Furthermore, there is a distinction between the display IP having support for the feature and the driver actually using it, so using HAS_DMC_WAKELOCK() outside of intel_dmc_wl.c would potentially be wrong anyway. Let's drop that macro. If other part of the driver needs to check if the driver is using the DMC wakelock feature, we would need actually to expose the function __intel_dmc_wl_supported(). Since HAS_DMC_WAKELOCK() was kind of self-documenting in the sense that it tells us what display IPs have support for the feature and we are now dropping it, let's also take this opportunity to add a documentation note on the subject. Reviewed-by: Daniel Charles Link: https://patch.msgid.link/20260429-drop-has_dmc_wakelock-v1-1-62cb6fab1da0@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_display_device.h | 1 - drivers/gpu/drm/i915/display/intel_dmc_wl.c | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index 074e3ba8fb77..12e5a522a299 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -162,7 +162,6 @@ struct intel_display_platforms { #define HAS_DDI(__display) (DISPLAY_INFO(__display)->has_ddi) #define HAS_DISPLAY(__display) (DISPLAY_RUNTIME_INFO(__display)->pipe_mask != 0) #define HAS_DMC(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dmc) -#define HAS_DMC_WAKELOCK(__display) (DISPLAY_VER(__display) >= 20) #define HAS_DOUBLE_BUFFERED_M_N(__display) (IS_DISPLAY_VER((__display), 9, 14) || (__display)->platform.broadwell) #define HAS_DOUBLE_BUFFERED_LUT(__display) (DISPLAY_VER(__display) >= 30) #define HAS_DOUBLE_WIDE(__display) (DISPLAY_VER(__display) < 4) diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index 605a4a555601..b007343721e1 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -39,6 +39,13 @@ * current implementation, we only need one wakelock, so only * DMC_WAKELOCK1_CTL is used. The other definitions are here for * potential future use. + * + * This is available starting with Xe2_LPD (display version 20) as an + * experimental feature and on Xe3_LPD (display version 30) as the + * first display release with official support. That means that we + * only enable the feature by default on the latter and using it on + * the former requires explicitly using the enable_dmc_wl module + * parameter. */ /* @@ -286,7 +293,7 @@ static void intel_dmc_wl_sanitize_param(struct intel_display *display) { const char *desc; - if (!HAS_DMC_WAKELOCK(display)) { + if (DISPLAY_VER(display) < 20) { display->params.enable_dmc_wl = ENABLE_DMC_WL_DISABLED; } else if (display->params.enable_dmc_wl < 0) { if (DISPLAY_VER(display) >= 30) From f30fddb4402313aa5301a74d721638d343395269 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Sun, 17 May 2026 08:17:09 +0530 Subject: [PATCH 25/80] Revert "drm/i915/backlight: Remove try_vesa_interface" This reverts commit 40d2f5820951dee818d05c14677277048bd85f9f. Removing the try_vesa_interface gate caused a backlight regression on panels whose VBT correctly reports INTEL_BACKLIGHT_DISPLAY_DDI and whose PWM path is the actual backlight control, but whose DPCD optimistically advertises DP_EDP_BACKLIGHT_AUX_ENABLE_CAP / _BRIGHTNESS_AUX_SET_CAP. After the commit such panels silently bind to the VESA AUX backlight funcs; AUX writes complete but the panel ignores them, leaving brightness stuck (no-op backlight). Observed on at least KBL and TGL eDP setups. Signed-off-by: Suraj Kandpal Reviewed-by: Ankit Nautiyal Link: https://patch.msgid.link/20260517024709.1016121-1-suraj.kandpal@intel.com --- .../drm/i915/display/intel_dp_aux_backlight.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index a8d56ebf06a2..7a6c07f6aaeb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -691,10 +691,9 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) struct intel_dp *intel_dp = intel_attached_dp(connector); struct drm_device *dev = connector->base.dev; struct intel_panel *panel = &connector->panel; - bool try_intel_interface = false; + bool try_intel_interface = false, try_vesa_interface = false; - /* - * Check the VBT and user's module parameters to figure out which + /* Check the VBT and user's module parameters to figure out which * interfaces to probe */ switch (display->params.enable_dpcd_backlight) { @@ -703,6 +702,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) case INTEL_DP_AUX_BACKLIGHT_AUTO: switch (panel->vbt.backlight.type) { case INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE: + try_vesa_interface = true; break; case INTEL_BACKLIGHT_DISPLAY_DDI: try_intel_interface = true; @@ -715,12 +715,20 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) if (panel->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE) try_intel_interface = true; + try_vesa_interface = true; + break; + case INTEL_DP_AUX_BACKLIGHT_FORCE_VESA: + try_vesa_interface = true; break; case INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL: try_intel_interface = true; break; } + /* For eDP 1.5 and above we are supposed to use VESA interface for brightness control */ + if (intel_dp->edp_dpcd[0] >= DP_EDP_15) + try_vesa_interface = true; + /* * Since Intel has their own backlight control interface, the majority of machines out there * using DPCD backlight controls with Intel GPUs will be using this interface as opposed to @@ -733,9 +741,6 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) * panel with Intel's OUI - which is also required for us to be able to detect Intel's * backlight interface at all. This means that the only sensible way for us to detect both * interfaces is to probe for Intel's first, and VESA's second. - * - * Also there is a chance some VBTs may advertise false Intel backlight support even if the - * TCON DPCD says otherwise. This means we keep VESA interface as fallback in that case. */ if (try_intel_interface && intel_dp->edp_dpcd[0] <= DP_EDP_14b && intel_dp_aux_supports_hdr_backlight(connector)) { @@ -745,7 +750,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) return 0; } - if (intel_dp_aux_supports_vesa_backlight(connector)) { + if (try_vesa_interface && intel_dp_aux_supports_vesa_backlight(connector)) { drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Using VESA eDP backlight controls\n", connector->base.base.id, connector->base.name); panel->backlight.funcs = &intel_dp_vesa_bl_funcs; From 7b67ade89ba1730780e6d4d286a35716871954bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grzelak?= Date: Sat, 9 May 2026 18:40:40 +0200 Subject: [PATCH 26/80] drm/i915/casf: fix comment typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove superfluous whitespace character and fix the spelling. Cc: Nemesa Garg Signed-off-by: Michał Grzelak Reviewed-by: Ville Syrjälä Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260509164048.627399-2-michal.grzelak@intel.com --- drivers/gpu/drm/i915/display/intel_casf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_casf.c b/drivers/gpu/drm/i915/display/intel_casf.c index c2d2746c5f04..9a306aee2199 100644 --- a/drivers/gpu/drm/i915/display/intel_casf.c +++ b/drivers/gpu/drm/i915/display/intel_casf.c @@ -162,7 +162,7 @@ static u32 casf_coeff(const struct intel_crtc_state *crtc_state, int t) /* * 17 phase of 7 taps requires 119 coefficients in 60 dwords per set. - * To enable casf: program scaler coefficients with the coeffients + * To enable casf: program scaler coefficients with the coefficients * that are calculated and stored in pch_pfit.casf.coeff as per * SCALER_COEFFICIENT_FORMAT */ From 4d381bcd68aea5c39ef8489120ecf4377a29d79f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grzelak?= Date: Sat, 9 May 2026 18:40:41 +0200 Subject: [PATCH 27/80] drm/i915/casf: rename *_coef*() into *_coeff*() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stick to the notion of already used *_coeff*() instead of *_coef*(). Rename that way convert_sharpness_coef_binary() and intel_casf_scaler_compute_coef(). v1->v2 - rename intel_casf_scaler_compute_coef() Cc: Nemesa Garg Signed-off-by: Michał Grzelak Reviewed-by: Ville Syrjälä Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260509164048.627399-3-michal.grzelak@intel.com --- drivers/gpu/drm/i915/display/intel_casf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_casf.c b/drivers/gpu/drm/i915/display/intel_casf.c index 9a306aee2199..c4fabffa369e 100644 --- a/drivers/gpu/drm/i915/display/intel_casf.c +++ b/drivers/gpu/drm/i915/display/intel_casf.c @@ -88,7 +88,7 @@ static void intel_casf_compute_win_size(struct intel_crtc_state *crtc_state) crtc_state->pch_pfit.casf.win_size = SHARPNESS_FILTER_SIZE_7X7; } -static void intel_casf_scaler_compute_coef(struct intel_crtc_state *crtc_state); +static void intel_casf_scaler_compute_coeff(struct intel_crtc_state *crtc_state); int intel_casf_compute_config(struct intel_crtc_state *crtc_state) { @@ -118,7 +118,7 @@ int intel_casf_compute_config(struct intel_crtc_state *crtc_state) intel_casf_compute_win_size(crtc_state); - intel_casf_scaler_compute_coef(crtc_state); + intel_casf_scaler_compute_coeff(crtc_state); return 0; } @@ -196,7 +196,7 @@ static void intel_casf_write_coeff(const struct intel_crtc_state *crtc_state) } } -static void convert_sharpness_coef_binary(struct scaler_filter_coeff *coeff, +static void convert_sharpness_coeff_binary(struct scaler_filter_coeff *coeff, u16 coefficient) { if (coefficient < 25) { @@ -214,7 +214,7 @@ static void convert_sharpness_coef_binary(struct scaler_filter_coeff *coeff, } } -static void intel_casf_scaler_compute_coef(struct intel_crtc_state *crtc_state) +static void intel_casf_scaler_compute_coeff(struct intel_crtc_state *crtc_state) { const u16 *filtercoeff; u16 filter_coeff[SCALER_FILTER_NUM_TAPS]; @@ -233,7 +233,7 @@ static void intel_casf_scaler_compute_coef(struct intel_crtc_state *crtc_state) for (i = 0; i < SCALER_FILTER_NUM_TAPS; i++) { filter_coeff[i] = (*(filtercoeff + i) * 100 / sumcoeff); - convert_sharpness_coef_binary(&crtc_state->pch_pfit.casf.coeff[i], + convert_sharpness_coeff_binary(&crtc_state->pch_pfit.casf.coeff[i], filter_coeff[i]); } } From 43291a4a1d892b0034ce53d48d138e74a09edbeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grzelak?= Date: Sat, 9 May 2026 18:40:42 +0200 Subject: [PATCH 28/80] drm/i915: rename t into tap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add more description to the casf_coeff()'s argument and casf_coeff_tap()'s returned value. Do the same for glk_nearest_filter_coef(). v1->v2 - apply the rename to nearest neighbor filter (Ville) Cc: Nemesa Garg Signed-off-by: Michał Grzelak Reviewed-by: Ville Syrjälä Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260509164048.627399-4-michal.grzelak@intel.com --- drivers/gpu/drm/i915/display/intel_casf.c | 14 +++++++------- drivers/gpu/drm/i915/display/skl_scaler.c | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_casf.c b/drivers/gpu/drm/i915/display/intel_casf.c index c4fabffa369e..b9643548d182 100644 --- a/drivers/gpu/drm/i915/display/intel_casf.c +++ b/drivers/gpu/drm/i915/display/intel_casf.c @@ -148,12 +148,12 @@ static int casf_coeff_tap(int i) return i % SCALER_FILTER_NUM_TAPS; } -static u32 casf_coeff(const struct intel_crtc_state *crtc_state, int t) +static u32 casf_coeff(const struct intel_crtc_state *crtc_state, int tap) { struct scaler_filter_coeff value; u32 coeff; - value = crtc_state->pch_pfit.casf.coeff[t]; + value = crtc_state->pch_pfit.casf.coeff[tap]; value.sign = 0; coeff = value.sign << 15 | value.exp << 12 | value.mantissa << 3; @@ -183,13 +183,13 @@ static void intel_casf_write_coeff(const struct intel_crtc_state *crtc_state) for (i = 0; i < 17 * SCALER_FILTER_NUM_TAPS; i += 2) { u32 tmp; - int t; + int tap; - t = casf_coeff_tap(i); - tmp = casf_coeff(crtc_state, t); + tap = casf_coeff_tap(i); + tmp = casf_coeff(crtc_state, tap); - t = casf_coeff_tap(i + 1); - tmp |= casf_coeff(crtc_state, t) << 16; + tap = casf_coeff_tap(i + 1); + tmp |= casf_coeff(crtc_state, tap) << 16; intel_de_write_fw(display, GLK_PS_COEF_DATA_SET(crtc->pipe, id, 0), tmp); diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 308b8d363bba..eceda1a909cc 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -661,9 +661,9 @@ static int glk_coef_tap(int i) return i % 7; } -static u16 glk_nearest_filter_coef(int t) +static u16 glk_nearest_filter_coef(int tap) { - return t == 3 ? 0x0800 : 0x3000; + return tap == 3 ? 0x0800 : 0x3000; } /* @@ -715,13 +715,13 @@ static void glk_program_nearest_filter_coefs(struct intel_display *display, for (i = 0; i < 17 * 7; i += 2) { u32 tmp; - int t; + int tap; - t = glk_coef_tap(i); - tmp = glk_nearest_filter_coef(t); + tap = glk_coef_tap(i); + tmp = glk_nearest_filter_coef(tap); - t = glk_coef_tap(i + 1); - tmp |= glk_nearest_filter_coef(t) << 16; + tap = glk_coef_tap(i + 1); + tmp |= glk_nearest_filter_coef(tap) << 16; intel_de_write_dsb(display, dsb, GLK_PS_COEF_DATA_SET(pipe, id, set), tmp); From 86049a7163ed64fa16f1342bbc6b10e45971b11d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grzelak?= Date: Sat, 9 May 2026 18:40:43 +0200 Subject: [PATCH 29/80] drm/i915/casf: rename sumcoeff into sum_coeff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stick to using snake_case in intel_casf_scaler_compute_coeff() where it is possible. Cc: Nemesa Garg Signed-off-by: Michał Grzelak Reviewed-by: Ville Syrjälä Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260509164048.627399-5-michal.grzelak@intel.com --- drivers/gpu/drm/i915/display/intel_casf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_casf.c b/drivers/gpu/drm/i915/display/intel_casf.c index b9643548d182..cafd21a03632 100644 --- a/drivers/gpu/drm/i915/display/intel_casf.c +++ b/drivers/gpu/drm/i915/display/intel_casf.c @@ -218,7 +218,7 @@ static void intel_casf_scaler_compute_coeff(struct intel_crtc_state *crtc_state) { const u16 *filtercoeff; u16 filter_coeff[SCALER_FILTER_NUM_TAPS]; - u16 sumcoeff = 0; + u16 sum_coeff = 0; int i; if (crtc_state->pch_pfit.casf.win_size == 0) @@ -229,10 +229,10 @@ static void intel_casf_scaler_compute_coeff(struct intel_crtc_state *crtc_state) filtercoeff = filtercoeff_3; for (i = 0; i < SCALER_FILTER_NUM_TAPS; i++) - sumcoeff += *(filtercoeff + i); + sum_coeff += *(filtercoeff + i); for (i = 0; i < SCALER_FILTER_NUM_TAPS; i++) { - filter_coeff[i] = (*(filtercoeff + i) * 100 / sumcoeff); + filter_coeff[i] = (*(filtercoeff + i) * 100 / sum_coeff); convert_sharpness_coeff_binary(&crtc_state->pch_pfit.casf.coeff[i], filter_coeff[i]); } From 20101fc2db2b244b90bf58eb723b487325b81799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grzelak?= Date: Sat, 9 May 2026 18:40:44 +0200 Subject: [PATCH 30/80] drm/i915/scaler: s/i/scaler_id/ where appropriate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch from generic iterator naming into more specific scaler_id where it is possible. Cc: Nemesa Garg Suggested-by: Ville Syrjälä Signed-off-by: Michał Grzelak Reviewed-by: Ville Syrjälä Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260509164048.627399-6-michal.grzelak@intel.com --- drivers/gpu/drm/i915/display/skl_scaler.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index eceda1a909cc..d15e0194ca10 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -950,26 +950,26 @@ void skl_scaler_get_config(struct intel_crtc_state *crtc_state) struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state; + int scaler_id; int id = -1; - int i; /* find scaler attached to this pipe */ - for (i = 0; i < crtc->num_scalers; i++) { + for (scaler_id = 0; scaler_id < crtc->num_scalers; scaler_id++) { u32 ctl, pos, size; - ctl = intel_de_read(display, SKL_PS_CTRL(crtc->pipe, i)); + ctl = intel_de_read(display, SKL_PS_CTRL(crtc->pipe, scaler_id)); if ((ctl & (PS_SCALER_EN | PS_BINDING_MASK)) != (PS_SCALER_EN | PS_BINDING_PIPE)) continue; - id = i; + id = scaler_id; - if (scaler_has_casf(display, i)) + if (scaler_has_casf(display, scaler_id)) intel_casf_sharpness_get_config(crtc_state); crtc_state->pch_pfit.enabled = true; - pos = intel_de_read(display, SKL_PS_WIN_POS(crtc->pipe, i)); - size = intel_de_read(display, SKL_PS_WIN_SZ(crtc->pipe, i)); + pos = intel_de_read(display, SKL_PS_WIN_POS(crtc->pipe, scaler_id)); + size = intel_de_read(display, SKL_PS_WIN_SZ(crtc->pipe, scaler_id)); drm_rect_init(&crtc_state->pch_pfit.dst, REG_FIELD_GET(PS_WIN_XPOS_MASK, pos), @@ -977,7 +977,7 @@ void skl_scaler_get_config(struct intel_crtc_state *crtc_state) REG_FIELD_GET(PS_WIN_XSIZE_MASK, size), REG_FIELD_GET(PS_WIN_YSIZE_MASK, size)); - scaler_state->scalers[i].in_use = true; + scaler_state->scalers[scaler_id].in_use = true; break; } From b8ccfbc01d71eb794829ebdb7a3b1f203b7865b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grzelak?= Date: Sat, 9 May 2026 18:40:45 +0200 Subject: [PATCH 31/80] drm/i915/scaler: remove id in favor of scaler_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit id is not really used anywhere in skl_scaler_get_config(). Replace it with scaler_id. Return if no scaler was found. v1->v2 - check if any scaler was found (Ville) Cc: Nemesa Garg Suggested-by: Ville Syrjälä Signed-off-by: Michał Grzelak Reviewed-by: Ville Syrjälä Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260509164048.627399-7-michal.grzelak@intel.com --- drivers/gpu/drm/i915/display/skl_scaler.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index d15e0194ca10..6d9080ec74ce 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -951,7 +951,6 @@ void skl_scaler_get_config(struct intel_crtc_state *crtc_state) struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state; int scaler_id; - int id = -1; /* find scaler attached to this pipe */ for (scaler_id = 0; scaler_id < crtc->num_scalers; scaler_id++) { @@ -961,8 +960,6 @@ void skl_scaler_get_config(struct intel_crtc_state *crtc_state) if ((ctl & (PS_SCALER_EN | PS_BINDING_MASK)) != (PS_SCALER_EN | PS_BINDING_PIPE)) continue; - id = scaler_id; - if (scaler_has_casf(display, scaler_id)) intel_casf_sharpness_get_config(crtc_state); @@ -981,8 +978,11 @@ void skl_scaler_get_config(struct intel_crtc_state *crtc_state) break; } - scaler_state->scaler_id = id; - if (id >= 0) + if (scaler_id == crtc->num_scalers) + return; + + scaler_state->scaler_id = scaler_id; + if (scaler_id >= 0) scaler_state->scaler_users |= (1 << SKL_CRTC_INDEX); else scaler_state->scaler_users &= ~(1 << SKL_CRTC_INDEX); From fadb1ef10db1bccf3bd402734dd97e6344192c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grzelak?= Date: Sat, 9 May 2026 18:40:46 +0200 Subject: [PATCH 32/80] drm/i915/scaler: unloop scaler readout that is run once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of the loop's code is run once because of the continue statement at it's start and break statement at it's end. Kick it out of the loop. While at it, skl_scaler_get_config()'s loop is skipped when specified condition is met and broken when the condition is not met. Equivalently, invert the condition and break the loop. Changelog: v2->v3 - keep ctl inside the loop (Ville) Cc: Nemesa Garg Suggested-by: Ville Syrjälä Signed-off-by: Michał Grzelak Reviewed-by: Ville Syrjälä Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260509164048.627399-8-michal.grzelak@intel.com --- drivers/gpu/drm/i915/display/skl_scaler.c | 40 +++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 6d9080ec74ce..4e2f4c4ffc45 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -951,36 +951,36 @@ void skl_scaler_get_config(struct intel_crtc_state *crtc_state) struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state; int scaler_id; + u32 pos, size; /* find scaler attached to this pipe */ for (scaler_id = 0; scaler_id < crtc->num_scalers; scaler_id++) { - u32 ctl, pos, size; + u32 ctl; ctl = intel_de_read(display, SKL_PS_CTRL(crtc->pipe, scaler_id)); - if ((ctl & (PS_SCALER_EN | PS_BINDING_MASK)) != (PS_SCALER_EN | PS_BINDING_PIPE)) - continue; - - if (scaler_has_casf(display, scaler_id)) - intel_casf_sharpness_get_config(crtc_state); - - crtc_state->pch_pfit.enabled = true; - - pos = intel_de_read(display, SKL_PS_WIN_POS(crtc->pipe, scaler_id)); - size = intel_de_read(display, SKL_PS_WIN_SZ(crtc->pipe, scaler_id)); - - drm_rect_init(&crtc_state->pch_pfit.dst, - REG_FIELD_GET(PS_WIN_XPOS_MASK, pos), - REG_FIELD_GET(PS_WIN_YPOS_MASK, pos), - REG_FIELD_GET(PS_WIN_XSIZE_MASK, size), - REG_FIELD_GET(PS_WIN_YSIZE_MASK, size)); - - scaler_state->scalers[scaler_id].in_use = true; - break; + if ((ctl & (PS_SCALER_EN | PS_BINDING_MASK)) == (PS_SCALER_EN | PS_BINDING_PIPE)) + break; } if (scaler_id == crtc->num_scalers) return; + if (scaler_has_casf(display, scaler_id)) + intel_casf_sharpness_get_config(crtc_state); + + crtc_state->pch_pfit.enabled = true; + + pos = intel_de_read(display, SKL_PS_WIN_POS(crtc->pipe, scaler_id)); + size = intel_de_read(display, SKL_PS_WIN_SZ(crtc->pipe, scaler_id)); + + drm_rect_init(&crtc_state->pch_pfit.dst, + REG_FIELD_GET(PS_WIN_XPOS_MASK, pos), + REG_FIELD_GET(PS_WIN_YPOS_MASK, pos), + REG_FIELD_GET(PS_WIN_XSIZE_MASK, size), + REG_FIELD_GET(PS_WIN_YSIZE_MASK, size)); + + scaler_state->scalers[scaler_id].in_use = true; + scaler_state->scaler_id = scaler_id; if (scaler_id >= 0) scaler_state->scaler_users |= (1 << SKL_CRTC_INDEX); From e2255e9a5a7719a9759721387866d603640c05b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grzelak?= Date: Sat, 9 May 2026 18:40:47 +0200 Subject: [PATCH 33/80] drm/i915/scaler: abstract scaler searching loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a helper function hiding the search for scaler_id. Changelog: v2->v3 - keep ctl inside the loop (Ville) - separate impure function call from variable declaration block (Ville) Cc: Nemesa Garg Suggested-by: Ville Syrjälä Signed-off-by: Michał Grzelak Reviewed-by: Ville Syrjälä Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260509164048.627399-9-michal.grzelak@intel.com --- drivers/gpu/drm/i915/display/skl_scaler.c | 27 +++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 4e2f4c4ffc45..6acb54d5781b 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -836,6 +836,22 @@ void skl_pfit_enable(const struct intel_crtc_state *crtc_state) PS_WIN_XSIZE(width) | PS_WIN_YSIZE(height)); } +static int skl_pipe_scaler_get_hw_state(struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + + for (int scaler_id = 0; scaler_id < crtc->num_scalers; scaler_id++) { + u32 ctl; + + ctl = intel_de_read(display, SKL_PS_CTRL(crtc->pipe, scaler_id)); + if ((ctl & (PS_SCALER_EN | PS_BINDING_MASK)) == (PS_SCALER_EN | PS_BINDING_PIPE)) + return scaler_id; + } + + return -1; +} + void skl_program_plane_scaler(struct intel_dsb *dsb, struct intel_plane *plane, @@ -954,15 +970,8 @@ void skl_scaler_get_config(struct intel_crtc_state *crtc_state) u32 pos, size; /* find scaler attached to this pipe */ - for (scaler_id = 0; scaler_id < crtc->num_scalers; scaler_id++) { - u32 ctl; - - ctl = intel_de_read(display, SKL_PS_CTRL(crtc->pipe, scaler_id)); - if ((ctl & (PS_SCALER_EN | PS_BINDING_MASK)) == (PS_SCALER_EN | PS_BINDING_PIPE)) - break; - } - - if (scaler_id == crtc->num_scalers) + scaler_id = skl_pipe_scaler_get_hw_state(crtc_state); + if (scaler_id < 0) return; if (scaler_has_casf(display, scaler_id)) From c987f8c20946d41b9f191fdd2d7601e65e8cc120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grzelak?= Date: Sat, 9 May 2026 18:40:48 +0200 Subject: [PATCH 34/80] drm/i915/scaler: eliminate dead code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We short-cut skl_scaler_get_config() when skl_pipe_scaler_get_hw_state() has failed. Remove codepaths that assume scaler_id < 0. Cc: Nemesa Garg Signed-off-by: Michał Grzelak Reviewed-by: Ville Syrjälä Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260509164048.627399-10-michal.grzelak@intel.com --- drivers/gpu/drm/i915/display/skl_scaler.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 6acb54d5781b..7994b983d509 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -991,10 +991,7 @@ void skl_scaler_get_config(struct intel_crtc_state *crtc_state) scaler_state->scalers[scaler_id].in_use = true; scaler_state->scaler_id = scaler_id; - if (scaler_id >= 0) - scaler_state->scaler_users |= (1 << SKL_CRTC_INDEX); - else - scaler_state->scaler_users &= ~(1 << SKL_CRTC_INDEX); + scaler_state->scaler_users |= (1 << SKL_CRTC_INDEX); } void adl_scaler_ecc_mask(const struct intel_crtc_state *crtc_state) From f33862ec3e8849ad7c0a3dd46719083b13ade248 Mon Sep 17 00:00:00 2001 From: Pranay Samala Date: Tue, 19 May 2026 13:23:08 +0530 Subject: [PATCH 35/80] drm/i915/color: Fix HDR pre-CSC LUT programming loop The integer lut programming loop never executes completely due to incorrect condition (i++ > 130). Fix to properly program 129th+ entries for values > 1.0. Cc: #v6.19 Fixes: 82caa1c8813f ("drm/i915/color: Program Pre-CSC registers") Signed-off-by: Pranay Samala Signed-off-by: Chaitanya Kumar Borah Reviewed-by: Uma Shankar Signed-off-by: Suraj Kandpal Link: https://patch.msgid.link/20260519075308.383877-1-pranay.samala@intel.com --- drivers/gpu/drm/i915/display/intel_color.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 2d318e922671..3bfe09d81a4c 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -3976,7 +3976,7 @@ xelpd_program_plane_pre_csc_lut(struct intel_dsb *dsb, intel_de_write_dsb(display, dsb, PLANE_PRE_CSC_GAMC_DATA_ENH(pipe, plane, 0), (1 << 24)); - } while (i++ > 130); + } while (i++ < 130); } else { for (i = 0; i < lut_size; i++) { u32 v = (i * ((1 << 24) - 1)) / (lut_size - 1); From e2d57ceaa72d074273b42fbe0d03b74f87d8b583 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 5 May 2026 22:01:34 +0200 Subject: [PATCH 36/80] drm/intel/display: Add support for pipe background color (v4) Gen9 platforms allow CRTC's to be programmed with a background/canvas color below the programmable planes. Let's expose this as a property to allow userspace to program a desired value. This patch is based on earlier work by Chandra Konduru and Matt Roper. Between 2018 and now, intel/display has changed so much that another rewrite was necessary. v2: - Set initial background color (black) via proper helper function (Bob) - Fix debugfs output - General rebasing v3 (Maarten): - Rebase on top of recent changes. v4 (Maarten): - Complete rewrite based on the solution that went upstream, and on the new intel color management features. Cc: Chandra Konduru Cc: dri-devel@lists.freedesktop.org Co-developed-by: Matt Roper Signed-off-by: Maarten Lankhorst Reviewed-by: Chaitanya Kumar Borah Link: https://patch.msgid.link/20260505200133.636584-2-dev@lankhorst.se Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_color.c | 47 ++++++++++++------- drivers/gpu/drm/i915/display/intel_color.h | 3 ++ drivers/gpu/drm/i915/display/intel_crtc.c | 4 ++ drivers/gpu/drm/i915/display/intel_display.c | 5 ++ .../drm/i915/display/intel_display_debugfs.c | 6 +++ .../drm/i915/display/intel_display_types.h | 1 + .../drm/i915/display/intel_modeset_setup.c | 2 + 7 files changed, 52 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 3bfe09d81a4c..7ef870cd9a16 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -1102,19 +1102,37 @@ static void skl_get_config(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + u32 color; crtc_state->gamma_mode = hsw_read_gamma_mode(crtc); crtc_state->csc_mode = ilk_read_csc_mode(crtc); + color = intel_de_read(display, SKL_BOTTOM_COLOR(crtc->pipe)); if (DISPLAY_VER(display) < 35) { - u32 tmp = intel_de_read(display, SKL_BOTTOM_COLOR(crtc->pipe)); - - if (tmp & SKL_BOTTOM_COLOR_GAMMA_ENABLE) + if (color & SKL_BOTTOM_COLOR_GAMMA_ENABLE) crtc_state->gamma_enable = true; - if (tmp & SKL_BOTTOM_COLOR_CSC_ENABLE) + if (color & SKL_BOTTOM_COLOR_CSC_ENABLE) crtc_state->csc_enable = true; } + + crtc_state->hw.background_color = color & GENMASK(29, 0); +} + +u32 intel_color_background_color_drm_to_hw(u64 drm_background_color) +{ + return (DRM_ARGB64_GETR_BPC(drm_background_color, 10) << 20) | + (DRM_ARGB64_GETG_BPC(drm_background_color, 10) << 10) | + (DRM_ARGB64_GETB_BPC(drm_background_color, 10)); +} + +u64 intel_color_background_color_hw_to_drm(u32 hw_background_color) +{ + u16 r = (hw_background_color >> 20) & 0x3ff; + u16 g = (hw_background_color >> 10) & 0x3ff; + u16 b = hw_background_color & 0x3ff; + + return DRM_ARGB64_PREP_BPC(0x3ff, r, g, b, 10); } static void skl_color_commit_arm(struct intel_dsb *dsb, @@ -1123,16 +1141,11 @@ static void skl_color_commit_arm(struct intel_dsb *dsb, struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); enum pipe pipe = crtc->pipe; - u32 val = 0; + u32 val = crtc_state->hw.background_color; if (crtc_state->has_psr) ilk_load_csc_matrix(dsb, crtc_state); - /* - * We don't (yet) allow userspace to control the pipe background color, - * so force it to black, but apply pipe gamma and CSC appropriately - * so that its handling will match how we program our planes. - */ if (crtc_state->gamma_enable) val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE; if (crtc_state->csc_enable) @@ -1151,11 +1164,7 @@ static void icl_color_commit_arm(struct intel_dsb *dsb, struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); enum pipe pipe = crtc->pipe; - /* - * We don't (yet) allow userspace to control the pipe background color, - * so force it to black. - */ - intel_de_write_dsb(display, dsb, SKL_BOTTOM_COLOR(pipe), 0); + intel_de_write_dsb(display, dsb, SKL_BOTTOM_COLOR(pipe), crtc_state->hw.background_color); intel_de_write_dsb(display, dsb, GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode); @@ -2107,9 +2116,15 @@ int intel_color_check(struct intel_atomic_state *state, * May need to update pipe gamma enable bits * when C8 planes are getting enabled/disabled. */ - if (!old_crtc_state->c8_planes != !new_crtc_state->c8_planes) + if (!old_crtc_state->c8_planes != !new_crtc_state->c8_planes || + old_crtc_state->hw.background_color != new_crtc_state->hw.background_color) new_crtc_state->uapi.color_mgmt_changed = true; + if (DRM_ARGB64_GETA(new_crtc_state->uapi.background_color) != 0xffff) { + drm_dbg_kms(display->drm, "New background not completely opaque\n"); + return -EINVAL; + } + if (!intel_crtc_needs_color_update(new_crtc_state)) return 0; diff --git a/drivers/gpu/drm/i915/display/intel_color.h b/drivers/gpu/drm/i915/display/intel_color.h index c21b9bdf7bb8..f3963a8d1239 100644 --- a/drivers/gpu/drm/i915/display/intel_color.h +++ b/drivers/gpu/drm/i915/display/intel_color.h @@ -47,4 +47,7 @@ void intel_color_plane_program_pipeline(struct intel_dsb *dsb, void intel_color_plane_commit_arm(struct intel_dsb *dsb, const struct intel_plane_state *plane_state); bool intel_color_crtc_has_3dlut(struct intel_display *display, enum pipe pipe); +u32 intel_color_background_color_drm_to_hw(u64 drm_background_color); +u64 intel_color_background_color_hw_to_drm(u32 hw_background_color); + #endif /* __INTEL_COLOR_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 03de219f7a64..b7600cecafc8 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -405,6 +406,9 @@ static int __intel_crtc_init(struct intel_display *display, enum pipe pipe) BIT(DRM_SCALING_FILTER_DEFAULT) | BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR)); + if (DISPLAY_VER(display) >= 9) + drm_crtc_attach_background_color_property(&crtc->base); + intel_color_crtc_init(crtc); intel_drrs_crtc_init(crtc); intel_crtc_crc_init(crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 757a78c75bbf..6c8935f69db1 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4505,6 +4505,8 @@ intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state, crtc_state->uapi.gamma_lut); drm_property_replace_blob(&crtc_state->hw.ctm, crtc_state->uapi.ctm); + crtc_state->hw.background_color = + intel_color_background_color_drm_to_hw(crtc_state->uapi.background_color); } static void @@ -4544,6 +4546,7 @@ copy_joiner_crtc_state_nomodeset(struct intel_atomic_state *state, primary_crtc_state->hw.gamma_lut); drm_property_replace_blob(&secondary_crtc_state->hw.ctm, primary_crtc_state->hw.ctm); + secondary_crtc_state->hw.background_color = primary_crtc_state->hw.background_color; secondary_crtc_state->uapi.color_mgmt_changed = primary_crtc_state->uapi.color_mgmt_changed; } @@ -5360,6 +5363,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, else PIPE_CONF_CHECK_X(csc_mode); PIPE_CONF_CHECK_BOOL(gamma_enable); + + PIPE_CONF_CHECK_X(hw.background_color); PIPE_CONF_CHECK_BOOL(csc_enable); PIPE_CONF_CHECK_BOOL(wgc_enable); diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 81bef000a4e3..3d6f36773ad8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -572,6 +572,12 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc) intel_scaler_info(m, crtc); + if (DISPLAY_VER(display) >= 9) { + u32 background = crtc_state->hw.background_color; + + seq_printf(m, "\tbackground color (10bpc XRGB2101010): %08x\n", background); + } + if (crtc_state->joiner_pipes) seq_printf(m, "\tLinked to 0x%x pipes as a %s\n", crtc_state->joiner_pipes, diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index f44be5c689ae..1c0c32c4e43a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1035,6 +1035,7 @@ struct intel_crtc_state { /* logical state of LUTs */ struct drm_property_blob *degamma_lut, *gamma_lut, *ctm; struct drm_display_mode mode, pipe_mode, adjusted_mode; + u32 background_color; enum drm_scaling_filter scaling_filter; u8 sharpness_strength; } hw; diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index e88082c8caac..0c9775eabdf0 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -334,6 +334,8 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode; crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter; crtc_state->uapi.sharpness_strength = crtc_state->hw.sharpness_strength; + crtc_state->uapi.background_color = + intel_color_background_color_hw_to_drm(crtc_state->hw.background_color); if (DISPLAY_INFO(display)->color.degamma_lut_size) { /* assume 1:1 mapping */ From eb88560c9e955bf3d87900f35e1e37a0bdec7622 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Fri, 22 May 2026 12:45:48 +0200 Subject: [PATCH 37/80] drm/i915: Remove useless comment about MTRR. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 792d2b9a1259 ("drm: drop mtrr from i915"), added this comment, drop it since it since MTRR no longer exists since 2013 and is removed by commit 281856477cda ("drm: rip out drm_core_has_MTRR checks"). Cc: Ville Syrjälä Acked-by: Jani Nikula Link: https://patch.msgid.link/20260522104548.980226-1-dev@lankhorst.se Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/i915_driver.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index f06b2e8cf7d4..0363dbd231b7 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1869,9 +1869,6 @@ static const struct drm_ioctl_desc i915_ioctls[] = { #define DRIVER_PATCHLEVEL 0 static const struct drm_driver i915_drm_driver = { - /* Don't use MTRRs here; the Xserver or userspace app should - * deal with them for Intel hardware. - */ .driver_features = DRIVER_GEM | DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_SYNCOBJ | From eb5911f990554f7ce947dd53df00c114362e4465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Wed, 20 May 2026 13:49:43 +0300 Subject: [PATCH 38/80] drm/i915/psr: Block DC states on vblank enable when Panel Replay supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we are blocking DC states only when Panel Replay is enabled on vblank enable. It may happen that Panel Replay is getting enabled when vblank is already enabled. Fix this by blocking DC states always if Panel Replay is supported. While at it take care of possible dual eDP case by looping all encoders supporting PSR. Fixes: 0c427ac78a1d ("drm/i915/psr: Add interface to notify PSR of vblank enable/disable") Cc: # v6.16+ Signed-off-by: Jouni Högander Reviewed-by: Michał Grzelak Link: https://patch.msgid.link/20260520104944.239797-1-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index b0414bd1dc6b..70108e0a4c0c 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -4180,32 +4180,33 @@ void intel_psr_notify_vblank_enable_disable(struct intel_display *display, bool enable) { struct intel_encoder *encoder; + bool block_dc_states = false; for_each_intel_encoder_with_psr(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); mutex_lock(&intel_dp->psr.lock); - if (intel_dp->psr.panel_replay_enabled) { - mutex_unlock(&intel_dp->psr.lock); - break; - } + if (CAN_PANEL_REPLAY(intel_dp)) + block_dc_states = true; - if (intel_dp->psr.enabled && intel_dp->psr.pkg_c_latency_used) + if (intel_dp->psr.enabled && !intel_dp->psr.panel_replay_enabled && + intel_dp->psr.pkg_c_latency_used) intel_psr_apply_underrun_on_idle_wa_locked(intel_dp); mutex_unlock(&intel_dp->psr.lock); - return; } /* * NOTE: intel_display_power_set_target_dc_state is used - * only by PSR * code for DC3CO handling. DC3CO target + * only by PSR code for DC3CO handling. DC3CO target * state is currently disabled in * PSR code. If DC3CO * is taken into use we need take that into account here * as well. */ - intel_display_power_set_target_dc_state(display, enable ? DC_STATE_DISABLE : - DC_STATE_EN_UPTO_DC6); + if (block_dc_states) + intel_display_power_set_target_dc_state(display, enable ? + DC_STATE_DISABLE : + DC_STATE_EN_UPTO_DC6); } static void From 35485ac56d878192a3829a58cb26503125ec7104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Wed, 20 May 2026 13:49:44 +0300 Subject: [PATCH 39/80] drm/i915/psr: Use DC_OFF wake reference to block DC6 on vblank enable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are observing following warnings: *ERROR* power well DC_off state mismatch (refcount 0/enabled 1) gen9_dc_off_power_well_enabled is considering target state DC_STATE_DISABLE as DC_OFF power well being enabled. Fix this by using wakeref for the purpose. To achieve this we need to modify notification code as well. Currently it is possible that PSR gets notified vblank enable/disable twice on same status. This is currently not a problem as it is just triggering call to intel_display_power_set_target_dc_state with same target state as a parameter. When using wakeref this becomes a problem due to reference counting. Fix this storing vbank status on last notification and use that to ensure there are no more than one notification with same vblank status. v2: ensure there is no subsequent notifications with same status Fixes: aa451abcffb5 ("drm/i915/display: Prevent DC6 while vblank is enabled for Panel Replay") Cc: # v6.13+ Signed-off-by: Jouni Högander Reviewed-by: Michał Grzelak Link: https://patch.msgid.link/20260520104944.239797-2-jouni.hogander@intel.com --- .../gpu/drm/i915/display/intel_display_core.h | 1 + .../gpu/drm/i915/display/intel_display_irq.c | 8 +++++-- .../drm/i915/display/intel_display_types.h | 2 ++ drivers/gpu/drm/i915/display/intel_psr.c | 24 +++++++------------ 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 3dc5ac75a98b..09ce25a6d4b1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -494,6 +494,7 @@ struct intel_display { u8 vblank_enabled; int vblank_enable_count; + bool vblank_status_last_notified; struct work_struct vblank_notify_work; diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 899a38c0a7b7..4a821b0674fd 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1786,8 +1786,12 @@ static void intel_display_vblank_notify_work(struct work_struct *work) struct intel_display *display = container_of(work, typeof(*display), irq.vblank_notify_work); int vblank_enable_count = READ_ONCE(display->irq.vblank_enable_count); + bool vblank_status = !!vblank_enable_count; - intel_psr_notify_vblank_enable_disable(display, vblank_enable_count); + if (display->irq.vblank_status_last_notified != vblank_status) { + intel_psr_notify_vblank_enable_disable(display, vblank_status); + display->irq.vblank_status_last_notified = vblank_status; + } } int bdw_enable_vblank(struct drm_crtc *_crtc) @@ -1800,10 +1804,10 @@ int bdw_enable_vblank(struct drm_crtc *_crtc) if (gen11_dsi_configure_te(crtc, true)) return 0; + spin_lock_irqsave(&display->irq.lock, irqflags); if (crtc->vblank_psr_notify && display->irq.vblank_enable_count++ == 0) schedule_work(&display->irq.vblank_notify_work); - spin_lock_irqsave(&display->irq.lock, irqflags); bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_VBLANK); spin_unlock_irqrestore(&display->irq.lock, irqflags); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 1c0c32c4e43a..ac865b6557b6 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1791,6 +1791,8 @@ struct intel_psr { u8 active_non_psr_pipes; const char *no_psr_reason; + + struct ref_tracker *vblank_wakeref; }; struct intel_dp { diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 70108e0a4c0c..19cfb23fe9f8 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -4180,14 +4180,20 @@ void intel_psr_notify_vblank_enable_disable(struct intel_display *display, bool enable) { struct intel_encoder *encoder; - bool block_dc_states = false; for_each_intel_encoder_with_psr(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); mutex_lock(&intel_dp->psr.lock); - if (CAN_PANEL_REPLAY(intel_dp)) - block_dc_states = true; + if (CAN_PANEL_REPLAY(intel_dp)) { + if (enable) + intel_dp->psr.vblank_wakeref = + intel_display_power_get(display, + POWER_DOMAIN_DC_OFF); + else + intel_display_power_put(display, POWER_DOMAIN_DC_OFF, + intel_dp->psr.vblank_wakeref); + } if (intel_dp->psr.enabled && !intel_dp->psr.panel_replay_enabled && intel_dp->psr.pkg_c_latency_used) @@ -4195,18 +4201,6 @@ void intel_psr_notify_vblank_enable_disable(struct intel_display *display, mutex_unlock(&intel_dp->psr.lock); } - - /* - * NOTE: intel_display_power_set_target_dc_state is used - * only by PSR code for DC3CO handling. DC3CO target - * state is currently disabled in * PSR code. If DC3CO - * is taken into use we need take that into account here - * as well. - */ - if (block_dc_states) - intel_display_power_set_target_dc_state(display, enable ? - DC_STATE_DISABLE : - DC_STATE_EN_UPTO_DC6); } static void From 3638d90b23798290ae9a34af1481fdcf617238b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Tue, 12 May 2026 11:00:22 +0300 Subject: [PATCH 40/80] drm/i915/display: Handle odd position for planar formats in selective fetch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since Lunarlake there is no restriction planar planes has to be even positions. Due to this we may end up having odd offset for UV-plane in selective fetch configuration. Add handling for this case into selective fetch configuration. Bspec: 68927 Suggested-by: Vidya Srinivas Signed-off-by: Jouni Högander Reviewed-by: Vidya Srinivas Link: https://patch.msgid.link/20260512080022.2527094-1-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/skl_universal_plane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index ef431dd32e74..ad4bfff6903d 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1532,7 +1532,7 @@ static void icl_plane_update_sel_fetch_noarm(struct intel_dsb *dsb, if (!color_plane) y = plane_state->view.color_plane[color_plane].y + clip->y1; else - y = plane_state->view.color_plane[color_plane].y + clip->y1 / 2; + y = plane_state->view.color_plane[color_plane].y + DIV_ROUND_UP(clip->y1, 2); val = y << 16 | x; From d69da4f92d27c8ee178fc73dc5b035ad6d3201ae Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Sun, 17 May 2026 19:57:52 +0530 Subject: [PATCH 41/80] drm/i915/psr: Simplify the conditions for SCL computation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'needs_sel_update' is common for both display version branches, so check it once and keep the version specific checks as separate early returns. v2: Split into separate early returns. (Jani) Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Reviewed-by: Jouni Högander Link: https://patch.msgid.link/20260517142753.2813959-2-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 19cfb23fe9f8..6d3801cb0612 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1508,15 +1508,18 @@ int _intel_psr_min_set_context_latency(const struct intel_crtc_state *crtc_state * SRD_STATUS is used by PSR1 and Panel Replay DP on LunarLake. */ - if (DISPLAY_VER(display) >= 30 && (needs_panel_replay || - needs_sel_update)) + if (needs_sel_update) return 0; - else if (DISPLAY_VER(display) < 30 && (needs_sel_update || - intel_crtc_has_type(crtc_state, - INTEL_OUTPUT_EDP))) + + if (DISPLAY_VER(display) < 30 && + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) return 0; - else - return 1; + + if (DISPLAY_VER(display) >= 30 && + needs_panel_replay) + return 0; + + return 1; } static bool _wake_lines_fit_into_vblank(const struct intel_crtc_state *crtc_state, From 4f1cab2e4863d96ce13b8d94151f4848e38c3d5b Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Sun, 17 May 2026 19:57:53 +0530 Subject: [PATCH 42/80] drm/i915/psr: Allow SCL=0 on platforms with always-on VRR TG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For Legacy timing generator, if there are no panel replay/sel_update or other SRD constraints, the Set context latency (SCL) window should be at least 1. However, for VRR timing generator the SCL window can be 0. It has other guardband constraints, but that are checked during guardband computation. Allow SCL to be 0 for platforms that have VRR TG always on. Signed-off-by: Ankit Nautiyal Reviewed-by: Suraj Kandpal Reviewed-by: Jouni Högander Link: https://patch.msgid.link/20260517142753.2813959-3-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 6d3801cb0612..9382ad1e01d8 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1519,6 +1519,9 @@ int _intel_psr_min_set_context_latency(const struct intel_crtc_state *crtc_state needs_panel_replay) return 0; + if (intel_vrr_always_use_vrr_tg(display)) + return 0; + return 1; } From 47f6d0e09064c765326a4d96f30292bc2c2ee405 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 22 May 2026 19:05:11 +0300 Subject: [PATCH 43/80] drm/i915/dp: Reset link params after a DPRX capability change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no reason to distinguish between DPRX capability changes signaled via a long HPD and via an RX_CAP_CHANGED HPD IRQ. Both cases result in reading out the DPRX capabilities and updating the corresponding sink and common capabilities cached in intel_dp, however only the long HPD resets the link training/recovery state and MST link probe parameters correspondingly. The link training/recovery state may contain reduced maximum link rate/lane count values left over from a previous link training failure. Based on the above after an RX_CAP_CHANGED increased the link rate, lane count parameters the maximum link rate/lane count in the link training/recovery state may remain below these, leaving the newly added valid configurations unavailable for subsequent modesets in an inconsistent way. Handle RX_CAP_CHANGED IRQs the same way as long HPDs and reset the link recovery state and MST link probe parameters in that case as well. v2: Set intel_dp::reset_link_params instead of using a helper for this. (Ville). Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Imre Deak Link: https://patch.msgid.link/20260522160514.2628249-2-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 1920d2f02666..940e73ad451d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -6000,8 +6000,10 @@ static bool intel_dp_handle_link_service_irq(struct intel_dp *intel_dp, u8 irq_m drm_WARN_ON(display->drm, irq_mask & ~(INTEL_DP_LINK_SERVICE_IRQ_MASK_SST | INTEL_DP_LINK_SERVICE_IRQ_MASK_MST)); - if (irq_mask & RX_CAP_CHANGED) + if (irq_mask & RX_CAP_CHANGED) { + intel_dp->reset_link_params = true; reprobe_needed = true; + } if (irq_mask & LINK_STATUS_CHANGED) intel_dp_check_link_state(intel_dp); From 0759e16078f01a2420db3bcba8c9c8911a7dd885 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 22 May 2026 19:05:12 +0300 Subject: [PATCH 44/80] drm/i915/dp: Add helper to set common link params MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add intel_dp_set_common_link_params() to prepare for updating the maximum common lane count together with the common rates. Reviewed-by: Jouni Högander Reviewed-by: Ville Syrjälä Signed-off-by: Imre Deak Link: https://patch.msgid.link/20260522160514.2628249-3-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 940e73ad451d..e9eee452dc36 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -805,7 +805,11 @@ static void intel_dp_set_common_rates(struct intel_dp *intel_dp) intel_dp->common_rates[0] = 162000; intel_dp->num_common_rates = 1; } +} +static void intel_dp_set_common_link_params(struct intel_dp *intel_dp) +{ + intel_dp_set_common_rates(intel_dp); intel_dp_link_config_init(intel_dp); } @@ -4877,7 +4881,7 @@ void intel_dp_update_sink_caps(struct intel_dp *intel_dp) { intel_dp_set_sink_rates(intel_dp); intel_dp_set_max_sink_lane_count(intel_dp); - intel_dp_set_common_rates(intel_dp); + intel_dp_set_common_link_params(intel_dp); } static bool @@ -7318,7 +7322,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, } intel_dp_set_source_rates(intel_dp); - intel_dp_set_common_rates(intel_dp); + intel_dp_set_common_link_params(intel_dp); intel_dp_reset_link_params(intel_dp); /* init MST on ports that can support it */ From cc18eac531a656f9104f78a0d9358bb099080831 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 22 May 2026 19:05:13 +0300 Subject: [PATCH 45/80] drm/i915/dp: Cache max common lane count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cache the maximum common lane count together with the common link rates. This is safe because the cached value is updated: - during driver probe, before the connector is registered and can be used for mode validation or modesetting - during resume, before output HW state readout can query it - during connector detection, right after updating the sink/link capabilities Caching the value allows detecting max common lane count changes in a follow-up change and keeps the tracking of max common lane count aligned with that of common rates. Reviewed-by: Jouni Högander Reviewed-by: Ville Syrjälä Signed-off-by: Imre Deak Link: https://patch.msgid.link/20260522160514.2628249-4-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index ac865b6557b6..13ce37a71b68 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1823,6 +1823,7 @@ struct intel_dp { /* intersection of source and sink rates */ int num_common_rates; int common_rates[DP_MAX_SUPPORTED_RATES]; + int max_common_lane_count; struct { /* TODO: move the rest of link specific fields to here */ bool active; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index e9eee452dc36..1a6d00852eb1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -363,7 +363,7 @@ int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port) } /* Theoretical max between source and sink */ -int intel_dp_max_common_lane_count(struct intel_dp *intel_dp) +static void intel_dp_set_max_common_lane_count(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); int source_max = intel_dp_max_source_lane_count(dig_port); @@ -374,7 +374,12 @@ int intel_dp_max_common_lane_count(struct intel_dp *intel_dp) if (lttpr_max) sink_max = min(sink_max, lttpr_max); - return min3(source_max, sink_max, lane_max); + intel_dp->max_common_lane_count = min3(source_max, sink_max, lane_max); +} + +int intel_dp_max_common_lane_count(struct intel_dp *intel_dp) +{ + return intel_dp->max_common_lane_count; } static int forced_lane_count(struct intel_dp *intel_dp) @@ -810,6 +815,7 @@ static void intel_dp_set_common_rates(struct intel_dp *intel_dp) static void intel_dp_set_common_link_params(struct intel_dp *intel_dp) { intel_dp_set_common_rates(intel_dp); + intel_dp_set_max_common_lane_count(intel_dp); intel_dp_link_config_init(intel_dp); } From c0c49dead61f03b04563fe0fad916ce4bf4bb933 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 22 May 2026 19:05:14 +0300 Subject: [PATCH 46/80] drm/i915/dp: Detect changes in common link parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Detect DPRX capability changes without a long HPD or RX_CAP_CHANGED signal and queue a corresponding link params reset. Besides detecting the above unexpected capability changes, this also avoids races between queuing and handling a deferred link params reset. v2: (Ville) - Query/set intel_dp::reset_link_params instead of using helpers for these. - Assert matching types for old/new common rate elements as well. - Add TODO: for adding a struct tracking both rates and number of rates. Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Imre Deak Link: https://patch.msgid.link/20260522160514.2628249-5-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 54 +++++++++++++++++++++---- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 1a6d00852eb1..3f9123a53244 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -362,19 +362,25 @@ int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port) return max_lanes; } -/* Theoretical max between source and sink */ -static void intel_dp_set_max_common_lane_count(struct intel_dp *intel_dp) +/* + * Theoretical max between source and sink. + * Return %true if the max common lane count changed. + */ +static bool intel_dp_set_max_common_lane_count(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); int source_max = intel_dp_max_source_lane_count(dig_port); int sink_max = intel_dp->max_sink_lane_count; int lane_max = intel_tc_port_max_lane_count(dig_port); int lttpr_max = drm_dp_lttpr_max_lane_count(intel_dp->lttpr_common_caps); + int old_max_common_lane_count = intel_dp->max_common_lane_count; if (lttpr_max) sink_max = min(sink_max, lttpr_max); intel_dp->max_common_lane_count = min3(source_max, sink_max, lane_max); + + return intel_dp->max_common_lane_count != old_max_common_lane_count; } int intel_dp_max_common_lane_count(struct intel_dp *intel_dp) @@ -792,13 +798,22 @@ int intel_dp_link_config_index(struct intel_dp *intel_dp, int link_rate, int lan return -1; } -static void intel_dp_set_common_rates(struct intel_dp *intel_dp) +/* Return %true if the common rates changed. */ +static bool intel_dp_set_common_rates(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); + int num_old_common_rates = intel_dp->num_common_rates; + int old_common_rates[DP_MAX_SUPPORTED_RATES]; drm_WARN_ON(display->drm, !intel_dp->num_source_rates || !intel_dp->num_sink_rates); + /* TODO: Add a struct containing both rates and number of rates. */ + static_assert(__same_type(old_common_rates[0], intel_dp->common_rates[0]) && + sizeof(old_common_rates) == sizeof(intel_dp->common_rates)); + memcpy(old_common_rates, intel_dp->common_rates, + num_old_common_rates * sizeof(old_common_rates[0])); + intel_dp->num_common_rates = intersect_rates(intel_dp->source_rates, intel_dp->num_source_rates, intel_dp->sink_rates, @@ -810,13 +825,26 @@ static void intel_dp_set_common_rates(struct intel_dp *intel_dp) intel_dp->common_rates[0] = 162000; intel_dp->num_common_rates = 1; } + + return num_old_common_rates != intel_dp->num_common_rates || + memcmp(old_common_rates, intel_dp->common_rates, + num_old_common_rates * sizeof(old_common_rates[0])); } -static void intel_dp_set_common_link_params(struct intel_dp *intel_dp) +/* Return %true if any common link param changed. */ +static bool intel_dp_set_common_link_params(struct intel_dp *intel_dp) { - intel_dp_set_common_rates(intel_dp); - intel_dp_set_max_common_lane_count(intel_dp); + bool params_changed = false; + + if (intel_dp_set_common_rates(intel_dp)) + params_changed = true; + + if (intel_dp_set_max_common_lane_count(intel_dp)) + params_changed = true; + intel_dp_link_config_init(intel_dp); + + return params_changed; } bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate, @@ -4885,9 +4913,21 @@ intel_dp_has_sink_count(struct intel_dp *intel_dp) void intel_dp_update_sink_caps(struct intel_dp *intel_dp) { + struct intel_display *display = to_intel_display(intel_dp); + intel_dp_set_sink_rates(intel_dp); intel_dp_set_max_sink_lane_count(intel_dp); - intel_dp_set_common_link_params(intel_dp); + /* + * Handle unexpected sink cap changes, or a race between setting + * the deferred link params flag in the HPD IRQ handler and + * clearing the flag during connector detect. + */ + if (intel_dp_set_common_link_params(intel_dp) && + !intel_dp->reset_link_params) { + drm_dbg_kms(display->drm, + "DPRX capabilities changed before long HPD or RX_CAP_CHANGED signal\n"); + intel_dp->reset_link_params = true; + } } static bool From 344bafe9e0d3258a20f5a9353024c78bd5f69dc5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sat, 16 May 2026 13:18:52 +0300 Subject: [PATCH 47/80] drm/i915: relocate intel_hpd_cancel_work() call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The i915 and xe calls to display, in particular for probe/cleanup/suspend/resume, need to be unified. It does not help to have the related calls scattered around. As a small step forward, relocate the intel_hpd_cancel_work() call from intel_irq_uninstall() to i915_driver_remove(). Note that the other intel_irq_uninstall() call sites don't need the call, as they're on error paths where hotplug hasn't been enabled yet. Reviewed-by: Michał Grzelak Link: https://patch.msgid.link/20260516101852.1373108-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_driver.c | 1 + drivers/gpu/drm/i915/i915_irq.c | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 0363dbd231b7..7f792b537f4f 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -971,6 +971,7 @@ void i915_driver_remove(struct drm_i915_private *i915) intel_display_driver_remove(display); intel_irq_uninstall(i915); + intel_hpd_cancel_work(display); intel_display_driver_remove_noirq(display); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 30ce462e92ab..932409b943ad 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -37,7 +37,6 @@ #include #include "display/intel_display_irq.h" -#include "display/intel_hotplug.h" #include "gt/intel_breadcrumbs.h" #include "gt/intel_gt.h" @@ -1140,7 +1139,6 @@ int intel_irq_install(struct drm_i915_private *dev_priv) */ void intel_irq_uninstall(struct drm_i915_private *dev_priv) { - struct intel_display *display = dev_priv->display; int irq = to_pci_dev(dev_priv->drm.dev)->irq; if (drm_WARN_ON(&dev_priv->drm, !dev_priv->irqs_enabled)) @@ -1150,7 +1148,6 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) free_irq(irq, dev_priv); - intel_hpd_cancel_work(display); dev_priv->irqs_enabled = false; } From 6df932f162d74599b33705a77908674ea4c447ec Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 25 May 2026 14:05:53 +0300 Subject: [PATCH 48/80] drm/{i915, xe}: move xe_display_flush_cleanup_work() to i915 display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xe_display_flush_cleanup_work() is a bit of an oddball function in xe display code. There shouldn't be anything this specific or xe specific. While I'm not sure what the correct refactor for the function should be, move it to shared display code for starters, next to the eerily similar but slightly different intel_has_pending_fb_unpin() that is only called from i915 core. The main goal here is to unblock some refactors on for_each_intel_crtc(). v2: Add FIXME comment (Ville) Acked-by: Ville Syrjälä Link: https://patch.msgid.link/20260525110553.651208-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 22 ++++++++++++++++ drivers/gpu/drm/i915/display/intel_display.h | 1 + drivers/gpu/drm/xe/display/xe_display.c | 27 +++----------------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 6c8935f69db1..648155296fd2 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -737,6 +737,28 @@ bool intel_has_pending_fb_unpin(struct intel_display *display) return false; } +/* FIXME: remove this and just flush the cleanup wq where appropriate */ +void intel_display_flush_cleanup_work(struct intel_display *display) +{ + struct intel_crtc *crtc; + + for_each_intel_crtc(display->drm, crtc) { + struct drm_crtc_commit *commit; + + spin_lock(&crtc->base.commit_lock); + commit = list_first_entry_or_null(&crtc->base.commit_list, + struct drm_crtc_commit, commit_entry); + if (commit) + drm_crtc_commit_get(commit); + spin_unlock(&crtc->base.commit_lock); + + if (commit) { + wait_for_completion(&commit->cleanup_done); + drm_crtc_commit_put(commit); + } + } +} + /* * Finds the encoder associated with the given CRTC. This can only be * used when we know that the CRTC isn't feeding multiple encoders! diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 45a90d2fe6ec..72f33113a5a3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -402,6 +402,7 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state); void i830_enable_pipe(struct intel_display *display, enum pipe pipe); void i830_disable_pipe(struct intel_display *display, enum pipe pipe); bool intel_has_pending_fb_unpin(struct intel_display *display); +void intel_display_flush_cleanup_work(struct intel_display *display); void intel_encoder_destroy(struct drm_encoder *encoder); struct drm_display_mode * intel_encoder_current_mode(struct intel_encoder *encoder); diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 75324aa82631..766811cea07d 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -265,27 +265,6 @@ static bool suspend_to_idle(void) return false; } -static void xe_display_flush_cleanup_work(struct xe_device *xe) -{ - struct intel_crtc *crtc; - - for_each_intel_crtc(&xe->drm, crtc) { - struct drm_crtc_commit *commit; - - spin_lock(&crtc->base.commit_lock); - commit = list_first_entry_or_null(&crtc->base.commit_list, - struct drm_crtc_commit, commit_entry); - if (commit) - drm_crtc_commit_get(commit); - spin_unlock(&crtc->base.commit_lock); - - if (commit) { - wait_for_completion(&commit->cleanup_done); - drm_crtc_commit_put(commit); - } - } -} - static void xe_display_enable_d3cold(struct xe_device *xe) { struct intel_display *display = xe->display; @@ -299,7 +278,7 @@ static void xe_display_enable_d3cold(struct xe_device *xe) */ intel_power_domains_disable(display); - xe_display_flush_cleanup_work(xe); + intel_display_flush_cleanup_work(display); intel_opregion_suspend(display, PCI_D3cold); @@ -354,7 +333,7 @@ void xe_display_pm_suspend(struct xe_device *xe) intel_display_driver_suspend(display); } - xe_display_flush_cleanup_work(xe); + intel_display_flush_cleanup_work(display); intel_encoder_block_all_hpds(display); @@ -386,7 +365,7 @@ void xe_display_pm_shutdown(struct xe_device *xe) intel_display_driver_suspend(display); } - xe_display_flush_cleanup_work(xe); + intel_display_flush_cleanup_work(display); intel_dp_mst_suspend(display); intel_encoder_block_all_hpds(display); intel_hpd_cancel_work(display); From c2b0fdb1b9e8c46357421f060b5b59cc998888d7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 10:58:36 +0300 Subject: [PATCH 49/80] drm/i915/display: switch from drm_for_each_crtc() to for_each_intel_crtc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_has_pending_fb_unpin() has the last direct user of drm_for_each_crtc() in i915. Switch to for_each_intel_crtc() to ensure pipe order iteration in all cases. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/8ee4320cd15bc35a8b40676faae6db4b33eb50eb.1778659089.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 648155296fd2..fa05be282cbf 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -714,22 +714,22 @@ static void icl_set_pipe_chicken(const struct intel_crtc_state *crtc_state) bool intel_has_pending_fb_unpin(struct intel_display *display) { - struct drm_crtc *crtc; + struct intel_crtc *crtc; bool cleanup_done; - drm_for_each_crtc(crtc, display->drm) { + for_each_intel_crtc(display->drm, crtc) { struct drm_crtc_commit *commit; - spin_lock(&crtc->commit_lock); - commit = list_first_entry_or_null(&crtc->commit_list, + spin_lock(&crtc->base.commit_lock); + commit = list_first_entry_or_null(&crtc->base.commit_list, struct drm_crtc_commit, commit_entry); cleanup_done = commit ? try_wait_for_completion(&commit->cleanup_done) : true; - spin_unlock(&crtc->commit_lock); + spin_unlock(&crtc->base.commit_lock); if (cleanup_done) continue; - intel_crtc_wait_for_next_vblank(to_intel_crtc(crtc)); + intel_crtc_wait_for_next_vblank(crtc); return true; } From e007e1de1ebf282f89a5fc7cdba3b7264c4be1bc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 10:58:37 +0300 Subject: [PATCH 50/80] drm/i915/display: always pass display->drm to for_each_intel_crtc*() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for always passing struct intel_display to for_each_intel_crtc*() family of iterators, start off by unifying their usage to always having struct intel_display *display around, and passing display->drm to them. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/447a5b2309e213abb849601727d45b406d440c88.1778659089.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/i9xx_wm.c | 3 ++- drivers/gpu/drm/i915/display/intel_display.c | 3 ++- drivers/gpu/drm/i915/display/intel_plane.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 33d8f6b6afea..4cd07410ad72 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -3533,10 +3533,11 @@ static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc) static int ilk_sanitize_watermarks_add_affected(struct drm_atomic_commit *state) { + struct intel_display *display = to_intel_display(state->dev); struct drm_plane *plane; struct intel_crtc *crtc; - for_each_intel_crtc(state->dev, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state; crtc_state = intel_atomic_get_crtc_state(state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index fa05be282cbf..d741e2f7105f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5702,6 +5702,7 @@ int intel_modeset_commit_pipes(struct intel_display *display, */ static int hsw_mode_set_planes_workaround(struct intel_atomic_state *state) { + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state; struct intel_crtc *crtc; struct intel_crtc_state *first_crtc_state = NULL; @@ -5729,7 +5730,7 @@ static int hsw_mode_set_planes_workaround(struct intel_atomic_state *state) return 0; /* w/a possibly needed, check how many crtc's are already enabled. */ - for_each_intel_crtc(state->base.dev, crtc) { + for_each_intel_crtc(display->drm, crtc) { crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); if (IS_ERR(crtc_state)) return PTR_ERR(crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c index a1f9558d53af..911ae261d1b5 100644 --- a/drivers/gpu/drm/i915/display/intel_plane.c +++ b/drivers/gpu/drm/i915/display/intel_plane.c @@ -1794,6 +1794,7 @@ static u8 intel_joiner_affected_planes(struct intel_atomic_state *state, static int intel_joiner_add_affected_planes(struct intel_atomic_state *state, u8 joined_pipes) { + struct intel_display *display = to_intel_display(state); u8 prev_affected_planes, affected_planes = 0; /* @@ -1811,7 +1812,7 @@ static int intel_joiner_add_affected_planes(struct intel_atomic_state *state, do { struct intel_crtc *crtc; - for_each_intel_crtc_in_pipe_mask(state->base.dev, crtc, joined_pipes) { + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, joined_pipes) { int ret; ret = intel_crtc_add_planes_to_state(state, crtc, affected_planes); From 10629a422b598eaeb3fedf37fcb03615d89e869b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 10:58:38 +0300 Subject: [PATCH 51/80] drm/i915/display: pass struct intel_display to all for_each_intel_crtc*() macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the for_each_intel_crtc*() iterator macros primarily use display->pipe_list for iteration, it's more convenient to pass struct intel_display to them directly instead of struct drm_device. Make it so. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/90ec6b84d772a4842d4816efc10042ec4403e996.1778659089.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/i9xx_wm.c | 28 +++++++-------- drivers/gpu/drm/i915/display/intel_bw.c | 2 +- drivers/gpu/drm/i915/display/intel_cdclk.c | 2 +- drivers/gpu/drm/i915/display/intel_crtc.c | 2 +- drivers/gpu/drm/i915/display/intel_dbuf_bw.c | 2 +- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- drivers/gpu/drm/i915/display/intel_display.c | 36 +++++++++---------- drivers/gpu/drm/i915/display/intel_display.h | 26 +++++++------- .../drm/i915/display/intel_display_debugfs.c | 6 ++-- .../drm/i915/display/intel_display_power.c | 2 +- .../drm/i915/display/intel_display_trace.h | 6 ++-- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- drivers/gpu/drm/i915/display/intel_dp_test.c | 2 +- .../gpu/drm/i915/display/intel_dp_tunnel.c | 2 +- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 2 +- drivers/gpu/drm/i915/display/intel_drrs.c | 4 +-- drivers/gpu/drm/i915/display/intel_fbdev.c | 6 ++-- .../drm/i915/display/intel_fifo_underrun.c | 4 +-- drivers/gpu/drm/i915/display/intel_flipq.c | 2 +- .../gpu/drm/i915/display/intel_global_state.c | 8 ++--- .../drm/i915/display/intel_initial_plane.c | 4 +-- drivers/gpu/drm/i915/display/intel_link_bw.c | 2 +- .../gpu/drm/i915/display/intel_load_detect.c | 2 +- .../drm/i915/display/intel_modeset_setup.c | 32 ++++++++--------- drivers/gpu/drm/i915/display/intel_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_psr.c | 2 +- drivers/gpu/drm/i915/display/intel_tc.c | 2 +- drivers/gpu/drm/i915/display/skl_watermark.c | 16 ++++----- 29 files changed, 105 insertions(+), 105 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 4cd07410ad72..19b61d4c1fae 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -640,7 +640,7 @@ static struct intel_crtc *single_enabled_crtc(struct intel_display *display) { struct intel_crtc *crtc, *enabled = NULL; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { if (intel_crtc_active(crtc)) { if (enabled) return NULL; @@ -1393,7 +1393,7 @@ static void g4x_merge_wm(struct intel_display *display, wm->hpll_en = true; wm->fbc_en = true; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { const struct g4x_wm_state *wm_state = &crtc->wm.active.g4x; if (!crtc->active) @@ -1415,7 +1415,7 @@ static void g4x_merge_wm(struct intel_display *display, wm->fbc_en = false; } - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { const struct g4x_wm_state *wm_state = &crtc->wm.active.g4x; enum pipe pipe = crtc->pipe; @@ -2034,7 +2034,7 @@ static void vlv_merge_wm(struct intel_display *display, wm->level = display->wm.num_levels - 1; wm->cxsr = true; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { const struct vlv_wm_state *wm_state = &crtc->wm.active.vlv; if (!crtc->active) @@ -2053,7 +2053,7 @@ static void vlv_merge_wm(struct intel_display *display, if (num_active_pipes > 1) wm->level = VLV_WM_LEVEL_PM2; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { const struct vlv_wm_state *wm_state = &crtc->wm.active.vlv; enum pipe pipe = crtc->pipe; @@ -3078,7 +3078,7 @@ static void ilk_merge_wm_level(struct intel_display *display, ret_wm->enable = true; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { const struct intel_pipe_wm *active = &crtc->wm.active.ilk; const struct intel_wm_level *wm = &active->wm[level]; @@ -3218,7 +3218,7 @@ static void ilk_compute_wm_results(struct intel_display *display, } /* LP0 register values */ - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { enum pipe pipe = crtc->pipe; const struct intel_pipe_wm *pipe_wm = &crtc->wm.active.ilk; const struct intel_wm_level *r = &pipe_wm->wm[0]; @@ -3416,7 +3416,7 @@ static void ilk_compute_wm_config(struct intel_display *display, struct intel_crtc *crtc; /* Compute the currently _active_ config */ - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { const struct intel_pipe_wm *wm = &crtc->wm.active.ilk; if (!wm->pipe_enabled) @@ -3537,7 +3537,7 @@ static int ilk_sanitize_watermarks_add_affected(struct drm_atomic_commit *state) struct drm_plane *plane; struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state; crtc_state = intel_atomic_get_crtc_state(state, crtc); @@ -3770,7 +3770,7 @@ static void g4x_wm_get_hw_state(struct intel_display *display) wm->cxsr = intel_de_read(display, FW_BLC_SELF) & FW_BLC_SELF_EN; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct g4x_wm_state *active = &crtc->wm.active.g4x; @@ -3885,7 +3885,7 @@ static void g4x_wm_sanitize(struct intel_display *display) } } - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); int ret; @@ -3952,7 +3952,7 @@ static void vlv_wm_get_hw_state(struct intel_display *display) vlv_punit_put(display); } - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct vlv_wm_state *active = &crtc->wm.active.vlv; @@ -4034,7 +4034,7 @@ static void vlv_wm_sanitize(struct intel_display *display) } } - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); int ret; @@ -4075,7 +4075,7 @@ static void ilk_wm_get_hw_state(struct intel_display *display) ilk_init_lp_watermarks(display); - for_each_intel_crtc(display->drm, crtc) + for_each_intel_crtc(display, crtc) ilk_pipe_wm_get_hw_state(crtc); hw->wm_lp[0] = intel_de_read(display, WM1_LP_ILK); diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index d7b2bc80f8e3..07f711d6c762 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -1429,7 +1429,7 @@ void intel_bw_update_hw_state(struct intel_display *display) bw_state->pipe_sagv_reject = 0; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); enum pipe pipe = crtc->pipe; diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index a1bf01021d65..2fa7e8c3bb26 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -3647,7 +3647,7 @@ void intel_cdclk_update_hw_state(struct intel_display *display) cdclk_state->enabled_pipes = 0; cdclk_state->active_pipes = 0; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); enum pipe pipe = crtc->pipe; diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index b7600cecafc8..f3403128a313 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -56,7 +56,7 @@ struct intel_crtc *intel_crtc_for_pipe(struct intel_display *display, { struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { if (crtc->pipe == pipe) return crtc; } diff --git a/drivers/gpu/drm/i915/display/intel_dbuf_bw.c b/drivers/gpu/drm/i915/display/intel_dbuf_bw.c index 0562d4df6a07..1f38317b38bb 100644 --- a/drivers/gpu/drm/i915/display/intel_dbuf_bw.c +++ b/drivers/gpu/drm/i915/display/intel_dbuf_bw.c @@ -236,7 +236,7 @@ void intel_dbuf_bw_update_hw_state(struct intel_display *display) if (DISPLAY_VER(display) < 9) return; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 86520848892e..ad6b28e78cc5 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3672,7 +3672,7 @@ void intel_ddi_update_active_dpll(struct intel_atomic_state *state, if (!intel_encoder_is_tc(encoder) || !display->dpll.mgr) return; - for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc, + for_each_intel_crtc_in_pipe_mask(display, pipe_crtc, intel_crtc_joined_pipe_mask(crtc_state)) intel_dpll_update_active(state, pipe_crtc, encoder); } diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d741e2f7105f..af9a9bc52d11 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -717,7 +717,7 @@ bool intel_has_pending_fb_unpin(struct intel_display *display) struct intel_crtc *crtc; bool cleanup_done; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct drm_crtc_commit *commit; spin_lock(&crtc->base.commit_lock); commit = list_first_entry_or_null(&crtc->base.commit_list, @@ -742,7 +742,7 @@ void intel_display_flush_cleanup_work(struct intel_display *display) { struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct drm_crtc_commit *commit; spin_lock(&crtc->base.commit_lock); @@ -3527,7 +3527,7 @@ static void enabled_uncompressed_joiner_pipes(struct intel_display *display, if (!HAS_UNCOMPRESSED_JOINER(display)) return; - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, + for_each_intel_crtc_in_pipe_mask(display, crtc, joiner_pipes(display)) { enum intel_display_power_domain power_domain; enum pipe pipe = crtc->pipe; @@ -3555,7 +3555,7 @@ static void enabled_bigjoiner_pipes(struct intel_display *display, if (!HAS_BIGJOINER(display)) return; - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, + for_each_intel_crtc_in_pipe_mask(display, crtc, joiner_pipes(display)) { enum intel_display_power_domain power_domain; enum pipe pipe = crtc->pipe; @@ -3624,7 +3624,7 @@ static void enabled_ultrajoiner_pipes(struct intel_display *display, if (!HAS_ULTRAJOINER(display)) return; - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, + for_each_intel_crtc_in_pipe_mask(display, crtc, joiner_pipes(display)) { enum intel_display_power_domain power_domain; enum pipe pipe = crtc->pipe; @@ -5587,7 +5587,7 @@ int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state, struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc; - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, mask) { + for_each_intel_crtc_in_pipe_mask(display, crtc, mask) { struct intel_crtc_state *crtc_state; int ret; @@ -5634,7 +5634,7 @@ int intel_modeset_all_pipes_late(struct intel_atomic_state *state, struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state; int ret; @@ -5675,7 +5675,7 @@ int intel_modeset_commit_pipes(struct intel_display *display, state->acquire_ctx = ctx; to_intel_atomic_state(state)->internal = true; - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) { + for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) { struct intel_crtc_state *crtc_state = intel_atomic_get_crtc_state(state, crtc); @@ -5730,7 +5730,7 @@ static int hsw_mode_set_planes_workaround(struct intel_atomic_state *state) return 0; /* w/a possibly needed, check how many crtc's are already enabled. */ - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); if (IS_ERR(crtc_state)) return PTR_ERR(crtc_state); @@ -5927,7 +5927,7 @@ static int intel_atomic_check_joiner(struct intel_atomic_state *state, return -EINVAL; } - for_each_intel_crtc_in_pipe_mask(display->drm, secondary_crtc, + for_each_intel_crtc_in_pipe_mask(display, secondary_crtc, intel_crtc_joiner_secondary_pipes(primary_crtc_state)) { struct intel_crtc_state *secondary_crtc_state; int ret; @@ -5970,7 +5970,7 @@ static void kill_joiner_secondaries(struct intel_atomic_state *state, intel_atomic_get_new_crtc_state(state, primary_crtc); struct intel_crtc *secondary_crtc; - for_each_intel_crtc_in_pipe_mask(display->drm, secondary_crtc, + for_each_intel_crtc_in_pipe_mask(display, secondary_crtc, intel_crtc_joiner_secondary_pipes(primary_crtc_state)) { struct intel_crtc_state *secondary_crtc_state = intel_atomic_get_new_crtc_state(state, secondary_crtc); @@ -6269,13 +6269,13 @@ static int intel_joiner_add_affected_crtcs(struct intel_atomic_state *state) modeset_pipes |= crtc_state->joiner_pipes; } - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, affected_pipes) { + for_each_intel_crtc_in_pipe_mask(display, crtc, affected_pipes) { crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); if (IS_ERR(crtc_state)) return PTR_ERR(crtc_state); } - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, modeset_pipes) { + for_each_intel_crtc_in_pipe_mask(display, crtc, modeset_pipes) { int ret; crtc_state = intel_atomic_get_new_crtc_state(state, crtc); @@ -6760,7 +6760,7 @@ static void intel_enable_crtc(struct intel_atomic_state *state, if (!intel_crtc_needs_modeset(new_crtc_state)) return; - for_each_intel_crtc_in_pipe_mask_reverse(display->drm, pipe_crtc, + for_each_intel_crtc_in_pipe_mask_reverse(display, pipe_crtc, intel_crtc_joined_pipe_mask(new_crtc_state)) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); @@ -6898,7 +6898,7 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state, * We need to disable pipe CRC before disabling the pipe, * or we race against vblank off. */ - for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc, + for_each_intel_crtc_in_pipe_mask(display, pipe_crtc, intel_crtc_joined_pipe_mask(old_crtc_state)) intel_crtc_disable_pipe_crc(pipe_crtc); @@ -6906,7 +6906,7 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state, display->modeset.funcs->crtc_disable(state, crtc); - for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc, + for_each_intel_crtc_in_pipe_mask(display, pipe_crtc, intel_crtc_joined_pipe_mask(old_crtc_state)) { const struct intel_crtc_state *new_pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); @@ -7818,7 +7818,7 @@ static u32 intel_encoder_possible_crtcs(struct intel_encoder *encoder) struct intel_crtc *crtc; u32 possible_crtcs = 0; - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, encoder->pipe_mask) + for_each_intel_crtc_in_pipe_mask(display, crtc, encoder->pipe_mask) possible_crtcs |= drm_crtc_mask(&crtc->base); return possible_crtcs; @@ -8311,7 +8311,7 @@ int intel_initial_commit(struct intel_display *display) to_intel_atomic_state(state)->internal = true; retry: - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = intel_atomic_get_crtc_state(state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 72f33113a5a3..82c4aa9de7d3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -212,22 +212,22 @@ enum phy_fia { base.head) \ for_each_if((intel_plane)->pipe == (intel_crtc)->pipe) -#define for_each_intel_crtc(dev, crtc) \ +#define for_each_intel_crtc(display, crtc) \ list_for_each_entry((crtc), \ - &to_intel_display(dev)->pipe_list, \ + &(display)->pipe_list, \ pipe_head) -#define for_each_intel_crtc_reverse(dev, crtc) \ +#define for_each_intel_crtc_reverse(display, crtc) \ list_for_each_entry_reverse((crtc), \ - &to_intel_display(dev)->pipe_list, \ + &(display)->pipe_list, \ pipe_head) -#define for_each_intel_crtc_in_pipe_mask(dev, crtc, pipe_mask) \ - for_each_intel_crtc((dev), (crtc)) \ +#define for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) \ + for_each_intel_crtc((display), (crtc)) \ for_each_if((pipe_mask) & BIT((crtc)->pipe)) -#define for_each_intel_crtc_in_pipe_mask_reverse(dev, crtc, pipe_mask) \ - for_each_intel_crtc_reverse((dev), (crtc)) \ +#define for_each_intel_crtc_in_pipe_mask_reverse(display, crtc, pipe_mask) \ + for_each_intel_crtc_reverse((display), (crtc)) \ for_each_if((pipe_mask) & BIT((crtc)->pipe)) #define for_each_intel_encoder(dev, intel_encoder) \ @@ -288,28 +288,28 @@ enum phy_fia { for_each_if(plane) #define for_each_old_intel_crtc_in_state(__state, crtc, old_crtc_state, __i) \ - for_each_intel_crtc((__state)->base.dev, (crtc)) \ + for_each_intel_crtc(to_intel_display(__state), (crtc)) \ for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \ (old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)))) #define for_each_new_intel_crtc_in_state(__state, crtc, new_crtc_state, __i) \ - for_each_intel_crtc((__state)->base.dev, (crtc)) \ + for_each_intel_crtc(to_intel_display(__state), (crtc)) \ for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \ (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc)))) #define for_each_new_intel_crtc_in_state_reverse(__state, crtc, new_crtc_state, __i) \ - for_each_intel_crtc_reverse((__state)->base.dev, (crtc)) \ + for_each_intel_crtc_reverse(to_intel_display(__state), (crtc)) \ for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \ (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc)))) #define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \ - for_each_intel_crtc((__state)->base.dev, (crtc)) \ + for_each_intel_crtc(to_intel_display(__state), (crtc)) \ for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \ (old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)), \ (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc)))) #define for_each_oldnew_intel_crtc_in_state_reverse(__state, crtc, old_crtc_state, new_crtc_state, __i) \ - for_each_intel_crtc_reverse((__state)->base.dev, (crtc)) \ + for_each_intel_crtc_reverse(to_intel_display(__state), (crtc)) \ for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \ (old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)), \ (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc)))) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 3d6f36773ad8..08004c1ba03f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -612,7 +612,7 @@ static int i915_display_info(struct seq_file *m, void *unused) seq_printf(m, "CRTC info\n"); seq_printf(m, "---------\n"); - for_each_intel_crtc(display->drm, crtc) + for_each_intel_crtc(display, crtc) intel_crtc_info(m, crtc); seq_printf(m, "\n"); @@ -670,7 +670,7 @@ static int i915_ddb_info(struct seq_file *m, void *unused) seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size"); - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); enum pipe pipe = crtc->pipe; @@ -777,7 +777,7 @@ i915_fifo_underrun_reset_write(struct file *filp, if (!reset) return cnt; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct drm_crtc_commit *commit; struct intel_crtc_state *crtc_state; diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 751e6b7d4a29..f2f028bdd0aa 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1203,7 +1203,7 @@ static void assert_can_disable_lcpll(struct intel_display *display) { struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) + for_each_intel_crtc(display, crtc) INTEL_DISPLAY_STATE_WARN(display, crtc->active, "CRTC for pipe %c enabled\n", pipe_name(crtc->pipe)); diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h b/drivers/gpu/drm/i915/display/intel_display_trace.h index 27ebc32cb61a..504d105935bc 100644 --- a/drivers/gpu/drm/i915/display/intel_display_trace.h +++ b/drivers/gpu/drm/i915/display/intel_display_trace.h @@ -84,7 +84,7 @@ TRACE_EVENT(intel_pipe_enable, sizeof(__entry->frame[0]) * I915_MAX_PIPES); memset(__entry->scanline, 0, sizeof(__entry->scanline[0]) * I915_MAX_PIPES); - for_each_intel_crtc(display->drm, it__) { + for_each_intel_crtc(display, it__) { __entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__); __entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__); } @@ -114,7 +114,7 @@ TRACE_EVENT(intel_pipe_disable, sizeof(__entry->frame[0]) * I915_MAX_PIPES); memset(__entry->scanline, 0, sizeof(__entry->scanline[0]) * I915_MAX_PIPES); - for_each_intel_crtc(display->drm, it__) { + for_each_intel_crtc(display, it__) { __entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__); __entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__); } @@ -244,7 +244,7 @@ TRACE_EVENT(intel_memory_cxsr, sizeof(__entry->frame[0]) * I915_MAX_PIPES); memset(__entry->scanline, 0, sizeof(__entry->scanline[0]) * I915_MAX_PIPES); - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { __entry->frame[crtc->pipe] = intel_crtc_get_vblank_counter(crtc); __entry->scanline[crtc->pipe] = intel_get_crtc_scanline(crtc); } diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 3f9123a53244..f76800db03f3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -6803,7 +6803,7 @@ static int intel_modeset_affected_transcoders(struct intel_atomic_state *state, if (transcoders == 0) return 0; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state; int ret; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 8f73e01db17c..be8febe3d234 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -837,7 +837,7 @@ static int intel_dp_mst_check_dsc_change(struct intel_atomic_state *state, mst_pipe_mask = get_pipes_downstream_of_mst_port(state, mst_mgr, NULL); - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, mst_pipe_mask) { + for_each_intel_crtc_in_pipe_mask(display, crtc, mst_pipe_mask) { struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c index 5cfa1dd411da..ba44769c9cfb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.c +++ b/drivers/gpu/drm/i915/display/intel_dp_test.c @@ -471,7 +471,7 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder, drm_dbg_kms(display->drm, "[ENCODER:%d:%s] PHY test\n", encoder->base.base.id, encoder->base.name); - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) { + for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c index 11712a151f72..10d47faa6996 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c +++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c @@ -146,7 +146,7 @@ static int allocate_initial_tunnel_bw_for_pipes(struct intel_dp *intel_dp, u8 pi int tunnel_bw = 0; int err; - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) { + for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); int stream_bw = intel_dp_config_required_rate(crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index bb487e647f76..0f933101b7dd 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -4965,7 +4965,7 @@ static void readout_dpll_hw_state(struct intel_display *display, pll->wakeref = intel_display_power_get(display, pll->info->power_domain); pll->state.pipe_mask = 0; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c index 0fdb32ef241c..6c95d4ae1ea9 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.c +++ b/drivers/gpu/drm/i915/display/intel_drrs.c @@ -137,7 +137,7 @@ static unsigned int intel_drrs_frontbuffer_bits(const struct intel_crtc_state *c frontbuffer_bits = INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe); - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, + for_each_intel_crtc_in_pipe_mask(display, crtc, crtc_state->joiner_pipes) frontbuffer_bits |= INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe); @@ -227,7 +227,7 @@ static void intel_drrs_frontbuffer_update(struct intel_display *display, { struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { unsigned int frontbuffer_bits; mutex_lock(&crtc->drrs.mutex); diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index df1d3d9dc3e5..c8d4e3a5ce6b 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -380,7 +380,7 @@ static bool intel_fbdev_init_bios(struct intel_display *display, unsigned int max_size = 0; /* Find the largest fb */ - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane *plane = @@ -419,7 +419,7 @@ static bool intel_fbdev_init_bios(struct intel_display *display, } /* Now make sure all the pipes will fit into it */ - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane *plane = @@ -489,7 +489,7 @@ static bool intel_fbdev_init_bios(struct intel_display *display, drm_framebuffer_get(&ifbdev->fb->base); /* Final pass to check if any active pipes don't have fbs */ - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane *plane = diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c index 02013e89d8f2..eca016d725d2 100644 --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c @@ -527,7 +527,7 @@ void intel_check_cpu_fifo_underruns(struct intel_display *display) spin_lock_irq(&display->irq.lock); - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { if (crtc->cpu_fifo_underrun_disabled) continue; @@ -554,7 +554,7 @@ void intel_check_pch_fifo_underruns(struct intel_display *display) spin_lock_irq(&display->irq.lock); - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { if (crtc->pch_fifo_underrun_disabled) continue; diff --git a/drivers/gpu/drm/i915/display/intel_flipq.c b/drivers/gpu/drm/i915/display/intel_flipq.c index 333d28faf4ca..bf278f60bba7 100644 --- a/drivers/gpu/drm/i915/display/intel_flipq.c +++ b/drivers/gpu/drm/i915/display/intel_flipq.c @@ -132,7 +132,7 @@ void intel_flipq_init(struct intel_display *display) intel_dmc_wait_fw_load(display); - for_each_intel_crtc(display->drm, crtc) + for_each_intel_crtc(display, crtc) intel_flipq_crtc_init(crtc); } diff --git a/drivers/gpu/drm/i915/display/intel_global_state.c b/drivers/gpu/drm/i915/display/intel_global_state.c index 9e1369c834e4..886caf29c9ae 100644 --- a/drivers/gpu/drm/i915/display/intel_global_state.c +++ b/drivers/gpu/drm/i915/display/intel_global_state.c @@ -140,7 +140,7 @@ static void assert_global_state_write_locked(struct intel_display *display) { struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) + for_each_intel_crtc(display, crtc) drm_modeset_lock_assert_held(&crtc->base.mutex); } @@ -163,7 +163,7 @@ static void assert_global_state_read_locked(struct intel_atomic_state *state) struct drm_modeset_acquire_ctx *ctx = state->base.acquire_ctx; struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { if (modeset_lock_is_held(ctx, &crtc->base.mutex)) return; } @@ -301,7 +301,7 @@ int intel_atomic_lock_global_state(struct intel_global_state *obj_state) struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { int ret; ret = drm_modeset_lock(&crtc->base.mutex, @@ -334,7 +334,7 @@ intel_atomic_global_state_is_serialized(struct intel_atomic_state *state) struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) + for_each_intel_crtc(display, crtc) if (!intel_atomic_get_new_crtc_state(state, crtc)) return false; return true; diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c index 034fe199c2a1..6aa253678ec9 100644 --- a/drivers/gpu/drm/i915/display/intel_initial_plane.c +++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c @@ -50,7 +50,7 @@ intel_reuse_initial_plane_obj(struct intel_crtc *this, struct intel_display *display = to_intel_display(this); struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_plane *plane = to_intel_plane(crtc->base.primary); const struct intel_plane_state *plane_state = @@ -208,7 +208,7 @@ void intel_initial_plane_config(struct intel_display *display) struct intel_initial_plane_configs all_plane_configs = {}; struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_initial_plane_config *plane_config = diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c b/drivers/gpu/drm/i915/display/intel_link_bw.c index d2862de894fa..b47474a3e9fe 100644 --- a/drivers/gpu/drm/i915/display/intel_link_bw.c +++ b/drivers/gpu/drm/i915/display/intel_link_bw.c @@ -108,7 +108,7 @@ static int __intel_link_bw_reduce_bpp(struct intel_atomic_state *state, struct intel_crtc *crtc; int max_bpp_x16 = 0; - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) { + for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) { struct intel_crtc_state *crtc_state; int link_bpp_x16; diff --git a/drivers/gpu/drm/i915/display/intel_load_detect.c b/drivers/gpu/drm/i915/display/intel_load_detect.c index 2f767b15a7f9..3fef1ebc6357 100644 --- a/drivers/gpu/drm/i915/display/intel_load_detect.c +++ b/drivers/gpu/drm/i915/display/intel_load_detect.c @@ -89,7 +89,7 @@ intel_load_detect_get_pipe(struct drm_connector *connector, } /* Find an unused one (if possible) */ - for_each_intel_crtc(display->drm, possible_crtc) { + for_each_intel_crtc(display, possible_crtc) { if (!(encoder->base.possible_crtcs & drm_crtc_mask(&possible_crtc->base))) continue; diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 0c9775eabdf0..6a7982551929 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -71,7 +71,7 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc, to_intel_atomic_state(state)->internal = true; /* Everything's already locked, -EDEADLK can't happen. */ - for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, + for_each_intel_crtc_in_pipe_mask(display, temp_crtc, BIT(pipe) | intel_crtc_joiner_secondary_pipes(crtc_state)) { struct intel_crtc_state *temp_crtc_state = @@ -192,7 +192,7 @@ static u8 get_transcoder_pipes(struct intel_display *display, struct intel_crtc *temp_crtc; u8 pipes = 0; - for_each_intel_crtc(display->drm, temp_crtc) { + for_each_intel_crtc(display, temp_crtc) { struct intel_crtc_state *temp_crtc_state = to_intel_crtc_state(temp_crtc->base.state); @@ -248,7 +248,7 @@ static u8 get_joiner_secondary_pipes(struct intel_display *display, u8 primary_p struct intel_crtc *primary_crtc; u8 pipes = 0; - for_each_intel_crtc_in_pipe_mask(display->drm, primary_crtc, primary_pipes_mask) { + for_each_intel_crtc_in_pipe_mask(display, primary_crtc, primary_pipes_mask) { struct intel_crtc_state *primary_crtc_state = to_intel_crtc_state(primary_crtc->base.state); @@ -278,16 +278,16 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc, portsync_master_mask & joiner_secondaries_mask || portsync_slaves_mask & joiner_secondaries_mask); - for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, joiner_secondaries_mask) + for_each_intel_crtc_in_pipe_mask(display, temp_crtc, joiner_secondaries_mask) intel_crtc_disable_noatomic_begin(temp_crtc, ctx); - for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, portsync_slaves_mask) + for_each_intel_crtc_in_pipe_mask(display, temp_crtc, portsync_slaves_mask) intel_crtc_disable_noatomic_begin(temp_crtc, ctx); - for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, portsync_master_mask) + for_each_intel_crtc_in_pipe_mask(display, temp_crtc, portsync_master_mask) intel_crtc_disable_noatomic_begin(temp_crtc, ctx); - for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, + for_each_intel_crtc_in_pipe_mask(display, temp_crtc, joiner_secondaries_mask | portsync_slaves_mask | portsync_master_mask) @@ -378,7 +378,7 @@ intel_sanitize_plane_mapping(struct intel_display *display) if (DISPLAY_VER(display) >= 4) return; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_plane *plane = to_intel_plane(crtc->base.primary); struct intel_crtc *plane_crtc; @@ -534,7 +534,7 @@ static void intel_sanitize_all_crtcs(struct intel_display *display, for (;;) { u32 old_mask = crtcs_forced_off; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { u32 crtc_mask = drm_crtc_mask(&crtc->base); if (crtcs_forced_off & crtc_mask) @@ -547,7 +547,7 @@ static void intel_sanitize_all_crtcs(struct intel_display *display, break; } - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -683,7 +683,7 @@ static void readout_plane_state(struct intel_display *display) str_enabled_disabled(visible), pipe_name(pipe)); } - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -701,7 +701,7 @@ static void intel_modeset_readout_hw_state(struct intel_display *display) struct intel_connector *connector; struct drm_connector_list_iter conn_iter; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -743,7 +743,7 @@ static void intel_modeset_readout_hw_state(struct intel_display *display) /* encoder should read be linked to joiner primary */ WARN_ON(intel_crtc_is_joiner_secondary(crtc_state)); - for_each_intel_crtc_in_pipe_mask(display->drm, secondary_crtc, + for_each_intel_crtc_in_pipe_mask(display, secondary_crtc, intel_crtc_joiner_secondary_pipes(crtc_state)) { struct intel_crtc_state *secondary_crtc_state; @@ -816,7 +816,7 @@ static void intel_modeset_readout_hw_state(struct intel_display *display) } drm_connector_list_iter_end(&conn_iter); - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane *plane; @@ -963,7 +963,7 @@ void intel_modeset_setup_hw_state(struct intel_display *display, * intel_sanitize_plane_mapping() may need to do vblank * waits, so we need vblank interrupts restored beforehand. */ - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -999,7 +999,7 @@ void intel_modeset_setup_hw_state(struct intel_display *display, intel_wm_get_hw_state(display); intel_wm_sanitize(display); - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_power_domain_mask put_domains; diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c index 911ae261d1b5..e191a57f02cd 100644 --- a/drivers/gpu/drm/i915/display/intel_plane.c +++ b/drivers/gpu/drm/i915/display/intel_plane.c @@ -1812,7 +1812,7 @@ static int intel_joiner_add_affected_planes(struct intel_atomic_state *state, do { struct intel_crtc *crtc; - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, joined_pipes) { + for_each_intel_crtc_in_pipe_mask(display, crtc, joined_pipes) { int ret; ret = intel_crtc_add_planes_to_state(state, crtc, affected_planes); diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 9382ad1e01d8..5047e3fdc9ff 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1908,7 +1908,7 @@ void intel_psr_set_non_psr_pipes(struct intel_dp *intel_dp, return; /* We ignore possible secondary PSR/Panel Replay capable eDP */ - for_each_intel_crtc(display->drm, crtc) + for_each_intel_crtc(display, crtc) active_pipes |= crtc->active ? BIT(crtc->pipe) : 0; active_pipes = intel_calc_active_pipes(state, active_pipes); diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 2880f2aa4243..f2d86b29c415 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -1779,7 +1779,7 @@ static int reset_link_commit(struct intel_tc_port *tc, if (!pipe_mask) return 0; - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) { + for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) { struct intel_crtc_state *crtc_state; crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 96d2dcbe7bbc..346e97d91d92 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -2529,7 +2529,7 @@ skl_compute_ddb(struct intel_atomic_state *state) } } - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { enum pipe pipe = crtc->pipe; new_dbuf_state->slices[pipe] = @@ -2574,7 +2574,7 @@ skl_compute_ddb(struct intel_atomic_state *state) return ret; } - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { ret = skl_crtc_allocate_ddb(state, crtc); if (ret) return ret; @@ -2845,7 +2845,7 @@ static int pkgc_max_linetime(struct intel_atomic_state *state) } max_linetime = 0; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { if (display->pkgc.disable[crtc->pipe]) return 0; @@ -3033,7 +3033,7 @@ static void skl_wm_get_hw_state(struct intel_display *display) dbuf_state->mdclk_cdclk_ratio = intel_mdclk_cdclk_ratio(display, &display->cdclk.hw); dbuf_state->active_pipes = 0; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); enum pipe pipe = crtc->pipe; @@ -3446,7 +3446,7 @@ static void pipe_mbus_dbox_ctl_update(struct intel_display *display, { struct intel_crtc *crtc; - for_each_intel_crtc_in_pipe_mask(display->drm, crtc, dbuf_state->active_pipes) + for_each_intel_crtc_in_pipe_mask(display, crtc, dbuf_state->active_pipes) intel_de_write(display, PIPE_MBUS_DBOX_CTL(crtc->pipe), pipe_mbus_dbox_ctl(crtc, dbuf_state)); } @@ -3758,14 +3758,14 @@ static bool skl_dbuf_is_misconfigured(struct intel_display *display) struct skl_ddb_entry entries[I915_MAX_PIPES] = {}; struct intel_crtc *crtc; - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); entries[crtc->pipe] = crtc_state->wm.skl.ddb; } - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); u8 slices; @@ -3803,7 +3803,7 @@ static void skl_dbuf_sanitize(struct intel_display *display) drm_dbg_kms(display->drm, "BIOS has misprogrammed the DBUF, disabling all planes\n"); - for_each_intel_crtc(display->drm, crtc) { + for_each_intel_crtc(display, crtc) { struct intel_plane *plane = to_intel_plane(crtc->base.primary); const struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); From f49410baedcb46c015b7bf3ca66c449b05fe3cf0 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 10:58:39 +0300 Subject: [PATCH 52/80] drm/i915/display: stop passing i to for_each_*_intel_crtc_in_state() macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit None of the for_each_*_intel_crtc_in_state() macros or their users actually need the CRTC index i variable anymore. Remove them. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/edb9dc76cb9cad50622a1f425abaf076d1509888.1778659089.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/i9xx_wm.c | 3 +- drivers/gpu/drm/i915/display/intel_atomic.c | 3 +- drivers/gpu/drm/i915/display/intel_bw.c | 9 +- drivers/gpu/drm/i915/display/intel_cdclk.c | 12 +- drivers/gpu/drm/i915/display/intel_crtc.c | 11 +- drivers/gpu/drm/i915/display/intel_dbuf_bw.c | 5 +- drivers/gpu/drm/i915/display/intel_display.c | 115 +++++++----------- drivers/gpu/drm/i915/display/intel_display.h | 25 ++-- .../gpu/drm/i915/display/intel_dp_tunnel.c | 6 +- drivers/gpu/drm/i915/display/intel_fdi.c | 3 +- drivers/gpu/drm/i915/display/intel_plane.c | 6 +- drivers/gpu/drm/i915/display/intel_pmdemand.c | 6 +- drivers/gpu/drm/i915/display/intel_vrr.c | 4 +- drivers/gpu/drm/i915/display/skl_watermark.c | 22 ++-- 14 files changed, 89 insertions(+), 141 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 19b61d4c1fae..86d1c9f7f0ff 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -3582,7 +3582,6 @@ void ilk_wm_sanitize(struct intel_display *display) struct intel_crtc_state *crtc_state; struct drm_modeset_acquire_ctx ctx; int ret; - int i; /* Only supported on platforms that use atomic watermark design */ if (!display->wm.funcs->optimize_watermarks) @@ -3620,7 +3619,7 @@ void ilk_wm_sanitize(struct intel_display *display) goto fail; /* Write calculated watermark values back */ - for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state) { crtc_state->wm.need_postvbl_update = true; intel_optimize_watermarks(intel_state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index 38bbd6964d8e..0e4f0678c53c 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -200,9 +200,8 @@ bool intel_any_crtc_needs_modeset(struct intel_atomic_state *state) { struct intel_crtc *crtc; struct intel_crtc_state *crtc_state; - int i; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { if (intel_crtc_needs_modeset(crtc_state)) return true; } diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 07f711d6c762..d5aac5abea6f 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -1270,10 +1270,8 @@ static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *chan struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; - int i; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { unsigned int old_data_rate = intel_crtc_bw_data_rate(old_crtc_state); unsigned int new_data_rate = @@ -1319,10 +1317,9 @@ static int intel_bw_check_sagv_mask(struct intel_atomic_state *state) const struct intel_bw_state *old_bw_state = NULL; struct intel_bw_state *new_bw_state = NULL; struct intel_crtc *crtc; - int ret, i; + int ret; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { if (intel_crtc_can_enable_sagv(old_crtc_state) == intel_crtc_can_enable_sagv(new_crtc_state)) continue; diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 2fa7e8c3bb26..189ae2d3cfc9 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -3124,10 +3124,9 @@ static int bxt_compute_min_voltage_level(struct intel_atomic_state *state) struct intel_crtc *crtc; struct intel_crtc_state *crtc_state; u8 min_voltage_level; - int i; enum pipe pipe; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { int ret; if (crtc_state->hw.enable) @@ -3219,13 +3218,13 @@ static int skl_dpll0_vco(struct intel_atomic_state *state) intel_atomic_get_new_cdclk_state(state); struct intel_crtc *crtc; struct intel_crtc_state *crtc_state; - int vco, i; + int vco; vco = cdclk_state->logical.vco; if (!vco) vco = display->cdclk.skl_preferred_vco_freq; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { if (!crtc_state->hw.enable) continue; @@ -3424,10 +3423,9 @@ static int intel_crtcs_calc_min_cdclk(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state; const struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; - int i, ret; + int ret; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { ret = intel_cdclk_update_crtc_min_cdclk(state, crtc, old_crtc_state->min_cdclk, new_crtc_state->min_cdclk, diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index f3403128a313..7ce2b52297d1 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -538,9 +538,8 @@ void intel_wait_for_vblank_workers(struct intel_atomic_state *state) { struct intel_crtc_state *crtc_state; struct intel_crtc *crtc; - int i; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { if (!intel_crtc_needs_vblank_work(crtc_state)) continue; @@ -832,10 +831,8 @@ bool intel_any_crtc_enable_changed(struct intel_atomic_state *state) { const struct intel_crtc_state *old_crtc_state, *new_crtc_state; struct intel_crtc *crtc; - int i; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { if (intel_crtc_enable_changed(old_crtc_state, new_crtc_state)) return true; } @@ -853,10 +850,8 @@ bool intel_any_crtc_active_changed(struct intel_atomic_state *state) { const struct intel_crtc_state *old_crtc_state, *new_crtc_state; struct intel_crtc *crtc; - int i; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { if (intel_crtc_active_changed(old_crtc_state, new_crtc_state)) return true; } diff --git a/drivers/gpu/drm/i915/display/intel_dbuf_bw.c b/drivers/gpu/drm/i915/display/intel_dbuf_bw.c index 1f38317b38bb..6cf674c586dc 100644 --- a/drivers/gpu/drm/i915/display/intel_dbuf_bw.c +++ b/drivers/gpu/drm/i915/display/intel_dbuf_bw.c @@ -184,13 +184,12 @@ int intel_dbuf_bw_calc_min_cdclk(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state; const struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; - int ret, i; + int ret; if (DISPLAY_VER(display) < 9) return 0; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { struct intel_dbuf_bw old_dbuf_bw, new_dbuf_bw; skl_crtc_calc_dbuf_bw(&old_dbuf_bw, old_crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index af9a9bc52d11..290bbefece4a 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1317,14 +1317,13 @@ static void intel_encoders_update_prepare(struct intel_atomic_state *state) struct intel_display *display = to_intel_display(state); struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; - int i; /* * Make sure the DPLL state is up-to-date for fastset TypeC ports after non-blocking commits. * TODO: Update the DPLL state for all cases in the encoder->update_prepare() hook. */ if (display->dpll.mgr) { - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { if (intel_crtc_needs_modeset(new_crtc_state)) continue; @@ -5708,10 +5707,9 @@ static int hsw_mode_set_planes_workaround(struct intel_atomic_state *state) struct intel_crtc_state *first_crtc_state = NULL; struct intel_crtc_state *other_crtc_state = NULL; enum pipe first_pipe = INVALID_PIPE, enabled_pipe = INVALID_PIPE; - int i; /* look at all crtc's that are going to be enabled in during modeset */ - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { if (!crtc_state->hw.active || !intel_crtc_needs_modeset(crtc_state)) continue; @@ -5761,9 +5759,8 @@ u8 intel_calc_enabled_pipes(struct intel_atomic_state *state, { const struct intel_crtc_state *crtc_state; struct intel_crtc *crtc; - int i; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { if (crtc_state->hw.enable) enabled_pipes |= BIT(crtc->pipe); else @@ -5778,9 +5775,8 @@ u8 intel_calc_active_pipes(struct intel_atomic_state *state, { const struct intel_crtc_state *crtc_state; struct intel_crtc *crtc; - int i; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { if (crtc_state->hw.active) active_pipes |= BIT(crtc->pipe); else @@ -5851,9 +5847,8 @@ static int intel_atomic_check_crtcs(struct intel_atomic_state *state) struct intel_display *display = to_intel_display(state); struct intel_crtc_state __maybe_unused *crtc_state; struct intel_crtc *crtc; - int i; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { int ret; ret = intel_crtc_atomic_check(state, crtc); @@ -5873,9 +5868,8 @@ static bool intel_cpu_transcoders_need_modeset(struct intel_atomic_state *state, { const struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; - int i; - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { if (new_crtc_state->hw.enable && transcoders & BIT(new_crtc_state->cpu_transcoder) && intel_crtc_needs_modeset(new_crtc_state)) @@ -5890,9 +5884,8 @@ static bool intel_pipes_need_modeset(struct intel_atomic_state *state, { const struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; - int i; - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { if (new_crtc_state->hw.enable && pipes & BIT(crtc->pipe) && intel_crtc_needs_modeset(new_crtc_state)) @@ -6263,7 +6256,7 @@ static int intel_joiner_add_affected_crtcs(struct intel_atomic_state *state) } /* Now pull in all joined crtcs */ - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { affected_pipes |= crtc_state->joiner_pipes; if (intel_crtc_needs_modeset(crtc_state)) modeset_pipes |= crtc_state->joiner_pipes; @@ -6291,7 +6284,7 @@ static int intel_joiner_add_affected_crtcs(struct intel_atomic_state *state) return ret; } - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { /* Kill old joiner link, we may re-establish afterwards */ if (intel_crtc_needs_modeset(crtc_state) && intel_crtc_is_joiner_primary(crtc_state)) @@ -6309,7 +6302,6 @@ static int intel_atomic_check_config(struct intel_atomic_state *state, struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; int ret; - int i; *failed_pipe = INVALID_PIPE; @@ -6321,7 +6313,7 @@ static int intel_atomic_check_config(struct intel_atomic_state *state, if (ret) return ret; - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { if (!intel_crtc_needs_modeset(new_crtc_state)) { if (!intel_crtc_is_joiner_secondary(new_crtc_state)) intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc); @@ -6343,7 +6335,7 @@ static int intel_atomic_check_config(struct intel_atomic_state *state, goto fail; } - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { if (!intel_crtc_needs_modeset(new_crtc_state)) continue; @@ -6415,13 +6407,12 @@ int intel_atomic_check(struct drm_device *dev, struct intel_atomic_state *state = to_intel_atomic_state(_state); struct intel_crtc_state *old_crtc_state, *new_crtc_state; struct intel_crtc *crtc; - int ret, i; + int ret; if (!intel_display_driver_check_access(display)) return -ENODEV; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { /* * crtc's state no longer considered to be inherited * after the first userspace/client initiated commit. @@ -6447,7 +6438,7 @@ int intel_atomic_check(struct drm_device *dev, if (ret) goto fail; - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { ret = intel_async_flip_check_uapi(state, crtc); if (ret) return ret; @@ -6457,7 +6448,7 @@ int intel_atomic_check(struct drm_device *dev, if (ret) goto fail; - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { if (!intel_crtc_needs_modeset(new_crtc_state)) { if (intel_crtc_is_joiner_secondary(new_crtc_state)) copy_joiner_crtc_state_nomodeset(state, crtc); @@ -6474,8 +6465,7 @@ int intel_atomic_check(struct drm_device *dev, goto fail; } - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { if (!intel_crtc_needs_modeset(new_crtc_state)) continue; @@ -6495,7 +6485,7 @@ int intel_atomic_check(struct drm_device *dev, * needs a full modeset, all other synced crtcs should be * forced a full modeset. */ - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { if (!new_crtc_state->hw.enable || intel_crtc_needs_modeset(new_crtc_state)) continue; @@ -6525,8 +6515,7 @@ int intel_atomic_check(struct drm_device *dev, } } - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { if (!intel_crtc_needs_modeset(new_crtc_state)) continue; @@ -6543,7 +6532,7 @@ int intel_atomic_check(struct drm_device *dev, if (ret) goto fail; - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) new_crtc_state->min_cdclk = intel_crtc_min_cdclk(new_crtc_state); ret = intel_compute_global_watermarks(state); @@ -6576,8 +6565,7 @@ int intel_atomic_check(struct drm_device *dev, if (ret) goto fail; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { intel_color_assert_luts(new_crtc_state); ret = intel_async_flip_check_hw(state, crtc); @@ -6608,8 +6596,7 @@ int intel_atomic_check(struct drm_device *dev, * FIXME would probably be nice to know which crtc specifically * caused the failure, in cases where we can pinpoint it. */ - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) intel_crtc_state_dump(new_crtc_state, state, "failed"); return ret; @@ -6925,10 +6912,8 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) const struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; u8 disable_pipes = 0; - int i; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { if (!intel_crtc_needs_modeset(new_crtc_state)) continue; @@ -6944,7 +6929,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) disable_pipes |= BIT(crtc->pipe); } - for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) { + for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state) { if ((disable_pipes & BIT(crtc->pipe)) == 0) continue; @@ -6954,7 +6939,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) } /* Only disable port sync and MST slaves */ - for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) { + for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state) { if ((disable_pipes & BIT(crtc->pipe)) == 0) continue; @@ -6976,7 +6961,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) } /* Disable everything else left on */ - for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) { + for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state) { if ((disable_pipes & BIT(crtc->pipe)) == 0) continue; @@ -6995,9 +6980,8 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state) { struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; - int i; - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { if (!new_crtc_state->hw.active) continue; @@ -7005,7 +6989,7 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state) intel_pre_update_crtc(state, crtc); } - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { if (!new_crtc_state->hw.active) continue; @@ -7020,9 +7004,8 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) struct intel_crtc_state *old_crtc_state, *new_crtc_state; struct skl_ddb_entry entries[I915_MAX_PIPES] = {}; u8 update_pipes = 0, modeset_pipes = 0; - int i; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { enum pipe pipe = crtc->pipe; if (!new_crtc_state->hw.active) @@ -7046,7 +7029,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) * So first lets enable all pipes that do not need a fullmodeset as * those don't have any external dependency. */ - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { enum pipe pipe = crtc->pipe; if ((update_pipes & BIT(pipe)) == 0) @@ -7062,8 +7045,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) * Commit in reverse order to make joiner primary * send the uapi events after secondaries are done. */ - for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state, new_crtc_state) { enum pipe pipe = crtc->pipe; if ((update_pipes & BIT(pipe)) == 0) @@ -7099,7 +7081,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) * Enable all pipes that needs a modeset and do not depends on other * pipes */ - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { enum pipe pipe = crtc->pipe; if ((modeset_pipes & BIT(pipe)) == 0) @@ -7121,7 +7103,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) * Then we enable all remaining pipes that depend on other * pipes: MST slaves and port sync masters */ - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { enum pipe pipe = crtc->pipe; if ((modeset_pipes & BIT(pipe)) == 0) @@ -7138,7 +7120,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) /* * Finally we do the plane updates/etc. for all pipes that got enabled. */ - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { enum pipe pipe = crtc->pipe; if ((update_pipes & BIT(pipe)) == 0) @@ -7151,7 +7133,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) * Commit in reverse order to make joiner primary * send the uapi events after secondaries are done. */ - for_each_new_intel_crtc_in_state_reverse(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state_reverse(state, crtc, new_crtc_state) { enum pipe pipe = crtc->pipe; if ((update_pipes & BIT(pipe)) == 0) @@ -7216,9 +7198,8 @@ static void intel_atomic_cleanup_work(struct work_struct *work) struct intel_display *display = to_intel_display(state); struct intel_crtc_state *old_crtc_state; struct intel_crtc *crtc; - int i; - for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) + for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state) intel_atomic_dsb_cleanup(old_crtc_state); drm_atomic_helper_cleanup_planes(display->drm, &state->base); @@ -7448,9 +7429,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) struct intel_crtc *crtc; struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {}; struct ref_tracker *wakeref = NULL; - int i; - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) intel_atomic_dsb_prepare(state, crtc); intel_atomic_commit_fence_wait(state); @@ -7459,10 +7439,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_atomic_prepare_plane_clear_colors(state); - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) intel_fbc_prepare_dirty_rect(state, crtc); - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) intel_atomic_dsb_finish(state, crtc); drm_atomic_helper_wait_for_dependencies(&state->base); @@ -7498,8 +7478,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) */ wakeref = intel_display_power_get(display, POWER_DOMAIN_DC_OFF); - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { if (intel_crtc_needs_modeset(new_crtc_state) || intel_crtc_needs_fastset(new_crtc_state)) intel_modeset_get_crtc_power_domains(new_crtc_state, &put_domains[crtc->pipe]); @@ -7510,7 +7489,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_dp_tunnel_atomic_alloc_bw(state); /* FIXME: Eventually get rid of our crtc->config pointer */ - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) crtc->config = new_crtc_state; /* @@ -7532,7 +7511,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_sagv_pre_plane_update(state); /* Complete the events for pipes that have now been disabled */ - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { bool modeset = intel_crtc_needs_modeset(new_crtc_state); /* Complete events for now disable pipes here. */ @@ -7550,7 +7529,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_dbuf_pre_plane_update(state); - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { if (new_crtc_state->do_async_flip) intel_crtc_enable_flip_done(state, crtc); } @@ -7574,7 +7553,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) */ drm_atomic_helper_wait_for_flip_done(display->drm, &state->base); - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { if (new_crtc_state->do_async_flip) intel_crtc_disable_flip_done(state, crtc); @@ -7594,8 +7573,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * * TODO: Move this (and other cleanup) to an async worker eventually. */ - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { /* * Gen2 reports pipe underruns whenever all planes are disabled. * So re-enable underrun reporting after some planes get enabled. @@ -7612,7 +7590,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_dbuf_post_plane_update(state); - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { intel_post_plane_update(state, crtc); intel_modeset_put_crtc_power_domains(crtc, &put_domains[crtc->pipe]); @@ -7756,9 +7734,8 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_commit *_state if (DISPLAY_VER(display) < 9 && state->base.legacy_cursor_update) { struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; - int i; - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) if (new_crtc_state->wm.need_postvbl_update || new_crtc_state->update_wm_post) state->base.legacy_cursor_update = false; diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 82c4aa9de7d3..a24d16d02f96 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -287,31 +287,26 @@ enum phy_fia { (__i)++) \ for_each_if(plane) -#define for_each_old_intel_crtc_in_state(__state, crtc, old_crtc_state, __i) \ +#define for_each_old_intel_crtc_in_state(__state, crtc, old_crtc_state) \ for_each_intel_crtc(to_intel_display(__state), (crtc)) \ - for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \ - (old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)))) + for_each_if((old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc))) -#define for_each_new_intel_crtc_in_state(__state, crtc, new_crtc_state, __i) \ +#define for_each_new_intel_crtc_in_state(__state, crtc, new_crtc_state) \ for_each_intel_crtc(to_intel_display(__state), (crtc)) \ - for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \ - (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc)))) + for_each_if((new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc))) -#define for_each_new_intel_crtc_in_state_reverse(__state, crtc, new_crtc_state, __i) \ +#define for_each_new_intel_crtc_in_state_reverse(__state, crtc, new_crtc_state) \ for_each_intel_crtc_reverse(to_intel_display(__state), (crtc)) \ - for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \ - (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc)))) + for_each_if((new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc))) -#define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \ +#define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state) \ for_each_intel_crtc(to_intel_display(__state), (crtc)) \ - for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \ - (old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)), \ + for_each_if(((old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)), \ (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc)))) -#define for_each_oldnew_intel_crtc_in_state_reverse(__state, crtc, old_crtc_state, new_crtc_state, __i) \ +#define for_each_oldnew_intel_crtc_in_state_reverse(__state, crtc, old_crtc_state, new_crtc_state) \ for_each_intel_crtc_reverse(to_intel_display(__state), (crtc)) \ - for_each_if(((__i) = drm_crtc_index(&(crtc)->base), (void)(__i), \ - (old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)), \ + for_each_if(((old_crtc_state) = intel_atomic_get_old_crtc_state((__state), (crtc)), \ (new_crtc_state) = intel_atomic_get_new_crtc_state((__state), (crtc)))) #define intel_atomic_crtc_state_for_each_plane_state( \ diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c index 10d47faa6996..d6bd1f7e01e1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c +++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c @@ -740,9 +740,8 @@ static void atomic_decrease_bw(struct intel_atomic_state *state) struct intel_crtc *crtc; const struct intel_crtc_state *old_crtc_state; const struct intel_crtc_state *new_crtc_state; - int i; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { const struct drm_dp_tunnel_state *new_tunnel_state; struct drm_dp_tunnel *tunnel; int old_bw; @@ -795,9 +794,8 @@ static void atomic_increase_bw(struct intel_atomic_state *state) { struct intel_crtc *crtc; const struct intel_crtc_state *crtc_state; - int i; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { struct drm_dp_tunnel_state *tunnel_state; struct drm_dp_tunnel *tunnel = crtc_state->dp_tunnel_ref.tunnel; int bw; diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index f8876aa23c9f..c170d3104e4c 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -368,9 +368,8 @@ int intel_fdi_atomic_check_link(struct intel_atomic_state *state, { struct intel_crtc *crtc; struct intel_crtc_state *crtc_state; - int i; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { int ret; if (!crtc_state->has_pch_encoder || diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c index e191a57f02cd..2a52b36c646c 100644 --- a/drivers/gpu/drm/i915/display/intel_plane.c +++ b/drivers/gpu/drm/i915/display/intel_plane.c @@ -1831,9 +1831,8 @@ static int intel_add_affected_planes(struct intel_atomic_state *state) { const struct intel_crtc_state *crtc_state; struct intel_crtc *crtc; - int i; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { int ret; ret = intel_joiner_add_affected_planes(state, intel_crtc_joined_pipe_mask(crtc_state)); @@ -1867,8 +1866,7 @@ int intel_plane_atomic_check(struct intel_atomic_state *state) } } - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { u8 old_active_planes, new_active_planes; ret = icl_check_nv12_planes(state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_pmdemand.c b/drivers/gpu/drm/i915/display/intel_pmdemand.c index 7819b724795b..6d32c52269a6 100644 --- a/drivers/gpu/drm/i915/display/intel_pmdemand.c +++ b/drivers/gpu/drm/i915/display/intel_pmdemand.c @@ -190,7 +190,7 @@ intel_pmdemand_update_max_ddiclk(struct intel_display *display, struct intel_crtc *crtc; int i; - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) intel_pmdemand_update_port_clock(display, pmdemand_state, crtc->pipe, new_crtc_state->port_clock); @@ -299,7 +299,6 @@ static bool intel_pmdemand_needs_update(struct intel_atomic_state *state) { const struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; - int i; if (intel_bw_pmdemand_needs_update(state)) return true; @@ -310,8 +309,7 @@ static bool intel_pmdemand_needs_update(struct intel_atomic_state *state) if (intel_cdclk_pmdemand_needs_update(state)) return true; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) if (new_crtc_state->port_clock != old_crtc_state->port_clock) return true; diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 1b09992ce9fd..e03b5daac5be 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -94,12 +94,10 @@ bool intel_vrr_possible(const struct intel_crtc_state *crtc_state) void intel_vrr_check_modeset(struct intel_atomic_state *state) { - int i; struct intel_crtc_state *old_crtc_state, *new_crtc_state; struct intel_crtc *crtc; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { if (new_crtc_state->uapi.vrr_enabled != old_crtc_state->uapi.vrr_enabled) new_crtc_state->uapi.mode_changed = true; diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 346e97d91d92..5a3677ea25b0 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -2495,9 +2495,9 @@ skl_compute_ddb(struct intel_atomic_state *state) struct intel_dbuf_state *new_dbuf_state = NULL; struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; - int ret, i; + int ret; - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { new_dbuf_state = intel_atomic_get_dbuf_state(state); if (IS_ERR(new_dbuf_state)) return PTR_ERR(new_dbuf_state); @@ -2561,7 +2561,7 @@ skl_compute_ddb(struct intel_atomic_state *state) str_yes_no(new_dbuf_state->joined_mbus)); } - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { enum pipe pipe = crtc->pipe; new_dbuf_state->weight[pipe] = intel_crtc_ddb_weight(new_crtc_state); @@ -2580,7 +2580,7 @@ skl_compute_ddb(struct intel_atomic_state *state) return ret; } - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { ret = skl_crtc_allocate_plane_ddb(state, crtc); if (ret) return ret; @@ -2687,13 +2687,11 @@ skl_print_wm_changes(struct intel_atomic_state *state) const struct intel_crtc_state *new_crtc_state; struct intel_plane *plane; struct intel_crtc *crtc; - int i; if (!drm_debug_enabled(DRM_UT_KMS)) return; - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state) { const struct skl_pipe_wm *old_pipe_wm, *new_pipe_wm; old_pipe_wm = &old_crtc_state->wm.skl.optimal; @@ -2833,13 +2831,13 @@ static int pkgc_max_linetime(struct intel_atomic_state *state) struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *crtc_state; struct intel_crtc *crtc; - int i, max_linetime; + int max_linetime; /* * Apparenty the hardware uses WM_LINETIME internally for * this stuff, compute everything based on that. */ - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, crtc_state) { display->pkgc.disable[crtc->pipe] = crtc_state->vrr.enable; display->pkgc.linetime[crtc->pipe] = DIV_ROUND_UP(crtc_state->linetime, 8); } @@ -2909,9 +2907,9 @@ skl_compute_wm(struct intel_atomic_state *state) struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc; struct intel_crtc_state __maybe_unused *new_crtc_state; - int ret, i; + int ret; - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { ret = skl_build_pipe_wm(state, crtc); if (ret) return ret; @@ -2926,7 +2924,7 @@ skl_compute_wm(struct intel_atomic_state *state) * based on how much ddb is available. Now we can actually * check if the final watermarks changed. */ - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) { struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal; /* From 57b68f56b4d942cedb9c8e92de628c28f5e4f832 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 May 2026 10:58:40 +0300 Subject: [PATCH 53/80] drm/i915/display: stop passing i to for_each_pipe_crtc_modeset_{enable, disable}() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor for_each_pipe_crtc_modeset_{enable,disable}() and their underlying for_each_crtc_in_masks{,_reverse}() helpers to utilize __UNIQUE_ID() to avoid having to pass the for loop variable to them. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/2270d4a10663bb55d5b16902b02798234f440517.1778659089.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_ddi.c | 8 +++--- drivers/gpu/drm/i915/display/intel_display.c | 12 ++++----- drivers/gpu/drm/i915/display/intel_display.h | 28 ++++++++++---------- drivers/gpu/drm/i915/display/intel_dp_mst.c | 9 +++---- 4 files changed, 26 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index ad6b28e78cc5..205978c9feb6 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3230,9 +3230,8 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state, struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_crtc *pipe_crtc; bool is_hdmi = intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI); - int i; - for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { + for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state) { const struct intel_crtc_state *old_pipe_crtc_state = intel_atomic_get_old_crtc_state(state, pipe_crtc); @@ -3259,7 +3258,7 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state, intel_ddi_disable_transcoder_func(old_crtc_state); - for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { + for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state) { const struct intel_crtc_state *old_pipe_crtc_state = intel_atomic_get_old_crtc_state(state, pipe_crtc); @@ -3516,7 +3515,6 @@ static void intel_ddi_enable(struct intel_atomic_state *state, struct intel_crtc *pipe_crtc; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; bool is_hdmi = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI); - int i; /* 128b/132b SST */ if (!is_hdmi && intel_dp_is_uhbr(crtc_state)) { @@ -3550,7 +3548,7 @@ static void intel_ddi_enable(struct intel_atomic_state *state, intel_ddi_wait_for_fec_status(encoder, crtc_state, true); - for_each_pipe_crtc_modeset_enable(display, pipe_crtc, crtc_state, i) { + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, crtc_state) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 290bbefece4a..3d91495905e8 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1654,11 +1654,10 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, intel_atomic_get_new_crtc_state(state, crtc); enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder; struct intel_crtc *pipe_crtc; - int i; if (drm_WARN_ON(display->drm, crtc->active)) return; - for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) { + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state) { const struct intel_crtc_state *new_pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); @@ -1672,7 +1671,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, intel_encoders_pre_enable(state, crtc); - for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) { + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); @@ -1690,7 +1689,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, if (!transcoder_is_dsi(cpu_transcoder)) hsw_configure_cpu_transcoder(new_crtc_state); - for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) { + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); @@ -1720,7 +1719,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, intel_encoders_enable(state, crtc); - for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) { + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); enum pipe hsw_workaround_pipe; @@ -1788,7 +1787,6 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc *pipe_crtc; - int i; /* * FIXME collapse everything to one hook. @@ -1801,7 +1799,7 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_encoders_post_pll_disable(state, crtc); - for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { + for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state) { const struct intel_crtc_state *old_pipe_crtc_state = intel_atomic_get_old_crtc_state(state, pipe_crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index a24d16d02f96..1963dbc80221 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -325,29 +325,29 @@ enum phy_fia { ((connector) = to_intel_connector((__state)->base.connectors[__i].ptr), \ (new_connector_state) = to_intel_digital_connector_state((__state)->base.connectors[__i].new_state), 1)) -#define for_each_crtc_in_masks(display, crtc, first_pipes, second_pipes, i) \ - for ((i) = 0; \ +#define __for_each_crtc_in_masks(display, crtc, first_pipes, second_pipes, i) \ + for (int (i) = 0; \ (i) < (I915_MAX_PIPES * 2) && ((crtc) = intel_crtc_for_pipe(display, (i) % I915_MAX_PIPES), 1); \ (i)++) \ for_each_if((crtc) && ((first_pipes) | ((second_pipes) << I915_MAX_PIPES)) & BIT(i)) -#define for_each_crtc_in_masks_reverse(display, crtc, first_pipes, second_pipes, i) \ - for ((i) = (I915_MAX_PIPES * 2 - 1); \ +#define __for_each_crtc_in_masks_reverse(display, crtc, first_pipes, second_pipes, i) \ + for (int (i) = (I915_MAX_PIPES * 2 - 1); \ (i) >= 0 && ((crtc) = intel_crtc_for_pipe(display, (i) % I915_MAX_PIPES), 1); \ (i)--) \ for_each_if((crtc) && ((first_pipes) | ((second_pipes) << I915_MAX_PIPES)) & BIT(i)) -#define for_each_pipe_crtc_modeset_disable(display, crtc, crtc_state, i) \ - for_each_crtc_in_masks(display, crtc, \ - _intel_modeset_primary_pipes(crtc_state), \ - _intel_modeset_secondary_pipes(crtc_state), \ - i) +#define for_each_pipe_crtc_modeset_disable(display, crtc, crtc_state) \ + __for_each_crtc_in_masks(display, crtc, \ + _intel_modeset_primary_pipes(crtc_state), \ + _intel_modeset_secondary_pipes(crtc_state), \ + __UNIQUE_ID(i)) -#define for_each_pipe_crtc_modeset_enable(display, crtc, crtc_state, i) \ - for_each_crtc_in_masks_reverse(display, crtc, \ - _intel_modeset_primary_pipes(crtc_state), \ - _intel_modeset_secondary_pipes(crtc_state), \ - i) +#define for_each_pipe_crtc_modeset_enable(display, crtc, crtc_state) \ + __for_each_crtc_in_masks_reverse(display, crtc, \ + _intel_modeset_primary_pipes(crtc_state), \ + _intel_modeset_secondary_pipes(crtc_state), \ + __UNIQUE_ID(i)) int intel_atomic_check(struct drm_device *dev, struct drm_atomic_commit *state); u8 intel_calc_enabled_pipes(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index be8febe3d234..724d3ee23350 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1065,14 +1065,13 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, drm_atomic_get_mst_payload_state(new_mst_state, connector->mst.port); struct intel_crtc *pipe_crtc; bool last_mst_stream; - int i; last_mst_stream = intel_dp_mst_dec_active_streams(intel_dp); drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && last_mst_stream && !intel_dp_mst_is_master_trans(old_crtc_state)); - for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { + for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state) { const struct intel_crtc_state *old_pipe_crtc_state = intel_atomic_get_old_crtc_state(state, pipe_crtc); @@ -1099,7 +1098,7 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, intel_ddi_disable_transcoder_func(old_crtc_state); - for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { + for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state) { const struct intel_crtc_state *old_pipe_crtc_state = intel_atomic_get_old_crtc_state(state, pipe_crtc); @@ -1310,7 +1309,7 @@ static void mst_stream_enable(struct intel_atomic_state *state, enum transcoder trans = pipe_config->cpu_transcoder; bool first_mst_stream = intel_dp_mst_active_streams(intel_dp) == 1; struct intel_crtc *pipe_crtc; - int ret, i; + int ret; drm_WARN_ON(display->drm, pipe_config->has_pch_encoder); @@ -1355,7 +1354,7 @@ static void mst_stream_enable(struct intel_atomic_state *state, intel_enable_transcoder(pipe_config); - for_each_pipe_crtc_modeset_enable(display, pipe_crtc, pipe_config, i) { + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, pipe_config) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); From 1bef2dea0c1347bcb6bdd96acbb716eb15f508da Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 26 May 2026 15:55:57 +0300 Subject: [PATCH 54/80] drm/i915/power: make intel_power_domains_{suspend, resume}() static intel_power_domains_suspend() and intel_power_domains_resume() are only used inside intel_display_power.c. Make them static. Cc: Imre Deak Reviewed-by: Imre Deak Link: https://patch.msgid.link/bfb5f09794b6b5035839d0182d22980119da2165.1779800132.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_power.c | 4 ++-- drivers/gpu/drm/i915/display/intel_display_power.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index f2f028bdd0aa..8bf770a6a483 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -2094,7 +2094,7 @@ void intel_power_domains_disable(struct intel_display *display) * It must be called with power domains already disabled (after a call to * intel_power_domains_disable()) and paired with intel_power_domains_resume(). */ -void intel_power_domains_suspend(struct intel_display *display, bool s2idle) +static void intel_power_domains_suspend(struct intel_display *display, bool s2idle) { struct i915_power_domains *power_domains = &display->power.domains; struct ref_tracker *wakeref __maybe_unused = @@ -2147,7 +2147,7 @@ void intel_power_domains_suspend(struct intel_display *display, bool s2idle) * intel_power_domains_enable()) and must be paired with * intel_power_domains_suspend(). */ -void intel_power_domains_resume(struct intel_display *display) +static void intel_power_domains_resume(struct intel_display *display) { struct i915_power_domains *power_domains = &display->power.domains; diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index d616d5d09cbe..14806455c29e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -175,8 +175,6 @@ void intel_power_domains_init_hw(struct intel_display *display, bool resume); void intel_power_domains_driver_remove(struct intel_display *display); void intel_power_domains_enable(struct intel_display *display); void intel_power_domains_disable(struct intel_display *display); -void intel_power_domains_suspend(struct intel_display *display, bool s2idle); -void intel_power_domains_resume(struct intel_display *display); void intel_power_domains_sanitize_state(struct intel_display *display); void intel_display_power_suspend_late(struct intel_display *display, bool s2idle); From ad5190d6f35db62fba97a63872e3b2b4cf546782 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 26 May 2026 15:55:58 +0300 Subject: [PATCH 55/80] drm/i915/power: rename intel_power_domains_*() to intel_display_power_*() It's confusing that intel_display_power.[ch] exposes two groups of interfaces, one named intel_power_domains_*() and one intel_display_power_*(). Unify on the latter, based on the file name, but also because it's more generic. This makes the caller side easier to follow. Cc: Imre Deak Reviewed-by: Imre Deak Link: https://patch.msgid.link/8fae4b0e3476aeffb0164215b7e0f0ae1d825f72.1779800132.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_driver.c | 8 +-- .../drm/i915/display/intel_display_power.c | 50 +++++++++---------- .../drm/i915/display/intel_display_power.h | 14 +++--- .../drm/i915/display/intel_modeset_setup.c | 2 +- drivers/gpu/drm/i915/i915_driver.c | 14 +++--- drivers/gpu/drm/i915/intel_runtime_pm.c | 2 +- drivers/gpu/drm/xe/display/xe_display.c | 20 ++++---- 7 files changed, 55 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 8e6c3dfab5c0..6b7411f5c6a8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -212,13 +212,13 @@ int intel_display_driver_probe_noirq(struct intel_display *display) intel_psr_dc5_dc6_wa_init(display); /* FIXME: completely on the wrong abstraction layer */ - ret = intel_power_domains_init(display); + ret = intel_display_power_init(display); if (ret < 0) goto cleanup_bios; intel_pmdemand_init_early(display); - intel_power_domains_init_hw(display, false); + intel_display_power_init_hw(display, false); if (!HAS_DISPLAY(display)) return 0; @@ -300,7 +300,7 @@ int intel_display_driver_probe_noirq(struct intel_display *display) destroy_workqueue(display->hotplug.dp_wq); cleanup_pw_domain_dmc: intel_dmc_fini(display); - intel_power_domains_driver_remove(display); + intel_display_power_driver_remove(display); cleanup_bios: intel_bios_driver_remove(display); @@ -641,7 +641,7 @@ void intel_display_driver_remove_nogem(struct intel_display *display) { intel_dmc_fini(display); - intel_power_domains_driver_remove(display); + intel_display_power_driver_remove(display); intel_bios_driver_remove(display); } diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 8bf770a6a483..ae7e65a4ec8c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1018,13 +1018,13 @@ static u32 get_allowed_dc_mask(struct intel_display *display, int enable_dc) } /** - * intel_power_domains_init - initializes the power domain structures + * intel_display_power_init - initializes the power domain structures * @display: display device instance * * Initializes the power domain structures for @display depending upon the * supported platform. */ -int intel_power_domains_init(struct intel_display *display) +int intel_display_power_init(struct intel_display *display) { struct i915_power_domains *power_domains = &display->power.domains; @@ -1045,12 +1045,12 @@ int intel_power_domains_init(struct intel_display *display) } /** - * intel_power_domains_cleanup - clean up power domains resources + * intel_display_power_cleanup - clean up power domains resources * @display: display device instance * - * Release any resources acquired by intel_power_domains_init() + * Release any resources acquired by intel_display_power_init() */ -void intel_power_domains_cleanup(struct intel_display *display) +void intel_display_power_cleanup(struct intel_display *display) { intel_display_power_map_cleanup(&display->power.domains); } @@ -1918,7 +1918,7 @@ static void assert_isp_power_gated(struct intel_display *display) static void intel_power_domains_verify_state(struct intel_display *display); /** - * intel_power_domains_init_hw - initialize hardware power domain state + * intel_display_power_init_hw - initialize hardware power domain state * @display: display device instance * @resume: Called from resume code paths or not * @@ -1930,10 +1930,10 @@ static void intel_power_domains_verify_state(struct intel_display *display); * intel_power_domains_verify_state(). * * It will return with power domains disabled (to be enabled later by - * intel_power_domains_enable()) and must be paired with - * intel_power_domains_driver_remove(). + * intel_display_power_enable()) and must be paired with + * intel_display_power_driver_remove(). */ -void intel_power_domains_init_hw(struct intel_display *display, bool resume) +void intel_display_power_init_hw(struct intel_display *display, bool resume) { struct i915_power_domains *power_domains = &display->power.domains; @@ -1967,7 +1967,7 @@ void intel_power_domains_init_hw(struct intel_display *display, bool resume) * Keep all power wells enabled for any dependent HW access during * initialization and to make sure we keep BIOS enabled display HW * resources powered until display HW readout is complete. We drop - * this reference in intel_power_domains_enable(). + * this reference in intel_display_power_enable(). */ drm_WARN_ON(display->drm, power_domains->init_wakeref); power_domains->init_wakeref = @@ -1985,17 +1985,17 @@ void intel_power_domains_init_hw(struct intel_display *display, bool resume) } /** - * intel_power_domains_driver_remove - deinitialize hw power domain state + * intel_display_power_driver_remove - deinitialize hw power domain state * @display: display device instance * * De-initializes the display power domain HW state. It also ensures that the * device stays powered up so that the driver can be reloaded. * * It must be called with power domains already disabled (after a call to - * intel_power_domains_disable()) and must be paired with - * intel_power_domains_init_hw(). + * intel_display_power_disable()) and must be paired with + * intel_display_power_init_hw(). */ -void intel_power_domains_driver_remove(struct intel_display *display) +void intel_display_power_driver_remove(struct intel_display *display) { struct ref_tracker *wakeref __maybe_unused = fetch_and_zero(&display->power.domains.init_wakeref); @@ -2014,7 +2014,7 @@ void intel_power_domains_driver_remove(struct intel_display *display) } /** - * intel_power_domains_sanitize_state - sanitize power domains state + * intel_display_power_sanitize_state - sanitize power domains state * @display: display device instance * * Sanitize the power domains state during driver loading and system resume. @@ -2023,7 +2023,7 @@ void intel_power_domains_driver_remove(struct intel_display *display) * on it by the time this function is called, after the state of all the * pipe, encoder, etc. HW resources have been sanitized). */ -void intel_power_domains_sanitize_state(struct intel_display *display) +void intel_display_power_sanitize_state(struct intel_display *display) { struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *power_well; @@ -2045,18 +2045,18 @@ void intel_power_domains_sanitize_state(struct intel_display *display) } /** - * intel_power_domains_enable - enable toggling of display power wells + * intel_display_power_enable - enable toggling of display power wells * @display: display device instance * * Enable the ondemand enabling/disabling of the display power wells. Note that * power wells not belonging to POWER_DOMAIN_INIT are allowed to be toggled * only at specific points of the display modeset sequence, thus they are not - * affected by the intel_power_domains_enable()/disable() calls. The purpose + * affected by the intel_display_power_enable()/disable() calls. The purpose * of these function is to keep the rest of power wells enabled until the end * of display HW readout (which will acquire the power references reflecting * the current HW state). */ -void intel_power_domains_enable(struct intel_display *display) +void intel_display_power_enable(struct intel_display *display) { struct ref_tracker *wakeref __maybe_unused = fetch_and_zero(&display->power.domains.init_wakeref); @@ -2066,13 +2066,13 @@ void intel_power_domains_enable(struct intel_display *display) } /** - * intel_power_domains_disable - disable toggling of display power wells + * intel_display_power_disable - disable toggling of display power wells * @display: display device instance * * Disable the ondemand enabling/disabling of the display power wells. See - * intel_power_domains_enable() for which power wells this call controls. + * intel_display_power_enable() for which power wells this call controls. */ -void intel_power_domains_disable(struct intel_display *display) +void intel_display_power_disable(struct intel_display *display) { struct i915_power_domains *power_domains = &display->power.domains; @@ -2092,7 +2092,7 @@ void intel_power_domains_disable(struct intel_display *display) * system suspend. * * It must be called with power domains already disabled (after a call to - * intel_power_domains_disable()) and paired with intel_power_domains_resume(). + * intel_display_power_disable()) and paired with intel_power_domains_resume(). */ static void intel_power_domains_suspend(struct intel_display *display, bool s2idle) { @@ -2144,7 +2144,7 @@ static void intel_power_domains_suspend(struct intel_display *display, bool s2id * This function resume the hardware power domain state during system resume. * * It will return with power domain support disabled (to be enabled later by - * intel_power_domains_enable()) and must be paired with + * intel_display_power_enable()) and must be paired with * intel_power_domains_suspend(). */ static void intel_power_domains_resume(struct intel_display *display) @@ -2152,7 +2152,7 @@ static void intel_power_domains_resume(struct intel_display *display) struct i915_power_domains *power_domains = &display->power.domains; if (power_domains->display_core_suspended) { - intel_power_domains_init_hw(display, true); + intel_display_power_init_hw(display, true); power_domains->display_core_suspended = false; } else { drm_WARN_ON(display->drm, power_domains->init_wakeref); diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 14806455c29e..be051911514f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -169,13 +169,13 @@ struct intel_display_power_domain_set { for ((__domain) = 0; (__domain) < POWER_DOMAIN_NUM; (__domain)++) \ for_each_if(test_bit((__domain), (__mask)->bits)) -int intel_power_domains_init(struct intel_display *display); -void intel_power_domains_cleanup(struct intel_display *display); -void intel_power_domains_init_hw(struct intel_display *display, bool resume); -void intel_power_domains_driver_remove(struct intel_display *display); -void intel_power_domains_enable(struct intel_display *display); -void intel_power_domains_disable(struct intel_display *display); -void intel_power_domains_sanitize_state(struct intel_display *display); +int intel_display_power_init(struct intel_display *display); +void intel_display_power_cleanup(struct intel_display *display); +void intel_display_power_init_hw(struct intel_display *display, bool resume); +void intel_display_power_driver_remove(struct intel_display *display); +void intel_display_power_enable(struct intel_display *display); +void intel_display_power_disable(struct intel_display *display); +void intel_display_power_sanitize_state(struct intel_display *display); void intel_display_power_suspend_late(struct intel_display *display, bool s2idle); void intel_display_power_resume_early(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 6a7982551929..e8730b5baf2a 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -1011,5 +1011,5 @@ void intel_modeset_setup_hw_state(struct intel_display *display, intel_display_power_put(display, POWER_DOMAIN_INIT, wakeref); - intel_power_domains_sanitize_state(display); + intel_display_power_sanitize_state(display); } diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 7f792b537f4f..8b93bac600bf 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -297,7 +297,7 @@ static void i915_driver_late_release(struct drm_i915_private *dev_priv) struct intel_display *display = dev_priv->display; intel_irq_fini(dev_priv); - intel_power_domains_cleanup(display); + intel_display_power_cleanup(display); i915_gem_cleanup_early(dev_priv); intel_gt_driver_late_release_all(dev_priv); intel_region_ttm_device_fini(dev_priv); @@ -660,7 +660,7 @@ static int i915_driver_register(struct drm_i915_private *dev_priv) intel_display_driver_register(display); - intel_power_domains_enable(display); + intel_display_power_enable(display); intel_runtime_pm_enable(&dev_priv->runtime_pm); if (i915_switcheroo_register(dev_priv)) @@ -682,7 +682,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) i915_switcheroo_unregister(dev_priv); intel_runtime_pm_disable(&dev_priv->runtime_pm); - intel_power_domains_disable(display); + intel_display_power_disable(display); intel_display_driver_unregister(display); @@ -1043,7 +1043,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915) disable_rpm_wakeref_asserts(&i915->runtime_pm); intel_runtime_pm_disable(&i915->runtime_pm); - intel_power_domains_disable(display); + intel_display_power_disable(display); drm_client_dev_suspend(&i915->drm); if (intel_display_device_present(display)) { @@ -1079,7 +1079,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915) * - unify the driver remove and system/runtime suspend sequences with * the above unified shutdown/poweroff sequence. */ - intel_power_domains_driver_remove(display); + intel_display_power_driver_remove(display); enable_rpm_wakeref_asserts(&i915->runtime_pm); intel_runtime_pm_driver_last_release(&i915->runtime_pm); @@ -1126,7 +1126,7 @@ static int i915_drm_suspend(struct drm_device *dev) /* We do a lot of poking in a lot of registers, make sure they work * properly. */ - intel_power_domains_disable(display); + intel_display_power_disable(display); drm_client_dev_suspend(dev); if (intel_display_device_present(display)) { drm_kms_helper_poll_disable(dev); @@ -1326,7 +1326,7 @@ static int i915_drm_resume(struct drm_device *dev) drm_client_dev_resume(dev); - intel_power_domains_enable(display); + intel_display_power_enable(display); intel_gvt_resume(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index d11c2814b787..0d5b2624fe66 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -442,7 +442,7 @@ void intel_runtime_pm_put(struct intel_runtime_pm *rpm, intel_wakeref_t wref) * * Note that this function does currently not enable runtime pm for the * subordinate display power domains. That is done by - * intel_power_domains_enable(). + * intel_display_power_enable(). */ void intel_runtime_pm_enable(struct intel_runtime_pm *rpm) { diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 766811cea07d..08beaa4e89f4 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -109,7 +109,7 @@ static void xe_display_fini_early(void *arg) intel_display_driver_remove_nogem(display); intel_display_driver_remove_noirq(display); intel_opregion_cleanup(display); - intel_power_domains_cleanup(display); + intel_display_power_cleanup(display); } int xe_display_init_early(struct xe_device *xe) @@ -158,7 +158,7 @@ int xe_display_init_early(struct xe_device *xe) return devm_add_action_or_reset(xe->drm.dev, xe_display_fini_early, xe); err_noirq: intel_display_driver_remove_noirq(display); - intel_power_domains_cleanup(display); + intel_display_power_cleanup(display); err_opregion: intel_opregion_cleanup(display); return err; @@ -198,7 +198,7 @@ void xe_display_register(struct xe_device *xe) return; intel_display_driver_register(display); - intel_power_domains_enable(display); + intel_display_power_enable(display); } void xe_display_unregister(struct xe_device *xe) @@ -208,7 +208,7 @@ void xe_display_unregister(struct xe_device *xe) if (!xe->info.probe_display) return; - intel_power_domains_disable(display); + intel_display_power_disable(display); intel_display_driver_unregister(display); } @@ -276,7 +276,7 @@ static void xe_display_enable_d3cold(struct xe_device *xe) * We do a lot of poking in a lot of registers, make sure they work * properly. */ - intel_power_domains_disable(display); + intel_display_power_disable(display); intel_display_flush_cleanup_work(display); @@ -309,7 +309,7 @@ static void xe_display_disable_d3cold(struct xe_device *xe) intel_opregion_resume(display); - intel_power_domains_enable(display); + intel_display_power_enable(display); } void xe_display_pm_suspend(struct xe_device *xe) @@ -324,7 +324,7 @@ void xe_display_pm_suspend(struct xe_device *xe) * We do a lot of poking in a lot of registers, make sure they work * properly. */ - intel_power_domains_disable(display); + intel_display_power_disable(display); drm_client_dev_suspend(&xe->drm); if (intel_display_device_present(display)) { @@ -356,7 +356,7 @@ void xe_display_pm_shutdown(struct xe_device *xe) if (!xe->info.probe_display) return; - intel_power_domains_disable(display); + intel_display_power_disable(display); drm_client_dev_suspend(&xe->drm); if (intel_display_device_present(display)) { @@ -437,7 +437,7 @@ void xe_display_pm_shutdown_late(struct xe_device *xe) * for now leaving all display power wells in the INIT power domain * enabled. */ - intel_power_domains_driver_remove(display); + intel_display_power_driver_remove(display); } void xe_display_pm_resume_early(struct xe_device *xe) @@ -484,7 +484,7 @@ void xe_display_pm_resume(struct xe_device *xe) drm_client_dev_resume(&xe->drm); - intel_power_domains_enable(display); + intel_display_power_enable(display); } void xe_display_pm_runtime_resume(struct xe_device *xe) From 771394b4fb6d7d8be5a90228cea53affd20617f5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 26 May 2026 15:55:59 +0300 Subject: [PATCH 56/80] drm/i915/power: drop resume parameter from intel_display_power_init_hw() intel_power_domains_resume() calling intel_display_power_init_hw() with the resume parameter is an internal implementation detail. Hide it inside intel_display_power.c, and provide a clean external interface without the parameter. Cc: Imre Deak Reviewed-by: Imre Deak Link: https://patch.msgid.link/63666514d457f548c69ccd35c02f2b8200ca08a1.1779800132.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_driver.c | 2 +- .../drm/i915/display/intel_display_power.c | 40 ++++++++++--------- .../drm/i915/display/intel_display_power.h | 2 +- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 6b7411f5c6a8..d0729936f681 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -218,7 +218,7 @@ int intel_display_driver_probe_noirq(struct intel_display *display) intel_pmdemand_init_early(display); - intel_display_power_init_hw(display, false); + intel_display_power_init_hw(display); if (!HAS_DISPLAY(display)) return 0; diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index ae7e65a4ec8c..b2dcfeedbd2c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1917,23 +1917,7 @@ static void assert_isp_power_gated(struct intel_display *display) static void intel_power_domains_verify_state(struct intel_display *display); -/** - * intel_display_power_init_hw - initialize hardware power domain state - * @display: display device instance - * @resume: Called from resume code paths or not - * - * This function initializes the hardware power domain state and enables all - * power wells belonging to the INIT power domain. Power wells in other - * domains (and not in the INIT domain) are referenced or disabled by - * intel_modeset_readout_hw_state(). After that the reference count of each - * power well must match its HW enabled state, see - * intel_power_domains_verify_state(). - * - * It will return with power domains disabled (to be enabled later by - * intel_display_power_enable()) and must be paired with - * intel_display_power_driver_remove(). - */ -void intel_display_power_init_hw(struct intel_display *display, bool resume) +static void __intel_display_power_init_hw(struct intel_display *display, bool resume) { struct i915_power_domains *power_domains = &display->power.domains; @@ -1984,6 +1968,26 @@ void intel_display_power_init_hw(struct intel_display *display, bool resume) power_domains->initializing = false; } +/** + * intel_display_power_init_hw - initialize hardware power domain state + * @display: display device instance + * + * This function initializes the hardware power domain state and enables all + * power wells belonging to the INIT power domain. Power wells in other + * domains (and not in the INIT domain) are referenced or disabled by + * intel_modeset_readout_hw_state(). After that the reference count of each + * power well must match its HW enabled state, see + * intel_power_domains_verify_state(). + * + * It will return with power domains disabled (to be enabled later by + * intel_display_power_enable()) and must be paired with + * intel_display_power_driver_remove(). + */ +void intel_display_power_init_hw(struct intel_display *display) +{ + __intel_display_power_init_hw(display, false); +} + /** * intel_display_power_driver_remove - deinitialize hw power domain state * @display: display device instance @@ -2152,7 +2156,7 @@ static void intel_power_domains_resume(struct intel_display *display) struct i915_power_domains *power_domains = &display->power.domains; if (power_domains->display_core_suspended) { - intel_display_power_init_hw(display, true); + __intel_display_power_init_hw(display, true); power_domains->display_core_suspended = false; } else { drm_WARN_ON(display->drm, power_domains->init_wakeref); diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index be051911514f..a43fab19e530 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -171,7 +171,7 @@ struct intel_display_power_domain_set { int intel_display_power_init(struct intel_display *display); void intel_display_power_cleanup(struct intel_display *display); -void intel_display_power_init_hw(struct intel_display *display, bool resume); +void intel_display_power_init_hw(struct intel_display *display); void intel_display_power_driver_remove(struct intel_display *display); void intel_display_power_enable(struct intel_display *display); void intel_display_power_disable(struct intel_display *display); From 85bfe1cec2d1fb67db2bd8603df391466f4ae29f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 May 2026 23:03:37 +0300 Subject: [PATCH 57/80] drm/i915/bw: Fix num_planes handling on TGL+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TGL+ bw code has an off by one error on the num_planes calculation, and tgl_max_bw_index() incorrectly bumps the num_planes to 1 from 0. That approach made sense on ICL where num_planes is more or less a minimum number of planes to consider for the group, but on TGL+ num_planes really is a maximum number of planes, so these adjustments no longer make any sense there. Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260522200346.17377-2-ville.syrjala@linux.intel.com Reviewed-by: Michał Grzelak --- drivers/gpu/drm/i915/display/intel_bw.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index d5aac5abea6f..c7b59cad176a 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -636,8 +636,7 @@ static int tgl_get_bw_info(struct intel_display *display, bi_next = &display->bw.max[i + 1]; if (clpchgroup < clperchgroup) - bi_next->num_planes = (ipqdepth - clpchgroup) / - clpchgroup + 1; + bi_next->num_planes = (ipqdepth - clpchgroup) / clpchgroup; else bi_next->num_planes = 0; } @@ -802,11 +801,6 @@ static unsigned int tgl_max_bw_index(struct intel_display *display, { int i; - /* - * Let's return max bw for 0 planes - */ - num_planes = max(1, num_planes); - for (i = ARRAY_SIZE(display->bw.max) - 1; i >= 0; i--) { const struct intel_bw_info *bi = &display->bw.max[i]; From 1f0d572b27ad43982bbba9854513311f1cfa55eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 May 2026 23:03:38 +0300 Subject: [PATCH 58/80] drm/i915/bw: Fix DCLK rounding mess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix up the total mess when calculating the DCLK frequency. Some codepaths are trying to do both DIV_ROUND_UP() and an open coded "round to nearest" at the same time. The MTL+ codepath was the only one that was correct (using DIV_ROUND_CLOSEST()). Let's unify all of them, and borrow the actual '100/6' approach from adl_calc_psf_bw() so that we get even less rounding errors. Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260522200346.17377-3-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 26 +++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index c7b59cad176a..0530eb68aade 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -67,25 +67,31 @@ struct intel_qgv_info { u8 deinterleave; }; +static int dclk_freq_mhz(int ratio) +{ + /* multiple of 16.666 MHz (100/6) */ + return DIV_ROUND_CLOSEST(ratio * 100, 6); +} + static int dg1_mchbar_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { - u32 dclk_ratio, dclk_reference; + u32 dclk_ratio; u32 val; val = intel_mchbar_read(display, SA_PERF_STATUS_0_0_0_MCHBAR_PC); dclk_ratio = REG_FIELD_GET(DG1_QCLK_RATIO_MASK, val); if (val & DG1_QCLK_REFERENCE) - dclk_reference = 6; /* 6 * 16.666 MHz = 100 MHz */ + dclk_ratio *= 6; /* 6 * 16.666 MHz = 100 MHz */ else - dclk_reference = 8; /* 8 * 16.666 MHz = 133 MHz */ - sp->dclk = DIV_ROUND_UP((16667 * dclk_ratio * dclk_reference) + 500, 1000); + dclk_ratio *= 8; /* 8 * 16.666 MHz = 133 MHz */ val = intel_mchbar_read(display, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU); if (val & DG1_GEAR_TYPE) - sp->dclk *= 2; + dclk_ratio *= 2; + sp->dclk = dclk_freq_mhz(dclk_ratio); if (sp->dclk == 0) return -EINVAL; @@ -107,7 +113,6 @@ static int icl_pcode_read_qgv_point_info(struct intel_display *display, int point) { u32 val = 0, val2 = 0; - u16 dclk; int ret; ret = intel_parent_pcode_read(display, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | @@ -116,9 +121,7 @@ static int icl_pcode_read_qgv_point_info(struct intel_display *display, if (ret) return ret; - dclk = val & 0xffff; - sp->dclk = DIV_ROUND_UP((16667 * dclk) + (DISPLAY_VER(display) >= 12 ? 500 : 0), - 1000); + sp->dclk = dclk_freq_mhz(val & 0xffff); sp->t_rp = (val & 0xff0000) >> 16; sp->t_rcd = (val & 0xff000000) >> 24; @@ -208,12 +211,11 @@ static int mtl_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { u32 val, val2; - u16 dclk; val = intel_de_read(display, MTL_MEM_SS_INFO_QGV_POINT_LOW(point)); val2 = intel_de_read(display, MTL_MEM_SS_INFO_QGV_POINT_HIGH(point)); - dclk = REG_FIELD_GET(MTL_DCLK_MASK, val); - sp->dclk = DIV_ROUND_CLOSEST(16667 * dclk, 1000); + + sp->dclk = dclk_freq_mhz(REG_FIELD_GET(MTL_DCLK_MASK, val)); sp->t_rp = REG_FIELD_GET(MTL_TRP_MASK, val); sp->t_rcd = REG_FIELD_GET(MTL_TRCD_MASK, val); From 615b23a7d2a8e75a48ed04c6ff129809a817cf3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 May 2026 23:03:39 +0300 Subject: [PATCH 59/80] drm/i915/bw: Fix bw rounding direction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DRAM bandwidth value should be rounded down, not up. Bspec: 64631 Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260522200346.17377-4-ville.syrjala@linux.intel.com Reviewed-by: Michał Grzelak Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 0530eb68aade..76aab2965858 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -555,7 +555,7 @@ static int icl_get_bw_info(struct intel_display *display, */ ct = max_t(int, sp->t_rc, sp->t_rp + sp->t_rcd + (clpchgroup - 1) * qi.t_bl + sp->t_rdpre); - bw = DIV_ROUND_UP(sp->dclk * clpchgroup * 32 * num_channels, ct); + bw = sp->dclk * clpchgroup * 32 * num_channels / ct; bi->deratedbw[j] = min(maxdebw, bw * (100 - soc_bw_params->derating) / 100); @@ -658,7 +658,7 @@ static int tgl_get_bw_info(struct intel_display *display, */ ct = max_t(int, sp->t_rc, sp->t_rp + sp->t_rcd + (clpchgroup - 1) * qi.t_bl + sp->t_rdpre); - bw = DIV_ROUND_UP(sp->dclk * clpchgroup * 32 * num_channels, ct); + bw = sp->dclk * clpchgroup * 32 * num_channels / ct; bi->deratedbw[j] = min(maxdebw, bw * (100 - soc_bw_params->derating) / 100); From 67309d7fbe2084d5470e46754be9e4ff26068d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 May 2026 23:03:40 +0300 Subject: [PATCH 60/80] drm/i915/bw: Fix 'deinterleave' rounding direction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some reason we're rounding up when calculating the deinterleave value. But the spec says we should round down. Fix it. But I suppose this doesn't actually matter since the deinterleave values should always be power of two. The only exception is therefore the deinterleave==1 case, which gets handled by the max(..., 1). Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260522200346.17377-5-ville.syrjala@linux.intel.com Reviewed-by: Michał Grzelak --- drivers/gpu/drm/i915/display/intel_bw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 76aab2965858..65f626b1a90e 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -607,7 +607,7 @@ static int tgl_get_bw_info(struct intel_display *display, qi.deinterleave = qi.deinterleave ? : DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); if (num_channels < qi.max_numchannels && DISPLAY_VER(display) >= 12) - qi.deinterleave = max(DIV_ROUND_UP(qi.deinterleave, 2), 1); + qi.deinterleave = max(qi.deinterleave / 2, 1); if (DISPLAY_VER(display) >= 12 && num_channels > qi.max_numchannels) drm_warn(display->drm, "Number of channels exceeds max number of channels."); From ee0421aad3273b29151461bf684c492581dcbb27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 May 2026 23:03:41 +0300 Subject: [PATCH 61/80] drm/i915/bw: Fix rounding direction in clperchgroup calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The '8/num_channels' in the clperchgroup is supposed to be rounded down according to the spec. Make it so. Not sure we can ever actually have a non-power of two number of channels, so this might not matter. Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260522200346.17377-6-ville.syrjala@linux.intel.com Reviewed-by: Michał Grzelak --- drivers/gpu/drm/i915/display/intel_bw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 65f626b1a90e..53e83eb1a425 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -624,7 +624,7 @@ static int tgl_get_bw_info(struct intel_display *display, * clperchgroup = 4kpagespermempage * clperchperblock, * clperchperblock = 8 / num_channels * interleave */ - clperchgroup = 4 * DIV_ROUND_UP(8, num_channels) * qi.deinterleave; + clperchgroup = 4 * (8 / num_channels) * qi.deinterleave; for (i = 0; i < num_groups; i++) { struct intel_bw_info *bi = &display->bw.max[i]; From 7ceffa346ee993796cb207a60b8d33e9674c80e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 May 2026 23:03:42 +0300 Subject: [PATCH 62/80] drm/i915/bw: Fix DEPROGBWPCLIMIT handling on BMG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DEPROGBWPCLIMIT is specified in %, so divide by 100 instead of 10. Fortunately the deprobbwlimit is much lower than the peak memory bandwidth on BMG, so whether we take 60% or 600% of the peak bandwidth doesn't matter as the min() will pick the lower deprobbwlimit anyway. Eg. on the BMG here I get (with or without the fix): QGV 0: deratedbw=33600 peakbw=48000 QGV 1: deratedbw=53000 peakbw=456000 Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260522200346.17377-7-ville.syrjala@linux.intel.com Reviewed-by: Michał Grzelak --- drivers/gpu/drm/i915/display/intel_bw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 53e83eb1a425..6ebf33e6e343 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -738,7 +738,7 @@ static int xe2_hpd_get_bw_info(struct intel_display *display, } peakbw = num_channels * qi.channel_width / 8 * icl_sagv_max_dclk(&qi); - maxdebw = min(soc_bw_params->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 10); + maxdebw = min(soc_bw_params->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100); for (i = 0; i < qi.num_points; i++) { const struct intel_qgv_point *point = &qi.points[i]; From 9b85fe7e7b0f347a1d39984c086d9ba3d1aa39fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 May 2026 23:03:43 +0300 Subject: [PATCH 63/80] drm/i915/bw: Fix/unify peakbw calculations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have several copies of the same memory peak bandwidth calculations, and the rounding directions are all over the place in some of them. Unify it all into one small function (with rounding matching what Bspec says). Note that 'channel_width' is always a multiple of 8 anyway, so for 'channel_width / 8' the rounding direction doesn't actually matter. Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260522200346.17377-8-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 6ebf33e6e343..f1af6f2f7d4c 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -578,6 +578,11 @@ static int icl_get_bw_info(struct intel_display *display, return 0; } +static int tgl_peakbw(int num_channels, int channel_width, int dclk) +{ + return num_channels * (channel_width / 8) * dclk; +} + static int tgl_get_bw_info(struct intel_display *display, const struct dram_info *dram_info, const struct intel_soc_bw_params *soc_bw_params, @@ -587,7 +592,6 @@ static int tgl_get_bw_info(struct intel_display *display, bool is_y_tile = true; /* assume y tile may be used */ int num_channels = max_t(u8, 1, dram_info->num_channels); int ipqdepth, ipqdepthpch = 16; - int dclk_max; int maxdebw, peakbw; int clperchgroup; int num_groups = ARRAY_SIZE(display->bw.max); @@ -614,9 +618,7 @@ static int tgl_get_bw_info(struct intel_display *display, if (qi.max_numchannels != 0) num_channels = min_t(u8, num_channels, qi.max_numchannels); - dclk_max = icl_sagv_max_dclk(&qi); - - peakbw = num_channels * DIV_ROUND_UP(qi.channel_width, 8) * dclk_max; + peakbw = tgl_peakbw(num_channels, qi.channel_width, icl_sagv_max_dclk(&qi)); maxdebw = min(soc_bw_params->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100); ipqdepth = min(ipqdepthpch, display_bw_params->displayrtids / num_channels); @@ -662,9 +664,7 @@ static int tgl_get_bw_info(struct intel_display *display, bi->deratedbw[j] = min(maxdebw, bw * (100 - soc_bw_params->derating) / 100); - bi->peakbw[j] = DIV_ROUND_CLOSEST(sp->dclk * - num_channels * - qi.channel_width, 8); + bi->peakbw[j] = tgl_peakbw(num_channels, qi.channel_width, sp->dclk); drm_dbg_kms(display->drm, "BW%d / QGV %d: num_planes=%d deratedbw=%u peakbw: %u\n", @@ -737,12 +737,12 @@ static int xe2_hpd_get_bw_info(struct intel_display *display, return ret; } - peakbw = num_channels * qi.channel_width / 8 * icl_sagv_max_dclk(&qi); + peakbw = tgl_peakbw(num_channels, qi.channel_width, icl_sagv_max_dclk(&qi)); maxdebw = min(soc_bw_params->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100); for (i = 0; i < qi.num_points; i++) { - const struct intel_qgv_point *point = &qi.points[i]; - int bw = num_channels * (qi.channel_width / 8) * point->dclk; + const struct intel_qgv_point *sp = &qi.points[i]; + int bw = tgl_peakbw(num_channels, qi.channel_width, sp->dclk); display->bw.max[0].deratedbw[i] = min(maxdebw, (100 - soc_bw_params->derating) * bw / 100); From 7817373f0f3a29d62c17b4af24c684d84918ae8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 May 2026 23:03:44 +0300 Subject: [PATCH 64/80] drm/i915/bw: Round the PM demand bandwidth down MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bspec asks us to round down instead of closest doing the /100 for the PM demand bandwidth. Make it so. Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260522200346.17377-9-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index f1af6f2f7d4c..b1a2f08680d6 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -1150,7 +1150,7 @@ static int mtl_find_qgv_points(struct intel_display *display, } /* MTL PM DEMAND expects QGV BW parameter in multiples of 100 mbps */ - new_bw_state->qgv_point_peakbw = DIV_ROUND_CLOSEST(qgv_peak_bw, 100); + new_bw_state->qgv_point_peakbw = qgv_peak_bw / 100; return 0; } From 1d36507381ad3987bae3ca7c9c577ce6b5351054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 May 2026 23:03:45 +0300 Subject: [PATCH 65/80] drm/i915/bw: Remove deinterleave fallback for TGL+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the deinterleave fallback calculation from the TGL+ codepath. The fallback is using the ICL deinterleave calculation which was never in the TGL+ algorithm. All supported memory types have the correct deinterleave already specified for TGL+ anyway, so this is dead code. Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260522200346.17377-10-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index b1a2f08680d6..d0fb4ce91401 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -608,8 +608,6 @@ static int tgl_get_bw_info(struct intel_display *display, (dram_info->type == INTEL_DRAM_LPDDR4 || dram_info->type == INTEL_DRAM_LPDDR5)) num_channels *= 2; - qi.deinterleave = qi.deinterleave ? : DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); - if (num_channels < qi.max_numchannels && DISPLAY_VER(display) >= 12) qi.deinterleave = max(qi.deinterleave / 2, 1); From 2cd48d05fb677287c908555ccdcc3128ed8c55fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 May 2026 23:03:46 +0300 Subject: [PATCH 66/80] drm/i915/bw: Do not consider tile4 as tileY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For the purposes of memory bandwidth calculations tile4 should not be considered the same as tileY. Make it so. This should not actually change anything as the affected code only applies to pre-MTL integrated GPUs, which don't have tile4. Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260522200346.17377-11-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_bw.c | 29 ++++++++++++++----------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index d0fb4ce91401..dc5a5b639d87 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -240,10 +240,15 @@ intel_read_qgv_point_info(struct intel_display *display, return icl_pcode_read_qgv_point_info(display, sp, point); } +static bool is_y_tile(struct intel_display *display) +{ + /* assume Y tile may be used if supported */ + return !HAS_4TILE(display); +} + static int icl_get_qgv_points(struct intel_display *display, const struct dram_info *dram_info, - struct intel_qgv_info *qi, - bool is_y_tile) + struct intel_qgv_info *qi) { int i, ret; @@ -282,16 +287,16 @@ static int icl_get_qgv_points(struct intel_display *display, } else if (DISPLAY_VER(display) >= 12) { switch (dram_info->type) { case INTEL_DRAM_DDR4: - qi->t_bl = is_y_tile ? 8 : 4; + qi->t_bl = is_y_tile(display) ? 8 : 4; qi->max_numchannels = 2; qi->channel_width = 64; - qi->deinterleave = is_y_tile ? 1 : 2; + qi->deinterleave = is_y_tile(display) ? 1 : 2; break; case INTEL_DRAM_DDR5: - qi->t_bl = is_y_tile ? 16 : 8; + qi->t_bl = is_y_tile(display) ? 16 : 8; qi->max_numchannels = 4; qi->channel_width = 32; - qi->deinterleave = is_y_tile ? 1 : 2; + qi->deinterleave = is_y_tile(display) ? 1 : 2; break; case INTEL_DRAM_LPDDR4: if (display->platform.rocketlake) { @@ -306,7 +311,7 @@ static int icl_get_qgv_points(struct intel_display *display, qi->t_bl = 16; qi->max_numchannels = 8; qi->channel_width = 16; - qi->deinterleave = is_y_tile ? 2 : 4; + qi->deinterleave = is_y_tile(display) ? 2 : 4; break; default: qi->t_bl = 16; @@ -512,7 +517,6 @@ static int icl_get_bw_info(struct intel_display *display, const struct intel_display_bw_params *display_bw_params) { struct intel_qgv_info qi = {}; - bool is_y_tile = true; /* assume y tile may be used */ int num_channels = max_t(u8, 1, dram_info->num_channels); int ipqdepth, ipqdepthpch = 16; int dclk_max; @@ -520,7 +524,7 @@ static int icl_get_bw_info(struct intel_display *display, int num_groups = ARRAY_SIZE(display->bw.max); int i, ret; - ret = icl_get_qgv_points(display, dram_info, &qi, is_y_tile); + ret = icl_get_qgv_points(display, dram_info, &qi); if (ret) { drm_dbg_kms(display->drm, "Failed to get memory subsystem information, ignoring bandwidth limits"); @@ -530,7 +534,7 @@ static int icl_get_bw_info(struct intel_display *display, dclk_max = icl_sagv_max_dclk(&qi); maxdebw = min(soc_bw_params->deprogbwlimit * 1000, dclk_max * 16 * 6 / 10); ipqdepth = min(ipqdepthpch, display_bw_params->displayrtids / num_channels); - qi.deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); + qi.deinterleave = DIV_ROUND_UP(num_channels, is_y_tile(display) ? 4 : 2); for (i = 0; i < num_groups; i++) { struct intel_bw_info *bi = &display->bw.max[i]; @@ -589,7 +593,6 @@ static int tgl_get_bw_info(struct intel_display *display, const struct intel_display_bw_params *display_bw_params) { struct intel_qgv_info qi = {}; - bool is_y_tile = true; /* assume y tile may be used */ int num_channels = max_t(u8, 1, dram_info->num_channels); int ipqdepth, ipqdepthpch = 16; int maxdebw, peakbw; @@ -597,7 +600,7 @@ static int tgl_get_bw_info(struct intel_display *display, int num_groups = ARRAY_SIZE(display->bw.max); int i, ret; - ret = icl_get_qgv_points(display, dram_info, &qi, is_y_tile); + ret = icl_get_qgv_points(display, dram_info, &qi); if (ret) { drm_dbg_kms(display->drm, "Failed to get memory subsystem information, ignoring bandwidth limits"); @@ -728,7 +731,7 @@ static int xe2_hpd_get_bw_info(struct intel_display *display, int peakbw, maxdebw; int ret, i; - ret = icl_get_qgv_points(display, dram_info, &qi, true); + ret = icl_get_qgv_points(display, dram_info, &qi); if (ret) { drm_dbg_kms(display->drm, "Failed to get memory subsystem information, ignoring bandwidth limits"); From 638319d35eb6c0706329c312f2d586b3f56f1c9d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 27 May 2026 13:02:11 +0300 Subject: [PATCH 67/80] drm/i915/power: add "runtime" to intel_display_power_{suspend, resume}() names The intel_display_power_suspend() and intel_display_power_resume() functions are supposed to be called from the struct dev_pm_pops .runtime_suspend and .runtime_resume hook paths. Name them accordingly to intel_display_power_runtime_suspend() and intel_display_power_runtime_resume(). Cc: Imre Deak Reviewed-by: Imre Deak Link: https://patch.msgid.link/4a8ae520e3151d6cf5d9e9e3a452f620cf781ee5.1779876087.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_power.c | 4 ++-- drivers/gpu/drm/i915/display/intel_display_power.h | 5 +++-- drivers/gpu/drm/i915/i915_driver.c | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index b2dcfeedbd2c..2e51dfcd5dce 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -2289,7 +2289,7 @@ void intel_display_power_resume_early(struct intel_display *display) intel_power_domains_resume(display); } -void intel_display_power_suspend(struct intel_display *display) +void intel_display_power_runtime_suspend(struct intel_display *display) { if (DISPLAY_VER(display) >= 11) { icl_display_core_uninit(display); @@ -2302,7 +2302,7 @@ void intel_display_power_suspend(struct intel_display *display) } } -void intel_display_power_resume(struct intel_display *display) +void intel_display_power_runtime_resume(struct intel_display *display) { struct i915_power_domains *power_domains = &display->power.domains; diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index a43fab19e530..56dc89eed3f8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -179,12 +179,13 @@ void intel_display_power_sanitize_state(struct intel_display *display); void intel_display_power_suspend_late(struct intel_display *display, bool s2idle); void intel_display_power_resume_early(struct intel_display *display); -void intel_display_power_suspend(struct intel_display *display); -void intel_display_power_resume(struct intel_display *display); void intel_display_power_set_target_dc_state(struct intel_display *display, u32 state); u32 intel_display_power_get_current_dc_state(struct intel_display *display); +void intel_display_power_runtime_suspend(struct intel_display *display); +void intel_display_power_runtime_resume(struct intel_display *display); + bool intel_display_power_is_enabled(struct intel_display *display, enum intel_display_power_domain domain); struct ref_tracker *intel_display_power_get(struct intel_display *display, diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 8b93bac600bf..d6b94a29c91d 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1591,7 +1591,7 @@ static int intel_runtime_suspend(struct device *kdev) for_each_gt(gt, dev_priv, i) intel_uncore_suspend(gt->uncore); - intel_display_power_suspend(display); + intel_display_power_runtime_suspend(display); ret = vlv_suspend_complete(dev_priv); if (ret) { @@ -1685,7 +1685,7 @@ static int intel_runtime_resume(struct device *kdev) drm_dbg(&dev_priv->drm, "Unclaimed access during suspend, bios?\n"); - intel_display_power_resume(display); + intel_display_power_runtime_resume(display); ret = vlv_resume_prepare(dev_priv, true); From c1b58e57b4e51fc0efbef02feea5ebf9ba8e0091 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 27 May 2026 13:02:12 +0300 Subject: [PATCH 68/80] drm/i915: rename intel_runtime_{suspend, resume} to i915_pm_runtime_{suspend, resume} All the other struct dev_pm_ops hooks are named i915_pm_*(), but the .runtime_suspend and .runtime_resume hooks are called intel_runtime_suspend() and intel_runtime_resume(), respectively. Rename intel_runtime_suspend() to i915_pm_runtime_suspend() and intel_runtime_resume() to i915_pm_runtime_resume() to unify. Cc: Imre Deak Reviewed-by: Imre Deak Link: https://patch.msgid.link/fc5b796a3fd764a64b257edfdbe08e54b690efbc.1779876087.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_driver.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index d6b94a29c91d..58081b52461a 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1558,7 +1558,7 @@ static int i915_pm_restore(struct device *kdev) return i915_pm_resume(kdev); } -static int intel_runtime_suspend(struct device *kdev) +static int i915_pm_runtime_suspend(struct device *kdev) { struct drm_i915_private *dev_priv = kdev_to_i915(kdev); struct intel_display *display = dev_priv->display; @@ -1632,7 +1632,7 @@ static int intel_runtime_suspend(struct device *kdev) if (IS_BROADWELL(dev_priv)) { /* * On Broadwell, if we use PCI_D1 the PCH DDI ports will stop - * being detected, and the call we do at intel_runtime_resume() + * being detected, and the call we do at i915_pm_runtime_resume() * won't be able to restore them. Since PCI_D3hot matches the * actual specification and appears to be working, use it. */ @@ -1657,7 +1657,7 @@ static int intel_runtime_suspend(struct device *kdev) return 0; } -static int intel_runtime_resume(struct device *kdev) +static int i915_pm_runtime_resume(struct device *kdev) { struct drm_i915_private *dev_priv = kdev_to_i915(kdev); struct intel_display *display = dev_priv->display; @@ -1765,8 +1765,8 @@ const struct dev_pm_ops i915_pm_ops = { .restore = i915_pm_restore, /* S0ix (via runtime suspend) event handlers */ - .runtime_suspend = intel_runtime_suspend, - .runtime_resume = intel_runtime_resume, + .runtime_suspend = i915_pm_runtime_suspend, + .runtime_resume = i915_pm_runtime_resume, }; static const struct file_operations i915_driver_fops = { From c33185a35f29816bebf41f1e761e511a5db5be7d Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 27 May 2026 09:40:39 +0530 Subject: [PATCH 69/80] drm/i915/psr: Add helper to get Async Video timing support in PR active MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a helper to check if Panel Replay has Async Video Timing support during PR Active state. v2: Confirm that Panel Replay is supported before checking for Async Video Timing Support during PR active. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260527041050.601735-2-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 11 +++++++++++ drivers/gpu/drm/i915/display/intel_psr.h | 1 + 2 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 5047e3fdc9ff..138907537d03 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -4695,3 +4695,14 @@ bool intel_psr_use_trans_push(const struct intel_crtc_state *crtc_state) return HAS_PSR_TRANS_PUSH_FRAME_CHANGE(display) && crtc_state->has_psr; } + +bool intel_psr_pr_async_video_timing_supported(struct intel_dp *intel_dp) +{ + struct intel_connector *connector = intel_dp->attached_connector; + u8 *dpcd = connector->dp.panel_replay_caps.dpcd; + u8 pr_support = dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)]; + u8 pr_cap = dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)]; + + return (pr_support & DP_PANEL_REPLAY_SUPPORT) && + !(pr_cap & DP_PANEL_REPLAY_ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR); +} diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index 394b641840b3..29723e63888f 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -86,5 +86,6 @@ void intel_psr_compute_config_late(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state); int intel_psr_min_guardband(struct intel_crtc_state *crtc_state); bool intel_psr_use_trans_push(const struct intel_crtc_state *crtc_state); +bool intel_psr_pr_async_video_timing_supported(struct intel_dp *intel_dp); #endif /* __INTEL_PSR_H__ */ From 24e16c142a0c443aaa821623325c8db1a2cc788a Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 27 May 2026 09:40:40 +0530 Subject: [PATCH 70/80] drm/i915/dp: Add member to intel_dp to store AS SDP v2 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit eDP v1.5a advertises support for Adaptive Sync SDP and with that the support for AS SDP v2 is mandatory. DP v2.1 SCR advertises support for FAVT payload fields parsing in DPCD 0x2214 Bit 2. This indicates the support for Adaptive-Sync SDP version 2 (AS SDP v2), which allows the source to set the version in HB2[4:0] and the payload length in HB3[5:0] of the AS SDP header. DP v2.1 SCR also introduces ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR in the Panel Replay Capability DPCD 0x00b1 (Bit 3). When this bit is set, the sink does not support asynchronous video timing while in a Panel Replay Active state and the source is required to keep transmitting Adaptive-Sync SDPs. The spec mandates that such sinks shall support AS SDP v2. Infer AS SDP v2 support from these capabilities and store it in struct intel_dp for use by subsequent feature enablement changes. v2: - Include parsing ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR bit to determine AS SDP v2 support. (Ville) v3: - Use helper to determine asynch video timing support. v4: - Add AS SDP v2 support for eDP as per v1.5a. - Add a check for Panel Replay support before checking for Async video timing support in PR - Add a TODO for Display ID and PCON considerations. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260527041050.601735-3-ankit.k.nautiyal@intel.com --- .../drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 13ce37a71b68..c21e0c0ef0b1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1876,6 +1876,7 @@ struct intel_dp { /* connector directly attached - won't be use for modeset in mst world */ struct intel_connector *attached_connector; bool as_sdp_supported; + bool as_sdp_v2_supported; struct drm_dp_tunnel *tunnel; bool tunnel_suspended:1; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index f76800db03f3..10ced5efa12a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -6417,6 +6417,46 @@ intel_dp_unset_edid(struct intel_dp *intel_dp) false); } +static bool +intel_dp_sink_supports_as_sdp_v2(struct intel_dp *intel_dp) +{ + u8 rx_features; + + /* + * The DP spec does not explicitly provide the AS SDP v2 capability. + * So based on the DP v2.1 SCR, we infer it from the following bits: + * + * DP_AS_SDP_FAVT_PAYLOAD_FIELDS_PARSING_SUPPORTED indicates support for + * FAVT, which is explicitly defined to use AS SDP v2. + * + * DP_ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR indicates that the sink + * does not support asynchronous video timing while in PR Active, + * requiring the source to keep transmitting Adaptive-Sync SDPs. The + * spec mandates that such sinks shall support AS SDP v2. + * + * #TODO: Check the Adaptive-Sync DisplayID 2.1 block once DisplayID + * parsing is available. This may help detect AS SDP v2 support for + * native DP 2.1 sinks that do not expose FAVT or PR-based capability + * bits. + * + * In the presence of PCONs, check PCON support from DPCD and sink + * support from Display ID. + */ + + if (drm_dp_dpcd_read_byte(&intel_dp->aux, + DP_DPRX_FEATURE_ENUMERATION_LIST_CONT_1, + &rx_features) == 1) { + if (rx_features & DP_AS_SDP_FAVT_PAYLOAD_FIELDS_PARSING_SUPPORTED) + return true; + } + + if (intel_dp->psr.sink_panel_replay_support && + !intel_psr_pr_async_video_timing_supported(intel_dp)) + return true; + + return false; +} + static void intel_dp_detect_sdp_caps(struct intel_dp *intel_dp) { @@ -6424,6 +6464,15 @@ intel_dp_detect_sdp_caps(struct intel_dp *intel_dp) intel_dp->as_sdp_supported = HAS_AS_SDP(display) && drm_dp_as_sdp_supported(&intel_dp->aux, intel_dp->dpcd); + + if (!intel_dp->as_sdp_supported) + return; + + /* eDP Adaptive-Sync SDP always uses AS SDP v2 */ + if (intel_dp_is_edp(intel_dp)) + intel_dp->as_sdp_v2_supported = true; + else + intel_dp->as_sdp_v2_supported = intel_dp_sink_supports_as_sdp_v2(intel_dp); } static bool intel_dp_needs_dpcd_probe(struct intel_dp *intel_dp, bool force_on_external) From f0ae5307528867ce8dab8969846b7c346034d3dc Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 27 May 2026 09:40:41 +0530 Subject: [PATCH 71/80] drm/i915/dp: Allow AS SDP only if v2 is supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We do not support AS SDP version 1, so allow AS SDP only if AS SDP v2 is supported. Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260527041050.601735-4-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 10ced5efa12a..aea090cb3dae 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3210,11 +3210,11 @@ static void intel_dp_compute_vsc_colorimetry(const struct intel_crtc_state *crtc static bool intel_dp_needs_as_sdp(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { - if (!intel_dp->as_sdp_supported) + if (!intel_dp->as_sdp_v2_supported) return false; /* - * #TODO Implement AS SDP for DP branch device. + * #TODO: Add AS SDP v1 support for PCONs (DP branch devices). */ if (drm_dp_is_branch(intel_dp->dpcd)) return false; From 10228a9091437e80d5abd947b98b219983dd9052 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 27 May 2026 09:40:42 +0530 Subject: [PATCH 72/80] drm/i915/psr: Write the PR config DPCDs in burst mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the consecutive single-byte writes to PANEL_REPLAY_CONFIG and CONFIG2 with one drm_dp_dpcd_write() burst starting at PANEL_REPLAY_CONFIG, reducing AUX transactions. v2: Drop extra conditions, and optimize variables. (Ville) v3: Drop the error check after write. (Ville) Suggested-by: Ville Syrjälä Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260527041050.601735-5-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 138907537d03..ebacd3e74ad8 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -793,27 +793,27 @@ static bool psr2_su_region_et_valid(struct intel_connector *connector, bool pane static void _panel_replay_enable_sink(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { - u8 val = DP_PANEL_REPLAY_ENABLE | - DP_PANEL_REPLAY_VSC_SDP_CRC_EN | - DP_PANEL_REPLAY_UNRECOVERABLE_ERROR_EN | - DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN | - DP_PANEL_REPLAY_ACTIVE_FRAME_CRC_ERROR_EN; - u8 panel_replay_config2 = DP_PANEL_REPLAY_CRC_VERIFICATION; + u8 panel_replay_config[2]; + + panel_replay_config[0] = DP_PANEL_REPLAY_ENABLE | + DP_PANEL_REPLAY_VSC_SDP_CRC_EN | + DP_PANEL_REPLAY_UNRECOVERABLE_ERROR_EN | + DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN | + DP_PANEL_REPLAY_ACTIVE_FRAME_CRC_ERROR_EN; + panel_replay_config[1] = DP_PANEL_REPLAY_CRC_VERIFICATION; if (crtc_state->has_sel_update) - val |= DP_PANEL_REPLAY_SU_ENABLE; + panel_replay_config[0] |= DP_PANEL_REPLAY_SU_ENABLE; if (crtc_state->enable_psr2_su_region_et) - val |= DP_PANEL_REPLAY_ENABLE_SU_REGION_ET; + panel_replay_config[0] |= DP_PANEL_REPLAY_ENABLE_SU_REGION_ET; if (crtc_state->req_psr2_sdp_prior_scanline) - panel_replay_config2 |= + panel_replay_config[1] |= DP_PANEL_REPLAY_SU_REGION_SCANLINE_CAPTURE; - drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG, val); - - drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG2, - panel_replay_config2); + drm_dp_dpcd_write(&intel_dp->aux, PANEL_REPLAY_CONFIG, + panel_replay_config, sizeof(panel_replay_config)); } static void _psr_enable_sink(struct intel_dp *intel_dp, From 200bf467d4375067729744483fa3d338bb3b145d Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 27 May 2026 09:40:43 +0530 Subject: [PATCH 73/80] drm/i915/display: Add helper for AS SDP transmission time selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AS SDP may be transmitted at T1 or T2 depending on Panel Replay and Adaptive Sync SDP configuration as per DP 2.1. Current we are using T1 only, but future PR/AS SDP modes/features may require T2 or dynamic selection. Introduce a helper to return the appropriate AS SDP transmission time so that a single value is consistently used for programming PR_ALPM. For now this returns T1. v2: Avoid adding new member to crtc_state; use a helper. (Ville) v3: Clarify why AS SDP transmission time is fixed to T1. (Ville) v4: Return u8 from intel_dp_as_sdp_transmission_time(). (Ville) Bspec: 68920 Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260527041050.601735-6-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_alpm.c | 20 +++++++++++++++++++- drivers/gpu/drm/i915/display/intel_dp.c | 11 +++++++++++ drivers/gpu/drm/i915/display/intel_dp.h | 2 ++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c index a7350ce8e716..c6963ea420cc 100644 --- a/drivers/gpu/drm/i915/display/intel_alpm.c +++ b/drivers/gpu/drm/i915/display/intel_alpm.c @@ -11,6 +11,7 @@ #include "intel_crtc.h" #include "intel_de.h" #include "intel_display_types.h" +#include "intel_display_utils.h" #include "intel_dp.h" #include "intel_dp_aux.h" #include "intel_psr.h" @@ -359,6 +360,23 @@ void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp, crtc_state->has_lobf = true; } +static u32 get_pr_alpm_as_sdp_transmission_time(const struct intel_crtc_state *crtc_state) +{ + u8 as_sdp_setup_time = intel_dp_as_sdp_transmission_time(); + + switch (as_sdp_setup_time) { + case DP_PR_AS_SDP_SETUP_TIME_T1: + return PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1; + case DP_PR_AS_SDP_SETUP_TIME_DYNAMIC: + return PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1_OR_T2; + case DP_PR_AS_SDP_SETUP_TIME_T2: + return PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T2; + default: + MISSING_CASE(as_sdp_setup_time); + return PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1; + } +} + static void lnl_alpm_configure(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { @@ -382,7 +400,7 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp, ALPM_CTL_AUX_LESS_WAKE_TIME(crtc_state->alpm_state.aux_less_wake_lines); if (intel_dp->as_sdp_supported) { - u32 pr_alpm_ctl = PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1; + u32 pr_alpm_ctl = get_pr_alpm_as_sdp_transmission_time(crtc_state); if (crtc_state->link_off_after_as_sdp_when_pr_active) pr_alpm_ctl |= PR_ALPM_CTL_ALLOW_LINK_OFF_BETWEEN_AS_SDP_AND_SU; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index aea090cb3dae..53ba99f179c3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -7607,3 +7607,14 @@ bool intel_dp_joiner_candidate_valid(struct intel_connector *connector, return true; } + +u8 intel_dp_as_sdp_transmission_time(void) +{ + /* + * DP allows AS SDP position to move during PR active in some cases, but + * software-controlled refresh rate changes with DC6v / ALPM require the + * AS SDP to remain at T1. Use T1 unconditionally for now. + */ + + return DP_PR_AS_SDP_SETUP_TIME_T1; +} diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index f41480d24714..46a7f5c70981 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -241,4 +241,6 @@ bool intel_dp_joiner_candidate_valid(struct intel_connector *connector, for ((__num_joined_pipes) = 1; (__num_joined_pipes) <= (I915_MAX_PIPES); (__num_joined_pipes)++) \ for_each_if(intel_dp_joiner_candidate_valid(__connector, (__mode)->hdisplay, __num_joined_pipes)) +u8 intel_dp_as_sdp_transmission_time(void); + #endif /* __INTEL_DP_H__ */ From c3ea3fd4b4cf2dc321c7abbd81b7340577d0b4ee Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 27 May 2026 09:40:44 +0530 Subject: [PATCH 74/80] drm/i915/psr: Program Panel Replay CONFIG3 using AS SDP transmission time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Panel Replay requires the AS SDP transmission time to be written into PANEL_REPLAY_CONFIG3. This field was previously not programmed. Use the AS SDP transmission-time helper to populate CONFIG3. Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260527041050.601735-7-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index ebacd3e74ad8..e138982dc91f 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -794,6 +794,7 @@ static void _panel_replay_enable_sink(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { u8 panel_replay_config[2]; + u8 panel_replay_config_3; panel_replay_config[0] = DP_PANEL_REPLAY_ENABLE | DP_PANEL_REPLAY_VSC_SDP_CRC_EN | @@ -801,7 +802,6 @@ static void _panel_replay_enable_sink(struct intel_dp *intel_dp, DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN | DP_PANEL_REPLAY_ACTIVE_FRAME_CRC_ERROR_EN; panel_replay_config[1] = DP_PANEL_REPLAY_CRC_VERIFICATION; - if (crtc_state->has_sel_update) panel_replay_config[0] |= DP_PANEL_REPLAY_SU_ENABLE; @@ -814,6 +814,9 @@ static void _panel_replay_enable_sink(struct intel_dp *intel_dp, drm_dp_dpcd_write(&intel_dp->aux, PANEL_REPLAY_CONFIG, panel_replay_config, sizeof(panel_replay_config)); + + panel_replay_config_3 = intel_dp_as_sdp_transmission_time(); + drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG3, panel_replay_config_3); } static void _psr_enable_sink(struct intel_dp *intel_dp, From 38a7e9bf69bd2b1602c7ce8e10c2377e767076c2 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 27 May 2026 09:40:45 +0530 Subject: [PATCH 75/80] drm/i915/dp: Set relevant Downspread Ctrl DPCD bits for PR + Auxless ALPM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a Panel Replay capable sink, supports Async Video timing in PR active state, then source does not necessarily need to send AS SDPs during PR active. However, if asynchronous video timing is not supported, then for PR with Aux-less ALPM, the source must transmit Adaptive-Sync SDPs for video timing synchronization while PR is active. If the source needs to send AS SDP during PR active, this requires setting DPCD 0x0107[6] (FIXED_VTOTAL_AS_SDP_EN_IN_PR_ACTIVE). This applies whether VRR is enabled (AVT/FAVT) or fixed-timing mode is used. This bit defines AS SDP timing behavior during PR Active, even if AS SDPs are briefly suspended. Program the relevant Downspread Ctrl DPCD bits accordingly. v2: Instead of Panel Replay check simply use AS SDP enable check. (Ville) v3: Since the bit is defined in context of Panel Replay and AS SDP, add a check for both. (Ville) v4: Extract pr_with_as_sdp logic into helper function. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260527041050.601735-8-ankit.k.nautiyal@intel.com --- .../drm/i915/display/intel_dp_link_training.c | 20 +++++++++++++++++-- .../drm/i915/display/intel_dp_link_training.h | 3 ++- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index a26094223f78..e566f2b49594 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -34,8 +34,10 @@ #include "intel_dp.h" #include "intel_dp_link_training.h" #include "intel_encoder.h" +#include "intel_hdmi.h" #include "intel_hotplug.h" #include "intel_panel.h" +#include "intel_psr.h" #define LT_MSG_PREFIX "[CONNECTOR:%d:%s][ENCODER:%d:%s][%s] " #define LT_MSG_ARGS(_intel_dp, _dp_phy) (_intel_dp)->attached_connector->base.base.id, \ @@ -710,16 +712,28 @@ static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp, return true; } -void intel_dp_link_training_set_mode(struct intel_dp *intel_dp, int link_rate, bool is_vrr) +void intel_dp_link_training_set_mode(struct intel_dp *intel_dp, int link_rate, + bool is_vrr, + bool pr_with_as_sdp_enable) { u8 link_config[2]; link_config[0] = is_vrr ? DP_MSA_TIMING_PAR_IGNORE_EN : 0; + link_config[0] |= pr_with_as_sdp_enable ? DP_FIXED_VTOTAL_AS_SDP_EN_IN_PR_ACTIVE : 0; link_config[1] = drm_dp_is_uhbr_rate(link_rate) ? DP_SET_ANSI_128B132B : DP_SET_ANSI_8B10B; drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2); } +static bool +intel_dp_pr_with_as_sdp_enabled(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + return intel_psr_needs_alpm_aux_less(intel_dp, crtc_state) && + (crtc_state->infoframes.enable & + intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC)); +} + static void intel_dp_update_downspread_ctrl(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { @@ -737,7 +751,9 @@ static void intel_dp_update_downspread_ctrl(struct intel_dp *intel_dp, * especially on the first real commit when clearing the inherited flag. */ intel_dp_link_training_set_mode(intel_dp, - crtc_state->port_clock, crtc_state->vrr.in_range); + crtc_state->port_clock, + crtc_state->vrr.in_range, + intel_dp_pr_with_as_sdp_enabled(intel_dp, crtc_state)); } void intel_dp_link_training_set_bw(struct intel_dp *intel_dp, diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h index 33dcbde6a408..18c34c1a472f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h @@ -18,7 +18,8 @@ int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp); bool intel_dp_lttpr_transparent_mode_enabled(struct intel_dp *intel_dp); void intel_dp_link_training_set_mode(struct intel_dp *intel_dp, - int link_rate, bool is_vrr); + int link_rate, bool is_vrr, + bool pr_with_as_sdp_enable); void intel_dp_link_training_set_bw(struct intel_dp *intel_dp, int link_bw, int rate_select, int lane_count, bool enhanced_framing, bool post_lt_adj_req); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 724d3ee23350..bcdc50491347 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -2144,7 +2144,7 @@ void intel_dp_mst_prepare_probe(struct intel_dp *intel_dp) intel_dp_compute_rate(intel_dp, link_rate, &link_bw, &rate_select); - intel_dp_link_training_set_mode(intel_dp, link_rate, false); + intel_dp_link_training_set_mode(intel_dp, link_rate, false, false); intel_dp_link_training_set_bw(intel_dp, link_bw, rate_select, lane_count, drm_dp_enhanced_frame_cap(intel_dp->dpcd), false); From 1f41dd467333e5d6e8ee1163dd35f7086624b200 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 27 May 2026 09:40:46 +0530 Subject: [PATCH 76/80] drm/i915/dp: Program AS SDP DB[1:0] for PR with Link off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For Panel Replay with AUX-less ALPM (link-off PR), the source must send Adaptive-Sync SDP v2. Program DB[1:0] per DP spec v2.1: - VRR AVT: 00b (variable VTotal) - VRR FAVT: 10b/11b (TRR not reached/reached) - Fixed timing with PR link-off (VRR off): 01b (AS disabled; VTotal fixed) Also, drop the redundant target_rr assignment. v2: Fix the else case. (Ville) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260527041050.601735-9-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 53ba99f179c3..959e1575dffb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3249,9 +3249,10 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, as_sdp->mode = DP_AS_SDP_FAVT_TRR_REACHED; as_sdp->target_rr = drm_mode_vrefresh(adjusted_mode); as_sdp->target_rr_divider = true; - } else { + } else if (crtc_state->vrr.enable) { as_sdp->mode = DP_AS_SDP_AVT_DYNAMIC_VTOTAL; - as_sdp->target_rr = 0; + } else { + as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL; } } From 186113b419a2e5086b2148ea02646b1e2c74c6bd Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 27 May 2026 09:40:47 +0530 Subject: [PATCH 77/80] drm/i915/dp: Compute and include coasting vtotal for AS SDP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DP v2.1 allows the source to temporarily suspend Adaptive-Sync SDP transmission while Panel Replay is active when the sink supports asynchronous video timing. In such cases, the sink relies on the last transmitted AS SDP timing information to maintain the refresh rate. To support this behavior, compute and populate the coasting vtotal field in the AS SDP payload. Include coasting vtotal in AS SDP packing, unpacking, and comparison, and set it during late AS SDP configuration for PR with Aux-less ALPM when asynchronous video timing is supported. Note: The coasting vtotal value is fully under driver control i.e. the HW does not overwrite these payload bytes. HW only samples the PR_ALPM_CTL[AS SDP Transmission in Active Disable] bit during PR active state and reflects it in the AS SDP payload at the appropriate time. Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260527041050.601735-10-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 3 ++- drivers/gpu/drm/i915/display/intel_dp.c | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3d91495905e8..8e269b71f18e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4911,7 +4911,8 @@ intel_compare_dp_as_sdp(const struct drm_dp_as_sdp *a, a->duration_incr_ms == b->duration_incr_ms && a->duration_decr_ms == b->duration_decr_ms && a->target_rr_divider == b->target_rr_divider && - a->mode == b->mode; + a->mode == b->mode && + a->coasting_vtotal == b->coasting_vtotal; } static bool diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 959e1575dffb..9adf426ea110 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3254,6 +3254,22 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, } else { as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL; } + + /* + * For Panel Replay with Async Video Timing support, the source can + * disable sending the AS SDP during PR Active state. In that case, + * the sink needs the coasting vtotal value to maintain the refresh + * rate. The HW only samples this on PR_ALPM_CTL[AS SDP Transmission + * in Active Disable], which we never program, so providing the value + * unconditionally when the sink advertises the capability is safe. + * + * #TODO: + * If we ever advertise support for coasting at other refresh targets, + * this logic could be revisited. For now, use the minimum refresh rate + * as the only safe coasting value. + */ + if (intel_psr_pr_async_video_timing_supported(intel_dp)) + as_sdp->coasting_vtotal = crtc_state->vrr.vmax; } static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp, @@ -5245,6 +5261,9 @@ static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp, if (as_sdp->target_rr_divider) sdp->db[4] |= 0x20; + sdp->db[7] = as_sdp->coasting_vtotal & 0xFF; + sdp->db[8] = (as_sdp->coasting_vtotal >> 8) & 0xFF; + return length; } @@ -5429,6 +5448,7 @@ int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp, as_sdp->vtotal = (sdp->db[2] << 8) | sdp->db[1]; as_sdp->target_rr = ((sdp->db[4] & 0x3) << 8) | sdp->db[3]; as_sdp->target_rr_divider = sdp->db[4] & 0x20 ? true : false; + as_sdp->coasting_vtotal = (sdp->db[8] << 8) | sdp->db[7]; return 0; } From ae580a2d60085633693dbe6a4b7c23d0eecca1cf Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 27 May 2026 09:40:48 +0530 Subject: [PATCH 78/80] drm/i915/dp: Compute AS SDP after PSR compute config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A subsequent change makes intel_dp_needs_as_sdp() depend on crtc_state->has_panel_replay, which is set by intel_psr_compute_config(). Move call for intel_dp_compute_as_sdp() after the intel_psr_compute_config(). Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260527041050.601735-11-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 9adf426ea110..e13130bb9e9e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3744,8 +3744,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, pipe_config->dp_m_n.data_m *= pipe_config->splitter.link_count; intel_vrr_compute_config(pipe_config, conn_state); - intel_dp_compute_as_sdp(intel_dp, pipe_config); intel_psr_compute_config(intel_dp, pipe_config, conn_state); + intel_dp_compute_as_sdp(intel_dp, pipe_config); intel_alpm_lobf_compute_config(intel_dp, pipe_config, conn_state); intel_dp_drrs_compute_config(connector, pipe_config, link_bpp_x16); intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state); From 6a17120528597566afb94cd420ada471b8db286c Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 27 May 2026 09:40:49 +0530 Subject: [PATCH 79/80] drm/i915/dp: Enable AS SDP whenever VRR is possible or PR !async MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently AS SDP is only configured when VRR is enabled. With optimized guardband, we also need to account for wakeup time and other relevant details that depend on the AS SDP position whenever AS SDP is enabled. If a feature enabling AS SDP gets turned on later (after modeset), the guardband might not be sufficient and may need to increase, triggering a full modeset. Additionally, for Panel Replay with Aux-less ALPM where the sink does not support asynchronous video timing in PR active, the source must keep transmitting Adaptive-Sync SDPs while PR is active. So, always send AS SDP whenever there is a possibility to use it for VRR OR for Panel Replay for synchronization. v2: Check if AS SDP can be used for synchronization for VRR or PR. (Ville) v3: Use intel_psr_needs_alpm_aux_less() instead of intel_alpm_is_alpm_aux_less() to avoid including the LOBF case. (Ville) Modify the commit message and subject. Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260527041050.601735-12-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index e13130bb9e9e..03c2ec56ee81 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3219,7 +3219,11 @@ static bool intel_dp_needs_as_sdp(struct intel_dp *intel_dp, if (drm_dp_is_branch(intel_dp->dpcd)) return false; - return crtc_state->vrr.enable; + if (intel_psr_needs_alpm_aux_less(intel_dp, crtc_state) && + !intel_psr_pr_async_video_timing_supported(intel_dp)) + return true; + + return intel_vrr_possible(crtc_state); } static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, From 7185566c3db090aa5e17a17bca92dfcef9656b03 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 27 May 2026 09:40:50 +0530 Subject: [PATCH 80/80] drm/i915/dp: Account for AS_SDP guardband only when enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the intel_dp_sdp_min_guardband() accounts for AS_SDP for all platforms that support adaptive sync SDP even for configurations where it cannot be enabled. Instead account for adaptive sync SDP guardband only when it is enabled. Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/20260527041050.601735-13-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 03c2ec56ee81..0ce0c09835f6 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -7591,7 +7591,6 @@ int intel_dp_get_lines_for_sdp(const struct intel_crtc_state *crtc_state, u32 ty int intel_dp_sdp_min_guardband(const struct intel_crtc_state *crtc_state, bool assume_all_enabled) { - struct intel_display *display = to_intel_display(crtc_state); int sdp_guardband = 0; if (assume_all_enabled || @@ -7606,8 +7605,8 @@ int intel_dp_sdp_min_guardband(const struct intel_crtc_state *crtc_state, sdp_guardband = max(sdp_guardband, intel_dp_get_lines_for_sdp(crtc_state, DP_SDP_PPS)); - if ((assume_all_enabled && HAS_AS_SDP(display)) || - crtc_state->infoframes.enable & intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC)) + if (crtc_state->infoframes.enable & + intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC)) sdp_guardband = max(sdp_guardband, intel_dp_get_lines_for_sdp(crtc_state, DP_SDP_ADAPTIVE_SYNC));