Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/i915/dp_tunnel: Send BW change notification after tunnel creation

Detecting a bandwidth change for a sink connected through a DP tunnel
depends on updating the sink's DPRX link rate and lane count.

detect_new_tunnel() -> update_tunnel_state() updates the link
configuration only if the tunnel state changes. However, after the
tunnel is created and bandwidth allocation mode is enabled, the tunnel
state itself may remain unchanged.

Record the sink bandwidth before creating the tunnel and compare it to
the bandwidth after tunnel creation and enabling bandwidth allocation
mode, ensuring that any bandwidth change is detected and userspace is
notified accordingly.

Reviewed-by: Arun R Murthy <arun.r.murthy@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: https://patch.msgid.link/20260219182823.926702-6-imre.deak@intel.com

Imre Deak 230f8c99 23a5fd5b

+20 -5
+20 -5
drivers/gpu/drm/i915/display/intel_dp_tunnel.c
··· 62 62 return intel_dp_max_link_data_rate(intel_dp, rate, lane_count); 63 63 } 64 64 65 - static int __update_tunnel_state(struct intel_dp *intel_dp) 65 + static int __update_tunnel_state(struct intel_dp *intel_dp, bool force_sink_update) 66 66 { 67 67 struct intel_display *display = to_intel_display(intel_dp); 68 68 struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; ··· 79 79 return ret; 80 80 } 81 81 82 - if (ret == 0 || 83 - !drm_dp_tunnel_bw_alloc_is_enabled(intel_dp->tunnel)) 82 + if (!force_sink_update && 83 + (ret == 0 || !drm_dp_tunnel_bw_alloc_is_enabled(intel_dp->tunnel))) 84 84 return 0; 85 85 86 86 intel_dp_update_sink_caps(intel_dp); ··· 124 124 125 125 old_bw = get_current_link_bw(intel_dp); 126 126 127 - err = __update_tunnel_state(intel_dp); 127 + err = __update_tunnel_state(intel_dp, false); 128 128 if (err) 129 129 return err; 130 130 ··· 187 187 return allocate_initial_tunnel_bw_for_pipes(intel_dp, pipe_mask); 188 188 } 189 189 190 + /* 191 + * Returns: 192 + * - 0 in case of success - after any tunnel detected and added to @intel_dp 193 + * - 1 in case of success - after a tunnel detected and added to @intel_dp, 194 + * where the link BW via the tunnel changed in a way requiring a user 195 + * notification 196 + * - Negative error code if the tunnel detection failed 197 + */ 190 198 static int detect_new_tunnel(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx) 191 199 { 192 200 struct intel_display *display = to_intel_display(intel_dp); 193 201 struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; 194 202 struct drm_dp_tunnel *tunnel; 203 + int old_bw; 195 204 int ret; 205 + 206 + old_bw = get_current_link_bw(intel_dp); 196 207 197 208 tunnel = drm_dp_tunnel_detect(display->dp_tunnel_mgr, 198 209 &intel_dp->aux); ··· 234 223 return ret; 235 224 } 236 225 237 - return update_tunnel_state(intel_dp); 226 + ret = __update_tunnel_state(intel_dp, true); 227 + if (ret) 228 + return ret; 229 + 230 + return has_tunnel_bw_changed(intel_dp, old_bw) ? 1 : 0; 238 231 } 239 232 240 233 /**