From 0159e311772af9d6598aafe072c020687720f1d7 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 24 Feb 2025 11:32:42 +0200 Subject: [PATCH 01/92] drm/i915/dp_mst: Fix encoder HW state readout for UHBR MST The encoder HW/SW state verification should use a SW state which stays unchanged while the encoder/output is active. The intel_dp::is_mst flag used during state computation to choose between the DP SST/MST modes can change while the output is active, if the sink gets disconnected or the MST topology is removed for another reason. A subsequent state verification using intel_dp::is_mst leads then to a mismatch if the output is disabled/re-enabled without recomputing its state. Use the encoder's active MST link count instead, which will be always non-zero for an active MST output and will be zero for SST. Fixes: 35d2e4b75649 ("drm/i915/ddi: start distinguishing 128b/132b SST and MST at state readout") Fixes: 40d489fac0e8 ("drm/i915/ddi: handle 128b/132b SST in intel_ddi_read_func_ctl()") Cc: Jani Nikula Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250224093242.1859583-1-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 5fe689430744..f7d0c0463bce 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -890,7 +890,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, encoder->base.base.id, encoder->base.name); if (!mst_pipe_mask && dp128b132b_pipe_mask) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); /* * If we don't have 8b/10b MST, but have more than one @@ -902,7 +902,8 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, * we don't expect MST to have been enabled at that point, and * can assume it's SST. */ - if (hweight8(dp128b132b_pipe_mask) > 1 || intel_dp->is_mst) + if (hweight8(dp128b132b_pipe_mask) > 1 || + intel_dp_mst_encoder_active_links(dig_port)) mst_pipe_mask = dp128b132b_pipe_mask; } @@ -4127,13 +4128,13 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, } else if (ddi_mode == TRANS_DDI_MODE_SELECT_DP_MST) { intel_ddi_read_func_ctl_dp_mst(encoder, pipe_config, ddi_func_ctl); } else if (ddi_mode == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B && HAS_DP20(display)) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); /* * If this is true, we know we're being called from mst stream * encoder's ->get_config(). */ - if (intel_dp->is_mst) + if (intel_dp_mst_encoder_active_links(dig_port)) intel_ddi_read_func_ctl_dp_mst(encoder, pipe_config, ddi_func_ctl); else intel_ddi_read_func_ctl_dp_sst(encoder, pipe_config, ddi_func_ctl); From ad45492c7c59bd2fe9960a1969bfcef70d293187 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 14:17:42 +0200 Subject: [PATCH 02/92] drm/i915/power: move runtime power status info to power debugfs The i915 core debugfs has no business looking at power domain guts for runtime power status. Move the info to the more appropriate place. Cc: Imre Deak Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20250225121742.721871-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_power.c | 3 +++ drivers/gpu/drm/i915/i915_debugfs.c | 3 --- 2 files 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 396930937d98..96346b33d7e9 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -2317,6 +2317,9 @@ void intel_display_power_debug(struct intel_display *display, struct seq_file *m mutex_lock(&power_domains->lock); + seq_printf(m, "Runtime power status: %s\n", + str_enabled_disabled(!power_domains->init_wakeref)); + seq_printf(m, "%-25s %s\n", "Power well/domain", "Use count"); for (i = 0; i < power_domains->power_well_count; i++) { struct i915_power_well *power_well; diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1c2a97f593c7..0d9e263913ff 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -411,9 +411,6 @@ static int i915_runtime_pm_status(struct seq_file *m, void *unused) if (!HAS_RUNTIME_PM(dev_priv)) seq_puts(m, "Runtime power management not supported\n"); - seq_printf(m, "Runtime power status: %s\n", - str_enabled_disabled(!dev_priv->display.power.domains.init_wakeref)); - seq_printf(m, "GPU idle: %s\n", str_yes_no(!to_gt(dev_priv)->awake)); seq_printf(m, "IRQs disabled: %s\n", str_yes_no(!intel_irqs_enabled(dev_priv))); From db0d2d7572153490449e360d5ebf298badf5f395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 24 Feb 2025 19:30:17 +0200 Subject: [PATCH 03/92] drm/i915: Fix pipeDMC and ATS fault handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fault handler is supposed to return true when it handles the fault. The pipeDMC and ATS handlers are returning false instead which results in the "unreported faults" WARN triggering when it shouldn't. Fixes: f13011a79999 ("drm/i915: Pimp display fault reporting") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250224173017.29500-1-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_display_irq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 99fb7fc7be39..aa23bb817805 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1101,7 +1101,7 @@ static bool handle_plane_ats_fault(struct intel_crtc *crtc, enum plane_id plane_ "[CRTC:%d:%s] PLANE ATS fault\n", crtc->base.base.id, crtc->base.name); - return false; + return true; } static bool handle_pipedmc_ats_fault(struct intel_crtc *crtc, enum plane_id plane_id) @@ -1112,7 +1112,7 @@ static bool handle_pipedmc_ats_fault(struct intel_crtc *crtc, enum plane_id plan "[CRTC:%d:%s] PIPEDMC ATS fault\n", crtc->base.base.id, crtc->base.name); - return false; + return true; } static bool handle_pipedmc_fault(struct intel_crtc *crtc, enum plane_id plane_id) @@ -1123,7 +1123,7 @@ static bool handle_pipedmc_fault(struct intel_crtc *crtc, enum plane_id plane_id "[CRTC:%d:%s] PIPEDMC fault\n", crtc->base.base.id, crtc->base.name); - return false; + return true; } static const struct pipe_fault_handler mtl_pipe_fault_handlers[] = { From 15bccbfb78d63a2a621b30caff8b9424160c6c89 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 26 Feb 2025 15:56:26 +0200 Subject: [PATCH 04/92] drm/i915/mst: update max stream count to match number of pipes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We create the stream encoders and attach connectors for each pipe we have. As the number of pipes has increased, we've failed to update the topology manager maximum number of payloads to match that. Bump up the max stream count to match number of pipes, enabling the fourth stream on platforms that support four pipes. Cc: stable@vger.kernel.org Cc: Imre Deak Cc: Ville Syrjala Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250226135626.1956012-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index faa261c8930c..889b3a902b8f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1896,7 +1896,8 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id) /* create encoders */ mst_stream_encoders_create(dig_port); ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, display->drm, - &intel_dp->aux, 16, 3, conn_base_id); + &intel_dp->aux, 16, + INTEL_NUM_PIPES(display), conn_base_id); if (ret) { intel_dp->mst_mgr.cbs = NULL; return ret; From 0632d4f1b1c5049479124bbfc03f0b82eeaa5295 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 18:49:02 +0200 Subject: [PATCH 05/92] drm/i915/display: remove leftover struct drm_i915_private forward declarations A number of unused struct drm_i915_private forward declarations have been left behind. Remove them. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/ef354c3d812ac33061628063548b932507fdc9b7.1740502116.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_atomic.h | 1 - drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h | 1 - drivers/gpu/drm/i915/display/intel_hdmi.h | 1 - drivers/gpu/drm/i915/display/intel_overlay.h | 1 - drivers/gpu/drm/i915/display/intel_pipe_crc.h | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h index e506f6a87344..a5a7e2906ba8 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.h +++ b/drivers/gpu/drm/i915/display/intel_atomic.h @@ -14,7 +14,6 @@ struct drm_connector_state; struct drm_crtc; struct drm_crtc_state; struct drm_device; -struct drm_i915_private; struct drm_property; struct intel_atomic_state; struct intel_connector; diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h index 2133984a572b..29a190390192 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h @@ -8,7 +8,6 @@ #include -struct drm_i915_private; struct intel_encoder; struct intel_crtc_state; diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h index d237fe08c3e6..dec2ad7dd8a2 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.h +++ b/drivers/gpu/drm/i915/display/intel_hdmi.h @@ -14,7 +14,6 @@ enum port; struct drm_connector; struct drm_connector_state; struct drm_encoder; -struct drm_i915_private; struct intel_connector; struct intel_crtc_state; struct intel_digital_port; diff --git a/drivers/gpu/drm/i915/display/intel_overlay.h b/drivers/gpu/drm/i915/display/intel_overlay.h index 45a42fce754e..d259e4c74b03 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.h +++ b/drivers/gpu/drm/i915/display/intel_overlay.h @@ -10,7 +10,6 @@ struct drm_device; struct drm_file; -struct drm_i915_private; struct drm_printer; struct intel_display; struct intel_overlay; diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc.h b/drivers/gpu/drm/i915/display/intel_pipe_crc.h index 43012b189415..6ddcea38488b 100644 --- a/drivers/gpu/drm/i915/display/intel_pipe_crc.h +++ b/drivers/gpu/drm/i915/display/intel_pipe_crc.h @@ -9,7 +9,6 @@ #include struct drm_crtc; -struct drm_i915_private; struct intel_crtc; #ifdef CONFIG_DEBUG_FS From 0749f18967d3c4f01a8deec447dbf4da5f9c8b44 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 18:49:03 +0200 Subject: [PATCH 06/92] drm/i915/debugfs: continue display debugfs struct intel_display conversion Nudge intel_display_debugfs.[ch] conversion to struct intel_display forward. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/e1262dc019d42ed0e294606fc875427bda336cb9.1740502116.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_debugfs.c | 26 +++++++------------ .../drm/i915/display/intel_display_debugfs.h | 6 ++--- .../drm/i915/display/intel_display_driver.c | 2 +- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 9de7e512c0ab..7ee90cd8ed2d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -49,11 +49,6 @@ static struct intel_display *node_to_intel_display(struct drm_info_node *node) return to_intel_display(node->minor->dev); } -static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) -{ - return to_i915(node->minor->dev); -} - static int intel_display_caps(struct seq_file *m, void *data) { struct intel_display *display = node_to_intel_display(m->private); @@ -85,8 +80,8 @@ static int i915_frontbuffer_tracking(struct seq_file *m, void *unused) static int i915_sr_status(struct seq_file *m, void *unused) { - struct drm_i915_private *dev_priv = node_to_i915(m->private); struct intel_display *display = node_to_intel_display(m->private); + struct drm_i915_private *dev_priv = to_i915(display->drm); intel_wakeref_t wakeref; bool sr_enabled = false; @@ -102,7 +97,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) else if (display->platform.i915gm) sr_enabled = intel_de_read(display, INSTPM) & INSTPM_SELF_EN; else if (display->platform.pineview) - sr_enabled = intel_de_read(display, DSPFW3(dev_priv)) & PINEVIEW_SELF_REFRESH_EN; + sr_enabled = intel_de_read(display, DSPFW3(display)) & PINEVIEW_SELF_REFRESH_EN; else if (display->platform.valleyview || display->platform.cherryview) sr_enabled = intel_de_read(display, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; @@ -157,8 +152,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) static int i915_power_domain_info(struct seq_file *m, void *unused) { - struct drm_i915_private *i915 = node_to_i915(m->private); - struct intel_display *display = &i915->display; + struct intel_display *display = node_to_intel_display(m->private); intel_display_power_debug(display, m); @@ -588,7 +582,7 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc) static int i915_display_info(struct seq_file *m, void *unused) { struct intel_display *display = node_to_intel_display(m->private); - struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc; struct drm_connector *connector; struct drm_connector_list_iter conn_iter; @@ -713,14 +707,13 @@ intel_lpsp_power_well_enabled(struct intel_display *display, static int i915_lpsp_status(struct seq_file *m, void *unused) { struct intel_display *display = node_to_intel_display(m->private); - struct drm_i915_private *i915 = node_to_i915(m->private); bool lpsp_enabled = false; if (DISPLAY_VER(display) >= 13 || IS_DISPLAY_VER(display, 9, 10)) { lpsp_enabled = !intel_lpsp_power_well_enabled(display, SKL_DISP_PW_2); } else if (IS_DISPLAY_VER(display, 11, 12)) { lpsp_enabled = !intel_lpsp_power_well_enabled(display, ICL_DISP_PW_3); - } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { + } else if (display->platform.haswell || display->platform.broadwell) { lpsp_enabled = !intel_lpsp_power_well_enabled(display, HSW_DISP_PW_GLOBAL); } else { seq_puts(m, "LPSP: not supported\n"); @@ -836,10 +829,10 @@ static const struct drm_info_list intel_display_debugfs_list[] = { {"i915_lpsp_status", i915_lpsp_status, 0}, }; -void intel_display_debugfs_register(struct drm_i915_private *i915) +void intel_display_debugfs_register(struct intel_display *display) { - struct intel_display *display = &i915->display; - struct drm_minor *minor = i915->drm.primary; + struct drm_i915_private *i915 = to_i915(display->drm); + struct drm_minor *minor = display->drm->primary; debugfs_create_file("i915_fifo_underrun_reset", 0644, minor->debugfs_root, display, &i915_fifo_underrun_reset_ops); @@ -865,7 +858,6 @@ static int i915_lpsp_capability_show(struct seq_file *m, void *data) struct intel_connector *connector = m->private; struct intel_display *display = to_intel_display(connector); struct intel_encoder *encoder = intel_attached_encoder(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); int connector_type = connector->base.connector_type; bool lpsp_capable = false; @@ -892,7 +884,7 @@ static int i915_lpsp_capability_show(struct seq_file *m, void *data) (connector_type == DRM_MODE_CONNECTOR_DSI || connector_type == DRM_MODE_CONNECTOR_eDP || connector_type == DRM_MODE_CONNECTOR_DisplayPort)); - else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) + else if (display->platform.haswell || display->platform.broadwell) lpsp_capable = connector_type == DRM_MODE_CONNECTOR_eDP; seq_printf(m, "LPSP: %s\n", lpsp_capable ? "capable" : "incapable"); diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.h b/drivers/gpu/drm/i915/display/intel_display_debugfs.h index e1f479b7acd1..82af2f608111 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.h +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.h @@ -6,16 +6,16 @@ #ifndef __INTEL_DISPLAY_DEBUGFS_H__ #define __INTEL_DISPLAY_DEBUGFS_H__ -struct drm_i915_private; struct intel_connector; struct intel_crtc; +struct intel_display; #ifdef CONFIG_DEBUG_FS -void intel_display_debugfs_register(struct drm_i915_private *i915); +void intel_display_debugfs_register(struct intel_display *display); void intel_connector_debugfs_add(struct intel_connector *connector); void intel_crtc_debugfs_add(struct intel_crtc *crtc); #else -static inline void intel_display_debugfs_register(struct drm_i915_private *i915) {} +static inline void intel_display_debugfs_register(struct intel_display *display) {} static inline void intel_connector_debugfs_add(struct intel_connector *connector) {} static inline void intel_crtc_debugfs_add(struct intel_crtc *crtc) {} #endif diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 852f1129a058..defe08df9e97 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -550,7 +550,7 @@ void intel_display_driver_register(struct intel_display *display) intel_audio_register(display); - intel_display_debugfs_register(i915); + intel_display_debugfs_register(display); /* * We need to coordinate the hotplugs with the asynchronous From 7bcb697c94a117081a13cb40315c933247560cab Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 18:49:04 +0200 Subject: [PATCH 07/92] drm/i915/tdf: convert intel_tdf.[ch] to struct intel_display Going forward, struct intel_display is the main display device data pointer. Convert the intel_tdf.[ch] glue to struct intel_display. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/26d976f23295713f9a7cda20e32b7ef5aad3dd9e.1740502116.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/i915/display/intel_frontbuffer.c | 2 +- drivers/gpu/drm/i915/display/intel_tdf.h | 6 +++--- drivers/gpu/drm/xe/display/xe_tdf.c | 6 ++++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ab33792c9840..5ede3ee2543f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7425,7 +7425,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_atomic_commit_fence_wait(state); - intel_td_flush(dev_priv); + intel_td_flush(display); intel_atomic_prepare_plane_clear_colors(state); diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index 26128c610cb4..2fa4b0bf27c3 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -98,7 +98,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915, trace_intel_frontbuffer_flush(display, frontbuffer_bits, origin); might_sleep(); - intel_td_flush(i915); + intel_td_flush(display); intel_drrs_flush(i915, frontbuffer_bits); intel_psr_flush(display, frontbuffer_bits, origin); intel_fbc_flush(i915, frontbuffer_bits, origin); diff --git a/drivers/gpu/drm/i915/display/intel_tdf.h b/drivers/gpu/drm/i915/display/intel_tdf.h index 353cde21f6c2..0862c2bfd9cd 100644 --- a/drivers/gpu/drm/i915/display/intel_tdf.h +++ b/drivers/gpu/drm/i915/display/intel_tdf.h @@ -14,12 +14,12 @@ * the display flip, since display engine is never coherent with CPU/GPU caches. */ -struct drm_i915_private; +struct intel_display; #ifdef I915 -static inline void intel_td_flush(struct drm_i915_private *i915) {} +static inline void intel_td_flush(struct intel_display *display) {} #else -void intel_td_flush(struct drm_i915_private *i915); +void intel_td_flush(struct intel_display *display); #endif #endif diff --git a/drivers/gpu/drm/xe/display/xe_tdf.c b/drivers/gpu/drm/xe/display/xe_tdf.c index 2c0d4e144e09..2a7fccbeb1d5 100644 --- a/drivers/gpu/drm/xe/display/xe_tdf.c +++ b/drivers/gpu/drm/xe/display/xe_tdf.c @@ -7,7 +7,9 @@ #include "intel_display_types.h" #include "intel_tdf.h" -void intel_td_flush(struct drm_i915_private *i915) +void intel_td_flush(struct intel_display *display) { - xe_device_td_flush(i915); + struct xe_device *xe = to_xe_device(display->drm); + + xe_device_td_flush(xe); } From fe43444d0e5924bc37b55e558bd15e157225a9fb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 18:49:05 +0200 Subject: [PATCH 08/92] drm/i915/snps: convert intel_snps_phy.[ch] to struct intel_display Going forward, struct intel_display is the main display device data pointer. Convert the intel_snps_phy.[ch] to struct intel_display. Also convert the very much related intel_phy_is_snps() helper. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/2dcc9313f5cf7777af3b6f20124526f6b9462b91.1740502116.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- drivers/gpu/drm/i915/display/intel_display.c | 8 +- drivers/gpu/drm/i915/display/intel_display.h | 2 +- .../drm/i915/display/intel_display_power.c | 2 +- drivers/gpu/drm/i915/display/intel_snps_phy.c | 75 +++++++++---------- drivers/gpu/drm/i915/display/intel_snps_phy.h | 6 +- 6 files changed, 47 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index f7d0c0463bce..e34bf175262b 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -5135,7 +5135,7 @@ void intel_ddi_init(struct intel_display *display, return; } - if (intel_phy_is_snps(dev_priv, phy) && + if (intel_phy_is_snps(display, phy) && dev_priv->display.snps.phy_failed_calibration & BIT(phy)) { drm_dbg_kms(&dev_priv->drm, "SNPS PHY %c failed to calibrate, proceeding anyway\n", diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 5ede3ee2543f..e2b1445b4a66 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1925,13 +1925,13 @@ bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy) } /* Prefer intel_encoder_is_snps() */ -bool intel_phy_is_snps(struct drm_i915_private *dev_priv, enum phy phy) +bool intel_phy_is_snps(struct intel_display *display, enum phy phy) { /* * For DG2, and for DG2 only, all four "combo" ports and the TC1 port * (PHY E) use Synopsis PHYs. See intel_phy_is_tc(). */ - return IS_DG2(dev_priv) && phy > PHY_NONE && phy <= PHY_E; + return display->platform.dg2 && phy > PHY_NONE && phy <= PHY_E; } /* Prefer intel_encoder_to_phy() */ @@ -1980,9 +1980,9 @@ bool intel_encoder_is_combo(struct intel_encoder *encoder) bool intel_encoder_is_snps(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - return intel_phy_is_snps(i915, intel_encoder_to_phy(encoder)); + return intel_phy_is_snps(display, intel_encoder_to_phy(encoder)); } bool intel_encoder_is_tc(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index e58daefc978e..91f01e81a8f0 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -466,7 +466,7 @@ void intel_encoder_get_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state); bool intel_phy_is_combo(struct intel_display *display, enum phy phy); bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy); -bool intel_phy_is_snps(struct drm_i915_private *dev_priv, enum phy phy); +bool intel_phy_is_snps(struct intel_display *display, enum phy phy); enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv, enum port port); diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 96346b33d7e9..f7171e6932dc 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1684,7 +1684,7 @@ static void icl_display_core_init(struct intel_display *display, /* 8. Ensure PHYs have completed calibration and adaptation */ if (display->platform.dg2) - intel_snps_phy_wait_for_calibration(dev_priv); + intel_snps_phy_wait_for_calibration(display); /* 9. XE2_HPD: Program CHICKEN_MISC_2 before any cursor or planes are enabled */ if (DISPLAY_VERx100(display) == 1401) diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c index 353221d3e29f..b9acd9fe160c 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c @@ -5,8 +5,8 @@ #include -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "intel_ddi.h" #include "intel_ddi_buf_trans.h" #include "intel_de.h" @@ -27,12 +27,12 @@ * since it is not handled by the shared DPLL framework as on other platforms. */ -void intel_snps_phy_wait_for_calibration(struct drm_i915_private *i915) +void intel_snps_phy_wait_for_calibration(struct intel_display *display) { enum phy phy; for_each_phy_masked(phy, ~0) { - if (!intel_phy_is_snps(i915, phy)) + if (!intel_phy_is_snps(display, phy)) continue; /* @@ -40,16 +40,16 @@ void intel_snps_phy_wait_for_calibration(struct drm_i915_private *i915) * which phy was affected and skip setup of the corresponding * output later. */ - if (intel_de_wait_for_clear(i915, DG2_PHY_MISC(phy), + if (intel_de_wait_for_clear(display, DG2_PHY_MISC(phy), DG2_PHY_DP_TX_ACK_MASK, 25)) - i915->display.snps.phy_failed_calibration |= BIT(phy); + display->snps.phy_failed_calibration |= BIT(phy); } } void intel_snps_phy_update_psr_power_state(struct intel_encoder *encoder, bool enable) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); u32 val; @@ -58,20 +58,20 @@ void intel_snps_phy_update_psr_power_state(struct intel_encoder *encoder, val = REG_FIELD_PREP(SNPS_PHY_TX_REQ_LN_DIS_PWR_STATE_PSR, enable ? 2 : 3); - intel_de_rmw(i915, SNPS_PHY_TX_REQ(phy), + intel_de_rmw(display, SNPS_PHY_TX_REQ(phy), SNPS_PHY_TX_REQ_LN_DIS_PWR_STATE_PSR, val); } void intel_snps_phy_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_ddi_buf_trans *trans; enum phy phy = intel_encoder_to_phy(encoder); int n_entries, ln; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; for (ln = 0; ln < 4; ln++) { @@ -82,7 +82,7 @@ void intel_snps_phy_set_signal_levels(struct intel_encoder *encoder, val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_PRE, trans->entries[level].snps.pre_cursor); val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, trans->entries[level].snps.post_cursor); - intel_de_write(dev_priv, SNPS_PHY_TX_EQ(ln, phy), val); + intel_de_write(display, SNPS_PHY_TX_EQ(ln, phy), val); } } @@ -1817,7 +1817,7 @@ int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state, void intel_mpllb_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_mpllb_state *pll_state = &crtc_state->dpll_hw_state.mpllb; enum phy phy = intel_encoder_to_phy(encoder); i915_reg_t enable_reg = (phy <= PHY_D ? @@ -1827,13 +1827,13 @@ void intel_mpllb_enable(struct intel_encoder *encoder, * 3. Software programs the following PLL registers for the desired * frequency. */ - intel_de_write(dev_priv, SNPS_PHY_MPLLB_CP(phy), pll_state->mpllb_cp); - intel_de_write(dev_priv, SNPS_PHY_MPLLB_DIV(phy), pll_state->mpllb_div); - intel_de_write(dev_priv, SNPS_PHY_MPLLB_DIV2(phy), pll_state->mpllb_div2); - intel_de_write(dev_priv, SNPS_PHY_MPLLB_SSCEN(phy), pll_state->mpllb_sscen); - intel_de_write(dev_priv, SNPS_PHY_MPLLB_SSCSTEP(phy), pll_state->mpllb_sscstep); - intel_de_write(dev_priv, SNPS_PHY_MPLLB_FRACN1(phy), pll_state->mpllb_fracn1); - intel_de_write(dev_priv, SNPS_PHY_MPLLB_FRACN2(phy), pll_state->mpllb_fracn2); + intel_de_write(display, SNPS_PHY_MPLLB_CP(phy), pll_state->mpllb_cp); + intel_de_write(display, SNPS_PHY_MPLLB_DIV(phy), pll_state->mpllb_div); + intel_de_write(display, SNPS_PHY_MPLLB_DIV2(phy), pll_state->mpllb_div2); + intel_de_write(display, SNPS_PHY_MPLLB_SSCEN(phy), pll_state->mpllb_sscen); + intel_de_write(display, SNPS_PHY_MPLLB_SSCSTEP(phy), pll_state->mpllb_sscstep); + intel_de_write(display, SNPS_PHY_MPLLB_FRACN1(phy), pll_state->mpllb_fracn1); + intel_de_write(display, SNPS_PHY_MPLLB_FRACN2(phy), pll_state->mpllb_fracn2); /* * 4. If the frequency will result in a change to the voltage @@ -1844,7 +1844,7 @@ void intel_mpllb_enable(struct intel_encoder *encoder, */ /* 5. Software sets DPLL_ENABLE [PLL Enable] to "1". */ - intel_de_rmw(dev_priv, enable_reg, 0, PLL_ENABLE); + intel_de_rmw(display, enable_reg, 0, PLL_ENABLE); /* * 9. Software sets SNPS_PHY_MPLLB_DIV dp_mpllb_force_en to "1". This @@ -1853,7 +1853,7 @@ void intel_mpllb_enable(struct intel_encoder *encoder, * PLL because that will start the PLL before it has sampled the * divider values. */ - intel_de_write(dev_priv, SNPS_PHY_MPLLB_DIV(phy), + intel_de_write(display, SNPS_PHY_MPLLB_DIV(phy), pll_state->mpllb_div | SNPS_PHY_MPLLB_FORCE_EN); /* @@ -1861,8 +1861,8 @@ void intel_mpllb_enable(struct intel_encoder *encoder, * is locked at new settings. This register bit is sampling PHY * dp_mpllb_state interface signal. */ - if (intel_de_wait_for_set(dev_priv, enable_reg, PLL_LOCK, 5)) - drm_dbg_kms(&dev_priv->drm, "Port %c PLL not locked\n", phy_name(phy)); + if (intel_de_wait_for_set(display, enable_reg, PLL_LOCK, 5)) + drm_dbg_kms(display->drm, "Port %c PLL not locked\n", phy_name(phy)); /* * 11. If the frequency will result in a change to the voltage @@ -1875,7 +1875,7 @@ void intel_mpllb_enable(struct intel_encoder *encoder, void intel_mpllb_disable(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); i915_reg_t enable_reg = (phy <= PHY_D ? DG2_PLL_ENABLE(phy) : MG_PLL_ENABLE(0)); @@ -1889,20 +1889,20 @@ void intel_mpllb_disable(struct intel_encoder *encoder) */ /* 2. Software programs DPLL_ENABLE [PLL Enable] to "0" */ - intel_de_rmw(i915, enable_reg, PLL_ENABLE, 0); + intel_de_rmw(display, enable_reg, PLL_ENABLE, 0); /* * 4. Software programs SNPS_PHY_MPLLB_DIV dp_mpllb_force_en to "0". * This will allow the PLL to stop running. */ - intel_de_rmw(i915, SNPS_PHY_MPLLB_DIV(phy), SNPS_PHY_MPLLB_FORCE_EN, 0); + intel_de_rmw(display, SNPS_PHY_MPLLB_DIV(phy), SNPS_PHY_MPLLB_FORCE_EN, 0); /* * 5. Software polls DPLL_ENABLE [PLL Lock] for PHY acknowledgment * (dp_txX_ack) that the new transmitter setting request is completed. */ - if (intel_de_wait_for_clear(i915, enable_reg, PLL_LOCK, 5)) - drm_err(&i915->drm, "Port %c PLL not locked\n", phy_name(phy)); + if (intel_de_wait_for_clear(display, enable_reg, PLL_LOCK, 5)) + drm_err(display->drm, "Port %c PLL not locked\n", phy_name(phy)); /* * 6. If the frequency will result in a change to the voltage @@ -1947,16 +1947,16 @@ int intel_mpllb_calc_port_clock(struct intel_encoder *encoder, void intel_mpllb_readout_hw_state(struct intel_encoder *encoder, struct intel_mpllb_state *pll_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - pll_state->mpllb_cp = intel_de_read(dev_priv, SNPS_PHY_MPLLB_CP(phy)); - pll_state->mpllb_div = intel_de_read(dev_priv, SNPS_PHY_MPLLB_DIV(phy)); - pll_state->mpllb_div2 = intel_de_read(dev_priv, SNPS_PHY_MPLLB_DIV2(phy)); - pll_state->mpllb_sscen = intel_de_read(dev_priv, SNPS_PHY_MPLLB_SSCEN(phy)); - pll_state->mpllb_sscstep = intel_de_read(dev_priv, SNPS_PHY_MPLLB_SSCSTEP(phy)); - pll_state->mpllb_fracn1 = intel_de_read(dev_priv, SNPS_PHY_MPLLB_FRACN1(phy)); - pll_state->mpllb_fracn2 = intel_de_read(dev_priv, SNPS_PHY_MPLLB_FRACN2(phy)); + pll_state->mpllb_cp = intel_de_read(display, SNPS_PHY_MPLLB_CP(phy)); + pll_state->mpllb_div = intel_de_read(display, SNPS_PHY_MPLLB_DIV(phy)); + pll_state->mpllb_div2 = intel_de_read(display, SNPS_PHY_MPLLB_DIV2(phy)); + pll_state->mpllb_sscen = intel_de_read(display, SNPS_PHY_MPLLB_SSCEN(phy)); + pll_state->mpllb_sscstep = intel_de_read(display, SNPS_PHY_MPLLB_SSCSTEP(phy)); + pll_state->mpllb_fracn1 = intel_de_read(display, SNPS_PHY_MPLLB_FRACN1(phy)); + pll_state->mpllb_fracn2 = intel_de_read(display, SNPS_PHY_MPLLB_FRACN2(phy)); /* * REF_CONTROL is under firmware control and never programmed by the @@ -1964,7 +1964,7 @@ void intel_mpllb_readout_hw_state(struct intel_encoder *encoder, * only tells us the expected value for one field in this register, * so we'll only read out those specific bits here. */ - pll_state->ref_control = intel_de_read(dev_priv, SNPS_PHY_REF_CONTROL(phy)) & + pll_state->ref_control = intel_de_read(display, SNPS_PHY_REF_CONTROL(phy)) & SNPS_PHY_REF_CONTROL_REF_RANGE; /* @@ -1980,14 +1980,13 @@ void intel_mpllb_state_verify(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(state->base.dev); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_mpllb_state mpllb_hw_state = {}; const struct intel_mpllb_state *mpllb_sw_state = &new_crtc_state->dpll_hw_state.mpllb; struct intel_encoder *encoder; - if (!IS_DG2(i915)) + if (!display->platform.dg2) return; if (!new_crtc_state->hw.active) diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.h b/drivers/gpu/drm/i915/display/intel_snps_phy.h index 1dd564ed9fa8..7f96da22d028 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.h +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.h @@ -8,15 +8,15 @@ #include -struct drm_i915_private; +enum phy; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; +struct intel_display; struct intel_encoder; struct intel_mpllb_state; -enum phy; -void intel_snps_phy_wait_for_calibration(struct drm_i915_private *dev_priv); +void intel_snps_phy_wait_for_calibration(struct intel_display *display); void intel_snps_phy_update_psr_power_state(struct intel_encoder *encoder, bool enable); From 29eb839443058e2bf953566c8db99131c1542e0e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 18:49:06 +0200 Subject: [PATCH 09/92] drm/i915/dkl: convert intel_dkl_phy.[ch] to struct intel_display Going forward, struct intel_display is the main display device data pointer. Convert intel_dkl_phy.[ch] to struct intel_display. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/fce153dbd3a69dc574a66fb97b7c1f441df9726f.1740502116.git.jani.nikula@intel.com [Jani: Fix a missing include while applying] Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_driver.c | 2 +- drivers/gpu/drm/i915/display/intel_dkl_phy.c | 8 ++++---- drivers/gpu/drm/i915/display/intel_dkl_phy.h | 3 +-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index defe08df9e97..08585962a23b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -194,7 +194,7 @@ void intel_display_driver_early_probe(struct intel_display *display) mutex_init(&display->hdcp.hdcp_mutex); intel_display_irq_init(i915); - intel_dkl_phy_init(i915); + intel_dkl_phy_init(display); intel_color_init_hooks(display); intel_init_cdclk_hooks(display); intel_audio_hooks_init(display); diff --git a/drivers/gpu/drm/i915/display/intel_dkl_phy.c b/drivers/gpu/drm/i915/display/intel_dkl_phy.c index 0920f78f182e..0813fb9b5823 100644 --- a/drivers/gpu/drm/i915/display/intel_dkl_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dkl_phy.c @@ -3,7 +3,7 @@ * Copyright © 2022 Intel Corporation */ -#include "i915_drv.h" +#include #include "intel_de.h" #include "intel_display.h" @@ -12,11 +12,11 @@ /** * intel_dkl_phy_init - initialize Dekel PHY - * @i915: i915 device instance + * @display: display device instance */ -void intel_dkl_phy_init(struct drm_i915_private *i915) +void intel_dkl_phy_init(struct intel_display *display) { - spin_lock_init(&i915->display.dkl.phy_lock); + spin_lock_init(&display->dkl.phy_lock); } static void diff --git a/drivers/gpu/drm/i915/display/intel_dkl_phy.h b/drivers/gpu/drm/i915/display/intel_dkl_phy.h index 1d96e6be657c..ccb445c0022b 100644 --- a/drivers/gpu/drm/i915/display/intel_dkl_phy.h +++ b/drivers/gpu/drm/i915/display/intel_dkl_phy.h @@ -10,10 +10,9 @@ #include "intel_dkl_phy_regs.h" -struct drm_i915_private; struct intel_display; -void intel_dkl_phy_init(struct drm_i915_private *i915); +void intel_dkl_phy_init(struct intel_display *display); u32 intel_dkl_phy_read(struct intel_display *display, struct intel_dkl_phy_reg reg); void From 8266c81710942876d87c4684eca417e70c0d631a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 18:49:07 +0200 Subject: [PATCH 10/92] drm/i915/drrs: convert intel_drrs.[ch] to struct intel_display Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of intel_drrs.[ch] to struct intel_display. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/02a5189e349f91e58d3907fdf8d0d3c4c5384f4d.1740502116.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 4 +- drivers/gpu/drm/i915/display/intel_drrs.c | 39 +++++++++---------- drivers/gpu/drm/i915/display/intel_drrs.h | 10 ++--- .../gpu/drm/i915/display/intel_frontbuffer.c | 4 +- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 0e501ec7e73a..267b05b742be 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2912,7 +2912,7 @@ static bool can_enable_drrs(struct intel_connector *connector, const struct intel_crtc_state *pipe_config, const struct drm_display_mode *downclock_mode) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); if (pipe_config->vrr.enable) return false; @@ -2930,7 +2930,7 @@ static bool can_enable_drrs(struct intel_connector *connector, if (pipe_config->has_pch_encoder) return false; - if (!intel_cpu_transcoder_has_drrs(i915, pipe_config->cpu_transcoder)) + if (!intel_cpu_transcoder_has_drrs(display, pipe_config->cpu_transcoder)) return false; return downclock_mode && diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c index 0fec01b79b23..bf420400b505 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.c +++ b/drivers/gpu/drm/i915/display/intel_drrs.c @@ -65,10 +65,10 @@ const char *intel_drrs_type_str(enum drrs_type drrs_type) return str[drrs_type]; } -bool intel_cpu_transcoder_has_drrs(struct drm_i915_private *i915, +bool intel_cpu_transcoder_has_drrs(struct intel_display *display, enum transcoder cpu_transcoder) { - struct intel_display *display = &i915->display; + struct drm_i915_private *i915 = to_i915(display->drm); if (HAS_DOUBLE_BUFFERED_M_N(display)) return true; @@ -80,16 +80,16 @@ static void intel_drrs_set_refresh_rate_pipeconf(struct intel_crtc *crtc, enum drrs_refresh_rate refresh_rate) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); enum transcoder cpu_transcoder = crtc->drrs.cpu_transcoder; u32 bit; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if (display->platform.valleyview || display->platform.cherryview) bit = TRANSCONF_REFRESH_RATE_ALT_VLV; else bit = TRANSCONF_REFRESH_RATE_ALT_ILK; - intel_de_rmw(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), + intel_de_rmw(display, TRANSCONF(display, cpu_transcoder), bit, refresh_rate == DRRS_REFRESH_RATE_LOW ? bit : 0); } @@ -132,13 +132,13 @@ static void intel_drrs_schedule_work(struct intel_crtc *crtc) static unsigned int intel_drrs_frontbuffer_bits(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); unsigned int frontbuffer_bits; frontbuffer_bits = INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe); - for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, crtc_state->joiner_pipes) frontbuffer_bits |= INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe); @@ -222,13 +222,13 @@ static void intel_drrs_downclock_work(struct work_struct *work) mutex_unlock(&crtc->drrs.mutex); } -static void intel_drrs_frontbuffer_update(struct drm_i915_private *dev_priv, +static void intel_drrs_frontbuffer_update(struct intel_display *display, unsigned int all_frontbuffer_bits, bool invalidate) { struct intel_crtc *crtc; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { unsigned int frontbuffer_bits; mutex_lock(&crtc->drrs.mutex); @@ -262,7 +262,7 @@ static void intel_drrs_frontbuffer_update(struct drm_i915_private *dev_priv, /** * intel_drrs_invalidate - Disable Idleness DRRS - * @dev_priv: i915 device + * @display: display device * @frontbuffer_bits: frontbuffer plane tracking bits * * This function gets called everytime rendering on the given planes start. @@ -270,15 +270,15 @@ static void intel_drrs_frontbuffer_update(struct drm_i915_private *dev_priv, * * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. */ -void intel_drrs_invalidate(struct drm_i915_private *dev_priv, +void intel_drrs_invalidate(struct intel_display *display, unsigned int frontbuffer_bits) { - intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, true); + intel_drrs_frontbuffer_update(display, frontbuffer_bits, true); } /** * intel_drrs_flush - Restart Idleness DRRS - * @dev_priv: i915 device + * @display: display device * @frontbuffer_bits: frontbuffer plane tracking bits * * This function gets called every time rendering on the given planes has @@ -288,10 +288,10 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv, * * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. */ -void intel_drrs_flush(struct drm_i915_private *dev_priv, +void intel_drrs_flush(struct intel_display *display, unsigned int frontbuffer_bits) { - intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, false); + intel_drrs_frontbuffer_update(display, frontbuffer_bits, false); } /** @@ -312,7 +312,7 @@ void intel_drrs_crtc_init(struct intel_crtc *crtc) static int intel_drrs_debugfs_status_show(struct seq_file *m, void *unused) { struct intel_crtc *crtc = m->private; - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *crtc_state; int ret; @@ -325,7 +325,7 @@ static int intel_drrs_debugfs_status_show(struct seq_file *m, void *unused) mutex_lock(&crtc->drrs.mutex); seq_printf(m, "DRRS capable: %s\n", - str_yes_no(intel_cpu_transcoder_has_drrs(i915, + str_yes_no(intel_cpu_transcoder_has_drrs(display, crtc_state->cpu_transcoder))); seq_printf(m, "DRRS enabled: %s\n", @@ -353,7 +353,7 @@ DEFINE_SHOW_ATTRIBUTE(intel_drrs_debugfs_status); static int intel_drrs_debugfs_ctl_set(void *data, u64 val) { struct intel_crtc *crtc = data; - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_crtc_state *crtc_state; struct drm_crtc_commit *commit; int ret; @@ -375,8 +375,7 @@ static int intel_drrs_debugfs_ctl_set(void *data, u64 val) goto out; } - drm_dbg(&i915->drm, - "Manually %sactivating DRRS\n", val ? "" : "de"); + drm_dbg_kms(display->drm, "Manually %sactivating DRRS\n", val ? "" : "de"); if (val) intel_drrs_activate(crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h index 0982f95eab72..32b45a93a68f 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.h +++ b/drivers/gpu/drm/i915/display/intel_drrs.h @@ -10,21 +10,21 @@ enum drrs_type; enum transcoder; -struct drm_i915_private; struct intel_atomic_state; +struct intel_connector; struct intel_crtc; struct intel_crtc_state; -struct intel_connector; +struct intel_display; -bool intel_cpu_transcoder_has_drrs(struct drm_i915_private *i915, +bool intel_cpu_transcoder_has_drrs(struct intel_display *display, enum transcoder cpu_transcoder); const char *intel_drrs_type_str(enum drrs_type drrs_type); bool intel_drrs_is_active(struct intel_crtc *crtc); void intel_drrs_activate(const struct intel_crtc_state *crtc_state); void intel_drrs_deactivate(const struct intel_crtc_state *crtc_state); -void intel_drrs_invalidate(struct drm_i915_private *dev_priv, +void intel_drrs_invalidate(struct intel_display *display, unsigned int frontbuffer_bits); -void intel_drrs_flush(struct drm_i915_private *dev_priv, +void intel_drrs_flush(struct intel_display *display, unsigned int frontbuffer_bits); void intel_drrs_crtc_init(struct intel_crtc *crtc); void intel_drrs_crtc_debugfs_add(struct intel_crtc *crtc); diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index 2fa4b0bf27c3..89a145b3194c 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -99,7 +99,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915, might_sleep(); intel_td_flush(display); - intel_drrs_flush(i915, frontbuffer_bits); + intel_drrs_flush(display, frontbuffer_bits); intel_psr_flush(display, frontbuffer_bits, origin); intel_fbc_flush(i915, frontbuffer_bits, origin); } @@ -189,7 +189,7 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front, might_sleep(); intel_psr_invalidate(display, frontbuffer_bits, origin); - intel_drrs_invalidate(i915, frontbuffer_bits); + intel_drrs_invalidate(display, frontbuffer_bits); intel_fbc_invalidate(i915, frontbuffer_bits, origin); } From c9c672db1f9440e875ccb9b3f026edc516abd667 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 18:49:08 +0200 Subject: [PATCH 11/92] drm/i915/display: convert the M/N functions to struct intel_display Going forward, struct intel_display is the main display device data pointer. Convert the functions to set/get M/N values and check for M2/N2 support to struct intel_display. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/8ac3472fe8e6647c0da57013c8bef575d8324a88.1740502116.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 88 +++++++++---------- drivers/gpu/drm/i915/display/intel_display.h | 6 +- drivers/gpu/drm/i915/display/intel_dp.c | 3 +- drivers/gpu/drm/i915/display/intel_drrs.c | 8 +- .../gpu/drm/i915/display/intel_pch_display.c | 16 ++-- 5 files changed, 59 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e2b1445b4a66..3b8f619dab5e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2662,45 +2662,45 @@ void intel_zero_m_n(struct intel_link_m_n *m_n) m_n->tu = 1; } -void intel_set_m_n(struct drm_i915_private *i915, +void intel_set_m_n(struct intel_display *display, const struct intel_link_m_n *m_n, i915_reg_t data_m_reg, i915_reg_t data_n_reg, i915_reg_t link_m_reg, i915_reg_t link_n_reg) { - intel_de_write(i915, data_m_reg, TU_SIZE(m_n->tu) | m_n->data_m); - intel_de_write(i915, data_n_reg, m_n->data_n); - intel_de_write(i915, link_m_reg, m_n->link_m); + intel_de_write(display, data_m_reg, TU_SIZE(m_n->tu) | m_n->data_m); + intel_de_write(display, data_n_reg, m_n->data_n); + intel_de_write(display, link_m_reg, m_n->link_m); /* * On BDW+ writing LINK_N arms the double buffered update * of all the M/N registers, so it must be written last. */ - intel_de_write(i915, link_n_reg, m_n->link_n); + intel_de_write(display, link_n_reg, m_n->link_n); } -bool intel_cpu_transcoder_has_m2_n2(struct drm_i915_private *dev_priv, +bool intel_cpu_transcoder_has_m2_n2(struct intel_display *display, enum transcoder transcoder) { - if (IS_HASWELL(dev_priv)) + if (display->platform.haswell) return transcoder == TRANSCODER_EDP; - return IS_DISPLAY_VER(dev_priv, 5, 7) || IS_CHERRYVIEW(dev_priv); + return IS_DISPLAY_VER(display, 5, 7) || display->platform.cherryview; } void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc, enum transcoder transcoder, const struct intel_link_m_n *m_n) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); enum pipe pipe = crtc->pipe; - if (DISPLAY_VER(dev_priv) >= 5) - intel_set_m_n(dev_priv, m_n, - PIPE_DATA_M1(dev_priv, transcoder), - PIPE_DATA_N1(dev_priv, transcoder), - PIPE_LINK_M1(dev_priv, transcoder), - PIPE_LINK_N1(dev_priv, transcoder)); + if (DISPLAY_VER(display) >= 5) + intel_set_m_n(display, m_n, + PIPE_DATA_M1(display, transcoder), + PIPE_DATA_N1(display, transcoder), + PIPE_LINK_M1(display, transcoder), + PIPE_LINK_N1(display, transcoder)); else - intel_set_m_n(dev_priv, m_n, + intel_set_m_n(display, m_n, PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe), PIPE_LINK_M_G4X(pipe), PIPE_LINK_N_G4X(pipe)); } @@ -2709,16 +2709,16 @@ void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc, enum transcoder transcoder, const struct intel_link_m_n *m_n) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); - if (!intel_cpu_transcoder_has_m2_n2(dev_priv, transcoder)) + if (!intel_cpu_transcoder_has_m2_n2(display, transcoder)) return; - intel_set_m_n(dev_priv, m_n, - PIPE_DATA_M2(dev_priv, transcoder), - PIPE_DATA_N2(dev_priv, transcoder), - PIPE_LINK_M2(dev_priv, transcoder), - PIPE_LINK_N2(dev_priv, transcoder)); + intel_set_m_n(display, m_n, + PIPE_DATA_M2(display, transcoder), + PIPE_DATA_N2(display, transcoder), + PIPE_LINK_M2(display, transcoder), + PIPE_LINK_N2(display, transcoder)); } static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state) @@ -3404,33 +3404,33 @@ int ilk_get_lanes_required(int target_clock, int link_bw, int bpp) return DIV_ROUND_UP(bps, link_bw * 8); } -void intel_get_m_n(struct drm_i915_private *i915, +void intel_get_m_n(struct intel_display *display, struct intel_link_m_n *m_n, i915_reg_t data_m_reg, i915_reg_t data_n_reg, i915_reg_t link_m_reg, i915_reg_t link_n_reg) { - m_n->link_m = intel_de_read(i915, link_m_reg) & DATA_LINK_M_N_MASK; - m_n->link_n = intel_de_read(i915, link_n_reg) & DATA_LINK_M_N_MASK; - m_n->data_m = intel_de_read(i915, data_m_reg) & DATA_LINK_M_N_MASK; - m_n->data_n = intel_de_read(i915, data_n_reg) & DATA_LINK_M_N_MASK; - m_n->tu = REG_FIELD_GET(TU_SIZE_MASK, intel_de_read(i915, data_m_reg)) + 1; + m_n->link_m = intel_de_read(display, link_m_reg) & DATA_LINK_M_N_MASK; + m_n->link_n = intel_de_read(display, link_n_reg) & DATA_LINK_M_N_MASK; + m_n->data_m = intel_de_read(display, data_m_reg) & DATA_LINK_M_N_MASK; + m_n->data_n = intel_de_read(display, data_n_reg) & DATA_LINK_M_N_MASK; + m_n->tu = REG_FIELD_GET(TU_SIZE_MASK, intel_de_read(display, data_m_reg)) + 1; } void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc, enum transcoder transcoder, struct intel_link_m_n *m_n) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); enum pipe pipe = crtc->pipe; - if (DISPLAY_VER(dev_priv) >= 5) - intel_get_m_n(dev_priv, m_n, - PIPE_DATA_M1(dev_priv, transcoder), - PIPE_DATA_N1(dev_priv, transcoder), - PIPE_LINK_M1(dev_priv, transcoder), - PIPE_LINK_N1(dev_priv, transcoder)); + if (DISPLAY_VER(display) >= 5) + intel_get_m_n(display, m_n, + PIPE_DATA_M1(display, transcoder), + PIPE_DATA_N1(display, transcoder), + PIPE_LINK_M1(display, transcoder), + PIPE_LINK_N1(display, transcoder)); else - intel_get_m_n(dev_priv, m_n, + intel_get_m_n(display, m_n, PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe), PIPE_LINK_M_G4X(pipe), PIPE_LINK_N_G4X(pipe)); } @@ -3439,16 +3439,16 @@ void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc, enum transcoder transcoder, struct intel_link_m_n *m_n) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); - if (!intel_cpu_transcoder_has_m2_n2(dev_priv, transcoder)) + if (!intel_cpu_transcoder_has_m2_n2(display, transcoder)) return; - intel_get_m_n(dev_priv, m_n, - PIPE_DATA_M2(dev_priv, transcoder), - PIPE_DATA_N2(dev_priv, transcoder), - PIPE_LINK_M2(dev_priv, transcoder), - PIPE_LINK_N2(dev_priv, transcoder)); + intel_get_m_n(display, m_n, + PIPE_DATA_M2(display, transcoder), + PIPE_DATA_N2(display, transcoder), + PIPE_LINK_M2(display, transcoder), + PIPE_LINK_N2(display, transcoder)); } static void ilk_get_pfit_config(struct intel_crtc_state *crtc_state) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 91f01e81a8f0..f8b8610b0280 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -481,15 +481,15 @@ int ilk_get_lanes_required(int target_clock, int link_bw, int bpp); bool intel_fuzzy_clock_check(int clock1, int clock2); void intel_zero_m_n(struct intel_link_m_n *m_n); -void intel_set_m_n(struct drm_i915_private *i915, +void intel_set_m_n(struct intel_display *display, const struct intel_link_m_n *m_n, i915_reg_t data_m_reg, i915_reg_t data_n_reg, i915_reg_t link_m_reg, i915_reg_t link_n_reg); -void intel_get_m_n(struct drm_i915_private *i915, +void intel_get_m_n(struct intel_display *display, struct intel_link_m_n *m_n, i915_reg_t data_m_reg, i915_reg_t data_n_reg, i915_reg_t link_m_reg, i915_reg_t link_n_reg); -bool intel_cpu_transcoder_has_m2_n2(struct drm_i915_private *dev_priv, +bool intel_cpu_transcoder_has_m2_n2(struct intel_display *display, enum transcoder transcoder); void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc, enum transcoder cpu_transcoder, diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 267b05b742be..f61d716bad00 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2943,7 +2943,6 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, int link_bpp_x16) { struct intel_display *display = to_intel_display(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); const struct drm_display_mode *downclock_mode = intel_panel_downclock_mode(connector, &pipe_config->hw.adjusted_mode); int pixel_clock; @@ -2956,7 +2955,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, pipe_config->update_m_n = true; if (!can_enable_drrs(connector, pipe_config, downclock_mode)) { - if (intel_cpu_transcoder_has_m2_n2(i915, pipe_config->cpu_transcoder)) + if (intel_cpu_transcoder_has_m2_n2(display, pipe_config->cpu_transcoder)) intel_zero_m_n(&pipe_config->dp_m2_n2); return; } diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c index bf420400b505..05cd0f6e6d71 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.c +++ b/drivers/gpu/drm/i915/display/intel_drrs.c @@ -68,12 +68,10 @@ const char *intel_drrs_type_str(enum drrs_type drrs_type) bool intel_cpu_transcoder_has_drrs(struct intel_display *display, enum transcoder cpu_transcoder) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (HAS_DOUBLE_BUFFERED_M_N(display)) return true; - return intel_cpu_transcoder_has_m2_n2(i915, cpu_transcoder); + return intel_cpu_transcoder_has_m2_n2(display, cpu_transcoder); } static void @@ -110,12 +108,12 @@ bool intel_drrs_is_active(struct intel_crtc *crtc) static void intel_drrs_set_state(struct intel_crtc *crtc, enum drrs_refresh_rate refresh_rate) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); if (refresh_rate == crtc->drrs.refresh_rate) return; - if (intel_cpu_transcoder_has_m2_n2(dev_priv, crtc->drrs.cpu_transcoder)) + if (intel_cpu_transcoder_has_m2_n2(display, crtc->drrs.cpu_transcoder)) intel_drrs_set_refresh_rate_pipeconf(crtc, refresh_rate); else intel_drrs_set_refresh_rate_m_n(crtc, refresh_rate); diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.c b/drivers/gpu/drm/i915/display/intel_pch_display.c index 1abe0a784570..806729ec73c8 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_display.c +++ b/drivers/gpu/drm/i915/display/intel_pch_display.c @@ -181,10 +181,10 @@ static void ibx_sanitize_pch_ports(struct drm_i915_private *dev_priv) static void intel_pch_transcoder_set_m1_n1(struct intel_crtc *crtc, const struct intel_link_m_n *m_n) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); enum pipe pipe = crtc->pipe; - intel_set_m_n(dev_priv, m_n, + intel_set_m_n(display, m_n, PCH_TRANS_DATA_M1(pipe), PCH_TRANS_DATA_N1(pipe), PCH_TRANS_LINK_M1(pipe), PCH_TRANS_LINK_N1(pipe)); } @@ -192,10 +192,10 @@ static void intel_pch_transcoder_set_m1_n1(struct intel_crtc *crtc, static void intel_pch_transcoder_set_m2_n2(struct intel_crtc *crtc, const struct intel_link_m_n *m_n) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); enum pipe pipe = crtc->pipe; - intel_set_m_n(dev_priv, m_n, + intel_set_m_n(display, m_n, PCH_TRANS_DATA_M2(pipe), PCH_TRANS_DATA_N2(pipe), PCH_TRANS_LINK_M2(pipe), PCH_TRANS_LINK_N2(pipe)); } @@ -203,10 +203,10 @@ static void intel_pch_transcoder_set_m2_n2(struct intel_crtc *crtc, void intel_pch_transcoder_get_m1_n1(struct intel_crtc *crtc, struct intel_link_m_n *m_n) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); enum pipe pipe = crtc->pipe; - intel_get_m_n(dev_priv, m_n, + intel_get_m_n(display, m_n, PCH_TRANS_DATA_M1(pipe), PCH_TRANS_DATA_N1(pipe), PCH_TRANS_LINK_M1(pipe), PCH_TRANS_LINK_N1(pipe)); } @@ -214,10 +214,10 @@ void intel_pch_transcoder_get_m1_n1(struct intel_crtc *crtc, void intel_pch_transcoder_get_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); enum pipe pipe = crtc->pipe; - intel_get_m_n(dev_priv, m_n, + intel_get_m_n(display, m_n, PCH_TRANS_DATA_M2(pipe), PCH_TRANS_DATA_N2(pipe), PCH_TRANS_LINK_M2(pipe), PCH_TRANS_LINK_N2(pipe)); } From d1bba730a1052bf6a3648307b77b7e563b011718 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 18:49:09 +0200 Subject: [PATCH 12/92] drm/i915/dpt: convert intel_dpt.[ch] interfaces to struct intel_display Going forward, struct intel_display is the main display device data pointer. Convert the intel_dpt.[ch] interfaces to struct intel_display, though the file being very i915 specific, it's hard to convert the implementation. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/df2bf715639caeb662f08b776ba81bfe3c9288b9.1740502116.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dpt.c | 24 ++++++++++++------------ drivers/gpu/drm/i915/display/intel_dpt.h | 7 +++---- drivers/gpu/drm/i915/i915_driver.c | 4 ++-- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index 8b1f0e92a11c..fca7294b1def 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -183,7 +183,7 @@ void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm) /** * intel_dpt_resume - restore the memory mapping for all DPT FBs during system resume - * @i915: device instance + * @display: display device instance * * Restore the memory mapping during system resume for all framebuffers which * are mapped to HW via a GGTT->DPT page table. The content of these page @@ -193,26 +193,26 @@ void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm) * This function must be called after the mappings in GGTT have been restored calling * i915_ggtt_resume(). */ -void intel_dpt_resume(struct drm_i915_private *i915) +void intel_dpt_resume(struct intel_display *display) { struct drm_framebuffer *drm_fb; - if (!HAS_DISPLAY(i915)) + if (!HAS_DISPLAY(display)) return; - mutex_lock(&i915->drm.mode_config.fb_lock); - drm_for_each_fb(drm_fb, &i915->drm) { + mutex_lock(&display->drm->mode_config.fb_lock); + drm_for_each_fb(drm_fb, display->drm) { struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb); if (fb->dpt_vm) i915_ggtt_resume_vm(fb->dpt_vm, true); } - mutex_unlock(&i915->drm.mode_config.fb_lock); + mutex_unlock(&display->drm->mode_config.fb_lock); } /** * intel_dpt_suspend - suspend the memory mapping for all DPT FBs during system suspend - * @i915: device instance + * @display: display device instance * * Suspend the memory mapping during system suspend for all framebuffers which * are mapped to HW via a GGTT->DPT page table. @@ -220,23 +220,23 @@ void intel_dpt_resume(struct drm_i915_private *i915) * This function must be called before the mappings in GGTT are suspended calling * i915_ggtt_suspend(). */ -void intel_dpt_suspend(struct drm_i915_private *i915) +void intel_dpt_suspend(struct intel_display *display) { struct drm_framebuffer *drm_fb; - if (!HAS_DISPLAY(i915)) + if (!HAS_DISPLAY(display)) return; - mutex_lock(&i915->drm.mode_config.fb_lock); + mutex_lock(&display->drm->mode_config.fb_lock); - drm_for_each_fb(drm_fb, &i915->drm) { + drm_for_each_fb(drm_fb, display->drm) { struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb); if (fb->dpt_vm) i915_ggtt_suspend_vm(fb->dpt_vm, true); } - mutex_unlock(&i915->drm.mode_config.fb_lock); + mutex_unlock(&display->drm->mode_config.fb_lock); } struct i915_address_space * diff --git a/drivers/gpu/drm/i915/display/intel_dpt.h b/drivers/gpu/drm/i915/display/intel_dpt.h index 1f88b0ee17e7..db521401b828 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.h +++ b/drivers/gpu/drm/i915/display/intel_dpt.h @@ -8,18 +8,17 @@ #include -struct drm_i915_private; - struct i915_address_space; struct i915_vma; +struct intel_display; struct intel_framebuffer; void intel_dpt_destroy(struct i915_address_space *vm); struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, unsigned int alignment); void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm); -void intel_dpt_suspend(struct drm_i915_private *i915); -void intel_dpt_resume(struct drm_i915_private *i915); +void intel_dpt_suspend(struct intel_display *display); +void intel_dpt_resume(struct intel_display *display); struct i915_address_space * intel_dpt_create(struct intel_framebuffer *fb); u64 intel_dpt_offset(struct i915_vma *dpt_vma); diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 91a7748f4492..ccdfa137c2e0 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1075,7 +1075,7 @@ static int i915_drm_suspend(struct drm_device *dev) intel_encoder_suspend_all(&dev_priv->display); /* Must be called before GGTT is suspended. */ - intel_dpt_suspend(dev_priv); + intel_dpt_suspend(display); i915_ggtt_suspend(to_gt(dev_priv)->ggtt); i9xx_display_sr_save(display); @@ -1192,7 +1192,7 @@ static int i915_drm_resume(struct drm_device *dev) setup_private_pat(gt); /* Must be called after GGTT is resumed. */ - intel_dpt_resume(dev_priv); + intel_dpt_resume(display); intel_dmc_resume(display); From ecddc26b4c9b72c86265536c2ebf31f7637683fe Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 18:49:10 +0200 Subject: [PATCH 13/92] drm/i915/fbc: convert intel_fbc.[ch] to struct intel_display Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of intel_fbc.[ch] to struct intel_display. In a few places, change the variable declaration order to prefer having display first. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/4dfd7d62e99b75d26563bdf29f541ed2ffbe548e.1740502116.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_fbc.c | 113 +++++++----------- drivers/gpu/drm/i915/display/intel_fbc.h | 6 +- .../gpu/drm/i915/display/intel_frontbuffer.c | 5 +- 3 files changed, 51 insertions(+), 73 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index df05904bac8a..33142427f121 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -215,11 +215,9 @@ static unsigned int intel_fbc_cfb_stride(const struct intel_plane_state *plane_s */ static unsigned int intel_fbc_max_cfb_height(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (DISPLAY_VER(display) >= 8) return 2560; - else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915)) + else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) return 2048; else return 1536; @@ -269,9 +267,8 @@ static bool intel_fbc_has_fences(struct intel_display *display) static u32 i8xx_fbc_ctl(struct intel_fbc *fbc) { - const struct intel_fbc_state *fbc_state = &fbc->state; struct intel_display *display = fbc->display; - struct drm_i915_private *i915 = to_i915(display->drm); + const struct intel_fbc_state *fbc_state = &fbc->state; unsigned int cfb_stride; u32 fbc_ctl; @@ -287,7 +284,7 @@ static u32 i8xx_fbc_ctl(struct intel_fbc *fbc) FBC_CTL_INTERVAL(fbc_state->interval) | FBC_CTL_STRIDE(cfb_stride); - if (IS_I945GM(i915)) + if (display->platform.i945gm) fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ if (fbc_state->fence_id >= 0) @@ -333,8 +330,8 @@ static void i8xx_fbc_deactivate(struct intel_fbc *fbc) static void i8xx_fbc_activate(struct intel_fbc *fbc) { - const struct intel_fbc_state *fbc_state = &fbc->state; struct intel_display *display = fbc->display; + const struct intel_fbc_state *fbc_state = &fbc->state; int i; /* Clear old tags */ @@ -365,12 +362,12 @@ static bool i8xx_fbc_is_compressing(struct intel_fbc *fbc) static void i8xx_fbc_nuke(struct intel_fbc *fbc) { + struct intel_display *display = fbc->display; struct intel_fbc_state *fbc_state = &fbc->state; enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane; - struct drm_i915_private *dev_priv = to_i915(fbc->display->drm); - intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane), - intel_de_read_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane))); + intel_de_write_fw(display, DSPADDR(display, i9xx_plane), + intel_de_read_fw(display, DSPADDR(display, i9xx_plane))); } static void i8xx_fbc_program_cfb(struct intel_fbc *fbc) @@ -386,9 +383,9 @@ static void i8xx_fbc_program_cfb(struct intel_fbc *fbc) range_overflows_end_t(u64, i915_gem_stolen_area_address(i915), i915_gem_stolen_node_offset(&fbc->compressed_llb), U32_MAX)); - intel_de_write(i915, FBC_CFB_BASE, + intel_de_write(display, FBC_CFB_BASE, i915_gem_stolen_node_address(i915, &fbc->compressed_fb)); - intel_de_write(i915, FBC_LL_BASE, + intel_de_write(display, FBC_LL_BASE, i915_gem_stolen_node_address(i915, &fbc->compressed_llb)); } @@ -403,12 +400,12 @@ static const struct intel_fbc_funcs i8xx_fbc_funcs = { static void i965_fbc_nuke(struct intel_fbc *fbc) { + struct intel_display *display = fbc->display; struct intel_fbc_state *fbc_state = &fbc->state; enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane; - struct drm_i915_private *dev_priv = to_i915(fbc->display->drm); - intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane), - intel_de_read_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane))); + intel_de_write_fw(display, DSPSURF(display, i9xx_plane), + intel_de_read_fw(display, DSPSURF(display, i9xx_plane))); } static const struct intel_fbc_funcs i965_fbc_funcs = { @@ -437,15 +434,14 @@ static u32 g4x_dpfc_ctl_limit(struct intel_fbc *fbc) static u32 g4x_dpfc_ctl(struct intel_fbc *fbc) { - const struct intel_fbc_state *fbc_state = &fbc->state; struct intel_display *display = fbc->display; - struct drm_i915_private *i915 = to_i915(display->drm); + const struct intel_fbc_state *fbc_state = &fbc->state; u32 dpfc_ctl; dpfc_ctl = g4x_dpfc_ctl_limit(fbc) | DPFC_CTL_PLANE_G4X(fbc_state->plane->i9xx_plane); - if (IS_G4X(i915)) + if (display->platform.g4x) dpfc_ctl |= DPFC_CTL_SR_EN; if (fbc_state->fence_id >= 0) { @@ -460,8 +456,8 @@ static u32 g4x_dpfc_ctl(struct intel_fbc *fbc) static void g4x_fbc_activate(struct intel_fbc *fbc) { - const struct intel_fbc_state *fbc_state = &fbc->state; struct intel_display *display = fbc->display; + const struct intel_fbc_state *fbc_state = &fbc->state; intel_de_write(display, DPFC_FENCE_YOFF, fbc_state->fence_y_offset); @@ -512,8 +508,8 @@ static const struct intel_fbc_funcs g4x_fbc_funcs = { static void ilk_fbc_activate(struct intel_fbc *fbc) { - struct intel_fbc_state *fbc_state = &fbc->state; struct intel_display *display = fbc->display; + struct intel_fbc_state *fbc_state = &fbc->state; intel_de_write(display, ILK_DPFC_FENCE_YOFF(fbc->id), fbc_state->fence_y_offset); @@ -564,8 +560,8 @@ static const struct intel_fbc_funcs ilk_fbc_funcs = { static void snb_fbc_program_fence(struct intel_fbc *fbc) { - const struct intel_fbc_state *fbc_state = &fbc->state; struct intel_display *display = fbc->display; + const struct intel_fbc_state *fbc_state = &fbc->state; u32 ctl = 0; if (fbc_state->fence_id >= 0) @@ -601,8 +597,8 @@ static const struct intel_fbc_funcs snb_fbc_funcs = { static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc) { - const struct intel_fbc_state *fbc_state = &fbc->state; struct intel_display *display = fbc->display; + const struct intel_fbc_state *fbc_state = &fbc->state; u32 val = 0; if (fbc_state->override_cfb_stride) @@ -614,8 +610,8 @@ static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc) static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc) { - const struct intel_fbc_state *fbc_state = &fbc->state; struct intel_display *display = fbc->display; + const struct intel_fbc_state *fbc_state = &fbc->state; u32 val = 0; /* Display WA #0529: skl, kbl, bxt. */ @@ -630,14 +626,13 @@ static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc) static u32 ivb_dpfc_ctl(struct intel_fbc *fbc) { - const struct intel_fbc_state *fbc_state = &fbc->state; struct intel_display *display = fbc->display; - struct drm_i915_private *i915 = to_i915(display->drm); + const struct intel_fbc_state *fbc_state = &fbc->state; u32 dpfc_ctl; dpfc_ctl = g4x_dpfc_ctl_limit(fbc); - if (IS_IVYBRIDGE(i915)) + if (display->platform.ivybridge) dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane); if (DISPLAY_VER(display) >= 20) @@ -759,9 +754,7 @@ static void intel_fbc_deactivate(struct intel_fbc *fbc, const char *reason) static u64 intel_fbc_cfb_base_max(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - if (DISPLAY_VER(display) >= 5 || IS_G4X(i915)) + if (DISPLAY_VER(display) >= 5 || display->platform.g4x) return BIT_ULL(28); else return BIT_ULL(32); @@ -776,8 +769,8 @@ static u64 intel_fbc_stolen_end(struct intel_display *display) * reserved range size, so it always assumes the maximum (8mb) is used. * If we enable FBC using a CFB on that memory range we'll get FIFO * underruns, even if that range is not reserved by the BIOS. */ - if (IS_BROADWELL(i915) || - (DISPLAY_VER(display) == 9 && !IS_BROXTON(i915))) + if (display->platform.broadwell || + (DISPLAY_VER(display) == 9 && !display->platform.broxton)) end = i915_gem_stolen_area_size(i915) - 8 * 1024 * 1024; else end = U64_MAX; @@ -792,10 +785,8 @@ static int intel_fbc_min_limit(const struct intel_plane_state *plane_state) static int intel_fbc_max_limit(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - /* WaFbcOnly1to1Ratio:ctg */ - if (IS_G4X(i915)) + if (display->platform.g4x) return 1; /* @@ -843,7 +834,7 @@ static int intel_fbc_alloc_cfb(struct intel_fbc *fbc, drm_WARN_ON(display->drm, i915_gem_stolen_node_allocated(&fbc->compressed_llb)); - if (DISPLAY_VER(display) < 5 && !IS_G4X(i915)) { + if (DISPLAY_VER(display) < 5 && !display->platform.g4x) { ret = i915_gem_stolen_insert_node(i915, &fbc->compressed_llb, 4096, 4096); if (ret) @@ -882,9 +873,8 @@ static void intel_fbc_program_cfb(struct intel_fbc *fbc) static void intel_fbc_program_workarounds(struct intel_fbc *fbc) { struct intel_display *display = fbc->display; - struct drm_i915_private *i915 = to_i915(display->drm); - if (IS_SKYLAKE(i915) || IS_BROXTON(i915)) { + if (display->platform.skylake || display->platform.broxton) { /* * WaFbcHighMemBwCorruptionAvoidance:skl,bxt * Display WA #0883: skl,bxt @@ -893,8 +883,8 @@ static void intel_fbc_program_workarounds(struct intel_fbc *fbc) 0, DPFC_DISABLE_DUMMY0); } - if (IS_SKYLAKE(i915) || IS_KABYLAKE(i915) || - IS_COFFEELAKE(i915) || IS_COMETLAKE(i915)) { + if (display->platform.skylake || display->platform.kabylake || + display->platform.coffeelake || display->platform.cometlake) { /* * WaFbcNukeOnHostModify:skl,kbl,cfl * Display WA #0873: skl,kbl,cfl @@ -909,7 +899,7 @@ static void intel_fbc_program_workarounds(struct intel_fbc *fbc) 0, DPFC_CHICKEN_COMP_DUMMY_PIXEL); /* Wa_22014263786:icl,jsl,tgl,dg1,rkl,adls,adlp,mtl */ - if (DISPLAY_VER(display) >= 11 && !IS_DG2(i915)) + if (DISPLAY_VER(display) >= 11 && !display->platform.dg2) intel_de_rmw(display, ILK_DPFC_CHICKEN(fbc->id), 0, DPFC_CHICKEN_FORCE_SLB_INVALIDATION); } @@ -986,13 +976,12 @@ static bool icl_fbc_stride_is_valid(const struct intel_plane_state *plane_state) static bool stride_is_valid(const struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev); - struct drm_i915_private *i915 = to_i915(display->drm); if (DISPLAY_VER(display) >= 11) return icl_fbc_stride_is_valid(plane_state); else if (DISPLAY_VER(display) >= 9) return skl_fbc_stride_is_valid(plane_state); - else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915)) + else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) return g4x_fbc_stride_is_valid(plane_state); else if (DISPLAY_VER(display) == 4) return i965_fbc_stride_is_valid(plane_state); @@ -1023,7 +1012,6 @@ static bool i8xx_fbc_pixel_format_is_valid(const struct intel_plane_state *plane static bool g4x_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev); - struct drm_i915_private *i915 = to_i915(display->drm); const struct drm_framebuffer *fb = plane_state->hw.fb; switch (fb->format->format) { @@ -1032,7 +1020,7 @@ static bool g4x_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_ return true; case DRM_FORMAT_RGB565: /* WaFbcOnly1to1Ratio:ctg */ - if (IS_G4X(i915)) + if (display->platform.g4x) return false; return true; default: @@ -1059,11 +1047,10 @@ static bool lnl_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_ static bool pixel_format_is_valid(const struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev); - struct drm_i915_private *i915 = to_i915(display->drm); if (DISPLAY_VER(display) >= 20) return lnl_fbc_pixel_format_is_valid(plane_state); - else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915)) + else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) return g4x_fbc_pixel_format_is_valid(plane_state); else return i8xx_fbc_pixel_format_is_valid(plane_state); @@ -1094,11 +1081,10 @@ static bool skl_fbc_rotation_is_valid(const struct intel_plane_state *plane_stat static bool rotation_is_valid(const struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane_state->uapi.plane->dev); - struct drm_i915_private *i915 = to_i915(display->drm); if (DISPLAY_VER(display) >= 9) return skl_fbc_rotation_is_valid(plane_state); - else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915)) + else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) return g4x_fbc_rotation_is_valid(plane_state); else return i8xx_fbc_rotation_is_valid(plane_state); @@ -1107,8 +1093,6 @@ static bool rotation_is_valid(const struct intel_plane_state *plane_state) static void intel_fbc_max_surface_size(struct intel_display *display, unsigned int *w, unsigned int *h) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (DISPLAY_VER(display) >= 11) { *w = 8192; *h = 4096; @@ -1118,7 +1102,7 @@ static void intel_fbc_max_surface_size(struct intel_display *display, } else if (DISPLAY_VER(display) >= 7) { *w = 4096; *h = 4096; - } else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915)) { + } else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) { *w = 4096; *h = 2048; } else { @@ -1151,15 +1135,13 @@ static bool intel_fbc_surface_size_ok(const struct intel_plane_state *plane_stat static void intel_fbc_max_plane_size(struct intel_display *display, unsigned int *w, unsigned int *h) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (DISPLAY_VER(display) >= 10) { *w = 5120; *h = 4096; - } else if (DISPLAY_VER(display) >= 8 || IS_HASWELL(i915)) { + } else if (DISPLAY_VER(display) >= 8 || display->platform.haswell) { *w = 4096; *h = 4096; - } else if (DISPLAY_VER(display) >= 5 || IS_G4X(i915)) { + } else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) { *w = 4096; *h = 2048; } else { @@ -1317,7 +1299,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, } /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */ - if (i915_vtd_active(i915) && (IS_SKYLAKE(i915) || IS_BROXTON(i915))) { + if (i915_vtd_active(i915) && (display->platform.skylake || display->platform.broxton)) { plane_state->no_fbc_reason = "VT-d enabled"; return 0; } @@ -1347,7 +1329,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, /* Wa_14016291713 */ if ((IS_DISPLAY_VER(display, 12, 13) || - IS_DISPLAY_VERx100_STEP(i915, 1400, STEP_A0, STEP_C0)) && + IS_DISPLAY_VERx100_STEP(display, 1400, STEP_A0, STEP_C0)) && crtc_state->has_psr && !crtc_state->has_panel_replay) { plane_state->no_fbc_reason = "PSR1 enabled (Wa_14016291713)"; return 0; @@ -1410,7 +1392,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, } /* WaFbcExceedCdClockThreshold:hsw,bdw */ - if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { + if (display->platform.haswell || display->platform.broadwell) { const struct intel_cdclk_state *cdclk_state; cdclk_state = intel_atomic_get_cdclk_state(state); @@ -1614,14 +1596,14 @@ static void __intel_fbc_invalidate(struct intel_fbc *fbc, mutex_unlock(&fbc->lock); } -void intel_fbc_invalidate(struct drm_i915_private *i915, +void intel_fbc_invalidate(struct intel_display *display, unsigned int frontbuffer_bits, enum fb_op_origin origin) { struct intel_fbc *fbc; enum intel_fbc_id fbc_id; - for_each_intel_fbc(&i915->display, fbc, fbc_id) + for_each_intel_fbc(display, fbc, fbc_id) __intel_fbc_invalidate(fbc, frontbuffer_bits, origin); } @@ -1653,14 +1635,14 @@ static void __intel_fbc_flush(struct intel_fbc *fbc, mutex_unlock(&fbc->lock); } -void intel_fbc_flush(struct drm_i915_private *i915, +void intel_fbc_flush(struct intel_display *display, unsigned int frontbuffer_bits, enum fb_op_origin origin) { struct intel_fbc *fbc; enum intel_fbc_id fbc_id; - for_each_intel_fbc(&i915->display, fbc, fbc_id) + for_each_intel_fbc(display, fbc, fbc_id) __intel_fbc_flush(fbc, frontbuffer_bits, origin); } @@ -1897,15 +1879,13 @@ void intel_fbc_handle_fifo_underrun_irq(struct intel_display *display) */ static int intel_sanitize_fbc_option(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (display->params.enable_fbc >= 0) return !!display->params.enable_fbc; if (!HAS_FBC(display)) return 0; - if (IS_BROADWELL(i915) || DISPLAY_VER(display) >= 9) + if (display->platform.broadwell || DISPLAY_VER(display) >= 9) return 1; return 0; @@ -1919,7 +1899,6 @@ void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane) static struct intel_fbc *intel_fbc_create(struct intel_display *display, enum intel_fbc_id fbc_id) { - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_fbc *fbc; fbc = kzalloc(sizeof(*fbc), GFP_KERNEL); @@ -1937,7 +1916,7 @@ static struct intel_fbc *intel_fbc_create(struct intel_display *display, fbc->funcs = &snb_fbc_funcs; else if (DISPLAY_VER(display) == 5) fbc->funcs = &ilk_fbc_funcs; - else if (IS_G4X(i915)) + else if (display->platform.g4x) fbc->funcs = &g4x_fbc_funcs; else if (DISPLAY_VER(display) == 4) fbc->funcs = &i965_fbc_funcs; diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h index ceae55458e14..df20e63d6102 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.h +++ b/drivers/gpu/drm/i915/display/intel_fbc.h @@ -9,11 +9,11 @@ #include enum fb_op_origin; -struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; struct intel_display; +struct intel_display; struct intel_fbc; struct intel_plane; struct intel_plane_state; @@ -38,10 +38,10 @@ void intel_fbc_sanitize(struct intel_display *display); void intel_fbc_update(struct intel_atomic_state *state, struct intel_crtc *crtc); void intel_fbc_disable(struct intel_crtc *crtc); -void intel_fbc_invalidate(struct drm_i915_private *dev_priv, +void intel_fbc_invalidate(struct intel_display *display, unsigned int frontbuffer_bits, enum fb_op_origin origin); -void intel_fbc_flush(struct drm_i915_private *dev_priv, +void intel_fbc_flush(struct intel_display *display, unsigned int frontbuffer_bits, enum fb_op_origin origin); void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane); void intel_fbc_handle_fifo_underrun_irq(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index 89a145b3194c..f023f5a4dba6 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -101,7 +101,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915, intel_td_flush(display); intel_drrs_flush(display, frontbuffer_bits); intel_psr_flush(display, frontbuffer_bits, origin); - intel_fbc_flush(i915, frontbuffer_bits, origin); + intel_fbc_flush(display, frontbuffer_bits, origin); } /** @@ -176,7 +176,6 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front, unsigned int frontbuffer_bits) { struct intel_display *display = to_intel_display(front->obj->dev); - struct drm_i915_private *i915 = to_i915(display->drm); if (origin == ORIGIN_CS) { spin_lock(&display->fb_tracking.lock); @@ -190,7 +189,7 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front, might_sleep(); intel_psr_invalidate(display, frontbuffer_bits, origin); intel_drrs_invalidate(display, frontbuffer_bits); - intel_fbc_invalidate(i915, frontbuffer_bits, origin); + intel_fbc_invalidate(display, frontbuffer_bits, origin); } void __intel_fb_flush(struct intel_frontbuffer *front, From 0fe51805ce64222748310203132bd273483063f3 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 18:49:11 +0200 Subject: [PATCH 14/92] drm/i915/rps: convert intel_display_rps.[ch] to struct intel_display Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of intel_display_rps.[ch] to struct intel_display. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/c81156007bffbf0a1b1e6831afaf8fb05db546bc.1740502116.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_atomic_plane.c | 8 ++++---- drivers/gpu/drm/i915/display/intel_display_rps.c | 4 +++- drivers/gpu/drm/i915/display/intel_display_rps.h | 4 ++-- drivers/gpu/drm/xe/display/xe_display_rps.c | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 124cd9ddba0b..05dcfa3bea73 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -1119,11 +1119,11 @@ intel_prepare_plane_fb(struct drm_plane *_plane, { struct i915_sched_attr attr = { .priority = I915_PRIORITY_DISPLAY }; struct intel_plane *plane = to_intel_plane(_plane); + struct intel_display *display = to_intel_display(plane); struct intel_plane_state *new_plane_state = to_intel_plane_state(_new_plane_state); struct intel_atomic_state *state = to_intel_atomic_state(new_plane_state->uapi.state); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); struct intel_plane_state *old_plane_state = intel_atomic_get_old_plane_state(state, plane); struct drm_gem_object *obj = intel_fb_bo(new_plane_state->hw.fb); @@ -1181,7 +1181,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane, * that are not quite steady state without resorting to forcing * maximum clocks following a vblank miss (see do_rps_boost()). */ - intel_display_rps_mark_interactive(dev_priv, state, true); + intel_display_rps_mark_interactive(display, state, true); return 0; @@ -1202,17 +1202,17 @@ static void intel_cleanup_plane_fb(struct drm_plane *plane, struct drm_plane_state *_old_plane_state) { + struct intel_display *display = to_intel_display(plane->dev); struct intel_plane_state *old_plane_state = to_intel_plane_state(_old_plane_state); struct intel_atomic_state *state = to_intel_atomic_state(old_plane_state->uapi.state); - struct drm_i915_private *dev_priv = to_i915(plane->dev); struct drm_gem_object *obj = intel_fb_bo(old_plane_state->hw.fb); if (!obj) return; - intel_display_rps_mark_interactive(dev_priv, state, false); + intel_display_rps_mark_interactive(display, state, false); intel_plane_unpin_fb(old_plane_state); } diff --git a/drivers/gpu/drm/i915/display/intel_display_rps.c b/drivers/gpu/drm/i915/display/intel_display_rps.c index 918d0327169a..4074a1879828 100644 --- a/drivers/gpu/drm/i915/display/intel_display_rps.c +++ b/drivers/gpu/drm/i915/display/intel_display_rps.c @@ -69,10 +69,12 @@ void intel_display_rps_boost_after_vblank(struct drm_crtc *crtc, add_wait_queue(drm_crtc_vblank_waitqueue(crtc), &wait->wait); } -void intel_display_rps_mark_interactive(struct drm_i915_private *i915, +void intel_display_rps_mark_interactive(struct intel_display *display, struct intel_atomic_state *state, bool interactive) { + struct drm_i915_private *i915 = to_i915(display->drm); + if (state->rps_interactive == interactive) return; diff --git a/drivers/gpu/drm/i915/display/intel_display_rps.h b/drivers/gpu/drm/i915/display/intel_display_rps.h index e19009c2371a..556891edb2dd 100644 --- a/drivers/gpu/drm/i915/display/intel_display_rps.h +++ b/drivers/gpu/drm/i915/display/intel_display_rps.h @@ -10,12 +10,12 @@ struct dma_fence; struct drm_crtc; -struct drm_i915_private; struct intel_atomic_state; +struct intel_display; void intel_display_rps_boost_after_vblank(struct drm_crtc *crtc, struct dma_fence *fence); -void intel_display_rps_mark_interactive(struct drm_i915_private *i915, +void intel_display_rps_mark_interactive(struct intel_display *display, struct intel_atomic_state *state, bool interactive); diff --git a/drivers/gpu/drm/xe/display/xe_display_rps.c b/drivers/gpu/drm/xe/display/xe_display_rps.c index ab21c581c192..fa616f9688a5 100644 --- a/drivers/gpu/drm/xe/display/xe_display_rps.c +++ b/drivers/gpu/drm/xe/display/xe_display_rps.c @@ -10,7 +10,7 @@ void intel_display_rps_boost_after_vblank(struct drm_crtc *crtc, { } -void intel_display_rps_mark_interactive(struct drm_i915_private *i915, +void intel_display_rps_mark_interactive(struct intel_display *display, struct intel_atomic_state *state, bool interactive) { From c4fad8c64e4c561f346ad3bf34dc4d260803ce93 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 18:49:12 +0200 Subject: [PATCH 15/92] drm/i915/ddi: convert intel_wait_ddi_buf_idle() to struct intel_display Convert the intel_ddi.[ch] interfaces to struct intel_display. Postpone further conversion to avoid conflicts. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/2fe5c63f3a7f9861e3bd063b7355aafe32298f37.1740502116.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_ddi.c | 9 +++------ drivers/gpu/drm/i915/display/intel_ddi.h | 4 +--- drivers/gpu/drm/i915/display/intel_fdi.c | 6 ++++-- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index e34bf175262b..780dad5c5de7 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -187,11 +187,8 @@ static i915_reg_t intel_ddi_buf_status_reg(struct intel_display *display, enum p return DDI_BUF_CTL(port); } -void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, - enum port port) +void intel_wait_ddi_buf_idle(struct intel_display *display, enum port port) { - struct intel_display *display = &dev_priv->display; - /* * Bspec's platform specific timeouts: * MTL+ : 100 us @@ -3092,7 +3089,7 @@ static void intel_ddi_buf_disable(struct intel_encoder *encoder, intel_de_rmw(dev_priv, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0); if (DISPLAY_VER(display) >= 14) - intel_wait_ddi_buf_idle(dev_priv, port); + intel_wait_ddi_buf_idle(display, port); mtl_ddi_disable_d2d(encoder); @@ -3104,7 +3101,7 @@ static void intel_ddi_buf_disable(struct intel_encoder *encoder, intel_ddi_disable_fec(encoder, crtc_state); if (DISPLAY_VER(display) < 14) - intel_wait_ddi_buf_idle(dev_priv, port); + intel_wait_ddi_buf_idle(display, port); intel_ddi_wait_for_fec_status(encoder, crtc_state, false); } diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h index 2faadd1441e2..353eb04079e9 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.h +++ b/drivers/gpu/drm/i915/display/intel_ddi.h @@ -9,7 +9,6 @@ #include "i915_reg_defs.h" struct drm_connector_state; -struct drm_i915_private; struct intel_atomic_state; struct intel_bios_encoder_data; struct intel_connector; @@ -54,8 +53,7 @@ void hsw_ddi_get_config(struct intel_encoder *encoder, struct intel_shared_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder); void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); -void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, - enum port port); +void intel_wait_ddi_buf_idle(struct intel_display *display, enum port port); void intel_ddi_init(struct intel_display *display, const struct intel_bios_encoder_data *devdata); bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe); diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 024d0c7e0a88..7e67b3881fd0 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -886,6 +886,7 @@ static void ivb_manual_fdi_link_train(struct intel_crtc *crtc, void hsw_fdi_link_train(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 temp, i, rx_ctl_val; @@ -992,7 +993,7 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, intel_de_rmw(dev_priv, DP_TP_CTL(PORT_E), DP_TP_CTL_ENABLE, 0); intel_de_posting_read(dev_priv, DP_TP_CTL(PORT_E)); - intel_wait_ddi_buf_idle(dev_priv, PORT_E); + intel_wait_ddi_buf_idle(display, PORT_E); /* Reset FDI_RX_MISC pwrdn lanes */ intel_de_rmw(dev_priv, FDI_RX_MISC(PIPE_A), @@ -1011,6 +1012,7 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, void hsw_fdi_disable(struct intel_encoder *encoder) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); /* @@ -1021,7 +1023,7 @@ void hsw_fdi_disable(struct intel_encoder *encoder) */ intel_de_rmw(dev_priv, FDI_RX_CTL(PIPE_A), FDI_RX_ENABLE, 0); intel_de_rmw(dev_priv, DDI_BUF_CTL(PORT_E), DDI_BUF_CTL_ENABLE, 0); - intel_wait_ddi_buf_idle(dev_priv, PORT_E); + intel_wait_ddi_buf_idle(display, PORT_E); intel_ddi_disable_clock(encoder); intel_de_rmw(dev_priv, FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK, From 706184fad005d64f79d3931c70ad443fffe0d988 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 25 Feb 2025 18:49:13 +0200 Subject: [PATCH 16/92] drm/i915/fdi: convert intel_fdi.[ch] to struct intel_display Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of intel_fdi.[ch] to struct intel_display. Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/a1a4ae213a8823734908993f22bdc91517470b19.1740502116.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 4 +- .../drm/i915/display/intel_display_driver.c | 4 +- drivers/gpu/drm/i915/display/intel_fdi.c | 458 +++++++++--------- drivers/gpu/drm/i915/display/intel_fdi.h | 16 +- .../drm/i915/display/intel_modeset_verify.c | 3 +- .../gpu/drm/i915/display/intel_pch_display.c | 19 +- 6 files changed, 247 insertions(+), 257 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3b8f619dab5e..3045f21540d3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1568,8 +1568,8 @@ static void ilk_crtc_enable(struct intel_atomic_state *state, if (new_crtc_state->has_pch_encoder) { ilk_pch_pre_enable(state, crtc); } else { - assert_fdi_tx_disabled(dev_priv, pipe); - assert_fdi_rx_disabled(dev_priv, pipe); + assert_fdi_tx_disabled(display, pipe); + assert_fdi_rx_disabled(display, pipe); } ilk_pfit_enable(new_crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 08585962a23b..eb456ff724a3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -200,7 +200,7 @@ void intel_display_driver_early_probe(struct intel_display *display) intel_audio_hooks_init(display); intel_dpll_init_clock_hook(i915); intel_init_display_hooks(i915); - intel_fdi_init_hook(i915); + intel_fdi_init_hook(display); intel_dmc_wl_init(display); } @@ -449,7 +449,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display) intel_plane_possible_crtcs_init(display); intel_shared_dpll_init(display); - intel_fdi_pll_freq_update(i915); + intel_fdi_pll_freq_update(display); intel_update_czclk(i915); intel_display_driver_init_hw(display); diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 7e67b3881fd0..40deee0769ae 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -24,10 +24,9 @@ struct intel_fdi_funcs { const struct intel_crtc_state *crtc_state); }; -static void assert_fdi_tx(struct drm_i915_private *dev_priv, +static void assert_fdi_tx(struct intel_display *display, enum pipe pipe, bool state) { - struct intel_display *display = &dev_priv->display; bool cur_state; if (HAS_DDI(display)) { @@ -48,20 +47,19 @@ static void assert_fdi_tx(struct drm_i915_private *dev_priv, str_on_off(state), str_on_off(cur_state)); } -void assert_fdi_tx_enabled(struct drm_i915_private *i915, enum pipe pipe) +void assert_fdi_tx_enabled(struct intel_display *display, enum pipe pipe) { - assert_fdi_tx(i915, pipe, true); + assert_fdi_tx(display, pipe, true); } -void assert_fdi_tx_disabled(struct drm_i915_private *i915, enum pipe pipe) +void assert_fdi_tx_disabled(struct intel_display *display, enum pipe pipe) { - assert_fdi_tx(i915, pipe, false); + assert_fdi_tx(display, pipe, false); } -static void assert_fdi_rx(struct drm_i915_private *dev_priv, +static void assert_fdi_rx(struct intel_display *display, enum pipe pipe, bool state) { - struct intel_display *display = &dev_priv->display; bool cur_state; cur_state = intel_de_read(display, FDI_RX_CTL(pipe)) & FDI_RX_ENABLE; @@ -70,18 +68,17 @@ static void assert_fdi_rx(struct drm_i915_private *dev_priv, str_on_off(state), str_on_off(cur_state)); } -void assert_fdi_rx_enabled(struct drm_i915_private *i915, enum pipe pipe) +void assert_fdi_rx_enabled(struct intel_display *display, enum pipe pipe) { - assert_fdi_rx(i915, pipe, true); + assert_fdi_rx(display, pipe, true); } -void assert_fdi_rx_disabled(struct drm_i915_private *i915, enum pipe pipe) +void assert_fdi_rx_disabled(struct intel_display *display, enum pipe pipe) { - assert_fdi_rx(i915, pipe, false); + assert_fdi_rx(display, pipe, false); } -void assert_fdi_tx_pll_enabled(struct intel_display *display, - enum pipe pipe) +void assert_fdi_tx_pll_enabled(struct intel_display *display, enum pipe pipe) { bool cur_state; @@ -122,9 +119,9 @@ void assert_fdi_rx_pll_disabled(struct intel_display *display, enum pipe pipe) void intel_fdi_link_train(struct intel_crtc *crtc, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); - dev_priv->display.funcs.fdi->fdi_link_train(crtc, crtc_state); + display->funcs.fdi->fdi_link_train(crtc, crtc_state); } /** @@ -141,12 +138,11 @@ void intel_fdi_link_train(struct intel_crtc *crtc, int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(state->base.dev); const struct intel_crtc_state *old_crtc_state; const struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; - if (!IS_IVYBRIDGE(i915) || INTEL_NUM_PIPES(i915) != 3) + if (!display->platform.ivybridge || INTEL_NUM_PIPES(display) != 3) return 0; crtc = intel_crtc_for_pipe(display, PIPE_C); @@ -184,31 +180,29 @@ static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state) return 0; } -static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, +static int ilk_check_fdi_lanes(struct intel_display *display, enum pipe pipe, struct intel_crtc_state *pipe_config, enum pipe *pipe_to_reduce) { - struct intel_display *display = to_intel_display(dev); - struct drm_i915_private *dev_priv = to_i915(dev); struct drm_atomic_state *state = pipe_config->uapi.state; struct intel_crtc *other_crtc; struct intel_crtc_state *other_crtc_state; *pipe_to_reduce = pipe; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "checking fdi config on pipe %c, lanes %i\n", pipe_name(pipe), pipe_config->fdi_lanes); if (pipe_config->fdi_lanes > 4) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "invalid fdi lane config on pipe %c: %i lanes\n", pipe_name(pipe), pipe_config->fdi_lanes); return -EINVAL; } - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { + if (display->platform.haswell || display->platform.broadwell) { if (pipe_config->fdi_lanes > 2) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "only 2 lanes on haswell, required: %i lanes\n", pipe_config->fdi_lanes); return -EINVAL; @@ -217,7 +211,7 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, } } - if (INTEL_NUM_PIPES(dev_priv) == 2) + if (INTEL_NUM_PIPES(display) == 2) return 0; /* Ivybridge 3 pipe is really complicated */ @@ -235,7 +229,7 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, return PTR_ERR(other_crtc_state); if (pipe_required_fdi_lanes(other_crtc_state) > 0) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "invalid shared fdi lane config on pipe %c: %i lanes\n", pipe_name(pipe), pipe_config->fdi_lanes); return -EINVAL; @@ -243,7 +237,7 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, return 0; case PIPE_C: if (pipe_config->fdi_lanes > 2) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "only 2 lanes on pipe %c: required %i lanes\n", pipe_name(pipe), pipe_config->fdi_lanes); return -EINVAL; @@ -256,7 +250,7 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, return PTR_ERR(other_crtc_state); if (pipe_required_fdi_lanes(other_crtc_state) > 2) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "fdi link B uses too many lanes to enable link C\n"); *pipe_to_reduce = PIPE_B; @@ -270,29 +264,30 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, } } -void intel_fdi_pll_freq_update(struct drm_i915_private *i915) +void intel_fdi_pll_freq_update(struct intel_display *display) { - if (IS_IRONLAKE(i915)) { - u32 fdi_pll_clk = - intel_de_read(i915, FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK; + if (display->platform.ironlake) { + u32 fdi_pll_clk; + + fdi_pll_clk = intel_de_read(display, FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK; - i915->display.fdi.pll_freq = (fdi_pll_clk + 2) * 10000; - } else if (IS_SANDYBRIDGE(i915) || IS_IVYBRIDGE(i915)) { - i915->display.fdi.pll_freq = 270000; + display->fdi.pll_freq = (fdi_pll_clk + 2) * 10000; + } else if (display->platform.sandybridge || display->platform.ivybridge) { + display->fdi.pll_freq = 270000; } else { return; } - drm_dbg(&i915->drm, "FDI PLL freq=%d\n", i915->display.fdi.pll_freq); + drm_dbg(display->drm, "FDI PLL freq=%d\n", display->fdi.pll_freq); } -int intel_fdi_link_freq(struct drm_i915_private *i915, +int intel_fdi_link_freq(struct intel_display *display, const struct intel_crtc_state *pipe_config) { - if (HAS_DDI(i915)) + if (HAS_DDI(display)) return pipe_config->port_clock; /* SPLL */ else - return i915->display.fdi.pll_freq; + return display->fdi.pll_freq; } /** @@ -326,8 +321,7 @@ bool intel_fdi_compute_pipe_bpp(struct intel_crtc_state *crtc_state) int ilk_fdi_compute_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *i915 = to_i915(dev); + struct intel_display *display = to_intel_display(crtc); const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; int lane, link_bw, fdi_dotclock; @@ -338,7 +332,7 @@ int ilk_fdi_compute_config(struct intel_crtc *crtc, * Hence the bw of each lane in terms of the mode signal * is: */ - link_bw = intel_fdi_link_freq(i915, pipe_config); + link_bw = intel_fdi_link_freq(display, pipe_config); fdi_dotclock = adjusted_mode->crtc_clock; @@ -361,11 +355,11 @@ static int intel_fdi_atomic_check_bw(struct intel_atomic_state *state, struct intel_crtc_state *pipe_config, struct intel_link_bw_limits *limits) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); enum pipe pipe_to_reduce; int ret; - ret = ilk_check_fdi_lanes(&i915->drm, crtc->pipe, pipe_config, + ret = ilk_check_fdi_lanes(display, crtc->pipe, pipe_config, &pipe_to_reduce); if (ret != -EINVAL) return ret; @@ -418,48 +412,48 @@ int intel_fdi_atomic_check_link(struct intel_atomic_state *state, return 0; } -static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool enable) +static void cpt_set_fdi_bc_bifurcation(struct intel_display *display, bool enable) { u32 temp; - temp = intel_de_read(dev_priv, SOUTH_CHICKEN1); + temp = intel_de_read(display, SOUTH_CHICKEN1); if (!!(temp & FDI_BC_BIFURCATION_SELECT) == enable) return; - drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, FDI_RX_CTL(PIPE_B)) & + drm_WARN_ON(display->drm, + intel_de_read(display, FDI_RX_CTL(PIPE_B)) & FDI_RX_ENABLE); - drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, FDI_RX_CTL(PIPE_C)) & + drm_WARN_ON(display->drm, + intel_de_read(display, FDI_RX_CTL(PIPE_C)) & FDI_RX_ENABLE); temp &= ~FDI_BC_BIFURCATION_SELECT; if (enable) temp |= FDI_BC_BIFURCATION_SELECT; - drm_dbg_kms(&dev_priv->drm, "%sabling fdi C rx\n", + drm_dbg_kms(display->drm, "%sabling fdi C rx\n", enable ? "en" : "dis"); - intel_de_write(dev_priv, SOUTH_CHICKEN1, temp); - intel_de_posting_read(dev_priv, SOUTH_CHICKEN1); + intel_de_write(display, SOUTH_CHICKEN1, temp); + intel_de_posting_read(display, SOUTH_CHICKEN1); } static void ivb_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); switch (crtc->pipe) { case PIPE_A: break; case PIPE_B: if (crtc_state->fdi_lanes > 2) - cpt_set_fdi_bc_bifurcation(dev_priv, false); + cpt_set_fdi_bc_bifurcation(display, false); else - cpt_set_fdi_bc_bifurcation(dev_priv, true); + cpt_set_fdi_bc_bifurcation(display, true); break; case PIPE_C: - cpt_set_fdi_bc_bifurcation(dev_priv, true); + cpt_set_fdi_bc_bifurcation(display, true); break; default: @@ -469,26 +463,26 @@ static void ivb_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_st void intel_fdi_normal_train(struct intel_crtc *crtc) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(crtc); + struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe = crtc->pipe; i915_reg_t reg; u32 temp; /* enable normal train */ reg = FDI_TX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); - if (IS_IVYBRIDGE(dev_priv)) { + temp = intel_de_read(display, reg); + if (display->platform.ivybridge) { temp &= ~FDI_LINK_TRAIN_NONE_IVB; temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE; } else { temp &= ~FDI_LINK_TRAIN_NONE; temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; } - intel_de_write(dev_priv, reg, temp); + intel_de_write(display, reg, temp); reg = FDI_RX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); if (HAS_PCH_CPT(dev_priv)) { temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; temp |= FDI_LINK_TRAIN_NORMAL_CPT; @@ -496,15 +490,15 @@ void intel_fdi_normal_train(struct intel_crtc *crtc) temp &= ~FDI_LINK_TRAIN_NONE; temp |= FDI_LINK_TRAIN_NONE; } - intel_de_write(dev_priv, reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); + intel_de_write(display, reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); /* wait one idle pattern time */ - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(display, reg); udelay(1000); /* IVB wants error correction enabled */ - if (IS_IVYBRIDGE(dev_priv)) - intel_de_rmw(dev_priv, reg, 0, FDI_FS_ERRC_ENABLE | FDI_FE_ERRC_ENABLE); + if (display->platform.ivybridge) + intel_de_rmw(display, reg, 0, FDI_FS_ERRC_ENABLE | FDI_FE_ERRC_ENABLE); } /* The FDI link training functions for ILK/Ibexpeak. */ @@ -512,8 +506,6 @@ static void ilk_fdi_link_train(struct intel_crtc *crtc, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc); - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = crtc->pipe; i915_reg_t reg; u32 temp, tries; @@ -522,8 +514,8 @@ static void ilk_fdi_link_train(struct intel_crtc *crtc, * Write the TU size bits before fdi link training, so that error * detection works. */ - intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe), - intel_de_read(dev_priv, PIPE_DATA_M1(dev_priv, pipe)) & TU_SIZE_MASK); + intel_de_write(display, FDI_RX_TUSIZE1(pipe), + intel_de_read(display, PIPE_DATA_M1(display, pipe)) & TU_SIZE_MASK); /* FDI needs bits from pipe first */ assert_transcoder_enabled(display, crtc_state->cpu_transcoder); @@ -531,75 +523,75 @@ static void ilk_fdi_link_train(struct intel_crtc *crtc, /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit for train result */ reg = FDI_RX_IMR(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~FDI_RX_SYMBOL_LOCK; temp &= ~FDI_RX_BIT_LOCK; - intel_de_write(dev_priv, reg, temp); - intel_de_read(dev_priv, reg); + intel_de_write(display, reg, temp); + intel_de_read(display, reg); udelay(150); /* enable CPU FDI TX and PCH FDI RX */ reg = FDI_TX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~FDI_DP_PORT_WIDTH_MASK; temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes); temp &= ~FDI_LINK_TRAIN_NONE; temp |= FDI_LINK_TRAIN_PATTERN_1; - intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE); + intel_de_write(display, reg, temp | FDI_TX_ENABLE); reg = FDI_RX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~FDI_LINK_TRAIN_NONE; temp |= FDI_LINK_TRAIN_PATTERN_1; - intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE); + intel_de_write(display, reg, temp | FDI_RX_ENABLE); - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(display, reg); udelay(150); /* Ironlake workaround, enable clock pointer after FDI enable*/ - intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe), + intel_de_write(display, FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR); - intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe), + intel_de_write(display, FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR | FDI_RX_PHASE_SYNC_POINTER_EN); reg = FDI_RX_IIR(pipe); for (tries = 0; tries < 5; tries++) { - temp = intel_de_read(dev_priv, reg); - drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp); + temp = intel_de_read(display, reg); + drm_dbg_kms(display->drm, "FDI_RX_IIR 0x%x\n", temp); if ((temp & FDI_RX_BIT_LOCK)) { - drm_dbg_kms(&dev_priv->drm, "FDI train 1 done.\n"); - intel_de_write(dev_priv, reg, temp | FDI_RX_BIT_LOCK); + drm_dbg_kms(display->drm, "FDI train 1 done.\n"); + intel_de_write(display, reg, temp | FDI_RX_BIT_LOCK); break; } } if (tries == 5) - drm_err(&dev_priv->drm, "FDI train 1 fail!\n"); + drm_err(display->drm, "FDI train 1 fail!\n"); /* Train 2 */ - intel_de_rmw(dev_priv, FDI_TX_CTL(pipe), + intel_de_rmw(display, FDI_TX_CTL(pipe), FDI_LINK_TRAIN_NONE, FDI_LINK_TRAIN_PATTERN_2); - intel_de_rmw(dev_priv, FDI_RX_CTL(pipe), + intel_de_rmw(display, FDI_RX_CTL(pipe), FDI_LINK_TRAIN_NONE, FDI_LINK_TRAIN_PATTERN_2); - intel_de_posting_read(dev_priv, FDI_RX_CTL(pipe)); + intel_de_posting_read(display, FDI_RX_CTL(pipe)); udelay(150); reg = FDI_RX_IIR(pipe); for (tries = 0; tries < 5; tries++) { - temp = intel_de_read(dev_priv, reg); - drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp); + temp = intel_de_read(display, reg); + drm_dbg_kms(display->drm, "FDI_RX_IIR 0x%x\n", temp); if (temp & FDI_RX_SYMBOL_LOCK) { - intel_de_write(dev_priv, reg, + intel_de_write(display, reg, temp | FDI_RX_SYMBOL_LOCK); - drm_dbg_kms(&dev_priv->drm, "FDI train 2 done.\n"); + drm_dbg_kms(display->drm, "FDI train 2 done.\n"); break; } } if (tries == 5) - drm_err(&dev_priv->drm, "FDI train 2 fail!\n"); + drm_err(display->drm, "FDI train 2 fail!\n"); - drm_dbg_kms(&dev_priv->drm, "FDI train done\n"); + drm_dbg_kms(display->drm, "FDI train done\n"); } @@ -614,8 +606,8 @@ static const int snb_b_fdi_train_param[] = { static void gen6_fdi_link_train(struct intel_crtc *crtc, const struct intel_crtc_state *crtc_state) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(crtc); + struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe = crtc->pipe; i915_reg_t reg; u32 temp, i, retry; @@ -624,23 +616,23 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc, * Write the TU size bits before fdi link training, so that error * detection works. */ - intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe), - intel_de_read(dev_priv, PIPE_DATA_M1(dev_priv, pipe)) & TU_SIZE_MASK); + intel_de_write(display, FDI_RX_TUSIZE1(pipe), + intel_de_read(display, PIPE_DATA_M1(display, pipe)) & TU_SIZE_MASK); /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit for train result */ reg = FDI_RX_IMR(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~FDI_RX_SYMBOL_LOCK; temp &= ~FDI_RX_BIT_LOCK; - intel_de_write(dev_priv, reg, temp); + intel_de_write(display, reg, temp); - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(display, reg); udelay(150); /* enable CPU FDI TX and PCH FDI RX */ reg = FDI_TX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~FDI_DP_PORT_WIDTH_MASK; temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes); temp &= ~FDI_LINK_TRAIN_NONE; @@ -648,13 +640,13 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc, temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; /* SNB-B */ temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; - intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE); + intel_de_write(display, reg, temp | FDI_TX_ENABLE); - intel_de_write(dev_priv, FDI_RX_MISC(pipe), + intel_de_write(display, FDI_RX_MISC(pipe), FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); reg = FDI_RX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); if (HAS_PCH_CPT(dev_priv)) { temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; @@ -662,25 +654,25 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc, temp &= ~FDI_LINK_TRAIN_NONE; temp |= FDI_LINK_TRAIN_PATTERN_1; } - intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE); + intel_de_write(display, reg, temp | FDI_RX_ENABLE); - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(display, reg); udelay(150); for (i = 0; i < 4; i++) { - intel_de_rmw(dev_priv, FDI_TX_CTL(pipe), + intel_de_rmw(display, FDI_TX_CTL(pipe), FDI_LINK_TRAIN_VOL_EMP_MASK, snb_b_fdi_train_param[i]); - intel_de_posting_read(dev_priv, FDI_TX_CTL(pipe)); + intel_de_posting_read(display, FDI_TX_CTL(pipe)); udelay(500); for (retry = 0; retry < 5; retry++) { reg = FDI_RX_IIR(pipe); - temp = intel_de_read(dev_priv, reg); - drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp); + temp = intel_de_read(display, reg); + drm_dbg_kms(display->drm, "FDI_RX_IIR 0x%x\n", temp); if (temp & FDI_RX_BIT_LOCK) { - intel_de_write(dev_priv, reg, + intel_de_write(display, reg, temp | FDI_RX_BIT_LOCK); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "FDI train 1 done.\n"); break; } @@ -690,22 +682,22 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc, break; } if (i == 4) - drm_err(&dev_priv->drm, "FDI train 1 fail!\n"); + drm_err(display->drm, "FDI train 1 fail!\n"); /* Train 2 */ reg = FDI_TX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~FDI_LINK_TRAIN_NONE; temp |= FDI_LINK_TRAIN_PATTERN_2; - if (IS_SANDYBRIDGE(dev_priv)) { + if (display->platform.sandybridge) { temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; /* SNB-B */ temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; } - intel_de_write(dev_priv, reg, temp); + intel_de_write(display, reg, temp); reg = FDI_RX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); if (HAS_PCH_CPT(dev_priv)) { temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; @@ -713,25 +705,25 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc, temp &= ~FDI_LINK_TRAIN_NONE; temp |= FDI_LINK_TRAIN_PATTERN_2; } - intel_de_write(dev_priv, reg, temp); + intel_de_write(display, reg, temp); - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(display, reg); udelay(150); for (i = 0; i < 4; i++) { - intel_de_rmw(dev_priv, FDI_TX_CTL(pipe), + intel_de_rmw(display, FDI_TX_CTL(pipe), FDI_LINK_TRAIN_VOL_EMP_MASK, snb_b_fdi_train_param[i]); - intel_de_posting_read(dev_priv, FDI_TX_CTL(pipe)); + intel_de_posting_read(display, FDI_TX_CTL(pipe)); udelay(500); for (retry = 0; retry < 5; retry++) { reg = FDI_RX_IIR(pipe); - temp = intel_de_read(dev_priv, reg); - drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp); + temp = intel_de_read(display, reg); + drm_dbg_kms(display->drm, "FDI_RX_IIR 0x%x\n", temp); if (temp & FDI_RX_SYMBOL_LOCK) { - intel_de_write(dev_priv, reg, + intel_de_write(display, reg, temp | FDI_RX_SYMBOL_LOCK); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "FDI train 2 done.\n"); break; } @@ -741,17 +733,16 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc, break; } if (i == 4) - drm_err(&dev_priv->drm, "FDI train 2 fail!\n"); + drm_err(display->drm, "FDI train 2 fail!\n"); - drm_dbg_kms(&dev_priv->drm, "FDI train done.\n"); + drm_dbg_kms(display->drm, "FDI train done.\n"); } /* Manual link training for Ivy Bridge A0 parts */ static void ivb_manual_fdi_link_train(struct intel_crtc *crtc, const struct intel_crtc_state *crtc_state) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(crtc); enum pipe pipe = crtc->pipe; i915_reg_t reg; u32 temp, i, j; @@ -762,72 +753,72 @@ static void ivb_manual_fdi_link_train(struct intel_crtc *crtc, * Write the TU size bits before fdi link training, so that error * detection works. */ - intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe), - intel_de_read(dev_priv, PIPE_DATA_M1(dev_priv, pipe)) & TU_SIZE_MASK); + intel_de_write(display, FDI_RX_TUSIZE1(pipe), + intel_de_read(display, PIPE_DATA_M1(display, pipe)) & TU_SIZE_MASK); /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit for train result */ reg = FDI_RX_IMR(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~FDI_RX_SYMBOL_LOCK; temp &= ~FDI_RX_BIT_LOCK; - intel_de_write(dev_priv, reg, temp); + intel_de_write(display, reg, temp); - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(display, reg); udelay(150); - drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR before link train 0x%x\n", - intel_de_read(dev_priv, FDI_RX_IIR(pipe))); + drm_dbg_kms(display->drm, "FDI_RX_IIR before link train 0x%x\n", + intel_de_read(display, FDI_RX_IIR(pipe))); /* Try each vswing and preemphasis setting twice before moving on */ for (j = 0; j < ARRAY_SIZE(snb_b_fdi_train_param) * 2; j++) { /* disable first in case we need to retry */ reg = FDI_TX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB); temp &= ~FDI_TX_ENABLE; - intel_de_write(dev_priv, reg, temp); + intel_de_write(display, reg, temp); reg = FDI_RX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~FDI_LINK_TRAIN_AUTO; temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; temp &= ~FDI_RX_ENABLE; - intel_de_write(dev_priv, reg, temp); + intel_de_write(display, reg, temp); /* enable CPU FDI TX and PCH FDI RX */ reg = FDI_TX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~FDI_DP_PORT_WIDTH_MASK; temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes); temp |= FDI_LINK_TRAIN_PATTERN_1_IVB; temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; temp |= snb_b_fdi_train_param[j/2]; temp |= FDI_COMPOSITE_SYNC; - intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE); + intel_de_write(display, reg, temp | FDI_TX_ENABLE); - intel_de_write(dev_priv, FDI_RX_MISC(pipe), + intel_de_write(display, FDI_RX_MISC(pipe), FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); reg = FDI_RX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; temp |= FDI_COMPOSITE_SYNC; - intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE); + intel_de_write(display, reg, temp | FDI_RX_ENABLE); - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(display, reg); udelay(1); /* should be 0.5us */ for (i = 0; i < 4; i++) { reg = FDI_RX_IIR(pipe); - temp = intel_de_read(dev_priv, reg); - drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp); + temp = intel_de_read(display, reg); + drm_dbg_kms(display->drm, "FDI_RX_IIR 0x%x\n", temp); if (temp & FDI_RX_BIT_LOCK || - (intel_de_read(dev_priv, reg) & FDI_RX_BIT_LOCK)) { - intel_de_write(dev_priv, reg, + (intel_de_read(display, reg) & FDI_RX_BIT_LOCK)) { + intel_de_write(display, reg, temp | FDI_RX_BIT_LOCK); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "FDI train 1 done, level %i.\n", i); break; @@ -835,31 +826,31 @@ static void ivb_manual_fdi_link_train(struct intel_crtc *crtc, udelay(1); /* should be 0.5us */ } if (i == 4) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "FDI train 1 fail on vswing %d\n", j / 2); continue; } /* Train 2 */ - intel_de_rmw(dev_priv, FDI_TX_CTL(pipe), + intel_de_rmw(display, FDI_TX_CTL(pipe), FDI_LINK_TRAIN_NONE_IVB, FDI_LINK_TRAIN_PATTERN_2_IVB); - intel_de_rmw(dev_priv, FDI_RX_CTL(pipe), + intel_de_rmw(display, FDI_RX_CTL(pipe), FDI_LINK_TRAIN_PATTERN_MASK_CPT, FDI_LINK_TRAIN_PATTERN_2_CPT); - intel_de_posting_read(dev_priv, FDI_RX_CTL(pipe)); + intel_de_posting_read(display, FDI_RX_CTL(pipe)); udelay(2); /* should be 1.5us */ for (i = 0; i < 4; i++) { reg = FDI_RX_IIR(pipe); - temp = intel_de_read(dev_priv, reg); - drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp); + temp = intel_de_read(display, reg); + drm_dbg_kms(display->drm, "FDI_RX_IIR 0x%x\n", temp); if (temp & FDI_RX_SYMBOL_LOCK || - (intel_de_read(dev_priv, reg) & FDI_RX_SYMBOL_LOCK)) { - intel_de_write(dev_priv, reg, + (intel_de_read(display, reg) & FDI_RX_SYMBOL_LOCK)) { + intel_de_write(display, reg, temp | FDI_RX_SYMBOL_LOCK); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "FDI train 2 done, level %i.\n", i); goto train_done; @@ -867,12 +858,12 @@ static void ivb_manual_fdi_link_train(struct intel_crtc *crtc, udelay(2); /* should be 1.5us */ } if (i == 4) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "FDI train 2 fail on vswing %d\n", j / 2); } train_done: - drm_dbg_kms(&dev_priv->drm, "FDI train done.\n"); + drm_dbg_kms(display->drm, "FDI train done.\n"); } /* Starting with Haswell, different DDI ports can work in FDI mode for @@ -887,8 +878,6 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 temp, i, rx_ctl_val; int n_entries; @@ -903,33 +892,33 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, * * WaFDIAutoLinkSetTimingOverrride:hsw */ - intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A), + intel_de_write(display, FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2) | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); /* Enable the PCH Receiver FDI PLL */ - rx_ctl_val = dev_priv->display.fdi.rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | + rx_ctl_val = display->fdi.rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | FDI_RX_PLL_ENABLE | FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes); - intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val); - intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A)); + intel_de_write(display, FDI_RX_CTL(PIPE_A), rx_ctl_val); + intel_de_posting_read(display, FDI_RX_CTL(PIPE_A)); udelay(220); /* Switch from Rawclk to PCDclk */ rx_ctl_val |= FDI_PCDCLK; - intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val); + intel_de_write(display, FDI_RX_CTL(PIPE_A), rx_ctl_val); /* Configure Port Clock Select */ - drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll->info->id != DPLL_ID_SPLL); + drm_WARN_ON(display->drm, crtc_state->shared_dpll->info->id != DPLL_ID_SPLL); intel_ddi_enable_clock(encoder, crtc_state); /* Start the training iterating through available voltages and emphasis, * testing each value twice. */ for (i = 0; i < n_entries * 2; i++) { /* Configure DP_TP_CTL with auto-training */ - intel_de_write(dev_priv, DP_TP_CTL(PORT_E), + intel_de_write(display, DP_TP_CTL(PORT_E), DP_TP_CTL_FDI_AUTOTRAIN | DP_TP_CTL_ENHANCED_FRAME_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1 | @@ -939,36 +928,36 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, * DDI E does not support port reversal, the functionality is * achieved on the PCH side in FDI_RX_CTL, so no need to set the * port reversal bit */ - intel_de_write(dev_priv, DDI_BUF_CTL(PORT_E), + intel_de_write(display, DDI_BUF_CTL(PORT_E), DDI_BUF_CTL_ENABLE | ((crtc_state->fdi_lanes - 1) << 1) | DDI_BUF_TRANS_SELECT(i / 2)); - intel_de_posting_read(dev_priv, DDI_BUF_CTL(PORT_E)); + intel_de_posting_read(display, DDI_BUF_CTL(PORT_E)); udelay(600); /* Program PCH FDI Receiver TU */ - intel_de_write(dev_priv, FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64)); + intel_de_write(display, FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64)); /* Enable PCH FDI Receiver with auto-training */ rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO; - intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val); - intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A)); + intel_de_write(display, FDI_RX_CTL(PIPE_A), rx_ctl_val); + intel_de_posting_read(display, FDI_RX_CTL(PIPE_A)); /* Wait for FDI receiver lane calibration */ udelay(30); /* Unset FDI_RX_MISC pwrdn lanes */ - intel_de_rmw(dev_priv, FDI_RX_MISC(PIPE_A), + intel_de_rmw(display, FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK, 0); - intel_de_posting_read(dev_priv, FDI_RX_MISC(PIPE_A)); + intel_de_posting_read(display, FDI_RX_MISC(PIPE_A)); /* Wait for FDI auto training time */ udelay(5); - temp = intel_de_read(dev_priv, DP_TP_STATUS(PORT_E)); + temp = intel_de_read(display, DP_TP_STATUS(PORT_E)); if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "FDI link training done on step %d\n", i); break; } @@ -978,32 +967,32 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, * Results in less fireworks from the state checker. */ if (i == n_entries * 2 - 1) { - drm_err(&dev_priv->drm, "FDI link training failed!\n"); + drm_err(display->drm, "FDI link training failed!\n"); break; } rx_ctl_val &= ~FDI_RX_ENABLE; - intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val); - intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A)); + intel_de_write(display, FDI_RX_CTL(PIPE_A), rx_ctl_val); + intel_de_posting_read(display, FDI_RX_CTL(PIPE_A)); - intel_de_rmw(dev_priv, DDI_BUF_CTL(PORT_E), DDI_BUF_CTL_ENABLE, 0); - intel_de_posting_read(dev_priv, DDI_BUF_CTL(PORT_E)); + intel_de_rmw(display, DDI_BUF_CTL(PORT_E), DDI_BUF_CTL_ENABLE, 0); + intel_de_posting_read(display, DDI_BUF_CTL(PORT_E)); /* Disable DP_TP_CTL and FDI_RX_CTL and retry */ - intel_de_rmw(dev_priv, DP_TP_CTL(PORT_E), DP_TP_CTL_ENABLE, 0); - intel_de_posting_read(dev_priv, DP_TP_CTL(PORT_E)); + intel_de_rmw(display, DP_TP_CTL(PORT_E), DP_TP_CTL_ENABLE, 0); + intel_de_posting_read(display, DP_TP_CTL(PORT_E)); intel_wait_ddi_buf_idle(display, PORT_E); /* Reset FDI_RX_MISC pwrdn lanes */ - intel_de_rmw(dev_priv, FDI_RX_MISC(PIPE_A), + intel_de_rmw(display, FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK, FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2)); - intel_de_posting_read(dev_priv, FDI_RX_MISC(PIPE_A)); + intel_de_posting_read(display, FDI_RX_MISC(PIPE_A)); } /* Enable normal pixel sending for FDI */ - intel_de_write(dev_priv, DP_TP_CTL(PORT_E), + intel_de_write(display, DP_TP_CTL(PORT_E), DP_TP_CTL_FDI_AUTOTRAIN | DP_TP_CTL_LINK_TRAIN_NORMAL | DP_TP_CTL_ENHANCED_FRAME_ENABLE | @@ -1013,7 +1002,6 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, void hsw_fdi_disable(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); /* * Bspec lists this as both step 13 (before DDI_BUF_CTL disable) @@ -1021,103 +1009,103 @@ void hsw_fdi_disable(struct intel_encoder *encoder) * step 13 is the correct place for it. Step 18 is where it was * originally before the BUN. */ - intel_de_rmw(dev_priv, FDI_RX_CTL(PIPE_A), FDI_RX_ENABLE, 0); - intel_de_rmw(dev_priv, DDI_BUF_CTL(PORT_E), DDI_BUF_CTL_ENABLE, 0); + intel_de_rmw(display, FDI_RX_CTL(PIPE_A), FDI_RX_ENABLE, 0); + intel_de_rmw(display, DDI_BUF_CTL(PORT_E), DDI_BUF_CTL_ENABLE, 0); intel_wait_ddi_buf_idle(display, PORT_E); intel_ddi_disable_clock(encoder); - intel_de_rmw(dev_priv, FDI_RX_MISC(PIPE_A), + intel_de_rmw(display, FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK, FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2)); - intel_de_rmw(dev_priv, FDI_RX_CTL(PIPE_A), FDI_PCDCLK, 0); - intel_de_rmw(dev_priv, FDI_RX_CTL(PIPE_A), FDI_RX_PLL_ENABLE, 0); + intel_de_rmw(display, FDI_RX_CTL(PIPE_A), FDI_PCDCLK, 0); + intel_de_rmw(display, FDI_RX_CTL(PIPE_A), FDI_RX_PLL_ENABLE, 0); } void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; i915_reg_t reg; u32 temp; /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ reg = FDI_RX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16)); temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes); - temp |= (intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)) & TRANSCONF_BPC_MASK) << 11; - intel_de_write(dev_priv, reg, temp | FDI_RX_PLL_ENABLE); + temp |= (intel_de_read(display, TRANSCONF(display, pipe)) & TRANSCONF_BPC_MASK) << 11; + intel_de_write(display, reg, temp | FDI_RX_PLL_ENABLE); - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(display, reg); udelay(200); /* Switch from Rawclk to PCDclk */ - intel_de_rmw(dev_priv, reg, 0, FDI_PCDCLK); - intel_de_posting_read(dev_priv, reg); + intel_de_rmw(display, reg, 0, FDI_PCDCLK); + intel_de_posting_read(display, reg); udelay(200); /* Enable CPU FDI TX PLL, always on for Ironlake */ reg = FDI_TX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); if ((temp & FDI_TX_PLL_ENABLE) == 0) { - intel_de_write(dev_priv, reg, temp | FDI_TX_PLL_ENABLE); + intel_de_write(display, reg, temp | FDI_TX_PLL_ENABLE); - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(display, reg); udelay(100); } } void ilk_fdi_pll_disable(struct intel_crtc *crtc) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(crtc); enum pipe pipe = crtc->pipe; /* Switch from PCDclk to Rawclk */ - intel_de_rmw(dev_priv, FDI_RX_CTL(pipe), FDI_PCDCLK, 0); + intel_de_rmw(display, FDI_RX_CTL(pipe), FDI_PCDCLK, 0); /* Disable CPU FDI TX PLL */ - intel_de_rmw(dev_priv, FDI_TX_CTL(pipe), FDI_TX_PLL_ENABLE, 0); - intel_de_posting_read(dev_priv, FDI_TX_CTL(pipe)); + intel_de_rmw(display, FDI_TX_CTL(pipe), FDI_TX_PLL_ENABLE, 0); + intel_de_posting_read(display, FDI_TX_CTL(pipe)); udelay(100); /* Wait for the clocks to turn off. */ - intel_de_rmw(dev_priv, FDI_RX_CTL(pipe), FDI_RX_PLL_ENABLE, 0); - intel_de_posting_read(dev_priv, FDI_RX_CTL(pipe)); + intel_de_rmw(display, FDI_RX_CTL(pipe), FDI_RX_PLL_ENABLE, 0); + intel_de_posting_read(display, FDI_RX_CTL(pipe)); udelay(100); } void ilk_fdi_disable(struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; i915_reg_t reg; u32 temp; /* disable CPU FDI tx and PCH FDI rx */ - intel_de_rmw(dev_priv, FDI_TX_CTL(pipe), FDI_TX_ENABLE, 0); - intel_de_posting_read(dev_priv, FDI_TX_CTL(pipe)); + intel_de_rmw(display, FDI_TX_CTL(pipe), FDI_TX_ENABLE, 0); + intel_de_posting_read(display, FDI_TX_CTL(pipe)); reg = FDI_RX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); temp &= ~(0x7 << 16); - temp |= (intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)) & TRANSCONF_BPC_MASK) << 11; - intel_de_write(dev_priv, reg, temp & ~FDI_RX_ENABLE); + temp |= (intel_de_read(display, TRANSCONF(display, pipe)) & TRANSCONF_BPC_MASK) << 11; + intel_de_write(display, reg, temp & ~FDI_RX_ENABLE); - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(display, reg); udelay(100); /* Ironlake workaround, disable clock pointer after downing FDI */ if (HAS_PCH_IBX(dev_priv)) - intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe), + intel_de_write(display, FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR); /* still set train pattern 1 */ - intel_de_rmw(dev_priv, FDI_TX_CTL(pipe), + intel_de_rmw(display, FDI_TX_CTL(pipe), FDI_LINK_TRAIN_NONE, FDI_LINK_TRAIN_PATTERN_1); reg = FDI_RX_CTL(pipe); - temp = intel_de_read(dev_priv, reg); + temp = intel_de_read(display, reg); if (HAS_PCH_CPT(dev_priv)) { temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; @@ -1127,10 +1115,10 @@ void ilk_fdi_disable(struct intel_crtc *crtc) } /* BPC in FDI rx is consistent with that in TRANSCONF */ temp &= ~(0x07 << 16); - temp |= (intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)) & TRANSCONF_BPC_MASK) << 11; - intel_de_write(dev_priv, reg, temp); + temp |= (intel_de_read(display, TRANSCONF(display, pipe)) & TRANSCONF_BPC_MASK) << 11; + intel_de_write(display, reg, temp); - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(display, reg); udelay(100); } @@ -1147,14 +1135,14 @@ static const struct intel_fdi_funcs ivb_funcs = { }; void -intel_fdi_init_hook(struct drm_i915_private *dev_priv) +intel_fdi_init_hook(struct intel_display *display) { - if (IS_IRONLAKE(dev_priv)) { - dev_priv->display.funcs.fdi = &ilk_funcs; - } else if (IS_SANDYBRIDGE(dev_priv)) { - dev_priv->display.funcs.fdi = &gen6_funcs; - } else if (IS_IVYBRIDGE(dev_priv)) { + if (display->platform.ironlake) { + display->funcs.fdi = &ilk_funcs; + } else if (display->platform.sandybridge) { + display->funcs.fdi = &gen6_funcs; + } else if (display->platform.ivybridge) { /* FIXME: detect B0+ stepping and use auto training */ - dev_priv->display.funcs.fdi = &ivb_funcs; + display->funcs.fdi = &ivb_funcs; } } diff --git a/drivers/gpu/drm/i915/display/intel_fdi.h b/drivers/gpu/drm/i915/display/intel_fdi.h index b5be09efb36f..ad5e103c38a8 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.h +++ b/drivers/gpu/drm/i915/display/intel_fdi.h @@ -9,16 +9,16 @@ #include enum pipe; -struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; struct intel_display; +struct intel_display; struct intel_encoder; struct intel_link_bw_limits; int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state); -int intel_fdi_link_freq(struct drm_i915_private *i915, +int intel_fdi_link_freq(struct intel_display *display, const struct intel_crtc_state *pipe_config); bool intel_fdi_compute_pipe_bpp(struct intel_crtc_state *crtc_state); int ilk_fdi_compute_config(struct intel_crtc *intel_crtc, @@ -29,19 +29,19 @@ void intel_fdi_normal_train(struct intel_crtc *crtc); void ilk_fdi_disable(struct intel_crtc *crtc); void ilk_fdi_pll_disable(struct intel_crtc *intel_crtc); void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state); -void intel_fdi_init_hook(struct drm_i915_private *dev_priv); +void intel_fdi_init_hook(struct intel_display *display); void hsw_fdi_link_train(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); void hsw_fdi_disable(struct intel_encoder *encoder); -void intel_fdi_pll_freq_update(struct drm_i915_private *i915); +void intel_fdi_pll_freq_update(struct intel_display *display); void intel_fdi_link_train(struct intel_crtc *crtc, const struct intel_crtc_state *crtc_state); -void assert_fdi_tx_enabled(struct drm_i915_private *i915, enum pipe pipe); -void assert_fdi_tx_disabled(struct drm_i915_private *i915, enum pipe pipe); -void assert_fdi_rx_enabled(struct drm_i915_private *i915, enum pipe pipe); -void assert_fdi_rx_disabled(struct drm_i915_private *i915, enum pipe pipe); +void assert_fdi_tx_enabled(struct intel_display *display, enum pipe pipe); +void assert_fdi_tx_disabled(struct intel_display *display, enum pipe pipe); +void assert_fdi_rx_enabled(struct intel_display *display, enum pipe pipe); +void assert_fdi_rx_disabled(struct intel_display *display, enum pipe pipe); void assert_fdi_tx_pll_enabled(struct intel_display *display, enum pipe pipe); void assert_fdi_rx_pll_enabled(struct intel_display *display, enum pipe pipe); void assert_fdi_rx_pll_disabled(struct intel_display *display, enum pipe pipe); diff --git a/drivers/gpu/drm/i915/display/intel_modeset_verify.c b/drivers/gpu/drm/i915/display/intel_modeset_verify.c index bc70e72ccc2e..a008412fdd04 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_verify.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_verify.c @@ -90,10 +90,11 @@ verify_connector_state(struct intel_atomic_state *state, static void intel_pipe_config_sanity_check(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); if (crtc_state->has_pch_encoder) { - int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(i915, crtc_state), + int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(display, crtc_state), &crtc_state->fdi_m_n); int dotclock = crtc_state->hw.adjusted_mode.crtc_clock; diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.c b/drivers/gpu/drm/i915/display/intel_pch_display.c index 806729ec73c8..99f6d6f53fa7 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_display.c +++ b/drivers/gpu/drm/i915/display/intel_pch_display.c @@ -259,8 +259,8 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) assert_shared_dpll_enabled(display, crtc_state->shared_dpll); /* FDI must be feeding us bits for PCH ports */ - assert_fdi_tx_enabled(dev_priv, pipe); - assert_fdi_rx_enabled(dev_priv, pipe); + assert_fdi_tx_enabled(display, pipe); + assert_fdi_rx_enabled(display, pipe); if (HAS_PCH_CPT(dev_priv)) { reg = TRANS_CHICKEN2(pipe); @@ -316,13 +316,14 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) static void ilk_disable_pch_transcoder(struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; i915_reg_t reg; /* FDI relies on the transcoder */ - assert_fdi_tx_disabled(dev_priv, pipe); - assert_fdi_rx_disabled(dev_priv, pipe); + assert_fdi_tx_disabled(display, pipe); + assert_fdi_rx_disabled(display, pipe); /* Ports must be off as well */ assert_pch_ports_disabled(dev_priv, pipe); @@ -479,8 +480,7 @@ void ilk_pch_post_disable(struct intel_atomic_state *state, static void ilk_pch_clock_get(struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); /* read out port_clock from the DPLL */ i9xx_crtc_clock_get(crtc_state); @@ -491,7 +491,7 @@ static void ilk_pch_clock_get(struct intel_crtc_state *crtc_state) * Calculate one based on the FDI configuration. */ crtc_state->hw.adjusted_mode.crtc_clock = - intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, crtc_state), + intel_dotclock_calculate(intel_fdi_link_freq(display, crtc_state), &crtc_state->fdi_m_n); } @@ -549,14 +549,15 @@ void ilk_pch_get_config(struct intel_crtc_state *crtc_state) static void lpt_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 val, pipeconf_val; /* FDI must be feeding us bits for PCH ports */ - assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder); - assert_fdi_rx_enabled(dev_priv, PIPE_A); + assert_fdi_tx_enabled(display, (enum pipe)cpu_transcoder); + assert_fdi_rx_enabled(display, PIPE_A); val = intel_de_read(dev_priv, TRANS_CHICKEN2(PIPE_A)); /* Workaround: set timing override bit. */ From 9efa033704c5598db935a096863cbe64b97994b3 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 27 Feb 2025 16:52:40 +0530 Subject: [PATCH 17/92] drm/i915/vdsc: intel_display conversions intel_display conversions for vdsc in an effort to move away from drm_i915_private. While at it use display->platform.xx. Signed-off-by: Suraj Kandpal Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20250227112240.278827-1-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_vdsc.c | 182 +++++++++++----------- 1 file changed, 88 insertions(+), 94 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 6e7151346382..3ed64c17bdff 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -10,7 +10,7 @@ #include #include -#include "i915_drv.h" +#include "i915_utils.h" #include "intel_crtc.h" #include "intel_de.h" #include "intel_display_types.h" @@ -22,14 +22,13 @@ bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state) { - const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - if (!HAS_DSC(i915)) + if (!HAS_DSC(display)) return false; - if (DISPLAY_VER(i915) == 11 && cpu_transcoder == TRANSCODER_A) + if (DISPLAY_VER(display) == 11 && cpu_transcoder == TRANSCODER_A) return false; return true; @@ -37,9 +36,9 @@ bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state) static bool is_pipe_dsc(struct intel_crtc *crtc, enum transcoder cpu_transcoder) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); - if (DISPLAY_VER(i915) >= 12) + if (DISPLAY_VER(display) >= 12) return true; if (cpu_transcoder == TRANSCODER_EDP || @@ -48,7 +47,7 @@ static bool is_pipe_dsc(struct intel_crtc *crtc, enum transcoder cpu_transcoder) return false; /* There's no pipe A DSC engine on ICL */ - drm_WARN_ON(&i915->drm, crtc->pipe == PIPE_A); + drm_WARN_ON(display->drm, crtc->pipe == PIPE_A); return true; } @@ -262,8 +261,7 @@ static int intel_dsc_slice_dimensions_valid(struct intel_crtc_state *pipe_config int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) { - struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(pipe_config); struct drm_dsc_config *vdsc_cfg = &pipe_config->dsc.config; u16 compressed_bpp = fxp_q4_to_int(pipe_config->dsc.compressed_bpp_x16); int err; @@ -276,7 +274,7 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) err = intel_dsc_slice_dimensions_valid(pipe_config, vdsc_cfg); if (err) { - drm_dbg_kms(&dev_priv->drm, "Slice dimension requirements not met\n"); + drm_dbg_kms(display->drm, "Slice dimension requirements not met\n"); return err; } @@ -287,7 +285,7 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) vdsc_cfg->convert_rgb = pipe_config->output_format != INTEL_OUTPUT_FORMAT_YCBCR420 && pipe_config->output_format != INTEL_OUTPUT_FORMAT_YCBCR444; - if (DISPLAY_VER(dev_priv) >= 14 && + if (DISPLAY_VER(display) >= 14 && pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) vdsc_cfg->native_420 = true; /* We do not support YcBCr422 as of now */ @@ -308,7 +306,7 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) vdsc_cfg->bits_per_component = pipe_config->pipe_bpp / 3; if (vdsc_cfg->bits_per_component < 8) { - drm_dbg_kms(&dev_priv->drm, "DSC bpc requirements not met bpc: %d\n", + drm_dbg_kms(display->drm, "DSC bpc requirements not met bpc: %d\n", vdsc_cfg->bits_per_component); return -EINVAL; } @@ -320,7 +318,7 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) * upto uncompressed bpp-1, hence add calculations for all the rc * parameters */ - if (DISPLAY_VER(dev_priv) >= 13) { + if (DISPLAY_VER(display) >= 13) { calculate_rc_params(vdsc_cfg); } else { if ((compressed_bpp == 8 || @@ -356,7 +354,7 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) enum intel_display_power_domain intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); enum pipe pipe = crtc->pipe; /* @@ -370,7 +368,8 @@ intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder) * the pipe in use. Hence another reference on the pipe power domain * will suffice. (Except no VDSC/joining on ICL pipe A.) */ - if (DISPLAY_VER(i915) == 12 && !IS_ROCKETLAKE(i915) && pipe == PIPE_A) + if (DISPLAY_VER(display) == 12 && !display->platform.rocketlake && + pipe == PIPE_A) return POWER_DOMAIN_TRANSCODER_VDSC_PW2; else if (is_pipe_dsc(crtc, cpu_transcoder)) return POWER_DOMAIN_PIPE(pipe); @@ -416,26 +415,25 @@ static void intel_dsc_get_pps_reg(const struct intel_crtc_state *crtc_state, int static void intel_dsc_pps_write(const struct intel_crtc_state *crtc_state, int pps, u32 pps_val) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); i915_reg_t dsc_reg[3]; int i, vdsc_per_pipe, dsc_reg_num; vdsc_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state); dsc_reg_num = min_t(int, ARRAY_SIZE(dsc_reg), vdsc_per_pipe); - drm_WARN_ON_ONCE(&i915->drm, dsc_reg_num < vdsc_per_pipe); + drm_WARN_ON_ONCE(display->drm, dsc_reg_num < vdsc_per_pipe); intel_dsc_get_pps_reg(crtc_state, pps, dsc_reg, dsc_reg_num); for (i = 0; i < dsc_reg_num; i++) - intel_de_write(i915, dsc_reg[i], pps_val); + intel_de_write(display, dsc_reg[i], pps_val); } static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum pipe pipe = crtc->pipe; @@ -529,7 +527,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) vdsc_cfg->slice_height); intel_dsc_pps_write(crtc_state, 16, pps_val); - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { /* PPS 17 */ pps_val = DSC_PPS17_SL_BPG_OFFSET(vdsc_cfg->second_line_bpg_offset); intel_dsc_pps_write(crtc_state, 17, pps_val); @@ -547,44 +545,44 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) (u32)(vdsc_cfg->rc_buf_thresh[i] << BITS_PER_BYTE * (i % 4)); if (!is_pipe_dsc(crtc, cpu_transcoder)) { - intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_0, + intel_de_write(display, DSCA_RC_BUF_THRESH_0, rc_buf_thresh_dword[0]); - intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_0_UDW, + intel_de_write(display, DSCA_RC_BUF_THRESH_0_UDW, rc_buf_thresh_dword[1]); - intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_1, + intel_de_write(display, DSCA_RC_BUF_THRESH_1, rc_buf_thresh_dword[2]); - intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_1_UDW, + intel_de_write(display, DSCA_RC_BUF_THRESH_1_UDW, rc_buf_thresh_dword[3]); if (vdsc_instances_per_pipe > 1) { - intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_0, + intel_de_write(display, DSCC_RC_BUF_THRESH_0, rc_buf_thresh_dword[0]); - intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_0_UDW, + intel_de_write(display, DSCC_RC_BUF_THRESH_0_UDW, rc_buf_thresh_dword[1]); - intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_1, + intel_de_write(display, DSCC_RC_BUF_THRESH_1, rc_buf_thresh_dword[2]); - intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_1_UDW, + intel_de_write(display, DSCC_RC_BUF_THRESH_1_UDW, rc_buf_thresh_dword[3]); } } else { - intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_0(pipe), + intel_de_write(display, ICL_DSC0_RC_BUF_THRESH_0(pipe), rc_buf_thresh_dword[0]); - intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_0_UDW(pipe), + intel_de_write(display, ICL_DSC0_RC_BUF_THRESH_0_UDW(pipe), rc_buf_thresh_dword[1]); - intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_1(pipe), + intel_de_write(display, ICL_DSC0_RC_BUF_THRESH_1(pipe), rc_buf_thresh_dword[2]); - intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_1_UDW(pipe), + intel_de_write(display, ICL_DSC0_RC_BUF_THRESH_1_UDW(pipe), rc_buf_thresh_dword[3]); if (vdsc_instances_per_pipe > 1) { - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC1_RC_BUF_THRESH_0(pipe), rc_buf_thresh_dword[0]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC1_RC_BUF_THRESH_0_UDW(pipe), rc_buf_thresh_dword[1]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC1_RC_BUF_THRESH_1(pipe), rc_buf_thresh_dword[2]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC1_RC_BUF_THRESH_1_UDW(pipe), rc_buf_thresh_dword[3]); } @@ -601,88 +599,88 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) (vdsc_cfg->rc_range_params[i].range_min_qp << RC_MIN_QP_SHIFT)) << 16 * (i % 2)); if (!is_pipe_dsc(crtc, cpu_transcoder)) { - intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_0, + intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_0, rc_range_params_dword[0]); - intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_0_UDW, + intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_0_UDW, rc_range_params_dword[1]); - intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_1, + intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_1, rc_range_params_dword[2]); - intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_1_UDW, + intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_1_UDW, rc_range_params_dword[3]); - intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_2, + intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_2, rc_range_params_dword[4]); - intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_2_UDW, + intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_2_UDW, rc_range_params_dword[5]); - intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_3, + intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_3, rc_range_params_dword[6]); - intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_3_UDW, + intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_3_UDW, rc_range_params_dword[7]); if (vdsc_instances_per_pipe > 1) { - intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_0, + intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_0, rc_range_params_dword[0]); - intel_de_write(dev_priv, + intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_0_UDW, rc_range_params_dword[1]); - intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_1, + intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_1, rc_range_params_dword[2]); - intel_de_write(dev_priv, + intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_1_UDW, rc_range_params_dword[3]); - intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_2, + intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_2, rc_range_params_dword[4]); - intel_de_write(dev_priv, + intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_2_UDW, rc_range_params_dword[5]); - intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_3, + intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_3, rc_range_params_dword[6]); - intel_de_write(dev_priv, + intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_3_UDW, rc_range_params_dword[7]); } } else { - intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_0(pipe), + intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_0(pipe), rc_range_params_dword[0]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_0_UDW(pipe), rc_range_params_dword[1]); - intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_1(pipe), + intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_1(pipe), rc_range_params_dword[2]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_1_UDW(pipe), rc_range_params_dword[3]); - intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_2(pipe), + intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_2(pipe), rc_range_params_dword[4]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_2_UDW(pipe), rc_range_params_dword[5]); - intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_3(pipe), + intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_3(pipe), rc_range_params_dword[6]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_3_UDW(pipe), rc_range_params_dword[7]); if (vdsc_instances_per_pipe > 1) { - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC1_RC_RANGE_PARAMETERS_0(pipe), rc_range_params_dword[0]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC1_RC_RANGE_PARAMETERS_0_UDW(pipe), rc_range_params_dword[1]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC1_RC_RANGE_PARAMETERS_1(pipe), rc_range_params_dword[2]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC1_RC_RANGE_PARAMETERS_1_UDW(pipe), rc_range_params_dword[3]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC1_RC_RANGE_PARAMETERS_2(pipe), rc_range_params_dword[4]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC1_RC_RANGE_PARAMETERS_2_UDW(pipe), rc_range_params_dword[5]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC1_RC_RANGE_PARAMETERS_3(pipe), rc_range_params_dword[6]); - intel_de_write(dev_priv, + intel_de_write(display, ICL_DSC1_RC_RANGE_PARAMETERS_3_UDW(pipe), rc_range_params_dword[7]); } @@ -746,8 +744,8 @@ static i915_reg_t dss_ctl2_reg(struct intel_crtc *crtc, enum transcoder cpu_tran void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 dss_ctl1_val = 0; if (crtc_state->joiner_pipes && !crtc_state->dsc.compression_enable) { @@ -756,14 +754,15 @@ void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state) else dss_ctl1_val |= UNCOMPRESSED_JOINER_PRIMARY; - intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val); + intel_de_write(display, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), + dss_ctl1_val); } } void intel_dsc_enable(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 dss_ctl1_val = 0; u32 dss_ctl2_val = 0; int vdsc_instances_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state); @@ -796,28 +795,27 @@ void intel_dsc_enable(const struct intel_crtc_state *crtc_state) if (intel_crtc_is_bigjoiner_primary(crtc_state)) dss_ctl1_val |= PRIMARY_BIG_JOINER_ENABLE; } - intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val); - intel_de_write(dev_priv, dss_ctl2_reg(crtc, crtc_state->cpu_transcoder), dss_ctl2_val); + intel_de_write(display, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val); + intel_de_write(display, dss_ctl2_reg(crtc, crtc_state->cpu_transcoder), dss_ctl2_val); } void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state) { + struct intel_display *display = to_intel_display(old_crtc_state); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); /* Disable only if either of them is enabled */ if (old_crtc_state->dsc.compression_enable || old_crtc_state->joiner_pipes) { - intel_de_write(dev_priv, dss_ctl1_reg(crtc, old_crtc_state->cpu_transcoder), 0); - intel_de_write(dev_priv, dss_ctl2_reg(crtc, old_crtc_state->cpu_transcoder), 0); + intel_de_write(display, dss_ctl1_reg(crtc, old_crtc_state->cpu_transcoder), 0); + intel_de_write(display, dss_ctl2_reg(crtc, old_crtc_state->cpu_transcoder), 0); } } static u32 intel_dsc_pps_read(struct intel_crtc_state *crtc_state, int pps, bool *all_equal) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); i915_reg_t dsc_reg[3]; int i, vdsc_per_pipe, dsc_reg_num; u32 val; @@ -825,16 +823,16 @@ static u32 intel_dsc_pps_read(struct intel_crtc_state *crtc_state, int pps, vdsc_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state); dsc_reg_num = min_t(int, ARRAY_SIZE(dsc_reg), vdsc_per_pipe); - drm_WARN_ON_ONCE(&i915->drm, dsc_reg_num < vdsc_per_pipe); + drm_WARN_ON_ONCE(display->drm, dsc_reg_num < vdsc_per_pipe); intel_dsc_get_pps_reg(crtc_state, pps, dsc_reg, dsc_reg_num); *all_equal = true; - val = intel_de_read(i915, dsc_reg[0]); + val = intel_de_read(display, dsc_reg[0]); for (i = 1; i < dsc_reg_num; i++) { - if (intel_de_read(i915, dsc_reg[i]) != val) { + if (intel_de_read(display, dsc_reg[i]) != val) { *all_equal = false; break; } @@ -845,22 +843,20 @@ static u32 intel_dsc_pps_read(struct intel_crtc_state *crtc_state, int pps, static u32 intel_dsc_pps_read_and_verify(struct intel_crtc_state *crtc_state, int pps) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); u32 val; bool all_equal; val = intel_dsc_pps_read(crtc_state, pps, &all_equal); - drm_WARN_ON(&i915->drm, !all_equal); + drm_WARN_ON(display->drm, !all_equal); return val; } static void intel_dsc_get_pps_config(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state); u32 pps_temp; @@ -946,7 +942,7 @@ static void intel_dsc_get_pps_config(struct intel_crtc_state *crtc_state) vdsc_cfg->slice_chunk_size = REG_FIELD_GET(DSC_PPS16_SLICE_CHUNK_SIZE_MASK, pps_temp); - if (DISPLAY_VER(i915) >= 14) { + if (DISPLAY_VER(display) >= 14) { /* PPS 17 */ pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 17); @@ -964,7 +960,6 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; @@ -979,8 +974,8 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state) if (!wakeref) return; - dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc, cpu_transcoder)); - dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg(crtc, cpu_transcoder)); + dss_ctl1 = intel_de_read(display, dss_ctl1_reg(crtc, cpu_transcoder)); + dss_ctl2 = intel_de_read(display, dss_ctl2_reg(crtc, cpu_transcoder)); crtc_state->dsc.compression_enable = dss_ctl2 & VDSC0_ENABLE; if (!crtc_state->dsc.compression_enable) @@ -1020,8 +1015,7 @@ void intel_vdsc_state_dump(struct drm_printer *p, int indent, int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct intel_display *display = to_intel_display(crtc); + struct intel_display *display = to_intel_display(crtc_state); int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state); int min_cdclk; From e6b6de16782b5cd08b17b3a4ab11aa7a8194d7bd Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 26 Feb 2025 12:01:07 +0200 Subject: [PATCH 18/92] drm/i915/pfit: rename intel_panel_fitting() to intel_pfit_compute_config() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unify naming wrt both the prefix and suffix. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/33bb513e186c8838acde37f87aee732b63bd5702.1740564009.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 2 +- drivers/gpu/drm/i915/display/intel_lvds.c | 2 +- drivers/gpu/drm/i915/display/intel_pfit.c | 4 ++-- drivers/gpu/drm/i915/display/intel_pfit.h | 4 ++-- drivers/gpu/drm/i915/display/vlv_dsi.c | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index c1b5be0f5603..910336366e5f 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1647,7 +1647,7 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder, if (ret) return ret; - ret = intel_panel_fitting(pipe_config, conn_state); + ret = intel_pfit_compute_config(pipe_config, conn_state); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index f61d716bad00..ab9f62a8fac8 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3130,7 +3130,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, if ((intel_dp_is_edp(intel_dp) && fixed_mode) || pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) { - ret = intel_panel_fitting(pipe_config, conn_state); + ret = intel_pfit_compute_config(pipe_config, conn_state); if (ret) return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 7ffc76a2ec1e..4e3ce8f59141 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2360,7 +2360,7 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder, } if (intel_hdmi_is_ycbcr420(pipe_config)) { - ret = intel_panel_fitting(pipe_config, conn_state); + ret = intel_pfit_compute_config(pipe_config, conn_state); if (ret) return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 12bbd7ec9d81..ea144f7e7829 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -468,7 +468,7 @@ static int intel_lvds_compute_config(struct intel_encoder *encoder, if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) return -EINVAL; - ret = intel_panel_fitting(crtc_state, conn_state); + ret = intel_pfit_compute_config(crtc_state, conn_state); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_pfit.c b/drivers/gpu/drm/i915/display/intel_pfit.c index 4ee03d9d14ad..386ab57b9f8d 100644 --- a/drivers/gpu/drm/i915/display/intel_pfit.c +++ b/drivers/gpu/drm/i915/display/intel_pfit.c @@ -542,8 +542,8 @@ static int gmch_panel_fitting(struct intel_crtc_state *crtc_state, return intel_gmch_pfit_check_timings(crtc_state); } -int intel_panel_fitting(struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) +int intel_pfit_compute_config(struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_pfit.h b/drivers/gpu/drm/i915/display/intel_pfit.h index add8d78de2c9..e7acaa61e1ac 100644 --- a/drivers/gpu/drm/i915/display/intel_pfit.h +++ b/drivers/gpu/drm/i915/display/intel_pfit.h @@ -9,7 +9,7 @@ struct drm_connector_state; struct intel_crtc_state; -int intel_panel_fitting(struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); +int intel_pfit_compute_config(struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); #endif /* __INTEL_PFIT_H__ */ diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index 03ba63c0032b..a19d46c9f265 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -283,7 +283,7 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder, if (ret) return ret; - ret = intel_panel_fitting(pipe_config, conn_state); + ret = intel_pfit_compute_config(pipe_config, conn_state); if (ret) return ret; From 30d70e1e2680e6450d6be4d92d9ae3d366bbc9ce Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 26 Feb 2025 12:01:08 +0200 Subject: [PATCH 19/92] drm/i915/pfit: move ilk and i9xx pfit code to intel_pfit.[ch] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Group panel fitter code in one place. Rename *_get_pfit_config() to *_pfit_get_config() while at it. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/d1f18b2c0d0ae07a3f38fc859b10a9de2b9c5c24.1740564009.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_crt.c | 1 + drivers/gpu/drm/i915/display/intel_ddi.c | 1 + drivers/gpu/drm/i915/display/intel_display.c | 165 +------------------ drivers/gpu/drm/i915/display/intel_display.h | 2 - drivers/gpu/drm/i915/display/intel_dp_mst.c | 1 + drivers/gpu/drm/i915/display/intel_pfit.c | 160 ++++++++++++++++++ drivers/gpu/drm/i915/display/intel_pfit.h | 6 + 7 files changed, 173 insertions(+), 163 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index c2945c6f8de5..9deb3106a2b6 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -54,6 +54,7 @@ #include "intel_load_detect.h" #include "intel_pch_display.h" #include "intel_pch_refclk.h" +#include "intel_pfit.h" /* Here's the desired hotplug mode */ #define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_ENABLE | \ diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 780dad5c5de7..97543b2256ff 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -70,6 +70,7 @@ #include "intel_lspcon.h" #include "intel_mg_phy_regs.h" #include "intel_modeset_lock.h" +#include "intel_pfit.h" #include "intel_pps.h" #include "intel_psr.h" #include "intel_quirks.h" diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3045f21540d3..ecc39ffd8dd0 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -104,6 +104,7 @@ #include "intel_pch_display.h" #include "intel_pch_refclk.h" #include "intel_pcode.h" +#include "intel_pfit.h" #include "intel_pipe_crc.h" #include "intel_plane_initial.h" #include "intel_pmdemand.h" @@ -819,36 +820,6 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state, return encoder; } -static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state) -{ - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - const struct drm_rect *dst = &crtc_state->pch_pfit.dst; - enum pipe pipe = crtc->pipe; - int width = drm_rect_width(dst); - int height = drm_rect_height(dst); - int x = dst->x1; - int y = dst->y1; - - if (!crtc_state->pch_pfit.enabled) - return; - - /* Force use of hard-coded filter coefficients - * as some pre-programmed values are broken, - * e.g. x201. - */ - if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) - intel_de_write_fw(dev_priv, PF_CTL(pipe), PF_ENABLE | - PF_FILTER_MED_3x3 | PF_PIPE_SEL_IVB(pipe)); - else - intel_de_write_fw(dev_priv, PF_CTL(pipe), PF_ENABLE | - PF_FILTER_MED_3x3); - intel_de_write_fw(dev_priv, PF_WIN_POS(pipe), - PF_WIN_XPOS(x) | PF_WIN_YPOS(y)); - intel_de_write_fw(dev_priv, PF_WIN_SZ(pipe), - PF_WIN_XSIZE(width) | PF_WIN_YSIZE(height)); -} - static void intel_crtc_dpms_overlay_disable(struct intel_crtc *crtc) { if (crtc->overlay) @@ -1773,22 +1744,6 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, } } -void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state) -{ - struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - enum pipe pipe = crtc->pipe; - - /* To avoid upsetting the power well on haswell only disable the pfit if - * it's in use. The hw state code will make sure we get this right. */ - if (!old_crtc_state->pch_pfit.enabled) - return; - - intel_de_write_fw(dev_priv, PF_CTL(pipe), 0); - intel_de_write_fw(dev_priv, PF_WIN_POS(pipe), 0); - intel_de_write_fw(dev_priv, PF_WIN_SZ(pipe), 0); -} - static void ilk_crtc_disable(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -1856,32 +1811,6 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_dmc_disable_pipe(display, pipe_crtc->pipe); } -static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) -{ - struct intel_display *display = to_intel_display(crtc_state); - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - - if (!crtc_state->gmch_pfit.control) - return; - - /* - * The panel fitter should only be adjusted whilst the pipe is disabled, - * according to register description and PRM. - */ - drm_WARN_ON(display->drm, - intel_de_read(display, PFIT_CONTROL(display)) & PFIT_ENABLE); - assert_transcoder_disabled(display, crtc_state->cpu_transcoder); - - intel_de_write(display, PFIT_PGM_RATIOS(display), - crtc_state->gmch_pfit.pgm_ratios); - intel_de_write(display, PFIT_CONTROL(display), - crtc_state->gmch_pfit.control); - - /* Border color in case we don't scale up to the full screen. Black by - * default, change to something else for debugging. */ - intel_de_write(display, BCLRPAT(display, crtc->pipe), 0); -} - /* Prefer intel_encoder_is_combo() */ bool intel_phy_is_combo(struct intel_display *display, enum phy phy) { @@ -2190,20 +2119,6 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, intel_crtc_wait_for_next_vblank(crtc); } -static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state) -{ - struct intel_display *display = to_intel_display(old_crtc_state); - - if (!old_crtc_state->gmch_pfit.control) - return; - - assert_transcoder_disabled(display, old_crtc_state->cpu_transcoder); - - drm_dbg_kms(display->drm, "disabling pfit, current: 0x%08x\n", - intel_de_read(display, PFIT_CONTROL(display))); - intel_de_write(display, PFIT_CONTROL(display), 0); -} - static void i9xx_crtc_disable(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -3040,43 +2955,6 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder)); } -static bool i9xx_has_pfit(struct drm_i915_private *dev_priv) -{ - if (IS_I830(dev_priv)) - return false; - - return DISPLAY_VER(dev_priv) >= 4 || - IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv); -} - -static void i9xx_get_pfit_config(struct intel_crtc_state *crtc_state) -{ - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - enum pipe pipe; - u32 tmp; - - if (!i9xx_has_pfit(dev_priv)) - return; - - tmp = intel_de_read(dev_priv, PFIT_CONTROL(dev_priv)); - if (!(tmp & PFIT_ENABLE)) - return; - - /* Check whether the pfit is attached to our pipe. */ - if (DISPLAY_VER(dev_priv) >= 4) - pipe = REG_FIELD_GET(PFIT_PIPE_MASK, tmp); - else - pipe = PIPE_B; - - if (pipe != crtc->pipe) - return; - - crtc_state->gmch_pfit.control = tmp; - crtc_state->gmch_pfit.pgm_ratios = - intel_de_read(dev_priv, PFIT_PGM_RATIOS(dev_priv)); -} - static enum intel_output_format bdw_get_pipe_misc_output_format(struct intel_crtc *crtc) { @@ -3168,7 +3046,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, intel_get_transcoder_timings(crtc, pipe_config); intel_get_pipe_src_size(crtc, pipe_config); - i9xx_get_pfit_config(pipe_config); + i9xx_pfit_get_config(pipe_config); i9xx_dpll_get_hw_state(crtc, &pipe_config->dpll_hw_state); @@ -3451,41 +3329,6 @@ void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc, PIPE_LINK_N2(display, transcoder)); } -static void ilk_get_pfit_config(struct intel_crtc_state *crtc_state) -{ - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - u32 ctl, pos, size; - enum pipe pipe; - - ctl = intel_de_read(dev_priv, PF_CTL(crtc->pipe)); - if ((ctl & PF_ENABLE) == 0) - return; - - if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) - pipe = REG_FIELD_GET(PF_PIPE_SEL_MASK_IVB, ctl); - else - pipe = crtc->pipe; - - crtc_state->pch_pfit.enabled = true; - - pos = intel_de_read(dev_priv, PF_WIN_POS(crtc->pipe)); - size = intel_de_read(dev_priv, PF_WIN_SZ(crtc->pipe)); - - drm_rect_init(&crtc_state->pch_pfit.dst, - REG_FIELD_GET(PF_WIN_XPOS_MASK, pos), - REG_FIELD_GET(PF_WIN_YPOS_MASK, pos), - REG_FIELD_GET(PF_WIN_XSIZE_MASK, size), - REG_FIELD_GET(PF_WIN_YSIZE_MASK, size)); - - /* - * We currently do not free assignments of panel fitters on - * ivb/hsw (since we don't use the higher upscaling modes which - * differentiates them) so just WARN about this case for now. - */ - drm_WARN_ON(&dev_priv->drm, pipe != crtc->pipe); -} - static bool ilk_get_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { @@ -3558,7 +3401,7 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, intel_get_transcoder_timings(crtc, pipe_config); intel_get_pipe_src_size(crtc, pipe_config); - ilk_get_pfit_config(pipe_config); + ilk_pfit_get_config(pipe_config); ret = true; @@ -4133,7 +3976,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, if (DISPLAY_VER(dev_priv) >= 9) skl_scaler_get_config(pipe_config); else - ilk_get_pfit_config(pipe_config); + ilk_pfit_get_config(pipe_config); } hsw_ips_get_config(pipe_config); diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index f8b8610b0280..bc9a5a14ca6a 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -510,8 +510,6 @@ enum intel_display_power_domain intel_aux_power_domain(struct intel_digital_port *dig_port); void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state); -void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state); - int bdw_get_pipe_misc_bpp(struct intel_crtc *crtc); unsigned int intel_plane_fence_y_offset(const struct intel_plane_state *plane_state); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 889b3a902b8f..2782e18367c9 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -49,6 +49,7 @@ #include "intel_hdcp.h" #include "intel_hotplug.h" #include "intel_link_bw.h" +#include "intel_pfit.h" #include "intel_psr.h" #include "intel_vdsc.h" #include "skl_scaler.h" diff --git a/drivers/gpu/drm/i915/display/intel_pfit.c b/drivers/gpu/drm/i915/display/intel_pfit.c index 386ab57b9f8d..0a7609020c17 100644 --- a/drivers/gpu/drm/i915/display/intel_pfit.c +++ b/drivers/gpu/drm/i915/display/intel_pfit.c @@ -3,8 +3,10 @@ * Copyright © 2024 Intel Corporation */ +#include "i915_drv.h" #include "i915_reg.h" #include "i915_utils.h" +#include "intel_de.h" #include "intel_display_core.h" #include "intel_display_driver.h" #include "intel_display_types.h" @@ -552,3 +554,161 @@ int intel_pfit_compute_config(struct intel_crtc_state *crtc_state, else return pch_panel_fitting(crtc_state, conn_state); } + +void ilk_pfit_enable(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct drm_rect *dst = &crtc_state->pch_pfit.dst; + enum pipe pipe = crtc->pipe; + int width = drm_rect_width(dst); + int height = drm_rect_height(dst); + int x = dst->x1; + int y = dst->y1; + + if (!crtc_state->pch_pfit.enabled) + return; + + /* Force use of hard-coded filter coefficients + * as some pre-programmed values are broken, + * e.g. x201. + */ + if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) + intel_de_write_fw(dev_priv, PF_CTL(pipe), PF_ENABLE | + PF_FILTER_MED_3x3 | PF_PIPE_SEL_IVB(pipe)); + else + intel_de_write_fw(dev_priv, PF_CTL(pipe), PF_ENABLE | + PF_FILTER_MED_3x3); + intel_de_write_fw(dev_priv, PF_WIN_POS(pipe), + PF_WIN_XPOS(x) | PF_WIN_YPOS(y)); + intel_de_write_fw(dev_priv, PF_WIN_SZ(pipe), + PF_WIN_XSIZE(width) | PF_WIN_YSIZE(height)); +} + +void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum pipe pipe = crtc->pipe; + + /* To avoid upsetting the power well on haswell only disable the pfit if + * it's in use. The hw state code will make sure we get this right. */ + if (!old_crtc_state->pch_pfit.enabled) + return; + + intel_de_write_fw(dev_priv, PF_CTL(pipe), 0); + intel_de_write_fw(dev_priv, PF_WIN_POS(pipe), 0); + intel_de_write_fw(dev_priv, PF_WIN_SZ(pipe), 0); +} + +void ilk_pfit_get_config(struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + u32 ctl, pos, size; + enum pipe pipe; + + ctl = intel_de_read(dev_priv, PF_CTL(crtc->pipe)); + if ((ctl & PF_ENABLE) == 0) + return; + + if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) + pipe = REG_FIELD_GET(PF_PIPE_SEL_MASK_IVB, ctl); + else + pipe = crtc->pipe; + + crtc_state->pch_pfit.enabled = true; + + pos = intel_de_read(dev_priv, PF_WIN_POS(crtc->pipe)); + size = intel_de_read(dev_priv, PF_WIN_SZ(crtc->pipe)); + + drm_rect_init(&crtc_state->pch_pfit.dst, + REG_FIELD_GET(PF_WIN_XPOS_MASK, pos), + REG_FIELD_GET(PF_WIN_YPOS_MASK, pos), + REG_FIELD_GET(PF_WIN_XSIZE_MASK, size), + REG_FIELD_GET(PF_WIN_YSIZE_MASK, size)); + + /* + * We currently do not free assignments of panel fitters on + * ivb/hsw (since we don't use the higher upscaling modes which + * differentiates them) so just WARN about this case for now. + */ + drm_WARN_ON(&dev_priv->drm, pipe != crtc->pipe); +} + +void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + + if (!crtc_state->gmch_pfit.control) + return; + + /* + * The panel fitter should only be adjusted whilst the pipe is disabled, + * according to register description and PRM. + */ + drm_WARN_ON(display->drm, + intel_de_read(display, PFIT_CONTROL(display)) & PFIT_ENABLE); + assert_transcoder_disabled(display, crtc_state->cpu_transcoder); + + intel_de_write(display, PFIT_PGM_RATIOS(display), + crtc_state->gmch_pfit.pgm_ratios); + intel_de_write(display, PFIT_CONTROL(display), + crtc_state->gmch_pfit.control); + + /* Border color in case we don't scale up to the full screen. Black by + * default, change to something else for debugging. */ + intel_de_write(display, BCLRPAT(display, crtc->pipe), 0); +} + +void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state) +{ + struct intel_display *display = to_intel_display(old_crtc_state); + + if (!old_crtc_state->gmch_pfit.control) + return; + + assert_transcoder_disabled(display, old_crtc_state->cpu_transcoder); + + drm_dbg_kms(display->drm, "disabling pfit, current: 0x%08x\n", + intel_de_read(display, PFIT_CONTROL(display))); + intel_de_write(display, PFIT_CONTROL(display), 0); +} + +static bool i9xx_has_pfit(struct drm_i915_private *dev_priv) +{ + if (IS_I830(dev_priv)) + return false; + + return DISPLAY_VER(dev_priv) >= 4 || + IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv); +} + +void i9xx_pfit_get_config(struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum pipe pipe; + u32 tmp; + + if (!i9xx_has_pfit(dev_priv)) + return; + + tmp = intel_de_read(dev_priv, PFIT_CONTROL(dev_priv)); + if (!(tmp & PFIT_ENABLE)) + return; + + /* Check whether the pfit is attached to our pipe. */ + if (DISPLAY_VER(dev_priv) >= 4) + pipe = REG_FIELD_GET(PFIT_PIPE_MASK, tmp); + else + pipe = PIPE_B; + + if (pipe != crtc->pipe) + return; + + crtc_state->gmch_pfit.control = tmp; + crtc_state->gmch_pfit.pgm_ratios = + intel_de_read(dev_priv, PFIT_PGM_RATIOS(dev_priv)); +} diff --git a/drivers/gpu/drm/i915/display/intel_pfit.h b/drivers/gpu/drm/i915/display/intel_pfit.h index e7acaa61e1ac..ef34f9b49d09 100644 --- a/drivers/gpu/drm/i915/display/intel_pfit.h +++ b/drivers/gpu/drm/i915/display/intel_pfit.h @@ -11,5 +11,11 @@ struct intel_crtc_state; int intel_pfit_compute_config(struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); +void ilk_pfit_enable(const struct intel_crtc_state *crtc_state); +void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state); +void ilk_pfit_get_config(struct intel_crtc_state *crtc_state); +void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state); +void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state); +void i9xx_pfit_get_config(struct intel_crtc_state *crtc_state); #endif /* __INTEL_PFIT_H__ */ From a38a005d95796fb5d5b8c8be325facc75c4708c9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 26 Feb 2025 12:01:09 +0200 Subject: [PATCH 20/92] drm/i915/pfit: fix comment style for moved comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adhere to coding style. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/d3bc49cf04473a0be07bab1ad7fd9df1f671307f.1740564009.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_pfit.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_pfit.c b/drivers/gpu/drm/i915/display/intel_pfit.c index 0a7609020c17..5e4a6ef2ff8d 100644 --- a/drivers/gpu/drm/i915/display/intel_pfit.c +++ b/drivers/gpu/drm/i915/display/intel_pfit.c @@ -569,9 +569,9 @@ void ilk_pfit_enable(const struct intel_crtc_state *crtc_state) if (!crtc_state->pch_pfit.enabled) return; - /* Force use of hard-coded filter coefficients - * as some pre-programmed values are broken, - * e.g. x201. + /* + * Force use of hard-coded filter coefficients as some pre-programmed + * values are broken, e.g. x201. */ if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) intel_de_write_fw(dev_priv, PF_CTL(pipe), PF_ENABLE | @@ -591,8 +591,10 @@ void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state) struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - /* To avoid upsetting the power well on haswell only disable the pfit if - * it's in use. The hw state code will make sure we get this right. */ + /* + * To avoid upsetting the power well on haswell only disable the pfit if + * it's in use. The hw state code will make sure we get this right. + */ if (!old_crtc_state->pch_pfit.enabled) return; @@ -657,8 +659,10 @@ void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) intel_de_write(display, PFIT_CONTROL(display), crtc_state->gmch_pfit.control); - /* Border color in case we don't scale up to the full screen. Black by - * default, change to something else for debugging. */ + /* + * Border color in case we don't scale up to the full screen. Black by + * default, change to something else for debugging. + */ intel_de_write(display, BCLRPAT(display, crtc->pipe), 0); } From ecab9ac6aa57cf116b552c7eb6a5c8208c1746a0 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 26 Feb 2025 12:01:10 +0200 Subject: [PATCH 21/92] drm/i915/pfit: convert moved code to struct intel_display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recently relocated ilk/i9xx panel fitter code is still using struct drm_i915_private. Convert to struct intel_display. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/9967c49291c725037c3266832db4d9d8451dfa38.1740564009.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_pfit.c | 51 +++++++++++------------ 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_pfit.c b/drivers/gpu/drm/i915/display/intel_pfit.c index 5e4a6ef2ff8d..fa271c87de05 100644 --- a/drivers/gpu/drm/i915/display/intel_pfit.c +++ b/drivers/gpu/drm/i915/display/intel_pfit.c @@ -3,7 +3,6 @@ * Copyright © 2024 Intel Corporation */ -#include "i915_drv.h" #include "i915_reg.h" #include "i915_utils.h" #include "intel_de.h" @@ -557,8 +556,8 @@ int intel_pfit_compute_config(struct intel_crtc_state *crtc_state, void ilk_pfit_enable(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct drm_rect *dst = &crtc_state->pch_pfit.dst; enum pipe pipe = crtc->pipe; int width = drm_rect_width(dst); @@ -573,22 +572,22 @@ void ilk_pfit_enable(const struct intel_crtc_state *crtc_state) * Force use of hard-coded filter coefficients as some pre-programmed * values are broken, e.g. x201. */ - if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) - intel_de_write_fw(dev_priv, PF_CTL(pipe), PF_ENABLE | + if (display->platform.ivybridge || display->platform.haswell) + intel_de_write_fw(display, PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3 | PF_PIPE_SEL_IVB(pipe)); else - intel_de_write_fw(dev_priv, PF_CTL(pipe), PF_ENABLE | + intel_de_write_fw(display, PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3); - intel_de_write_fw(dev_priv, PF_WIN_POS(pipe), + intel_de_write_fw(display, PF_WIN_POS(pipe), PF_WIN_XPOS(x) | PF_WIN_YPOS(y)); - intel_de_write_fw(dev_priv, PF_WIN_SZ(pipe), + intel_de_write_fw(display, PF_WIN_SZ(pipe), PF_WIN_XSIZE(width) | PF_WIN_YSIZE(height)); } void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state) { + struct intel_display *display = to_intel_display(old_crtc_state); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; /* @@ -598,31 +597,31 @@ void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state) if (!old_crtc_state->pch_pfit.enabled) return; - intel_de_write_fw(dev_priv, PF_CTL(pipe), 0); - intel_de_write_fw(dev_priv, PF_WIN_POS(pipe), 0); - intel_de_write_fw(dev_priv, PF_WIN_SZ(pipe), 0); + intel_de_write_fw(display, PF_CTL(pipe), 0); + intel_de_write_fw(display, PF_WIN_POS(pipe), 0); + intel_de_write_fw(display, PF_WIN_SZ(pipe), 0); } void ilk_pfit_get_config(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 ctl, pos, size; enum pipe pipe; - ctl = intel_de_read(dev_priv, PF_CTL(crtc->pipe)); + ctl = intel_de_read(display, PF_CTL(crtc->pipe)); if ((ctl & PF_ENABLE) == 0) return; - if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) + if (display->platform.ivybridge || display->platform.haswell) pipe = REG_FIELD_GET(PF_PIPE_SEL_MASK_IVB, ctl); else pipe = crtc->pipe; crtc_state->pch_pfit.enabled = true; - pos = intel_de_read(dev_priv, PF_WIN_POS(crtc->pipe)); - size = intel_de_read(dev_priv, PF_WIN_SZ(crtc->pipe)); + pos = intel_de_read(display, PF_WIN_POS(crtc->pipe)); + size = intel_de_read(display, PF_WIN_SZ(crtc->pipe)); drm_rect_init(&crtc_state->pch_pfit.dst, REG_FIELD_GET(PF_WIN_XPOS_MASK, pos), @@ -635,7 +634,7 @@ void ilk_pfit_get_config(struct intel_crtc_state *crtc_state) * ivb/hsw (since we don't use the higher upscaling modes which * differentiates them) so just WARN about this case for now. */ - drm_WARN_ON(&dev_priv->drm, pipe != crtc->pipe); + drm_WARN_ON(display->drm, pipe != crtc->pipe); } void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) @@ -680,31 +679,31 @@ void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state) intel_de_write(display, PFIT_CONTROL(display), 0); } -static bool i9xx_has_pfit(struct drm_i915_private *dev_priv) +static bool i9xx_has_pfit(struct intel_display *display) { - if (IS_I830(dev_priv)) + if (display->platform.i830) return false; - return DISPLAY_VER(dev_priv) >= 4 || - IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv); + return DISPLAY_VER(display) >= 4 || + display->platform.pineview || display->platform.mobile; } void i9xx_pfit_get_config(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe; u32 tmp; - if (!i9xx_has_pfit(dev_priv)) + if (!i9xx_has_pfit(display)) return; - tmp = intel_de_read(dev_priv, PFIT_CONTROL(dev_priv)); + tmp = intel_de_read(display, PFIT_CONTROL(display)); if (!(tmp & PFIT_ENABLE)) return; /* Check whether the pfit is attached to our pipe. */ - if (DISPLAY_VER(dev_priv) >= 4) + if (DISPLAY_VER(display) >= 4) pipe = REG_FIELD_GET(PFIT_PIPE_MASK, tmp); else pipe = PIPE_B; @@ -714,5 +713,5 @@ void i9xx_pfit_get_config(struct intel_crtc_state *crtc_state) crtc_state->gmch_pfit.control = tmp; crtc_state->gmch_pfit.pgm_ratios = - intel_de_read(dev_priv, PFIT_PGM_RATIOS(dev_priv)); + intel_de_read(display, PFIT_PGM_RATIOS(display)); } From 24abc47205daa79dfde92274fa8c14b20b3cf797 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 26 Feb 2025 12:01:11 +0200 Subject: [PATCH 22/92] drm/i915/pfit: split out intel_pfit_regs.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split out the panel fitter registers to a separate file. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/db8952baa3e3e5eaaa8a3a5bc723c4e47aeaa6a7.1740564009.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_lvds.c | 1 + drivers/gpu/drm/i915/display/intel_overlay.c | 1 + drivers/gpu/drm/i915/display/intel_pfit.c | 1 + .../gpu/drm/i915/display/intel_pfit_regs.h | 79 +++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 70 ---------------- drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 1 + 6 files changed, 83 insertions(+), 70 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_pfit_regs.h diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index ea144f7e7829..b2562b581018 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -53,6 +53,7 @@ #include "intel_lvds_regs.h" #include "intel_panel.h" #include "intel_pfit.h" +#include "intel_pfit_regs.h" #include "intel_pps_regs.h" /* Private structure for the integrated LVDS support */ diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index 4d00db86131b..5c1b20af2a07 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -42,6 +42,7 @@ #include "intel_frontbuffer.h" #include "intel_overlay.h" #include "intel_pci_config.h" +#include "intel_pfit_regs.h" /* Limits for overlay size. According to intel doc, the real limits are: * Y width: 4095, UV width (planar): 2047, Y height: 2047, diff --git a/drivers/gpu/drm/i915/display/intel_pfit.c b/drivers/gpu/drm/i915/display/intel_pfit.c index fa271c87de05..6fc58fbee2f9 100644 --- a/drivers/gpu/drm/i915/display/intel_pfit.c +++ b/drivers/gpu/drm/i915/display/intel_pfit.c @@ -11,6 +11,7 @@ #include "intel_display_types.h" #include "intel_lvds_regs.h" #include "intel_pfit.h" +#include "intel_pfit_regs.h" static int intel_pch_pfit_check_dst_window(const struct intel_crtc_state *crtc_state) { diff --git a/drivers/gpu/drm/i915/display/intel_pfit_regs.h b/drivers/gpu/drm/i915/display/intel_pfit_regs.h new file mode 100644 index 000000000000..add8ce28004e --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_pfit_regs.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __INTEL_PFIT_REGS_H__ +#define __INTEL_PFIT_REGS_H__ + +#include "intel_display_reg_defs.h" + +/* Panel fitting */ +#define PFIT_CONTROL(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61230) +#define PFIT_ENABLE REG_BIT(31) +#define PFIT_PIPE_MASK REG_GENMASK(30, 29) /* 965+ */ +#define PFIT_PIPE(pipe) REG_FIELD_PREP(PFIT_PIPE_MASK, (pipe)) +#define PFIT_SCALING_MASK REG_GENMASK(28, 26) /* 965+ */ +#define PFIT_SCALING_AUTO REG_FIELD_PREP(PFIT_SCALING_MASK, 0) +#define PFIT_SCALING_PROGRAMMED REG_FIELD_PREP(PFIT_SCALING_MASK, 1) +#define PFIT_SCALING_PILLAR REG_FIELD_PREP(PFIT_SCALING_MASK, 2) +#define PFIT_SCALING_LETTER REG_FIELD_PREP(PFIT_SCALING_MASK, 3) +#define PFIT_FILTER_MASK REG_GENMASK(25, 24) /* 965+ */ +#define PFIT_FILTER_FUZZY REG_FIELD_PREP(PFIT_FILTER_MASK, 0) +#define PFIT_FILTER_CRISP REG_FIELD_PREP(PFIT_FILTER_MASK, 1) +#define PFIT_FILTER_MEDIAN REG_FIELD_PREP(PFIT_FILTER_MASK, 2) +#define PFIT_VERT_INTERP_MASK REG_GENMASK(11, 10) /* pre-965 */ +#define PFIT_VERT_INTERP_BILINEAR REG_FIELD_PREP(PFIT_VERT_INTERP_MASK, 1) +#define PFIT_VERT_AUTO_SCALE REG_BIT(9) /* pre-965 */ +#define PFIT_HORIZ_INTERP_MASK REG_GENMASK(7, 6) /* pre-965 */ +#define PFIT_HORIZ_INTERP_BILINEAR REG_FIELD_PREP(PFIT_HORIZ_INTERP_MASK, 1) +#define PFIT_HORIZ_AUTO_SCALE REG_BIT(5) /* pre-965 */ +#define PFIT_PANEL_8TO6_DITHER_ENABLE REG_BIT(3) /* pre-965 */ + +#define PFIT_PGM_RATIOS(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61234) +#define PFIT_VERT_SCALE_MASK REG_GENMASK(31, 20) /* pre-965 */ +#define PFIT_VERT_SCALE(x) REG_FIELD_PREP(PFIT_VERT_SCALE_MASK, (x)) +#define PFIT_HORIZ_SCALE_MASK REG_GENMASK(15, 4) /* pre-965 */ +#define PFIT_HORIZ_SCALE(x) REG_FIELD_PREP(PFIT_HORIZ_SCALE_MASK, (x)) +#define PFIT_VERT_SCALE_MASK_965 REG_GENMASK(28, 16) /* 965+ */ +#define PFIT_HORIZ_SCALE_MASK_965 REG_GENMASK(12, 0) /* 965+ */ + +#define PFIT_AUTO_RATIOS(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61238) + +/* CPU panel fitter */ +/* IVB+ has 3 fitters, 0 is 7x5 capable, the other two only 3x3 */ +#define _PFA_CTL_1 0x68080 +#define _PFB_CTL_1 0x68880 +#define PF_CTL(pipe) _MMIO_PIPE(pipe, _PFA_CTL_1, _PFB_CTL_1) +#define PF_ENABLE REG_BIT(31) +#define PF_PIPE_SEL_MASK_IVB REG_GENMASK(30, 29) /* ivb/hsw */ +#define PF_PIPE_SEL_IVB(pipe) REG_FIELD_PREP(PF_PIPE_SEL_MASK_IVB, (pipe)) +#define PF_FILTER_MASK REG_GENMASK(24, 23) +#define PF_FILTER_PROGRAMMED REG_FIELD_PREP(PF_FILTER_MASK, 0) +#define PF_FILTER_MED_3x3 REG_FIELD_PREP(PF_FILTER_MASK, 1) +#define PF_FILTER_EDGE_ENHANCE REG_FIELD_PREP(PF_FILTER_EDGE_MASK, 2) +#define PF_FILTER_EDGE_SOFTEN REG_FIELD_PREP(PF_FILTER_EDGE_MASK, 3) + +#define _PFA_WIN_SZ 0x68074 +#define _PFB_WIN_SZ 0x68874 +#define PF_WIN_SZ(pipe) _MMIO_PIPE(pipe, _PFA_WIN_SZ, _PFB_WIN_SZ) +#define PF_WIN_XSIZE_MASK REG_GENMASK(31, 16) +#define PF_WIN_XSIZE(w) REG_FIELD_PREP(PF_WIN_XSIZE_MASK, (w)) +#define PF_WIN_YSIZE_MASK REG_GENMASK(15, 0) +#define PF_WIN_YSIZE(h) REG_FIELD_PREP(PF_WIN_YSIZE_MASK, (h)) + +#define _PFA_WIN_POS 0x68070 +#define _PFB_WIN_POS 0x68870 +#define PF_WIN_POS(pipe) _MMIO_PIPE(pipe, _PFA_WIN_POS, _PFB_WIN_POS) +#define PF_WIN_XPOS_MASK REG_GENMASK(31, 16) +#define PF_WIN_XPOS(x) REG_FIELD_PREP(PF_WIN_XPOS_MASK, (x)) +#define PF_WIN_YPOS_MASK REG_GENMASK(15, 0) +#define PF_WIN_YPOS(y) REG_FIELD_PREP(PF_WIN_YPOS_MASK, (y)) + +#define _PFA_VSCALE 0x68084 +#define _PFB_VSCALE 0x68884 +#define PF_VSCALE(pipe) _MMIO_PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE) + +#define _PFA_HSCALE 0x68090 +#define _PFB_HSCALE 0x68890 +#define PF_HSCALE(pipe) _MMIO_PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE) + +#endif /* __INTEL_PFIT_REGS_H__ */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b31b26e9a685..8084debd28a2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1385,38 +1385,6 @@ /* ADL and later: */ #define VIDEO_DIP_ENABLE_AS_ADL REG_BIT(23) -/* Panel fitting */ -#define PFIT_CONTROL(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61230) -#define PFIT_ENABLE REG_BIT(31) -#define PFIT_PIPE_MASK REG_GENMASK(30, 29) /* 965+ */ -#define PFIT_PIPE(pipe) REG_FIELD_PREP(PFIT_PIPE_MASK, (pipe)) -#define PFIT_SCALING_MASK REG_GENMASK(28, 26) /* 965+ */ -#define PFIT_SCALING_AUTO REG_FIELD_PREP(PFIT_SCALING_MASK, 0) -#define PFIT_SCALING_PROGRAMMED REG_FIELD_PREP(PFIT_SCALING_MASK, 1) -#define PFIT_SCALING_PILLAR REG_FIELD_PREP(PFIT_SCALING_MASK, 2) -#define PFIT_SCALING_LETTER REG_FIELD_PREP(PFIT_SCALING_MASK, 3) -#define PFIT_FILTER_MASK REG_GENMASK(25, 24) /* 965+ */ -#define PFIT_FILTER_FUZZY REG_FIELD_PREP(PFIT_FILTER_MASK, 0) -#define PFIT_FILTER_CRISP REG_FIELD_PREP(PFIT_FILTER_MASK, 1) -#define PFIT_FILTER_MEDIAN REG_FIELD_PREP(PFIT_FILTER_MASK, 2) -#define PFIT_VERT_INTERP_MASK REG_GENMASK(11, 10) /* pre-965 */ -#define PFIT_VERT_INTERP_BILINEAR REG_FIELD_PREP(PFIT_VERT_INTERP_MASK, 1) -#define PFIT_VERT_AUTO_SCALE REG_BIT(9) /* pre-965 */ -#define PFIT_HORIZ_INTERP_MASK REG_GENMASK(7, 6) /* pre-965 */ -#define PFIT_HORIZ_INTERP_BILINEAR REG_FIELD_PREP(PFIT_HORIZ_INTERP_MASK, 1) -#define PFIT_HORIZ_AUTO_SCALE REG_BIT(5) /* pre-965 */ -#define PFIT_PANEL_8TO6_DITHER_ENABLE REG_BIT(3) /* pre-965 */ - -#define PFIT_PGM_RATIOS(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61234) -#define PFIT_VERT_SCALE_MASK REG_GENMASK(31, 20) /* pre-965 */ -#define PFIT_VERT_SCALE(x) REG_FIELD_PREP(PFIT_VERT_SCALE_MASK, (x)) -#define PFIT_HORIZ_SCALE_MASK REG_GENMASK(15, 4) /* pre-965 */ -#define PFIT_HORIZ_SCALE(x) REG_FIELD_PREP(PFIT_HORIZ_SCALE_MASK, (x)) -#define PFIT_VERT_SCALE_MASK_965 REG_GENMASK(28, 16) /* 965+ */ -#define PFIT_HORIZ_SCALE_MASK_965 REG_GENMASK(12, 0) /* 965+ */ - -#define PFIT_AUTO_RATIOS(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61238) - #define PCH_GTC_CTL _MMIO(0xe7000) #define PCH_GTC_ENABLE (1 << 31) @@ -1911,44 +1879,6 @@ #define _PIPEB_LINK_N2 0x6104c #define PIPE_LINK_N2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_N2) -/* CPU panel fitter */ -/* IVB+ has 3 fitters, 0 is 7x5 capable, the other two only 3x3 */ -#define _PFA_CTL_1 0x68080 -#define _PFB_CTL_1 0x68880 -#define PF_CTL(pipe) _MMIO_PIPE(pipe, _PFA_CTL_1, _PFB_CTL_1) -#define PF_ENABLE REG_BIT(31) -#define PF_PIPE_SEL_MASK_IVB REG_GENMASK(30, 29) /* ivb/hsw */ -#define PF_PIPE_SEL_IVB(pipe) REG_FIELD_PREP(PF_PIPE_SEL_MASK_IVB, (pipe)) -#define PF_FILTER_MASK REG_GENMASK(24, 23) -#define PF_FILTER_PROGRAMMED REG_FIELD_PREP(PF_FILTER_MASK, 0) -#define PF_FILTER_MED_3x3 REG_FIELD_PREP(PF_FILTER_MASK, 1) -#define PF_FILTER_EDGE_ENHANCE REG_FIELD_PREP(PF_FILTER_EDGE_MASK, 2) -#define PF_FILTER_EDGE_SOFTEN REG_FIELD_PREP(PF_FILTER_EDGE_MASK, 3) - -#define _PFA_WIN_SZ 0x68074 -#define _PFB_WIN_SZ 0x68874 -#define PF_WIN_SZ(pipe) _MMIO_PIPE(pipe, _PFA_WIN_SZ, _PFB_WIN_SZ) -#define PF_WIN_XSIZE_MASK REG_GENMASK(31, 16) -#define PF_WIN_XSIZE(w) REG_FIELD_PREP(PF_WIN_XSIZE_MASK, (w)) -#define PF_WIN_YSIZE_MASK REG_GENMASK(15, 0) -#define PF_WIN_YSIZE(h) REG_FIELD_PREP(PF_WIN_YSIZE_MASK, (h)) - -#define _PFA_WIN_POS 0x68070 -#define _PFB_WIN_POS 0x68870 -#define PF_WIN_POS(pipe) _MMIO_PIPE(pipe, _PFA_WIN_POS, _PFB_WIN_POS) -#define PF_WIN_XPOS_MASK REG_GENMASK(31, 16) -#define PF_WIN_XPOS(x) REG_FIELD_PREP(PF_WIN_XPOS_MASK, (x)) -#define PF_WIN_YPOS_MASK REG_GENMASK(15, 0) -#define PF_WIN_YPOS(y) REG_FIELD_PREP(PF_WIN_YPOS_MASK, (y)) - -#define _PFA_VSCALE 0x68084 -#define _PFB_VSCALE 0x68884 -#define PF_VSCALE(pipe) _MMIO_PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE) - -#define _PFA_HSCALE 0x68090 -#define _PFB_HSCALE 0x68890 -#define PF_HSCALE(pipe) _MMIO_PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE) - /* * Skylake scalers */ diff --git a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c index 04076316e139..76d84cbb8361 100644 --- a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c +++ b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c @@ -18,6 +18,7 @@ #include "display/intel_fbc_regs.h" #include "display/intel_fdi_regs.h" #include "display/intel_lvds_regs.h" +#include "display/intel_pfit_regs.h" #include "display/intel_psr_regs.h" #include "display/intel_sprite_regs.h" #include "display/skl_universal_plane_regs.h" From 76b7be63d9f33e8f319e480c50d3e53460927add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 18 Feb 2025 22:58:47 +0200 Subject: [PATCH 23/92] drm/i915/dsb: Allow DSB based updates without planes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't actually need any planes to get updated in order to perform the commit on the DSB. Allow DSB based updates even when we don't touch planes. The main benefit here is that pure LUT updates will now go through the DSB path and therefore we don't have to do vblank evasion/etc. on the CPU. I think the reason I had this excluded was that I was originally contemplating using frame/flip timestamps as a way to complete the commits. But I had to scrap that idea when it turned out that those timestamp get corrupted when DSB is poking at random registers. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250218205850.1422-2-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/display/intel_display.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ecc39ffd8dd0..4843ad19899e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7175,7 +7175,6 @@ static void intel_atomic_dsb_prepare(struct intel_atomic_state *state, /* FIXME deal with everything */ new_crtc_state->use_dsb = - new_crtc_state->update_planes && !new_crtc_state->do_async_flip && (DISPLAY_VER(display) >= 20 || !new_crtc_state->has_psr) && !new_crtc_state->scaler_state.scaler_users && From b4ebc06212a3b8906c837bf899b34a2ae36a5e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 18 Feb 2025 22:58:48 +0200 Subject: [PATCH 24/92] drm/i915/dsb: Plumb dsb into plane scaler functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to start doing scaler programming (plane scalers only initially) on the DSB. To that end plumb the DSB into the relevant places in the scaler code. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250218205850.1422-3-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/i915/display/skl_scaler.c | 60 +++++++++++-------- drivers/gpu/drm/i915/display/skl_scaler.h | 7 ++- .../drm/i915/display/skl_universal_plane.c | 4 +- 4 files changed, 42 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 4843ad19899e..2a5acf45ff41 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6648,7 +6648,7 @@ static void commit_pipe_post_planes(struct intel_atomic_state *state, */ if (DISPLAY_VER(dev_priv) >= 9 && !intel_crtc_needs_modeset(new_crtc_state)) - skl_detach_scalers(new_crtc_state); + skl_detach_scalers(NULL, new_crtc_state); if (intel_crtc_vrr_enabling(state, crtc)) intel_vrr_enable(new_crtc_state); diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 3d24fa773094..ee81220a7c88 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -666,12 +666,14 @@ static u16 glk_nearest_filter_coef(int t) */ static void glk_program_nearest_filter_coefs(struct intel_display *display, + struct intel_dsb *dsb, enum pipe pipe, int id, int set) { int i; - intel_de_write_fw(display, GLK_PS_COEF_INDEX_SET(pipe, id, set), - PS_COEF_INDEX_AUTO_INC); + intel_de_write_dsb(display, dsb, + GLK_PS_COEF_INDEX_SET(pipe, id, set), + PS_COEF_INDEX_AUTO_INC); for (i = 0; i < 17 * 7; i += 2) { u32 tmp; @@ -683,11 +685,12 @@ static void glk_program_nearest_filter_coefs(struct intel_display *display, t = glk_coef_tap(i + 1); tmp |= glk_nearest_filter_coef(t) << 16; - intel_de_write_fw(display, GLK_PS_COEF_DATA_SET(pipe, id, set), - tmp); + intel_de_write_dsb(display, dsb, + GLK_PS_COEF_DATA_SET(pipe, id, set), tmp); } - intel_de_write_fw(display, GLK_PS_COEF_INDEX_SET(pipe, id, set), 0); + intel_de_write_dsb(display, dsb, + GLK_PS_COEF_INDEX_SET(pipe, id, set), 0); } static u32 skl_scaler_get_filter_select(enum drm_scaling_filter filter, int set) @@ -703,14 +706,15 @@ static u32 skl_scaler_get_filter_select(enum drm_scaling_filter filter, int set) return PS_FILTER_MEDIUM; } -static void skl_scaler_setup_filter(struct intel_display *display, enum pipe pipe, +static void skl_scaler_setup_filter(struct intel_display *display, + struct intel_dsb *dsb, enum pipe pipe, int id, int set, enum drm_scaling_filter filter) { switch (filter) { case DRM_SCALING_FILTER_DEFAULT: break; case DRM_SCALING_FILTER_NEAREST_NEIGHBOR: - glk_program_nearest_filter_coefs(display, pipe, id, set); + glk_program_nearest_filter_coefs(display, dsb, pipe, id, set); break; default: MISSING_CASE(filter); @@ -759,7 +763,7 @@ void skl_pfit_enable(const struct intel_crtc_state *crtc_state) trace_intel_pipe_scaler_update_arm(crtc, id, x, y, width, height); - skl_scaler_setup_filter(display, pipe, id, 0, + skl_scaler_setup_filter(display, NULL, pipe, id, 0, crtc_state->hw.scaling_filter); intel_de_write_fw(display, SKL_PS_CTRL(pipe, id), ps_ctrl); @@ -775,7 +779,8 @@ void skl_pfit_enable(const struct intel_crtc_state *crtc_state) } void -skl_program_plane_scaler(struct intel_plane *plane, +skl_program_plane_scaler(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { @@ -825,35 +830,38 @@ skl_program_plane_scaler(struct intel_plane *plane, trace_intel_plane_scaler_update_arm(plane, scaler_id, crtc_x, crtc_y, crtc_w, crtc_h); - skl_scaler_setup_filter(display, pipe, scaler_id, 0, + skl_scaler_setup_filter(display, dsb, pipe, scaler_id, 0, plane_state->hw.scaling_filter); - intel_de_write_fw(display, SKL_PS_CTRL(pipe, scaler_id), ps_ctrl); - intel_de_write_fw(display, SKL_PS_VPHASE(pipe, scaler_id), - PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase)); - intel_de_write_fw(display, SKL_PS_HPHASE(pipe, scaler_id), - PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase)); - intel_de_write_fw(display, SKL_PS_WIN_POS(pipe, scaler_id), - PS_WIN_XPOS(crtc_x) | PS_WIN_YPOS(crtc_y)); - intel_de_write_fw(display, SKL_PS_WIN_SZ(pipe, scaler_id), - PS_WIN_XSIZE(crtc_w) | PS_WIN_YSIZE(crtc_h)); + intel_de_write_dsb(display, dsb, SKL_PS_CTRL(pipe, scaler_id), + ps_ctrl); + intel_de_write_dsb(display, dsb, SKL_PS_VPHASE(pipe, scaler_id), + PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase)); + intel_de_write_dsb(display, dsb, SKL_PS_HPHASE(pipe, scaler_id), + PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase)); + intel_de_write_dsb(display, dsb, SKL_PS_WIN_POS(pipe, scaler_id), + PS_WIN_XPOS(crtc_x) | PS_WIN_YPOS(crtc_y)); + intel_de_write_dsb(display, dsb, SKL_PS_WIN_SZ(pipe, scaler_id), + PS_WIN_XSIZE(crtc_w) | PS_WIN_YSIZE(crtc_h)); } -static void skl_detach_scaler(struct intel_crtc *crtc, int id) +static void skl_detach_scaler(struct intel_dsb *dsb, + struct intel_crtc *crtc, int id) { struct intel_display *display = to_intel_display(crtc); trace_intel_scaler_disable_arm(crtc, id); - intel_de_write_fw(display, SKL_PS_CTRL(crtc->pipe, id), 0); - intel_de_write_fw(display, SKL_PS_WIN_POS(crtc->pipe, id), 0); - intel_de_write_fw(display, SKL_PS_WIN_SZ(crtc->pipe, id), 0); + intel_de_write_dsb(display, dsb, SKL_PS_CTRL(crtc->pipe, id), 0); + intel_de_write_dsb(display, dsb, SKL_PS_WIN_POS(crtc->pipe, id), 0); + intel_de_write_dsb(display, dsb, SKL_PS_WIN_SZ(crtc->pipe, id), 0); } /* * This function detaches (aka. unbinds) unused scalers in hardware */ -void skl_detach_scalers(const struct intel_crtc_state *crtc_state) +void skl_detach_scalers(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); const struct intel_crtc_scaler_state *scaler_state = @@ -863,7 +871,7 @@ void skl_detach_scalers(const struct intel_crtc_state *crtc_state) /* loop through and disable scalers that aren't in use */ for (i = 0; i < crtc->num_scalers; i++) { if (!scaler_state->scalers[i].in_use) - skl_detach_scaler(crtc, i); + skl_detach_scaler(dsb, crtc, i); } } @@ -873,7 +881,7 @@ void skl_scaler_disable(const struct intel_crtc_state *old_crtc_state) int i; for (i = 0; i < crtc->num_scalers; i++) - skl_detach_scaler(crtc, i); + skl_detach_scaler(NULL, crtc, i); } void skl_scaler_get_config(struct intel_crtc_state *crtc_state) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.h b/drivers/gpu/drm/i915/display/skl_scaler.h index 4d2e2dbb1666..355ea15260ca 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.h +++ b/drivers/gpu/drm/i915/display/skl_scaler.h @@ -8,6 +8,7 @@ struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; +struct intel_dsb; struct intel_plane; struct intel_plane_state; @@ -21,10 +22,12 @@ int intel_atomic_setup_scalers(struct intel_atomic_state *state, void skl_pfit_enable(const struct intel_crtc_state *crtc_state); -void skl_program_plane_scaler(struct intel_plane *plane, +void skl_program_plane_scaler(struct intel_dsb *dsb, + struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); -void skl_detach_scalers(const struct intel_crtc_state *crtc_state); +void skl_detach_scalers(struct intel_dsb *dsb, + const struct intel_crtc_state *crtc_state); void skl_scaler_disable(const struct intel_crtc_state *old_crtc_state); void skl_scaler_get_config(struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index cd9762947f1d..3488c7ae6d8a 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1466,7 +1466,7 @@ skl_plane_update_arm(struct intel_dsb *dsb, * TODO: split into noarm+arm pair */ if (plane_state->scaler_id >= 0) - skl_program_plane_scaler(plane, crtc_state, plane_state); + skl_program_plane_scaler(dsb, plane, crtc_state, plane_state); /* * The control register self-arms if the plane was previously @@ -1646,7 +1646,7 @@ icl_plane_update_arm(struct intel_dsb *dsb, * TODO: split into noarm+arm pair */ if (plane_state->scaler_id >= 0) - skl_program_plane_scaler(plane, crtc_state, plane_state); + skl_program_plane_scaler(dsb, plane, crtc_state, plane_state); icl_plane_update_sel_fetch_arm(dsb, plane, crtc_state, plane_state); From 67093883808b5b39894d8859937be4468eca50db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 18 Feb 2025 22:58:49 +0200 Subject: [PATCH 25/92] drm/i915/dsb: Allow DSB based commits when scalers are in use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Have DSB perform plane scaler programming as well. Changes to pfit/pipe scaler are not being done on the dsb since those take the fastset path. However we do now allow DSB based plane updates when the pfit/pipe scaler is currently enabled (the pfit/pipe scaler just won't be touched by the DSB). Fortunately the hardware issue where some scaler registers are latched at frame start and some at start of vblank has been fixed on icl+ (IIRC), and since DSB is tgl+ only we don't have to do any changes to the DSB vblank evasion. Not that we handle that hardware issue correctly in the CPU vblank evasion either... Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250218205850.1422-4-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/display/intel_display.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 2a5acf45ff41..f0fbe18d2f7e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7162,8 +7162,6 @@ static void intel_atomic_dsb_prepare(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - const struct intel_crtc_state *old_crtc_state = - intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); @@ -7177,8 +7175,6 @@ static void intel_atomic_dsb_prepare(struct intel_atomic_state *state, new_crtc_state->use_dsb = !new_crtc_state->do_async_flip && (DISPLAY_VER(display) >= 20 || !new_crtc_state->has_psr) && - !new_crtc_state->scaler_state.scaler_users && - !old_crtc_state->scaler_state.scaler_users && !intel_crtc_needs_modeset(new_crtc_state) && !intel_crtc_needs_fastset(new_crtc_state); @@ -7188,6 +7184,7 @@ static void intel_atomic_dsb_prepare(struct intel_atomic_state *state, static void intel_atomic_dsb_finish(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); @@ -7234,6 +7231,10 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, intel_crtc_planes_update_arm(new_crtc_state->dsb_commit, state, crtc); + if (DISPLAY_VER(display) >= 9) + skl_detach_scalers(new_crtc_state->dsb_commit, + new_crtc_state); + if (!new_crtc_state->dsb_color_vblank) { intel_dsb_wait_vblanks(new_crtc_state->dsb_commit, 1); From 02649bbde017a3ff0ff24105d791016022bd443d Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Thu, 27 Feb 2025 17:28:17 -0300 Subject: [PATCH 26/92] drm/i915/display: Use IP version check for Wa_14020863754 Wa_14020863754 applies to the display IP, so we should be checking on display IP version instead of platform. So, let's replace display->platform.battlemage with the proper IP version check (14.01 for Xe2_HPD). Furthermore, for workarounds, we should be checking on full IP versions to avoid applying the workaround to some variant of the IP that could theoretically appear in the future (which is likely to have a different minor release number), since the issue addressed by the workaround could be fixed in such new release. Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20250227-xe3lpd-wa-14020863754-v2-1-92b35de1c563@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_audio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index aaba438ab41e..115c30a5ff70 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -190,7 +190,8 @@ static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = { */ static bool needs_wa_14020863754(struct intel_display *display) { - return DISPLAY_VER(display) == 20 || display->platform.battlemage; + return DISPLAY_VERx100(display) == 2000 || + DISPLAY_VERx100(display) == 1401; } /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */ From 2c2e7170a750506ed9e1d28e225b647a6563fb3c Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Thu, 27 Feb 2025 17:28:18 -0300 Subject: [PATCH 27/92] drm/i915/audio: Extend Wa_14020863754 to Xe3_LPD Workaround Wa_14020863754 also applies to Xe3_LPD. Update needs_wa_14020863754() accordingly. Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20250227-xe3lpd-wa-14020863754-v2-2-92b35de1c563@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_audio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 115c30a5ff70..ea935a5d94c8 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -190,7 +190,8 @@ static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = { */ static bool needs_wa_14020863754(struct intel_display *display) { - return DISPLAY_VERx100(display) == 2000 || + return DISPLAY_VERx100(display) == 3000 || + DISPLAY_VERx100(display) == 2000 || DISPLAY_VERx100(display) == 1401; } From 322ec93e9081d717fbc02c14fe80f754709e8b9c Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Thu, 27 Feb 2025 18:09:12 -0300 Subject: [PATCH 28/92] drm/i915/display: Use explicit base values in POWER_DOMAIN_*() macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although we have comments in intel_display_limits.h saying that the code expects PIPE_A and TRANSCODER_A to be zero, it doesn't hurt to add them as explicit base values for calculating the power domain offset in POWER_DOMAIN_*() macros. On the plus side, we have that this: * Fixes a warning reported by kernel test robot about doing arithmetic with two different enum types. * Makes the code arguably more robust (in the unlikely event of those bases becoming non-zero). v2: - Prefer using explicit base values instead of simply casting the macro argument to int. (Ville) - Update commit message to match the new approach (for reference, the old message subject was "drm/i915/display: Use explicit cast in POWER_DOMAIN_*() macros"). Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202502120809.XfmcqkBD-lkp@intel.com/ Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250227-improve-type-safey-power-domain-macros-v3-1-b6eaa00f9c33@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_display_power.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index a3a5c1be8bab..4ad35bd4b040 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -117,12 +117,12 @@ enum intel_display_power_domain { POWER_DOMAIN_INVALID = POWER_DOMAIN_NUM, }; -#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A) +#define POWER_DOMAIN_PIPE(pipe) ((pipe) - PIPE_A + POWER_DOMAIN_PIPE_A) #define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \ - ((pipe) + POWER_DOMAIN_PIPE_PANEL_FITTER_A) + ((pipe) - PIPE_A + POWER_DOMAIN_PIPE_PANEL_FITTER_A) #define POWER_DOMAIN_TRANSCODER(tran) \ ((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \ - (tran) + POWER_DOMAIN_TRANSCODER_A) + (tran) - TRANSCODER_A + POWER_DOMAIN_TRANSCODER_A) struct intel_power_domain_mask { DECLARE_BITMAP(bits, POWER_DOMAIN_NUM); From 5c91b5ad7155ee6e22930f7cbcb8e47dadbe13e7 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Thu, 27 Feb 2025 18:09:13 -0300 Subject: [PATCH 29/92] drm/i915/display: Make POWER_DOMAIN_*() always result in enum intel_display_power_domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the hope of contributing to type safety in our code, let's ensure that the type returned by the POWER_DOMAIN_*() macros is always of type enum intel_display_power_domain. v2: - Remove accidental +1 in definition of POWER_DOMAIN_PIPE(). (Jani) Cc: Jani Nikula Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250227-improve-type-safey-power-domain-macros-v3-2-b6eaa00f9c33@intel.com Signed-off-by: Gustavo Sousa --- drivers/gpu/drm/i915/display/intel_display_power.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 4ad35bd4b040..1b53d67f9b60 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -117,12 +117,13 @@ enum intel_display_power_domain { POWER_DOMAIN_INVALID = POWER_DOMAIN_NUM, }; -#define POWER_DOMAIN_PIPE(pipe) ((pipe) - PIPE_A + POWER_DOMAIN_PIPE_A) +#define POWER_DOMAIN_PIPE(pipe) \ + ((enum intel_display_power_domain)((pipe) - PIPE_A + POWER_DOMAIN_PIPE_A)) #define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \ - ((pipe) - PIPE_A + POWER_DOMAIN_PIPE_PANEL_FITTER_A) + ((enum intel_display_power_domain)((pipe) - PIPE_A + POWER_DOMAIN_PIPE_PANEL_FITTER_A)) #define POWER_DOMAIN_TRANSCODER(tran) \ ((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \ - (tran) - TRANSCODER_A + POWER_DOMAIN_TRANSCODER_A) + (enum intel_display_power_domain)((tran) - TRANSCODER_A + POWER_DOMAIN_TRANSCODER_A)) struct intel_power_domain_mask { DECLARE_BITMAP(bits, POWER_DOMAIN_NUM); From abf874a328a885592a6bfe6f7db463974e14b615 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 28 Feb 2025 14:49:29 +0200 Subject: [PATCH 30/92] drm/i915/mst: add mst sub-struct to struct intel_dp Move active_mst_links, mst_encoders[], and mst_mgr members of struct intel_dp under an mst sub-struct to group mst related things together. Rename them active_links, stream_encoders[] and mgr for clarity. Note that is_mst and mst_detect are not included, as they're also relevant for non-mst. The sub-struct is for active mst. Cc: Imre Deak Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/6f282f90bfe2dd9162e2dee8f681c84313971992.1740746939.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_debugfs.c | 2 +- .../drm/i915/display/intel_display_types.h | 9 +- drivers/gpu/drm/i915/display/intel_dp.c | 26 +++-- drivers/gpu/drm/i915/display/intel_dp_mst.c | 94 +++++++++---------- drivers/gpu/drm/i915/display/intel_hdcp.c | 2 +- 5 files changed, 66 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 7ee90cd8ed2d..408f80194334 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -749,7 +749,7 @@ static int i915_dp_mst_info(struct seq_file *m, void *unused) seq_printf(m, "MST Source Port [ENCODER:%d:%s]\n", dig_port->base.base.base.id, dig_port->base.base.name); - drm_dp_mst_dump_topology(m, &dig_port->dp.mst_mgr); + drm_dp_mst_dump_topology(m, &dig_port->dp.mst.mgr); } drm_connector_list_iter_end(&conn_iter); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 4440521e3e9e..2aa8f6264708 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1724,7 +1724,6 @@ struct intel_dp { struct intel_pps pps; bool is_mst; - int active_mst_links; enum drm_dp_mst_mode mst_detect; /* connector directly attached - won't be use for modeset in mst world */ @@ -1734,9 +1733,11 @@ struct intel_dp { struct drm_dp_tunnel *tunnel; bool tunnel_suspended:1; - /* mst connector list */ - struct intel_dp_mst_encoder *mst_encoders[I915_MAX_PIPES]; - struct drm_dp_mst_topology_mgr mst_mgr; + struct { + struct intel_dp_mst_encoder *stream_encoders[I915_MAX_PIPES]; + struct drm_dp_mst_topology_mgr mgr; + int active_links; + } mst; u32 (*get_aux_clock_divider)(struct intel_dp *dp, int index); /* diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 4d0166f17357..5e84103c8d54 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4396,7 +4396,7 @@ intel_dp_mst_configure(struct intel_dp *intel_dp) if (intel_dp->is_mst) intel_dp_mst_prepare_probe(intel_dp); - drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst); + drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst.mgr, intel_dp->is_mst); /* Avoid stale info on the next detect cycle. */ intel_dp->mst_detect = DRM_DP_SST; @@ -4412,9 +4412,9 @@ intel_dp_mst_disconnect(struct intel_dp *intel_dp) drm_dbg_kms(display->drm, "MST device may have disappeared %d vs %d\n", - intel_dp->is_mst, intel_dp->mst_mgr.mst_state); + intel_dp->is_mst, intel_dp->mst.mgr.mst_state); intel_dp->is_mst = false; - drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst); + drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst.mgr, intel_dp->is_mst); } static bool @@ -4920,7 +4920,7 @@ intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, u8 *ack) { bool handled = false; - drm_dp_mst_hpd_irq_handle_event(&intel_dp->mst_mgr, esi, ack, &handled); + drm_dp_mst_hpd_irq_handle_event(&intel_dp->mst.mgr, esi, ack, &handled); if (esi[1] & DP_CP_IRQ) { intel_hdcp_handle_cp_irq(intel_dp->attached_connector); @@ -4969,7 +4969,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) bool link_ok = true; bool reprobe_needed = false; - drm_WARN_ON_ONCE(display->drm, intel_dp->active_mst_links < 0); + drm_WARN_ON_ONCE(display->drm, intel_dp->mst.active_links < 0); for (;;) { u8 esi[4] = {}; @@ -4985,7 +4985,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) drm_dbg_kms(display->drm, "DPRX ESI: %4ph\n", esi); - if (intel_dp->active_mst_links > 0 && link_ok && + if (intel_dp->mst.active_links > 0 && link_ok && esi[3] & LINK_STATUS_CHANGED) { if (!intel_dp_mst_link_status(intel_dp)) link_ok = false; @@ -5008,7 +5008,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) drm_dbg_kms(display->drm, "Failed to ack ESI\n"); if (ack[1] & (DP_DOWN_REP_MSG_RDY | DP_UP_REQ_MSG_RDY)) - drm_dp_mst_hpd_irq_send_new_request(&intel_dp->mst_mgr); + drm_dp_mst_hpd_irq_send_new_request(&intel_dp->mst.mgr); } if (!link_ok || intel_dp->link.force_retrain) @@ -5107,7 +5107,7 @@ bool intel_dp_has_connector(struct intel_dp *intel_dp, /* MST */ for_each_pipe(display, pipe) { - encoder = &intel_dp->mst_encoders[pipe]->base; + encoder = &intel_dp->mst.stream_encoders[pipe]->base; if (conn_state->best_encoder == &encoder->base) return true; } @@ -6066,7 +6066,7 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn, return ret; if (intel_dp_mst_source_support(intel_dp)) { - ret = drm_dp_mst_root_conn_atomic_check(conn_state, &intel_dp->mst_mgr); + ret = drm_dp_mst_root_conn_atomic_check(conn_state, &intel_dp->mst.mgr); if (ret) return ret; } @@ -6604,7 +6604,7 @@ void intel_dp_mst_suspend(struct intel_display *display) continue; if (intel_dp->is_mst) - drm_dp_mst_topology_mgr_suspend(&intel_dp->mst_mgr); + drm_dp_mst_topology_mgr_suspend(&intel_dp->mst.mgr); } } @@ -6627,12 +6627,10 @@ void intel_dp_mst_resume(struct intel_display *display) if (!intel_dp_mst_source_support(intel_dp)) continue; - ret = drm_dp_mst_topology_mgr_resume(&intel_dp->mst_mgr, - true); + ret = drm_dp_mst_topology_mgr_resume(&intel_dp->mst.mgr, true); if (ret) { intel_dp->is_mst = false; - drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, - false); + drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst.mgr, false); } } } diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 90cc07b72817..e96236fbe407 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -253,7 +253,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, fxp_q4_to_frac(bpp_step_x16))); if (is_mst) { - mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr); + mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst.mgr); if (IS_ERR(mst_state)) return PTR_ERR(mst_state); @@ -355,7 +355,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, drm_WARN_ON(display->drm, remote_tu < crtc_state->dp_m_n.tu); crtc_state->dp_m_n.tu = remote_tu; - slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr, + slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst.mgr, connector->port, dfixed_trunc(pbn)); } else { @@ -479,7 +479,7 @@ static int mst_stream_update_slots(struct intel_dp *intel_dp, struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; + struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst.mgr; struct drm_dp_mst_topology_state *topology_state; u8 link_coding_cap = intel_dp_is_uhbr(crtc_state) ? DP_CAP_ANSI_128B132B : DP_CAP_ANSI_8B10B; @@ -769,7 +769,7 @@ static u8 get_pipes_downstream_of_mst_port(struct intel_atomic_state *state, if (!conn_state->base.crtc) continue; - if (&connector->mst_port->mst_mgr != mst_mgr) + if (&connector->mst_port->mst.mgr != mst_mgr) continue; if (connector->port != parent_port && @@ -981,7 +981,7 @@ mst_connector_atomic_check(struct drm_connector *_connector, } return drm_dp_atomic_release_time_slots(&state->base, - &connector->mst_port->mst_mgr, + &connector->mst_port->mst.mgr, connector->port); } @@ -998,9 +998,9 @@ static void mst_stream_disable(struct intel_atomic_state *state, enum transcoder trans = old_crtc_state->cpu_transcoder; drm_dbg_kms(display->drm, "active links %d\n", - intel_dp->active_mst_links); + intel_dp->mst.active_links); - if (intel_dp->active_mst_links == 1) + if (intel_dp->mst.active_links == 1) intel_dp->link_trained = false; intel_hdcp_disable(intel_mst->connector); @@ -1023,9 +1023,9 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, struct intel_connector *connector = to_intel_connector(old_conn_state->connector); struct drm_dp_mst_topology_state *old_mst_state = - drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr); + drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst.mgr); struct drm_dp_mst_topology_state *new_mst_state = - drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr); + drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst.mgr); const struct drm_dp_mst_atomic_payload *old_payload = drm_atomic_get_mst_payload_state(old_mst_state, connector->port); struct drm_dp_mst_atomic_payload *new_payload = @@ -1034,8 +1034,8 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, bool last_mst_stream; int i; - intel_dp->active_mst_links--; - last_mst_stream = intel_dp->active_mst_links == 0; + intel_dp->mst.active_links--; + last_mst_stream = intel_dp->mst.active_links == 0; drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && last_mst_stream && !intel_dp_mst_is_master_trans(old_crtc_state)); @@ -1048,7 +1048,7 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, intel_disable_transcoder(old_crtc_state); - drm_dp_remove_payload_part1(&intel_dp->mst_mgr, new_mst_state, new_payload); + drm_dp_remove_payload_part1(&intel_dp->mst.mgr, new_mst_state, new_payload); intel_ddi_clear_act_sent(encoder, old_crtc_state); @@ -1057,9 +1057,9 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, TRANS_DDI_DP_VC_PAYLOAD_ALLOC, 0); intel_ddi_wait_for_act_sent(encoder, old_crtc_state); - drm_dp_check_act_status(&intel_dp->mst_mgr); + drm_dp_check_act_status(&intel_dp->mst.mgr); - drm_dp_remove_payload_part2(&intel_dp->mst_mgr, new_mst_state, + drm_dp_remove_payload_part2(&intel_dp->mst.mgr, new_mst_state, old_payload, new_payload); intel_ddi_disable_transcoder_func(old_crtc_state); @@ -1080,7 +1080,7 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, * Power down mst path before disabling the port, otherwise we end * up getting interrupts from the sink upon detecting link loss. */ - drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, + drm_dp_send_power_updown_phy(&intel_dp->mst.mgr, connector->port, false); /* @@ -1105,7 +1105,7 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, old_crtc_state, NULL); drm_dbg_kms(display->drm, "active links %d\n", - intel_dp->active_mst_links); + intel_dp->mst.active_links); } static void mst_stream_post_pll_disable(struct intel_atomic_state *state, @@ -1116,7 +1116,7 @@ static void mst_stream_post_pll_disable(struct intel_atomic_state *state, struct intel_encoder *primary_encoder = to_primary_encoder(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); - if (intel_dp->active_mst_links == 0 && + if (intel_dp->mst.active_links == 0 && primary_encoder->post_pll_disable) primary_encoder->post_pll_disable(state, primary_encoder, old_crtc_state, old_conn_state); } @@ -1129,7 +1129,7 @@ static void mst_stream_pre_pll_enable(struct intel_atomic_state *state, struct intel_encoder *primary_encoder = to_primary_encoder(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); - if (intel_dp->active_mst_links == 0) + if (intel_dp->mst.active_links == 0) primary_encoder->pre_pll_enable(state, primary_encoder, pipe_config, NULL); else @@ -1162,7 +1162,7 @@ static void intel_mst_reprobe_topology(struct intel_dp *intel_dp, crtc_state->port_clock, crtc_state->lane_count)) return; - drm_dp_mst_topology_queue_probe(&intel_dp->mst_mgr); + drm_dp_mst_topology_queue_probe(&intel_dp->mst.mgr); intel_mst_set_probed_link_params(intel_dp, crtc_state->port_clock, crtc_state->lane_count); @@ -1180,7 +1180,7 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state, struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_dp_mst_topology_state *mst_state = - drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr); + drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst.mgr); int ret; bool first_mst_stream; @@ -1189,17 +1189,17 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state, */ connector->encoder = encoder; intel_mst->connector = connector; - first_mst_stream = intel_dp->active_mst_links == 0; + first_mst_stream = intel_dp->mst.active_links == 0; drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && first_mst_stream && !intel_dp_mst_is_master_trans(pipe_config)); drm_dbg_kms(display->drm, "active links %d\n", - intel_dp->active_mst_links); + intel_dp->mst.active_links); if (first_mst_stream) intel_dp_set_power(intel_dp, DP_SET_POWER_D0); - drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true); + drm_dp_send_power_updown_phy(&intel_dp->mst.mgr, connector->port, true); intel_dp_sink_enable_decompression(state, connector, pipe_config); @@ -1210,9 +1210,9 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state, intel_mst_reprobe_topology(intel_dp, pipe_config); } - intel_dp->active_mst_links++; + intel_dp->mst.active_links++; - ret = drm_dp_add_payload_part1(&intel_dp->mst_mgr, mst_state, + ret = drm_dp_add_payload_part1(&intel_dp->mst.mgr, mst_state, drm_atomic_get_mst_payload_state(mst_state, connector->port)); if (ret < 0) intel_dp_queue_modeset_retry_for_link(state, primary_encoder, pipe_config); @@ -1277,9 +1277,9 @@ static void mst_stream_enable(struct intel_atomic_state *state, struct intel_dp *intel_dp = to_primary_dp(encoder); struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_dp_mst_topology_state *mst_state = - drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr); + drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst.mgr); enum transcoder trans = pipe_config->cpu_transcoder; - bool first_mst_stream = intel_dp->active_mst_links == 1; + bool first_mst_stream = intel_dp->mst.active_links == 1; struct intel_crtc *pipe_crtc; int ret, i, min_hblank; @@ -1329,15 +1329,15 @@ static void mst_stream_enable(struct intel_atomic_state *state, TRANS_DDI_DP_VC_PAYLOAD_ALLOC); drm_dbg_kms(display->drm, "active links %d\n", - intel_dp->active_mst_links); + intel_dp->mst.active_links); intel_ddi_wait_for_act_sent(encoder, pipe_config); - drm_dp_check_act_status(&intel_dp->mst_mgr); + drm_dp_check_act_status(&intel_dp->mst.mgr); if (first_mst_stream) intel_ddi_wait_for_fec_status(encoder, pipe_config, true); - ret = drm_dp_add_payload_part2(&intel_dp->mst_mgr, + ret = drm_dp_add_payload_part2(&intel_dp->mst.mgr, drm_atomic_get_mst_payload_state(mst_state, connector->port)); if (ret < 0) @@ -1402,7 +1402,7 @@ static int mst_connector_get_ddc_modes(struct drm_connector *_connector) if (!intel_display_driver_check_access(display)) return drm_edid_connector_add_modes(&connector->base); - drm_edid = drm_dp_mst_edid_read(&connector->base, &intel_dp->mst_mgr, connector->port); + drm_edid = drm_dp_mst_edid_read(&connector->base, &intel_dp->mst.mgr, connector->port); ret = intel_connector_update_modes(&connector->base, drm_edid); @@ -1464,7 +1464,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, struct intel_connector *connector = to_intel_connector(_connector); struct intel_display *display = to_intel_display(connector); struct intel_dp *intel_dp = connector->mst_port; - struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; + struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst.mgr; struct drm_dp_mst_port *port = connector->port; const int min_bpp = 18; int max_dotclk = display->cdclk.max_dotclk_freq; @@ -1579,7 +1579,7 @@ mst_connector_atomic_best_encoder(struct drm_connector *_connector, struct intel_dp *intel_dp = connector->mst_port; struct intel_crtc *crtc = to_intel_crtc(connector_state->crtc); - return &intel_dp->mst_encoders[crtc->pipe]->base.base; + return &intel_dp->mst.stream_encoders[crtc->pipe]->base.base; } static int @@ -1601,7 +1601,7 @@ mst_connector_detect_ctx(struct drm_connector *_connector, intel_dp_flush_connector_commits(connector); - return drm_dp_mst_detect_port(&connector->base, ctx, &intel_dp->mst_mgr, + return drm_dp_mst_detect_port(&connector->base, ctx, &intel_dp->mst.mgr, connector->port); } @@ -1731,7 +1731,7 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *pathprop) { - struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr); + struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst.mgr); struct intel_display *display = to_intel_display(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_connector *connector; @@ -1762,7 +1762,7 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, for_each_pipe(display, pipe) { struct drm_encoder *enc = - &intel_dp->mst_encoders[pipe]->base.base; + &intel_dp->mst.stream_encoders[pipe]->base.base; ret = drm_connector_attach_encoder(&connector->base, enc); if (ret) @@ -1792,7 +1792,7 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, static void mst_topology_poll_hpd_irq(struct drm_dp_mst_topology_mgr *mgr) { - struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr); + struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst.mgr); intel_hpd_trigger_irq(dp_to_dig_port(intel_dp)); } @@ -1865,14 +1865,14 @@ mst_stream_encoders_create(struct intel_digital_port *dig_port) enum pipe pipe; for_each_pipe(display, pipe) - intel_dp->mst_encoders[pipe] = mst_stream_encoder_create(dig_port, pipe); + intel_dp->mst.stream_encoders[pipe] = mst_stream_encoder_create(dig_port, pipe); return true; } int intel_dp_mst_encoder_active_links(struct intel_digital_port *dig_port) { - return dig_port->dp.active_mst_links; + return dig_port->dp.mst.active_links; } int @@ -1892,15 +1892,15 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id) if (DISPLAY_VER(display) < 11 && port == PORT_E) return 0; - intel_dp->mst_mgr.cbs = &mst_topology_cbs; + intel_dp->mst.mgr.cbs = &mst_topology_cbs; /* create encoders */ mst_stream_encoders_create(dig_port); - ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, display->drm, + ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst.mgr, display->drm, &intel_dp->aux, 16, INTEL_NUM_PIPES(display), conn_base_id); if (ret) { - intel_dp->mst_mgr.cbs = NULL; + intel_dp->mst.mgr.cbs = NULL; return ret; } @@ -1909,7 +1909,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id) bool intel_dp_mst_source_support(struct intel_dp *intel_dp) { - return intel_dp->mst_mgr.cbs; + return intel_dp->mst.mgr.cbs; } void @@ -1920,10 +1920,10 @@ intel_dp_mst_encoder_cleanup(struct intel_digital_port *dig_port) if (!intel_dp_mst_source_support(intel_dp)) return; - drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr); + drm_dp_mst_topology_mgr_destroy(&intel_dp->mst.mgr); /* encoders will get killed by normal cleanup */ - intel_dp->mst_mgr.cbs = NULL; + intel_dp->mst.mgr.cbs = NULL; } bool intel_dp_mst_is_master_trans(const struct intel_crtc_state *crtc_state) @@ -1958,7 +1958,7 @@ intel_dp_mst_add_topology_state_for_connector(struct intel_atomic_state *state, return 0; mst_state = drm_atomic_get_mst_topology_state(&state->base, - &connector->mst_port->mst_mgr); + &connector->mst_port->mst.mgr); if (IS_ERR(mst_state)) return PTR_ERR(mst_state); @@ -2140,7 +2140,7 @@ bool intel_dp_mst_verify_dpcd_state(struct intel_dp *intel_dp) if (!intel_dp->is_mst) return true; - ret = drm_dp_dpcd_readb(intel_dp->mst_mgr.aux, DP_MSTM_CTRL, &val); + ret = drm_dp_dpcd_readb(intel_dp->mst.mgr.aux, DP_MSTM_CTRL, &val); /* Adjust the expected register value for SST + SideBand. */ if (ret < 0 || val != (DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC)) { diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 7063e3f5c538..100f3fb1c1a0 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -136,7 +136,7 @@ intel_hdcp_required_content_stream(struct intel_atomic_state *state, data->k++; /* if there is only one active stream */ - if (dig_port->dp.active_mst_links <= 1) + if (dig_port->dp.mst.active_links <= 1) break; } drm_connector_list_iter_end(&conn_iter); From aa389adeaa8565cc664a6ee4a5dbdc7a6000d46f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 28 Feb 2025 14:49:30 +0200 Subject: [PATCH 31/92] drm/i915/mst: add mst sub-struct to struct intel_connector Move port and mst_port members of struct intel_connector under an mst sub-struct to group mst related things together. Rename the latter dp for clarity. Cc: Imre Deak Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/e2afaf4595ae8e3241aaca1c1bb4d6356b07e44a.1740746939.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../gpu/drm/i915/display/intel_connector.c | 4 +- .../drm/i915/display/intel_display_debugfs.c | 4 +- .../drm/i915/display/intel_display_types.h | 13 ++-- drivers/gpu/drm/i915/display/intel_dp.c | 12 ++-- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 6 +- drivers/gpu/drm/i915/display/intel_dp_mst.c | 72 +++++++++---------- drivers/gpu/drm/i915/display/intel_hdcp.c | 8 +-- 7 files changed, 60 insertions(+), 59 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c index 358965fc7f55..e42357bd9e80 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.c +++ b/drivers/gpu/drm/i915/display/intel_connector.c @@ -145,8 +145,8 @@ void intel_connector_destroy(struct drm_connector *connector) drm_connector_cleanup(connector); - if (intel_connector->port) - drm_dp_mst_put_port_malloc(intel_connector->port); + if (intel_connector->mst.port) + drm_dp_mst_put_port_malloc(intel_connector->mst.port); kfree(connector); } diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 408f80194334..510c15a6271f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -261,7 +261,7 @@ static void intel_connector_info(struct seq_file *m, switch (connector->connector_type) { case DRM_MODE_CONNECTOR_DisplayPort: case DRM_MODE_CONNECTOR_eDP: - if (intel_connector->mst_port) + if (intel_connector->mst.dp) intel_dp_mst_info(m, intel_connector); else intel_dp_info(m, intel_connector); @@ -1341,7 +1341,7 @@ void intel_connector_debugfs_add(struct intel_connector *connector) intel_dp_link_training_debugfs_add(connector); if (DISPLAY_VER(display) >= 11 && - ((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !connector->mst_port) || + ((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !connector->mst.dp) || connector_type == DRM_MODE_CONNECTOR_eDP)) { debugfs_create_file("i915_dsc_fec_support", 0644, root, connector, &i915_dsc_fec_support_fops); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 2aa8f6264708..b52fca816591 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -534,10 +534,6 @@ struct intel_connector { state of connector->polled in case hotplug storm detection changes it */ u8 polled; - struct drm_dp_mst_port *port; - - struct intel_dp *mst_port; - int force_joined_pipes; struct { @@ -549,6 +545,11 @@ struct intel_connector { u8 dsc_decompression_enabled:1; } dp; + struct { + struct drm_dp_mst_port *port; + struct intel_dp *dp; + } mst; + /* Work struct to schedule a uevent on link train failure */ struct work_struct modeset_retry_work; @@ -1956,8 +1957,8 @@ static inline struct intel_dp *enc_to_intel_dp(struct intel_encoder *encoder) static inline struct intel_dp *intel_attached_dp(struct intel_connector *connector) { - if (connector->mst_port) - return connector->mst_port; + if (connector->mst.dp) + return connector->mst.dp; else return enc_to_intel_dp(intel_attached_encoder(connector)); } diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 5e84103c8d54..205ec315b413 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1376,7 +1376,7 @@ bool intel_dp_has_dsc(const struct intel_connector *connector) if (!HAS_DSC(display)) return false; - if (connector->mst_port && !HAS_DSC_MST(display)) + if (connector->mst.dp && !HAS_DSC_MST(display)) return false; if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP && @@ -3080,7 +3080,7 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state, if (!conn_state->base.crtc) continue; - if (connector->mst_port == intel_dp) + if (connector->mst.dp == intel_dp) intel_connector_queue_modeset_retry_work(connector); } } @@ -3302,8 +3302,8 @@ intel_dp_sink_set_dsc_passthrough(const struct intel_connector *connector, bool enable) { struct intel_display *display = to_intel_display(connector); - struct drm_dp_aux *aux = connector->port ? - connector->port->passthrough_aux : NULL; + struct drm_dp_aux *aux = connector->mst.port ? + connector->mst.port->passthrough_aux : NULL; if (!aux) return; @@ -3330,7 +3330,7 @@ static int intel_dp_dsc_aux_ref_count(struct intel_atomic_state *state, * On SST the decompression AUX device won't be shared, each connector * uses for this its own AUX targeting the sink device. */ - if (!connector->mst_port) + if (!connector->mst.dp) return connector->dp.dsc_decompression_enabled ? 1 : 0; for_each_oldnew_connector_in_state(&state->base, _connector_iter, @@ -3338,7 +3338,7 @@ static int intel_dp_dsc_aux_ref_count(struct intel_atomic_state *state, const struct intel_connector * connector_iter = to_intel_connector(_connector_iter); - if (connector_iter->mst_port != connector->mst_port) + if (connector_iter->mst.dp != connector->mst.dp) continue; if (!connector_iter->dp.dsc_decompression_enabled) diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c index 00c493cc8a4b..4c9481124c90 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -705,10 +705,10 @@ int intel_dp_hdcp_get_remote_capability(struct intel_connector *connector, *hdcp_capable = false; *hdcp2_capable = false; - if (!connector->mst_port) + if (!connector->mst.dp) return -EINVAL; - aux = &connector->port->aux; + aux = &connector->mst.port->aux; ret = _intel_dp_hdcp2_get_capability(aux, hdcp2_capable); if (ret) drm_dbg_kms(display->drm, @@ -883,7 +883,7 @@ int intel_dp_hdcp_init(struct intel_digital_port *dig_port, if (!is_hdcp_supported(display, port)) return 0; - if (intel_connector->mst_port) + if (intel_connector->mst.dp) return intel_hdcp_init(intel_connector, dig_port, &intel_dp_mst_hdcp_shim); else if (!intel_dp_is_edp(intel_dp)) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index e96236fbe407..02f95108c637 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -356,7 +356,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, crtc_state->dp_m_n.tu = remote_tu; slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst.mgr, - connector->port, + connector->mst.port, dfixed_trunc(pbn)); } else { /* Same as above for remote_tu */ @@ -509,8 +509,8 @@ hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector, { const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - bool is_uhbr_sink = connector->mst_port && - drm_dp_128b132b_supported(connector->mst_port->dpcd); + bool is_uhbr_sink = connector->mst.dp && + drm_dp_128b132b_supported(connector->mst.dp->dpcd); int hblank_limit = is_uhbr_sink ? 500 : 300; if (!connector->dp.dsc_hblank_expansion_quirk) @@ -741,7 +741,7 @@ intel_dp_mst_transcoder_mask(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state; struct intel_crtc *crtc; - if (connector->mst_port != mst_port || !conn_state->base.crtc) + if (connector->mst.dp != mst_port || !conn_state->base.crtc) continue; crtc = to_intel_crtc(conn_state->base.crtc); @@ -769,12 +769,12 @@ static u8 get_pipes_downstream_of_mst_port(struct intel_atomic_state *state, if (!conn_state->base.crtc) continue; - if (&connector->mst_port->mst.mgr != mst_mgr) + if (&connector->mst.dp->mst.mgr != mst_mgr) continue; - if (connector->port != parent_port && + if (connector->mst.port != parent_port && !drm_dp_mst_port_downstream_of_parent(mst_mgr, - connector->port, + connector->mst.port, parent_port)) continue; @@ -925,7 +925,7 @@ mst_connector_atomic_topology_check(struct intel_connector *connector, struct intel_crtc_state *crtc_state; struct intel_crtc *crtc; - if (connector_iter->mst_port != connector->mst_port || + if (connector_iter->mst.dp != connector->mst.dp || connector_iter == connector) continue; @@ -974,15 +974,15 @@ mst_connector_atomic_check(struct drm_connector *_connector, if (intel_connector_needs_modeset(state, &connector->base)) { ret = intel_dp_tunnel_atomic_check_state(state, - connector->mst_port, + connector->mst.dp, connector); if (ret) return ret; } return drm_dp_atomic_release_time_slots(&state->base, - &connector->mst_port->mst.mgr, - connector->port); + &connector->mst.dp->mst.mgr, + connector->mst.port); } static void mst_stream_disable(struct intel_atomic_state *state, @@ -1027,9 +1027,9 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, struct drm_dp_mst_topology_state *new_mst_state = drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst.mgr); const struct drm_dp_mst_atomic_payload *old_payload = - drm_atomic_get_mst_payload_state(old_mst_state, connector->port); + drm_atomic_get_mst_payload_state(old_mst_state, connector->mst.port); struct drm_dp_mst_atomic_payload *new_payload = - drm_atomic_get_mst_payload_state(new_mst_state, connector->port); + drm_atomic_get_mst_payload_state(new_mst_state, connector->mst.port); struct intel_crtc *pipe_crtc; bool last_mst_stream; int i; @@ -1080,7 +1080,7 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, * Power down mst path before disabling the port, otherwise we end * up getting interrupts from the sink upon detecting link loss. */ - drm_dp_send_power_updown_phy(&intel_dp->mst.mgr, connector->port, + drm_dp_send_power_updown_phy(&intel_dp->mst.mgr, connector->mst.port, false); /* @@ -1199,7 +1199,7 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state, if (first_mst_stream) intel_dp_set_power(intel_dp, DP_SET_POWER_D0); - drm_dp_send_power_updown_phy(&intel_dp->mst.mgr, connector->port, true); + drm_dp_send_power_updown_phy(&intel_dp->mst.mgr, connector->mst.port, true); intel_dp_sink_enable_decompression(state, connector, pipe_config); @@ -1213,7 +1213,7 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state, intel_dp->mst.active_links++; ret = drm_dp_add_payload_part1(&intel_dp->mst.mgr, mst_state, - drm_atomic_get_mst_payload_state(mst_state, connector->port)); + drm_atomic_get_mst_payload_state(mst_state, connector->mst.port)); if (ret < 0) intel_dp_queue_modeset_retry_for_link(state, primary_encoder, pipe_config); @@ -1339,7 +1339,7 @@ static void mst_stream_enable(struct intel_atomic_state *state, ret = drm_dp_add_payload_part2(&intel_dp->mst.mgr, drm_atomic_get_mst_payload_state(mst_state, - connector->port)); + connector->mst.port)); if (ret < 0) intel_dp_queue_modeset_retry_for_link(state, primary_encoder, pipe_config); @@ -1392,7 +1392,7 @@ static int mst_connector_get_ddc_modes(struct drm_connector *_connector) { struct intel_connector *connector = to_intel_connector(_connector); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = connector->mst_port; + struct intel_dp *intel_dp = connector->mst.dp; const struct drm_edid *drm_edid; int ret; @@ -1402,7 +1402,7 @@ static int mst_connector_get_ddc_modes(struct drm_connector *_connector) if (!intel_display_driver_check_access(display)) return drm_edid_connector_add_modes(&connector->base); - drm_edid = drm_dp_mst_edid_read(&connector->base, &intel_dp->mst.mgr, connector->port); + drm_edid = drm_dp_mst_edid_read(&connector->base, &intel_dp->mst.mgr, connector->mst.port); ret = intel_connector_update_modes(&connector->base, drm_edid); @@ -1417,13 +1417,13 @@ mst_connector_late_register(struct drm_connector *_connector) struct intel_connector *connector = to_intel_connector(_connector); int ret; - ret = drm_dp_mst_connector_late_register(&connector->base, connector->port); + ret = drm_dp_mst_connector_late_register(&connector->base, connector->mst.port); if (ret < 0) return ret; ret = intel_connector_register(&connector->base); if (ret < 0) - drm_dp_mst_connector_early_unregister(&connector->base, connector->port); + drm_dp_mst_connector_early_unregister(&connector->base, connector->mst.port); return ret; } @@ -1434,7 +1434,7 @@ mst_connector_early_unregister(struct drm_connector *_connector) struct intel_connector *connector = to_intel_connector(_connector); intel_connector_unregister(&connector->base); - drm_dp_mst_connector_early_unregister(&connector->base, connector->port); + drm_dp_mst_connector_early_unregister(&connector->base, connector->mst.port); } static const struct drm_connector_funcs mst_connector_funcs = { @@ -1463,9 +1463,9 @@ mst_connector_mode_valid_ctx(struct drm_connector *_connector, { struct intel_connector *connector = to_intel_connector(_connector); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = connector->mst_port; + struct intel_dp *intel_dp = connector->mst.dp; struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst.mgr; - struct drm_dp_mst_port *port = connector->port; + struct drm_dp_mst_port *port = connector->mst.port; const int min_bpp = 18; int max_dotclk = display->cdclk.max_dotclk_freq; int max_rate, mode_rate, max_lanes, max_link_clock; @@ -1576,7 +1576,7 @@ mst_connector_atomic_best_encoder(struct drm_connector *_connector, struct intel_connector *connector = to_intel_connector(_connector); struct drm_connector_state *connector_state = drm_atomic_get_new_connector_state(state, &connector->base); - struct intel_dp *intel_dp = connector->mst_port; + struct intel_dp *intel_dp = connector->mst.dp; struct intel_crtc *crtc = to_intel_crtc(connector_state->crtc); return &intel_dp->mst.stream_encoders[crtc->pipe]->base.base; @@ -1588,7 +1588,7 @@ mst_connector_detect_ctx(struct drm_connector *_connector, { struct intel_connector *connector = to_intel_connector(_connector); struct intel_display *display = to_intel_display(connector); - struct intel_dp *intel_dp = connector->mst_port; + struct intel_dp *intel_dp = connector->mst.dp; if (!intel_display_device_enabled(display)) return connector_status_disconnected; @@ -1602,7 +1602,7 @@ mst_connector_detect_ctx(struct drm_connector *_connector, intel_dp_flush_connector_commits(connector); return drm_dp_mst_detect_port(&connector->base, ctx, &intel_dp->mst.mgr, - connector->port); + connector->mst.port); } static const struct drm_connector_helper_funcs mst_connector_helper_funcs = { @@ -1693,10 +1693,10 @@ static bool detect_dsc_hblank_expansion_quirk(const struct intel_connector *conn * A logical port's OUI (at least for affected sinks) is all 0, so * instead of that the parent port's OUI is used for identification. */ - if (drm_dp_mst_port_is_logical(connector->port)) { - aux = drm_dp_mst_aux_for_parent(connector->port); + if (drm_dp_mst_port_is_logical(connector->mst.port)) { + aux = drm_dp_mst_aux_for_parent(connector->mst.port); if (!aux) - aux = &connector->mst_port->aux; + aux = &connector->mst.dp->aux; } if (drm_dp_read_dpcd_caps(aux, dpcd) < 0) @@ -1744,8 +1744,8 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, connector->get_hw_state = mst_connector_get_hw_state; connector->sync_state = intel_dp_connector_sync_state; - connector->mst_port = intel_dp; - connector->port = port; + connector->mst.dp = intel_dp; + connector->mst.port = port; drm_dp_mst_get_port_malloc(port); ret = drm_connector_dynamic_init(display->drm, &connector->base, &mst_connector_funcs, @@ -1954,11 +1954,11 @@ intel_dp_mst_add_topology_state_for_connector(struct intel_atomic_state *state, { struct drm_dp_mst_topology_state *mst_state; - if (!connector->mst_port) + if (!connector->mst.dp) return 0; mst_state = drm_atomic_get_mst_topology_state(&state->base, - &connector->mst_port->mst.mgr); + &connector->mst.dp->mst.mgr); if (IS_ERR(mst_state)) return PTR_ERR(mst_state); @@ -2056,7 +2056,7 @@ bool intel_dp_mst_crtc_needs_modeset(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state; struct intel_crtc *crtc_iter; - if (connector->mst_port != crtc_connector->mst_port || + if (connector->mst.dp != crtc_connector->mst.dp || !conn_state->crtc) continue; @@ -2079,7 +2079,7 @@ bool intel_dp_mst_crtc_needs_modeset(struct intel_atomic_state *state, * case. */ if (connector->dp.dsc_decompression_aux == - &connector->mst_port->aux) + &connector->mst.dp->aux) return true; } diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 100f3fb1c1a0..46f53ade432e 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -70,13 +70,13 @@ static int intel_conn_to_vcpi(struct intel_atomic_state *state, int vcpi = 0; /* For HDMI this is forced to be 0x0. For DP SST also this is 0x0. */ - if (!connector->port) + if (!connector->mst.port) return 0; - mgr = connector->port->mgr; + mgr = connector->mst.port->mgr; drm_modeset_lock(&mgr->base.lock, state->base.acquire_ctx); mst_state = to_drm_dp_mst_topology_state(mgr->base.state); - payload = drm_atomic_get_mst_payload_state(mst_state, connector->port); + payload = drm_atomic_get_mst_payload_state(mst_state, connector->mst.port); if (drm_WARN_ON(mgr->dev, !payload)) goto out; @@ -2775,7 +2775,7 @@ static void __intel_hdcp_info(struct seq_file *m, struct intel_connector *connec void intel_hdcp_info(struct seq_file *m, struct intel_connector *connector) { seq_puts(m, "\tHDCP version: "); - if (connector->mst_port) { + if (connector->mst.dp) { __intel_hdcp_info(m, connector, true); seq_puts(m, "\tMST Hub HDCP version: "); } From f953c6585e2d59254511c8d122e8d1d55a693133 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 28 Feb 2025 14:49:31 +0200 Subject: [PATCH 32/92] drm/i915/hdcp: add hdcp sub-struct to struct intel_digital_port Move hdcp_mutex, num_hdcp_streams, hdcp_auth_status, hdcp_port_data, and hdcp_mst_type1_capable members of struct intel_digital_port under an hdcp sub-struct to group hdcp related things together. Rename them mutex, num_streams, auth_status, port_data, and mst_type1_capable for clarity. Cc: Suraj Kandpal Reviewed-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/9da4be57b068acd06dec8b93977f0a70627103d4.1740746939.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/g4x_dp.c | 2 +- drivers/gpu/drm/i915/display/g4x_hdmi.c | 2 +- drivers/gpu/drm/i915/display/intel_ddi.c | 6 +- .../drm/i915/display/intel_display_types.h | 22 ++--- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 2 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 84 +++++++++---------- 6 files changed, 60 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 372c3683c193..55b9e9bfcc4d 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -1311,7 +1311,7 @@ bool g4x_dp_init(struct intel_display *display, intel_encoder->devdata = devdata; - mutex_init(&dig_port->hdcp_mutex); + mutex_init(&dig_port->hdcp.mutex); if (drm_encoder_init(display->drm, &intel_encoder->base, &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS, diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c index d9d1304dcc36..3dc2c59a3df0 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.c +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c @@ -715,7 +715,7 @@ bool g4x_hdmi_init(struct intel_display *display, intel_encoder->devdata = devdata; - mutex_init(&dig_port->hdcp_mutex); + mutex_init(&dig_port->hdcp.mutex); if (drm_encoder_init(display->drm, &intel_encoder->base, &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS, diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index ca7983ef373d..20fc258a4d6d 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4582,7 +4582,7 @@ static void intel_ddi_encoder_destroy(struct drm_encoder *encoder) intel_display_power_flush_work(display); drm_encoder_cleanup(encoder); - kfree(dig_port->hdcp_port_data.streams); + kfree(dig_port->hdcp.port_data.streams); kfree(dig_port); } @@ -5187,8 +5187,8 @@ void intel_ddi_init(struct intel_display *display, intel_encoder_link_check_init(encoder, intel_ddi_link_check); - mutex_init(&dig_port->hdcp_mutex); - dig_port->num_hdcp_streams = 0; + mutex_init(&dig_port->hdcp.mutex); + dig_port->hdcp.num_streams = 0; encoder->hotplug = intel_ddi_hotplug; encoder->compute_output_type = intel_ddi_compute_output_type; diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index b52fca816591..053be62a5be1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1849,16 +1849,18 @@ struct intel_digital_port { struct intel_tc_port *tc; - /* protects num_hdcp_streams reference count, hdcp_port_data and hdcp_auth_status */ - struct mutex hdcp_mutex; - /* the number of pipes using HDCP signalling out of this port */ - unsigned int num_hdcp_streams; - /* port HDCP auth status */ - bool hdcp_auth_status; - /* HDCP port data need to pass to security f/w */ - struct hdcp_port_data hdcp_port_data; - /* Whether the MST topology supports HDCP Type 1 Content */ - bool hdcp_mst_type1_capable; + struct { + /* protects num_streams reference count, port_data and auth_status */ + struct mutex mutex; + /* the number of pipes using HDCP signalling out of this port */ + unsigned int num_streams; + /* port HDCP auth status */ + bool auth_status; + /* HDCP port data need to pass to security f/w */ + struct hdcp_port_data port_data; + /* Whether the MST topology supports HDCP Type 1 Content */ + bool mst_type1_capable; + } hdcp; void (*write_infoframe)(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c index 4c9481124c90..cc312596fb77 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -799,7 +799,7 @@ intel_dp_mst_hdcp2_stream_encryption(struct intel_connector *connector, { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct intel_hdcp *hdcp = &connector->hdcp; enum transcoder cpu_transcoder = hdcp->stream_transcoder; enum pipe pipe = (enum pipe)cpu_transcoder; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 46f53ade432e..1bf424a822f3 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -107,16 +107,16 @@ intel_hdcp_required_content_stream(struct intel_atomic_state *state, struct drm_connector_list_iter conn_iter; struct intel_digital_port *conn_dig_port; struct intel_connector *connector; - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; bool enforce_type0 = false; int k; - if (dig_port->hdcp_auth_status) + if (dig_port->hdcp.auth_status) return 0; data->k = 0; - if (!dig_port->hdcp_mst_type1_capable) + if (!dig_port->hdcp.mst_type1_capable) enforce_type0 = true; drm_connector_list_iter_begin(display->drm, &conn_iter); @@ -159,7 +159,7 @@ static int intel_hdcp_prepare_streams(struct intel_atomic_state *state, struct intel_connector *connector) { struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct intel_hdcp *hdcp = &connector->hdcp; if (intel_encoder_is_mst(intel_attached_encoder(connector))) @@ -1001,7 +1001,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector) * don't disable it until it disabled HDCP encryption for * all connectors in MST topology. */ - if (dig_port->num_hdcp_streams > 0) + if (dig_port->hdcp.num_streams > 0) return 0; } @@ -1094,13 +1094,13 @@ static void intel_hdcp_update_value(struct intel_connector *connector, if (hdcp->value == value) return; - drm_WARN_ON(display->drm, !mutex_is_locked(&dig_port->hdcp_mutex)); + drm_WARN_ON(display->drm, !mutex_is_locked(&dig_port->hdcp.mutex)); if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) { - if (!drm_WARN_ON(display->drm, dig_port->num_hdcp_streams == 0)) - dig_port->num_hdcp_streams--; + if (!drm_WARN_ON(display->drm, dig_port->hdcp.num_streams == 0)) + dig_port->hdcp.num_streams--; } else if (value == DRM_MODE_CONTENT_PROTECTION_ENABLED) { - dig_port->num_hdcp_streams++; + dig_port->hdcp.num_streams++; } hdcp->value = value; @@ -1122,7 +1122,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector) int ret = 0; mutex_lock(&hdcp->mutex); - mutex_lock(&dig_port->hdcp_mutex); + mutex_lock(&dig_port->hdcp.mutex); cpu_transcoder = hdcp->cpu_transcoder; @@ -1177,7 +1177,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector) } out: - mutex_unlock(&dig_port->hdcp_mutex); + mutex_unlock(&dig_port->hdcp.mutex); mutex_unlock(&hdcp->mutex); return ret; } @@ -1219,7 +1219,7 @@ hdcp2_prepare_ake_init(struct intel_connector *connector, { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct i915_hdcp_arbiter *arbiter; int ret; @@ -1249,7 +1249,7 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector, { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct i915_hdcp_arbiter *arbiter; int ret; @@ -1277,7 +1277,7 @@ static int hdcp2_verify_hprime(struct intel_connector *connector, { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct i915_hdcp_arbiter *arbiter; int ret; @@ -1303,7 +1303,7 @@ hdcp2_store_pairing_info(struct intel_connector *connector, { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct i915_hdcp_arbiter *arbiter; int ret; @@ -1330,7 +1330,7 @@ hdcp2_prepare_lc_init(struct intel_connector *connector, { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct i915_hdcp_arbiter *arbiter; int ret; @@ -1357,7 +1357,7 @@ hdcp2_verify_lprime(struct intel_connector *connector, { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct i915_hdcp_arbiter *arbiter; int ret; @@ -1383,7 +1383,7 @@ static int hdcp2_prepare_skey(struct intel_connector *connector, { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct i915_hdcp_arbiter *arbiter; int ret; @@ -1412,7 +1412,7 @@ hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector, { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct i915_hdcp_arbiter *arbiter; int ret; @@ -1442,7 +1442,7 @@ hdcp2_verify_mprime(struct intel_connector *connector, { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct i915_hdcp_arbiter *arbiter; int ret; @@ -1466,7 +1466,7 @@ static int hdcp2_authenticate_port(struct intel_connector *connector) { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct i915_hdcp_arbiter *arbiter; int ret; @@ -1503,7 +1503,7 @@ static int hdcp2_close_session(struct intel_connector *connector) } ret = arbiter->ops->close_hdcp_session(arbiter->hdcp_dev, - &dig_port->hdcp_port_data); + &dig_port->hdcp.port_data); mutex_unlock(&display->hdcp.hdcp_mutex); return ret; @@ -1691,7 +1691,7 @@ static int _hdcp2_propagate_stream_management_info(struct intel_connector *connector) { struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct intel_hdcp *hdcp = &connector->hdcp; union { struct hdcp2_rep_stream_manage stream_manage; @@ -1769,11 +1769,11 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) * MST topology is not Type 1 capable if it contains a downstream * device that is only HDCP 1.x or Legacy HDCP 2.0/2.1 compliant. */ - dig_port->hdcp_mst_type1_capable = + dig_port->hdcp.mst_type1_capable = !HDCP_2_2_HDCP1_DEVICE_CONNECTED(rx_info[1]) && !HDCP_2_2_HDCP_2_0_REP_CONNECTED(rx_info[1]); - if (!dig_port->hdcp_mst_type1_capable && hdcp->content_type) { + if (!dig_port->hdcp.mst_type1_capable && hdcp->content_type) { drm_dbg_kms(display->drm, "HDCP1.x or 2.0 Legacy Device Downstream\n"); return -EINVAL; @@ -1869,7 +1869,7 @@ static int hdcp2_enable_stream_encryption(struct intel_connector *connector) { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct intel_hdcp *hdcp = &connector->hdcp; enum transcoder cpu_transcoder = hdcp->cpu_transcoder; enum port port = dig_port->base.port; @@ -1900,7 +1900,7 @@ static int hdcp2_enable_stream_encryption(struct intel_connector *connector) if (hdcp2_deauthenticate_port(connector) < 0) drm_dbg_kms(display->drm, "Port deauth failed.\n"); - dig_port->hdcp_auth_status = false; + dig_port->hdcp.auth_status = false; data->k = 0; return ret; @@ -1940,7 +1940,7 @@ static int hdcp2_enable_encryption(struct intel_connector *connector) port), LINK_ENCRYPTION_STATUS, HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS); - dig_port->hdcp_auth_status = true; + dig_port->hdcp.auth_status = true; return ret; } @@ -2019,7 +2019,7 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state, struct intel_digital_port *dig_port = intel_attached_dig_port(connector); int ret = 0, i, tries = 3; - for (i = 0; i < tries && !dig_port->hdcp_auth_status; i++) { + for (i = 0; i < tries && !dig_port->hdcp.auth_status; i++) { ret = hdcp2_authenticate_sink(connector); if (!ret) { ret = intel_hdcp_prepare_streams(state, connector); @@ -2052,7 +2052,7 @@ static int hdcp2_authenticate_and_encrypt(struct intel_atomic_state *state, drm_dbg_kms(display->drm, "Port deauth failed.\n"); } - if (!ret && !dig_port->hdcp_auth_status) { + if (!ret && !dig_port->hdcp.auth_status) { /* * Ensuring the required 200mSec min time interval between * Session Key Exchange and encryption. @@ -2106,7 +2106,7 @@ _intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery { struct intel_display *display = to_intel_display(connector); struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; struct intel_hdcp *hdcp = &connector->hdcp; int ret; @@ -2123,7 +2123,7 @@ _intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery drm_dbg_kms(display->drm, "HDCP 2.2 transcoder: %s stream encryption disabled\n", transcoder_name(hdcp->stream_transcoder)); - if (dig_port->num_hdcp_streams > 0 && !hdcp2_link_recovery) + if (dig_port->hdcp.num_streams > 0 && !hdcp2_link_recovery) return 0; } @@ -2133,7 +2133,7 @@ _intel_hdcp2_disable(struct intel_connector *connector, bool hdcp2_link_recovery drm_dbg_kms(display->drm, "Port deauth failed.\n"); connector->hdcp.hdcp2_encrypted = false; - dig_port->hdcp_auth_status = false; + dig_port->hdcp.auth_status = false; data->k = 0; return ret; @@ -2150,7 +2150,7 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) int ret = 0; mutex_lock(&hdcp->mutex); - mutex_lock(&dig_port->hdcp_mutex); + mutex_lock(&dig_port->hdcp.mutex); cpu_transcoder = hdcp->cpu_transcoder; /* hdcp2_check_link is expected only when HDCP2.2 is Enabled */ @@ -2221,7 +2221,7 @@ static int intel_hdcp2_check_link(struct intel_connector *connector) intel_hdcp_update_value(connector, DRM_MODE_CONTENT_PROTECTION_DESIRED, true); out: - mutex_unlock(&dig_port->hdcp_mutex); + mutex_unlock(&dig_port->hdcp.mutex); mutex_unlock(&hdcp->mutex); return ret; } @@ -2303,7 +2303,7 @@ static int initialize_hdcp_port_data(struct intel_connector *connector, const struct intel_hdcp_shim *shim) { struct intel_display *display = to_intel_display(connector); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct hdcp_port_data *data = &dig_port->hdcp.port_data; enum port port = dig_port->base.port; if (DISPLAY_VER(display) < 12) @@ -2414,7 +2414,7 @@ int intel_hdcp_init(struct intel_connector *connector, hdcp->hdcp2_supported); if (ret) { hdcp->hdcp2_supported = false; - kfree(dig_port->hdcp_port_data.streams); + kfree(dig_port->hdcp.port_data.streams); return ret; } @@ -2451,7 +2451,7 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state, } mutex_lock(&hdcp->mutex); - mutex_lock(&dig_port->hdcp_mutex); + mutex_lock(&dig_port->hdcp.mutex); drm_WARN_ON(display->drm, hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED); hdcp->content_type = (u8)conn_state->hdcp_content_type; @@ -2465,7 +2465,7 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state, } if (DISPLAY_VER(display) >= 12) - dig_port->hdcp_port_data.hdcp_transcoder = + dig_port->hdcp.port_data.hdcp_transcoder = intel_get_hdcp_transcoder(hdcp->cpu_transcoder); /* @@ -2499,7 +2499,7 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state, true); } - mutex_unlock(&dig_port->hdcp_mutex); + mutex_unlock(&dig_port->hdcp.mutex); mutex_unlock(&hdcp->mutex); return ret; } @@ -2535,7 +2535,7 @@ int intel_hdcp_disable(struct intel_connector *connector) return -ENOENT; mutex_lock(&hdcp->mutex); - mutex_lock(&dig_port->hdcp_mutex); + mutex_lock(&dig_port->hdcp.mutex); if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED) goto out; @@ -2548,7 +2548,7 @@ int intel_hdcp_disable(struct intel_connector *connector) ret = _intel_hdcp_disable(connector); out: - mutex_unlock(&dig_port->hdcp_mutex); + mutex_unlock(&dig_port->hdcp.mutex); mutex_unlock(&hdcp->mutex); cancel_delayed_work_sync(&hdcp->check_work); return ret; From fe7fad476ec8153a8b8767a08114e3e4a58a837e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 28 Feb 2025 13:45:27 +0200 Subject: [PATCH 33/92] drm/i915/pxp & drm/xe/pxp: Figure out pxp instance from the gem object It's undesirable to have to figure out the pxp pointer in display code. For one thing, its type is different for i915 and xe. Since we can figure the pxp pointer out in the pxp code from the gem object, offload it there. v2: Rebase Cc: Daniele Ceraolo Spurio Cc: Alan Previn Reviewed-by: Daniele Ceraolo Spurio Link: https://patchwork.freedesktop.org/patch/msgid/20250228114527.3091620-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/skl_universal_plane.c | 3 +-- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +- drivers/gpu/drm/i915/pxp/intel_pxp.c | 6 +++--- drivers/gpu/drm/i915/pxp/intel_pxp.h | 4 +--- drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h | 7 ++----- drivers/gpu/drm/xe/xe_pxp.c | 9 ++++++--- drivers/gpu/drm/xe/xe_pxp.h | 2 +- 7 files changed, 15 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 3488c7ae6d8a..87d003498722 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2258,14 +2258,13 @@ static bool skl_fb_scalable(const struct drm_framebuffer *fb) static void check_protection(struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane_state); - struct drm_i915_private *i915 = to_i915(display->drm); const struct drm_framebuffer *fb = plane_state->hw.fb; struct drm_gem_object *obj = intel_fb_bo(fb); if (DISPLAY_VER(display) < 11) return; - plane_state->decrypt = intel_pxp_key_check(i915->pxp, obj, false) == 0; + plane_state->decrypt = intel_pxp_key_check(obj, false) == 0; plane_state->force_black = intel_bo_is_protected(obj) && !plane_state->decrypt; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index c8107502190d..7796c4119ef5 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -915,7 +915,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle) */ if (i915_gem_context_uses_protected_content(eb->gem_context) && i915_gem_object_is_protected(obj)) { - err = intel_pxp_key_check(eb->i915->pxp, intel_bo_to_drm_bo(obj), true); + err = intel_pxp_key_check(intel_bo_to_drm_bo(obj), true); if (err) { i915_gem_object_put(obj); return ERR_PTR(err); diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c index 9cf169665d7c..f8da693ad3ce 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c @@ -460,11 +460,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp) intel_pxp_irq_disable(pxp); } -int intel_pxp_key_check(struct intel_pxp *pxp, - struct drm_gem_object *_obj, - bool assign) +int intel_pxp_key_check(struct drm_gem_object *_obj, bool assign) { struct drm_i915_gem_object *obj = to_intel_bo(_obj); + struct drm_i915_private *i915 = to_i915(_obj->dev); + struct intel_pxp *pxp = i915->pxp; if (!intel_pxp_is_active(pxp)) return -ENODEV; diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h index 4ed97db5e7c6..7b19109845a3 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h @@ -31,9 +31,7 @@ int intel_pxp_get_backend_timeout_ms(struct intel_pxp *pxp); int intel_pxp_start(struct intel_pxp *pxp); void intel_pxp_end(struct intel_pxp *pxp); -int intel_pxp_key_check(struct intel_pxp *pxp, - struct drm_gem_object *obj, - bool assign); +int intel_pxp_key_check(struct drm_gem_object *obj, bool assign); void intel_pxp_invalidate(struct intel_pxp *pxp); diff --git a/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h b/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h index d2eb8e1f6c4b..97fd0ddf0b3a 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h @@ -12,11 +12,8 @@ #include "xe_pxp.h" struct drm_gem_object; -struct xe_pxp; -static inline int intel_pxp_key_check(struct xe_pxp *pxp, - struct drm_gem_object *obj, - bool assign) +static inline int intel_pxp_key_check(struct drm_gem_object *obj, bool assign) { /* * The assign variable is used in i915 to assign the key to the BO at @@ -26,7 +23,7 @@ static inline int intel_pxp_key_check(struct xe_pxp *pxp, if (assign) return -EINVAL; - return xe_pxp_obj_key_check(pxp, obj); + return xe_pxp_obj_key_check(obj); } #endif diff --git a/drivers/gpu/drm/xe/xe_pxp.c b/drivers/gpu/drm/xe/xe_pxp.c index 3cd3f83e86b0..f98e7836e5e7 100644 --- a/drivers/gpu/drm/xe/xe_pxp.c +++ b/drivers/gpu/drm/xe/xe_pxp.c @@ -791,7 +791,6 @@ int xe_pxp_bo_key_check(struct xe_pxp *pxp, struct xe_bo *bo) /** * xe_pxp_obj_key_check - check if the key used by a drm_gem_obj is valid - * @pxp: the xe->pxp pointer (it will be NULL if PXP is disabled) * @obj: the drm_gem_obj we want to check * * Checks whether a drm_gem_obj was encrypted with the current key or an @@ -800,9 +799,13 @@ int xe_pxp_bo_key_check(struct xe_pxp *pxp, struct xe_bo *bo) * Returns: 0 if the key is valid, -ENODEV if PXP is disabled, -EINVAL if the * obj is not using PXP, -ENOEXEC if the key is not valid. */ -int xe_pxp_obj_key_check(struct xe_pxp *pxp, struct drm_gem_object *obj) +int xe_pxp_obj_key_check(struct drm_gem_object *obj) { - return xe_pxp_bo_key_check(pxp, gem_to_xe_bo(obj)); + struct xe_bo *bo = gem_to_xe_bo(obj); + struct xe_device *xe = xe_bo_device(bo); + struct xe_pxp *pxp = xe->pxp; + + return xe_pxp_bo_key_check(pxp, bo); } /** diff --git a/drivers/gpu/drm/xe/xe_pxp.h b/drivers/gpu/drm/xe/xe_pxp.h index 546b156d63aa..71a23280b900 100644 --- a/drivers/gpu/drm/xe/xe_pxp.h +++ b/drivers/gpu/drm/xe/xe_pxp.h @@ -30,6 +30,6 @@ void xe_pxp_exec_queue_remove(struct xe_pxp *pxp, struct xe_exec_queue *q); int xe_pxp_key_assign(struct xe_pxp *pxp, struct xe_bo *bo); int xe_pxp_bo_key_check(struct xe_pxp *pxp, struct xe_bo *bo); -int xe_pxp_obj_key_check(struct xe_pxp *pxp, struct drm_gem_object *obj); +int xe_pxp_obj_key_check(struct drm_gem_object *obj); #endif /* __XE_PXP_H__ */ From 7c04b6c7e9c5b1d8121b4fe88bc47daed2ff8665 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 24 Feb 2025 18:00:48 +0200 Subject: [PATCH 34/92] drm/i915: relocate intel_plane_ggtt_offset() to intel_atomic_plane.c With the primary goal of removing #include "i915_vma.h" from intel_display_types.h, move intel_plane_ggtt_offset() to a proper function in intel_atomic_plane.c. This reveals tons of implicit dependencies all over the place that we pulled in via i915_vma.h. Fix the fallout. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/70ac6d19518f355abf37ac8c4b0f1d18878be28c.1740412806.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_acpi.c | 2 ++ drivers/gpu/drm/i915/display/intel_atomic_plane.c | 8 +++++++- drivers/gpu/drm/i915/display/intel_atomic_plane.h | 2 ++ drivers/gpu/drm/i915/display/intel_display_power_map.c | 2 ++ drivers/gpu/drm/i915/display/intel_display_types.h | 7 +------ drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c | 2 ++ drivers/gpu/drm/i915/display/intel_dp_link_training.c | 1 + drivers/gpu/drm/i915/display/intel_dp_test.c | 2 ++ drivers/gpu/drm/i915/display/intel_dp_tunnel.c | 1 + drivers/gpu/drm/i915/display/intel_fbdev.c | 2 ++ drivers/gpu/drm/i915/display/intel_frontbuffer.c | 1 + drivers/gpu/drm/i915/display/intel_link_bw.c | 1 + drivers/gpu/drm/i915/display/intel_panel.c | 1 + drivers/gpu/drm/i915/display/intel_pfit.c | 2 ++ drivers/gpu/drm/i915/display/intel_quirks.c | 2 ++ drivers/gpu/drm/xe/display/xe_fb_pin.c | 1 + 16 files changed, 30 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c index bbf8c5a8fdbd..1addd6288241 100644 --- a/drivers/gpu/drm/i915/display/intel_acpi.c +++ b/drivers/gpu/drm/i915/display/intel_acpi.c @@ -9,6 +9,8 @@ #include #include +#include + #include "i915_utils.h" #include "intel_acpi.h" #include "intel_display_core.h" diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 05dcfa3bea73..4a3a7125152f 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -40,8 +40,9 @@ #include #include -#include "i915_drv.h" #include "i915_config.h" +#include "i915_drv.h" +#include "i915_vma.h" #include "i9xx_plane_regs.h" #include "intel_atomic_plane.h" #include "intel_cdclk.h" @@ -1532,3 +1533,8 @@ int intel_atomic_check_planes(struct intel_atomic_state *state) return 0; } + +u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state) +{ + return i915_ggtt_offset(plane_state->ggtt_vma); +} diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 65edd88d28a9..6efac923dcbc 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -88,4 +88,6 @@ int intel_atomic_add_affected_planes(struct intel_atomic_state *state, struct intel_crtc *crtc); int intel_atomic_check_planes(struct intel_atomic_state *state); +u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state); + #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_power_map.c b/drivers/gpu/drm/i915/display/intel_display_power_map.c index 0c8ac1af6db7..e80e1fd611ca 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_map.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_map.c @@ -3,6 +3,8 @@ * Copyright © 2022 Intel Corporation */ +#include + #include "i915_reg.h" #include "intel_display_core.h" #include "intel_display_power_map.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 053be62a5be1..259cc20c5233 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -40,8 +40,8 @@ #include #include #include +#include -#include "i915_vma.h" #include "i915_vma_types.h" #include "intel_bios.h" #include "intel_display.h" @@ -2104,11 +2104,6 @@ intel_crtc_needs_color_update(const struct intel_crtc_state *crtc_state) intel_crtc_needs_modeset(crtc_state); } -static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state) -{ - return i915_ggtt_offset(plane_state->ggtt_vma); -} - static inline struct intel_frontbuffer * to_intel_frontbuffer(struct drm_framebuffer *fb) { 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 f53c8355d5be..8173de8aec63 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -34,6 +34,8 @@ * for some reason. */ +#include + #include "i915_utils.h" #include "intel_backlight.h" #include "intel_display_core.h" diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 11953b03bb6a..581f1dab618e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -24,6 +24,7 @@ #include #include +#include #include "i915_utils.h" #include "intel_display_core.h" diff --git a/drivers/gpu/drm/i915/display/intel_dp_test.c b/drivers/gpu/drm/i915/display/intel_dp_test.c index 614b90d6938f..bd61f3c3ec91 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_test.c +++ b/drivers/gpu/drm/i915/display/intel_dp_test.c @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include "i915_reg.h" diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c index 280f302967e3..faa2b7a46699 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c +++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c @@ -4,6 +4,7 @@ */ #include +#include #include "intel_atomic.h" #include "intel_display_core.h" diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 301b5fd301a2..64fbd2461df3 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -43,8 +43,10 @@ #include #include #include +#include #include "i915_drv.h" +#include "i915_vma.h" #include "intel_bo.h" #include "intel_display_types.h" #include "intel_fb.h" diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index f023f5a4dba6..ba2f88ca6117 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -59,6 +59,7 @@ #include "i915_active.h" #include "i915_drv.h" +#include "i915_vma.h" #include "intel_bo.h" #include "intel_display_trace.h" #include "intel_display_types.h" diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c b/drivers/gpu/drm/i915/display/intel_link_bw.c index f4d60e77aa18..a10cd3992607 100644 --- a/drivers/gpu/drm/i915/display/intel_link_bw.c +++ b/drivers/gpu/drm/i915/display/intel_link_bw.c @@ -4,6 +4,7 @@ */ #include +#include #include "intel_atomic.h" #include "intel_crtc.h" diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index 4e6c5592c7ae..f5c972880391 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -32,6 +32,7 @@ #include #include +#include #include "intel_backlight.h" #include "intel_connector.h" diff --git a/drivers/gpu/drm/i915/display/intel_pfit.c b/drivers/gpu/drm/i915/display/intel_pfit.c index 6fc58fbee2f9..3c3ecf288570 100644 --- a/drivers/gpu/drm/i915/display/intel_pfit.c +++ b/drivers/gpu/drm/i915/display/intel_pfit.c @@ -3,6 +3,8 @@ * Copyright © 2024 Intel Corporation */ +#include + #include "i915_reg.h" #include "i915_utils.h" #include "intel_de.h" diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c index 8b30e9fd936e..a32fae510ed2 100644 --- a/drivers/gpu/drm/i915/display/intel_quirks.c +++ b/drivers/gpu/drm/i915/display/intel_quirks.c @@ -5,6 +5,8 @@ #include +#include + #include "intel_display_core.h" #include "intel_display_types.h" #include "intel_quirks.h" diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index 11a6b996d739..b69896baa20c 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -5,6 +5,7 @@ #include +#include "i915_vma.h" #include "intel_display_types.h" #include "intel_dpt.h" #include "intel_fb.h" From 767bb0b172fcfe62000265c91c4a84837d2428a7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 24 Feb 2025 18:00:49 +0200 Subject: [PATCH 35/92] drm/i915: split out i915_gtt_view_types.h from i915_vma_types.h In the interest of limiting the display dependencies on i915 core headers, split out i915_gtt_view_types.h from i915_vma_types.h, and only include the new header from intel_display_types.h. Reuse the new header from xe compat code too, failing build if partial view is used in display code. Side note: Why would we ever have set enum i915_gtt_view_type values to size of each type?! What an insane hack. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/bb31885c32dbddad76d634c6fdb98a73b546b42e.1740412806.git.jani.nikula@intel.com --- .../drm/i915/display/intel_display_types.h | 2 +- drivers/gpu/drm/i915/i915_gtt_view_types.h | 59 +++++++++++++++ drivers/gpu/drm/i915/i915_vma_types.h | 52 +------------ .../compat-i915-headers/i915_gtt_view_types.h | 7 ++ .../xe/compat-i915-headers/i915_vma_types.h | 74 ------------------- 5 files changed, 69 insertions(+), 125 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_gtt_view_types.h create mode 100644 drivers/gpu/drm/xe/compat-i915-headers/i915_gtt_view_types.h delete mode 100644 drivers/gpu/drm/xe/compat-i915-headers/i915_vma_types.h diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 259cc20c5233..ffa311845d05 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -42,7 +42,7 @@ #include #include -#include "i915_vma_types.h" +#include "i915_gtt_view_types.h" #include "intel_bios.h" #include "intel_display.h" #include "intel_display_conversion.h" diff --git a/drivers/gpu/drm/i915/i915_gtt_view_types.h b/drivers/gpu/drm/i915/i915_gtt_view_types.h new file mode 100644 index 000000000000..c084f67bc880 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gtt_view_types.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __I915_GTT_VIEW_TYPES_H__ +#define __I915_GTT_VIEW_TYPES_H__ + +#include + +struct intel_remapped_plane_info { + /* in gtt pages */ + u32 offset:31; + u32 linear:1; + union { + /* in gtt pages for !linear */ + struct { + u16 width; + u16 height; + u16 src_stride; + u16 dst_stride; + }; + + /* in gtt pages for linear */ + u32 size; + }; +} __packed; + +struct intel_rotation_info { + struct intel_remapped_plane_info plane[2]; +} __packed; + +struct intel_partial_info { + u64 offset; + unsigned int size; +} __packed; + +struct intel_remapped_info { + struct intel_remapped_plane_info plane[4]; + /* in gtt pages */ + u32 plane_alignment; +} __packed; + +enum i915_gtt_view_type { + I915_GTT_VIEW_NORMAL = 0, + I915_GTT_VIEW_ROTATED = sizeof(struct intel_rotation_info), + I915_GTT_VIEW_PARTIAL = sizeof(struct intel_partial_info), + I915_GTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info), +}; + +struct i915_gtt_view { + enum i915_gtt_view_type type; + union { + /* Members need to contain no holes/padding */ + struct intel_partial_info partial; + struct intel_rotation_info rotated; + struct intel_remapped_info remapped; + }; +}; + +#endif /* __I915_GTT_VIEW_TYPES_H__ */ diff --git a/drivers/gpu/drm/i915/i915_vma_types.h b/drivers/gpu/drm/i915/i915_vma_types.h index 559de74d0b11..a499a3bea874 100644 --- a/drivers/gpu/drm/i915/i915_vma_types.h +++ b/drivers/gpu/drm/i915/i915_vma_types.h @@ -32,6 +32,8 @@ #include "gem/i915_gem_object_types.h" +#include "i915_gtt_view_types.h" + /** * DOC: Global GTT views * @@ -95,46 +97,6 @@ struct i915_vma_resource; -struct intel_remapped_plane_info { - /* in gtt pages */ - u32 offset:31; - u32 linear:1; - union { - /* in gtt pages for !linear */ - struct { - u16 width; - u16 height; - u16 src_stride; - u16 dst_stride; - }; - - /* in gtt pages for linear */ - u32 size; - }; -} __packed; - -struct intel_remapped_info { - struct intel_remapped_plane_info plane[4]; - /* in gtt pages */ - u32 plane_alignment; -} __packed; - -struct intel_rotation_info { - struct intel_remapped_plane_info plane[2]; -} __packed; - -struct intel_partial_info { - u64 offset; - unsigned int size; -} __packed; - -enum i915_gtt_view_type { - I915_GTT_VIEW_NORMAL = 0, - I915_GTT_VIEW_ROTATED = sizeof(struct intel_rotation_info), - I915_GTT_VIEW_PARTIAL = sizeof(struct intel_partial_info), - I915_GTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info), -}; - static inline void assert_i915_gem_gtt_types(void) { BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 2 * sizeof(u32) + 8 * sizeof(u16)); @@ -160,16 +122,6 @@ static inline void assert_i915_gem_gtt_types(void) } } -struct i915_gtt_view { - enum i915_gtt_view_type type; - union { - /* Members need to contain no holes/padding */ - struct intel_partial_info partial; - struct intel_rotation_info rotated; - struct intel_remapped_info remapped; - }; -}; - /** * DOC: Virtual Memory Address * diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_gtt_view_types.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_gtt_view_types.h new file mode 100644 index 000000000000..b261910cd6f9 --- /dev/null +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_gtt_view_types.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#include "../../i915/i915_gtt_view_types.h" + +/* Partial view not supported in xe, fail build if used. */ +#define I915_GTT_VIEW_PARTIAL diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_vma_types.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_vma_types.h deleted file mode 100644 index e7aaf50f5485..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_vma_types.h +++ /dev/null @@ -1,74 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#include -#include - -/* XX: Figure out how to handle this vma mapping in xe */ -struct intel_remapped_plane_info { - /* in gtt pages */ - u32 offset:31; - u32 linear:1; - union { - /* in gtt pages for !linear */ - struct { - u16 width; - u16 height; - u16 src_stride; - u16 dst_stride; - }; - - /* in gtt pages for linear */ - u32 size; - }; -} __packed; - -struct intel_remapped_info { - struct intel_remapped_plane_info plane[4]; - /* in gtt pages */ - u32 plane_alignment; -} __packed; - -struct intel_rotation_info { - struct intel_remapped_plane_info plane[2]; -} __packed; - -enum i915_gtt_view_type { - I915_GTT_VIEW_NORMAL = 0, - I915_GTT_VIEW_ROTATED = sizeof(struct intel_rotation_info), - I915_GTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info), -}; - -static inline void assert_i915_gem_gtt_types(void) -{ - BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 2 * sizeof(u32) + 8 * sizeof(u16)); - BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 5 * sizeof(u32) + 16 * sizeof(u16)); - - /* Check that rotation/remapped shares offsets for simplicity */ - BUILD_BUG_ON(offsetof(struct intel_remapped_info, plane[0]) != - offsetof(struct intel_rotation_info, plane[0])); - BUILD_BUG_ON(offsetofend(struct intel_remapped_info, plane[1]) != - offsetofend(struct intel_rotation_info, plane[1])); - - /* As we encode the size of each branch inside the union into its type, - * we have to be careful that each branch has a unique size. - */ - switch ((enum i915_gtt_view_type)0) { - case I915_GTT_VIEW_NORMAL: - case I915_GTT_VIEW_ROTATED: - case I915_GTT_VIEW_REMAPPED: - /* gcc complains if these are identical cases */ - break; - } -} - -struct i915_gtt_view { - enum i915_gtt_view_type type; - union { - /* Members need to contain no holes/padding */ - struct intel_rotation_info rotated; - struct intel_remapped_info remapped; - }; -}; From 840cb2dc27174e06697b5d16ad76cd5adbfb4cdc Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:37:54 +0200 Subject: [PATCH 36/92] drm/i915/fbc: remove one duplicate forward declaration Remove the duplicate "intel_display"declaration from intel_fbc.h Signed-off-by: Vinod Govindapillai Reviewed-by: Jani Nikula Signed-off-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250228093802.27091-2-vinod.govindapillai@intel.com --- drivers/gpu/drm/i915/display/intel_fbc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h index df20e63d6102..2e1dd7e8a18f 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.h +++ b/drivers/gpu/drm/i915/display/intel_fbc.h @@ -13,7 +13,6 @@ struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; struct intel_display; -struct intel_display; struct intel_fbc; struct intel_plane; struct intel_plane_state; From 9a112dd8c17fa6397785f2227dfe4f6f175ed524 Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:37:55 +0200 Subject: [PATCH 37/92] drm/damage-helper: add const qualifier in drm_atomic_helper_damage_merged() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a const qualifier for the "state" parameter as well as we could use this helper to get the combined damage in cases of const drm_plane_state as well. Needed mainly for xe driver big joiner cases where we need to track the damage from immutable plane state. Reviewed-by: Ville Syrjälä Signed-off-by: Vinod Govindapillai Acked-by: Thomas Zimmermann Signed-off-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250228093802.27091-3-vinod.govindapillai@intel.com --- drivers/gpu/drm/drm_damage_helper.c | 2 +- include/drm/drm_damage_helper.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c index afb02aae707b..44a5a36806e3 100644 --- a/drivers/gpu/drm/drm_damage_helper.c +++ b/drivers/gpu/drm/drm_damage_helper.c @@ -308,7 +308,7 @@ EXPORT_SYMBOL(drm_atomic_helper_damage_iter_next); * True if there is valid plane damage otherwise false. */ bool drm_atomic_helper_damage_merged(const struct drm_plane_state *old_state, - struct drm_plane_state *state, + const struct drm_plane_state *state, struct drm_rect *rect) { struct drm_atomic_helper_damage_iter iter; diff --git a/include/drm/drm_damage_helper.h b/include/drm/drm_damage_helper.h index effda42cce31..a58cbcd11276 100644 --- a/include/drm/drm_damage_helper.h +++ b/include/drm/drm_damage_helper.h @@ -78,7 +78,7 @@ bool drm_atomic_helper_damage_iter_next(struct drm_atomic_helper_damage_iter *iter, struct drm_rect *rect); bool drm_atomic_helper_damage_merged(const struct drm_plane_state *old_state, - struct drm_plane_state *state, + const struct drm_plane_state *state, struct drm_rect *rect); #endif From 6f60de67d7e4ae0f6c7aebcb9b62d89fed7233a4 Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:37:56 +0200 Subject: [PATCH 38/92] drm/i915/display: update and store the plane damage clips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Userspace can pass damage area clips per plane to track changes in a plane and some display components can utilze these damage clips for efficiently handling use cases like FBC, PSR etc. A merged damage area is generated and its coordinates are updated relative to viewport and HW and stored in the plane_state. This merged damage areas will be used for FBC dirty rect support in xe3 in the follow-up patch. Big thanks to Ville Syrjala for his contribuitions in shaping up of this series. v1: - Move damage_merged helper to cover bigjoiner case and use the correct plane state for damage find helper (Ville) - Damage handling code under HAS_FBC_DIRTY_RECT() so the the related part will be executed only for xe3+ - Changed dev_priv to i915 in one of the functions v2: - damage reported is stored in the plane state after coords adjustmentments irrespective of fbc dirty rect support. - Damage to be empty in case of plane not visible (Ville) - Handle fb could be NULL and plane not visible cases (Ville) v3: - No need to empty damage in case disp ver < 12 (Ville) - update to the patch subject Reviewed-by: Ville Syrjälä Signed-off-by: Vinod Govindapillai Signed-off-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250228093802.27091-4-vinod.govindapillai@intel.com --- .../gpu/drm/i915/display/intel_atomic_plane.c | 29 ++++++++++++ .../drm/i915/display/intel_display_types.h | 2 + .../drm/i915/display/skl_universal_plane.c | 46 ++++++++++++++++++- 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 4a3a7125152f..9ac3c008f375 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -132,6 +133,7 @@ intel_plane_duplicate_state(struct drm_plane *plane) intel_state->ggtt_vma = NULL; intel_state->dpt_vma = NULL; intel_state->flags = 0; + intel_state->damage = DRM_RECT_INIT(0, 0, 0, 0); /* add reference to fb */ if (intel_state->hw.fb) @@ -337,6 +339,25 @@ static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state) memset(&plane_state->hw, 0, sizeof(plane_state->hw)); } +static void +intel_plane_copy_uapi_plane_damage(struct intel_plane_state *new_plane_state, + const struct intel_plane_state *old_uapi_plane_state, + const struct intel_plane_state *new_uapi_plane_state) +{ + struct intel_display *display = to_intel_display(new_plane_state); + struct drm_rect *damage = &new_plane_state->damage; + + /* damage property tracking enabled from display version 12 onwards */ + if (DISPLAY_VER(display) < 12) + return; + + if (!drm_atomic_helper_damage_merged(&old_uapi_plane_state->uapi, + &new_uapi_plane_state->uapi, + damage)) + /* Incase helper fails, mark whole plane region as damage */ + *damage = drm_plane_state_src(&new_uapi_plane_state->uapi); +} + void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state, const struct intel_plane_state *from_plane_state, struct intel_crtc *crtc) @@ -706,6 +727,7 @@ int intel_plane_atomic_check(struct intel_atomic_state *state, const struct intel_plane_state *old_plane_state = intel_atomic_get_old_plane_state(state, plane); const struct intel_plane_state *new_primary_crtc_plane_state; + const struct intel_plane_state *old_primary_crtc_plane_state; struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); @@ -720,10 +742,17 @@ int intel_plane_atomic_check(struct intel_atomic_state *state, new_primary_crtc_plane_state = intel_atomic_get_new_plane_state(state, primary_crtc_plane); + old_primary_crtc_plane_state = + intel_atomic_get_old_plane_state(state, primary_crtc_plane); } else { new_primary_crtc_plane_state = new_plane_state; + old_primary_crtc_plane_state = old_plane_state; } + intel_plane_copy_uapi_plane_damage(new_plane_state, + old_primary_crtc_plane_state, + new_primary_crtc_plane_state); + intel_plane_copy_uapi_to_hw_state(new_plane_state, new_primary_crtc_plane_state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index ffa311845d05..99a6fd2900b9 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -693,6 +693,8 @@ struct intel_plane_state { u64 ccval; const char *no_fbc_reason; + + struct drm_rect damage; }; struct intel_initial_plane_config { diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 87d003498722..70e550539bb2 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2269,6 +2269,44 @@ static void check_protection(struct intel_plane_state *plane_state) !plane_state->decrypt; } +static void +make_damage_viewport_relative(struct intel_plane_state *plane_state) +{ + const struct drm_framebuffer *fb = plane_state->hw.fb; + const struct drm_rect *src = &plane_state->uapi.src; + unsigned int rotation = plane_state->hw.rotation; + struct drm_rect *damage = &plane_state->damage; + + if (!drm_rect_visible(damage)) + return; + + if (!fb || !plane_state->uapi.visible) { + plane_state->damage = DRM_RECT_INIT(0, 0, 0, 0); + return; + } + + if (drm_rotation_90_or_270(rotation)) { + drm_rect_rotate(damage, fb->width, fb->height, + DRM_MODE_ROTATE_270); + drm_rect_translate(damage, -(src->y1 >> 16), -(src->x1 >> 16)); + } else { + drm_rect_translate(damage, -(src->x1 >> 16), -(src->y1 >> 16)); + } +} + +static void clip_damage(struct intel_plane_state *plane_state) +{ + struct drm_rect *damage = &plane_state->damage; + struct drm_rect src; + + if (!drm_rect_visible(damage)) + return; + + drm_rect_fp_to_int(&src, &plane_state->uapi.src); + drm_rect_translate(damage, src.x1, src.y1); + drm_rect_intersect(damage, &src); +} + static int skl_plane_check(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { @@ -2294,6 +2332,8 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state, if (ret) return ret; + make_damage_viewport_relative(plane_state); + ret = skl_check_plane_surface(plane_state); if (ret) return ret; @@ -2309,6 +2349,8 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state, if (ret) return ret; + clip_damage(plane_state); + ret = skl_plane_check_nv12_rotation(plane_state); if (ret) return ret; @@ -2316,8 +2358,10 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state, check_protection(plane_state); /* HW only has 8 bits pixel precision, disable plane if invisible */ - if (!(plane_state->hw.alpha >> 8)) + if (!(plane_state->hw.alpha >> 8)) { plane_state->uapi.visible = false; + plane_state->damage = DRM_RECT_INIT(0, 0, 0, 0); + } plane_state->ctl = skl_plane_ctl(crtc_state, plane_state); From 22a28633a40fd419f91ec8304336841d0f9c880d Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:37:57 +0200 Subject: [PATCH 39/92] drm/i915/fbc: add register definitions for fbc dirty rect support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Register definitions for FBC dirty rect support v2: - update to the patch subject Bspec: 71675, 73424 Reviewed-by: Ville Syrjälä Signed-off-by: Vinod Govindapillai Signed-off-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250228093802.27091-5-vinod.govindapillai@intel.com --- drivers/gpu/drm/i915/display/intel_fbc_regs.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_fbc_regs.h b/drivers/gpu/drm/i915/display/intel_fbc_regs.h index ae0699c3c2fe..b1d0161a3196 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_fbc_regs.h @@ -100,6 +100,15 @@ #define FBC_STRIDE_MASK REG_GENMASK(14, 0) #define FBC_STRIDE(x) REG_FIELD_PREP(FBC_STRIDE_MASK, (x)) +#define XE3_FBC_DIRTY_RECT(fbc_id) _MMIO_PIPE((fbc_id), 0x43230, 0x43270) +#define FBC_DIRTY_RECT_END_LINE_MASK REG_GENMASK(31, 16) +#define FBC_DIRTY_RECT_END_LINE(val) REG_FIELD_PREP(FBC_DIRTY_RECT_END_LINE_MASK, (val)) +#define FBC_DIRTY_RECT_START_LINE_MASK REG_GENMASK(15, 0) +#define FBC_DIRTY_RECT_START_LINE(val) REG_FIELD_PREP(FBC_DIRTY_RECT_START_LINE_MASK, (val)) + +#define XE3_FBC_DIRTY_CTL(fbc_id) _MMIO_PIPE((fbc_id), 0x43234, 0x43274) +#define FBC_DIRTY_RECT_EN REG_BIT(31) + #define ILK_FBC_RT_BASE _MMIO(0x2128) #define ILK_FBC_RT_VALID REG_BIT(0) #define SNB_FBC_FRONT_BUFFER REG_BIT(1) From c931a0aa82c65964bf62d02d3fb7e69153ff37eb Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:37:58 +0200 Subject: [PATCH 40/92] drm/i915/fbc: introduce HAS_FBC_DIRTY_RECT() for FBC dirty rect support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a macro to check if the platform supports FBC dirty rect capability. v2: - update to the patch subject Reviewed-by: Ville Syrjälä Signed-off-by: Vinod Govindapillai Signed-off-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250228093802.27091-6-vinod.govindapillai@intel.com --- drivers/gpu/drm/i915/display/intel_display_device.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index fc33791f02b9..717286981687 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -163,6 +163,7 @@ struct intel_display_platforms { #define HAS_DSC(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dsc) #define HAS_DSC_MST(__display) (DISPLAY_VER(__display) >= 12 && HAS_DSC(__display)) #define HAS_FBC(__display) (DISPLAY_RUNTIME_INFO(__display)->fbc_mask != 0) +#define HAS_FBC_DIRTY_RECT(__display) (DISPLAY_VER(__display) >= 30) #define HAS_FPGA_DBG_UNCLAIMED(__display) (DISPLAY_INFO(__display)->has_fpga_dbg) #define HAS_FW_BLC(__display) (DISPLAY_VER(__display) >= 3) #define HAS_GMBUS_IRQ(__display) (DISPLAY_VER(__display) >= 4) From 5adac4c9f321db0b2efb1b6ac6d6d9791ecb6fc0 Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:37:59 +0200 Subject: [PATCH 41/92] drm/i915/fbc: avoid calling fbc activate if fbc is active MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If FBC is already active, we don't need to call FBC activate routine again unless there are changes to the fences. So skip this on all platforms that don't have fences. Any FBC register updates done after enabling the dirty rect support in xe3 will trigger nuke by FBC which is counter productive to the fbc dirty rect feature. The front buffer rendering sequence will call intel_fbc_flush() and which will call intel_fbc_nuke() or intel_fbc_activate() based on FBC status explicitly and won't get impacted by this change. v2: use HAS_FBC_DIRTY_RECT() move this functionality within intel_fbc_activate() v3: update to intel_fbc_activate logic (Ville) update to the patch description Reviewed-by: Ville Syrjälä Signed-off-by: Vinod Govindapillai Signed-off-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250228093802.27091-7-vinod.govindapillai@intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 33142427f121..ca44cec73fd2 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -734,8 +734,19 @@ static void intel_fbc_nuke(struct intel_fbc *fbc) static void intel_fbc_activate(struct intel_fbc *fbc) { + struct intel_display *display = fbc->display; + lockdep_assert_held(&fbc->lock); + /* only the fence can change for a flip nuke */ + if (fbc->active && !intel_fbc_has_fences(display)) + return; + /* + * In case of FBC dirt rect, any updates to the FBC registers will + * trigger the nuke. + */ + drm_WARN_ON(display->drm, fbc->active && HAS_FBC_DIRTY_RECT(display)); + intel_fbc_hw_activate(fbc); intel_fbc_nuke(fbc); From 194ecad0b5fcd6f1a325e31ade9c19490260b40f Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:38:00 +0200 Subject: [PATCH 42/92] drm/i915/fbc: dirty rect support for FBC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dirty rectangle feature allows FBC to recompress a subsection of a frame. When this feature is enabled, display will read the scan lines between dirty rectangle start line and dirty rectangle end line in subsequent frames. Use the merged damage clip stored in the plane state to configure the FBC dirty rect areas. v2: - Move dirty rect handling to fbc state (Ville) v3: - Use intel_fbc_dirty_rect_update_noarm (Ville) - Split plane damage collection and dirty rect preparation - Handle case where dirty rect fall outside the visible region v4: - A state variable to check if we need to update dirty rect registers in case intel_fbc_can_flip_nuke() (Ville) v5: - No need to use a separate valid flag, updates to the conditions for prepare damage rect (Ville) - Usage of locks in fbc dirty rect related functions (Ville) v6: - updates dirty rect handling (Ville) v7: - Loop through all planes in atomic state is good enough (Ville) Bspec: 68881, 71675, 73424 Reviewed-by: Ville Syrjälä Signed-off-by: Vinod Govindapillai Signed-off-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250228093802.27091-8-vinod.govindapillai@intel.com --- .../gpu/drm/i915/display/intel_atomic_plane.c | 3 + drivers/gpu/drm/i915/display/intel_display.c | 2 + drivers/gpu/drm/i915/display/intel_fbc.c | 84 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_fbc.h | 4 + 4 files changed, 93 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 9ac3c008f375..a26b54185d5b 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -818,6 +818,9 @@ void intel_plane_update_noarm(struct intel_dsb *dsb, trace_intel_plane_update_noarm(plane_state, crtc); + if (plane->fbc) + intel_fbc_dirty_rect_update_noarm(dsb, plane); + if (plane->update_noarm) plane->update_noarm(dsb, plane, crtc_state, plane_state); } diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b795de186602..bdc25b8153e0 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7272,6 +7272,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_atomic_prepare_plane_clear_colors(state); + intel_fbc_prepare_dirty_rect(state); + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) intel_atomic_dsb_finish(state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index ca44cec73fd2..ee2d75303e41 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -88,6 +88,7 @@ struct intel_fbc_state { u16 override_cfb_stride; u16 interval; s8 fence_id; + struct drm_rect dirty_rect; }; struct intel_fbc { @@ -523,6 +524,9 @@ static void ilk_fbc_deactivate(struct intel_fbc *fbc) struct intel_display *display = fbc->display; u32 dpfc_ctl; + if (HAS_FBC_DIRTY_RECT(display)) + intel_de_write(display, XE3_FBC_DIRTY_CTL(fbc->id), 0); + /* Disable compression */ dpfc_ctl = intel_de_read(display, ILK_DPFC_CONTROL(fbc->id)); if (dpfc_ctl & DPFC_CTL_EN) { @@ -665,6 +669,10 @@ static void ivb_fbc_activate(struct intel_fbc *fbc) if (DISPLAY_VER(display) >= 20) intel_de_write(display, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl); + if (HAS_FBC_DIRTY_RECT(display)) + intel_de_write(display, XE3_FBC_DIRTY_CTL(fbc->id), + FBC_DIRTY_RECT_EN); + intel_de_write(display, ILK_DPFC_CONTROL(fbc->id), DPFC_CTL_EN | dpfc_ctl); } @@ -1196,6 +1204,82 @@ static bool tiling_is_valid(const struct intel_plane_state *plane_state) return i8xx_fbc_tiling_valid(plane_state); } +static void +intel_fbc_dirty_rect_update(struct intel_dsb *dsb, struct intel_fbc *fbc) +{ + struct intel_display *display = fbc->display; + const struct drm_rect *fbc_dirty_rect = &fbc->state.dirty_rect; + + lockdep_assert_held(&fbc->lock); + + intel_de_write_dsb(display, dsb, XE3_FBC_DIRTY_RECT(fbc->id), + FBC_DIRTY_RECT_START_LINE(fbc_dirty_rect->y1) | + FBC_DIRTY_RECT_END_LINE(fbc_dirty_rect->y2 - 1)); +} + +void +intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb, + struct intel_plane *plane) +{ + struct intel_display *display = to_intel_display(plane); + struct intel_fbc *fbc = plane->fbc; + + if (!HAS_FBC_DIRTY_RECT(display)) + return; + + mutex_lock(&fbc->lock); + + if (fbc->state.plane == plane) + intel_fbc_dirty_rect_update(dsb, fbc); + + mutex_unlock(&fbc->lock); +} + +static void +__intel_fbc_prepare_dirty_rect(const struct intel_plane_state *plane_state) +{ + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + struct intel_fbc *fbc = plane->fbc; + struct drm_rect *fbc_dirty_rect = &fbc->state.dirty_rect; + int width = drm_rect_width(&plane_state->uapi.src) >> 16; + const struct drm_rect *damage = &plane_state->damage; + int y_offset = plane_state->view.color_plane[0].y; + + lockdep_assert_held(&fbc->lock); + + if (drm_rect_visible(damage)) + *fbc_dirty_rect = *damage; + else + /* dirty rect must cover at least one line */ + *fbc_dirty_rect = DRM_RECT_INIT(0, y_offset, width, 1); +} + +void +intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state) +{ + struct intel_display *display = to_intel_display(state); + struct intel_plane_state *plane_state; + struct intel_plane *plane; + int i; + + if (!HAS_FBC_DIRTY_RECT(display)) + return; + + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { + struct intel_fbc *fbc = plane->fbc; + + if (!fbc) + continue; + + mutex_lock(&fbc->lock); + + if (fbc->state.plane == plane) + __intel_fbc_prepare_dirty_rect(plane_state); + + mutex_unlock(&fbc->lock); + } +} + static void intel_fbc_update_state(struct intel_atomic_state *state, struct intel_crtc *crtc, struct intel_plane *plane) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h index 2e1dd7e8a18f..08743057ff14 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.h +++ b/drivers/gpu/drm/i915/display/intel_fbc.h @@ -13,6 +13,7 @@ struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; struct intel_display; +struct intel_dsb; struct intel_fbc; struct intel_plane; struct intel_plane_state; @@ -47,5 +48,8 @@ void intel_fbc_handle_fifo_underrun_irq(struct intel_display *display); void intel_fbc_reset_underrun(struct intel_display *display); void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc); void intel_fbc_debugfs_register(struct intel_display *display); +void intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state); +void intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb, + struct intel_plane *plane); #endif /* __INTEL_FBC_H__ */ From e2364a56ad47d3299b1bf2fdb854359d4a770230 Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:38:01 +0200 Subject: [PATCH 43/92] drm/i915/fbc: disable FBC if PSR2 selective fetch is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is not recommended to have both FBC dirty rect and PSR2 selective fetch be enabled at the same time. Mark FBC as not possible, if PSR2 selective fetch is enabled. v2: fix the condition to disable FBC if PSR2 enabled (Jani) v3: use HAS_FBC_DIRTY_RECT() v4: Update to patch description Bspec: 68881 Reviewed-by: Ville Syrjälä Signed-off-by: Vinod Govindapillai Signed-off-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250228093802.27091-9-vinod.govindapillai@intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index ee2d75303e41..5b6a9315fa8f 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1415,9 +1415,14 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, * Display 12+ is not supporting FBC with PSR2. * Recommendation is to keep this combination disabled * Bspec: 50422 HSD: 14010260002 + * + * In Xe3, PSR2 selective fetch and FBC dirty rect feature cannot + * coexist. So if PSR2 selective fetch is supported then mark that + * FBC is not supported. + * TODO: Need a logic to decide between PSR2 and FBC Dirty rect */ - if (IS_DISPLAY_VER(display, 12, 14) && crtc_state->has_sel_update && - !crtc_state->has_panel_replay) { + if ((IS_DISPLAY_VER(display, 12, 14) || HAS_FBC_DIRTY_RECT(display)) && + crtc_state->has_sel_update && !crtc_state->has_panel_replay) { plane_state->no_fbc_reason = "PSR2 enabled"; return 0; } From af23476af8a9ee881bd7a6ef5c94b6f4049ad096 Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:38:02 +0200 Subject: [PATCH 44/92] drm/i915/fbc: handle dirty rect coords for the first frame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During enabling FBC, for the very first frame, the prepare dirty rect routine wouldnt have executed as at that time the plane reference in the fbc_state would be NULL. So this could make driver program some invalid entries as the damage area. Though fbc hw ignores the dirty rect values programmed for the first frame after enabling FBC, driver must ensure that valid dirty rect coords are programmed. So ensure that for the first frame correct dirty rect coords are updated to the HW. Signed-off-by: Vinod Govindapillai Reviewed-by: Ville Syrjälä Signed-off-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20250228093802.27091-10-vinod.govindapillai@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 3 +- drivers/gpu/drm/i915/display/intel_fbc.c | 137 +++++++++++++------ drivers/gpu/drm/i915/display/intel_fbc.h | 3 +- 3 files changed, 99 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index bdc25b8153e0..c4b0ec60fded 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7272,7 +7272,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_atomic_prepare_plane_clear_colors(state); - intel_fbc_prepare_dirty_rect(state); + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) + intel_fbc_prepare_dirty_rect(state, crtc); for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) intel_atomic_dsb_finish(state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 5b6a9315fa8f..b6978135e8ad 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1205,18 +1205,39 @@ static bool tiling_is_valid(const struct intel_plane_state *plane_state) } static void -intel_fbc_dirty_rect_update(struct intel_dsb *dsb, struct intel_fbc *fbc) +intel_fbc_invalidate_dirty_rect(struct intel_fbc *fbc) +{ + lockdep_assert_held(&fbc->lock); + + fbc->state.dirty_rect = DRM_RECT_INIT(0, 0, 0, 0); +} + +static void +intel_fbc_program_dirty_rect(struct intel_dsb *dsb, struct intel_fbc *fbc, + const struct drm_rect *fbc_dirty_rect) { struct intel_display *display = fbc->display; - const struct drm_rect *fbc_dirty_rect = &fbc->state.dirty_rect; - lockdep_assert_held(&fbc->lock); + drm_WARN_ON(display->drm, fbc_dirty_rect->y2 == 0); intel_de_write_dsb(display, dsb, XE3_FBC_DIRTY_RECT(fbc->id), FBC_DIRTY_RECT_START_LINE(fbc_dirty_rect->y1) | FBC_DIRTY_RECT_END_LINE(fbc_dirty_rect->y2 - 1)); } +static void +intel_fbc_dirty_rect_update(struct intel_dsb *dsb, struct intel_fbc *fbc) +{ + const struct drm_rect *fbc_dirty_rect = &fbc->state.dirty_rect; + + lockdep_assert_held(&fbc->lock); + + if (!drm_rect_visible(fbc_dirty_rect)) + return; + + intel_fbc_program_dirty_rect(dsb, fbc, fbc_dirty_rect); +} + void intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb, struct intel_plane *plane) @@ -1236,48 +1257,19 @@ intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb, } static void -__intel_fbc_prepare_dirty_rect(const struct intel_plane_state *plane_state) -{ - struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct intel_fbc *fbc = plane->fbc; - struct drm_rect *fbc_dirty_rect = &fbc->state.dirty_rect; - int width = drm_rect_width(&plane_state->uapi.src) >> 16; - const struct drm_rect *damage = &plane_state->damage; - int y_offset = plane_state->view.color_plane[0].y; - - lockdep_assert_held(&fbc->lock); - - if (drm_rect_visible(damage)) - *fbc_dirty_rect = *damage; - else - /* dirty rect must cover at least one line */ - *fbc_dirty_rect = DRM_RECT_INIT(0, y_offset, width, 1); -} - -void -intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state) +intel_fbc_hw_intialize_dirty_rect(struct intel_fbc *fbc, + const struct intel_plane_state *plane_state) { - struct intel_display *display = to_intel_display(state); - struct intel_plane_state *plane_state; - struct intel_plane *plane; - int i; - - if (!HAS_FBC_DIRTY_RECT(display)) - return; - - for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - struct intel_fbc *fbc = plane->fbc; + struct drm_rect src; - if (!fbc) - continue; - - mutex_lock(&fbc->lock); - - if (fbc->state.plane == plane) - __intel_fbc_prepare_dirty_rect(plane_state); + /* + * Initializing the FBC HW with the whole plane area as the dirty rect. + * This is to ensure that we have valid coords be written to the + * HW as dirty rect. + */ + drm_rect_fp_to_int(&src, &plane_state->uapi.src); - mutex_unlock(&fbc->lock); - } + intel_fbc_program_dirty_rect(NULL, fbc, &src); } static void intel_fbc_update_state(struct intel_atomic_state *state, @@ -1353,6 +1345,62 @@ static bool intel_fbc_is_ok(const struct intel_plane_state *plane_state) intel_fbc_is_cfb_ok(plane_state); } +static void +__intel_fbc_prepare_dirty_rect(const struct intel_plane_state *plane_state, + const struct intel_crtc_state *crtc_state) +{ + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + struct intel_fbc *fbc = plane->fbc; + struct drm_rect *fbc_dirty_rect = &fbc->state.dirty_rect; + int width = drm_rect_width(&plane_state->uapi.src) >> 16; + const struct drm_rect *damage = &plane_state->damage; + int y_offset = plane_state->view.color_plane[0].y; + + lockdep_assert_held(&fbc->lock); + + if (intel_crtc_needs_modeset(crtc_state) || + !intel_fbc_is_ok(plane_state)) { + intel_fbc_invalidate_dirty_rect(fbc); + return; + } + + if (drm_rect_visible(damage)) + *fbc_dirty_rect = *damage; + else + /* dirty rect must cover at least one line */ + *fbc_dirty_rect = DRM_RECT_INIT(0, y_offset, width, 1); +} + +void +intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(state); + const struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + struct intel_plane_state *plane_state; + struct intel_plane *plane; + int i; + + if (!HAS_FBC_DIRTY_RECT(display)) + return; + + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { + struct intel_fbc *fbc = plane->fbc; + + if (!fbc || plane->pipe != crtc->pipe) + continue; + + mutex_lock(&fbc->lock); + + if (fbc->state.plane == plane) + __intel_fbc_prepare_dirty_rect(plane_state, + crtc_state); + + mutex_unlock(&fbc->lock); + } +} + static int intel_fbc_check_plane(struct intel_atomic_state *state, struct intel_plane *plane) { @@ -1629,6 +1677,8 @@ static void __intel_fbc_disable(struct intel_fbc *fbc) drm_dbg_kms(display->drm, "Disabling FBC on [PLANE:%d:%s]\n", plane->base.base.id, plane->base.name); + intel_fbc_invalidate_dirty_rect(fbc); + __intel_fbc_cleanup_cfb(fbc); fbc->state.plane = NULL; @@ -1814,6 +1864,9 @@ static void __intel_fbc_enable(struct intel_atomic_state *state, intel_fbc_update_state(state, crtc, plane); + if (HAS_FBC_DIRTY_RECT(display)) + intel_fbc_hw_intialize_dirty_rect(fbc, plane_state); + intel_fbc_program_workarounds(fbc); intel_fbc_program_cfb(fbc); } diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h index 08743057ff14..0e715cb6b4e6 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.h +++ b/drivers/gpu/drm/i915/display/intel_fbc.h @@ -48,7 +48,8 @@ void intel_fbc_handle_fifo_underrun_irq(struct intel_display *display); void intel_fbc_reset_underrun(struct intel_display *display); void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc); void intel_fbc_debugfs_register(struct intel_display *display); -void intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state); +void intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state, + struct intel_crtc *crtc); void intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb, struct intel_plane *plane); From 6498a5e010fdeeab14b678fba58a6097ffad7e31 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Mar 2025 13:27:03 +0200 Subject: [PATCH 45/92] drm/i915/display: convert display reset to struct intel_display * Going forward, struct intel_display will be the main display device structure. Convert display reset to it as much as possible. Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/060c309189f1c084e012521822f4a0247f64528e.1741001054.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_reset.c | 51 ++++++++++--------- .../drm/i915/display/intel_display_reset.h | 6 +-- drivers/gpu/drm/i915/gt/intel_reset.c | 7 ++- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.c b/drivers/gpu/drm/i915/display/intel_display_reset.c index a690968885bf..c1e448e8a26e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.c +++ b/drivers/gpu/drm/i915/display/intel_display_reset.c @@ -14,24 +14,27 @@ #include "intel_hotplug.h" #include "intel_pps.h" -static bool gpu_reset_clobbers_display(struct drm_i915_private *dev_priv) +static bool gpu_reset_clobbers_display(struct intel_display *display) { - return (INTEL_INFO(dev_priv)->gpu_reset_clobbers_display && - intel_has_gpu_reset(to_gt(dev_priv))); + struct drm_i915_private *i915 = to_i915(display->drm); + + return (INTEL_INFO(i915)->gpu_reset_clobbers_display && + intel_has_gpu_reset(to_gt(i915))); } -void intel_display_reset_prepare(struct drm_i915_private *dev_priv) +void intel_display_reset_prepare(struct intel_display *display) { - struct drm_modeset_acquire_ctx *ctx = &dev_priv->display.restore.reset_ctx; + struct drm_i915_private *dev_priv = to_i915(display->drm); + struct drm_modeset_acquire_ctx *ctx = &display->restore.reset_ctx; struct drm_atomic_state *state; int ret; - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; /* reset doesn't touch the display */ - if (!dev_priv->display.params.force_reset_modeset_test && - !gpu_reset_clobbers_display(dev_priv)) + if (!display->params.force_reset_modeset_test && + !gpu_reset_clobbers_display(display)) return; /* We have a modeset vs reset deadlock, defensively unbreak it. */ @@ -40,7 +43,7 @@ void intel_display_reset_prepare(struct drm_i915_private *dev_priv) wake_up_bit(&to_gt(dev_priv)->reset.flags, I915_RESET_MODESET); if (atomic_read(&dev_priv->gpu_error.pending_fb_pin)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Modeset potentially stuck, unbreaking through wedging\n"); intel_gt_set_wedged(to_gt(dev_priv)); } @@ -49,10 +52,10 @@ void intel_display_reset_prepare(struct drm_i915_private *dev_priv) * Need mode_config.mutex so that we don't * trample ongoing ->detect() and whatnot. */ - mutex_lock(&dev_priv->drm.mode_config.mutex); + mutex_lock(&display->drm->mode_config.mutex); drm_modeset_acquire_init(ctx, 0); while (1) { - ret = drm_modeset_lock_all_ctx(&dev_priv->drm, ctx); + ret = drm_modeset_lock_all_ctx(display->drm, ctx); if (ret != -EDEADLK) break; @@ -62,34 +65,34 @@ void intel_display_reset_prepare(struct drm_i915_private *dev_priv) * Disabling the crtcs gracefully seems nicer. Also the * g33 docs say we should at least disable all the planes. */ - state = drm_atomic_helper_duplicate_state(&dev_priv->drm, ctx); + state = drm_atomic_helper_duplicate_state(display->drm, ctx); if (IS_ERR(state)) { ret = PTR_ERR(state); - drm_err(&dev_priv->drm, "Duplicating state failed with %i\n", + drm_err(display->drm, "Duplicating state failed with %i\n", ret); return; } - ret = drm_atomic_helper_disable_all(&dev_priv->drm, ctx); + ret = drm_atomic_helper_disable_all(display->drm, ctx); if (ret) { - drm_err(&dev_priv->drm, "Suspending crtc's failed with %i\n", + drm_err(display->drm, "Suspending crtc's failed with %i\n", ret); drm_atomic_state_put(state); return; } - dev_priv->display.restore.modeset_state = state; + display->restore.modeset_state = state; state->acquire_ctx = ctx; } -void intel_display_reset_finish(struct drm_i915_private *i915) +void intel_display_reset_finish(struct intel_display *display) { - struct intel_display *display = &i915->display; + struct drm_i915_private *i915 = to_i915(display->drm); struct drm_modeset_acquire_ctx *ctx = &display->restore.reset_ctx; struct drm_atomic_state *state; int ret; - if (!HAS_DISPLAY(i915)) + if (!HAS_DISPLAY(display)) return; /* reset doesn't touch the display */ @@ -101,12 +104,12 @@ void intel_display_reset_finish(struct drm_i915_private *i915) goto unlock; /* reset doesn't touch the display */ - if (!gpu_reset_clobbers_display(i915)) { + if (!gpu_reset_clobbers_display(display)) { /* for testing only restore the display */ ret = drm_atomic_helper_commit_duplicated_state(state, ctx); if (ret) { - drm_WARN_ON(&i915->drm, ret == -EDEADLK); - drm_err(&i915->drm, + drm_WARN_ON(display->drm, ret == -EDEADLK); + drm_err(display->drm, "Restoring old state failed with %i\n", ret); } } else { @@ -122,7 +125,7 @@ void intel_display_reset_finish(struct drm_i915_private *i915) ret = __intel_display_driver_resume(display, state, ctx); if (ret) - drm_err(&i915->drm, + drm_err(display->drm, "Restoring old state failed with %i\n", ret); intel_hpd_poll_disable(i915); @@ -132,7 +135,7 @@ void intel_display_reset_finish(struct drm_i915_private *i915) unlock: drm_modeset_drop_locks(ctx); drm_modeset_acquire_fini(ctx); - mutex_unlock(&i915->drm.mode_config.mutex); + mutex_unlock(&display->drm->mode_config.mutex); clear_bit_unlock(I915_RESET_MODESET, &to_gt(i915)->reset.flags); } diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.h b/drivers/gpu/drm/i915/display/intel_display_reset.h index f06d0d35b86b..9a1fe99bfcd4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.h +++ b/drivers/gpu/drm/i915/display/intel_display_reset.h @@ -6,9 +6,9 @@ #ifndef __INTEL_RESET_H__ #define __INTEL_RESET_H__ -struct drm_i915_private; +struct intel_display; -void intel_display_reset_prepare(struct drm_i915_private *i915); -void intel_display_reset_finish(struct drm_i915_private *i915); +void intel_display_reset_prepare(struct intel_display *display); +void intel_display_reset_finish(struct intel_display *display); #endif /* __INTEL_RESET_H__ */ diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index b33007cd1504..a4b1fec52b21 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -1413,11 +1413,14 @@ static void intel_gt_reset_global(struct intel_gt *gt, /* Use a watchdog to ensure that our reset completes */ intel_wedge_on_timeout(&w, gt, 60 * HZ) { - intel_display_reset_prepare(gt->i915); + struct drm_i915_private *i915 = gt->i915; + struct intel_display *display = &i915->display; + + intel_display_reset_prepare(display); intel_gt_reset(gt, engine_mask, reason); - intel_display_reset_finish(gt->i915); + intel_display_reset_finish(display); } if (!test_bit(I915_WEDGED, >->reset.flags)) From 30f2581b639e6a4a7c3139f3e5086447db5bb9e6 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Mar 2025 13:27:04 +0200 Subject: [PATCH 46/92] drm/i915: move pending_fb_pin to struct intel_display pending_fb_pin is more about display than GPU reset. Move it to struct intel_display. The restore sub-struct already contains reset related members, so move it there. Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/ff779ae318610e6f6813474bcaa53851ffff909d.1741001054.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_core.h | 2 ++ drivers/gpu/drm/i915/display/intel_display_reset.c | 2 +- drivers/gpu/drm/i915/display/intel_dpt.c | 5 +++-- drivers/gpu/drm/i915/display/intel_fb_pin.c | 10 ++++++---- drivers/gpu/drm/i915/display/intel_overlay.c | 5 ++--- drivers/gpu/drm/i915/i915_gpu_error.h | 2 -- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 554870d2494b..1970d4c15090 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -512,6 +512,8 @@ struct intel_display { /* restore state for suspend/resume and display reset */ struct drm_atomic_state *modeset_state; struct drm_modeset_acquire_ctx reset_ctx; + /* modeset stuck tracking for reset */ + atomic_t pending_fb_pin; u32 saveDSPARB; u32 saveSWF0[16]; u32 saveSWF1[16]; diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.c b/drivers/gpu/drm/i915/display/intel_display_reset.c index c1e448e8a26e..cef9536c461c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.c +++ b/drivers/gpu/drm/i915/display/intel_display_reset.c @@ -42,7 +42,7 @@ void intel_display_reset_prepare(struct intel_display *display) smp_mb__after_atomic(); wake_up_bit(&to_gt(dev_priv)->reset.flags, I915_RESET_MODESET); - if (atomic_read(&dev_priv->gpu_error.pending_fb_pin)) { + if (atomic_read(&display->restore.pending_fb_pin)) { drm_dbg_kms(display->drm, "Modeset potentially stuck, unbreaking through wedging\n"); intel_gt_set_wedged(to_gt(dev_priv)); diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index fca7294b1def..0d8ebe38226e 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -125,6 +125,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, unsigned int alignment) { struct drm_i915_private *i915 = vm->i915; + struct intel_display *display = &i915->display; struct i915_dpt *dpt = i915_vm_to_dpt(vm); intel_wakeref_t wakeref; struct i915_vma *vma; @@ -137,7 +138,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, pin_flags |= PIN_MAPPABLE; wakeref = intel_runtime_pm_get(&i915->runtime_pm); - atomic_inc(&i915->gpu_error.pending_fb_pin); + atomic_inc(&display->restore.pending_fb_pin); for_i915_gem_ww(&ww, err, true) { err = i915_gem_object_lock(dpt->obj, &ww); @@ -167,7 +168,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, dpt->obj->mm.dirty = true; - atomic_dec(&i915->gpu_error.pending_fb_pin); + atomic_dec(&display->restore.pending_fb_pin); intel_runtime_pm_put(&i915->runtime_pm, wakeref); return err ? ERR_PTR(err) : vma; diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index 204e7e3e48ca..30ac9b089ad6 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -25,6 +25,7 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb, struct i915_address_space *vm) { struct drm_device *dev = fb->dev; + struct intel_display *display = to_intel_display(dev); struct drm_i915_private *dev_priv = to_i915(dev); struct drm_gem_object *_obj = intel_fb_bo(fb); struct drm_i915_gem_object *obj = to_intel_bo(_obj); @@ -42,7 +43,7 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb, if (WARN_ON(!i915_gem_object_is_framebuffer(obj))) return ERR_PTR(-EINVAL); - atomic_inc(&dev_priv->gpu_error.pending_fb_pin); + atomic_inc(&display->restore.pending_fb_pin); for_i915_gem_ww(&ww, ret, true) { ret = i915_gem_object_lock(obj, &ww); @@ -97,7 +98,7 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb, i915_vma_get(vma); err: - atomic_dec(&dev_priv->gpu_error.pending_fb_pin); + atomic_dec(&display->restore.pending_fb_pin); return vma; } @@ -112,6 +113,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, unsigned long *out_flags) { struct drm_device *dev = fb->dev; + struct intel_display *display = to_intel_display(dev); struct drm_i915_private *dev_priv = to_i915(dev); struct drm_gem_object *_obj = intel_fb_bo(fb); struct drm_i915_gem_object *obj = to_intel_bo(_obj); @@ -136,7 +138,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, */ wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); - atomic_inc(&dev_priv->gpu_error.pending_fb_pin); + atomic_inc(&display->restore.pending_fb_pin); /* * Valleyview is definitely limited to scanning out the first @@ -212,7 +214,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, if (ret) vma = ERR_PTR(ret); - atomic_dec(&dev_priv->gpu_error.pending_fb_pin); + atomic_dec(&display->restore.pending_fb_pin); intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); return vma; } diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index 5c1b20af2a07..aff9a3455c1b 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -800,7 +800,6 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, struct drm_intel_overlay_put_image *params) { struct intel_display *display = overlay->display; - struct drm_i915_private *dev_priv = to_i915(display->drm); struct overlay_registers __iomem *regs = overlay->regs; u32 swidth, swidthsw, sheight, ostride; enum pipe pipe = overlay->crtc->pipe; @@ -815,7 +814,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, if (ret != 0) return ret; - atomic_inc(&dev_priv->gpu_error.pending_fb_pin); + atomic_inc(&display->restore.pending_fb_pin); vma = intel_overlay_pin_fb(new_bo); if (IS_ERR(vma)) { @@ -903,7 +902,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, out_unpin: i915_vma_unpin(vma); out_pin_section: - atomic_dec(&dev_priv->gpu_error.pending_fb_pin); + atomic_dec(&display->restore.pending_fb_pin); return ret; } diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h index 78a8928562a9..749e1c55613e 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.h +++ b/drivers/gpu/drm/i915/i915_gpu_error.h @@ -224,8 +224,6 @@ struct i915_gpu_error { /* Protected by the above dev->gpu_error.lock. */ struct i915_gpu_coredump *first_error; - atomic_t pending_fb_pin; - /** Number of times the device has been reset (global) */ atomic_t reset_count; From 711c39ea9885028a674a669d5b66e7f5e0651db8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Mar 2025 13:27:05 +0200 Subject: [PATCH 47/92] drm/i915/reset: add intel_gt_gpu_reset_clobbers_display() helper Add a helper for checking the gpu_reset_clobbers_display flag to make it easier to relocate the flag later. Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/434d5db7675ed9717b3beae1389008b68a961855.1741001054.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 2 +- drivers/gpu/drm/i915/gt/intel_gt_pm.c | 2 +- drivers/gpu/drm/i915/gt/intel_reset.c | 15 +++++++++++---- drivers/gpu/drm/i915/gt/intel_reset.h | 2 ++ drivers/gpu/drm/i915/i915_driver.c | 2 +- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index ec136eb12d48..39f6ba4bf1ab 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -677,7 +677,7 @@ void intel_engines_release(struct intel_gt *gt) * in case we aborted before completely initialising the engines. */ GEM_BUG_ON(intel_gt_pm_is_awake(gt)); - if (!INTEL_INFO(gt->i915)->gpu_reset_clobbers_display) + if (!intel_gt_gpu_reset_clobbers_display(gt)) intel_gt_reset_all_engines(gt); /* Decouple the backend; but keep the layout for late GPU resets */ diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c index 175fa2db0551..3182f19b9837 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c @@ -158,7 +158,7 @@ void intel_gt_pm_init(struct intel_gt *gt) static bool reset_engines(struct intel_gt *gt) { - if (INTEL_INFO(gt->i915)->gpu_reset_clobbers_display) + if (intel_gt_gpu_reset_clobbers_display(gt)) return false; return intel_gt_reset_all_engines(gt) == 0; diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index a4b1fec52b21..2dbfb5c39d69 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -986,7 +986,7 @@ static void __intel_gt_set_wedged(struct intel_gt *gt) awake = reset_prepare(gt); /* Even if the GPU reset fails, it should still stop the engines */ - if (!INTEL_INFO(gt->i915)->gpu_reset_clobbers_display) + if (!intel_gt_gpu_reset_clobbers_display(gt)) intel_gt_reset_all_engines(gt); for_each_engine(engine, gt, id) @@ -1106,7 +1106,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt) /* We must reset pending GPU events before restoring our submission */ ok = !HAS_EXECLISTS(gt->i915); /* XXX better agnosticism desired */ - if (!INTEL_INFO(gt->i915)->gpu_reset_clobbers_display) + if (!intel_gt_gpu_reset_clobbers_display(gt)) ok = intel_gt_reset_all_engines(gt) == 0; if (!ok) { /* @@ -1178,6 +1178,13 @@ static int resume(struct intel_gt *gt) return 0; } +bool intel_gt_gpu_reset_clobbers_display(struct intel_gt *gt) +{ + struct drm_i915_private *i915 = gt->i915; + + return INTEL_INFO(i915)->gpu_reset_clobbers_display; +} + /** * intel_gt_reset - reset chip after a hang * @gt: #intel_gt to reset @@ -1234,7 +1241,7 @@ void intel_gt_reset(struct intel_gt *gt, goto error; } - if (INTEL_INFO(gt->i915)->gpu_reset_clobbers_display) + if (intel_gt_gpu_reset_clobbers_display(gt)) intel_irq_suspend(gt->i915); if (do_reset(gt, stalled_mask)) { @@ -1242,7 +1249,7 @@ void intel_gt_reset(struct intel_gt *gt, goto taint; } - if (INTEL_INFO(gt->i915)->gpu_reset_clobbers_display) + if (intel_gt_gpu_reset_clobbers_display(gt)) intel_irq_resume(gt->i915); intel_overlay_reset(display); diff --git a/drivers/gpu/drm/i915/gt/intel_reset.h b/drivers/gpu/drm/i915/gt/intel_reset.h index c00de353075c..724ea6d64f33 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.h +++ b/drivers/gpu/drm/i915/gt/intel_reset.h @@ -28,6 +28,8 @@ void intel_gt_handle_error(struct intel_gt *gt, const char *fmt, ...); #define I915_ERROR_CAPTURE BIT(0) +bool intel_gt_gpu_reset_clobbers_display(struct intel_gt *gt); + void intel_gt_reset(struct intel_gt *gt, intel_engine_mask_t stalled_mask, const char *reason); diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 613084fd0097..59bf2d45403f 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -200,7 +200,7 @@ static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv) static void sanitize_gpu(struct drm_i915_private *i915) { - if (!INTEL_INFO(i915)->gpu_reset_clobbers_display) { + if (!intel_gt_gpu_reset_clobbers_display(to_gt(i915))) { struct intel_gt *gt; unsigned int i; From fddbcd1532930fc8732f3018135e75f5779a8f3a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Mar 2025 13:27:06 +0200 Subject: [PATCH 48/92] drm/i915/reset: add intel_display_reset_test() Add a helper for checking if we want to test display reset regardless of whether it's strictly necessary. This will come in handy in follow-up work where we want to check this from gt reset side. v2: Drop superfluous newline Cc: Matt Roper Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/487dec72f753302cd565c3a8164afa7fc1e12ed7.1741001054.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_reset.c | 7 ++++++- drivers/gpu/drm/i915/display/intel_display_reset.h | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.c b/drivers/gpu/drm/i915/display/intel_display_reset.c index cef9536c461c..121679b4230f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.c +++ b/drivers/gpu/drm/i915/display/intel_display_reset.c @@ -22,6 +22,11 @@ static bool gpu_reset_clobbers_display(struct intel_display *display) intel_has_gpu_reset(to_gt(i915))); } +bool intel_display_reset_test(struct intel_display *display) +{ + return display->params.force_reset_modeset_test; +} + void intel_display_reset_prepare(struct intel_display *display) { struct drm_i915_private *dev_priv = to_i915(display->drm); @@ -33,7 +38,7 @@ void intel_display_reset_prepare(struct intel_display *display) return; /* reset doesn't touch the display */ - if (!display->params.force_reset_modeset_test && + if (!intel_display_reset_test(display) && !gpu_reset_clobbers_display(display)) return; diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.h b/drivers/gpu/drm/i915/display/intel_display_reset.h index 9a1fe99bfcd4..c1dd2e8d0914 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.h +++ b/drivers/gpu/drm/i915/display/intel_display_reset.h @@ -6,8 +6,11 @@ #ifndef __INTEL_RESET_H__ #define __INTEL_RESET_H__ +#include + struct intel_display; +bool intel_display_reset_test(struct intel_display *display); void intel_display_reset_prepare(struct intel_display *display); void intel_display_reset_finish(struct intel_display *display); From ea349ec038c40b4bc6f20a61137282569d944ee0 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Mar 2025 13:27:07 +0200 Subject: [PATCH 49/92] drm/i915/reset: remove I915_RESET_MODESET flag Since commit d59cf7bb73f3 ("drm/i915/display: Use dma_fence interfaces instead of i915_sw_fence") we don't have anyone waiting on the I915_RESET_MODESET bit, and there's no need for its semantics. Instead, simply return true from intel_display_reset_prepare() to indicate that intel_display_reset_finish() should be called. Cc: Matt Roper Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/294690db3fae8fec7f356edf467e79882ed494db.1741001054.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../drm/i915/display/intel_display_reset.c | 24 +++++++------------ .../drm/i915/display/intel_display_reset.h | 2 +- drivers/gpu/drm/i915/gt/intel_reset.c | 8 ++++--- drivers/gpu/drm/i915/gt/intel_reset_types.h | 3 +-- 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.c b/drivers/gpu/drm/i915/display/intel_display_reset.c index 121679b4230f..acc728c75328 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.c +++ b/drivers/gpu/drm/i915/display/intel_display_reset.c @@ -27,7 +27,8 @@ bool intel_display_reset_test(struct intel_display *display) return display->params.force_reset_modeset_test; } -void intel_display_reset_prepare(struct intel_display *display) +/* returns true if intel_display_reset_finish() needs to be called */ +bool intel_display_reset_prepare(struct intel_display *display) { struct drm_i915_private *dev_priv = to_i915(display->drm); struct drm_modeset_acquire_ctx *ctx = &display->restore.reset_ctx; @@ -35,17 +36,12 @@ void intel_display_reset_prepare(struct intel_display *display) int ret; if (!HAS_DISPLAY(display)) - return; + return false; /* reset doesn't touch the display */ if (!intel_display_reset_test(display) && !gpu_reset_clobbers_display(display)) - return; - - /* We have a modeset vs reset deadlock, defensively unbreak it. */ - set_bit(I915_RESET_MODESET, &to_gt(dev_priv)->reset.flags); - smp_mb__after_atomic(); - wake_up_bit(&to_gt(dev_priv)->reset.flags, I915_RESET_MODESET); + return false; if (atomic_read(&display->restore.pending_fb_pin)) { drm_dbg_kms(display->drm, @@ -75,7 +71,7 @@ void intel_display_reset_prepare(struct intel_display *display) ret = PTR_ERR(state); drm_err(display->drm, "Duplicating state failed with %i\n", ret); - return; + return true; } ret = drm_atomic_helper_disable_all(display->drm, ctx); @@ -83,11 +79,13 @@ void intel_display_reset_prepare(struct intel_display *display) drm_err(display->drm, "Suspending crtc's failed with %i\n", ret); drm_atomic_state_put(state); - return; + return true; } display->restore.modeset_state = state; state->acquire_ctx = ctx; + + return true; } void intel_display_reset_finish(struct intel_display *display) @@ -100,10 +98,6 @@ void intel_display_reset_finish(struct intel_display *display) if (!HAS_DISPLAY(display)) return; - /* reset doesn't touch the display */ - if (!test_bit(I915_RESET_MODESET, &to_gt(i915)->reset.flags)) - return; - state = fetch_and_zero(&display->restore.modeset_state); if (!state) goto unlock; @@ -141,6 +135,4 @@ void intel_display_reset_finish(struct intel_display *display) drm_modeset_drop_locks(ctx); drm_modeset_acquire_fini(ctx); mutex_unlock(&display->drm->mode_config.mutex); - - clear_bit_unlock(I915_RESET_MODESET, &to_gt(i915)->reset.flags); } diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.h b/drivers/gpu/drm/i915/display/intel_display_reset.h index c1dd2e8d0914..311b5af8ca0c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.h +++ b/drivers/gpu/drm/i915/display/intel_display_reset.h @@ -11,7 +11,7 @@ struct intel_display; bool intel_display_reset_test(struct intel_display *display); -void intel_display_reset_prepare(struct intel_display *display); +bool intel_display_reset_prepare(struct intel_display *display); void intel_display_reset_finish(struct intel_display *display); #endif /* __INTEL_RESET_H__ */ diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index 2dbfb5c39d69..d8425ce019df 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -1422,12 +1422,14 @@ static void intel_gt_reset_global(struct intel_gt *gt, intel_wedge_on_timeout(&w, gt, 60 * HZ) { struct drm_i915_private *i915 = gt->i915; struct intel_display *display = &i915->display; + bool reset_display; - intel_display_reset_prepare(display); + reset_display = intel_display_reset_prepare(display); intel_gt_reset(gt, engine_mask, reason); - intel_display_reset_finish(display); + if (reset_display) + intel_display_reset_finish(display); } if (!test_bit(I915_WEDGED, >->reset.flags)) @@ -1495,7 +1497,7 @@ void intel_gt_handle_error(struct intel_gt *gt, intel_has_reset_engine(gt) && !intel_gt_is_wedged(gt)) { local_bh_disable(); for_each_engine_masked(engine, gt, engine_mask, tmp) { - BUILD_BUG_ON(I915_RESET_MODESET >= I915_RESET_ENGINE); + BUILD_BUG_ON(I915_RESET_BACKOFF >= I915_RESET_ENGINE); if (test_and_set_bit(I915_RESET_ENGINE + engine->id, >->reset.flags)) continue; diff --git a/drivers/gpu/drm/i915/gt/intel_reset_types.h b/drivers/gpu/drm/i915/gt/intel_reset_types.h index 80351f0a856c..4f5fd393af6f 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset_types.h +++ b/drivers/gpu/drm/i915/gt/intel_reset_types.h @@ -41,8 +41,7 @@ struct intel_reset { */ unsigned long flags; #define I915_RESET_BACKOFF 0 -#define I915_RESET_MODESET 1 -#define I915_RESET_ENGINE 2 +#define I915_RESET_ENGINE 1 #define I915_WEDGED_ON_INIT (BITS_PER_LONG - 3) #define I915_WEDGED_ON_FINI (BITS_PER_LONG - 2) #define I915_WEDGED (BITS_PER_LONG - 1) From 4684498cf9991e97a001ef5814391c7f7321ff99 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Mar 2025 13:27:08 +0200 Subject: [PATCH 50/92] drm/i915/reset: decide whether display reset is needed on gt side Move the checks for whether display reset is needed at all to gt side of things. This way, we can decide to skip the display calls altogether if display reset is not required. Cc: Matt Roper Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/c32a88f292f516ec702bd07001ac609b8acc2888.1741001054.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_reset.c | 5 ----- drivers/gpu/drm/i915/gt/intel_reset.c | 10 +++++++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.c b/drivers/gpu/drm/i915/display/intel_display_reset.c index acc728c75328..c48d822db58e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.c +++ b/drivers/gpu/drm/i915/display/intel_display_reset.c @@ -38,11 +38,6 @@ bool intel_display_reset_prepare(struct intel_display *display) if (!HAS_DISPLAY(display)) return false; - /* reset doesn't touch the display */ - if (!intel_display_reset_test(display) && - !gpu_reset_clobbers_display(display)) - return false; - if (atomic_read(&display->restore.pending_fb_pin)) { drm_dbg_kms(display->drm, "Modeset potentially stuck, unbreaking through wedging\n"); diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index d8425ce019df..23f3fdaadb33 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -1422,9 +1422,17 @@ static void intel_gt_reset_global(struct intel_gt *gt, intel_wedge_on_timeout(&w, gt, 60 * HZ) { struct drm_i915_private *i915 = gt->i915; struct intel_display *display = &i915->display; + bool need_display_reset; bool reset_display; - reset_display = intel_display_reset_prepare(display); + need_display_reset = intel_gt_gpu_reset_clobbers_display(gt) && + intel_has_gpu_reset(gt); + + reset_display = intel_display_reset_test(display) || + need_display_reset; + + if (reset_display) + reset_display = intel_display_reset_prepare(display); intel_gt_reset(gt, engine_mask, reason); From d1b97b121e3c2bbb3c74fe91e42d13e59fd9d96e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Mar 2025 13:27:09 +0200 Subject: [PATCH 51/92] drm/i915/reset: pass test only parameter to intel_display_reset_finish() Deduplicate the gpu_reset_clobbers_display() part by passing the information in from gt side. Cc: Matt Roper Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/a36481db334fedcde50ae0e66c4d57825cae8cb7.1741001054.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_reset.c | 12 ++---------- drivers/gpu/drm/i915/display/intel_display_reset.h | 2 +- drivers/gpu/drm/i915/gt/intel_reset.c | 2 +- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.c b/drivers/gpu/drm/i915/display/intel_display_reset.c index c48d822db58e..d5ce0ac43377 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.c +++ b/drivers/gpu/drm/i915/display/intel_display_reset.c @@ -14,14 +14,6 @@ #include "intel_hotplug.h" #include "intel_pps.h" -static bool gpu_reset_clobbers_display(struct intel_display *display) -{ - struct drm_i915_private *i915 = to_i915(display->drm); - - return (INTEL_INFO(i915)->gpu_reset_clobbers_display && - intel_has_gpu_reset(to_gt(i915))); -} - bool intel_display_reset_test(struct intel_display *display) { return display->params.force_reset_modeset_test; @@ -83,7 +75,7 @@ bool intel_display_reset_prepare(struct intel_display *display) return true; } -void intel_display_reset_finish(struct intel_display *display) +void intel_display_reset_finish(struct intel_display *display, bool test_only) { struct drm_i915_private *i915 = to_i915(display->drm); struct drm_modeset_acquire_ctx *ctx = &display->restore.reset_ctx; @@ -98,7 +90,7 @@ void intel_display_reset_finish(struct intel_display *display) goto unlock; /* reset doesn't touch the display */ - if (!gpu_reset_clobbers_display(display)) { + if (test_only) { /* for testing only restore the display */ ret = drm_atomic_helper_commit_duplicated_state(state, ctx); if (ret) { diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.h b/drivers/gpu/drm/i915/display/intel_display_reset.h index 311b5af8ca0c..f518147199a1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.h +++ b/drivers/gpu/drm/i915/display/intel_display_reset.h @@ -12,6 +12,6 @@ struct intel_display; bool intel_display_reset_test(struct intel_display *display); bool intel_display_reset_prepare(struct intel_display *display); -void intel_display_reset_finish(struct intel_display *display); +void intel_display_reset_finish(struct intel_display *display, bool test_only); #endif /* __INTEL_RESET_H__ */ diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index 23f3fdaadb33..9a92afcd9b0b 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -1437,7 +1437,7 @@ static void intel_gt_reset_global(struct intel_gt *gt, intel_gt_reset(gt, engine_mask, reason); if (reset_display) - intel_display_reset_finish(display); + intel_display_reset_finish(display, !need_display_reset); } if (!test_bit(I915_WEDGED, >->reset.flags)) From 916f2740b82a1b58dce2bbd51c9130ae77a56e25 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Mar 2025 13:27:10 +0200 Subject: [PATCH 52/92] drm/i915/reset: add modeset_stuck callback to intel_display_reset_prepare() Drop the dependency on gt by providing a callback for trying to unbreak stuck modeset. Do intel_gt_set_wedged() via the callback. It's by no means pretty, but this is perhaps the most straightforward alternative. Cc: Matt Roper Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/d322e20927326afa47c0df8a4d4776ee77010e6d.1741001054.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_reset.c | 6 +++--- drivers/gpu/drm/i915/display/intel_display_reset.h | 5 ++++- drivers/gpu/drm/i915/gt/intel_reset.c | 9 ++++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.c b/drivers/gpu/drm/i915/display/intel_display_reset.c index d5ce0ac43377..1f2798404f2c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.c +++ b/drivers/gpu/drm/i915/display/intel_display_reset.c @@ -20,9 +20,9 @@ bool intel_display_reset_test(struct intel_display *display) } /* returns true if intel_display_reset_finish() needs to be called */ -bool intel_display_reset_prepare(struct intel_display *display) +bool intel_display_reset_prepare(struct intel_display *display, + modeset_stuck_fn modeset_stuck, void *context) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct drm_modeset_acquire_ctx *ctx = &display->restore.reset_ctx; struct drm_atomic_state *state; int ret; @@ -33,7 +33,7 @@ bool intel_display_reset_prepare(struct intel_display *display) if (atomic_read(&display->restore.pending_fb_pin)) { drm_dbg_kms(display->drm, "Modeset potentially stuck, unbreaking through wedging\n"); - intel_gt_set_wedged(to_gt(dev_priv)); + modeset_stuck(context); } /* diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.h b/drivers/gpu/drm/i915/display/intel_display_reset.h index f518147199a1..8b3bda134454 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.h +++ b/drivers/gpu/drm/i915/display/intel_display_reset.h @@ -10,8 +10,11 @@ struct intel_display; +typedef void modeset_stuck_fn(void *context); + bool intel_display_reset_test(struct intel_display *display); -bool intel_display_reset_prepare(struct intel_display *display); +bool intel_display_reset_prepare(struct intel_display *display, + modeset_stuck_fn modeset_stuck, void *context); void intel_display_reset_finish(struct intel_display *display, bool test_only); #endif /* __INTEL_RESET_H__ */ diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index 9a92afcd9b0b..3ee544e7c203 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -1403,6 +1403,11 @@ int intel_engine_reset(struct intel_engine_cs *engine, const char *msg) return err; } +static void display_reset_modeset_stuck(void *gt) +{ + intel_gt_set_wedged(gt); +} + static void intel_gt_reset_global(struct intel_gt *gt, u32 engine_mask, const char *reason) @@ -1432,7 +1437,9 @@ static void intel_gt_reset_global(struct intel_gt *gt, need_display_reset; if (reset_display) - reset_display = intel_display_reset_prepare(display); + reset_display = intel_display_reset_prepare(display, + display_reset_modeset_stuck, + gt); intel_gt_reset(gt, engine_mask, reason); From 1bdad3f21671d28b68fd52b5115ff905c26dc4a8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Mar 2025 12:27:30 +0200 Subject: [PATCH 53/92] drm/i915/display: convert various port/phy helpers to struct intel_display Going forward, struct intel_display is the main display device data pointer. The intel_display.[ch] files are too big to convert in one go. Convert the various port/phy helpers to struct intel_display. Reviewed-by: Nemesa Garg Link: https://patchwork.freedesktop.org/patch/msgid/e28e53bad5014ba3ef17431557b517f1b8530963.1741084010.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_bios.c | 5 +-- drivers/gpu/drm/i915/display/intel_ddi.c | 6 +-- drivers/gpu/drm/i915/display/intel_display.c | 40 +++++++++---------- drivers/gpu/drm/i915/display/intel_display.h | 7 ++-- .../i915/display/intel_display_power_well.c | 9 ++--- 5 files changed, 31 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index e0e4e9b62d8d..a8d08d7d82b3 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -2902,7 +2902,6 @@ init_vbt_panel_defaults(struct intel_panel *panel) static void init_vbt_missing_defaults(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); unsigned int ports = DISPLAY_RUNTIME_INFO(display)->port_mask; enum port port; @@ -2912,13 +2911,13 @@ init_vbt_missing_defaults(struct intel_display *display) for_each_port_masked(port, ports) { struct intel_bios_encoder_data *devdata; struct child_device_config *child; - enum phy phy = intel_port_to_phy(i915, port); + enum phy phy = intel_port_to_phy(display, port); /* * VBT has the TypeC mode (native,TBT/USB) and we don't want * to detect it. */ - if (intel_phy_is_tc(i915, phy)) + if (intel_phy_is_tc(display, phy)) continue; /* Create fake child device config */ diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 20fc258a4d6d..3b7ec0be9011 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -5100,7 +5100,7 @@ void intel_ddi_init(struct intel_display *display, return; } - phy = intel_port_to_phy(dev_priv, port); + phy = intel_port_to_phy(display, port); /* * On platforms with HTI (aka HDPORT), if it's enabled at boot it may @@ -5160,7 +5160,7 @@ void intel_ddi_init(struct intel_display *display, port_name(port - PORT_D_XELPD + PORT_D), phy_name(phy)); } else if (DISPLAY_VER(dev_priv) >= 12) { - enum tc_port tc_port = intel_port_to_tc(dev_priv, port); + enum tc_port tc_port = intel_port_to_tc(display, port); drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, @@ -5170,7 +5170,7 @@ void intel_ddi_init(struct intel_display *display, tc_port != TC_PORT_NONE ? "TC" : "", tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); } else if (DISPLAY_VER(dev_priv) >= 11) { - enum tc_port tc_port = intel_port_to_tc(dev_priv, port); + enum tc_port tc_port = intel_port_to_tc(display, port); drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index c4b0ec60fded..9d4f2dacbbce 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1834,20 +1834,20 @@ bool intel_phy_is_combo(struct intel_display *display, enum phy phy) } /* Prefer intel_encoder_is_tc() */ -bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy) +bool intel_phy_is_tc(struct intel_display *display, enum phy phy) { /* * Discrete GPU phy's are not attached to FIA's to support TC * subsystem Legacy or non-legacy, and only support native DP/HDMI */ - if (IS_DGFX(dev_priv)) + if (display->platform.dgfx) return false; - if (DISPLAY_VER(dev_priv) >= 13) + if (DISPLAY_VER(display) >= 13) return phy >= PHY_F && phy <= PHY_I; - else if (IS_TIGERLAKE(dev_priv)) + else if (display->platform.tigerlake) return phy >= PHY_D && phy <= PHY_I; - else if (IS_ICELAKE(dev_priv)) + else if (display->platform.icelake) return phy >= PHY_C && phy <= PHY_F; return false; @@ -1864,17 +1864,17 @@ bool intel_phy_is_snps(struct intel_display *display, enum phy phy) } /* Prefer intel_encoder_to_phy() */ -enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port) +enum phy intel_port_to_phy(struct intel_display *display, enum port port) { - if (DISPLAY_VER(i915) >= 13 && port >= PORT_D_XELPD) + if (DISPLAY_VER(display) >= 13 && port >= PORT_D_XELPD) return PHY_D + port - PORT_D_XELPD; - else if (DISPLAY_VER(i915) >= 13 && port >= PORT_TC1) + else if (DISPLAY_VER(display) >= 13 && port >= PORT_TC1) return PHY_F + port - PORT_TC1; - else if (IS_ALDERLAKE_S(i915) && port >= PORT_TC1) + else if (display->platform.alderlake_s && port >= PORT_TC1) return PHY_B + port - PORT_TC1; - else if ((IS_DG1(i915) || IS_ROCKETLAKE(i915)) && port >= PORT_TC1) + else if ((display->platform.dg1 || display->platform.rocketlake) && port >= PORT_TC1) return PHY_C + port - PORT_TC1; - else if ((IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) && + else if ((display->platform.jasperlake || display->platform.elkhartlake) && port == PORT_D) return PHY_A; @@ -1882,12 +1882,12 @@ enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port) } /* Prefer intel_encoder_to_tc() */ -enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv, enum port port) +enum tc_port intel_port_to_tc(struct intel_display *display, enum port port) { - if (!intel_phy_is_tc(dev_priv, intel_port_to_phy(dev_priv, port))) + if (!intel_phy_is_tc(display, intel_port_to_phy(display, port))) return TC_PORT_NONE; - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) return TC_PORT_1 + port - PORT_TC1; else return TC_PORT_1 + port - PORT_C; @@ -1895,9 +1895,9 @@ enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv, enum port port) enum phy intel_encoder_to_phy(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - return intel_port_to_phy(i915, encoder->port); + return intel_port_to_phy(display, encoder->port); } bool intel_encoder_is_combo(struct intel_encoder *encoder) @@ -1916,16 +1916,16 @@ bool intel_encoder_is_snps(struct intel_encoder *encoder) bool intel_encoder_is_tc(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - return intel_phy_is_tc(i915, intel_encoder_to_phy(encoder)); + return intel_phy_is_tc(display, intel_encoder_to_phy(encoder)); } enum tc_port intel_encoder_to_tc(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - return intel_port_to_tc(i915, encoder->port); + return intel_port_to_tc(display, encoder->port); } enum intel_display_power_domain diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index bc9a5a14ca6a..45d70d3e1041 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -426,7 +426,7 @@ intel_mode_valid_max_plane_size(struct intel_display *display, enum drm_mode_status intel_cpu_transcoder_mode_valid(struct intel_display *display, const struct drm_display_mode *mode); -enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port); +enum phy intel_port_to_phy(struct intel_display *display, enum port port); bool is_trans_port_sync_mode(const struct intel_crtc_state *state); bool is_trans_port_sync_master(const struct intel_crtc_state *state); u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state); @@ -465,10 +465,9 @@ intel_encoder_current_mode(struct intel_encoder *encoder); void intel_encoder_get_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state); bool intel_phy_is_combo(struct intel_display *display, enum phy phy); -bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy); +bool intel_phy_is_tc(struct intel_display *display, enum phy phy); bool intel_phy_is_snps(struct intel_display *display, enum phy phy); -enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv, - enum port port); +enum tc_port intel_port_to_tc(struct intel_display *display, enum port port); enum phy intel_encoder_to_phy(struct intel_encoder *encoder); bool intel_encoder_is_combo(struct intel_encoder *encoder); diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index 5b60db597329..8ec87ffd87d2 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -549,10 +549,9 @@ static void icl_aux_power_well_enable(struct intel_display *display, struct i915_power_well *power_well) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum phy phy = icl_aux_pw_to_phy(display, power_well); - if (intel_phy_is_tc(dev_priv, phy)) + if (intel_phy_is_tc(display, phy)) return icl_tc_phy_aux_power_well_enable(display, power_well); else if (display->platform.icelake) return icl_combo_phy_aux_power_well_enable(display, @@ -565,10 +564,9 @@ static void icl_aux_power_well_disable(struct intel_display *display, struct i915_power_well *power_well) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum phy phy = icl_aux_pw_to_phy(display, power_well); - if (intel_phy_is_tc(dev_priv, phy)) + if (intel_phy_is_tc(display, phy)) return hsw_power_well_disable(display, power_well); else if (display->platform.icelake) return icl_combo_phy_aux_power_well_disable(display, @@ -1829,11 +1827,10 @@ tgl_tc_cold_off_power_well_is_enabled(struct intel_display *display, static void xelpdp_aux_power_well_enable(struct intel_display *display, struct i915_power_well *power_well) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch; enum phy phy = icl_aux_pw_to_phy(display, power_well); - if (intel_phy_is_tc(dev_priv, phy)) + if (intel_phy_is_tc(display, phy)) icl_tc_port_assert_ref_held(display, power_well, aux_ch_to_digital_port(display, aux_ch)); From 7c4a393f974c26da8803618ca2c94fdccf5c7de7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Mar 2025 12:27:31 +0200 Subject: [PATCH 54/92] drm/i915/display: convert some intel_display.[ch] functions to struct intel_display Going forward, struct intel_display is the main display device data pointer. The intel_display.[ch] files are too big to convert in one go. Convert the interface towards intel_display_driver.c to struct intel_display. Reviewed-by: Nemesa Garg Link: https://patchwork.freedesktop.org/patch/msgid/ee8b108420763cbf47ee77fa35b782a7293f9cfe.1741084010.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 161 +++++++++--------- drivers/gpu/drm/i915/display/intel_display.h | 11 +- .../drm/i915/display/intel_display_driver.c | 10 +- 3 files changed, 94 insertions(+), 88 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9d4f2dacbbce..debf9826fd2f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -182,16 +182,17 @@ int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv, return hpll; } -void intel_update_czclk(struct drm_i915_private *dev_priv) +void intel_update_czclk(struct intel_display *display) { - if (!(IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))) + struct drm_i915_private *dev_priv = to_i915(display->drm); + + if (!display->platform.valleyview && !display->platform.cherryview) return; dev_priv->czclk_freq = vlv_get_cck_clock_hpll(dev_priv, "czclk", CCK_CZ_CLOCK_CONTROL); - drm_dbg(&dev_priv->drm, "CZ clock rate: %d kHz\n", - dev_priv->czclk_freq); + drm_dbg_kms(display->drm, "CZ clock rate: %d kHz\n", dev_priv->czclk_freq); } static bool is_hdr_mode(const struct intel_crtc_state *crtc_state) @@ -2547,8 +2548,10 @@ intel_link_compute_m_n(u16 bits_per_pixel_x16, int nlanes, 0x80000); } -void intel_panel_sanitize_ssc(struct drm_i915_private *dev_priv) +void intel_panel_sanitize_ssc(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + /* * There may be no VBT; and if the BIOS enabled SSC we can * just keep using it to avoid unnecessary flicker. Whereas if the @@ -2556,16 +2559,16 @@ void intel_panel_sanitize_ssc(struct drm_i915_private *dev_priv) * indicates as much. */ if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) { - bool bios_lvds_use_ssc = intel_de_read(dev_priv, + bool bios_lvds_use_ssc = intel_de_read(display, PCH_DREF_CONTROL) & DREF_SSC1_ENABLE; - if (dev_priv->display.vbt.lvds_use_ssc != bios_lvds_use_ssc) { - drm_dbg_kms(&dev_priv->drm, + if (display->vbt.lvds_use_ssc != bios_lvds_use_ssc) { + drm_dbg_kms(display->drm, "SSC %s by BIOS, overriding VBT which says %s\n", str_enabled_disabled(bios_lvds_use_ssc), - str_enabled_disabled(dev_priv->display.vbt.lvds_use_ssc)); - dev_priv->display.vbt.lvds_use_ssc = bios_lvds_use_ssc; + str_enabled_disabled(display->vbt.lvds_use_ssc)); + display->vbt.lvds_use_ssc = bios_lvds_use_ssc; } } } @@ -7635,37 +7638,39 @@ static u32 intel_encoder_possible_crtcs(struct intel_encoder *encoder) return possible_crtcs; } -static bool ilk_has_edp_a(struct drm_i915_private *dev_priv) +static bool ilk_has_edp_a(struct intel_display *display) { - if (!IS_MOBILE(dev_priv)) + if (!display->platform.mobile) return false; - if ((intel_de_read(dev_priv, DP_A) & DP_DETECTED) == 0) + if ((intel_de_read(display, DP_A) & DP_DETECTED) == 0) return false; - if (IS_IRONLAKE(dev_priv) && (intel_de_read(dev_priv, FUSE_STRAP) & ILK_eDP_A_DISABLE)) + if (display->platform.ironlake && (intel_de_read(display, FUSE_STRAP) & ILK_eDP_A_DISABLE)) return false; return true; } -static bool intel_ddi_crt_present(struct drm_i915_private *dev_priv) +static bool intel_ddi_crt_present(struct intel_display *display) { - if (DISPLAY_VER(dev_priv) >= 9) + struct drm_i915_private *dev_priv = to_i915(display->drm); + + if (DISPLAY_VER(display) >= 9) return false; - if (IS_HASWELL_ULT(dev_priv) || IS_BROADWELL_ULT(dev_priv)) + if (display->platform.haswell_ult || display->platform.broadwell_ult) return false; if (HAS_PCH_LPT_H(dev_priv) && - intel_de_read(dev_priv, SFUSE_STRAP) & SFUSE_STRAP_CRT_DISABLED) + intel_de_read(display, SFUSE_STRAP) & SFUSE_STRAP_CRT_DISABLED) return false; /* DDI E can't be used if DDI A requires 4 lanes */ - if (intel_de_read(dev_priv, DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) + if (intel_de_read(display, DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) return false; - if (!dev_priv->display.vbt.int_crt_support) + if (!display->vbt.int_crt_support) return false; return true; @@ -7677,24 +7682,24 @@ bool assert_port_valid(struct intel_display *display, enum port port) "Platform does not support port %c\n", port_name(port)); } -void intel_setup_outputs(struct drm_i915_private *dev_priv) +void intel_setup_outputs(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder; bool dpd_is_edp = false; intel_pps_unlock_regs_wa(display); - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; - if (HAS_DDI(dev_priv)) { - if (intel_ddi_crt_present(dev_priv)) + if (HAS_DDI(display)) { + if (intel_ddi_crt_present(display)) intel_crt_init(display); intel_bios_for_each_encoder(display, intel_ddi_init); - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) vlv_dsi_init(dev_priv); } else if (HAS_PCH_SPLIT(dev_priv)) { int found; @@ -7709,33 +7714,33 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) dpd_is_edp = intel_dp_is_port_edp(display, PORT_D); - if (ilk_has_edp_a(dev_priv)) + if (ilk_has_edp_a(display)) g4x_dp_init(display, DP_A, PORT_A); - if (intel_de_read(dev_priv, PCH_HDMIB) & SDVO_DETECTED) { + if (intel_de_read(display, PCH_HDMIB) & SDVO_DETECTED) { /* PCH SDVOB multiplex with HDMIB */ found = intel_sdvo_init(display, PCH_SDVOB, PORT_B); if (!found) g4x_hdmi_init(display, PCH_HDMIB, PORT_B); - if (!found && (intel_de_read(dev_priv, PCH_DP_B) & DP_DETECTED)) + if (!found && (intel_de_read(display, PCH_DP_B) & DP_DETECTED)) g4x_dp_init(display, PCH_DP_B, PORT_B); } - if (intel_de_read(dev_priv, PCH_HDMIC) & SDVO_DETECTED) + if (intel_de_read(display, PCH_HDMIC) & SDVO_DETECTED) g4x_hdmi_init(display, PCH_HDMIC, PORT_C); - if (!dpd_is_edp && intel_de_read(dev_priv, PCH_HDMID) & SDVO_DETECTED) + if (!dpd_is_edp && intel_de_read(display, PCH_HDMID) & SDVO_DETECTED) g4x_hdmi_init(display, PCH_HDMID, PORT_D); - if (intel_de_read(dev_priv, PCH_DP_C) & DP_DETECTED) + if (intel_de_read(display, PCH_DP_C) & DP_DETECTED) g4x_dp_init(display, PCH_DP_C, PORT_C); - if (intel_de_read(dev_priv, PCH_DP_D) & DP_DETECTED) + if (intel_de_read(display, PCH_DP_D) & DP_DETECTED) g4x_dp_init(display, PCH_DP_D, PORT_D); - } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + } else if (display->platform.valleyview || display->platform.cherryview) { bool has_edp, has_port; - if (IS_VALLEYVIEW(dev_priv) && dev_priv->display.vbt.int_crt_support) + if (display->platform.valleyview && display->vbt.int_crt_support) intel_crt_init(display); /* @@ -7755,87 +7760,87 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) */ has_edp = intel_dp_is_port_edp(display, PORT_B); has_port = intel_bios_is_port_present(display, PORT_B); - if (intel_de_read(dev_priv, VLV_DP_B) & DP_DETECTED || has_port) + if (intel_de_read(display, VLV_DP_B) & DP_DETECTED || has_port) has_edp &= g4x_dp_init(display, VLV_DP_B, PORT_B); - if ((intel_de_read(dev_priv, VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp) + if ((intel_de_read(display, VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp) g4x_hdmi_init(display, VLV_HDMIB, PORT_B); has_edp = intel_dp_is_port_edp(display, PORT_C); has_port = intel_bios_is_port_present(display, PORT_C); - if (intel_de_read(dev_priv, VLV_DP_C) & DP_DETECTED || has_port) + if (intel_de_read(display, VLV_DP_C) & DP_DETECTED || has_port) has_edp &= g4x_dp_init(display, VLV_DP_C, PORT_C); - if ((intel_de_read(dev_priv, VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp) + if ((intel_de_read(display, VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp) g4x_hdmi_init(display, VLV_HDMIC, PORT_C); - if (IS_CHERRYVIEW(dev_priv)) { + if (display->platform.cherryview) { /* * eDP not supported on port D, * so no need to worry about it */ has_port = intel_bios_is_port_present(display, PORT_D); - if (intel_de_read(dev_priv, CHV_DP_D) & DP_DETECTED || has_port) + if (intel_de_read(display, CHV_DP_D) & DP_DETECTED || has_port) g4x_dp_init(display, CHV_DP_D, PORT_D); - if (intel_de_read(dev_priv, CHV_HDMID) & SDVO_DETECTED || has_port) + if (intel_de_read(display, CHV_HDMID) & SDVO_DETECTED || has_port) g4x_hdmi_init(display, CHV_HDMID, PORT_D); } vlv_dsi_init(dev_priv); - } else if (IS_PINEVIEW(dev_priv)) { + } else if (display->platform.pineview) { intel_lvds_init(dev_priv); intel_crt_init(display); - } else if (IS_DISPLAY_VER(dev_priv, 3, 4)) { + } else if (IS_DISPLAY_VER(display, 3, 4)) { bool found = false; - if (IS_MOBILE(dev_priv)) + if (display->platform.mobile) intel_lvds_init(dev_priv); intel_crt_init(display); - if (intel_de_read(dev_priv, GEN3_SDVOB) & SDVO_DETECTED) { - drm_dbg_kms(&dev_priv->drm, "probing SDVOB\n"); + if (intel_de_read(display, GEN3_SDVOB) & SDVO_DETECTED) { + drm_dbg_kms(display->drm, "probing SDVOB\n"); found = intel_sdvo_init(display, GEN3_SDVOB, PORT_B); - if (!found && IS_G4X(dev_priv)) { - drm_dbg_kms(&dev_priv->drm, + if (!found && display->platform.g4x) { + drm_dbg_kms(display->drm, "probing HDMI on SDVOB\n"); g4x_hdmi_init(display, GEN4_HDMIB, PORT_B); } - if (!found && IS_G4X(dev_priv)) + if (!found && display->platform.g4x) g4x_dp_init(display, DP_B, PORT_B); } /* Before G4X SDVOC doesn't have its own detect register */ - if (intel_de_read(dev_priv, GEN3_SDVOB) & SDVO_DETECTED) { - drm_dbg_kms(&dev_priv->drm, "probing SDVOC\n"); + if (intel_de_read(display, GEN3_SDVOB) & SDVO_DETECTED) { + drm_dbg_kms(display->drm, "probing SDVOC\n"); found = intel_sdvo_init(display, GEN3_SDVOC, PORT_C); } - if (!found && (intel_de_read(dev_priv, GEN3_SDVOC) & SDVO_DETECTED)) { + if (!found && (intel_de_read(display, GEN3_SDVOC) & SDVO_DETECTED)) { - if (IS_G4X(dev_priv)) { - drm_dbg_kms(&dev_priv->drm, + if (display->platform.g4x) { + drm_dbg_kms(display->drm, "probing HDMI on SDVOC\n"); g4x_hdmi_init(display, GEN4_HDMIC, PORT_C); } - if (IS_G4X(dev_priv)) + if (display->platform.g4x) g4x_dp_init(display, DP_C, PORT_C); } - if (IS_G4X(dev_priv) && (intel_de_read(dev_priv, DP_D) & DP_DETECTED)) + if (display->platform.g4x && (intel_de_read(display, DP_D) & DP_DETECTED)) g4x_dp_init(display, DP_D, PORT_D); - if (SUPPORTS_TV(dev_priv)) + if (SUPPORTS_TV(display)) intel_tv_init(display); - } else if (DISPLAY_VER(dev_priv) == 2) { - if (IS_I85X(dev_priv)) + } else if (DISPLAY_VER(display) == 2) { + if (display->platform.i85x) intel_lvds_init(dev_priv); intel_crt_init(display); intel_dvo_init(dev_priv); } - for_each_intel_encoder(&dev_priv->drm, encoder) { + for_each_intel_encoder(display->drm, encoder) { encoder->base.possible_crtcs = intel_encoder_possible_crtcs(encoder); encoder->base.possible_clones = @@ -7844,7 +7849,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv) intel_init_pch_refclk(dev_priv); - drm_helper_move_panel_connectors_to_head(&dev_priv->drm); + drm_helper_move_panel_connectors_to_head(display->drm); } static int max_dotclock(struct drm_i915_private *i915) @@ -8061,32 +8066,34 @@ static const struct intel_display_funcs i9xx_display_funcs = { /** * intel_init_display_hooks - initialize the display modesetting hooks - * @dev_priv: device private + * @display: display device private */ -void intel_init_display_hooks(struct drm_i915_private *dev_priv) +void intel_init_display_hooks(struct intel_display *display) { - if (DISPLAY_VER(dev_priv) >= 9) { - dev_priv->display.funcs.display = &skl_display_funcs; - } else if (HAS_DDI(dev_priv)) { - dev_priv->display.funcs.display = &ddi_display_funcs; + struct drm_i915_private *dev_priv = to_i915(display->drm); + + if (DISPLAY_VER(display) >= 9) { + display->funcs.display = &skl_display_funcs; + } else if (HAS_DDI(display)) { + display->funcs.display = &ddi_display_funcs; } else if (HAS_PCH_SPLIT(dev_priv)) { - dev_priv->display.funcs.display = &pch_split_display_funcs; - } else if (IS_CHERRYVIEW(dev_priv) || - IS_VALLEYVIEW(dev_priv)) { - dev_priv->display.funcs.display = &vlv_display_funcs; + display->funcs.display = &pch_split_display_funcs; + } else if (display->platform.cherryview || + display->platform.valleyview) { + display->funcs.display = &vlv_display_funcs; } else { - dev_priv->display.funcs.display = &i9xx_display_funcs; + display->funcs.display = &i9xx_display_funcs; } } -int intel_initial_commit(struct drm_device *dev) +int intel_initial_commit(struct intel_display *display) { struct drm_atomic_state *state = NULL; struct drm_modeset_acquire_ctx ctx; struct intel_crtc *crtc; int ret = 0; - state = drm_atomic_state_alloc(dev); + state = drm_atomic_state_alloc(display->drm); if (!state) return -ENOMEM; @@ -8096,7 +8103,7 @@ int intel_initial_commit(struct drm_device *dev) to_intel_atomic_state(state)->internal = true; retry: - for_each_intel_crtc(dev, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = intel_atomic_get_crtc_state(state, crtc); @@ -8120,7 +8127,7 @@ int intel_initial_commit(struct drm_device *dev) */ crtc_state->uapi.color_mgmt_changed = true; - for_each_intel_encoder_mask(dev, encoder, + for_each_intel_encoder_mask(display->drm, encoder, crtc_state->uapi.encoder_mask) { if (encoder->initial_fastset_check && !encoder->initial_fastset_check(encoder, crtc_state)) { diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 45d70d3e1041..83a820b72a6e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -457,7 +457,6 @@ int vlv_get_cck_clock(struct drm_i915_private *dev_priv, const char *name, u32 reg, int ref_freq); int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv, const char *name, u32 reg); -void intel_init_display_hooks(struct drm_i915_private *dev_priv); bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv); void intel_encoder_destroy(struct drm_encoder *encoder); struct drm_display_mode * @@ -541,11 +540,11 @@ void intel_modeset_put_crtc_power_domains(struct intel_crtc *crtc, struct intel_power_domain_mask *domains); /* interface for intel_display_driver.c */ -void intel_setup_outputs(struct drm_i915_private *i915); -int intel_initial_commit(struct drm_device *dev); -void intel_panel_sanitize_ssc(struct drm_i915_private *i915); -void intel_update_czclk(struct drm_i915_private *i915); -void intel_atomic_helper_free_state_worker(struct work_struct *work); +void intel_init_display_hooks(struct intel_display *display); +void intel_setup_outputs(struct intel_display *display); +int intel_initial_commit(struct intel_display *display); +void intel_panel_sanitize_ssc(struct intel_display *display); +void intel_update_czclk(struct intel_display *display); enum drm_mode_status intel_mode_valid(struct drm_device *dev, const struct drm_display_mode *mode); int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 68d0753659e8..31740a677dd8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -199,7 +199,7 @@ void intel_display_driver_early_probe(struct intel_display *display) intel_init_cdclk_hooks(display); intel_audio_hooks_init(display); intel_dpll_init_clock_hook(i915); - intel_init_display_hooks(i915); + intel_init_display_hooks(display); intel_fdi_init_hook(display); intel_dmc_wl_init(display); } @@ -431,7 +431,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display) intel_wm_init(i915); - intel_panel_sanitize_ssc(i915); + intel_panel_sanitize_ssc(display); intel_pps_setup(display); @@ -451,7 +451,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display) intel_shared_dpll_init(display); intel_fdi_pll_freq_update(display); - intel_update_czclk(i915); + intel_update_czclk(display); intel_display_driver_init_hw(display); intel_dpll_update_ref_clks(display); @@ -462,7 +462,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display) /* Just disable it once at startup */ intel_vga_disable(display); - intel_setup_outputs(i915); + intel_setup_outputs(display); ret = intel_dp_tunnel_mgr_init(display); if (ret) @@ -517,7 +517,7 @@ int intel_display_driver_probe(struct intel_display *display) * are already calculated and there is no assert_plane warnings * during bootup. */ - ret = intel_initial_commit(display->drm); + ret = intel_initial_commit(display); if (ret) drm_dbg_kms(display->drm, "Initial modeset failed, %d\n", ret); From 7e43a00be19a152cea7dca4ae7078cad999230cc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Mar 2025 12:27:32 +0200 Subject: [PATCH 55/92] drm/i915/display: convert intel_has_pending_fb_unpin() to struct intel_display Going forward, struct intel_display is the main display device data pointer. The intel_display.[ch] files are too big to convert in one go. Convert intel_has_pending_fb_unpin() to struct intel_display. Reviewed-by: Nemesa Garg Link: https://patchwork.freedesktop.org/patch/msgid/d70ad8f9cbba5ee32d985b76047b56996ad4b31e.1741084010.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_ddi.c | 3 ++- drivers/gpu/drm/i915/display/intel_display.c | 10 +++++----- drivers/gpu/drm/i915/display/intel_display.h | 4 ++-- drivers/gpu/drm/i915/display/intel_dp.c | 3 +-- drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c | 3 ++- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 3b7ec0be9011..676c1826f15c 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4660,6 +4660,7 @@ static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) static int intel_hdmi_reset_link(struct intel_encoder *encoder, struct drm_modeset_acquire_ctx *ctx) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder); struct intel_connector *connector = hdmi->attached_connector; @@ -4726,7 +4727,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, * would be perfectly happy if were to just reconfigure * the SCDC settings on the fly. */ - return intel_modeset_commit_pipes(dev_priv, BIT(crtc->pipe), ctx); + return intel_modeset_commit_pipes(display, BIT(crtc->pipe), ctx); } static void intel_ddi_link_check(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index debf9826fd2f..6962bc0da53c 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -764,12 +764,12 @@ static void icl_set_pipe_chicken(const struct intel_crtc_state *crtc_state) intel_de_write(dev_priv, PIPE_CHICKEN(pipe), tmp); } -bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv) +bool intel_has_pending_fb_unpin(struct intel_display *display) { struct drm_crtc *crtc; bool cleanup_done; - drm_for_each_crtc(crtc, &dev_priv->drm) { + drm_for_each_crtc(crtc, display->drm) { struct drm_crtc_commit *commit; spin_lock(&crtc->commit_lock); commit = list_first_entry_or_null(&crtc->commit_list, @@ -5574,7 +5574,7 @@ int intel_modeset_all_pipes_late(struct intel_atomic_state *state, return 0; } -int intel_modeset_commit_pipes(struct drm_i915_private *i915, +int intel_modeset_commit_pipes(struct intel_display *display, u8 pipe_mask, struct drm_modeset_acquire_ctx *ctx) { @@ -5582,14 +5582,14 @@ int intel_modeset_commit_pipes(struct drm_i915_private *i915, struct intel_crtc *crtc; int ret; - state = drm_atomic_state_alloc(&i915->drm); + state = drm_atomic_state_alloc(display->drm); if (!state) return -ENOMEM; state->acquire_ctx = ctx; to_intel_atomic_state(state)->internal = true; - for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) { + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) { struct intel_crtc_state *crtc_state = intel_atomic_get_crtc_state(state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 83a820b72a6e..65245ef04347 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -457,7 +457,7 @@ int vlv_get_cck_clock(struct drm_i915_private *dev_priv, const char *name, u32 reg, int ref_freq); int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv, const char *name, u32 reg); -bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv); +bool intel_has_pending_fb_unpin(struct intel_display *display); void intel_encoder_destroy(struct drm_encoder *encoder); struct drm_display_mode * intel_encoder_current_mode(struct intel_encoder *encoder); @@ -531,7 +531,7 @@ int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state, const char *reason, u8 pipe_mask); int intel_modeset_all_pipes_late(struct intel_atomic_state *state, const char *reason); -int intel_modeset_commit_pipes(struct drm_i915_private *i915, +int intel_modeset_commit_pipes(struct intel_display *display, u8 pipe_mask, struct drm_modeset_acquire_ctx *ctx); void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 205ec315b413..a236b5fc7a3d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5193,7 +5193,6 @@ static int intel_dp_retrain_link(struct intel_encoder *encoder, struct drm_modeset_acquire_ctx *ctx) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); u8 pipe_mask; int ret; @@ -5224,7 +5223,7 @@ static int intel_dp_retrain_link(struct intel_encoder *encoder, encoder->base.base.id, encoder->base.name, str_yes_no(intel_dp->link.force_retrain)); - ret = intel_modeset_commit_pipes(dev_priv, pipe_mask, ctx); + ret = intel_modeset_commit_pipes(display, pipe_mask, ctx); if (ret == -EDEADLK) return ret; diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c index 0ffba50981e3..f6b780f893f5 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c @@ -328,6 +328,7 @@ static bool fence_is_active(const struct i915_fence_reg *fence) static struct i915_fence_reg *fence_find(struct i915_ggtt *ggtt) { + struct intel_display *display = &ggtt->vm.i915->display; struct i915_fence_reg *active = NULL; struct i915_fence_reg *fence, *fn; @@ -353,7 +354,7 @@ static struct i915_fence_reg *fence_find(struct i915_ggtt *ggtt) } /* Wait for completion of pending flips which consume fences */ - if (intel_has_pending_fb_unpin(ggtt->vm.i915)) + if (intel_has_pending_fb_unpin(display)) return ERR_PTR(-EAGAIN); return ERR_PTR(-ENOBUFS); From 055e8af4c9a432f28132f6b42818a56e5b94cf12 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Mar 2025 12:27:33 +0200 Subject: [PATCH 56/92] drm/i915/display: remove dupe intel_update_watermarks() declaration intel_wm.h already has intel_update_watermarks() declaration. Remove the dupe. Reviewed-by: Nemesa Garg Link: https://patchwork.freedesktop.org/patch/msgid/67eeebff3ec9459f7854fbc56cfd7f2aa8c1fdc6.1741084010.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 65245ef04347..3b54a62c290a 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -521,8 +521,6 @@ void intel_set_plane_visible(struct intel_crtc_state *crtc_state, bool visible); void intel_plane_fixup_bitmasks(struct intel_crtc_state *crtc_state); -void intel_update_watermarks(struct drm_i915_private *i915); - bool intel_crtc_vrr_disabling(struct intel_atomic_state *state, struct intel_crtc *crtc); From 6069b21f58dc96e5d57c9c2fd64240135952a545 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Mar 2025 12:27:34 +0200 Subject: [PATCH 57/92] drm/i915/display: convert intel_display.c to struct intel_display Going forward, struct intel_display is the main display device data pointer. Convert as much as possible of intel_display.c to struct intel_display. This exposes a couple of outside issues that need to be fixed as well, in a register macro and a DSI PLL stub. Reviewed-by: Nemesa Garg Link: https://patchwork.freedesktop.org/patch/msgid/1c0bafcb978d1cf4f4d54be2f497386f5302f7c8.1741084010.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 834 +++++++++---------- drivers/gpu/drm/i915/display/vlv_dsi_pll.h | 6 +- drivers/gpu/drm/i915/i915_reg.h | 4 +- 3 files changed, 413 insertions(+), 431 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 6962bc0da53c..f7cb38145e9d 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -203,29 +203,29 @@ static bool is_hdr_mode(const struct intel_crtc_state *crtc_state) /* WA Display #0827: Gen9:all */ static void -skl_wa_827(struct drm_i915_private *dev_priv, enum pipe pipe, bool enable) +skl_wa_827(struct intel_display *display, enum pipe pipe, bool enable) { - intel_de_rmw(dev_priv, CLKGATE_DIS_PSL(pipe), + intel_de_rmw(display, CLKGATE_DIS_PSL(pipe), DUPS1_GATING_DIS | DUPS2_GATING_DIS, enable ? DUPS1_GATING_DIS | DUPS2_GATING_DIS : 0); } /* Wa_2006604312:icl,ehl */ static void -icl_wa_scalerclkgating(struct drm_i915_private *dev_priv, enum pipe pipe, +icl_wa_scalerclkgating(struct intel_display *display, enum pipe pipe, bool enable) { - intel_de_rmw(dev_priv, CLKGATE_DIS_PSL(pipe), + intel_de_rmw(display, CLKGATE_DIS_PSL(pipe), DPFR_GATING_DIS, enable ? DPFR_GATING_DIS : 0); } /* Wa_1604331009:icl,jsl,ehl */ static void -icl_wa_cursorclkgating(struct drm_i915_private *dev_priv, enum pipe pipe, +icl_wa_cursorclkgating(struct intel_display *display, enum pipe pipe, bool enable) { - intel_de_rmw(dev_priv, CLKGATE_DIS_PSL(pipe), + intel_de_rmw(display, CLKGATE_DIS_PSL(pipe), CURSOR_GATING_DIS, enable ? CURSOR_GATING_DIS : 0); } @@ -405,16 +405,16 @@ struct intel_crtc *intel_primary_crtc(const struct intel_crtc_state *crtc_state) static void intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state) { + struct intel_display *display = to_intel_display(old_crtc_state); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - if (DISPLAY_VER(dev_priv) >= 4) { + if (DISPLAY_VER(display) >= 4) { enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; /* Wait for the Pipe State to go off */ - if (intel_de_wait_for_clear(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), + if (intel_de_wait_for_clear(display, TRANSCONF(display, cpu_transcoder), TRANSCONF_STATE_ENABLE, 100)) - drm_WARN(&dev_priv->drm, 1, "pipe_off wait timed out\n"); + drm_WARN(display->drm, 1, "pipe_off wait timed out\n"); } else { intel_wait_for_pipe_scanline_stopped(crtc); } @@ -468,10 +468,10 @@ static void assert_plane(struct intel_plane *plane, bool state) static void assert_planes_disabled(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_plane *plane; - for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) + for_each_intel_plane_on_crtc(display->drm, crtc, plane) assert_plane_disabled(plane); } @@ -479,7 +479,6 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state) { struct intel_display *display = to_intel_display(new_crtc_state); struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder; enum pipe pipe = crtc->pipe; u32 val; @@ -493,7 +492,7 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state) * a plane. On ILK+ the pipe PLLs are integrated, so we don't * need the check. */ - if (HAS_GMCH(dev_priv)) { + if (HAS_GMCH(display)) { if (intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI)) assert_dsi_pll_enabled(display); else @@ -510,11 +509,11 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state) } /* Wa_22012358565:adl-p */ - if (DISPLAY_VER(dev_priv) == 13) + if (DISPLAY_VER(display) == 13) intel_de_rmw(display, PIPE_ARB_CTL(display, pipe), 0, PIPE_ARB_USE_PROG_SLOTS); - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { u32 clear = DP_DSC_INSERT_SF_AT_EOL_WA; u32 set = 0; @@ -528,7 +527,7 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state) val = intel_de_read(display, TRANSCONF(display, cpu_transcoder)); if (val & TRANSCONF_ENABLE) { /* we keep both pipes enabled on 830 */ - drm_WARN_ON(&dev_priv->drm, !IS_I830(dev_priv)); + drm_WARN_ON(display->drm, !display->platform.i830); return; } @@ -559,12 +558,11 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state) { struct intel_display *display = to_intel_display(old_crtc_state); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; enum pipe pipe = crtc->pipe; u32 val; - drm_dbg_kms(&dev_priv->drm, "disabling pipe %c\n", pipe_name(pipe)); + drm_dbg_kms(display->drm, "disabling pipe %c\n", pipe_name(pipe)); /* * Make sure planes won't keep trying to pump pixels to us, @@ -572,7 +570,7 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state) */ assert_planes_disabled(crtc); - val = intel_de_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder)); + val = intel_de_read(display, TRANSCONF(display, cpu_transcoder)); if ((val & TRANSCONF_ENABLE) == 0) return; @@ -584,17 +582,17 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state) val &= ~TRANSCONF_DOUBLE_WIDE; /* Don't disable pipe or pipe PLLs if needed */ - if (!IS_I830(dev_priv)) + if (!display->platform.i830) val &= ~TRANSCONF_ENABLE; /* Wa_1409098942:adlp+ */ - if (DISPLAY_VER(dev_priv) >= 13 && + if (DISPLAY_VER(display) >= 13 && old_crtc_state->dsc.compression_enable) val &= ~TRANSCONF_PIXEL_COUNT_SCALING_MASK; - intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val); + intel_de_write(display, TRANSCONF(display, cpu_transcoder), val); - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) intel_de_rmw(display, CHICKEN_TRANS(display, cpu_transcoder), FECSTALL_DIS_DPTSTREAM_DPTTG, 0); @@ -643,7 +641,7 @@ void intel_set_plane_visible(struct intel_crtc_state *crtc_state, void intel_plane_fixup_bitmasks(struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); struct drm_plane *plane; /* @@ -654,7 +652,7 @@ void intel_plane_fixup_bitmasks(struct intel_crtc_state *crtc_state) crtc_state->enabled_planes = 0; crtc_state->active_planes = 0; - drm_for_each_plane_mask(plane, &dev_priv->drm, + drm_for_each_plane_mask(plane, display->drm, crtc_state->uapi.plane_mask) { crtc_state->enabled_planes |= BIT(to_intel_plane(plane)->id); crtc_state->active_planes |= BIT(to_intel_plane(plane)->id); @@ -671,7 +669,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Disabling [PLANE:%d:%s] on [CRTC:%d:%s]\n", plane->base.base.id, plane->base.name, crtc->base.base.id, crtc->base.name); @@ -699,7 +697,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, * event which is after the vblank start event, so we need to have a * wait-for-vblank between disabling the plane and the pipe. */ - if (HAS_GMCH(dev_priv) && + if (HAS_GMCH(display) && intel_set_memory_cxsr(dev_priv, false)) intel_plane_initial_vblank_wait(crtc); @@ -707,7 +705,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, * Gen2 reports pipe underruns whenever all planes are disabled. * So disable underrun reporting before all the planes get disabled. */ - if (DISPLAY_VER(dev_priv) == 2 && !crtc_state->active_planes) + if (DISPLAY_VER(display) == 2 && !crtc_state->active_planes) intel_set_cpu_fifo_underrun_reporting(display, crtc->pipe, false); intel_plane_disable_arm(NULL, plane, crtc_state); @@ -727,12 +725,12 @@ intel_plane_fence_y_offset(const struct intel_plane_state *plane_state) static void icl_set_pipe_chicken(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; u32 tmp; - tmp = intel_de_read(dev_priv, PIPE_CHICKEN(pipe)); + tmp = intel_de_read(display, PIPE_CHICKEN(pipe)); /* * Display WA #1153: icl @@ -752,16 +750,16 @@ static void icl_set_pipe_chicken(const struct intel_crtc_state *crtc_state) * Underrun recovery must always be disabled on display 13+. * DG2 chicken bit meaning is inverted compared to other platforms. */ - if (IS_DG2(dev_priv)) + if (display->platform.dg2) tmp &= ~UNDERRUN_RECOVERY_ENABLE_DG2; - else if ((DISPLAY_VER(dev_priv) >= 13) && (DISPLAY_VER(dev_priv) < 30)) + else if ((DISPLAY_VER(display) >= 13) && (DISPLAY_VER(display) < 30)) tmp |= UNDERRUN_RECOVERY_DISABLE_ADLP; /* Wa_14010547955:dg2 */ - if (IS_DG2(dev_priv)) + if (display->platform.dg2) tmp |= DG2_RENDER_CCSTAG_4_3_EN; - intel_de_write(dev_priv, PIPE_CHICKEN(pipe), tmp); + intel_de_write(display, PIPE_CHICKEN(pipe), tmp); } bool intel_has_pending_fb_unpin(struct intel_display *display) @@ -833,13 +831,13 @@ static void intel_crtc_dpms_overlay_disable(struct intel_crtc *crtc) static bool needs_nv12_wa(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); if (!crtc_state->nv12_planes) return false; /* WA Display #0827: Gen9:all */ - if (DISPLAY_VER(dev_priv) == 9) + if (DISPLAY_VER(display) == 9) return true; return false; @@ -847,10 +845,10 @@ static bool needs_nv12_wa(const struct intel_crtc_state *crtc_state) static bool needs_scalerclk_wa(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); /* Wa_2006604312:icl,ehl */ - if (crtc_state->scaler_state.scaler_users > 0 && DISPLAY_VER(dev_priv) == 11) + if (crtc_state->scaler_state.scaler_users > 0 && DISPLAY_VER(display) == 11) return true; return false; @@ -858,31 +856,31 @@ static bool needs_scalerclk_wa(const struct intel_crtc_state *crtc_state) static bool needs_cursorclk_wa(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); /* Wa_1604331009:icl,jsl,ehl */ if (is_hdr_mode(crtc_state) && crtc_state->active_planes & BIT(PLANE_CURSOR) && - DISPLAY_VER(dev_priv) == 11) + DISPLAY_VER(display) == 11) return true; return false; } -static void intel_async_flip_vtd_wa(struct drm_i915_private *i915, +static void intel_async_flip_vtd_wa(struct intel_display *display, enum pipe pipe, bool enable) { - if (DISPLAY_VER(i915) == 9) { + if (DISPLAY_VER(display) == 9) { /* * "Plane N stretch max must be programmed to 11b (x1) * when Async flips are enabled on that plane." */ - intel_de_rmw(i915, CHICKEN_PIPESL_1(pipe), + intel_de_rmw(display, CHICKEN_PIPESL_1(pipe), SKL_PLANE1_STRETCH_MAX_MASK, enable ? SKL_PLANE1_STRETCH_MAX_X1 : SKL_PLANE1_STRETCH_MAX_X8); } else { /* Also needed on HSW/BDW albeit undocumented */ - intel_de_rmw(i915, CHICKEN_PIPESL_1(pipe), + intel_de_rmw(display, CHICKEN_PIPESL_1(pipe), HSW_PRI_STRETCH_MAX_MASK, enable ? HSW_PRI_STRETCH_MAX_X1 : HSW_PRI_STRETCH_MAX_X8); } @@ -890,10 +888,12 @@ static void intel_async_flip_vtd_wa(struct drm_i915_private *i915, static bool needs_async_flip_vtd_wa(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); return crtc_state->uapi.async_flip && i915_vtd_active(i915) && - (DISPLAY_VER(i915) == 9 || IS_BROADWELL(i915) || IS_HASWELL(i915)); + (DISPLAY_VER(display) == 9 || display->platform.broadwell || + display->platform.haswell); } static void intel_encoders_audio_enable(struct intel_atomic_state *state, @@ -1042,6 +1042,7 @@ static bool audio_disabling(const struct intel_crtc_state *old_crtc_state, static void intel_post_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); struct drm_i915_private *dev_priv = to_i915(state->base.dev); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); @@ -1060,19 +1061,19 @@ static void intel_post_plane_update(struct intel_atomic_state *state, if (needs_async_flip_vtd_wa(old_crtc_state) && !needs_async_flip_vtd_wa(new_crtc_state)) - intel_async_flip_vtd_wa(dev_priv, pipe, false); + intel_async_flip_vtd_wa(display, pipe, false); if (needs_nv12_wa(old_crtc_state) && !needs_nv12_wa(new_crtc_state)) - skl_wa_827(dev_priv, pipe, false); + skl_wa_827(display, pipe, false); if (needs_scalerclk_wa(old_crtc_state) && !needs_scalerclk_wa(new_crtc_state)) - icl_wa_scalerclkgating(dev_priv, pipe, false); + icl_wa_scalerclkgating(display, pipe, false); if (needs_cursorclk_wa(old_crtc_state) && !needs_cursorclk_wa(new_crtc_state)) - icl_wa_cursorclkgating(dev_priv, pipe, false); + icl_wa_cursorclkgating(display, pipe, false); if (intel_crtc_needs_color_update(new_crtc_state)) intel_color_post_update(new_crtc_state); @@ -1194,22 +1195,22 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, if (!needs_async_flip_vtd_wa(old_crtc_state) && needs_async_flip_vtd_wa(new_crtc_state)) - intel_async_flip_vtd_wa(dev_priv, pipe, true); + intel_async_flip_vtd_wa(display, pipe, true); /* Display WA 827 */ if (!needs_nv12_wa(old_crtc_state) && needs_nv12_wa(new_crtc_state)) - skl_wa_827(dev_priv, pipe, true); + skl_wa_827(display, pipe, true); /* Wa_2006604312:icl,ehl */ if (!needs_scalerclk_wa(old_crtc_state) && needs_scalerclk_wa(new_crtc_state)) - icl_wa_scalerclkgating(dev_priv, pipe, true); + icl_wa_scalerclkgating(display, pipe, true); /* Wa_1604331009:icl,jsl,ehl */ if (!needs_cursorclk_wa(old_crtc_state) && needs_cursorclk_wa(new_crtc_state)) - icl_wa_cursorclkgating(dev_priv, pipe, true); + icl_wa_cursorclkgating(display, pipe, true); /* * Vblank time updates from the shadow to live plane control register @@ -1220,7 +1221,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, * event which is after the vblank start event, so we need to have a * wait-for-vblank between disabling the plane and the pipe. */ - if (HAS_GMCH(dev_priv) && old_crtc_state->hw.active && + if (HAS_GMCH(display) && old_crtc_state->hw.active && new_crtc_state->disable_cxsr && intel_set_memory_cxsr(dev_priv, false)) intel_crtc_wait_for_next_vblank(crtc); @@ -1231,7 +1232,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, * * WaCxSRDisabledForSpriteScaling:ivb */ - if (!HAS_GMCH(dev_priv) && old_crtc_state->hw.active && + if (!HAS_GMCH(display) && old_crtc_state->hw.active && new_crtc_state->disable_cxsr && ilk_disable_cxsr(dev_priv)) intel_crtc_wait_for_next_vblank(crtc); @@ -1267,7 +1268,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, * chance of catching underruns with the intermediate watermarks * vs. the old plane configuration. */ - if (DISPLAY_VER(dev_priv) == 2 && planes_disabling(old_crtc_state, new_crtc_state)) + if (DISPLAY_VER(display) == 2 && planes_disabling(old_crtc_state, new_crtc_state)) intel_set_cpu_fifo_underrun_reporting(display, pipe, false); /* @@ -1308,7 +1309,7 @@ static void intel_crtc_disable_planes(struct intel_atomic_state *state, static void intel_encoders_update_prepare(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; int i; @@ -1317,7 +1318,7 @@ static void intel_encoders_update_prepare(struct intel_atomic_state *state) * Make sure the DPLL state is up-to-date for fastset TypeC ports after non-blocking commits. * TODO: Update the DPLL state for all cases in the encoder->update_prepare() hook. */ - if (i915->display.dpll.mgr) { + if (display->dpll.mgr) { for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { if (intel_crtc_needs_modeset(new_crtc_state)) continue; @@ -1513,7 +1514,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state, struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - if (drm_WARN_ON(&dev_priv->drm, crtc->active)) + if (drm_WARN_ON(display->drm, crtc->active)) return; /* @@ -1582,26 +1583,26 @@ static void ilk_crtc_enable(struct intel_atomic_state *state, /* Display WA #1180: WaDisableScalarClockGating: glk */ static bool glk_need_scaler_clock_gating_wa(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); - return DISPLAY_VER(i915) == 10 && crtc_state->pch_pfit.enabled; + return DISPLAY_VER(display) == 10 && crtc_state->pch_pfit.enabled; } static void glk_pipe_scaler_clock_gating_wa(struct intel_crtc *crtc, bool enable) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); u32 mask = DPF_GATING_DIS | DPF_RAM_GATING_DIS | DPFR_GATING_DIS; - intel_de_rmw(i915, CLKGATE_DIS_PSL(crtc->pipe), + intel_de_rmw(display, CLKGATE_DIS_PSL(crtc->pipe), mask, enable ? mask : 0); } static void hsw_set_linetime_wm(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - intel_de_write(dev_priv, WM_LINETIME(crtc->pipe), + intel_de_write(display, WM_LINETIME(crtc->pipe), HSW_LINETIME(crtc_state->linetime) | HSW_IPS_LINETIME(crtc_state->ips_linetime)); } @@ -1617,8 +1618,8 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state) static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; if (crtc_state->has_pch_encoder) { @@ -1632,11 +1633,11 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta } intel_set_transcoder_timings(crtc_state); - if (HAS_VRR(dev_priv)) + if (HAS_VRR(display)) intel_vrr_set_transcoder_timings(crtc_state); if (cpu_transcoder != TRANSCODER_EDP) - intel_de_write(dev_priv, TRANS_MULT(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_MULT(display, cpu_transcoder), crtc_state->pixel_multiplier - 1); hsw_set_frame_start_delay(crtc_state); @@ -1650,12 +1651,11 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder; struct intel_crtc *pipe_crtc; int i; - if (drm_WARN_ON(&dev_priv->drm, crtc->active)) + if (drm_WARN_ON(display->drm, crtc->active)) return; for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) intel_dmc_enable_pipe(display, pipe_crtc->pipe); @@ -1678,12 +1678,12 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, intel_dsc_enable(pipe_crtc_state); - if (HAS_UNCOMPRESSED_JOINER(dev_priv)) + if (HAS_UNCOMPRESSED_JOINER(display)) intel_uncompressed_joiner_enable(pipe_crtc_state); intel_set_pipe_src_size(pipe_crtc_state); - if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) + if (DISPLAY_VER(display) >= 9 || display->platform.broadwell) bdw_set_pipe_misc(NULL, pipe_crtc_state); } @@ -1699,7 +1699,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, if (glk_need_scaler_clock_gating_wa(pipe_crtc_state)) glk_pipe_scaler_clock_gating_wa(pipe_crtc, true); - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) skl_pfit_enable(pipe_crtc_state); else ilk_pfit_enable(pipe_crtc_state); @@ -1712,7 +1712,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, hsw_set_linetime_wm(pipe_crtc_state); - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) icl_set_pipe_chicken(pipe_crtc_state); intel_initial_watermarks(state, pipe_crtc); @@ -1735,7 +1735,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, * enabling, we need to change the workaround. */ hsw_workaround_pipe = pipe_crtc_state->hsw_workaround_pipe; - if (IS_HASWELL(dev_priv) && hsw_workaround_pipe != INVALID_PIPE) { + if (display->platform.haswell && hsw_workaround_pipe != INVALID_PIPE) { struct intel_crtc *wa_crtc = intel_crtc_for_pipe(display, hsw_workaround_pipe); @@ -1943,8 +1943,8 @@ intel_aux_power_domain(struct intel_digital_port *dig_port) static void get_crtc_power_domains(struct intel_crtc_state *crtc_state, struct intel_power_domain_mask *mask) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; struct drm_encoder *encoder; enum pipe pipe = crtc->pipe; @@ -1960,14 +1960,14 @@ static void get_crtc_power_domains(struct intel_crtc_state *crtc_state, crtc_state->pch_pfit.force_thru) set_bit(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe), mask->bits); - drm_for_each_encoder_mask(encoder, &dev_priv->drm, + drm_for_each_encoder_mask(encoder, display->drm, crtc_state->uapi.encoder_mask) { struct intel_encoder *intel_encoder = to_intel_encoder(encoder); set_bit(intel_encoder->power_domain, mask->bits); } - if (HAS_DDI(dev_priv) && crtc_state->has_audio) + if (HAS_DDI(display) && crtc_state->has_audio) set_bit(POWER_DOMAIN_AUDIO_MMIO, mask->bits); if (crtc_state->shared_dpll) @@ -2035,22 +2035,21 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - if (drm_WARN_ON(&dev_priv->drm, crtc->active)) + if (drm_WARN_ON(display->drm, crtc->active)) return; i9xx_configure_cpu_transcoder(new_crtc_state); intel_set_pipe_src_size(new_crtc_state); - intel_de_write(dev_priv, VLV_PIPE_MSA_MISC(pipe), 0); + intel_de_write(display, VLV_PIPE_MSA_MISC(display, pipe), 0); - if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { - intel_de_write(dev_priv, CHV_BLEND(dev_priv, pipe), + if (display->platform.cherryview && pipe == PIPE_B) { + intel_de_write(display, CHV_BLEND(display, pipe), CHV_BLEND_LEGACY); - intel_de_write(dev_priv, CHV_CANVAS(dev_priv, pipe), 0); + intel_de_write(display, CHV_CANVAS(display, pipe), 0); } crtc->active = true; @@ -2059,7 +2058,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, intel_encoders_pre_pll_enable(state, crtc); - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) chv_enable_pll(new_crtc_state); else vlv_enable_pll(new_crtc_state); @@ -2087,7 +2086,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - if (drm_WARN_ON(&dev_priv->drm, crtc->active)) + if (drm_WARN_ON(display->drm, crtc->active)) return; i9xx_configure_cpu_transcoder(new_crtc_state); @@ -2096,7 +2095,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, crtc->active = true; - if (DISPLAY_VER(dev_priv) != 2) + if (DISPLAY_VER(display) != 2) intel_set_cpu_fifo_underrun_reporting(display, pipe, true); intel_encoders_pre_enable(state, crtc); @@ -2116,7 +2115,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, intel_encoders_enable(state, crtc); /* prevents spurious underruns */ - if (DISPLAY_VER(dev_priv) == 2) + if (DISPLAY_VER(display) == 2) intel_crtc_wait_for_next_vblank(crtc); } @@ -2133,7 +2132,7 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, * On gen2 planes are double buffered but the pipe isn't, so we must * wait for planes to fully turn off before disabling the pipe. */ - if (DISPLAY_VER(dev_priv) == 2) + if (DISPLAY_VER(display) == 2) intel_crtc_wait_for_next_vblank(crtc); intel_encoders_disable(state, crtc); @@ -2147,9 +2146,9 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, intel_encoders_post_disable(state, crtc); if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI)) { - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) chv_disable_pll(dev_priv, pipe); - else if (IS_VALLEYVIEW(dev_priv)) + else if (display->platform.valleyview) vlv_disable_pll(dev_priv, pipe); else i9xx_disable_pll(old_crtc_state); @@ -2157,14 +2156,14 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, intel_encoders_post_pll_disable(state, crtc); - if (DISPLAY_VER(dev_priv) != 2) + if (DISPLAY_VER(display) != 2) intel_set_cpu_fifo_underrun_reporting(display, pipe, false); - if (!dev_priv->display.funcs.wm->initial_watermarks) + if (!display->funcs.wm->initial_watermarks) intel_update_watermarks(dev_priv); /* clock the pipe down to 640x480@60 to potentially save power */ - if (IS_I830(dev_priv)) + if (display->platform.i830) i830_enable_pipe(display, pipe); } @@ -2178,11 +2177,11 @@ void intel_encoder_destroy(struct drm_encoder *encoder) static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc) { - const struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); /* GDG double wide on either pipe, otherwise pipe A only */ - return HAS_DOUBLE_WIDE(dev_priv) && - (crtc->pipe == PIPE_A || IS_I915G(dev_priv)); + return HAS_DOUBLE_WIDE(display) && + (crtc->pipe == PIPE_A || display->platform.i915g); } static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state) @@ -2229,9 +2228,9 @@ static void intel_mode_from_crtc_timings(struct drm_display_mode *mode, static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); - if (HAS_GMCH(dev_priv)) + if (HAS_GMCH(display)) /* FIXME calculate proper pipe pixel rate for GMCH pfit */ crtc_state->pixel_rate = crtc_state->hw.pipe_mode.crtc_clock; @@ -2342,6 +2341,7 @@ static void intel_joiner_compute_pipe_src(struct intel_crtc_state *crtc_state) static int intel_crtc_compute_pipe_src(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); @@ -2355,7 +2355,7 @@ static int intel_crtc_compute_pipe_src(struct intel_crtc_state *crtc_state) */ if (drm_rect_width(&crtc_state->pipe_src) & 1) { if (crtc_state->double_wide) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] Odd pipe source width not supported with double wide pipe\n", crtc->base.base.id, crtc->base.name); return -EINVAL; @@ -2363,7 +2363,7 @@ static int intel_crtc_compute_pipe_src(struct intel_crtc_state *crtc_state) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && intel_is_dual_link_lvds(i915)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] Odd pipe source width not supported with dual link LVDS\n", crtc->base.base.id, crtc->base.name); return -EINVAL; @@ -2375,11 +2375,11 @@ static int intel_crtc_compute_pipe_src(struct intel_crtc_state *crtc_state) static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode; - int clock_limit = i915->display.cdclk.max_dotclk_freq; + int clock_limit = display->cdclk.max_dotclk_freq; /* * Start with the adjusted_mode crtc timings, which @@ -2394,8 +2394,8 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state) intel_joiner_adjust_timings(crtc_state, pipe_mode); intel_mode_from_crtc_timings(pipe_mode, pipe_mode); - if (DISPLAY_VER(i915) < 4) { - clock_limit = i915->display.cdclk.max_cdclk_freq * 9 / 10; + if (DISPLAY_VER(display) < 4) { + clock_limit = display->cdclk.max_cdclk_freq * 9 / 10; /* * Enable double wide mode when the dot clock @@ -2403,13 +2403,13 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state) */ if (intel_crtc_supports_double_wide(crtc) && pipe_mode->crtc_clock > clock_limit) { - clock_limit = i915->display.cdclk.max_dotclk_freq; + clock_limit = display->cdclk.max_dotclk_freq; crtc_state->double_wide = true; } } if (pipe_mode->crtc_clock > clock_limit) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n", crtc->base.base.id, crtc->base.name, pipe_mode->crtc_clock, clock_limit, @@ -2641,15 +2641,15 @@ void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc, static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; u32 crtc_vdisplay, crtc_vtotal, crtc_vblank_start, crtc_vblank_end; int vsyncshift = 0; - drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)); + drm_WARN_ON(display->drm, transcoder_is_dsi(cpu_transcoder)); /* We need to be careful not to changed the adjusted mode, for otherwise * the hw state checker will get angry at the mismatch. */ @@ -2676,9 +2676,9 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta * VBLANK_START no longer works on ADL+, instead we must use * TRANS_SET_CONTEXT_LATENCY to configure the pipe vblank start. */ - if (DISPLAY_VER(dev_priv) >= 13) { - intel_de_write(dev_priv, - TRANS_SET_CONTEXT_LATENCY(dev_priv, cpu_transcoder), + if (DISPLAY_VER(display) >= 13) { + intel_de_write(display, + TRANS_SET_CONTEXT_LATENCY(display, cpu_transcoder), crtc_vblank_start - crtc_vdisplay); /* @@ -2688,28 +2688,28 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta crtc_vblank_start = 1; } - if (DISPLAY_VER(dev_priv) >= 4) - intel_de_write(dev_priv, - TRANS_VSYNCSHIFT(dev_priv, cpu_transcoder), + if (DISPLAY_VER(display) >= 4) + intel_de_write(display, + TRANS_VSYNCSHIFT(display, cpu_transcoder), vsyncshift); - intel_de_write(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_HTOTAL(display, cpu_transcoder), HACTIVE(adjusted_mode->crtc_hdisplay - 1) | HTOTAL(adjusted_mode->crtc_htotal - 1)); - intel_de_write(dev_priv, TRANS_HBLANK(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_HBLANK(display, cpu_transcoder), HBLANK_START(adjusted_mode->crtc_hblank_start - 1) | HBLANK_END(adjusted_mode->crtc_hblank_end - 1)); - intel_de_write(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_HSYNC(display, cpu_transcoder), HSYNC_START(adjusted_mode->crtc_hsync_start - 1) | HSYNC_END(adjusted_mode->crtc_hsync_end - 1)); - intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_VTOTAL(display, cpu_transcoder), VACTIVE(crtc_vdisplay - 1) | VTOTAL(crtc_vtotal - 1)); - intel_de_write(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_VBLANK(display, cpu_transcoder), VBLANK_START(crtc_vblank_start - 1) | VBLANK_END(crtc_vblank_end - 1)); - intel_de_write(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_VSYNC(display, cpu_transcoder), VSYNC_START(adjusted_mode->crtc_vsync_start - 1) | VSYNC_END(adjusted_mode->crtc_vsync_end - 1)); @@ -2717,22 +2717,21 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta * programmed with the VTOTAL_EDP value. Same for VTOTAL_C. This is * documented on the DDI_FUNC_CTL register description, EDP Input Select * bits. */ - if (IS_HASWELL(dev_priv) && cpu_transcoder == TRANSCODER_EDP && + if (display->platform.haswell && cpu_transcoder == TRANSCODER_EDP && (pipe == PIPE_B || pipe == PIPE_C)) - intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, pipe), + intel_de_write(display, TRANS_VTOTAL(display, pipe), VACTIVE(crtc_vdisplay - 1) | VTOTAL(crtc_vtotal - 1)); } static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; u32 crtc_vdisplay, crtc_vtotal, crtc_vblank_start, crtc_vblank_end; - drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)); + drm_WARN_ON(display->drm, transcoder_is_dsi(cpu_transcoder)); crtc_vdisplay = adjusted_mode->crtc_vdisplay; crtc_vtotal = adjusted_mode->crtc_vtotal; @@ -2745,9 +2744,9 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc crtc_vblank_end -= 1; } - if (DISPLAY_VER(dev_priv) >= 13) { - intel_de_write(dev_priv, - TRANS_SET_CONTEXT_LATENCY(dev_priv, cpu_transcoder), + if (DISPLAY_VER(display) >= 13) { + intel_de_write(display, + TRANS_SET_CONTEXT_LATENCY(display, cpu_transcoder), crtc_vblank_start - crtc_vdisplay); /* @@ -2761,22 +2760,22 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc * The hardware actually ignores TRANS_VBLANK.VBLANK_END in DP mode. * But let's write it anyway to keep the state checker happy. */ - intel_de_write(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_VBLANK(display, cpu_transcoder), VBLANK_START(crtc_vblank_start - 1) | VBLANK_END(crtc_vblank_end - 1)); /* * The double buffer latch point for TRANS_VTOTAL * is the transcoder's undelayed vblank. */ - intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_VTOTAL(display, cpu_transcoder), VACTIVE(crtc_vdisplay - 1) | VTOTAL(crtc_vtotal - 1)); } static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); int width = drm_rect_width(&crtc_state->pipe_src); int height = drm_rect_height(&crtc_state->pipe_src); enum pipe pipe = crtc->pipe; @@ -2784,63 +2783,62 @@ static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state) /* pipesrc controls the size that is scaled from, which should * always be the user's requested size. */ - intel_de_write(dev_priv, PIPESRC(dev_priv, pipe), + intel_de_write(display, PIPESRC(display, pipe), PIPESRC_WIDTH(width - 1) | PIPESRC_HEIGHT(height - 1)); } static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - if (DISPLAY_VER(dev_priv) == 2) + if (DISPLAY_VER(display) == 2) return false; - if (DISPLAY_VER(dev_priv) >= 9 || - IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) - return intel_de_read(dev_priv, - TRANSCONF(dev_priv, cpu_transcoder)) & TRANSCONF_INTERLACE_MASK_HSW; + if (DISPLAY_VER(display) >= 9 || + display->platform.broadwell || display->platform.haswell) + return intel_de_read(display, + TRANSCONF(display, cpu_transcoder)) & TRANSCONF_INTERLACE_MASK_HSW; else - return intel_de_read(dev_priv, - TRANSCONF(dev_priv, cpu_transcoder)) & TRANSCONF_INTERLACE_MASK; + return intel_de_read(display, + TRANSCONF(display, cpu_transcoder)) & TRANSCONF_INTERLACE_MASK; } static void intel_get_transcoder_timings(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(crtc); enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; u32 tmp; - tmp = intel_de_read(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder)); + tmp = intel_de_read(display, TRANS_HTOTAL(display, cpu_transcoder)); adjusted_mode->crtc_hdisplay = REG_FIELD_GET(HACTIVE_MASK, tmp) + 1; adjusted_mode->crtc_htotal = REG_FIELD_GET(HTOTAL_MASK, tmp) + 1; if (!transcoder_is_dsi(cpu_transcoder)) { - tmp = intel_de_read(dev_priv, - TRANS_HBLANK(dev_priv, cpu_transcoder)); + tmp = intel_de_read(display, + TRANS_HBLANK(display, cpu_transcoder)); adjusted_mode->crtc_hblank_start = REG_FIELD_GET(HBLANK_START_MASK, tmp) + 1; adjusted_mode->crtc_hblank_end = REG_FIELD_GET(HBLANK_END_MASK, tmp) + 1; } - tmp = intel_de_read(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder)); + tmp = intel_de_read(display, TRANS_HSYNC(display, cpu_transcoder)); adjusted_mode->crtc_hsync_start = REG_FIELD_GET(HSYNC_START_MASK, tmp) + 1; adjusted_mode->crtc_hsync_end = REG_FIELD_GET(HSYNC_END_MASK, tmp) + 1; - tmp = intel_de_read(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder)); + tmp = intel_de_read(display, TRANS_VTOTAL(display, cpu_transcoder)); adjusted_mode->crtc_vdisplay = REG_FIELD_GET(VACTIVE_MASK, tmp) + 1; adjusted_mode->crtc_vtotal = REG_FIELD_GET(VTOTAL_MASK, tmp) + 1; /* FIXME TGL+ DSI transcoders have this! */ if (!transcoder_is_dsi(cpu_transcoder)) { - tmp = intel_de_read(dev_priv, - TRANS_VBLANK(dev_priv, cpu_transcoder)); + tmp = intel_de_read(display, + TRANS_VBLANK(display, cpu_transcoder)); adjusted_mode->crtc_vblank_start = REG_FIELD_GET(VBLANK_START_MASK, tmp) + 1; adjusted_mode->crtc_vblank_end = REG_FIELD_GET(VBLANK_END_MASK, tmp) + 1; } - tmp = intel_de_read(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder)); + tmp = intel_de_read(display, TRANS_VSYNC(display, cpu_transcoder)); adjusted_mode->crtc_vsync_start = REG_FIELD_GET(VSYNC_START_MASK, tmp) + 1; adjusted_mode->crtc_vsync_end = REG_FIELD_GET(VSYNC_END_MASK, tmp) + 1; @@ -2850,11 +2848,11 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc, adjusted_mode->crtc_vblank_end += 1; } - if (DISPLAY_VER(dev_priv) >= 13 && !transcoder_is_dsi(cpu_transcoder)) + if (DISPLAY_VER(display) >= 13 && !transcoder_is_dsi(cpu_transcoder)) adjusted_mode->crtc_vblank_start = adjusted_mode->crtc_vdisplay + - intel_de_read(dev_priv, - TRANS_SET_CONTEXT_LATENCY(dev_priv, cpu_transcoder)); + intel_de_read(display, + TRANS_SET_CONTEXT_LATENCY(display, cpu_transcoder)); } static void intel_joiner_adjust_pipe_src(struct intel_crtc_state *crtc_state) @@ -2877,11 +2875,10 @@ static void intel_joiner_adjust_pipe_src(struct intel_crtc_state *crtc_state) static void intel_get_pipe_src_size(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(crtc); u32 tmp; - tmp = intel_de_read(dev_priv, PIPESRC(dev_priv, crtc->pipe)); + tmp = intel_de_read(display, PIPESRC(display, crtc->pipe)); drm_rect_init(&pipe_config->pipe_src, 0, 0, REG_FIELD_GET(PIPESRC_WIDTH_MASK, tmp) + 1, @@ -2892,8 +2889,7 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc, void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 val = 0; @@ -2902,15 +2898,15 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) * - During modeset the pipe is still disabled and must remain so * - During fastset the pipe is already enabled and must remain so */ - if (IS_I830(dev_priv) || !intel_crtc_needs_modeset(crtc_state)) + if (display->platform.i830 || !intel_crtc_needs_modeset(crtc_state)) val |= TRANSCONF_ENABLE; if (crtc_state->double_wide) val |= TRANSCONF_DOUBLE_WIDE; /* only g4x and later have fancy bpc/dither controls */ - if (IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) || - IS_CHERRYVIEW(dev_priv)) { + if (display->platform.g4x || display->platform.valleyview || + display->platform.cherryview) { /* Bspec claims that we can't use dithering for 30bpp pipes. */ if (crtc_state->dither && crtc_state->pipe_bpp != 30) val |= TRANSCONF_DITHER_EN | @@ -2934,7 +2930,7 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) } if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) { - if (DISPLAY_VER(dev_priv) < 4 || + if (DISPLAY_VER(display) < 4 || intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO)) val |= TRANSCONF_INTERLACE_W_FIELD_INDICATION; else @@ -2943,8 +2939,8 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) val |= TRANSCONF_INTERLACE_PROGRESSIVE; } - if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && - crtc_state->limited_color_range) + if ((display->platform.valleyview || display->platform.cherryview) && + crtc_state->limited_color_range) val |= TRANSCONF_COLOR_RANGE_SELECT; val |= TRANSCONF_GAMMA_MODE(crtc_state->gamma_mode); @@ -2954,17 +2950,17 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) val |= TRANSCONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1); - intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val); - intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder)); + intel_de_write(display, TRANSCONF(display, cpu_transcoder), val); + intel_de_posting_read(display, TRANSCONF(display, cpu_transcoder)); } static enum intel_output_format bdw_get_pipe_misc_output_format(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); u32 tmp; - tmp = intel_de_read(dev_priv, PIPE_MISC(crtc->pipe)); + tmp = intel_de_read(display, PIPE_MISC(crtc->pipe)); if (tmp & PIPE_MISC_YUV420_ENABLE) { /* @@ -2972,8 +2968,8 @@ bdw_get_pipe_misc_output_format(struct intel_crtc *crtc) * For xe3_lpd+ this is implied in YUV420 Enable bit. * Ensure the same for prior platforms in YUV420 Mode bit. */ - if (DISPLAY_VER(dev_priv) < 30) - drm_WARN_ON(&dev_priv->drm, + if (DISPLAY_VER(display) < 30) + drm_WARN_ON(display->drm, (tmp & PIPE_MISC_YUV420_MODE_FULL_BLEND) == 0); return INTEL_OUTPUT_FORMAT_YCBCR420; @@ -2988,7 +2984,6 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; u32 tmp; @@ -3006,13 +3001,13 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, ret = false; - tmp = intel_de_read(dev_priv, - TRANSCONF(dev_priv, pipe_config->cpu_transcoder)); + tmp = intel_de_read(display, + TRANSCONF(display, pipe_config->cpu_transcoder)); if (!(tmp & TRANSCONF_ENABLE)) goto out; - if (IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) || - IS_CHERRYVIEW(dev_priv)) { + if (display->platform.g4x || display->platform.valleyview || + display->platform.cherryview) { switch (tmp & TRANSCONF_BPC_MASK) { case TRANSCONF_BPC_6: pipe_config->pipe_bpp = 18; @@ -3029,7 +3024,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, } } - if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && + if ((display->platform.valleyview || display->platform.cherryview) && (tmp & TRANSCONF_COLOR_RANGE_SELECT)) pipe_config->limited_color_range = true; @@ -3037,13 +3032,13 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, pipe_config->framestart_delay = REG_FIELD_GET(TRANSCONF_FRAME_START_DELAY_MASK, tmp) + 1; - if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && + if ((display->platform.valleyview || display->platform.cherryview) && (tmp & TRANSCONF_WGC_ENABLE)) pipe_config->wgc_enable = true; intel_color_get_config(pipe_config); - if (HAS_DOUBLE_WIDE(dev_priv)) + if (HAS_DOUBLE_WIDE(display)) pipe_config->double_wide = tmp & TRANSCONF_DOUBLE_WIDE; intel_get_transcoder_timings(crtc, pipe_config); @@ -3053,13 +3048,13 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, i9xx_dpll_get_hw_state(crtc, &pipe_config->dpll_hw_state); - if (DISPLAY_VER(dev_priv) >= 4) { + if (DISPLAY_VER(display) >= 4) { tmp = pipe_config->dpll_hw_state.i9xx.dpll_md; pipe_config->pixel_multiplier = ((tmp & DPLL_MD_UDI_MULTIPLIER_MASK) >> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1; - } else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) || - IS_G33(dev_priv) || IS_PINEVIEW(dev_priv)) { + } else if (display->platform.i945g || display->platform.i945gm || + display->platform.g33 || display->platform.pineview) { tmp = pipe_config->dpll_hw_state.i9xx.dpll; pipe_config->pixel_multiplier = ((tmp & SDVO_MULTIPLIER_MASK) @@ -3071,9 +3066,9 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, pipe_config->pixel_multiplier = 1; } - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) chv_crtc_clock_get(pipe_config); - else if (IS_VALLEYVIEW(dev_priv)) + else if (display->platform.valleyview) vlv_crtc_clock_get(pipe_config); else i9xx_crtc_clock_get(pipe_config); @@ -3096,8 +3091,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 val = 0; @@ -3139,7 +3133,7 @@ void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state) * This would end up with an odd purple hue over * the entire display. Make sure we don't do it. */ - drm_WARN_ON(&dev_priv->drm, crtc_state->limited_color_range && + drm_WARN_ON(display->drm, crtc_state->limited_color_range && crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB); if (crtc_state->limited_color_range && @@ -3154,14 +3148,13 @@ void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state) val |= TRANSCONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1); val |= TRANSCONF_MSA_TIMING_DELAY(crtc_state->msa_timing_delay); - intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val); - intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder)); + intel_de_write(display, TRANSCONF(display, cpu_transcoder), val); + intel_de_posting_read(display, TRANSCONF(display, cpu_transcoder)); } static void hsw_set_transconf(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 val = 0; @@ -3172,7 +3165,7 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state) if (!intel_crtc_needs_modeset(crtc_state)) val |= TRANSCONF_ENABLE; - if (IS_HASWELL(dev_priv) && crtc_state->dither) + if (display->platform.haswell && crtc_state->dither) val |= TRANSCONF_DITHER_EN | TRANSCONF_DITHER_TYPE_SP; if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) @@ -3180,20 +3173,19 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state) else val |= TRANSCONF_INTERLACE_PF_PD_ILK; - if (IS_HASWELL(dev_priv) && + if (display->platform.haswell && crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) val |= TRANSCONF_OUTPUT_COLORSPACE_YUV_HSW; - intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val); - intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder)); + intel_de_write(display, TRANSCONF(display, cpu_transcoder), val); + intel_de_posting_read(display, TRANSCONF(display, cpu_transcoder)); } static void bdw_set_pipe_misc(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct intel_display *display = to_intel_display(crtc->base.dev); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 val = 0; switch (crtc_state->pipe_bpp) { @@ -3208,7 +3200,7 @@ static void bdw_set_pipe_misc(struct intel_dsb *dsb, break; case 36: /* Port output 12BPC defined for ADLP+ */ - if (DISPLAY_VER(dev_priv) >= 13) + if (DISPLAY_VER(display) >= 13) val |= PIPE_MISC_BPC_12_ADLP; break; default: @@ -3227,14 +3219,14 @@ static void bdw_set_pipe_misc(struct intel_dsb *dsb, val |= DISPLAY_VER(display) >= 30 ? PIPE_MISC_YUV420_ENABLE : PIPE_MISC_YUV420_ENABLE | PIPE_MISC_YUV420_MODE_FULL_BLEND; - if (DISPLAY_VER(dev_priv) >= 11 && is_hdr_mode(crtc_state)) + if (DISPLAY_VER(display) >= 11 && is_hdr_mode(crtc_state)) val |= PIPE_MISC_HDR_MODE_PRECISION; - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) val |= PIPE_MISC_PIXEL_ROUNDING_TRUNC; /* allow PSR with sprite enabled */ - if (IS_BROADWELL(dev_priv)) + if (display->platform.broadwell) val |= PIPE_MISC_PSR_MASK_SPRITE_ENABLE; intel_de_write_dsb(display, dsb, PIPE_MISC(crtc->pipe), val); @@ -3242,10 +3234,10 @@ static void bdw_set_pipe_misc(struct intel_dsb *dsb, int bdw_get_pipe_misc_bpp(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); u32 tmp; - tmp = intel_de_read(dev_priv, PIPE_MISC(crtc->pipe)); + tmp = intel_de_read(display, PIPE_MISC(crtc->pipe)); switch (tmp & PIPE_MISC_BPC_MASK) { case PIPE_MISC_BPC_6: @@ -3265,7 +3257,7 @@ int bdw_get_pipe_misc_bpp(struct intel_crtc *crtc) * MIPI DSI HW readout. */ case PIPE_MISC_BPC_12_ADLP: - if (DISPLAY_VER(dev_priv) >= 13) + if (DISPLAY_VER(display) >= 13) return 36; fallthrough; default: @@ -3336,8 +3328,6 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct intel_display *display = to_intel_display(crtc); - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; u32 tmp; @@ -3352,8 +3342,8 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, pipe_config->shared_dpll = NULL; ret = false; - tmp = intel_de_read(dev_priv, - TRANSCONF(dev_priv, pipe_config->cpu_transcoder)); + tmp = intel_de_read(display, + TRANSCONF(display, pipe_config->cpu_transcoder)); if (!(tmp & TRANSCONF_ENABLE)) goto out; @@ -3414,24 +3404,23 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, return ret; } -static u8 joiner_pipes(struct drm_i915_private *i915) +static u8 joiner_pipes(struct intel_display *display) { u8 pipes; - if (DISPLAY_VER(i915) >= 12) + if (DISPLAY_VER(display) >= 12) pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D); - else if (DISPLAY_VER(i915) >= 11) + else if (DISPLAY_VER(display) >= 11) pipes = BIT(PIPE_B) | BIT(PIPE_C); else pipes = 0; - return pipes & DISPLAY_RUNTIME_INFO(i915)->pipe_mask; + return pipes & DISPLAY_RUNTIME_INFO(display)->pipe_mask; } -static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv, +static bool transcoder_ddi_func_is_enabled(struct intel_display *display, enum transcoder cpu_transcoder) { - struct intel_display *display = &dev_priv->display; enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; u32 tmp = 0; @@ -3439,8 +3428,8 @@ static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv, power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); with_intel_display_power_if_enabled(display, power_domain, wakeref) - tmp = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); + tmp = intel_de_read(display, + TRANS_DDI_FUNC_CTL(display, cpu_transcoder)); return tmp & TRANS_DDI_FUNC_ENABLE; } @@ -3448,7 +3437,6 @@ static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv, static void enabled_uncompressed_joiner_pipes(struct intel_display *display, u8 *primary_pipes, u8 *secondary_pipes) { - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_crtc *crtc; *primary_pipes = 0; @@ -3457,8 +3445,8 @@ static void enabled_uncompressed_joiner_pipes(struct intel_display *display, if (!HAS_UNCOMPRESSED_JOINER(display)) return; - for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, - joiner_pipes(i915)) { + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, + joiner_pipes(display)) { enum intel_display_power_domain power_domain; enum pipe pipe = crtc->pipe; intel_wakeref_t wakeref; @@ -3478,7 +3466,6 @@ static void enabled_uncompressed_joiner_pipes(struct intel_display *display, static void enabled_bigjoiner_pipes(struct intel_display *display, u8 *primary_pipes, u8 *secondary_pipes) { - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_crtc *crtc; *primary_pipes = 0; @@ -3487,8 +3474,8 @@ static void enabled_bigjoiner_pipes(struct intel_display *display, if (!HAS_BIGJOINER(display)) return; - for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, - joiner_pipes(i915)) { + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, + joiner_pipes(display)) { enum intel_display_power_domain power_domain; enum pipe pipe = crtc->pipe; intel_wakeref_t wakeref; @@ -3546,10 +3533,9 @@ static u8 fixup_ultrajoiner_secondary_pipes(u8 ultrajoiner_primary_pipes, return ultrajoiner_secondary_pipes | ultrajoiner_primary_pipes << 3; } -static void enabled_ultrajoiner_pipes(struct drm_i915_private *i915, +static void enabled_ultrajoiner_pipes(struct intel_display *display, u8 *primary_pipes, u8 *secondary_pipes) { - struct intel_display *display = &i915->display; struct intel_crtc *crtc; *primary_pipes = 0; @@ -3558,15 +3544,15 @@ static void enabled_ultrajoiner_pipes(struct drm_i915_private *i915, if (!HAS_ULTRAJOINER(display)) return; - for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, - joiner_pipes(i915)) { + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, + joiner_pipes(display)) { enum intel_display_power_domain power_domain; enum pipe pipe = crtc->pipe; intel_wakeref_t wakeref; power_domain = intel_dsc_power_domain(crtc, (enum transcoder)pipe); with_intel_display_power_if_enabled(display, power_domain, wakeref) { - u32 tmp = intel_de_read(i915, ICL_PIPE_DSS_CTL1(pipe)); + u32 tmp = intel_de_read(display, ICL_PIPE_DSS_CTL1(pipe)); if (!(tmp & ULTRA_JOINER_ENABLE)) continue; @@ -3579,11 +3565,10 @@ static void enabled_ultrajoiner_pipes(struct drm_i915_private *i915, } } -static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, +static void enabled_joiner_pipes(struct intel_display *display, enum pipe pipe, u8 *primary_pipe, u8 *secondary_pipes) { - struct intel_display *display = to_intel_display(&dev_priv->drm); u8 primary_ultrajoiner_pipes; u8 primary_uncompressed_joiner_pipes, primary_bigjoiner_pipes; u8 secondary_ultrajoiner_pipes; @@ -3591,21 +3576,21 @@ static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, u8 ultrajoiner_pipes; u8 uncompressed_joiner_pipes, bigjoiner_pipes; - enabled_ultrajoiner_pipes(dev_priv, &primary_ultrajoiner_pipes, + enabled_ultrajoiner_pipes(display, &primary_ultrajoiner_pipes, &secondary_ultrajoiner_pipes); /* * For some strange reason the last pipe in the set of four * shouldn't have ultrajoiner enable bit set in hardware. * Set the bit anyway to make life easier. */ - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, expected_secondary_pipes(primary_ultrajoiner_pipes, 3) != secondary_ultrajoiner_pipes); secondary_ultrajoiner_pipes = fixup_ultrajoiner_secondary_pipes(primary_ultrajoiner_pipes, secondary_ultrajoiner_pipes); - drm_WARN_ON(&dev_priv->drm, (primary_ultrajoiner_pipes & secondary_ultrajoiner_pipes) != 0); + drm_WARN_ON(display->drm, (primary_ultrajoiner_pipes & secondary_ultrajoiner_pipes) != 0); enabled_uncompressed_joiner_pipes(display, &primary_uncompressed_joiner_pipes, &secondary_uncompressed_joiner_pipes); @@ -3699,11 +3684,11 @@ static void enabled_joiner_pipes(struct drm_i915_private *dev_priv, } } -static u8 hsw_panel_transcoders(struct drm_i915_private *i915) +static u8 hsw_panel_transcoders(struct intel_display *display) { u8 panel_transcoder_mask = BIT(TRANSCODER_EDP); - if (DISPLAY_VER(i915) >= 11) + if (DISPLAY_VER(display) >= 11) panel_transcoder_mask |= BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1); return panel_transcoder_mask; @@ -3712,9 +3697,7 @@ static u8 hsw_panel_transcoders(struct drm_i915_private *i915) static u8 hsw_enabled_transcoders(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - u8 panel_transcoder_mask = hsw_panel_transcoders(dev_priv); + u8 panel_transcoder_mask = hsw_panel_transcoders(display); enum transcoder cpu_transcoder; u8 primary_pipe, secondary_pipes; u8 enabled_transcoders = 0; @@ -3723,7 +3706,7 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc) * XXX: Do intel_display_power_get_if_enabled before reading this (for * consistency and less surprising code; it's in always on power). */ - for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, + for_each_cpu_transcoder_masked(display, cpu_transcoder, panel_transcoder_mask) { enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; @@ -3732,15 +3715,15 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc) power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); with_intel_display_power_if_enabled(display, power_domain, wakeref) - tmp = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); + tmp = intel_de_read(display, + TRANS_DDI_FUNC_CTL(display, cpu_transcoder)); if (!(tmp & TRANS_DDI_FUNC_ENABLE)) continue; switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { default: - drm_WARN(dev, 1, + drm_WARN(display->drm, 1, "unknown pipe linked to transcoder %s\n", transcoder_name(cpu_transcoder)); fallthrough; @@ -3765,14 +3748,14 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc) /* single pipe or joiner primary */ cpu_transcoder = (enum transcoder) crtc->pipe; - if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder)) + if (transcoder_ddi_func_is_enabled(display, cpu_transcoder)) enabled_transcoders |= BIT(cpu_transcoder); /* joiner secondary -> consider the primary pipe's transcoder as well */ - enabled_joiner_pipes(dev_priv, crtc->pipe, &primary_pipe, &secondary_pipes); + enabled_joiner_pipes(display, crtc->pipe, &primary_pipe, &secondary_pipes); if (secondary_pipes & BIT(crtc->pipe)) { cpu_transcoder = (enum transcoder)ffs(primary_pipe) - 1; - if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder)) + if (transcoder_ddi_func_is_enabled(display, cpu_transcoder)) enabled_transcoders |= BIT(cpu_transcoder); } @@ -3797,17 +3780,17 @@ static bool has_pipe_transcoders(u8 enabled_transcoders) BIT(TRANSCODER_DSI_1)); } -static void assert_enabled_transcoders(struct drm_i915_private *i915, +static void assert_enabled_transcoders(struct intel_display *display, u8 enabled_transcoders) { /* Only one type of transcoder please */ - drm_WARN_ON(&i915->drm, + drm_WARN_ON(display->drm, has_edp_transcoders(enabled_transcoders) + has_dsi_transcoders(enabled_transcoders) + has_pipe_transcoders(enabled_transcoders) > 1); /* Only DSI transcoders can be ganged */ - drm_WARN_ON(&i915->drm, + drm_WARN_ON(display->drm, !has_dsi_transcoders(enabled_transcoders) && !is_power_of_2(enabled_transcoders)); } @@ -3817,8 +3800,6 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, struct intel_display_power_domain_set *power_domain_set) { struct intel_display *display = to_intel_display(crtc); - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); unsigned long enabled_transcoders; u32 tmp; @@ -3826,7 +3807,7 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, if (!enabled_transcoders) return false; - assert_enabled_transcoders(dev_priv, enabled_transcoders); + assert_enabled_transcoders(display, enabled_transcoders); /* * With the exception of DSI we should only ever have @@ -3839,16 +3820,16 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder))) return false; - if (hsw_panel_transcoders(dev_priv) & BIT(pipe_config->cpu_transcoder)) { - tmp = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, pipe_config->cpu_transcoder)); + if (hsw_panel_transcoders(display) & BIT(pipe_config->cpu_transcoder)) { + tmp = intel_de_read(display, + TRANS_DDI_FUNC_CTL(display, pipe_config->cpu_transcoder)); if ((tmp & TRANS_DDI_EDP_INPUT_MASK) == TRANS_DDI_EDP_INPUT_A_ONOFF) pipe_config->pch_pfit.force_thru = true; } - tmp = intel_de_read(dev_priv, - TRANSCONF(dev_priv, pipe_config->cpu_transcoder)); + tmp = intel_de_read(display, + TRANSCONF(display, pipe_config->cpu_transcoder)); return tmp & TRANSCONF_ENABLE; } @@ -3901,12 +3882,12 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, static void intel_joiner_get_config(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); u8 primary_pipe, secondary_pipes; enum pipe pipe = crtc->pipe; - enabled_joiner_pipes(i915, pipe, &primary_pipe, &secondary_pipes); + enabled_joiner_pipes(display, pipe, &primary_pipe, &secondary_pipes); if (((primary_pipe | secondary_pipes) & BIT(pipe)) == 0) return; @@ -3918,7 +3899,6 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); bool active; u32 tmp; @@ -3930,9 +3910,9 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, active = hsw_get_transcoder_state(crtc, pipe_config, &crtc->hw_readout_power_domains); - if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) && + if ((display->platform.geminilake || display->platform.broxton) && bxt_get_dsi_transcoder_state(crtc, pipe_config, &crtc->hw_readout_power_domains)) { - drm_WARN_ON(&dev_priv->drm, active); + drm_WARN_ON(display->drm, active); active = true; } @@ -3943,17 +3923,17 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, intel_dsc_get_config(pipe_config); if (!transcoder_is_dsi(pipe_config->cpu_transcoder) || - DISPLAY_VER(dev_priv) >= 11) + DISPLAY_VER(display) >= 11) intel_get_transcoder_timings(crtc, pipe_config); - if (HAS_VRR(dev_priv) && !transcoder_is_dsi(pipe_config->cpu_transcoder)) + if (HAS_VRR(display) && !transcoder_is_dsi(pipe_config->cpu_transcoder)) intel_vrr_get_config(pipe_config); intel_get_pipe_src_size(crtc, pipe_config); - if (IS_HASWELL(dev_priv)) { - u32 tmp = intel_de_read(dev_priv, - TRANSCONF(dev_priv, pipe_config->cpu_transcoder)); + if (display->platform.haswell) { + u32 tmp = intel_de_read(display, + TRANSCONF(display, pipe_config->cpu_transcoder)); if (tmp & TRANSCONF_OUTPUT_COLORSPACE_YUV_HSW) pipe_config->output_format = INTEL_OUTPUT_FORMAT_YCBCR444; @@ -3968,15 +3948,15 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, intel_color_get_config(pipe_config); - tmp = intel_de_read(dev_priv, WM_LINETIME(crtc->pipe)); + tmp = intel_de_read(display, WM_LINETIME(crtc->pipe)); pipe_config->linetime = REG_FIELD_GET(HSW_LINETIME_MASK, tmp); - if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) + if (display->platform.broadwell || display->platform.haswell) pipe_config->ips_linetime = REG_FIELD_GET(HSW_IPS_LINETIME_MASK, tmp); if (intel_display_power_get_in_set_if_enabled(display, &crtc->hw_readout_power_domains, POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe))) { - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) skl_scaler_get_config(pipe_config); else ilk_pfit_get_config(pipe_config); @@ -3987,8 +3967,8 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, if (pipe_config->cpu_transcoder != TRANSCODER_EDP && !transcoder_is_dsi(pipe_config->cpu_transcoder)) { pipe_config->pixel_multiplier = - intel_de_read(dev_priv, - TRANS_MULT(dev_priv, pipe_config->cpu_transcoder)) + 1; + intel_de_read(display, + TRANS_MULT(display, pipe_config->cpu_transcoder)) + 1; } else { pipe_config->pixel_multiplier = 1; } @@ -4010,10 +3990,10 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, bool intel_crtc_get_pipe_config(struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - if (!i915->display.funcs.display->get_pipe_config(crtc, crtc_state)) + if (!display->funcs.display->get_pipe_config(crtc, crtc_state)) return false; crtc_state->hw.active = true; @@ -4172,6 +4152,7 @@ static u16 hsw_ips_linetime_wm(const struct intel_crtc_state *crtc_state, static u16 skl_linetime_wm(const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct drm_display_mode *pipe_mode = @@ -4185,7 +4166,7 @@ static u16 skl_linetime_wm(const struct intel_crtc_state *crtc_state) crtc_state->pixel_rate); /* Display WA #1135: BXT:ALL GLK:ALL */ - if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) && + if ((display->platform.geminilake || display->platform.broxton) && skl_watermark_ipc_enabled(dev_priv)) linetime_wm /= 2; @@ -4195,12 +4176,12 @@ static u16 skl_linetime_wm(const struct intel_crtc_state *crtc_state) static int hsw_compute_linetime_wm(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_cdclk_state *cdclk_state; - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) crtc_state->linetime = skl_linetime_wm(crtc_state); else crtc_state->linetime = hsw_linetime_wm(crtc_state); @@ -4222,12 +4203,11 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); int ret; - if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv) && + if (DISPLAY_VER(display) < 5 && !display->platform.g4x && intel_crtc_needs_modeset(crtc_state) && !crtc_state->hw.active) crtc_state->update_wm_post = true; @@ -4244,13 +4224,13 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state, ret = intel_wm_compute(state, crtc); if (ret) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] watermarks are invalid\n", crtc->base.base.id, crtc->base.name); return ret; } - if (DISPLAY_VER(dev_priv) >= 9) { + if (DISPLAY_VER(display) >= 9) { if (intel_crtc_needs_modeset(crtc_state) || intel_crtc_needs_fastset(crtc_state)) { ret = skl_update_scaler_crtc(crtc_state); @@ -4269,8 +4249,8 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state, return ret; } - if (DISPLAY_VER(dev_priv) >= 9 || - IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) { + if (DISPLAY_VER(display) >= 9 || + display->platform.broadwell || display->platform.haswell) { ret = hsw_compute_linetime_wm(state, crtc); if (ret) return ret; @@ -4288,8 +4268,8 @@ static int compute_sink_pipe_bpp(const struct drm_connector_state *conn_state, struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(crtc_state); struct drm_connector *connector = conn_state->connector; - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); const struct drm_display_info *info = &connector->display_info; int bpp; @@ -4312,7 +4292,7 @@ compute_sink_pipe_bpp(const struct drm_connector_state *conn_state, } if (bpp < crtc_state->pipe_bpp) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Limiting display bpp to %d " "(EDID bpp %d, max requested bpp %d, max platform bpp %d)\n", connector->base.id, connector->name, @@ -4330,17 +4310,17 @@ static int compute_baseline_pipe_bpp(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct drm_connector *connector; struct drm_connector_state *connector_state; int bpp, i; - if ((IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) || - IS_CHERRYVIEW(dev_priv))) + if (display->platform.g4x || display->platform.valleyview || + display->platform.cherryview) bpp = 10*3; - else if (DISPLAY_VER(dev_priv) >= 5) + else if (DISPLAY_VER(display) >= 5) bpp = 12*3; else bpp = 8*3; @@ -4364,7 +4344,7 @@ compute_baseline_pipe_bpp(struct intel_atomic_state *state, static bool check_digital_port_conflicts(struct intel_atomic_state *state) { - struct drm_device *dev = state->base.dev; + struct intel_display *display = to_intel_display(state); struct drm_connector *connector; struct drm_connector_list_iter conn_iter; unsigned int used_ports = 0; @@ -4375,14 +4355,14 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state) * We're going to peek into connector->state, * hence connection_mutex must be held. */ - drm_modeset_lock_assert_held(&dev->mode_config.connection_mutex); + drm_modeset_lock_assert_held(&display->drm->mode_config.connection_mutex); /* * Walk the connector list instead of the encoder * list to detect the problem on ddi platforms * where there's just one encoder per digital port. */ - drm_connector_list_iter_begin(dev, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); drm_for_each_connector_iter(connector, &conn_iter) { struct drm_connector_state *connector_state; struct intel_encoder *encoder; @@ -4398,11 +4378,11 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state) encoder = to_intel_encoder(connector_state->best_encoder); - drm_WARN_ON(dev, !connector_state->crtc); + drm_WARN_ON(display->drm, !connector_state->crtc); switch (encoder->type) { case INTEL_OUTPUT_DDI: - if (drm_WARN_ON(dev, !HAS_DDI(to_i915(dev)))) + if (drm_WARN_ON(display->drm, !HAS_DDI(display))) break; fallthrough; case INTEL_OUTPUT_DP: @@ -4550,9 +4530,9 @@ static int intel_crtc_prepare_cleared_state(struct intel_atomic_state *state, struct intel_crtc *crtc) { + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_crtc_state *saved_state; saved_state = intel_crtc_state_alloc(crtc); @@ -4577,8 +4557,8 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state, memcpy(saved_state->icl_port_dplls, crtc_state->icl_port_dplls, sizeof(saved_state->icl_port_dplls)); saved_state->crc_enabled = crtc_state->crc_enabled; - if (IS_G4X(dev_priv) || - IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if (display->platform.g4x || + display->platform.valleyview || display->platform.cherryview) saved_state->wm = crtc_state->wm; memcpy(crtc_state, saved_state, sizeof(*crtc_state)); @@ -4594,7 +4574,7 @@ intel_modeset_pipe_config(struct intel_atomic_state *state, struct intel_crtc *crtc, const struct intel_link_bw_limits *limits) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct drm_connector *connector; @@ -4627,7 +4607,7 @@ intel_modeset_pipe_config(struct intel_atomic_state *state, crtc_state->max_link_bpp_x16 = limits->max_bpp_x16[crtc->pipe]; if (crtc_state->pipe_bpp > fxp_q4_to_int(crtc_state->max_link_bpp_x16)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] Link bpp limited to " FXP_Q4_FMT "\n", crtc->base.base.id, crtc->base.name, FXP_Q4_ARGS(crtc_state->max_link_bpp_x16)); @@ -4657,7 +4637,7 @@ intel_modeset_pipe_config(struct intel_atomic_state *state, continue; if (!check_single_encoder_cloning(state, crtc, encoder)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] rejecting invalid cloning configuration\n", encoder->base.base.id, encoder->base.name); return -EINVAL; @@ -4699,7 +4679,7 @@ intel_modeset_pipe_config(struct intel_atomic_state *state, if (ret == -EDEADLK) return ret; if (ret < 0) { - drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] config failure: %d\n", + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] config failure: %d\n", encoder->base.base.id, encoder->base.name, ret); return ret; } @@ -4715,7 +4695,7 @@ intel_modeset_pipe_config(struct intel_atomic_state *state, if (ret == -EDEADLK) return ret; if (ret < 0) { - drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] config failure: %d\n", + drm_dbg_kms(display->drm, "[CRTC:%d:%s] config failure: %d\n", crtc->base.base.id, crtc->base.name, ret); return ret; } @@ -4726,7 +4706,7 @@ intel_modeset_pipe_config(struct intel_atomic_state *state, */ crtc_state->dither = (crtc_state->pipe_bpp == 6*3) && !crtc_state->dither_force_disable; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] hw max bpp: %i, pipe bpp: %i, dithering: %i\n", crtc->base.base.id, crtc->base.name, base_bpp, crtc_state->pipe_bpp, crtc_state->dither); @@ -4858,7 +4838,7 @@ pipe_config_infoframe_mismatch(struct drm_printer *p, bool fastset, const union hdmi_infoframe *a, const union hdmi_infoframe *b) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); const char *loglevel; if (fastset) { @@ -4873,9 +4853,9 @@ pipe_config_infoframe_mismatch(struct drm_printer *p, bool fastset, pipe_config_mismatch(p, fastset, crtc, name, "infoframe"); drm_printf(p, "expected:\n"); - hdmi_infoframe_log(loglevel, i915->drm.dev, a); + hdmi_infoframe_log(loglevel, display->drm->dev, a); drm_printf(p, "found:\n"); - hdmi_infoframe_log(loglevel, i915->drm.dev, b); + hdmi_infoframe_log(loglevel, display->drm->dev, b); } static void @@ -4991,16 +4971,15 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, bool fastset) { struct intel_display *display = to_intel_display(current_config); - struct drm_i915_private *dev_priv = to_i915(current_config->uapi.crtc->dev); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct drm_printer p; u32 exclude_infoframes = 0; bool ret = true; if (fastset) - p = drm_dbg_printer(&dev_priv->drm, DRM_UT_KMS, NULL); + p = drm_dbg_printer(display->drm, DRM_UT_KMS, NULL); else - p = drm_err_printer(&dev_priv->drm, NULL); + p = drm_err_printer(display->drm, NULL); #define PIPE_CONF_CHECK_X(name) do { \ if (current_config->name != pipe_config->name) { \ @@ -5267,8 +5246,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_I(output_format); PIPE_CONF_CHECK_BOOL(has_hdmi_sink); - if ((DISPLAY_VER(dev_priv) < 8 && !IS_HASWELL(dev_priv)) || - IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if ((DISPLAY_VER(display) < 8 && !display->platform.haswell) || + display->platform.valleyview || display->platform.cherryview) PIPE_CONF_CHECK_BOOL(limited_color_range); PIPE_CONF_CHECK_BOOL(hdmi_scrambling); @@ -5284,7 +5263,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_X(gmch_pfit.control); /* pfit ratios are autocomputed by the hw on gen4+ */ - if (DISPLAY_VER(dev_priv) < 4) + if (DISPLAY_VER(display) < 4) PIPE_CONF_CHECK_X(gmch_pfit.pgm_ratios); PIPE_CONF_CHECK_X(gmch_pfit.lvds_border_bits); @@ -5304,7 +5283,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_I(pixel_rate); PIPE_CONF_CHECK_X(gamma_mode); - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) PIPE_CONF_CHECK_X(cgm_mode); else PIPE_CONF_CHECK_X(csc_mode); @@ -5324,21 +5303,21 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_BOOL(double_wide); - if (dev_priv->display.dpll.mgr) + if (display->dpll.mgr) PIPE_CONF_CHECK_P(shared_dpll); /* FIXME convert everything over the dpll_mgr */ - if (dev_priv->display.dpll.mgr || HAS_GMCH(dev_priv)) + if (display->dpll.mgr || HAS_GMCH(display)) PIPE_CONF_CHECK_PLL(dpll_hw_state); /* FIXME convert MTL+ platforms over to dpll_mgr */ - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) PIPE_CONF_CHECK_PLL_CX0(dpll_hw_state.cx0pll); PIPE_CONF_CHECK_X(dsi_pll.ctrl); PIPE_CONF_CHECK_X(dsi_pll.div); - if (IS_G4X(dev_priv) || DISPLAY_VER(dev_priv) >= 5) + if (display->platform.g4x || DISPLAY_VER(display) >= 5) PIPE_CONF_CHECK_I(pipe_bpp); if (!fastset || !pipe_config->update_m_n) { @@ -5454,11 +5433,11 @@ static int intel_modeset_pipe(struct intel_atomic_state *state, struct intel_crtc_state *crtc_state, const char *reason) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); int ret; - drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] Full modeset due to %s\n", + drm_dbg_kms(display->drm, "[CRTC:%d:%s] Full modeset due to %s\n", crtc->base.base.id, crtc->base.name, reason); ret = drm_atomic_add_affected_connectors(&state->base, @@ -5498,10 +5477,10 @@ static int intel_modeset_pipe(struct intel_atomic_state *state, int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state, const char *reason, u8 mask) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc; - for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, mask) { + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, mask) { struct intel_crtc_state *crtc_state; int ret; @@ -5545,10 +5524,10 @@ intel_crtc_flag_modeset(struct intel_crtc_state *crtc_state) int intel_modeset_all_pipes_late(struct intel_atomic_state *state, const char *reason) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state; int ret; @@ -5688,11 +5667,11 @@ u8 intel_calc_active_pipes(struct intel_atomic_state *state, static int intel_modeset_checks(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); state->modeset = true; - if (IS_HASWELL(dev_priv)) + if (display->platform.haswell) return hsw_mode_set_planes_workaround(state); return 0; @@ -5709,15 +5688,15 @@ static bool lrr_params_changed(const struct drm_display_mode *old_adjusted_mode, static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_state, struct intel_crtc_state *new_crtc_state) { + struct intel_display *display = to_intel_display(new_crtc_state); struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); /* only allow LRR when the timings stay within the VRR range */ if (old_crtc_state->vrr.in_range != new_crtc_state->vrr.in_range) new_crtc_state->update_lrr = false; if (!intel_pipe_config_compare(old_crtc_state, new_crtc_state, true)) { - drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] fastset requirement not met, forcing full modeset\n", + drm_dbg_kms(display->drm, "[CRTC:%d:%s] fastset requirement not met, forcing full modeset\n", crtc->base.base.id, crtc->base.name); } else { if (allow_vblank_delay_fastset(old_crtc_state)) @@ -5741,17 +5720,17 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta static int intel_atomic_check_crtcs(struct intel_atomic_state *state) { + struct intel_display *display = to_intel_display(state); struct intel_crtc_state __maybe_unused *crtc_state; struct intel_crtc *crtc; int i; for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); int ret; ret = intel_crtc_atomic_check(state, crtc); if (ret) { - drm_dbg_atomic(&i915->drm, + drm_dbg_atomic(display->drm, "[CRTC:%d:%s] atomic driver check failed\n", crtc->base.base.id, crtc->base.name); return ret; @@ -5798,7 +5777,7 @@ static bool intel_pipes_need_modeset(struct intel_atomic_state *state, static int intel_atomic_check_joiner(struct intel_atomic_state *state, struct intel_crtc *primary_crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *primary_crtc_state = intel_atomic_get_new_crtc_state(state, primary_crtc); struct intel_crtc *secondary_crtc; @@ -5807,20 +5786,20 @@ static int intel_atomic_check_joiner(struct intel_atomic_state *state, return 0; /* sanity check */ - if (drm_WARN_ON(&i915->drm, + if (drm_WARN_ON(display->drm, primary_crtc->pipe != joiner_primary_pipe(primary_crtc_state))) return -EINVAL; - if (primary_crtc_state->joiner_pipes & ~joiner_pipes(i915)) { - drm_dbg_kms(&i915->drm, + if (primary_crtc_state->joiner_pipes & ~joiner_pipes(display)) { + drm_dbg_kms(display->drm, "[CRTC:%d:%s] Cannot act as joiner primary " "(need 0x%x as pipes, only 0x%x possible)\n", primary_crtc->base.base.id, primary_crtc->base.name, - primary_crtc_state->joiner_pipes, joiner_pipes(i915)); + primary_crtc_state->joiner_pipes, joiner_pipes(display)); return -EINVAL; } - for_each_intel_crtc_in_pipe_mask(&i915->drm, secondary_crtc, + for_each_intel_crtc_in_pipe_mask(display->drm, secondary_crtc, intel_crtc_joiner_secondary_pipes(primary_crtc_state)) { struct intel_crtc_state *secondary_crtc_state; int ret; @@ -5831,7 +5810,7 @@ static int intel_atomic_check_joiner(struct intel_atomic_state *state, /* primary being enabled, secondary was already configured? */ if (secondary_crtc_state->uapi.enable) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] secondary is enabled as normal CRTC, but " "[CRTC:%d:%s] claiming this CRTC for joiner.\n", secondary_crtc->base.base.id, secondary_crtc->base.name, @@ -5850,7 +5829,7 @@ static int intel_atomic_check_joiner(struct intel_atomic_state *state, drm_crtc_index(&secondary_crtc->base))) return -EINVAL; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] Used as secondary for joiner primary [CRTC:%d:%s]\n", secondary_crtc->base.base.id, secondary_crtc->base.name, primary_crtc->base.base.id, primary_crtc->base.name); @@ -5869,12 +5848,12 @@ static int intel_atomic_check_joiner(struct intel_atomic_state *state, static void kill_joiner_secondaries(struct intel_atomic_state *state, struct intel_crtc *primary_crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *primary_crtc_state = intel_atomic_get_new_crtc_state(state, primary_crtc); struct intel_crtc *secondary_crtc; - for_each_intel_crtc_in_pipe_mask(&i915->drm, secondary_crtc, + for_each_intel_crtc_in_pipe_mask(display->drm, secondary_crtc, intel_crtc_joiner_secondary_pipes(primary_crtc_state)) { struct intel_crtc_state *secondary_crtc_state = intel_atomic_get_new_crtc_state(state, secondary_crtc); @@ -5908,7 +5887,7 @@ static void kill_joiner_secondaries(struct intel_atomic_state *state, static int intel_async_flip_check_uapi(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_plane_state *old_plane_state; @@ -5920,14 +5899,14 @@ static int intel_async_flip_check_uapi(struct intel_atomic_state *state, return 0; if (!new_crtc_state->uapi.active) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] not active\n", crtc->base.base.id, crtc->base.name); return -EINVAL; } if (intel_crtc_needs_modeset(new_crtc_state)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] modeset required\n", crtc->base.base.id, crtc->base.name); return -EINVAL; @@ -5938,7 +5917,7 @@ static int intel_async_flip_check_uapi(struct intel_atomic_state *state, * Remove this check once the issues are fixed. */ if (new_crtc_state->joiner_pipes) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] async flip disallowed with joiner\n", crtc->base.base.id, crtc->base.name); return -EINVAL; @@ -5957,14 +5936,14 @@ static int intel_async_flip_check_uapi(struct intel_atomic_state *state, * enabled in the atomic IOCTL path. */ if (!plane->async_flip) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] async flip not supported\n", plane->base.base.id, plane->base.name); return -EINVAL; } if (!old_plane_state->uapi.fb || !new_plane_state->uapi.fb) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] no old or new framebuffer\n", plane->base.base.id, plane->base.name); return -EINVAL; @@ -5976,7 +5955,7 @@ static int intel_async_flip_check_uapi(struct intel_atomic_state *state, static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *old_crtc_state, *new_crtc_state; const struct intel_plane_state *new_plane_state, *old_plane_state; struct intel_plane *plane; @@ -5989,21 +5968,21 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in return 0; if (!new_crtc_state->hw.active) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] not active\n", crtc->base.base.id, crtc->base.name); return -EINVAL; } if (intel_crtc_needs_modeset(new_crtc_state)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] modeset required\n", crtc->base.base.id, crtc->base.name); return -EINVAL; } if (old_crtc_state->active_planes != new_crtc_state->active_planes) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] Active planes cannot be in async flip\n", crtc->base.base.id, crtc->base.name); return -EINVAL; @@ -6019,7 +5998,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in * if we're really about to ask the hardware to perform * an async flip. We should never get this far otherwise. */ - if (drm_WARN_ON(&i915->drm, + if (drm_WARN_ON(display->drm, new_crtc_state->do_async_flip && !plane->async_flip)) return -EINVAL; @@ -6035,7 +6014,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in continue; if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->modifier)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Modifier 0x%llx does not support async flip\n", plane->base.base.id, plane->base.name, new_plane_state->hw.fb->modifier); @@ -6044,7 +6023,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in if (intel_format_info_is_yuv_semiplanar(new_plane_state->hw.fb->format, new_plane_state->hw.fb->modifier)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Planar formats do not support async flips\n", plane->base.base.id, plane->base.name); return -EINVAL; @@ -6059,7 +6038,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in if (old_plane_state->view.color_plane[0].mapping_stride != new_plane_state->view.color_plane[0].mapping_stride) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Stride cannot be changed in async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; @@ -6067,7 +6046,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in if (old_plane_state->hw.fb->modifier != new_plane_state->hw.fb->modifier) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Modifier cannot be changed in async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; @@ -6075,7 +6054,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in if (old_plane_state->hw.fb->format != new_plane_state->hw.fb->format) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Pixel format cannot be changed in async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; @@ -6083,7 +6062,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in if (old_plane_state->hw.rotation != new_plane_state->hw.rotation) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Rotation cannot be changed in async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; @@ -6091,7 +6070,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in if (skl_plane_aux_dist(old_plane_state, 0) != skl_plane_aux_dist(new_plane_state, 0)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] AUX_DIST cannot be changed in async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; @@ -6099,14 +6078,14 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in if (!drm_rect_equals(&old_plane_state->uapi.src, &new_plane_state->uapi.src) || !drm_rect_equals(&old_plane_state->uapi.dst, &new_plane_state->uapi.dst)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Size/co-ordinates cannot be changed in async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; } if (old_plane_state->hw.alpha != new_plane_state->hw.alpha) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANES:%d:%s] Alpha value cannot be changed in async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; @@ -6114,21 +6093,21 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in if (old_plane_state->hw.pixel_blend_mode != new_plane_state->hw.pixel_blend_mode) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Pixel blend mode cannot be changed in async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; } if (old_plane_state->hw.color_encoding != new_plane_state->hw.color_encoding) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Color encoding cannot be changed in async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; } if (old_plane_state->hw.color_range != new_plane_state->hw.color_range) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Color range cannot be changed in async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; @@ -6136,7 +6115,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in /* plane decryption is allow to change only in synchronous flips */ if (old_plane_state->decrypt != new_plane_state->decrypt) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Decryption cannot be changed in async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; @@ -6148,7 +6127,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in static int intel_joiner_add_affected_crtcs(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_plane_state *plane_state; struct intel_crtc_state *crtc_state; struct intel_plane *plane; @@ -6179,13 +6158,13 @@ static int intel_joiner_add_affected_crtcs(struct intel_atomic_state *state) modeset_pipes |= crtc_state->joiner_pipes; } - for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, affected_pipes) { + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, affected_pipes) { crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); if (IS_ERR(crtc_state)) return PTR_ERR(crtc_state); } - for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, modeset_pipes) { + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, modeset_pipes) { int ret; crtc_state = intel_atomic_get_new_crtc_state(state, crtc); @@ -6215,7 +6194,7 @@ static int intel_atomic_check_config(struct intel_atomic_state *state, struct intel_link_bw_limits *limits, enum pipe *failed_pipe) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; int ret; @@ -6240,7 +6219,7 @@ static int intel_atomic_check_config(struct intel_atomic_state *state, continue; } - if (drm_WARN_ON(&i915->drm, intel_crtc_is_joiner_secondary(new_crtc_state))) + if (drm_WARN_ON(display->drm, intel_crtc_is_joiner_secondary(new_crtc_state))) continue; ret = intel_crtc_prepare_cleared_state(state, crtc); @@ -6259,7 +6238,7 @@ static int intel_atomic_check_config(struct intel_atomic_state *state, if (!intel_crtc_needs_modeset(new_crtc_state)) continue; - if (drm_WARN_ON(&i915->drm, intel_crtc_is_joiner_secondary(new_crtc_state))) + if (drm_WARN_ON(display->drm, intel_crtc_is_joiner_secondary(new_crtc_state))) continue; if (!new_crtc_state->hw.enable) @@ -6324,7 +6303,6 @@ int intel_atomic_check(struct drm_device *dev, struct drm_atomic_state *_state) { struct intel_display *display = to_intel_display(dev); - struct drm_i915_private *dev_priv = to_i915(dev); struct intel_atomic_state *state = to_intel_atomic_state(_state); struct intel_crtc_state *old_crtc_state, *new_crtc_state; struct intel_crtc *crtc; @@ -6372,7 +6350,7 @@ int intel_atomic_check(struct drm_device *dev, continue; if (intel_crtc_is_joiner_secondary(new_crtc_state)) { - drm_WARN_ON(&dev_priv->drm, new_crtc_state->uapi.enable); + drm_WARN_ON(display->drm, new_crtc_state->uapi.enable); continue; } @@ -6443,7 +6421,7 @@ int intel_atomic_check(struct drm_device *dev, } if (any_ms && !check_digital_port_conflicts(state)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "rejecting conflicting digital port configuration\n"); ret = -EINVAL; goto fail; @@ -6499,7 +6477,7 @@ int intel_atomic_check(struct drm_device *dev, goto fail; /* Either full modeset or fastset (or neither), never both */ - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, intel_crtc_needs_modeset(new_crtc_state) && intel_crtc_needs_fastset(new_crtc_state)); @@ -6559,6 +6537,7 @@ void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc, static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state, const struct intel_crtc_state *new_crtc_state) { + struct intel_display *display = to_intel_display(new_crtc_state); struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -6573,7 +6552,7 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state, intel_set_pipe_src_size(new_crtc_state); /* on skylake this is done by detaching scalers */ - if (DISPLAY_VER(dev_priv) >= 9) { + if (DISPLAY_VER(display) >= 9) { if (new_crtc_state->pch_pfit.enabled) skl_pfit_enable(new_crtc_state); } else if (HAS_PCH_SPLIT(dev_priv)) { @@ -6591,8 +6570,8 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state, * HSW/BDW only really need this here for fastboot, after * that the value should not change without a full modeset. */ - if (DISPLAY_VER(dev_priv) >= 9 || - IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) + if (DISPLAY_VER(display) >= 9 || + display->platform.broadwell || display->platform.haswell) hsw_set_linetime_wm(new_crtc_state); if (new_crtc_state->update_m_n) @@ -6606,14 +6585,14 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state, static void commit_pipe_pre_planes(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); bool modeset = intel_crtc_needs_modeset(new_crtc_state); - drm_WARN_ON(&dev_priv->drm, new_crtc_state->use_dsb); + drm_WARN_ON(display->drm, new_crtc_state->use_dsb); /* * During modesets pipe configuration was programmed as the @@ -6623,7 +6602,7 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state, if (intel_crtc_needs_color_update(new_crtc_state)) intel_color_commit_arm(NULL, new_crtc_state); - if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) + if (DISPLAY_VER(display) >= 9 || display->platform.broadwell) bdw_set_pipe_misc(NULL, new_crtc_state); if (intel_crtc_needs_fastset(new_crtc_state)) @@ -6638,18 +6617,18 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state, static void commit_pipe_post_planes(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - drm_WARN_ON(&dev_priv->drm, new_crtc_state->use_dsb); + drm_WARN_ON(display->drm, new_crtc_state->use_dsb); /* * Disable the scaler(s) after the plane(s) so that we don't * get a catastrophic underrun even if the two operations * end up happening in two different frames. */ - if (DISPLAY_VER(dev_priv) >= 9 && + if (DISPLAY_VER(display) >= 9 && !intel_crtc_needs_modeset(new_crtc_state)) skl_detach_scalers(NULL, new_crtc_state); @@ -6660,7 +6639,7 @@ static void commit_pipe_post_planes(struct intel_atomic_state *state, static void intel_enable_crtc(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_crtc *pipe_crtc; @@ -6668,7 +6647,7 @@ static void intel_enable_crtc(struct intel_atomic_state *state, if (!intel_crtc_needs_modeset(new_crtc_state)) return; - for_each_intel_crtc_in_pipe_mask_reverse(&dev_priv->drm, pipe_crtc, + for_each_intel_crtc_in_pipe_mask_reverse(display->drm, pipe_crtc, intel_crtc_joined_pipe_mask(new_crtc_state)) { const struct intel_crtc_state *pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); @@ -6677,7 +6656,7 @@ static void intel_enable_crtc(struct intel_atomic_state *state, intel_crtc_update_active_timings(pipe_crtc_state, false); } - dev_priv->display.funcs.display->crtc_enable(state, crtc); + display->funcs.display->crtc_enable(state, crtc); /* vblanks work again, re-enable pipe CRC. */ intel_crtc_enable_pipe_crc(crtc); @@ -6687,7 +6666,6 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(state->base.dev); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc_state *new_crtc_state = @@ -6696,7 +6674,7 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state, if (old_crtc_state->inherited || intel_crtc_needs_modeset(new_crtc_state)) { - if (HAS_DPT(i915)) + if (HAS_DPT(display)) intel_dpt_configure(crtc); } @@ -6710,7 +6688,7 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state, if (intel_crtc_needs_fastset(new_crtc_state)) intel_encoders_update_pipe(state, crtc); - if (DISPLAY_VER(i915) >= 11 && + if (DISPLAY_VER(display) >= 11 && intel_crtc_needs_fastset(new_crtc_state)) icl_set_pipe_chicken(new_crtc_state); @@ -6784,7 +6762,7 @@ static void intel_update_crtc(struct intel_atomic_state *state, static void intel_old_crtc_state_disables(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc *pipe_crtc; @@ -6793,13 +6771,13 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state, * We need to disable pipe CRC before disabling the pipe, * or we race against vblank off. */ - for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, pipe_crtc, + for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc, intel_crtc_joined_pipe_mask(old_crtc_state)) intel_crtc_disable_pipe_crc(pipe_crtc); - dev_priv->display.funcs.display->crtc_disable(state, crtc); + display->funcs.display->crtc_disable(state, crtc); - for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, pipe_crtc, + for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc, intel_crtc_joined_pipe_mask(old_crtc_state)) { const struct intel_crtc_state *new_pipe_crtc_state = intel_atomic_get_new_crtc_state(state, pipe_crtc); @@ -6814,7 +6792,7 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state, static void intel_commit_modeset_disables(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; u8 disable_pipes = 0; @@ -6881,7 +6859,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) disable_pipes &= ~intel_crtc_joined_pipe_mask(old_crtc_state); } - drm_WARN_ON(&i915->drm, disable_pipes); + drm_WARN_ON(display->drm, disable_pipes); } static void intel_commit_modeset_enables(struct intel_atomic_state *state) @@ -6908,7 +6886,7 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state) static void skl_commit_modeset_enables(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc; struct intel_crtc_state *old_crtc_state, *new_crtc_state; struct skl_ddb_entry entries[I915_MAX_PIPES] = {}; @@ -7050,8 +7028,9 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) if ((update_pipes & BIT(pipe)) == 0) continue; - drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb, - entries, I915_MAX_PIPES, pipe)); + drm_WARN_ON(display->drm, + skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb, + entries, I915_MAX_PIPES, pipe)); entries[pipe] = new_crtc_state->wm.skl.ddb; update_pipes &= ~BIT(pipe); @@ -7059,8 +7038,8 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) intel_update_crtc(state, crtc); } - drm_WARN_ON(&dev_priv->drm, modeset_pipes); - drm_WARN_ON(&dev_priv->drm, update_pipes); + drm_WARN_ON(display->drm, modeset_pipes); + drm_WARN_ON(display->drm, update_pipes); } static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_state) @@ -7105,7 +7084,7 @@ static void intel_atomic_cleanup_work(struct work_struct *work) { struct intel_atomic_state *state = container_of(work, struct intel_atomic_state, cleanup_work); - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *old_crtc_state; struct intel_crtc *crtc; int i; @@ -7113,14 +7092,14 @@ static void intel_atomic_cleanup_work(struct work_struct *work) for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) intel_atomic_dsb_cleanup(old_crtc_state); - drm_atomic_helper_cleanup_planes(&i915->drm, &state->base); + drm_atomic_helper_cleanup_planes(display->drm, &state->base); drm_atomic_helper_commit_cleanup_done(&state->base); drm_atomic_state_put(&state->base); } static void intel_atomic_prepare_plane_clear_colors(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_plane *plane; struct intel_plane_state *plane_state; int i; @@ -7157,7 +7136,7 @@ static void intel_atomic_prepare_plane_clear_colors(struct intel_atomic_state *s &plane_state->ccval, sizeof(plane_state->ccval)); /* The above could only fail if the FB obj has an unexpected backing store type. */ - drm_WARN_ON(&i915->drm, ret); + drm_WARN_ON(display->drm, ret); } } @@ -7258,8 +7237,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, static void intel_atomic_commit_tail(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_device *dev = state->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {}; @@ -7338,7 +7316,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_pmdemand_pre_plane_update(state); if (state->modeset) { - drm_atomic_helper_update_legacy_modeset_state(dev, &state->base); + drm_atomic_helper_update_legacy_modeset_state(display->drm, &state->base); intel_set_cdclk_pre_plane_update(state); @@ -7353,10 +7331,10 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) /* Complete events for now disable pipes here. */ if (modeset && !new_crtc_state->hw.active && new_crtc_state->uapi.event) { - spin_lock_irq(&dev->event_lock); + spin_lock_irq(&display->drm->event_lock); drm_crtc_send_vblank_event(&crtc->base, new_crtc_state->uapi.event); - spin_unlock_irq(&dev->event_lock); + spin_unlock_irq(&display->drm->event_lock); new_crtc_state->uapi.event = NULL; } @@ -7372,7 +7350,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) } /* Now enable the clocks, plane, pipe, and connectors that we set up. */ - dev_priv->display.funcs.display->commit_modeset_enables(state); + display->funcs.display->commit_modeset_enables(state); intel_program_dpkgc_latency(state); @@ -7390,7 +7368,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * - switch over to the vblank wait helper in the core after that since * we don't need out special handling any more. */ - drm_atomic_helper_wait_for_flip_done(dev, &state->base); + drm_atomic_helper_wait_for_flip_done(display->drm, &state->base); for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { if (new_crtc_state->do_async_flip) @@ -7419,7 +7397,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * chance of catching underruns with the intermediate watermarks * vs. the new plane configuration. */ - if (DISPLAY_VER(dev_priv) == 2 && planes_enabling(old_crtc_state, new_crtc_state)) + if (DISPLAY_VER(display) == 2 && planes_enabling(old_crtc_state, new_crtc_state)) intel_set_cpu_fifo_underrun_reporting(display, crtc->pipe, true); intel_optimize_watermarks(state, crtc); @@ -7485,7 +7463,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * down. */ INIT_WORK(&state->cleanup_work, intel_atomic_cleanup_work); - queue_work(dev_priv->display.wq.cleanup, &state->cleanup_work); + queue_work(display->wq.cleanup, &state->cleanup_work); } static void intel_atomic_commit_work(struct work_struct *work) @@ -7544,6 +7522,7 @@ static int intel_atomic_swap_state(struct intel_atomic_state *state) int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, bool nonblock) { + struct intel_display *display = to_intel_display(dev); struct intel_atomic_state *state = to_intel_atomic_state(_state); struct drm_i915_private *dev_priv = to_i915(dev); int ret = 0; @@ -7567,7 +7546,7 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, * FIXME doing watermarks and fb cleanup from a vblank worker * (assuming we had any) would solve these problems. */ - if (DISPLAY_VER(dev_priv) < 9 && state->base.legacy_cursor_update) { + if (DISPLAY_VER(display) < 9 && state->base.legacy_cursor_update) { struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; int i; @@ -7580,7 +7559,7 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, ret = intel_atomic_prepare_commit(state); if (ret) { - drm_dbg_atomic(&dev_priv->drm, + drm_dbg_atomic(display->drm, "Preparing state failed with %i\n", ret); intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); return ret; @@ -7600,12 +7579,12 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, INIT_WORK(&state->base.commit_work, intel_atomic_commit_work); if (nonblock && state->modeset) { - queue_work(dev_priv->display.wq.modeset, &state->base.commit_work); + queue_work(display->wq.modeset, &state->base.commit_work); } else if (nonblock) { - queue_work(dev_priv->display.wq.flip, &state->base.commit_work); + queue_work(display->wq.flip, &state->base.commit_work); } else { if (state->modeset) - flush_workqueue(dev_priv->display.wq.modeset); + flush_workqueue(display->wq.modeset); intel_atomic_commit_tail(state); } @@ -7614,11 +7593,11 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, static u32 intel_encoder_possible_clones(struct intel_encoder *encoder) { - struct drm_device *dev = encoder->base.dev; + struct intel_display *display = to_intel_display(encoder); struct intel_encoder *source_encoder; u32 possible_clones = 0; - for_each_intel_encoder(dev, source_encoder) { + for_each_intel_encoder(display->drm, source_encoder) { if (encoders_cloneable(encoder, source_encoder)) possible_clones |= drm_encoder_mask(&source_encoder->base); } @@ -7628,11 +7607,11 @@ static u32 intel_encoder_possible_clones(struct intel_encoder *encoder) static u32 intel_encoder_possible_crtcs(struct intel_encoder *encoder) { - struct drm_device *dev = encoder->base.dev; + struct intel_display *display = to_intel_display(encoder); struct intel_crtc *crtc; u32 possible_crtcs = 0; - for_each_intel_crtc_in_pipe_mask(dev, crtc, encoder->pipe_mask) + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, encoder->pipe_mask) possible_crtcs |= drm_crtc_mask(&crtc->base); return possible_crtcs; @@ -7852,9 +7831,8 @@ void intel_setup_outputs(struct intel_display *display) drm_helper_move_panel_connectors_to_head(display->drm); } -static int max_dotclock(struct drm_i915_private *i915) +static int max_dotclock(struct intel_display *display) { - struct intel_display *display = &i915->display; int max_dotclock = display->cdclk.max_dotclk_freq; if (HAS_ULTRAJOINER(display)) @@ -7868,7 +7846,7 @@ static int max_dotclock(struct drm_i915_private *i915) enum drm_mode_status intel_mode_valid(struct drm_device *dev, const struct drm_display_mode *mode) { - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(dev); int hdisplay_max, htotal_max; int vdisplay_max, vtotal_max; @@ -7905,22 +7883,22 @@ enum drm_mode_status intel_mode_valid(struct drm_device *dev, * Reject clearly excessive dotclocks early to * avoid having to worry about huge integers later. */ - if (mode->clock > max_dotclock(dev_priv)) + if (mode->clock > max_dotclock(display)) return MODE_CLOCK_HIGH; /* Transcoder timing limits */ - if (DISPLAY_VER(dev_priv) >= 11) { + if (DISPLAY_VER(display) >= 11) { hdisplay_max = 16384; vdisplay_max = 8192; htotal_max = 16384; vtotal_max = 8192; - } else if (DISPLAY_VER(dev_priv) >= 9 || - IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) { + } else if (DISPLAY_VER(display) >= 9 || + display->platform.broadwell || display->platform.haswell) { hdisplay_max = 8192; /* FDI max 4096 handled elsewhere */ vdisplay_max = 4096; htotal_max = 8192; vtotal_max = 8192; - } else if (DISPLAY_VER(dev_priv) >= 3) { + } else if (DISPLAY_VER(display) >= 3) { hdisplay_max = 4096; vdisplay_max = 4096; htotal_max = 8192; diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_pll.h b/drivers/gpu/drm/i915/display/vlv_dsi_pll.h index a032cc2a2524..f975660fa609 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi_pll.h +++ b/drivers/gpu/drm/i915/display/vlv_dsi_pll.h @@ -23,7 +23,6 @@ u32 vlv_dsi_get_pclk(struct intel_encoder *encoder, struct intel_crtc_state *config); void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port); -bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv); int bxt_dsi_pll_compute(struct intel_encoder *encoder, struct intel_crtc_state *config); void bxt_dsi_pll_enable(struct intel_encoder *encoder, @@ -34,9 +33,14 @@ u32 bxt_dsi_get_pclk(struct intel_encoder *encoder, void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port); #ifdef I915 +bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv); void assert_dsi_pll_enabled(struct intel_display *display); void assert_dsi_pll_disabled(struct intel_display *display); #else +static inline bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv) +{ + return false; +} static inline void assert_dsi_pll_enabled(struct intel_display *display) { } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8084debd28a2..c5064eebe063 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4165,8 +4165,8 @@ enum skl_power_gate { _MMIO_PIPE(pipe, _PIPE_FLIPDONETMSTMP_A, _PIPE_FLIPDONETMSTMP_B) #define _VLV_PIPE_MSA_MISC_A 0x70048 -#define VLV_PIPE_MSA_MISC(pipe) \ - _MMIO_PIPE2(dev_priv, pipe, _VLV_PIPE_MSA_MISC_A) +#define VLV_PIPE_MSA_MISC(__display, pipe) \ + _MMIO_PIPE2(__display, pipe, _VLV_PIPE_MSA_MISC_A) #define VLV_MSA_MISC1_HW_ENABLE REG_BIT(31) #define VLV_MSA_MISC1_SW_S3D_MASK REG_GENMASK(2, 0) /* MSA MISC1 3:1 */ From f2887e7ff3eede887ae0980169dfd1932e4f086e Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 5 Mar 2025 12:01:06 +0100 Subject: [PATCH 58/92] drm/xe/display: Fix fbdev GGTT mapping handling. FBDEV ggtt is not restored correctly, add missing GGTT flag to intel_fbdev_fb_alloc to make it work. This ensures that the global GGTT mapping is always restored on resume. The GGTT mapping would otherwise be created in intel_fb_pin_to_ggtt() by intel_fbdev anyway. This fixes the fbdev device not working after resume. Fixes: 67a98f7e27ba ("drm/xe/display: Re-use display vmas when possible") Cc: Lucas De Marchi Reviewed-by: Lucas De Marchi Link: https://patchwork.freedesktop.org/patch/msgid/20250305110106.564366-1-dev@lankhorst.se Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/xe/display/intel_fbdev_fb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c index ca95fcd098ec..3a1e505ff182 100644 --- a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c +++ b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c @@ -45,7 +45,7 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, NULL, size, ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT | XE_BO_FLAG_STOLEN | - XE_BO_FLAG_PINNED); + XE_BO_FLAG_GGTT | XE_BO_FLAG_PINNED); if (!IS_ERR(obj)) drm_info(&xe->drm, "Allocated fbdev into stolen\n"); else @@ -56,7 +56,7 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, obj = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe), NULL, size, ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT | XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) | - XE_BO_FLAG_PINNED); + XE_BO_FLAG_GGTT | XE_BO_FLAG_PINNED); } if (IS_ERR(obj)) { From d0a83b2e212dbb3e61c08e154f48d7238a4a8950 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Dec 2024 18:08:42 +0100 Subject: [PATCH 59/92] drm/{i915, xe}: Suspend/resume fbdev emulation via client interfaces Implement drm_client_dev_suspend() and drm_client_dev_resume() for i915's fbdev emulation and call the helper via DRM client interfaces. This is required to convert i915 and xe to DRM's generic fbdev client. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Rodrigo Vivi Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-2-tzimmermann@suse.de Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_fbdev.c | 16 ++++++++++++++++ drivers/gpu/drm/i915/i915_driver.c | 9 +++++---- drivers/gpu/drm/xe/display/xe_display.c | 10 ++++++---- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 64fbd2461df3..ea5f92906354 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -643,11 +643,27 @@ static int intel_fbdev_client_hotplug(struct drm_client_dev *client) return ret; } +static int intel_fbdev_client_suspend(struct drm_client_dev *client, bool holds_console_lock) +{ + intel_fbdev_set_suspend(client->dev, FBINFO_STATE_SUSPENDED, true); + + return 0; +} + +static int intel_fbdev_client_resume(struct drm_client_dev *client, bool holds_console_lock) +{ + intel_fbdev_set_suspend(client->dev, FBINFO_STATE_RUNNING, false); + + return 0; +} + static const struct drm_client_funcs intel_fbdev_client_funcs = { .owner = THIS_MODULE, .unregister = intel_fbdev_client_unregister, .restore = intel_fbdev_client_restore, .hotplug = intel_fbdev_client_hotplug, + .suspend = intel_fbdev_client_suspend, + .resume = intel_fbdev_client_resume, }; void intel_fbdev_setup(struct drm_i915_private *i915) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 59bf2d45403f..2cabfd611671 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -41,6 +41,8 @@ #include #include +#include +#include #include #include #include @@ -54,7 +56,6 @@ #include "display/intel_dp.h" #include "display/intel_dpt.h" #include "display/intel_encoder.h" -#include "display/intel_fbdev.h" #include "display/intel_hotplug.h" #include "display/intel_overlay.h" #include "display/intel_pch_refclk.h" @@ -968,7 +969,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915) intel_runtime_pm_disable(&i915->runtime_pm); intel_power_domains_disable(display); - intel_fbdev_set_suspend(&i915->drm, FBINFO_STATE_SUSPENDED, true); + drm_client_dev_suspend(&i915->drm, false); if (HAS_DISPLAY(i915)) { drm_kms_helper_poll_disable(&i915->drm); intel_display_driver_disable_user_access(display); @@ -1051,7 +1052,7 @@ static int i915_drm_suspend(struct drm_device *dev) /* We do a lot of poking in a lot of registers, make sure they work * properly. */ intel_power_domains_disable(display); - intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED, true); + drm_client_dev_suspend(dev, false); if (HAS_DISPLAY(dev_priv)) { drm_kms_helper_poll_disable(dev); intel_display_driver_disable_user_access(display); @@ -1237,7 +1238,7 @@ static int i915_drm_resume(struct drm_device *dev) intel_opregion_resume(display); - intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING, false); + drm_client_dev_resume(dev, false); intel_power_domains_enable(display); diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 02a413a07382..0c1b45b855de 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -8,6 +8,8 @@ #include +#include +#include #include #include #include @@ -25,7 +27,6 @@ #include "intel_dmc_wl.h" #include "intel_dp.h" #include "intel_encoder.h" -#include "intel_fbdev.h" #include "intel_hdcp.h" #include "intel_hotplug.h" #include "intel_opregion.h" @@ -348,7 +349,7 @@ void xe_display_pm_suspend(struct xe_device *xe) * properly. */ intel_power_domains_disable(display); - intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true); + drm_client_dev_suspend(&xe->drm, false); if (has_display(xe)) { drm_kms_helper_poll_disable(&xe->drm); @@ -378,7 +379,8 @@ void xe_display_pm_shutdown(struct xe_device *xe) return; intel_power_domains_disable(display); - intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true); + drm_client_dev_suspend(&xe->drm, false); + if (has_display(xe)) { drm_kms_helper_poll_disable(&xe->drm); intel_display_driver_disable_user_access(display); @@ -497,7 +499,7 @@ void xe_display_pm_resume(struct xe_device *xe) intel_opregion_resume(display); - intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_RUNNING, false); + drm_client_dev_resume(&xe->drm, false); intel_power_domains_enable(display); } From 603cc828aa70260ee28e5ba6a085fdc0d6485941 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Dec 2024 18:08:43 +0100 Subject: [PATCH 60/92] drm/client: Add client-hotplug helper Move client hotplug calls to drm_client_hotplug(). We'll need this helper to send hotplug events after resuming. Signed-off-by: Thomas Zimmermann Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-3-tzimmermann@suse.de Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_client_event.c | 32 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/drm_client_event.c b/drivers/gpu/drm/drm_client_event.c index e303de564485..8514df4a2e65 100644 --- a/drivers/gpu/drm/drm_client_event.c +++ b/drivers/gpu/drm/drm_client_event.c @@ -49,6 +49,23 @@ void drm_client_dev_unregister(struct drm_device *dev) } EXPORT_SYMBOL(drm_client_dev_unregister); +static void drm_client_hotplug(struct drm_client_dev *client) +{ + struct drm_device *dev = client->dev; + int ret; + + if (!client->funcs || !client->funcs->hotplug) + return; + + if (client->hotplug_failed) + return; + + ret = client->funcs->hotplug(client); + drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret); + if (ret) + client->hotplug_failed = true; +} + /** * drm_client_dev_hotplug - Send hotplug event to clients * @dev: DRM device @@ -61,7 +78,6 @@ EXPORT_SYMBOL(drm_client_dev_unregister); void drm_client_dev_hotplug(struct drm_device *dev) { struct drm_client_dev *client; - int ret; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return; @@ -72,18 +88,8 @@ void drm_client_dev_hotplug(struct drm_device *dev) } mutex_lock(&dev->clientlist_mutex); - list_for_each_entry(client, &dev->clientlist, list) { - if (!client->funcs || !client->funcs->hotplug) - continue; - - if (client->hotplug_failed) - continue; - - ret = client->funcs->hotplug(client); - drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret); - if (ret) - client->hotplug_failed = true; - } + list_for_each_entry(client, &dev->clientlist, list) + drm_client_hotplug(client); mutex_unlock(&dev->clientlist_mutex); } EXPORT_SYMBOL(drm_client_dev_hotplug); From a93247b58d04750a5d8dff922053d8d7ad6e8917 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Dec 2024 18:08:44 +0100 Subject: [PATCH 61/92] drm/client: Send pending hotplug events after resume If a hotplug event arrives while the client has been suspended, DRM's client code will deliver the event after resuming. The functionality has been taken form i915, where it can be removed by a later commit. Signed-off-by: Thomas Zimmermann Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-4-tzimmermann@suse.de Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_client_event.c | 9 +++++++++ include/drm/drm_client.h | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/drm_client_event.c b/drivers/gpu/drm/drm_client_event.c index 8514df4a2e65..bd93cd93d519 100644 --- a/drivers/gpu/drm/drm_client_event.c +++ b/drivers/gpu/drm/drm_client_event.c @@ -60,6 +60,12 @@ static void drm_client_hotplug(struct drm_client_dev *client) if (client->hotplug_failed) return; + if (client->suspended) { + client->hotplug_pending = true; + return; + } + + client->hotplug_pending = false; ret = client->funcs->hotplug(client); drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret); if (ret) @@ -159,6 +165,9 @@ static int drm_client_resume(struct drm_client_dev *client, bool holds_console_l client->suspended = false; + if (client->hotplug_pending) + drm_client_hotplug(client); + return ret; } diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 3b13cf29ed55..146ca80e35db 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -142,6 +142,14 @@ struct drm_client_dev { */ bool suspended; + /** + * @hotplug_pending: + * + * A hotplug event has been received while the client was suspended. + * Try again on resume. + */ + bool hotplug_pending; + /** * @hotplug_failed: * From f4e43719d026696f4f20a420eadf67e3f55729b6 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Dec 2024 18:08:45 +0100 Subject: [PATCH 62/92] drm/i915/display: Remove fbdev suspend and hotplug tracking The DRM client code already tracks suspend status and hotplug events for each client. Remove similar code from i915's fbdev client. Allows for the removal of all hdp_* fields form struct intel_fbdev. Calls to intel_fbdev_output_poll_changed() are reduced the shared helper drm_fb_helper_hotplug_event(). Signed-off-by: Thomas Zimmermann Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-5-tzimmermann@suse.de Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_fbdev.c | 63 +--------------------- 1 file changed, 2 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index ea5f92906354..024dde94b1d7 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -61,14 +61,6 @@ struct intel_fbdev { struct i915_vma *vma; unsigned long vma_flags; int preferred_bpp; - - /* Whether or not fbdev hpd processing is temporarily suspended */ - bool hpd_suspended: 1; - /* Set when a hotplug was received while HPD processing was suspended */ - bool hpd_waiting: 1; - - /* Protects hpd_suspended */ - struct mutex hpd_lock; }; static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper) @@ -187,12 +179,6 @@ static int intelfb_create(struct drm_fb_helper *helper, struct drm_gem_object *obj; int ret; - mutex_lock(&ifbdev->hpd_lock); - ret = ifbdev->hpd_suspended ? -EAGAIN : 0; - mutex_unlock(&ifbdev->hpd_lock); - if (ret) - return ret; - ifbdev->fb = NULL; if (fb && @@ -459,27 +445,6 @@ static void intel_fbdev_suspend_worker(struct work_struct *work) true); } -/* Suspends/resumes fbdev processing of incoming HPD events. When resuming HPD - * processing, fbdev will perform a full connector reprobe if a hotplug event - * was received while HPD was suspended. - */ -static void intel_fbdev_hpd_set_suspend(struct drm_i915_private *i915, int state) -{ - struct intel_fbdev *ifbdev = i915->display.fbdev.fbdev; - bool send_hpd = false; - - mutex_lock(&ifbdev->hpd_lock); - ifbdev->hpd_suspended = state == FBINFO_STATE_SUSPENDED; - send_hpd = !ifbdev->hpd_suspended && ifbdev->hpd_waiting; - ifbdev->hpd_waiting = false; - mutex_unlock(&ifbdev->hpd_lock); - - if (send_hpd) { - drm_dbg_kms(&i915->drm, "Handling delayed fbcon HPD event\n"); - drm_fb_helper_hotplug_event(&ifbdev->helper); - } -} - void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous) { struct drm_i915_private *dev_priv = to_i915(dev); @@ -493,7 +458,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous return; if (!ifbdev->vma) - goto set_suspend; + return; info = ifbdev->helper.info; @@ -536,28 +501,6 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous drm_fb_helper_set_suspend(&ifbdev->helper, state); console_unlock(); - -set_suspend: - intel_fbdev_hpd_set_suspend(dev_priv, state); -} - -static int intel_fbdev_output_poll_changed(struct drm_device *dev) -{ - struct intel_fbdev *ifbdev = to_i915(dev)->display.fbdev.fbdev; - bool send_hpd; - - if (!ifbdev) - return -EINVAL; - - mutex_lock(&ifbdev->hpd_lock); - send_hpd = !ifbdev->hpd_suspended; - ifbdev->hpd_waiting = true; - mutex_unlock(&ifbdev->hpd_lock); - - if (send_hpd && (ifbdev->vma || ifbdev->helper.deferred_setup)) - drm_fb_helper_hotplug_event(&ifbdev->helper); - - return 0; } static int intel_fbdev_restore_mode(struct drm_i915_private *dev_priv) @@ -622,7 +565,7 @@ static int intel_fbdev_client_hotplug(struct drm_client_dev *client) int ret; if (dev->fb_helper) - return intel_fbdev_output_poll_changed(dev); + return drm_fb_helper_hotplug_event(dev->fb_helper); ret = drm_fb_helper_init(dev, fb_helper); if (ret) @@ -682,7 +625,6 @@ void intel_fbdev_setup(struct drm_i915_private *i915) i915->display.fbdev.fbdev = ifbdev; INIT_WORK(&i915->display.fbdev.suspend_work, intel_fbdev_suspend_worker); - mutex_init(&ifbdev->hpd_lock); if (intel_fbdev_init_bios(dev, ifbdev)) ifbdev->helper.preferred_bpp = ifbdev->preferred_bpp; else @@ -701,7 +643,6 @@ void intel_fbdev_setup(struct drm_i915_private *i915) err_drm_fb_helper_unprepare: drm_fb_helper_unprepare(&ifbdev->helper); - mutex_destroy(&ifbdev->hpd_lock); kfree(ifbdev); } From 2ef5754c9649151ce438c9b30ec720840762d2a2 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Dec 2024 18:08:46 +0100 Subject: [PATCH 63/92] drm/i915/display: fbdev: Move custom restore code to new callback i915's fbdev contains code for restoring the client's framebuffer. It is specific to i195 and cannot be ported to the common fbdev client. Introduce the callback struct drm_fb_helper.fb_restore and implement it for i915. The fbdev helpers invoke the callback after restoring the fbdev client. Signed-off-by: Thomas Zimmermann Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-6-tzimmermann@suse.de Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_fb_helper.c | 3 +++ drivers/gpu/drm/i915/display/intel_fbdev.c | 10 ++++++++-- include/drm/drm_fb_helper.h | 13 +++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index fb3614a7ba44..87bb25648d92 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -245,6 +245,9 @@ __drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper, if (do_delayed) drm_fb_helper_hotplug_event(fb_helper); + if (fb_helper->funcs->fb_restore) + fb_helper->funcs->fb_restore(fb_helper); + return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 024dde94b1d7..408e44251c47 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -278,9 +278,17 @@ static int intelfb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *cli return 0; } +static void intelfb_restore(struct drm_fb_helper *fb_helper) +{ + struct intel_fbdev *ifbdev = to_intel_fbdev(fb_helper); + + intel_fbdev_invalidate(ifbdev); +} + static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { .fb_probe = intelfb_create, .fb_dirty = intelfb_dirty, + .fb_restore = intelfb_restore, }; /* @@ -518,8 +526,6 @@ static int intel_fbdev_restore_mode(struct drm_i915_private *dev_priv) if (ret) return ret; - intel_fbdev_invalidate(ifbdev); - return 0; } diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 8426b9921a03..a7d7a3b945ea 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -99,6 +99,19 @@ struct drm_fb_helper_funcs { * 0 on success, or an error code otherwise. */ int (*fb_dirty)(struct drm_fb_helper *helper, struct drm_clip_rect *clip); + + /** + * @fb_restore: + * + * Driver callback to restore internal fbdev state. If set, fbdev + * emulation will invoke this callback after restoring the display + * mode. + * + * Only for i915. Do not use in new code. + * + * TODO: Fix i915 to not require this callback. + */ + void (*fb_restore)(struct drm_fb_helper *helper); }; /** From a1c008b987d0f0fc5a9d746dd7782350ba48ce57 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Dec 2024 18:08:47 +0100 Subject: [PATCH 64/92] drm/i915/display: fbdev: Move custom suspend code to new callback If the fbdev buffer is backed by stolen memory, it has to be cleared upon resume from hibernation. Move the code into the new callback fb_set_suspend, so that it can run from DRM's generic fbdev client. No functional change. Other drivers are not affected. Signed-off-by: Thomas Zimmermann Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-7-tzimmermann@suse.de Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_fb_helper.c | 9 +++++-- drivers/gpu/drm/i915/display/intel_fbdev.c | 28 +++++++++++++--------- include/drm/drm_fb_helper.h | 14 +++++++++++ 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 87bb25648d92..0703fddd750f 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -757,7 +757,12 @@ EXPORT_SYMBOL(drm_fb_helper_deferred_io); */ void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend) { - if (fb_helper && fb_helper->info) + if (!fb_helper || !fb_helper->info) + return; + + if (fb_helper->funcs->fb_set_suspend) + fb_helper->funcs->fb_set_suspend(fb_helper, suspend); + else fb_set_suspend(fb_helper->info, suspend); } EXPORT_SYMBOL(drm_fb_helper_set_suspend); @@ -803,7 +808,7 @@ void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, } } - fb_set_suspend(fb_helper->info, suspend); + drm_fb_helper_set_suspend(fb_helper, suspend); console_unlock(); } EXPORT_SYMBOL(drm_fb_helper_set_suspend_unlocked); diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 408e44251c47..a99793723695 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -285,10 +285,27 @@ static void intelfb_restore(struct drm_fb_helper *fb_helper) intel_fbdev_invalidate(ifbdev); } +static void intelfb_set_suspend(struct drm_fb_helper *fb_helper, bool suspend) +{ + struct fb_info *info = fb_helper->info; + + /* + * When resuming from hibernation, Linux restores the object's + * content from swap if the buffer is backed by shmemfs. If the + * object is stolen however, it will be full of whatever garbage + * was left in there. Clear it to zero in this case. + */ + if (!suspend && !intel_bo_is_shmem(intel_fb_bo(fb_helper->fb))) + memset_io(info->screen_base, 0, info->screen_size); + + fb_set_suspend(info, suspend); +} + static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { .fb_probe = intelfb_create, .fb_dirty = intelfb_dirty, .fb_restore = intelfb_restore, + .fb_set_suspend = intelfb_set_suspend, }; /* @@ -457,7 +474,6 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev; - struct fb_info *info; if (!ifbdev) return; @@ -468,8 +484,6 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous if (!ifbdev->vma) return; - info = ifbdev->helper.info; - if (synchronous) { /* Flush any pending work to turn the console on, and then * wait to turn it off. It must be synchronous as we are @@ -499,14 +513,6 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous } } - /* On resume from hibernation: If the object is shmemfs backed, it has - * been restored from swap. If the object is stolen however, it will be - * full of whatever garbage was left in there. - */ - if (state == FBINFO_STATE_RUNNING && - !intel_bo_is_shmem(intel_fb_bo(&ifbdev->fb->base))) - memset_io(info->screen_base, 0, info->screen_size); - drm_fb_helper_set_suspend(&ifbdev->helper, state); console_unlock(); } diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index a7d7a3b945ea..ddce2408ca2b 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -112,6 +112,20 @@ struct drm_fb_helper_funcs { * TODO: Fix i915 to not require this callback. */ void (*fb_restore)(struct drm_fb_helper *helper); + + /** + * @fb_set_suspend: + * + * Driver callback to suspend or resume, if set, fbdev emulation will + * invoke this callback during suspend and resume. Driver should call + * fb_set_suspend() from their implementation. If not set, fbdev + * emulation will invoke fb_set_suspend() directly. + * + * Only for i915. Do not use in new code. + * + * TODO: Fix i915 to not require this callback. + */ + void (*fb_set_suspend)(struct drm_fb_helper *helper, bool suspend); }; /** From 03e1b3df217a94c75e644bf50d3b3b2203acba00 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Dec 2024 18:08:48 +0100 Subject: [PATCH 65/92] drm/i915/display: Remove preferred_bpp from struct intel_fbdev The value preferred_bpp in struct intel_fbdev duplicates preferred_bpp in struct drm_fb_helper. Remove the former. Instead let intel_fbdev_init_bios() read the framebuffer from the hardware. Then derive preferred_bpp from its format and initialize struct drm_fb_helper with the value. The default is 32 (i.e., XRGB8888). Also removes one of those deprecated references to the cpp field of struct drm_format_info. Signed-off-by: Thomas Zimmermann Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-8-tzimmermann@suse.de Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_fbdev.c | 29 +++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index a99793723695..db396e1856de 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -60,7 +60,6 @@ struct intel_fbdev { struct intel_framebuffer *fb; struct i915_vma *vma; unsigned long vma_flags; - int preferred_bpp; }; static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper) @@ -430,7 +429,6 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, goto out; } - ifbdev->preferred_bpp = fb->base.format->cpp[0] * 8; ifbdev->fb = fb; drm_framebuffer_get(&ifbdev->fb->base); @@ -461,6 +459,23 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, return false; } +static unsigned int intel_fbdev_color_mode(const struct drm_format_info *info) +{ + unsigned int bpp; + + if (!info->depth || info->num_planes != 1 || info->has_alpha || info->is_yuv) + return 0; + + bpp = drm_format_info_bpp(info, 0); + + switch (bpp) { + case 16: + return info->depth; // 15 or 16 + default: + return bpp; + } +} + static void intel_fbdev_suspend_worker(struct work_struct *work) { intel_fbdev_set_suspend(&container_of(work, @@ -625,6 +640,7 @@ void intel_fbdev_setup(struct drm_i915_private *i915) { struct drm_device *dev = &i915->drm; struct intel_fbdev *ifbdev; + unsigned int preferred_bpp = 0; int ret; if (!HAS_DISPLAY(i915)) @@ -633,14 +649,15 @@ void intel_fbdev_setup(struct drm_i915_private *i915) ifbdev = kzalloc(sizeof(*ifbdev), GFP_KERNEL); if (!ifbdev) return; - drm_fb_helper_prepare(dev, &ifbdev->helper, 32, &intel_fb_helper_funcs); i915->display.fbdev.fbdev = ifbdev; INIT_WORK(&i915->display.fbdev.suspend_work, intel_fbdev_suspend_worker); if (intel_fbdev_init_bios(dev, ifbdev)) - ifbdev->helper.preferred_bpp = ifbdev->preferred_bpp; - else - ifbdev->preferred_bpp = ifbdev->helper.preferred_bpp; + preferred_bpp = intel_fbdev_color_mode(ifbdev->fb->base.format); + if (!preferred_bpp) + preferred_bpp = 32; + + drm_fb_helper_prepare(dev, &ifbdev->helper, preferred_bpp, &intel_fb_helper_funcs); ret = drm_client_init(dev, &ifbdev->helper.client, "intel-fbdev", &intel_fbdev_client_funcs); From 04a1c47798f773cc6b071790c56eaa460a1e5caf Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Dec 2024 18:08:49 +0100 Subject: [PATCH 66/92] drm/i915/display: Remove struct drm_fb_helper from struct intel_fbdev Store instances of drm_fb_helper and struct intel_fbdev separately. This will allow i915 to use the common fbdev client, which allocates its own instance of struct drm_fb_helper. There is at most one instance of type each per DRM device, so both can be referenced directly from the i915 and DRM device structures. A later patchset might rework the common fbdev client to allow for storing both, drm_fb_helper and intel_fbdev, together in the same place. Signed-off-by: Thomas Zimmermann Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-9-tzimmermann@suse.de Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_fbdev.c | 49 ++++++++++++---------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index db396e1856de..7f9de9f49087 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include "i915_drv.h" @@ -56,7 +57,6 @@ #include "intel_frontbuffer.h" struct intel_fbdev { - struct drm_fb_helper helper; struct intel_framebuffer *fb; struct i915_vma *vma; unsigned long vma_flags; @@ -64,7 +64,9 @@ struct intel_fbdev { static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper) { - return container_of(fb_helper, struct intel_fbdev, helper); + struct drm_i915_private *i915 = to_i915(fb_helper->client.dev); + + return i915->display.fbdev.fbdev; } static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev) @@ -120,8 +122,8 @@ static int intel_fbdev_pan_display(struct fb_var_screeninfo *var, static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) { - struct intel_fbdev *fbdev = to_intel_fbdev(info->par); - struct drm_gem_object *obj = drm_gem_fb_get_obj(&fbdev->fb->base, 0); + struct drm_fb_helper *fb_helper = info->par; + struct drm_gem_object *obj = drm_gem_fb_get_obj(fb_helper->fb, 0); return intel_bo_fb_mmap(obj, vma); } @@ -129,9 +131,9 @@ static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) static void intel_fbdev_fb_destroy(struct fb_info *info) { struct drm_fb_helper *fb_helper = info->par; - struct intel_fbdev *ifbdev = container_of(fb_helper, struct intel_fbdev, helper); + struct intel_fbdev *ifbdev = to_intel_fbdev(fb_helper); - drm_fb_helper_fini(&ifbdev->helper); + drm_fb_helper_fini(fb_helper); /* * We rely on the object-free to release the VMA pinning for @@ -139,11 +141,11 @@ static void intel_fbdev_fb_destroy(struct fb_info *info) * trying to rectify all the possible error paths leading here. */ intel_fb_unpin_vma(ifbdev->vma, ifbdev->vma_flags); - drm_framebuffer_remove(&ifbdev->fb->base); + drm_framebuffer_remove(fb_helper->fb); drm_client_release(&fb_helper->client); - drm_fb_helper_unprepare(&ifbdev->helper); - kfree(ifbdev); + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); } __diag_push(); @@ -227,7 +229,7 @@ static int intelfb_create(struct drm_fb_helper *helper, goto out_unpin; } - ifbdev->helper.fb = &fb->base; + helper->fb = &fb->base; info->fbops = &intelfb_ops; @@ -237,7 +239,7 @@ static int intelfb_create(struct drm_fb_helper *helper, if (ret) goto out_unpin; - drm_fb_helper_fill_info(info, &ifbdev->helper, sizes); + drm_fb_helper_fill_info(info, dev->fb_helper, sizes); /* If the object is shmemfs backed, it will have given us zeroed pages. * If the object is stolen however, it will be full of whatever @@ -528,13 +530,14 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous } } - drm_fb_helper_set_suspend(&ifbdev->helper, state); + drm_fb_helper_set_suspend(dev->fb_helper, state); console_unlock(); } static int intel_fbdev_restore_mode(struct drm_i915_private *dev_priv) { struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev; + struct drm_device *dev = &dev_priv->drm; int ret; if (!ifbdev) @@ -543,7 +546,7 @@ static int intel_fbdev_restore_mode(struct drm_i915_private *dev_priv) if (!ifbdev->vma) return -ENOMEM; - ret = drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper); + ret = drm_fb_helper_restore_fbdev_mode_unlocked(dev->fb_helper); if (ret) return ret; @@ -640,13 +643,14 @@ void intel_fbdev_setup(struct drm_i915_private *i915) { struct drm_device *dev = &i915->drm; struct intel_fbdev *ifbdev; + struct drm_fb_helper *fb_helper; unsigned int preferred_bpp = 0; int ret; if (!HAS_DISPLAY(i915)) return; - ifbdev = kzalloc(sizeof(*ifbdev), GFP_KERNEL); + ifbdev = drmm_kzalloc(dev, sizeof(*ifbdev), GFP_KERNEL); if (!ifbdev) return; @@ -657,30 +661,33 @@ void intel_fbdev_setup(struct drm_i915_private *i915) if (!preferred_bpp) preferred_bpp = 32; - drm_fb_helper_prepare(dev, &ifbdev->helper, preferred_bpp, &intel_fb_helper_funcs); + fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); + if (!fb_helper) + return; + drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &intel_fb_helper_funcs); - ret = drm_client_init(dev, &ifbdev->helper.client, "intel-fbdev", + ret = drm_client_init(dev, &fb_helper->client, "intel-fbdev", &intel_fbdev_client_funcs); if (ret) { drm_err(dev, "Failed to register client: %d\n", ret); goto err_drm_fb_helper_unprepare; } - drm_client_register(&ifbdev->helper.client); + drm_client_register(&fb_helper->client); return; err_drm_fb_helper_unprepare: - drm_fb_helper_unprepare(&ifbdev->helper); - kfree(ifbdev); + drm_fb_helper_unprepare(dev->fb_helper); + kfree(fb_helper); } struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) { - if (!fbdev || !fbdev->helper.fb) + if (!fbdev) return NULL; - return to_intel_framebuffer(fbdev->helper.fb); + return fbdev->fb; } struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) From ef9e0e2ef958cd50a50b63f4444ebd946e24d99a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Dec 2024 18:08:50 +0100 Subject: [PATCH 67/92] drm/i915/display: Move fbdev code around Move fbdev code around in the source file before switching to DRM's generic fbdev client. This will make the conversion less intrusive. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-10-tzimmermann@suse.de Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_fbdev.c | 85 +++++++++++----------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 7f9de9f49087..4578634cc4ab 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -56,6 +56,9 @@ #include "intel_fbdev_fb.h" #include "intel_frontbuffer.h" +static int intelfb_create(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes); + struct intel_fbdev { struct intel_framebuffer *fb; struct i915_vma *vma; @@ -165,6 +168,47 @@ static const struct fb_ops intelfb_ops = { __diag_pop(); +static int intelfb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) +{ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->fb->funcs->dirty) + return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + + return 0; +} + +static void intelfb_restore(struct drm_fb_helper *fb_helper) +{ + struct intel_fbdev *ifbdev = to_intel_fbdev(fb_helper); + + intel_fbdev_invalidate(ifbdev); +} + +static void intelfb_set_suspend(struct drm_fb_helper *fb_helper, bool suspend) +{ + struct fb_info *info = fb_helper->info; + + /* + * When resuming from hibernation, Linux restores the object's + * content from swap if the buffer is backed by shmemfs. If the + * object is stolen however, it will be full of whatever garbage + * was left in there. Clear it to zero in this case. + */ + if (!suspend && !intel_bo_is_shmem(intel_fb_bo(fb_helper->fb))) + memset_io(info->screen_base, 0, info->screen_size); + + fb_set_suspend(info, suspend); +} + +static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { + .fb_probe = intelfb_create, + .fb_dirty = intelfb_dirty, + .fb_restore = intelfb_restore, + .fb_set_suspend = intelfb_set_suspend, +}; + static int intelfb_create(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { @@ -268,47 +312,6 @@ static int intelfb_create(struct drm_fb_helper *helper, return ret; } -static int intelfb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) -{ - if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) - return 0; - - if (helper->fb->funcs->dirty) - return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); - - return 0; -} - -static void intelfb_restore(struct drm_fb_helper *fb_helper) -{ - struct intel_fbdev *ifbdev = to_intel_fbdev(fb_helper); - - intel_fbdev_invalidate(ifbdev); -} - -static void intelfb_set_suspend(struct drm_fb_helper *fb_helper, bool suspend) -{ - struct fb_info *info = fb_helper->info; - - /* - * When resuming from hibernation, Linux restores the object's - * content from swap if the buffer is backed by shmemfs. If the - * object is stolen however, it will be full of whatever garbage - * was left in there. Clear it to zero in this case. - */ - if (!suspend && !intel_bo_is_shmem(intel_fb_bo(fb_helper->fb))) - memset_io(info->screen_base, 0, info->screen_size); - - fb_set_suspend(info, suspend); -} - -static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { - .fb_probe = intelfb_create, - .fb_dirty = intelfb_dirty, - .fb_restore = intelfb_restore, - .fb_set_suspend = intelfb_set_suspend, -}; - /* * Build an intel_fbdev struct using a BIOS allocated framebuffer, if possible. * The core display code will have read out the current plane configuration, From 9fa154f40eb6b4bc17fefaf94e91f6f4d5b4fda2 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Dec 2024 18:08:51 +0100 Subject: [PATCH 68/92] drm/{i915,xe}: Run DRM default client setup Rework fbdev probing to support fbdev_probe in struct drm_driver and remove the old fb_probe callback. Provide an initializer macro that sets the callback in struct drm_driver according to the kernel configuration. Call drm_client_setup_with_color_mode() to run the kernel's default client setup for DRM. This commit also prepares support for the kernel's drm_log client (or any future client) in i915. Using drm_log will also require vmap support in GEM objects. Signed-off-by: Thomas Zimmermann Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-11-tzimmermann@suse.de Signed-off-by: Maarten Lankhorst --- .../gpu/drm/i915/display/intel_display_core.h | 1 - drivers/gpu/drm/i915/display/intel_fbdev.c | 194 +----------------- drivers/gpu/drm/i915/display/intel_fbdev.h | 17 +- drivers/gpu/drm/i915/i915_driver.c | 3 + drivers/gpu/drm/xe/display/xe_display.c | 5 + 5 files changed, 21 insertions(+), 199 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 1970d4c15090..7360ad39b1cc 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -386,7 +386,6 @@ struct intel_display { struct { /* list of fbdev register on this device */ struct intel_fbdev *fbdev; - struct work_struct suspend_work; } fbdev; struct { diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 4578634cc4ab..adc19d5607de 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -56,9 +57,6 @@ #include "intel_fbdev_fb.h" #include "intel_frontbuffer.h" -static int intelfb_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes); - struct intel_fbdev { struct intel_framebuffer *fb; struct i915_vma *vma; @@ -203,14 +201,13 @@ static void intelfb_set_suspend(struct drm_fb_helper *fb_helper, bool suspend) } static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { - .fb_probe = intelfb_create, .fb_dirty = intelfb_dirty, .fb_restore = intelfb_restore, .fb_set_suspend = intelfb_set_suspend, }; -static int intelfb_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) +int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes) { struct intel_fbdev *ifbdev = to_intel_fbdev(helper); struct intel_framebuffer *fb = ifbdev->fb; @@ -273,6 +270,7 @@ static int intelfb_create(struct drm_fb_helper *helper, goto out_unpin; } + helper->funcs = &intel_fb_helper_funcs; helper->fb = &fb->base; info->fbops = &intelfb_ops; @@ -481,174 +479,11 @@ static unsigned int intel_fbdev_color_mode(const struct drm_format_info *info) } } -static void intel_fbdev_suspend_worker(struct work_struct *work) -{ - intel_fbdev_set_suspend(&container_of(work, - struct drm_i915_private, - display.fbdev.suspend_work)->drm, - FBINFO_STATE_RUNNING, - true); -} - -void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev; - - if (!ifbdev) - return; - - if (drm_WARN_ON(&dev_priv->drm, !HAS_DISPLAY(dev_priv))) - return; - - if (!ifbdev->vma) - return; - - if (synchronous) { - /* Flush any pending work to turn the console on, and then - * wait to turn it off. It must be synchronous as we are - * about to suspend or unload the driver. - * - * Note that from within the work-handler, we cannot flush - * ourselves, so only flush outstanding work upon suspend! - */ - if (state != FBINFO_STATE_RUNNING) - flush_work(&dev_priv->display.fbdev.suspend_work); - - console_lock(); - } else { - /* - * The console lock can be pretty contented on resume due - * to all the printk activity. Try to keep it out of the hot - * path of resume if possible. - */ - drm_WARN_ON(dev, state != FBINFO_STATE_RUNNING); - if (!console_trylock()) { - /* Don't block our own workqueue as this can - * be run in parallel with other i915.ko tasks. - */ - queue_work(dev_priv->unordered_wq, - &dev_priv->display.fbdev.suspend_work); - return; - } - } - - drm_fb_helper_set_suspend(dev->fb_helper, state); - console_unlock(); -} - -static int intel_fbdev_restore_mode(struct drm_i915_private *dev_priv) -{ - struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev; - struct drm_device *dev = &dev_priv->drm; - int ret; - - if (!ifbdev) - return -EINVAL; - - if (!ifbdev->vma) - return -ENOMEM; - - ret = drm_fb_helper_restore_fbdev_mode_unlocked(dev->fb_helper); - if (ret) - return ret; - - return 0; -} - -/* - * Fbdev client and struct drm_client_funcs - */ - -static void intel_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = fb_helper->dev; - struct pci_dev *pdev = to_pci_dev(dev->dev); - - if (fb_helper->info) { - vga_switcheroo_client_fb_set(pdev, NULL); - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_fb_helper_unprepare(fb_helper); - drm_client_release(&fb_helper->client); - kfree(fb_helper); - } -} - -static int intel_fbdev_client_restore(struct drm_client_dev *client) -{ - struct drm_i915_private *dev_priv = to_i915(client->dev); - int ret; - - ret = intel_fbdev_restore_mode(dev_priv); - if (ret) - return ret; - - vga_switcheroo_process_delayed_switch(); - - return 0; -} - -static int intel_fbdev_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - struct pci_dev *pdev = to_pci_dev(dev->dev); - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - vga_switcheroo_client_fb_set(pdev, fb_helper->info); - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup i915 fbdev emulation (ret=%d)\n", ret); - return ret; -} - -static int intel_fbdev_client_suspend(struct drm_client_dev *client, bool holds_console_lock) -{ - intel_fbdev_set_suspend(client->dev, FBINFO_STATE_SUSPENDED, true); - - return 0; -} - -static int intel_fbdev_client_resume(struct drm_client_dev *client, bool holds_console_lock) -{ - intel_fbdev_set_suspend(client->dev, FBINFO_STATE_RUNNING, false); - - return 0; -} - -static const struct drm_client_funcs intel_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = intel_fbdev_client_unregister, - .restore = intel_fbdev_client_restore, - .hotplug = intel_fbdev_client_hotplug, - .suspend = intel_fbdev_client_suspend, - .resume = intel_fbdev_client_resume, -}; - void intel_fbdev_setup(struct drm_i915_private *i915) { struct drm_device *dev = &i915->drm; struct intel_fbdev *ifbdev; - struct drm_fb_helper *fb_helper; unsigned int preferred_bpp = 0; - int ret; if (!HAS_DISPLAY(i915)) return; @@ -658,31 +493,12 @@ void intel_fbdev_setup(struct drm_i915_private *i915) return; i915->display.fbdev.fbdev = ifbdev; - INIT_WORK(&i915->display.fbdev.suspend_work, intel_fbdev_suspend_worker); if (intel_fbdev_init_bios(dev, ifbdev)) preferred_bpp = intel_fbdev_color_mode(ifbdev->fb->base.format); if (!preferred_bpp) preferred_bpp = 32; - fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); - if (!fb_helper) - return; - drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &intel_fb_helper_funcs); - - ret = drm_client_init(dev, &fb_helper->client, "intel-fbdev", - &intel_fbdev_client_funcs); - if (ret) { - drm_err(dev, "Failed to register client: %d\n", ret); - goto err_drm_fb_helper_unprepare; - } - - drm_client_register(&fb_helper->client); - - return; - -err_drm_fb_helper_unprepare: - drm_fb_helper_unprepare(dev->fb_helper); - kfree(fb_helper); + drm_client_setup_with_color_mode(dev, preferred_bpp); } struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h index 24a3434558cb..ca2c8c438f02 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.h +++ b/drivers/gpu/drm/i915/display/intel_fbdev.h @@ -6,28 +6,27 @@ #ifndef __INTEL_FBDEV_H__ #define __INTEL_FBDEV_H__ -#include - -struct drm_device; +struct drm_fb_helper; +struct drm_fb_helper_surface_size; struct drm_i915_private; struct intel_fbdev; struct intel_framebuffer; #ifdef CONFIG_DRM_FBDEV_EMULATION +int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes); +#define INTEL_FBDEV_DRIVER_OPS \ + .fbdev_probe = intel_fbdev_driver_fbdev_probe void intel_fbdev_setup(struct drm_i915_private *dev_priv); -void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous); struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev); struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev); #else +#define INTEL_FBDEV_DRIVER_OPS \ + .fbdev_probe = NULL static inline void intel_fbdev_setup(struct drm_i915_private *dev_priv) { } - -static inline void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous) -{ -} - static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) { return NULL; diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 2cabfd611671..ce3cc93ea211 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -56,6 +56,7 @@ #include "display/intel_dp.h" #include "display/intel_dpt.h" #include "display/intel_encoder.h" +#include "display/intel_fbdev.h" #include "display/intel_hotplug.h" #include "display/intel_overlay.h" #include "display/intel_pch_refclk.h" @@ -1808,6 +1809,8 @@ static const struct drm_driver i915_drm_driver = { .dumb_create = i915_gem_dumb_create, .dumb_map_offset = i915_gem_dumb_mmap_offset, + INTEL_FBDEV_DRIVER_OPS, + .ioctls = i915_ioctls, .num_ioctls = ARRAY_SIZE(i915_ioctls), .fops = &i915_driver_fops, diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 0c1b45b855de..4f434f84b2cc 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -27,6 +27,7 @@ #include "intel_dmc_wl.h" #include "intel_dp.h" #include "intel_encoder.h" +#include "intel_fbdev.h" #include "intel_hdcp.h" #include "intel_hotplug.h" #include "intel_opregion.h" @@ -68,6 +69,10 @@ void xe_display_driver_set_hooks(struct drm_driver *driver) if (!xe_modparam.probe_display) return; +#ifdef CONFIG_DRM_FBDEV_EMULATION + driver->fbdev_probe = intel_fbdev_driver_fbdev_probe; +#endif + driver->driver_features |= DRIVER_MODESET | DRIVER_ATOMIC; } From 69acb6bd5e9bf6587883a3528a9cae3e63c9e9c5 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Dec 2024 18:08:52 +0100 Subject: [PATCH 69/92] drm/i915/display: Remove compile guard around fbdev debugfs output If fbdev support has been disabled, no output will be shown. Remove the fbdev-related compile guard from the driver's debugfs code. Signed-off-by: Thomas Zimmermann Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-12-tzimmermann@suse.de Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 510c15a6271f..fdedf65bee53 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -114,7 +114,6 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) struct intel_framebuffer *fbdev_fb = NULL; struct drm_framebuffer *drm_fb; -#ifdef CONFIG_DRM_FBDEV_EMULATION fbdev_fb = intel_fbdev_framebuffer(display->fbdev.fbdev); if (fbdev_fb) { seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ", @@ -127,7 +126,6 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) intel_bo_describe(m, intel_fb_bo(&fbdev_fb->base)); seq_putc(m, '\n'); } -#endif mutex_lock(&display->drm->mode_config.fb_lock); drm_for_each_fb(drm_fb, display->drm) { From 41ff0b424d81b7936bc4d96e8957aa7f454c3527 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 12 Dec 2024 18:08:53 +0100 Subject: [PATCH 70/92] drm/fb-helper: Remove struct drm_fb_helper.fb_probe The callback fb_probe in struct drm_fb_helper is unused. Remove it. New drivers should set struct drm_driver.fbdev_probe instead and call drm_client_setup() to instantiate in-kernel DRM clients. Signed-off-by: Thomas Zimmermann Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-13-tzimmermann@suse.de Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_fb_helper.c | 8 ++++---- include/drm/drm_fb_helper.h | 17 ----------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 0703fddd750f..937c3939e502 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1634,6 +1634,9 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper) struct fb_info *info; int ret; + if (drm_WARN_ON(dev, !dev->driver->fbdev_probe)) + return -EINVAL; + ret = drm_fb_helper_find_sizes(fb_helper, &sizes); if (ret) { /* First time: disable all crtc's.. */ @@ -1643,10 +1646,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper) } /* push down into drivers */ - if (dev->driver->fbdev_probe) - ret = dev->driver->fbdev_probe(fb_helper, &sizes); - else if (fb_helper->funcs) - ret = fb_helper->funcs->fb_probe(fb_helper, &sizes); + ret = dev->driver->fbdev_probe(fb_helper, &sizes); if (ret < 0) return ret; diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index ddce2408ca2b..c1d38d54a112 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -69,23 +69,6 @@ struct drm_fb_helper_surface_size { * Driver callbacks used by the fbdev emulation helper library. */ struct drm_fb_helper_funcs { - /** - * @fb_probe: - * - * Driver callback to allocate and initialize the fbdev info structure. - * Furthermore it also needs to allocate the DRM framebuffer used to - * back the fbdev. - * - * This callback is mandatory. - * - * RETURNS: - * - * The driver should return 0 on success and a negative error code on - * failure. - */ - int (*fb_probe)(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes); - /** * @fb_dirty: * From fb64f5568c0e0b5730733d70a012ae26b1a55815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 18 Feb 2025 23:18:55 +0200 Subject: [PATCH 71/92] drm/i915/cdclk: Do cdclk post plane programming later MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We currently call intel_set_cdclk_post_plane_update() far too early. When pipes are active during the reprogramming the current spot only works for the cd2x divider update case, as that is synchronize to the pipe's vblank. Squashing and crawling are not synchronized in any way, so doing the programming while the pipes/planes are potentially still using the old hardware state could lead to underruns. Move the post plane reprgramming to a spot where we know that the pipes/planes have switched over the new hardware state. Cc: stable@vger.kernel.org Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250218211913.27867-2-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- drivers/gpu/drm/i915/display/intel_display.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index f7cb38145e9d..51c011de4a16 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7354,9 +7354,6 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_program_dpkgc_latency(state); - if (state->modeset) - intel_set_cdclk_post_plane_update(state); - intel_wait_for_vblank_workers(state); /* FIXME: We should call drm_atomic_helper_commit_hw_done() here @@ -7433,6 +7430,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_verify_planes(state); intel_sagv_post_plane_update(state); + if (state->modeset) + intel_set_cdclk_post_plane_update(state); intel_pmdemand_post_plane_update(state); drm_atomic_helper_commit_hw_done(&state->base); From 2fff55d499eea7c61a2671c5d7394e9c62995d9f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 5 Mar 2025 18:38:22 +0200 Subject: [PATCH 72/92] drm/xe/compat: refactor compat i915_drv.h The compat i915_drv.h contains things that aren't there in the original i915_drv.h. Split out gem/i915_gem_object.h and i915_scheduler_types.h, moving the corresponding pieces out, including FORCEWAKE_ALL to intel_uncore.h. Technically I915_PRIORITY_DISPLAY should be in i915_priolist_types.h, but it's a bit overkill to split out another file just for that. i915_scheduler_types.h shall do. With this, the compat i915_drv.h becomes a strict subset of the original. Reviewed-by: Nemesa Garg Link: https://patchwork.freedesktop.org/patch/msgid/d6bd95bf52aa37f48ddec3e675b7a3cc66829eef.1741192597.git.jani.nikula@intel.com [Jani: fix i915_gem_object.h header guard while applying] Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_atomic_plane.c | 2 ++ .../xe/compat-i915-headers/gem/i915_gem_object.h | 15 +++++++++++++++ drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h | 8 -------- .../xe/compat-i915-headers/i915_scheduler_types.h | 13 +++++++++++++ .../gpu/drm/xe/compat-i915-headers/intel_uncore.h | 2 ++ 5 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h create mode 100644 drivers/gpu/drm/xe/compat-i915-headers/i915_scheduler_types.h diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index a26b54185d5b..d899c37d80c6 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -41,8 +41,10 @@ #include #include +#include "gem/i915_gem_object.h" #include "i915_config.h" #include "i915_drv.h" +#include "i915_scheduler_types.h" #include "i915_vma.h" #include "i9xx_plane_regs.h" #include "intel_atomic_plane.h" diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h new file mode 100644 index 000000000000..8a048980ea38 --- /dev/null +++ b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __I915_GEM_OBJECT_H__ +#define __I915_GEM_OBJECT_H__ + +struct dma_fence; +struct i915_sched_attr; + +static inline void i915_gem_fence_wait_priority(struct dma_fence *fence, + const struct i915_sched_attr *attr) +{ +} + +#endif diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h index 84b0991b35b3..dfec5108d2c3 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h @@ -95,14 +95,6 @@ static inline struct drm_i915_private *to_i915(const struct drm_device *dev) #define HAS_128_BYTE_Y_TILING(xe) (xe || 1) -#define I915_PRIORITY_DISPLAY 0 -struct i915_sched_attr { - int priority; -}; -#define i915_gem_fence_wait_priority(fence, attr) do { (void) attr; } while (0) - -#define FORCEWAKE_ALL XE_FORCEWAKE_ALL - #ifdef CONFIG_ARM64 /* * arm64 indirectly includes linux/rtc.h, diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_scheduler_types.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_scheduler_types.h new file mode 100644 index 000000000000..c11130440d31 --- /dev/null +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_scheduler_types.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __I915_SCHEDULER_TYPES_H__ +#define __I915_SCHEDULER_TYPES_H__ + +#define I915_PRIORITY_DISPLAY 0 + +struct i915_sched_attr { + int priority; +}; + +#endif diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h index 4fc3e535de91..0c1e88e36a1e 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h @@ -10,6 +10,8 @@ #include "xe_device_types.h" #include "xe_mmio.h" +#define FORCEWAKE_ALL XE_FORCEWAKE_ALL + static inline struct intel_uncore *to_intel_uncore(struct drm_device *drm) { return &to_xe_device(drm)->uncore; From 30a6be2c200fdbdaad8adcdd68eae9d90a23c291 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 5 Mar 2025 18:38:23 +0200 Subject: [PATCH 73/92] drm/i915/plane: convert intel_atomic_plane.[ch] to struct intel_display Going forward, struct intel_display is the main display device data pointer. Convert intel_atomic_plane.[ch] to struct intel_display. Reviewed-by: Nemesa Garg Link: https://patchwork.freedesktop.org/patch/msgid/d7e28ad43f67d92e54fb7e14373872b5e561038c.1741192597.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- .../gpu/drm/i915/display/intel_atomic_plane.c | 78 +++++++++---------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index d899c37d80c6..7276179df878 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -43,7 +43,6 @@ #include "gem/i915_gem_object.h" #include "i915_config.h" -#include "i915_drv.h" #include "i915_scheduler_types.h" #include "i915_vma.h" #include "i9xx_plane_regs.h" @@ -169,10 +168,10 @@ intel_plane_destroy_state(struct drm_plane *plane, bool intel_plane_needs_physical(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); return plane->id == PLANE_CURSOR && - DISPLAY_INFO(i915)->cursor_needs_physical; + DISPLAY_INFO(display)->cursor_needs_physical; } bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier) @@ -277,7 +276,7 @@ int intel_plane_calc_min_cdclk(struct intel_atomic_state *state, struct intel_plane *plane, bool *need_cdclk_calc) { - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); const struct intel_plane_state *plane_state = intel_atomic_get_new_plane_state(state, plane); struct intel_crtc *crtc = to_intel_crtc(plane_state->hw.crtc); @@ -322,7 +321,7 @@ int intel_plane_calc_min_cdclk(struct intel_atomic_state *state, cdclk_state->min_cdclk[crtc->pipe]) return 0; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] min cdclk (%d kHz) > [CRTC:%d:%s] min cdclk (%d kHz)\n", plane->base.base.id, plane->base.name, new_crtc_state->min_cdclk[plane->id], @@ -435,7 +434,7 @@ static bool intel_plane_do_async_flip(struct intel_plane *plane, const struct intel_crtc_state *old_crtc_state, const struct intel_crtc_state *new_crtc_state) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); if (!plane->async_flip) return false; @@ -456,7 +455,7 @@ static bool intel_plane_do_async_flip(struct intel_plane *plane, * extend this so other scanout parameters (stride/etc) could * be changed as well... */ - return DISPLAY_VER(i915) < 9 || old_crtc_state->uapi.async_flip; + return DISPLAY_VER(display) < 9 || old_crtc_state->uapi.async_flip; } static bool i9xx_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state, @@ -560,16 +559,16 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr const struct intel_plane_state *old_plane_state, struct intel_plane_state *new_plane_state) { + struct intel_display *display = to_intel_display(new_crtc_state); struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); bool mode_changed = intel_crtc_needs_modeset(new_crtc_state); bool was_crtc_enabled = old_crtc_state->hw.active; bool is_crtc_enabled = new_crtc_state->hw.active; bool turn_off, turn_on, visible, was_visible; int ret; - if (DISPLAY_VER(dev_priv) >= 9 && plane->id != PLANE_CURSOR) { + if (DISPLAY_VER(display) >= 9 && plane->id != PLANE_CURSOR) { ret = skl_update_scaler_plane(new_crtc_state, new_plane_state); if (ret) return ret; @@ -578,7 +577,7 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr was_visible = old_plane_state->uapi.visible; visible = new_plane_state->uapi.visible; - if (!was_crtc_enabled && drm_WARN_ON(&dev_priv->drm, was_visible)) + if (!was_crtc_enabled && drm_WARN_ON(display->drm, was_visible)) was_visible = false; /* @@ -602,7 +601,7 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr turn_off = was_visible && (!visible || mode_changed); turn_on = visible && (!was_visible || mode_changed); - drm_dbg_atomic(&dev_priv->drm, + drm_dbg_atomic(display->drm, "[CRTC:%d:%s] with [PLANE:%d:%s] visible %i -> %i, off %i, on %i, ms %i\n", crtc->base.base.id, crtc->base.name, plane->base.base.id, plane->base.name, @@ -612,11 +611,11 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr if (visible || was_visible) new_crtc_state->fb_bits |= plane->frontbuffer_bit; - if (HAS_GMCH(dev_priv) && + if (HAS_GMCH(display) && i9xx_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state)) new_crtc_state->disable_cxsr = true; - if ((IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) && + if ((display->platform.ironlake || display->platform.sandybridge || display->platform.ivybridge) && ilk_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state)) new_crtc_state->disable_cxsr = true; @@ -709,10 +708,10 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ struct intel_plane * intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_plane *plane; - for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) { + for_each_intel_plane_on_crtc(display->drm, crtc, plane) { if (plane->id == plane_id) return plane; } @@ -961,9 +960,9 @@ void intel_crtc_planes_update_arm(struct intel_dsb *dsb, struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); - if (DISPLAY_VER(i915) >= 9) + if (DISPLAY_VER(display) >= 9) skl_crtc_planes_update_arm(dsb, state, crtc); else i9xx_crtc_planes_update_arm(dsb, state, crtc); @@ -974,7 +973,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, int min_scale, int max_scale, bool can_position) { - struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); struct drm_framebuffer *fb = plane_state->hw.fb; struct drm_rect *src = &plane_state->uapi.src; @@ -994,7 +993,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); if (hscale < 0 || vscale < 0) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] invalid scaling "DRM_RECT_FP_FMT " -> " DRM_RECT_FMT "\n", plane->base.base.id, plane->base.name, DRM_RECT_FP_ARG(src), DRM_RECT_ARG(dst)); @@ -1011,7 +1010,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, if (!can_position && plane_state->uapi.visible && !drm_rect_equals(dst, clip)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] plane (" DRM_RECT_FMT ") must cover entire CRTC (" DRM_RECT_FMT ")\n", plane->base.base.id, plane->base.name, DRM_RECT_ARG(dst), DRM_RECT_ARG(clip)); @@ -1026,7 +1025,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) { - struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); const struct drm_framebuffer *fb = plane_state->hw.fb; struct drm_rect *src = &plane_state->uapi.src; @@ -1060,18 +1059,18 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) if (fb->format->format == DRM_FORMAT_RGB565 && rotated) { hsub = 2; vsub = 2; - } else if (DISPLAY_VER(i915) >= 20 && + } else if (DISPLAY_VER(display) >= 20 && intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) { /* * This allows NV12 and P0xx formats to have odd size and/or odd - * source coordinates on DISPLAY_VER(i915) >= 20 + * source coordinates on DISPLAY_VER(display) >= 20 */ hsub = 1; vsub = 1; /* Wa_16023981245 */ - if ((DISPLAY_VERx100(i915) == 2000 || - DISPLAY_VERx100(i915) == 3000) && + if ((DISPLAY_VERx100(display) == 2000 || + DISPLAY_VERx100(display) == 3000) && src_x % 2 != 0) hsub = 2; } else { @@ -1083,7 +1082,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) hsub = vsub = max(hsub, vsub); if (src_x % hsub || src_w % hsub) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n", plane->base.base.id, plane->base.name, src_x, src_w, hsub, str_yes_no(rotated)); @@ -1091,7 +1090,7 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) } if (src_y % vsub || src_h % vsub) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n", plane->base.base.id, plane->base.name, src_y, src_h, vsub, str_yes_no(rotated)); @@ -1336,14 +1335,13 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(state->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_plane_state *plane_state; struct intel_plane *plane; int i; - if (DISPLAY_VER(dev_priv) < 11) + if (DISPLAY_VER(display) < 11) return 0; /* @@ -1371,7 +1369,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, if ((crtc_state->nv12_planes & BIT(plane->id)) == 0) continue; - for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, y_plane) { + for_each_intel_plane_on_crtc(display->drm, crtc, y_plane) { if (!icl_is_nv12_y_plane(display, y_plane->id)) continue; @@ -1386,7 +1384,7 @@ static int icl_check_nv12_planes(struct intel_atomic_state *state, } if (!y_plane_state) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] need %d free Y planes for planar YUV\n", crtc->base.base.id, crtc->base.name, hweight8(crtc_state->nv12_planes)); @@ -1403,10 +1401,10 @@ static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state, struct intel_crtc *crtc, u8 plane_ids_mask) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_plane *plane; - for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { + for_each_intel_plane_on_crtc(display->drm, crtc, plane) { struct intel_plane_state *plane_state; if ((plane_ids_mask & BIT(plane->id)) == 0) @@ -1433,12 +1431,12 @@ int intel_atomic_add_affected_planes(struct intel_atomic_state *state, new_crtc_state->enabled_planes); } -static bool active_planes_affects_min_cdclk(struct drm_i915_private *dev_priv) +static bool active_planes_affects_min_cdclk(struct intel_display *display) { /* See {hsw,vlv,ivb}_plane_ratio() */ - return IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv) || - IS_CHERRYVIEW(dev_priv) || IS_VALLEYVIEW(dev_priv) || - IS_IVYBRIDGE(dev_priv); + return display->platform.broadwell || display->platform.haswell || + display->platform.cherryview || display->platform.valleyview || + display->platform.ivybridge; } static u8 intel_joiner_affected_planes(struct intel_atomic_state *state, @@ -1517,7 +1515,7 @@ static int intel_add_affected_planes(struct intel_atomic_state *state) int intel_atomic_check_planes(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *old_crtc_state, *new_crtc_state; struct intel_plane_state __maybe_unused *plane_state; struct intel_plane *plane; @@ -1531,7 +1529,7 @@ int intel_atomic_check_planes(struct intel_atomic_state *state) for_each_new_intel_plane_in_state(state, plane, plane_state, i) { ret = intel_plane_atomic_check(state, plane); if (ret) { - drm_dbg_atomic(&dev_priv->drm, + drm_dbg_atomic(display->drm, "[PLANE:%d:%s] atomic driver check failed\n", plane->base.base.id, plane->base.name); return ret; @@ -1551,7 +1549,7 @@ int intel_atomic_check_planes(struct intel_atomic_state *state) * the planes' minimum cdclk calculation. Add such planes * to the state before we compute the minimum cdclk. */ - if (!active_planes_affects_min_cdclk(dev_priv)) + if (!active_planes_affects_min_cdclk(display)) continue; old_active_planes = old_crtc_state->active_planes & ~BIT(PLANE_CURSOR); From 68b97b12c46105b0859dd7636f3247e9f6fceab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 3 Mar 2025 14:39:52 +0200 Subject: [PATCH 74/92] drm/i915: Program CURSOR_PROGRAM and COEFF_POLARITY for icl+ combo PHYs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bspec asks us to clear the CURSOR_PROGRAM and COEFF_POLARITY bits in PORT_TX_DW5 on icl+ combo PHYs. Make it so. Bspec: 21257, 49291 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250303123952.5669-2-ville.syrjala@linux.intel.com Reviewed-by: Chaitanya Kumar Borah --- drivers/gpu/drm/i915/display/intel_combo_phy_regs.h | 2 ++ drivers/gpu/drm/i915/display/intel_ddi.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h b/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h index 0964e392d02c..ee41acdccf4e 100644 --- a/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h +++ b/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h @@ -133,6 +133,8 @@ #define TX_TRAINING_EN REG_BIT(31) #define TAP2_DISABLE REG_BIT(30) #define TAP3_DISABLE REG_BIT(29) +#define CURSOR_PROGRAM REG_BIT(26) +#define COEFF_POLARITY REG_BIT(25) #define SCALING_MODE_SEL_MASK REG_GENMASK(20, 18) #define SCALING_MODE_SEL(x) REG_FIELD_PREP(SCALING_MODE_SEL_MASK, (x)) #define RTERM_SELECT_MASK REG_GENMASK(5, 3) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 676c1826f15c..f38c998935b9 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1193,7 +1193,8 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, /* Set PORT_TX_DW5 */ val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK | - TAP2_DISABLE | TAP3_DISABLE); + COEFF_POLARITY | CURSOR_PROGRAM | + TAP2_DISABLE | TAP3_DISABLE); val |= SCALING_MODE_SEL(0x2); val |= RTERM_SELECT(0x6); val |= TAP3_DISABLE; From 72eea9175e4d30097ca4a8834de03a7227be5c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:03 +0200 Subject: [PATCH 75/92] drm/i915: Drop redundant shared_dpll=NULL assignments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The crtc state is expected to be fully cleared before readout, so there is no need to clear the shared_dpll pointers by hand. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-2-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 51c011de4a16..5c1c2cb83d51 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2997,7 +2997,6 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->sink_format = pipe_config->output_format; pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; - pipe_config->shared_dpll = NULL; ret = false; @@ -3339,7 +3338,6 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, return false; pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; - pipe_config->shared_dpll = NULL; ret = false; tmp = intel_de_read(display, @@ -3906,8 +3904,6 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, POWER_DOMAIN_PIPE(crtc->pipe))) return false; - pipe_config->shared_dpll = NULL; - active = hsw_get_transcoder_state(crtc, pipe_config, &crtc->hw_readout_power_domains); if ((display->platform.geminilake || display->platform.broxton) && From 0851227d62bb3b7c3e819bb7de3d0918a3c6889c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:04 +0200 Subject: [PATCH 76/92] drm/i915: Don't clobber crtc_state->cpu_transcoder for inactive crtcs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inactive crtcs are supposed to have their crtc_state completely cleared. Currently we are clobbering crtc_state->cpu_transcoder before determining whether it's actually enabled or not. Don't do that. I want to rework the inherited flag handling for inactive crtcs a bit, and having a bogus cpu_transcoder in the crtc state can then cause confusing fastset mismatches even when the crtc never changes state during the commit. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-3-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 28 +++++++++----------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 5c1c2cb83d51..8d94ab7de669 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2985,26 +2985,25 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, { struct intel_display *display = to_intel_display(crtc); enum intel_display_power_domain power_domain; + enum transcoder cpu_transcoder = (enum transcoder)crtc->pipe; intel_wakeref_t wakeref; + bool ret = false; u32 tmp; - bool ret; power_domain = POWER_DOMAIN_PIPE(crtc->pipe); wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return false; - pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; - pipe_config->sink_format = pipe_config->output_format; - pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; - - ret = false; - - tmp = intel_de_read(display, - TRANSCONF(display, pipe_config->cpu_transcoder)); + tmp = intel_de_read(display, TRANSCONF(display, cpu_transcoder)); if (!(tmp & TRANSCONF_ENABLE)) goto out; + pipe_config->cpu_transcoder = cpu_transcoder; + + pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; + pipe_config->sink_format = pipe_config->output_format; + if (display->platform.g4x || display->platform.valleyview || display->platform.cherryview) { switch (tmp & TRANSCONF_BPC_MASK) { @@ -3328,23 +3327,22 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, { struct intel_display *display = to_intel_display(crtc); enum intel_display_power_domain power_domain; + enum transcoder cpu_transcoder = (enum transcoder)crtc->pipe; intel_wakeref_t wakeref; + bool ret = false; u32 tmp; - bool ret; power_domain = POWER_DOMAIN_PIPE(crtc->pipe); wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) return false; - pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; - - ret = false; - tmp = intel_de_read(display, - TRANSCONF(display, pipe_config->cpu_transcoder)); + tmp = intel_de_read(display, TRANSCONF(display, cpu_transcoder)); if (!(tmp & TRANSCONF_ENABLE)) goto out; + pipe_config->cpu_transcoder = cpu_transcoder; + switch (tmp & TRANSCONF_BPC_MASK) { case TRANSCONF_BPC_6: pipe_config->pipe_bpp = 18; From cd5693cf5ec4f45dface7db611e8f30526048b40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:05 +0200 Subject: [PATCH 77/92] drm/i915: Use intel_plane_set_invisible() in intel_plane_disable_noatomic() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reuse intel_plane_set_invisible() in intel_plane_disable_noatomic() instead of hand rolling the same stuff. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-4-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 8d94ab7de669..5d7b28f6009f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -674,13 +674,9 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, plane->base.base.id, plane->base.name, crtc->base.base.id, crtc->base.name); + intel_plane_set_invisible(crtc_state, plane_state); intel_set_plane_visible(crtc_state, plane_state, false); intel_plane_fixup_bitmasks(crtc_state); - crtc_state->data_rate[plane->id] = 0; - crtc_state->data_rate_y[plane->id] = 0; - crtc_state->rel_data_rate[plane->id] = 0; - crtc_state->rel_data_rate_y[plane->id] = 0; - crtc_state->min_cdclk[plane->id] = 0; if ((crtc_state->active_planes & ~BIT(PLANE_CURSOR)) == 0 && hsw_ips_disable(crtc_state)) { From 082ed1ffc24ab25be1d21f2edc83b2657142749d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:06 +0200 Subject: [PATCH 78/92] drm/i915: Extract intel_cdclk_crtc_disable_noatomic() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hoist the cdclk stuff into a separate function from intel_crtc_disable_noatomic_complete() so that the details are better hidden inside intel_cdclk.c. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-5-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_cdclk.c | 12 ++++++++++++ drivers/gpu/drm/i915/display/intel_cdclk.h | 2 ++ drivers/gpu/drm/i915/display/intel_modeset_setup.c | 6 +----- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index c6cfc57a0346..4b7058e65588 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -3340,6 +3340,18 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) return 0; } +void intel_cdclk_crtc_disable_noatomic(struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(crtc); + struct intel_cdclk_state *cdclk_state = + to_intel_cdclk_state(display->cdclk.obj.state); + enum pipe pipe = crtc->pipe; + + cdclk_state->min_cdclk[pipe] = 0; + cdclk_state->min_voltage_level[pipe] = 0; + cdclk_state->active_pipes &= ~BIT(pipe); +} + static int intel_compute_max_dotclk(struct intel_display *display) { int ppc = intel_cdclk_ppc(display, HAS_DOUBLE_WIDE(display)); diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index 6b0e7a41eba3..689e12e2196b 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -12,6 +12,7 @@ #include "intel_global_state.h" struct intel_atomic_state; +struct intel_crtc; struct intel_crtc_state; struct intel_display; @@ -83,6 +84,7 @@ int intel_cdclk_atomic_check(struct intel_atomic_state *state, int intel_cdclk_state_set_joined_mbus(struct intel_atomic_state *state, bool joined_mbus); struct intel_cdclk_state * intel_atomic_get_cdclk_state(struct intel_atomic_state *state); +void intel_cdclk_crtc_disable_noatomic(struct intel_crtc *crtc); #define to_intel_cdclk_state(global_state) \ container_of_const((global_state), struct intel_cdclk_state, base) diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index a5a00b3ce98f..826998909045 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -158,8 +158,6 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc) struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_bw_state *bw_state = to_intel_bw_state(i915->display.bw.obj.state); - struct intel_cdclk_state *cdclk_state = - to_intel_cdclk_state(i915->display.cdclk.obj.state); struct intel_dbuf_state *dbuf_state = to_intel_dbuf_state(i915->display.dbuf.obj.state); struct intel_pmdemand_state *pmdemand_state = @@ -179,9 +177,7 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc) intel_display_power_put_all_in_set(display, &crtc->enabled_power_domains); - cdclk_state->min_cdclk[pipe] = 0; - cdclk_state->min_voltage_level[pipe] = 0; - cdclk_state->active_pipes &= ~BIT(pipe); + intel_cdclk_crtc_disable_noatomic(crtc); dbuf_state->active_pipes &= ~BIT(pipe); From d66fbd662ddae1ab133e3269a4c2d68971075afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:07 +0200 Subject: [PATCH 79/92] drm/i915: Extract skl_wm_crtc_disable_noatomic() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hoist the dbuf stuff into a separate function from intel_crtc_disable_noatomic_complete() so that the details are better hidden inside skl_watermark.c. We can also skip the whole thing on pre-skl since the dbuf state isn't actually used on those platforms. The readout path does still fill dbuf_state->active_pipes but we'll remedy that later. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-6-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_modeset_setup.c | 5 +---- drivers/gpu/drm/i915/display/skl_watermark.c | 13 +++++++++++++ drivers/gpu/drm/i915/display/skl_watermark.h | 2 ++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 826998909045..10a2421f7c50 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -158,8 +158,6 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc) struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_bw_state *bw_state = to_intel_bw_state(i915->display.bw.obj.state); - struct intel_dbuf_state *dbuf_state = - to_intel_dbuf_state(i915->display.dbuf.obj.state); struct intel_pmdemand_state *pmdemand_state = to_intel_pmdemand_state(i915->display.pmdemand.obj.state); struct intel_crtc_state *crtc_state = @@ -178,8 +176,7 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc) intel_display_power_put_all_in_set(display, &crtc->enabled_power_domains); intel_cdclk_crtc_disable_noatomic(crtc); - - dbuf_state->active_pipes &= ~BIT(pipe); + skl_wm_crtc_disable_noatomic(crtc); bw_state->data_rate[pipe] = 0; bw_state->num_active_planes[pipe] = 0; diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 10a1daad28eb..4930e52322d3 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -3845,6 +3845,19 @@ static void skl_wm_get_hw_state_and_sanitize(struct drm_i915_private *i915) skl_dbuf_sanitize(i915); } +void skl_wm_crtc_disable_noatomic(struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(crtc); + struct intel_dbuf_state *dbuf_state = + to_intel_dbuf_state(display->dbuf.obj.state); + enum pipe pipe = crtc->pipe; + + if (DISPLAY_VER(display) < 9) + return; + + dbuf_state->active_pipes &= ~BIT(pipe); +} + void intel_wm_state_verify(struct intel_atomic_state *state, struct intel_crtc *crtc) { diff --git a/drivers/gpu/drm/i915/display/skl_watermark.h b/drivers/gpu/drm/i915/display/skl_watermark.h index c5547485225a..8c07c11135c7 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.h +++ b/drivers/gpu/drm/i915/display/skl_watermark.h @@ -41,6 +41,8 @@ bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb, void intel_wm_state_verify(struct intel_atomic_state *state, struct intel_crtc *crtc); +void skl_wm_crtc_disable_noatomic(struct intel_crtc *crtc); + void skl_watermark_ipc_init(struct drm_i915_private *i915); void skl_watermark_ipc_update(struct drm_i915_private *i915); bool skl_watermark_ipc_enabled(struct drm_i915_private *i915); From 1dc6076c67a0341acc168858e833c9cebd734a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:08 +0200 Subject: [PATCH 80/92] drm/i915: clean up pipe's ddb usage in intel_crtc_disable_noatomic() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the ddb tracking information when we disable a pipe during sanitization. Avoids leaving stale junk in the states. Currently this doesn't do anything as we haven't read out this state yet when we do the sanitization, but that will change soon. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-7-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/skl_watermark.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 4930e52322d3..9584d4da13d0 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -3848,6 +3848,8 @@ static void skl_wm_get_hw_state_and_sanitize(struct drm_i915_private *i915) void skl_wm_crtc_disable_noatomic(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); + struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); struct intel_dbuf_state *dbuf_state = to_intel_dbuf_state(display->dbuf.obj.state); enum pipe pipe = crtc->pipe; @@ -3856,6 +3858,13 @@ void skl_wm_crtc_disable_noatomic(struct intel_crtc *crtc) return; dbuf_state->active_pipes &= ~BIT(pipe); + + dbuf_state->weight[pipe] = 0; + dbuf_state->slices[pipe] = 0; + + memset(&dbuf_state->ddb[pipe], 0, sizeof(dbuf_state->ddb[pipe])); + + memset(&crtc_state->wm.skl.ddb, 0, sizeof(crtc_state->wm.skl.ddb)); } void intel_wm_state_verify(struct intel_atomic_state *state, From d34b59d5ba411e26ec13d71dda98ff40510feae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:09 +0200 Subject: [PATCH 81/92] drm/i915: Add skl_wm_plane_disable_noatomic() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add skl_wm_plane_disable_noatomic() which will clear out all the ddb and wm state for the plane. And let's do this _before_ we call plane->disable_arm() so that it'll actually clear out the state in the hardware as well. Currently this won't do anything new for most of the intel_plane_disable_noatomic() calls since those are done before wm readout, and thus everything wm/ddb related in the state will still be zeroed anyway. The only difference will be for skl_dbuf_sanitize() is happens after wm readout. But I'll be reordering thigns so that wm readout happens earlier and at that point this will guarantee that we still clear out the old wm/ddb junk from the state. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-8-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 2 ++ drivers/gpu/drm/i915/display/skl_watermark.c | 22 ++++++++++++++++++++ drivers/gpu/drm/i915/display/skl_watermark.h | 2 ++ 3 files changed, 26 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 5d7b28f6009f..3afb85fe8536 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -678,6 +678,8 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, intel_set_plane_visible(crtc_state, plane_state, false); intel_plane_fixup_bitmasks(crtc_state); + skl_wm_plane_disable_noatomic(crtc, plane); + if ((crtc_state->active_planes & ~BIT(PLANE_CURSOR)) == 0 && hsw_ips_disable(crtc_state)) { crtc_state->ips_enabled = false; diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 9584d4da13d0..da7ffcfd9478 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -3867,6 +3867,28 @@ void skl_wm_crtc_disable_noatomic(struct intel_crtc *crtc) memset(&crtc_state->wm.skl.ddb, 0, sizeof(crtc_state->wm.skl.ddb)); } +void skl_wm_plane_disable_noatomic(struct intel_crtc *crtc, + struct intel_plane *plane) +{ + struct intel_display *display = to_intel_display(crtc); + struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); + + if (DISPLAY_VER(display) < 9) + return; + + skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[plane->id], 0, 0); + skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[plane->id], 0, 0); + + crtc_state->wm.skl.plane_min_ddb[plane->id] = 0; + crtc_state->wm.skl.plane_interim_ddb[plane->id] = 0; + + memset(&crtc_state->wm.skl.raw.planes[plane->id], 0, + sizeof(crtc_state->wm.skl.raw.planes[plane->id])); + memset(&crtc_state->wm.skl.optimal.planes[plane->id], 0, + sizeof(crtc_state->wm.skl.optimal.planes[plane->id])); +} + void intel_wm_state_verify(struct intel_atomic_state *state, struct intel_crtc *crtc) { diff --git a/drivers/gpu/drm/i915/display/skl_watermark.h b/drivers/gpu/drm/i915/display/skl_watermark.h index 8c07c11135c7..d9cff6c54310 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.h +++ b/drivers/gpu/drm/i915/display/skl_watermark.h @@ -42,6 +42,8 @@ void intel_wm_state_verify(struct intel_atomic_state *state, struct intel_crtc *crtc); void skl_wm_crtc_disable_noatomic(struct intel_crtc *crtc); +void skl_wm_plane_disable_noatomic(struct intel_crtc *crtc, + struct intel_plane *plane); void skl_watermark_ipc_init(struct drm_i915_private *i915); void skl_watermark_ipc_update(struct drm_i915_private *i915); From 1ec968609518a0316301ce15b41b401d3976f1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:10 +0200 Subject: [PATCH 82/92] drm/i915: Extract intel_bw_crtc_disable_noatomic() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hoist the bw stuff into a separate function from intel_crtc_disable_noatomic_complete() so that the details are better hidden inside intel_bw.c. We can also skip the whole thing on pre-skl since the dbuf state isn't actually used on those platforms. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-9-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_bw.c | 14 ++++++++++++++ drivers/gpu/drm/i915/display/intel_bw.h | 2 ++ drivers/gpu/drm/i915/display/intel_modeset_setup.c | 6 +----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 23edc81741de..417d2d527ae4 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -1422,6 +1422,20 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) return 0; } +void intel_bw_crtc_disable_noatomic(struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(crtc); + struct intel_bw_state *bw_state = + to_intel_bw_state(display->bw.obj.state); + enum pipe pipe = crtc->pipe; + + if (DISPLAY_VER(display) < 9) + return; + + bw_state->data_rate[pipe] = 0; + bw_state->num_active_planes[pipe] = 0; +} + static struct intel_global_state * intel_bw_duplicate_state(struct intel_global_obj *obj) { diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h index 161813cca473..bd94dde207ee 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.h +++ b/drivers/gpu/drm/i915/display/intel_bw.h @@ -14,6 +14,7 @@ struct drm_i915_private; struct intel_atomic_state; +struct intel_crtc; struct intel_crtc_state; struct intel_dbuf_bw { @@ -81,5 +82,6 @@ int intel_bw_calc_min_cdclk(struct intel_atomic_state *state, bool *need_cdclk_calc); int intel_bw_min_cdclk(struct drm_i915_private *i915, const struct intel_bw_state *bw_state); +void intel_bw_crtc_disable_noatomic(struct intel_crtc *crtc); #endif /* __INTEL_BW_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 10a2421f7c50..e9b0533526f6 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -156,8 +156,6 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); - struct intel_bw_state *bw_state = - to_intel_bw_state(i915->display.bw.obj.state); struct intel_pmdemand_state *pmdemand_state = to_intel_pmdemand_state(i915->display.pmdemand.obj.state); struct intel_crtc_state *crtc_state = @@ -177,9 +175,7 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc) intel_cdclk_crtc_disable_noatomic(crtc); skl_wm_crtc_disable_noatomic(crtc); - - bw_state->data_rate[pipe] = 0; - bw_state->num_active_planes[pipe] = 0; + intel_bw_crtc_disable_noatomic(crtc); intel_pmdemand_update_port_clock(display, pmdemand_state, pipe, 0); } From bd17fc4b6b2b522567982b7a0b2f6c5972e504fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:11 +0200 Subject: [PATCH 83/92] drm/i915: Extract intel_cdclk_update_hw_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hoist the cdclk stuff into a separate function from intel_modeset_readout_hw_state() so that the details are better hidden inside intel_cdclk.c. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-10-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_cdclk.c | 29 ++++++++++++++++++- drivers/gpu/drm/i915/display/intel_cdclk.h | 2 +- .../drm/i915/display/intel_modeset_setup.c | 16 ++-------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 4b7058e65588..947833a96ab7 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2788,7 +2788,7 @@ static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state) return min_cdclk; } -int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) +static int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) { int min_cdclk; @@ -3340,6 +3340,33 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) return 0; } +void intel_cdclk_update_hw_state(struct intel_display *display) +{ + struct intel_cdclk_state *cdclk_state = + to_intel_cdclk_state(display->cdclk.obj.state); + struct intel_crtc *crtc; + + cdclk_state->active_pipes = 0; + + for_each_intel_crtc(display->drm, crtc) { + const struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); + enum pipe pipe = crtc->pipe; + int min_cdclk = 0; + + if (crtc_state->hw.active) { + cdclk_state->active_pipes |= BIT(pipe); + + min_cdclk = intel_crtc_compute_min_cdclk(crtc_state); + if (drm_WARN_ON(display->drm, min_cdclk < 0)) + min_cdclk = 0; + } + + cdclk_state->min_cdclk[pipe] = min_cdclk; + cdclk_state->min_voltage_level[pipe] = crtc_state->min_voltage_level; + } +} + void intel_cdclk_crtc_disable_noatomic(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index 689e12e2196b..a1cefd455d92 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -59,7 +59,6 @@ struct intel_cdclk_state { bool disable_pipes; }; -int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state); void intel_cdclk_init_hw(struct intel_display *display); void intel_cdclk_uninit_hw(struct intel_display *display); void intel_init_cdclk_hooks(struct intel_display *display); @@ -84,6 +83,7 @@ int intel_cdclk_atomic_check(struct intel_atomic_state *state, int intel_cdclk_state_set_joined_mbus(struct intel_atomic_state *state, bool joined_mbus); struct intel_cdclk_state * intel_atomic_get_cdclk_state(struct intel_atomic_state *state); +void intel_cdclk_update_hw_state(struct intel_display *display); void intel_cdclk_crtc_disable_noatomic(struct intel_crtc *crtc); #define to_intel_cdclk_state(global_state) \ diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index e9b0533526f6..1cfa03bd3224 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -693,8 +693,6 @@ static void readout_plane_state(struct drm_i915_private *i915) static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) { struct intel_display *display = &i915->display; - struct intel_cdclk_state *cdclk_state = - to_intel_cdclk_state(i915->display.cdclk.obj.state); struct intel_dbuf_state *dbuf_state = to_intel_dbuf_state(i915->display.dbuf.obj.state); struct intel_pmdemand_state *pmdemand_state = @@ -730,7 +728,6 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) str_enabled_disabled(crtc_state->hw.active)); } - cdclk_state->active_pipes = active_pipes; dbuf_state->active_pipes = active_pipes; readout_plane_state(i915); @@ -833,7 +830,6 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane *plane; - int min_cdclk = 0; if (crtc_state->hw.active) { /* @@ -882,22 +878,14 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) crtc_state->min_cdclk[plane->id]); } - if (crtc_state->hw.active) { - min_cdclk = intel_crtc_compute_min_cdclk(crtc_state); - if (drm_WARN_ON(&i915->drm, min_cdclk < 0)) - min_cdclk = 0; - } - - cdclk_state->min_cdclk[crtc->pipe] = min_cdclk; - cdclk_state->min_voltage_level[crtc->pipe] = - crtc_state->min_voltage_level; - intel_pmdemand_update_port_clock(display, pmdemand_state, pipe, crtc_state->port_clock); intel_bw_crtc_update(bw_state, crtc_state); } + intel_cdclk_update_hw_state(display); + intel_pmdemand_init_pmdemand_params(display, pmdemand_state); } From ad2d834f888b0eeed8675e82705258fdd81021b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:12 +0200 Subject: [PATCH 84/92] drm/i915: Extract intel_bw_update_hw_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hoist the bw stuff into a separate function from intel_modeset_readout_hw_state() so that the details are better hidden inside intel_bw.c. We can also skip the whole thing on pre-skl since the dbuf state isn't actually used on those platforms. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-11-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_bw.c | 21 +++++++++++++++++-- drivers/gpu/drm/i915/display/intel_bw.h | 4 ++-- .../drm/i915/display/intel_modeset_setup.c | 5 +---- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 417d2d527ae4..0090ee7e73a1 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -806,8 +806,8 @@ static int intel_bw_crtc_min_cdclk(const struct intel_crtc_state *crtc_state) return DIV_ROUND_UP_ULL(mul_u32_u32(intel_bw_crtc_data_rate(crtc_state), 10), 512); } -void intel_bw_crtc_update(struct intel_bw_state *bw_state, - const struct intel_crtc_state *crtc_state) +static void intel_bw_crtc_update(struct intel_bw_state *bw_state, + const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); @@ -1422,6 +1422,23 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) return 0; } +void intel_bw_update_hw_state(struct intel_display *display) +{ + struct intel_bw_state *bw_state = + to_intel_bw_state(display->bw.obj.state); + struct intel_crtc *crtc; + + if (DISPLAY_VER(display) < 9) + return; + + for_each_intel_crtc(display->drm, crtc) { + const struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); + + intel_bw_crtc_update(bw_state, crtc_state); + } +} + void intel_bw_crtc_disable_noatomic(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h index bd94dde207ee..3313e4eac4f0 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.h +++ b/drivers/gpu/drm/i915/display/intel_bw.h @@ -16,6 +16,7 @@ struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; +struct intel_display; struct intel_dbuf_bw { unsigned int max_bw[I915_MAX_DBUF_SLICES]; @@ -74,14 +75,13 @@ intel_atomic_get_bw_state(struct intel_atomic_state *state); void intel_bw_init_hw(struct drm_i915_private *dev_priv); int intel_bw_init(struct drm_i915_private *dev_priv); int intel_bw_atomic_check(struct intel_atomic_state *state); -void intel_bw_crtc_update(struct intel_bw_state *bw_state, - const struct intel_crtc_state *crtc_state); int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv, u32 points_mask); int intel_bw_calc_min_cdclk(struct intel_atomic_state *state, bool *need_cdclk_calc); int intel_bw_min_cdclk(struct drm_i915_private *i915, const struct intel_bw_state *bw_state); +void intel_bw_update_hw_state(struct intel_display *display); void intel_bw_crtc_disable_noatomic(struct intel_crtc *crtc); #endif /* __INTEL_BW_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 1cfa03bd3224..70fad9f89cea 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -825,8 +825,6 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) drm_connector_list_iter_end(&conn_iter); for_each_intel_crtc(&i915->drm, crtc) { - struct intel_bw_state *bw_state = - to_intel_bw_state(i915->display.bw.obj.state); struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane *plane; @@ -880,10 +878,9 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) intel_pmdemand_update_port_clock(display, pmdemand_state, pipe, crtc_state->port_clock); - - intel_bw_crtc_update(bw_state, crtc_state); } + intel_bw_update_hw_state(display); intel_cdclk_update_hw_state(display); intel_pmdemand_init_pmdemand_params(display, pmdemand_state); From 7b65b24a4ecbe11763a68625e7f626d3b913f041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:13 +0200 Subject: [PATCH 85/92] drm/i915: Update bw_state->active_pipes during readout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update bw_state->active_pipes during readout. This was completely missing from the current readout code. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-12-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_bw.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 0090ee7e73a1..30e6f33d6f30 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -1431,9 +1431,15 @@ void intel_bw_update_hw_state(struct intel_display *display) if (DISPLAY_VER(display) < 9) return; + bw_state->active_pipes = 0; + for_each_intel_crtc(display->drm, crtc) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); + enum pipe pipe = crtc->pipe; + + if (crtc_state->hw.active) + bw_state->active_pipes |= BIT(pipe); intel_bw_crtc_update(bw_state, crtc_state); } From ff79a131d37a9ab6301c310f8ea9c12e93212baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:14 +0200 Subject: [PATCH 86/92] drm/i915: Skip some bw_state readout on pre-icl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We only compute bw_state->data_rate and bw_state->num_active_planes on icl+. Do the same during readout so that we don't leave random junk inside the state. v2: Skip the whole intel_bw_crtc_update() (Vinod) Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-13-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_bw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 30e6f33d6f30..e4d79b496e12 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -1441,7 +1441,8 @@ void intel_bw_update_hw_state(struct intel_display *display) if (crtc_state->hw.active) bw_state->active_pipes |= BIT(pipe); - intel_bw_crtc_update(bw_state, crtc_state); + if (DISPLAY_VER(display) >= 11) + intel_bw_crtc_update(bw_state, crtc_state); } } From e45b8192c7e757d33dd1a7f1b1ea6696fbdc218b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:15 +0200 Subject: [PATCH 87/92] sem/i915: Simplify intel_cdclk_update_hw_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_crtc_calculate_min_cdclk() can't return an error (since commit 5ac860cc5254 ("drm/i915: Fix DBUF bandwidth vs. cdclk handling")) so there is no point in checking for one. Also we can just call it unconditionally since it itself checks crtc_state->hw.enabled. We are currently checking crtc_state->hw.active in the readout path, but active==enabled during readout, and arguably enabled is the more correct thing to check anyway. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-14-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_cdclk.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 947833a96ab7..62caee4a8b64 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -3352,17 +3352,11 @@ void intel_cdclk_update_hw_state(struct intel_display *display) const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); enum pipe pipe = crtc->pipe; - int min_cdclk = 0; - if (crtc_state->hw.active) { + if (crtc_state->hw.active) cdclk_state->active_pipes |= BIT(pipe); - min_cdclk = intel_crtc_compute_min_cdclk(crtc_state); - if (drm_WARN_ON(display->drm, min_cdclk < 0)) - min_cdclk = 0; - } - - cdclk_state->min_cdclk[pipe] = min_cdclk; + cdclk_state->min_cdclk[pipe] = intel_crtc_compute_min_cdclk(crtc_state); cdclk_state->min_voltage_level[pipe] = crtc_state->min_voltage_level; } } From 003ec4ce424cc3421cf82ec1b6f004f9c0fcb8a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:16 +0200 Subject: [PATCH 88/92] drm/i915: Simplify cdclk_disable_noatomic() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of hand rolling the cdclk state disabling for a pipe in noatomic() let's just recompute the whole thing from scratch. Less code we have to remember to keep in sync. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-15-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_cdclk.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 62caee4a8b64..2a8749a0213e 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -3364,13 +3364,8 @@ void intel_cdclk_update_hw_state(struct intel_display *display) void intel_cdclk_crtc_disable_noatomic(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); - struct intel_cdclk_state *cdclk_state = - to_intel_cdclk_state(display->cdclk.obj.state); - enum pipe pipe = crtc->pipe; - cdclk_state->min_cdclk[pipe] = 0; - cdclk_state->min_voltage_level[pipe] = 0; - cdclk_state->active_pipes &= ~BIT(pipe); + intel_cdclk_update_hw_state(display); } static int intel_compute_max_dotclk(struct intel_display *display) From dbf1b1ed55badf205f649c626338288f1d076391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:17 +0200 Subject: [PATCH 89/92] drm/i915: Split wm sanitize from readout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I'll need to move the wm readout to an earlier point in the sequence (since the bw state readout will need ddb information from the wm readout). But (at least for now) the wm sanitation will need to stay put as it needs to also sanitize things for any pipes/planes we disable later during the hw state takeover. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-16-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/i9xx_wm.c | 18 ++++-------------- .../gpu/drm/i915/display/intel_display_core.h | 1 + .../gpu/drm/i915/display/intel_modeset_setup.c | 1 + drivers/gpu/drm/i915/display/intel_wm.c | 6 ++++++ drivers/gpu/drm/i915/display/intel_wm.h | 1 + drivers/gpu/drm/i915/display/skl_watermark.c | 7 +++---- 6 files changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 497850a6ac81..7c80e37c1c5f 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -3902,12 +3902,6 @@ static void g4x_wm_sanitize(struct drm_i915_private *dev_priv) mutex_unlock(&dev_priv->display.wm.wm_mutex); } -static void g4x_wm_get_hw_state_and_sanitize(struct drm_i915_private *i915) -{ - g4x_wm_get_hw_state(i915); - g4x_wm_sanitize(i915); -} - static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) { struct vlv_wm_values *wm = &dev_priv->display.wm.vlv; @@ -4055,12 +4049,6 @@ static void vlv_wm_sanitize(struct drm_i915_private *dev_priv) mutex_unlock(&dev_priv->display.wm.wm_mutex); } -static void vlv_wm_get_hw_state_and_sanitize(struct drm_i915_private *i915) -{ - vlv_wm_get_hw_state(i915); - vlv_wm_sanitize(i915); -} - /* * FIXME should probably kill this and improve * the real watermark readout/sanitation instead @@ -4122,14 +4110,16 @@ static const struct intel_wm_funcs vlv_wm_funcs = { .initial_watermarks = vlv_initial_watermarks, .optimize_watermarks = vlv_optimize_watermarks, .atomic_update_watermarks = vlv_atomic_update_fifo, - .get_hw_state = vlv_wm_get_hw_state_and_sanitize, + .get_hw_state = vlv_wm_get_hw_state, + .sanitize = vlv_wm_sanitize, }; static const struct intel_wm_funcs g4x_wm_funcs = { .compute_watermarks = g4x_compute_watermarks, .initial_watermarks = g4x_initial_watermarks, .optimize_watermarks = g4x_optimize_watermarks, - .get_hw_state = g4x_wm_get_hw_state_and_sanitize, + .get_hw_state = g4x_wm_get_hw_state, + .sanitize = g4x_wm_sanitize, }; static const struct intel_wm_funcs pnv_wm_funcs = { diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 7360ad39b1cc..eeb7ae3eaea8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -91,6 +91,7 @@ struct intel_wm_funcs { struct intel_crtc *crtc); int (*compute_global_watermarks)(struct intel_atomic_state *state); void (*get_hw_state)(struct drm_i915_private *i915); + void (*sanitize)(struct drm_i915_private *i915); }; struct intel_audio_state { diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 70fad9f89cea..03c0facfad7a 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -991,6 +991,7 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915, intel_dpll_sanitize_state(display); intel_wm_get_hw_state(i915); + intel_wm_sanitize(i915); for_each_intel_crtc(&i915->drm, crtc) { struct intel_crtc_state *crtc_state = diff --git a/drivers/gpu/drm/i915/display/intel_wm.c b/drivers/gpu/drm/i915/display/intel_wm.c index d7dc49aecd27..f00f4cfc58e5 100644 --- a/drivers/gpu/drm/i915/display/intel_wm.c +++ b/drivers/gpu/drm/i915/display/intel_wm.c @@ -108,6 +108,12 @@ void intel_wm_get_hw_state(struct drm_i915_private *i915) return i915->display.funcs.wm->get_hw_state(i915); } +void intel_wm_sanitize(struct drm_i915_private *i915) +{ + if (i915->display.funcs.wm->sanitize) + return i915->display.funcs.wm->sanitize(i915); +} + bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { diff --git a/drivers/gpu/drm/i915/display/intel_wm.h b/drivers/gpu/drm/i915/display/intel_wm.h index e97cdca89a5c..7d3a447054b3 100644 --- a/drivers/gpu/drm/i915/display/intel_wm.h +++ b/drivers/gpu/drm/i915/display/intel_wm.h @@ -25,6 +25,7 @@ void intel_optimize_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc); int intel_compute_global_watermarks(struct intel_atomic_state *state); void intel_wm_get_hw_state(struct drm_i915_private *i915); +void intel_wm_sanitize(struct drm_i915_private *i915); bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); void intel_print_wm_latency(struct drm_i915_private *i915, diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index da7ffcfd9478..0bd7aa3b2877 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -3837,10 +3837,8 @@ static void skl_dbuf_sanitize(struct drm_i915_private *i915) } } -static void skl_wm_get_hw_state_and_sanitize(struct drm_i915_private *i915) +static void skl_wm_sanitize(struct drm_i915_private *i915) { - skl_wm_get_hw_state(i915); - skl_mbus_sanitize(i915); skl_dbuf_sanitize(i915); } @@ -4016,7 +4014,8 @@ void intel_wm_state_verify(struct intel_atomic_state *state, static const struct intel_wm_funcs skl_wm_funcs = { .compute_global_watermarks = skl_compute_wm, - .get_hw_state = skl_wm_get_hw_state_and_sanitize, + .get_hw_state = skl_wm_get_hw_state, + .sanitize = skl_wm_sanitize, }; void skl_wm_init(struct drm_i915_private *i915) From 14968c207a0f88c6d21c798af14fb318b90f2eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:18 +0200 Subject: [PATCH 90/92] drm/i915: Do wm readout ealier for skl+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the wm readout to happen earlier. This is needed because the bw_state readout will need ddb information populated by the wm readout. For now limit this to skl+ as I've not really analyzed the implications of doing this on other platforms. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-17-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_modeset_setup.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 03c0facfad7a..6a4142d7d025 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -880,6 +880,10 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) crtc_state->port_clock); } + /* TODO move here (or even earlier?) on all platforms */ + if (DISPLAY_VER(display) >= 9) + intel_wm_get_hw_state(i915); + intel_bw_update_hw_state(display); intel_cdclk_update_hw_state(display); @@ -990,7 +994,9 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915, intel_dpll_sanitize_state(display); - intel_wm_get_hw_state(i915); + /* TODO move earlier on all platforms */ + if (DISPLAY_VER(display) < 9) + intel_wm_get_hw_state(i915); intel_wm_sanitize(i915); for_each_intel_crtc(&i915->drm, crtc) { From e6001c930aae40f676227a27e0674e4c8953b1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:19 +0200 Subject: [PATCH 91/92] drm/i915: Move dbuf_state->active_pipes into skl_wm_get_hw_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the dbuf_state readout parts into skl_wm_get_hw_state() so that the details are better hidden from sight. This will stop updating this on pre-skl, but that's what we want since the dbuf state is only used on skl+. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-18-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_modeset_setup.c | 8 -------- drivers/gpu/drm/i915/display/skl_watermark.c | 5 ++++- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 6a4142d7d025..312b21b1ab59 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -693,8 +693,6 @@ static void readout_plane_state(struct drm_i915_private *i915) static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) { struct intel_display *display = &i915->display; - struct intel_dbuf_state *dbuf_state = - to_intel_dbuf_state(i915->display.dbuf.obj.state); struct intel_pmdemand_state *pmdemand_state = to_intel_pmdemand_state(i915->display.pmdemand.obj.state); enum pipe pipe; @@ -702,7 +700,6 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) struct intel_encoder *encoder; struct intel_connector *connector; struct drm_connector_list_iter conn_iter; - u8 active_pipes = 0; for_each_intel_crtc(&i915->drm, crtc) { struct intel_crtc_state *crtc_state = @@ -719,17 +716,12 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) crtc->base.enabled = crtc_state->hw.enable; crtc->active = crtc_state->hw.active; - if (crtc_state->hw.active) - active_pipes |= BIT(crtc->pipe); - drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] hw state readout: %s\n", crtc->base.base.id, crtc->base.name, str_enabled_disabled(crtc_state->hw.active)); } - dbuf_state->active_pipes = active_pipes; - readout_plane_state(i915); for_each_intel_encoder(&i915->drm, encoder) { diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 0bd7aa3b2877..2d0de1c63308 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -3157,6 +3157,7 @@ static void skl_wm_get_hw_state(struct drm_i915_private *i915) dbuf_state->joined_mbus = intel_de_read(display, MBUS_CTL) & MBUS_JOIN; dbuf_state->mdclk_cdclk_ratio = intel_mdclk_cdclk_ratio(display, &display->cdclk.hw); + dbuf_state->active_pipes = 0; for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = @@ -3168,8 +3169,10 @@ static void skl_wm_get_hw_state(struct drm_i915_private *i915) memset(&crtc_state->wm.skl.optimal, 0, sizeof(crtc_state->wm.skl.optimal)); - if (crtc_state->hw.active) + if (crtc_state->hw.active) { skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal); + dbuf_state->active_pipes |= BIT(pipe); + } crtc_state->wm.skl.raw = crtc_state->wm.skl.optimal; memset(&dbuf_state->ddb[pipe], 0, sizeof(dbuf_state->ddb[pipe])); From bb800b56f01f430f4d7b360c758a9ed28f758d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 6 Mar 2025 18:34:20 +0200 Subject: [PATCH 92/92] drm/i915: Relocate intel_bw_crtc_update() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_bw_crtc_update() is only used by the readout path, so relocate the function next its only caller. Easier to read the code when related things are nearby. Reviewed-by: Vinod Govindapillai Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250306163420.3961-19-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_bw.c | 36 ++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index e4d79b496e12..048be2872247 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -806,24 +806,6 @@ static int intel_bw_crtc_min_cdclk(const struct intel_crtc_state *crtc_state) return DIV_ROUND_UP_ULL(mul_u32_u32(intel_bw_crtc_data_rate(crtc_state), 10), 512); } -static void intel_bw_crtc_update(struct intel_bw_state *bw_state, - const struct intel_crtc_state *crtc_state) -{ - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - - bw_state->data_rate[crtc->pipe] = - intel_bw_crtc_data_rate(crtc_state); - bw_state->num_active_planes[crtc->pipe] = - intel_bw_crtc_num_active_planes(crtc_state); - bw_state->force_check_qgv = true; - - drm_dbg_kms(&i915->drm, "pipe %c data rate %u num active planes %u\n", - pipe_name(crtc->pipe), - bw_state->data_rate[crtc->pipe], - bw_state->num_active_planes[crtc->pipe]); -} - static unsigned int intel_bw_num_active_planes(struct drm_i915_private *dev_priv, const struct intel_bw_state *bw_state) { @@ -1422,6 +1404,24 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) return 0; } +static void intel_bw_crtc_update(struct intel_bw_state *bw_state, + const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + + bw_state->data_rate[crtc->pipe] = + intel_bw_crtc_data_rate(crtc_state); + bw_state->num_active_planes[crtc->pipe] = + intel_bw_crtc_num_active_planes(crtc_state); + bw_state->force_check_qgv = true; + + drm_dbg_kms(&i915->drm, "pipe %c data rate %u num active planes %u\n", + pipe_name(crtc->pipe), + bw_state->data_rate[crtc->pipe], + bw_state->num_active_planes[crtc->pipe]); +} + void intel_bw_update_hw_state(struct intel_display *display) { struct intel_bw_state *bw_state =