From 2c2e7170a750506ed9e1d28e225b647a6563fb3c Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Thu, 27 Feb 2025 17:28:18 -0300 Subject: [PATCH 01/16] 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; } -- 2.51.0 From 322ec93e9081d717fbc02c14fe80f754709e8b9c Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Thu, 27 Feb 2025 18:09:12 -0300 Subject: [PATCH 02/16] drm/i915/display: Use explicit base values in POWER_DOMAIN_*() macros MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 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); -- 2.51.0 From 5c91b5ad7155ee6e22930f7cbcb8e47dadbe13e7 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa Date: Thu, 27 Feb 2025 18:09:13 -0300 Subject: [PATCH 03/16] drm/i915/display: Make POWER_DOMAIN_*() always result in enum intel_display_power_domain MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 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); -- 2.51.0 From abf874a328a885592a6bfe6f7db463974e14b615 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 28 Feb 2025 14:49:29 +0200 Subject: [PATCH 04/16] 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 @@ err_put_port: 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); -- 2.51.0 From aa389adeaa8565cc664a6ee4a5dbdc7a6000d46f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 28 Feb 2025 14:49:30 +0200 Subject: [PATCH 05/16] 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 @@ out: 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: "); } -- 2.51.0 From f953c6585e2d59254511c8d122e8d1d55a693133 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 28 Feb 2025 14:49:31 +0200 Subject: [PATCH 06/16] 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 @@ link_recover: 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; -- 2.51.0 From fe7fad476ec8153a8b8767a08114e3e4a58a837e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 28 Feb 2025 13:45:27 +0200 Subject: [PATCH 07/16] 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__ */ -- 2.51.0 From 7c04b6c7e9c5b1d8121b4fe88bc47daed2ff8665 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 24 Feb 2025 18:00:48 +0200 Subject: [PATCH 08/16] 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" -- 2.51.0 From 767bb0b172fcfe62000265c91c4a84837d2428a7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 24 Feb 2025 18:00:49 +0200 Subject: [PATCH 09/16] 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; - }; -}; -- 2.51.0 From 840cb2dc27174e06697b5d16ad76cd5adbfb4cdc Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:37:54 +0200 Subject: [PATCH 10/16] 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; -- 2.51.0 From 9a112dd8c17fa6397785f2227dfe4f6f175ed524 Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:37:55 +0200 Subject: [PATCH 11/16] drm/damage-helper: add const qualifier in drm_atomic_helper_damage_merged() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 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 -- 2.51.0 From 6f60de67d7e4ae0f6c7aebcb9b62d89fed7233a4 Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:37:56 +0200 Subject: [PATCH 12/16] drm/i915/display: update and store the plane damage clips MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 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); -- 2.51.0 From 22a28633a40fd419f91ec8304336841d0f9c880d Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:37:57 +0200 Subject: [PATCH 13/16] drm/i915/fbc: add register definitions for fbc dirty rect support MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 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) -- 2.51.0 From c931a0aa82c65964bf62d02d3fb7e69153ff37eb Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:37:58 +0200 Subject: [PATCH 14/16] drm/i915/fbc: introduce HAS_FBC_DIRTY_RECT() for FBC dirty rect support MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 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) -- 2.51.0 From 5adac4c9f321db0b2efb1b6ac6d6d9791ecb6fc0 Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:37:59 +0200 Subject: [PATCH 15/16] drm/i915/fbc: avoid calling fbc activate if fbc is active MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 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); -- 2.51.0 From 194ecad0b5fcd6f1a325e31ade9c19490260b40f Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Fri, 28 Feb 2025 11:38:00 +0200 Subject: [PATCH 16/16] drm/i915/fbc: dirty rect support for FBC MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 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__ */ -- 2.51.0