drm/i915/dp_mst: Use link caps for MST DSC config selection

Use the link caps helper to select the maximum DP MST link configuration
for DSC computation, instead of using the separate max rate and lane
count limits, which may not form a valid configuration after individual
configs are disabled by fallback.

Also look up the maximum rate for state computation via the configuration
mask when checking the DSC hblank expansion quirk.

This is a step towards unifying configuration selection and iteration
across connector types and between compute and fallback paths.

The state computation should likely consider all allowed configurations,
as noted in the code comment; for now keep the existing DP MST DSC
behavior of selecting the maximum BW configuration determined by the MST
connector BW config iteration order.

Reviewed-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: https://patch.msgid.link/20260701153204.4124150-22-imre.deak@intel.com
This commit is contained in:
Imre Deak
2026-07-01 18:31:50 +03:00
parent 58e57526d4
commit b66fe0e1bc

View File

@@ -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)