drm/i915/dp: Set min_bpp limit to 30 in HDR mode

Update intel_dp_compute_config_limits() to use a minimum of
30 bits per pixel when the connector is in HDR mode
(specifically, when EOTF is SMPTE ST2084), aligning with HDR
display requirements.

To support this, the function now takes a drm_connector_state
instead of an intel_connector, and the required updates are
made in all call sites, including MST handling.

This ensures sufficient bitdepth for HDR content to avoid
banding.

If the required bandwidth for 30 bpp cannot be supported,
the driver will either fall back to DSC or reject the mode
during atomic check if DSC is not supported.

Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
Link: https://lore.kernel.org/r/20250730055523.2214966-3-chaitanya.kumar.borah@intel.com
This commit is contained in:
Chaitanya Kumar Borah 2025-07-30 11:25:23 +05:30 committed by Suraj Kandpal
parent 2e9da93d60
commit ba49a4643c
3 changed files with 15 additions and 9 deletions

View File

@ -2536,13 +2536,15 @@ intel_dp_dsc_compute_pipe_bpp_limits(struct intel_dp *intel_dp,
bool bool
intel_dp_compute_config_limits(struct intel_dp *intel_dp, intel_dp_compute_config_limits(struct intel_dp *intel_dp,
struct intel_connector *connector, struct drm_connector_state *conn_state,
struct intel_crtc_state *crtc_state, struct intel_crtc_state *crtc_state,
bool respect_downstream_limits, bool respect_downstream_limits,
bool dsc, bool dsc,
struct link_config_limits *limits) struct link_config_limits *limits)
{ {
bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST);
struct intel_connector *connector =
to_intel_connector(conn_state->connector);
limits->min_rate = intel_dp_min_link_rate(intel_dp); limits->min_rate = intel_dp_min_link_rate(intel_dp);
limits->max_rate = intel_dp_max_link_rate(intel_dp); limits->max_rate = intel_dp_max_link_rate(intel_dp);
@ -2552,7 +2554,8 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
limits->min_lane_count = intel_dp_min_lane_count(intel_dp); limits->min_lane_count = intel_dp_min_lane_count(intel_dp);
limits->max_lane_count = intel_dp_max_lane_count(intel_dp); limits->max_lane_count = intel_dp_max_lane_count(intel_dp);
limits->pipe.min_bpp = intel_dp_min_bpp(crtc_state->output_format); limits->pipe.min_bpp = intel_dp_in_hdr_mode(conn_state) ? 30 :
intel_dp_min_bpp(crtc_state->output_format);
if (is_mst) { if (is_mst) {
/* /*
* FIXME: If all the streams can't fit into the link with their * FIXME: If all the streams can't fit into the link with their
@ -2651,7 +2654,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes); joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes);
dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en || dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
!intel_dp_compute_config_limits(intel_dp, connector, pipe_config, !intel_dp_compute_config_limits(intel_dp, conn_state, pipe_config,
respect_downstream_limits, respect_downstream_limits,
false, false,
&limits); &limits);
@ -2685,7 +2688,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
str_yes_no(ret), str_yes_no(joiner_needs_dsc), str_yes_no(ret), str_yes_no(joiner_needs_dsc),
str_yes_no(intel_dp->force_dsc_en)); str_yes_no(intel_dp->force_dsc_en));
if (!intel_dp_compute_config_limits(intel_dp, connector, pipe_config, if (!intel_dp_compute_config_limits(intel_dp, conn_state, pipe_config,
respect_downstream_limits, respect_downstream_limits,
true, true,
&limits)) &limits))

View File

@ -193,7 +193,7 @@ void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
int intel_dp_output_bpp(enum intel_output_format output_format, int bpp); int intel_dp_output_bpp(enum intel_output_format output_format, int bpp);
bool intel_dp_compute_config_limits(struct intel_dp *intel_dp, bool intel_dp_compute_config_limits(struct intel_dp *intel_dp,
struct intel_connector *connector, struct drm_connector_state *conn_state,
struct intel_crtc_state *crtc_state, struct intel_crtc_state *crtc_state,
bool respect_downstream_limits, bool respect_downstream_limits,
bool dsc, bool dsc,

View File

@ -611,12 +611,15 @@ adjust_limits_for_dsc_hblank_expansion_quirk(struct intel_dp *intel_dp,
static bool static bool
mst_stream_compute_config_limits(struct intel_dp *intel_dp, mst_stream_compute_config_limits(struct intel_dp *intel_dp,
struct intel_connector *connector, struct drm_connector_state *conn_state,
struct intel_crtc_state *crtc_state, struct intel_crtc_state *crtc_state,
bool dsc, bool dsc,
struct link_config_limits *limits) struct link_config_limits *limits)
{ {
if (!intel_dp_compute_config_limits(intel_dp, connector, struct intel_connector *connector =
to_intel_connector(conn_state->connector);
if (!intel_dp_compute_config_limits(intel_dp, conn_state,
crtc_state, false, dsc, crtc_state, false, dsc,
limits)) limits))
return false; return false;
@ -665,7 +668,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder,
joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes); joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes);
dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en || dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
!mst_stream_compute_config_limits(intel_dp, connector, !mst_stream_compute_config_limits(intel_dp, conn_state,
pipe_config, false, &limits); pipe_config, false, &limits);
if (!dsc_needed) { if (!dsc_needed) {
@ -691,7 +694,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder,
str_yes_no(intel_dp->force_dsc_en)); str_yes_no(intel_dp->force_dsc_en));
if (!mst_stream_compute_config_limits(intel_dp, connector, if (!mst_stream_compute_config_limits(intel_dp, conn_state,
pipe_config, true, pipe_config, true,
&limits)) &limits))
return -EINVAL; return -EINVAL;