Skip to content

Commit ea11731

Browse files
tanderson-googlealexdeucher
authored andcommitted
drm/amd/display: Reduce HDMI pixel encoding if max clock is exceeded
For high-res (8K) or HFR (4K120) displays, using uncompressed pixel formats like YCbCr444 would exceed the bandwidth of HDMI 2.0, so the "interesting" modes would be disabled, leaving only low-res or low framerate modes. This change lowers the pixel encoding to 4:2:2 or 4:2:0 if the max TMDS clock is exceeded. Verified that 8K30 and 4K120 are now available and working with a Samsung Q900R over an HDMI 2.0b link from a Radeon 5700. Reviewed-by: Harry Wentland <[email protected]> Signed-off-by: Thomas Anderson <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent d12baba commit ea11731

File tree

1 file changed

+23
-22
lines changed

1 file changed

+23
-22
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3704,27 +3704,21 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing)
37043704
return color_space;
37053705
}
37063706

3707-
static void reduce_mode_colour_depth(struct dc_crtc_timing *timing_out)
3708-
{
3709-
if (timing_out->display_color_depth <= COLOR_DEPTH_888)
3710-
return;
3711-
3712-
timing_out->display_color_depth--;
3713-
}
3714-
3715-
static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_out,
3716-
const struct drm_display_info *info)
3707+
static bool adjust_colour_depth_from_display_info(
3708+
struct dc_crtc_timing *timing_out,
3709+
const struct drm_display_info *info)
37173710
{
3711+
enum dc_color_depth depth = timing_out->display_color_depth;
37183712
int normalized_clk;
3719-
if (timing_out->display_color_depth <= COLOR_DEPTH_888)
3720-
return;
37213713
do {
37223714
normalized_clk = timing_out->pix_clk_100hz / 10;
37233715
/* YCbCr 4:2:0 requires additional adjustment of 1/2 */
37243716
if (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420)
37253717
normalized_clk /= 2;
37263718
/* Adjusting pix clock following on HDMI spec based on colour depth */
3727-
switch (timing_out->display_color_depth) {
3719+
switch (depth) {
3720+
case COLOR_DEPTH_888:
3721+
break;
37283722
case COLOR_DEPTH_101010:
37293723
normalized_clk = (normalized_clk * 30) / 24;
37303724
break;
@@ -3735,14 +3729,15 @@ static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_
37353729
normalized_clk = (normalized_clk * 48) / 24;
37363730
break;
37373731
default:
3738-
return;
3732+
/* The above depths are the only ones valid for HDMI. */
3733+
return false;
37393734
}
3740-
if (normalized_clk <= info->max_tmds_clock)
3741-
return;
3742-
reduce_mode_colour_depth(timing_out);
3743-
3744-
} while (timing_out->display_color_depth > COLOR_DEPTH_888);
3745-
3735+
if (normalized_clk <= info->max_tmds_clock) {
3736+
timing_out->display_color_depth = depth;
3737+
return true;
3738+
}
3739+
} while (--depth > COLOR_DEPTH_666);
3740+
return false;
37463741
}
37473742

37483743
static void fill_stream_properties_from_drm_display_mode(
@@ -3823,8 +3818,14 @@ static void fill_stream_properties_from_drm_display_mode(
38233818

38243819
stream->out_transfer_func->type = TF_TYPE_PREDEFINED;
38253820
stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
3826-
if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
3827-
adjust_colour_depth_from_display_info(timing_out, info);
3821+
if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
3822+
if (!adjust_colour_depth_from_display_info(timing_out, info) &&
3823+
drm_mode_is_420_also(info, mode_in) &&
3824+
timing_out->pixel_encoding != PIXEL_ENCODING_YCBCR420) {
3825+
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
3826+
adjust_colour_depth_from_display_info(timing_out, info);
3827+
}
3828+
}
38283829
}
38293830

38303831
static void fill_audio_info(struct audio_info *audio_info,

0 commit comments

Comments
 (0)