From: Timur Kristóf Date: Mon, 26 Jan 2026 21:08:29 +0000 (+0100) Subject: drm/amd/display: Implement BIOS parser external encoder control X-Git-Tag: v7.1-rc1~167^2~31^2~119 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ee5c4855f43c1af96c3f7e4412ce9492b00023fe;p=thirdparty%2Fkernel%2Flinux.git drm/amd/display: Implement BIOS parser external encoder control The VBIOS has a function called ExternalEncoderControl which controls the DP bridge encoders that some GPUs use for analog and LVDS output. Fixup this old functionality. For reference, see the legacy non-DC amdgpu display code: amdgpu_atombios_encoder_setup_external_encoder() - Set same parameters for the ENABLE action as the SETUP action - Add missing enum values for DDC setup and DAC load detection - Fix the bits per color field - Clarify the code that sets the link rate - Expose the function so that it can be called by rest of DC A subsequent commit will call this function from DCE HWSS. Signed-off-by: Timur Kristóf Reviewed-by: Alex Hung Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c index 234a7f137cf5a..f947f82013c66 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c @@ -780,6 +780,18 @@ static enum bp_result bios_parser_encoder_control( return bp->cmd_tbl.dig_encoder_control(bp, cntl); } +static enum bp_result bios_parser_external_encoder_control( + struct dc_bios *dcb, + struct bp_external_encoder_control *cntl) +{ + struct bios_parser *bp = BP_FROM_DCB(dcb); + + if (!bp->cmd_tbl.external_encoder_control) + return BP_RESULT_UNSUPPORTED; + + return bp->cmd_tbl.external_encoder_control(bp, cntl); +} + static enum bp_result bios_parser_dac_load_detection( struct dc_bios *dcb, enum engine_id engine_id) @@ -2909,6 +2921,8 @@ static const struct dc_vbios_funcs vbios_funcs = { .encoder_control = bios_parser_encoder_control, + .external_encoder_control = bios_parser_external_encoder_control, + .dac_load_detection = bios_parser_dac_load_detection, .transmitter_control = bios_parser_transmitter_control, diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c index fdc699b8c7a56..f6e22dcecf29e 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c @@ -2520,6 +2520,7 @@ static enum bp_result external_encoder_control_v3( cpu_to_le16((uint16_t)cntl->connector_obj_id.id); break; case EXTERNAL_ENCODER_CONTROL_SETUP: + case EXTERNAL_ENCODER_CONTROL_ENABLE: /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in * 10KHz * output display device pixel clock frequency in unit of 10KHz. @@ -2536,26 +2537,24 @@ static enum bp_result external_encoder_control_v3( if (is_input_signal_dp) { /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz, * only valid in encoder setup with DP mode. */ - if (LINK_RATE_HIGH == cntl->link_rate) - cntl_params->ucConfig |= 1; + if (cntl->link_rate == LINK_RATE_LOW) + cntl_params->ucConfig |= + EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_1_62GHZ; + else if (cntl->link_rate == LINK_RATE_HIGH) + cntl_params->ucConfig |= + EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; + else + dm_error("Link rate not supported by external encoder"); + /* output color depth Indicate encoder data bpc format * in DP mode, only valid in encoder setup in DP mode. */ - cntl_params->ucBitPerColor = - (uint8_t)(cntl->color_depth); + cntl_params->ucBitPerColor = dc_color_depth_to_atom(cntl->color_depth); } /* Indicate how many lanes used by external encoder, only valid * in encoder setup and enableoutput. */ cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number); break; - case EXTERNAL_ENCODER_CONTROL_ENABLE: - cntl_params->usPixelClock = - cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); - cntl_params->ucEncoderMode = - (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( - cntl->signal, false); - cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number; - break; default: break; } diff --git a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h index 06fdde281a0c3..6f96c5cf39fe8 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h @@ -97,6 +97,9 @@ struct dc_vbios_funcs { enum bp_result (*encoder_control)( struct dc_bios *bios, struct bp_encoder_control *cntl); + enum bp_result (*external_encoder_control)( + struct dc_bios *bios, + struct bp_external_encoder_control *cntl); enum bp_result (*dac_load_detection)( struct dc_bios *bios, enum engine_id engine_id); diff --git a/drivers/gpu/drm/amd/display/include/bios_parser_types.h b/drivers/gpu/drm/amd/display/include/bios_parser_types.h index f40dc612ec73b..b5d97b394131b 100644 --- a/drivers/gpu/drm/amd/display/include/bios_parser_types.h +++ b/drivers/gpu/drm/amd/display/include/bios_parser_types.h @@ -93,6 +93,8 @@ enum bp_external_encoder_control_action { EXTERNAL_ENCODER_CONTROL_SETUP = 0xf, EXTERNAL_ENCODER_CONTROL_UNBLANK = 0x10, EXTERNAL_ENCODER_CONTROL_BLANK = 0x11, + EXTERNAL_ENCODER_CONTROL_DAC_LOAD_DETECT = 0x12, + EXTERNAL_ENCODER_CONTROL_DDC_SETUP = 0x14, }; enum bp_pipe_control_action {