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

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

authored by

Chaitanya Kumar Borah and committed by
Suraj Kandpal
ba49a464 2e9da93d

+15 -9
+7 -4
drivers/gpu/drm/i915/display/intel_dp.c
··· 2536 2536 2537 2537 bool 2538 2538 intel_dp_compute_config_limits(struct intel_dp *intel_dp, 2539 - struct intel_connector *connector, 2539 + struct drm_connector_state *conn_state, 2540 2540 struct intel_crtc_state *crtc_state, 2541 2541 bool respect_downstream_limits, 2542 2542 bool dsc, 2543 2543 struct link_config_limits *limits) 2544 2544 { 2545 2545 bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); 2546 + struct intel_connector *connector = 2547 + to_intel_connector(conn_state->connector); 2546 2548 2547 2549 limits->min_rate = intel_dp_min_link_rate(intel_dp); 2548 2550 limits->max_rate = intel_dp_max_link_rate(intel_dp); ··· 2554 2552 limits->min_lane_count = intel_dp_min_lane_count(intel_dp); 2555 2553 limits->max_lane_count = intel_dp_max_lane_count(intel_dp); 2556 2554 2557 - limits->pipe.min_bpp = intel_dp_min_bpp(crtc_state->output_format); 2555 + limits->pipe.min_bpp = intel_dp_in_hdr_mode(conn_state) ? 30 : 2556 + intel_dp_min_bpp(crtc_state->output_format); 2558 2557 if (is_mst) { 2559 2558 /* 2560 2559 * FIXME: If all the streams can't fit into the link with their ··· 2654 2651 joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes); 2655 2652 2656 2653 dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en || 2657 - !intel_dp_compute_config_limits(intel_dp, connector, pipe_config, 2654 + !intel_dp_compute_config_limits(intel_dp, conn_state, pipe_config, 2658 2655 respect_downstream_limits, 2659 2656 false, 2660 2657 &limits); ··· 2688 2685 str_yes_no(ret), str_yes_no(joiner_needs_dsc), 2689 2686 str_yes_no(intel_dp->force_dsc_en)); 2690 2687 2691 - if (!intel_dp_compute_config_limits(intel_dp, connector, pipe_config, 2688 + if (!intel_dp_compute_config_limits(intel_dp, conn_state, pipe_config, 2692 2689 respect_downstream_limits, 2693 2690 true, 2694 2691 &limits))
+1 -1
drivers/gpu/drm/i915/display/intel_dp.h
··· 193 193 int intel_dp_output_bpp(enum intel_output_format output_format, int bpp); 194 194 195 195 bool intel_dp_compute_config_limits(struct intel_dp *intel_dp, 196 - struct intel_connector *connector, 196 + struct drm_connector_state *conn_state, 197 197 struct intel_crtc_state *crtc_state, 198 198 bool respect_downstream_limits, 199 199 bool dsc,
+7 -4
drivers/gpu/drm/i915/display/intel_dp_mst.c
··· 611 611 612 612 static bool 613 613 mst_stream_compute_config_limits(struct intel_dp *intel_dp, 614 - struct intel_connector *connector, 614 + struct drm_connector_state *conn_state, 615 615 struct intel_crtc_state *crtc_state, 616 616 bool dsc, 617 617 struct link_config_limits *limits) 618 618 { 619 - if (!intel_dp_compute_config_limits(intel_dp, connector, 619 + struct intel_connector *connector = 620 + to_intel_connector(conn_state->connector); 621 + 622 + if (!intel_dp_compute_config_limits(intel_dp, conn_state, 620 623 crtc_state, false, dsc, 621 624 limits)) 622 625 return false; ··· 668 665 joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes); 669 666 670 667 dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en || 671 - !mst_stream_compute_config_limits(intel_dp, connector, 668 + !mst_stream_compute_config_limits(intel_dp, conn_state, 672 669 pipe_config, false, &limits); 673 670 674 671 if (!dsc_needed) { ··· 694 691 str_yes_no(intel_dp->force_dsc_en)); 695 692 696 693 697 - if (!mst_stream_compute_config_limits(intel_dp, connector, 694 + if (!mst_stream_compute_config_limits(intel_dp, conn_state, 698 695 pipe_config, true, 699 696 &limits)) 700 697 return -EINVAL;