]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Pass proper DAC encoder ID to VBIOS
authorTimur Kristóf <timur.kristof@gmail.com>
Sat, 6 Dec 2025 02:31:02 +0000 (03:31 +0100)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 5 Jan 2026 22:00:00 +0000 (17:00 -0500)
Similarly to the analog_engine field, add a new analog_id field
which contains the encoder ID of the analog encoder that
corresponds to the link encoder.

Previously, the default encoder ID of the link encoder was used,
which meant that we passed the wrong ID in case of DVI-I.

Fixes: 5834c33fd3f6 ("drm/amd/display: Add concept of analog encoders (v2)")
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
drivers/gpu/drm/amd/display/dc/link/link_factory.c
drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c

index b44c364519dce4c6705e2a4e08e6ea10ef9d56ca..7f0766b5fa3d59ff4a1315de8bd554d7f690a4aa 100644 (file)
@@ -852,6 +852,7 @@ void dce110_link_encoder_construct(
        enc110->base.funcs = &dce110_lnk_enc_funcs;
        enc110->base.ctx = init_data->ctx;
        enc110->base.id = init_data->encoder;
+       enc110->base.analog_id = init_data->analog_encoder;
 
        enc110->base.hpd_gpio = init_data->hpd_gpio;
        enc110->base.hpd_source = init_data->hpd_source;
@@ -1837,6 +1838,7 @@ void dce60_link_encoder_construct(
        enc110->base.funcs = &dce60_lnk_enc_funcs;
        enc110->base.ctx = init_data->ctx;
        enc110->base.id = init_data->encoder;
+       enc110->base.analog_id = init_data->analog_encoder;
 
        enc110->base.hpd_gpio = init_data->hpd_gpio;
        enc110->base.hpd_source = init_data->hpd_source;
index cff705c495640a1339ffae18c76b7f5bff3b59ea..d795fc43dc9d9c7068898301213aa56aa062c94f 100644 (file)
@@ -48,6 +48,7 @@ struct encoder_init_data {
        enum hpd_source_id hpd_source;
        /* TODO: in DAL2, here was pointer to EventManagerInterface */
        struct graphics_object_id encoder;
+       struct graphics_object_id analog_encoder;
        enum engine_id analog_engine;
        struct dc_context *ctx;
        enum transmitter transmitter;
@@ -82,6 +83,7 @@ struct link_encoder {
        int32_t aux_channel_offset;
        struct dc_context *ctx;
        struct graphics_object_id id;
+       struct graphics_object_id analog_id;
        struct graphics_object_id connector;
        uint32_t output_signals;
        enum engine_id preferred_engine;
index 56fdd1446a5933dbfc0234fc66bc29c086c32172..92351771565186187d0b1da87a01a0295bdce890 100644 (file)
@@ -431,20 +431,19 @@ static enum channel_id get_ddc_line(struct dc_link *link)
        return channel;
 }
 
-static enum engine_id find_analog_engine(struct dc_link *link)
+static enum engine_id find_analog_engine(struct dc_link *link, struct graphics_object_id *enc)
 {
        struct dc_bios *bp = link->ctx->dc_bios;
-       struct graphics_object_id encoder = {0};
        enum bp_result bp_result = BP_RESULT_OK;
        int i;
 
        for (i = 0; i < 3; i++) {
-               bp_result = bp->funcs->get_src_obj(bp, link->link_id, i, &encoder);
+               bp_result = bp->funcs->get_src_obj(bp, link->link_id, i, enc);
 
                if (bp_result != BP_RESULT_OK)
                        return ENGINE_ID_UNKNOWN;
 
-               switch (encoder.id) {
+               switch (enc->id) {
                case ENCODER_ID_INTERNAL_DAC1:
                case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
                        return ENGINE_ID_DACA;
@@ -454,6 +453,7 @@ static enum engine_id find_analog_engine(struct dc_link *link)
                }
        }
 
+       memset(enc, 0, sizeof(*enc));
        return ENGINE_ID_UNKNOWN;
 }
 
@@ -506,7 +506,7 @@ static bool construct_phy(struct dc_link *link,
         */
        bp_funcs->get_src_obj(bios, link->link_id, 0, &link_encoder);
        transmitter_from_encoder = translate_encoder_to_transmitter(link_encoder);
-       link_analog_engine = find_analog_engine(link);
+       link_analog_engine = find_analog_engine(link, &enc_init_data.analog_encoder);
 
        if (transmitter_from_encoder == TRANSMITTER_UNKNOWN &&
            !analog_engine_supported(link_analog_engine)) {
@@ -552,6 +552,7 @@ static bool construct_phy(struct dc_link *link,
        enc_init_data.connector = link->link_id;
        enc_init_data.channel = get_ddc_line(link);
        enc_init_data.transmitter = transmitter_from_encoder;
+       enc_init_data.analog_engine = find_analog_engine(link, &enc_init_data.analog_encoder);
        enc_init_data.encoder = link_encoder;
        enc_init_data.analog_engine = link_analog_engine;
        enc_init_data.hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id,
index cd54382c0af3ee19e7ce4bb25dde56daff538611..7c09825cd9bd3ba030fba7571444a5e914a8f701 100644 (file)
@@ -895,6 +895,8 @@ static void get_pixel_clock_parameters(
         */
        pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz;
        pixel_clk_params->encoder_object_id = stream->link->link_enc->id;
+       if (dc_is_rgb_signal(pipe_ctx->stream->signal))
+               pixel_clk_params->encoder_object_id = stream->link->link_enc->analog_id;
        pixel_clk_params->signal_type = pipe_ctx->stream->signal;
        pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
        /* TODO: un-hardcode*/