This patch adds all relevant includes in DC that are
used by the HDMI FRL implementation in DC.

Signed-off-by: Harry Wentland <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/dc.h           | 121 ++++++++++
 .../gpu/drm/amd/display/dc/dc_hdmi_types.h    | 162 ++++++++++++-
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h  |   8 +
 drivers/gpu/drm/amd/display/dc/dc_types.h     |  24 ++
 drivers/gpu/drm/amd/display/dc/dm_cp_psp.h    |   1 +
 .../drm/amd/display/dc/dm_services_types.h    |   1 +
 .../drm/amd/display/dc/dml/dml1_frl_cap_chk.h | 173 +++++++++++++
 .../gpu/drm/amd/display/dc/inc/core_status.h  |   2 +
 .../gpu/drm/amd/display/dc/inc/core_types.h   |  12 +
 drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h  |  10 +
 .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h |   1 +
 .../drm/amd/display/dc/inc/hw/link_encoder.h  | 176 ++++++++++++++
 .../amd/display/dc/inc/hw/stream_encoder.h    | 227 ++++++++++++++++++
 .../amd/display/dc/inc/hw/timing_generator.h  |   6 +
 .../gpu/drm/amd/display/dc/inc/link_service.h |  15 ++
 drivers/gpu/drm/amd/display/dc/inc/resource.h |   7 +
 .../gpu/drm/amd/display/include/audio_types.h |   1 +
 .../amd/display/include/bios_parser_types.h   |  14 +-
 .../drm/amd/display/include/logger_types.h    |   2 +
 .../drm/amd/display/include/signal_types.h    |  12 +-
 20 files changed, 966 insertions(+), 9 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dml1_frl_cap_chk.h

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 50ec5acb6c7b..965fa9830355 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -46,6 +46,8 @@
 
 #include "dmub/inc/dmub_cmd.h"
 
+#include "dml/dml1_frl_cap_chk.h"
+
 #include "sspl/dc_spl_types.h"
 
 struct abm_save_restore;
@@ -84,6 +86,49 @@ struct dcn_dccg_reg_state;
 
 #define NUM_FAST_FLIPS_TO_STEADY_STATE 20
 
+struct frl_cap_chk_intermediates_fixed31_32 {
+       int      c_frl_sb;
+       struct fixed31_32   overhead_sb;
+       struct fixed31_32   overhead_rs;
+       struct fixed31_32   overhead_map;
+       struct fixed31_32   overhead_min;
+       struct fixed31_32   overhead_max;
+       struct fixed31_32   f_pixel_clock_max;
+       struct fixed31_32   t_line;
+       struct fixed31_32   r_bit_min;
+       struct fixed31_32   r_frl_char_min;
+       struct fixed31_32   c_frl_line;
+       struct fixed31_32   ap;
+       struct fixed31_32   r_ap;
+       struct fixed31_32   avg_audio_packets_line;
+       struct fixed31_32   margin;
+       int      audio_packets_line;
+       int      blank_audio_min;
+};
+
+struct frl_cap_chk_params_fixed31_32 {
+       int      lanes;
+       struct fixed31_32   f_pixel_clock_nominal;   /* Pixel Clock rate (Hz)  
*/
+       struct fixed31_32   r_bit_nominal;           /* FRL bitrate (bps) */
+       int      audio_packet_type;
+       struct fixed31_32   f_audio;                 /* Audio rate (Hz) */
+       int      h_active;                /* Active pixels per line */
+       int      h_blank;                 /* Blanking pixels per line */
+       int      bpc;                     /* Bits per component */
+       int      vic;                     /* Video Identification Code */
+
+       enum hdmi_frl_pixel_encoding    pixel_encoding;
+
+       bool     compressed;              /* set to true if DSC is enabled */
+       bool     bypass_hc_target_calc;   /* debug only */
+       int      layout;
+       int      acat;    /* not supported */
+
+       /* outputs */
+       struct frl_dml_borrow_params borrow_params;
+       int      average_tribyte_rate;
+};
+
 /* Display Core Interfaces */
 struct dc_versions {
        const char *dc_ver;
@@ -332,6 +377,7 @@ struct dc_caps {
        bool ips_v2_support;
        uint32_t num_of_internal_disp;
        enum dp_protocol_version max_dp_protocol_version;
+       bool hdmi_hpo;
        unsigned int mall_size_per_mem_channel;
        unsigned int mall_size_total;
        unsigned int cursor_cache_size;
@@ -537,6 +583,8 @@ struct dc_config {
        int smart_mux_version;
        bool ignore_dpref_ss;
        bool enable_mipi_converter_optimization;
+       bool force_hdmi21_frl_enc_enable;
+       bool skip_frl_pretraining;
        bool use_default_clock_table;
        bool force_bios_enable_lttpr;
        uint8_t force_bios_fixed_vs;
@@ -1095,6 +1143,18 @@ struct dc_debug_options {
        bool validate_dml_output;
        bool enable_dmcub_surface_flip;
        bool usbc_combo_phy_reset_wa;
+       bool force_vrr;
+       bool force_fva;
+       int max_frl_rate;
+       int  force_frl_rate;
+       bool ignore_ffe;
+       int  select_ffe;
+       int  limit_ffe;
+       bool force_frl_always;
+       bool force_frl_max;
+       bool apply_vsdb_rcc_wa;
+       bool enable_hdmi_idcc;
+
        bool enable_dram_clock_change_one_display_vactive;
        /* TODO - remove once tested */
        bool legacy_dp2_lt;
@@ -1667,6 +1727,7 @@ struct dc_scratch_space {
        bool edp_sink_present;
 
        struct dp_trace dp_trace;
+       volatile bool is_link_locked;
 
        /* caps is the same as reported_link_cap. link_traing use
         * reported_link_cap. Will clean up.  TODO
@@ -1681,6 +1742,7 @@ struct dc_scratch_space {
         * management of the override pointers.
         */
        struct dc_link_training_overrides preferred_training_settings;
+       struct dc_hdmi_frl_link_training_overrides preferred_hdmi_frl_settings;
        struct dp_audio_test_data audio_test_data;
 
        uint8_t ddc_hw_inst;
@@ -1726,6 +1788,12 @@ struct dc_scratch_space {
 
        struct panel_cntl *panel_cntl;
        struct link_encoder *link_enc;
+       struct hpo_frl_link_encoder *hpo_frl_link_enc;
+       struct dc_hdmi_frl_link_settings frl_reported_link_cap;
+       struct dc_hdmi_frl_link_settings frl_verified_link_cap;
+       struct dc_hdmi_frl_link_settings frl_link_settings;
+       struct dc_hdmi_frl_flags frl_flags;
+       union hdmi_idcc_cable_id hdmi_cable_id;
        struct graphics_object_id link_id;
 
        /* External encoder eg. NUTMEG or TRAVIS used on CIK APUs. */
@@ -2071,6 +2139,17 @@ struct dc_plane_state *dc_get_surface_for_mpcc(struct dc 
*dc,
 
 
 uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane);
+bool dc_set_fva_vrr_adjust(struct dc *dc,
+       struct dc_stream_state *stream,
+       struct fva_adj *fva_adj,
+       struct dc_crtc_timing_adjust *vrr_adj);
+
+int dc_get_hw_max_fva_factor(struct dc *dc,
+               struct dc_stream_state *stream,
+               unsigned int max_pixel_clock);
+
+void dc_set_vstartup_start(struct dc *dc,
+               struct dc_stream_state *stream);
 
 void dc_set_disable_128b_132b_stream_overhead(bool disable);
 
@@ -2282,6 +2361,12 @@ enum dc_status dc_link_dp_read_hpd_rx_irq_data(
        struct dc_link *link,
        union hpd_irq_data *irq_data);
 
+bool dc_link_frl_poll_status_flag(struct dc_link *link);
+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);
+
 /* The function clears recorded DP RX states in the link. DM should call this
  * function when it is resuming from S3 power state to previously connected 
links.
  *
@@ -2306,6 +2391,12 @@ uint32_t dc_link_bandwidth_kbps(
        const struct dc_link *link,
        const struct dc_link_settings *link_setting);
 
+/* The function returns effective HDMI FRL bandwidth given link rate.
+ * return - total effective link bandwidth in kbps.
+ */
+uint32_t dc_link_frl_bandwidth_kbps(const struct dc_link *link,
+               enum hdmi_frl_link_rate link_rate);
+
 struct dp_audio_bandwidth_params {
        const struct dc_crtc_timing *crtc_timing;
        enum dp_link_encoding link_encoding;
@@ -2357,6 +2448,8 @@ void dc_get_cur_link_res_map(const struct dc *dc, 
uint32_t *map);
  */
 void dc_restore_link_res_map(const struct dc *dc, uint32_t *map);
 
+void dc_link_wait_for_unlocked(struct dc_link *link);
+
 /* TODO: this is not meant to be exposed to DM. Should switch to stream update
  * interface i.e stream_update->dsc_config
  */
@@ -2410,6 +2503,16 @@ const struct dc_link_settings 
*dc_link_get_link_cap(const struct dc_link *link);
  */
 enum dc_link_encoding_format dc_link_get_highest_encoding_format(const struct 
dc_link *link);
 
+/* get max frl link settings the link can enable with all things considered.
+ * (i.e TX/RX capabilities and link verification result.
+ *
+ * @link - a link with FRL RX connection
+ * return - max frl link settings the link can enable.
+ *
+ */
+struct dc_hdmi_frl_link_settings *dc_link_get_frl_link_cap(
+               struct dc_link *link);
+
 /* Check if a RX (ex. DP sink, MST hub, passive or active dongle) is connected
  * to a link with dp connector signal type.
  * @link - a link with dp connector signal type
@@ -2459,6 +2562,16 @@ void dc_link_set_preferred_link_settings(struct dc *dc,
                struct dc_link_settings *link_setting,
                struct dc_link *link);
 
+/* Force FRL link settings to always use a specific value until reboot to a
+ * specific link. If link has already been enabled, the interface will also
+ * switch to desired link settings immediately. This is a debug interface to
+ * generic FRL issue trouble shooting.
+ */
+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);
+
 /* Force DP link to customize a specific link training behavior by overriding 
to
  * standard DP specs defined protocol. This is a debug interface to trouble 
shoot
  * display specific link training issues or apply some display specific
@@ -3132,6 +3245,14 @@ struct dc_register_software_state {
                uint32_t symclk32_le_enable[2];          /* 
SYMCLK32_LE_CNTL->SYMCLK32_LE0_EN from dccg31_enable_symclk32_le() enable */
                uint32_t symclk32_le_gate_disable[2];    /* 
DCCG_GATE_DISABLE_CNTL3->SYMCLK32_LE0_GATE_DISABLE from 
debug.root_clock_optimization.bits.symclk32_le */
 
+               /* HDMI Clock Control */
+               uint32_t hdmicharclk_enable;             /* 
HDMICHARCLK0_CLOCK_CNTL->HDMICHARCLK0_EN from dccg31_enable_hdmicharclk() */
+               uint32_t hdmicharclk_src_sel;            /* 
HDMICHARCLK0_CLOCK_CNTL->HDMICHARCLK0_SRC_SEL from dccg31_enable_hdmicharclk() 
phypll_inst source */
+               uint32_t hdmistreamclk_src_sel;          /* 
HDMISTREAMCLK_CNTL->HDMISTREAMCLK0_SRC_SEL from dccg31_set_hdmistreamclk() src 
selection */
+               uint32_t hdmistreamclk_dto_force_dis;    /* 
HDMISTREAMCLK_CNTL->HDMISTREAMCLK0_DTO_FORCE_DIS from 
dccg31_set_hdmistreamclk() DTO force bypass */
+               uint32_t hdmistreamclk_dto_phase;        /* 
HDMISTREAMCLK0_DTO_PARAM->HDMISTREAMCLK0_DTO_PHASE from 
dccg31_disable_hdmistreamclk() */
+               uint32_t hdmistreamclk_dto_modulo;       /* 
HDMISTREAMCLK0_DTO_PARAM->HDMISTREAMCLK0_DTO_MODULO from 
dccg31_disable_hdmistreamclk() */
+
                /* DPIA Clock Control */
                uint32_t dpiaclk_540m_dto_modulo;        /* 
DPIACLK_540M_DTO_MODULO->DPIA 540MHz DTO modulo */
                uint32_t dpiaclk_540m_dto_phase;         /* 
DPIACLK_540M_DTO_PHASE->DPIA 540MHz DTO phase */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h
index fcd3ab4b0045..afd21eb6bbcd 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h
@@ -65,19 +65,65 @@ struct dp_hdmi_dongle_signature_data {
 #define HDMI_SCDC_CONFIG_1 0x31
 #define HDMI_SCDC_SOURCE_TEST_REQ 0x35
 #define HDMI_SCDC_STATUS_FLAGS 0x40
+#define HDMI_SCDC_LTP_REQ 0x41
 #define HDMI_SCDC_ERR_DETECT 0x50
 #define HDMI_SCDC_TEST_CONFIG 0xC0
 
 #define HDMI_SCDC_MANUFACTURER_OUI 0xD0
 #define HDMI_SCDC_DEVICE_ID 0xDB
 
+/* IDCC defines (HDMI 2.0) */
+#define HDMI_IDCC_ADDRESS 0x50
+#define HDMI_IDCC_MARKER0 0xAE
+#define HDMI_IDCC_MARKER1 0x6E
+#define HDMI_IDCC_MARKER2 0x60
+
+enum hdmi_idcc_scope {
+       HDMI_IDCC_SCOPE_WRITE = 0x00,
+       HDMI_IDCC_SCOPE_RW_CA = 0x01,
+       HDMI_IDCC_SCOPE_RW_SINK = 0x02,
+};
+
+union hdmi_idcc_source_id {
+       struct {
+               uint8_t SI_PCA_n:1;
+               uint8_t AC_n:1;
+               uint8_t RESERVED:6;
+       } bits;
+       uint8_t raw;
+};
+
+union hdmi_idcc_cable_id {
+       struct {
+               uint8_t Cat1_n:1;
+               uint8_t Cat2_n:1;
+               uint8_t Cat3_n:1;
+               uint8_t Cat4_n:1;
+               uint8_t RESERVED:4;
+               uint8_t HEAC_n:1;
+               uint8_t PCA_DEP_n:1;
+               uint8_t MonoDir_n:1;
+               uint8_t MonoDirErr_n:1;
+               uint8_t PCA_ON_n:1;
+               uint8_t no_DeEmphasis_n:1;
+               uint8_t no_PreShoot_n:1;
+               uint8_t RESERVED2:1;
+               uint8_t RND_bits_7_0:8;
+               uint8_t RND_bits_15_8:8;
+       } bits;
+       uint8_t raw[4];
+};
 union hdmi_scdc_update_read_data {
        uint8_t byte[2];
        struct {
                uint8_t STATUS_UPDATE:1;
                uint8_t CED_UPDATE:1;
                uint8_t RR_TEST:1;
-               uint8_t RESERVED:5;
+               uint8_t SOURCE_TEST_UPDATE:1;
+               uint8_t FRL_START:1;
+               uint8_t FLT_UPDATE:1;
+               uint8_t RSED_UPDATE:1;
+               uint8_t RESERVED:1;
                uint8_t RESERVED2:8;
        } fields;
 };
@@ -89,7 +135,19 @@ union hdmi_scdc_status_flags_data {
                uint8_t CH0_LOCKED:1;
                uint8_t CH1_LOCKED:1;
                uint8_t CH2_LOCKED:1;
-               uint8_t RESERVED:4;
+               uint8_t LANE3_LOCKED:1;
+               uint8_t RESERVED:1;
+               uint8_t FLT_READY:1;
+       } fields;
+};
+
+union hdmi_scdc_LTP_req_data {
+       uint8_t byte[2];
+       struct {
+               uint8_t LN0_LTP_REQ:4;
+               uint8_t LN1_LTP_REQ:4;
+               uint8_t LN2_LTP_REQ:4;
+               uint8_t LN3_LTP_REQ:4;
        } fields;
 };
 
@@ -106,10 +164,12 @@ union hdmi_scdc_ced_data {
                uint8_t CH2_7HIGH:7;
                uint8_t CH2_VALID:1;
                uint8_t CHECKSUM:8;
-               uint8_t RESERVED:8;
-               uint8_t RESERVED2:8;
-               uint8_t RESERVED3:8;
-               uint8_t RESERVED4:4;
+               uint8_t LN3_8LOW:8;
+               uint8_t LN3_7HIGH:7;
+               uint8_t LN3_VALID:1;
+               uint8_t RSC_8LOW:8;
+               uint8_t RSC_7HIGH:7;
+               uint8_t RSC_VALID:1;
        } fields;
 };
 
@@ -130,4 +190,94 @@ union hdmi_scdc_device_id_data {
        } fields;
 };
 
+union hdmi_scdc_configuration {
+       uint8_t byte[2];
+       struct {
+               uint8_t RR_ENABLE:1;
+               uint8_t FLT_NO_RETRAIN:1;
+               uint8_t RESERVED:6;
+               uint8_t FRL_RATE:4;
+               uint8_t FFE_LEVELS:4;
+       } fields;
+};
+
+union hdmi_scdc_source_test_req {
+       uint8_t byte;
+       struct {
+               uint8_t RESERVED:1;
+               uint8_t TXFFE_PRESHOOT:1;
+               uint8_t TXFFE_DEEMPHASIS:1;
+               uint8_t TXFFE_NOFFE:1;
+               uint8_t RESERVED2:1;
+               uint8_t FLT_NO_TIMEOUT:1;
+               uint8_t DSC_FRL_MAX:1;
+               uint8_t FRL_MAX:1;
+       } fields;
+};
+
+union hdmi_scdc_test_config_Data {
+       uint8_t byte;
+       struct {
+               uint8_t TEST_READ_REQUEST_DELAY:7;
+               uint8_t TEST_READ_REQUEST: 1;
+       } fields;
+};
+
+enum hdmi_frl_borrow_mode {
+       BORROW_MODE_NONE,
+       BORROW_MODE_FROM_ACTIVE,
+       BORROW_MODE_FROM_BLANK
+};
+
+enum link_result {
+       LINK_RESULT_UNKNOWN = 0,
+       LINK_RESULT_SUCCESS,
+       LINK_RESULT_LOWER_LINKRATE,
+       LINK_RESULT_TIMEOUT,
+       LINK_RESULT_FALLBACK
+};
+
+enum hdmi_frl_link_rate {
+       HDMI_FRL_LINK_RATE_DISABLE = 0,
+       HDMI_FRL_LINK_RATE_3GBPS,
+       HDMI_FRL_LINK_RATE_6GBPS,
+       HDMI_FRL_LINK_RATE_6GBPS_4LANE,
+       HDMI_FRL_LINK_RATE_8GBPS,
+       HDMI_FRL_LINK_RATE_10GBPS,
+       HDMI_FRL_LINK_RATE_12GBPS,
+       HDMI_FRL_LINK_RATE_16GBPS,
+       HDMI_FRL_LINK_RATE_20GBPS,
+       HDMI_FRL_LINK_RATE_24GBPS
+};
+
+struct frl_borrow_params {
+       int audio_packets_line;
+       int hc_active_target;
+       int hc_blank_target;
+       enum hdmi_frl_borrow_mode borrow_mode;
+};
+
+struct dc_hdmi_frl_link_settings {
+       enum hdmi_frl_link_rate frl_link_rate;
+       uint8_t frl_num_lanes;
+       struct frl_borrow_params borrow_params;
+       int average_tribyte_rate;
+};
+
+struct dc_hdmi_frl_flags {
+       int  force_frl_rate;
+       bool ignore_ffe;
+       int  select_ffe;
+       int  limit_ffe;
+       bool force_frl_always;
+       bool force_frl_max;
+       bool apply_vsdb_rcc_wa;
+};
+
+struct dc_hdmi_frl_link_training_overrides {
+       bool force_frl_always;
+       bool force_frl_max;
+       uint8_t max_retries;
+       bool valid;
+};
 #endif /* DC_HDMI_TYPES_H */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index c2ca08d26e37..c13a824c9d35 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -886,6 +886,8 @@ struct dc_dsc_config {
        bool ycbcr422_simple; /* Tell DSC engine to convert YCbCr 4:2:2 to 
'YCbCr 4:2:2 simple'. */
        int32_t rc_buffer_size; /* DSC RC buffer block size in bytes */
        bool is_frl; /* indicate if DSC is applied based on HDMI FRL sink's 
capability */
+       bool is_vic_all_bpp; /* indicate of DSC_ALL_BPP = 1 */
+       uint32_t total_chunk_kbytes; /* total chunk kbytes in EDID */
        bool is_dp; /* indicate if DSC is applied based on DP's capability */
        uint32_t mst_pbn; /* pbn of display on dsc mst hub */
        const struct dc_dsc_rc_params_override *rc_params_ovrd; /* DM owned 
memory. If not NULL, apply custom dsc rc params */
@@ -1162,6 +1164,12 @@ struct tg_color {
        uint16_t color_b_cb;
 };
 
+struct fva_adj {
+       unsigned int pixel_clock_100hz;
+       unsigned int max_pixel_clock_100hz;
+       unsigned int fva_factor;
+};
+
 enum symclk_state {
        SYMCLK_OFF_TX_OFF,
        SYMCLK_ON_TX_ON,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 476db257d4ee..be2c9f754d52 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -77,6 +77,7 @@ struct dc_perf_trace {
 };
 
 #define NUM_PIXEL_FORMATS 10
+#define DTBCLK_LIMIT 2920
 
 enum tiling_mode {
        TILING_MODE_INVALID,
@@ -174,6 +175,14 @@ struct dc_panel_patch {
        unsigned int max_dsc_target_bpp_limit;
        unsigned int embedded_tiled_slave;
        unsigned int disable_fams;
+       unsigned int hdmi_spe_handling;
+       unsigned int block_420_Freesync;
+       unsigned int block_10g;
+       unsigned int hdmi_comp_manual;
+       unsigned int hdmi_comp_auto;
+       unsigned int force_frl;
+       unsigned int vsdb_rcc_wa;
+       unsigned int delay_hdmi_link_training;
        unsigned int skip_avmute;
        unsigned int skip_audio_sab_check;
        unsigned int mst_start_top_delay;
@@ -221,6 +230,17 @@ struct dc_edid_caps {
        bool scdc_present;
        bool analog;
 
+       /*HDMI 2.1 caps*/
+       uint8_t max_frl_rate;
+       bool frl_dsc_support;
+       bool frl_dsc_10bpc;
+       bool frl_dsc_12bpc;
+       bool frl_dsc_all_bpp;
+       bool frl_dsc_native_420;
+       uint8_t frl_dsc_max_slices;
+       uint8_t frl_dsc_max_frl_rate;
+       uint8_t frl_dsc_total_chunk_kbytes;
+
        struct dc_panel_patch panel_patch;
 };
 
@@ -545,6 +565,7 @@ struct audio_info {
 struct audio_check {
        unsigned int audio_packet_type;
        unsigned int max_audiosample_rate;
+       unsigned int max_channel_count;
        unsigned int acat;
 };
 enum dc_infoframe_type {
@@ -929,6 +950,9 @@ struct dsc_dec_dpcd_caps {
        uint32_t branch_overall_throughput_0_mps; /* In MPs */
        uint32_t branch_overall_throughput_1_mps; /* In MPs */
        uint32_t branch_max_line_width;
+       bool is_frl; /* Decoded format */
+       bool is_vic_all_bpp;
+       uint32_t total_chunk_kbytes;
        bool is_dp; /* Decoded format */
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h 
b/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h
index f4d3f04ec857..cb20bfe9c1c8 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h
@@ -41,6 +41,7 @@ struct cp_psp_stream_config {
        uint8_t phy_idx;
        uint8_t assr_enabled;
        uint8_t mst_enabled;
+       uint8_t frl_enabled;
        uint8_t dp2_enabled;
        uint8_t usb4_enabled;
        void *dm_stream_ctx;
diff --git a/drivers/gpu/drm/amd/display/dc/dm_services_types.h 
b/drivers/gpu/drm/amd/display/dc/dm_services_types.h
index 3b093b8699ab..e676e395cabf 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_services_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_services_types.h
@@ -292,6 +292,7 @@ struct dm_process_phy_transition_init_params {
        enum dc_link_rate display_port_link_rate;
        uint32_t transition_bitmask;
        uint8_t hdmi_frl_num_lanes;
+       enum hdmi_frl_link_rate hdmi_frl_link_rate;
 };
 
 struct dm_process_phy_transition_input_params {
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_frl_cap_chk.h 
b/drivers/gpu/drm/amd/display/dc/dml/dml1_frl_cap_chk.h
new file mode 100644
index 000000000000..debe4c1dc0f7
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_frl_cap_chk.h
@@ -0,0 +1,173 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DML1_FRL_CAP_CHK_H__
+#define __DML1_FRL_CAP_CHK_H__
+
+#include "os_types.h"
+
+#define TB_BORROWED_MAX          400
+#define C_FRL_CB         510
+#define TOLERANCE_FRL_BIT 300    /* ppm */
+#define ACR_RATE_MAX     1500
+
+enum hdmi_frl_pixel_encoding {
+       HDMI_FRL_PIXEL_ENCODING_444,
+       HDMI_FRL_PIXEL_ENCODING_422,
+       HDMI_FRL_PIXEL_ENCODING_420
+};
+
+enum frl_cap_chk_result {
+       FRL_CAP_CHK_OK = 0,
+
+       FRL_CAP_CHK_ERROR_AUDIO_BW   = -1,
+       FRL_CAP_CHK_ERROR_BORROW     = -2,
+       FRL_CAP_CHK_ERROR_MAX_BORROW = -3,
+       FRL_CAP_CHK_ERROR_MARGIN     = -4,
+
+       FRL_CAP_CHK_ERROR_UNSUPPORTED_AUDIO = -1000
+};
+
+enum frl_borrow_mode {
+       FRL_BORROW_MODE_NONE,
+       FRL_BORROW_MODE_FROM_ACTIVE,
+       FRL_BORROW_MODE_FROM_BLANK
+};
+
+enum frl_link_rate {
+       FRL_LINK_RATE_DISABLE = 0,
+       FRL_LINK_RATE_3GBPS,
+       FRL_LINK_RATE_6GBPS,
+       FRL_LINK_RATE_6GBPS_4LANE,
+       FRL_LINK_RATE_8GBPS,
+       FRL_LINK_RATE_10GBPS,
+       FRL_LINK_RATE_12GBPS,
+       FRL_LINK_RATE_16GBPS,
+       FRL_LINK_RATE_20GBPS,
+       FRL_LINK_RATE_24GBPS
+};
+
+struct frl_dml_borrow_params {
+       int audio_packets_line;
+       int hc_active_target;
+       int hc_blank_target;
+       enum frl_borrow_mode borrow_mode;
+};
+
+struct frl_primary_format {
+       uint32_t vic;
+       uint32_t frl_rate;
+       uint32_t frl_lanes;
+       uint32_t hc_active;
+       uint32_t hc_blank;
+};
+
+struct frl_cap_chk_intermediates {
+       int      c_frl_sb;
+       double   overhead_sb;
+       double   overhead_rs;
+       double   overhead_map;
+       double   overhead_min;
+       double   overhead_max;
+       double   f_pixel_clock_max;
+       double   t_line;
+       double   r_bit_min;
+       double   r_frl_char_min;
+       double   c_frl_line;
+       double   ap;
+       double   r_ap;
+       double   avg_audio_packets_line;
+       int      audio_packets_line;
+       int      blank_audio_min;
+};
+
+struct frl_cap_chk_params {
+       int      lanes;
+       double   f_pixel_clock_nominal;   /* Pixel Clock rate (Hz)  */
+       double   r_bit_nominal;           /* FRL bitrate (bps) */
+       int      audio_packet_type;
+       double   f_audio;                 /* Audio rate (Hz) */
+       int      h_active;                /* Active pixels per line */
+       int      h_blank;                 /* Blanking pixels per line */
+       int      bpc;                     /* Bits per component */
+       int      vic;                     /* Video Identification Code */
+
+       enum hdmi_frl_pixel_encoding    pixel_encoding;
+
+       bool     compressed;              /* set to true if DSC is enabled */
+       bool     bypass_hc_target_calc;   /* debug only */
+       bool     allow_all_bpp;           /* dsc_all_bpp */
+
+       /* DSC parameters */
+       int      slices;
+       int      slice_width;
+       double   bpp_target;
+       bool     is_ovt;
+       int      layout;
+       int      acat;    /* not supported */
+
+       /* outputs */
+       struct frl_dml_borrow_params borrow_params;
+       int      average_tribyte_rate;
+};
+
+enum frl_cap_chk_result dml1_frl_cap_chk(struct frl_cap_chk_params *params);
+
+enum frl_cap_chk_result dml1_frl_cap_chk_inter(struct frl_cap_chk_params 
*params,
+                                              struct frl_cap_chk_intermediates 
*inter);
+
+enum frl_cap_chk_result dml1_frl_cap_chk_common(struct 
frl_cap_chk_intermediates *inter,
+                                               struct frl_cap_chk_params 
*params);
+
+enum frl_cap_chk_result dml1_frl_cap_chk_uncompressed(struct 
frl_cap_chk_params *params,
+                                                     struct 
frl_cap_chk_intermediates *inter);
+
+enum frl_cap_chk_result dml1_frl_cap_chk_compressed(struct frl_cap_chk_params 
*params,
+                                                   struct 
frl_cap_chk_intermediates *inter);
+#endif
+
+void frl_modified_pix_clock_for_dsc_padding(const int hc_active_target,
+       const int hc_blank_target,
+       const uint8_t frl_num_lanes,
+       const uint32_t pix_clk_100hz,
+       const int frl_link_rate,
+       const uint32_t h_addressable,
+       const uint32_t h_border_left,
+       const uint32_t h_border_right,
+       const uint32_t h_total,
+       const uint32_t h_addressable_otg,
+       uint32_t *pix_clk_100hz_otg,
+       uint32_t *h_total_otg);
+
+int frl_modify_borrow_mode_for_dsc_padding(const uint32_t pix_clk_100hz,
+       const uint32_t h_active,
+       const uint32_t h_active_padded,
+       const uint32_t h_blank,
+       const uint32_t h_blank_padded,
+       const int hc_active,
+       const int hc_blank,
+       const uint8_t frl_num_lanes,
+       const int frl_link_rate);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_status.h 
b/drivers/gpu/drm/amd/display/dc/inc/core_status.h
index 82085d9c3f40..388f801f4582 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_status.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_status.h
@@ -48,6 +48,8 @@ enum dc_status {
        DC_FAIL_DSC_VALIDATE = 16,
        DC_NO_DSC_RESOURCE = 17,
        DC_FAIL_UNSUPPORTED_1 = 18,
+       DC_FAIL_HDMI_FRL_LINK_TRAINING = 19,
+       DC_NO_HDMI_FRL_LINK_BANDWIDTH = 20,
        DC_FAIL_CLK_EXCEED_MAX = 21,
        DC_FAIL_CLK_BELOW_MIN = 22, /*THIS IS MIN PER IP*/
        DC_FAIL_CLK_BELOW_CFG_REQUIRED = 23, /*THIS IS hard_min in PPLIB*/
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h 
b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index e960ca9062ad..ac33fa6c8da4 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -82,6 +82,9 @@ struct resource_funcs {
        /* Create a minimal link encoder object with no dc_link object
         * associated with it. */
        struct link_encoder *(*link_enc_create_minimal)(struct dc_context *ctx, 
enum engine_id eng_id);
+       struct hpo_frl_link_encoder *(*hpo_frl_link_enc_create)(
+                       enum engine_id eng_id,
+                       struct dc_context *ctx);
        enum dc_status (*validate_bandwidth)(
                                        struct dc *dc,
                                        struct dc_state *context,
@@ -285,6 +288,10 @@ struct resource_pool {
        /* Number of USB4 DPIA (DisplayPort Input Adapter) link objects 
created.*/
        unsigned int usb4_dpia_count;
 
+       unsigned int hpo_frl_stream_enc_count;
+       struct hpo_frl_stream_encoder 
*hpo_frl_stream_enc[MAX_HDMI_FRL_ENCODERS];
+       unsigned int hpo_frl_link_enc_count;
+       struct hpo_frl_link_encoder *hpo_frl_link_enc[MAX_HDMI_FRL_ENCODERS];
        unsigned int hpo_dp_stream_enc_count;
        struct hpo_dp_stream_encoder *hpo_dp_stream_enc[MAX_HPO_DP2_ENCODERS];
        unsigned int hpo_dp_link_enc_count;
@@ -351,6 +358,7 @@ struct stream_resource {
        struct display_stream_compressor *dsc;
        struct timing_generator *tg;
        struct stream_encoder *stream_enc;
+       struct hpo_frl_stream_encoder *hpo_frl_stream_enc;
        struct hpo_dp_stream_encoder *hpo_dp_stream_enc;
        struct audio *audio;
 
@@ -394,6 +402,7 @@ struct plane_resource {
 struct link_resource {
        struct link_encoder *dio_link_enc;
        struct hpo_dp_link_encoder *hpo_dp_link_enc;
+       struct hpo_frl_link_encoder *hpo_frl_link_enc;
 };
 
 struct link_config {
@@ -531,6 +540,9 @@ struct resource_context {
        struct link_enc_cfg_context link_enc_cfg_ctx;
        unsigned int dio_link_enc_to_link_idx[MAX_LINK_ENCODERS];
        int dio_link_enc_ref_cnts[MAX_LINK_ENCODERS];
+       bool is_hpo_frl_stream_enc_acquired[MAX_HDMI_FRL_ENCODERS];
+       unsigned int hpo_frl_link_enc_to_link_idx[MAX_HDMI_FRL_ENCODERS];
+       int hpo_frl_link_enc_ref_cnts[MAX_HDMI_FRL_ENCODERS];
        bool is_hpo_dp_stream_enc_acquired[MAX_HPO_DP2_ENCODERS];
        unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS];
        int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS];
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
index d6f5e01a0b66..6db7c8753081 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
@@ -228,6 +228,16 @@ struct dccg_funcs {
        void (*allow_clock_gating)(struct dccg *dccg, bool allow);
        void (*enable_memory_low_power)(struct dccg *dccg, bool enable);
        bool (*is_s0i3_golden_init_wa_done)(struct dccg *dccg);
+       void (*enable_hdmicharclk)(struct dccg *dccg, int hpo_inst, int 
phypll_inst);
+       void (*disable_hdmicharclk)(struct dccg *dccg, int hpo_inst);
+       void (*set_hdmistreamclk)(
+                       struct dccg *dccg,
+                       enum streamclk_source src,
+                       uint32_t otg_inst);
+
+       void (*set_hdmistreamclk_root_clock_gating)(
+                       struct dccg *dccg,
+                       bool enable);
        void (*set_dpstreamclk_root_clock_gating)(
                        struct dccg *dccg,
                        int dp_hpo_inst,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
index 51581c10fd6b..176d048a64e7 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
@@ -76,6 +76,7 @@
 #define MAX_LINK_ENCODERS (MAX_DIG_LINK_ENCODERS + MAX_DAC_LINK_ENCODERS)
 
 #define MAX_DWB_PIPES  1
+#define MAX_HDMI_FRL_ENCODERS  2
 #define MAX_HPO_DP2_ENCODERS   4
 #define MAX_HPO_DP2_LINK_ENCODERS      4
 
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
index 5abbf485d273..e7727ed3300c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -67,6 +67,13 @@ struct encoder_feature_support {
                        uint32_t IS_UHBR13_5_CAPABLE:1;
                        uint32_t IS_UHBR20_CAPABLE:1;
                        uint32_t DP_IS_USB_C:1;
+                       uint32_t IS_HDMI_FRL_CAPABLE:1;
+                       uint32_t IS_FRL_8G_CAPABLE:1;
+                       uint32_t IS_FRL_10G_CAPABLE:1;
+                       uint32_t IS_FRL_12G_CAPABLE:1;
+                       uint32_t IS_FRL_16G_CAPABLE:1;
+                       uint32_t IS_FRL_20G_CAPABLE:1;
+                       uint32_t IS_FRL_24G_CAPABLE:1;
                } bits;
                uint32_t raw;
        } flags;
@@ -78,6 +85,11 @@ struct encoder_feature_support {
        bool fec_supported;
 };
 
+enum phy_source_select {
+       PHY_SOURCE_DIG,
+       PHY_SOURCE_HPO
+};
+
 struct link_encoder {
        const struct link_encoder_funcs *funcs;
        int32_t aux_channel_offset;
@@ -93,6 +105,7 @@ struct link_encoder {
        struct gpio *hpd_gpio;
        enum hpd_source_id hpd_source;
        bool usbc_combo_phy;
+       uint8_t txffe_state;
 };
 
 struct link_enc_state {
@@ -104,6 +117,12 @@ struct link_enc_state {
 
 };
 
+struct frl_txffe {
+       uint32_t   amplitude[4];
+       uint32_t   pre_emphasis[4];
+       uint32_t   post_emphasis[4];
+};
+
 enum encoder_type_select {
        ENCODER_TYPE_DIG = 0,
        ENCODER_TYPE_HDMI_FRL = 1,
@@ -172,6 +191,43 @@ struct link_encoder_funcs {
        enum signal_type (*get_dig_mode)(
                struct link_encoder *enc);
 
+       void (*dpcstx_set_order_invert_18_bit)(
+               struct link_encoder *enc,
+               bool invert);
+
+       void (*set_phy_source)(
+               struct link_encoder *enc,
+               enum phy_source_select src_sel,
+               uint32_t hpo_inst);
+
+       void (*dpcs_initialize_phy)(
+               struct link_encoder *enc,
+               uint32_t hpo_inst,
+               enum hdmi_frl_link_rate frl_link_rate);
+
+       void (*dpcs_configure_phypll)(
+               struct link_encoder *enc,
+               uint32_t hpo_inst,
+               enum hdmi_frl_link_rate frl_link_rate);
+
+       void (*dpcs_configure_dpcs)(
+               struct link_encoder *enc);
+
+       void (*dpcs_enable_dpcs)(
+               struct link_encoder *enc);
+       void (*prog_eq_setting)(
+               struct link_encoder *enc,
+               uint8_t FFE_Level,
+               bool de_emphasis_only,
+               bool pre_shoot_only,
+               bool no_ffe,
+               const struct dc_hdmi_frl_link_settings *link_settings);
+       void (*get_txffe)(
+               struct link_encoder *enc,
+               struct frl_txffe *lane_settings);
+       void (*set_txffe)(
+               struct link_encoder *enc,
+               struct frl_txffe *lane_settings);
        void (*set_dio_phy_mux)(
                struct link_encoder *enc,
                enum encoder_type_select sel,
@@ -207,6 +263,126 @@ enum link_enc_cfg_mode {
        LINK_ENC_CFG_TRANSIENT /* During commit state - use state to be 
committed. */
 };
 
+struct hpo_frl_link_encoder {
+       const struct hpo_frl_link_encoder_funcs *funcs;
+       struct dc_context *ctx;
+       int inst;
+};
+
+/**
+ * @hpo_frl_link_enc_state - FRL data from the device
+ *
+ * This struct is used to store FRL information retrieved from the hardware.
+ * This is used as a parameter for the read_state function.
+ */
+struct hpo_frl_link_enc_state {
+       /**
+        * @link_enc_enabled: 0 means disable and 1 enabled.
+        */
+       uint32_t link_enc_enabled;
+
+       /**
+        * @link_active:
+        *
+        * If link training is enable this field should be set to 1.
+        */
+       uint32_t link_active;
+
+       /**
+        * @lane_count: FRL lane count.
+        */
+       uint32_t lane_count;
+};
+
+/***
+ * @hpo_frl_link_encoder_funcs - FRL encoder functions
+ *
+ * DC handles FRL as an encoder; each ASIC may have some peculiarities in
+ * setting FRL. Thus, this struct, adds all the necessary callbacks that each
+ * DCN version must implement.
+ */
+struct hpo_frl_link_encoder_funcs {
+       /**
+        * @setup_link_encoder:
+        *
+        * This function is responsible for setup the ASIC to use FRL, i.e., it
+        * contains a register configuration. This function implementation
+        * expects the enablement of the link clock, lane count configuration,
+        * any reset/cleanup, and, finally, the enablement of the link.
+        */
+       void (*setup_link_encoder)(struct hpo_frl_link_encoder *enc,
+                                  int lane_count);
+
+       /**
+        * @disable_link_encoder:
+        *
+        * Disable the FRL link. Note that this function must do the reverse of
+        * the setup_link_encoder.
+        */
+       void (*disable_link_encoder)(struct hpo_frl_link_encoder *enc);
+
+       /**
+        * @set_hdmi_training_pattern:
+        *
+        * Register level configuration for each lane.
+        */
+       void (*set_hdmi_training_pattern)(struct hpo_frl_link_encoder *enc,
+                                         uint32_t lane0_pattern,
+                                         uint32_t lane1_pattern,
+                                         uint32_t lane2_pattern,
+                                         uint32_t lane3_pattern);
+
+       /**
+        * @get_hdmi_training_pattern:
+        *
+        * Retrieve from the registers each of the lane pattern configurations.
+        */
+       void (*get_hdmi_training_pattern)(struct hpo_frl_link_encoder *enc,
+                                         uint32_t *lane0_pattern,
+                                         uint32_t *lane1_pattern,
+                                         uint32_t *lane2_pattern,
+                                         uint32_t *lane3_pattern);
+
+       /**
+        * @enable_frl_phy_output:
+        *
+        * Based on the parameters, this function should fill out the
+        * bp_transmitter_control struct and use it to enable the FRL PHY link
+        * via VBIOS.
+        */
+       void (*enable_frl_phy_output)(struct hpo_frl_link_encoder *hpo_enc,
+                                     struct link_encoder *enc,
+                                     enum clock_source_id clock_source,
+                                     enum hdmi_frl_link_rate frl_link_rate);
+
+       /**
+        * @enable_output:
+        *
+        * Enable FRL by sending the enable packet training.
+        */
+       void (*enable_output)(struct hpo_frl_link_encoder *enc);
+
+       /**
+        * @read_state:
+        *
+        * Get the FRL information from registers and fill it out in the
+        * hpo_frl_link_enc_state struct.
+        */
+       void (*read_state)(struct hpo_frl_link_encoder *enc,
+                          struct hpo_frl_link_enc_state *state);
+
+       /**
+        * @destroy:
+        *
+        * Destroy encoder object.
+        */
+       void (*destroy)(struct hpo_frl_link_encoder **enc);
+
+       void (*apply_vsdb_rcc_wa)(
+               struct hpo_frl_link_encoder *enc);
+
+};
+
 enum dp2_link_mode {
        DP2_LINK_TRAINING_TPS1,
        DP2_LINK_TRAINING_TPS2,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
index 27f950ae45ee..1800b1929b16 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
@@ -71,6 +71,16 @@ enum dynamic_metadata_mode {
        dmdata_dolby_vision
 };
 
+struct frl_audio_clock_info {
+       uint32_t frl_character_clock_kHz;
+       uint32_t n_32khz;
+       uint32_t cts_32khz;
+       uint32_t n_44khz;
+       uint32_t cts_44khz;
+       uint32_t n_48khz;
+       uint32_t cts_48khz;
+};
+
 struct enc_sdp_line_num {
        /* Adaptive Sync SDP */
        bool adaptive_sync_line_num_valid;
@@ -277,6 +287,223 @@ struct stream_encoder_funcs {
        uint32_t (*get_pixels_per_cycle)(struct stream_encoder *enc);
 };
 
+/**
+ * @hpo_frl_stream_encoder_state - Stream encoder parameters
+ */
+struct hpo_frl_stream_encoder_state {
+       uint32_t stream_enc_enabled;
+       uint32_t otg_inst;
+       uint32_t color_depth;
+       uint32_t num_odm_segments;
+       uint32_t h_active;
+       uint32_t h_blank;
+       uint32_t borrow_mode;
+       enum dc_pixel_encoding pixel_format;
+};
+
+/**
+ * @hpo_frl_stream_encoder - Encoder stream instance
+ *
+ * This struct keeps the reference to the struct with the FRL stream encoder
+ * callbacks. Additionally, it has other references that simplify the stream
+ * configuration.
+ */
+struct hpo_frl_stream_encoder {
+       /**
+        * @funcs: callback functions for using FRL stream encoder.
+        */
+       const struct hpo_frl_stream_encoder_funcs *funcs;
+
+       /**
+        * @stream_enc_inst: Instance ID reference.
+        */
+       uint32_t stream_enc_inst;
+
+       /**
+        * @ctx: DC context.
+        */
+       struct dc_context *ctx;
+
+       /**
+        * @bp: Bios parser reference.
+        */
+       struct dc_bios *bp;
+
+       /**
+        * @id: ID to the Engine object type.
+        */
+       enum engine_id id;
+
+       /**
+        * @afmt:
+        *
+        * Audio Formatter (AFMT) reference used for select the correct audio
+        * reference.
+        */
+       struct afmt *afmt;
+
+       /**
+        * @vpg:
+        *
+        * The VBI Packet Generator (VPG) reference which is used for
+        * generating the HDMI data island packet headers for ISRC1 and generic
+        * packages.
+        */
+       struct vpg *vpg;
+
+       /**
+        * @afmt:
+        *
+        * Audio Pattern Generator (APG) reference used for select the correct 
audio
+        * reference.
+        */
+       struct apg *apg;
+};
+
+/**
+ * @hpo_frl_stream_encoder_funcs - FRL stream encoder functions callbacks
+ *
+ * DC must set up the FRL encoder and the stream encoder; however, each ASIC
+ * may have some quirks in setting FRL. Thus, this struct, adds all the encoder
+ * stream interfaces for setup the FRL stream encoder.
+ */
+struct hpo_frl_stream_encoder_funcs {
+       /**
+        * @hdmi_frl_enable:
+        *
+        * This callback initializes a new FRL stream by enabling HDMI Dispclk,
+        * SOCCLK, and HDMI stream clock. Additionally, this callback is also
+        * used to initialize some debug options, such as the CRC validation.
+        * Finally, it must setup the OTG instance.
+        */
+       void (*hdmi_frl_enable)(struct hpo_frl_stream_encoder *enc,
+                               int otg_inst);
+
+       /**
+        * @hdmi_frl_unblank:
+        *
+        * Ensure that the FIFO video stream is active, reset the necessary
+        * FIFO registers, enable HDMI tribyte encoder, and finally, adjust the
+        * clock ramp registers for FIFO. Notice that all the configuration
+        * made by this function it is at the register level.
+        */
+       void (*hdmi_frl_unblank)(struct hpo_frl_stream_encoder *enc,
+                                int otg_inst);
+
+       /**
+        * @hdmi_frl_blank:
+        *
+        * This callback is a register-level configuration that must disable
+        * the clock ramp adjuster FIFO, disable the HDMI Tribyte encoder, and
+        * disable the stream clocks (dispclk, socclk, and hdmistreamclk).
+        */
+       void (*hdmi_frl_blank)(struct hpo_frl_stream_encoder *enc);
+
+       /**
+        * @hdmi_frl_fifo_odm_enabled:
+        *
+        * This callback checks if the FIFO ODM Combine mode is enabled
+        */
+       bool (*hdmi_frl_fifo_odm_enabled)(struct hpo_frl_stream_encoder *enc);
+
+       /**
+        * @hdmi_frl_set_stream_attribute:
+        *
+        * This callback should be invoked only after the link is trained. The
+        * implementation should configure the pixel encode, color depth, ODM
+        * mode, configure horizontal blank/active size, configure borrow
+        * parameters, enable general control packet, enable/setup audio, and
+        * AVMute.
+        */
+       void (*hdmi_frl_set_stream_attribute)(struct hpo_frl_stream_encoder 
*enc,
+                                             struct dc_crtc_timing 
*crtc_timing,
+                                             struct frl_borrow_params 
*borrow_params,
+                                             int odm_combine_num_segments);
+
+       /**
+        * @update_hdmi_info_packets:
+        *
+        * Update the HDMI packet control option.
+        */
+       void (*update_hdmi_info_packets)(struct hpo_frl_stream_encoder *enc,
+                                        const struct encoder_info_frame 
*info_frame);
+
+       /**
+        * @stop_hdmi_info_packets:
+        *
+        * Update HDMI info packet (avi, vendoer, gamut, spd, hdrsmd, hfvsif,
+        * vtem, etc).
+        */
+       void (*stop_hdmi_info_packets)(struct hpo_frl_stream_encoder *enc);
+
+       /**
+        * @audio_mute_control:
+        *
+        * Just mute the audio.
+        */
+       void (*audio_mute_control)(struct hpo_frl_stream_encoder *enc,
+                                  bool mute);
+
+       /**
+        * @hdmi_audio_setup:
+        *
+        * Setup HDMI audio based on the Azila info.
+        */
+       void (*hdmi_audio_setup)(struct hpo_frl_stream_encoder *enc,
+                                unsigned int az_inst,
+                                struct audio_info *info,
+                                struct audio_crtc_info *audio_crtc_info);
+
+       /**
+        * @hdmi_audio_disable:
+        *
+        * Disable audio.
+        */
+       void (*hdmi_audio_disable)(struct hpo_frl_stream_encoder *enc);
+
+       /**
+        * @set_avmute:
+        *
+        * Disable AVmute at the register-level.
+        */
+       void (*set_avmute)(struct hpo_frl_stream_encoder *enc, bool enable);
+
+       /**
+        * @validate_hdmi_frl_output:
+        *
+        * Validate FRL inputs, DSC, audio parameters, FRL capacity, and borrow
+        * parameters.
+        */
+       bool (*validate_hdmi_frl_output)(struct hpo_frl_stream_encoder *enc,
+                                        const struct dc_crtc_timing *timing,
+                                        const struct audio_check *audio,
+                                        struct dc_hdmi_frl_link_settings 
*frl_link_settings,
+                                        unsigned int dsc_max_rate);
+
+       /**
+        * @read_state:
+        *
+        * Fill out the hpo_frl_stream_encoder_state with the info retrieved
+        * from ASIC registers.
+        */
+       void (*read_state)(struct hpo_frl_stream_encoder *enc,
+                          struct hpo_frl_stream_encoder_state *state);
+
+       /**
+        * @set_dynamic_metadata:
+        *
+        * Metadata configuration that sets:
+        *  - Using Enfine or disable DME.
+        *  - HUBP setup for the physical instance that has the DME enabled.
+        *  - Metadata packet type.
+        *  - Ensure OTG master update locks in the changing DME configuration.
+        */
+       void (*set_dynamic_metadata)(struct hpo_frl_stream_encoder *enc,
+                                    bool enable_dme,
+                                    uint32_t hubp_requestor_id,
+                                    enum dynamic_metadata_mode dmdata_mode);
+};
+
 struct hpo_dp_stream_encoder_state {
        uint32_t stream_enc_enabled;
        uint32_t vid_stream_enabled;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
index 2f70bb476c97..cf124838f354 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
@@ -106,6 +106,7 @@ enum crc_selection {
 
 enum otg_out_mux_dest {
        OUT_MUX_DIO = 0,
+       OUT_MUX_HPO_FRL = 1,
        OUT_MUX_HPO_DP = 2,
 };
 
@@ -493,6 +494,11 @@ struct timing_generator_funcs {
        void (*set_out_mux)(struct timing_generator *tg, enum otg_out_mux_dest 
dest);
        void (*set_drr_trigger_window)(struct timing_generator *optc,
                        uint32_t window_start, uint32_t window_end);
+       int (*set_fva_factor)(struct timing_generator *optc, struct fva_adj 
*fva_adj);
+       int (*get_max_hw_supported_fva_factor)(struct timing_generator *optc,
+               struct dc_crtc_timing *timing,
+               unsigned int max_pixclk_100hz);
+       void (*set_vstartup_dsc_frl)(struct timing_generator *optc);
        void (*set_vtotal_change_limit)(struct timing_generator *optc,
                        uint32_t limit);
        void (*align_vblanks)(struct timing_generator *master_optc,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_service.h 
b/drivers/gpu/drm/amd/display/dc/inc/link_service.h
index 57bb82e94942..aaef74755226 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_service.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_service.h
@@ -144,6 +144,10 @@ struct link_service {
        enum dc_status (*validate_dp_tunnel_bandwidth)(
                const struct dc *dc,
                const struct dc_state *new_ctx);
+       uint32_t (*frl_link_bandwidth_kbps)(enum hdmi_frl_link_rate link_rate);
+       bool (*frl_margin_check_uncompressed_video)(
+               struct frl_cap_chk_params_fixed31_32 *params,
+               struct frl_cap_chk_intermediates_fixed31_32 *inter);
 
        uint32_t (*dp_required_hblank_size_bytes)(
                const struct dc_link *link,
@@ -164,6 +168,7 @@ struct link_service {
        void (*set_dsc_on_stream)(struct pipe_ctx *pipe_ctx, bool enable);
        bool (*set_dsc_enable)(struct pipe_ctx *pipe_ctx, bool enable);
        bool (*update_dsc_config)(struct pipe_ctx *pipe_ctx);
+       void (*wait_for_unlocked)(struct dc_link *link);
 
 
        /*************************** DDC **************************************/
@@ -311,6 +316,16 @@ struct link_service {
        void (*edp_set_panel_power)(struct dc_link *link, bool powerOn);
 
 
+       /*************************** HDMI FRL *********************************/
+       bool (*hdmi_frl_poll_status_flag)(struct dc_link *link);
+       struct dc_hdmi_frl_link_settings *(*hdmi_frl_get_verified_link_cap)(
+                       struct dc_link *link);
+       void (*hdmi_frl_set_preferred_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);
+
+
        /*************************** DP CTS 
************************************/
        void (*dp_handle_automated_test)(struct dc_link *link);
        bool (*dp_set_test_pattern)(
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h 
b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index cecd3282a29f..6352e078b132 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -57,6 +57,7 @@ struct resource_caps {
        int num_dsc;
        unsigned int num_dig_link_enc; // Total number of DIGs (digital 
encoders) in DIO (Display Input/Output).
        unsigned int num_usb4_dpia; // Total number of USB4 DPIA (DisplayPort 
Input Adapters).
+       int num_hpo_frl;
        int num_hpo_dp_stream_encoder;
        int num_hpo_dp_link_encoder;
        int num_mpc_3dlut;
@@ -86,6 +87,10 @@ struct resource_create_funcs {
        struct stream_encoder *(*create_stream_encoder)(
                        enum engine_id eng_id, struct dc_context *ctx);
 
+       struct hpo_frl_stream_encoder *(*create_hpo_frl_stream_encoder)(
+                       enum engine_id eng_id, struct dc_context *ctx);
+       struct hpo_frl_link_encoder *(*create_hpo_frl_link_encoder)(
+                       enum engine_id eng_id, struct dc_context *ctx);
        struct hpo_dp_stream_encoder *(*create_hpo_dp_stream_encoder)(
                        enum engine_id eng_id, struct dc_context *ctx);
        struct hpo_dp_link_encoder *(*create_hpo_dp_link_encoder)(
@@ -604,6 +609,8 @@ unsigned int resource_pixel_format_to_bpp(enum 
surface_pixel_format format);
 bool get_temp_dp_link_res(struct dc_link *link,
                struct link_resource *link_res,
                struct dc_link_settings *link_settings);
+bool get_temp_frl_link_res(struct dc_link *link,
+               struct link_resource *link_res);
 
 void reset_syncd_pipes_from_disabled_pipes(struct dc *dc,
        struct dc_state *context);
diff --git a/drivers/gpu/drm/amd/display/include/audio_types.h 
b/drivers/gpu/drm/amd/display/include/audio_types.h
index 6699ad4fa825..2a0f1a9c30a5 100644
--- a/drivers/gpu/drm/amd/display/include/audio_types.h
+++ b/drivers/gpu/drm/amd/display/include/audio_types.h
@@ -56,6 +56,7 @@ struct audio_crtc_info {
        uint16_t refresh_rate;
        uint8_t pixel_repetition;
        bool interlaced;
+       uint32_t frl_character_clock_kHz; /* in KHz */
 };
 struct azalia_clock_info {
        uint32_t pixel_clock_in_10khz;
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 b5d97b394131..aeeac1f0c2c3 100644
--- a/drivers/gpu/drm/amd/display/include/bios_parser_types.h
+++ b/drivers/gpu/drm/amd/display/include/bios_parser_types.h
@@ -329,7 +329,11 @@ struct bp_encoder_cap_info {
        uint32_t DP_UHBR13_5_EN:1;
        uint32_t DP_UHBR20_EN:1;
        uint32_t DP_IS_USB_C:1;
-       uint32_t RESERVED:27;
+       uint32_t IS_HDMI_FRL_CAPABLE:1;
+       uint32_t FRL_8G_EN:1;
+       uint32_t FRL_10G_EN:1;
+       uint32_t FRL_12G_EN:1;
+       uint32_t RESERVED:19;
 };
 
 struct bp_soc_bb_info {
@@ -346,7 +350,13 @@ struct bp_connector_speed_cap_info {
        uint32_t DP_UHBR13_5_EN:1;
        uint32_t DP_UHBR20_EN:1;
        uint32_t DP_IS_USB_C:1;
-       uint32_t RESERVED:28;
+       uint32_t FRL_8G_EN:1;
+       uint32_t FRL_10G_EN:1;
+       uint32_t FRL_12G_EN:1;
+       uint32_t FRL_16G_EN:1;
+       uint32_t FRL_20G_EN:1;
+       uint32_t FRL_24G_EN:1;
+       uint32_t RESERVED:19;
 };
 
 #endif /*__DAL_BIOS_PARSER_TYPES_H__ */
diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h 
b/drivers/gpu/drm/amd/display/include/logger_types.h
index 177acb0574f1..a11bfb2e7cdd 100644
--- a/drivers/gpu/drm/amd/display/include/logger_types.h
+++ b/drivers/gpu/drm/amd/display/include/logger_types.h
@@ -62,6 +62,8 @@
 #define DC_LOG_ALL_TF_CHANNELS(...) pr_debug("[GAMMA]:"__VA_ARGS__)
 #define DC_LOG_DSC(...) drm_dbg_dp((DC_LOGGER)->dev, __VA_ARGS__)
 #define DC_LOG_SMU(...) pr_debug("[SMU_MSG]:"__VA_ARGS__)
+#define DC_LOG_HDMI_FRL(...) drm_dbg((DC_LOGGER)->dev, __VA_ARGS__)
+#define DC_LOG_HDMI_FRL_LTP(...) drm_dbg((DC_LOGGER)->dev, __VA_ARGS__)
 #define DC_LOG_DWB(...) drm_dbg((DC_LOGGER)->dev, __VA_ARGS__)
 #define DC_LOG_DP2(...) drm_dbg_dp((DC_LOGGER)->dev, __VA_ARGS__)
 #define DC_LOG_AUTO_DPM_TEST(...) pr_debug("[AutoDPMTest]: "__VA_ARGS__)
diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h 
b/drivers/gpu/drm/amd/display/include/signal_types.h
index 3a2c2d2fb629..9b134aa3e275 100644
--- a/drivers/gpu/drm/amd/display/include/signal_types.h
+++ b/drivers/gpu/drm/amd/display/include/signal_types.h
@@ -30,6 +30,8 @@
 #define TMDS_MIN_PIXEL_CLOCK 25000
 /* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */
 #define TMDS_MAX_PIXEL_CLOCK 165000
+/* Maximum pixel clock, in KHz. For HDMI2 TMDS signal is 600 MHz */
+#define HDMI2_TMDS_MAX_PIXEL_CLOCK 600000
 
 enum signal_type {
        SIGNAL_TYPE_NONE                = 0L,           /* no signal */
@@ -41,6 +43,7 @@ enum signal_type {
        SIGNAL_TYPE_DISPLAY_PORT        = (1 << 5),
        SIGNAL_TYPE_DISPLAY_PORT_MST    = (1 << 6),
        SIGNAL_TYPE_EDP                 = (1 << 7),
+       SIGNAL_TYPE_HDMI_FRL            = (1 << 8),
        SIGNAL_TYPE_VIRTUAL             = (1 << 9),     /* Virtual Display */
 };
 
@@ -65,6 +68,8 @@ static inline const char *signal_type_to_string(const int 
type)
                return "Display Port: MST";
        case SIGNAL_TYPE_EDP:
                return "Embedded Display Port";
+       case SIGNAL_TYPE_HDMI_FRL:
+               return "HDMI: FRL";
        case SIGNAL_TYPE_VIRTUAL:
                return "Virtual";
        default:
@@ -78,9 +83,14 @@ static inline bool dc_is_hdmi_tmds_signal(enum signal_type 
signal)
        return (signal == SIGNAL_TYPE_HDMI_TYPE_A);
 }
 
+static inline bool dc_is_hdmi_frl_signal(enum signal_type signal)
+{
+       return ((signal == SIGNAL_TYPE_HDMI_FRL));
+}
+
 static inline bool dc_is_hdmi_signal(enum signal_type signal)
 {
-       return (signal == SIGNAL_TYPE_HDMI_TYPE_A);
+       return (dc_is_hdmi_tmds_signal(signal) || 
dc_is_hdmi_frl_signal(signal));
 }
 
 static inline bool dc_is_dp_sst_signal(enum signal_type signal)
-- 
2.54.0

Reply via email to