mirror of
https://github.com/torvalds/linux.git
synced 2026-07-30 19:21:28 +02:00
drm/i915/dp: Handle Synaptics DSC throughput link-bpp quirk
Handle the DSC pixel throughput quirk, limiting the compressed link-bpp value for Synaptics Panamera branch devices, working around a blank/unstable output issue observed on docking stations containing these branch devices, when using a mode with a high pixel clock and a high compressed link-bpp value. For now use the same mode clock limit for RGB/YUV444 and YUV422/420 output modes. This may result in limiting the link-bpp value for a YUV422/420 output mode already at a lower than required mode clock. v2: Apply the quirk only when DSC is enabled. v3 (Ville): - Move adjustment of link-bpp within the already existing is_dsc if branch. - Add TODO comment to move the HW revision check as well to the DRM core quirk table. v4: - Fix incorrect fxp_q4_from_int(INT_MAX) vs. INT_MAX return value from dsc_throughput_quirk_max_bpp_x16(). Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reported-by: Vidya Srinivas <vidya.srinivas@intel.com> Reported-and-tested-by: Swati Sharma <swati2.sharma@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://lore.kernel.org/r/20250930182450.563016-7-imre.deak@intel.com
This commit is contained in:
parent
a086950670
commit
8d677285a3
|
|
@ -551,6 +551,7 @@ struct intel_connector {
|
|||
u8 fec_capability;
|
||||
|
||||
u8 dsc_hblank_expansion_quirk:1;
|
||||
u8 dsc_throughput_quirk:1;
|
||||
u8 dsc_decompression_enabled:1;
|
||||
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -2485,6 +2485,40 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dsc_throughput_quirk_max_bpp_x16(const struct intel_connector *connector,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&crtc_state->hw.adjusted_mode;
|
||||
|
||||
if (!connector->dp.dsc_throughput_quirk)
|
||||
return INT_MAX;
|
||||
|
||||
/*
|
||||
* Synaptics Panamera branch devices have a problem decompressing a
|
||||
* stream with a compressed link-bpp higher than 12, if the pixel
|
||||
* clock is higher than ~50 % of the maximum overall throughput
|
||||
* reported by the branch device. Work around this by limiting the
|
||||
* maximum link bpp for such pixel clocks.
|
||||
*
|
||||
* TODO: Use the throughput value specific to the actual RGB/YUV
|
||||
* format of the output, after determining the pixel clock limit for
|
||||
* YUV modes. For now use the smaller of the throughput values, which
|
||||
* may result in limiting the link-bpp value already at a lower than
|
||||
* required mode clock in case of native YUV422/420 output formats.
|
||||
* The RGB/YUV444 throughput value should be always either equal or
|
||||
* smaller than the YUV422/420 value, but let's not depend on this
|
||||
* assumption.
|
||||
*/
|
||||
if (adjusted_mode->crtc_clock <
|
||||
min(connector->dp.dsc_branch_caps.overall_throughput.rgb_yuv444,
|
||||
connector->dp.dsc_branch_caps.overall_throughput.yuv422_420) / 2)
|
||||
return INT_MAX;
|
||||
|
||||
return fxp_q4_from_int(12);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the output link min, max bpp values in limits based on the pipe bpp
|
||||
* range, crtc_state and dsc mode. Return true on success.
|
||||
|
|
@ -2516,6 +2550,7 @@ intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
|
|||
} else {
|
||||
int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp;
|
||||
int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp;
|
||||
int throughput_max_bpp_x16;
|
||||
|
||||
dsc_src_min_bpp = intel_dp_dsc_min_src_compressed_bpp();
|
||||
dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(crtc_state);
|
||||
|
|
@ -2530,6 +2565,19 @@ intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
|
|||
min(dsc_sink_max_bpp, dsc_src_max_bpp) : dsc_src_max_bpp;
|
||||
|
||||
max_link_bpp_x16 = min(max_link_bpp_x16, fxp_q4_from_int(dsc_max_bpp));
|
||||
|
||||
throughput_max_bpp_x16 = dsc_throughput_quirk_max_bpp_x16(connector, crtc_state);
|
||||
throughput_max_bpp_x16 = clamp(throughput_max_bpp_x16,
|
||||
limits->link.min_bpp_x16, max_link_bpp_x16);
|
||||
if (throughput_max_bpp_x16 < max_link_bpp_x16) {
|
||||
max_link_bpp_x16 = throughput_max_bpp_x16;
|
||||
|
||||
drm_dbg_kms(display->drm,
|
||||
"[CRTC:%d:%s][CONNECTOR:%d:%s] Decreasing link max bpp to " FXP_Q4_FMT " due to DSC throughput quirk\n",
|
||||
crtc->base.base.id, crtc->base.name,
|
||||
connector->base.base.id, connector->base.name,
|
||||
FXP_Q4_ARGS(max_link_bpp_x16));
|
||||
}
|
||||
}
|
||||
|
||||
limits->link.max_bpp_x16 = max_link_bpp_x16;
|
||||
|
|
@ -4237,6 +4285,7 @@ void intel_dp_get_dsc_sink_cap(u8 dpcd_rev,
|
|||
connector->dp.fec_capability = 0;
|
||||
|
||||
memset(&connector->dp.dsc_branch_caps, 0, sizeof(connector->dp.dsc_branch_caps));
|
||||
connector->dp.dsc_throughput_quirk = false;
|
||||
|
||||
if (dpcd_rev < DP_DPCD_REV_14)
|
||||
return;
|
||||
|
|
@ -4257,6 +4306,14 @@ void intel_dp_get_dsc_sink_cap(u8 dpcd_rev,
|
|||
return;
|
||||
|
||||
init_dsc_overall_throughput_limits(connector, is_branch);
|
||||
|
||||
/*
|
||||
* TODO: Move the HW rev check as well to the DRM core quirk table if
|
||||
* that's required after clarifying the list of affected devices.
|
||||
*/
|
||||
if (drm_dp_has_quirk(desc, DP_DPCD_QUIRK_DSC_THROUGHPUT_BPP_LIMIT) &&
|
||||
desc->ident.hw_rev == 0x10)
|
||||
connector->dp.dsc_throughput_quirk = true;
|
||||
}
|
||||
|
||||
static void intel_edp_get_dsc_sink_cap(u8 edp_dpcd_rev, struct intel_connector *connector)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user