]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amd/display: Fix DP_PIXEL_FORMAT fields & update clk_src for DCN4x
authorOvidiu Bunea <ovidiu.bunea@amd.com>
Thu, 14 May 2026 21:39:25 +0000 (17:39 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 3 Jun 2026 17:39:58 +0000 (13:39 -0400)
[Why & How]
The enc1_stream_encoder_dp_get_pixel_format() function reads fields of the
DP_PIXEL_FORMAT register that are deprecated on DCN4x. This breaks seamless
boot because driver cannot properly determine the pixel format programmed by VBIOS.
The previous changed submitted for this issue incorrectly calculated the DP DTO
frequency because register access to DCN4x DP DTO registers was not working.

Create a new function that reads the correct fields.
Update clk_src structs to support register access for new DCN4x registers & fields.

Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Signed-off-by: Ovidiu Bunea <ovidiu.bunea@amd.com>
Signed-off-by: Ray Wu <ray.wu@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h
drivers/gpu/drm/amd/display/dc/dio/dcn42/dcn42_dio_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dio/dcn42/dcn42_dio_stream_encoder.h
drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.h

index 09910333bd71071b05a3e85c2c5349427f9342c5..6f14b98a054bb08b7c63dee1ef5dca0c39aab4d1 100644 (file)
@@ -1264,8 +1264,6 @@ static bool dcn401_get_dp_dto_frequency_100hz(const struct clock_source *clock_s
                 *     - DPDTO MODULO = DTBCLK_P rate
                 *     - target pix_clk_hz = (DPDTO INTEGER * DPDTO MODULO + DPDTO PHASE)
                 */
-
-               dp_dto_integer += 1; // integer=0 represents 1x multiplier, etc.
                temp = (unsigned long long)dp_dto_integer * modulo_hz + phase_hz;
 
                if (temp / 100 > 0xFFFFFFFFUL) {
index 9441aa6a897f772238095494c2361df835d6b3ea..55c96b4b776560ce0def2936fcafe28b1b088b82 100644 (file)
        CS_COMMON_MASK_SH_LIST_DCN2_0(mask_sh),\
        CS_SF(OTG0_PIXEL_RATE_CNTL, PIPE0_DTO_SRC_SEL, mask_sh)
 
+#define CS_COMMON_MASK_SH_LIST_DCN4_0_1(mask_sh)\
+       CS_COMMON_MASK_SH_LIST_DCN3_2(mask_sh),\
+       CS_SF(OTG_PIXEL_RATE_DIV, OTG0_TMDS_PIXEL_RATE_DIV, mask_sh),\
+       CS_SF(OTG_PIXEL_RATE_DIV, DPDTO0_INT, mask_sh),\
+       CS_SF(OTG_PIXEL_RATE_DIV, OTG1_TMDS_PIXEL_RATE_DIV, mask_sh),\
+       CS_SF(OTG_PIXEL_RATE_DIV, DPDTO1_INT, mask_sh),\
+       CS_SF(OTG_PIXEL_RATE_DIV, OTG2_TMDS_PIXEL_RATE_DIV, mask_sh),\
+       CS_SF(OTG_PIXEL_RATE_DIV, DPDTO2_INT, mask_sh),\
+       CS_SF(OTG_PIXEL_RATE_DIV, OTG3_TMDS_PIXEL_RATE_DIV, mask_sh),\
+       CS_SF(OTG_PIXEL_RATE_DIV, DPDTO3_INT, mask_sh)
+
 #define CS_COMMON_REG_LIST_DCN1_0(index, pllid) \
                SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\
                SRII(PHASE, DP_DTO, 0),\
        type PLL_REF_DIV; \
        type DP_DTO0_PHASE; \
        type DP_DTO0_MODULO; \
-       type DP_DTO0_ENABLE; \
-       type DPDTO0_INT; \
-       type DPDTO1_INT; \
-       type DPDTO2_INT; \
-       type DPDTO3_INT;
+       type DP_DTO0_ENABLE;
 
 #define CS_REG_FIELD_LIST_DCN32(type) \
        type PIPE0_DTO_SRC_SEL;
 
+#define CS_REG_FIELD_LIST_DCN401(type) \
+       type DPDTO0_INT; \
+       type DPDTO1_INT; \
+       type DPDTO2_INT; \
+       type DPDTO3_INT; \
+       type OTG0_TMDS_PIXEL_RATE_DIV; \
+       type OTG1_TMDS_PIXEL_RATE_DIV; \
+       type OTG2_TMDS_PIXEL_RATE_DIV; \
+       type OTG3_TMDS_PIXEL_RATE_DIV;
+
 struct dce110_clk_src_shift {
        CS_REG_FIELD_LIST(uint8_t)
        CS_REG_FIELD_LIST_DCN32(uint8_t)
+       CS_REG_FIELD_LIST_DCN401(uint8_t)
 };
 
-struct dce110_clk_src_mask{
+struct dce110_clk_src_mask {
        CS_REG_FIELD_LIST(uint32_t)
        CS_REG_FIELD_LIST_DCN32(uint32_t)
+       CS_REG_FIELD_LIST_DCN401(uint32_t)
 };
 
 struct dce110_clk_src_regs {
index 55ddb9cf8a520821cbceb8b5d1fa03b7eae03272..35845e6dd5aa471f20d3405d4401f059f6139809 100644 (file)
@@ -447,6 +447,68 @@ void enc42_reset_hdmi_stream_attribute(
                HDMI_CLOCK_CHANNEL_RATE, 0);
 }
 
+bool enc42_dio_get_uncompressed_dp_pixel_format(
+       struct stream_encoder *enc,
+       enum dc_pixel_encoding *encoding,
+       enum dc_color_depth *depth)
+{
+       struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+       uint32_t is_compressed_pixel_format, uncompressed_component_depth, uncompressed_pixel_format, compressed_pixel_format;
+
+       if (enc == NULL || encoding == NULL || depth == NULL)
+               return false;
+
+       REG_GET_4(DP_PIXEL_FORMAT,
+               PIXEL_ENCODING_TYPE, &is_compressed_pixel_format,
+               UNCOMPRESSED_COMPONENT_DEPTH, &uncompressed_component_depth,
+               UNCOMPRESSED_PIXEL_FORMAT, &uncompressed_pixel_format,
+               COMPRESSED_PIXEL_FORMAT, &compressed_pixel_format);
+
+       if (!is_compressed_pixel_format) {
+               switch (uncompressed_component_depth) {
+               case DP_COMPONENT_PIXEL_DEPTH_6BPC:
+                       *depth = COLOR_DEPTH_666;
+                       break;
+               case DP_COMPONENT_PIXEL_DEPTH_8BPC:
+                       *depth = COLOR_DEPTH_888;
+                       break;
+               case DP_COMPONENT_PIXEL_DEPTH_10BPC:
+                       *depth = COLOR_DEPTH_101010;
+                       break;
+               case DP_COMPONENT_PIXEL_DEPTH_12BPC:
+                       *depth = COLOR_DEPTH_121212;
+                       break;
+               case DP_COMPONENT_PIXEL_DEPTH_16BPC:
+                       *depth = COLOR_DEPTH_161616;
+                       break;
+               default:
+                       *depth = COLOR_DEPTH_UNDEFINED;
+                       break;
+               }
+
+               switch (uncompressed_pixel_format) {
+               case DP_PIXEL_ENCODING_TYPE_RGB444:
+                       *encoding = PIXEL_ENCODING_RGB;
+                       break;
+               case DP_PIXEL_ENCODING_TYPE_YCBCR422:
+                       *encoding = PIXEL_ENCODING_YCBCR422;
+                       break;
+               case DP_PIXEL_ENCODING_TYPE_YCBCR444:
+               case DP_PIXEL_ENCODING_TYPE_Y_ONLY:
+                       *encoding = PIXEL_ENCODING_YCBCR444;
+                       break;
+               case DP_PIXEL_ENCODING_TYPE_YCBCR420:
+                       *encoding = PIXEL_ENCODING_YCBCR420;
+                       break;
+               default:
+                       *encoding = PIXEL_ENCODING_UNDEFINED;
+                       break;
+               }
+       }
+
+       return true;
+}
+
 static const struct stream_encoder_funcs dcn42_str_enc_funcs = {
        .dp_set_stream_attribute =
                enc401_stream_encoder_dp_set_stream_attribute,
@@ -483,7 +545,7 @@ static const struct stream_encoder_funcs dcn42_str_enc_funcs = {
        .dig_connect_to_otg = enc1_dig_connect_to_otg,
        .dig_source_otg = enc1_dig_source_otg,
 
-       .dp_get_pixel_format  = enc1_stream_encoder_dp_get_pixel_format,
+       .dp_get_pixel_format  = enc42_dio_get_uncompressed_dp_pixel_format,
 
        .enc_read_state = enc401_read_state,
        .dp_set_dsc_config = NULL,
index 7a98fee46081ffff29f43791bc8df5aa3e8d8c35..5c2d81cb040f1ddbc54421b57ef5c1c55a238ca8 100644 (file)
@@ -203,4 +203,10 @@ void enc42_se_enable_audio_clock(
 
 void enc42_reset_hdmi_stream_attribute(
        struct stream_encoder *enc);
+
+bool enc42_dio_get_uncompressed_dp_pixel_format(
+       struct stream_encoder *enc,
+       enum dc_pixel_encoding *encoding,
+       enum dc_color_depth *depth);
+
 #endif /* __DC_DIO_STREAM_ENCODER_DCN42_H__ */
index e24d908bcf6895abd668877f60b659887045b010..74a6c8ea4bb62fe2abe7a1ab4f06460b34ab9f4e 100644 (file)
@@ -197,11 +197,11 @@ static struct bios_registers bios_regs;
 static struct dce110_clk_src_regs clk_src_regs[5];
 
 static const struct dce110_clk_src_shift cs_shift = {
-               CS_COMMON_MASK_SH_LIST_DCN3_2(__SHIFT)
+       CS_COMMON_MASK_SH_LIST_DCN4_0_1(__SHIFT)
 };
 
 static const struct dce110_clk_src_mask cs_mask = {
-               CS_COMMON_MASK_SH_LIST_DCN3_2(_MASK)
+       CS_COMMON_MASK_SH_LIST_DCN4_0_1(_MASK)
 };
 
 #define abm_regs_init(id)\
index 0feb4872412fc3ff2ccf5be1099b853014ad14f8..f2b7c820a3d25b5ee757ad55d180ac943b80fc89 100644 (file)
@@ -214,10 +214,10 @@ static struct bios_registers bios_regs;
 static struct dce110_clk_src_regs clk_src_regs[5];
 
 static const struct dce110_clk_src_shift cs_shift = {
-       CS_COMMON_MASK_SH_LIST_DCN3_1_4(__SHIFT)
+       CS_COMMON_MASK_SH_LIST_DCN4_0_1(__SHIFT)
 };
 static const struct dce110_clk_src_mask cs_mask = {
-       CS_COMMON_MASK_SH_LIST_DCN3_1_4(_MASK)
+       CS_COMMON_MASK_SH_LIST_DCN4_0_1(_MASK)
 };
 #define abm_regs_init(id) \
        ABM_DCN42_REG_LIST_RI(id)
@@ -874,8 +874,7 @@ static struct clock_source *dcn42_clock_source_create(
        if (!clk_src)
                return NULL;
 
-       if (dcn401_clk_src_construct(clk_src, ctx, bios, id,
-                                                                regs, &cs_shift, &cs_mask)) {
+       if (dcn401_clk_src_construct(clk_src, ctx, bios, id, regs, &cs_shift, &cs_mask)) {
                clk_src->base.dp_clk_src = dp_clk_src;
                return &clk_src->base;
        }
index fe960542d7bdb24b1dded6cb291db867c5fce1e1..3e4d9b188b2685c6a14d74bf67298bb6acd73f55 100644 (file)
                SRII_ARR_2(PIXEL_RATE_CNTL, OTG, 0, index),             \
                SRII_ARR_2(PIXEL_RATE_CNTL, OTG, 1, index),             \
                SRII_ARR_2(PIXEL_RATE_CNTL, OTG, 2, index),             \
-               SRII_ARR_2(PIXEL_RATE_CNTL, OTG, 3, index)
+               SRII_ARR_2(PIXEL_RATE_CNTL, OTG, 3, index),             \
+               SR_ARR(OTG_PIXEL_RATE_DIV, index)
 
 /* ABM */
 #define ABM_DCN42_REG_LIST_RI(id)                               \