From 485aaebd738bfd666cf446e3a6166faf4a5dde3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 5 Sep 2025 10:27:05 +0300 Subject: [PATCH 01/36] drm/i915/psr: Pass intel_crtc_state instead of intel_dp in wait_for_idle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is preparation to add own function for polling PSR being ready for update when doing dsb commit. Signed-off-by: Jouni Högander Reviewed-by: Mika Kahola Link: https://lore.kernel.org/r/20250905072708.2659411-2-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 22433fe2ee14..6ab5c028845a 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2997,10 +2997,11 @@ void intel_psr_post_plane_update(struct intel_atomic_state *state, } } -static int _psr2_ready_for_pipe_update_locked(struct intel_dp *intel_dp) +static int +_psr2_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state) { - struct intel_display *display = to_intel_display(intel_dp); - enum transcoder cpu_transcoder = intel_dp->psr.transcoder; + struct intel_display *display = to_intel_display(new_crtc_state); + enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder; /* * Any state lower than EDP_PSR2_STATUS_STATE_DEEP_SLEEP is enough. @@ -3012,10 +3013,11 @@ static int _psr2_ready_for_pipe_update_locked(struct intel_dp *intel_dp) EDP_PSR2_STATUS_STATE_DEEP_SLEEP, 50); } -static int _psr1_ready_for_pipe_update_locked(struct intel_dp *intel_dp) +static int +_psr1_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state) { - struct intel_display *display = to_intel_display(intel_dp); - enum transcoder cpu_transcoder = intel_dp->psr.transcoder; + struct intel_display *display = to_intel_display(new_crtc_state); + enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder; /* * From bspec: Panel Self Refresh (BDW+) @@ -3054,9 +3056,9 @@ void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_stat continue; if (intel_dp->psr.sel_update_enabled) - ret = _psr2_ready_for_pipe_update_locked(intel_dp); + ret = _psr2_ready_for_pipe_update_locked(new_crtc_state); else - ret = _psr1_ready_for_pipe_update_locked(intel_dp); + ret = _psr1_ready_for_pipe_update_locked(new_crtc_state); if (ret) drm_err(display->drm, From a0f7f3b1654c28739e1ae338afa354c83946c3d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 5 Sep 2025 10:27:06 +0300 Subject: [PATCH 02/36] drm/i915/psr: Add new define for PSR idle timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we are using value 50ms as timeout for waiting PSR to idle. Add own define for this purpose. Signed-off-by: Jouni Högander Reviewed-by: Mika Kahola Link: https://lore.kernel.org/r/20250905072708.2659411-3-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 6ab5c028845a..eae1eedbbb26 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -2997,6 +2997,14 @@ void intel_psr_post_plane_update(struct intel_atomic_state *state, } } +/* + * From bspec: Panel Self Refresh (BDW+) + * Max. time for PSR to idle = Inverse of the refresh rate + 6 ms of + * exit training time + 1.5 ms of aux channel handshake. 50 ms is + * defensive enough to cover everything. + */ +#define PSR_IDLE_TIMEOUT_MS 50 + static int _psr2_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state) { @@ -3010,7 +3018,8 @@ _psr2_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state */ return intel_de_wait_for_clear(display, EDP_PSR2_STATUS(display, cpu_transcoder), - EDP_PSR2_STATUS_STATE_DEEP_SLEEP, 50); + EDP_PSR2_STATUS_STATE_DEEP_SLEEP, + PSR_IDLE_TIMEOUT_MS); } static int @@ -3019,15 +3028,10 @@ _psr1_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state struct intel_display *display = to_intel_display(new_crtc_state); enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder; - /* - * From bspec: Panel Self Refresh (BDW+) - * Max. time for PSR to idle = Inverse of the refresh rate + 6 ms of - * exit training time + 1.5 ms of aux channel handshake. 50 ms is - * defensive enough to cover everything. - */ return intel_de_wait_for_clear(display, psr_status_reg(display, cpu_transcoder), - EDP_PSR_STATUS_STATE_MASK, 50); + EDP_PSR_STATUS_STATE_MASK, + PSR_IDLE_TIMEOUT_MS); } /** From 11b0567ee605e95becc02f858f8f42706687a068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 5 Sep 2025 10:27:07 +0300 Subject: [PATCH 03/36] drm/i915/psr: New interface adding PSR idle poll into dsb commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are currently observing crc failures after we started using dsb for PSR updates as well. This seems to happen because PSR HW is still sending couple of updates using old framebuffers on wake-up. This patch is preparing to fix that by adding interface which can be used to add poll ensuring PSR HW is idle into dsb commit. v3: add intel_dsb as a parameter to intel_psr_wait_for_idle_dsb v2: add pass crtc_state->dsb_commit as parameter Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/20250905072708.2659411-4-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 39 +++++++++++++++++++++--- drivers/gpu/drm/i915/display/intel_psr.h | 2 ++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index eae1eedbbb26..1aa4a127afaf 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -42,6 +42,7 @@ #include "intel_dmc.h" #include "intel_dp.h" #include "intel_dp_aux.h" +#include "intel_dsb.h" #include "intel_frontbuffer.h" #include "intel_hdmi.h" #include "intel_psr.h" @@ -3006,7 +3007,8 @@ void intel_psr_post_plane_update(struct intel_atomic_state *state, #define PSR_IDLE_TIMEOUT_MS 50 static int -_psr2_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state) +_psr2_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state, + struct intel_dsb *dsb) { struct intel_display *display = to_intel_display(new_crtc_state); enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder; @@ -3016,6 +3018,13 @@ _psr2_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state * As all higher states has bit 4 of PSR2 state set we can just wait for * EDP_PSR2_STATUS_STATE_DEEP_SLEEP to be cleared. */ + if (dsb) { + intel_dsb_poll(dsb, EDP_PSR2_STATUS(display, cpu_transcoder), + EDP_PSR2_STATUS_STATE_DEEP_SLEEP, 0, 200, + PSR_IDLE_TIMEOUT_MS * 1000 / 200); + return true; + } + return intel_de_wait_for_clear(display, EDP_PSR2_STATUS(display, cpu_transcoder), EDP_PSR2_STATUS_STATE_DEEP_SLEEP, @@ -3023,11 +3032,19 @@ _psr2_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state } static int -_psr1_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state) +_psr1_ready_for_pipe_update_locked(const struct intel_crtc_state *new_crtc_state, + struct intel_dsb *dsb) { struct intel_display *display = to_intel_display(new_crtc_state); enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder; + if (dsb) { + intel_dsb_poll(dsb, psr_status_reg(display, cpu_transcoder), + EDP_PSR_STATUS_STATE_MASK, 0, 200, + PSR_IDLE_TIMEOUT_MS * 1000 / 200); + return true; + } + return intel_de_wait_for_clear(display, psr_status_reg(display, cpu_transcoder), EDP_PSR_STATUS_STATE_MASK, @@ -3060,9 +3077,11 @@ void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_stat continue; if (intel_dp->psr.sel_update_enabled) - ret = _psr2_ready_for_pipe_update_locked(new_crtc_state); + ret = _psr2_ready_for_pipe_update_locked(new_crtc_state, + NULL); else - ret = _psr1_ready_for_pipe_update_locked(new_crtc_state); + ret = _psr1_ready_for_pipe_update_locked(new_crtc_state, + NULL); if (ret) drm_err(display->drm, @@ -3070,6 +3089,18 @@ void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_stat } } +void intel_psr_wait_for_idle_dsb(struct intel_dsb *dsb, + const struct intel_crtc_state *new_crtc_state) +{ + if (!new_crtc_state->has_psr || new_crtc_state->has_panel_replay) + return; + + if (new_crtc_state->has_sel_update) + _psr2_ready_for_pipe_update_locked(new_crtc_state, dsb); + else + _psr1_ready_for_pipe_update_locked(new_crtc_state, dsb); +} + static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index 9b061a22361f..077751aa599f 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -52,6 +52,8 @@ void intel_psr_get_config(struct intel_encoder *encoder, void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir); void intel_psr_short_pulse(struct intel_dp *intel_dp); void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_state); +void intel_psr_wait_for_idle_dsb(struct intel_dsb *dsb, + const struct intel_crtc_state *new_crtc_state); bool intel_psr_enabled(struct intel_dp *intel_dp); int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, struct intel_crtc *crtc); From 8bc70f2ea932976604876756d6d868eca3ac4cbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Fri, 5 Sep 2025 10:27:08 +0300 Subject: [PATCH 04/36] drm/i915/psr: Add poll for checking PSR is idle before starting update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are currently observing crc failures after we started using dsb for PSR updates as well. This seems to happen because PSR HW is still sending couple of updates using old framebuffers on wake-up. Fix this by adding poll ensuring PSR is idle before starting update. v2: pass new_crtc_state->dsb_commit to intel_psr_wait_for_idle_dsb Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/20250905072708.2659411-5-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index c1a3a95c65f0..5dca7f96b425 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7271,6 +7271,9 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, intel_psr_trigger_frame_change_event(new_crtc_state->dsb_commit, state, crtc); + intel_psr_wait_for_idle_dsb(new_crtc_state->dsb_commit, + new_crtc_state); + if (new_crtc_state->use_dsb) intel_dsb_vblank_evade(state, new_crtc_state->dsb_commit); From 90d8aad11f613e13e1eddc35c0225cce9e54ba94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Wed, 27 Aug 2025 09:08:09 +0300 Subject: [PATCH 05/36] drm/i915/psr: Panel Replay SU cap dpcd read return value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently return value of drm_dpcd_readb is not checked when reading sink Panel Replay Selective Update capabilities. Fix this and switch to drm_dpcd_read_byte. Signed-off-by: Jouni Högander Reviewed-by: Mika Kahola Reviewed-by: Michał Grzelak Link: https://lore.kernel.org/r/20250827060809.2461725-1-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 1aa4a127afaf..01bf304c705f 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -495,12 +495,14 @@ static u8 intel_dp_get_su_capability(struct intel_dp *intel_dp) { u8 su_capability = 0; - if (intel_dp->psr.sink_panel_replay_su_support) - drm_dp_dpcd_readb(&intel_dp->aux, - DP_PANEL_REPLAY_CAP_CAPABILITY, - &su_capability); - else + if (intel_dp->psr.sink_panel_replay_su_support) { + if (drm_dp_dpcd_read_byte(&intel_dp->aux, + DP_PANEL_REPLAY_CAP_CAPABILITY, + &su_capability) < 0) + return 0; + } else { su_capability = intel_dp->psr_dpcd[1]; + } return su_capability; } From 7ea3baa6efe4bb93d11e1c0e6528b1468d7debf6 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Sep 2025 13:41:49 +0300 Subject: [PATCH 06/36] drm/i915/power: fix size for for_each_set_bit() in abox iteration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit for_each_set_bit() expects size to be in bits, not bytes. The abox mask iteration uses bytes, but it works by coincidence, because the local variable holding the mask is unsigned long, and the mask only ever has bit 2 as the highest bit. Using a smaller type could lead to subtle and very hard to track bugs. Fixes: 62afef2811e4 ("drm/i915/rkl: RKL uses ABOX0 for pixel transfers") Cc: Ville Syrjälä Cc: Matt Roper Cc: stable@vger.kernel.org # v5.9+ Reviewed-by: Matt Roper Link: https://lore.kernel.org/r/20250905104149.1144751-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_power.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 7f9a2d743bac..da4babfd6bcb 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1174,7 +1174,7 @@ static void icl_mbus_init(struct intel_display *display) if (DISPLAY_VER(display) == 12) abox_regs |= BIT(0); - for_each_set_bit(i, &abox_regs, sizeof(abox_regs)) + for_each_set_bit(i, &abox_regs, BITS_PER_TYPE(abox_regs)) intel_de_rmw(display, MBUS_ABOX_CTL(i), mask, val); } @@ -1639,11 +1639,11 @@ static void tgl_bw_buddy_init(struct intel_display *display) if (table[config].page_mask == 0) { drm_dbg_kms(display->drm, "Unknown memory configuration; disabling address buddy logic.\n"); - for_each_set_bit(i, &abox_mask, sizeof(abox_mask)) + for_each_set_bit(i, &abox_mask, BITS_PER_TYPE(abox_mask)) intel_de_write(display, BW_BUDDY_CTL(i), BW_BUDDY_DISABLE); } else { - for_each_set_bit(i, &abox_mask, sizeof(abox_mask)) { + for_each_set_bit(i, &abox_mask, BITS_PER_TYPE(abox_mask)) { intel_de_write(display, BW_BUDDY_PAGE_MASK(i), table[config].page_mask); From 55c771b0d8a70a10d549d5296cf5e3342bef548f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 3 Sep 2025 13:10:50 +0300 Subject: [PATCH 07/36] drm/i915/ddi: abstract figuring out encoder name The encoder name deduction has become a bit cumbersome within intel_ddi_init(). Split it out to a separate function to declutter intel_ddi_init(), even if that means having to use a temp seq buffer for the name. Cc: Ankit Nautiyal Reviewed-by: Ankit Nautiyal Link: https://lore.kernel.org/r/20250903101050.3671305-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_ddi.c | 69 +++++++++++++----------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 46017091bb0b..08083ac83a74 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -26,6 +26,7 @@ */ #include +#include #include #include @@ -5067,11 +5068,45 @@ static bool port_in_use(struct intel_display *display, enum port port) return false; } +static const char *intel_ddi_encoder_name(struct intel_display *display, + enum port port, enum phy phy, + struct seq_buf *s) +{ + if (DISPLAY_VER(display) >= 13 && port >= PORT_D_XELPD) { + seq_buf_printf(s, "DDI %c/PHY %c", + port_name(port - PORT_D_XELPD + PORT_D), + phy_name(phy)); + } else if (DISPLAY_VER(display) >= 12) { + enum tc_port tc_port = intel_port_to_tc(display, port); + + seq_buf_printf(s, "DDI %s%c/PHY %s%c", + port >= PORT_TC1 ? "TC" : "", + port >= PORT_TC1 ? port_tc_name(port) : port_name(port), + tc_port != TC_PORT_NONE ? "TC" : "", + tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); + } else if (DISPLAY_VER(display) >= 11) { + enum tc_port tc_port = intel_port_to_tc(display, port); + + seq_buf_printf(s, "DDI %c%s/PHY %s%c", + port_name(port), + port >= PORT_C ? " (TC)" : "", + tc_port != TC_PORT_NONE ? "TC" : "", + tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); + } else { + seq_buf_printf(s, "DDI %c/PHY %c", port_name(port), phy_name(phy)); + } + + drm_WARN_ON(display->drm, seq_buf_has_overflowed(s)); + + return seq_buf_str(s); +} + void intel_ddi_init(struct intel_display *display, const struct intel_bios_encoder_data *devdata) { struct intel_digital_port *dig_port; struct intel_encoder *encoder; + DECLARE_SEQ_BUF(encoder_name, 20); bool init_hdmi, init_dp; enum port port; enum phy phy; @@ -5156,37 +5191,9 @@ void intel_ddi_init(struct intel_display *display, encoder = &dig_port->base; encoder->devdata = devdata; - if (DISPLAY_VER(display) >= 13 && port >= PORT_D_XELPD) { - drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, - DRM_MODE_ENCODER_TMDS, - "DDI %c/PHY %c", - port_name(port - PORT_D_XELPD + PORT_D), - phy_name(phy)); - } else if (DISPLAY_VER(display) >= 12) { - enum tc_port tc_port = intel_port_to_tc(display, port); - - drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, - DRM_MODE_ENCODER_TMDS, - "DDI %s%c/PHY %s%c", - port >= PORT_TC1 ? "TC" : "", - port >= PORT_TC1 ? port_tc_name(port) : port_name(port), - tc_port != TC_PORT_NONE ? "TC" : "", - tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); - } else if (DISPLAY_VER(display) >= 11) { - enum tc_port tc_port = intel_port_to_tc(display, port); - - drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, - DRM_MODE_ENCODER_TMDS, - "DDI %c%s/PHY %s%c", - port_name(port), - port >= PORT_C ? " (TC)" : "", - tc_port != TC_PORT_NONE ? "TC" : "", - tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); - } else { - drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, - DRM_MODE_ENCODER_TMDS, - "DDI %c/PHY %c", port_name(port), phy_name(phy)); - } + drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, + DRM_MODE_ENCODER_TMDS, "%s", + intel_ddi_encoder_name(display, port, phy, &encoder_name)); intel_encoder_link_check_init(encoder, intel_ddi_link_check); From 30c3ffb880315b907ccd682ed4e17d20f786fdf9 Mon Sep 17 00:00:00 2001 From: Liao Yuanhong Date: Thu, 4 Sep 2025 19:26:40 +0800 Subject: [PATCH 08/36] drm/i915/gvt: Remove redundant ternary operators For ternary operators in the form of "a ? false : true", if 'a' itself returns a boolean result, the ternary operator can be omitted. Remove redundant ternary operators to clean up the code. Signed-off-by: Liao Yuanhong Link: https://lore.kernel.org/r/20250904112644.350512-1-liaoyuanhong@vivo.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gvt/cmd_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index a91e23c22ea1..d432fdd69833 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -1921,7 +1921,7 @@ static int perform_bb_shadow(struct parser_exec_state *s) if (!bb) return -ENOMEM; - bb->ppgtt = (s->buf_addr_type == GTT_BUFFER) ? false : true; + bb->ppgtt = s->buf_addr_type != GTT_BUFFER; /* * The start_offset stores the batch buffer's start gma's From 45b95459802afe9b7d7add22db98176749c88d6c Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Thu, 4 Sep 2025 15:23:38 +0530 Subject: [PATCH 09/36] drm/i915/display: Remove FBC modulo 4 restriction for ADL-P+ WA:22010751166 does not apply past display version 12. Or, in other words, the FBC restriction where FBC is disabled for non-modulo 4 plane sizes (including plane size + yoffset) is fixed from display version 13 and onwards. Relax the restriction for the same. v4: Dropped redundant commit message v3: Update comments for clarity (Jonathan Cavitt) v2: Update the macro for display version check (Vinod) Suggested-by: Vidya Srinivas Signed-off-by: Uma Shankar Reviewed-by: Vinod Govindapillai Reviewed-by: Jonathan Cavitt Link: https://lore.kernel.org/r/20250904095338.300813-2-uma.shankar@intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index d4c5deff9cbe..9e097ed80bd1 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1550,14 +1550,14 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, * having a Y offset that isn't divisible by 4 causes FIFO underrun * and screen flicker. */ - if (DISPLAY_VER(display) >= 9 && + if (IS_DISPLAY_VER(display, 9, 12) && plane_state->view.color_plane[0].y & 3) { plane_state->no_fbc_reason = "plane start Y offset misaligned"; return 0; } /* Wa_22010751166: icl, ehl, tgl, dg1, rkl */ - if (DISPLAY_VER(display) >= 11 && + if (IS_DISPLAY_VER(display, 9, 12) && (plane_state->view.color_plane[0].y + (drm_rect_height(&plane_state->uapi.src) >> 16)) & 3) { plane_state->no_fbc_reason = "plane end Y offset misaligned"; From cef2c7266feaf15676fb5e47cbb6d7d832b61563 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 2 Sep 2025 20:51:47 +0300 Subject: [PATCH 10/36] drm/i915/fb: add intel_framebuffer_alloc() Add intel_framebuffer_alloc() to hide intel_bo_alloc_framebuffer(), as that doesn't feel like the correct abstraction. Cc: Jocelyn Falempe Cc: Maarten Lankhorst Signed-off-by: Jani Nikula Reviewed-by: Jocelyn Falempe Link: https://lore.kernel.org/r/379c306c692c50f6af3b6f2488c213f12627954f.1756835342.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/i9xx_plane.c | 3 +-- drivers/gpu/drm/i915/display/intel_fb.c | 7 ++++++- drivers/gpu/drm/i915/display/intel_fb.h | 3 +++ drivers/gpu/drm/i915/display/skl_universal_plane.c | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 3eb96d8abba8..9a39e9efbfaf 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -15,7 +15,6 @@ #include "i9xx_plane.h" #include "i9xx_plane_regs.h" #include "intel_atomic.h" -#include "intel_bo.h" #include "intel_de.h" #include "intel_display_irq.h" #include "intel_display_regs.h" @@ -1178,7 +1177,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, drm_WARN_ON(display->drm, pipe != crtc->pipe); - intel_fb = intel_bo_alloc_framebuffer(); + intel_fb = intel_framebuffer_alloc(); if (!intel_fb) { drm_dbg_kms(display->drm, "failed to alloc fb\n"); return; diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 71b4fa19f1e5..3f2cbcd2626d 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -2340,6 +2340,11 @@ intel_user_framebuffer_create(struct drm_device *dev, return fb; } +struct intel_framebuffer *intel_framebuffer_alloc(void) +{ + return intel_bo_alloc_framebuffer(); +} + struct drm_framebuffer * intel_framebuffer_create(struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd) @@ -2347,7 +2352,7 @@ intel_framebuffer_create(struct drm_gem_object *obj, struct intel_framebuffer *intel_fb; int ret; - intel_fb = intel_bo_alloc_framebuffer(); + intel_fb = intel_framebuffer_alloc(); if (!intel_fb) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index bdd76b372957..7d77022235a5 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -103,6 +103,9 @@ void intel_add_fb_offsets(int *x, int *y, int intel_framebuffer_init(struct intel_framebuffer *ifb, struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd); + +struct intel_framebuffer *intel_framebuffer_alloc(void); + struct drm_framebuffer * intel_framebuffer_create(struct drm_gem_object *obj, struct drm_mode_fb_cmd2 *mode_cmd); diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 950dc79dbdd4..59ee0830de02 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -3028,7 +3028,7 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, return; } - intel_fb = intel_bo_alloc_framebuffer(); + intel_fb = intel_framebuffer_alloc(); if (!intel_fb) { drm_dbg_kms(display->drm, "failed to alloc fb\n"); return; From 5f54b2196c674adc02a22f99da414b503daccb4c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 2 Sep 2025 20:51:48 +0300 Subject: [PATCH 11/36] drm/{i915,xe}/panic: split out intel_panic.[ch] intel_bo.[ch] is not the appropriate location for the panic functionality. Split out intel_panic.[ch] and xe_panic.c in i915 and xe. Keep the function names for now. Cc: Jocelyn Falempe Cc: Maarten Lankhorst Signed-off-by: Jani Nikula Reviewed-by: Jocelyn Falempe Link: https://lore.kernel.org/r/d98b831a011a028ffd33ce99b0ba62be061ee235.1756835342.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/display/i9xx_plane.c | 1 + drivers/gpu/drm/i915/display/intel_bo.c | 15 --- drivers/gpu/drm/i915/display/intel_bo.h | 3 - drivers/gpu/drm/i915/display/intel_fb.c | 1 + drivers/gpu/drm/i915/display/intel_panic.c | 20 ++++ drivers/gpu/drm/i915/display/intel_panic.h | 14 +++ drivers/gpu/drm/i915/display/intel_plane.c | 2 +- .../drm/i915/display/skl_universal_plane.c | 1 + drivers/gpu/drm/xe/Makefile | 1 + drivers/gpu/drm/xe/display/intel_bo.c | 91 ------------------ drivers/gpu/drm/xe/display/xe_panic.c | 96 +++++++++++++++++++ 12 files changed, 136 insertions(+), 110 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_panic.c create mode 100644 drivers/gpu/drm/i915/display/intel_panic.h create mode 100644 drivers/gpu/drm/xe/display/xe_panic.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 853543443072..db150a0c33ce 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -280,6 +280,7 @@ i915-y += \ display/intel_modeset_setup.o \ display/intel_modeset_verify.o \ display/intel_overlay.o \ + display/intel_panic.o \ display/intel_pch.o \ display/intel_pch_display.o \ display/intel_pch_refclk.o \ diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 9a39e9efbfaf..407deb5dfb57 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -22,6 +22,7 @@ #include "intel_fb.h" #include "intel_fbc.h" #include "intel_frontbuffer.h" +#include "intel_panic.h" #include "intel_plane.h" #include "intel_sprite.h" diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c index d29c1508ccb9..6ae1374d5c2b 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.c +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -59,18 +59,3 @@ void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) { i915_debugfs_describe_obj(m, to_intel_bo(obj)); } - -struct intel_framebuffer *intel_bo_alloc_framebuffer(void) -{ - return i915_gem_object_alloc_framebuffer(); -} - -int intel_bo_panic_setup(struct drm_scanout_buffer *sb) -{ - return i915_gem_object_panic_setup(sb); -} - -void intel_bo_panic_finish(struct intel_framebuffer *fb) -{ - return i915_gem_object_panic_finish(fb); -} diff --git a/drivers/gpu/drm/i915/display/intel_bo.h b/drivers/gpu/drm/i915/display/intel_bo.h index 97087a64d23b..48d87019e48a 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.h +++ b/drivers/gpu/drm/i915/display/intel_bo.h @@ -25,8 +25,5 @@ struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj, struct intel_frontbuffer *front); void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj); -struct intel_framebuffer *intel_bo_alloc_framebuffer(void); -int intel_bo_panic_setup(struct drm_scanout_buffer *sb); -void intel_bo_panic_finish(struct intel_framebuffer *fb); #endif /* __INTEL_BO__ */ diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 3f2cbcd2626d..4b415dfb5a66 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -20,6 +20,7 @@ #include "intel_fb.h" #include "intel_fb_bo.h" #include "intel_frontbuffer.h" +#include "intel_panic.h" #include "intel_plane.h" #define check_array_bounds(display, a, i) drm_WARN_ON((display)->drm, (i) >= ARRAY_SIZE(a)) diff --git a/drivers/gpu/drm/i915/display/intel_panic.c b/drivers/gpu/drm/i915/display/intel_panic.c new file mode 100644 index 000000000000..9eae210bb4cd --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_panic.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2025 Intel Corporation */ + +#include "gem/i915_gem_object.h" +#include "intel_panic.h" + +struct intel_framebuffer *intel_bo_alloc_framebuffer(void) +{ + return i915_gem_object_alloc_framebuffer(); +} + +int intel_bo_panic_setup(struct drm_scanout_buffer *sb) +{ + return i915_gem_object_panic_setup(sb); +} + +void intel_bo_panic_finish(struct intel_framebuffer *fb) +{ + return i915_gem_object_panic_finish(fb); +} diff --git a/drivers/gpu/drm/i915/display/intel_panic.h b/drivers/gpu/drm/i915/display/intel_panic.h new file mode 100644 index 000000000000..07e72240cbd7 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_panic.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __INTEL_PANIC_H__ +#define __INTEL_PANIC_H__ + +struct drm_scanout_buffer; +struct intel_framebuffer; + +struct intel_framebuffer *intel_bo_alloc_framebuffer(void); +int intel_bo_panic_setup(struct drm_scanout_buffer *sb); +void intel_bo_panic_finish(struct intel_framebuffer *fb); + +#endif /* __INTEL_PANIC_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c index 81f05ee9a21a..a467e14e6388 100644 --- a/drivers/gpu/drm/i915/display/intel_plane.c +++ b/drivers/gpu/drm/i915/display/intel_plane.c @@ -47,7 +47,6 @@ #include "gem/i915_gem_object.h" #include "i915_scheduler_types.h" #include "i9xx_plane_regs.h" -#include "intel_bo.h" #include "intel_cdclk.h" #include "intel_cursor.h" #include "intel_display_rps.h" @@ -56,6 +55,7 @@ #include "intel_fb.h" #include "intel_fb_pin.h" #include "intel_fbdev.h" +#include "intel_panic.h" #include "intel_plane.h" #include "intel_psr.h" #include "skl_scaler.h" diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 59ee0830de02..e13fb781e7b2 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -20,6 +20,7 @@ #include "intel_fb.h" #include "intel_fbc.h" #include "intel_frontbuffer.h" +#include "intel_panic.h" #include "intel_plane.h" #include "intel_psr.h" #include "intel_psr_regs.h" diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index c83d72de81dd..d2202f2a2374 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -192,6 +192,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ display/xe_dsb_buffer.o \ display/xe_fb_pin.o \ display/xe_hdcp_gsc.o \ + display/xe_panic.o \ display/xe_plane_initial.o \ display/xe_tdf.o diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c index 910632f57c3d..27437c22bd70 100644 --- a/drivers/gpu/drm/xe/display/intel_bo.c +++ b/drivers/gpu/drm/xe/display/intel_bo.c @@ -1,12 +1,7 @@ // SPDX-License-Identifier: MIT /* Copyright © 2024 Intel Corporation */ -#include #include -#include - -#include "intel_fb.h" -#include "intel_display_types.h" #include "xe_bo.h" #include "intel_bo.h" @@ -64,89 +59,3 @@ void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) { /* FIXME */ } - -struct xe_panic_data { - struct page **pages; - int page; - void *vaddr; -}; - -struct xe_framebuffer { - struct intel_framebuffer base; - struct xe_panic_data panic; -}; - -static inline struct xe_panic_data *to_xe_panic_data(struct intel_framebuffer *fb) -{ - return &container_of_const(fb, struct xe_framebuffer, base)->panic; -} - -static void xe_panic_kunmap(struct xe_panic_data *panic) -{ - if (panic->vaddr) { - drm_clflush_virt_range(panic->vaddr, PAGE_SIZE); - kunmap_local(panic->vaddr); - panic->vaddr = NULL; - } -} - -/* - * The scanout buffer pages are not mapped, so for each pixel, - * use kmap_local_page_try_from_panic() to map the page, and write the pixel. - * Try to keep the map from the previous pixel, to avoid too much map/unmap. - */ -static void xe_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int x, - unsigned int y, u32 color) -{ - struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; - struct xe_panic_data *panic = to_xe_panic_data(fb); - struct xe_bo *bo = gem_to_xe_bo(intel_fb_bo(&fb->base)); - unsigned int new_page; - unsigned int offset; - - if (fb->panic_tiling) - offset = fb->panic_tiling(sb->width, x, y); - else - offset = y * sb->pitch[0] + x * sb->format->cpp[0]; - - new_page = offset >> PAGE_SHIFT; - offset = offset % PAGE_SIZE; - if (new_page != panic->page) { - xe_panic_kunmap(panic); - panic->page = new_page; - panic->vaddr = ttm_bo_kmap_try_from_panic(&bo->ttm, - panic->page); - } - if (panic->vaddr) { - u32 *pix = panic->vaddr + offset; - *pix = color; - } -} - -struct intel_framebuffer *intel_bo_alloc_framebuffer(void) -{ - struct xe_framebuffer *xe_fb; - - xe_fb = kzalloc(sizeof(*xe_fb), GFP_KERNEL); - if (xe_fb) - return &xe_fb->base; - return NULL; -} - -int intel_bo_panic_setup(struct drm_scanout_buffer *sb) -{ - struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; - struct xe_panic_data *panic = to_xe_panic_data(fb); - - panic->page = -1; - sb->set_pixel = xe_panic_page_set_pixel; - return 0; -} - -void intel_bo_panic_finish(struct intel_framebuffer *fb) -{ - struct xe_panic_data *panic = to_xe_panic_data(fb); - - xe_panic_kunmap(panic); - panic->page = -1; -} diff --git a/drivers/gpu/drm/xe/display/xe_panic.c b/drivers/gpu/drm/xe/display/xe_panic.c new file mode 100644 index 000000000000..14fba8aa4e5f --- /dev/null +++ b/drivers/gpu/drm/xe/display/xe_panic.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2025 Intel Corporation */ + +#include +#include + +#include "intel_display_types.h" +#include "intel_fb.h" +#include "intel_panic.h" +#include "xe_bo.h" + +struct xe_panic_data { + struct page **pages; + int page; + void *vaddr; +}; + +struct xe_framebuffer { + struct intel_framebuffer base; + struct xe_panic_data panic; +}; + +static inline struct xe_panic_data *to_xe_panic_data(struct intel_framebuffer *fb) +{ + return &container_of_const(fb, struct xe_framebuffer, base)->panic; +} + +static void xe_panic_kunmap(struct xe_panic_data *panic) +{ + if (panic->vaddr) { + drm_clflush_virt_range(panic->vaddr, PAGE_SIZE); + kunmap_local(panic->vaddr); + panic->vaddr = NULL; + } +} + +/* + * The scanout buffer pages are not mapped, so for each pixel, + * use kmap_local_page_try_from_panic() to map the page, and write the pixel. + * Try to keep the map from the previous pixel, to avoid too much map/unmap. + */ +static void xe_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int x, + unsigned int y, u32 color) +{ + struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; + struct xe_panic_data *panic = to_xe_panic_data(fb); + struct xe_bo *bo = gem_to_xe_bo(intel_fb_bo(&fb->base)); + unsigned int new_page; + unsigned int offset; + + if (fb->panic_tiling) + offset = fb->panic_tiling(sb->width, x, y); + else + offset = y * sb->pitch[0] + x * sb->format->cpp[0]; + + new_page = offset >> PAGE_SHIFT; + offset = offset % PAGE_SIZE; + if (new_page != panic->page) { + xe_panic_kunmap(panic); + panic->page = new_page; + panic->vaddr = ttm_bo_kmap_try_from_panic(&bo->ttm, + panic->page); + } + if (panic->vaddr) { + u32 *pix = panic->vaddr + offset; + *pix = color; + } +} + +struct intel_framebuffer *intel_bo_alloc_framebuffer(void) +{ + struct xe_framebuffer *xe_fb; + + xe_fb = kzalloc(sizeof(*xe_fb), GFP_KERNEL); + if (xe_fb) + return &xe_fb->base; + return NULL; +} + +int intel_bo_panic_setup(struct drm_scanout_buffer *sb) +{ + struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; + struct xe_panic_data *panic = to_xe_panic_data(fb); + + panic->page = -1; + sb->set_pixel = xe_panic_page_set_pixel; + return 0; +} + +void intel_bo_panic_finish(struct intel_framebuffer *fb) +{ + struct xe_panic_data *panic = to_xe_panic_data(fb); + + xe_panic_kunmap(panic); + panic->page = -1; +} From 05a85e781ff0e37ccadcac133aa355b81db86ada Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 2 Sep 2025 20:51:49 +0300 Subject: [PATCH 12/36] drm/{i915,xe}/panic: rename intel_bo_panic_*() to intel_panic_*() Rename the intel_bo_panic_*() functions according to the functionality, dropping the misleading intel_bo reference. Keep intel_bo_alloc_framebuffer() for now; it'll be refactored later. Cc: Jocelyn Falempe Cc: Maarten Lankhorst Signed-off-by: Jani Nikula Reviewed-by: Jocelyn Falempe Link: https://lore.kernel.org/r/a3be8f8b5e7dd208027a1131e89452d9a214054f.1756835342.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_panic.c | 4 ++-- drivers/gpu/drm/i915/display/intel_panic.h | 4 ++-- drivers/gpu/drm/i915/display/intel_plane.c | 4 ++-- drivers/gpu/drm/xe/display/xe_panic.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_panic.c b/drivers/gpu/drm/i915/display/intel_panic.c index 9eae210bb4cd..20eecb0f168f 100644 --- a/drivers/gpu/drm/i915/display/intel_panic.c +++ b/drivers/gpu/drm/i915/display/intel_panic.c @@ -9,12 +9,12 @@ struct intel_framebuffer *intel_bo_alloc_framebuffer(void) return i915_gem_object_alloc_framebuffer(); } -int intel_bo_panic_setup(struct drm_scanout_buffer *sb) +int intel_panic_setup(struct drm_scanout_buffer *sb) { return i915_gem_object_panic_setup(sb); } -void intel_bo_panic_finish(struct intel_framebuffer *fb) +void intel_panic_finish(struct intel_framebuffer *fb) { return i915_gem_object_panic_finish(fb); } diff --git a/drivers/gpu/drm/i915/display/intel_panic.h b/drivers/gpu/drm/i915/display/intel_panic.h index 07e72240cbd7..67ce253fcdf5 100644 --- a/drivers/gpu/drm/i915/display/intel_panic.h +++ b/drivers/gpu/drm/i915/display/intel_panic.h @@ -8,7 +8,7 @@ struct drm_scanout_buffer; struct intel_framebuffer; struct intel_framebuffer *intel_bo_alloc_framebuffer(void); -int intel_bo_panic_setup(struct drm_scanout_buffer *sb); -void intel_bo_panic_finish(struct intel_framebuffer *fb); +int intel_panic_setup(struct drm_scanout_buffer *sb); +void intel_panic_finish(struct intel_framebuffer *fb); #endif /* __INTEL_PANIC_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c index a467e14e6388..890d897bda10 100644 --- a/drivers/gpu/drm/i915/display/intel_plane.c +++ b/drivers/gpu/drm/i915/display/intel_plane.c @@ -1326,7 +1326,7 @@ static void intel_panic_flush(struct drm_plane *plane) struct drm_framebuffer *fb = plane_state->hw.fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - intel_bo_panic_finish(intel_fb); + intel_panic_finish(intel_fb); if (crtc_state->enable_psr2_sel_fetch) { /* Force a full update for psr2 */ @@ -1409,7 +1409,7 @@ static int intel_get_scanout_buffer(struct drm_plane *plane, return -EOPNOTSUPP; } sb->private = intel_fb; - ret = intel_bo_panic_setup(sb); + ret = intel_panic_setup(sb); if (ret) return ret; } diff --git a/drivers/gpu/drm/xe/display/xe_panic.c b/drivers/gpu/drm/xe/display/xe_panic.c index 14fba8aa4e5f..18b27a06b260 100644 --- a/drivers/gpu/drm/xe/display/xe_panic.c +++ b/drivers/gpu/drm/xe/display/xe_panic.c @@ -77,7 +77,7 @@ struct intel_framebuffer *intel_bo_alloc_framebuffer(void) return NULL; } -int intel_bo_panic_setup(struct drm_scanout_buffer *sb) +int intel_panic_setup(struct drm_scanout_buffer *sb) { struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; struct xe_panic_data *panic = to_xe_panic_data(fb); @@ -87,7 +87,7 @@ int intel_bo_panic_setup(struct drm_scanout_buffer *sb) return 0; } -void intel_bo_panic_finish(struct intel_framebuffer *fb) +void intel_panic_finish(struct intel_framebuffer *fb) { struct xe_panic_data *panic = to_xe_panic_data(fb); From 4e839f2c7bafb18c450af78a1b6fc78e423a2039 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 2 Sep 2025 20:51:50 +0300 Subject: [PATCH 13/36] drm/{i915,xe}/fb: add panic pointer member to struct intel_framebuffer Add a panic data pointer member in struct intel_framebuffer in preparation for breaking the artificial subclassing between intel_framebuffer and panic structures. Cc: Jocelyn Falempe Cc: Maarten Lankhorst Signed-off-by: Jani Nikula Reviewed-by: Jocelyn Falempe Link: https://lore.kernel.org/r/41f42e1de8545409274d54854aa12e0fb390e394.1756835342.git.jani.nikula@intel.com --- .../drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/gem/i915_gem_pages.c | 20 +++++++++---------- drivers/gpu/drm/xe/display/xe_panic.c | 20 +++++++++---------- 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index fd9d2527889b..608fd69af657 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -149,6 +149,7 @@ struct intel_framebuffer { unsigned int vtd_guard; unsigned int (*panic_tiling)(unsigned int x, unsigned int y, unsigned int width); + void *panic; }; enum intel_hotplug_state { diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index c16a57160b26..c54ed1b33e60 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -368,11 +368,6 @@ struct i915_framebuffer { struct i915_panic_data panic; }; -static inline struct i915_panic_data *to_i915_panic_data(struct intel_framebuffer *fb) -{ - return &container_of_const(fb, struct i915_framebuffer, base)->panic; -} - static void i915_panic_kunmap(struct i915_panic_data *panic) { if (panic->vaddr) { @@ -420,7 +415,7 @@ static void i915_gem_object_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int new_page; unsigned int offset; struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; - struct i915_panic_data *panic = to_i915_panic_data(fb); + struct i915_panic_data *panic = fb->panic; if (fb->panic_tiling) offset = fb->panic_tiling(sb->width, x, y); @@ -446,9 +441,12 @@ struct intel_framebuffer *i915_gem_object_alloc_framebuffer(void) struct i915_framebuffer *i915_fb; i915_fb = kzalloc(sizeof(*i915_fb), GFP_KERNEL); - if (i915_fb) - return &i915_fb->base; - return NULL; + if (!i915_fb) + return NULL; + + i915_fb->base.panic = &i915_fb->panic; + + return &i915_fb->base; } /* @@ -460,7 +458,7 @@ int i915_gem_object_panic_setup(struct drm_scanout_buffer *sb) { enum i915_map_type has_type; struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; - struct i915_panic_data *panic = to_i915_panic_data(fb); + struct i915_panic_data *panic = fb->panic; struct drm_i915_gem_object *obj = to_intel_bo(intel_fb_bo(&fb->base)); void *ptr; @@ -488,7 +486,7 @@ int i915_gem_object_panic_setup(struct drm_scanout_buffer *sb) void i915_gem_object_panic_finish(struct intel_framebuffer *fb) { - struct i915_panic_data *panic = to_i915_panic_data(fb); + struct i915_panic_data *panic = fb->panic; i915_panic_kunmap(panic); panic->page = -1; diff --git a/drivers/gpu/drm/xe/display/xe_panic.c b/drivers/gpu/drm/xe/display/xe_panic.c index 18b27a06b260..fc1804d330e4 100644 --- a/drivers/gpu/drm/xe/display/xe_panic.c +++ b/drivers/gpu/drm/xe/display/xe_panic.c @@ -20,11 +20,6 @@ struct xe_framebuffer { struct xe_panic_data panic; }; -static inline struct xe_panic_data *to_xe_panic_data(struct intel_framebuffer *fb) -{ - return &container_of_const(fb, struct xe_framebuffer, base)->panic; -} - static void xe_panic_kunmap(struct xe_panic_data *panic) { if (panic->vaddr) { @@ -43,7 +38,7 @@ static void xe_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int unsigned int y, u32 color) { struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; - struct xe_panic_data *panic = to_xe_panic_data(fb); + struct xe_panic_data *panic = fb->panic; struct xe_bo *bo = gem_to_xe_bo(intel_fb_bo(&fb->base)); unsigned int new_page; unsigned int offset; @@ -72,15 +67,18 @@ struct intel_framebuffer *intel_bo_alloc_framebuffer(void) struct xe_framebuffer *xe_fb; xe_fb = kzalloc(sizeof(*xe_fb), GFP_KERNEL); - if (xe_fb) - return &xe_fb->base; - return NULL; + if (!xe_fb) + return NULL; + + xe_fb->base.panic = &xe_fb->panic; + + return &xe_fb->base; } int intel_panic_setup(struct drm_scanout_buffer *sb) { struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; - struct xe_panic_data *panic = to_xe_panic_data(fb); + struct xe_panic_data *panic = fb->panic; panic->page = -1; sb->set_pixel = xe_panic_page_set_pixel; @@ -89,7 +87,7 @@ int intel_panic_setup(struct drm_scanout_buffer *sb) void intel_panic_finish(struct intel_framebuffer *fb) { - struct xe_panic_data *panic = to_xe_panic_data(fb); + struct xe_panic_data *panic = fb->panic; xe_panic_kunmap(panic); panic->page = -1; From fa48f6335af9b063303d9e9a036514bbdc774d5b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 2 Sep 2025 20:51:51 +0300 Subject: [PATCH 14/36] drm/{i915,xe}/panic: rename struct {i915,xe}_panic_data to struct intel_panic Prepare for better shared interfaces between panic implementations. The struct intel_panic remains an opaque data type, with unique implementations in i915 and xe. This allows us to change the panic data pointer from void * to struct intel_panic *, helping type safety. Cc: Jocelyn Falempe Cc: Maarten Lankhorst Signed-off-by: Jani Nikula Reviewed-by: Jocelyn Falempe Link: https://lore.kernel.org/r/884ffc80c8b5fef1b92956e644a4e559560cc2ba.1756835342.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 3 ++- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 12 ++++++------ drivers/gpu/drm/xe/display/xe_panic.c | 12 ++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 608fd69af657..358ab922d7a7 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -60,6 +60,7 @@ struct intel_ddi_buf_trans; struct intel_fbc; struct intel_global_objs_state; struct intel_hdcp_shim; +struct intel_panic; struct intel_tc_port; /* @@ -149,7 +150,7 @@ struct intel_framebuffer { unsigned int vtd_guard; unsigned int (*panic_tiling)(unsigned int x, unsigned int y, unsigned int width); - void *panic; + struct intel_panic *panic; }; enum intel_hotplug_state { diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index c54ed1b33e60..e36d60b785b1 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -357,7 +357,7 @@ static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj, return vaddr ?: ERR_PTR(-ENOMEM); } -struct i915_panic_data { +struct intel_panic { struct page **pages; int page; void *vaddr; @@ -365,10 +365,10 @@ struct i915_panic_data { struct i915_framebuffer { struct intel_framebuffer base; - struct i915_panic_data panic; + struct intel_panic panic; }; -static void i915_panic_kunmap(struct i915_panic_data *panic) +static void i915_panic_kunmap(struct intel_panic *panic) { if (panic->vaddr) { drm_clflush_virt_range(panic->vaddr, PAGE_SIZE); @@ -415,7 +415,7 @@ static void i915_gem_object_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int new_page; unsigned int offset; struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; - struct i915_panic_data *panic = fb->panic; + struct intel_panic *panic = fb->panic; if (fb->panic_tiling) offset = fb->panic_tiling(sb->width, x, y); @@ -458,7 +458,7 @@ int i915_gem_object_panic_setup(struct drm_scanout_buffer *sb) { enum i915_map_type has_type; struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; - struct i915_panic_data *panic = fb->panic; + struct intel_panic *panic = fb->panic; struct drm_i915_gem_object *obj = to_intel_bo(intel_fb_bo(&fb->base)); void *ptr; @@ -486,7 +486,7 @@ int i915_gem_object_panic_setup(struct drm_scanout_buffer *sb) void i915_gem_object_panic_finish(struct intel_framebuffer *fb) { - struct i915_panic_data *panic = fb->panic; + struct intel_panic *panic = fb->panic; i915_panic_kunmap(panic); panic->page = -1; diff --git a/drivers/gpu/drm/xe/display/xe_panic.c b/drivers/gpu/drm/xe/display/xe_panic.c index fc1804d330e4..3ef23a6795b3 100644 --- a/drivers/gpu/drm/xe/display/xe_panic.c +++ b/drivers/gpu/drm/xe/display/xe_panic.c @@ -9,7 +9,7 @@ #include "intel_panic.h" #include "xe_bo.h" -struct xe_panic_data { +struct intel_panic { struct page **pages; int page; void *vaddr; @@ -17,10 +17,10 @@ struct xe_panic_data { struct xe_framebuffer { struct intel_framebuffer base; - struct xe_panic_data panic; + struct intel_panic panic; }; -static void xe_panic_kunmap(struct xe_panic_data *panic) +static void xe_panic_kunmap(struct intel_panic *panic) { if (panic->vaddr) { drm_clflush_virt_range(panic->vaddr, PAGE_SIZE); @@ -38,7 +38,7 @@ static void xe_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int unsigned int y, u32 color) { struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; - struct xe_panic_data *panic = fb->panic; + struct intel_panic *panic = fb->panic; struct xe_bo *bo = gem_to_xe_bo(intel_fb_bo(&fb->base)); unsigned int new_page; unsigned int offset; @@ -78,7 +78,7 @@ struct intel_framebuffer *intel_bo_alloc_framebuffer(void) int intel_panic_setup(struct drm_scanout_buffer *sb) { struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; - struct xe_panic_data *panic = fb->panic; + struct intel_panic *panic = fb->panic; panic->page = -1; sb->set_pixel = xe_panic_page_set_pixel; @@ -87,7 +87,7 @@ int intel_panic_setup(struct drm_scanout_buffer *sb) void intel_panic_finish(struct intel_framebuffer *fb) { - struct xe_panic_data *panic = fb->panic; + struct intel_panic *panic = fb->panic; xe_panic_kunmap(panic); panic->page = -1; From 729c5f7ffa83391b44939efc26b7ea34a08aea74 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 2 Sep 2025 20:51:52 +0300 Subject: [PATCH 15/36] drm/{i915,xe}/panic: move framebuffer allocation where it belongs The struct intel_framebuffer allocation naturally belongs in intel_fb.c, not hidden inside panic implementation. Separate the panic allocation. Drop the unnecessary struct i915_framebuffer and struct xe_framebuffer types. Cc: Jocelyn Falempe Cc: Maarten Lankhorst Signed-off-by: Jani Nikula Reviewed-by: Jocelyn Falempe Link: https://lore.kernel.org/r/d29f63e0118d002fc8edd368caea7e8185418e17.1756835342.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_fb.c | 17 ++++++++++++++++- drivers/gpu/drm/i915/display/intel_panic.c | 4 ++-- drivers/gpu/drm/i915/display/intel_panic.h | 3 ++- drivers/gpu/drm/i915/gem/i915_gem_object.h | 5 +++-- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 17 ++++------------- drivers/gpu/drm/xe/display/xe_panic.c | 17 ++++------------- 6 files changed, 31 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 4b415dfb5a66..c55855729628 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -2343,7 +2343,22 @@ intel_user_framebuffer_create(struct drm_device *dev, struct intel_framebuffer *intel_framebuffer_alloc(void) { - return intel_bo_alloc_framebuffer(); + struct intel_framebuffer *intel_fb; + struct intel_panic *panic; + + intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); + if (!intel_fb) + return NULL; + + panic = intel_panic_alloc(); + if (!panic) { + kfree(intel_fb); + return NULL; + } + + intel_fb->panic = panic; + + return intel_fb; } struct drm_framebuffer * diff --git a/drivers/gpu/drm/i915/display/intel_panic.c b/drivers/gpu/drm/i915/display/intel_panic.c index 20eecb0f168f..5431bd4d3a7d 100644 --- a/drivers/gpu/drm/i915/display/intel_panic.c +++ b/drivers/gpu/drm/i915/display/intel_panic.c @@ -4,9 +4,9 @@ #include "gem/i915_gem_object.h" #include "intel_panic.h" -struct intel_framebuffer *intel_bo_alloc_framebuffer(void) +struct intel_panic *intel_panic_alloc(void) { - return i915_gem_object_alloc_framebuffer(); + return i915_gem_object_alloc_panic(); } int intel_panic_setup(struct drm_scanout_buffer *sb) diff --git a/drivers/gpu/drm/i915/display/intel_panic.h b/drivers/gpu/drm/i915/display/intel_panic.h index 67ce253fcdf5..45ce6104e6fb 100644 --- a/drivers/gpu/drm/i915/display/intel_panic.h +++ b/drivers/gpu/drm/i915/display/intel_panic.h @@ -6,8 +6,9 @@ struct drm_scanout_buffer; struct intel_framebuffer; +struct intel_panic; -struct intel_framebuffer *intel_bo_alloc_framebuffer(void); +struct intel_panic *intel_panic_alloc(void); int intel_panic_setup(struct drm_scanout_buffer *sb); void intel_panic_finish(struct intel_framebuffer *fb); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 565f8fa330db..9b3f25cb48db 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -16,9 +16,10 @@ #include "i915_gem_ww.h" #include "i915_vma_types.h" -struct drm_scanout_buffer; enum intel_region_id; +struct drm_scanout_buffer; struct intel_framebuffer; +struct intel_panic; #define obj_to_i915(obj__) to_i915((obj__)->base.dev) @@ -693,7 +694,7 @@ i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj) int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj); int i915_gem_object_truncate(struct drm_i915_gem_object *obj); -struct intel_framebuffer *i915_gem_object_alloc_framebuffer(void); +struct intel_panic *i915_gem_object_alloc_panic(void); int i915_gem_object_panic_setup(struct drm_scanout_buffer *sb); void i915_gem_object_panic_finish(struct intel_framebuffer *fb); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index e36d60b785b1..b219474aecc7 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -363,11 +363,6 @@ struct intel_panic { void *vaddr; }; -struct i915_framebuffer { - struct intel_framebuffer base; - struct intel_panic panic; -}; - static void i915_panic_kunmap(struct intel_panic *panic) { if (panic->vaddr) { @@ -436,17 +431,13 @@ static void i915_gem_object_panic_page_set_pixel(struct drm_scanout_buffer *sb, } } -struct intel_framebuffer *i915_gem_object_alloc_framebuffer(void) +struct intel_panic *i915_gem_object_alloc_panic(void) { - struct i915_framebuffer *i915_fb; + struct intel_panic *panic; - i915_fb = kzalloc(sizeof(*i915_fb), GFP_KERNEL); - if (!i915_fb) - return NULL; + panic = kzalloc(sizeof(*panic), GFP_KERNEL); - i915_fb->base.panic = &i915_fb->panic; - - return &i915_fb->base; + return panic; } /* diff --git a/drivers/gpu/drm/xe/display/xe_panic.c b/drivers/gpu/drm/xe/display/xe_panic.c index 3ef23a6795b3..b5a7615708a1 100644 --- a/drivers/gpu/drm/xe/display/xe_panic.c +++ b/drivers/gpu/drm/xe/display/xe_panic.c @@ -15,11 +15,6 @@ struct intel_panic { void *vaddr; }; -struct xe_framebuffer { - struct intel_framebuffer base; - struct intel_panic panic; -}; - static void xe_panic_kunmap(struct intel_panic *panic) { if (panic->vaddr) { @@ -62,17 +57,13 @@ static void xe_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int } } -struct intel_framebuffer *intel_bo_alloc_framebuffer(void) +struct intel_panic *intel_panic_alloc(void) { - struct xe_framebuffer *xe_fb; + struct intel_panic *panic; - xe_fb = kzalloc(sizeof(*xe_fb), GFP_KERNEL); - if (!xe_fb) - return NULL; + panic = kzalloc(sizeof(*panic), GFP_KERNEL); - xe_fb->base.panic = &xe_fb->panic; - - return &xe_fb->base; + return panic; } int intel_panic_setup(struct drm_scanout_buffer *sb) From 427a3f939aa3d0c77beb34b469d17244f775b14b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 2 Sep 2025 20:51:53 +0300 Subject: [PATCH 16/36] drm/{i915,xe}/panic: convert intel_panic_finish() to struct intel_panic The intel_panic_finish() function really needs the struct intel_panic pointer, not struct intel_framebuffer. Make it so. Cc: Jocelyn Falempe Cc: Maarten Lankhorst Signed-off-by: Jani Nikula Reviewed-by: Jocelyn Falempe Link: https://lore.kernel.org/r/3fdbcbe17e0e90c4a590f2a2486a9ec79a90cf62.1756835342.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_panic.c | 4 ++-- drivers/gpu/drm/i915/display/intel_panic.h | 3 +-- drivers/gpu/drm/i915/display/intel_plane.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_object.h | 3 +-- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 4 +--- drivers/gpu/drm/xe/display/xe_panic.c | 4 +--- 6 files changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_panic.c b/drivers/gpu/drm/i915/display/intel_panic.c index 5431bd4d3a7d..c8ac8b5a39f3 100644 --- a/drivers/gpu/drm/i915/display/intel_panic.c +++ b/drivers/gpu/drm/i915/display/intel_panic.c @@ -14,7 +14,7 @@ int intel_panic_setup(struct drm_scanout_buffer *sb) return i915_gem_object_panic_setup(sb); } -void intel_panic_finish(struct intel_framebuffer *fb) +void intel_panic_finish(struct intel_panic *panic) { - return i915_gem_object_panic_finish(fb); + return i915_gem_object_panic_finish(panic); } diff --git a/drivers/gpu/drm/i915/display/intel_panic.h b/drivers/gpu/drm/i915/display/intel_panic.h index 45ce6104e6fb..cec193e725a4 100644 --- a/drivers/gpu/drm/i915/display/intel_panic.h +++ b/drivers/gpu/drm/i915/display/intel_panic.h @@ -5,11 +5,10 @@ #define __INTEL_PANIC_H__ struct drm_scanout_buffer; -struct intel_framebuffer; struct intel_panic; struct intel_panic *intel_panic_alloc(void); int intel_panic_setup(struct drm_scanout_buffer *sb); -void intel_panic_finish(struct intel_framebuffer *fb); +void intel_panic_finish(struct intel_panic *panic); #endif /* __INTEL_PANIC_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c index 890d897bda10..6a3f4a7b6dfd 100644 --- a/drivers/gpu/drm/i915/display/intel_plane.c +++ b/drivers/gpu/drm/i915/display/intel_plane.c @@ -1326,7 +1326,7 @@ static void intel_panic_flush(struct drm_plane *plane) struct drm_framebuffer *fb = plane_state->hw.fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - intel_panic_finish(intel_fb); + intel_panic_finish(intel_fb->panic); if (crtc_state->enable_psr2_sel_fetch) { /* Force a full update for psr2 */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 9b3f25cb48db..08da7ec670fe 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -18,7 +18,6 @@ enum intel_region_id; struct drm_scanout_buffer; -struct intel_framebuffer; struct intel_panic; #define obj_to_i915(obj__) to_i915((obj__)->base.dev) @@ -696,7 +695,7 @@ int i915_gem_object_truncate(struct drm_i915_gem_object *obj); struct intel_panic *i915_gem_object_alloc_panic(void); int i915_gem_object_panic_setup(struct drm_scanout_buffer *sb); -void i915_gem_object_panic_finish(struct intel_framebuffer *fb); +void i915_gem_object_panic_finish(struct intel_panic *panic); /** * i915_gem_object_pin_map - return a contiguous mapping of the entire object diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index b219474aecc7..3505b1842c40 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -475,10 +475,8 @@ int i915_gem_object_panic_setup(struct drm_scanout_buffer *sb) return -EOPNOTSUPP; } -void i915_gem_object_panic_finish(struct intel_framebuffer *fb) +void i915_gem_object_panic_finish(struct intel_panic *panic) { - struct intel_panic *panic = fb->panic; - i915_panic_kunmap(panic); panic->page = -1; kfree(panic->pages); diff --git a/drivers/gpu/drm/xe/display/xe_panic.c b/drivers/gpu/drm/xe/display/xe_panic.c index b5a7615708a1..ea9583473ea3 100644 --- a/drivers/gpu/drm/xe/display/xe_panic.c +++ b/drivers/gpu/drm/xe/display/xe_panic.c @@ -76,10 +76,8 @@ int intel_panic_setup(struct drm_scanout_buffer *sb) return 0; } -void intel_panic_finish(struct intel_framebuffer *fb) +void intel_panic_finish(struct intel_panic *panic) { - struct intel_panic *panic = fb->panic; - xe_panic_kunmap(panic); panic->page = -1; } From 0b470321e931432157820ab417f54ec4deb50ffa Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 2 Sep 2025 20:51:54 +0300 Subject: [PATCH 17/36] drm/{i915,xe}/panic: pass struct intel_panic to intel_panic_setup() Reduce the struct intel_framebuffer usage within the panic implementation. Cc: Jocelyn Falempe Cc: Maarten Lankhorst Signed-off-by: Jani Nikula Reviewed-by: Jocelyn Falempe Link: https://lore.kernel.org/r/2a016167b1f6f0b432aed0a630f9dbcd07fadb7b.1756835342.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_panic.c | 11 +++++++++-- drivers/gpu/drm/i915/display/intel_panic.h | 2 +- drivers/gpu/drm/i915/display/intel_plane.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_object.h | 3 ++- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 9 ++++----- drivers/gpu/drm/xe/display/xe_panic.c | 5 +---- 6 files changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_panic.c b/drivers/gpu/drm/i915/display/intel_panic.c index c8ac8b5a39f3..7311ce4e8b6c 100644 --- a/drivers/gpu/drm/i915/display/intel_panic.c +++ b/drivers/gpu/drm/i915/display/intel_panic.c @@ -1,7 +1,11 @@ // SPDX-License-Identifier: MIT /* Copyright © 2025 Intel Corporation */ +#include + #include "gem/i915_gem_object.h" +#include "intel_display_types.h" +#include "intel_fb.h" #include "intel_panic.h" struct intel_panic *intel_panic_alloc(void) @@ -9,9 +13,12 @@ struct intel_panic *intel_panic_alloc(void) return i915_gem_object_alloc_panic(); } -int intel_panic_setup(struct drm_scanout_buffer *sb) +int intel_panic_setup(struct intel_panic *panic, struct drm_scanout_buffer *sb) { - return i915_gem_object_panic_setup(sb); + struct intel_framebuffer *fb = sb->private; + struct drm_gem_object *obj = intel_fb_bo(&fb->base); + + return i915_gem_object_panic_setup(panic, sb, obj, fb->panic_tiling); } void intel_panic_finish(struct intel_panic *panic) diff --git a/drivers/gpu/drm/i915/display/intel_panic.h b/drivers/gpu/drm/i915/display/intel_panic.h index cec193e725a4..afb472e924aa 100644 --- a/drivers/gpu/drm/i915/display/intel_panic.h +++ b/drivers/gpu/drm/i915/display/intel_panic.h @@ -8,7 +8,7 @@ struct drm_scanout_buffer; struct intel_panic; struct intel_panic *intel_panic_alloc(void); -int intel_panic_setup(struct drm_scanout_buffer *sb); +int intel_panic_setup(struct intel_panic *panic, struct drm_scanout_buffer *sb); void intel_panic_finish(struct intel_panic *panic); #endif /* __INTEL_PANIC_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c index 6a3f4a7b6dfd..2329f09d413d 100644 --- a/drivers/gpu/drm/i915/display/intel_plane.c +++ b/drivers/gpu/drm/i915/display/intel_plane.c @@ -1409,7 +1409,7 @@ static int intel_get_scanout_buffer(struct drm_plane *plane, return -EOPNOTSUPP; } sb->private = intel_fb; - ret = intel_panic_setup(sb); + ret = intel_panic_setup(intel_fb->panic, sb); if (ret) return ret; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 08da7ec670fe..148034ef504d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -694,7 +694,8 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj); int i915_gem_object_truncate(struct drm_i915_gem_object *obj); struct intel_panic *i915_gem_object_alloc_panic(void); -int i915_gem_object_panic_setup(struct drm_scanout_buffer *sb); +int i915_gem_object_panic_setup(struct intel_panic *panic, struct drm_scanout_buffer *sb, + struct drm_gem_object *_obj, bool panic_tiling); void i915_gem_object_panic_finish(struct intel_panic *panic); /** diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index 3505b1842c40..76d2178572b6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -445,12 +445,11 @@ struct intel_panic *i915_gem_object_alloc_panic(void) * Use current vaddr if it exists, or setup a list of pages. * pfn is not supported yet. */ -int i915_gem_object_panic_setup(struct drm_scanout_buffer *sb) +int i915_gem_object_panic_setup(struct intel_panic *panic, struct drm_scanout_buffer *sb, + struct drm_gem_object *_obj, bool panic_tiling) { enum i915_map_type has_type; - struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; - struct intel_panic *panic = fb->panic; - struct drm_i915_gem_object *obj = to_intel_bo(intel_fb_bo(&fb->base)); + struct drm_i915_gem_object *obj = to_intel_bo(_obj); void *ptr; ptr = page_unpack_bits(obj->mm.mapping, &has_type); @@ -460,7 +459,7 @@ int i915_gem_object_panic_setup(struct drm_scanout_buffer *sb) else iosys_map_set_vaddr(&sb->map[0], ptr); - if (fb->panic_tiling) + if (panic_tiling) sb->set_pixel = i915_gem_object_panic_map_set_pixel; return 0; } diff --git a/drivers/gpu/drm/xe/display/xe_panic.c b/drivers/gpu/drm/xe/display/xe_panic.c index ea9583473ea3..f32b23338331 100644 --- a/drivers/gpu/drm/xe/display/xe_panic.c +++ b/drivers/gpu/drm/xe/display/xe_panic.c @@ -66,11 +66,8 @@ struct intel_panic *intel_panic_alloc(void) return panic; } -int intel_panic_setup(struct drm_scanout_buffer *sb) +int intel_panic_setup(struct intel_panic *panic, struct drm_scanout_buffer *sb) { - struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; - struct intel_panic *panic = fb->panic; - panic->page = -1; sb->set_pixel = xe_panic_page_set_pixel; return 0; From 1e4c85167cf672312a178b2af0b058add77e448b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 29 Aug 2025 20:45:59 +0300 Subject: [PATCH 18/36] drm/i915: rename range_overflows_end() to range_end_overflows() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename range_overflows_end() to range_end_overflows(), along with the _t variant. It's all rather subjective, but I think range_end_overflows() reads better. Cc: Kees Cook Cc: "Gustavo A. R. Silva" Cc: linux-hardening@vger.kernel.org Reviewed-by: Jouni Högander Link: https://lore.kernel.org/r/20250829174601.2163064-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_fbc.c | 4 ++-- drivers/gpu/drm/i915/gt/intel_rc6.c | 2 +- drivers/gpu/drm/i915/i915_utils.h | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 9e097ed80bd1..06c35c7ab4e2 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -383,11 +383,11 @@ static void i8xx_fbc_program_cfb(struct intel_fbc *fbc) struct drm_i915_private *i915 = to_i915(display->drm); drm_WARN_ON(display->drm, - range_overflows_end_t(u64, i915_gem_stolen_area_address(i915), + range_end_overflows_t(u64, i915_gem_stolen_area_address(i915), i915_gem_stolen_node_offset(&fbc->compressed_fb), U32_MAX)); drm_WARN_ON(display->drm, - range_overflows_end_t(u64, i915_gem_stolen_area_address(i915), + range_end_overflows_t(u64, i915_gem_stolen_area_address(i915), i915_gem_stolen_node_offset(&fbc->compressed_llb), U32_MAX)); intel_de_write(display, FBC_CFB_BASE, diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c index 9ca42589da4d..bf38cc5fe872 100644 --- a/drivers/gpu/drm/i915/gt/intel_rc6.c +++ b/drivers/gpu/drm/i915/gt/intel_rc6.c @@ -341,7 +341,7 @@ static int vlv_rc6_init(struct intel_rc6 *rc6) return PTR_ERR(pctx); } - GEM_BUG_ON(range_overflows_end_t(u64, + GEM_BUG_ON(range_end_overflows_t(u64, i915->dsm.stolen.start, pctx->stolen->start, U32_MAX)); diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index 9cb40c2c4b12..fdac9a158b53 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -79,7 +79,7 @@ bool i915_error_injected(void); #define range_overflows_t(type, start, size, max) \ range_overflows((type)(start), (type)(size), (type)(max)) -#define range_overflows_end(start, size, max) ({ \ +#define range_end_overflows(start, size, max) ({ \ typeof(start) start__ = (start); \ typeof(size) size__ = (size); \ typeof(max) max__ = (max); \ @@ -88,8 +88,8 @@ bool i915_error_injected(void); start__ > max__ || size__ > max__ - start__; \ }) -#define range_overflows_end_t(type, start, size, max) \ - range_overflows_end((type)(start), (type)(size), (type)(max)) +#define range_end_overflows_t(type, start, size, max) \ + range_end_overflows((type)(start), (type)(size), (type)(max)) #define ptr_mask_bits(ptr, n) ({ \ unsigned long __v = (unsigned long)(ptr); \ From 59bf37add1d2223d699d1855354277b7330765e4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 29 Aug 2025 20:46:00 +0300 Subject: [PATCH 19/36] drm/i915: document range_overflows() and range_end_overflows() macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the macros in preparation for making them more generally available. Cc: Kees Cook Cc: "Gustavo A. R. Silva" Cc: linux-hardening@vger.kernel.org Reviewed-by: Jouni Högander Link: https://lore.kernel.org/r/20250829174601.2163064-2-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_utils.h | 46 +++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index fdac9a158b53..968dae941532 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -67,6 +67,18 @@ bool i915_error_injected(void); drm_err(&(i915)->drm, fmt, ##__VA_ARGS__); \ }) +/** + * range_overflows() - Check if a range is out of bounds + * @start: Start of the range. + * @size: Size of the range. + * @max: Exclusive upper boundary. + * + * A strict check to determine if the range [@start, @start + @size) is + * invalid with respect to the allowable range [0, @max). Any range + * starting at or beyond @max is considered an overflow, even if @size is 0. + * + * Returns: true if the range is out of bounds. + */ #define range_overflows(start, size, max) ({ \ typeof(start) start__ = (start); \ typeof(size) size__ = (size); \ @@ -76,9 +88,32 @@ bool i915_error_injected(void); start__ >= max__ || size__ > max__ - start__; \ }) +/** + * range_overflows_t() - Check if a range is out of bounds + * @type: Data type to use. + * @start: Start of the range. + * @size: Size of the range. + * @max: Exclusive upper boundary. + * + * Same as range_overflows() but forcing the parameters to @type. + * + * Returns: true if the range is out of bounds. + */ #define range_overflows_t(type, start, size, max) \ range_overflows((type)(start), (type)(size), (type)(max)) +/** + * range_end_overflows() - Check if a range's endpoint is out of bounds + * @start: Start of the range. + * @size: Size of the range. + * @max: Exclusive upper boundary. + * + * Checks only if the endpoint of a range (@start + @size) exceeds @max. + * Unlike range_overflows(), a zero-sized range at the boundary (@start == @max) + * is not considered an overflow. Useful for iterator-style checks. + * + * Returns: true if the endpoint exceeds the boundary. + */ #define range_end_overflows(start, size, max) ({ \ typeof(start) start__ = (start); \ typeof(size) size__ = (size); \ @@ -88,6 +123,17 @@ bool i915_error_injected(void); start__ > max__ || size__ > max__ - start__; \ }) +/** + * range_end_overflows_t() - Check if a range's endpoint is out of bounds + * @type: Data type to use. + * @start: Start of the range. + * @size: Size of the range. + * @max: Exclusive upper boundary. + * + * Same as range_end_overflows() but forcing the parameters to @type. + * + * Returns: true if the endpoint exceeds the boundary. + */ #define range_end_overflows_t(type, start, size, max) \ range_end_overflows((type)(start), (type)(size), (type)(max)) From 5f3cec21f6d57336a2cbfa9ee428ac66c77a7211 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 29 Aug 2025 20:46:01 +0300 Subject: [PATCH 20/36] overflow: add range_overflows() and range_end_overflows() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the range_overflows() and range_end_overflows() along with the _t variants over from drm/i915 and drm/buddy to overflow.h. Cc: Kees Cook Cc: "Gustavo A. R. Silva" Cc: linux-hardening@vger.kernel.org Reviewed-by: Kees Cook Reviewed-by: Jouni Högander Acked-by: Thomas Zimmermann Link: https://lore.kernel.org/r/20250829174601.2163064-3-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_utils.h | 70 ------------------------------- include/drm/drm_buddy.h | 9 ---- include/linux/overflow.h | 70 +++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 79 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index 968dae941532..eb4d43c40009 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -67,76 +67,6 @@ bool i915_error_injected(void); drm_err(&(i915)->drm, fmt, ##__VA_ARGS__); \ }) -/** - * range_overflows() - Check if a range is out of bounds - * @start: Start of the range. - * @size: Size of the range. - * @max: Exclusive upper boundary. - * - * A strict check to determine if the range [@start, @start + @size) is - * invalid with respect to the allowable range [0, @max). Any range - * starting at or beyond @max is considered an overflow, even if @size is 0. - * - * Returns: true if the range is out of bounds. - */ -#define range_overflows(start, size, max) ({ \ - typeof(start) start__ = (start); \ - typeof(size) size__ = (size); \ - typeof(max) max__ = (max); \ - (void)(&start__ == &size__); \ - (void)(&start__ == &max__); \ - start__ >= max__ || size__ > max__ - start__; \ -}) - -/** - * range_overflows_t() - Check if a range is out of bounds - * @type: Data type to use. - * @start: Start of the range. - * @size: Size of the range. - * @max: Exclusive upper boundary. - * - * Same as range_overflows() but forcing the parameters to @type. - * - * Returns: true if the range is out of bounds. - */ -#define range_overflows_t(type, start, size, max) \ - range_overflows((type)(start), (type)(size), (type)(max)) - -/** - * range_end_overflows() - Check if a range's endpoint is out of bounds - * @start: Start of the range. - * @size: Size of the range. - * @max: Exclusive upper boundary. - * - * Checks only if the endpoint of a range (@start + @size) exceeds @max. - * Unlike range_overflows(), a zero-sized range at the boundary (@start == @max) - * is not considered an overflow. Useful for iterator-style checks. - * - * Returns: true if the endpoint exceeds the boundary. - */ -#define range_end_overflows(start, size, max) ({ \ - typeof(start) start__ = (start); \ - typeof(size) size__ = (size); \ - typeof(max) max__ = (max); \ - (void)(&start__ == &size__); \ - (void)(&start__ == &max__); \ - start__ > max__ || size__ > max__ - start__; \ -}) - -/** - * range_end_overflows_t() - Check if a range's endpoint is out of bounds - * @type: Data type to use. - * @start: Start of the range. - * @size: Size of the range. - * @max: Exclusive upper boundary. - * - * Same as range_end_overflows() but forcing the parameters to @type. - * - * Returns: true if the endpoint exceeds the boundary. - */ -#define range_end_overflows_t(type, start, size, max) \ - range_end_overflows((type)(start), (type)(size), (type)(max)) - #define ptr_mask_bits(ptr, n) ({ \ unsigned long __v = (unsigned long)(ptr); \ (typeof(ptr))(__v & -BIT(n)); \ diff --git a/include/drm/drm_buddy.h b/include/drm/drm_buddy.h index 9689a7c5dd36..236971681514 100644 --- a/include/drm/drm_buddy.h +++ b/include/drm/drm_buddy.h @@ -13,15 +13,6 @@ #include -#define range_overflows(start, size, max) ({ \ - typeof(start) start__ = (start); \ - typeof(size) size__ = (size); \ - typeof(max) max__ = (max); \ - (void)(&start__ == &size__); \ - (void)(&start__ == &max__); \ - start__ >= max__ || size__ > max__ - start__; \ -}) - #define DRM_BUDDY_RANGE_ALLOCATION BIT(0) #define DRM_BUDDY_TOPDOWN_ALLOCATION BIT(1) #define DRM_BUDDY_CONTIGUOUS_ALLOCATION BIT(2) diff --git a/include/linux/overflow.h b/include/linux/overflow.h index 154ed0dbb43f..725f95f7e416 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -238,6 +238,76 @@ static inline bool __must_check __must_check_overflow(bool overflow) __overflows_type_constexpr(n, T), \ __overflows_type(n, T)) +/** + * range_overflows() - Check if a range is out of bounds + * @start: Start of the range. + * @size: Size of the range. + * @max: Exclusive upper boundary. + * + * A strict check to determine if the range [@start, @start + @size) is + * invalid with respect to the allowable range [0, @max). Any range + * starting at or beyond @max is considered an overflow, even if @size is 0. + * + * Returns: true if the range is out of bounds. + */ +#define range_overflows(start, size, max) ({ \ + typeof(start) start__ = (start); \ + typeof(size) size__ = (size); \ + typeof(max) max__ = (max); \ + (void)(&start__ == &size__); \ + (void)(&start__ == &max__); \ + start__ >= max__ || size__ > max__ - start__; \ +}) + +/** + * range_overflows_t() - Check if a range is out of bounds + * @type: Data type to use. + * @start: Start of the range. + * @size: Size of the range. + * @max: Exclusive upper boundary. + * + * Same as range_overflows() but forcing the parameters to @type. + * + * Returns: true if the range is out of bounds. + */ +#define range_overflows_t(type, start, size, max) \ + range_overflows((type)(start), (type)(size), (type)(max)) + +/** + * range_end_overflows() - Check if a range's endpoint is out of bounds + * @start: Start of the range. + * @size: Size of the range. + * @max: Exclusive upper boundary. + * + * Checks only if the endpoint of a range (@start + @size) exceeds @max. + * Unlike range_overflows(), a zero-sized range at the boundary (@start == @max) + * is not considered an overflow. Useful for iterator-style checks. + * + * Returns: true if the endpoint exceeds the boundary. + */ +#define range_end_overflows(start, size, max) ({ \ + typeof(start) start__ = (start); \ + typeof(size) size__ = (size); \ + typeof(max) max__ = (max); \ + (void)(&start__ == &size__); \ + (void)(&start__ == &max__); \ + start__ > max__ || size__ > max__ - start__; \ +}) + +/** + * range_end_overflows_t() - Check if a range's endpoint is out of bounds + * @type: Data type to use. + * @start: Start of the range. + * @size: Size of the range. + * @max: Exclusive upper boundary. + * + * Same as range_end_overflows() but forcing the parameters to @type. + * + * Returns: true if the endpoint exceeds the boundary. + */ +#define range_end_overflows_t(type, start, size, max) \ + range_end_overflows((type)(start), (type)(size), (type)(max)) + /** * castable_to_type - like __same_type(), but also allows for casted literals * From 854c0dc80e25a408ecf7cf27661c28b8c10c291e Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 4 Sep 2025 10:18:04 +0530 Subject: [PATCH 21/36] drm/i915/backlight: Disable backlight when using luminance control We just return when using luminance control instead we should be calling the disable helper to get everything cleaned up properly by default. Signed-off-by: Suraj Kandpal Reviewed-by: Arun R Murthy Link: https://lore.kernel.org/r/20250904044804.948391-1-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index f665d845c809..0cf49219c44d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -550,9 +550,6 @@ static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state struct intel_panel *panel = &connector->panel; struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); - if (panel->backlight.edp.vesa.luminance_control_support) - return; - drm_edp_backlight_disable(&intel_dp->aux, &panel->backlight.edp.vesa.info); if (!panel->backlight.edp.vesa.info.aux_enable) From f985e105ced10304abd3b2d822994b87c88145f8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 3 Sep 2025 12:04:08 +0300 Subject: [PATCH 22/36] drm/i915/display: add intel_display_device_present() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a proper function for display && HAS_DISPLAY(display) to hide indirect struct intel_display access via the macro from a number of places outside of display. This makes struct intel_display * an opaque pointer in these places. All HAS_DISPLAY() usage is now constrained within display. Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/20250903090408.3492875-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_device.c | 5 +++ .../drm/i915/display/intel_display_device.h | 1 + .../i915/gem/selftests/i915_gem_client_blt.c | 4 +-- drivers/gpu/drm/i915/i915_driver.c | 18 +++++----- drivers/gpu/drm/i915/i915_switcheroo.c | 7 ++-- drivers/gpu/drm/i915/soc/intel_dram.c | 2 +- drivers/gpu/drm/xe/display/xe_display.c | 33 ++++++++----------- 7 files changed, 36 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 65f0efc35bb7..a002bc6ce7b0 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -1944,6 +1944,11 @@ void intel_display_device_info_print(const struct intel_display_device_info *inf drm_printf(p, "rawclk rate: %u kHz\n", runtime->rawclk_freq); } +bool intel_display_device_present(struct intel_display *display) +{ + return display && HAS_DISPLAY(display); +} + /* * Assuming the device has display hardware, should it be enabled? * diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index 6e87b763fe7c..f329f1beafef 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -306,6 +306,7 @@ struct intel_display_device_info { } color; }; +bool intel_display_device_present(struct intel_display *display); bool intel_display_device_enabled(struct intel_display *display); struct intel_display *intel_display_device_probe(struct pci_dev *pdev); void intel_display_device_remove(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c index e747f5ed195e..539c620364e3 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c @@ -5,7 +5,7 @@ #include "i915_selftest.h" -#include "display/intel_display_core.h" +#include "display/intel_display_device.h" #include "gt/intel_context.h" #include "gt/intel_engine_regs.h" #include "gt/intel_engine_user.h" @@ -122,7 +122,7 @@ static bool fastblit_supports_x_tiling(const struct drm_i915_private *i915) if (GRAPHICS_VER_FULL(i915) < IP_VER(12, 55)) return false; - return HAS_DISPLAY(display); + return intel_display_device_present(display); } static bool fast_blit_ok(const struct blit_buffer *buf) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 70f042ce8705..a28c3710c4d5 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -51,13 +51,15 @@ #include "display/intel_bw.h" #include "display/intel_cdclk.h" #include "display/intel_crtc.h" -#include "display/intel_display_core.h" +#include "display/intel_display_device.h" #include "display/intel_display_driver.h" +#include "display/intel_display_power.h" #include "display/intel_dmc.h" #include "display/intel_dp.h" #include "display/intel_dpt.h" #include "display/intel_encoder.h" #include "display/intel_fbdev.h" +#include "display/intel_gmbus.h" #include "display/intel_hotplug.h" #include "display/intel_opregion.h" #include "display/intel_overlay.h" @@ -977,7 +979,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915) intel_power_domains_disable(display); drm_client_dev_suspend(&i915->drm, false); - if (HAS_DISPLAY(display)) { + if (intel_display_device_present(display)) { drm_kms_helper_poll_disable(&i915->drm); intel_display_driver_disable_user_access(display); @@ -989,7 +991,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915) intel_irq_suspend(i915); intel_hpd_cancel_work(display); - if (HAS_DISPLAY(display)) + if (intel_display_device_present(display)) intel_display_driver_suspend_access(display); intel_encoder_suspend_all(display); @@ -1060,7 +1062,7 @@ static int i915_drm_suspend(struct drm_device *dev) * properly. */ intel_power_domains_disable(display); drm_client_dev_suspend(dev, false); - if (HAS_DISPLAY(display)) { + if (intel_display_device_present(display)) { drm_kms_helper_poll_disable(dev); intel_display_driver_disable_user_access(display); } @@ -1072,7 +1074,7 @@ static int i915_drm_suspend(struct drm_device *dev) intel_irq_suspend(dev_priv); intel_hpd_cancel_work(display); - if (HAS_DISPLAY(display)) + if (intel_display_device_present(display)) intel_display_driver_suspend_access(display); intel_encoder_suspend_all(display); @@ -1219,7 +1221,7 @@ static int i915_drm_resume(struct drm_device *dev) */ intel_irq_resume(dev_priv); - if (HAS_DISPLAY(display)) + if (intel_display_device_present(display)) drm_mode_config_reset(dev); i915_gem_resume(dev_priv); @@ -1228,14 +1230,14 @@ static int i915_drm_resume(struct drm_device *dev) intel_clock_gating_init(dev_priv); - if (HAS_DISPLAY(display)) + if (intel_display_device_present(display)) intel_display_driver_resume_access(display); intel_hpd_init(display); intel_display_driver_resume(display); - if (HAS_DISPLAY(display)) { + if (intel_display_device_present(display)) { intel_display_driver_enable_user_access(display); drm_kms_helper_poll_enable(dev); } diff --git a/drivers/gpu/drm/i915/i915_switcheroo.c b/drivers/gpu/drm/i915/i915_switcheroo.c index 3a95a55b2e87..d5b6d8ab31a2 100644 --- a/drivers/gpu/drm/i915/i915_switcheroo.c +++ b/drivers/gpu/drm/i915/i915_switcheroo.c @@ -5,7 +5,7 @@ #include -#include "display/intel_display_core.h" +#include "display/intel_display_device.h" #include "i915_driver.h" #include "i915_drv.h" @@ -22,7 +22,7 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, dev_err(&pdev->dev, "DRM not initialized, aborting switch.\n"); return; } - if (!HAS_DISPLAY(display)) { + if (!intel_display_device_present(display)) { dev_err(&pdev->dev, "Device state not initialized, aborting switch.\n"); return; } @@ -52,7 +52,8 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) * locking inversion with the driver load path. And the access here is * completely racy anyway. So don't bother with locking for now. */ - return i915 && HAS_DISPLAY(display) && atomic_read(&i915->drm.open_count) == 0; + return i915 && intel_display_device_present(display) && + atomic_read(&i915->drm.open_count) == 0; } static const struct vga_switcheroo_client_ops i915_switcheroo_ops = { diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c index 149527827624..edffaed8f9a7 100644 --- a/drivers/gpu/drm/i915/soc/intel_dram.c +++ b/drivers/gpu/drm/i915/soc/intel_dram.c @@ -732,7 +732,7 @@ int intel_dram_detect(struct drm_i915_private *i915) struct dram_info *dram_info; int ret; - if (IS_DG2(i915) || !HAS_DISPLAY(display)) + if (IS_DG2(i915) || !intel_display_device_present(display)) return 0; dram_info = drmm_kzalloc(&i915->drm, sizeof(*dram_info), GFP_KERNEL); diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 8b68d70db6c8..19e691fccf8c 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -20,7 +20,7 @@ #include "intel_audio.h" #include "intel_bw.h" #include "intel_display.h" -#include "intel_display_core.h" +#include "intel_display_device.h" #include "intel_display_driver.h" #include "intel_display_irq.h" #include "intel_display_types.h" @@ -37,13 +37,6 @@ /* Xe device functions */ -static bool has_display(struct xe_device *xe) -{ - struct intel_display *display = xe->display; - - return HAS_DISPLAY(display); -} - /** * xe_display_driver_probe_defer - Detect if we need to wait for other drivers * early on @@ -290,7 +283,7 @@ static void xe_display_enable_d3cold(struct xe_device *xe) intel_dmc_suspend(display); - if (has_display(xe)) + if (intel_display_device_present(display)) intel_hpd_poll_enable(display); } @@ -303,14 +296,14 @@ static void xe_display_disable_d3cold(struct xe_device *xe) intel_dmc_resume(display); - if (has_display(xe)) + if (intel_display_device_present(display)) drm_mode_config_reset(&xe->drm); intel_display_driver_init_hw(display); intel_hpd_init(display); - if (has_display(xe)) + if (intel_display_device_present(display)) intel_hpd_poll_disable(display); intel_opregion_resume(display); @@ -333,7 +326,7 @@ void xe_display_pm_suspend(struct xe_device *xe) intel_power_domains_disable(display); drm_client_dev_suspend(&xe->drm, false); - if (has_display(xe)) { + if (intel_display_device_present(display)) { drm_kms_helper_poll_disable(&xe->drm); intel_display_driver_disable_user_access(display); intel_display_driver_suspend(display); @@ -345,7 +338,7 @@ void xe_display_pm_suspend(struct xe_device *xe) intel_hpd_cancel_work(display); - if (has_display(xe)) { + if (intel_display_device_present(display)) { intel_display_driver_suspend_access(display); intel_encoder_suspend_all(display); } @@ -365,7 +358,7 @@ void xe_display_pm_shutdown(struct xe_device *xe) intel_power_domains_disable(display); drm_client_dev_suspend(&xe->drm, false); - if (has_display(xe)) { + if (intel_display_device_present(display)) { drm_kms_helper_poll_disable(&xe->drm); intel_display_driver_disable_user_access(display); intel_display_driver_suspend(display); @@ -376,7 +369,7 @@ void xe_display_pm_shutdown(struct xe_device *xe) intel_encoder_block_all_hpds(display); intel_hpd_cancel_work(display); - if (has_display(xe)) + if (intel_display_device_present(display)) intel_display_driver_suspend_access(display); intel_encoder_suspend_all(display); @@ -465,25 +458,25 @@ void xe_display_pm_resume(struct xe_device *xe) intel_dmc_resume(display); - if (has_display(xe)) + if (intel_display_device_present(display)) drm_mode_config_reset(&xe->drm); intel_display_driver_init_hw(display); - if (has_display(xe)) + if (intel_display_device_present(display)) intel_display_driver_resume_access(display); intel_hpd_init(display); intel_encoder_unblock_all_hpds(display); - if (has_display(xe)) { + if (intel_display_device_present(display)) { intel_display_driver_resume(display); drm_kms_helper_poll_enable(&xe->drm); intel_display_driver_enable_user_access(display); } - if (has_display(xe)) + if (intel_display_device_present(display)) intel_hpd_poll_disable(display); intel_opregion_resume(display); @@ -548,7 +541,7 @@ int xe_display_probe(struct xe_device *xe) xe->display = display; - if (has_display(xe)) + if (intel_display_device_present(display)) return 0; no_display: From 86a9fe82e9b1f43e6d2bc867bf96bb40660d8719 Mon Sep 17 00:00:00 2001 From: Luiz Otavio Mello Date: Mon, 8 Sep 2025 09:15:09 -0400 Subject: [PATCH 23/36] drm/i915: Move struct_mutex to drm_i915_private Move legacy BKL struct_mutex from drm_device to drm_i915_private, which is the last remaining user. Signed-off-by: Luiz Otavio Mello Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/20250908131518.36625-2-luiz.mello@estudante.ufscar.br Acked-by: Thomas Zimmermann Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/drm_drv.c | 2 -- drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 4 ++-- drivers/gpu/drm/i915/i915_driver.c | 2 ++ drivers/gpu/drm/i915/i915_drv.h | 11 +++++++++++ drivers/gpu/drm/i915/i915_irq.c | 4 ++-- include/drm/drm_device.h | 10 ---------- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 02556363e918..287cf4a09101 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -697,7 +697,6 @@ static void drm_dev_init_release(struct drm_device *dev, void *res) mutex_destroy(&dev->master_mutex); mutex_destroy(&dev->clientlist_mutex); mutex_destroy(&dev->filelist_mutex); - mutex_destroy(&dev->struct_mutex); } static int drm_dev_init(struct drm_device *dev, @@ -738,7 +737,6 @@ static int drm_dev_init(struct drm_device *dev, INIT_LIST_HEAD(&dev->vblank_event_list); spin_lock_init(&dev->event_lock); - mutex_init(&dev->struct_mutex); mutex_init(&dev->filelist_mutex); mutex_init(&dev->clientlist_mutex); mutex_init(&dev->master_mutex); diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c index e8a04e476c57..7135fdb0ebb4 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c @@ -678,7 +678,7 @@ int intel_guc_log_set_level(struct intel_guc_log *log, u32 level) if (level < GUC_LOG_LEVEL_DISABLED || level > GUC_LOG_LEVEL_MAX) return -EINVAL; - mutex_lock(&i915->drm.struct_mutex); + mutex_lock(&i915->struct_mutex); if (log->level == level) goto out_unlock; @@ -696,7 +696,7 @@ int intel_guc_log_set_level(struct intel_guc_log *log, u32 level) log->level = level; out_unlock: - mutex_unlock(&i915->drm.struct_mutex); + mutex_unlock(&i915->struct_mutex); return ret; } diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index a28c3710c4d5..2677c39a3246 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -235,6 +235,7 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv) intel_sbi_init(display); vlv_iosf_sb_init(dev_priv); + mutex_init(&dev_priv->struct_mutex); mutex_init(&dev_priv->sb_lock); i915_memcpy_init_early(dev_priv); @@ -293,6 +294,7 @@ static void i915_driver_late_release(struct drm_i915_private *dev_priv) i915_workqueues_cleanup(dev_priv); mutex_destroy(&dev_priv->sb_lock); + mutex_destroy(&dev_priv->struct_mutex); vlv_iosf_sb_fini(dev_priv); intel_sbi_fini(display); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f76d138df0af..55f13cb2c395 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -224,6 +224,17 @@ struct drm_i915_private { bool irqs_enabled; + /* + * Currently, struct_mutex is only used by the i915 driver as a replacement + * for BKL. + * + * For this reason, it is no longer part of struct drm_device. + */ + struct mutex struct_mutex; + + /* LPT/WPT IOSF sideband protection */ + struct mutex sbi_lock; + /* VLV/CHV IOSF sideband */ struct { struct mutex lock; /* protect sideband access */ diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a5fa40ab5de2..5916a648efbb 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -167,7 +167,7 @@ static void ivb_parity_work(struct work_struct *work) * In order to prevent a get/put style interface, acquire struct mutex * any time we access those registers. */ - mutex_lock(&dev_priv->drm.struct_mutex); + mutex_lock(&dev_priv->struct_mutex); /* If we've screwed up tracking, just let the interrupt fire again */ if (drm_WARN_ON(&dev_priv->drm, !dev_priv->l3_parity.which_slice)) @@ -225,7 +225,7 @@ static void ivb_parity_work(struct work_struct *work) gen5_gt_enable_irq(gt, GT_PARITY_ERROR(dev_priv)); spin_unlock_irq(gt->irq_lock); - mutex_unlock(&dev_priv->drm.struct_mutex); + mutex_unlock(&dev_priv->struct_mutex); } static irqreturn_t valleyview_irq_handler(int irq, void *arg) diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index 08b3b2467c4c..cb16fd47e075 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -186,16 +186,6 @@ struct drm_device { /** @unique: Unique name of the device */ char *unique; - /** - * @struct_mutex: - * - * Lock for others (not &drm_minor.master and &drm_file.is_master) - * - * TODO: This lock used to be the BKL of the DRM subsystem. Move the - * lock into i915, which is the only remaining user. - */ - struct mutex struct_mutex; - /** * @master_mutex: * From 793d31671bdf583c876ac9fa9948bb231c689036 Mon Sep 17 00:00:00 2001 From: Luiz Otavio Mello Date: Mon, 8 Sep 2025 09:15:10 -0400 Subject: [PATCH 24/36] drm/i915: Remove struct_mutex in i915_irq.c Remove struct_mutex from ivb_parity_work() function. The ivb_parity_work runs in a workqueue so it cannot race with itself. Also, it is not protecting anything with the other remaining usage of struct_mutex. Signed-off-by: Luiz Otavio Mello Suggested-by: Rodrigo Vivi Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/20250908131518.36625-3-luiz.mello@estudante.ufscar.br Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_irq.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5916a648efbb..8d5da222a187 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -163,11 +163,6 @@ static void ivb_parity_work(struct work_struct *work) u32 misccpctl; u8 slice = 0; - /* We must turn off DOP level clock gating to access the L3 registers. - * In order to prevent a get/put style interface, acquire struct mutex - * any time we access those registers. - */ - mutex_lock(&dev_priv->struct_mutex); /* If we've screwed up tracking, just let the interrupt fire again */ if (drm_WARN_ON(&dev_priv->drm, !dev_priv->l3_parity.which_slice)) @@ -225,7 +220,6 @@ static void ivb_parity_work(struct work_struct *work) gen5_gt_enable_irq(gt, GT_PARITY_ERROR(dev_priv)); spin_unlock_irq(gt->irq_lock); - mutex_unlock(&dev_priv->struct_mutex); } static irqreturn_t valleyview_irq_handler(int irq, void *arg) From 1bafff0252e3e46286f558ba67d63bc16e8685cd Mon Sep 17 00:00:00 2001 From: Luiz Otavio Mello Date: Mon, 8 Sep 2025 09:15:11 -0400 Subject: [PATCH 25/36] drm/i915: Change mutex initialization in intel_guc_log The intel_guc_log->relay.lock is currently initialized in intel_guc_log_init_early(), but it lacks a corresponding destructor, which can lead to a memory leak. This patch replaces the use of mutex_init() with drmm_mutex_init(), which ensures the lock is properly destroyed when the driver is unloaded. Signed-off-by: Luiz Otavio Mello Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/20250908131518.36625-4-luiz.mello@estudante.ufscar.br Acked-by: Tvrtko Ursulin Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c index 7135fdb0ebb4..469173791394 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c @@ -6,6 +6,8 @@ #include #include +#include + #include "gt/intel_gt.h" #include "i915_drv.h" #include "i915_irq.h" @@ -512,7 +514,10 @@ static void guc_log_relay_unmap(struct intel_guc_log *log) void intel_guc_log_init_early(struct intel_guc_log *log) { - mutex_init(&log->relay.lock); + struct intel_guc *guc = log_to_guc(log); + struct drm_i915_private *i915 = guc_to_i915(guc); + + drmm_mutex_init(&i915->drm, &log->relay.lock); INIT_WORK(&log->relay.flush_work, copy_debug_logs_work); log->relay.started = false; } From 1bd3db82e9f39c45ce035ac07e7acd9a4cd2e1d3 Mon Sep 17 00:00:00 2001 From: Luiz Otavio Mello Date: Mon, 8 Sep 2025 09:15:12 -0400 Subject: [PATCH 26/36] drm/i915: Replace struct_mutex in intel_guc_log MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the use of struct_mutex from intel_guc_log.c and replace it with a dedicated lock, guc_lock, defined within the intel_guc_log struct.      The struct_mutex was previously used to protect concurrent access and modification of intel_guc_log->level in intel_guc_log_set_level(). However, it was suggested that the lock should reside within the intel_guc_log struct itself.      Initialize the new guc_lock in intel_guc_log_init_early(), alongside the existing relay.lock. The lock is initialized using drmm_mutex_init(), which also ensures it is properly destroyed when the driver is unloaded. Signed-off-by: Luiz Otavio Mello Suggested-by: Rodrigo Vivi Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/20250908131518.36625-5-luiz.mello@estudante.ufscar.br Acked-by: Tvrtko Ursulin Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 5 +++-- drivers/gpu/drm/i915/gt/uc/intel_guc_log.h | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c index 469173791394..0104fffd5852 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c @@ -518,6 +518,7 @@ void intel_guc_log_init_early(struct intel_guc_log *log) struct drm_i915_private *i915 = guc_to_i915(guc); drmm_mutex_init(&i915->drm, &log->relay.lock); + drmm_mutex_init(&i915->drm, &log->guc_lock); INIT_WORK(&log->relay.flush_work, copy_debug_logs_work); log->relay.started = false; } @@ -683,7 +684,7 @@ int intel_guc_log_set_level(struct intel_guc_log *log, u32 level) if (level < GUC_LOG_LEVEL_DISABLED || level > GUC_LOG_LEVEL_MAX) return -EINVAL; - mutex_lock(&i915->struct_mutex); + mutex_lock(&log->guc_lock); if (log->level == level) goto out_unlock; @@ -701,7 +702,7 @@ int intel_guc_log_set_level(struct intel_guc_log *log, u32 level) log->level = level; out_unlock: - mutex_unlock(&i915->struct_mutex); + mutex_unlock(&log->guc_lock); return ret; } diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h index 02127703be80..13cb93ad0710 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h @@ -42,6 +42,14 @@ enum { struct intel_guc_log { u32 level; + /* + * Protects concurrent access and modification of intel_guc_log->level. + * + * This lock replaces the legacy struct_mutex usage in + * intel_guc_log system. + */ + struct mutex guc_lock; + /* Allocation settings */ struct { s32 bytes; /* Size in bytes */ From 24af523936b81a479d65ff835e27e1a22afa0bf8 Mon Sep 17 00:00:00 2001 From: Luiz Otavio Mello Date: Mon, 8 Sep 2025 09:15:13 -0400 Subject: [PATCH 27/36] drm/i915/gem: Clean-up outdated struct_mutex comments The struct_mutex will be removed from the DRM subsystem, as it was a legacy BKL that was only used by i915 driver. After review, it was concluded that its usage was no longer necessary This patch updates various comments in the i915/gem and i915/gt codebase to either remove or clarify references to struct_mutex, in order to prevent future misunderstandings. * i915_gem_execbuffer.c: Replace reference to struct_mutex with vm->mutex, as noted in the eb_reserve() function, which states that vm->mutex handles deadlocks. * i915_gem_object.c: Change struct_mutex by drm_i915_gem_object->vma.lock. i915_gem_object_unbind() in i915_gem.c states that this lock is who actually protects the unbind. * i915_gem_shrinker.c: The correct lock is actually i915->mm.obj, as already documented in its declaration. * i915_gem_wait.c: The existing comment already mentioned that struct_mutex was no longer necessary. Updated to refer to a generic global lock instead. * intel_reset_types.h: Cleaned up the comment text. Updated to refer to a generic global lock instead. Signed-off-by: Luiz Otavio Mello Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/20250908131518.36625-6-luiz.mello@estudante.ufscar.br Acked-by: Tvrtko Ursulin Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_object.c | 4 ++-- drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 4 ++-- drivers/gpu/drm/i915/gem/i915_gem_wait.c | 8 ++++---- drivers/gpu/drm/i915/gt/intel_reset_types.h | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index ca7e9216934a..07500fd5b82d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -182,7 +182,7 @@ enum { * the object. Simple! ... The relocation entries are stored in user memory * and so to access them we have to copy them into a local buffer. That copy * has to avoid taking any pagefaults as they may lead back to a GEM object - * requiring the struct_mutex (i.e. recursive deadlock). So once again we split + * requiring the vm->mutex (i.e. recursive deadlock). So once again we split * the relocation into multiple passes. First we try to do everything within an * atomic context (avoid the pagefaults) which requires that we never wait. If * we detect that we may wait, or if we need to fault, then we have to fallback diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index 1f38e367c60b..478011e5ecb3 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -459,8 +459,8 @@ static void i915_gem_free_object(struct drm_gem_object *gem_obj) atomic_inc(&i915->mm.free_count); /* - * Since we require blocking on struct_mutex to unbind the freed - * object from the GPU before releasing resources back to the + * Since we require blocking on drm_i915_gem_object->vma.lock to unbind + * the freed object from the GPU before releasing resources back to the * system, we can not do that directly from the RCU callback (which may * be a softirq context), but must instead then defer that work onto a * kthread. We use the RCU callback rather than move the freed object diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c index b81e67504bbe..7a3e74a6676e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c @@ -170,7 +170,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww, * Also note that although these lists do not hold a reference to * the object we can safely grab one here: The final object * unreferencing and the bound_list are both protected by the - * dev->struct_mutex and so we won't ever be able to observe an + * i915->mm.obj_lock and so we won't ever be able to observe an * object on the bound_list with a reference count equals 0. */ for (phase = phases; phase->list; phase++) { @@ -185,7 +185,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww, /* * We serialize our access to unreferenced objects through - * the use of the struct_mutex. While the objects are not + * the use of the obj_lock. While the objects are not * yet freed (due to RCU then a workqueue) we still want * to be able to shrink their pages, so they remain on * the unbound/bound list until actually freed. diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c index 7127e90c1a8f..04a18580e7d4 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c @@ -222,10 +222,10 @@ static unsigned long to_wait_timeout(s64 timeout_ns) * * The wait ioctl with a timeout of 0 reimplements the busy ioctl. With any * non-zero timeout parameter the wait ioctl will wait for the given number of - * nanoseconds on an object becoming unbusy. Since the wait itself does so - * without holding struct_mutex the object may become re-busied before this - * function completes. A similar but shorter * race condition exists in the busy - * ioctl + * nanoseconds on an object becoming unbusy. Since the wait occurs without + * holding a global or exclusive lock the object may become re-busied before + * this function completes. A similar but shorter * race condition exists + * in the busy ioctl */ int i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) diff --git a/drivers/gpu/drm/i915/gt/intel_reset_types.h b/drivers/gpu/drm/i915/gt/intel_reset_types.h index 4f5fd393af6f..ee4eb574a219 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset_types.h +++ b/drivers/gpu/drm/i915/gt/intel_reset_types.h @@ -20,7 +20,7 @@ struct intel_reset { * FENCE registers). * * #I915_RESET_ENGINE[num_engines] - Since the driver doesn't need to - * acquire the struct_mutex to reset an engine, we need an explicit + * acquire a global lock to reset an engine, we need an explicit * flag to prevent two concurrent reset attempts in the same engine. * As the number of engines continues to grow, allocate the flags from * the most significant bits. From 5be4fa95ec5ce3039a622517d10327639da29e44 Mon Sep 17 00:00:00 2001 From: Luiz Otavio Mello Date: Mon, 8 Sep 2025 09:15:14 -0400 Subject: [PATCH 28/36] drm/i915/display: Remove outdated struct_mutex comments The struct_mutex will be removed from the DRM subsystem, as it was a legacy BKL that was only used by i915 driver. After review, it was concluded that its usage was no longer necessary This patch update a comment about struct_mutex in i915/display, in order to prevent future misunderstandings. * intel_fbc.c: Removed the statement that intel_fbc->lock is the inner lock when overlapping with struct_mutex, since struct_mutex is no longer used anywhere in the driver. Signed-off-by: Luiz Otavio Mello Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/20250908131518.36625-7-luiz.mello@estudante.ufscar.br Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_fbc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 06c35c7ab4e2..0d380c825791 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -98,11 +98,7 @@ struct intel_fbc { struct intel_display *display; const struct intel_fbc_funcs *funcs; - /* - * This is always the inner lock when overlapping with - * struct_mutex and it's the outer lock when overlapping - * with stolen_lock. - */ + /* This is always the outer lock when overlapping with stolen_lock */ struct mutex lock; unsigned int busy_bits; From 9e6651659b8a8686ca16fcefa7739600b047d8c5 Mon Sep 17 00:00:00 2001 From: Luiz Otavio Mello Date: Mon, 8 Sep 2025 09:15:15 -0400 Subject: [PATCH 29/36] drm/i915: Clean-up outdated struct_mutex comments The struct_mutex will be removed from the DRM subsystem, as it was a legacy BKL that was only used by i915 driver. After review, it was concluded that its usage was no longer necessary This patch updates various comments in the i915 codebase to either remove or clarify references to struct_mutex, in order to prevent future misunderstandings. * i915_drv.h: Removed the statement that stolen_lock is the inner lock when overlaps with struct_mutex, since struct_mutex is no longer used in the driver. * i915_gem.c: Removed parentheses suggesting usage of struct_mutex, which which is no longer used. Signed-off-by: Luiz Otavio Mello Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/20250908131518.36625-8-luiz.mello@estudante.ufscar.br Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_drv.h | 3 +-- drivers/gpu/drm/i915/i915_gem.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 55f13cb2c395..50fdecb79b49 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -116,8 +116,7 @@ struct i915_gem_mm { struct intel_memory_region *stolen_region; /** Memory allocator for GTT stolen memory */ struct drm_mm stolen; - /** Protects the usage of the GTT stolen memory allocator. This is - * always the inner lock when overlapping with struct_mutex. */ + /** Protects the usage of the GTT stolen memory allocator */ struct mutex stolen_lock; /* Protects bound_list/unbound_list and #drm_i915_gem_object.mm.link */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8c8d43451f35..e14a0c3db999 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -847,8 +847,7 @@ void i915_gem_runtime_suspend(struct drm_i915_private *i915) /* * Only called during RPM suspend. All users of the userfault_list * must be holding an RPM wakeref to ensure that this can not - * run concurrently with themselves (and use the struct_mutex for - * protection between themselves). + * run concurrently with themselves. */ list_for_each_entry_safe(obj, on, From 34ac58ded89dd81fc2f776b19c44bcc48fe9764d Mon Sep 17 00:00:00 2001 From: Luiz Otavio Mello Date: Mon, 8 Sep 2025 09:15:16 -0400 Subject: [PATCH 30/36] drm/i915: Drop unused struct_mutex from drm_i915_private The struct_mutex field in drm_i915_private is no longer used anywhere in the driver. This patch removes it completely to clean up unused code and avoid confusion. Signed-off-by: Luiz Otavio Mello Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/20250908131518.36625-9-luiz.mello@estudante.ufscar.br Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_driver.c | 2 -- drivers/gpu/drm/i915/i915_drv.h | 8 -------- 2 files changed, 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 2677c39a3246..a28c3710c4d5 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -235,7 +235,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv) intel_sbi_init(display); vlv_iosf_sb_init(dev_priv); - mutex_init(&dev_priv->struct_mutex); mutex_init(&dev_priv->sb_lock); i915_memcpy_init_early(dev_priv); @@ -294,7 +293,6 @@ static void i915_driver_late_release(struct drm_i915_private *dev_priv) i915_workqueues_cleanup(dev_priv); mutex_destroy(&dev_priv->sb_lock); - mutex_destroy(&dev_priv->struct_mutex); vlv_iosf_sb_fini(dev_priv); intel_sbi_fini(display); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 50fdecb79b49..7de68ebc2beb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -223,14 +223,6 @@ struct drm_i915_private { bool irqs_enabled; - /* - * Currently, struct_mutex is only used by the i915 driver as a replacement - * for BKL. - * - * For this reason, it is no longer part of struct drm_device. - */ - struct mutex struct_mutex; - /* LPT/WPT IOSF sideband protection */ struct mutex sbi_lock; From b69f8c496ea05f80c2bae91a74b48c00c06c524e Mon Sep 17 00:00:00 2001 From: Luiz Otavio Mello Date: Mon, 8 Sep 2025 09:15:17 -0400 Subject: [PATCH 31/36] drm/i915: Remove todo and comments about struct_mutex This patch completes the removal of struct_mutex from the driver. Remove the related TODO item, as the transition away from struct_mutex is now complete. Also clean up references to struct_mutex in i915.rst to avoid outdated documentation. Signed-off-by: Luiz Otavio Mello Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/20250908131518.36625-10-luiz.mello@estudante.ufscar.br Acked-by: Thomas Zimmermann Signed-off-by: Rodrigo Vivi --- Documentation/gpu/i915.rst | 7 ------- Documentation/gpu/todo.rst | 25 ------------------------- 2 files changed, 32 deletions(-) diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst index 72932fa31b8d..eba09c3ddce4 100644 --- a/Documentation/gpu/i915.rst +++ b/Documentation/gpu/i915.rst @@ -358,8 +358,6 @@ Locking Guidelines #. All locking rules and interface contracts with cross-driver interfaces (dma-buf, dma_fence) need to be followed. -#. No struct_mutex anywhere in the code - #. dma_resv will be the outermost lock (when needed) and ww_acquire_ctx is to be hoisted at highest level and passed down within i915_gem_ctx in the call chain @@ -367,11 +365,6 @@ Locking Guidelines #. While holding lru/memory manager (buddy, drm_mm, whatever) locks system memory allocations are not allowed - * Enforce this by priming lockdep (with fs_reclaim). If we - allocate memory while holding these looks we get a rehash - of the shrinker vs. struct_mutex saga, and that would be - real bad. - #. Do not nest different lru/memory manager locks within each other. Take them in turn to update memory allocations, relying on the object’s dma_resv ww_mutex to serialize against other operations. diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index be8637da3fe9..c796331d9acc 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -173,31 +173,6 @@ Contact: Simona Vetter Level: Intermediate -Get rid of dev->struct_mutex from GEM drivers ---------------------------------------------- - -``dev->struct_mutex`` is the Big DRM Lock from legacy days and infested -everything. Nowadays in modern drivers the only bit where it's mandatory is -serializing GEM buffer object destruction. Which unfortunately means drivers -have to keep track of that lock and either call ``unreference`` or -``unreference_locked`` depending upon context. - -Core GEM doesn't have a need for ``struct_mutex`` any more since kernel 4.8, -and there's a GEM object ``free`` callback for any drivers which are -entirely ``struct_mutex`` free. - -For drivers that need ``struct_mutex`` it should be replaced with a driver- -private lock. The tricky part is the BO free functions, since those can't -reliably take that lock any more. Instead state needs to be protected with -suitable subordinate locks or some cleanup work pushed to a worker thread. For -performance-critical drivers it might also be better to go with a more -fine-grained per-buffer object and per-context lockings scheme. Currently only -the ``msm`` and `i915` drivers use ``struct_mutex``. - -Contact: Simona Vetter, respective driver maintainers - -Level: Advanced - Move Buffer Object Locking to dma_resv_lock() --------------------------------------------- From 72136efb875d8438c20b9c8ab72945d474933471 Mon Sep 17 00:00:00 2001 From: Aaron Ma Date: Sat, 23 Aug 2025 20:16:47 +0800 Subject: [PATCH 32/36] drm/i915/backlight: Honor VESA eDP backlight luminance control capability The VESA AUX backlight fails to be enable luminance based backlight mainpulation becaused luminance_set is false by default. Fix it by using luminance support control capabitliy. Fixes: e13af5166a359 ("drm/i915/backlight: Use drm helper to initialize edp backlight") Signed-off-by: Aaron Ma Reviewed-by: Suraj Kandpal Signed-off-by: Suraj Kandpal Link: https://lore.kernel.org/r/20250823121647.275834-1-aaron.ma@canonical.com --- drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index 0dc45db56b82..eb05ef4bd9f6 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -530,7 +530,7 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, luminance_range->max_luminance, panel->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd, ¤t_level, ¤t_mode, - false); + panel->backlight.edp.vesa.luminance_control_support); if (ret < 0) return ret; From a394f12a4d6d6ec3c72d62107282c6022cd96333 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 11 Sep 2025 12:17:37 +0300 Subject: [PATCH 33/36] drm/i915: split out i915_ptr_util.h Move pointer related utilities from i915_utils.h to a separate new i915_ptr_util.h header. Clean up related includes. Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/3cd06aa2483e68f19401292e9d4c28bf2977fce5.1757582214.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gt/intel_context_types.h | 1 - drivers/gpu/drm/i915/gt/intel_timeline.h | 1 + drivers/gpu/drm/i915/i915_ptr_util.h | 66 +++++++++++++++++++ drivers/gpu/drm/i915/i915_request.h | 5 +- drivers/gpu/drm/i915/i915_utils.h | 57 ---------------- drivers/gpu/drm/i915/i915_vma.h | 6 +- 6 files changed, 73 insertions(+), 63 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_ptr_util.h diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index 98c7f6052069..10070ee4d74c 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -14,7 +14,6 @@ #include "i915_active_types.h" #include "i915_sw_fence.h" -#include "i915_utils.h" #include "intel_engine_types.h" #include "intel_sseu.h" #include "intel_wakeref.h" diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.h b/drivers/gpu/drm/i915/gt/intel_timeline.h index 57308c4d664a..5f8c8f79714e 100644 --- a/drivers/gpu/drm/i915/gt/intel_timeline.h +++ b/drivers/gpu/drm/i915/gt/intel_timeline.h @@ -10,6 +10,7 @@ #include "i915_active.h" #include "i915_syncmap.h" +#include "i915_utils.h" #include "intel_timeline_types.h" struct drm_printer; diff --git a/drivers/gpu/drm/i915/i915_ptr_util.h b/drivers/gpu/drm/i915/i915_ptr_util.h new file mode 100644 index 000000000000..9f8931d7d99b --- /dev/null +++ b/drivers/gpu/drm/i915/i915_ptr_util.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __I915_PTR_UTIL_H__ +#define __I915_PTR_UTIL_H__ + +#include + +#define ptr_mask_bits(ptr, n) ({ \ + unsigned long __v = (unsigned long)(ptr); \ + (typeof(ptr))(__v & -BIT(n)); \ +}) + +#define ptr_unmask_bits(ptr, n) ((unsigned long)(ptr) & (BIT(n) - 1)) + +#define ptr_unpack_bits(ptr, bits, n) ({ \ + unsigned long __v = (unsigned long)(ptr); \ + *(bits) = __v & (BIT(n) - 1); \ + (typeof(ptr))(__v & -BIT(n)); \ +}) + +#define ptr_pack_bits(ptr, bits, n) ({ \ + unsigned long __bits = (bits); \ + GEM_BUG_ON(__bits & -BIT(n)); \ + ((typeof(ptr))((unsigned long)(ptr) | __bits)); \ +}) + +#define ptr_dec(ptr) ({ \ + unsigned long __v = (unsigned long)(ptr); \ + (typeof(ptr))(__v - 1); \ +}) + +#define ptr_inc(ptr) ({ \ + unsigned long __v = (unsigned long)(ptr); \ + (typeof(ptr))(__v + 1); \ +}) + +#define page_mask_bits(ptr) ptr_mask_bits(ptr, PAGE_SHIFT) +#define page_unmask_bits(ptr) ptr_unmask_bits(ptr, PAGE_SHIFT) +#define page_pack_bits(ptr, bits) ptr_pack_bits(ptr, bits, PAGE_SHIFT) +#define page_unpack_bits(ptr, bits) ptr_unpack_bits(ptr, bits, PAGE_SHIFT) + +static __always_inline ptrdiff_t ptrdiff(const void *a, const void *b) +{ + return a - b; +} + +#define u64_to_ptr(T, x) ({ \ + typecheck(u64, x); \ + (T *)(uintptr_t)(x); \ +}) + +/* + * container_of_user: Extract the superclass from a pointer to a member. + * + * Exactly like container_of() with the exception that it plays nicely + * with sparse for __user @ptr. + */ +#define container_of_user(ptr, type, member) ({ \ + void __user *__mptr = (void __user *)(ptr); \ + BUILD_BUG_ON_MSG(!__same_type(*(ptr), typeof_member(type, member)) && \ + !__same_type(*(ptr), void), \ + "pointer type mismatch in container_of()"); \ + ((type __user *)(__mptr - offsetof(type, member))); }) + +#endif /* __I915_PTR_UTIL_H__ */ diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index 5f7e8138ec14..b09135301f39 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -31,19 +31,20 @@ #include #include +#include + #include "gem/i915_gem_context_types.h" #include "gt/intel_context_types.h" #include "gt/intel_engine_types.h" #include "gt/intel_timeline_types.h" #include "i915_gem.h" +#include "i915_ptr_util.h" #include "i915_scheduler.h" #include "i915_selftest.h" #include "i915_sw_fence.h" #include "i915_vma_resource.h" -#include - struct drm_file; struct drm_i915_gem_object; struct drm_printer; diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index eb4d43c40009..dff02a944a57 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -67,64 +67,12 @@ bool i915_error_injected(void); drm_err(&(i915)->drm, fmt, ##__VA_ARGS__); \ }) -#define ptr_mask_bits(ptr, n) ({ \ - unsigned long __v = (unsigned long)(ptr); \ - (typeof(ptr))(__v & -BIT(n)); \ -}) - -#define ptr_unmask_bits(ptr, n) ((unsigned long)(ptr) & (BIT(n) - 1)) - -#define ptr_unpack_bits(ptr, bits, n) ({ \ - unsigned long __v = (unsigned long)(ptr); \ - *(bits) = __v & (BIT(n) - 1); \ - (typeof(ptr))(__v & -BIT(n)); \ -}) - -#define ptr_pack_bits(ptr, bits, n) ({ \ - unsigned long __bits = (bits); \ - GEM_BUG_ON(__bits & -BIT(n)); \ - ((typeof(ptr))((unsigned long)(ptr) | __bits)); \ -}) - -#define ptr_dec(ptr) ({ \ - unsigned long __v = (unsigned long)(ptr); \ - (typeof(ptr))(__v - 1); \ -}) - -#define ptr_inc(ptr) ({ \ - unsigned long __v = (unsigned long)(ptr); \ - (typeof(ptr))(__v + 1); \ -}) - -#define page_mask_bits(ptr) ptr_mask_bits(ptr, PAGE_SHIFT) -#define page_unmask_bits(ptr) ptr_unmask_bits(ptr, PAGE_SHIFT) -#define page_pack_bits(ptr, bits) ptr_pack_bits(ptr, bits, PAGE_SHIFT) -#define page_unpack_bits(ptr, bits) ptr_unpack_bits(ptr, bits, PAGE_SHIFT) - #define fetch_and_zero(ptr) ({ \ typeof(*ptr) __T = *(ptr); \ *(ptr) = (typeof(*ptr))0; \ __T; \ }) -static __always_inline ptrdiff_t ptrdiff(const void *a, const void *b) -{ - return a - b; -} - -/* - * container_of_user: Extract the superclass from a pointer to a member. - * - * Exactly like container_of() with the exception that it plays nicely - * with sparse for __user @ptr. - */ -#define container_of_user(ptr, type, member) ({ \ - void __user *__mptr = (void __user *)(ptr); \ - BUILD_BUG_ON_MSG(!__same_type(*(ptr), typeof_member(type, member)) && \ - !__same_type(*(ptr), void), \ - "pointer type mismatch in container_of()"); \ - ((type __user *)(__mptr - offsetof(type, member))); }) - /* * check_user_mbz: Check that a user value exists and is zero * @@ -143,11 +91,6 @@ static __always_inline ptrdiff_t ptrdiff(const void *a, const void *b) get_user(mbz__, (U)) ? -EFAULT : mbz__ ? -EINVAL : 0; \ }) -#define u64_to_ptr(T, x) ({ \ - typecheck(u64, x); \ - (T *)(uintptr_t)(x); \ -}) - #define __mask_next_bit(mask) ({ \ int __idx = ffs(mask) - 1; \ mask &= ~BIT(__idx); \ diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index 0f9eee6d18d2..8054047840aa 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -30,12 +30,12 @@ #include -#include "gt/intel_ggtt_fencing.h" #include "gem/i915_gem_object.h" - -#include "i915_gem_gtt.h" +#include "gt/intel_ggtt_fencing.h" #include "i915_active.h" +#include "i915_gem_gtt.h" +#include "i915_ptr_util.h" #include "i915_request.h" #include "i915_vma_resource.h" #include "i915_vma_types.h" From df7d085b585016fdda440719a58ee3ac73c5db7c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 11 Sep 2025 12:17:38 +0300 Subject: [PATCH 34/36] drm/i915: split out i915_timer_util.[ch] Move timer related utilities from i915_utils.[ch] to separate new files i915_timer_util.[ch]. Clean up related includes. Note: Arguably none of this should exist in i915 in the first place. At least isolate it better. Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/0a83d9489626121dcefcd4c1a05317399b5708f3.1757582214.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/Makefile | 1 + .../drm/i915/gt/intel_execlists_submission.c | 4 ++- drivers/gpu/drm/i915/gt/sysfs_engines.c | 1 + drivers/gpu/drm/i915/i915_timer_util.c | 36 +++++++++++++++++++ drivers/gpu/drm/i915/i915_timer_util.h | 23 ++++++++++++ drivers/gpu/drm/i915/i915_utils.c | 30 ---------------- drivers/gpu/drm/i915/i915_utils.h | 14 -------- 7 files changed, 64 insertions(+), 45 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_timer_util.c create mode 100644 drivers/gpu/drm/i915/i915_timer_util.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index db150a0c33ce..e58c0c158b3a 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -32,6 +32,7 @@ i915-y += \ i915_scatterlist.o \ i915_switcheroo.o \ i915_sysfs.o \ + i915_timer_util.o \ i915_utils.o \ intel_clock_gating.o \ intel_cpu_info.o \ diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c index 03baa7fa0a27..52c8fddedfce 100644 --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -106,14 +106,16 @@ * preemption, but just sampling the new tail pointer). * */ + #include #include +#include "gen8_engine_cs.h" #include "i915_drv.h" #include "i915_reg.h" +#include "i915_timer_util.h" #include "i915_trace.h" #include "i915_vgpu.h" -#include "gen8_engine_cs.h" #include "intel_breadcrumbs.h" #include "intel_context.h" #include "intel_engine_heartbeat.h" diff --git a/drivers/gpu/drm/i915/gt/sysfs_engines.c b/drivers/gpu/drm/i915/gt/sysfs_engines.c index aab2759067d2..4a81bc396b21 100644 --- a/drivers/gpu/drm/i915/gt/sysfs_engines.c +++ b/drivers/gpu/drm/i915/gt/sysfs_engines.c @@ -7,6 +7,7 @@ #include #include "i915_drv.h" +#include "i915_timer_util.h" #include "intel_engine.h" #include "intel_engine_heartbeat.h" #include "sysfs_engines.h" diff --git a/drivers/gpu/drm/i915/i915_timer_util.c b/drivers/gpu/drm/i915/i915_timer_util.c new file mode 100644 index 000000000000..ee4cfd8b3c07 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_timer_util.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2025 Intel Corporation */ + +#include + +#include "i915_timer_util.h" + +void cancel_timer(struct timer_list *t) +{ + if (!timer_active(t)) + return; + + timer_delete(t); + WRITE_ONCE(t->expires, 0); +} + +void set_timer_ms(struct timer_list *t, unsigned long timeout) +{ + if (!timeout) { + cancel_timer(t); + return; + } + + timeout = msecs_to_jiffies(timeout); + + /* + * Paranoia to make sure the compiler computes the timeout before + * loading 'jiffies' as jiffies is volatile and may be updated in + * the background by a timer tick. All to reduce the complexity + * of the addition and reduce the risk of losing a jiffy. + */ + barrier(); + + /* Keep t->expires = 0 reserved to indicate a canceled timer. */ + mod_timer(t, jiffies + timeout ?: 1); +} diff --git a/drivers/gpu/drm/i915/i915_timer_util.h b/drivers/gpu/drm/i915/i915_timer_util.h new file mode 100644 index 000000000000..f35ad730820c --- /dev/null +++ b/drivers/gpu/drm/i915/i915_timer_util.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __I915_TIMER_UTIL_H__ +#define __I915_TIMER_UTIL_H__ + +#include +#include + +void cancel_timer(struct timer_list *t); +void set_timer_ms(struct timer_list *t, unsigned long timeout); + +static inline bool timer_active(const struct timer_list *t) +{ + return READ_ONCE(t->expires); +} + +static inline bool timer_expired(const struct timer_list *t) +{ + return timer_active(t) && !timer_pending(t); +} + +#endif /* __I915_TIMER_UTIL_H__ */ diff --git a/drivers/gpu/drm/i915/i915_utils.c b/drivers/gpu/drm/i915/i915_utils.c index b60c28fbd207..49f7ed413132 100644 --- a/drivers/gpu/drm/i915/i915_utils.c +++ b/drivers/gpu/drm/i915/i915_utils.c @@ -47,36 +47,6 @@ bool i915_error_injected(void) #endif -void cancel_timer(struct timer_list *t) -{ - if (!timer_active(t)) - return; - - timer_delete(t); - WRITE_ONCE(t->expires, 0); -} - -void set_timer_ms(struct timer_list *t, unsigned long timeout) -{ - if (!timeout) { - cancel_timer(t); - return; - } - - timeout = msecs_to_jiffies(timeout); - - /* - * Paranoia to make sure the compiler computes the timeout before - * loading 'jiffies' as jiffies is volatile and may be updated in - * the background by a timer tick. All to reduce the complexity - * of the addition and reduce the risk of losing a jiffy. - */ - barrier(); - - /* Keep t->expires = 0 reserved to indicate a canceled timer. */ - mod_timer(t, jiffies + timeout ?: 1); -} - bool i915_vtd_active(struct drm_i915_private *i915) { if (device_iommu_mapped(i915->drm.dev)) diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index dff02a944a57..6278a74d08c2 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -38,7 +38,6 @@ #endif struct drm_i915_private; -struct timer_list; #define MISSING_CASE(x) WARN(1, "Missing case (%s == %ld)\n", \ __stringify(x), (long)(x)) @@ -270,19 +269,6 @@ static inline void __add_taint_for_CI(unsigned int taint) add_taint(taint, LOCKDEP_STILL_OK); } -void cancel_timer(struct timer_list *t); -void set_timer_ms(struct timer_list *t, unsigned long timeout); - -static inline bool timer_active(const struct timer_list *t) -{ - return READ_ONCE(t->expires); -} - -static inline bool timer_expired(const struct timer_list *t) -{ - return timer_active(t) && !timer_pending(t); -} - static inline bool i915_run_as_guest(void) { #if IS_ENABLED(CONFIG_X86) From 2f04432fcf0ad7b825d67ee283345e2721c83f5c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 11 Sep 2025 12:17:39 +0300 Subject: [PATCH 35/36] drm/i915: split out i915_list_util.h Move list related utilities from i915_utils.h to separate new file i915_list_util.h. Clean up related includes. Note: Arguably none of this should exist in i915 in the first place. At least isolate it better. Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/d7526809735194137116682f37cfa126a6a87ec9.1757582214.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/gt/intel_execlists_submission.c | 1 + .../gpu/drm/i915/gt/intel_gt_buffer_pool.c | 1 + drivers/gpu/drm/i915/gt/intel_timeline.h | 2 +- drivers/gpu/drm/i915/i915_list_util.h | 23 +++++++++++++++++++ drivers/gpu/drm/i915/i915_utils.h | 14 ----------- 5 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_list_util.h diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c index 52c8fddedfce..0c1b2df02d26 100644 --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -112,6 +112,7 @@ #include "gen8_engine_cs.h" #include "i915_drv.h" +#include "i915_list_util.h" #include "i915_reg.h" #include "i915_timer_util.h" #include "i915_trace.h" diff --git a/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c b/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c index 86b5a9ba323d..c7befc5c20d0 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c @@ -7,6 +7,7 @@ #include "gem/i915_gem_object.h" #include "i915_drv.h" +#include "i915_list_util.h" #include "intel_engine_pm.h" #include "intel_gt_buffer_pool.h" diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.h b/drivers/gpu/drm/i915/gt/intel_timeline.h index 5f8c8f79714e..85b43f9b9d95 100644 --- a/drivers/gpu/drm/i915/gt/intel_timeline.h +++ b/drivers/gpu/drm/i915/gt/intel_timeline.h @@ -9,8 +9,8 @@ #include #include "i915_active.h" +#include "i915_list_util.h" #include "i915_syncmap.h" -#include "i915_utils.h" #include "intel_timeline_types.h" struct drm_printer; diff --git a/drivers/gpu/drm/i915/i915_list_util.h b/drivers/gpu/drm/i915/i915_list_util.h new file mode 100644 index 000000000000..4e515dc8a3e0 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_list_util.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __I915_LIST_UTIL_H__ +#define __I915_LIST_UTIL_H__ + +#include +#include + +static inline void __list_del_many(struct list_head *head, + struct list_head *first) +{ + first->prev = head; + WRITE_ONCE(head->next, first); +} + +static inline int list_is_last_rcu(const struct list_head *list, + const struct list_head *head) +{ + return READ_ONCE(list->next) == head; +} + +#endif /* __I915_LIST_UTIL_H__ */ diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index 6278a74d08c2..4a6437d6e00e 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -25,7 +25,6 @@ #ifndef __I915_UTILS_H #define __I915_UTILS_H -#include #include #include #include @@ -101,19 +100,6 @@ static inline bool is_power_of_2_u64(u64 n) return (n != 0 && ((n & (n - 1)) == 0)); } -static inline void __list_del_many(struct list_head *head, - struct list_head *first) -{ - first->prev = head; - WRITE_ONCE(head->next, first); -} - -static inline int list_is_last_rcu(const struct list_head *list, - const struct list_head *head) -{ - return READ_ONCE(list->next) == head; -} - static inline unsigned long msecs_to_jiffies_timeout(const unsigned int m) { unsigned long j = msecs_to_jiffies(m); From 65805c2ed74ee47e81246f97f4b3c126a75f0b0e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 11 Sep 2025 12:17:40 +0300 Subject: [PATCH 36/36] drm/i915: split out i915_wait_util.h Move waiting related utilities from i915_utils.h to separate new file i915_wait_util.h. Clean up related includes. Note: Many of the various wait macro usages could likely be refactored to use poll_timeout_us(). Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/431396ac8cdb3e2f4ff053a8933290289a66ce42.1757582214.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/gt/intel_execlists_submission.c | 1 + drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 1 + drivers/gpu/drm/i915/gt/intel_reset.c | 7 +- .../gpu/drm/i915/gt/intel_ring_submission.c | 7 +- drivers/gpu/drm/i915/gt/intel_rps.c | 2 + drivers/gpu/drm/i915/gt/selftest_tlb.c | 6 +- drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c | 6 +- .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c | 2 + drivers/gpu/drm/i915/gt/uc/intel_guc.c | 8 +- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 3 +- drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 4 +- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 15 ++- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 10 +- drivers/gpu/drm/i915/gvt/mmio_context.c | 6 +- drivers/gpu/drm/i915/i915_debugfs.c | 3 +- drivers/gpu/drm/i915/i915_utils.h | 106 ---------------- drivers/gpu/drm/i915/i915_wait_util.h | 119 ++++++++++++++++++ drivers/gpu/drm/i915/intel_pcode.c | 1 + drivers/gpu/drm/i915/intel_uncore.c | 7 +- drivers/gpu/drm/i915/pxp/intel_pxp.c | 4 +- drivers/gpu/drm/i915/selftests/i915_request.c | 5 +- .../gpu/drm/i915/selftests/i915_selftest.c | 2 +- drivers/gpu/drm/i915/selftests/igt_spinner.c | 5 +- drivers/gpu/drm/i915/vlv_suspend.c | 5 +- 24 files changed, 184 insertions(+), 151 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_wait_util.h diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c index 0c1b2df02d26..7f389cb0bde4 100644 --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -117,6 +117,7 @@ #include "i915_timer_util.h" #include "i915_trace.h" #include "i915_vgpu.h" +#include "i915_wait_util.h" #include "intel_breadcrumbs.h" #include "intel_context.h" #include "intel_engine_heartbeat.h" diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c index a60822e2b5d4..c3afa321fe30 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c @@ -4,6 +4,7 @@ */ #include "i915_drv.h" +#include "i915_wait_util.h" #include "intel_gt.h" #include "intel_gt_mcr.h" #include "intel_gt_print.h" diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index 4a1675dea1c7..41b5036dc538 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -9,18 +9,17 @@ #include "display/intel_display_reset.h" #include "display/intel_overlay.h" - #include "gem/i915_gem_context.h" - #include "gt/intel_gt_regs.h" - #include "gt/uc/intel_gsc_fw.h" +#include "uc/intel_guc.h" #include "i915_drv.h" #include "i915_file_private.h" #include "i915_gpu_error.h" #include "i915_irq.h" #include "i915_reg.h" +#include "i915_wait_util.h" #include "intel_breadcrumbs.h" #include "intel_engine_pm.h" #include "intel_engine_regs.h" @@ -32,8 +31,6 @@ #include "intel_pci_config.h" #include "intel_reset.h" -#include "uc/intel_guc.h" - #define RESET_MAX_RETRIES 3 static void client_mark_guilty(struct i915_gem_context *ctx, bool banned) diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c index 2a6d79abf25b..8314a4b0505e 100644 --- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c @@ -15,18 +15,19 @@ #include "i915_irq.h" #include "i915_mitigations.h" #include "i915_reg.h" +#include "i915_wait_util.h" #include "intel_breadcrumbs.h" #include "intel_context.h" +#include "intel_engine_heartbeat.h" +#include "intel_engine_pm.h" #include "intel_engine_regs.h" #include "intel_gt.h" #include "intel_gt_irq.h" +#include "intel_gt_print.h" #include "intel_gt_regs.h" #include "intel_reset.h" #include "intel_ring.h" #include "shmem_utils.h" -#include "intel_engine_heartbeat.h" -#include "intel_engine_pm.h" -#include "intel_gt_print.h" /* Rough estimate of the typical request size, performing a flush, * set-context and then emitting the batch. diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c index 006042e0b229..4da94098bd3e 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps.c +++ b/drivers/gpu/drm/i915/gt/intel_rps.c @@ -10,9 +10,11 @@ #include "display/intel_display.h" #include "display/intel_display_rps.h" #include "soc/intel_dram.h" + #include "i915_drv.h" #include "i915_irq.h" #include "i915_reg.h" +#include "i915_wait_util.h" #include "intel_breadcrumbs.h" #include "intel_gt.h" #include "intel_gt_clock_utils.h" diff --git a/drivers/gpu/drm/i915/gt/selftest_tlb.c b/drivers/gpu/drm/i915/gt/selftest_tlb.c index 69ed946a39e5..a5184f09d1de 100644 --- a/drivers/gpu/drm/i915/gt/selftest_tlb.c +++ b/drivers/gpu/drm/i915/gt/selftest_tlb.c @@ -3,17 +3,17 @@ * Copyright © 2022 Intel Corporation */ -#include "i915_selftest.h" - #include "gem/i915_gem_internal.h" #include "gem/i915_gem_lmem.h" #include "gem/i915_gem_region.h" #include "gen8_engine_cs.h" #include "i915_gem_ww.h" +#include "i915_selftest.h" +#include "i915_wait_util.h" +#include "intel_context.h" #include "intel_engine_regs.h" #include "intel_gpu_commands.h" -#include "intel_context.h" #include "intel_gt.h" #include "intel_ring.h" diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c index d8edd7c054c8..e7444ebc373e 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c @@ -10,11 +10,13 @@ #include "gt/intel_gt.h" #include "gt/intel_gt_print.h" + +#include "i915_drv.h" +#include "i915_reg.h" +#include "i915_wait_util.h" #include "intel_gsc_proxy.h" #include "intel_gsc_uc.h" #include "intel_gsc_uc_heci_cmd_submit.h" -#include "i915_drv.h" -#include "i915_reg.h" /* * GSC proxy: diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c index 2fde5c360cff..9bd29be7656f 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c @@ -8,6 +8,8 @@ #include "gt/intel_gpu_commands.h" #include "gt/intel_gt.h" #include "gt/intel_ring.h" + +#include "i915_wait_util.h" #include "intel_gsc_uc_heci_cmd_submit.h" struct gsc_heci_pkt { diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c index f360f020d8f1..52ec4421a211 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c @@ -8,15 +8,17 @@ #include "gt/intel_gt_irq.h" #include "gt/intel_gt_pm_irq.h" #include "gt/intel_gt_regs.h" + +#include "i915_drv.h" +#include "i915_irq.h" +#include "i915_reg.h" +#include "i915_wait_util.h" #include "intel_guc.h" #include "intel_guc_ads.h" #include "intel_guc_capture.h" #include "intel_guc_print.h" #include "intel_guc_slpc.h" #include "intel_guc_submission.h" -#include "i915_drv.h" -#include "i915_irq.h" -#include "i915_reg.h" /** * DOC: GuC diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index 380a11c92d63..3e7e5badcc2b 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -5,11 +5,12 @@ #include #include -#include #include +#include #include #include "i915_drv.h" +#include "i915_wait_util.h" #include "intel_guc_ct.h" #include "intel_guc_print.h" diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c index e7ccfa520df3..1bb1491f90fc 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c @@ -13,9 +13,11 @@ #include "gt/intel_gt_mcr.h" #include "gt/intel_gt_regs.h" #include "gt/intel_rps.h" + +#include "i915_drv.h" +#include "i915_wait_util.h" #include "intel_guc_fw.h" #include "intel_guc_print.h" -#include "i915_drv.h" static void guc_prepare_xfer(struct intel_gt *gt) { diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index d5ee6e5e1443..fa9af08f9708 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -3,18 +3,21 @@ * Copyright © 2021 Intel Corporation */ -#include #include -#include "i915_drv.h" -#include "i915_reg.h" -#include "intel_guc_slpc.h" -#include "intel_guc_print.h" -#include "intel_mchbar_regs.h" +#include + #include "gt/intel_gt.h" #include "gt/intel_gt_regs.h" #include "gt/intel_rps.h" +#include "i915_drv.h" +#include "i915_reg.h" +#include "i915_wait_util.h" +#include "intel_guc_print.h" +#include "intel_guc_slpc.h" +#include "intel_mchbar_regs.h" + /** * DOC: SLPC - Dynamic Frequency management * diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index 127316d2c8aa..68f2b8d363ac 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -25,16 +25,16 @@ #include "gt/intel_mocs.h" #include "gt/intel_ring.h" +#include "i915_drv.h" +#include "i915_irq.h" +#include "i915_reg.h" +#include "i915_trace.h" +#include "i915_wait_util.h" #include "intel_guc_ads.h" #include "intel_guc_capture.h" #include "intel_guc_print.h" #include "intel_guc_submission.h" -#include "i915_drv.h" -#include "i915_reg.h" -#include "i915_irq.h" -#include "i915_trace.h" - /** * DOC: GuC-based command submission * diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.c b/drivers/gpu/drm/i915/gvt/mmio_context.c index 2f7208843367..0b810baad20a 100644 --- a/drivers/gpu/drm/i915/gvt/mmio_context.c +++ b/drivers/gpu/drm/i915/gvt/mmio_context.c @@ -33,14 +33,16 @@ * */ -#include "i915_drv.h" -#include "i915_reg.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_ring.h" + #include "gvt.h" +#include "i915_drv.h" +#include "i915_reg.h" +#include "i915_wait_util.h" #include "trace.h" #define GEN9_MOCS_SIZE 64 diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 23fa098c4479..c2e38d4bcd01 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -26,11 +26,11 @@ * */ +#include #include #include #include -#include #include #include "gem/i915_gem_context.h" @@ -54,6 +54,7 @@ #include "i915_irq.h" #include "i915_reg.h" #include "i915_scheduler.h" +#include "i915_wait_util.h" #include "intel_mchbar_regs.h" static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index 4a6437d6e00e..a0c892e4c40d 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -134,112 +134,6 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms) } } -/* - * __wait_for - magic wait macro - * - * Macro to help avoid open coding check/wait/timeout patterns. Note that it's - * important that we check the condition again after having timed out, since the - * timeout could be due to preemption or similar and we've never had a chance to - * check the condition before the timeout. - */ -#define __wait_for(OP, COND, US, Wmin, Wmax) ({ \ - const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (US)); \ - long wait__ = (Wmin); /* recommended min for usleep is 10 us */ \ - int ret__; \ - might_sleep(); \ - for (;;) { \ - const bool expired__ = ktime_after(ktime_get_raw(), end__); \ - OP; \ - /* Guarantee COND check prior to timeout */ \ - barrier(); \ - if (COND) { \ - ret__ = 0; \ - break; \ - } \ - if (expired__) { \ - ret__ = -ETIMEDOUT; \ - break; \ - } \ - usleep_range(wait__, wait__ * 2); \ - if (wait__ < (Wmax)) \ - wait__ <<= 1; \ - } \ - ret__; \ -}) - -#define _wait_for(COND, US, Wmin, Wmax) __wait_for(, (COND), (US), (Wmin), \ - (Wmax)) -#define wait_for(COND, MS) _wait_for((COND), (MS) * 1000, 10, 1000) - -/* - * If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. - * On PREEMPT_RT the context isn't becoming atomic because it is used in an - * interrupt handler or because a spinlock_t is acquired. This leads to - * warnings which don't occur otherwise and therefore the check is disabled. - */ -#if IS_ENABLED(CONFIG_DRM_I915_DEBUG) && IS_ENABLED(CONFIG_PREEMPT_COUNT) && !defined(CONFIG_PREEMPT_RT) -# define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) WARN_ON_ONCE((ATOMIC) && !in_atomic()) -#else -# define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) do { } while (0) -#endif - -#define _wait_for_atomic(COND, US, ATOMIC) \ -({ \ - int cpu, ret, timeout = (US) * 1000; \ - u64 base; \ - _WAIT_FOR_ATOMIC_CHECK(ATOMIC); \ - if (!(ATOMIC)) { \ - preempt_disable(); \ - cpu = smp_processor_id(); \ - } \ - base = local_clock(); \ - for (;;) { \ - u64 now = local_clock(); \ - if (!(ATOMIC)) \ - preempt_enable(); \ - /* Guarantee COND check prior to timeout */ \ - barrier(); \ - if (COND) { \ - ret = 0; \ - break; \ - } \ - if (now - base >= timeout) { \ - ret = -ETIMEDOUT; \ - break; \ - } \ - cpu_relax(); \ - if (!(ATOMIC)) { \ - preempt_disable(); \ - if (unlikely(cpu != smp_processor_id())) { \ - timeout -= now - base; \ - cpu = smp_processor_id(); \ - base = local_clock(); \ - } \ - } \ - } \ - ret; \ -}) - -#define wait_for_us(COND, US) \ -({ \ - int ret__; \ - BUILD_BUG_ON(!__builtin_constant_p(US)); \ - if ((US) > 10) \ - ret__ = _wait_for((COND), (US), 10, 10); \ - else \ - ret__ = _wait_for_atomic((COND), (US), 0); \ - ret__; \ -}) - -#define wait_for_atomic_us(COND, US) \ -({ \ - BUILD_BUG_ON(!__builtin_constant_p(US)); \ - BUILD_BUG_ON((US) > 50000); \ - _wait_for_atomic((COND), (US), 1); \ -}) - -#define wait_for_atomic(COND, MS) wait_for_atomic_us((COND), (MS) * 1000) - #define KHz(x) (1000 * (x)) #define MHz(x) KHz(1000 * (x)) diff --git a/drivers/gpu/drm/i915/i915_wait_util.h b/drivers/gpu/drm/i915/i915_wait_util.h new file mode 100644 index 000000000000..7376898e3bf8 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_wait_util.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __I915_WAIT_UTIL_H__ +#define __I915_WAIT_UTIL_H__ + +#include +#include +#include +#include +#include + +/* + * __wait_for - magic wait macro + * + * Macro to help avoid open coding check/wait/timeout patterns. Note that it's + * important that we check the condition again after having timed out, since the + * timeout could be due to preemption or similar and we've never had a chance to + * check the condition before the timeout. + */ +#define __wait_for(OP, COND, US, Wmin, Wmax) ({ \ + const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (US)); \ + long wait__ = (Wmin); /* recommended min for usleep is 10 us */ \ + int ret__; \ + might_sleep(); \ + for (;;) { \ + const bool expired__ = ktime_after(ktime_get_raw(), end__); \ + OP; \ + /* Guarantee COND check prior to timeout */ \ + barrier(); \ + if (COND) { \ + ret__ = 0; \ + break; \ + } \ + if (expired__) { \ + ret__ = -ETIMEDOUT; \ + break; \ + } \ + usleep_range(wait__, wait__ * 2); \ + if (wait__ < (Wmax)) \ + wait__ <<= 1; \ + } \ + ret__; \ +}) + +#define _wait_for(COND, US, Wmin, Wmax) __wait_for(, (COND), (US), (Wmin), \ + (Wmax)) +#define wait_for(COND, MS) _wait_for((COND), (MS) * 1000, 10, 1000) + +/* + * If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. + * On PREEMPT_RT the context isn't becoming atomic because it is used in an + * interrupt handler or because a spinlock_t is acquired. This leads to + * warnings which don't occur otherwise and therefore the check is disabled. + */ +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG) && IS_ENABLED(CONFIG_PREEMPT_COUNT) && !defined(CONFIG_PREEMPT_RT) +# define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) WARN_ON_ONCE((ATOMIC) && !in_atomic()) +#else +# define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) do { } while (0) +#endif + +#define _wait_for_atomic(COND, US, ATOMIC) \ +({ \ + int cpu, ret, timeout = (US) * 1000; \ + u64 base; \ + _WAIT_FOR_ATOMIC_CHECK(ATOMIC); \ + if (!(ATOMIC)) { \ + preempt_disable(); \ + cpu = smp_processor_id(); \ + } \ + base = local_clock(); \ + for (;;) { \ + u64 now = local_clock(); \ + if (!(ATOMIC)) \ + preempt_enable(); \ + /* Guarantee COND check prior to timeout */ \ + barrier(); \ + if (COND) { \ + ret = 0; \ + break; \ + } \ + if (now - base >= timeout) { \ + ret = -ETIMEDOUT; \ + break; \ + } \ + cpu_relax(); \ + if (!(ATOMIC)) { \ + preempt_disable(); \ + if (unlikely(cpu != smp_processor_id())) { \ + timeout -= now - base; \ + cpu = smp_processor_id(); \ + base = local_clock(); \ + } \ + } \ + } \ + ret; \ +}) + +#define wait_for_us(COND, US) \ +({ \ + int ret__; \ + BUILD_BUG_ON(!__builtin_constant_p(US)); \ + if ((US) > 10) \ + ret__ = _wait_for((COND), (US), 10, 10); \ + else \ + ret__ = _wait_for_atomic((COND), (US), 0); \ + ret__; \ +}) + +#define wait_for_atomic_us(COND, US) \ +({ \ + BUILD_BUG_ON(!__builtin_constant_p(US)); \ + BUILD_BUG_ON((US) > 50000); \ + _wait_for_atomic((COND), (US), 1); \ +}) + +#define wait_for_atomic(COND, MS) wait_for_atomic_us((COND), (MS) * 1000) + +#endif /* __I915_WAIT_UTIL_H__ */ diff --git a/drivers/gpu/drm/i915/intel_pcode.c b/drivers/gpu/drm/i915/intel_pcode.c index 81da75108c60..55ffedad2490 100644 --- a/drivers/gpu/drm/i915/intel_pcode.c +++ b/drivers/gpu/drm/i915/intel_pcode.c @@ -5,6 +5,7 @@ #include "i915_drv.h" #include "i915_reg.h" +#include "i915_wait_util.h" #include "intel_pcode.h" static int gen6_check_mailbox_status(u32 mbox) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 4ccba7c8ffb3..8cb59f8d1f4c 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -21,19 +21,20 @@ * IN THE SOFTWARE. */ -#include #include -#include "display/intel_display_core.h" +#include -#include "gt/intel_gt.h" +#include "display/intel_display_core.h" #include "gt/intel_engine_regs.h" +#include "gt/intel_gt.h" #include "gt/intel_gt_regs.h" #include "i915_drv.h" #include "i915_iosf_mbi.h" #include "i915_reg.h" #include "i915_vgpu.h" +#include "i915_wait_util.h" #include "intel_uncore_trace.h" #define FORCEWAKE_ACK_TIMEOUT_MS 50 diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c index f8da693ad3ce..27d545c4e6a5 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c @@ -2,15 +2,15 @@ /* * Copyright(c) 2020 Intel Corporation. */ + #include #include "gem/i915_gem_context.h" - #include "gt/intel_context.h" #include "gt/intel_gt.h" #include "i915_drv.h" - +#include "i915_wait_util.h" #include "intel_pxp.h" #include "intel_pxp_gsccs.h" #include "intel_pxp_irq.h" diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c index 2fb7a9e7efec..48cd617247d1 100644 --- a/drivers/gpu/drm/i915/selftests/i915_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_request.c @@ -22,14 +22,13 @@ * */ -#include #include +#include #include #include "gem/i915_gem_internal.h" #include "gem/i915_gem_pm.h" #include "gem/selftests/mock_context.h" - #include "gt/intel_engine_heartbeat.h" #include "gt/intel_engine_pm.h" #include "gt/intel_engine_user.h" @@ -40,11 +39,11 @@ #include "i915_random.h" #include "i915_selftest.h" +#include "i915_wait_util.h" #include "igt_flush_test.h" #include "igt_live_test.h" #include "igt_spinner.h" #include "lib_sw_fence.h" - #include "mock_drm.h" #include "mock_gem_device.h" diff --git a/drivers/gpu/drm/i915/selftests/i915_selftest.c b/drivers/gpu/drm/i915/selftests/i915_selftest.c index 889281819c5b..9c276c9d0a75 100644 --- a/drivers/gpu/drm/i915/selftests/i915_selftest.c +++ b/drivers/gpu/drm/i915/selftests/i915_selftest.c @@ -31,7 +31,7 @@ #include "i915_driver.h" #include "i915_drv.h" #include "i915_selftest.h" - +#include "i915_wait_util.h" #include "igt_flush_test.h" struct i915_selftest i915_selftest __read_mostly = { diff --git a/drivers/gpu/drm/i915/selftests/igt_spinner.c b/drivers/gpu/drm/i915/selftests/igt_spinner.c index 8c3e1f20e5a1..820364171ebe 100644 --- a/drivers/gpu/drm/i915/selftests/igt_spinner.c +++ b/drivers/gpu/drm/i915/selftests/igt_spinner.c @@ -3,12 +3,13 @@ * * Copyright © 2018 Intel Corporation */ -#include "gt/intel_gpu_commands.h" -#include "gt/intel_gt.h" #include "gem/i915_gem_internal.h" #include "gem/selftests/igt_gem_utils.h" +#include "gt/intel_gpu_commands.h" +#include "gt/intel_gt.h" +#include "i915_wait_util.h" #include "igt_spinner.h" int igt_spinner_init(struct igt_spinner *spin, struct intel_gt *gt) diff --git a/drivers/gpu/drm/i915/vlv_suspend.c b/drivers/gpu/drm/i915/vlv_suspend.c index fc9f311ea1db..221e4c0b2c58 100644 --- a/drivers/gpu/drm/i915/vlv_suspend.c +++ b/drivers/gpu/drm/i915/vlv_suspend.c @@ -8,16 +8,17 @@ #include +#include "gt/intel_gt_regs.h" + #include "i915_drv.h" #include "i915_reg.h" #include "i915_trace.h" #include "i915_utils.h" +#include "i915_wait_util.h" #include "intel_clock_gating.h" #include "intel_uncore_trace.h" #include "vlv_suspend.h" -#include "gt/intel_gt_regs.h" - struct vlv_s0ix_state { /* GAM */ u32 wr_watermark;