]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Add SelectCRTC_Source to BIOS parser
authorTimur Kristóf <timur.kristof@gmail.com>
Fri, 26 Sep 2025 18:01:45 +0000 (20:01 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 28 Oct 2025 14:08:24 +0000 (10:08 -0400)
The SelectCRTC_Source command will be used to change which CRTC
should be connected to which encoder.

For reference, see the legacy display code:
amdgpu_atombios_encoder_set_crtc_source

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
drivers/gpu/drm/amd/display/dc/bios/command_table.c
drivers/gpu/drm/amd/display/dc/bios/command_table.h
drivers/gpu/drm/amd/display/dc/dc_bios_types.h
drivers/gpu/drm/amd/display/include/bios_parser_types.h

index 318be0bb5549e403b69f7bc2390d98338acf07b8..c7875edea3213cfa7c5ee51cfa41fa1d0537a4e6 100644 (file)
@@ -736,6 +736,18 @@ static enum bp_result bios_parser_transmitter_control(
        return bp->cmd_tbl.transmitter_control(bp, cntl);
 }
 
+static enum bp_result bios_parser_select_crtc_source(
+       struct dc_bios *dcb,
+       struct bp_crtc_source_select *bp_params)
+{
+       struct bios_parser *bp = BP_FROM_DCB(dcb);
+
+       if (!bp->cmd_tbl.select_crtc_source)
+               return BP_RESULT_FAILURE;
+
+       return bp->cmd_tbl.select_crtc_source(bp, bp_params);
+}
+
 static enum bp_result bios_parser_encoder_control(
        struct dc_bios *dcb,
        struct bp_encoder_control *cntl)
@@ -2845,6 +2857,8 @@ static const struct dc_vbios_funcs vbios_funcs = {
        .is_device_id_supported = bios_parser_is_device_id_supported,
 
        /* COMMANDS */
+       .select_crtc_source = bios_parser_select_crtc_source,
+
        .encoder_control = bios_parser_encoder_control,
 
        .transmitter_control = bios_parser_transmitter_control,
index 58e88778da7ffd521cd764b44d220cc69058bcf7..dbd84477ceb7dbd89de8db1f06da01738afdccb2 100644 (file)
@@ -52,6 +52,7 @@ static void init_transmitter_control(struct bios_parser *bp);
 static void init_set_pixel_clock(struct bios_parser *bp);
 static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);
 static void init_adjust_display_pll(struct bios_parser *bp);
+static void init_select_crtc_source(struct bios_parser *bp);
 static void init_dac_encoder_control(struct bios_parser *bp);
 static void init_dac_output_control(struct bios_parser *bp);
 static void init_set_crtc_timing(struct bios_parser *bp);
@@ -69,6 +70,7 @@ void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp)
        init_set_pixel_clock(bp);
        init_enable_spread_spectrum_on_ppll(bp);
        init_adjust_display_pll(bp);
+       init_select_crtc_source(bp);
        init_dac_encoder_control(bp);
        init_dac_output_control(bp);
        init_set_crtc_timing(bp);
@@ -1609,6 +1611,198 @@ static enum bp_result adjust_display_pll_v3(
        return result;
 }
 
+/*******************************************************************************
+ ********************************************************************************
+ **
+ **                  SELECT CRTC SOURCE
+ **
+ ********************************************************************************
+ *******************************************************************************/
+
+static enum bp_result select_crtc_source_v1(
+       struct bios_parser *bp,
+       struct bp_crtc_source_select *bp_params);
+static enum bp_result select_crtc_source_v2(
+       struct bios_parser *bp,
+       struct bp_crtc_source_select *bp_params);
+static enum bp_result select_crtc_source_v3(
+       struct bios_parser *bp,
+       struct bp_crtc_source_select *bp_params);
+
+static void init_select_crtc_source(struct bios_parser *bp)
+{
+       switch (BIOS_CMD_TABLE_PARA_REVISION(SelectCRTC_Source)) {
+       case 1:
+               bp->cmd_tbl.select_crtc_source = select_crtc_source_v1;
+               break;
+       case 2:
+               bp->cmd_tbl.select_crtc_source = select_crtc_source_v2;
+               break;
+       case 3:
+               bp->cmd_tbl.select_crtc_source = select_crtc_source_v3;
+               break;
+       default:
+               bp->cmd_tbl.select_crtc_source = NULL;
+               break;
+       }
+}
+
+static enum bp_result select_crtc_source_v1(
+       struct bios_parser *bp,
+       struct bp_crtc_source_select *bp_params)
+{
+       enum bp_result result = BP_RESULT_FAILURE;
+       SELECT_CRTC_SOURCE_PS_ALLOCATION params;
+
+       if (!bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &params.ucCRTC))
+               return BP_RESULT_BADINPUT;
+
+       switch (bp_params->engine_id) {
+       case ENGINE_ID_DACA:
+               params.ucDevice = ATOM_DEVICE_CRT1_INDEX;
+               break;
+       case ENGINE_ID_DACB:
+               params.ucDevice = ATOM_DEVICE_CRT2_INDEX;
+               break;
+       default:
+               return BP_RESULT_BADINPUT;
+       }
+
+       if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
+               result = BP_RESULT_OK;
+
+       return result;
+}
+
+static bool select_crtc_source_v2_encoder_id(
+       enum engine_id engine_id, uint8_t *out_encoder_id)
+{
+       uint8_t encoder_id = 0;
+
+       switch (engine_id) {
+       case ENGINE_ID_DIGA:
+               encoder_id = ASIC_INT_DIG1_ENCODER_ID;
+               break;
+       case ENGINE_ID_DIGB:
+               encoder_id = ASIC_INT_DIG2_ENCODER_ID;
+               break;
+       case ENGINE_ID_DIGC:
+               encoder_id = ASIC_INT_DIG3_ENCODER_ID;
+               break;
+       case ENGINE_ID_DIGD:
+               encoder_id = ASIC_INT_DIG4_ENCODER_ID;
+               break;
+       case ENGINE_ID_DIGE:
+               encoder_id = ASIC_INT_DIG5_ENCODER_ID;
+               break;
+       case ENGINE_ID_DIGF:
+               encoder_id = ASIC_INT_DIG6_ENCODER_ID;
+               break;
+       case ENGINE_ID_DIGG:
+               encoder_id = ASIC_INT_DIG7_ENCODER_ID;
+               break;
+       case ENGINE_ID_DACA:
+               encoder_id = ASIC_INT_DAC1_ENCODER_ID;
+               break;
+       case ENGINE_ID_DACB:
+               encoder_id = ASIC_INT_DAC2_ENCODER_ID;
+               break;
+       default:
+               return false;
+       }
+
+       *out_encoder_id = encoder_id;
+       return true;
+}
+
+static bool select_crtc_source_v2_encoder_mode(
+       enum signal_type signal_type, uint8_t *out_encoder_mode)
+{
+       uint8_t encoder_mode = 0;
+
+       switch (signal_type) {
+       case SIGNAL_TYPE_DVI_SINGLE_LINK:
+       case SIGNAL_TYPE_DVI_DUAL_LINK:
+               encoder_mode = ATOM_ENCODER_MODE_DVI;
+               break;
+       case SIGNAL_TYPE_HDMI_TYPE_A:
+               encoder_mode = ATOM_ENCODER_MODE_HDMI;
+               break;
+       case SIGNAL_TYPE_LVDS:
+               encoder_mode = ATOM_ENCODER_MODE_LVDS;
+               break;
+       case SIGNAL_TYPE_RGB:
+               encoder_mode = ATOM_ENCODER_MODE_CRT;
+               break;
+       case SIGNAL_TYPE_DISPLAY_PORT:
+               encoder_mode = ATOM_ENCODER_MODE_DP;
+               break;
+       case SIGNAL_TYPE_DISPLAY_PORT_MST:
+               encoder_mode = ATOM_ENCODER_MODE_DP_MST;
+               break;
+       case SIGNAL_TYPE_EDP:
+               encoder_mode = ATOM_ENCODER_MODE_DP;
+               break;
+       default:
+               return false;
+       }
+
+       *out_encoder_mode = encoder_mode;
+       return true;
+}
+
+static enum bp_result select_crtc_source_v2(
+       struct bios_parser *bp,
+       struct bp_crtc_source_select *bp_params)
+{
+       enum bp_result result = BP_RESULT_FAILURE;
+       SELECT_CRTC_SOURCE_PARAMETERS_V3 params;
+
+       if (!bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &params.ucCRTC))
+               return BP_RESULT_BADINPUT;
+
+       if (!select_crtc_source_v2_encoder_id(
+               bp_params->engine_id,
+               &params.ucEncoderID))
+               return BP_RESULT_BADINPUT;
+       if (!select_crtc_source_v2_encoder_mode(
+               bp_params->sink_signal,
+               &params.ucEncodeMode))
+               return BP_RESULT_BADINPUT;
+
+       if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
+               result = BP_RESULT_OK;
+
+       return result;
+}
+
+static enum bp_result select_crtc_source_v3(
+       struct bios_parser *bp,
+       struct bp_crtc_source_select *bp_params)
+{
+       enum bp_result result = BP_RESULT_FAILURE;
+       SELECT_CRTC_SOURCE_PARAMETERS_V3 params;
+
+       if (!bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &params.ucCRTC))
+               return BP_RESULT_BADINPUT;
+
+       if (!select_crtc_source_v2_encoder_id(
+               bp_params->engine_id,
+               &params.ucEncoderID))
+               return BP_RESULT_BADINPUT;
+       if (!select_crtc_source_v2_encoder_mode(
+               bp_params->sink_signal,
+               &params.ucEncodeMode))
+               return BP_RESULT_BADINPUT;
+
+       params.ucDstBpc = bp_params->bit_depth;
+
+       if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
+               result = BP_RESULT_OK;
+
+       return result;
+}
+
 /*******************************************************************************
  ********************************************************************************
  **
index ad533775e72428c2ff1c3c97756823d4d037de12..8b04b903e93d0e08882f6f944a49adc0caafe3f5 100644 (file)
@@ -52,6 +52,9 @@ struct cmd_tbl {
        enum bp_result (*adjust_display_pll)(
                struct bios_parser *bp,
                struct bp_adjust_pixel_clock_parameters *bp_params);
+       enum bp_result (*select_crtc_source)(
+               struct bios_parser *bp,
+               struct bp_crtc_source_select *bp_params);
        enum bp_result (*dac1_encoder_control)(
                struct bios_parser *bp,
                bool enable,
index 5fa5e2b63fb7ce0299746ac9aa2e42c6e071ecec..545ce1e15eaeb0ffcef3e7fa23be5c37d71fbebe 100644 (file)
@@ -91,6 +91,9 @@ struct dc_vbios_funcs {
                struct device_id id);
        /* COMMANDS */
 
+       enum bp_result (*select_crtc_source)(
+               struct dc_bios *bios,
+               struct bp_crtc_source_select *bp_params);
        enum bp_result (*encoder_control)(
                struct dc_bios *bios,
                struct bp_encoder_control *cntl);
index 812377d9e48f67926fad7f6c6cade9cb51719023..d9e58a6a0d3695710704fd176989a4f8603bf6e0 100644 (file)
@@ -135,12 +135,8 @@ struct bp_external_encoder_control {
 struct bp_crtc_source_select {
        enum engine_id engine_id;
        enum controller_id controller_id;
-       /* from GPU Tx aka asic_signal */
-       enum signal_type signal;
-       /* sink_signal may differ from asicSignal if Translator encoder */
        enum signal_type sink_signal;
-       enum display_output_bit_depth display_output_bit_depth;
-       bool enable_dp_audio;
+       uint8_t bit_depth;
 };
 
 struct bp_transmitter_control {