On 2026-05-07 11:51, Harry Wentland wrote:
> Here we add support for reading BIOS caps and tie FRL bits
> into the rest of DC core.
> 
> Signed-off-by: Harry Wentland <[email protected]>
> ---
>  .../drm/amd/display/dc/bios/bios_parser2.c    |  21 ++
>  .../drm/amd/display/dc/bios/command_table2.c  |   6 +
>  .../dce112/command_table_helper2_dce112.c     |   3 +
>  .../bios/dce112/command_table_helper_dce112.c |   3 +
>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  45 +++-
>  .../gpu/drm/amd/display/dc/core/dc_debug.c    |   4 +
>  .../drm/amd/display/dc/core/dc_hw_sequencer.c |  36 +++
>  .../drm/amd/display/dc/core/dc_link_enc_cfg.c |   3 +
>  .../drm/amd/display/dc/core/dc_link_exports.c |  45 ++++
>  .../gpu/drm/amd/display/dc/core/dc_resource.c | 233 ++++++++++++++++++
>  .../gpu/drm/amd/display/dc/core/dc_stream.c   |  35 +++
>  .../gpu/drm/amd/display/dc/dce/dce_audio.c    |   8 +
>  .../drm/amd/display/dc/dce/dce_clock_source.c |  30 ++-
>  .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   |   5 +-
>  14 files changed, 469 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c 
> b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
> index b4dd8219b8f0..135556b8fd87 100644
> --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
> +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
> @@ -2126,6 +2126,12 @@ static enum bp_result get_firmware_info_v3_5(
>       return BP_RESULT_OK;
>  }
>  
> +/* TODO: Remove this temp define after atomfirmware.h is updated */
> +#define ATOM_ENCODER_CAP_RECORD_HDMI_FRL_TEMP  0x200
> +#define ATOM_ENCODER_CAP_RECORD_HDMI_FRL_8GbEn_TEMP 0x400        // HDMI FRL 
> 8Gb support
> +#define ATOM_ENCODER_CAP_RECORD_HDMI_FRL_10GbEn_TEMP 0x800        // HDMI 
> FRL 10Gb support
> +#define ATOM_ENCODER_CAP_RECORD_HDMI_FRL_12GbEn_TEMP 0x1000       // HDMI 
> FRL 12Gb support
> +
>  static enum bp_result bios_parser_get_encoder_cap_info(
>       struct dc_bios *dcb,
>       struct graphics_object_id object_id,
> @@ -2173,6 +2179,15 @@ static enum bp_result bios_parser_get_encoder_cap_info(
>       info->DP_IS_USB_C = (record->encodercaps &
>                       ATOM_ENCODER_CAP_RECORD_USB_C_TYPE) ? 1 : 0;
>       DC_LOG_BIOS("\t info->DP_IS_USB_C %d", info->DP_IS_USB_C);
> +     info->IS_HDMI_FRL_CAPABLE = (record->encodercaps &
> +                     ATOM_ENCODER_CAP_RECORD_HDMI_FRL_TEMP) ? 1 : 0;
> +     info->FRL_8G_EN = (record->encodercaps &
> +                     ATOM_ENCODER_CAP_RECORD_HDMI_FRL_8GbEn_TEMP) ? 1 : 0;
> +     info->FRL_10G_EN = (record->encodercaps &
> +                     ATOM_ENCODER_CAP_RECORD_HDMI_FRL_10GbEn_TEMP) ? 1 : 0;
> +     info->FRL_12G_EN = (record->encodercaps &
> +                     ATOM_ENCODER_CAP_RECORD_HDMI_FRL_12GbEn_TEMP) ? 1 : 0;
> +     DC_LOG_BIOS("\t info->IS_HDMI_FRL_CAPABLE %d\n", 
> info->IS_HDMI_FRL_CAPABLE);
>  
>       return BP_RESULT_OK;
>  }
> @@ -2401,6 +2416,12 @@ static enum bp_result 
> bios_parser_get_connector_speed_cap_info(
>       info->DP_UHBR10_EN = (record->connector_max_speed >= 10000) ? 1 : 0;
>       info->DP_UHBR13_5_EN = (record->connector_max_speed >= 13500) ? 1 : 0;
>       info->DP_UHBR20_EN = (record->connector_max_speed >= 20000) ? 1 : 0;
> +     info->FRL_8G_EN = (record->connector_max_speed >= 8000) ? 1 : 0;
> +     info->FRL_10G_EN = (record->connector_max_speed >= 10000) ? 1 : 0;
> +     info->FRL_12G_EN = (record->connector_max_speed >= 12000) ? 1 : 0;
> +     info->FRL_16G_EN = (record->connector_max_speed >= 16000) ? 1 : 0;
> +     info->FRL_20G_EN = (record->connector_max_speed >= 20000) ? 1 : 0;
> +     info->FRL_24G_EN = (record->connector_max_speed >= 24000) ? 1 : 0;
>       return BP_RESULT_OK;
>  }
>  
> diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c 
> b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
> index 88625daf5378..5bca5e534277 100644
> --- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
> +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
> @@ -371,6 +371,10 @@ static enum bp_result transmitter_control_v1_7(
>       if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||
>               cntl->action == TRANSMITTER_CONTROL_ACTIAVATE ||
>               cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) {
> +             if (dc_is_hdmi_frl_signal(cntl->signal))
> +                     DC_LOG_BIOS("%s:dig_v1_7.symclk_units.symclk_Hz = %d\n",
> +                     __func__, dig_v1_7.symclk_units.symclk_Hz);
> +             else
>                       DC_LOG_BIOS("%s:dig_v1_7.symclk_units.symclk_10khz = 
> %d\n",
>                       __func__, dig_v1_7.symclk_units.symclk_10khz);
>       }
> @@ -395,6 +399,8 @@ static enum bp_result transmitter_control_v1_7(
>                               
> process_phy_transition_init_params.sym_clock_10khz          = 
> dig_v1_7.symclk_units.symclk_10khz;
>                               
> process_phy_transition_init_params.display_port_link_rate   = 
> link->cur_link_settings.link_rate;
>                               
> process_phy_transition_init_params.transition_bitmask       = 
> link->phy_transition_bitmask;
> +                             
> process_phy_transition_init_params.hdmi_frl_num_lanes       = 
> link->frl_link_settings.frl_num_lanes;
> +                             
> process_phy_transition_init_params.hdmi_frl_link_rate       = 
> link->frl_link_settings.frl_link_rate;
>                       }
>                       dig_v1_7.skip_phy_ssc_reduction = 
> link->wa_flags.skip_phy_ssc_reduction;
>               }
> diff --git 
> a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c 
> b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c
> index 478465fba224..642bc52dcc40 100644
> --- 
> a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c
> +++ 
> b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c
> @@ -49,6 +49,9 @@ static uint8_t signal_type_to_atom_dig_mode(enum 
> signal_type s)
>       case SIGNAL_TYPE_HDMI_TYPE_A:
>               atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_HDMI;
>               break;
> +     case SIGNAL_TYPE_HDMI_FRL:
> +             atom_dig_mode = 4;
> +             break;
>       case SIGNAL_TYPE_DISPLAY_PORT_MST:
>               atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP_MST;
>               break;
> diff --git 
> a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper_dce112.c 
> b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper_dce112.c
> index 6b8a87f2c49e..41d11d8410a0 100644
> --- a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper_dce112.c
> +++ b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper_dce112.c
> @@ -47,6 +47,9 @@ static uint8_t signal_type_to_atom_dig_mode(enum 
> signal_type s)
>       case SIGNAL_TYPE_HDMI_TYPE_A:
>               atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_HDMI;
>               break;
> +     case SIGNAL_TYPE_HDMI_FRL:
> +             atom_dig_mode = 4;
> +             break;
>       case SIGNAL_TYPE_DISPLAY_PORT_MST:
>               atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP_MST;
>               break;
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index ad927e63c207..b4ad3ec0f029 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -487,6 +487,25 @@ bool dc_stream_get_last_used_drr_vtotal(struct dc *dc,
>       return status;
>  }
>  
> +void dc_set_vstartup_start(struct dc *dc,
> +             struct dc_stream_state *stream)
> +{
> +     int i = 0;
> +
> +     dc_exit_ips_for_hw_access(dc);
> +
> +     for (i = 0; i < MAX_PIPES; i++) {
> +             struct pipe_ctx *pipe =
> +                             &dc->current_state->res_ctx.pipe_ctx[i];
> +
> +             if (pipe->stream == stream && pipe->stream_res.stream_enc) {
> +                     /*one pipe for now*/
> +                     if (dc->hwss.set_vstartup_dsc_frl)
> +                             dc->hwss.set_vstartup_dsc_frl(dc, pipe);
> +             }
> +     }
> +}

Minor correction: this function is here erroneously. Will drop it.

> +
>  #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
>  static inline void
>  dc_stream_forward_dmub_crc_window(struct dc_dmub_srv *dmub_srv,
> @@ -3893,17 +3912,20 @@ static void add_update_info_frame_sequence(
>  {
>       bool is_hdmi_tmds;
>       bool is_dp;
> +     bool is_hdmi_frl;
>  
>       if (!pipe_ctx || !pipe_ctx->stream)
>               return;
>  
> -     if (pipe_ctx->stream_res.stream_enc == NULL)
> +     if (pipe_ctx->stream_res.stream_enc == NULL &&
> +                     pipe_ctx->stream_res.hpo_frl_stream_enc == NULL)
>               return;
>  
>       is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);
>       is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);
>  
> -     if (!is_hdmi_tmds && !is_dp)
> +     is_hdmi_frl = dc_is_hdmi_frl_signal(pipe_ctx->stream->signal);
> +     if (!is_hdmi_tmds && !is_dp && !is_hdmi_frl)
>               return;
>  
>       if (is_hdmi_tmds) {
> @@ -3911,6 +3933,11 @@ static void add_update_info_frame_sequence(
>               return;
>       }
>  
> +     if (is_hdmi_frl) {
> +             hwss_add_hpo_frl_stream_enc_update_hdmi_info_packets(seq_state, 
> pipe_ctx);
> +             return;
> +     }
> +
>       if (is_dp) {
>               if (dp_is_128b_132b_signal(pipe_ctx)) {
>                       
> hwss_add_hpo_dp_stream_enc_update_dp_info_packets_sdp_line_num(seq_state, 
> pipe_ctx);
> @@ -7442,6 +7469,20 @@ bool dc_capture_register_software_state(struct dc *dc, 
> struct dc_register_softwa
>                       state->dccg.symclk32_le_enable[i] = 0; /* Default: 
> disabled */
>               }
>  
> +             /* Check for active HPO usage that affects symclk32_le */
> +             for (unsigned int pipe_idx = 0; pipe_idx < MAX_PIPES && 
> pipe_idx < dc->res_pool->pipe_count; pipe_idx++) {
> +                     struct pipe_ctx *pipe_ctx = 
> &res_ctx->pipe_ctx[pipe_idx];
> +                     if (!pipe_ctx->stream)
> +                             continue;
> +
> +                     /* HPO FRL (HDMI FRL) streams use symclk32_le */
> +                     if (pipe_ctx->stream_res.hpo_frl_stream_enc && 
> pipe_ctx->link_res.hpo_frl_link_enc) {
> +                             int hpo_le_inst = 
> pipe_ctx->link_res.hpo_frl_link_enc->inst;
> +                             if (hpo_le_inst >= 0 && hpo_le_inst < 2) {
> +                                     
> state->dccg.symclk32_le_enable[hpo_le_inst] = 1;
> +                             }
> +                     }
> +             }
>       }
>  
>       /* Capture essential DSC configuration for underflow analysis */
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
> index bbce751b485f..deb7f419e26c 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
> @@ -250,6 +250,10 @@ char *dc_status_to_str(enum dc_status status)
>               return "No DSC resource";
>       case DC_FAIL_UNSUPPORTED_1:
>               return "Unsupported";
> +     case DC_FAIL_HDMI_FRL_LINK_TRAINING:
> +             return "HDMI frl link training failure";
> +     case DC_NO_HDMI_FRL_LINK_BANDWIDTH:
> +             return "No DHMI frl link bandwidth";
>       case DC_FAIL_CLK_EXCEED_MAX:
>               return "Clk exceed max failure";
>       case DC_FAIL_CLK_BELOW_MIN:
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
> index b3a5935e3811..c0c35d6653a5 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
> @@ -1615,6 +1615,9 @@ void hwss_execute_sequence(struct dc *dc,
>               case STREAM_ENC_UPDATE_HDMI_INFO_PACKETS:
>                       hwss_stream_enc_update_hdmi_info_packets(params);
>                       break;
> +             case HPO_FRL_STREAM_ENC_UPDATE_HDMI_INFO_PACKETS:
> +                     
> hwss_hpo_frl_stream_enc_update_hdmi_info_packets(params);
> +                     break;
>               case HPO_DP_STREAM_ENC_UPDATE_DP_INFO_PACKETS_SDP_LINE_NUM:
>                       
> hwss_hpo_dp_stream_enc_update_dp_info_packets_sdp_line_num(params);
>                       break;
> @@ -3642,6 +3645,15 @@ void hwss_stream_enc_update_hdmi_info_packets(union 
> block_sequence_params *param
>                       
> &params->stream_enc_update_hdmi_info_packets_params.pipe_ctx->stream_res.encoder_info_frame);
>  }
>  
> +void hwss_hpo_frl_stream_enc_update_hdmi_info_packets(union 
> block_sequence_params *params)
> +{
> +     if 
> (params->hpo_frl_stream_enc_update_hdmi_info_packets_params.pipe_ctx->stream_res.hpo_frl_stream_enc
>  &&
> +         
> params->hpo_frl_stream_enc_update_hdmi_info_packets_params.pipe_ctx->stream_res.hpo_frl_stream_enc->funcs->update_hdmi_info_packets)
> +             
> params->hpo_frl_stream_enc_update_hdmi_info_packets_params.pipe_ctx->stream_res.hpo_frl_stream_enc->funcs->update_hdmi_info_packets(
> +                     
> params->hpo_frl_stream_enc_update_hdmi_info_packets_params.pipe_ctx->stream_res.hpo_frl_stream_enc,
> +                     
> &params->hpo_frl_stream_enc_update_hdmi_info_packets_params.pipe_ctx->stream_res.encoder_info_frame);
> +}
> +
>  void hwss_hpo_dp_stream_enc_update_dp_info_packets_sdp_line_num(union 
> block_sequence_params *params)
>  {
>       if 
> (params->hpo_dp_stream_enc_update_dp_info_packets_sdp_line_num_params.pipe_ctx->stream_res.hpo_dp_stream_enc
>  &&
> @@ -4865,6 +4877,16 @@ void 
> hwss_add_stream_enc_update_hdmi_info_packets(struct block_sequence_state *s
>       }
>  }
>  
> +void hwss_add_hpo_frl_stream_enc_update_hdmi_info_packets(struct 
> block_sequence_state *seq_state,
> +             struct pipe_ctx *pipe_ctx)
> +{
> +     if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
> +             seq_state->steps[*seq_state->num_steps].func = 
> HPO_FRL_STREAM_ENC_UPDATE_HDMI_INFO_PACKETS;
> +             
> seq_state->steps[*seq_state->num_steps].params.hpo_frl_stream_enc_update_hdmi_info_packets_params.pipe_ctx
>  = pipe_ctx;
> +             (*seq_state->num_steps)++;
> +     }
> +}
> +
>  void hwss_add_hpo_dp_stream_enc_update_dp_info_packets_sdp_line_num(struct 
> block_sequence_state *seq_state,
>               struct pipe_ctx *pipe_ctx)
>  {
> @@ -4963,6 +4985,20 @@ void 
> hwss_add_stream_enc_dp_set_dsc_pps_info_packet(struct block_sequence_state
>       }
>  }
>  
> +void hwss_add_hpo_frl_stream_enc_set_dsc_config(struct block_sequence_state 
> *seq_state,
> +             struct hpo_frl_stream_encoder *hpo_frl_stream_enc,
> +             const struct dc_crtc_timing *timing,
> +             uint8_t *dsc_packed_pps)
> +{
> +     if (*seq_state->num_steps < MAX_HWSS_BLOCK_SEQUENCE_SIZE) {
> +             seq_state->steps[*seq_state->num_steps].func = 
> HPO_FRL_STREAM_ENC_SET_DSC_CONFIG;
> +             
> seq_state->steps[*seq_state->num_steps].params.hpo_frl_stream_enc_set_dsc_config_params.hpo_frl_stream_enc
>  = hpo_frl_stream_enc;
> +             
> seq_state->steps[*seq_state->num_steps].params.hpo_frl_stream_enc_set_dsc_config_params.timing
>  = timing;
> +             
> seq_state->steps[*seq_state->num_steps].params.hpo_frl_stream_enc_set_dsc_config_params.dsc_packed_pps
>  = dsc_packed_pps;
> +             (*seq_state->num_steps)++;
> +     }
> +}
> +
>  void hwss_add_setup_periodic_interrupt(struct block_sequence_state 
> *seq_state,
>               struct dc *dc,
>               struct pipe_ctx *pipe_ctx)
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
> index deb23d20bca6..6c3d442587a4 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
> @@ -45,6 +45,9 @@ static bool is_dig_link_enc_stream(struct dc_stream_state 
> *stream)
>                        */
>                       if (link_enc && 
> ((uint32_t)stream->link->connector_signal & link_enc->output_signals)) {
>                               is_dig_stream = true;
> +                             /* If stream is HDMI FRL, then it is not a DIG 
> stream. */
> +                             if (dc_is_hdmi_frl_signal(stream->signal))
> +                                     is_dig_stream = false;
>                               break;
>                       }
>               }
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
> index f4e99ca7918f..ef9b7ab6eddf 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
> @@ -126,6 +126,19 @@ uint32_t dc_link_bandwidth_kbps(
>       return link->dc->link_srv->dp_link_bandwidth_kbps(link, link_settings);
>  }
>  
> +uint32_t dc_link_frl_bandwidth_kbps(const struct dc_link *link, enum 
> hdmi_frl_link_rate link_rate)
> +{
> +     return link->dc->link_srv->frl_link_bandwidth_kbps(link_rate);
> +}
> +
> +bool dc_link_frl_margin_check_uncompressed_video(
> +             const struct dc_link *link,
> +             struct frl_cap_chk_params_fixed31_32 *params,
> +             struct frl_cap_chk_intermediates_fixed31_32 *inter)
> +{
> +     return link->dc->link_srv->frl_margin_check_uncompressed_video(params, 
> inter);
> +}
> +
>  uint32_t dc_link_required_hblank_size_bytes(
>       const struct dc_link *link,
>       struct dp_audio_bandwidth_params *audio_params)
> @@ -144,6 +157,11 @@ void dc_restore_link_res_map(const struct dc *dc, 
> uint32_t *map)
>       dc->link_srv->restore_res_map(dc, map);
>  }
>  
> +void dc_link_wait_for_unlocked(struct dc_link *link)
> +{
> +     link->dc->link_srv->wait_for_unlocked(link);
> +}
> +
>  bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx)
>  {
>       struct dc_link *link = pipe_ctx->stream->link;
> @@ -345,6 +363,14 @@ enum dc_link_encoding_format 
> dc_link_get_highest_encoding_format(const struct dc
>                               DP_128b_132b_ENCODING)
>                       return DC_LINK_ENCODING_DP_128b_132b;
>       } else if (dc_is_hdmi_signal(link->connector_signal)) {
> +             const struct dc_hdmi_frl_link_settings *frl_link_settings =
> +                             &link->frl_verified_link_cap;
> +
> +             if (frl_link_settings->frl_link_rate == 
> HDMI_FRL_LINK_RATE_DISABLE)
> +                     return DC_LINK_ENCODING_HDMI_TMDS;
> +             else if (frl_link_settings->frl_link_rate >= 
> HDMI_FRL_LINK_RATE_3GBPS &&
> +                             frl_link_settings->frl_link_rate <= 
> HDMI_FRL_LINK_RATE_12GBPS)
> +                     return DC_LINK_ENCODING_HDMI_FRL;
>       }
>  
>       return DC_LINK_ENCODING_UNSPECIFIED;
> @@ -518,6 +544,25 @@ bool dc_link_wait_for_t12(struct dc_link *link)
>       return link->dc->link_srv->edp_wait_for_t12(link);
>  }
>  
> +bool dc_link_frl_poll_status_flag(struct dc_link *link)
> +{
> +     return link->dc->link_srv->hdmi_frl_poll_status_flag(link);
> +}
> +
> +struct dc_hdmi_frl_link_settings *dc_link_get_frl_link_cap(
> +             struct dc_link *link)
> +{
> +     return link->dc->link_srv->hdmi_frl_get_verified_link_cap(link);
> +}
> +
> +void dc_link_set_preferred_frl_link_settings(struct dc *dc,
> +             struct dc_hdmi_frl_link_settings *link_setting,
> +             struct dc_hdmi_frl_link_training_overrides *lt_overrides,
> +             struct dc_link *link)
> +{
> +     link->dc->link_srv->hdmi_frl_set_preferred_link_settings(dc, 
> link_setting, lt_overrides, link);
> +}
> +
>  bool dc_link_get_hpd_state(struct dc_link *link)
>  {
>       return link->dc->link_srv->get_hpd_state(link);
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> index 19526a278b2a..2457b563e6c8 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> @@ -96,6 +96,8 @@
>  #define DC_LOGGER \
>       dc->ctx->logger
>  #define DC_LOGGER_INIT(logger)
> +#include "link/hwss/link_hwss_hpo_frl.h"
> +#include "dml/dml1_frl_cap_chk.h"
>  #include "dml2_0/dml2_wrapper.h"
>  
>  #define UNABLE_TO_SPLIT -1
> @@ -497,6 +499,25 @@ bool resource_construct(
>               }
>       }
>  
> +     pool->hpo_frl_stream_enc_count = 0;
> +     if (create_funcs->create_hpo_frl_stream_encoder) {
> +             for (i = 0; i < (unsigned int)caps->num_hpo_frl; i++) {
> +                     pool->hpo_frl_stream_enc[i] = 
> create_funcs->create_hpo_frl_stream_encoder(i+ENGINE_ID_HPO_0, ctx);
> +                     if (pool->hpo_frl_stream_enc[i] == NULL)
> +                             DC_ERR("DC: failed to create HPO FRL stream 
> encoder!\n");
> +                     pool->hpo_frl_stream_enc_count++;
> +
> +             }
> +     }
> +     pool->hpo_frl_link_enc_count = 0;
> +     if (create_funcs->create_hpo_frl_link_encoder) {
> +             for (i = 0; i < (unsigned int)caps->num_hpo_frl; i++) {
> +                     pool->hpo_frl_link_enc[i] = 
> create_funcs->create_hpo_frl_link_encoder(i+ENGINE_ID_HPO_0, ctx);
> +                     if (pool->hpo_frl_link_enc[i] == NULL)
> +                             DC_ERR("DC: failed to create HPO FRL link 
> encoder!\n");
> +                     pool->hpo_frl_link_enc_count++;
> +             }
> +     }
>       pool->hpo_dp_stream_enc_count = 0;
>       if (create_funcs->create_hpo_dp_stream_encoder) {
>               for (i = 0; i < caps->num_hpo_dp_stream_encoder; i++) {
> @@ -2648,6 +2669,164 @@ static void update_stream_engine_usage(
>       }
>  }
>  
> +static void update_hpo_frl_stream_engine_usage(
> +             struct resource_context *res_ctx,
> +             const struct resource_pool *pool,
> +             struct hpo_frl_stream_encoder *hpo_frl_stream_enc,
> +             bool acquired)
> +{
> +     unsigned int i;
> +
> +     for (i = 0; i < pool->hpo_frl_stream_enc_count; i++) {
> +             if (pool->hpo_frl_stream_enc[i] == hpo_frl_stream_enc)
> +                     res_ctx->is_hpo_frl_stream_enc_acquired[i] = acquired;
> +     }
> +}
> +
> +static struct hpo_frl_stream_encoder 
> *find_first_free_match_hpo_frl_stream_enc_for_link(
> +             struct resource_context *res_ctx,
> +             const struct resource_pool *pool,
> +             struct dc_stream_state *stream)
> +{
> +     (void)stream;
> +     unsigned int i;
> +
> +     for (i = 0; i < pool->hpo_frl_stream_enc_count; i++) {
> +             if (!res_ctx->is_hpo_frl_stream_enc_acquired[i] &&
> +                             pool->hpo_frl_stream_enc[i]) {
> +
> +                     return pool->hpo_frl_stream_enc[i];
> +             }
> +     }
> +
> +     return NULL;
> +}
> +
> +static inline int find_acquired_hpo_frl_link_enc_for_link(
> +             const struct resource_context *res_ctx,
> +             const struct dc_link *link)
> +{
> +     int i;
> +
> +     for (i = 0; i < ARRAY_SIZE(res_ctx->hpo_frl_link_enc_to_link_idx); i++)
> +             if (res_ctx->hpo_frl_link_enc_ref_cnts[i] > 0 &&
> +                             res_ctx->hpo_frl_link_enc_to_link_idx[i] == 
> link->link_index)
> +                     return i;
> +
> +     return -1;
> +}
> +
> +static inline int find_free_hpo_frl_link_enc(const struct resource_context 
> *res_ctx,
> +             const struct resource_pool *pool)
> +{
> +     unsigned int i;
> +
> +     for (i = 0; i < ARRAY_SIZE(res_ctx->hpo_frl_link_enc_ref_cnts); i++)
> +             if (res_ctx->hpo_frl_link_enc_ref_cnts[i] == 0)
> +                     break;
> +
> +     return (i < ARRAY_SIZE(res_ctx->hpo_frl_link_enc_ref_cnts) &&
> +                     i < pool->hpo_frl_link_enc_count) ? (int)i : -1;
> +}
> +
> +static inline void acquire_hpo_frl_link_enc(
> +             struct resource_context *res_ctx,
> +             unsigned int link_index,
> +             int enc_index)
> +{
> +     res_ctx->hpo_frl_link_enc_to_link_idx[enc_index] = link_index;
> +     res_ctx->hpo_frl_link_enc_ref_cnts[enc_index] = 1;
> +}
> +
> +static inline void retain_hpo_frl_link_enc(
> +             struct resource_context *res_ctx,
> +             int enc_index)
> +{
> +     res_ctx->hpo_frl_link_enc_ref_cnts[enc_index]++;
> +}
> +
> +static inline void release_hpo_frl_link_enc(
> +             struct resource_context *res_ctx,
> +             int enc_index)
> +{
> +     ASSERT(res_ctx->hpo_frl_link_enc_ref_cnts[enc_index] > 0);
> +     res_ctx->hpo_frl_link_enc_ref_cnts[enc_index]--;
> +}
> +
> +static bool add_hpo_frl_link_enc_to_ctx(struct resource_context *res_ctx,
> +             const struct resource_pool *pool,
> +             struct pipe_ctx *pipe_ctx,
> +             struct dc_stream_state *stream)
> +{
> +     int enc_index;
> +
> +     enc_index = find_acquired_hpo_frl_link_enc_for_link(res_ctx, 
> stream->link);
> +
> +     if (enc_index >= 0) {
> +             retain_hpo_frl_link_enc(res_ctx, enc_index);
> +     } else {
> +             enc_index = find_free_hpo_frl_link_enc(res_ctx, pool);
> +             if (enc_index >= 0)
> +                     acquire_hpo_frl_link_enc(res_ctx, 
> stream->link->link_index, enc_index);
> +     }
> +
> +     if (enc_index >= 0)
> +             pipe_ctx->link_res.hpo_frl_link_enc = 
> pool->hpo_frl_link_enc[enc_index];
> +
> +     return pipe_ctx->link_res.hpo_frl_link_enc != NULL;
> +}
> +
> +static void remove_hpo_frl_link_enc_from_ctx(struct resource_context 
> *res_ctx,
> +             struct pipe_ctx *pipe_ctx,
> +             struct dc_stream_state *stream)
> +{
> +     int enc_index;
> +
> +     enc_index = find_acquired_hpo_frl_link_enc_for_link(res_ctx, 
> stream->link);
> +
> +     if (enc_index >= 0) {
> +             release_hpo_frl_link_enc(res_ctx, enc_index);
> +             pipe_ctx->link_res.hpo_frl_link_enc = NULL;
> +     }
> +}
> +
> +static struct hpo_frl_link_encoder *get_temp_hpo_frl_link_enc(
> +             const struct resource_context *res_ctx,
> +             const struct resource_pool *const pool,
> +             const struct dc_link *link)
> +{
> +     struct hpo_frl_link_encoder *hpo_frl_link_enc = NULL;
> +     int enc_index;
> +
> +     enc_index = find_acquired_hpo_frl_link_enc_for_link(res_ctx, link);
> +
> +     if (enc_index < 0)
> +             enc_index = find_free_hpo_frl_link_enc(res_ctx, pool);
> +
> +     if (enc_index >= 0)
> +             hpo_frl_link_enc = pool->hpo_frl_link_enc[enc_index];
> +
> +     return hpo_frl_link_enc;
> +}
> +
> +bool get_temp_frl_link_res(struct dc_link *link,
> +             struct link_resource *link_res)
> +{
> +     const struct dc *dc  = link->dc;
> +     const struct resource_context *res_ctx = &dc->current_state->res_ctx;
> +
> +     memset(link_res, 0, sizeof(*link_res));
> +     link_res->hpo_frl_link_enc = get_temp_hpo_frl_link_enc(res_ctx, 
> dc->res_pool, link);
> +     if (!link_res->hpo_frl_link_enc)
> +             return false;
> +
> +     link_res->dio_link_enc = get_temp_dio_link_enc(res_ctx,
> +                     dc->res_pool, link);
> +     if (!link_res->dio_link_enc)
> +             return false;
> +
> +     return true;
> +}
>  static void update_hpo_dp_stream_engine_usage(
>               struct resource_context *res_ctx,
>               const struct resource_pool *pool,
> @@ -2969,6 +3148,15 @@ void 
> resource_remove_otg_master_for_stream_output(struct dc_state *context,
>                       otg_master->stream_res.stream_enc,
>                       false);
>  
> +     if (dc_is_hdmi_frl_signal(stream->signal)) {
> +             update_hpo_frl_stream_engine_usage(
> +                     &context->res_ctx, pool,
> +                     otg_master->stream_res.hpo_frl_stream_enc,
> +                     false);
> +             remove_hpo_frl_link_enc_from_ctx(
> +                     &context->res_ctx, otg_master, stream);
> +             remove_dio_link_enc_from_ctx(&context->res_ctx, otg_master, 
> stream);
> +     }
>       if (stream->ctx->dc->link_srv->dp_is_128b_132b_signal(otg_master)) {
>               update_hpo_dp_stream_engine_usage(
>                       &context->res_ctx, pool,
> @@ -4016,6 +4204,33 @@ enum dc_status resource_map_pool_resources(
>               pipe_ctx->stream_res.stream_enc,
>               true);
>  
> +     if (dc_is_hdmi_frl_signal(stream->signal)) {
> +             is_dio_encoder = false;
> +             pipe_ctx->stream_res.hpo_frl_stream_enc =
> +                     find_first_free_match_hpo_frl_stream_enc_for_link(
> +                             &context->res_ctx, pool, stream);
> +
> +             if (!pipe_ctx->stream_res.hpo_frl_stream_enc)
> +                     if (stream->timing.pix_clk_100hz < 6000000)
> +                             stream->signal = SIGNAL_TYPE_HDMI_TYPE_A;
> +                     else
> +                             return DC_NO_STREAM_ENC_RESOURCE;
> +             else {
> +                     update_hpo_frl_stream_engine_usage(
> +                             &context->res_ctx, pool,
> +                             pipe_ctx->stream_res.hpo_frl_stream_enc,
> +                             true);
> +                     pipe_ctx->link_res.hpo_frl_link_enc =
> +                             pipe_ctx->stream->link->hpo_frl_link_enc;
> +                     if (!pipe_ctx->link_res.hpo_frl_link_enc) {
> +                             if 
> (!add_hpo_frl_link_enc_to_ctx(&context->res_ctx, pool, pipe_ctx, stream))
> +                                     return DC_NO_LINK_ENC_RESOURCE;
> +                     }
> +                     if (!add_dio_link_enc_to_ctx(dc, context, pool, 
> pipe_ctx, stream))
> +                             return DC_NO_LINK_ENC_RESOURCE;
> +             }
> +     }
> +
>       /* Allocate DP HPO Stream Encoder based on signal, hw capabilities
>        * and link settings
>        */
> @@ -4081,6 +4296,8 @@ enum dc_status resource_map_pool_resources(
>               if (context->streams[i] == stream) {
>                       context->stream_status[i].primary_otg_inst = 
> pipe_ctx->stream_res.tg->inst;
>                       context->stream_status[i].stream_enc_inst = 
> pipe_ctx->stream_res.stream_enc->stream_enc_inst;
> +                     if (pipe_ctx->stream_res.hpo_frl_stream_enc != NULL)
> +                             context->stream_status[i].stream_enc_inst = 
> pipe_ctx->stream_res.hpo_frl_stream_enc->stream_enc_inst;
>                       context->stream_status[i].audio_inst =
>                               pipe_ctx->stream_res.audio ? 
> pipe_ctx->stream_res.audio->inst : -1;
>  
> @@ -4923,6 +5140,9 @@ void resource_build_info_frame(struct pipe_ctx 
> *pipe_ctx)
>  
>               set_hdr_static_info_packet(&info->hdrsmd, pipe_ctx->stream);
>  
> +             if (dc_is_hdmi_frl_signal(signal)) {
> +                     /* TODO: additional packets for HDMI 2.1 */
> +             }
>       } else if (dc_is_dp_signal(signal)) {
>               set_vsc_info_packet(&info->vsc, pipe_ctx->stream);
>  
> @@ -5020,6 +5240,8 @@ bool pipe_need_reprogram(
>       if (pipe_ctx_old->stream_res.dsc != pipe_ctx->stream_res.dsc)
>               return true;
>  
> +     if (pipe_ctx_old->stream_res.hpo_frl_stream_enc != 
> pipe_ctx->stream_res.hpo_frl_stream_enc)
> +             return true;
>       if (pipe_ctx_old->stream_res.hpo_dp_stream_enc != 
> pipe_ctx->stream_res.hpo_dp_stream_enc)
>               return true;
>       if (pipe_ctx_old->link_res.hpo_dp_link_enc != 
> pipe_ctx->link_res.hpo_dp_link_enc)
> @@ -5282,10 +5504,13 @@ void get_audio_check(struct audio_info *aud_modes,
>               audio_chk->audio_packet_type = 0x2;/*audio sample packet AP = 
> .25 for layout0, 1 for layout1*/
>  
>               audio_chk->max_audiosample_rate = 0;
> +             audio_chk->max_channel_count = 0;
>               for (i = 0; i < aud_modes->mode_count; i++) {
>                       max_sample_rate = 
> get_max_audio_sample_rate(&aud_modes->modes[i]);
>                       if (audio_chk->max_audiosample_rate < max_sample_rate)
>                               audio_chk->max_audiosample_rate = 
> max_sample_rate;
> +                     if (audio_chk->max_channel_count < 
> aud_modes->modes[i].channel_count)
> +                             audio_chk->max_channel_count = 
> aud_modes->modes[i].channel_count;
>                       /*dts takes the same as type 2: AP = 0.25*/
>               }
>               /*check which one take more bandwidth*/
> @@ -5497,6 +5722,8 @@ const struct link_hwss *get_link_hwss(const struct 
> dc_link *link,
>                */
>               return (requires_fixed_vs_pe_retimer_hpo_link_hwss(link) ?
>                               get_hpo_fixed_vs_pe_retimer_dp_link_hwss() : 
> get_hpo_dp_link_hwss());
> +     else if (can_use_hpo_frl_link_hwss(link, link_res))
> +             return get_hpo_frl_link_hwss();
>       else if (can_use_dpia_link_hwss(link, link_res))
>               return get_dpia_link_hwss();
>       else if (can_use_dio_link_hwss(link, link_res))
> @@ -5724,5 +5951,11 @@ bool resource_is_hpo_acquired(struct dc_state *context)
>               }
>       }
>  
> +     for (i = 0; i < MAX_HDMI_FRL_ENCODERS; i++) {
> +             if (context->res_ctx.is_hpo_frl_stream_enc_acquired[i]) {
> +                     return true;
> +             }
> +     }
> +
>       return false;
>  }
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
> index 9c1d721011ca..f694c6ad6e98 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
> @@ -54,6 +54,7 @@
>   
> ******************************************************************************/
>  void update_stream_signal(struct dc_stream_state *stream, struct dc_sink 
> *sink)
>  {
> +     unsigned int pix_clk;
>       if (sink->sink_signal == SIGNAL_TYPE_NONE)
>               stream->signal = stream->link->connector_signal;
>       else
> @@ -67,6 +68,40 @@ void update_stream_signal(struct dc_stream_state *stream, 
> struct dc_sink *sink)
>               else
>                       stream->signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
>       }
> +     if (dc_is_hdmi_frl_signal(stream->signal)) {
> +             pix_clk = stream->timing.pix_clk_100hz / 10;
> +             if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
> +                     pix_clk /= 2;
> +
> +             // YCbCr422 to use assume 12-bit interface always, clock stays 
> the same
> +             if (stream->timing.pixel_encoding != PIXEL_ENCODING_YCBCR422) {
> +                     switch (stream->timing.display_color_depth) {
> +                     case COLOR_DEPTH_666:
> +                     case COLOR_DEPTH_888:
> +                             break;
> +                     case COLOR_DEPTH_101010:
> +                             pix_clk = pix_clk * 10 / 8;
> +                             break;
> +                     case COLOR_DEPTH_121212:
> +                             pix_clk = pix_clk * 12 / 8;
> +                             break;
> +                     default:
> +                             break;
> +                     }
> +             }
> +             if (pix_clk != 0 && pix_clk < HDMI2_TMDS_MAX_PIXEL_CLOCK)
> +                     stream->signal = SIGNAL_TYPE_HDMI_TYPE_A;
> +             if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420 &&
> +                             stream->timing.h_addressable > 4096)
> +                     stream->signal = SIGNAL_TYPE_HDMI_FRL;
> +             if (stream->timing.rid != 0)
> +                     stream->signal = SIGNAL_TYPE_HDMI_FRL;
> +
> +             if (stream->link->frl_flags.force_frl_always ||
> +                             stream->link->frl_flags.force_frl_max
> +                             )
> +                     stream->signal = SIGNAL_TYPE_HDMI_FRL;
> +     }
>  }
>  
>  bool dc_stream_construct(struct dc_stream_state *stream,
> diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c 
> b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
> index 8af8e2c17134..239ba2b352a1 100644
> --- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
> +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
> @@ -535,6 +535,7 @@ static void check_audio_bandwidth(
>  {
>       switch (signal) {
>       case SIGNAL_TYPE_HDMI_TYPE_A:
> +     case SIGNAL_TYPE_HDMI_FRL:
>               check_audio_bandwidth_hdmi(
>                       crtc_info, channel_count, sample_rates);
>               break;
> @@ -738,6 +739,7 @@ void dce_aud_az_configure(
>       /* set audio for output signal */
>       switch (signal) {
>       case SIGNAL_TYPE_HDMI_TYPE_A:
> +     case SIGNAL_TYPE_HDMI_FRL:
>               set_reg_field_value(value,
>                       1,
>                       AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
> @@ -798,6 +800,12 @@ void dce_aud_az_configure(
>                       /* adjust specific properties */
>                       switch (audio_format_code) {
>                       case AUDIO_FORMAT_CODE_LINEARPCM: {
> +                             if (signal == SIGNAL_TYPE_HDMI_FRL
> +                                             && channel_count > 2
> +                                             && crtc_info != NULL
> +                                             && crtc_info->v_active <= 576) {
> +                                     channel_count = 2;
> +                             }
>  
>                               check_audio_bandwidth(
>                                       crtc_info,
> diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c 
> b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
> index b97b4cd23eaa..7a0caace1604 100644
> --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
> +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
> @@ -981,7 +981,9 @@ static bool dcn31_program_pix_clk(
>               dp_dto_ref_khz = 
> clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz;
>  
>       // For these signal types Driver to program DP_DTO without calling 
> VBIOS Command table
> -     if (dc_is_dp_signal(pix_clk_params->signal_type) || 
> dc_is_virtual_signal(pix_clk_params->signal_type)) {
> +     if (dc_is_hdmi_frl_signal(pix_clk_params->signal_type) ||
> +                     dc_is_virtual_signal(pix_clk_params->signal_type) ||
> +                     dc_is_dp_signal(pix_clk_params->signal_type)) {
>               if (e) {
>                       /* Set DTO values: phase = target clock, modulo = 
> reference clock*/
>                       REG_WRITE(PHASE[inst], e->target_pixel_rate_khz * 
> e->mult_factor);
> @@ -997,6 +999,10 @@ static bool dcn31_program_pix_clk(
>                               REG_UPDATE_2(PIXEL_RATE_CNTL[inst],
>                                               DP_DTO0_ENABLE, 1,
>                                               PIPE0_DTO_SRC_SEL, 2);
> +                     else if 
> (dc_is_hdmi_frl_signal(pix_clk_params->signal_type) || encoding == 
> DP_128b_132b_ENCODING)
> +                             REG_UPDATE_2(PIXEL_RATE_CNTL[inst],
> +                                             DP_DTO0_ENABLE, 0,
> +                                             PIPE0_DTO_SRC_SEL, 2);
>                       else
>                               REG_UPDATE_2(PIXEL_RATE_CNTL[inst],
>                                               DP_DTO0_ENABLE, 1,
> @@ -1084,8 +1090,14 @@ static bool dcn401_program_pix_clk(
>       if (!dc_is_tmds_signal(pix_clk_params->signal_type)) {
>               long long dtbclk_p_src_clk_khz;
>  
> -             dtbclk_p_src_clk_khz = 
> clock_source->ctx->dc->clk_mgr->dprefclk_khz;
> -             dto_params.clk_src = DPREFCLK;
> +             /* if signal is HDMI FRL dtbclk_p_src is DTBCLK else DPREFCLK */
> +             if (dc_is_hdmi_frl_signal(pix_clk_params->signal_type)) {
> +                     dtbclk_p_src_clk_khz = 
> clock_source->ctx->dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(clock_source->ctx->dc->clk_mgr);
> +                     dto_params.clk_src = DTBCLK0;
> +             } else {
> +                     dtbclk_p_src_clk_khz = 
> clock_source->ctx->dc->clk_mgr->dprefclk_khz;
> +                     dto_params.clk_src = DPREFCLK;
> +             }
>  
>               if (e) {
>                       dto_params.pixclk_hz = e->target_pixel_rate_khz;
> @@ -1103,7 +1115,15 @@ static bool dcn401_program_pix_clk(
>               clock_source->ctx->dc->res_pool->dccg->funcs->set_dp_dto(
>                               clock_source->ctx->dc->res_pool->dccg,
>                               &dto_params);
> -
> +             if (clock_source->ctx->dc->caps.is_apu &&
> +                     pix_clk_params->requested_pix_clk_100hz &&
> +                     dc_is_hdmi_frl_signal(pix_clk_params->signal_type)) {
> +                     /*need hdmistreamclk before vpg block register access*/
> +                     
> clock_source->ctx->dc->res_pool->dccg->funcs->set_hdmistreamclk(
> +                             clock_source->ctx->dc->res_pool->dccg,
> +                             DTBCLK0,
> +                             pix_clk_params->controller_id - 1);
> +             }
>       } else {
>               if (pll_settings->actual_pix_clk_100hz > 6000000UL)
>                       return false;
> @@ -1335,7 +1355,7 @@ static bool dcn3_program_pix_clk(
>                       
> look_up_in_video_optimized_rate_tlb(pix_clk_params->requested_pix_clk_100hz / 
> 10);
>  
>       // For these signal types Driver to program DP_DTO without calling 
> VBIOS Command table
> -     if (dc_is_dp_signal(pix_clk_params->signal_type)) {
> +     if ((pix_clk_params->signal_type == SIGNAL_TYPE_HDMI_FRL) || 
> dc_is_dp_signal(pix_clk_params->signal_type)) {
>               if (e) {
>                       /* Set DTO values: phase = target clock, modulo = 
> reference clock*/
>                       REG_WRITE(PHASE[inst], e->target_pixel_rate_khz * 
> e->mult_factor);
> diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h 
> b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
> index fe9431cea3e5..29986ee3fd2b 100644
> --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
> +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
> @@ -2898,16 +2898,19 @@ struct dmub_dig_transmitter_control_data_v1_7 {
>       union {
>               uint8_t digmode; /**< enum atom_encode_mode_def */
>               uint8_t dplaneset; /**< DP voltage swing and pre-emphasis 
> value, "DP_LANE_SET__xDB_y_zV" */
> +             uint8_t txffe; /**< TxFFE settings for HDMI 2.1 */
>       } mode_laneset;
>       uint8_t lanenum; /**< Number of lanes */
>       union {
>               uint32_t symclk_10khz; /**< Symbol Clock in 10Khz */
> +             uint32_t symclk_Hz; /**< Symbol clock in Hz for FRL */
>       } symclk_units;
>       uint8_t hpdsel; /**< =1: HPD1, =2: HPD2, ..., =6: HPD6, =0: HPD is not 
> assigned */
>       uint8_t digfe_sel; /**< DIG front-end selection, bit0 means DIG0 FE is 
> enabled */
>       uint8_t connobj_id; /**< Connector Object Id defined in ObjectId.h */
>       uint8_t HPO_instance; /**< HPO instance (0: inst0, 1: inst1) */
> -     uint8_t reserved1; /**< For future use */
> +     uint8_t TxFFELaneSel; /**< TxFFE lane select [3:0]
> +                             (bit0: lane0, bit1: lane1, bit2: lane3, bit3: 
> lane3) */
>       uint8_t skip_phy_ssc_reduction;
>       uint8_t reserved2[2]; /**< For future use */
>       uint32_t reserved3[11]; /**< For future use */

Reply via email to