From a61bf068f1fe359203f1af191cb523b77dc32752 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 8 Dec 2025 19:15:50 +0100 Subject: [PATCH 01/92] drm/xe: Fix ggtt fb alignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the correct alignment from intel_fb_pin_to_ggtt() down to __xe_pin_fb_vma(). Signed-off-by: Tvrtko Ursulin Reported-by: Ville Syrjälä Closes: https://lore.kernel.org/intel-xe/aNL_RgLy13fXJbYx@intel.com/ Cc: Juha-Pekka Heikkila Reviewed-by: Ville Syrjälä Fixes: b0228a337de8 ("drm/xe/display: align framebuffers according to hw requirements") Cc: # v6.13+ Signed-off-by: Thomas Hellström Link: https://patch.msgid.link/20251208181550.6618-1-tursulin@igalia.com --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 1fd4a815e784..b18d15cc3c53 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -378,7 +378,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, { *out_flags = 0; - return __xe_pin_fb_vma(to_intel_framebuffer(fb), view, phys_alignment); + return __xe_pin_fb_vma(to_intel_framebuffer(fb), view, alignment); } void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags) From 0734802d6130076fe52d3c75bc618e64048c2765 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:15 +0200 Subject: [PATCH 02/92] drm/i915: move display/intel_plane_initial.c to i915_initial_plane.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_plane_initial.c is i915 specific. Move it to i915 core. Start renaming stuff with the slightly more natural "initial plane" rather than "plane initial". Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/cdad733192690a61fbb44921c57fc68cc1cd809f.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/Makefile | 2 +- ...tel_plane_initial.c => i915_initial_plane.c} | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) rename drivers/gpu/drm/i915/{display/intel_plane_initial.c => i915_initial_plane.c} (97%) diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 801dd155d1f0..58bb7e4fad3b 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -78,6 +78,7 @@ i915-$(CONFIG_PERF_EVENTS) += \ i915-y += \ i915_display_pc8.o \ i915_hdcp_gsc.o \ + i915_initial_plane.o \ i915_panic.o # "Graphics Technology" (aka we talk to the gpu) @@ -301,7 +302,6 @@ i915-y += \ display/intel_pch_display.o \ display/intel_pch_refclk.o \ display/intel_plane.o \ - display/intel_plane_initial.o \ display/intel_pmdemand.o \ display/intel_psr.o \ display/intel_quirks.o \ diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/i915_initial_plane.c similarity index 97% rename from drivers/gpu/drm/i915/display/intel_plane_initial.c rename to drivers/gpu/drm/i915/i915_initial_plane.c index ff1afd3a8f20..87c964485a41 100644 --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -5,17 +5,18 @@ #include +#include "display/intel_crtc.h" +#include "display/intel_display.h" +#include "display/intel_display_core.h" +#include "display/intel_display_types.h" +#include "display/intel_fb.h" +#include "display/intel_frontbuffer.h" +#include "display/intel_plane.h" +#include "display/intel_plane_initial.h" #include "gem/i915_gem_lmem.h" #include "gem/i915_gem_region.h" + #include "i915_drv.h" -#include "intel_crtc.h" -#include "intel_display.h" -#include "intel_display_core.h" -#include "intel_display_types.h" -#include "intel_fb.h" -#include "intel_frontbuffer.h" -#include "intel_plane.h" -#include "intel_plane_initial.h" void intel_plane_initial_vblank_wait(struct intel_crtc *crtc) { From 6a3e94ff052963dea8585fb7d5a2bb7dcf4140c6 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:16 +0200 Subject: [PATCH 03/92] drm/xe/display: rename xe_plane_initial.c to xe_initial_plane.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow i915 with the more naturally flowing naming. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/62eb56fe348a8fe7c17333d784192da701367cc7.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/xe/Makefile | 2 +- .../drm/xe/display/{xe_plane_initial.c => xe_initial_plane.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename drivers/gpu/drm/xe/display/{xe_plane_initial.c => xe_initial_plane.c} (100%) diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 35f71dbd1bac..4af7f5562221 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -215,8 +215,8 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ display/xe_dsb_buffer.o \ display/xe_fb_pin.o \ display/xe_hdcp_gsc.o \ + display/xe_initial_plane.o \ display/xe_panic.o \ - display/xe_plane_initial.o \ display/xe_stolen.o \ display/xe_tdf.o diff --git a/drivers/gpu/drm/xe/display/xe_plane_initial.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c similarity index 100% rename from drivers/gpu/drm/xe/display/xe_plane_initial.c rename to drivers/gpu/drm/xe/display/xe_initial_plane.c From b99690ffbca0994bb66e12deb20e37a34abf0ae6 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:17 +0200 Subject: [PATCH 04/92] drm/i915: rename intel_plane_initial.h to intel_initial_plane.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow the more naturally flowing naming. Rename both the header and the vblank wait function. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/32c2d68a9ae7d2262ad2c63e873e522e67bc78df.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 8 ++++---- drivers/gpu/drm/i915/display/intel_display_driver.c | 2 +- .../{intel_plane_initial.h => intel_initial_plane.h} | 6 +++--- drivers/gpu/drm/i915/i915_initial_plane.c | 6 +++--- drivers/gpu/drm/xe/display/xe_initial_plane.c | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) rename drivers/gpu/drm/i915/display/{intel_plane_initial.h => intel_initial_plane.h} (60%) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d5947cc9b94c..1e3c5761fc5e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -100,6 +100,7 @@ #include "intel_frontbuffer.h" #include "intel_hdmi.h" #include "intel_hotplug.h" +#include "intel_initial_plane.h" #include "intel_link_bw.h" #include "intel_lt_phy.h" #include "intel_lvds.h" @@ -113,7 +114,6 @@ #include "intel_pfit.h" #include "intel_pipe_crc.h" #include "intel_plane.h" -#include "intel_plane_initial.h" #include "intel_pmdemand.h" #include "intel_pps.h" #include "intel_psr.h" @@ -639,7 +639,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, if ((crtc_state->active_planes & ~BIT(PLANE_CURSOR)) == 0 && hsw_ips_disable(crtc_state)) { crtc_state->ips_enabled = false; - intel_plane_initial_vblank_wait(crtc); + intel_initial_plane_vblank_wait(crtc); } /* @@ -653,7 +653,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, */ if (HAS_GMCH(display) && intel_set_memory_cxsr(display, false)) - intel_plane_initial_vblank_wait(crtc); + intel_initial_plane_vblank_wait(crtc); /* * Gen2 reports pipe underruns whenever all planes are disabled. @@ -663,7 +663,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, intel_set_cpu_fifo_underrun_reporting(display, crtc->pipe, false); intel_plane_disable_arm(NULL, plane, crtc_state); - intel_plane_initial_vblank_wait(crtc); + intel_initial_plane_vblank_wait(crtc); } unsigned int diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index e1d29aea0ddc..468a6e96bb84 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -54,11 +54,11 @@ #include "intel_hdcp.h" #include "intel_hotplug.h" #include "intel_hti.h" +#include "intel_initial_plane.h" #include "intel_modeset_lock.h" #include "intel_modeset_setup.h" #include "intel_opregion.h" #include "intel_overlay.h" -#include "intel_plane_initial.h" #include "intel_pmdemand.h" #include "intel_pps.h" #include "intel_psr.h" diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.h b/drivers/gpu/drm/i915/display/intel_initial_plane.h similarity index 60% rename from drivers/gpu/drm/i915/display/intel_plane_initial.h rename to drivers/gpu/drm/i915/display/intel_initial_plane.h index 5c315acda210..5f9a347be8f0 100644 --- a/drivers/gpu/drm/i915/display/intel_plane_initial.h +++ b/drivers/gpu/drm/i915/display/intel_initial_plane.h @@ -3,13 +3,13 @@ * Copyright © 2021 Intel Corporation */ -#ifndef __INTEL_PLANE_INITIAL_H__ -#define __INTEL_PLANE_INITIAL_H__ +#ifndef __INTEL_INITIAL_PLANE_H__ +#define __INTEL_INITIAL_PLANE_H__ struct intel_crtc; struct intel_display; void intel_initial_plane_config(struct intel_display *display); -void intel_plane_initial_vblank_wait(struct intel_crtc *crtc); +void intel_initial_plane_vblank_wait(struct intel_crtc *crtc); #endif diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index 87c964485a41..b7f115708c32 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -11,14 +11,14 @@ #include "display/intel_display_types.h" #include "display/intel_fb.h" #include "display/intel_frontbuffer.h" +#include "display/intel_initial_plane.h" #include "display/intel_plane.h" -#include "display/intel_plane_initial.h" #include "gem/i915_gem_lmem.h" #include "gem/i915_gem_region.h" #include "i915_drv.h" -void intel_plane_initial_vblank_wait(struct intel_crtc *crtc) +void intel_initial_plane_vblank_wait(struct intel_crtc *crtc) { intel_crtc_wait_for_next_vblank(crtc); } @@ -436,7 +436,7 @@ void intel_initial_plane_config(struct intel_display *display) intel_find_initial_plane_obj(crtc, plane_configs); if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config)) - intel_plane_initial_vblank_wait(crtc); + intel_initial_plane_vblank_wait(crtc); plane_config_fini(plane_config); } diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c index 01c105a93bb9..9d5760e56c4c 100644 --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c @@ -19,15 +19,15 @@ #include "intel_fb.h" #include "intel_fb_pin.h" #include "intel_frontbuffer.h" +#include "intel_initial_plane.h" #include "intel_plane.h" -#include "intel_plane_initial.h" #include "xe_bo.h" #include "xe_vram_types.h" #include "xe_wa.h" #include -void intel_plane_initial_vblank_wait(struct intel_crtc *crtc) +void intel_initial_plane_vblank_wait(struct intel_crtc *crtc) { /* Early xe has no irq */ struct xe_device *xe = to_xe_device(crtc->base.dev); @@ -314,7 +314,7 @@ void intel_initial_plane_config(struct intel_display *display) intel_find_initial_plane_obj(crtc, plane_configs); if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config)) - intel_plane_initial_vblank_wait(crtc); + intel_initial_plane_vblank_wait(crtc); plane_config_fini(plane_config); } From 9dacae143e6ff18e77fbad6f1413fb8f2f975407 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:18 +0200 Subject: [PATCH 05/92] drm/{i915, xe}: move initial plane calls to parent interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the initial plane handling functions to the display parent interface. Add the call wrappers in dedicated intel_initial_plane.c instead of intel_parent.c, as we'll be refactoring the calls heavily. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/ab91c891677fe2bb83bf5aafa5ee984b2442b84d.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/Makefile | 1 + .../drm/i915/display/intel_initial_plane.c | 20 +++++++++++++++++++ drivers/gpu/drm/i915/i915_driver.c | 2 ++ drivers/gpu/drm/i915/i915_initial_plane.c | 16 +++++++++++---- drivers/gpu/drm/i915/i915_initial_plane.h | 9 +++++++++ drivers/gpu/drm/xe/Makefile | 1 + drivers/gpu/drm/xe/display/xe_display.c | 2 ++ drivers/gpu/drm/xe/display/xe_initial_plane.c | 17 ++++++++++++---- drivers/gpu/drm/xe/display/xe_initial_plane.h | 9 +++++++++ include/drm/intel/display_parent_interface.h | 9 +++++++++ 10 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_initial_plane.c create mode 100644 drivers/gpu/drm/i915/i915_initial_plane.h create mode 100644 drivers/gpu/drm/xe/display/xe_initial_plane.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 58bb7e4fad3b..fb2b21593020 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -290,6 +290,7 @@ i915-y += \ display/intel_hotplug.o \ display/intel_hotplug_irq.o \ display/intel_hti.o \ + display/intel_initial_plane.o \ display/intel_link_bw.o \ display/intel_load_detect.o \ display/intel_lpe_audio.o \ diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c new file mode 100644 index 000000000000..c68d7555aee5 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2025 Intel Corporation */ + +#include + +#include "intel_display_core.h" +#include "intel_display_types.h" +#include "intel_initial_plane.h" + +void intel_initial_plane_vblank_wait(struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(crtc); + + display->parent->initial_plane->vblank_wait(&crtc->base); +} + +void intel_initial_plane_config(struct intel_display *display) +{ + display->parent->initial_plane->config(display->drm); +} diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index e025273e9ab1..f0105c5b49a7 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -99,6 +99,7 @@ #include "i915_gmch.h" #include "i915_hdcp_gsc.h" #include "i915_hwmon.h" +#include "i915_initial_plane.h" #include "i915_ioc32.h" #include "i915_ioctl.h" #include "i915_irq.h" @@ -764,6 +765,7 @@ static bool vgpu_active(struct drm_device *drm) static const struct intel_display_parent_interface parent = { .hdcp = &i915_display_hdcp_interface, + .initial_plane = &i915_display_initial_plane_interface, .irq = &i915_display_irq_interface, .panic = &i915_display_panic_interface, .pc8 = &i915_display_pc8_interface, diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index b7f115708c32..f26563eed9ba 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -4,6 +4,7 @@ */ #include +#include #include "display/intel_crtc.h" #include "display/intel_display.h" @@ -17,10 +18,11 @@ #include "gem/i915_gem_region.h" #include "i915_drv.h" +#include "i915_initial_plane.h" -void intel_initial_plane_vblank_wait(struct intel_crtc *crtc) +static void i915_initial_plane_vblank_wait(struct drm_crtc *crtc) { - intel_crtc_wait_for_next_vblank(crtc); + intel_crtc_wait_for_next_vblank(to_intel_crtc(crtc)); } static bool @@ -406,8 +408,9 @@ static void plane_config_fini(struct intel_initial_plane_config *plane_config) i915_vma_put(plane_config->vma); } -void intel_initial_plane_config(struct intel_display *display) +static void i915_initial_plane_config(struct drm_device *drm) { + struct intel_display *display = to_intel_display(drm); struct intel_initial_plane_config plane_configs[I915_MAX_PIPES] = {}; struct intel_crtc *crtc; @@ -436,8 +439,13 @@ void intel_initial_plane_config(struct intel_display *display) intel_find_initial_plane_obj(crtc, plane_configs); if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config)) - intel_initial_plane_vblank_wait(crtc); + i915_initial_plane_vblank_wait(&crtc->base); plane_config_fini(plane_config); } } + +const struct intel_display_initial_plane_interface i915_display_initial_plane_interface = { + .vblank_wait = i915_initial_plane_vblank_wait, + .config = i915_initial_plane_config, +}; diff --git a/drivers/gpu/drm/i915/i915_initial_plane.h b/drivers/gpu/drm/i915/i915_initial_plane.h new file mode 100644 index 000000000000..99ba462659a6 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_initial_plane.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __I915_INITIAL_PLANE_H__ +#define __I915_INITIAL_PLANE_H__ + +extern const struct intel_display_initial_plane_interface i915_display_initial_plane_interface; + +#endif diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 4af7f5562221..2751599a5cc8 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -292,6 +292,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/intel_hotplug.o \ i915-display/intel_hotplug_irq.o \ i915-display/intel_hti.o \ + i915-display/intel_initial_plane.o \ i915-display/intel_link_bw.o \ i915-display/intel_lspcon.o \ i915-display/intel_lt_phy.o \ diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index eda65a05f601..f8a831b5dc7d 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -37,6 +37,7 @@ #include "skl_watermark.h" #include "xe_display_rpm.h" #include "xe_hdcp_gsc.h" +#include "xe_initial_plane.h" #include "xe_module.h" #include "xe_panic.h" #include "xe_stolen.h" @@ -538,6 +539,7 @@ static const struct intel_display_irq_interface xe_display_irq_interface = { static const struct intel_display_parent_interface parent = { .hdcp = &xe_display_hdcp_interface, + .initial_plane = &xe_display_initial_plane_interface, .irq = &xe_display_irq_interface, .panic = &xe_display_panic_interface, .rpm = &xe_display_rpm_interface, diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c index 9d5760e56c4c..dd69f1c65903 100644 --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c @@ -6,6 +6,8 @@ /* for ioread64 */ #include +#include + #include "regs/xe_gtt_defs.h" #include "xe_ggtt.h" #include "xe_mmio.h" @@ -27,9 +29,10 @@ #include -void intel_initial_plane_vblank_wait(struct intel_crtc *crtc) +/* Early xe has no irq */ +static void xe_initial_plane_vblank_wait(struct drm_crtc *_crtc) { - /* Early xe has no irq */ + struct intel_crtc *crtc = to_intel_crtc(_crtc); struct xe_device *xe = to_xe_device(crtc->base.dev); struct xe_reg pipe_frmtmstmp = XE_REG(i915_mmio_reg_offset(PIPE_FRMTMSTMP(crtc->pipe))); u32 timestamp; @@ -284,8 +287,9 @@ static void plane_config_fini(struct intel_initial_plane_config *plane_config) } } -void intel_initial_plane_config(struct intel_display *display) +static void xe_initial_plane_config(struct drm_device *drm) { + struct intel_display *display = to_intel_display(drm); struct intel_initial_plane_config plane_configs[I915_MAX_PIPES] = {}; struct intel_crtc *crtc; @@ -314,8 +318,13 @@ void intel_initial_plane_config(struct intel_display *display) intel_find_initial_plane_obj(crtc, plane_configs); if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config)) - intel_initial_plane_vblank_wait(crtc); + xe_initial_plane_vblank_wait(&crtc->base); plane_config_fini(plane_config); } } + +const struct intel_display_initial_plane_interface xe_display_initial_plane_interface = { + .vblank_wait = xe_initial_plane_vblank_wait, + .config = xe_initial_plane_config, +}; diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.h b/drivers/gpu/drm/xe/display/xe_initial_plane.h new file mode 100644 index 000000000000..399d15f14441 --- /dev/null +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __XE_INITIAL_PLANE_H__ +#define __XE_INITIAL_PLANE_H__ + +extern const struct intel_display_initial_plane_interface xe_display_initial_plane_interface; + +#endif diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 10c50b42844e..48d52bee4cee 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -7,6 +7,7 @@ #include struct dma_fence; +struct drm_crtc; struct drm_device; struct drm_scanout_buffer; struct intel_hdcp_gsc_context; @@ -25,6 +26,11 @@ struct intel_display_hdcp_interface { void (*gsc_context_free)(struct intel_hdcp_gsc_context *gsc_context); }; +struct intel_display_initial_plane_interface { + void (*vblank_wait)(struct drm_crtc *crtc); + void (*config)(struct drm_device *drm); +}; + struct intel_display_irq_interface { bool (*enabled)(struct drm_device *drm); void (*synchronize)(struct drm_device *drm); @@ -95,6 +101,9 @@ struct intel_display_parent_interface { /** @hdcp: HDCP GSC interface */ const struct intel_display_hdcp_interface *hdcp; + /** @initial_plane: Initial plane interface */ + const struct intel_display_initial_plane_interface *initial_plane; + /** @irq: IRQ interface */ const struct intel_display_irq_interface *irq; From a13f152a6c09338a7f81efdd414425a9d8d50b16 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:19 +0200 Subject: [PATCH 06/92] drm/{i915, xe}: deduplicate intel_initial_plane_config() between i915 and xe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the parent interface at one step lower level, allowing deduplication. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/0cb4077a5a39274c7a2dae95d548d7b33365a518.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_initial_plane.c | 48 ++++++++++++++++++- drivers/gpu/drm/i915/i915_initial_plane.c | 47 +++--------------- drivers/gpu/drm/xe/display/xe_initial_plane.c | 47 +++--------------- include/drm/intel/display_parent_interface.h | 4 +- 4 files changed, 62 insertions(+), 84 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c index c68d7555aee5..561a2ba2a486 100644 --- a/drivers/gpu/drm/i915/display/intel_initial_plane.c +++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c @@ -14,7 +14,53 @@ void intel_initial_plane_vblank_wait(struct intel_crtc *crtc) display->parent->initial_plane->vblank_wait(&crtc->base); } +static void +intel_find_initial_plane_obj(struct intel_crtc *crtc, + struct intel_initial_plane_config plane_configs[]) +{ + struct intel_display *display = to_intel_display(crtc); + + display->parent->initial_plane->find_obj(&crtc->base, plane_configs); +} + +static void plane_config_fini(struct intel_display *display, + struct intel_initial_plane_config *plane_config) +{ + display->parent->initial_plane->config_fini(plane_config); +} + void intel_initial_plane_config(struct intel_display *display) { - display->parent->initial_plane->config(display->drm); + struct intel_initial_plane_config plane_configs[I915_MAX_PIPES] = {}; + struct intel_crtc *crtc; + + for_each_intel_crtc(display->drm, crtc) { + const struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); + struct intel_initial_plane_config *plane_config = + &plane_configs[crtc->pipe]; + + if (!crtc_state->hw.active) + continue; + + /* + * Note that reserving the BIOS fb up front prevents us + * from stuffing other stolen allocations like the ring + * on top. This prevents some ugliness at boot time, and + * can even allow for smooth boot transitions if the BIOS + * fb is large enough for the active pipe configuration. + */ + display->funcs.display->get_initial_plane_config(crtc, plane_config); + + /* + * If the fb is shared between multiple heads, we'll + * just get the first one. + */ + intel_find_initial_plane_obj(crtc, plane_configs); + + if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config)) + intel_initial_plane_vblank_wait(crtc); + + plane_config_fini(display, plane_config); + } } diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index f26563eed9ba..68cf2499855a 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -312,9 +312,10 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, } static void -intel_find_initial_plane_obj(struct intel_crtc *crtc, - struct intel_initial_plane_config plane_configs[]) +i915_find_initial_plane_obj(struct drm_crtc *_crtc, + struct intel_initial_plane_config plane_configs[]) { + struct intel_crtc *crtc = to_intel_crtc(_crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_initial_plane_config *plane_config = &plane_configs[crtc->pipe]; @@ -392,7 +393,7 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits); } -static void plane_config_fini(struct intel_initial_plane_config *plane_config) +static void i915_plane_config_fini(struct intel_initial_plane_config *plane_config) { if (plane_config->fb) { struct drm_framebuffer *fb = &plane_config->fb->base; @@ -408,44 +409,8 @@ static void plane_config_fini(struct intel_initial_plane_config *plane_config) i915_vma_put(plane_config->vma); } -static void i915_initial_plane_config(struct drm_device *drm) -{ - struct intel_display *display = to_intel_display(drm); - struct intel_initial_plane_config plane_configs[I915_MAX_PIPES] = {}; - struct intel_crtc *crtc; - - for_each_intel_crtc(display->drm, crtc) { - const struct intel_crtc_state *crtc_state = - to_intel_crtc_state(crtc->base.state); - struct intel_initial_plane_config *plane_config = - &plane_configs[crtc->pipe]; - - if (!crtc_state->hw.active) - continue; - - /* - * Note that reserving the BIOS fb up front prevents us - * from stuffing other stolen allocations like the ring - * on top. This prevents some ugliness at boot time, and - * can even allow for smooth boot transitions if the BIOS - * fb is large enough for the active pipe configuration. - */ - display->funcs.display->get_initial_plane_config(crtc, plane_config); - - /* - * If the fb is shared between multiple heads, we'll - * just get the first one. - */ - intel_find_initial_plane_obj(crtc, plane_configs); - - if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config)) - i915_initial_plane_vblank_wait(&crtc->base); - - plane_config_fini(plane_config); - } -} - const struct intel_display_initial_plane_interface i915_display_initial_plane_interface = { .vblank_wait = i915_initial_plane_vblank_wait, - .config = i915_initial_plane_config, + .find_obj = i915_find_initial_plane_obj, + .config_fini = i915_plane_config_fini, }; diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c index dd69f1c65903..0007337c60da 100644 --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c @@ -204,9 +204,10 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, } static void -intel_find_initial_plane_obj(struct intel_crtc *crtc, - struct intel_initial_plane_config plane_configs[]) +xe_find_initial_plane_obj(struct drm_crtc *_crtc, + struct intel_initial_plane_config plane_configs[]) { + struct intel_crtc *crtc = to_intel_crtc(_crtc); struct intel_initial_plane_config *plane_config = &plane_configs[crtc->pipe]; struct intel_plane *plane = @@ -274,7 +275,7 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, intel_plane_disable_noatomic(crtc, plane); } -static void plane_config_fini(struct intel_initial_plane_config *plane_config) +static void xe_plane_config_fini(struct intel_initial_plane_config *plane_config) { if (plane_config->fb) { struct drm_framebuffer *fb = &plane_config->fb->base; @@ -287,44 +288,8 @@ static void plane_config_fini(struct intel_initial_plane_config *plane_config) } } -static void xe_initial_plane_config(struct drm_device *drm) -{ - struct intel_display *display = to_intel_display(drm); - struct intel_initial_plane_config plane_configs[I915_MAX_PIPES] = {}; - struct intel_crtc *crtc; - - for_each_intel_crtc(display->drm, crtc) { - const struct intel_crtc_state *crtc_state = - to_intel_crtc_state(crtc->base.state); - struct intel_initial_plane_config *plane_config = - &plane_configs[crtc->pipe]; - - if (!crtc_state->hw.active) - continue; - - /* - * Note that reserving the BIOS fb up front prevents us - * from stuffing other stolen allocations like the ring - * on top. This prevents some ugliness at boot time, and - * can even allow for smooth boot transitions if the BIOS - * fb is large enough for the active pipe configuration. - */ - display->funcs.display->get_initial_plane_config(crtc, plane_config); - - /* - * If the fb is shared between multiple heads, we'll - * just get the first one. - */ - intel_find_initial_plane_obj(crtc, plane_configs); - - if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config)) - xe_initial_plane_vblank_wait(&crtc->base); - - plane_config_fini(plane_config); - } -} - const struct intel_display_initial_plane_interface xe_display_initial_plane_interface = { .vblank_wait = xe_initial_plane_vblank_wait, - .config = xe_initial_plane_config, + .find_obj = xe_find_initial_plane_obj, + .config_fini = xe_plane_config_fini, }; diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 48d52bee4cee..87cd3c5e1055 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -11,6 +11,7 @@ struct drm_crtc; struct drm_device; struct drm_scanout_buffer; struct intel_hdcp_gsc_context; +struct intel_initial_plane_config; struct intel_panic; struct intel_stolen_node; struct ref_tracker; @@ -28,7 +29,8 @@ struct intel_display_hdcp_interface { struct intel_display_initial_plane_interface { void (*vblank_wait)(struct drm_crtc *crtc); - void (*config)(struct drm_device *drm); + void (*find_obj)(struct drm_crtc *crtc, struct intel_initial_plane_config *plane_configs); + void (*config_fini)(struct intel_initial_plane_config *plane_configs); }; struct intel_display_irq_interface { From 6bb14ea387fee901b62a29af568f39eeac23e451 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:20 +0200 Subject: [PATCH 07/92] drm/{i915, xe}: deduplicate plane_config_fini() between i915 and xe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the common code to display. Retain empty xe_plane_config_fini() for now, in case it's needed in the future. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/14322386cdb1a0f4f6c7ff74a5a9696ea0ff84bf.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_initial_plane.c | 10 ++++++++++ drivers/gpu/drm/i915/i915_initial_plane.c | 10 ---------- drivers/gpu/drm/xe/display/xe_initial_plane.c | 9 --------- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c index 561a2ba2a486..62f4fb3be9f0 100644 --- a/drivers/gpu/drm/i915/display/intel_initial_plane.c +++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c @@ -26,6 +26,16 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, static void plane_config_fini(struct intel_display *display, struct intel_initial_plane_config *plane_config) { + if (plane_config->fb) { + struct drm_framebuffer *fb = &plane_config->fb->base; + + /* We may only have the stub and not a full framebuffer */ + if (drm_framebuffer_read_refcount(fb)) + drm_framebuffer_put(fb); + else + kfree(fb); + } + display->parent->initial_plane->config_fini(plane_config); } diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index 68cf2499855a..d8f2a2a11dd0 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -395,16 +395,6 @@ i915_find_initial_plane_obj(struct drm_crtc *_crtc, static void i915_plane_config_fini(struct intel_initial_plane_config *plane_config) { - if (plane_config->fb) { - struct drm_framebuffer *fb = &plane_config->fb->base; - - /* We may only have the stub and not a full framebuffer */ - if (drm_framebuffer_read_refcount(fb)) - drm_framebuffer_put(fb); - else - kfree(fb); - } - if (plane_config->vma) i915_vma_put(plane_config->vma); } diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c index 0007337c60da..95000f8b0662 100644 --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c @@ -277,15 +277,6 @@ xe_find_initial_plane_obj(struct drm_crtc *_crtc, static void xe_plane_config_fini(struct intel_initial_plane_config *plane_config) { - if (plane_config->fb) { - struct drm_framebuffer *fb = &plane_config->fb->base; - - /* We may only have the stub and not a full framebuffer */ - if (drm_framebuffer_read_refcount(fb)) - drm_framebuffer_put(fb); - else - kfree(fb); - } } const struct intel_display_initial_plane_interface xe_display_initial_plane_interface = { From 1b3cc68df363820537d6c837069db4c303ee58a9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:21 +0200 Subject: [PATCH 08/92] drm/{i915, xe}: start deduplicating intel_find_initial_plane_obj() between i915 and xe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move some easy common parts to display. Initially, the intel_find_initial_plane_obj() error path seems silly, but it'll be more helpful this way for later changes. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/950d308172443d5bae975aa1ab72111720134219.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_initial_plane.c | 27 ++++++++++++++- drivers/gpu/drm/i915/i915_initial_plane.c | 34 +++---------------- drivers/gpu/drm/xe/display/xe_initial_plane.c | 25 +++----------- include/drm/intel/display_parent_interface.h | 2 +- 4 files changed, 36 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c index 62f4fb3be9f0..9e67da94ac02 100644 --- a/drivers/gpu/drm/i915/display/intel_initial_plane.c +++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c @@ -19,8 +19,33 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, struct intel_initial_plane_config plane_configs[]) { struct intel_display *display = to_intel_display(crtc); + struct intel_initial_plane_config *plane_config = &plane_configs[crtc->pipe]; + struct intel_plane *plane = to_intel_plane(crtc->base.primary); + int ret; - display->parent->initial_plane->find_obj(&crtc->base, plane_configs); + /* + * TODO: + * Disable planes if get_initial_plane_config() failed. + * Make sure things work if the surface base is not page aligned. + */ + if (!plane_config->fb) + return; + + ret = display->parent->initial_plane->find_obj(&crtc->base, plane_configs); + if (ret) + goto nofb; + + return; + +nofb: + /* + * We've failed to reconstruct the BIOS FB. Current display state + * indicates that the primary plane is visible, but has a NULL FB, + * which will lead to problems later if we don't fix it up. The + * simplest solution is to just disable the primary plane now and + * pretend the BIOS never had it enabled. + */ + intel_plane_disable_noatomic(crtc, plane); } static void plane_config_fini(struct intel_display *display, diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index d8f2a2a11dd0..57afe6e29ce3 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -311,7 +311,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, return false; } -static void +static int i915_find_initial_plane_obj(struct drm_crtc *_crtc, struct intel_initial_plane_config plane_configs[]) { @@ -326,39 +326,13 @@ i915_find_initial_plane_obj(struct drm_crtc *_crtc, struct drm_framebuffer *fb; struct i915_vma *vma; - /* - * TODO: - * Disable planes if get_initial_plane_config() failed. - * Make sure things work if the surface base is not page aligned. - */ - if (!plane_config->fb) - return; - if (intel_alloc_initial_plane_obj(crtc, plane_config)) { fb = &plane_config->fb->base; vma = plane_config->vma; - goto valid_fb; + } else if (!intel_reuse_initial_plane_obj(crtc, plane_configs, &fb, &vma)) { + return -EINVAL; } - /* - * Failed to alloc the obj, check to see if we should share - * an fb with another CRTC instead - */ - if (intel_reuse_initial_plane_obj(crtc, plane_configs, &fb, &vma)) - goto valid_fb; - - /* - * We've failed to reconstruct the BIOS FB. Current display state - * indicates that the primary plane is visible, but has a NULL FB, - * which will lead to problems later if we don't fix it up. The - * simplest solution is to just disable the primary plane now and - * pretend the BIOS never had it enabled. - */ - intel_plane_disable_noatomic(crtc, plane); - - return; - -valid_fb: plane_state->uapi.rotation = plane_config->rotation; intel_fb_fill_view(to_intel_framebuffer(fb), plane_state->uapi.rotation, &plane_state->view); @@ -391,6 +365,8 @@ i915_find_initial_plane_obj(struct drm_crtc *_crtc, intel_plane_copy_uapi_to_hw_state(plane_state, plane_state, crtc); atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits); + + return 0; } static void i915_plane_config_fini(struct intel_initial_plane_config *plane_config) diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c index 95000f8b0662..ddf22631240e 100644 --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c @@ -203,7 +203,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, return false; } -static void +static int xe_find_initial_plane_obj(struct drm_crtc *_crtc, struct intel_initial_plane_config plane_configs[]) { @@ -217,18 +217,10 @@ xe_find_initial_plane_obj(struct drm_crtc *_crtc, struct drm_framebuffer *fb; struct i915_vma *vma; - /* - * TODO: - * Disable planes if get_initial_plane_config() failed. - * Make sure things work if the surface base is not page aligned. - */ - if (!plane_config->fb) - return; - if (intel_alloc_initial_plane_obj(crtc, plane_config)) fb = &plane_config->fb->base; else if (!intel_reuse_initial_plane_obj(crtc, plane_configs, &fb)) - goto nofb; + return -EINVAL; plane_state->uapi.rotation = plane_config->rotation; intel_fb_fill_view(to_intel_framebuffer(fb), @@ -237,7 +229,7 @@ xe_find_initial_plane_obj(struct drm_crtc *_crtc, vma = intel_fb_pin_to_ggtt(fb, &plane_state->view.gtt, 0, 0, 0, false, &plane_state->flags); if (IS_ERR(vma)) - goto nofb; + return PTR_ERR(vma); plane_state->ggtt_vma = vma; @@ -262,17 +254,8 @@ xe_find_initial_plane_obj(struct drm_crtc *_crtc, atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits); plane_config->vma = vma; - return; -nofb: - /* - * We've failed to reconstruct the BIOS FB. Current display state - * indicates that the primary plane is visible, but has a NULL FB, - * which will lead to problems later if we don't fix it up. The - * simplest solution is to just disable the primary plane now and - * pretend the BIOS never had it enabled. - */ - intel_plane_disable_noatomic(crtc, plane); + return 0; } static void xe_plane_config_fini(struct intel_initial_plane_config *plane_config) diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 87cd3c5e1055..997a9746dc83 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -29,7 +29,7 @@ struct intel_display_hdcp_interface { struct intel_display_initial_plane_interface { void (*vblank_wait)(struct drm_crtc *crtc); - void (*find_obj)(struct drm_crtc *crtc, struct intel_initial_plane_config *plane_configs); + int (*find_obj)(struct drm_crtc *crtc, struct intel_initial_plane_config *plane_configs); void (*config_fini)(struct intel_initial_plane_config *plane_configs); }; From 3629264e4d7dd255180e99ed6be05af57e4bea6b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:22 +0200 Subject: [PATCH 09/92] drm/i915: return plane_state from intel_reuse_initial_plane_obj() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initialize fb and vma in the same level as the other code path. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/96985a18593408f07fba131cf49ca0f97bf8fb93.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_initial_plane.c | 26 ++++++++++++----------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index 57afe6e29ce3..40b9f981c9ac 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -25,11 +25,9 @@ static void i915_initial_plane_vblank_wait(struct drm_crtc *crtc) intel_crtc_wait_for_next_vblank(to_intel_crtc(crtc)); } -static bool +static const struct intel_plane_state * intel_reuse_initial_plane_obj(struct intel_crtc *this, - const struct intel_initial_plane_config plane_configs[], - struct drm_framebuffer **fb, - struct i915_vma **vma) + const struct intel_initial_plane_config plane_configs[]) { struct intel_display *display = to_intel_display(this); struct intel_crtc *crtc; @@ -48,14 +46,11 @@ intel_reuse_initial_plane_obj(struct intel_crtc *this, if (!plane_state->ggtt_vma) continue; - if (plane_configs[this->pipe].base == plane_configs[crtc->pipe].base) { - *fb = plane_state->hw.fb; - *vma = plane_state->ggtt_vma; - return true; - } + if (plane_configs[this->pipe].base == plane_configs[crtc->pipe].base) + return plane_state; } - return false; + return NULL; } static enum intel_memory_type @@ -329,8 +324,15 @@ i915_find_initial_plane_obj(struct drm_crtc *_crtc, if (intel_alloc_initial_plane_obj(crtc, plane_config)) { fb = &plane_config->fb->base; vma = plane_config->vma; - } else if (!intel_reuse_initial_plane_obj(crtc, plane_configs, &fb, &vma)) { - return -EINVAL; + } else { + const struct intel_plane_state *other_plane_state; + + other_plane_state = intel_reuse_initial_plane_obj(crtc, plane_configs); + if (!other_plane_state) + return -EINVAL; + + fb = other_plane_state->hw.fb; + vma = other_plane_state->ggtt_vma; } plane_state->uapi.rotation = plane_config->rotation; From 9a864b5487c6f819488f64bb5ad3f5efcb720330 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:23 +0200 Subject: [PATCH 10/92] drm/xe: return plane_state from intel_reuse_initial_plane_obj() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initialize fb in the same level as the other code path. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/47d3272cff13dc8f5d7323c32bfb3cc34c0c977d.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/xe/display/xe_initial_plane.c | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c index ddf22631240e..42d2c2f8138e 100644 --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c @@ -45,10 +45,9 @@ static void xe_initial_plane_vblank_wait(struct drm_crtc *_crtc) drm_warn(&xe->drm, "waiting for early vblank failed with %i\n", ret); } -static bool +static const struct intel_plane_state * intel_reuse_initial_plane_obj(struct intel_crtc *this, - const struct intel_initial_plane_config plane_configs[], - struct drm_framebuffer **fb) + const struct intel_initial_plane_config plane_configs[]) { struct xe_device *xe = to_xe_device(this->base.dev); struct intel_crtc *crtc; @@ -67,13 +66,11 @@ intel_reuse_initial_plane_obj(struct intel_crtc *this, if (!plane_state->ggtt_vma) continue; - if (plane_configs[this->pipe].base == plane_configs[crtc->pipe].base) { - *fb = plane_state->hw.fb; - return true; - } + if (plane_configs[this->pipe].base == plane_configs[crtc->pipe].base) + return plane_state; } - return false; + return NULL; } static struct xe_bo * @@ -217,10 +214,17 @@ xe_find_initial_plane_obj(struct drm_crtc *_crtc, struct drm_framebuffer *fb; struct i915_vma *vma; - if (intel_alloc_initial_plane_obj(crtc, plane_config)) + if (intel_alloc_initial_plane_obj(crtc, plane_config)) { fb = &plane_config->fb->base; - else if (!intel_reuse_initial_plane_obj(crtc, plane_configs, &fb)) - return -EINVAL; + } else { + const struct intel_plane_state *other_plane_state; + + other_plane_state = intel_reuse_initial_plane_obj(crtc, plane_configs); + if (!other_plane_state) + return -EINVAL; + + fb = other_plane_state->hw.fb; + } plane_state->uapi.rotation = plane_config->rotation; intel_fb_fill_view(to_intel_framebuffer(fb), From adf7968e52e8d9f1b76ecc46ac5720c0e61c9d51 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:24 +0200 Subject: [PATCH 11/92] drm/i915: further deduplicate intel_find_initial_plane_obj() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move intel_reuse_initial_plane_obj() into common display code, and split the ->find_obj hook into ->alloc_obj and ->setup hooks. Return the struct drm_gem_object from ->alloc_obj in preparation for moving more things to display. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/c71011dbb11afaa5c4da30aa2627833374300d63.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_initial_plane.c | 55 ++++++++++++++- drivers/gpu/drm/i915/i915_initial_plane.c | 70 ++++--------------- drivers/gpu/drm/xe/display/xe_initial_plane.c | 67 ++++-------------- include/drm/intel/display_parent_interface.h | 7 +- 4 files changed, 88 insertions(+), 111 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c index 9e67da94ac02..cbfcc52f180f 100644 --- a/drivers/gpu/drm/i915/display/intel_initial_plane.c +++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c @@ -14,6 +14,43 @@ void intel_initial_plane_vblank_wait(struct intel_crtc *crtc) display->parent->initial_plane->vblank_wait(&crtc->base); } +static const struct intel_plane_state * +intel_reuse_initial_plane_obj(struct intel_crtc *this, + const struct intel_initial_plane_config plane_configs[]) +{ + struct intel_display *display = to_intel_display(this); + struct intel_crtc *crtc; + + for_each_intel_crtc(display->drm, 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); + const struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); + + if (!crtc_state->hw.active) + continue; + + if (!plane_state->ggtt_vma) + continue; + + if (plane_configs[this->pipe].base == plane_configs[crtc->pipe].base) + return plane_state; + } + + return NULL; +} + +static struct drm_gem_object * +intel_alloc_initial_plane_obj(struct intel_crtc *crtc, + struct intel_initial_plane_config *plane_config) +{ + struct intel_display *display = to_intel_display(crtc); + + return display->parent->initial_plane->alloc_obj(&crtc->base, plane_config); +} + static void intel_find_initial_plane_obj(struct intel_crtc *crtc, struct intel_initial_plane_config plane_configs[]) @@ -21,6 +58,8 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, struct intel_display *display = to_intel_display(crtc); struct intel_initial_plane_config *plane_config = &plane_configs[crtc->pipe]; struct intel_plane *plane = to_intel_plane(crtc->base.primary); + struct drm_framebuffer *fb; + struct i915_vma *vma; int ret; /* @@ -31,7 +70,21 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, if (!plane_config->fb) return; - ret = display->parent->initial_plane->find_obj(&crtc->base, plane_configs); + if (intel_alloc_initial_plane_obj(crtc, plane_config)) { + fb = &plane_config->fb->base; + vma = plane_config->vma; + } else { + const struct intel_plane_state *other_plane_state; + + other_plane_state = intel_reuse_initial_plane_obj(crtc, plane_configs); + if (!other_plane_state) + goto nofb; + + fb = other_plane_state->hw.fb; + vma = other_plane_state->ggtt_vma; + } + + ret = display->parent->initial_plane->setup(&crtc->base, plane_config, fb, vma); if (ret) goto nofb; diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index 40b9f981c9ac..0117f9e115d1 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -25,34 +25,6 @@ static void i915_initial_plane_vblank_wait(struct drm_crtc *crtc) intel_crtc_wait_for_next_vblank(to_intel_crtc(crtc)); } -static const struct intel_plane_state * -intel_reuse_initial_plane_obj(struct intel_crtc *this, - const struct intel_initial_plane_config plane_configs[]) -{ - struct intel_display *display = to_intel_display(this); - struct intel_crtc *crtc; - - for_each_intel_crtc(display->drm, 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); - const struct intel_crtc_state *crtc_state = - to_intel_crtc_state(crtc->base.state); - - if (!crtc_state->hw.active) - continue; - - if (!plane_state->ggtt_vma) - continue; - - if (plane_configs[this->pipe].base == plane_configs[crtc->pipe].base) - return plane_state; - } - - return NULL; -} - static enum intel_memory_type initial_plane_memory_type(struct intel_display *display) { @@ -258,10 +230,11 @@ initial_plane_vma(struct intel_display *display, return NULL; } -static bool -intel_alloc_initial_plane_obj(struct intel_crtc *crtc, - struct intel_initial_plane_config *plane_config) +static struct drm_gem_object * +i915_alloc_initial_plane_obj(struct drm_crtc *_crtc, + struct intel_initial_plane_config *plane_config) { + struct intel_crtc *crtc = to_intel_crtc(_crtc); struct intel_display *display = to_intel_display(crtc); struct drm_mode_fb_cmd2 mode_cmd = {}; struct drm_framebuffer *fb = &plane_config->fb->base; @@ -277,12 +250,12 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, drm_dbg(display->drm, "Unsupported modifier for initial FB: 0x%llx\n", fb->modifier); - return false; + return NULL; } vma = initial_plane_vma(display, plane_config); if (!vma) - return false; + return NULL; mode_cmd.pixel_format = fb->format->format; mode_cmd.width = fb->width; @@ -299,41 +272,25 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, } plane_config->vma = vma; - return true; + return intel_bo_to_drm_bo(vma->obj); err_vma: i915_vma_put(vma); - return false; + return NULL; } static int -i915_find_initial_plane_obj(struct drm_crtc *_crtc, - struct intel_initial_plane_config plane_configs[]) +i915_initial_plane_setup(struct drm_crtc *_crtc, + struct intel_initial_plane_config *plane_config, + struct drm_framebuffer *fb, + struct i915_vma *vma) { struct intel_crtc *crtc = to_intel_crtc(_crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct intel_initial_plane_config *plane_config = - &plane_configs[crtc->pipe]; struct intel_plane *plane = to_intel_plane(crtc->base.primary); struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); - struct drm_framebuffer *fb; - struct i915_vma *vma; - - if (intel_alloc_initial_plane_obj(crtc, plane_config)) { - fb = &plane_config->fb->base; - vma = plane_config->vma; - } else { - const struct intel_plane_state *other_plane_state; - - other_plane_state = intel_reuse_initial_plane_obj(crtc, plane_configs); - if (!other_plane_state) - return -EINVAL; - - fb = other_plane_state->hw.fb; - vma = other_plane_state->ggtt_vma; - } plane_state->uapi.rotation = plane_config->rotation; intel_fb_fill_view(to_intel_framebuffer(fb), @@ -379,6 +336,7 @@ static void i915_plane_config_fini(struct intel_initial_plane_config *plane_conf const struct intel_display_initial_plane_interface i915_display_initial_plane_interface = { .vblank_wait = i915_initial_plane_vblank_wait, - .find_obj = i915_find_initial_plane_obj, + .alloc_obj = i915_alloc_initial_plane_obj, + .setup = i915_initial_plane_setup, .config_fini = i915_plane_config_fini, }; diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c index 42d2c2f8138e..2ce0f78cd7b1 100644 --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c @@ -45,34 +45,6 @@ static void xe_initial_plane_vblank_wait(struct drm_crtc *_crtc) drm_warn(&xe->drm, "waiting for early vblank failed with %i\n", ret); } -static const struct intel_plane_state * -intel_reuse_initial_plane_obj(struct intel_crtc *this, - const struct intel_initial_plane_config plane_configs[]) -{ - struct xe_device *xe = to_xe_device(this->base.dev); - struct intel_crtc *crtc; - - for_each_intel_crtc(&xe->drm, 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); - const struct intel_crtc_state *crtc_state = - to_intel_crtc_state(crtc->base.state); - - if (!crtc_state->hw.active) - continue; - - if (!plane_state->ggtt_vma) - continue; - - if (plane_configs[this->pipe].base == plane_configs[crtc->pipe].base) - return plane_state; - } - - return NULL; -} - static struct xe_bo * initial_plane_bo(struct xe_device *xe, struct intel_initial_plane_config *plane_config) @@ -152,10 +124,11 @@ initial_plane_bo(struct xe_device *xe, return bo; } -static bool -intel_alloc_initial_plane_obj(struct intel_crtc *crtc, - struct intel_initial_plane_config *plane_config) +static struct drm_gem_object * +xe_alloc_initial_plane_obj(struct drm_crtc *_crtc, + struct intel_initial_plane_config *plane_config) { + struct intel_crtc *crtc = to_intel_crtc(_crtc); struct xe_device *xe = to_xe_device(crtc->base.dev); struct drm_mode_fb_cmd2 mode_cmd = { 0 }; struct drm_framebuffer *fb = &plane_config->fb->base; @@ -171,7 +144,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, drm_dbg_kms(&xe->drm, "Unsupported modifier for initial FB: 0x%llx\n", fb->modifier); - return false; + return NULL; } mode_cmd.pixel_format = fb->format->format; @@ -183,7 +156,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, bo = initial_plane_bo(xe, plane_config); if (!bo) - return false; + return NULL; if (intel_framebuffer_init(to_intel_framebuffer(fb), &bo->ttm.base, fb->format, &mode_cmd)) { @@ -193,39 +166,26 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, /* Reference handed over to fb */ xe_bo_put(bo); - return true; + return &bo->ttm.base; err_bo: xe_bo_unpin_map_no_vm(bo); - return false; + return NULL; } static int -xe_find_initial_plane_obj(struct drm_crtc *_crtc, - struct intel_initial_plane_config plane_configs[]) +xe_initial_plane_setup(struct drm_crtc *_crtc, + struct intel_initial_plane_config *plane_config, + struct drm_framebuffer *fb, + struct i915_vma *_unused) { struct intel_crtc *crtc = to_intel_crtc(_crtc); - struct intel_initial_plane_config *plane_config = - &plane_configs[crtc->pipe]; struct intel_plane *plane = to_intel_plane(crtc->base.primary); struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); - struct drm_framebuffer *fb; struct i915_vma *vma; - if (intel_alloc_initial_plane_obj(crtc, plane_config)) { - fb = &plane_config->fb->base; - } else { - const struct intel_plane_state *other_plane_state; - - other_plane_state = intel_reuse_initial_plane_obj(crtc, plane_configs); - if (!other_plane_state) - return -EINVAL; - - fb = other_plane_state->hw.fb; - } - plane_state->uapi.rotation = plane_config->rotation; intel_fb_fill_view(to_intel_framebuffer(fb), plane_state->uapi.rotation, &plane_state->view); @@ -268,6 +228,7 @@ static void xe_plane_config_fini(struct intel_initial_plane_config *plane_config const struct intel_display_initial_plane_interface xe_display_initial_plane_interface = { .vblank_wait = xe_initial_plane_vblank_wait, - .find_obj = xe_find_initial_plane_obj, + .alloc_obj = xe_alloc_initial_plane_obj, + .setup = xe_initial_plane_setup, .config_fini = xe_plane_config_fini, }; diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 997a9746dc83..f0f379ae912d 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -9,7 +9,10 @@ struct dma_fence; struct drm_crtc; struct drm_device; +struct drm_framebuffer; +struct drm_gem_object; struct drm_scanout_buffer; +struct i915_vma; struct intel_hdcp_gsc_context; struct intel_initial_plane_config; struct intel_panic; @@ -29,7 +32,9 @@ struct intel_display_hdcp_interface { struct intel_display_initial_plane_interface { void (*vblank_wait)(struct drm_crtc *crtc); - int (*find_obj)(struct drm_crtc *crtc, struct intel_initial_plane_config *plane_configs); + struct drm_gem_object *(*alloc_obj)(struct drm_crtc *crtc, struct intel_initial_plane_config *plane_config); + int (*setup)(struct drm_crtc *crtc, struct intel_initial_plane_config *plane_config, + struct drm_framebuffer *fb, struct i915_vma *vma); void (*config_fini)(struct intel_initial_plane_config *plane_configs); }; From 64ee50c6f025c0a62e173bd96c33e48da6012383 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:25 +0200 Subject: [PATCH 12/92] drm/{i915, xe}: deduplicate intel_alloc_initial_plane_obj() FB modifier checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the modifier checks into common code to deduplicate. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/3c62ad48595aa2306219b1d6a215cf7680a67da2.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_initial_plane.c | 14 ++++++++++++++ drivers/gpu/drm/i915/i915_initial_plane.c | 13 ------------- drivers/gpu/drm/xe/display/xe_initial_plane.c | 13 ------------- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c index cbfcc52f180f..e45d2f4e80ad 100644 --- a/drivers/gpu/drm/i915/display/intel_initial_plane.c +++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT /* Copyright © 2025 Intel Corporation */ +#include #include #include "intel_display_core.h" @@ -47,6 +48,19 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, struct intel_initial_plane_config *plane_config) { struct intel_display *display = to_intel_display(crtc); + struct intel_framebuffer *fb = plane_config->fb; + + switch (fb->base.modifier) { + case DRM_FORMAT_MOD_LINEAR: + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_4_TILED: + break; + default: + drm_dbg_kms(display->drm, "Unsupported modifier for initial FB: 0x%llx\n", + fb->base.modifier); + return NULL; + } return display->parent->initial_plane->alloc_obj(&crtc->base, plane_config); } diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index 0117f9e115d1..5f7dfe7c6d42 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -240,19 +240,6 @@ i915_alloc_initial_plane_obj(struct drm_crtc *_crtc, struct drm_framebuffer *fb = &plane_config->fb->base; struct i915_vma *vma; - switch (fb->modifier) { - case DRM_FORMAT_MOD_LINEAR: - case I915_FORMAT_MOD_X_TILED: - case I915_FORMAT_MOD_Y_TILED: - case I915_FORMAT_MOD_4_TILED: - break; - default: - drm_dbg(display->drm, - "Unsupported modifier for initial FB: 0x%llx\n", - fb->modifier); - return NULL; - } - vma = initial_plane_vma(display, plane_config); if (!vma) return NULL; diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c index 2ce0f78cd7b1..e819175d5946 100644 --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c @@ -134,19 +134,6 @@ xe_alloc_initial_plane_obj(struct drm_crtc *_crtc, struct drm_framebuffer *fb = &plane_config->fb->base; struct xe_bo *bo; - switch (fb->modifier) { - case DRM_FORMAT_MOD_LINEAR: - case I915_FORMAT_MOD_X_TILED: - case I915_FORMAT_MOD_Y_TILED: - case I915_FORMAT_MOD_4_TILED: - break; - default: - drm_dbg_kms(&xe->drm, - "Unsupported modifier for initial FB: 0x%llx\n", - fb->modifier); - return NULL; - } - mode_cmd.pixel_format = fb->format->format; mode_cmd.width = fb->width; mode_cmd.height = fb->height; From dcff3266cfc49000b95b461a41031db3cfc55c62 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:26 +0200 Subject: [PATCH 13/92] drm/{i915,xe}: deduplicate initial plane setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deduplicate more of the identical parts of i915 and xe initial plane setup. This lets us reduce the core dependency on display internals. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/1a2abbceedb9e7d03f262c44cd54a24556ef6b61.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_initial_plane.c | 26 +++++++++++++++++++ drivers/gpu/drm/i915/i915_initial_plane.c | 25 ------------------ drivers/gpu/drm/xe/display/xe_initial_plane.c | 25 ------------------ 3 files changed, 26 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c index e45d2f4e80ad..6e7bd6c3c02d 100644 --- a/drivers/gpu/drm/i915/display/intel_initial_plane.c +++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c @@ -6,7 +6,10 @@ #include "intel_display_core.h" #include "intel_display_types.h" +#include "intel_fb.h" +#include "intel_frontbuffer.h" #include "intel_initial_plane.h" +#include "intel_plane.h" void intel_initial_plane_vblank_wait(struct intel_crtc *crtc) { @@ -72,6 +75,7 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, struct intel_display *display = to_intel_display(crtc); struct intel_initial_plane_config *plane_config = &plane_configs[crtc->pipe]; struct intel_plane *plane = to_intel_plane(crtc->base.primary); + struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); struct drm_framebuffer *fb; struct i915_vma *vma; int ret; @@ -98,10 +102,32 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, vma = other_plane_state->ggtt_vma; } + plane_state->uapi.rotation = plane_config->rotation; + intel_fb_fill_view(to_intel_framebuffer(fb), + plane_state->uapi.rotation, &plane_state->view); + ret = display->parent->initial_plane->setup(&crtc->base, plane_config, fb, vma); if (ret) goto nofb; + plane_state->uapi.src_x = 0; + plane_state->uapi.src_y = 0; + plane_state->uapi.src_w = fb->width << 16; + plane_state->uapi.src_h = fb->height << 16; + + plane_state->uapi.crtc_x = 0; + plane_state->uapi.crtc_y = 0; + plane_state->uapi.crtc_w = fb->width; + plane_state->uapi.crtc_h = fb->height; + + plane_state->uapi.fb = fb; + drm_framebuffer_get(fb); + + plane_state->uapi.crtc = &crtc->base; + intel_plane_copy_uapi_to_hw_state(plane_state, plane_state, crtc); + + atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits); + return; nofb: diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index 5f7dfe7c6d42..5fe96b52d2cd 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -11,9 +11,6 @@ #include "display/intel_display_core.h" #include "display/intel_display_types.h" #include "display/intel_fb.h" -#include "display/intel_frontbuffer.h" -#include "display/intel_initial_plane.h" -#include "display/intel_plane.h" #include "gem/i915_gem_lmem.h" #include "gem/i915_gem_region.h" @@ -279,10 +276,6 @@ i915_initial_plane_setup(struct drm_crtc *_crtc, struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); - plane_state->uapi.rotation = plane_config->rotation; - intel_fb_fill_view(to_intel_framebuffer(fb), - plane_state->uapi.rotation, &plane_state->view); - __i915_vma_pin(vma); plane_state->ggtt_vma = i915_vma_get(vma); if (intel_plane_uses_fence(plane_state) && @@ -291,27 +284,9 @@ i915_initial_plane_setup(struct drm_crtc *_crtc, plane_state->surf = i915_ggtt_offset(plane_state->ggtt_vma); - plane_state->uapi.src_x = 0; - plane_state->uapi.src_y = 0; - plane_state->uapi.src_w = fb->width << 16; - plane_state->uapi.src_h = fb->height << 16; - - plane_state->uapi.crtc_x = 0; - plane_state->uapi.crtc_y = 0; - plane_state->uapi.crtc_w = fb->width; - plane_state->uapi.crtc_h = fb->height; - if (fb->modifier != DRM_FORMAT_MOD_LINEAR) dev_priv->preserve_bios_swizzle = true; - plane_state->uapi.fb = fb; - drm_framebuffer_get(fb); - - plane_state->uapi.crtc = &crtc->base; - intel_plane_copy_uapi_to_hw_state(plane_state, plane_state, crtc); - - atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits); - return 0; } diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c index e819175d5946..45513fd79766 100644 --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c @@ -20,9 +20,6 @@ #include "intel_display_types.h" #include "intel_fb.h" #include "intel_fb_pin.h" -#include "intel_frontbuffer.h" -#include "intel_initial_plane.h" -#include "intel_plane.h" #include "xe_bo.h" #include "xe_vram_types.h" #include "xe_wa.h" @@ -173,10 +170,6 @@ xe_initial_plane_setup(struct drm_crtc *_crtc, to_intel_plane_state(plane->base.state); struct i915_vma *vma; - plane_state->uapi.rotation = plane_config->rotation; - intel_fb_fill_view(to_intel_framebuffer(fb), - plane_state->uapi.rotation, &plane_state->view); - vma = intel_fb_pin_to_ggtt(fb, &plane_state->view.gtt, 0, 0, 0, false, &plane_state->flags); if (IS_ERR(vma)) @@ -186,24 +179,6 @@ xe_initial_plane_setup(struct drm_crtc *_crtc, plane_state->surf = i915_ggtt_offset(plane_state->ggtt_vma); - plane_state->uapi.src_x = 0; - plane_state->uapi.src_y = 0; - plane_state->uapi.src_w = fb->width << 16; - plane_state->uapi.src_h = fb->height << 16; - - plane_state->uapi.crtc_x = 0; - plane_state->uapi.crtc_y = 0; - plane_state->uapi.crtc_w = fb->width; - plane_state->uapi.crtc_h = fb->height; - - plane_state->uapi.fb = fb; - drm_framebuffer_get(fb); - - plane_state->uapi.crtc = &crtc->base; - intel_plane_copy_uapi_to_hw_state(plane_state, plane_state, crtc); - - atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits); - plane_config->vma = vma; return 0; From 5bad00377ec844d93947fd4c081abd2000a63dfc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:27 +0200 Subject: [PATCH 14/92] drm/{i915, xe}: pass struct drm_plane_state instead of struct drm_crtc to ->setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The initial plane parent interface ->setup hook no longer needs the crtc for anything. Pass the struct drm_plane_state instead. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/c3db101ef5fd13c56cb3a9329adecf521a807abc.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_initial_plane.c | 2 +- drivers/gpu/drm/i915/i915_initial_plane.c | 10 +++------- drivers/gpu/drm/xe/display/xe_initial_plane.c | 8 ++------ include/drm/intel/display_parent_interface.h | 3 ++- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c index 6e7bd6c3c02d..e4d6aa438e66 100644 --- a/drivers/gpu/drm/i915/display/intel_initial_plane.c +++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c @@ -106,7 +106,7 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, intel_fb_fill_view(to_intel_framebuffer(fb), plane_state->uapi.rotation, &plane_state->view); - ret = display->parent->initial_plane->setup(&crtc->base, plane_config, fb, vma); + ret = display->parent->initial_plane->setup(plane->base.state, plane_config, fb, vma); if (ret) goto nofb; diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index 5fe96b52d2cd..40d4f990f23c 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -264,17 +264,13 @@ i915_alloc_initial_plane_obj(struct drm_crtc *_crtc, } static int -i915_initial_plane_setup(struct drm_crtc *_crtc, +i915_initial_plane_setup(struct drm_plane_state *_plane_state, struct intel_initial_plane_config *plane_config, struct drm_framebuffer *fb, struct i915_vma *vma) { - struct intel_crtc *crtc = to_intel_crtc(_crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct intel_plane *plane = - to_intel_plane(crtc->base.primary); - struct intel_plane_state *plane_state = - to_intel_plane_state(plane->base.state); + struct intel_plane_state *plane_state = to_intel_plane_state(_plane_state); + struct drm_i915_private *dev_priv = to_i915(_plane_state->plane->dev); __i915_vma_pin(vma); plane_state->ggtt_vma = i915_vma_get(vma); diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c index 45513fd79766..9999bc07743b 100644 --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c @@ -158,16 +158,12 @@ xe_alloc_initial_plane_obj(struct drm_crtc *_crtc, } static int -xe_initial_plane_setup(struct drm_crtc *_crtc, +xe_initial_plane_setup(struct drm_plane_state *_plane_state, struct intel_initial_plane_config *plane_config, struct drm_framebuffer *fb, struct i915_vma *_unused) { - struct intel_crtc *crtc = to_intel_crtc(_crtc); - struct intel_plane *plane = - to_intel_plane(crtc->base.primary); - struct intel_plane_state *plane_state = - to_intel_plane_state(plane->base.state); + struct intel_plane_state *plane_state = to_intel_plane_state(_plane_state); struct i915_vma *vma; vma = intel_fb_pin_to_ggtt(fb, &plane_state->view.gtt, diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index f0f379ae912d..129e2b9e9a21 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -11,6 +11,7 @@ struct drm_crtc; struct drm_device; struct drm_framebuffer; struct drm_gem_object; +struct drm_plane_state; struct drm_scanout_buffer; struct i915_vma; struct intel_hdcp_gsc_context; @@ -33,7 +34,7 @@ struct intel_display_hdcp_interface { struct intel_display_initial_plane_interface { void (*vblank_wait)(struct drm_crtc *crtc); struct drm_gem_object *(*alloc_obj)(struct drm_crtc *crtc, struct intel_initial_plane_config *plane_config); - int (*setup)(struct drm_crtc *crtc, struct intel_initial_plane_config *plane_config, + int (*setup)(struct drm_plane_state *plane_state, struct intel_initial_plane_config *plane_config, struct drm_framebuffer *fb, struct i915_vma *vma); void (*config_fini)(struct intel_initial_plane_config *plane_configs); }; From 82eaf3459dbf92ea78243150508740c007e0eea7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:28 +0200 Subject: [PATCH 15/92] drm/{i915, xe}: pass struct drm_device instead of drm_device to ->alloc_obj MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The initial plane parent interface ->alloc_obj hook no longer needs the crtc for anything. Pass struct drm_device instead. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/7a40381be6d98dc0916a5447be5dd6cba86cfd0a.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_initial_plane.c | 7 +++---- drivers/gpu/drm/i915/i915_initial_plane.c | 5 ++--- drivers/gpu/drm/xe/display/xe_initial_plane.c | 7 ++----- include/drm/intel/display_parent_interface.h | 2 +- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c index e4d6aa438e66..ee545c033da6 100644 --- a/drivers/gpu/drm/i915/display/intel_initial_plane.c +++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c @@ -47,10 +47,9 @@ intel_reuse_initial_plane_obj(struct intel_crtc *this, } static struct drm_gem_object * -intel_alloc_initial_plane_obj(struct intel_crtc *crtc, +intel_alloc_initial_plane_obj(struct intel_display *display, struct intel_initial_plane_config *plane_config) { - struct intel_display *display = to_intel_display(crtc); struct intel_framebuffer *fb = plane_config->fb; switch (fb->base.modifier) { @@ -65,7 +64,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, return NULL; } - return display->parent->initial_plane->alloc_obj(&crtc->base, plane_config); + return display->parent->initial_plane->alloc_obj(display->drm, plane_config); } static void @@ -88,7 +87,7 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, if (!plane_config->fb) return; - if (intel_alloc_initial_plane_obj(crtc, plane_config)) { + if (intel_alloc_initial_plane_obj(display, plane_config)) { fb = &plane_config->fb->base; vma = plane_config->vma; } else { diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index 40d4f990f23c..de90ca69e0bb 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -228,11 +228,10 @@ initial_plane_vma(struct intel_display *display, } static struct drm_gem_object * -i915_alloc_initial_plane_obj(struct drm_crtc *_crtc, +i915_alloc_initial_plane_obj(struct drm_device *drm, struct intel_initial_plane_config *plane_config) { - struct intel_crtc *crtc = to_intel_crtc(_crtc); - struct intel_display *display = to_intel_display(crtc); + struct intel_display *display = to_intel_display(drm); struct drm_mode_fb_cmd2 mode_cmd = {}; struct drm_framebuffer *fb = &plane_config->fb->base; struct i915_vma *vma; diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c index 9999bc07743b..4cfeafcc158d 100644 --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c @@ -14,8 +14,6 @@ #include "i915_vma.h" #include "intel_crtc.h" -#include "intel_display.h" -#include "intel_display_core.h" #include "intel_display_regs.h" #include "intel_display_types.h" #include "intel_fb.h" @@ -122,11 +120,10 @@ initial_plane_bo(struct xe_device *xe, } static struct drm_gem_object * -xe_alloc_initial_plane_obj(struct drm_crtc *_crtc, +xe_alloc_initial_plane_obj(struct drm_device *drm, struct intel_initial_plane_config *plane_config) { - struct intel_crtc *crtc = to_intel_crtc(_crtc); - struct xe_device *xe = to_xe_device(crtc->base.dev); + struct xe_device *xe = to_xe_device(drm); struct drm_mode_fb_cmd2 mode_cmd = { 0 }; struct drm_framebuffer *fb = &plane_config->fb->base; struct xe_bo *bo; diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 129e2b9e9a21..ce946859a3a9 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -33,7 +33,7 @@ struct intel_display_hdcp_interface { struct intel_display_initial_plane_interface { void (*vblank_wait)(struct drm_crtc *crtc); - struct drm_gem_object *(*alloc_obj)(struct drm_crtc *crtc, struct intel_initial_plane_config *plane_config); + struct drm_gem_object *(*alloc_obj)(struct drm_device *drm, struct intel_initial_plane_config *plane_config); int (*setup)(struct drm_plane_state *plane_state, struct intel_initial_plane_config *plane_config, struct drm_framebuffer *fb, struct i915_vma *vma); void (*config_fini)(struct intel_initial_plane_config *plane_configs); From a6e6f8b50bbb2b7c12f09a4f9c5f5d9c67b45f8b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 15 Dec 2025 17:28:29 +0200 Subject: [PATCH 16/92] drm/i915: drop dependency on struct intel_display from i915 initial plane MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The i915 core initial plane handling doesn't actually need struct intel_display for anything. Switch to i915 specific data structures in i915 core code. Reviewed-by: Ville Syrjälä Link: https://patch.msgid.link/58d7605a16b360080921ff2af7120b6da2eb042d.1765812266.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_initial_plane.c | 43 +++++++++-------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index de90ca69e0bb..7fb52d81f7b6 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -7,8 +7,6 @@ #include #include "display/intel_crtc.h" -#include "display/intel_display.h" -#include "display/intel_display_core.h" #include "display/intel_display_types.h" #include "display/intel_fb.h" #include "gem/i915_gem_lmem.h" @@ -23,11 +21,9 @@ static void i915_initial_plane_vblank_wait(struct drm_crtc *crtc) } static enum intel_memory_type -initial_plane_memory_type(struct intel_display *display) +initial_plane_memory_type(struct drm_i915_private *i915) { - struct drm_i915_private *i915 = to_i915(display->drm); - - if (display->platform.dgfx) + if (IS_DGFX(i915)) return INTEL_MEMORY_LOCAL; else if (HAS_LMEMBAR_SMEM_STOLEN(i915)) return INTEL_MEMORY_STOLEN_LOCAL; @@ -36,10 +32,9 @@ initial_plane_memory_type(struct intel_display *display) } static bool -initial_plane_phys(struct intel_display *display, +initial_plane_phys(struct drm_i915_private *i915, struct intel_initial_plane_config *plane_config) { - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_ggtt *ggtt = to_gt(i915)->ggtt; struct intel_memory_region *mem; enum intel_memory_type mem_type; @@ -47,10 +42,10 @@ initial_plane_phys(struct intel_display *display, dma_addr_t dma_addr; u32 base; - mem_type = initial_plane_memory_type(display); + mem_type = initial_plane_memory_type(i915); mem = intel_memory_region_by_type(i915, mem_type); if (!mem) { - drm_dbg_kms(display->drm, + drm_dbg_kms(&i915->drm, "Initial plane memory region (type %s) not initialized\n", intel_memory_type_str(mem_type)); return false; @@ -61,27 +56,24 @@ initial_plane_phys(struct intel_display *display, dma_addr = intel_ggtt_read_entry(&ggtt->vm, base, &is_present, &is_local); if (!is_present) { - drm_err(display->drm, - "Initial plane FB PTE not present\n"); + drm_err(&i915->drm, "Initial plane FB PTE not present\n"); return false; } if (intel_memory_type_is_local(mem->type) != is_local) { - drm_err(display->drm, - "Initial plane FB PTE unsuitable for %s\n", + drm_err(&i915->drm, "Initial plane FB PTE unsuitable for %s\n", mem->region.name); return false; } if (dma_addr < mem->region.start || dma_addr > mem->region.end) { - drm_err(display->drm, + drm_err(&i915->drm, "Initial plane programming using invalid range, dma_addr=%pa (%s [%pa-%pa])\n", &dma_addr, mem->region.name, &mem->region.start, &mem->region.end); return false; } - drm_dbg(display->drm, - "Using dma_addr=%pa, based on initial plane programming\n", + drm_dbg(&i915->drm, "Using dma_addr=%pa, based on initial plane programming\n", &dma_addr); plane_config->phys_base = dma_addr - mem->region.start; @@ -91,10 +83,9 @@ initial_plane_phys(struct intel_display *display, } static struct i915_vma * -initial_plane_vma(struct intel_display *display, +initial_plane_vma(struct drm_i915_private *i915, struct intel_initial_plane_config *plane_config) { - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_memory_region *mem; struct drm_i915_gem_object *obj; struct drm_mm_node orig_mm = {}; @@ -107,7 +98,7 @@ initial_plane_vma(struct intel_display *display, if (plane_config->size == 0) return NULL; - if (!initial_plane_phys(display, plane_config)) + if (!initial_plane_phys(i915, plane_config)) return NULL; phys_base = plane_config->phys_base; @@ -126,7 +117,7 @@ initial_plane_vma(struct intel_display *display, if (IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) && mem == i915->mm.stolen_region && size * 2 > i915->dsm.usable_size) { - drm_dbg_kms(display->drm, "Initial FB size exceeds half of stolen, discarding\n"); + drm_dbg_kms(&i915->drm, "Initial FB size exceeds half of stolen, discarding\n"); return NULL; } @@ -134,7 +125,7 @@ initial_plane_vma(struct intel_display *display, I915_BO_ALLOC_USER | I915_BO_PREALLOC); if (IS_ERR(obj)) { - drm_dbg_kms(display->drm, "Failed to preallocate initial FB in %s\n", + drm_dbg_kms(&i915->drm, "Failed to preallocate initial FB in %s\n", mem->region.name); return NULL; } @@ -214,7 +205,7 @@ initial_plane_vma(struct intel_display *display, if (drm_mm_node_allocated(&orig_mm)) drm_mm_remove_node(&orig_mm); - drm_dbg_kms(display->drm, + drm_dbg_kms(&i915->drm, "Initial plane fb bound to 0x%x in the ggtt (original 0x%x)\n", i915_ggtt_offset(vma), plane_config->base); @@ -231,12 +222,12 @@ static struct drm_gem_object * i915_alloc_initial_plane_obj(struct drm_device *drm, struct intel_initial_plane_config *plane_config) { - struct intel_display *display = to_intel_display(drm); + struct drm_i915_private *i915 = to_i915(drm); struct drm_mode_fb_cmd2 mode_cmd = {}; struct drm_framebuffer *fb = &plane_config->fb->base; struct i915_vma *vma; - vma = initial_plane_vma(display, plane_config); + vma = initial_plane_vma(i915, plane_config); if (!vma) return NULL; @@ -250,7 +241,7 @@ i915_alloc_initial_plane_obj(struct drm_device *drm, if (intel_framebuffer_init(to_intel_framebuffer(fb), intel_bo_to_drm_bo(vma->obj), fb->format, &mode_cmd)) { - drm_dbg_kms(display->drm, "intel fb init failed\n"); + drm_dbg_kms(&i915->drm, "intel fb init failed\n"); goto err_vma; } From 7394321a06638bf5132fec8d817cdfedc26057c2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 19 Dec 2025 12:40:36 +0200 Subject: [PATCH 17/92] drm/xe/display: drop i915_utils.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the i915 switch to generic fault injection, display no longer needs the compat i915_utils.h. Remove it, along with a few includes. Reviewed-by: Michał Grzelak Link: https://patch.msgid.link/20251219104036.855258-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_connector.c | 2 -- drivers/gpu/drm/i915/display/intel_display_driver.c | 2 -- drivers/gpu/drm/xe/compat-i915-headers/i915_utils.h | 7 ------- 3 files changed, 11 deletions(-) delete mode 100644 drivers/gpu/drm/xe/compat-i915-headers/i915_utils.h diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c index c128bc4215c4..682bf1be350d 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.c +++ b/drivers/gpu/drm/i915/display/intel_connector.c @@ -31,8 +31,6 @@ #include #include -#include "i915_drv.h" -#include "i915_utils.h" /* for i915_inject_probe_failure() */ #include "intel_connector.h" #include "intel_display_core.h" #include "intel_display_debugfs.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 468a6e96bb84..268b1de45b81 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -18,8 +18,6 @@ #include #include -#include "i915_drv.h" -#include "i915_utils.h" /* for i915_inject_probe_failure() */ #include "i9xx_wm.h" #include "intel_acpi.h" #include "intel_atomic.h" diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_utils.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_utils.h deleted file mode 100644 index 3639721f0bf8..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_utils.h +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -/* for a couple of users under i915/display */ -#define i915_inject_probe_failure(unused) ((unused) && 0) From fb3fba6933d169a4a12a7aa33cb68abfeed62ef4 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Tue, 23 Dec 2025 12:04:22 +0530 Subject: [PATCH 18/92] drm/i915/cx0: Use the consolidated HDMI tables Use the consolidated HDMI tables before we try to compute them via algorithm. The reason is that these are the ideal values and even though the values calculated via the HDMI algorithm are correct but not always ideal. This is done for C20 and already exists for C10. Signed-off-by: Suraj Kandpal Reviewed-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223063422.1444968-1-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 2c87c58812da..7288065d2461 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -2671,15 +2671,18 @@ static int intel_c20pll_calc_state(const struct intel_crtc_state *crtc_state, hw_state->cx0pll.use_c10 = false; hw_state->cx0pll.lane_count = crtc_state->lane_count; - /* try computed C20 HDMI tables before using consolidated tables */ - if (!is_dp) - /* TODO: Update SSC state for HDMI as well */ - err = intel_c20_compute_hdmi_tmds_pll(crtc_state, &hw_state->cx0pll.c20); - + /* + * Try the ideal C20 HDMI tables before computing them, since the calculated + * values, although correct, may not be optimal. + */ if (err) err = intel_c20pll_calc_state_from_table(crtc_state, encoder, &hw_state->cx0pll); + /* TODO: Update SSC state for HDMI as well */ + if (!is_dp && err) + err = intel_c20_compute_hdmi_tmds_pll(crtc_state, &hw_state->cx0pll.c20); + if (err) return err; From 345ad34565c371f71aeb37d048c845a0fea7eb3a Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Tue, 23 Dec 2025 20:38:26 +0530 Subject: [PATCH 19/92] drm/i915/vdsc: Account for DSC slice overhead in intel_vdsc_min_cdclk() When DSC is enabled on a pipe, the pipe pixel rate input to the CDCLK frequency and pipe joining calculation needs an adjustment to account for compression overhead "bubbles" added at each horizontal slice boundary. Account for this overhead while computing min cdclk required for DSC. v2: - Get rid of the scaling factor and return unchanged pixel-rate instead of 0. v3: - Use mul_u32_u32() for the bubble-adjusted pixel rate to avoid 64x64 multiplication and drop redundant casts in DIV_ROUND_UP_ULL(). (Imre) Bspec:68912 Signed-off-by: Ankit Nautiyal Reviewed-by: Imre Deak Link: https://patch.msgid.link/20251223150826.2591182-1-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_vdsc.c | 35 ++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index ad5fe841e4b3..5493082f30a7 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -1050,15 +1050,40 @@ void intel_vdsc_state_dump(struct drm_printer *p, int indent, drm_dsc_dump_config(p, indent, &crtc_state->dsc.config); } +static +int intel_dsc_get_pixel_rate_with_dsc_bubbles(struct intel_display *display, + int pixel_rate, int htotal, + int dsc_horizontal_slices) +{ + int dsc_slice_bubbles; + u64 num; + + if (drm_WARN_ON(display->drm, !htotal)) + return pixel_rate; + + dsc_slice_bubbles = 14 * dsc_horizontal_slices; + num = mul_u32_u32(pixel_rate, (htotal + dsc_slice_bubbles)); + + return DIV_ROUND_UP_ULL(num, htotal); +} + int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state); + int htotal = crtc_state->hw.adjusted_mode.crtc_htotal; + int dsc_slices = crtc_state->dsc.slice_count; + int pixel_rate; int min_cdclk; if (!crtc_state->dsc.compression_enable) return 0; + pixel_rate = intel_dsc_get_pixel_rate_with_dsc_bubbles(display, + crtc_state->pixel_rate, + htotal, + dsc_slices); + /* * When we decide to use only one VDSC engine, since * each VDSC operates with 1 ppc throughput, pixel clock @@ -1066,7 +1091,7 @@ int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state) * If there 2 VDSC engines, then pixel clock can't be higher than * VDSC clock(cdclk) * 2 and so on. */ - min_cdclk = DIV_ROUND_UP(crtc_state->pixel_rate, num_vdsc_instances); + min_cdclk = DIV_ROUND_UP(pixel_rate, num_vdsc_instances); if (crtc_state->joiner_pipes) { int pixel_clock = intel_dp_mode_to_fec_clock(crtc_state->hw.adjusted_mode.clock); @@ -1084,9 +1109,11 @@ int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state) * => CDCLK >= compressed_bpp * Pixel clock / 2 * Bigjoiner Interface bits */ int bigjoiner_interface_bits = DISPLAY_VER(display) >= 14 ? 36 : 24; - int min_cdclk_bj = - (fxp_q4_to_int_roundup(crtc_state->dsc.compressed_bpp_x16) * - pixel_clock) / (2 * bigjoiner_interface_bits); + int adjusted_pixel_rate = + intel_dsc_get_pixel_rate_with_dsc_bubbles(display, pixel_clock, + htotal, dsc_slices); + int min_cdclk_bj = (fxp_q4_to_int_roundup(crtc_state->dsc.compressed_bpp_x16) * + adjusted_pixel_rate) / (2 * bigjoiner_interface_bits); min_cdclk = max(min_cdclk, min_cdclk_bj); } From 765ec7411b9d7a4b1f19c5ca3191c9039ac63c09 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 22 Dec 2025 14:34:00 +0200 Subject: [PATCH 20/92] drm/i915: remove unused dev_priv local variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 35ec71285c93 ("drm/i915/pc8: Add parent interface for PC8 forcewake tricks"), the __maybe_unused dev_priv has become definitely unused. Remove, along with the i915_drv.h include. Reviewed-by: Michał Grzelak Link: https://patch.msgid.link/222871a73efbe1049862d11a03abf253611e46b1.1766406794.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_power.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 47042a4c3a30..d27397f43863 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -8,7 +8,6 @@ #include -#include "i915_drv.h" #include "i915_reg.h" #include "intel_backlight_regs.h" #include "intel_cdclk.h" @@ -31,6 +30,7 @@ #include "intel_pmdemand.h" #include "intel_pps_regs.h" #include "intel_snps_phy.h" +#include "intel_step.h" #include "skl_watermark.h" #include "skl_watermark_regs.h" #include "vlv_sideband.h" @@ -1328,7 +1328,6 @@ static void hsw_disable_lcpll(struct intel_display *display, */ static void hsw_restore_lcpll(struct intel_display *display) { - struct drm_i915_private __maybe_unused *dev_priv = to_i915(display->drm); u32 val; int ret; From 5f1a87efd60d0d7ca612ea33127bccefbbe07a07 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 22 Dec 2025 14:34:01 +0200 Subject: [PATCH 21/92] drm/xe/compat: remove unused forcewake get/put macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 35ec71285c93 ("drm/i915/pc8: Add parent interface for PC8 forcewake tricks"), the compat intel_uncore_forcewake_{get,put} and FORCEWAKE_ALL macros have become unused. Remove them. Reviewed-by: Michał Grzelak Link: https://patch.msgid.link/5081b00a6fa20bdbcc1c973c6920cd590e1dc98f.1766406794.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h index d93ddacdf743..0d60a0bf2e4b 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h @@ -10,8 +10,6 @@ #include "xe_device_types.h" #include "xe_mmio.h" -#define FORCEWAKE_ALL XE_FORCEWAKE_ALL - static inline struct intel_uncore *to_intel_uncore(struct drm_device *drm) { return &to_xe_device(drm)->uncore; @@ -154,9 +152,6 @@ static inline void intel_uncore_write_notrace(struct intel_uncore *uncore, xe_mmio_write32(__compat_uncore_to_mmio(uncore), reg, val); } -#define intel_uncore_forcewake_get(x, y) do { } while (0) -#define intel_uncore_forcewake_put(x, y) do { } while (0) - #define intel_uncore_arm_unclaimed_mmio_detection(x) do { } while (0) #endif /* __INTEL_UNCORE_H__ */ From 80d3db9b62d2740b7cd1a10228ec04f6d61f1bae Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 22 Dec 2025 14:34:02 +0200 Subject: [PATCH 22/92] drm/xe/compat: convert uncore macro to static inlines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use static inline instead of macro for intel_uncore_arm_unclaimed_mmio_detection() to avoid the need for __maybe_unused annotations. v2: Rebase, intel_uncore_arm_unclaimed_mmio_detection() Cc: Ville Syrjala Reviewed-by: Ville Syrjälä # v1 Reviewed-by: Michał Grzelak Link: https://patch.msgid.link/7ddee71952315e70e4a7df23638100b664e293bd.1766406794.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 1e3c5761fc5e..c7f4d5e3b4d1 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7381,7 +7381,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, static void intel_atomic_commit_tail(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private __maybe_unused *dev_priv = to_i915(display->drm); + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {}; diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h index 0d60a0bf2e4b..c05d4c4292d3 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h @@ -152,6 +152,10 @@ static inline void intel_uncore_write_notrace(struct intel_uncore *uncore, xe_mmio_write32(__compat_uncore_to_mmio(uncore), reg, val); } -#define intel_uncore_arm_unclaimed_mmio_detection(x) do { } while (0) +static inline bool +intel_uncore_arm_unclaimed_mmio_detection(struct intel_uncore *uncore) +{ + return false; +} #endif /* __INTEL_UNCORE_H__ */ From fb48cb435500dce125e1ba1640def3df251b7301 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 22 Dec 2025 14:34:03 +0200 Subject: [PATCH 23/92] drm/i915/display: use to_intel_uncore() to avoid i915_drv.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A number of places that include i915_drv.h only need it to get from display to i915 to uncore. We have to_intel_uncore() for that, use it to avoid the i915_drv.h include. v2: Rebase Cc: Ville Syrjala Reviewed-by: Ville Syrjälä Reviewed-by: Michał Grzelak Link: https://patch.msgid.link/44a5d526a097ab9276e60162263fa8cd23325ce7.1766406794.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/i9xx_wm.c | 17 ++++---- drivers/gpu/drm/i915/display/intel_bw.c | 19 ++++----- drivers/gpu/drm/i915/display/intel_display.c | 4 +- drivers/gpu/drm/i915/display/intel_dram.c | 42 +++++++++----------- drivers/gpu/drm/i915/display/intel_rom.c | 8 ++-- drivers/gpu/drm/i915/display/intel_vblank.c | 13 +++--- 6 files changed, 48 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 167277cd8877..39dfceb438ae 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -7,7 +7,6 @@ #include -#include "i915_drv.h" #include "i915_reg.h" #include "i9xx_wm.h" #include "i9xx_wm_regs.h" @@ -17,6 +16,7 @@ #include "intel_display.h" #include "intel_display_regs.h" #include "intel_display_trace.h" +#include "intel_display_utils.h" #include "intel_dram.h" #include "intel_fb.h" #include "intel_mchbar_regs.h" @@ -1863,8 +1863,7 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct intel_uncore *uncore = &dev_priv->uncore; + struct intel_uncore *uncore = to_intel_uncore(display->drm); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct vlv_fifo_state *fifo_state = @@ -2743,12 +2742,12 @@ static void ilk_compute_wm_level(struct intel_display *display, static void hsw_read_wm_latency(struct intel_display *display, u16 wm[]) { - struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); u64 sskpd; display->wm.num_levels = 5; - sskpd = intel_uncore_read64(&i915->uncore, MCH_SSKPD); + sskpd = intel_uncore_read64(uncore, MCH_SSKPD); wm[0] = REG_FIELD_GET64(SSKPD_NEW_WM0_MASK_HSW, sskpd); if (wm[0] == 0) @@ -2761,12 +2760,12 @@ static void hsw_read_wm_latency(struct intel_display *display, u16 wm[]) static void snb_read_wm_latency(struct intel_display *display, u16 wm[]) { - struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 sskpd; display->wm.num_levels = 4; - sskpd = intel_uncore_read(&i915->uncore, MCH_SSKPD); + sskpd = intel_uncore_read(uncore, MCH_SSKPD); wm[0] = REG_FIELD_GET(SSKPD_WM0_MASK_SNB, sskpd); wm[1] = REG_FIELD_GET(SSKPD_WM1_MASK_SNB, sskpd); @@ -2776,12 +2775,12 @@ static void snb_read_wm_latency(struct intel_display *display, u16 wm[]) static void ilk_read_wm_latency(struct intel_display *display, u16 wm[]) { - struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 mltr; display->wm.num_levels = 3; - mltr = intel_uncore_read(&i915->uncore, MLTR_ILK); + mltr = intel_uncore_read(uncore, MLTR_ILK); /* ILK primary LP0 latency is 700 ns */ wm[0] = 7; diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index d27835ed49c2..4ee3f5172f4e 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -6,7 +6,6 @@ #include #include -#include "i915_drv.h" #include "i915_reg.h" #include "intel_bw.h" #include "intel_crtc.h" @@ -75,11 +74,11 @@ static int dg1_mchbar_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { - struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 dclk_ratio, dclk_reference; u32 val; - val = intel_uncore_read(&i915->uncore, SA_PERF_STATUS_0_0_0_MCHBAR_PC); + val = intel_uncore_read(uncore, 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 */ @@ -87,18 +86,18 @@ static int dg1_mchbar_read_qgv_point_info(struct intel_display *display, dclk_reference = 8; /* 8 * 16.666 MHz = 133 MHz */ sp->dclk = DIV_ROUND_UP((16667 * dclk_ratio * dclk_reference) + 500, 1000); - val = intel_uncore_read(&i915->uncore, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU); + val = intel_uncore_read(uncore, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU); if (val & DG1_GEAR_TYPE) sp->dclk *= 2; if (sp->dclk == 0) return -EINVAL; - val = intel_uncore_read(&i915->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR); + val = intel_uncore_read(uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR); sp->t_rp = REG_FIELD_GET(DG1_DRAM_T_RP_MASK, val); sp->t_rdpre = REG_FIELD_GET(DG1_DRAM_T_RDPRE_MASK, val); - val = intel_uncore_read(&i915->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH); + val = intel_uncore_read(uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH); sp->t_rcd = REG_FIELD_GET(DG1_DRAM_T_RCD_MASK, val); sp->t_ras = REG_FIELD_GET(DG1_DRAM_T_RAS_MASK, val); @@ -212,14 +211,12 @@ static int icl_pcode_restrict_qgv_points(struct intel_display *display, static int mtl_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { - struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 val, val2; u16 dclk; - val = intel_uncore_read(&i915->uncore, - MTL_MEM_SS_INFO_QGV_POINT_LOW(point)); - val2 = intel_uncore_read(&i915->uncore, - MTL_MEM_SS_INFO_QGV_POINT_HIGH(point)); + val = intel_uncore_read(uncore, MTL_MEM_SS_INFO_QGV_POINT_LOW(point)); + val2 = intel_uncore_read(uncore, 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->t_rp = REG_FIELD_GET(MTL_TRP_MASK, val); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index c7f4d5e3b4d1..cd482e5ff929 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7381,7 +7381,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, static void intel_atomic_commit_tail(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {}; @@ -7591,7 +7591,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * so enable debugging for the next modeset - and hope we catch * the culprit. */ - intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore); + intel_uncore_arm_unclaimed_mmio_detection(uncore); } /* * Delay re-enabling DC states by 17 ms to avoid the off->on->off diff --git a/drivers/gpu/drm/i915/display/intel_dram.c b/drivers/gpu/drm/i915/display/intel_dram.c index 019a722a38bf..170de304fe96 100644 --- a/drivers/gpu/drm/i915/display/intel_dram.c +++ b/drivers/gpu/drm/i915/display/intel_dram.c @@ -8,7 +8,6 @@ #include #include -#include "i915_drv.h" #include "i915_reg.h" #include "intel_display_core.h" #include "intel_display_utils.h" @@ -58,18 +57,18 @@ const char *intel_dram_type_str(enum intel_dram_type type) static enum intel_dram_type pnv_dram_type(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); - return intel_uncore_read(&i915->uncore, CSHRDDR3CTL) & CSHRDDR3CTL_DDR3 ? + return intel_uncore_read(uncore, CSHRDDR3CTL) & CSHRDDR3CTL_DDR3 ? INTEL_DRAM_DDR3 : INTEL_DRAM_DDR2; } static unsigned int pnv_mem_freq(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 tmp; - tmp = intel_uncore_read(&dev_priv->uncore, CLKCFG); + tmp = intel_uncore_read(uncore, CLKCFG); switch (tmp & CLKCFG_MEM_MASK) { case CLKCFG_MEM_533: @@ -85,10 +84,10 @@ static unsigned int pnv_mem_freq(struct intel_display *display) static unsigned int ilk_mem_freq(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); u16 ddrpll; - ddrpll = intel_uncore_read16(&dev_priv->uncore, DDRMPLL1); + ddrpll = intel_uncore_read16(uncore, DDRMPLL1); switch (ddrpll & 0xff) { case 0xc: return 800000; @@ -158,7 +157,7 @@ unsigned int intel_mem_freq(struct intel_display *display) static unsigned int i9xx_fsb_freq(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 fsb; /* @@ -169,7 +168,7 @@ static unsigned int i9xx_fsb_freq(struct intel_display *display) * don't know which registers have that information, * and all the relevant docs have gone to bit heaven :( */ - fsb = intel_uncore_read(&i915->uncore, CLKCFG) & CLKCFG_FSB_MASK; + fsb = intel_uncore_read(uncore, CLKCFG) & CLKCFG_FSB_MASK; if (display->platform.pineview || display->platform.mobile) { switch (fsb) { @@ -214,10 +213,10 @@ static unsigned int i9xx_fsb_freq(struct intel_display *display) static unsigned int ilk_fsb_freq(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); u16 fsb; - fsb = intel_uncore_read16(&dev_priv->uncore, CSIPLL0) & 0x3ff; + fsb = intel_uncore_read16(uncore, CSIPLL0) & 0x3ff; switch (fsb) { case 0x00c: @@ -484,7 +483,7 @@ intel_is_dram_symmetric(const struct dram_channel_info *ch0, static int skl_dram_get_channels_info(struct intel_display *display, struct dram_info *dram_info) { - struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); struct dram_channel_info ch0 = {}, ch1 = {}; u32 val; int ret; @@ -492,14 +491,12 @@ skl_dram_get_channels_info(struct intel_display *display, struct dram_info *dram /* Assume 16Gb+ DIMMs are present until proven otherwise */ dram_info->has_16gb_dimms = true; - val = intel_uncore_read(&i915->uncore, - SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN); + val = intel_uncore_read(uncore, SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN); ret = skl_dram_get_channel_info(display, &ch0, 0, val); if (ret == 0) dram_info->num_channels++; - val = intel_uncore_read(&i915->uncore, - SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN); + val = intel_uncore_read(uncore, SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN); ret = skl_dram_get_channel_info(display, &ch1, 1, val); if (ret == 0) dram_info->num_channels++; @@ -530,11 +527,10 @@ skl_dram_get_channels_info(struct intel_display *display, struct dram_info *dram static enum intel_dram_type skl_get_dram_type(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 val; - val = intel_uncore_read(&i915->uncore, - SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN); + val = intel_uncore_read(uncore, SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN); switch (val & SKL_DRAM_DDR_TYPE_MASK) { case SKL_DRAM_DDR_TYPE_DDR3: @@ -645,7 +641,7 @@ static void bxt_get_dimm_info(struct dram_dimm_info *dimm, u32 val) static int bxt_get_dram_info(struct intel_display *display, struct dram_info *dram_info) { - struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 val; u8 valid_ranks = 0; int i; @@ -657,7 +653,7 @@ static int bxt_get_dram_info(struct intel_display *display, struct dram_info *dr struct dram_dimm_info dimm; enum intel_dram_type type; - val = intel_uncore_read(&i915->uncore, BXT_D_CR_DRP0_DUNIT(i)); + val = intel_uncore_read(uncore, BXT_D_CR_DRP0_DUNIT(i)); if (val == 0xFFFFFFFF) continue; @@ -770,8 +766,8 @@ static int gen12_get_dram_info(struct intel_display *display, struct dram_info * static int xelpdp_get_dram_info(struct intel_display *display, struct dram_info *dram_info) { - struct drm_i915_private *i915 = to_i915(display->drm); - u32 val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_GLOBAL); + struct intel_uncore *uncore = to_intel_uncore(display->drm); + u32 val = intel_uncore_read(uncore, MTL_MEM_SS_INFO_GLOBAL); switch (REG_FIELD_GET(MTL_DDR_TYPE_MASK, val)) { case 0: diff --git a/drivers/gpu/drm/i915/display/intel_rom.c b/drivers/gpu/drm/i915/display/intel_rom.c index 2f17dc856e7f..c8f615315310 100644 --- a/drivers/gpu/drm/i915/display/intel_rom.c +++ b/drivers/gpu/drm/i915/display/intel_rom.c @@ -3,7 +3,10 @@ * Copyright © 2024 Intel Corporation */ -#include "i915_drv.h" +#include + +#include + #include "i915_reg.h" #include "intel_rom.h" @@ -41,7 +44,6 @@ static u16 spi_read16(struct intel_rom *rom, loff_t offset) struct intel_rom *intel_rom_spi(struct drm_device *drm) { - struct drm_i915_private *i915 = to_i915(drm); struct intel_rom *rom; u32 static_region; @@ -49,7 +51,7 @@ struct intel_rom *intel_rom_spi(struct drm_device *drm) if (!rom) return NULL; - rom->uncore = &i915->uncore; + rom->uncore = to_intel_uncore(drm); static_region = intel_uncore_read(rom->uncore, SPI_STATIC_REGIONS); static_region &= OPTIONROM_SPI_REGIONID_MASK; diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index 671f357c6563..d7028ac2c4bd 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -8,7 +8,6 @@ #include #include -#include "i915_drv.h" #include "intel_color.h" #include "intel_crtc.h" #include "intel_de.h" @@ -305,17 +304,17 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) */ #ifdef I915 static void intel_vblank_section_enter(struct intel_display *display) - __acquires(i915->uncore.lock) + __acquires(uncore->lock) { - struct drm_i915_private *i915 = to_i915(display->drm); - spin_lock(&i915->uncore.lock); + struct intel_uncore *uncore = to_intel_uncore(display->drm); + spin_lock(&uncore->lock); } static void intel_vblank_section_exit(struct intel_display *display) - __releases(i915->uncore.lock) + __releases(uncore->lock) { - struct drm_i915_private *i915 = to_i915(display->drm); - spin_unlock(&i915->uncore.lock); + struct intel_uncore *uncore = to_intel_uncore(display->drm); + spin_unlock(&uncore->lock); } #else static void intel_vblank_section_enter(struct intel_display *display) From 71813ecc8436a6b10d528b305a827238e98530c9 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Fri, 19 Dec 2025 11:32:54 +0530 Subject: [PATCH 24/92] drm/i915/display: Abstract pipe/trans/cursor offset calculation Introduce INTEL_DISPLAY_DEVICE_*_OFFSET() macros to compute absolute MMIO offsets for pipe, transcoder, and cursor registers. Update _MMIO_PIPE2/_MMIO_TRANS2/_MMIO_CURSOR2 to use these macros for cleaner abstraction and to prepare for external API usage (e.g. GVT). Also move DISPLAY_MMIO_BASE() to intel_display_device.h so it can be abstracted in GVT, allowing register macros to resolve via exported helpers rather than peeking into struct intel_display. v2: Wrap the macro argument usages in parenthesis. (Jani) Suggested-by: Jani Nikula Signed-off-by: Ankit Nautiyal Reviewed-by: Jani Nikula Link: https://patch.msgid.link/20251219060302.2365123-2-ankit.k.nautiyal@intel.com --- .../gpu/drm/i915/display/intel_display_device.h | 17 +++++++++++++++++ .../drm/i915/display/intel_display_reg_defs.h | 15 ++++----------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index 50b2e9ae2c18..13b6616bc496 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -260,6 +260,23 @@ struct intel_display_platforms { ((id) == ARLS_HOST_BRIDGE_PCI_ID3) || \ ((id) == ARLS_HOST_BRIDGE_PCI_ID4)) +#define INTEL_DISPLAY_DEVICE_PIPE_OFFSET(display, pipe) \ + (DISPLAY_INFO((display))->pipe_offsets[(pipe)] - \ + DISPLAY_INFO((display))->pipe_offsets[PIPE_A] + \ + DISPLAY_MMIO_BASE((display))) + +#define INTEL_DISPLAY_DEVICE_TRANS_OFFSET(display, trans) \ + (DISPLAY_INFO((display))->trans_offsets[(trans)] - \ + DISPLAY_INFO((display))->trans_offsets[TRANSCODER_A] + \ + DISPLAY_MMIO_BASE((display))) + +#define INTEL_DISPLAY_DEVICE_CURSOR_OFFSET(display, pipe) \ + (DISPLAY_INFO((display))->cursor_offsets[(pipe)] - \ + DISPLAY_INFO((display))->cursor_offsets[PIPE_A] + \ + DISPLAY_MMIO_BASE((display))) + +#define DISPLAY_MMIO_BASE(display) (DISPLAY_INFO((display))->mmio_offset) + struct intel_display_runtime_info { struct intel_display_ip_ver { u16 ver; diff --git a/drivers/gpu/drm/i915/display/intel_display_reg_defs.h b/drivers/gpu/drm/i915/display/intel_display_reg_defs.h index b83ad06f2ea7..175334b41bba 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reg_defs.h +++ b/drivers/gpu/drm/i915/display/intel_display_reg_defs.h @@ -8,8 +8,6 @@ #include "i915_reg_defs.h" -#define DISPLAY_MMIO_BASE(dev_priv) (DISPLAY_INFO(dev_priv)->mmio_offset) - #define VLV_DISPLAY_BASE 0x180000 /* @@ -36,14 +34,9 @@ * Device info offset array based helpers for groups of registers with unevenly * spaced base offsets. */ -#define _MMIO_PIPE2(display, pipe, reg) _MMIO(DISPLAY_INFO(display)->pipe_offsets[(pipe)] - \ - DISPLAY_INFO(display)->pipe_offsets[PIPE_A] + \ - DISPLAY_MMIO_BASE(display) + (reg)) -#define _MMIO_TRANS2(display, tran, reg) _MMIO(DISPLAY_INFO(display)->trans_offsets[(tran)] - \ - DISPLAY_INFO(display)->trans_offsets[TRANSCODER_A] + \ - DISPLAY_MMIO_BASE(display) + (reg)) -#define _MMIO_CURSOR2(display, pipe, reg) _MMIO(DISPLAY_INFO(display)->cursor_offsets[(pipe)] - \ - DISPLAY_INFO(display)->cursor_offsets[PIPE_A] + \ - DISPLAY_MMIO_BASE(display) + (reg)) + +#define _MMIO_PIPE2(display, pipe, reg) _MMIO(INTEL_DISPLAY_DEVICE_PIPE_OFFSET((display), (pipe)) + (reg)) +#define _MMIO_TRANS2(display, trans, reg) _MMIO(INTEL_DISPLAY_DEVICE_TRANS_OFFSET((display), (trans)) + (reg)) +#define _MMIO_CURSOR2(display, pipe, reg) _MMIO(INTEL_DISPLAY_DEVICE_CURSOR_OFFSET((display), (pipe)) + (reg)) #endif /* __INTEL_DISPLAY_REG_DEFS_H__ */ From f3255cf4490ef63b477c1142fc608cf6388e66d4 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Fri, 19 Dec 2025 11:32:55 +0530 Subject: [PATCH 25/92] drm/i915/display: Add APIs to be used by gvt to get the register offsets GVT code uses macros for register offsets that require display internal structures. This makes clean separation of display code and modularization difficult. Introduce APIs to abstract offset calculations: - intel_display_device_pipe_offset() - intel_display_device_trans_offset() - intel_display_device_cursor_offset() - intel_display_device_mmio_base() These APIs return absolute base offsets for the respective register groups, allowing GVT to compute MMIO addresses without using internal macros or struct fields. This prepares the path to separate display-dependent code from i915/gvt/*. v2: - Build GVT APIs only when GVT is actually enabled. (Jani) Signed-off-by: Ankit Nautiyal Reviewed-by: Jani Nikula (#v1) Link: https://patch.msgid.link/20251219060302.2365123-3-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/Makefile | 3 ++ .../drm/i915/display/intel_display_limits.c | 0 drivers/gpu/drm/i915/display/intel_gvt_api.c | 34 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_gvt_api.h | 20 +++++++++++ 4 files changed, 57 insertions(+) create mode 100644 drivers/gpu/drm/i915/display/intel_display_limits.c create mode 100644 drivers/gpu/drm/i915/display/intel_gvt_api.c create mode 100644 drivers/gpu/drm/i915/display/intel_gvt_api.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index fb2b21593020..fad3cf0e9ab2 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -383,6 +383,9 @@ i915-y += \ i915-$(CONFIG_DRM_I915_DP_TUNNEL) += \ display/intel_dp_tunnel.o +i915-$(CONFIG_DRM_I915_GVT) += \ + display/intel_gvt_api.o + i915-y += \ i915_perf.o diff --git a/drivers/gpu/drm/i915/display/intel_display_limits.c b/drivers/gpu/drm/i915/display/intel_display_limits.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/drivers/gpu/drm/i915/display/intel_gvt_api.c b/drivers/gpu/drm/i915/display/intel_gvt_api.c new file mode 100644 index 000000000000..b1bfe4843135 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_gvt_api.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2025 Intel Corporation + */ + +#include + +#include "intel_display_core.h" +#include "intel_display_regs.h" +#include "intel_gvt_api.h" + +u32 intel_display_device_pipe_offset(struct intel_display *display, enum pipe pipe) +{ + return INTEL_DISPLAY_DEVICE_PIPE_OFFSET(display, pipe); +} +EXPORT_SYMBOL_NS_GPL(intel_display_device_pipe_offset, "I915_GVT"); + +u32 intel_display_device_trans_offset(struct intel_display *display, enum transcoder trans) +{ + return INTEL_DISPLAY_DEVICE_TRANS_OFFSET(display, trans); +} +EXPORT_SYMBOL_NS_GPL(intel_display_device_trans_offset, "I915_GVT"); + +u32 intel_display_device_cursor_offset(struct intel_display *display, enum pipe pipe) +{ + return INTEL_DISPLAY_DEVICE_CURSOR_OFFSET(display, pipe); +} +EXPORT_SYMBOL_NS_GPL(intel_display_device_cursor_offset, "I915_GVT"); + +u32 intel_display_device_mmio_base(struct intel_display *display) +{ + return DISPLAY_MMIO_BASE(display); +} +EXPORT_SYMBOL_NS_GPL(intel_display_device_mmio_base, "I915_GVT"); diff --git a/drivers/gpu/drm/i915/display/intel_gvt_api.h b/drivers/gpu/drm/i915/display/intel_gvt_api.h new file mode 100644 index 000000000000..53c851c3479d --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_gvt_api.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright © 2025 Intel Corporation + */ + +#ifndef __INTEL_GVT_API_H__ +#define __INTEL_GVT_API_H__ + +#include + +enum pipe; +enum transcoder; +struct intel_display; + +u32 intel_display_device_pipe_offset(struct intel_display *display, enum pipe pipe); +u32 intel_display_device_trans_offset(struct intel_display *display, enum transcoder trans); +u32 intel_display_device_cursor_offset(struct intel_display *display, enum pipe pipe); +u32 intel_display_device_mmio_base(struct intel_display *display); + +#endif /* __INTEL_GVT_API_H__ */ From d6a3a678569431ed816ac490bf489541bc87b424 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Fri, 19 Dec 2025 11:32:56 +0530 Subject: [PATCH 26/92] drm/i915/gvt: Add header to use display offset functions in macros Introduce gvt/display_helpers.h to make DISPLAY_MMIO_BASE and INTEL_DISPLAY_DEVICE_*_OFFSET macros call exported display functions. This lets GVT keep using existing register macros (e.g., TRANSCONF(display, pipe)) while ensuring offset calculations happen through functions instead of accessing display internals. Ideally, we would remove the display headers that define these macros, but some macros in GVT still depend on them and have not yet been ported. Keeping those headers leads to build conflicts, so as a stopgap, we use temporary ifdef/undef blocks to override the macros with API-backed versions. These will be removed once all dependent macros are ported and the conflicting headers can be safely dropped. Note: TRANSCONF() expects a pipe index but some GVT callers pass a transcoder, causing -Werror=enum-conversion. Fix: cast to enum pipe in the GVT-side macro override. This works for all cases as TRANSCODER_{A,B,C,D} all have 1:1 mapping to PIPE_{A,B,C,D} except for TRANSCODER_EDP which is used in one place. In any case, the cast preserves the previous behaviour. v2: - Remove prefix `gvt/` while including the header file. (Jani) - Explain the rationale behind temporary ifdef/undefs and plan to drop them. (Jani). v3: - Meld the patch to cast argument to enum pipe for the pipe-offset macro. (Jani) - Add a FIXME to highlight the cast. (Jani) Signed-off-by: Ankit Nautiyal Reviewed-by: Jani Nikula Link: https://patch.msgid.link/20251219060302.2365123-4-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/gvt/cmd_parser.c | 1 + drivers/gpu/drm/i915/gvt/display.c | 1 + drivers/gpu/drm/i915/gvt/display_helpers.h | 45 ++++++++++++++++++++++ drivers/gpu/drm/i915/gvt/fb_decoder.c | 1 + drivers/gpu/drm/i915/gvt/handlers.c | 1 + 5 files changed, 49 insertions(+) create mode 100644 drivers/gpu/drm/i915/gvt/display_helpers.h diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index df04e4ead8ea..fbc8a5e28576 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -58,6 +58,7 @@ #include "gem/i915_gem_context.h" #include "gem/i915_gem_pm.h" #include "gt/intel_context.h" +#include "display_helpers.h" #define INVALID_OP (~0U) diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index 06517d1f07a2..9d6b22b2e4d0 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c @@ -46,6 +46,7 @@ #include "display/intel_cursor_regs.h" #include "display/intel_display.h" #include "display/intel_display_core.h" +#include "display_helpers.h" #include "display/intel_dpio_phy.h" #include "display/intel_sprite_regs.h" diff --git a/drivers/gpu/drm/i915/gvt/display_helpers.h b/drivers/gpu/drm/i915/gvt/display_helpers.h new file mode 100644 index 000000000000..cbe383f677d5 --- /dev/null +++ b/drivers/gpu/drm/i915/gvt/display_helpers.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright © 2025 Intel Corporation + */ + +#ifndef __DISPLAY_HELPERS_H__ +#define __DISPLAY_HELPERS_H__ + +#include "display/intel_gvt_api.h" + +#ifdef DISPLAY_MMIO_BASE +#undef DISPLAY_MMIO_BASE +#endif +#define DISPLAY_MMIO_BASE(display) \ + intel_display_device_mmio_base((display)) + +#ifdef INTEL_DISPLAY_DEVICE_PIPE_OFFSET +#undef INTEL_DISPLAY_DEVICE_PIPE_OFFSET +#endif +/* + * #FIXME: + * TRANSCONF() uses pipe-based addressing via _MMIO_PIPE2(). + * Some GVT call sites pass enum transcoder instead of enum pipe. + * Cast the argument to enum pipe for now since TRANSCODER_A..D map + * 1:1 to PIPE_A..D. + * TRANSCODER_EDP is an exception, the cast preserves the existing + * behaviour but this needs to be handled later either by using the + * correct pipe or by switching TRANSCONF() to use _MMIO_TRANS2(). + */ +#define INTEL_DISPLAY_DEVICE_PIPE_OFFSET(display, idx) \ + intel_display_device_pipe_offset((display), (enum pipe)(idx)) + +#ifdef INTEL_DISPLAY_DEVICE_TRANS_OFFSET +#undef INTEL_DISPLAY_DEVICE_TRANS_OFFSET +#endif +#define INTEL_DISPLAY_DEVICE_TRANS_OFFSET(display, trans) \ + intel_display_device_trans_offset((display), (trans)) + +#ifdef INTEL_DISPLAY_DEVICE_CURSOR_OFFSET +#undef INTEL_DISPLAY_DEVICE_CURSOR_OFFSET +#endif +#define INTEL_DISPLAY_DEVICE_CURSOR_OFFSET(display, pipe) \ + intel_display_device_cursor_offset((display), (pipe)) + +#endif /* __DISPLAY_HELPERS_H__ */ diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c b/drivers/gpu/drm/i915/gvt/fb_decoder.c index a8079cfa8e1d..c402f3b5a0ab 100644 --- a/drivers/gpu/drm/i915/gvt/fb_decoder.c +++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c @@ -46,6 +46,7 @@ #include "display/intel_display_core.h" #include "display/intel_sprite_regs.h" #include "display/skl_universal_plane_regs.h" +#include "display_helpers.h" #define PRIMARY_FORMAT_NUM 16 struct pixel_format { diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 36ea12ade849..9ada97d01b6c 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -66,6 +66,7 @@ #include "display/vlv_dsi_pll_regs.h" #include "gt/intel_gt_regs.h" #include +#include "display_helpers.h" /* XXX FIXME i915 has changed PP_XXX definition */ #define PCH_PP_STATUS _MMIO(0xc7200) From d805e879e15a126a00da2fd02cef0ad353365c6a Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Fri, 19 Dec 2025 11:32:57 +0530 Subject: [PATCH 27/92] drm/i915/gvt: Change for_each_pipe to use pipe_valid API Add a new API to check if a given pipe is valid using DISPLAY_RUNTIME_INFO() for GVT. Update GVT to use this API instead of accessing `DISPLAY_RUNTIME_INFO->pipe_mask` directly in the `for_each_pipe` macro. Since `for_each_pipe` is defined in i915/display/intel_display.h, which also contains other macros used by gvt/display.c, we cannot drop the intel_display.h header yet. This causes a build error because `for_each_pipe` is included from both i915/display/intel_display.h and gvt/display_helpers.h. To resolve this, rename the GVT macro to `gvt_for_each_pipe` and make it call the new API. This avoids exposing display internals and prepares for display modularization. v2: - Expose API to check if pipe is valid rather than the runtime info pipe mask. (Jani) - Rename the macro to `gvt_for_each_pipe` to resolve build error. v3: - Use EXPORT_SYMBOL_NS_GPL(..., "I915_GVT"); (Jani) - Use enum pipe at call sites instead of casting in the macro. (Jani) Signed-off-by: Ankit Nautiyal Reviewed-by: Jani Nikula Link: https://patch.msgid.link/20251219060302.2365123-5-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_gvt_api.c | 9 +++++++++ drivers/gpu/drm/i915/display/intel_gvt_api.h | 1 + drivers/gpu/drm/i915/gvt/display.c | 10 +++++----- drivers/gpu/drm/i915/gvt/display_helpers.h | 4 ++++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_gvt_api.c b/drivers/gpu/drm/i915/display/intel_gvt_api.c index b1bfe4843135..a69e249395ae 100644 --- a/drivers/gpu/drm/i915/display/intel_gvt_api.c +++ b/drivers/gpu/drm/i915/display/intel_gvt_api.c @@ -32,3 +32,12 @@ u32 intel_display_device_mmio_base(struct intel_display *display) return DISPLAY_MMIO_BASE(display); } EXPORT_SYMBOL_NS_GPL(intel_display_device_mmio_base, "I915_GVT"); + +bool intel_display_device_pipe_valid(struct intel_display *display, enum pipe pipe) +{ + if (pipe < PIPE_A || pipe >= I915_MAX_PIPES) + return false; + + return DISPLAY_RUNTIME_INFO(display)->pipe_mask & BIT(pipe); +} +EXPORT_SYMBOL_NS_GPL(intel_display_device_pipe_valid, "I915_GVT"); diff --git a/drivers/gpu/drm/i915/display/intel_gvt_api.h b/drivers/gpu/drm/i915/display/intel_gvt_api.h index 53c851c3479d..d4eea74026c6 100644 --- a/drivers/gpu/drm/i915/display/intel_gvt_api.h +++ b/drivers/gpu/drm/i915/display/intel_gvt_api.h @@ -16,5 +16,6 @@ u32 intel_display_device_pipe_offset(struct intel_display *display, enum pipe pi u32 intel_display_device_trans_offset(struct intel_display *display, enum transcoder trans); u32 intel_display_device_cursor_offset(struct intel_display *display, enum pipe pipe); u32 intel_display_device_mmio_base(struct intel_display *display); +bool intel_display_device_pipe_valid(struct intel_display *display, enum pipe pipe); #endif /* __INTEL_GVT_API_H__ */ diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index 9d6b22b2e4d0..1d0c581a8ccc 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c @@ -188,7 +188,7 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) { struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915; struct intel_display *display = dev_priv->display; - int pipe; + enum pipe pipe; if (IS_BROXTON(dev_priv)) { enum transcoder trans; @@ -200,7 +200,7 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) GEN8_DE_PORT_HOTPLUG(HPD_PORT_B) | GEN8_DE_PORT_HOTPLUG(HPD_PORT_C)); - for_each_pipe(display, pipe) { + gvt_for_each_pipe(display, pipe) { vgpu_vreg_t(vgpu, TRANSCONF(display, pipe)) &= ~(TRANSCONF_ENABLE | TRANSCONF_STATE_ENABLE); vgpu_vreg_t(vgpu, DSPCNTR(display, pipe)) &= ~DISP_ENABLE; @@ -516,7 +516,7 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK; /* Disable Primary/Sprite/Cursor plane */ - for_each_pipe(display, pipe) { + gvt_for_each_pipe(display, pipe) { vgpu_vreg_t(vgpu, DSPCNTR(display, pipe)) &= ~DISP_ENABLE; vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE; vgpu_vreg_t(vgpu, CURCNTR(display, pipe)) &= ~MCURSOR_MODE_MASK; @@ -669,10 +669,10 @@ void intel_vgpu_emulate_vblank(struct intel_vgpu *vgpu) { struct drm_i915_private *i915 = vgpu->gvt->gt->i915; struct intel_display *display = i915->display; - int pipe; + enum pipe pipe; mutex_lock(&vgpu->vgpu_lock); - for_each_pipe(display, pipe) + gvt_for_each_pipe(display, pipe) emulate_vblank_on_pipe(vgpu, pipe); mutex_unlock(&vgpu->vgpu_lock); } diff --git a/drivers/gpu/drm/i915/gvt/display_helpers.h b/drivers/gpu/drm/i915/gvt/display_helpers.h index cbe383f677d5..d0975ed507d3 100644 --- a/drivers/gpu/drm/i915/gvt/display_helpers.h +++ b/drivers/gpu/drm/i915/gvt/display_helpers.h @@ -42,4 +42,8 @@ #define INTEL_DISPLAY_DEVICE_CURSOR_OFFSET(display, pipe) \ intel_display_device_cursor_offset((display), (pipe)) +#define gvt_for_each_pipe(display, __p) \ + for ((__p) = PIPE_A; (__p) < I915_MAX_PIPES; (__p)++) \ + for_each_if(intel_display_device_pipe_valid((display), (__p))) + #endif /* __DISPLAY_HELPERS_H__ */ From 1908784fbc05201e6b969473989dc76d160546c3 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Fri, 19 Dec 2025 11:32:58 +0530 Subject: [PATCH 28/92] drm/i915/gvt: Use the appropriate header for the DPLL macro The macro `DPLL_ID_SKL_DPLL0` is defined in display/intel_dpll_mgr.h. Previously, GVT included the header display/intel_display_core.h` because other macros also depended on it. After porting those macros to use the new APIs, the only remaining dependency was for the DPLL macro. Replace the indirect include with the correct header and drop intel_display_core.h to reduce unnecessary dependencies. Signed-off-by: Ankit Nautiyal Reviewed-by: Jani Nikula Link: https://patch.msgid.link/20251219060302.2365123-6-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/gvt/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index 1d0c581a8ccc..f230b07a12ae 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c @@ -45,9 +45,9 @@ #include "display/intel_crt_regs.h" #include "display/intel_cursor_regs.h" #include "display/intel_display.h" -#include "display/intel_display_core.h" #include "display_helpers.h" #include "display/intel_dpio_phy.h" +#include "display/intel_dpll_mgr.h" #include "display/intel_sprite_regs.h" static int get_edp_pipe(struct intel_vgpu *vgpu) From a2e3dda51d550f4226a3e490469fde469ee57189 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Fri, 19 Dec 2025 11:32:59 +0530 Subject: [PATCH 29/92] drm/i915/gvt/display_helper: Get rid of #ifdef/#undefs Now that i915/display macros have been substituted with wrappers that call the new display-device helpers, we can drop the conflicting includes from GVT and remove the temporary #ifdef/#undef macro overrides. Signed-off-by: Ankit Nautiyal Reviewed-by: Jani Nikula Link: https://patch.msgid.link/20251219060302.2365123-7-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/gvt/cmd_parser.c | 1 - drivers/gpu/drm/i915/gvt/display_helpers.h | 12 ------------ drivers/gpu/drm/i915/gvt/fb_decoder.c | 1 - drivers/gpu/drm/i915/gvt/handlers.c | 1 - 4 files changed, 15 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index fbc8a5e28576..e5301733f4e4 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -53,7 +53,6 @@ #include "trace.h" #include "display/i9xx_plane_regs.h" -#include "display/intel_display_core.h" #include "display/intel_sprite_regs.h" #include "gem/i915_gem_context.h" #include "gem/i915_gem_pm.h" diff --git a/drivers/gpu/drm/i915/gvt/display_helpers.h b/drivers/gpu/drm/i915/gvt/display_helpers.h index d0975ed507d3..0418397c09c4 100644 --- a/drivers/gpu/drm/i915/gvt/display_helpers.h +++ b/drivers/gpu/drm/i915/gvt/display_helpers.h @@ -8,15 +8,9 @@ #include "display/intel_gvt_api.h" -#ifdef DISPLAY_MMIO_BASE -#undef DISPLAY_MMIO_BASE -#endif #define DISPLAY_MMIO_BASE(display) \ intel_display_device_mmio_base((display)) -#ifdef INTEL_DISPLAY_DEVICE_PIPE_OFFSET -#undef INTEL_DISPLAY_DEVICE_PIPE_OFFSET -#endif /* * #FIXME: * TRANSCONF() uses pipe-based addressing via _MMIO_PIPE2(). @@ -30,15 +24,9 @@ #define INTEL_DISPLAY_DEVICE_PIPE_OFFSET(display, idx) \ intel_display_device_pipe_offset((display), (enum pipe)(idx)) -#ifdef INTEL_DISPLAY_DEVICE_TRANS_OFFSET -#undef INTEL_DISPLAY_DEVICE_TRANS_OFFSET -#endif #define INTEL_DISPLAY_DEVICE_TRANS_OFFSET(display, trans) \ intel_display_device_trans_offset((display), (trans)) -#ifdef INTEL_DISPLAY_DEVICE_CURSOR_OFFSET -#undef INTEL_DISPLAY_DEVICE_CURSOR_OFFSET -#endif #define INTEL_DISPLAY_DEVICE_CURSOR_OFFSET(display, pipe) \ intel_display_device_cursor_offset((display), (pipe)) diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c b/drivers/gpu/drm/i915/gvt/fb_decoder.c index c402f3b5a0ab..3d1a7e5c8cd3 100644 --- a/drivers/gpu/drm/i915/gvt/fb_decoder.c +++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c @@ -43,7 +43,6 @@ #include "display/i9xx_plane_regs.h" #include "display/intel_cursor_regs.h" -#include "display/intel_display_core.h" #include "display/intel_sprite_regs.h" #include "display/skl_universal_plane_regs.h" #include "display_helpers.h" diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 9ada97d01b6c..7063d3c77562 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -49,7 +49,6 @@ #include "display/i9xx_plane_regs.h" #include "display/intel_crt_regs.h" #include "display/intel_cursor_regs.h" -#include "display/intel_display_core.h" #include "display/intel_display_types.h" #include "display/intel_dmc_regs.h" #include "display/intel_dp_aux_regs.h" From 6739e03a9affdc3d94134d8734299971ec8d8bf5 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 23 Dec 2025 16:15:23 +0530 Subject: [PATCH 30/92] drm/i915/display: Add source param for dc balance Add source param for dc balance enablement. --v2: - Arrange in alphabetic order. (Ankit) - Update name. (Ankit) --v3: - Commit message update. (Ankit) Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-2-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_display_device.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index 13b6616bc496..6c74d6b0cc48 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -205,6 +205,7 @@ struct intel_display_platforms { #define HAS_ULTRAJOINER(__display) (((__display)->platform.dgfx && \ DISPLAY_VER(__display) == 14) && HAS_DSC(__display)) #define HAS_VRR(__display) (DISPLAY_VER(__display) >= 11) +#define HAS_VRR_DC_BALANCE(__display) (DISPLAY_VER(__display) >= 30) #define INTEL_NUM_PIPES(__display) (hweight8(DISPLAY_RUNTIME_INFO(__display)->pipe_mask)) #define OVERLAY_NEEDS_PHYSICAL(__display) (DISPLAY_INFO(__display)->overlay_needs_physical) #define SUPPORTS_TV(__display) (DISPLAY_INFO(__display)->supports_tv) From 1dee5a4db242e4e351570b74ab2b5793280eeac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 23 Dec 2025 16:15:24 +0530 Subject: [PATCH 31/92] drm/i915/dmc: Add pipe dmc registers and bits for DC Balance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add pipe dmc registers and access bits for DC Balance params configuration and enablement. --v2: - Separate register definitions for transcoder and pipe dmc. (Ankit) - Use MMIO pipe macros instead of transcoder ones. (Ankit) - Remove dev_priv use. (Jani, Nikula) --v3: - Add all register address, from capital alphabet to small. (Ankit) - Add EVT CTL registers. - Add co-author tag. - Add event flag for Triggering DC Balance. --v4: - Add DCB Flip count and balance reset registers. --v5: - Correct macro usage for flip count. (Ankit) - Use register offset in lower case. Signed-off-by: Ville Syrjälä Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-3-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_dmc_regs.h | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h b/drivers/gpu/drm/i915/display/intel_dmc_regs.h index c5aa49921cb9..38e342b45af0 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h @@ -584,4 +584,64 @@ enum pipedmc_event_id { #define PTL_PIPEDMC_EXEC_TIME_LINES(start_mmioaddr) _MMIO((start_mmioaddr) + 0x6b8) #define PTL_PIPEDMC_END_OF_EXEC_GB(start_mmioaddr) _MMIO((start_mmioaddr) + 0x6c0) +#define _PIPEDMC_DCB_CTL_A 0x5f1a0 +#define _PIPEDMC_DCB_CTL_B 0x5f5a0 +#define PIPEDMC_DCB_CTL(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_CTL_A,\ + _PIPEDMC_DCB_CTL_B) +#define PIPEDMC_ADAPTIVE_DCB_ENABLE REG_BIT(31) + +#define _PIPEDMC_DCB_VBLANK_A 0x5f1bc +#define _PIPEDMC_DCB_VBLANK_B 0x5f5bc +#define PIPEDMC_DCB_VBLANK(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_VBLANK_A,\ + _PIPEDMC_DCB_VBLANK_B) + +#define _PIPEDMC_DCB_SLOPE_A 0x5f1b8 +#define _PIPEDMC_DCB_SLOPE_B 0x5f5b8 +#define PIPEDMC_DCB_SLOPE(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_SLOPE_A,\ + _PIPEDMC_DCB_SLOPE_B) + +#define _PIPEDMC_DCB_GUARDBAND_A 0x5f1b4 +#define _PIPEDMC_DCB_GUARDBAND_B 0x5f5b4 +#define PIPEDMC_DCB_GUARDBAND(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_GUARDBAND_A,\ + _PIPEDMC_DCB_GUARDBAND_B) + +#define _PIPEDMC_DCB_MAX_INCREASE_A 0x5f1ac +#define _PIPEDMC_DCB_MAX_INCREASE_B 0x5f5ac +#define PIPEDMC_DCB_MAX_INCREASE(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_MAX_INCREASE_A,\ + _PIPEDMC_DCB_MAX_INCREASE_B) + +#define _PIPEDMC_DCB_MAX_DECREASE_A 0x5f1b0 +#define _PIPEDMC_DCB_MAX_DECREASE_B 0x5f5b0 +#define PIPEDMC_DCB_MAX_DECREASE(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_MAX_DECREASE_A,\ + _PIPEDMC_DCB_MAX_DECREASE_B) + +#define _PIPEDMC_DCB_VMIN_A 0x5f1a4 +#define _PIPEDMC_DCB_VMIN_B 0x5f5a4 +#define PIPEDMC_DCB_VMIN(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_VMIN_A,\ + _PIPEDMC_DCB_VMIN_B) + +#define _PIPEDMC_DCB_VMAX_A 0x5f1a8 +#define _PIPEDMC_DCB_VMAX_B 0x5f5a8 +#define PIPEDMC_DCB_VMAX(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_VMAX_A,\ + _PIPEDMC_DCB_VMAX_B) + +#define _PIPEDMC_DCB_DEBUG_A 0x5f1c0 +#define _PIPEDMC_DCB_DEBUG_B 0x5f5c0 +#define PIPEDMC_DCB_DEBUG(pipe) _MMIO_PIPE(pipe, _PIPEDMC_DCB_DEBUG_A,\ + _PIPEDMC_DCB_DEBUG_B) + +#define _PIPEDMC_EVT_CTL_3_A 0x5f040 +#define _PIPEDMC_EVT_CTL_3_B 0x5f440 +#define PIPEDMC_EVT_CTL_3(pipe) _MMIO_PIPE(pipe, _PIPEDMC_EVT_CTL_3_A,\ + _PIPEDMC_EVT_CTL_3_B) + +#define _PIPEDMC_DCB_FLIP_COUNT_A 0x906a4 +#define _PIPEDMC_DCB_FLIP_COUNT_B 0x986a4 +#define PIPEDMC_DCB_FLIP_COUNT(pipe) _MMIO_PIPE(pipe, _PIPEDMC_DCB_FLIP_COUNT_A,\ + _PIPEDMC_DCB_FLIP_COUNT_B) + +#define _PIPEDMC_DCB_BALANCE_RESET_A 0x906a8 +#define _PIPEDMC_DCB_BALANCE_RESET_B 0x986a8 +#define PIPEDMC_DCB_BALANCE_RESET(pipe) _MMIO_PIPE(pipe, _PIPEDMC_DCB_BALANCE_RESET_A,\ + _PIPEDMC_DCB_BALANCE_RESET_B) #endif /* __INTEL_DMC_REGS_H__ */ From be19d803df438880528b20f541638507cbefc7e4 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 23 Dec 2025 16:15:25 +0530 Subject: [PATCH 32/92] drm/i915/vrr: Add VRR DC balance registers Add VRR register offsets and bits to access DC Balance configuration. --v2: - Separate register definitions. (Ankit) - Remove usage of dev_priv. (Jani, Nikula) --v3: - Convert register address offset, from capital to small. (Ankit) - Move mask bits near to register offsets. (Ankit) --v4: - Use _MMIO_TRANS wherever possible. (Jani) --v5: - Added LIVE Value registers for VMAX and FLIPLINE as provided by DMC fw - For pipe B it is temporary and expected to change later once finalised. --v6: - Add live value registers for DCB VMAX/FLIPLINE. --v7: - Correct commit message file. (Jani Nikula) - Add bits in highest to lowest order. (Jani Nikula) --v8: - Register/bitfields indentation changes as per i915_reg.h mentioned format (Jani, Ankit) --v9: - Remove comment. (Ankit) Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-4-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_vrr_regs.h | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_vrr_regs.h b/drivers/gpu/drm/i915/display/intel_vrr_regs.h index ba9b9215dc11..427ada0d3973 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr_regs.h +++ b/drivers/gpu/drm/i915/display/intel_vrr_regs.h @@ -8,6 +8,73 @@ #include "intel_display_reg_defs.h" +#define _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_A 0x604d4 +#define _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_B 0x614d4 +#define TRANS_VRR_DCB_ADJ_FLIPLINE_CFG(trans) _MMIO_TRANS(trans, \ + _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_A, \ + _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_B) +#define VRR_DCB_ADJ_FLIPLINE_CNT_MASK REG_GENMASK(31, 24) +#define VRR_DCB_ADJ_FLIPLINE_MASK REG_GENMASK(19, 0) +#define VRR_DCB_ADJ_FLIPLINE(flipline) REG_FIELD_PREP(VRR_DCB_ADJ_FLIPLINE_MASK, \ + (flipline)) + +#define _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE_A 0x90700 +#define _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE_B 0x98700 +#define TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE(trans) _MMIO_TRANS(trans, \ + _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE_A, \ + _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE_B) + +#define _TRANS_VRR_DCB_ADJ_VMAX_CFG_A 0x604d8 +#define _TRANS_VRR_DCB_ADJ_VMAX_CFG_B 0x614d8 +#define TRANS_VRR_DCB_ADJ_VMAX_CFG(trans) _MMIO_TRANS(trans, \ + _TRANS_VRR_DCB_ADJ_VMAX_CFG_A, \ + _TRANS_VRR_DCB_ADJ_VMAX_CFG_B) +#define VRR_DCB_ADJ_VMAX_CNT_MASK REG_GENMASK(31, 24) +#define VRR_DCB_ADJ_VMAX_MASK REG_GENMASK(19, 0) +#define VRR_DCB_ADJ_VMAX(vmax) REG_FIELD_PREP(VRR_DCB_ADJ_VMAX_MASK, (vmax)) + +#define _TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE_A 0x906f8 +#define _TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE_B 0x986f8 +#define TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE(trans) _MMIO_TRANS(trans, \ + _TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE_A, \ + _TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE_B) + +#define _TRANS_VRR_DCB_FLIPLINE_A 0x60418 +#define _TRANS_VRR_DCB_FLIPLINE_B 0x61418 +#define TRANS_VRR_DCB_FLIPLINE(trans) _MMIO_TRANS(trans, \ + _TRANS_VRR_DCB_FLIPLINE_A, \ + _TRANS_VRR_DCB_FLIPLINE_B) +#define VRR_DCB_FLIPLINE_MASK REG_GENMASK(19, 0) +#define VRR_DCB_FLIPLINE(flipline) REG_FIELD_PREP(VRR_DCB_FLIPLINE_MASK, \ + (flipline)) + +#define _TRANS_VRR_DCB_FLIPLINE_LIVE_A 0x906fc +#define _TRANS_VRR_DCB_FLIPLINE_LIVE_B 0x986fc +#define TRANS_VRR_DCB_FLIPLINE_LIVE(trans) _MMIO_TRANS(trans, \ + _TRANS_VRR_DCB_FLIPLINE_LIVE_A, \ + _TRANS_VRR_DCB_FLIPLINE_LIVE_B) + +#define _TRANS_VRR_DCB_VMAX_A 0x60414 +#define _TRANS_VRR_DCB_VMAX_B 0x61414 +#define TRANS_VRR_DCB_VMAX(trans) _MMIO_TRANS(trans, \ + _TRANS_VRR_DCB_VMAX_A, \ + _TRANS_VRR_DCB_VMAX_B) +#define VRR_DCB_VMAX_MASK REG_GENMASK(19, 0) +#define VRR_DCB_VMAX(vmax) REG_FIELD_PREP(VRR_DCB_VMAX_MASK, (vmax)) + +#define _TRANS_VRR_DCB_VMAX_LIVE_A 0x906f4 +#define _TRANS_VRR_DCB_VMAX_LIVE_B 0x986f4 +#define TRANS_VRR_DCB_VMAX_LIVE(trans) _MMIO_TRANS(trans, \ + _TRANS_VRR_DCB_VMAX_LIVE_A, \ + _TRANS_VRR_DCB_VMAX_LIVE_B) + +#define _TRANS_ADAPTIVE_SYNC_DCB_CTL_A 0x604c0 +#define _TRANS_ADAPTIVE_SYNC_DCB_CTL_B 0x614c0 +#define TRANS_ADAPTIVE_SYNC_DCB_CTL(trans) _MMIO_TRANS(trans, \ + _TRANS_ADAPTIVE_SYNC_DCB_CTL_A, \ + _TRANS_ADAPTIVE_SYNC_DCB_CTL_B) +#define ADAPTIVE_SYNC_COUNTER_EN REG_BIT(31) + #define _TRANS_VRR_CTL_A 0x60420 #define _TRANS_VRR_CTL_B 0x61420 #define _TRANS_VRR_CTL_C 0x62420 @@ -19,6 +86,7 @@ #define VRR_CTL_CMRR_ENABLE REG_BIT(27) #define VRR_CTL_PIPELINE_FULL_MASK REG_GENMASK(10, 3) #define VRR_CTL_PIPELINE_FULL(x) REG_FIELD_PREP(VRR_CTL_PIPELINE_FULL_MASK, (x)) +#define VRR_CTL_DCB_ADJ_ENABLE REG_BIT(28) #define VRR_CTL_PIPELINE_FULL_OVERRIDE REG_BIT(0) #define XELPD_VRR_CTL_VRR_GUARDBAND_MASK REG_GENMASK(15, 0) #define XELPD_VRR_CTL_VRR_GUARDBAND(x) REG_FIELD_PREP(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, (x)) From 19467b46c219878adfd81b9de3f9cb38a198fbe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 23 Dec 2025 16:15:26 +0530 Subject: [PATCH 33/92] drm/i915/vrr: Add functions to read out vmin/vmax stuff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calculate delayed vblank start position with the help of added vmin/vmax stuff for next frame and final computation. --v2: - Correct Author details. --v3: - Separate register details from this patch. --v4: - Add mask macros. --v5: - As live prefix params indicate timings for current frame, read just _live prefix values instead of next frame timings as done previously. - Squash Refactor vrr params patch. --v6: - Use error code while returning invalid values. (Jani, Nikula) Signed-off-by: Ville Syrjälä Signed-off-by: Mitul Golani Reviewed-by: Uma Shankar Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-5-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_vrr.c | 56 ++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_vrr.h | 5 +++ 2 files changed, 61 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index b92c42fde937..31f3a7b6e00d 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -261,6 +261,12 @@ static int intel_vrr_hw_value(const struct intel_crtc_state *crtc_state, return value - crtc_state->set_context_latency; } +static int intel_vrr_vblank_start(const struct intel_crtc_state *crtc_state, + int vmin_vmax) +{ + return intel_vrr_hw_value(crtc_state, vmin_vmax) - crtc_state->vrr.guardband; +} + /* * For fixed refresh rate mode Vmin, Vmax and Flipline all are set to * Vtotal value. @@ -898,3 +904,53 @@ int intel_vrr_vmin_safe_window_end(const struct intel_crtc_state *crtc_state) return intel_vrr_vmin_vblank_start(crtc_state) - crtc_state->set_context_latency; } + +int intel_vrr_dcb_vmin_vblank_start_next(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + u32 tmp = 0; + + tmp = intel_de_read(display, TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE(cpu_transcoder)); + + if (REG_FIELD_GET(VRR_DCB_ADJ_FLIPLINE_CNT_MASK, tmp) == 0) + return -EINVAL; + + return intel_vrr_vblank_start(crtc_state, VRR_DCB_ADJ_FLIPLINE(tmp) + 1); +} + +int intel_vrr_dcb_vmax_vblank_start_next(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + u32 tmp = 0; + + tmp = intel_de_read(display, TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE(cpu_transcoder)); + + if (REG_FIELD_GET(VRR_DCB_ADJ_VMAX_CNT_MASK, tmp) == 0) + return -EINVAL; + + return intel_vrr_vblank_start(crtc_state, VRR_DCB_ADJ_VMAX(tmp) + 1); +} + +int intel_vrr_dcb_vmin_vblank_start_final(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + u32 tmp = 0; + + tmp = intel_de_read(display, TRANS_VRR_DCB_FLIPLINE_LIVE(cpu_transcoder)); + + return intel_vrr_vblank_start(crtc_state, VRR_DCB_FLIPLINE(tmp) + 1); +} + +int intel_vrr_dcb_vmax_vblank_start_final(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + u32 tmp = 0; + + tmp = intel_de_read(display, TRANS_VRR_DCB_VMAX_LIVE(cpu_transcoder)); + + return intel_vrr_vblank_start(crtc_state, VRR_DCB_VMAX(tmp) + 1); +} diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h index bc9044621635..66fb9ad846f2 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.h +++ b/drivers/gpu/drm/i915/display/intel_vrr.h @@ -43,4 +43,9 @@ bool intel_vrr_always_use_vrr_tg(struct intel_display *display); int intel_vrr_safe_window_start(const struct intel_crtc_state *crtc_state); int intel_vrr_vmin_safe_window_end(const struct intel_crtc_state *crtc_state); +int intel_vrr_dcb_vmin_vblank_start_next(const struct intel_crtc_state *crtc_state); +int intel_vrr_dcb_vmax_vblank_start_next(const struct intel_crtc_state *crtc_state); +int intel_vrr_dcb_vmin_vblank_start_final(const struct intel_crtc_state *crtc_state); +int intel_vrr_dcb_vmax_vblank_start_final(const struct intel_crtc_state *crtc_state); + #endif /* __INTEL_VRR_H__ */ From be843f34803520341324a8c4487caee6d8e14444 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 23 Dec 2025 16:15:27 +0530 Subject: [PATCH 34/92] drm/i915/vrr: Add DC Balance params to crtc_state Add DC Balance params to crtc_state, also add state checker params for related properties. --v3: - Seggregate crtc_state params with this patch. (Ankit) --v4: - Update commit message and header. (Ankit) - Add +1 to VMIN and VMAX only when it is non-zero. (Ankit) --v5: - Add headers in sorted order. (Jani Nikula) --v6: - Add a separate function to get and check dc_balance params. - Avoid repeatative use of MMIO read. (Ankit) Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-6-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 7 ++++ .../drm/i915/display/intel_display_types.h | 7 ++++ drivers/gpu/drm/i915/display/intel_vrr.c | 32 +++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index cd482e5ff929..a7e71ad8a886 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5476,6 +5476,13 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_LLI(cmrr.cmrr_m); PIPE_CONF_CHECK_LLI(cmrr.cmrr_n); PIPE_CONF_CHECK_BOOL(cmrr.enable); + PIPE_CONF_CHECK_I(vrr.dc_balance.vmin); + PIPE_CONF_CHECK_I(vrr.dc_balance.vmax); + PIPE_CONF_CHECK_I(vrr.dc_balance.guardband); + PIPE_CONF_CHECK_I(vrr.dc_balance.slope); + PIPE_CONF_CHECK_I(vrr.dc_balance.max_increase); + PIPE_CONF_CHECK_I(vrr.dc_balance.max_decrease); + PIPE_CONF_CHECK_I(vrr.dc_balance.vblank_target); } if (!fastset || intel_vrr_always_use_vrr_tg(display)) { diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 6ff53cd58052..75acfe043997 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1384,6 +1384,13 @@ struct intel_crtc_state { u8 pipeline_full; u16 flipline, vmin, vmax, guardband; u32 vsync_end, vsync_start; + struct { + bool enable; + u16 vmin, vmax; + u16 guardband, slope; + u16 max_increase, max_decrease; + u16 vblank_target; + } dc_balance; } vrr; /* Content Match Refresh Rate state */ diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 31f3a7b6e00d..427ef1741051 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -9,6 +9,7 @@ #include "intel_de.h" #include "intel_display_regs.h" #include "intel_display_types.h" +#include "intel_dmc_regs.h" #include "intel_dp.h" #include "intel_psr.h" #include "intel_vrr.h" @@ -785,6 +786,35 @@ bool intel_vrr_is_fixed_rr(const struct intel_crtc_state *crtc_state) crtc_state->vrr.flipline == crtc_state->vrr.vmin; } +static +void intel_vrr_get_dc_balance_config(struct intel_crtc_state *crtc_state) +{ + u32 reg_val; + 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; + + if (!HAS_VRR_DC_BALANCE(display)) + return; + + reg_val = intel_de_read(display, PIPEDMC_DCB_VMIN(pipe)); + crtc_state->vrr.dc_balance.vmin = reg_val ? reg_val + 1 : 0; + + reg_val = intel_de_read(display, PIPEDMC_DCB_VMAX(pipe)); + crtc_state->vrr.dc_balance.vmax = reg_val ? reg_val + 1 : 0; + + crtc_state->vrr.dc_balance.guardband = + intel_de_read(display, PIPEDMC_DCB_GUARDBAND(pipe)); + crtc_state->vrr.dc_balance.max_increase = + intel_de_read(display, PIPEDMC_DCB_MAX_INCREASE(pipe)); + crtc_state->vrr.dc_balance.max_decrease = + intel_de_read(display, PIPEDMC_DCB_MAX_DECREASE(pipe)); + crtc_state->vrr.dc_balance.slope = + intel_de_read(display, PIPEDMC_DCB_SLOPE(pipe)); + crtc_state->vrr.dc_balance.vblank_target = + intel_de_read(display, PIPEDMC_DCB_VBLANK(pipe)); +} + void intel_vrr_get_config(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); @@ -866,6 +896,8 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) else crtc_state->vrr.enable = vrr_enable; + intel_vrr_get_dc_balance_config(crtc_state); + /* * #TODO: For Both VRR and CMRR the flag I915_MODE_FLAG_VRR is set for mode_flags. * Since CMRR is currently disabled, set this flag for VRR for now. From c09112ca3cc9f0d73a53adf4fe5103f6a06e061b Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 23 Dec 2025 16:15:28 +0530 Subject: [PATCH 35/92] drm/i915/vrr: Add state dump for DC Balance params Add state dump for dc balance params to track DC Balance crtc state config. -v1: -- nitpick: s/Vblank target/vblank target. (Ankit) Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-7-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_crtc_state_dump.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index c2a6217c2262..234843b8f83a 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -303,6 +303,14 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, drm_printf(&p, "vrr: vmin vblank: %d, vmax vblank: %d, vmin vtotal: %d, vmax vtotal: %d\n", intel_vrr_vmin_vblank_start(pipe_config), intel_vrr_vmax_vblank_start(pipe_config), intel_vrr_vmin_vtotal(pipe_config), intel_vrr_vmax_vtotal(pipe_config)); + drm_printf(&p, "vrr: dc balance: %s, vmin: %d vmax: %d guardband: %d, slope: %d max increase: %d max decrease: %d vblank target: %d\n", + str_yes_no(pipe_config->vrr.dc_balance.enable), + pipe_config->vrr.dc_balance.vmin, pipe_config->vrr.dc_balance.vmax, + pipe_config->vrr.dc_balance.guardband, + pipe_config->vrr.dc_balance.slope, + pipe_config->vrr.dc_balance.max_increase, + pipe_config->vrr.dc_balance.max_decrease, + pipe_config->vrr.dc_balance.vblank_target); drm_printf(&p, "requested mode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&pipe_config->hw.mode)); From 2873c8eaa1e9020b2cfa7abe39ea69af9f93058a Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 23 Dec 2025 16:15:29 +0530 Subject: [PATCH 36/92] drm/i915/vrr: Add compute config for DC Balance params Compute DC Balance parameters and tunable params based on experiments. --v2: - Document tunable params. (Ankit) --v3: - Add line spaces to compute config. (Ankit) - Remove redundancy checks. --v4: - Separate out conpute config to separate function. - As all the valuse are being computed in scanlines, and slope is still in usec, convert and store it to scanlines. --v5: - Update and add comments for slope calculation. (Ankit) - Update early return conditions for dc balance compute. (Ankit) --v6: - Early return condition simplified for dc balance compute config. (Ankit) - Make use of pipe restrictions to this patch. (Ankit) --v7: - Separate out PIPE_A and PIPE_B restrictions to other patch.(Ankit) Signed-off-by: Mitul Golani Reviewed-by: Uma Shankar Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-8-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_vrr.c | 45 ++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 427ef1741051..952e3c31bacc 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -6,6 +6,7 @@ #include +#include "intel_crtc.h" #include "intel_de.h" #include "intel_display_regs.h" #include "intel_display_types.h" @@ -20,6 +21,14 @@ #define FIXED_POINT_PRECISION 100 #define CMRR_PRECISION_TOLERANCE 10 +/* + * Tunable parameters for DC Balance correction. + * These are captured based on experimentations. + */ +#define DCB_CORRECTION_SENSITIVITY 30 +#define DCB_CORRECTION_AGGRESSIVENESS 1000 /* ms × 100; 10 ms */ +#define DCB_BLANK_TARGET 50 + bool intel_vrr_is_capable(struct intel_connector *connector) { struct intel_display *display = to_intel_display(connector); @@ -342,6 +351,40 @@ int intel_vrr_compute_vmax(struct intel_connector *connector, return vmax; } +static void +intel_vrr_dc_balance_compute_config(struct intel_crtc_state *crtc_state) +{ + int guardband_usec, adjustment_usec; + struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; + + if (!HAS_VRR_DC_BALANCE(display) || !crtc_state->vrr.enable) + return; + + crtc_state->vrr.dc_balance.vmax = crtc_state->vrr.vmax; + crtc_state->vrr.dc_balance.vmin = crtc_state->vrr.vmin; + crtc_state->vrr.dc_balance.max_increase = + crtc_state->vrr.vmax - crtc_state->vrr.vmin; + crtc_state->vrr.dc_balance.max_decrease = + crtc_state->vrr.vmax - crtc_state->vrr.vmin; + crtc_state->vrr.dc_balance.guardband = + DIV_ROUND_UP(crtc_state->vrr.dc_balance.vmax * + DCB_CORRECTION_SENSITIVITY, 100); + guardband_usec = + intel_scanlines_to_usecs(adjusted_mode, + crtc_state->vrr.dc_balance.guardband); + /* + * The correction_aggressiveness/100 is the number of milliseconds to + * adjust by when the balance is at twice the guardband. + * guardband_slope = correction_aggressiveness / (guardband * 100) + */ + adjustment_usec = DCB_CORRECTION_AGGRESSIVENESS * 10; + crtc_state->vrr.dc_balance.slope = + DIV_ROUND_UP(adjustment_usec, guardband_usec); + crtc_state->vrr.dc_balance.vblank_target = + DIV_ROUND_UP((crtc_state->vrr.vmax - crtc_state->vrr.vmin) * + DCB_BLANK_TARGET, 100); +} + void intel_vrr_compute_config(struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) @@ -399,6 +442,8 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, (crtc_state->hw.adjusted_mode.crtc_vtotal - crtc_state->hw.adjusted_mode.crtc_vsync_end); } + + intel_vrr_dc_balance_compute_config(crtc_state); } static int From 7bf11bc2f716f6824b3b3d418319967213aab2a5 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 23 Dec 2025 16:15:30 +0530 Subject: [PATCH 37/92] drm/i915/vrr: Add function to check if DC Balance Possible Add a function that checks if DC Balance enabling is possible on the requested PIPE. Apart from the DISPLAY_VER check, account for current firmware limitations, which only allow DC Balance on PIPE A and PIPE B. v2: Rephrased commit message. (Ankit) Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-9-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_vrr.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 952e3c31bacc..dbfe56e8973d 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -351,13 +351,28 @@ int intel_vrr_compute_vmax(struct intel_connector *connector, return vmax; } +static bool intel_vrr_dc_balance_possible(const 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); + enum pipe pipe = crtc->pipe; + + /* + * FIXME: Currently Firmware supports DC Balancing on PIPE A + * and PIPE B. Account those limitation while computing DC + * Balance parameters. + */ + return (HAS_VRR_DC_BALANCE(display) && + ((pipe == PIPE_A) || (pipe == PIPE_B))); +} + static void intel_vrr_dc_balance_compute_config(struct intel_crtc_state *crtc_state) { int guardband_usec, adjustment_usec; struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - if (!HAS_VRR_DC_BALANCE(display) || !crtc_state->vrr.enable) + if (!intel_vrr_dc_balance_possible(crtc_state) || !crtc_state->vrr.enable) return; crtc_state->vrr.dc_balance.vmax = crtc_state->vrr.vmax; @@ -839,7 +854,7 @@ void intel_vrr_get_dc_balance_config(struct intel_crtc_state *crtc_state) struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); enum pipe pipe = crtc->pipe; - if (!HAS_VRR_DC_BALANCE(display)) + if (!intel_vrr_dc_balance_possible(crtc_state)) return; reg_val = intel_de_read(display, PIPEDMC_DCB_VMIN(pipe)); From 80d14983595ba3bc10d4e1349db295a5645276ce Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 23 Dec 2025 16:15:31 +0530 Subject: [PATCH 38/92] drm/i915/vrr: Add function to reset DC balance accumulated params Add function which resets all accumulated DC Balance parameters whenever adaptive mode of VRR goes off. This helps to give a fresh start when VRR is re-enabled. --v2: - Typo, change crtc_state to old_crtc_state. (Ankit) Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-10-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 1 + drivers/gpu/drm/i915/display/intel_vrr.c | 13 +++++++++++++ drivers/gpu/drm/i915/display/intel_vrr.h | 3 +++ 3 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a7e71ad8a886..35a97d6bc059 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1158,6 +1158,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, if (intel_crtc_vrr_disabling(state, crtc)) { intel_vrr_disable(old_crtc_state); + intel_vrr_dcb_reset(old_crtc_state, crtc); intel_crtc_update_active_timings(old_crtc_state, false); } diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index dbfe56e8973d..c3a8161fb8e1 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -646,6 +646,19 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state) EMP_AS_SDP_DB_TL(crtc_state->vrr.vsync_start)); } +void +intel_vrr_dcb_reset(const struct intel_crtc_state *old_crtc_state, + struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(old_crtc_state); + enum pipe pipe = crtc->pipe; + + if (!old_crtc_state->vrr.dc_balance.enable) + return; + + intel_de_write(display, PIPEDMC_DCB_BALANCE_RESET(pipe), 0); +} + void intel_vrr_send_push(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state) { diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h index 66fb9ad846f2..d40ed5504180 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.h +++ b/drivers/gpu/drm/i915/display/intel_vrr.h @@ -11,6 +11,7 @@ struct drm_connector_state; struct intel_atomic_state; struct intel_connector; +struct intel_crtc; struct intel_crtc_state; struct intel_dsb; struct intel_display; @@ -39,6 +40,8 @@ bool intel_vrr_is_fixed_rr(const struct intel_crtc_state *crtc_state); void intel_vrr_transcoder_enable(const struct intel_crtc_state *crtc_state); void intel_vrr_transcoder_disable(const struct intel_crtc_state *crtc_state); void intel_vrr_set_fixed_rr_timings(const struct intel_crtc_state *crtc_state); +void intel_vrr_dcb_reset(const struct intel_crtc_state *old_crtc_state, + struct intel_crtc *crtc); bool intel_vrr_always_use_vrr_tg(struct intel_display *display); int intel_vrr_safe_window_start(const struct intel_crtc_state *crtc_state); int intel_vrr_vmin_safe_window_end(const struct intel_crtc_state *crtc_state); From d780bbebaac137869ad5d95bd42e525fec812830 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 23 Dec 2025 16:15:32 +0530 Subject: [PATCH 39/92] drm/i915/display: Add DC Balance flip count operations Track dc balance flip count with params per crtc. Increment DC Balance Flip count before every flip to indicate DMC firmware about new flip occurrence which needs to be adjusted for dc balancing. This is tracked separately from legacy FLIP_COUNT register also Reset DC balance flip count value while disabling VRR adaptive mode, this is to start with fresh counts when VRR adaptive refresh mode is triggered again. --v2: - Call during intel_update_crtc.(Ankit) Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-11-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ .../gpu/drm/i915/display/intel_display_types.h | 4 ++++ drivers/gpu/drm/i915/display/intel_vrr.c | 15 +++++++++++++++ drivers/gpu/drm/i915/display/intel_vrr.h | 2 ++ 4 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 35a97d6bc059..68e67dc2631f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6864,6 +6864,9 @@ static void intel_update_crtc(struct intel_atomic_state *state, intel_crtc_update_active_timings(new_crtc_state, new_crtc_state->vrr.enable); + if (new_crtc_state->vrr.dc_balance.enable) + intel_vrr_dcb_increment_flip_count(new_crtc_state, crtc); + /* * We usually enable FIFO underrun interrupts as part of the * CRTC enable sequence during modesets. But when we inherit a diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 75acfe043997..113e43bc1f6d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1531,6 +1531,10 @@ struct intel_crtc { struct intel_link_m_n m_n, m2_n2; } drrs; + struct { + u64 flip_count; + } dc_balance; + int scanline_offset; struct { diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index c3a8161fb8e1..92be789a6500 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -646,6 +646,20 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state) EMP_AS_SDP_DB_TL(crtc_state->vrr.vsync_start)); } +void +intel_vrr_dcb_increment_flip_count(struct intel_crtc_state *crtc_state, + struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum pipe pipe = crtc->pipe; + + if (!crtc_state->vrr.dc_balance.enable) + return; + + intel_de_write(display, PIPEDMC_DCB_FLIP_COUNT(pipe), + ++crtc->dc_balance.flip_count); +} + void intel_vrr_dcb_reset(const struct intel_crtc_state *old_crtc_state, struct intel_crtc *crtc) @@ -656,6 +670,7 @@ intel_vrr_dcb_reset(const struct intel_crtc_state *old_crtc_state, if (!old_crtc_state->vrr.dc_balance.enable) return; + intel_de_write(display, PIPEDMC_DCB_FLIP_COUNT(pipe), 0); intel_de_write(display, PIPEDMC_DCB_BALANCE_RESET(pipe), 0); } diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h index d40ed5504180..bedcc8c4bff2 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.h +++ b/drivers/gpu/drm/i915/display/intel_vrr.h @@ -29,6 +29,8 @@ void intel_vrr_send_push(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state); void intel_vrr_check_push_sent(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state); +void intel_vrr_dcb_increment_flip_count(struct intel_crtc_state *crtc_state, + struct intel_crtc *crtc); bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state); void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state); void intel_vrr_get_config(struct intel_crtc_state *crtc_state); From 4ca36702d808e67a68cb51163f3101875594d0ba Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 23 Dec 2025 16:15:33 +0530 Subject: [PATCH 40/92] drm/i915/vrr: Write DC balance params to hw registers Write DC Balance parameters to hw registers. --v2: - Update commit header. - Separate crtc_state params from this patch. (Ankit) --v3: - Write registers at compute config. - Update condition for write. --v4: - Address issue with state checker. --v5: - Initialise some more dc balance register while enabling VRR. --v6: - FLIPLINE_CFG need to be configure at last, as it is double buffer arming point. --v7: - Initialise and reset live value of vmax and vmin as well. --v8: - Add separate functions while writing hw registers. (Ankit) --v9: - Add DC Balance counter enable bit to this patch. (Ankit) --v10: - Add rigister writes to vrr_enable/disable. (Ankit) Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-12-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_vrr.c | 76 ++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 92be789a6500..68b39fe0f7bc 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -781,6 +781,80 @@ static void intel_vrr_set_vrr_timings(const struct intel_crtc_state *crtc_state) intel_vrr_hw_flipline(crtc_state) - 1); } +static void +intel_vrr_enable_dc_balancing(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + enum pipe pipe = crtc->pipe; + + if (!crtc_state->vrr.dc_balance.enable) + return; + + intel_de_write(display, TRANS_VRR_DCB_ADJ_VMAX_CFG(cpu_transcoder), + VRR_DCB_ADJ_VMAX(crtc_state->vrr.vmax - 1)); + intel_de_write(display, TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE(cpu_transcoder), + VRR_DCB_ADJ_VMAX(crtc_state->vrr.vmax - 1)); + intel_de_write(display, TRANS_VRR_DCB_VMAX(cpu_transcoder), + VRR_DCB_VMAX(crtc_state->vrr.vmax - 1)); + intel_de_write(display, TRANS_VRR_DCB_VMAX_LIVE(cpu_transcoder), + VRR_DCB_VMAX(crtc_state->vrr.vmax - 1)); + intel_de_write(display, TRANS_VRR_DCB_FLIPLINE(cpu_transcoder), + VRR_DCB_FLIPLINE(crtc_state->vrr.flipline - 1)); + intel_de_write(display, TRANS_VRR_DCB_FLIPLINE_LIVE(cpu_transcoder), + VRR_DCB_FLIPLINE(crtc_state->vrr.flipline - 1)); + intel_de_write(display, TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE(cpu_transcoder), + VRR_DCB_ADJ_FLIPLINE(crtc_state->vrr.flipline - 1)); + intel_de_write(display, TRANS_VRR_DCB_ADJ_FLIPLINE_CFG(cpu_transcoder), + VRR_DCB_ADJ_FLIPLINE(crtc_state->vrr.flipline - 1)); + intel_de_write(display, PIPEDMC_DCB_VMIN(pipe), + crtc_state->vrr.dc_balance.vmin - 1); + intel_de_write(display, PIPEDMC_DCB_VMAX(pipe), + crtc_state->vrr.dc_balance.vmax - 1); + intel_de_write(display, PIPEDMC_DCB_MAX_INCREASE(pipe), + crtc_state->vrr.dc_balance.max_increase); + intel_de_write(display, PIPEDMC_DCB_MAX_DECREASE(pipe), + crtc_state->vrr.dc_balance.max_decrease); + intel_de_write(display, PIPEDMC_DCB_GUARDBAND(pipe), + crtc_state->vrr.dc_balance.guardband); + intel_de_write(display, PIPEDMC_DCB_SLOPE(pipe), + crtc_state->vrr.dc_balance.slope); + intel_de_write(display, PIPEDMC_DCB_VBLANK(pipe), + crtc_state->vrr.dc_balance.vblank_target); + intel_de_write(display, TRANS_ADAPTIVE_SYNC_DCB_CTL(cpu_transcoder), + ADAPTIVE_SYNC_COUNTER_EN); +} + +static void +intel_vrr_disable_dc_balancing(const struct intel_crtc_state *old_crtc_state) +{ + struct intel_display *display = to_intel_display(old_crtc_state); + enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; + struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); + enum pipe pipe = crtc->pipe; + + if (!old_crtc_state->vrr.dc_balance.enable) + return; + + intel_de_write(display, TRANS_ADAPTIVE_SYNC_DCB_CTL(cpu_transcoder), 0); + intel_de_write(display, PIPEDMC_DCB_VMIN(pipe), 0); + intel_de_write(display, PIPEDMC_DCB_VMAX(pipe), 0); + intel_de_write(display, PIPEDMC_DCB_MAX_INCREASE(pipe), 0); + intel_de_write(display, PIPEDMC_DCB_MAX_DECREASE(pipe), 0); + intel_de_write(display, PIPEDMC_DCB_GUARDBAND(pipe), 0); + intel_de_write(display, PIPEDMC_DCB_SLOPE(pipe), 0); + intel_de_write(display, PIPEDMC_DCB_VBLANK(pipe), 0); + intel_de_write(display, TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE(cpu_transcoder), 0); + intel_de_write(display, TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE(cpu_transcoder), 0); + intel_de_write(display, TRANS_VRR_DCB_VMAX_LIVE(cpu_transcoder), 0); + intel_de_write(display, TRANS_VRR_DCB_FLIPLINE_LIVE(cpu_transcoder), 0); + intel_de_write(display, TRANS_VRR_DCB_ADJ_VMAX_CFG(cpu_transcoder), 0); + intel_de_write(display, TRANS_VRR_DCB_ADJ_FLIPLINE_CFG(cpu_transcoder), 0); + intel_de_write(display, TRANS_VRR_DCB_VMAX(cpu_transcoder), 0); + intel_de_write(display, TRANS_VRR_DCB_FLIPLINE(cpu_transcoder), 0); +} + static void intel_vrr_tg_enable(const struct intel_crtc_state *crtc_state, bool cmrr_enable) { @@ -827,6 +901,7 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state) return; intel_vrr_set_vrr_timings(crtc_state); + intel_vrr_enable_dc_balancing(crtc_state); if (!intel_vrr_always_use_vrr_tg(display)) intel_vrr_tg_enable(crtc_state, crtc_state->cmrr.enable); @@ -842,6 +917,7 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state) if (!intel_vrr_always_use_vrr_tg(display)) intel_vrr_tg_disable(old_crtc_state); + intel_vrr_disable_dc_balancing(old_crtc_state); intel_vrr_set_fixed_rr_timings(old_crtc_state); } From 5e32a46f56035e329005f9d8fc7a317127e99909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 23 Dec 2025 16:15:34 +0530 Subject: [PATCH 41/92] drm/i915/vblank: Extract vrr_vblank_start() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initialise delayed vblank position for evasion logic. Signed-off-by: Ville Syrjälä Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-13-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_vblank.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index d7028ac2c4bd..2369d07de63f 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -651,6 +651,14 @@ intel_pre_commit_crtc_state(struct intel_atomic_state *state, return pre_commit_crtc_state(old_crtc_state, new_crtc_state); } +static int vrr_vblank_start(const struct intel_crtc_state *crtc_state) +{ + if (intel_vrr_is_push_sent(crtc_state)) + return intel_vrr_vmin_vblank_start(crtc_state); + else + return intel_vrr_vmax_vblank_start(crtc_state); +} + void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, const struct intel_crtc_state *new_crtc_state, struct intel_vblank_evade_ctx *evade) @@ -677,10 +685,7 @@ void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, drm_WARN_ON(crtc->base.dev, intel_crtc_needs_modeset(new_crtc_state) || new_crtc_state->update_m_n || new_crtc_state->update_lrr); - if (intel_vrr_is_push_sent(crtc_state)) - evade->vblank_start = intel_vrr_vmin_vblank_start(crtc_state); - else - evade->vblank_start = intel_vrr_vmax_vblank_start(crtc_state); + evade->vblank_start = vrr_vblank_start(crtc_state); vblank_delay = crtc_state->set_context_latency; } else { From 5bb6250c34781f3c6856b41454ea83325f2adc1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 23 Dec 2025 16:15:35 +0530 Subject: [PATCH 42/92] drm/i915/vrr: Implement vblank evasion with DC balancing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add vblank evasion logic when vrr is already enabled along with dc balance is computed. Signed-off-by: Ville Syrjälä Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-14-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_dsb.c | 31 ++++++++++++++++++++- drivers/gpu/drm/i915/display/intel_vblank.c | 26 +++++++++++++++-- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index ec2a3fb171ab..91060e2a5762 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -704,7 +704,36 @@ void intel_dsb_vblank_evade(struct intel_atomic_state *state, if (crtc_state->has_psr) intel_dsb_emit_wait_dsl(dsb, DSB_OPCODE_WAIT_DSL_OUT, 0, 0); - if (pre_commit_is_vrr_active(state, crtc)) { + if (pre_commit_is_vrr_active(state, crtc) && crtc_state->vrr.dc_balance.enable) { + int vblank_delay = crtc_state->set_context_latency; + int vmin_vblank_start, vmax_vblank_start; + + vmin_vblank_start = intel_vrr_dcb_vmin_vblank_start_next(crtc_state); + + if (vmin_vblank_start >= 0) { + end = vmin_vblank_start; + start = end - vblank_delay - latency; + intel_dsb_wait_scanline_out(state, dsb, start, end); + } + + vmax_vblank_start = intel_vrr_dcb_vmax_vblank_start_next(crtc_state); + + if (vmax_vblank_start >= 0) { + end = vmax_vblank_start; + start = end - vblank_delay - latency; + intel_dsb_wait_scanline_out(state, dsb, start, end); + } + + vmin_vblank_start = intel_vrr_dcb_vmin_vblank_start_final(crtc_state); + end = vmin_vblank_start; + start = end - vblank_delay - latency; + intel_dsb_wait_scanline_out(state, dsb, start, end); + + vmax_vblank_start = intel_vrr_dcb_vmax_vblank_start_final(crtc_state); + end = vmax_vblank_start; + start = end - vblank_delay - latency; + intel_dsb_wait_scanline_out(state, dsb, start, end); + } else if (pre_commit_is_vrr_active(state, crtc)) { int vblank_delay = crtc_state->set_context_latency; end = intel_vrr_vmin_vblank_start(crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index 2369d07de63f..1b7cfe226ff8 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -653,10 +653,30 @@ intel_pre_commit_crtc_state(struct intel_atomic_state *state, static int vrr_vblank_start(const struct intel_crtc_state *crtc_state) { - if (intel_vrr_is_push_sent(crtc_state)) - return intel_vrr_vmin_vblank_start(crtc_state); + bool is_push_sent = intel_vrr_is_push_sent(crtc_state); + int vblank_start; + + if (!crtc_state->vrr.dc_balance.enable) { + if (is_push_sent) + return intel_vrr_vmin_vblank_start(crtc_state); + else + return intel_vrr_vmax_vblank_start(crtc_state); + } + + if (is_push_sent) + vblank_start = intel_vrr_dcb_vmin_vblank_start_next(crtc_state); else - return intel_vrr_vmax_vblank_start(crtc_state); + vblank_start = intel_vrr_dcb_vmax_vblank_start_next(crtc_state); + + if (vblank_start >= 0) + return vblank_start; + + if (is_push_sent) + vblank_start = intel_vrr_dcb_vmin_vblank_start_final(crtc_state); + else + vblank_start = intel_vrr_dcb_vmax_vblank_start_final(crtc_state); + + return vblank_start; } void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, From c4aba65c26fdf15e00b4591b615f5f30ef33633d Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 23 Dec 2025 16:15:36 +0530 Subject: [PATCH 43/92] drm/i915/display: Wait for VRR PUSH status update After VRR Push is sent, need to wait till flipline decision boundary to get Push bit to get cleared. --v2: - Adjust delays to vrr vmin vblank delays. (Ankit) --v3: - Change intel_vrr_vmin_safe_window_end() so that intel_dsb_wait_for_delayed_vblank() uses correct delay. (Ankit) --v4: - Simplify intel_vrr_vmin_safe_window_end implementation. (Ankit) Signed-off-by: Mitul Golani Reviewed-by: Uma Shankar Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-15-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_vrr.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 68b39fe0f7bc..a4a198a28519 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -1095,10 +1095,21 @@ int intel_vrr_safe_window_start(const struct intel_crtc_state *crtc_state) return crtc_state->hw.adjusted_mode.crtc_vdisplay; } +static int +intel_vrr_dcb_vmin_vblank_start(const struct intel_crtc_state *crtc_state) +{ + return (intel_vrr_dcb_vmin_vblank_start_next(crtc_state) < 0) ? + intel_vrr_dcb_vmin_vblank_start_final(crtc_state) : + intel_vrr_dcb_vmin_vblank_start_next(crtc_state); +} + int intel_vrr_vmin_safe_window_end(const struct intel_crtc_state *crtc_state) { - return intel_vrr_vmin_vblank_start(crtc_state) - - crtc_state->set_context_latency; + int vmin_vblank_start = crtc_state->vrr.dc_balance.enable ? + intel_vrr_dcb_vmin_vblank_start(crtc_state) : + intel_vrr_vmin_vblank_start(crtc_state); + + return vmin_vblank_start - crtc_state->set_context_latency; } int intel_vrr_dcb_vmin_vblank_start_next(const struct intel_crtc_state *crtc_state) From 27a4250ca27a0995bbe66fc37c7f9bebc7a61744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 23 Dec 2025 16:15:37 +0530 Subject: [PATCH 44/92] drm/i915/dsb: Add pipedmc dc balance enable/disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add function to control DC balance enable/disable bit via DSB. --v2: Remove redundant forward declaration. Signed-off-by: Ville Syrjälä Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-16-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 17 +++++++++++++++++ drivers/gpu/drm/i915/display/intel_dmc.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 2fb6fec6dc99..e076ba7e0f28 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -1755,3 +1755,20 @@ u32 intel_pipedmc_start_mmioaddr(struct intel_crtc *crtc) return dmc ? dmc->dmc_info[dmc_id].start_mmioaddr : 0; } + +void intel_pipedmc_dcb_enable(struct intel_dsb *dsb, struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(crtc); + enum pipe pipe = crtc->pipe; + + intel_de_write_dsb(display, dsb, PIPEDMC_DCB_CTL(pipe), + PIPEDMC_ADAPTIVE_DCB_ENABLE); +} + +void intel_pipedmc_dcb_disable(struct intel_dsb *dsb, struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(crtc); + enum pipe pipe = crtc->pipe; + + intel_de_write_dsb(display, dsb, PIPEDMC_DCB_CTL(pipe), 0); +} diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index 40e9dcb033cc..9c6a42fc820e 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.h +++ b/drivers/gpu/drm/i915/display/intel_dmc.h @@ -15,6 +15,7 @@ struct intel_crtc; struct intel_crtc_state; struct intel_display; struct intel_dmc_snapshot; +struct intel_dsb; void intel_dmc_init(struct intel_display *display); void intel_dmc_load_program(struct intel_display *display); @@ -39,6 +40,8 @@ void intel_dmc_update_dc6_allowed_count(struct intel_display *display, bool star void assert_main_dmc_loaded(struct intel_display *display); void intel_pipedmc_irq_handler(struct intel_display *display, enum pipe pipe); +void intel_pipedmc_dcb_enable(struct intel_dsb *dsb, struct intel_crtc *crtc); +void intel_pipedmc_dcb_disable(struct intel_dsb *dsb, struct intel_crtc *crtc); u32 intel_pipedmc_start_mmioaddr(struct intel_crtc *crtc); void intel_pipedmc_enable_event(struct intel_crtc *crtc, From 192bc98c6fcf8c602ceaf712dc0cd616ebd73f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 23 Dec 2025 16:15:38 +0530 Subject: [PATCH 45/92] drm/i915/vrr: Pause DC Balancing for DSB commits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pause the DMC DC Balancing for the remainder of the commit so that vmin/vmax won't change after we've baked them into the DSB vblank evasion commands. --v2: - Remove typo. (Ankit) - Separate vrr enable structuring. (Ankit) --v3: - Add gaurd before accessing DC balance bits. - Remove redundancy checks. --v4: - Move events to separate function. Signed-off-by: Ville Syrjälä Signed-off-by: Mitul Golani Reviewed-by: Uma Shankar Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-17-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 19 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_vrr.c | 3 +++ 2 files changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 68e67dc2631f..039cf34b8f12 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7330,6 +7330,21 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, if (new_crtc_state->use_flipq) intel_flipq_wait_dmc_halt(new_crtc_state->dsb_commit, crtc); + if (new_crtc_state->vrr.dc_balance.enable) { + /* + * Pause the DMC DC balancing for the remainder of + * the commit so that vmin/vmax won't change after + * we've baked them into the DSB vblank evasion + * commands. + * + * FIXME maybe need a small delay here to make sure + * DMC has finished updating the values? Or we need + * a better DMC<->driver protocol that gives is real + * guarantees about that... + */ + intel_pipedmc_dcb_disable(NULL, crtc); + } + if (intel_crtc_needs_color_update(new_crtc_state)) intel_color_commit_noarm(new_crtc_state->dsb_commit, new_crtc_state); @@ -7383,6 +7398,10 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, intel_dsb_wait_for_delayed_vblank(state, new_crtc_state->dsb_commit); intel_vrr_check_push_sent(new_crtc_state->dsb_commit, new_crtc_state); + + if (new_crtc_state->vrr.dc_balance.enable) + intel_pipedmc_dcb_enable(new_crtc_state->dsb_commit, crtc); + intel_dsb_interrupt(new_crtc_state->dsb_commit); } diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index a4a198a28519..ac612cf08d98 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -10,6 +10,7 @@ #include "intel_de.h" #include "intel_display_regs.h" #include "intel_display_types.h" +#include "intel_dmc.h" #include "intel_dmc_regs.h" #include "intel_dp.h" #include "intel_psr.h" @@ -824,6 +825,7 @@ intel_vrr_enable_dc_balancing(const struct intel_crtc_state *crtc_state) crtc_state->vrr.dc_balance.vblank_target); intel_de_write(display, TRANS_ADAPTIVE_SYNC_DCB_CTL(cpu_transcoder), ADAPTIVE_SYNC_COUNTER_EN); + intel_pipedmc_dcb_enable(NULL, crtc); } static void @@ -837,6 +839,7 @@ intel_vrr_disable_dc_balancing(const struct intel_crtc_state *old_crtc_state) if (!old_crtc_state->vrr.dc_balance.enable) return; + intel_pipedmc_dcb_disable(NULL, crtc); intel_de_write(display, TRANS_ADAPTIVE_SYNC_DCB_CTL(cpu_transcoder), 0); intel_de_write(display, PIPEDMC_DCB_VMIN(pipe), 0); intel_de_write(display, PIPEDMC_DCB_VMAX(pipe), 0); From 5786499a42e6baaf27f28b64d3e55fb6b289141d Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 23 Dec 2025 16:15:39 +0530 Subject: [PATCH 46/92] drm/i915/display: Add function to configure event for dc balance Configure pipe dmc event for dc balance enable/disable. --v2: - Keeping function and removing unnecessary comments. (Jani, Nikula) Signed-off-by: Mitul Golani Reviewed-by: Uma Shankar Reviewed-by: Ankit Nautiyal Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-18-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 8 ++++++++ drivers/gpu/drm/i915/display/intel_dmc.h | 2 ++ drivers/gpu/drm/i915/display/intel_vrr.c | 2 ++ 3 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index e076ba7e0f28..1182bc9a2e6d 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -859,6 +859,14 @@ static void dmc_configure_event(struct intel_display *display, dmc_id, num_handlers, event_id); } +void intel_dmc_configure_dc_balance_event(struct intel_display *display, + enum pipe pipe, bool enable) +{ + enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe); + + dmc_configure_event(display, dmc_id, PIPEDMC_EVENT_ADAPTIVE_DCB_TRIGGER, enable); +} + /** * intel_dmc_block_pkgc() - block PKG C-state * @display: display instance diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index 9c6a42fc820e..3d8a9a593319 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.h +++ b/drivers/gpu/drm/i915/display/intel_dmc.h @@ -25,6 +25,8 @@ void intel_dmc_enable_pipe(const struct intel_crtc_state *crtc_state); void intel_dmc_disable_pipe(const struct intel_crtc_state *crtc_state); void intel_dmc_block_pkgc(struct intel_display *display, enum pipe pipe, bool block); +void intel_dmc_configure_dc_balance_event(struct intel_display *display, + enum pipe pipe, bool enable); void intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(struct intel_display *display, enum pipe pipe, bool enable); void intel_dmc_fini(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index ac612cf08d98..1522ec3a98b8 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -823,6 +823,7 @@ intel_vrr_enable_dc_balancing(const struct intel_crtc_state *crtc_state) crtc_state->vrr.dc_balance.slope); intel_de_write(display, PIPEDMC_DCB_VBLANK(pipe), crtc_state->vrr.dc_balance.vblank_target); + intel_dmc_configure_dc_balance_event(display, pipe, true); intel_de_write(display, TRANS_ADAPTIVE_SYNC_DCB_CTL(cpu_transcoder), ADAPTIVE_SYNC_COUNTER_EN); intel_pipedmc_dcb_enable(NULL, crtc); @@ -840,6 +841,7 @@ intel_vrr_disable_dc_balancing(const struct intel_crtc_state *old_crtc_state) return; intel_pipedmc_dcb_disable(NULL, crtc); + intel_dmc_configure_dc_balance_event(display, pipe, false); intel_de_write(display, TRANS_ADAPTIVE_SYNC_DCB_CTL(cpu_transcoder), 0); intel_de_write(display, PIPEDMC_DCB_VMIN(pipe), 0); intel_de_write(display, PIPEDMC_DCB_VMAX(pipe), 0); From 5558192707072d810b2c9792dfa7e4455d163705 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Tue, 23 Dec 2025 16:15:40 +0530 Subject: [PATCH 47/92] drm/i915/vrr: Enable DC Balance Enable DC Balance from vrr compute config and related hw flag. Also to add pipe restrictions along with this. --v2: - Use dc balance check instead of source restriction. --v3: - Club pipe restriction check with dc balance enablement. (Ankit) --v4: - Separate out Pipe restrictions to patch#7 Signed-off-by: Mitul Golani Reviewed-by: Uma Shankar Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20251223104542.2688548-19-mitulkumar.ajitkumar.golani@intel.com --- drivers/gpu/drm/i915/display/intel_vrr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 1522ec3a98b8..db74744ddb31 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -399,6 +399,7 @@ intel_vrr_dc_balance_compute_config(struct intel_crtc_state *crtc_state) crtc_state->vrr.dc_balance.vblank_target = DIV_ROUND_UP((crtc_state->vrr.vmax - crtc_state->vrr.vmin) * DCB_BLANK_TARGET, 100); + crtc_state->vrr.dc_balance.enable = true; } void @@ -789,6 +790,7 @@ intel_vrr_enable_dc_balancing(const struct intel_crtc_state *crtc_state) enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); enum pipe pipe = crtc->pipe; + u32 vrr_ctl = intel_de_read(display, TRANS_VRR_CTL(display, cpu_transcoder)); if (!crtc_state->vrr.dc_balance.enable) return; @@ -827,6 +829,9 @@ intel_vrr_enable_dc_balancing(const struct intel_crtc_state *crtc_state) intel_de_write(display, TRANS_ADAPTIVE_SYNC_DCB_CTL(cpu_transcoder), ADAPTIVE_SYNC_COUNTER_EN); intel_pipedmc_dcb_enable(NULL, crtc); + + vrr_ctl |= VRR_CTL_DCB_ADJ_ENABLE; + intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), vrr_ctl); } static void @@ -836,6 +841,7 @@ intel_vrr_disable_dc_balancing(const struct intel_crtc_state *old_crtc_state) enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); enum pipe pipe = crtc->pipe; + u32 vrr_ctl = intel_de_read(display, TRANS_VRR_CTL(display, cpu_transcoder)); if (!old_crtc_state->vrr.dc_balance.enable) return; @@ -858,6 +864,9 @@ intel_vrr_disable_dc_balancing(const struct intel_crtc_state *old_crtc_state) intel_de_write(display, TRANS_VRR_DCB_ADJ_FLIPLINE_CFG(cpu_transcoder), 0); intel_de_write(display, TRANS_VRR_DCB_VMAX(cpu_transcoder), 0); intel_de_write(display, TRANS_VRR_DCB_FLIPLINE(cpu_transcoder), 0); + + vrr_ctl &= ~VRR_CTL_DCB_ADJ_ENABLE; + intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), vrr_ctl); } static void intel_vrr_tg_enable(const struct intel_crtc_state *crtc_state, From aae766f5d31070284561073086ed0a8d2ae15856 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 29 Dec 2025 13:54:43 +0200 Subject: [PATCH 48/92] drm/i915: drop i915 param from i915_fence{, _context}_timeout() The i915_fence_context_timeout() and i915_fence_timeout() functions both have the struct drm_i915_private parameter, which is unused. It's likely in preparation for something that just didn't end up happening. Remove them, dropping the last struct drm_i915_private usage for xe display build. Reviewed-by: Matt Roper Link: https://patch.msgid.link/dce86cb031d523a95a96ed2bf9c93bb28e6b20ab.1767009044.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 4 +--- drivers/gpu/drm/i915/gem/i915_gem_clflush.c | 2 +- drivers/gpu/drm/i915/i915_config.c | 3 +-- drivers/gpu/drm/i915/i915_config.h | 10 +++------- drivers/gpu/drm/i915/i915_request.c | 3 +-- drivers/gpu/drm/xe/compat-i915-headers/i915_config.h | 5 +---- 6 files changed, 8 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 039cf34b8f12..81b3a6692ca2 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -50,7 +50,6 @@ #include "g4x_hdmi.h" #include "hsw_ips.h" #include "i915_config.h" -#include "i915_drv.h" #include "i915_reg.h" #include "i9xx_plane.h" #include "i9xx_plane_regs.h" @@ -7165,7 +7164,6 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_state) { - struct drm_i915_private *i915 = to_i915(intel_state->base.dev); struct drm_plane *plane; struct drm_plane_state *new_plane_state; long ret; @@ -7174,7 +7172,7 @@ static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_stat for_each_new_plane_in_state(&intel_state->base, plane, new_plane_state, i) { if (new_plane_state->fence) { ret = dma_fence_wait_timeout(new_plane_state->fence, false, - i915_fence_timeout(i915)); + i915_fence_timeout()); if (ret <= 0) break; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_clflush.c b/drivers/gpu/drm/i915/gem/i915_gem_clflush.c index c4854c5b4e0f..c1deea20c28a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_clflush.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_clflush.c @@ -113,7 +113,7 @@ bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, if (clflush) { i915_sw_fence_await_reservation(&clflush->base.chain, obj->base.resv, true, - i915_fence_timeout(i915), + i915_fence_timeout(), I915_FENCE_GFP); dma_resv_add_fence(obj->base.resv, &clflush->base.dma, DMA_RESV_USAGE_KERNEL); diff --git a/drivers/gpu/drm/i915/i915_config.c b/drivers/gpu/drm/i915/i915_config.c index 3cb615ffa96d..9e13b1be407c 100644 --- a/drivers/gpu/drm/i915/i915_config.c +++ b/drivers/gpu/drm/i915/i915_config.c @@ -8,8 +8,7 @@ #include "i915_config.h" #include "i915_jiffies.h" -unsigned long -i915_fence_context_timeout(const struct drm_i915_private *i915, u64 context) +unsigned long i915_fence_context_timeout(u64 context) { if (CONFIG_DRM_I915_FENCE_TIMEOUT && context) return msecs_to_jiffies_timeout(CONFIG_DRM_I915_FENCE_TIMEOUT); diff --git a/drivers/gpu/drm/i915/i915_config.h b/drivers/gpu/drm/i915/i915_config.h index 10e18b036489..f386328d9e95 100644 --- a/drivers/gpu/drm/i915/i915_config.h +++ b/drivers/gpu/drm/i915/i915_config.h @@ -9,15 +9,11 @@ #include #include -struct drm_i915_private; +unsigned long i915_fence_context_timeout(u64 context); -unsigned long i915_fence_context_timeout(const struct drm_i915_private *i915, - u64 context); - -static inline unsigned long -i915_fence_timeout(const struct drm_i915_private *i915) +static inline unsigned long i915_fence_timeout(void) { - return i915_fence_context_timeout(i915, U64_MAX); + return i915_fence_context_timeout(U64_MAX); } #endif /* __I915_CONFIG_H__ */ diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 4399941236cb..d2c7b1090df0 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -1351,8 +1351,7 @@ __i915_request_await_external(struct i915_request *rq, struct dma_fence *fence) { mark_external(rq); return i915_sw_fence_await_dma_fence(&rq->submit, fence, - i915_fence_context_timeout(rq->i915, - fence->context), + i915_fence_context_timeout(fence->context), I915_FENCE_GFP); } diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_config.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_config.h index e835bea08d1b..d4522203e2dd 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_config.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_config.h @@ -8,10 +8,7 @@ #include -struct drm_i915_private; - -static inline unsigned long -i915_fence_timeout(const struct drm_i915_private *i915) +static inline unsigned long i915_fence_timeout(void) { return MAX_SCHEDULE_TIMEOUT; } From 51489bae202f629abb5c896b00099f0de22c875d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 29 Dec 2025 13:54:44 +0200 Subject: [PATCH 49/92] drm/xe: remove compat i915_drv.h and -Ddrm_i915_private=xe_device hack The xe display build no longer needs the compat i915_drv.h or the ugly -Ddrm_i915_private=xe_device hack. Remove them, with great pleasure. Reviewed-by: Matt Roper Link: https://patch.msgid.link/8d2da5404439ed334d7682922b599f36eeb60e9d.1767009044.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/xe/Makefile | 3 +-- .../gpu/drm/xe/compat-i915-headers/i915_drv.h | 22 ------------------- 2 files changed, 1 insertion(+), 24 deletions(-) delete mode 100644 drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 2751599a5cc8..e76224c848d0 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -196,8 +196,7 @@ endif # i915 Display compat #defines and #includes subdir-ccflags-$(CONFIG_DRM_XE_DISPLAY) += \ -I$(src)/compat-i915-headers \ - -I$(srctree)/drivers/gpu/drm/i915/display/ \ - -Ddrm_i915_private=xe_device + -I$(srctree)/drivers/gpu/drm/i915/display/ # Rule to build display code shared with i915 $(obj)/i915-display/%.o: $(srctree)/drivers/gpu/drm/i915/display/%.c FORCE diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h deleted file mode 100644 index 04d1925f9a19..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ -#ifndef _XE_I915_DRV_H_ -#define _XE_I915_DRV_H_ - -/* - * "Adaptation header" to allow i915 display to also build for xe driver. - * TODO: refactor i915 and xe so this can cease to exist - */ - -#include - -#include "xe_device_types.h" - -static inline struct drm_i915_private *to_i915(const struct drm_device *dev) -{ - return container_of(dev, struct drm_i915_private, drm); -} - -#endif From bb6a4985680b89653809bc4aa54c940796f14066 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 29 Dec 2025 13:54:45 +0200 Subject: [PATCH 50/92] drm/i915/utils: drop unnecessary ifdefs The i915_utils.h and intel_display_utils.h were in some cases included from the same files, the former via i915_drv.h and the latter directly. This lead to a clash between MISSING_CASE() and fetch_and_zero() defined in both, requiring ifdefs. With the display dependency on i915_drv.h removed, we can also remove the now unnecessary ifdefs. Reviewed-by: Matt Roper Link: https://patch.msgid.link/f40a1fd365cbcfb77bd76ce0041c4523699f6052.1767009044.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_utils.h | 4 ---- drivers/gpu/drm/i915/i915_utils.h | 4 ---- 2 files changed, 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_utils.h b/drivers/gpu/drm/i915/display/intel_display_utils.h index 2a18f160320c..affa3179f52c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_utils.h +++ b/drivers/gpu/drm/i915/display/intel_display_utils.h @@ -9,18 +9,14 @@ struct intel_display; -#ifndef MISSING_CASE #define MISSING_CASE(x) WARN(1, "Missing case (%s == %ld)\n", \ __stringify(x), (long)(x)) -#endif -#ifndef fetch_and_zero #define fetch_and_zero(ptr) ({ \ typeof(*ptr) __T = *(ptr); \ *(ptr) = (typeof(*ptr))0; \ __T; \ }) -#endif #define KHz(x) (1000 * (x)) #define MHz(x) KHz(1000 * (x)) diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index 9e5b7fcadbe2..ecc20e0528f4 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -38,22 +38,18 @@ struct drm_i915_private; -#ifndef MISSING_CASE #define MISSING_CASE(x) WARN(1, "Missing case (%s == %ld)\n", \ __stringify(x), (long)(x)) -#endif #define i915_probe_error(i915, fmt, ...) ({ \ drm_err(&(i915)->drm, fmt, ##__VA_ARGS__); \ }) -#ifndef fetch_and_zero #define fetch_and_zero(ptr) ({ \ typeof(*ptr) __T = *(ptr); \ *(ptr) = (typeof(*ptr))0; \ __T; \ }) -#endif /* * check_user_mbz: Check that a user value exists and is zero From 9c4a56a8b73aacfaec741b81051eefeac92d8987 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 31 Dec 2025 12:32:32 +0200 Subject: [PATCH 51/92] drm/i915/display: remove accidentally added empty file intel_display_limits.c was never supposed to be added. Remove it. Fixes: f3255cf4490e ("drm/i915/display: Add APIs to be used by gvt to get the register offsets") Cc: Ankit Nautiyal Reviewed-by: Ankit Nautiyal Link: https://patch.msgid.link/20251231103232.627666-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_limits.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 drivers/gpu/drm/i915/display/intel_display_limits.c diff --git a/drivers/gpu/drm/i915/display/intel_display_limits.c b/drivers/gpu/drm/i915/display/intel_display_limits.c deleted file mode 100644 index e69de29bb2d1..000000000000 From 1bc99cdc1db9c74204ca3706bb60f0eba58bcb52 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 31 Dec 2025 13:26:07 +0200 Subject: [PATCH 52/92] drm/i915/gvt: sort and group include directives The include directives are a bit of a mess in gvt. Sort and group them to make them easier to deal with. Reviewed-by: Ankit Nautiyal Link: https://patch.msgid.link/c9f2b5a7367671965a7f5fa4f22b94ce9b980cfd.1767180318.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gvt/aperture_gm.c | 5 +++-- drivers/gpu/drm/i915/gvt/cfg_space.c | 2 +- drivers/gpu/drm/i915/gvt/cmd_parser.c | 24 +++++++++++---------- drivers/gpu/drm/i915/gvt/debugfs.c | 4 +++- drivers/gpu/drm/i915/gvt/display.c | 12 +++++------ drivers/gpu/drm/i915/gvt/display.h | 2 +- drivers/gpu/drm/i915/gvt/dmabuf.c | 6 +++--- drivers/gpu/drm/i915/gvt/dmabuf.h | 1 + drivers/gpu/drm/i915/gvt/edid.c | 1 + drivers/gpu/drm/i915/gvt/execlist.c | 2 +- drivers/gpu/drm/i915/gvt/fb_decoder.c | 14 ++++++------ drivers/gpu/drm/i915/gvt/firmware.c | 4 ++-- drivers/gpu/drm/i915/gvt/gtt.c | 9 ++++---- drivers/gpu/drm/i915/gvt/gvt.h | 23 ++++++++++---------- drivers/gpu/drm/i915/gvt/handlers.c | 17 +++++++++------ drivers/gpu/drm/i915/gvt/interrupt.c | 5 +++-- drivers/gpu/drm/i915/gvt/kvmgt.c | 23 ++++++++++---------- drivers/gpu/drm/i915/gvt/mmio.c | 13 +++++------ drivers/gpu/drm/i915/gvt/opregion.c | 3 ++- drivers/gpu/drm/i915/gvt/page_track.c | 3 ++- drivers/gpu/drm/i915/gvt/sched_policy.c | 2 +- drivers/gpu/drm/i915/gvt/scheduler.c | 3 ++- drivers/gpu/drm/i915/gvt/trace.h | 2 +- drivers/gpu/drm/i915/gvt/trace_points.c | 2 ++ drivers/gpu/drm/i915/gvt/vgpu.c | 5 +++-- drivers/gpu/drm/i915/intel_gvt.c | 13 ++++++----- drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 4 +++- 27 files changed, 113 insertions(+), 91 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c index 8cc6e712b0f7..253b41789be9 100644 --- a/drivers/gpu/drm/i915/gvt/aperture_gm.c +++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c @@ -36,10 +36,11 @@ #include +#include "gt/intel_ggtt_fencing.h" + +#include "gvt.h" #include "i915_drv.h" #include "i915_reg.h" -#include "gt/intel_ggtt_fencing.h" -#include "gvt.h" static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm) { diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c index 295a7b5e1d7c..1937e04d3791 100644 --- a/drivers/gpu/drm/i915/gvt/cfg_space.c +++ b/drivers/gpu/drm/i915/gvt/cfg_space.c @@ -33,8 +33,8 @@ #include -#include "i915_drv.h" #include "gvt.h" +#include "i915_drv.h" #include "intel_pci_config.h" enum { diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index e5301733f4e4..bf7c3d3f5f8a 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -38,26 +38,28 @@ #include -#include "i915_drv.h" -#include "i915_reg.h" +#include "display/i9xx_plane_regs.h" #include "display/intel_display_regs.h" +#include "display/intel_sprite_regs.h" + +#include "gem/i915_gem_context.h" +#include "gem/i915_gem_pm.h" + +#include "gt/intel_context.h" #include "gt/intel_engine_regs.h" #include "gt/intel_gpu_commands.h" #include "gt/intel_gt_regs.h" +#include "gt/intel_gt_requests.h" #include "gt/intel_lrc.h" #include "gt/intel_ring.h" -#include "gt/intel_gt_requests.h" #include "gt/shmem_utils.h" -#include "gvt.h" -#include "i915_pvinfo.h" -#include "trace.h" -#include "display/i9xx_plane_regs.h" -#include "display/intel_sprite_regs.h" -#include "gem/i915_gem_context.h" -#include "gem/i915_gem_pm.h" -#include "gt/intel_context.h" #include "display_helpers.h" +#include "gvt.h" +#include "i915_drv.h" +#include "i915_pvinfo.h" +#include "i915_reg.h" +#include "trace.h" #define INVALID_OP (~0U) diff --git a/drivers/gpu/drm/i915/gvt/debugfs.c b/drivers/gpu/drm/i915/gvt/debugfs.c index 415422b5943c..ae3fd2c3cd23 100644 --- a/drivers/gpu/drm/i915/gvt/debugfs.c +++ b/drivers/gpu/drm/i915/gvt/debugfs.c @@ -20,10 +20,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ + #include #include -#include "i915_drv.h" + #include "gvt.h" +#include "i915_drv.h" struct mmio_diff_param { struct intel_vgpu *vgpu; diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index f230b07a12ae..21341842c0a9 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c @@ -35,21 +35,21 @@ #include #include -#include "i915_drv.h" -#include "i915_reg.h" -#include "display/intel_display_regs.h" -#include "gvt.h" - #include "display/bxt_dpio_phy_regs.h" #include "display/i9xx_plane_regs.h" #include "display/intel_crt_regs.h" #include "display/intel_cursor_regs.h" #include "display/intel_display.h" -#include "display_helpers.h" +#include "display/intel_display_regs.h" #include "display/intel_dpio_phy.h" #include "display/intel_dpll_mgr.h" #include "display/intel_sprite_regs.h" +#include "display_helpers.h" +#include "gvt.h" +#include "i915_drv.h" +#include "i915_reg.h" + static int get_edp_pipe(struct intel_vgpu *vgpu) { u32 data = vgpu_vreg(vgpu, _TRANS_DDI_FUNC_CTL_EDP); diff --git a/drivers/gpu/drm/i915/gvt/display.h b/drivers/gpu/drm/i915/gvt/display.h index bc7f05f9a271..41a3b053663a 100644 --- a/drivers/gpu/drm/i915/gvt/display.h +++ b/drivers/gpu/drm/i915/gvt/display.h @@ -35,8 +35,8 @@ #ifndef _GVT_DISPLAY_H_ #define _GVT_DISPLAY_H_ -#include #include +#include struct intel_gvt; struct intel_vgpu; diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c index 92506c80322d..8e76869b352c 100644 --- a/drivers/gpu/drm/i915/gvt/dmabuf.c +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c @@ -35,12 +35,12 @@ #include #include +#include "display/skl_universal_plane_regs.h" + #include "gem/i915_gem_dmabuf.h" -#include "i915_drv.h" #include "gvt.h" - -#include "display/skl_universal_plane_regs.h" +#include "i915_drv.h" #define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12)) diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.h b/drivers/gpu/drm/i915/gvt/dmabuf.h index 3dcdb6570eda..06445e1cf3cf 100644 --- a/drivers/gpu/drm/i915/gvt/dmabuf.h +++ b/drivers/gpu/drm/i915/gvt/dmabuf.h @@ -30,6 +30,7 @@ #ifndef _GVT_DMABUF_H_ #define _GVT_DMABUF_H_ + #include struct intel_vgpu_fb_info { diff --git a/drivers/gpu/drm/i915/gvt/edid.c b/drivers/gpu/drm/i915/gvt/edid.c index 30e414381af3..021afff1cd5d 100644 --- a/drivers/gpu/drm/i915/gvt/edid.c +++ b/drivers/gpu/drm/i915/gvt/edid.c @@ -38,6 +38,7 @@ #include "display/intel_dp_aux_regs.h" #include "display/intel_gmbus.h" #include "display/intel_gmbus_regs.h" + #include "gvt.h" #include "i915_drv.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c index 274c6ef42400..29147a9f162e 100644 --- a/drivers/gpu/drm/i915/gvt/execlist.c +++ b/drivers/gpu/drm/i915/gvt/execlist.c @@ -32,8 +32,8 @@ * */ -#include "i915_drv.h" #include "gvt.h" +#include "i915_drv.h" #define _EL_OFFSET_STATUS 0x234 #define _EL_OFFSET_STATUS_BUF 0x370 diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c b/drivers/gpu/drm/i915/gvt/fb_decoder.c index 3d1a7e5c8cd3..d7abf38df532 100644 --- a/drivers/gpu/drm/i915/gvt/fb_decoder.c +++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c @@ -35,17 +35,17 @@ #include +#include "display/i9xx_plane_regs.h" +#include "display/intel_cursor_regs.h" +#include "display/intel_display_regs.h" +#include "display/intel_sprite_regs.h" +#include "display/skl_universal_plane_regs.h" + +#include "display_helpers.h" #include "gvt.h" #include "i915_drv.h" #include "i915_pvinfo.h" #include "i915_reg.h" -#include "display/intel_display_regs.h" - -#include "display/i9xx_plane_regs.h" -#include "display/intel_cursor_regs.h" -#include "display/intel_sprite_regs.h" -#include "display/skl_universal_plane_regs.h" -#include "display_helpers.h" #define PRIMARY_FORMAT_NUM 16 struct pixel_format { diff --git a/drivers/gpu/drm/i915/gvt/firmware.c b/drivers/gpu/drm/i915/gvt/firmware.c index 221a3ae81baf..e452298991be 100644 --- a/drivers/gpu/drm/i915/gvt/firmware.c +++ b/drivers/gpu/drm/i915/gvt/firmware.c @@ -28,12 +28,12 @@ * */ -#include #include +#include #include -#include "i915_drv.h" #include "gvt.h" +#include "i915_drv.h" #include "i915_pvinfo.h" #define FIRMWARE_VERSION (0x0) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 076d9139edc6..49028e7ef1e0 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -33,16 +33,17 @@ * */ +#include + #include -#include "i915_drv.h" +#include "gt/intel_gt_regs.h" + #include "gvt.h" +#include "i915_drv.h" #include "i915_pvinfo.h" #include "trace.h" -#include "gt/intel_gt_regs.h" -#include - #if defined(VERBOSE_DEBUG) #define gvt_vdbg_mm(fmt, args...) gvt_dbg_mm(fmt, ##args) #else diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 1d10c16e6465..965d94610d56 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -34,29 +34,28 @@ #define _GVT_H_ #include -#include #include - +#include #include #include "gt/intel_gt.h" -#include "intel_gvt.h" +#include "cmd_parser.h" #include "debug.h" -#include "mmio.h" -#include "reg.h" -#include "interrupt.h" -#include "gtt.h" #include "display.h" +#include "dmabuf.h" #include "edid.h" #include "execlist.h" -#include "scheduler.h" -#include "sched_policy.h" -#include "mmio_context.h" -#include "cmd_parser.h" #include "fb_decoder.h" -#include "dmabuf.h" +#include "gtt.h" +#include "intel_gvt.h" +#include "interrupt.h" +#include "mmio.h" +#include "mmio_context.h" #include "page_track.h" +#include "reg.h" +#include "sched_policy.h" +#include "scheduler.h" #define GVT_MAX_VGPU 8 diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 7063d3c77562..04cfe0997cde 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -36,19 +36,16 @@ */ +#include + #include #include -#include "i915_drv.h" -#include "i915_reg.h" -#include "display/intel_display_regs.h" -#include "gvt.h" -#include "i915_pvinfo.h" -#include "intel_mchbar_regs.h" #include "display/bxt_dpio_phy_regs.h" #include "display/i9xx_plane_regs.h" #include "display/intel_crt_regs.h" #include "display/intel_cursor_regs.h" +#include "display/intel_display_regs.h" #include "display/intel_display_types.h" #include "display/intel_dmc_regs.h" #include "display/intel_dp_aux_regs.h" @@ -63,9 +60,15 @@ #include "display/skl_universal_plane_regs.h" #include "display/skl_watermark_regs.h" #include "display/vlv_dsi_pll_regs.h" + #include "gt/intel_gt_regs.h" -#include + #include "display_helpers.h" +#include "gvt.h" +#include "i915_drv.h" +#include "i915_pvinfo.h" +#include "i915_reg.h" +#include "intel_mchbar_regs.h" /* XXX FIXME i915 has changed PP_XXX definition */ #define PCH_PP_STATUS _MMIO(0xc7200) diff --git a/drivers/gpu/drm/i915/gvt/interrupt.c b/drivers/gpu/drm/i915/gvt/interrupt.c index 3e66269bc4ee..91d22b1c62e2 100644 --- a/drivers/gpu/drm/i915/gvt/interrupt.c +++ b/drivers/gpu/drm/i915/gvt/interrupt.c @@ -33,10 +33,11 @@ #include +#include "display/intel_display_regs.h" + +#include "gvt.h" #include "i915_drv.h" #include "i915_reg.h" -#include "display/intel_display_regs.h" -#include "gvt.h" #include "trace.h" struct intel_gvt_irq_info { diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 3abc9206f1a8..b3739c9fcc48 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -33,26 +33,25 @@ * Zhi Wang */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include - +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include +#include "gvt.h" #include "i915_drv.h" #include "intel_gvt.h" -#include "gvt.h" MODULE_IMPORT_NS("DMA_BUF"); MODULE_IMPORT_NS("I915_GVT"); diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c index 214eb7effa31..9e98db2d4f67 100644 --- a/drivers/gpu/drm/i915/gvt/mmio.c +++ b/drivers/gpu/drm/i915/gvt/mmio.c @@ -37,14 +37,15 @@ #include +#include "display/bxt_dpio_phy_regs.h" +#include "display/intel_display_regs.h" +#include "display/intel_dpio_phy.h" + +#include "gt/intel_gt_regs.h" + +#include "gvt.h" #include "i915_drv.h" #include "i915_reg.h" -#include "display/intel_display_regs.h" -#include "gvt.h" - -#include "display/bxt_dpio_phy_regs.h" -#include "display/intel_dpio_phy.h" -#include "gt/intel_gt_regs.h" /** * intel_vgpu_gpa_to_mmio_offset - translate a GPA to MMIO offset diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c index dbad4d853d3a..d6e76ba31d60 100644 --- a/drivers/gpu/drm/i915/gvt/opregion.c +++ b/drivers/gpu/drm/i915/gvt/opregion.c @@ -22,8 +22,9 @@ */ #include -#include "i915_drv.h" + #include "gvt.h" +#include "i915_drv.h" /* * Note: Only for GVT-g virtual VBT generation, other usage must diff --git a/drivers/gpu/drm/i915/gvt/page_track.c b/drivers/gpu/drm/i915/gvt/page_track.c index 20c3cd807488..b22ef801963e 100644 --- a/drivers/gpu/drm/i915/gvt/page_track.c +++ b/drivers/gpu/drm/i915/gvt/page_track.c @@ -20,8 +20,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "i915_drv.h" + #include "gvt.h" +#include "i915_drv.h" /** * intel_vgpu_find_page_track - find page track rcord of guest page diff --git a/drivers/gpu/drm/i915/gvt/sched_policy.c b/drivers/gpu/drm/i915/gvt/sched_policy.c index 6c2d68e88266..df787472b1cf 100644 --- a/drivers/gpu/drm/i915/gvt/sched_policy.c +++ b/drivers/gpu/drm/i915/gvt/sched_policy.c @@ -31,8 +31,8 @@ * */ -#include "i915_drv.h" #include "gvt.h" +#include "i915_drv.h" static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu) { diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 63ad1fed525a..a91accfd371d 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -38,16 +38,17 @@ #include #include "gem/i915_gem_pm.h" + #include "gt/intel_context.h" #include "gt/intel_execlists_submission.h" #include "gt/intel_gt_regs.h" #include "gt/intel_lrc.h" #include "gt/intel_ring.h" +#include "gvt.h" #include "i915_drv.h" #include "i915_gem_gtt.h" #include "i915_perf_oa_regs.h" -#include "gvt.h" #define RING_CTX_OFF(x) \ offsetof(struct execlist_ring_context, x) diff --git a/drivers/gpu/drm/i915/gvt/trace.h b/drivers/gpu/drm/i915/gvt/trace.h index 63874d385c6f..8cd0601e478f 100644 --- a/drivers/gpu/drm/i915/gvt/trace.h +++ b/drivers/gpu/drm/i915/gvt/trace.h @@ -31,9 +31,9 @@ #if !defined(_GVT_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) #define _GVT_TRACE_H_ -#include #include #include +#include #include #undef TRACE_SYSTEM diff --git a/drivers/gpu/drm/i915/gvt/trace_points.c b/drivers/gpu/drm/i915/gvt/trace_points.c index fe552e877e09..79b75356d622 100644 --- a/drivers/gpu/drm/i915/gvt/trace_points.c +++ b/drivers/gpu/drm/i915/gvt/trace_points.c @@ -30,5 +30,7 @@ #ifndef __CHECKER__ #define CREATE_TRACE_POINTS + #include "trace.h" + #endif diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c index c49e4bf95a30..a12011410874 100644 --- a/drivers/gpu/drm/i915/gvt/vgpu.c +++ b/drivers/gpu/drm/i915/gvt/vgpu.c @@ -31,12 +31,13 @@ * */ +#include + #include -#include "i915_drv.h" #include "gvt.h" +#include "i915_drv.h" #include "i915_pvinfo.h" -#include void populate_pvinfo_page(struct intel_vgpu *vgpu) { diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c index 5f615ec0e580..6b43713899b8 100644 --- a/drivers/gpu/drm/i915/intel_gvt.c +++ b/drivers/gpu/drm/i915/intel_gvt.c @@ -21,16 +21,19 @@ * SOFTWARE. */ +#include + #include +#include "gem/i915_gem_dmabuf.h" + +#include "gt/intel_context.h" +#include "gt/intel_ring.h" +#include "gt/shmem_utils.h" + #include "i915_drv.h" #include "i915_vgpu.h" #include "intel_gvt.h" -#include "gem/i915_gem_dmabuf.h" -#include "gt/intel_context.h" -#include "gt/intel_ring.h" -#include "gt/shmem_utils.h" -#include /** * DOC: Intel GVT-g host support diff --git a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c index ca57a3dd3148..478d00f89a4b 100644 --- a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c +++ b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c @@ -12,6 +12,7 @@ #include "display/intel_crt_regs.h" #include "display/intel_cursor_regs.h" #include "display/intel_display_core.h" +#include "display/intel_display_regs.h" #include "display/intel_display_types.h" #include "display/intel_dmc_regs.h" #include "display/intel_dp_aux_regs.h" @@ -27,14 +28,15 @@ #include "display/skl_universal_plane_regs.h" #include "display/skl_watermark_regs.h" #include "display/vlv_dsi_pll_regs.h" + #include "gt/intel_engine_regs.h" #include "gt/intel_gt_regs.h" + #include "gvt/reg.h" #include "i915_drv.h" #include "i915_pvinfo.h" #include "i915_reg.h" -#include "display/intel_display_regs.h" #include "intel_gvt.h" #include "intel_mchbar_regs.h" From 0eccf37660aebf9be4b35dac6c30ae729c42a720 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 31 Dec 2025 13:26:08 +0200 Subject: [PATCH 53/92] drm/i915/gvt: include sched_policy.h only where needed Not everything needs sched_policy.h. Drop it from gvt.h, and include where needed. Reviewed-by: Ankit Nautiyal Link: https://patch.msgid.link/2807f82cf571ed6e736242bdfad786efcad50f02.1767180318.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gvt/gvt.h | 1 - drivers/gpu/drm/i915/gvt/handlers.c | 1 + drivers/gpu/drm/i915/gvt/kvmgt.c | 1 + drivers/gpu/drm/i915/gvt/sched_policy.c | 1 + drivers/gpu/drm/i915/gvt/scheduler.c | 1 + drivers/gpu/drm/i915/gvt/vgpu.c | 1 + 6 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 965d94610d56..9adcdecadaa8 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -54,7 +54,6 @@ #include "mmio_context.h" #include "page_track.h" #include "reg.h" -#include "sched_policy.h" #include "scheduler.h" #define GVT_MAX_VGPU 8 diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 04cfe0997cde..68afd9b046d4 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -69,6 +69,7 @@ #include "i915_pvinfo.h" #include "i915_reg.h" #include "intel_mchbar_regs.h" +#include "sched_policy.h" /* XXX FIXME i915 has changed PP_XXX definition */ #define PCH_PP_STATUS _MMIO(0xc7200) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index b3739c9fcc48..009aa2df7958 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -52,6 +52,7 @@ #include "gvt.h" #include "i915_drv.h" #include "intel_gvt.h" +#include "sched_policy.h" MODULE_IMPORT_NS("DMA_BUF"); MODULE_IMPORT_NS("I915_GVT"); diff --git a/drivers/gpu/drm/i915/gvt/sched_policy.c b/drivers/gpu/drm/i915/gvt/sched_policy.c index df787472b1cf..9736a15a896f 100644 --- a/drivers/gpu/drm/i915/gvt/sched_policy.c +++ b/drivers/gpu/drm/i915/gvt/sched_policy.c @@ -33,6 +33,7 @@ #include "gvt.h" #include "i915_drv.h" +#include "sched_policy.h" static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu) { diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index a91accfd371d..6b5ee40a4386 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -49,6 +49,7 @@ #include "i915_drv.h" #include "i915_gem_gtt.h" #include "i915_perf_oa_regs.h" +#include "sched_policy.h" #define RING_CTX_OFF(x) \ offsetof(struct execlist_ring_context, x) diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c index a12011410874..96d0bd1fa337 100644 --- a/drivers/gpu/drm/i915/gvt/vgpu.c +++ b/drivers/gpu/drm/i915/gvt/vgpu.c @@ -38,6 +38,7 @@ #include "gvt.h" #include "i915_drv.h" #include "i915_pvinfo.h" +#include "sched_policy.h" void populate_pvinfo_page(struct intel_vgpu *vgpu) { From fcb6fc87f1a189c4b0141513556ed01419f4d90e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 31 Dec 2025 13:26:09 +0200 Subject: [PATCH 54/92] drm/i915/gvt: reduce include of gt/intel_engine_regs.h Move IS_RESTORE_INHIBIT() to scheduler.c, along with the gt/intel_engine_regs.h include. Reviewed-by: Ankit Nautiyal Link: https://patch.msgid.link/2f5440016b5d164a6f3889565761caa17cccd4b7.1767180318.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gvt/handlers.c | 1 + drivers/gpu/drm/i915/gvt/mmio_context.h | 5 ----- drivers/gpu/drm/i915/gvt/scheduler.c | 4 ++++ 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 68afd9b046d4..bd20f287720f 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -61,6 +61,7 @@ #include "display/skl_watermark_regs.h" #include "display/vlv_dsi_pll_regs.h" +#include "gt/intel_engine_regs.h" #include "gt/intel_gt_regs.h" #include "display_helpers.h" diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.h b/drivers/gpu/drm/i915/gvt/mmio_context.h index a821edf574dd..c0e3695e3bbe 100644 --- a/drivers/gpu/drm/i915/gvt/mmio_context.h +++ b/drivers/gpu/drm/i915/gvt/mmio_context.h @@ -38,8 +38,6 @@ #include -#include "gt/intel_engine_regs.h" - struct i915_request; struct intel_context; struct intel_engine_cs; @@ -57,7 +55,4 @@ bool is_inhibit_context(struct intel_context *ce); int intel_vgpu_restore_inhibit_context(struct intel_vgpu *vgpu, struct i915_request *req); -#define IS_RESTORE_INHIBIT(a) \ - IS_MASKED_BITS_ENABLED(a, CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT) - #endif diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 6b5ee40a4386..15fdd514ca83 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -40,6 +40,7 @@ #include "gem/i915_gem_pm.h" #include "gt/intel_context.h" +#include "gt/intel_engine_regs.h" #include "gt/intel_execlists_submission.h" #include "gt/intel_gt_regs.h" #include "gt/intel_lrc.h" @@ -54,6 +55,9 @@ #define RING_CTX_OFF(x) \ offsetof(struct execlist_ring_context, x) +#define IS_RESTORE_INHIBIT(a) \ + IS_MASKED_BITS_ENABLED(a, CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT) + static void set_context_pdp_root_pointer( struct execlist_ring_context *ring_context, u32 pdp[8]) From 045033fb02e744d577316429aa082e581356b63b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 31 Dec 2025 13:26:10 +0200 Subject: [PATCH 55/92] drm/i915/gvt: reduce include of vfio.h Nothing in dmabuf.h needs vfio.h. Replace with actually needed minimal includes. Reviewed-by: Ankit Nautiyal Link: https://patch.msgid.link/fbfca6252798ab58717486d1592fed310f880d42.1767180318.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gvt/dmabuf.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.h b/drivers/gpu/drm/i915/gvt/dmabuf.h index 06445e1cf3cf..aa7523386d94 100644 --- a/drivers/gpu/drm/i915/gvt/dmabuf.h +++ b/drivers/gpu/drm/i915/gvt/dmabuf.h @@ -31,7 +31,11 @@ #ifndef _GVT_DMABUF_H_ #define _GVT_DMABUF_H_ -#include +#include +#include + +struct intel_vgpu; +struct intel_vgpu_dmabuf_obj; struct intel_vgpu_fb_info { __u64 start; From 65f329ff234705b07a6e4429499fdf578cccca49 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 31 Dec 2025 13:26:11 +0200 Subject: [PATCH 56/92] drm/i915/gvt: include intel_display_limits.h where needed In this case, it's actually gvt.h that needs I915_MAX_PORTS etc. from intel_display_limits.h. Make this more evident by moving the include there, instead of getting it via fb_decoder.h. Reviewed-by: Ankit Nautiyal Link: https://patch.msgid.link/30696b712f4beba171c15765632ad9c3e1b8b1d1.1767180318.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gvt/fb_decoder.h | 2 -- drivers/gpu/drm/i915/gvt/gvt.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.h b/drivers/gpu/drm/i915/gvt/fb_decoder.h index 436d43c0087b..bc1e9d149e25 100644 --- a/drivers/gpu/drm/i915/gvt/fb_decoder.h +++ b/drivers/gpu/drm/i915/gvt/fb_decoder.h @@ -38,8 +38,6 @@ #include -#include "display/intel_display_limits.h" - struct intel_vgpu; #define _PLANE_CTL_FORMAT_SHIFT 24 diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 9adcdecadaa8..7fd2356f463c 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -38,6 +38,8 @@ #include #include +#include "display/intel_display_limits.h" + #include "gt/intel_gt.h" #include "cmd_parser.h" From c7830b51c77f85b95bd538b2d79a8de02cc05db1 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Mon, 5 Jan 2026 11:29:35 +0530 Subject: [PATCH 57/92] drm/i915/ltphy: Remove state verification for LT PHY fields Currently we do state verification for all VDR Registers. Remove LT PHY State verification for all VDR register fields other than VDR0_CONFIG and VDR2_CONFIG. The reason being that VDR0_CONFIG and VDR2_CONFIG are the only reliable shadow register which hold onto their values over the course of power gatings which happen internally due to features like PSR/PR. Signed-off-by: Suraj Kandpal Reviewed-by: Ankit Nautiyal Link: https://patch.msgid.link/20260105055937.136522-1-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_lt_phy.c | 30 +++++---------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c index 939c8975fd4c..9501ac861712 100644 --- a/drivers/gpu/drm/i915/display/intel_lt_phy.c +++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c @@ -2259,8 +2259,6 @@ void intel_lt_phy_pll_state_verify(struct intel_atomic_state *state, struct intel_encoder *encoder; struct intel_lt_phy_pll_state pll_hw_state = {}; const struct intel_lt_phy_pll_state *pll_sw_state = &new_crtc_state->dpll_hw_state.ltpll; - int clock; - int i, j; if (DISPLAY_VER(display) < 35) return; @@ -2275,33 +2273,19 @@ void intel_lt_phy_pll_state_verify(struct intel_atomic_state *state, encoder = intel_get_crtc_new_encoder(state, new_crtc_state); intel_lt_phy_pll_readout_hw_state(encoder, new_crtc_state, &pll_hw_state); - clock = intel_lt_phy_calc_port_clock(encoder, new_crtc_state); dig_port = enc_to_dig_port(encoder); if (intel_tc_port_in_tbt_alt_mode(dig_port)) return; - INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.clock != clock, - "[CRTC:%d:%s] mismatch in LT PHY: Register CLOCK (expected %d, found %d)", + INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.config[0] != pll_sw_state->config[0], + "[CRTC:%d:%s] mismatch in LT PHY PLL CONFIG 0: (expected 0x%04x, found 0x%04x)", crtc->base.base.id, crtc->base.name, - pll_sw_state->clock, pll_hw_state.clock); - - for (i = 0; i < 3; i++) { - INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.config[i] != pll_sw_state->config[i], - "[CRTC:%d:%s] mismatch in LT PHY PLL CONFIG%d: (expected 0x%04x, found 0x%04x)", - crtc->base.base.id, crtc->base.name, i, - pll_sw_state->config[i], pll_hw_state.config[i]); - } - - for (i = 0; i <= 12; i++) { - for (j = 3; j >= 0; j--) - INTEL_DISPLAY_STATE_WARN(display, - pll_hw_state.data[i][j] != - pll_sw_state->data[i][j], - "[CRTC:%d:%s] mismatch in LT PHY PLL DATA[%d][%d]: (expected 0x%04x, found 0x%04x)", - crtc->base.base.id, crtc->base.name, i, j, - pll_sw_state->data[i][j], pll_hw_state.data[i][j]); - } + pll_sw_state->config[0], pll_hw_state.config[0]); + INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.config[2] != pll_sw_state->config[2], + "[CRTC:%d:%s] mismatch in LT PHY PLL CONFIG 2: (expected 0x%04x, found 0x%04x)", + crtc->base.base.id, crtc->base.name, + pll_sw_state->config[2], pll_hw_state.config[2]); } void intel_xe3plpd_pll_enable(struct intel_encoder *encoder, From 73b506e6aa11dd1e8f2bdd3d82280341c510b0a2 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Mon, 5 Jan 2026 11:29:36 +0530 Subject: [PATCH 58/92] drm/i915/ltphy: Compare only certain fields in state verify function Verify only the config[0,2] fields in the LT PHY state since these are the only reliable values we can get back when we read the VDR registers. The reason being that the state does not persist for other VDR registers when power gating comes into picture. Though not ideal this change does not hit us badly in perspective of how we use the compare function to decide if fastset is required or if we wrote the state correctly. VDR0_CONFIG and VDR1_CONFIG hold the values that indicate the PLL operating mode and link rate which is usually what we need to check if something has changed or not. Signed-off-by: Suraj Kandpal Reviewed-by: Ankit Nautiyal Link: https://patch.msgid.link/20260105055937.136522-2-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_lt_phy.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c index 9501ac861712..9addb7661b6b 100644 --- a/drivers/gpu/drm/i915/display/intel_lt_phy.c +++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c @@ -2207,13 +2207,18 @@ bool intel_lt_phy_pll_compare_hw_state(const struct intel_lt_phy_pll_state *a, const struct intel_lt_phy_pll_state *b) { - if (memcmp(&a->config, &b->config, sizeof(a->config)) != 0) - return false; + /* + * With LT PHY values other than VDR0_CONFIG and VDR2_CONFIG are + * unreliable. They cannot always be read back since internally + * after power gating values are not restored back to the + * shadow VDR registers. Thus we do not compare the whole state + * just the two VDR registers. + */ + if (a->config[0] == b->config[0] && + a->config[2] == b->config[2]) + return true; - if (memcmp(&a->data, &b->data, sizeof(a->data)) != 0) - return false; - - return true; + return false; } void intel_lt_phy_pll_readout_hw_state(struct intel_encoder *encoder, From b3aa6769288303567d5a2f069778f37de32942f1 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Mon, 5 Jan 2026 11:29:37 +0530 Subject: [PATCH 59/92] drm/i915/ltphy: Provide protection against unsupported modes We need to make sure we return some port clock in case we have unsupported LT PHY modes or if we were not able to read the LT PHY state for whatever reason and the mode ends up being 0. Signed-off-by: Suraj Kandpal Reviewed-by: Ankit Nautiyal Link: https://patch.msgid.link/20260105055937.136522-3-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_lt_phy.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c index 9addb7661b6b..6cdae03ee172 100644 --- a/drivers/gpu/drm/i915/display/intel_lt_phy.c +++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c @@ -31,6 +31,7 @@ #define INTEL_LT_PHY_BOTH_LANES (INTEL_LT_PHY_LANE1 |\ INTEL_LT_PHY_LANE0) #define MODE_DP 3 +#define MODE_HDMI_20 4 #define Q32_TO_INT(x) ((x) >> 32) #define Q32_TO_FRAC(x) ((x) & 0xFFFFFFFF) #define DCO_MIN_FREQ_MHZ 11850 @@ -1751,6 +1752,7 @@ int intel_lt_phy_calc_port_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(encoder); int clk; const struct intel_lt_phy_pll_state *lt_state = &crtc_state->dpll_hw_state.ltpll; @@ -1768,8 +1770,11 @@ intel_lt_phy_calc_port_clock(struct intel_encoder *encoder, rate = REG_FIELD_GET8(LT_PHY_VDR_RATE_ENCODING_MASK, lt_state->config[0]); clk = intel_lt_phy_get_dp_clock(rate); - } else { + } else if (mode == MODE_HDMI_20) { clk = intel_lt_phy_calc_hdmi_port_clock(crtc_state); + } else { + drm_WARN_ON(display->drm, "Unsupported LT PHY Mode!\n"); + clk = xe3plpd_lt_hdmi_252.clock; } return clk; From 67ccf6c60bc324d78c24893e8c1eb6a62973838d Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Mon, 22 Dec 2025 19:18:47 -0300 Subject: [PATCH 60/92] drm/i915/display_wa: Keep enum intel_display_wa sorted For a consistent way of updating enum intel_display_wa, let's sort it by lineage number and add a comment asking for future updates to keep it sorted. In the same way, let's also keep __intel_display_wa() sorted. Reviewed-by: Matt Roper Link: https://patch.msgid.link/20251222-display-wa-13012396614-timing-of-mdclk-source-selection-v1-1-a2f7e9447f7a@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_display_wa.c | 12 ++++++------ drivers/gpu/drm/i915/display/intel_display_wa.h | 11 ++++++++--- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.c b/drivers/gpu/drm/i915/display/intel_display_wa.c index a00af39f7538..2b360447e92e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_wa.c +++ b/drivers/gpu/drm/i915/display/intel_display_wa.c @@ -62,18 +62,18 @@ static bool intel_display_needs_wa_16025573575(struct intel_display *display) bool __intel_display_wa(struct intel_display *display, enum intel_display_wa wa, const char *name) { switch (wa) { + case INTEL_DISPLAY_WA_14011503117: + return DISPLAY_VER(display) == 13; + case INTEL_DISPLAY_WA_14025769978: + return DISPLAY_VER(display) == 35; + case INTEL_DISPLAY_WA_15018326506: + return display->platform.battlemage; case INTEL_DISPLAY_WA_16023588340: return intel_display_needs_wa_16023588340(display); case INTEL_DISPLAY_WA_16025573575: return intel_display_needs_wa_16025573575(display); - case INTEL_DISPLAY_WA_14011503117: - return DISPLAY_VER(display) == 13; case INTEL_DISPLAY_WA_22014263786: return IS_DISPLAY_VERx100(display, 1100, 1400); - case INTEL_DISPLAY_WA_15018326506: - return display->platform.battlemage; - case INTEL_DISPLAY_WA_14025769978: - return DISPLAY_VER(display) == 35; default: drm_WARN(display->drm, 1, "Missing Wa number: %s\n", name); break; diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.h b/drivers/gpu/drm/i915/display/intel_display_wa.h index a68c0bb7e516..56b586e38306 100644 --- a/drivers/gpu/drm/i915/display/intel_display_wa.h +++ b/drivers/gpu/drm/i915/display/intel_display_wa.h @@ -21,13 +21,18 @@ static inline bool intel_display_needs_wa_16023588340(struct intel_display *disp bool intel_display_needs_wa_16023588340(struct intel_display *display); #endif +/* + * This enum lists display workarounds; each entry here must have a + * corresponding case in __intel_display_wa(). Keep both sorted by lineage + * number. + */ enum intel_display_wa { + INTEL_DISPLAY_WA_14011503117, + INTEL_DISPLAY_WA_14025769978, + INTEL_DISPLAY_WA_15018326506, INTEL_DISPLAY_WA_16023588340, INTEL_DISPLAY_WA_16025573575, - INTEL_DISPLAY_WA_14011503117, INTEL_DISPLAY_WA_22014263786, - INTEL_DISPLAY_WA_15018326506, - INTEL_DISPLAY_WA_14025769978, }; bool __intel_display_wa(struct intel_display *display, enum intel_display_wa wa, const char *name); From 968290fa8a42d9d2d2fd0fcdeb82d7533e83071d Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Mon, 22 Dec 2025 19:18:48 -0300 Subject: [PATCH 61/92] drm/i915/cdclk: Implement Wa_13012396614 A new workaround was defined for Xe3_LPD, which requires a tweak on how we handle MDCLK selection. Implement it. Reviewed-by: Dnyaneshwar Bhadane Link: https://patch.msgid.link/20251222-display-wa-13012396614-timing-of-mdclk-source-selection-v1-2-a2f7e9447f7a@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 31 +++++++++++++++++-- .../gpu/drm/i915/display/intel_display_wa.c | 2 ++ .../gpu/drm/i915/display/intel_display_wa.h | 1 + 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 0aa59d624095..7443e5285942 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -39,6 +39,7 @@ #include "intel_display_regs.h" #include "intel_display_types.h" #include "intel_display_utils.h" +#include "intel_display_wa.h" #include "intel_dram.h" #include "intel_mchbar_regs.h" #include "intel_pci_config.h" @@ -1858,6 +1859,20 @@ static void bxt_de_pll_enable(struct intel_display *display, int vco) static void icl_cdclk_pll_disable(struct intel_display *display) { + /* + * Wa_13012396614: + * Fixes: A sporadic race condition between MDCLK selection and PLL + * enabling. + * Workaround: + * Change programming of MDCLK source selection in CDCLK_CTL: + * - When disabling the CDCLK PLL, first set MDCLK source to be CD2XCLK. + * - When enabling the CDCLK PLL, update MDCLK source selection only + * after the PLL is enabled (which is already done as part of the + * normal flow of _bxt_set_cdclk()). + */ + if (intel_display_wa(display, 13012396614)) + intel_de_rmw(display, CDCLK_CTL, MDCLK_SOURCE_SEL_MASK, MDCLK_SOURCE_SEL_CD2XCLK); + intel_de_rmw(display, BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE, 0); @@ -2147,10 +2162,20 @@ static u32 bxt_cdclk_ctl(struct intel_display *display, cdclk >= 500000) val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE; - if (DISPLAY_VER(display) >= 20) - val |= xe2lpd_mdclk_source_sel(display); - else + if (DISPLAY_VER(display) >= 20) { + /* + * Wa_13012396614 requires selecting CD2XCLK as MDCLK source + * prior to disabling the PLL, which is already handled by + * icl_cdclk_pll_disable(). Here we are just making sure + * we keep the expected value. + */ + if (intel_display_wa(display, 13012396614) && vco == 0) + val |= MDCLK_SOURCE_SEL_CD2XCLK; + else + val |= xe2lpd_mdclk_source_sel(display); + } else { val |= skl_cdclk_decimal(cdclk); + } return val; } diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.c b/drivers/gpu/drm/i915/display/intel_display_wa.c index 2b360447e92e..581d943b9bdc 100644 --- a/drivers/gpu/drm/i915/display/intel_display_wa.c +++ b/drivers/gpu/drm/i915/display/intel_display_wa.c @@ -62,6 +62,8 @@ static bool intel_display_needs_wa_16025573575(struct intel_display *display) bool __intel_display_wa(struct intel_display *display, enum intel_display_wa wa, const char *name) { switch (wa) { + case INTEL_DISPLAY_WA_13012396614: + return DISPLAY_VERx100(display) == 3000; case INTEL_DISPLAY_WA_14011503117: return DISPLAY_VER(display) == 13; case INTEL_DISPLAY_WA_14025769978: diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.h b/drivers/gpu/drm/i915/display/intel_display_wa.h index 56b586e38306..40f989f19df1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_wa.h +++ b/drivers/gpu/drm/i915/display/intel_display_wa.h @@ -27,6 +27,7 @@ bool intel_display_needs_wa_16023588340(struct intel_display *display); * number. */ enum intel_display_wa { + INTEL_DISPLAY_WA_13012396614, INTEL_DISPLAY_WA_14011503117, INTEL_DISPLAY_WA_14025769978, INTEL_DISPLAY_WA_15018326506, From 692ec65421799fdc4c97d09a1b349a29bc8d8a64 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 5 Jan 2026 17:05:35 +0530 Subject: [PATCH 62/92] drm/i915/intel_alpm: Fix the SPDX identifier comment Fix the SPDX identifier comment as per the licensing rules [1]. [1] https://www.kernel.org/doc/html/latest/process/license-rules.html Reviewed-by: Jani Nikula Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20260105113544.574323-2-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_alpm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_alpm.h b/drivers/gpu/drm/i915/display/intel_alpm.h index 53599b464dea..c6a4ec5b9561 100644 --- a/drivers/gpu/drm/i915/display/intel_alpm.h +++ b/drivers/gpu/drm/i915/display/intel_alpm.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: MIT - * +/* SPDX-License-Identifier: MIT */ +/* * Copyright © 2024 Intel Corporation */ From 1d72c4d3a1929c628fe87f50ade2e043b855528c Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 5 Jan 2026 17:05:36 +0530 Subject: [PATCH 63/92] drm/i915/intel_cx0_phy: Fix the SPDX identifier comment Fix the SPDX identifier comment as per the licensing rules [1]. [1] https://www.kernel.org/doc/html/latest/process/license-rules.html Reviewed-by: Jani Nikula Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20260105113544.574323-3-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_cx0_phy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.h b/drivers/gpu/drm/i915/display/intel_cx0_phy.h index 9f10113e2d18..ae98ac23ea22 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +/* SPDX-License-Identifier: MIT */ /* * Copyright © 2023 Intel Corporation */ From babd0b8db9dbf6da541025e76eb58fbba2a2151c Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 5 Jan 2026 17:05:37 +0530 Subject: [PATCH 64/92] drm/i915/intel_cx0_phy_regs: Fix the SPDX identifier comment Fix the SPDX identifier comment as per the licensing rules [1]. [1] https://www.kernel.org/doc/html/latest/process/license-rules.html Reviewed-by: Jani Nikula Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20260105113544.574323-4-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h index 8df5cd5ce418..658890f73515 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: MIT - * +/* SPDX-License-Identifier: MIT */ +/* * Copyright © 2023 Intel Corporation */ From 8b140ae6d57f35735a33c8ace0ca79272ef1d5c6 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 5 Jan 2026 17:05:38 +0530 Subject: [PATCH 65/92] drm/i915/intel_display_params: Fix the SPDX identifier comment Fix the SPDX identifier comment as per the licensing rules [1]. [1] https://www.kernel.org/doc/html/latest/process/license-rules.html Reviewed-by: Jani Nikula Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20260105113544.574323-5-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display_params.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_params.h b/drivers/gpu/drm/i915/display/intel_display_params.h index b01bc5700c52..b95ecf728daa 100644 --- a/drivers/gpu/drm/i915/display/intel_display_params.h +++ b/drivers/gpu/drm/i915/display/intel_display_params.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +/* SPDX-License-Identifier: MIT */ /* * Copyright © 2023 Intel Corporation */ From e9d95194bd413b837a57096069bf85d71d48d7af Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 5 Jan 2026 17:05:39 +0530 Subject: [PATCH 66/92] drm/i915/intel_dsb: Fix the SPDX identifier comment Fix the SPDX identifier comment as per the licensing rules [1]. [1] https://www.kernel.org/doc/html/latest/process/license-rules.html Reviewed-by: Jani Nikula Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20260105113544.574323-6-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dsb.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h index 2f31f2c1d0c5..386a5a942572 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.h +++ b/drivers/gpu/drm/i915/display/intel_dsb.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: MIT - * +/* SPDX-License-Identifier: MIT */ +/* * Copyright © 2019 Intel Corporation */ From 483f06ff8e56423d301a1b46a8b70285c1a8f3a3 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 5 Jan 2026 17:05:40 +0530 Subject: [PATCH 67/92] drm/i915/intel_dsb_buffer: Fix the SPDX identifier comment Fix the SPDX identifier comment as per the licensing rules [1]. [1] https://www.kernel.org/doc/html/latest/process/license-rules.html Reviewed-by: Jani Nikula Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20260105113544.574323-7-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dsb_buffer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb_buffer.h b/drivers/gpu/drm/i915/display/intel_dsb_buffer.h index d746c872e0c7..f4577d1f25cd 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb_buffer.h +++ b/drivers/gpu/drm/i915/display/intel_dsb_buffer.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: MIT - * +/* SPDX-License-Identifier: MIT */ +/* * Copyright © 2023 Intel Corporation */ From a87a681860e857c9a0d05d084d4357bd2fbe9560 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 5 Jan 2026 17:05:41 +0530 Subject: [PATCH 68/92] drm/i915/intel_gvt_api: Fix the SPDX identifier comment Fix the SPDX identifier comment as per the licensing rules [1]. [1] https://www.kernel.org/doc/html/latest/process/license-rules.html Reviewed-by: Jani Nikula Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20260105113544.574323-8-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_gvt_api.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_gvt_api.h b/drivers/gpu/drm/i915/display/intel_gvt_api.h index d4eea74026c6..ce3b744142a5 100644 --- a/drivers/gpu/drm/i915/display/intel_gvt_api.h +++ b/drivers/gpu/drm/i915/display/intel_gvt_api.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: MIT - * +/* SPDX-License-Identifier: MIT */ +/* * Copyright © 2025 Intel Corporation */ From 152fc133419417bf33cbcd05060fba83dbdb36ad Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 5 Jan 2026 17:49:28 +0530 Subject: [PATCH 69/92] drm/i915/intel_lt_phy: Fix the SPDX identifier comment Fix the SPDX identifier comment as per the licensing rules [1]. [1] https://www.kernel.org/doc/html/latest/process/license-rules.html v2: Drop the superfluous blank line. (Jani) Reviewed-by: Jani Nikula Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20260105121929.576304-1-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_lt_phy.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.h b/drivers/gpu/drm/i915/display/intel_lt_phy.h index 7659c92b6c3c..bf41858f1bc3 100644 --- a/drivers/gpu/drm/i915/display/intel_lt_phy.h +++ b/drivers/gpu/drm/i915/display/intel_lt_phy.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: MIT - * +/* SPDX-License-Identifier: MIT */ +/* * Copyright © 2025 Intel Corporation */ From a5a9fd93d2c3c2bd31d27a25a601ae313d4aa74f Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Mon, 5 Jan 2026 17:05:43 +0530 Subject: [PATCH 70/92] drm/i915/lt_phy_regs: Fix the SPDX identifier comment Fix the SPDX identifier comment as per the licensing rules [1]. [1] https://www.kernel.org/doc/html/latest/process/license-rules.html Reviewed-by: Jani Nikula Signed-off-by: Ankit Nautiyal Link: https://patch.msgid.link/20260105113544.574323-10-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_lt_phy_regs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy_regs.h b/drivers/gpu/drm/i915/display/intel_lt_phy_regs.h index 98ccc069a69b..37e46fb9abde 100644 --- a/drivers/gpu/drm/i915/display/intel_lt_phy_regs.h +++ b/drivers/gpu/drm/i915/display/intel_lt_phy_regs.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: MIT - * +/* SPDX-License-Identifier: MIT */ +/* * Copyright © 2025 Intel Corporation */ From 936cae9254e55a39aeaa0c156a764d22f319338b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 7 Jan 2026 18:02:26 +0200 Subject: [PATCH 71/92] mei: late_bind: fix struct intel_lb_component_ops kernel-doc Fix kernel-doc warnings on struct intel_lb_component_ops: Warning: include/drm/intel/intel_lb_mei_interface.h:55 Incorrect use of kernel-doc format: * push_payload - Sends a payload to the authentication firmware And a bunch more. There isn't really support for documenting function pointer struct members in kernel-doc, but at least reference the member properly. Fixes: 741eeabb7c78 ("mei: late_bind: add late binding component driver") Cc: Alexander Usyskin Reviewed-by: Nitin Gote Link: https://patch.msgid.link/20260107160226.2381388-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- include/drm/intel/intel_lb_mei_interface.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/drm/intel/intel_lb_mei_interface.h b/include/drm/intel/intel_lb_mei_interface.h index d65be2cba2ab..0850738a30fc 100644 --- a/include/drm/intel/intel_lb_mei_interface.h +++ b/include/drm/intel/intel_lb_mei_interface.h @@ -53,7 +53,8 @@ enum intel_lb_status { */ struct intel_lb_component_ops { /** - * push_payload - Sends a payload to the authentication firmware + * @push_payload: Sends a payload to the authentication firmware + * * @dev: Device struct corresponding to the mei device * @type: Payload type (see &enum intel_lb_type) * @flags: Payload flags bitmap (e.g. %INTEL_LB_FLAGS_IS_PERSISTENT) From 0f8d0d764cc936cb834f39f0279c7776e0c1209d Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Tue, 6 Jan 2026 18:40:21 -0300 Subject: [PATCH 72/92] drm/i915/cdclk: Incorporate Xe3_LPD changes for CD2X divider On Xe3_LPD, there is no instruction to program the CD2X divider anymore and the hardware is expected to always use the default value of 0b00, meaning "divide by 1". With that, the CDCLK_CTL register was changed so that: (1) The field "CD2X Divider Select" became a debug-only field. Because we are programming CDCLK_CTL with a direct write instead of read-modify-write operation, we still need to program "CD2X Divider Select" in order to keep the field from deviating from its default value. Let's, however, throw a warning if we encounter a CDCLK value that would result in an unexpected value for that field. (2) The field "CD2X Pipe Select" has been removed. In fact, some debugging in a PTL machine showed that such field comes back as zero after writing a non-zero value to it. As such, do not program it starting with Xe3_LPD. v2: - Add missing "val |= " when calling bxt_cdclk_cd2x_pipe(). (Dnyaneshwar) Bspec: 68864, 69090 Reviewed-by: Dnyaneshwar Bhadane Link: https://patch.msgid.link/20260106-xe3_lpd-no-cd2x-divider-v2-1-06e5cbc9dabb@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_cdclk.c | 29 +++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 7443e5285942..9bfbfbf34dc0 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1948,6 +1948,8 @@ static u32 bxt_cdclk_cd2x_pipe(struct intel_display *display, enum pipe pipe) static u32 bxt_cdclk_cd2x_div_sel(struct intel_display *display, int cdclk, int vco, u16 waveform) { + u32 ret; + /* cdclk = vco / 2 / div{1,1.5,2,4} */ switch (cdclk_divider(cdclk, vco, waveform)) { default: @@ -1956,14 +1958,27 @@ static u32 bxt_cdclk_cd2x_div_sel(struct intel_display *display, drm_WARN_ON(display->drm, vco != 0); fallthrough; case 2: - return BXT_CDCLK_CD2X_DIV_SEL_1; + ret = BXT_CDCLK_CD2X_DIV_SEL_1; + break; case 3: - return BXT_CDCLK_CD2X_DIV_SEL_1_5; + ret = BXT_CDCLK_CD2X_DIV_SEL_1_5; + break; case 4: - return BXT_CDCLK_CD2X_DIV_SEL_2; + ret = BXT_CDCLK_CD2X_DIV_SEL_2; + break; case 8: - return BXT_CDCLK_CD2X_DIV_SEL_4; + ret = BXT_CDCLK_CD2X_DIV_SEL_4; + break; } + + /* + * On Xe3_LPD onward, the expectation is to always have + * BXT_CDCLK_CD2X_DIV_SEL_1 as the default. + */ + if (DISPLAY_VER(display) >= 30) + drm_WARN_ON(display->drm, ret != BXT_CDCLK_CD2X_DIV_SEL_1); + + return ret; } static u16 cdclk_squash_waveform(struct intel_display *display, @@ -2151,8 +2166,10 @@ static u32 bxt_cdclk_ctl(struct intel_display *display, waveform = cdclk_squash_waveform(display, cdclk); - val = bxt_cdclk_cd2x_div_sel(display, cdclk, vco, waveform) | - bxt_cdclk_cd2x_pipe(display, pipe); + val = bxt_cdclk_cd2x_div_sel(display, cdclk, vco, waveform); + + if (DISPLAY_VER(display) < 30) + val |= bxt_cdclk_cd2x_pipe(display, pipe); /* * Disable SSA Precharge when CD clock frequency < 500 MHz, From 701c47493328a8173996e7590733be3493af572f Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 8 Jan 2026 15:12:03 -0500 Subject: [PATCH 73/92] drm/i915/guc: make 'guc_hw_reg_state' static as it isn't exported The guc_hw_reg_state array is not exported, so make it static. Fixes the following sparse warning: drivers/gpu/drm/i915/i915_gpu_error.c:692:3: warning: symbol 'guc_hw_reg_state' was not declared. Should it be static? Fixes: ba391a102ec11 ("drm/i915/guc: Include the GuC registers in the error state") Signed-off-by: Ben Dooks Reviewed-by: Rodrigo Vivi Link: https://patch.msgid.link/20260108201202.59250-2-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 7582ef34bf3f..303d8d9b7775 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -686,7 +686,7 @@ static void err_print_guc_ctb(struct drm_i915_error_state_buf *m, } /* This list includes registers that are useful in debugging GuC hangs. */ -const struct { +static const struct { u32 start; u32 count; } guc_hw_reg_state[] = { From 7427f30e5c4938ebe813aa46e578cb5afc375de4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:28 +0200 Subject: [PATCH 74/92] drm/i915/dp: Drop unused timeslots param from dsc_compute_link_config() Drop the unused timeslots parameter from dsc_compute_link_config() and other functions calling it. Reviewed-by: Luca Coelho Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-2-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 2dadbf7e8922..cc0549b41045 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2047,8 +2047,7 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, const struct link_config_limits *limits, - int dsc_bpp_x16, - int timeslots) + int dsc_bpp_x16) { const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; int link_rate, lane_count; @@ -2241,8 +2240,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, const struct link_config_limits *limits, - int pipe_bpp, - int timeslots) + int pipe_bpp) { struct intel_display *display = to_intel_display(intel_dp); const struct intel_connector *connector = to_intel_connector(conn_state->connector); @@ -2270,8 +2268,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, pipe_config, conn_state, limits, - bpp_x16, - timeslots); + bpp_x16); if (ret == 0) { pipe_config->dsc.compressed_bpp_x16 = bpp_x16; if (intel_dp->force_dsc_fractional_bpp_en && @@ -2328,8 +2325,7 @@ int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp, static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, - const struct link_config_limits *limits, - int timeslots) + const struct link_config_limits *limits) { const struct intel_connector *connector = to_intel_connector(conn_state->connector); @@ -2341,7 +2337,7 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, if (forced_bpp) { ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, - limits, forced_bpp, timeslots); + limits, forced_bpp); if (ret == 0) { pipe_config->pipe_bpp = forced_bpp; return 0; @@ -2359,7 +2355,7 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, continue; ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, - limits, pipe_bpp, timeslots); + limits, pipe_bpp); if (ret == 0) { pipe_config->pipe_bpp = pipe_bpp; return 0; @@ -2470,7 +2466,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, conn_state, limits); else ret = intel_dp_dsc_compute_pipe_bpp(intel_dp, pipe_config, - conn_state, limits, timeslots); + conn_state, limits); if (ret) { drm_dbg_kms(display->drm, "No Valid pipe bpp for given mode ret = %d\n", ret); From 85b4360d2b72b4a38497f5267da5cb817dd91b34 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:30 +0200 Subject: [PATCH 75/92] drm/i915/dp: Factor out align_max_sink_dsc_input_bpp() Factor out align_max_sink_dsc_input_bpp(), also used later for computing the maximum DSC input BPP limit. Reviewed-by: Vinod Govindapillai Reviewed-by: Luca Coelho Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-4-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 28 ++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index cc0549b41045..5b08d308ead1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1894,12 +1894,27 @@ int intel_dp_dsc_max_src_input_bpc(struct intel_display *display) return intel_dp_dsc_min_src_input_bpc(); } +static int align_max_sink_dsc_input_bpp(const struct intel_connector *connector, + int max_pipe_bpp) +{ + u8 dsc_bpc[3]; + int num_bpc; + int i; + + num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, + dsc_bpc); + for (i = 0; i < num_bpc; i++) { + if (dsc_bpc[i] * 3 <= max_pipe_bpp) + return dsc_bpc[i] * 3; + } + + return 0; +} + int intel_dp_dsc_compute_max_bpp(const struct intel_connector *connector, u8 max_req_bpc) { struct intel_display *display = to_intel_display(connector); - int i, num_bpc; - u8 dsc_bpc[3] = {}; int dsc_max_bpc; dsc_max_bpc = intel_dp_dsc_max_src_input_bpc(display); @@ -1909,14 +1924,7 @@ int intel_dp_dsc_compute_max_bpp(const struct intel_connector *connector, dsc_max_bpc = min(dsc_max_bpc, max_req_bpc); - num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, - dsc_bpc); - for (i = 0; i < num_bpc; i++) { - if (dsc_max_bpc >= dsc_bpc[i]) - return dsc_bpc[i] * 3; - } - - return 0; + return align_max_sink_dsc_input_bpp(connector, dsc_max_bpc * 3); } static int intel_dp_source_dsc_version_minor(struct intel_display *display) From 44a95ffe685d3b9428ab81f632e9b34bb2e4641c Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:31 +0200 Subject: [PATCH 76/92] drm/i915/dp: Factor out align_max_vesa_compressed_bpp_x16() Factor out align_max_vesa_compressed_bpp_x16(), also used later for computing the maximum DSC compressed BPP limit. Reviewed-by: Vinod Govindapillai Reviewed-by: Luca Coelho Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-5-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 37 ++++++++++++++----------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 5b08d308ead1..9d7a1df179a4 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -868,10 +868,23 @@ small_joiner_ram_size_bits(struct intel_display *display) return 6144 * 8; } +static int align_max_vesa_compressed_bpp_x16(int max_link_bpp_x16) +{ + int i; + + for (i = ARRAY_SIZE(valid_dsc_bpp) - 1; i >= 0; i--) { + int vesa_bpp_x16 = fxp_q4_from_int(valid_dsc_bpp[i]); + + if (vesa_bpp_x16 <= max_link_bpp_x16) + return vesa_bpp_x16; + } + + return 0; +} + static u32 intel_dp_dsc_nearest_valid_bpp(struct intel_display *display, u32 bpp, u32 pipe_bpp) { u32 bits_per_pixel = bpp; - int i; /* Error out if the max bpp is less than smallest allowed valid bpp */ if (bits_per_pixel < valid_dsc_bpp[0]) { @@ -900,15 +913,13 @@ static u32 intel_dp_dsc_nearest_valid_bpp(struct intel_display *display, u32 bpp } bits_per_pixel = min_t(u32, bits_per_pixel, 27); } else { - /* Find the nearest match in the array of known BPPs from VESA */ - for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) { - if (bits_per_pixel < valid_dsc_bpp[i + 1]) - break; - } - drm_dbg_kms(display->drm, "Set dsc bpp from %d to VESA %d\n", - bits_per_pixel, valid_dsc_bpp[i]); + int link_bpp_x16 = fxp_q4_from_int(bits_per_pixel); - bits_per_pixel = valid_dsc_bpp[i]; + /* Find the nearest match in the array of known BPPs from VESA */ + link_bpp_x16 = align_max_vesa_compressed_bpp_x16(link_bpp_x16); + + drm_WARN_ON(display->drm, fxp_q4_to_frac(link_bpp_x16)); + bits_per_pixel = fxp_q4_to_int(link_bpp_x16); } return bits_per_pixel; @@ -2220,7 +2231,6 @@ int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector) bool intel_dp_dsc_valid_compressed_bpp(struct intel_dp *intel_dp, int bpp_x16) { struct intel_display *display = to_intel_display(intel_dp); - int i; if (DISPLAY_VER(display) >= 13) { if (intel_dp->force_dsc_fractional_bpp_en && !fxp_q4_to_frac(bpp_x16)) @@ -2232,12 +2242,7 @@ bool intel_dp_dsc_valid_compressed_bpp(struct intel_dp *intel_dp, int bpp_x16) if (fxp_q4_to_frac(bpp_x16)) return false; - for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) { - if (fxp_q4_to_int(bpp_x16) == valid_dsc_bpp[i]) - return true; - } - - return false; + return align_max_vesa_compressed_bpp_x16(bpp_x16) == bpp_x16; } /* From 753d6b404e12ac950a6b9207ba788f7f2e0a6303 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:32 +0200 Subject: [PATCH 77/92] drm/i915/dp: Align min/max DSC input BPPs to sink caps Align the minimum/maximum DSC input BPPs to the corresponding sink DSC input BPP capability limits already when computing the BPP limits. This alignment is also performed later during state computation, however there is no reason to initialize the limits to an unaligned/incorrect value. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-6-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 9d7a1df179a4..4807a98d396a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1905,6 +1905,23 @@ int intel_dp_dsc_max_src_input_bpc(struct intel_display *display) return intel_dp_dsc_min_src_input_bpc(); } +static int align_min_sink_dsc_input_bpp(const struct intel_connector *connector, + int min_pipe_bpp) +{ + u8 dsc_bpc[3]; + int num_bpc; + int i; + + num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, + dsc_bpc); + for (i = num_bpc - 1; i >= 0; i--) { + if (dsc_bpc[i] * 3 >= min_pipe_bpp) + return dsc_bpc[i] * 3; + } + + return 0; +} + static int align_max_sink_dsc_input_bpp(const struct intel_connector *connector, int max_pipe_bpp) { @@ -2680,15 +2697,19 @@ intel_dp_dsc_compute_pipe_bpp_limits(struct intel_connector *connector, int dsc_max_bpc = intel_dp_dsc_max_src_input_bpc(display); limits->pipe.min_bpp = max(limits->pipe.min_bpp, dsc_min_bpc * 3); + limits->pipe.min_bpp = align_min_sink_dsc_input_bpp(connector, limits->pipe.min_bpp); + limits->pipe.max_bpp = min(limits->pipe.max_bpp, dsc_max_bpc * 3); + limits->pipe.max_bpp = align_max_sink_dsc_input_bpp(connector, limits->pipe.max_bpp); if (limits->pipe.min_bpp <= 0 || limits->pipe.min_bpp > limits->pipe.max_bpp) { drm_dbg_kms(display->drm, - "[CONNECTOR:%d:%s] Invalid DSC src/sink input BPP (src:%d-%d pipe:%d-%d)\n", + "[CONNECTOR:%d:%s] Invalid DSC src/sink input BPP (src:%d-%d pipe:%d-%d sink-align:%d-%d)\n", connector->base.base.id, connector->base.name, dsc_min_bpc * 3, dsc_max_bpc * 3, - orig_limits.pipe.min_bpp, orig_limits.pipe.max_bpp); + orig_limits.pipe.min_bpp, orig_limits.pipe.max_bpp, + limits->pipe.min_bpp, limits->pipe.max_bpp); return false; } From f55c1f62b6ce801d40b524bef97108d274a252b7 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:33 +0200 Subject: [PATCH 78/92] drm/i915/dp: Align min/max compressed BPPs when calculating BPP limits Align the minimum/maximum DSC compressed BPPs to the corresponding source compressed BPP limits already when computing the BPP limits. This alignment is also performed later during state computation, however there is no reason to initialize the limits to an unaligned/incorrect value. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-7-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 57 +++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 4807a98d396a..daab43187eb0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -868,6 +868,20 @@ small_joiner_ram_size_bits(struct intel_display *display) return 6144 * 8; } +static int align_min_vesa_compressed_bpp_x16(int min_link_bpp_x16) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) { + int vesa_bpp_x16 = fxp_q4_from_int(valid_dsc_bpp[i]); + + if (vesa_bpp_x16 >= min_link_bpp_x16) + return vesa_bpp_x16; + } + + return 0; +} + static int align_max_vesa_compressed_bpp_x16(int max_link_bpp_x16) { int i; @@ -2262,6 +2276,40 @@ bool intel_dp_dsc_valid_compressed_bpp(struct intel_dp *intel_dp, int bpp_x16) return align_max_vesa_compressed_bpp_x16(bpp_x16) == bpp_x16; } +static int align_min_compressed_bpp_x16(const struct intel_connector *connector, int min_bpp_x16) +{ + struct intel_display *display = to_intel_display(connector); + + if (DISPLAY_VER(display) >= 13) { + int bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); + + drm_WARN_ON(display->drm, !is_power_of_2(bpp_step_x16)); + + return round_up(min_bpp_x16, bpp_step_x16); + } else { + return align_min_vesa_compressed_bpp_x16(min_bpp_x16); + } +} + +static int align_max_compressed_bpp_x16(const struct intel_connector *connector, + enum intel_output_format output_format, + int pipe_bpp, int max_bpp_x16) +{ + struct intel_display *display = to_intel_display(connector); + int link_bpp_x16 = intel_dp_output_format_link_bpp_x16(output_format, pipe_bpp); + int bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); + + max_bpp_x16 = min(max_bpp_x16, link_bpp_x16 - bpp_step_x16); + + if (DISPLAY_VER(display) >= 13) { + drm_WARN_ON(display->drm, !is_power_of_2(bpp_step_x16)); + + return round_down(max_bpp_x16, bpp_step_x16); + } else { + return align_max_vesa_compressed_bpp_x16(max_bpp_x16); + } +} + /* * Find the max compressed BPP we can find a link configuration for. The BPPs to * try depend on the source (platform) and sink. @@ -2640,6 +2688,9 @@ intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp, dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp); limits->link.min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp); + limits->link.min_bpp_x16 = + align_min_compressed_bpp_x16(connector, limits->link.min_bpp_x16); + dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp); joiner_max_bpp = get_max_compressed_bpp_with_joiner(display, @@ -2664,6 +2715,12 @@ intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp, connector->base.base.id, connector->base.name, FXP_Q4_ARGS(max_link_bpp_x16)); } + + max_link_bpp_x16 = + align_max_compressed_bpp_x16(connector, + crtc_state->output_format, + limits->pipe.max_bpp, + max_link_bpp_x16); } limits->link.max_bpp_x16 = max_link_bpp_x16; From 756009d0fdfa15b5536de138aab0e5f15ab69f6d Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:34 +0200 Subject: [PATCH 79/92] drm/i915/dp: Drop intel_dp parameter from intel_dp_compute_config_link_bpp_limits() The intel_dp pointer can be deducted from the connector pointer, so it's enough to pass only connector to intel_dp_compute_config_link_bpp_limits(), do so. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-8-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index daab43187eb0..bbb7cff90818 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2654,13 +2654,13 @@ dsc_throughput_quirk_max_bpp_x16(const struct intel_connector *connector, * range, crtc_state and dsc mode. Return true on success. */ static bool -intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp, - const struct intel_connector *connector, +intel_dp_compute_config_link_bpp_limits(struct intel_connector *connector, const struct intel_crtc_state *crtc_state, bool dsc, struct link_config_limits *limits) { - struct intel_display *display = to_intel_display(intel_dp); + struct intel_display *display = to_intel_display(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -2832,8 +2832,7 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp, intel_dp_test_compute_config(intel_dp, crtc_state, limits); - return intel_dp_compute_config_link_bpp_limits(intel_dp, - connector, + return intel_dp_compute_config_link_bpp_limits(connector, crtc_state, dsc, limits); From 9212733a30e349536e2c17baa5ac9b279b948877 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:35 +0200 Subject: [PATCH 80/92] drm/i915/dp: Pass intel_output_format to intel_dp_dsc_sink_{min_max}_compressed_bpp() Prepare for follow-up changes also calling intel_dp_dsc_min_sink_compressed_bpp() / intel_dp_dsc_max_sink_compressed_bpp_x16() without an intel_crtc_state. While at it remove the stale function declarations from the header file. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-9-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 24 ++++++++++++------------ drivers/gpu/drm/i915/display/intel_dp.h | 4 ---- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index bbb7cff90818..57b93a811cb6 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2157,7 +2157,7 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp, static u16 intel_dp_dsc_max_sink_compressed_bppx16(const struct intel_connector *connector, - const struct intel_crtc_state *pipe_config, + enum intel_output_format output_format, int bpc) { u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(connector->dp.dsc_dpcd); @@ -2168,43 +2168,43 @@ u16 intel_dp_dsc_max_sink_compressed_bppx16(const struct intel_connector *connec * If support not given in DPCD 67h, 68h use the Maximum Allowed bit rate * values as given in spec Table 2-157 DP v2.0 */ - switch (pipe_config->output_format) { + switch (output_format) { case INTEL_OUTPUT_FORMAT_RGB: case INTEL_OUTPUT_FORMAT_YCBCR444: return (3 * bpc) << 4; case INTEL_OUTPUT_FORMAT_YCBCR420: return (3 * (bpc / 2)) << 4; default: - MISSING_CASE(pipe_config->output_format); + MISSING_CASE(output_format); break; } return 0; } -int intel_dp_dsc_sink_min_compressed_bpp(const struct intel_crtc_state *pipe_config) +static int intel_dp_dsc_sink_min_compressed_bpp(enum intel_output_format output_format) { /* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */ - switch (pipe_config->output_format) { + switch (output_format) { case INTEL_OUTPUT_FORMAT_RGB: case INTEL_OUTPUT_FORMAT_YCBCR444: return 8; case INTEL_OUTPUT_FORMAT_YCBCR420: return 6; default: - MISSING_CASE(pipe_config->output_format); + MISSING_CASE(output_format); break; } return 0; } -int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector, - const struct intel_crtc_state *pipe_config, - int bpc) +static int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector, + enum intel_output_format output_format, + int bpc) { return intel_dp_dsc_max_sink_compressed_bppx16(connector, - pipe_config, bpc) >> 4; + output_format, bpc) >> 4; } int intel_dp_dsc_min_src_compressed_bpp(void) @@ -2684,7 +2684,7 @@ intel_dp_compute_config_link_bpp_limits(struct intel_connector *connector, int joiner_max_bpp; dsc_src_min_bpp = intel_dp_dsc_min_src_compressed_bpp(); - dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(crtc_state); + dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(crtc_state->output_format); dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp); limits->link.min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp); @@ -2698,7 +2698,7 @@ intel_dp_compute_config_link_bpp_limits(struct intel_connector *connector, adjusted_mode->hdisplay, intel_crtc_num_joined_pipes(crtc_state)); dsc_sink_max_bpp = intel_dp_dsc_sink_max_compressed_bpp(connector, - crtc_state, + crtc_state->output_format, limits->pipe.max_bpp / 3); dsc_max_bpp = min(dsc_sink_max_bpp, dsc_src_max_bpp); dsc_max_bpp = min(dsc_max_bpp, joiner_max_bpp); diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 30eebb8cad6d..489b8c945da3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -150,10 +150,6 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct intel_display *display, enum intel_output_format output_format, u32 pipe_bpp, u32 timeslots); -int intel_dp_dsc_sink_min_compressed_bpp(const struct intel_crtc_state *pipe_config); -int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector, - const struct intel_crtc_state *pipe_config, - int bpc); bool intel_dp_dsc_valid_compressed_bpp(struct intel_dp *intel_dp, int bpp_x16); u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector, int mode_clock, int mode_hdisplay, From 07b34db2a0982480a30fe001d5f480d9e58e24db Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:36 +0200 Subject: [PATCH 81/92] drm/i915/dp: Pass mode clock to dsc_throughput_quirk_max_bpp_x16() Prepare for follow-up changes using dsc_throughput_quirk_max_bpp_x16() without an intel_crtc_state pointer. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-10-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 57b93a811cb6..bed41d7f97e8 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2617,11 +2617,8 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, static int dsc_throughput_quirk_max_bpp_x16(const struct intel_connector *connector, - const struct intel_crtc_state *crtc_state) + int mode_clock) { - const struct drm_display_mode *adjusted_mode = - &crtc_state->hw.adjusted_mode; - if (!connector->dp.dsc_throughput_quirk) return INT_MAX; @@ -2641,7 +2638,7 @@ dsc_throughput_quirk_max_bpp_x16(const struct intel_connector *connector, * smaller than the YUV422/420 value, but let's not depend on this * assumption. */ - if (adjusted_mode->crtc_clock < + if (mode_clock < min(connector->dp.dsc_branch_caps.overall_throughput.rgb_yuv444, connector->dp.dsc_branch_caps.overall_throughput.yuv422_420) / 2) return INT_MAX; @@ -2705,7 +2702,8 @@ intel_dp_compute_config_link_bpp_limits(struct intel_connector *connector, max_link_bpp_x16 = min(max_link_bpp_x16, fxp_q4_from_int(dsc_max_bpp)); - throughput_max_bpp_x16 = dsc_throughput_quirk_max_bpp_x16(connector, crtc_state); + throughput_max_bpp_x16 = + dsc_throughput_quirk_max_bpp_x16(connector, adjusted_mode->crtc_clock); if (throughput_max_bpp_x16 < max_link_bpp_x16) { max_link_bpp_x16 = throughput_max_bpp_x16; From 28e59c7e24ea1189bd925bf0efede4324ca3aaa6 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:37 +0200 Subject: [PATCH 82/92] drm/i915/dp: Factor out compute_min_compressed_bpp_x16() Factor out compute_min_compressed_bpp_x16() also used during mode validation in a follow-up change. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-11-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 26 +++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index bed41d7f97e8..8aeb61441322 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2646,6 +2646,23 @@ dsc_throughput_quirk_max_bpp_x16(const struct intel_connector *connector, return fxp_q4_from_int(12); } +static int compute_min_compressed_bpp_x16(struct intel_connector *connector, + enum intel_output_format output_format) +{ + int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp; + int min_bpp_x16; + + dsc_src_min_bpp = intel_dp_dsc_min_src_compressed_bpp(); + dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(output_format); + dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp); + + min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp); + + min_bpp_x16 = align_min_compressed_bpp_x16(connector, min_bpp_x16); + + return min_bpp_x16; +} + /* * Calculate the output link min, max bpp values in limits based on the pipe bpp * range, crtc_state and dsc mode. Return true on success. @@ -2675,18 +2692,11 @@ intel_dp_compute_config_link_bpp_limits(struct intel_connector *connector, limits->link.min_bpp_x16 = fxp_q4_from_int(limits->pipe.min_bpp); } else { - int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp; int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp; int throughput_max_bpp_x16; int joiner_max_bpp; - - dsc_src_min_bpp = intel_dp_dsc_min_src_compressed_bpp(); - dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(crtc_state->output_format); - dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp); - limits->link.min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp); - limits->link.min_bpp_x16 = - align_min_compressed_bpp_x16(connector, limits->link.min_bpp_x16); + compute_min_compressed_bpp_x16(connector, crtc_state->output_format); dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp); joiner_max_bpp = From e68aecf473449d625bc5e3e2f0c754711d5f680d Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:38 +0200 Subject: [PATCH 83/92] drm/i915/dp: Factor out compute_max_compressed_bpp_x16() Factor out compute_max_compressed_bpp_x16() also used during mode validation in a follow-up change. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-12-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 82 +++++++++++++++---------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 8aeb61441322..d1139d6582e1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2663,6 +2663,48 @@ static int compute_min_compressed_bpp_x16(struct intel_connector *connector, return min_bpp_x16; } +static int compute_max_compressed_bpp_x16(struct intel_connector *connector, + int mode_clock, int mode_hdisplay, + int num_joined_pipes, + enum intel_output_format output_format, + int pipe_max_bpp, int max_link_bpp_x16) +{ + struct intel_display *display = to_intel_display(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); + int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp; + int throughput_max_bpp_x16; + int joiner_max_bpp; + + dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp); + joiner_max_bpp = get_max_compressed_bpp_with_joiner(display, + mode_clock, + mode_hdisplay, + num_joined_pipes); + dsc_sink_max_bpp = intel_dp_dsc_sink_max_compressed_bpp(connector, + output_format, + pipe_max_bpp / 3); + dsc_max_bpp = min(dsc_sink_max_bpp, dsc_src_max_bpp); + dsc_max_bpp = min(dsc_max_bpp, joiner_max_bpp); + + max_link_bpp_x16 = min(max_link_bpp_x16, fxp_q4_from_int(dsc_max_bpp)); + + throughput_max_bpp_x16 = dsc_throughput_quirk_max_bpp_x16(connector, + mode_clock); + if (throughput_max_bpp_x16 < max_link_bpp_x16) { + max_link_bpp_x16 = throughput_max_bpp_x16; + + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] Decreasing link max bpp to " FXP_Q4_FMT " due to DSC throughput quirk\n", + connector->base.base.id, connector->base.name, + FXP_Q4_ARGS(max_link_bpp_x16)); + } + + max_link_bpp_x16 = align_max_compressed_bpp_x16(connector, output_format, + pipe_max_bpp, max_link_bpp_x16); + + return max_link_bpp_x16; +} + /* * Calculate the output link min, max bpp values in limits based on the pipe bpp * range, crtc_state and dsc mode. Return true on success. @@ -2692,43 +2734,17 @@ intel_dp_compute_config_link_bpp_limits(struct intel_connector *connector, limits->link.min_bpp_x16 = fxp_q4_from_int(limits->pipe.min_bpp); } else { - int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp; - int throughput_max_bpp_x16; - int joiner_max_bpp; limits->link.min_bpp_x16 = compute_min_compressed_bpp_x16(connector, crtc_state->output_format); - dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp); - joiner_max_bpp = - get_max_compressed_bpp_with_joiner(display, - adjusted_mode->crtc_clock, - adjusted_mode->hdisplay, - intel_crtc_num_joined_pipes(crtc_state)); - dsc_sink_max_bpp = intel_dp_dsc_sink_max_compressed_bpp(connector, - crtc_state->output_format, - limits->pipe.max_bpp / 3); - dsc_max_bpp = min(dsc_sink_max_bpp, dsc_src_max_bpp); - dsc_max_bpp = min(dsc_max_bpp, joiner_max_bpp); - - max_link_bpp_x16 = min(max_link_bpp_x16, fxp_q4_from_int(dsc_max_bpp)); - - throughput_max_bpp_x16 = - dsc_throughput_quirk_max_bpp_x16(connector, adjusted_mode->crtc_clock); - if (throughput_max_bpp_x16 < max_link_bpp_x16) { - max_link_bpp_x16 = throughput_max_bpp_x16; - - drm_dbg_kms(display->drm, - "[CRTC:%d:%s][CONNECTOR:%d:%s] Decreasing link max bpp to " FXP_Q4_FMT " due to DSC throughput quirk\n", - crtc->base.base.id, crtc->base.name, - connector->base.base.id, connector->base.name, - FXP_Q4_ARGS(max_link_bpp_x16)); - } - max_link_bpp_x16 = - align_max_compressed_bpp_x16(connector, - crtc_state->output_format, - limits->pipe.max_bpp, - max_link_bpp_x16); + compute_max_compressed_bpp_x16(connector, + adjusted_mode->crtc_clock, + adjusted_mode->hdisplay, + intel_crtc_num_joined_pipes(crtc_state), + crtc_state->output_format, + limits->pipe.max_bpp, + max_link_bpp_x16); } limits->link.max_bpp_x16 = max_link_bpp_x16; From 745395b51c26766b070f5761d97f9fbad15618c3 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:39 +0200 Subject: [PATCH 84/92] drm/i915/dp: Add intel_dp_mode_valid_with_dsc() Add intel_dp_mode_valid_with_dsc() and call this for an SST/MST mode validation to prepare for a follow-up change using a way to verify the mode's required BW the same way this is done elsewhere during state computation (which in turn depends on the mode's effective data rate with the corresponding BW overhead). Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-13-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 57 +++++++++++++++------ drivers/gpu/drm/i915/display/intel_dp.h | 7 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 29 ++++------- 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index d1139d6582e1..abd763266618 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1580,24 +1580,20 @@ intel_dp_mode_valid(struct drm_connector *_connector, dsc_slice_count = drm_dp_dsc_sink_max_slice_count(connector->dp.dsc_dpcd, true); + dsc = dsc_max_compressed_bpp && dsc_slice_count; } else if (drm_dp_sink_supports_fec(connector->dp.fec_capability)) { - dsc_max_compressed_bpp = - intel_dp_dsc_get_max_compressed_bpp(display, - max_link_clock, - max_lanes, - target_clock, - mode->hdisplay, - num_joined_pipes, - output_format, - pipe_bpp, 64); - dsc_slice_count = - intel_dp_dsc_get_slice_count(connector, - target_clock, - mode->hdisplay, - num_joined_pipes); - } + unsigned long bw_overhead_flags = 0; - dsc = dsc_max_compressed_bpp && dsc_slice_count; + if (!drm_dp_is_uhbr_rate(max_link_clock)) + bw_overhead_flags |= DRM_DP_BW_OVERHEAD_FEC; + + dsc = intel_dp_mode_valid_with_dsc(connector, + max_link_clock, max_lanes, + target_clock, mode->hdisplay, + num_joined_pipes, + output_format, pipe_bpp, + bw_overhead_flags); + } } if (intel_dp_joiner_needs_dsc(display, num_joined_pipes) && !dsc) @@ -2705,6 +2701,35 @@ static int compute_max_compressed_bpp_x16(struct intel_connector *connector, return max_link_bpp_x16; } +bool intel_dp_mode_valid_with_dsc(struct intel_connector *connector, + int link_clock, int lane_count, + int mode_clock, int mode_hdisplay, + int num_joined_pipes, + enum intel_output_format output_format, + int pipe_bpp, unsigned long bw_overhead_flags) +{ + struct intel_display *display = to_intel_display(connector); + int dsc_max_compressed_bpp; + int dsc_slice_count; + + dsc_max_compressed_bpp = + intel_dp_dsc_get_max_compressed_bpp(display, + link_clock, + lane_count, + mode_clock, + mode_hdisplay, + num_joined_pipes, + output_format, + pipe_bpp, 64); + dsc_slice_count = + intel_dp_dsc_get_slice_count(connector, + mode_clock, + mode_hdisplay, + num_joined_pipes); + + return dsc_max_compressed_bpp && dsc_slice_count; +} + /* * Calculate the output link min, max bpp values in limits based on the pipe bpp * range, crtc_state and dsc mode. Return true on success. diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 489b8c945da3..0ec7baec7a8e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -150,6 +150,13 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct intel_display *display, enum intel_output_format output_format, u32 pipe_bpp, u32 timeslots); + +bool intel_dp_mode_valid_with_dsc(struct intel_connector *connector, + int link_clock, int lane_count, + int mode_clock, int mode_hdisplay, + int num_joined_pipes, + enum intel_output_format output_format, + int pipe_bpp, unsigned long bw_overhead_flags); bool intel_dp_dsc_valid_compressed_bpp(struct intel_dp *intel_dp, int bpp_x16); u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector, int mode_clock, int mode_hdisplay, diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 0db6ed2d9664..e3f8679e9525 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1462,8 +1462,6 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, DRM_DP_BW_OVERHEAD_MST | DRM_DP_BW_OVERHEAD_SSC_REF_CLK; int ret; bool dsc = false; - u16 dsc_max_compressed_bpp = 0; - u8 dsc_slice_count = 0; int target_clock = mode->clock; int num_joined_pipes; @@ -1522,31 +1520,22 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, return 0; } - if (intel_dp_has_dsc(connector)) { + if (intel_dp_has_dsc(connector) && drm_dp_sink_supports_fec(connector->dp.fec_capability)) { /* * TBD pass the connector BPC, * for now U8_MAX so that max BPC on that platform would be picked */ int pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, U8_MAX); - if (drm_dp_sink_supports_fec(connector->dp.fec_capability)) { - dsc_max_compressed_bpp = - intel_dp_dsc_get_max_compressed_bpp(display, - max_link_clock, - max_lanes, - target_clock, - mode->hdisplay, - num_joined_pipes, - INTEL_OUTPUT_FORMAT_RGB, - pipe_bpp, 64); - dsc_slice_count = - intel_dp_dsc_get_slice_count(connector, - target_clock, - mode->hdisplay, - num_joined_pipes); - } + if (!drm_dp_is_uhbr_rate(max_link_clock)) + bw_overhead_flags |= DRM_DP_BW_OVERHEAD_FEC; - dsc = dsc_max_compressed_bpp && dsc_slice_count; + dsc = intel_dp_mode_valid_with_dsc(connector, + max_link_clock, max_lanes, + target_clock, mode->hdisplay, + num_joined_pipes, + INTEL_OUTPUT_FORMAT_RGB, pipe_bpp, + bw_overhead_flags); } if (intel_dp_joiner_needs_dsc(display, num_joined_pipes) && !dsc) { From 2bd5dd6e720952778233636e0d0dd1ede3563634 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:40 +0200 Subject: [PATCH 85/92] drm/i915/dp: Unify detect and compute time DSC mode BW validation Atm, a DP DSC video mode's required BW vs. the available BW is determined by calculating the maximum compressed BPP value allowed by the available BW. Doing that using a closed-form formula as it's done atm (vs. an iterative way) is problematic, since the overhead of the required BW itself depends on the BPP value being calculated. Instead of that calculate the required BW for the minimum compressed BPP value supported both by the source and the sink and check this BW against the available BW. This change also aligns the BW calculation during mode validation with how this is done during state computation, calculating the required effective data rate with the corresponding BW overhead. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-14-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 137 ++++-------------------- drivers/gpu/drm/i915/display/intel_dp.h | 8 -- 2 files changed, 18 insertions(+), 127 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index abd763266618..e59c06b6e0b9 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -896,49 +896,6 @@ static int align_max_vesa_compressed_bpp_x16(int max_link_bpp_x16) return 0; } -static u32 intel_dp_dsc_nearest_valid_bpp(struct intel_display *display, u32 bpp, u32 pipe_bpp) -{ - u32 bits_per_pixel = bpp; - - /* Error out if the max bpp is less than smallest allowed valid bpp */ - if (bits_per_pixel < valid_dsc_bpp[0]) { - drm_dbg_kms(display->drm, "Unsupported BPP %u, min %u\n", - bits_per_pixel, valid_dsc_bpp[0]); - return 0; - } - - /* From XE_LPD onwards we support from bpc upto uncompressed bpp-1 BPPs */ - if (DISPLAY_VER(display) >= 13) { - bits_per_pixel = min(bits_per_pixel, pipe_bpp - 1); - - /* - * According to BSpec, 27 is the max DSC output bpp, - * 8 is the min DSC output bpp. - * While we can still clamp higher bpp values to 27, saving bandwidth, - * if it is required to oompress up to bpp < 8, means we can't do - * that and probably means we can't fit the required mode, even with - * DSC enabled. - */ - if (bits_per_pixel < 8) { - drm_dbg_kms(display->drm, - "Unsupported BPP %u, min 8\n", - bits_per_pixel); - return 0; - } - bits_per_pixel = min_t(u32, bits_per_pixel, 27); - } else { - int link_bpp_x16 = fxp_q4_from_int(bits_per_pixel); - - /* Find the nearest match in the array of known BPPs from VESA */ - link_bpp_x16 = align_max_vesa_compressed_bpp_x16(link_bpp_x16); - - drm_WARN_ON(display->drm, fxp_q4_to_frac(link_bpp_x16)); - bits_per_pixel = fxp_q4_to_int(link_bpp_x16); - } - - return bits_per_pixel; -} - static int bigjoiner_interface_bits(struct intel_display *display) { return DISPLAY_VER(display) >= 14 ? 36 : 24; @@ -1002,64 +959,6 @@ u32 get_max_compressed_bpp_with_joiner(struct intel_display *display, return max_bpp; } -/* TODO: return a bpp_x16 value */ -u16 intel_dp_dsc_get_max_compressed_bpp(struct intel_display *display, - u32 link_clock, u32 lane_count, - u32 mode_clock, u32 mode_hdisplay, - int num_joined_pipes, - enum intel_output_format output_format, - u32 pipe_bpp, - u32 timeslots) -{ - u32 bits_per_pixel, joiner_max_bpp; - - /* - * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)* - * (LinkSymbolClock)* 8 * (TimeSlots / 64) - * for SST -> TimeSlots is 64(i.e all TimeSlots that are available) - * for MST -> TimeSlots has to be calculated, based on mode requirements - * - * Due to FEC overhead, the available bw is reduced to 97.2261%. - * To support the given mode: - * Bandwidth required should be <= Available link Bandwidth * FEC Overhead - * =>ModeClock * bits_per_pixel <= Available Link Bandwidth * FEC Overhead - * =>bits_per_pixel <= Available link Bandwidth * FEC Overhead / ModeClock - * =>bits_per_pixel <= (NumberOfLanes * LinkSymbolClock) * 8 (TimeSlots / 64) / - * (ModeClock / FEC Overhead) - * =>bits_per_pixel <= (NumberOfLanes * LinkSymbolClock * TimeSlots) / - * (ModeClock / FEC Overhead * 8) - */ - bits_per_pixel = ((link_clock * lane_count) * timeslots) / - (intel_dp_mode_to_fec_clock(mode_clock) * 8); - - /* Bandwidth required for 420 is half, that of 444 format */ - if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420) - bits_per_pixel *= 2; - - /* - * According to DSC 1.2a Section 4.1.1 Table 4.1 the maximum - * supported PPS value can be 63.9375 and with the further - * mention that for 420, 422 formats, bpp should be programmed double - * the target bpp restricting our target bpp to be 31.9375 at max. - */ - if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420) - bits_per_pixel = min_t(u32, bits_per_pixel, 31); - - drm_dbg_kms(display->drm, "Max link bpp is %u for %u timeslots " - "total bw %u pixel clock %u\n", - bits_per_pixel, timeslots, - (link_clock * lane_count * 8), - intel_dp_mode_to_fec_clock(mode_clock)); - - joiner_max_bpp = get_max_compressed_bpp_with_joiner(display, mode_clock, - mode_hdisplay, num_joined_pipes); - bits_per_pixel = min(bits_per_pixel, joiner_max_bpp); - - bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(display, bits_per_pixel, pipe_bpp); - - return bits_per_pixel; -} - u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector, int mode_clock, int mode_hdisplay, int num_joined_pipes) @@ -2708,26 +2607,26 @@ bool intel_dp_mode_valid_with_dsc(struct intel_connector *connector, enum intel_output_format output_format, int pipe_bpp, unsigned long bw_overhead_flags) { - struct intel_display *display = to_intel_display(connector); - int dsc_max_compressed_bpp; - int dsc_slice_count; + struct intel_dp *intel_dp = intel_attached_dp(connector); + int min_bpp_x16 = compute_min_compressed_bpp_x16(connector, output_format); + int max_bpp_x16 = compute_max_compressed_bpp_x16(connector, + mode_clock, mode_hdisplay, + num_joined_pipes, + output_format, + pipe_bpp, INT_MAX); + int dsc_slice_count = intel_dp_dsc_get_slice_count(connector, + mode_clock, + mode_hdisplay, + num_joined_pipes); - dsc_max_compressed_bpp = - intel_dp_dsc_get_max_compressed_bpp(display, - link_clock, - lane_count, - mode_clock, - mode_hdisplay, - num_joined_pipes, - output_format, - pipe_bpp, 64); - dsc_slice_count = - intel_dp_dsc_get_slice_count(connector, - mode_clock, - mode_hdisplay, - num_joined_pipes); + if (min_bpp_x16 <= 0 || min_bpp_x16 > max_bpp_x16) + return false; - return dsc_max_compressed_bpp && dsc_slice_count; + return is_bw_sufficient_for_dsc_config(intel_dp, + link_clock, lane_count, + mode_clock, mode_hdisplay, + dsc_slice_count, min_bpp_x16, + bw_overhead_flags); } /* diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 0ec7baec7a8e..25bfbfd291b0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -143,14 +143,6 @@ bool intel_digital_port_connected(struct intel_encoder *encoder); bool intel_digital_port_connected_locked(struct intel_encoder *encoder); int intel_dp_dsc_compute_max_bpp(const struct intel_connector *connector, u8 dsc_max_bpc); -u16 intel_dp_dsc_get_max_compressed_bpp(struct intel_display *display, - u32 link_clock, u32 lane_count, - u32 mode_clock, u32 mode_hdisplay, - int num_joined_pipes, - enum intel_output_format output_format, - u32 pipe_bpp, - u32 timeslots); - bool intel_dp_mode_valid_with_dsc(struct intel_connector *connector, int link_clock, int lane_count, int mode_clock, int mode_hdisplay, From 4d2dd780970d33d4dd66c718077ee703938b0a71 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:41 +0200 Subject: [PATCH 86/92] drm/i915/dp: Use helpers to align min/max compressed BPPs The minimum/maximum compressed BPP values are aligned/bounded in intel_dp_compute_link_bpp_limits() to the corresponding source limits. The minimum compressed BPP value doesn't change afterwards, so no need to align it again, remove that. The maximum compressed BPP, which depends on the pipe BPP value still needs to be aligned, since the pipe BPP value could change after the above limits were computed, via intel_dp_force_dsc_pipe_bpp(). Use the corresponding helper for this alignment instead of open-coding the same. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-15-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index e59c06b6e0b9..36cbb6aef243 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2218,20 +2218,15 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, struct intel_display *display = to_intel_display(intel_dp); const struct intel_connector *connector = to_intel_connector(conn_state->connector); int min_bpp_x16, max_bpp_x16, bpp_step_x16; - int link_bpp_x16; int bpp_x16; int ret; + min_bpp_x16 = limits->link.min_bpp_x16; max_bpp_x16 = limits->link.max_bpp_x16; bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); - /* Compressed BPP should be less than the Input DSC bpp */ - link_bpp_x16 = intel_dp_output_format_link_bpp_x16(pipe_config->output_format, pipe_bpp); - max_bpp_x16 = min(max_bpp_x16, link_bpp_x16 - bpp_step_x16); - - drm_WARN_ON(display->drm, !is_power_of_2(bpp_step_x16)); - min_bpp_x16 = round_up(limits->link.min_bpp_x16, bpp_step_x16); - max_bpp_x16 = round_down(max_bpp_x16, bpp_step_x16); + max_bpp_x16 = align_max_compressed_bpp_x16(connector, pipe_config->output_format, + pipe_bpp, max_bpp_x16); for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) { if (!intel_dp_dsc_valid_compressed_bpp(intel_dp, bpp_x16)) @@ -2347,8 +2342,6 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, struct intel_connector *connector = to_intel_connector(conn_state->connector); int pipe_bpp, forced_bpp; - int dsc_min_bpp; - int dsc_max_bpp; forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, limits); @@ -2368,15 +2361,9 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, pipe_config->port_clock = limits->max_rate; pipe_config->lane_count = limits->max_lane_count; - dsc_min_bpp = fxp_q4_to_int_roundup(limits->link.min_bpp_x16); - - dsc_max_bpp = fxp_q4_to_int(limits->link.max_bpp_x16); - - /* Compressed BPP should be less than the Input DSC bpp */ - dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1); - pipe_config->dsc.compressed_bpp_x16 = - fxp_q4_from_int(max(dsc_min_bpp, dsc_max_bpp)); + align_max_compressed_bpp_x16(connector, pipe_config->output_format, + pipe_bpp, limits->link.max_bpp_x16); pipe_config->pipe_bpp = pipe_bpp; From 8193ce906a8656892334b17e60e19ae7aeea220f Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:42 +0200 Subject: [PATCH 87/92] drm/i915/dp: Simplify computing DSC BPPs for eDP The maximum pipe BPP value (used as the DSC input BPP) has been aligned already to the corresponding source/sink input BPP capabilities in intel_dp_compute_config_limits(). So it isn't needed to perform the same alignment again in intel_edp_dsc_compute_pipe_bpp() called later, this function can simply use the already aligned maximum pipe BPP value, do that. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-16-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 36cbb6aef243..e38e307bddff 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2338,26 +2338,16 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, struct drm_connector_state *conn_state, const struct link_config_limits *limits) { - struct intel_display *display = to_intel_display(intel_dp); struct intel_connector *connector = to_intel_connector(conn_state->connector); int pipe_bpp, forced_bpp; forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, limits); - - if (forced_bpp) { + if (forced_bpp) pipe_bpp = forced_bpp; - } else { - int max_bpc = limits->pipe.max_bpp / 3; + else + pipe_bpp = limits->pipe.max_bpp; - /* For eDP use max bpp that can be supported with DSC. */ - pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, max_bpc); - if (!is_dsc_pipe_bpp_sufficient(limits, pipe_bpp)) { - drm_dbg_kms(display->drm, - "Computed BPC is not in DSC BPC limits\n"); - return -EINVAL; - } - } pipe_config->port_clock = limits->max_rate; pipe_config->lane_count = limits->max_lane_count; From ce46682f89111fd0ded74a90c1ea04b36780221b Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:43 +0200 Subject: [PATCH 88/92] drm/i915/dp: Simplify computing DSC BPPs for DP-SST The maximum pipe BPP value (used as the DSC input BPP) has been aligned already to the corresponding source/sink input BPP capabilities in intel_dp_compute_config_limits(). So it isn't needed to perform the same alignment again in intel_dp_dsc_compute_pipe_bpp() called later, this function can simply use the already aligned maximum pipe BPP value, do that. Also, there is no point in trying pipe BPP values lower than the maximum: this would only make dsc_compute_compressed_bpp() start with a lower _compressed_ BPP value, but this lower compressed BPP value has been tried already when dsc_compute_compressed_bpp() was called with the higher pipe BPP value (i.e. the first dsc_compute_compressed_bpp() call tries already all the possible compressed BPP values which are all below the pipe BPP value passed to it). Simplify the function accordingly trying only the maximum pipe BPP value. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-17-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 29 +++++++------------------ 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index e38e307bddff..4603745dee37 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2295,11 +2295,8 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, struct drm_connector_state *conn_state, const struct link_config_limits *limits) { - const struct intel_connector *connector = - to_intel_connector(conn_state->connector); - u8 dsc_bpc[3] = {}; int forced_bpp, pipe_bpp; - int num_bpc, i, ret; + int ret; forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, limits); @@ -2312,25 +2309,15 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, } } - /* - * Get the maximum DSC bpc that will be supported by any valid - * link configuration and compressed bpp. - */ - num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, dsc_bpc); - for (i = 0; i < num_bpc; i++) { - pipe_bpp = dsc_bpc[i] * 3; - if (pipe_bpp < limits->pipe.min_bpp || pipe_bpp > limits->pipe.max_bpp) - continue; + pipe_bpp = limits->pipe.max_bpp; + ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, + limits, pipe_bpp); + if (ret) + return -EINVAL; - ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, - limits, pipe_bpp); - if (ret == 0) { - pipe_config->pipe_bpp = pipe_bpp; - return 0; - } - } + pipe_config->pipe_bpp = pipe_bpp; - return -EINVAL; + return 0; } static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, From 2b68b9b80f9ee75d4e7e159aa082dcd8c1e4e05c Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:44 +0200 Subject: [PATCH 89/92] drm/i915/dp: Simplify computing forced DSC BPP for DP-SST If dsc_compute_compressed_bpp() failed with a forced pipe BPP value (where the forced pipe BPP value itself is valid within the min/max pipe BPP limits), the function will also fail when called with the maximum pipe BPP value: dsc_compute_compressed_bpp() will try all compressed BPPs below the passed in pipe BPP value and if the function failed with a given (low) compressed BPP value it will also fail with a compressed BPP value higher than the one which failed already. Based on the above remove the logic to retry computing a compressed BPP value with the maximum pipe BPP value if computing the compressed BPP failed already with the (lower) forced pipe BPP value. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-18-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 4603745dee37..75ae8811442a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2299,17 +2299,11 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, int ret; forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, limits); + if (forced_bpp) + pipe_bpp = forced_bpp; + else + pipe_bpp = limits->pipe.max_bpp; - if (forced_bpp) { - ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, - limits, forced_bpp); - if (ret == 0) { - pipe_config->pipe_bpp = forced_bpp; - return 0; - } - } - - pipe_bpp = limits->pipe.max_bpp; ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, limits, pipe_bpp); if (ret) From 2b601460d1291310e4f04418eae2de93d0cc18d1 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:45 +0200 Subject: [PATCH 90/92] drm/i915/dp: Unify computing compressed BPP for DP-SST and eDP Move computing the eDP compressed BPP value to the function computing this for DP, allowing further simplifications later. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-19-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 75ae8811442a..96fddb8c54c3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2227,6 +2227,14 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, max_bpp_x16 = align_max_compressed_bpp_x16(connector, pipe_config->output_format, pipe_bpp, max_bpp_x16); + if (intel_dp_is_edp(intel_dp)) { + pipe_config->port_clock = limits->max_rate; + pipe_config->lane_count = limits->max_lane_count; + + pipe_config->dsc.compressed_bpp_x16 = max_bpp_x16; + + return 0; + } for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) { if (!intel_dp_dsc_valid_compressed_bpp(intel_dp, bpp_x16)) @@ -2319,9 +2327,8 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, struct drm_connector_state *conn_state, const struct link_config_limits *limits) { - struct intel_connector *connector = - to_intel_connector(conn_state->connector); int pipe_bpp, forced_bpp; + int ret; forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, limits); if (forced_bpp) @@ -2329,12 +2336,10 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, else pipe_bpp = limits->pipe.max_bpp; - pipe_config->port_clock = limits->max_rate; - pipe_config->lane_count = limits->max_lane_count; - - pipe_config->dsc.compressed_bpp_x16 = - align_max_compressed_bpp_x16(connector, pipe_config->output_format, - pipe_bpp, limits->link.max_bpp_x16); + ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, + limits, pipe_bpp); + if (ret) + return -EINVAL; pipe_config->pipe_bpp = pipe_bpp; From 3045a4eb12e9affb526cf24fb4a41d3487d55978 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:46 +0200 Subject: [PATCH 91/92] drm/i915/dp: Simplify eDP vs. DP compressed BPP computation intel_edp_dsc_compute_pipe_bpp() matches now intel_dp_dsc_compute_pipe_bpp(), remove the former function. Reviewed-by: Vinod Govindapillai Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-20-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 32 ++----------------------- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 96fddb8c54c3..7e022c47e8ac 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2322,30 +2322,6 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, return 0; } -static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - struct drm_connector_state *conn_state, - const struct link_config_limits *limits) -{ - int pipe_bpp, forced_bpp; - int ret; - - forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, limits); - if (forced_bpp) - pipe_bpp = forced_bpp; - else - pipe_bpp = limits->pipe.max_bpp; - - ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, - limits, pipe_bpp); - if (ret) - return -EINVAL; - - pipe_config->pipe_bpp = pipe_bpp; - - return 0; -} - /* * Return whether FEC must be enabled for 8b10b SST or MST links. On 128b132b * links FEC is always enabled implicitly by the HW, so this function returns @@ -2397,12 +2373,8 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, * figured out for DP MST DSC. */ if (!is_mst) { - if (intel_dp_is_edp(intel_dp)) - ret = intel_edp_dsc_compute_pipe_bpp(intel_dp, pipe_config, - conn_state, limits); - else - ret = intel_dp_dsc_compute_pipe_bpp(intel_dp, pipe_config, - conn_state, limits); + ret = intel_dp_dsc_compute_pipe_bpp(intel_dp, pipe_config, + conn_state, limits); if (ret) { drm_dbg_kms(display->drm, "No Valid pipe bpp for given mode ret = %d\n", ret); From d30f75d2dba913754dbacb982b19b783a30253ea Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 22 Dec 2025 17:35:47 +0200 Subject: [PATCH 92/92] drm/i915/dp: Simplify computing the DSC compressed BPP for DP-MST MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The minimum/maximum DSC input (i.e. pipe) and compressed (i.e. link) BPP limits are computed already in intel_dp_compute_config_limits(), so there is no need to do this again in mst_stream_dsc_compute_link_config() called later. Remove the corresponding alignments from the latter function and use the precomputed (aligned and within bounds) maximum pipe BPP and the min/max compressed BPP values instead as-is. Reviewed-by: Jouni Högander Signed-off-by: Imre Deak Link: https://patch.msgid.link/20251222153547.713360-21-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 48 +++------------------ 1 file changed, 6 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index e3f8679e9525..24f8e60df9ac 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -463,57 +463,21 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, { struct intel_display *display = to_intel_display(intel_dp); struct intel_connector *connector = to_intel_connector(conn_state->connector); - int num_bpc; - u8 dsc_bpc[3] = {}; - int min_bpp, max_bpp, sink_min_bpp, sink_max_bpp; - int min_compressed_bpp_x16, max_compressed_bpp_x16; - int bpp_step_x16; - max_bpp = limits->pipe.max_bpp; - min_bpp = limits->pipe.min_bpp; - - num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, - dsc_bpc); - - drm_dbg_kms(display->drm, "DSC Source supported min bpp %d max bpp %d\n", - min_bpp, max_bpp); - - sink_min_bpp = min_array(dsc_bpc, num_bpc) * 3; - sink_max_bpp = max_array(dsc_bpc, num_bpc) * 3; - - drm_dbg_kms(display->drm, "DSC Sink supported min bpp %d max bpp %d\n", - sink_min_bpp, sink_max_bpp); - - if (min_bpp < sink_min_bpp) - min_bpp = sink_min_bpp; - - if (max_bpp > sink_max_bpp) - max_bpp = sink_max_bpp; - - crtc_state->pipe_bpp = max_bpp; - - min_compressed_bpp_x16 = limits->link.min_bpp_x16; - max_compressed_bpp_x16 = limits->link.max_bpp_x16; + crtc_state->pipe_bpp = limits->pipe.max_bpp; drm_dbg_kms(display->drm, "DSC Sink supported compressed min bpp " FXP_Q4_FMT " compressed max bpp " FXP_Q4_FMT "\n", - FXP_Q4_ARGS(min_compressed_bpp_x16), FXP_Q4_ARGS(max_compressed_bpp_x16)); - - bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); - - max_compressed_bpp_x16 = min(max_compressed_bpp_x16, fxp_q4_from_int(crtc_state->pipe_bpp) - bpp_step_x16); - - drm_WARN_ON(display->drm, !is_power_of_2(bpp_step_x16)); - min_compressed_bpp_x16 = round_up(min_compressed_bpp_x16, bpp_step_x16); - max_compressed_bpp_x16 = round_down(max_compressed_bpp_x16, bpp_step_x16); + FXP_Q4_ARGS(limits->link.min_bpp_x16), FXP_Q4_ARGS(limits->link.max_bpp_x16)); crtc_state->lane_count = limits->max_lane_count; crtc_state->port_clock = limits->max_rate; return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state, - min_compressed_bpp_x16, - max_compressed_bpp_x16, - bpp_step_x16, true); + limits->link.min_bpp_x16, + limits->link.max_bpp_x16, + intel_dp_dsc_bpp_step_x16(connector), + true); } static int mode_hblank_period_ns(const struct drm_display_mode *mode)