diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 47b8563f85e4..df6e54508e5d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -477,6 +477,7 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, { struct intel_display *display = to_intel_display(intel_dp); struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct intel_dp_link_config max_link_config; crtc_state->pipe_bpp = limits->pipe.max_bpp; @@ -484,8 +485,17 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, "DSC Sink supported compressed min bpp " FXP_Q4_FMT " compressed max bpp " FXP_Q4_FMT "\n", FXP_Q4_ARGS(limits->link.min_bpp_x16), FXP_Q4_ARGS(limits->link.max_bpp_x16)); - crtc_state->lane_count = limits->max_lane_count; - crtc_state->port_clock = limits->max_rate; + /* + * FIXME: Use a proper iteration over the link configurations, instead + * of using only the max BW config. For instance UHBR rate configs may + * have additional limitations over non-UHBR ones, due to the DSC DPT + * bpp maximum limit. + */ + if (!intel_dp_get_connector_max_link_config(connector, limits, &max_link_config)) + return -EINVAL; + + crtc_state->port_clock = max_link_config.rate; + crtc_state->lane_count = max_link_config.lane_count; return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state, limits->link.min_bpp_x16, @@ -501,6 +511,20 @@ static int mode_hblank_period_ns(const struct drm_display_mode *mode) mode->crtc_clock); } +static int get_connector_max_rate(const struct intel_connector *connector, + const struct link_config_limits *limits) +{ + struct intel_dp *intel_dp = intel_attached_dp((struct intel_connector *)connector); + struct intel_dp_link_caps *link_caps = intel_dp->link.caps; + struct intel_dp_link_config max_link_config; + + intel_dp_link_caps_get_max_config(link_caps, + INTEL_DP_LINK_CAPS_ORDER_KEY_RATE_LANE, + limits->link_config_filter, &max_link_config); + + return max_link_config.rate; +} + static bool hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector, const struct intel_crtc_state *crtc_state, @@ -511,11 +535,13 @@ hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector, bool is_uhbr_sink = connector->mst.dp && drm_dp_128b132b_supported(connector->mst.dp->dpcd); int hblank_limit = is_uhbr_sink ? 500 : 300; + int max_rate; if (!connector->dp.dsc_hblank_expansion_quirk) return false; - if (is_uhbr_sink && !drm_dp_is_uhbr_rate(limits->max_rate)) + max_rate = get_connector_max_rate(connector, limits); + if (is_uhbr_sink && !drm_dp_is_uhbr_rate(max_rate)) return false; if (mode_hblank_period_ns(adjusted_mode) > hblank_limit) @@ -537,6 +563,7 @@ adjust_limits_for_dsc_hblank_expansion_quirk(struct intel_dp *intel_dp, struct intel_display *display = to_intel_display(connector); const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); int min_bpp_x16 = limits->link.min_bpp_x16; + int max_rate; if (!hblank_expansion_quirk_needs_dsc(connector, crtc_state, limits)) return true; @@ -563,11 +590,10 @@ adjust_limits_for_dsc_hblank_expansion_quirk(struct intel_dp *intel_dp, return true; } - drm_WARN_ON(display->drm, limits->min_rate != limits->max_rate); - - if (limits->max_rate < 540000) + max_rate = get_connector_max_rate(connector, limits); + if (max_rate < 540000) min_bpp_x16 = fxp_q4_from_int(13); - else if (limits->max_rate < 810000) + else if (max_rate < 810000) min_bpp_x16 = fxp_q4_from_int(10); if (limits->link.min_bpp_x16 >= min_bpp_x16)