diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4174-drm-amd-display-create-dcn21_link_encoder-files.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4174-drm-amd-display-create-dcn21_link_encoder-files.patch | 668 |
1 files changed, 668 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4174-drm-amd-display-create-dcn21_link_encoder-files.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4174-drm-amd-display-create-dcn21_link_encoder-files.patch new file mode 100644 index 00000000..69b71fce --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4174-drm-amd-display-create-dcn21_link_encoder-files.patch @@ -0,0 +1,668 @@ +From eedab588549241d11646033a4667dd8851e5a97f Mon Sep 17 00:00:00 2001 +From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> +Date: Wed, 2 Oct 2019 11:55:12 -0400 +Subject: [PATCH 4174/4736] drm/amd/display: create dcn21_link_encoder files + +[Why] +DCN20 and DCN21 have different phy programming sequences. + +[How] +Create a separate dcn21_link_encoder for Renoir + +Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> +Reviewed-by: Roman Li <Roman.Li@amd.com> +--- + .../amd/display/dc/dcn10/dcn10_link_encoder.h | 35 +- + .../amd/display/dc/dcn20/dcn20_link_encoder.h | 7 + + drivers/gpu/drm/amd/display/dc/dcn21/Makefile | 2 +- + .../amd/display/dc/dcn21/dcn21_link_encoder.c | 379 ++++++++++++++++++ + .../amd/display/dc/dcn21/dcn21_link_encoder.h | 51 +++ + .../drm/amd/display/dc/dcn21/dcn21_resource.c | 85 +++- + 6 files changed, 555 insertions(+), 4 deletions(-) + create mode 100644 drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c + create mode 100644 drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.h + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h +index 0c12395cfa36..239a6c90ffb9 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h +@@ -250,6 +250,10 @@ struct dcn10_link_enc_registers { + type RDPCS_EXT_REFCLK_EN;\ + type RDPCS_TX_FIFO_EN;\ + type UNIPHY_LINK_ENABLE;\ ++ type UNIPHY_CHANNEL0_XBAR_SOURCE;\ ++ type UNIPHY_CHANNEL1_XBAR_SOURCE;\ ++ type UNIPHY_CHANNEL2_XBAR_SOURCE;\ ++ type UNIPHY_CHANNEL3_XBAR_SOURCE;\ + type UNIPHY_CHANNEL0_INVERT;\ + type UNIPHY_CHANNEL1_INVERT;\ + type UNIPHY_CHANNEL2_INVERT;\ +@@ -342,12 +346,41 @@ struct dcn10_link_enc_registers { + type RDPCS_PHY_DPALT_DISABLE_ACK;\ + type RDPCS_PHY_DP_MPLLB_V2I;\ + type RDPCS_PHY_DP_MPLLB_FREQ_VCO;\ ++ type RDPCS_PHY_DP_MPLLB_CP_INT_GS;\ ++ type RDPCS_PHY_RX_VREF_CTRL;\ + type RDPCS_PHY_DP_MPLLB_CP_INT;\ + type RDPCS_PHY_DP_MPLLB_CP_PROP;\ + type RDPCS_PHY_RX_REF_LD_VAL;\ + type RDPCS_PHY_RX_VCO_LD_VAL;\ + type DPCSTX_DEBUG_CONFIG; \ +- type RDPCSTX_DEBUG_CONFIG ++ type RDPCSTX_DEBUG_CONFIG; \ ++ type RDPCS_PHY_DP_TX0_EQ_MAIN;\ ++ type RDPCS_PHY_DP_TX0_EQ_PRE;\ ++ type RDPCS_PHY_DP_TX0_EQ_POST;\ ++ type RDPCS_PHY_DP_TX1_EQ_MAIN;\ ++ type RDPCS_PHY_DP_TX1_EQ_PRE;\ ++ type RDPCS_PHY_DP_TX1_EQ_POST;\ ++ type RDPCS_PHY_DP_TX2_EQ_MAIN;\ ++ type RDPCS_PHY_DP_MPLLB_CP_PROP_GS;\ ++ type RDPCS_PHY_DP_TX2_EQ_PRE;\ ++ type RDPCS_PHY_DP_TX2_EQ_POST;\ ++ type RDPCS_PHY_DP_TX3_EQ_MAIN;\ ++ type RDPCS_PHY_DCO_RANGE;\ ++ type RDPCS_PHY_DCO_FINETUNE;\ ++ type RDPCS_PHY_DP_TX3_EQ_PRE;\ ++ type RDPCS_PHY_DP_TX3_EQ_POST;\ ++ type RDPCS_PHY_SUP_PRE_HP;\ ++ type RDPCS_PHY_DP_TX0_VREGDRV_BYP;\ ++ type RDPCS_PHY_DP_TX1_VREGDRV_BYP;\ ++ type RDPCS_PHY_DP_TX2_VREGDRV_BYP;\ ++ type RDPCS_PHY_DP_TX3_VREGDRV_BYP;\ ++ type RDPCS_DMCU_DPALT_DIS_BLOCK_REG;\ ++ type UNIPHYA_SOFT_RESET;\ ++ type UNIPHYB_SOFT_RESET;\ ++ type UNIPHYC_SOFT_RESET;\ ++ type UNIPHYD_SOFT_RESET;\ ++ type UNIPHYE_SOFT_RESET;\ ++ type UNIPHYF_SOFT_RESET + + #define DCN20_LINK_ENCODER_REG_FIELD_LIST(type) \ + type DIG_LANE0EN;\ +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h +index 3736b5548a25..0c98a0bbbd14 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h +@@ -91,6 +91,13 @@ struct mpll_cfg { + uint32_t ref_range; + uint32_t ref_clk; + bool hdmimode_enable; ++ bool sup_pre_hp; ++ bool dp_tx0_vergdrv_byp; ++ bool dp_tx1_vergdrv_byp; ++ bool dp_tx2_vergdrv_byp; ++ bool dp_tx3_vergdrv_byp; ++ ++ + }; + + struct dpcssys_phy_seq_cfg { +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile +index 5b8f42ae2334..b7a9285348fb 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile +@@ -1,7 +1,7 @@ + # + # Makefile for DCN21. + +-DCN21 = dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o dcn21_hwseq.o ++DCN21 = dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o dcn21_hwseq.o dcn21_link_encoder.o + + CFLAGS_dcn21_resource.o := -mhard-float -msse -mpreferred-stack-boundary=4 + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c +new file mode 100644 +index 000000000000..526865c43b48 +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c +@@ -0,0 +1,379 @@ ++/* ++ * Copyright 2012-15 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 ++ * ++ */ ++ ++#include "reg_helper.h" ++ ++#include <linux/delay.h> ++#include "core_types.h" ++#include "link_encoder.h" ++#include "dcn21_link_encoder.h" ++#include "stream_encoder.h" ++ ++#include "i2caux_interface.h" ++#include "dc_bios_types.h" ++ ++#include "gpio_service_interface.h" ++ ++#define CTX \ ++ enc10->base.ctx ++#define DC_LOGGER \ ++ enc10->base.ctx->logger ++ ++#define REG(reg)\ ++ (enc10->link_regs->reg) ++ ++#undef FN ++#define FN(reg_name, field_name) \ ++ enc10->link_shift->field_name, enc10->link_mask->field_name ++ ++#define IND_REG(index) \ ++ (enc10->link_regs->index) ++ ++static struct mpll_cfg dcn21_mpll_cfg_ref[] = { ++ // RBR ++ { ++ .hdmimode_enable = 0, ++ .ref_range = 1, ++ .ref_clk_mpllb_div = 1, ++ .mpllb_ssc_en = 1, ++ .mpllb_div5_clk_en = 1, ++ .mpllb_multiplier = 238, ++ .mpllb_fracn_en = 0, ++ .mpllb_fracn_quot = 0, ++ .mpllb_fracn_rem = 0, ++ .mpllb_fracn_den = 1, ++ .mpllb_ssc_up_spread = 0, ++ .mpllb_ssc_peak = 44237, ++ .mpllb_ssc_stepsize = 59454, ++ .mpllb_div_clk_en = 0, ++ .mpllb_div_multiplier = 0, ++ .mpllb_hdmi_div = 0, ++ .mpllb_tx_clk_div = 2, ++ .tx_vboost_lvl = 5, ++ .mpllb_pmix_en = 1, ++ .mpllb_word_div2_en = 0, ++ .mpllb_ana_v2i = 2, ++ .mpllb_ana_freq_vco = 2, ++ .mpllb_ana_cp_int = 9, ++ .mpllb_ana_cp_prop = 15, ++ .hdmi_pixel_clk_div = 0, ++ }, ++ // HBR ++ { ++ .hdmimode_enable = 0, ++ .ref_range = 1, ++ .ref_clk_mpllb_div = 1, ++ .mpllb_ssc_en = 1, ++ .mpllb_div5_clk_en = 1, ++ .mpllb_multiplier = 192, ++ .mpllb_fracn_en = 1, ++ .mpllb_fracn_quot = 32768, ++ .mpllb_fracn_rem = 0, ++ .mpllb_fracn_den = 1, ++ .mpllb_ssc_up_spread = 0, ++ .mpllb_ssc_peak = 36864, ++ .mpllb_ssc_stepsize = 49545, ++ .mpllb_div_clk_en = 0, ++ .mpllb_div_multiplier = 0, ++ .mpllb_hdmi_div = 0, ++ .mpllb_tx_clk_div = 1, ++ .tx_vboost_lvl = 5, ++ .mpllb_pmix_en = 1, ++ .mpllb_word_div2_en = 0, ++ .mpllb_ana_v2i = 2, ++ .mpllb_ana_freq_vco = 3, ++ .mpllb_ana_cp_int = 9, ++ .mpllb_ana_cp_prop = 15, ++ .hdmi_pixel_clk_div = 0, ++ }, ++ //HBR2 ++ { ++ .hdmimode_enable = 0, ++ .ref_range = 1, ++ .ref_clk_mpllb_div = 1, ++ .mpllb_ssc_en = 1, ++ .mpllb_div5_clk_en = 1, ++ .mpllb_multiplier = 192, ++ .mpllb_fracn_en = 1, ++ .mpllb_fracn_quot = 32768, ++ .mpllb_fracn_rem = 0, ++ .mpllb_fracn_den = 1, ++ .mpllb_ssc_up_spread = 0, ++ .mpllb_ssc_peak = 36864, ++ .mpllb_ssc_stepsize = 49545, ++ .mpllb_div_clk_en = 0, ++ .mpllb_div_multiplier = 0, ++ .mpllb_hdmi_div = 0, ++ .mpllb_tx_clk_div = 0, ++ .tx_vboost_lvl = 5, ++ .mpllb_pmix_en = 1, ++ .mpllb_word_div2_en = 0, ++ .mpllb_ana_v2i = 2, ++ .mpllb_ana_freq_vco = 3, ++ .mpllb_ana_cp_int = 9, ++ .mpllb_ana_cp_prop = 15, ++ .hdmi_pixel_clk_div = 0, ++ }, ++ //HBR3 ++ { ++ .hdmimode_enable = 0, ++ .ref_range = 1, ++ .ref_clk_mpllb_div = 1, ++ .mpllb_ssc_en = 1, ++ .mpllb_div5_clk_en = 1, ++ .mpllb_multiplier = 304, ++ .mpllb_fracn_en = 1, ++ .mpllb_fracn_quot = 49152, ++ .mpllb_fracn_rem = 0, ++ .mpllb_fracn_den = 1, ++ .mpllb_ssc_up_spread = 0, ++ .mpllb_ssc_peak = 55296, ++ .mpllb_ssc_stepsize = 74318, ++ .mpllb_div_clk_en = 0, ++ .mpllb_div_multiplier = 0, ++ .mpllb_hdmi_div = 0, ++ .mpllb_tx_clk_div = 0, ++ .tx_vboost_lvl = 5, ++ .mpllb_pmix_en = 1, ++ .mpllb_word_div2_en = 0, ++ .mpllb_ana_v2i = 2, ++ .mpllb_ana_freq_vco = 1, ++ .mpllb_ana_cp_int = 7, ++ .mpllb_ana_cp_prop = 16, ++ .hdmi_pixel_clk_div = 0, ++ }, ++}; ++ ++ ++static bool update_cfg_data( ++ struct dcn10_link_encoder *enc10, ++ const struct dc_link_settings *link_settings, ++ struct dpcssys_phy_seq_cfg *cfg) ++{ ++ int i; ++ ++ cfg->load_sram_fw = false; ++ cfg->use_calibration_setting = true; ++ ++ //TODO: need to implement a proper lane mapping for Renoir. ++ for (i = 0; i < 4; i++) ++ cfg->lane_en[i] = true; ++ ++ switch (link_settings->link_rate) { ++ case LINK_RATE_LOW: ++ cfg->mpll_cfg = dcn21_mpll_cfg_ref[0]; ++ break; ++ case LINK_RATE_HIGH: ++ cfg->mpll_cfg = dcn21_mpll_cfg_ref[1]; ++ break; ++ case LINK_RATE_HIGH2: ++ cfg->mpll_cfg = dcn21_mpll_cfg_ref[2]; ++ break; ++ case LINK_RATE_HIGH3: ++ cfg->mpll_cfg = dcn21_mpll_cfg_ref[3]; ++ break; ++ default: ++ DC_LOG_ERROR("%s: No supported link rate found %X!\n", ++ __func__, link_settings->link_rate); ++ return false; ++ } ++ ++ return true; ++} ++ ++void dcn21_link_encoder_enable_dp_output( ++ struct link_encoder *enc, ++ const struct dc_link_settings *link_settings, ++ enum clock_source_id clock_source) ++{ ++ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); ++ struct dcn21_link_encoder *enc21 = (struct dcn21_link_encoder *) enc10; ++ struct dpcssys_phy_seq_cfg *cfg = &enc21->phy_seq_cfg; ++ ++ if (!enc->ctx->dc->debug.avoid_vbios_exec_table) { ++ dcn10_link_encoder_enable_dp_output(enc, link_settings, clock_source); ++ return; ++ } ++ ++ if (!update_cfg_data(enc10, link_settings, cfg)) ++ return; ++ ++ enc1_configure_encoder(enc10, link_settings); ++ ++ dcn10_link_encoder_setup(enc, SIGNAL_TYPE_DISPLAY_PORT); ++ ++} ++ ++void dcn21_link_encoder_disable_output( ++ struct link_encoder *enc, ++ enum signal_type signal) ++{ ++ dcn10_link_encoder_disable_output(enc, signal); ++ ++} ++static const struct link_encoder_funcs dcn21_link_enc_funcs = { ++#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT ++ .read_state = link_enc2_read_state, ++#endif ++ .validate_output_with_stream = ++ dcn10_link_encoder_validate_output_with_stream, ++ .hw_init = enc2_hw_init, ++ .setup = dcn10_link_encoder_setup, ++ .enable_tmds_output = dcn10_link_encoder_enable_tmds_output, ++ .enable_dp_output = dcn21_link_encoder_enable_dp_output, ++ .enable_dp_mst_output = dcn10_link_encoder_enable_dp_mst_output, ++ .disable_output = dcn21_link_encoder_disable_output, ++ .dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings, ++ .dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern, ++ .update_mst_stream_allocation_table = ++ dcn10_link_encoder_update_mst_stream_allocation_table, ++ .psr_program_dp_dphy_fast_training = ++ dcn10_psr_program_dp_dphy_fast_training, ++ .psr_program_secondary_packet = dcn10_psr_program_secondary_packet, ++ .connect_dig_be_to_fe = dcn10_link_encoder_connect_dig_be_to_fe, ++ .enable_hpd = dcn10_link_encoder_enable_hpd, ++ .disable_hpd = dcn10_link_encoder_disable_hpd, ++ .is_dig_enabled = dcn10_is_dig_enabled, ++ .destroy = dcn10_link_encoder_destroy, ++ .fec_set_enable = enc2_fec_set_enable, ++ .fec_set_ready = enc2_fec_set_ready, ++ .fec_is_active = enc2_fec_is_active, ++ .get_dig_frontend = dcn10_get_dig_frontend, ++}; ++ ++void dcn21_link_encoder_construct( ++ struct dcn21_link_encoder *enc21, ++ const struct encoder_init_data *init_data, ++ const struct encoder_feature_support *enc_features, ++ const struct dcn10_link_enc_registers *link_regs, ++ const struct dcn10_link_enc_aux_registers *aux_regs, ++ const struct dcn10_link_enc_hpd_registers *hpd_regs, ++ const struct dcn10_link_enc_shift *link_shift, ++ const struct dcn10_link_enc_mask *link_mask) ++{ ++ struct bp_encoder_cap_info bp_cap_info = {0}; ++ const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs; ++ enum bp_result result = BP_RESULT_OK; ++ struct dcn10_link_encoder *enc10 = &enc21->enc10; ++ ++ enc10->base.funcs = &dcn21_link_enc_funcs; ++ enc10->base.ctx = init_data->ctx; ++ enc10->base.id = init_data->encoder; ++ ++ enc10->base.hpd_source = init_data->hpd_source; ++ enc10->base.connector = init_data->connector; ++ ++ enc10->base.preferred_engine = ENGINE_ID_UNKNOWN; ++ ++ enc10->base.features = *enc_features; ++ ++ enc10->base.transmitter = init_data->transmitter; ++ ++ /* set the flag to indicate whether driver poll the I2C data pin ++ * while doing the DP sink detect ++ */ ++ ++/* if (dal_adapter_service_is_feature_supported(as, ++ FEATURE_DP_SINK_DETECT_POLL_DATA_PIN)) ++ enc10->base.features.flags.bits. ++ DP_SINK_DETECT_POLL_DATA_PIN = true;*/ ++ ++ enc10->base.output_signals = ++ SIGNAL_TYPE_DVI_SINGLE_LINK | ++ SIGNAL_TYPE_DVI_DUAL_LINK | ++ SIGNAL_TYPE_LVDS | ++ SIGNAL_TYPE_DISPLAY_PORT | ++ SIGNAL_TYPE_DISPLAY_PORT_MST | ++ SIGNAL_TYPE_EDP | ++ SIGNAL_TYPE_HDMI_TYPE_A; ++ ++ /* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE. ++ * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY. ++ * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer ++ * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS. ++ * Prefer DIG assignment is decided by board design. ++ * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design ++ * and VBIOS will filter out 7 UNIPHY for DCE 8.0. ++ * By this, adding DIGG should not hurt DCE 8.0. ++ * This will let DCE 8.1 share DCE 8.0 as much as possible ++ */ ++ ++ enc10->link_regs = link_regs; ++ enc10->aux_regs = aux_regs; ++ enc10->hpd_regs = hpd_regs; ++ enc10->link_shift = link_shift; ++ enc10->link_mask = link_mask; ++ ++ switch (enc10->base.transmitter) { ++ case TRANSMITTER_UNIPHY_A: ++ enc10->base.preferred_engine = ENGINE_ID_DIGA; ++ break; ++ case TRANSMITTER_UNIPHY_B: ++ enc10->base.preferred_engine = ENGINE_ID_DIGB; ++ break; ++ case TRANSMITTER_UNIPHY_C: ++ enc10->base.preferred_engine = ENGINE_ID_DIGC; ++ break; ++ case TRANSMITTER_UNIPHY_D: ++ enc10->base.preferred_engine = ENGINE_ID_DIGD; ++ break; ++ case TRANSMITTER_UNIPHY_E: ++ enc10->base.preferred_engine = ENGINE_ID_DIGE; ++ break; ++ case TRANSMITTER_UNIPHY_F: ++ enc10->base.preferred_engine = ENGINE_ID_DIGF; ++ break; ++ case TRANSMITTER_UNIPHY_G: ++ enc10->base.preferred_engine = ENGINE_ID_DIGG; ++ break; ++ default: ++ ASSERT_CRITICAL(false); ++ enc10->base.preferred_engine = ENGINE_ID_UNKNOWN; ++ } ++ ++ /* default to one to mirror Windows behavior */ ++ enc10->base.features.flags.bits.HDMI_6GB_EN = 1; ++ ++ result = bp_funcs->get_encoder_cap_info(enc10->base.ctx->dc_bios, ++ enc10->base.id, &bp_cap_info); ++ ++ /* Override features with DCE-specific values */ ++ if (result == BP_RESULT_OK) { ++ enc10->base.features.flags.bits.IS_HBR2_CAPABLE = ++ bp_cap_info.DP_HBR2_EN; ++ enc10->base.features.flags.bits.IS_HBR3_CAPABLE = ++ bp_cap_info.DP_HBR3_EN; ++ enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; ++ enc10->base.features.flags.bits.DP_IS_USB_C = ++ bp_cap_info.DP_IS_USB_C; ++ } else { ++ DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", ++ __func__, ++ result); ++ } ++ if (enc10->base.ctx->dc->debug.hdmi20_disable) { ++ enc10->base.features.flags.bits.HDMI_6GB_EN = 0; ++ } ++} +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.h +new file mode 100644 +index 000000000000..438321e547db +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.h +@@ -0,0 +1,51 @@ ++/* ++ * Copyright 2012-15 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 __DC_LINK_ENCODER__DCN21_H__ ++#define __DC_LINK_ENCODER__DCN21_H__ ++ ++#include "dcn20/dcn20_link_encoder.h" ++ ++struct dcn21_link_encoder { ++ struct dcn10_link_encoder enc10; ++ struct dpcssys_phy_seq_cfg phy_seq_cfg; ++}; ++ ++void dcn21_link_encoder_enable_dp_output( ++ struct link_encoder *enc, ++ const struct dc_link_settings *link_settings, ++ enum clock_source_id clock_source); ++ ++void dcn21_link_encoder_construct( ++ struct dcn21_link_encoder *enc21, ++ const struct encoder_init_data *init_data, ++ const struct encoder_feature_support *enc_features, ++ const struct dcn10_link_enc_registers *link_regs, ++ const struct dcn10_link_enc_aux_registers *aux_regs, ++ const struct dcn10_link_enc_hpd_registers *hpd_regs, ++ const struct dcn10_link_enc_shift *link_shift, ++ const struct dcn10_link_enc_mask *link_mask); ++ ++#endif +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +index 1bac7eca5963..085e6d38c45e 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -44,7 +44,7 @@ + #include "dce110/dce110_hw_sequencer.h" + #include "dcn20/dcn20_opp.h" + #include "dcn20/dcn20_dsc.h" +-#include "dcn20/dcn20_link_encoder.h" ++#include "dcn21/dcn21_link_encoder.h" + #include "dcn20/dcn20_stream_encoder.h" + #include "dce/dce_clock_source.h" + #include "dce/dce_audio.h" +@@ -1513,6 +1513,87 @@ static struct link_encoder *dcn21_link_encoder_create( + return &enc21->enc10.base; + } + ++static const struct encoder_feature_support link_enc_feature = { ++ .max_hdmi_deep_color = COLOR_DEPTH_121212, ++ .max_hdmi_pixel_clock = 600000, ++ .hdmi_ycbcr420_supported = true, ++ .dp_ycbcr420_supported = true, ++ .flags.bits.IS_HBR2_CAPABLE = true, ++ .flags.bits.IS_HBR3_CAPABLE = true, ++ .flags.bits.IS_TPS3_CAPABLE = true, ++ .flags.bits.IS_TPS4_CAPABLE = true ++}; ++ ++ ++#define link_regs(id, phyid)\ ++[id] = {\ ++ LE_DCN10_REG_LIST(id), \ ++ UNIPHY_DCN2_REG_LIST(phyid), \ ++ SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \ ++} ++ ++static const struct dcn10_link_enc_registers link_enc_regs[] = { ++ link_regs(0, A), ++ link_regs(1, B), ++ link_regs(2, C), ++ link_regs(3, D), ++ link_regs(4, E), ++}; ++ ++#define aux_regs(id)\ ++[id] = {\ ++ DCN2_AUX_REG_LIST(id)\ ++} ++ ++static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = { ++ aux_regs(0), ++ aux_regs(1), ++ aux_regs(2), ++ aux_regs(3), ++ aux_regs(4) ++}; ++ ++#define hpd_regs(id)\ ++[id] = {\ ++ HPD_REG_LIST(id)\ ++} ++ ++static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = { ++ hpd_regs(0), ++ hpd_regs(1), ++ hpd_regs(2), ++ hpd_regs(3), ++ hpd_regs(4) ++}; ++ ++static const struct dcn10_link_enc_shift le_shift = { ++ LINK_ENCODER_MASK_SH_LIST_DCN20(__SHIFT) ++}; ++ ++static const struct dcn10_link_enc_mask le_mask = { ++ LINK_ENCODER_MASK_SH_LIST_DCN20(_MASK) ++}; ++ ++static struct link_encoder *dcn21_link_encoder_create( ++ const struct encoder_init_data *enc_init_data) ++{ ++ struct dcn21_link_encoder *enc21 = ++ kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL); ++ ++ if (!enc21) ++ return NULL; ++ ++ dcn21_link_encoder_construct(enc21, ++ enc_init_data, ++ &link_enc_feature, ++ &link_enc_regs[enc_init_data->transmitter], ++ &link_enc_aux_regs[enc_init_data->channel - 1], ++ &link_enc_hpd_regs[enc_init_data->hpd_source], ++ &le_shift, ++ &le_mask); ++ ++ return &enc21->enc10.base; ++} + #define CTX ctx + + #define REG(reg_name) \ +@@ -1528,7 +1609,7 @@ static uint32_t read_pipe_fuses(struct dc_context *ctx) + + static struct resource_funcs dcn21_res_pool_funcs = { + .destroy = dcn21_destroy_resource_pool, +- .link_enc_create = dcn20_link_encoder_create, ++ .link_enc_create = dcn21_link_encoder_create, + .validate_bandwidth = dcn21_validate_bandwidth, + .add_stream_to_ctx = dcn20_add_stream_to_ctx, + .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, +-- +2.17.1 + |