commit 7e5760f084d0 ("drm/amd/display: add HDMI 2.1 Compliance Support")
selects YCbCr 4:2:0 for a 4:2:0-only mode only when the IGT override asks
for it, and YCbCr 4:4:4 only when that override is YCbCr 4:4:4. On a
normal boot the override is unset.

A 3840x2160@60 mode that the sink lists only in the YCbCr 4:2:0 block
then falls through to 4:4:4 or RGB, and the Wayland session cannot build
the output layer: kwin_wayland_drm: Failed to create framebuffer (EINVAL)
right after login. v7.3-rc5 selects 4:2:0 again for those modes when the
color format is automatic. Do the same here, including HDMI FRL.

Keep automatic YCbCr 4:4:4 for the other HDMI modes, as 7.1 did. The TMDS
depth fallback also runs for HDMI FRL, so a mode that does not fit at
4:4:4 can still drop to 4:2:0.

This is not a backport of a mainline commit. The 7.3 fix is the rewrite
in 0b0ff65d3c ("drm/amd/display: Refactor stream validation"), which
cannot be cherry-picked to 7.2; Jerry Zuo confirmed the pre-7.3 logic is
gone there. This patch restores the pre-regression selection on the 7.2
code, following the v7.3-rc5 rule. Mario Limonciello asked for it to be
sent to stable in drm/amd#5760.

Regression: black screen after login on HDMI sinks whose modes fall
through to RGB, e.g. Strix Halo (gfx1151) + TCL 4K TV whose 3840x2160@60
is YCbCr 4:2:0-only (VIC 97). 7e5760f084d0 shipped in 7.2; still unfixed
in 7.2.9.

Tested on CachyOS linux-cachyos-bore 7.2.7-3 (znver4) on that Strix Halo
box: Plasma runs at 3840x2160@60 with the same userspace and firmware
that stayed black on every stock 7.2.x kernel.

Link: https://gitlab.freedesktop.org/drm/amd/-/work_items/5760
Link: https://gitlab.freedesktop.org/drm/amd/-/work_items/5893
Reported-by: Michał Górny <[email protected]>
Reported-by: Miguel Mesa <[email protected]>
Suggested-by: Mario Limonciello <[email protected]>
Tested-by: Miguel Mesa <[email protected]>
Signed-off-by: Miguel Mesa <[email protected]>
Co-authored-by: Cursor <[email protected]>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index e594548..8f60df9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7017,9 +7017,7 @@ static void fill_stream_properties_from_drm_display_mode(
        /* TODO: un-hardcode */
        if (drm_mode_is_420_only(info, mode_in)
                        && (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A ||
-                           stream->signal == SIGNAL_TYPE_HDMI_FRL)
-                       && aconnector
-                       && aconnector->force_yuv_pixel_format == 
PIXEL_ENCODING_YCBCR420)
+                           stream->signal == SIGNAL_TYPE_HDMI_FRL))
                timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
        else if (drm_mode_is_420_also(info, mode_in)
                        && aconnector
@@ -7034,8 +7032,9 @@ static void fill_stream_properties_from_drm_display_mode(
        else if ((connector->display_info.color_formats & 
BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444))
                        && (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A ||
                            stream->signal == SIGNAL_TYPE_HDMI_FRL)
-                       && aconnector
-                       && aconnector->force_yuv_pixel_format == 
PIXEL_ENCODING_YCBCR444)
+                       && (!aconnector
+                           || aconnector->force_yuv_pixel_format == 
PIXEL_ENCODING_UNDEFINED
+                           || aconnector->force_yuv_pixel_format == 
PIXEL_ENCODING_YCBCR444))
                timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;
        else
                timing_out->pixel_encoding = PIXEL_ENCODING_RGB;
@@ -7104,7 +7103,8 @@ static void fill_stream_properties_from_drm_display_mode(
 
        stream->out_transfer_func.type = TF_TYPE_PREDEFINED;
        stream->out_transfer_func.tf = TRANSFER_FUNCTION_SRGB;
-       if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
+       if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A ||
+           stream->signal == SIGNAL_TYPE_HDMI_FRL) {
                if (!adjust_colour_depth_from_display_info(timing_out, info) &&
                    drm_mode_is_420_also(info, mode_in) &&
                    timing_out->pixel_encoding != PIXEL_ENCODING_YCBCR420) {
-- 
2.56.0

Reply via email to