LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/display/dc/dcn10 - dcn10_link_encoder.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 506 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 43 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2012-15 Advanced Micro Devices, Inc.
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the "Software"),
       6             :  * to deal in the Software without restriction, including without limitation
       7             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8             :  * and/or sell copies of the Software, and to permit persons to whom the
       9             :  * Software is furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included in
      12             :  * all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      17             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      18             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      19             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      20             :  * OTHER DEALINGS IN THE SOFTWARE.
      21             :  *
      22             :  * Authors: AMD
      23             :  *
      24             :  */
      25             : 
      26             : #include "reg_helper.h"
      27             : 
      28             : #include "core_types.h"
      29             : #include "link_encoder.h"
      30             : #include "dcn10_link_encoder.h"
      31             : #include "stream_encoder.h"
      32             : #include "i2caux_interface.h"
      33             : #include "dc_bios_types.h"
      34             : 
      35             : #include "gpio_service_interface.h"
      36             : 
      37             : #define CTX \
      38             :         enc10->base.ctx
      39             : #define DC_LOGGER \
      40             :         enc10->base.ctx->logger
      41             : 
      42             : #define REG(reg)\
      43             :         (enc10->link_regs->reg)
      44             : 
      45             : #undef FN
      46             : #define FN(reg_name, field_name) \
      47             :         enc10->link_shift->field_name, enc10->link_mask->field_name
      48             : 
      49             : 
      50             : /*
      51             :  * @brief
      52             :  * Trigger Source Select
      53             :  * ASIC-dependent, actual values for register programming
      54             :  */
      55             : #define DCN10_DIG_FE_SOURCE_SELECT_INVALID 0x0
      56             : #define DCN10_DIG_FE_SOURCE_SELECT_DIGA 0x1
      57             : #define DCN10_DIG_FE_SOURCE_SELECT_DIGB 0x2
      58             : #define DCN10_DIG_FE_SOURCE_SELECT_DIGC 0x4
      59             : #define DCN10_DIG_FE_SOURCE_SELECT_DIGD 0x08
      60             : #define DCN10_DIG_FE_SOURCE_SELECT_DIGE 0x10
      61             : #define DCN10_DIG_FE_SOURCE_SELECT_DIGF 0x20
      62             : #define DCN10_DIG_FE_SOURCE_SELECT_DIGG 0x40
      63             : 
      64             : enum {
      65             :         DP_MST_UPDATE_MAX_RETRY = 50
      66             : };
      67             : 
      68             : static const struct link_encoder_funcs dcn10_lnk_enc_funcs = {
      69             :         .validate_output_with_stream =
      70             :                 dcn10_link_encoder_validate_output_with_stream,
      71             :         .hw_init = dcn10_link_encoder_hw_init,
      72             :         .setup = dcn10_link_encoder_setup,
      73             :         .enable_tmds_output = dcn10_link_encoder_enable_tmds_output,
      74             :         .enable_dp_output = dcn10_link_encoder_enable_dp_output,
      75             :         .enable_dp_mst_output = dcn10_link_encoder_enable_dp_mst_output,
      76             :         .disable_output = dcn10_link_encoder_disable_output,
      77             :         .dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings,
      78             :         .dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern,
      79             :         .update_mst_stream_allocation_table =
      80             :                 dcn10_link_encoder_update_mst_stream_allocation_table,
      81             :         .psr_program_dp_dphy_fast_training =
      82             :                         dcn10_psr_program_dp_dphy_fast_training,
      83             :         .psr_program_secondary_packet = dcn10_psr_program_secondary_packet,
      84             :         .connect_dig_be_to_fe = dcn10_link_encoder_connect_dig_be_to_fe,
      85             :         .enable_hpd = dcn10_link_encoder_enable_hpd,
      86             :         .disable_hpd = dcn10_link_encoder_disable_hpd,
      87             :         .is_dig_enabled = dcn10_is_dig_enabled,
      88             :         .get_dig_frontend = dcn10_get_dig_frontend,
      89             :         .get_dig_mode = dcn10_get_dig_mode,
      90             :         .destroy = dcn10_link_encoder_destroy,
      91             :         .get_max_link_cap = dcn10_link_encoder_get_max_link_cap,
      92             : };
      93             : 
      94             : static enum bp_result link_transmitter_control(
      95             :         struct dcn10_link_encoder *enc10,
      96             :         struct bp_transmitter_control *cntl)
      97             : {
      98             :         enum bp_result result;
      99           0 :         struct dc_bios *bp = enc10->base.ctx->dc_bios;
     100             : 
     101           0 :         result = bp->funcs->transmitter_control(bp, cntl);
     102             : 
     103             :         return result;
     104             : }
     105             : 
     106           0 : static void enable_phy_bypass_mode(
     107             :         struct dcn10_link_encoder *enc10,
     108             :         bool enable)
     109             : {
     110             :         /* This register resides in DP back end block;
     111             :          * transmitter is used for the offset
     112             :          */
     113           0 :         REG_UPDATE(DP_DPHY_CNTL, DPHY_BYPASS, enable);
     114             : 
     115           0 : }
     116             : 
     117           0 : static void disable_prbs_symbols(
     118             :         struct dcn10_link_encoder *enc10,
     119             :         bool disable)
     120             : {
     121             :         /* This register resides in DP back end block;
     122             :          * transmitter is used for the offset
     123             :          */
     124           0 :         REG_UPDATE_4(DP_DPHY_CNTL,
     125             :                         DPHY_ATEST_SEL_LANE0, disable,
     126             :                         DPHY_ATEST_SEL_LANE1, disable,
     127             :                         DPHY_ATEST_SEL_LANE2, disable,
     128             :                         DPHY_ATEST_SEL_LANE3, disable);
     129           0 : }
     130             : 
     131           0 : static void disable_prbs_mode(
     132             :         struct dcn10_link_encoder *enc10)
     133             : {
     134           0 :         REG_UPDATE(DP_DPHY_PRBS_CNTL, DPHY_PRBS_EN, 0);
     135           0 : }
     136             : 
     137           0 : static void program_pattern_symbols(
     138             :         struct dcn10_link_encoder *enc10,
     139             :         uint16_t pattern_symbols[8])
     140             : {
     141             :         /* This register resides in DP back end block;
     142             :          * transmitter is used for the offset
     143             :          */
     144           0 :         REG_SET_3(DP_DPHY_SYM0, 0,
     145             :                         DPHY_SYM1, pattern_symbols[0],
     146             :                         DPHY_SYM2, pattern_symbols[1],
     147             :                         DPHY_SYM3, pattern_symbols[2]);
     148             : 
     149             :         /* This register resides in DP back end block;
     150             :          * transmitter is used for the offset
     151             :          */
     152           0 :         REG_SET_3(DP_DPHY_SYM1, 0,
     153             :                         DPHY_SYM4, pattern_symbols[3],
     154             :                         DPHY_SYM5, pattern_symbols[4],
     155             :                         DPHY_SYM6, pattern_symbols[5]);
     156             : 
     157             :         /* This register resides in DP back end block;
     158             :          * transmitter is used for the offset
     159             :          */
     160           0 :         REG_SET_2(DP_DPHY_SYM2, 0,
     161             :                         DPHY_SYM7, pattern_symbols[6],
     162             :                         DPHY_SYM8, pattern_symbols[7]);
     163           0 : }
     164             : 
     165           0 : static void set_dp_phy_pattern_d102(
     166             :         struct dcn10_link_encoder *enc10)
     167             : {
     168             :         /* Disable PHY Bypass mode to setup the test pattern */
     169           0 :         enable_phy_bypass_mode(enc10, false);
     170             : 
     171             :         /* For 10-bit PRBS or debug symbols
     172             :          * please use the following sequence:
     173             :          *
     174             :          * Enable debug symbols on the lanes
     175             :          */
     176           0 :         disable_prbs_symbols(enc10, true);
     177             : 
     178             :         /* Disable PRBS mode */
     179           0 :         disable_prbs_mode(enc10);
     180             : 
     181             :         /* Program debug symbols to be output */
     182             :         {
     183           0 :                 uint16_t pattern_symbols[8] = {
     184             :                         0x2AA, 0x2AA, 0x2AA, 0x2AA,
     185             :                         0x2AA, 0x2AA, 0x2AA, 0x2AA
     186             :                 };
     187             : 
     188           0 :                 program_pattern_symbols(enc10, pattern_symbols);
     189             :         }
     190             : 
     191             :         /* Enable phy bypass mode to enable the test pattern */
     192             : 
     193           0 :         enable_phy_bypass_mode(enc10, true);
     194           0 : }
     195             : 
     196           0 : static void set_link_training_complete(
     197             :         struct dcn10_link_encoder *enc10,
     198             :         bool complete)
     199             : {
     200             :         /* This register resides in DP back end block;
     201             :          * transmitter is used for the offset
     202             :          */
     203           0 :         REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, complete);
     204             : 
     205           0 : }
     206             : 
     207           0 : void dcn10_link_encoder_set_dp_phy_pattern_training_pattern(
     208             :         struct link_encoder *enc,
     209             :         uint32_t index)
     210             : {
     211           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
     212             :         /* Write Training Pattern */
     213             : 
     214           0 :         REG_WRITE(DP_DPHY_TRAINING_PATTERN_SEL, index);
     215             : 
     216             :         /* Set HW Register Training Complete to false */
     217             : 
     218           0 :         set_link_training_complete(enc10, false);
     219             : 
     220             :         /* Disable PHY Bypass mode to output Training Pattern */
     221             : 
     222           0 :         enable_phy_bypass_mode(enc10, false);
     223             : 
     224             :         /* Disable PRBS mode */
     225           0 :         disable_prbs_mode(enc10);
     226           0 : }
     227             : 
     228           0 : static void setup_panel_mode(
     229             :         struct dcn10_link_encoder *enc10,
     230             :         enum dp_panel_mode panel_mode)
     231             : {
     232             :         uint32_t value;
     233             : 
     234           0 :         if (!REG(DP_DPHY_INTERNAL_CTRL))
     235             :                 return;
     236             : 
     237           0 :         value = REG_READ(DP_DPHY_INTERNAL_CTRL);
     238             : 
     239           0 :         switch (panel_mode) {
     240             :         case DP_PANEL_MODE_EDP:
     241             :                 value = 0x1;
     242             :                 break;
     243             :         case DP_PANEL_MODE_SPECIAL:
     244           0 :                 value = 0x11;
     245             :                 break;
     246             :         default:
     247           0 :                 value = 0x0;
     248             :                 break;
     249             :         }
     250             : 
     251           0 :         REG_WRITE(DP_DPHY_INTERNAL_CTRL, value);
     252             : }
     253             : 
     254           0 : static void set_dp_phy_pattern_symbol_error(
     255             :         struct dcn10_link_encoder *enc10)
     256             : {
     257             :         /* Disable PHY Bypass mode to setup the test pattern */
     258           0 :         enable_phy_bypass_mode(enc10, false);
     259             : 
     260             :         /* program correct panel mode*/
     261           0 :         setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
     262             : 
     263             :         /* A PRBS23 pattern is used for most DP electrical measurements. */
     264             : 
     265             :         /* Enable PRBS symbols on the lanes */
     266           0 :         disable_prbs_symbols(enc10, false);
     267             : 
     268             :         /* For PRBS23 Set bit DPHY_PRBS_SEL=1 and Set bit DPHY_PRBS_EN=1 */
     269           0 :         REG_UPDATE_2(DP_DPHY_PRBS_CNTL,
     270             :                         DPHY_PRBS_SEL, 1,
     271             :                         DPHY_PRBS_EN, 1);
     272             : 
     273             :         /* Enable phy bypass mode to enable the test pattern */
     274           0 :         enable_phy_bypass_mode(enc10, true);
     275           0 : }
     276             : 
     277           0 : static void set_dp_phy_pattern_prbs7(
     278             :         struct dcn10_link_encoder *enc10)
     279             : {
     280             :         /* Disable PHY Bypass mode to setup the test pattern */
     281           0 :         enable_phy_bypass_mode(enc10, false);
     282             : 
     283             :         /* A PRBS7 pattern is used for most DP electrical measurements. */
     284             : 
     285             :         /* Enable PRBS symbols on the lanes */
     286           0 :         disable_prbs_symbols(enc10, false);
     287             : 
     288             :         /* For PRBS7 Set bit DPHY_PRBS_SEL=0 and Set bit DPHY_PRBS_EN=1 */
     289           0 :         REG_UPDATE_2(DP_DPHY_PRBS_CNTL,
     290             :                         DPHY_PRBS_SEL, 0,
     291             :                         DPHY_PRBS_EN, 1);
     292             : 
     293             :         /* Enable phy bypass mode to enable the test pattern */
     294           0 :         enable_phy_bypass_mode(enc10, true);
     295           0 : }
     296             : 
     297           0 : static void set_dp_phy_pattern_80bit_custom(
     298             :         struct dcn10_link_encoder *enc10,
     299             :         const uint8_t *pattern)
     300             : {
     301             :         /* Disable PHY Bypass mode to setup the test pattern */
     302           0 :         enable_phy_bypass_mode(enc10, false);
     303             : 
     304             :         /* Enable debug symbols on the lanes */
     305             : 
     306           0 :         disable_prbs_symbols(enc10, true);
     307             : 
     308             :         /* Enable PHY bypass mode to enable the test pattern */
     309             :         /* TODO is it really needed ? */
     310             : 
     311           0 :         enable_phy_bypass_mode(enc10, true);
     312             : 
     313             :         /* Program 80 bit custom pattern */
     314             :         {
     315             :                 uint16_t pattern_symbols[8];
     316             : 
     317           0 :                 pattern_symbols[0] =
     318           0 :                         ((pattern[1] & 0x03) << 8) | pattern[0];
     319           0 :                 pattern_symbols[1] =
     320           0 :                         ((pattern[2] & 0x0f) << 6) | ((pattern[1] >> 2) & 0x3f);
     321           0 :                 pattern_symbols[2] =
     322           0 :                         ((pattern[3] & 0x3f) << 4) | ((pattern[2] >> 4) & 0x0f);
     323           0 :                 pattern_symbols[3] =
     324           0 :                         (pattern[4] << 2) | ((pattern[3] >> 6) & 0x03);
     325           0 :                 pattern_symbols[4] =
     326           0 :                         ((pattern[6] & 0x03) << 8) | pattern[5];
     327           0 :                 pattern_symbols[5] =
     328           0 :                         ((pattern[7] & 0x0f) << 6) | ((pattern[6] >> 2) & 0x3f);
     329           0 :                 pattern_symbols[6] =
     330           0 :                         ((pattern[8] & 0x3f) << 4) | ((pattern[7] >> 4) & 0x0f);
     331           0 :                 pattern_symbols[7] =
     332           0 :                         (pattern[9] << 2) | ((pattern[8] >> 6) & 0x03);
     333             : 
     334           0 :                 program_pattern_symbols(enc10, pattern_symbols);
     335             :         }
     336             : 
     337             :         /* Enable phy bypass mode to enable the test pattern */
     338             : 
     339           0 :         enable_phy_bypass_mode(enc10, true);
     340           0 : }
     341             : 
     342           0 : static void set_dp_phy_pattern_hbr2_compliance_cp2520_2(
     343             :         struct dcn10_link_encoder *enc10,
     344             :         unsigned int cp2520_pattern)
     345             : {
     346             : 
     347             :         /* previously there is a register DP_HBR2_EYE_PATTERN
     348             :          * that is enabled to get the pattern.
     349             :          * But it does not work with the latest spec change,
     350             :          * so we are programming the following registers manually.
     351             :          *
     352             :          * The following settings have been confirmed
     353             :          * by Nick Chorney and Sandra Liu
     354             :          */
     355             : 
     356             :         /* Disable PHY Bypass mode to setup the test pattern */
     357             : 
     358           0 :         enable_phy_bypass_mode(enc10, false);
     359             : 
     360             :         /* Setup DIG encoder in DP SST mode */
     361           0 :         enc10->base.funcs->setup(&enc10->base, SIGNAL_TYPE_DISPLAY_PORT);
     362             : 
     363             :         /* ensure normal panel mode. */
     364           0 :         setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
     365             : 
     366             :         /* no vbid after BS (SR)
     367             :          * DP_LINK_FRAMING_CNTL changed history Sandra Liu
     368             :          * 11000260 / 11000104 / 110000FC
     369             :          */
     370           0 :         REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
     371             :                         DP_IDLE_BS_INTERVAL, 0xFC,
     372             :                         DP_VBID_DISABLE, 1,
     373             :                         DP_VID_ENHANCED_FRAME_MODE, 1);
     374             : 
     375             :         /* swap every BS with SR */
     376           0 :         REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0);
     377             : 
     378             :         /* select cp2520 patterns */
     379           0 :         if (REG(DP_DPHY_HBR2_PATTERN_CONTROL))
     380           0 :                 REG_UPDATE(DP_DPHY_HBR2_PATTERN_CONTROL,
     381             :                                 DP_DPHY_HBR2_PATTERN_CONTROL, cp2520_pattern);
     382             :         else
     383             :                 /* pre-DCE11 can only generate CP2520 pattern 2 */
     384           0 :                 ASSERT(cp2520_pattern == 2);
     385             : 
     386             :         /* set link training complete */
     387           0 :         set_link_training_complete(enc10, true);
     388             : 
     389             :         /* disable video stream */
     390           0 :         REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0);
     391             : 
     392             :         /* Disable PHY Bypass mode to setup the test pattern */
     393           0 :         enable_phy_bypass_mode(enc10, false);
     394           0 : }
     395             : 
     396           0 : static void set_dp_phy_pattern_passthrough_mode(
     397             :         struct dcn10_link_encoder *enc10,
     398             :         enum dp_panel_mode panel_mode)
     399             : {
     400             :         /* program correct panel mode */
     401           0 :         setup_panel_mode(enc10, panel_mode);
     402             : 
     403             :         /* restore LINK_FRAMING_CNTL and DPHY_SCRAMBLER_BS_COUNT
     404             :          * in case we were doing HBR2 compliance pattern before
     405             :          */
     406           0 :         REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
     407             :                         DP_IDLE_BS_INTERVAL, 0x2000,
     408             :                         DP_VBID_DISABLE, 0,
     409             :                         DP_VID_ENHANCED_FRAME_MODE, 1);
     410             : 
     411           0 :         REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0x1FF);
     412             : 
     413             :         /* set link training complete */
     414           0 :         set_link_training_complete(enc10, true);
     415             : 
     416             :         /* Disable PHY Bypass mode to setup the test pattern */
     417           0 :         enable_phy_bypass_mode(enc10, false);
     418             : 
     419             :         /* Disable PRBS mode */
     420           0 :         disable_prbs_mode(enc10);
     421           0 : }
     422             : 
     423             : /* return value is bit-vector */
     424           0 : static uint8_t get_frontend_source(
     425             :         enum engine_id engine)
     426             : {
     427           0 :         switch (engine) {
     428             :         case ENGINE_ID_DIGA:
     429             :                 return DCN10_DIG_FE_SOURCE_SELECT_DIGA;
     430             :         case ENGINE_ID_DIGB:
     431           0 :                 return DCN10_DIG_FE_SOURCE_SELECT_DIGB;
     432             :         case ENGINE_ID_DIGC:
     433           0 :                 return DCN10_DIG_FE_SOURCE_SELECT_DIGC;
     434             :         case ENGINE_ID_DIGD:
     435           0 :                 return DCN10_DIG_FE_SOURCE_SELECT_DIGD;
     436             :         case ENGINE_ID_DIGE:
     437           0 :                 return DCN10_DIG_FE_SOURCE_SELECT_DIGE;
     438             :         case ENGINE_ID_DIGF:
     439           0 :                 return DCN10_DIG_FE_SOURCE_SELECT_DIGF;
     440             :         case ENGINE_ID_DIGG:
     441           0 :                 return DCN10_DIG_FE_SOURCE_SELECT_DIGG;
     442             :         default:
     443           0 :                 ASSERT_CRITICAL(false);
     444           0 :                 return DCN10_DIG_FE_SOURCE_SELECT_INVALID;
     445             :         }
     446             : }
     447             : 
     448           0 : unsigned int dcn10_get_dig_frontend(struct link_encoder *enc)
     449             : {
     450           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
     451             :         int32_t value;
     452             :         enum engine_id result;
     453             : 
     454           0 :         REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &value);
     455             : 
     456           0 :         switch (value) {
     457             :         case DCN10_DIG_FE_SOURCE_SELECT_DIGA:
     458             :                 result = ENGINE_ID_DIGA;
     459             :                 break;
     460             :         case DCN10_DIG_FE_SOURCE_SELECT_DIGB:
     461           0 :                 result = ENGINE_ID_DIGB;
     462           0 :                 break;
     463             :         case DCN10_DIG_FE_SOURCE_SELECT_DIGC:
     464           0 :                 result = ENGINE_ID_DIGC;
     465           0 :                 break;
     466             :         case DCN10_DIG_FE_SOURCE_SELECT_DIGD:
     467           0 :                 result = ENGINE_ID_DIGD;
     468           0 :                 break;
     469             :         case DCN10_DIG_FE_SOURCE_SELECT_DIGE:
     470           0 :                 result = ENGINE_ID_DIGE;
     471           0 :                 break;
     472             :         case DCN10_DIG_FE_SOURCE_SELECT_DIGF:
     473           0 :                 result = ENGINE_ID_DIGF;
     474           0 :                 break;
     475             :         case DCN10_DIG_FE_SOURCE_SELECT_DIGG:
     476           0 :                 result = ENGINE_ID_DIGG;
     477           0 :                 break;
     478             :         default:
     479             :                 // invalid source select DIG
     480           0 :                 result = ENGINE_ID_UNKNOWN;
     481             :         }
     482             : 
     483           0 :         return result;
     484             : 
     485             : }
     486             : 
     487           0 : void enc1_configure_encoder(
     488             :         struct dcn10_link_encoder *enc10,
     489             :         const struct dc_link_settings *link_settings)
     490             : {
     491             :         /* set number of lanes */
     492           0 :         REG_SET(DP_CONFIG, 0,
     493             :                         DP_UDI_LANES, link_settings->lane_count - LANE_COUNT_ONE);
     494             : 
     495             :         /* setup scrambler */
     496           0 :         REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1);
     497           0 : }
     498             : 
     499           0 : void dcn10_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
     500             :                         bool exit_link_training_required)
     501             : {
     502           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
     503             : 
     504           0 :         if (exit_link_training_required)
     505           0 :                 REG_UPDATE(DP_DPHY_FAST_TRAINING,
     506             :                                 DPHY_RX_FAST_TRAINING_CAPABLE, 1);
     507             :         else {
     508           0 :                 REG_UPDATE(DP_DPHY_FAST_TRAINING,
     509             :                                 DPHY_RX_FAST_TRAINING_CAPABLE, 0);
     510             :                 /*In DCE 11, we are able to pre-program a Force SR register
     511             :                  * to be able to trigger SR symbol after 5 idle patterns
     512             :                  * transmitted. Upon PSR Exit, DMCU can trigger
     513             :                  * DPHY_LOAD_BS_COUNT_START = 1. Upon writing 1 to
     514             :                  * DPHY_LOAD_BS_COUNT_START and the internal counter
     515             :                  * reaches DPHY_LOAD_BS_COUNT, the next BS symbol will be
     516             :                  * replaced by SR symbol once.
     517             :                  */
     518             : 
     519           0 :                 REG_UPDATE(DP_DPHY_BS_SR_SWAP_CNTL, DPHY_LOAD_BS_COUNT, 0x5);
     520             :         }
     521           0 : }
     522             : 
     523           0 : void dcn10_psr_program_secondary_packet(struct link_encoder *enc,
     524             :                         unsigned int sdp_transmit_line_num_deadline)
     525             : {
     526           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
     527             : 
     528           0 :         REG_UPDATE_2(DP_SEC_CNTL1,
     529             :                 DP_SEC_GSP0_LINE_NUM, sdp_transmit_line_num_deadline,
     530             :                 DP_SEC_GSP0_PRIORITY, 1);
     531           0 : }
     532             : 
     533           0 : bool dcn10_is_dig_enabled(struct link_encoder *enc)
     534             : {
     535           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
     536             :         uint32_t value;
     537             : 
     538           0 :         REG_GET(DIG_BE_EN_CNTL, DIG_ENABLE, &value);
     539           0 :         return value;
     540             : }
     541             : 
     542           0 : static void link_encoder_disable(struct dcn10_link_encoder *enc10)
     543             : {
     544             :         /* reset training pattern */
     545           0 :         REG_SET(DP_DPHY_TRAINING_PATTERN_SEL, 0,
     546             :                         DPHY_TRAINING_PATTERN_SEL, 0);
     547             : 
     548             :         /* reset training complete */
     549           0 :         REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0);
     550             : 
     551             :         /* reset panel mode */
     552           0 :         setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
     553           0 : }
     554             : 
     555           0 : static void hpd_initialize(
     556             :         struct dcn10_link_encoder *enc10)
     557             : {
     558             :         /* Associate HPD with DIG_BE */
     559           0 :         enum hpd_source_id hpd_source = enc10->base.hpd_source;
     560             : 
     561           0 :         REG_UPDATE(DIG_BE_CNTL, DIG_HPD_SELECT, hpd_source);
     562           0 : }
     563             : 
     564           0 : bool dcn10_link_encoder_validate_dvi_output(
     565             :         const struct dcn10_link_encoder *enc10,
     566             :         enum signal_type connector_signal,
     567             :         enum signal_type signal,
     568             :         const struct dc_crtc_timing *crtc_timing)
     569             : {
     570           0 :         uint32_t max_pixel_clock = TMDS_MAX_PIXEL_CLOCK;
     571             : 
     572           0 :         if (signal == SIGNAL_TYPE_DVI_DUAL_LINK)
     573           0 :                 max_pixel_clock *= 2;
     574             : 
     575             :         /* This handles the case of HDMI downgrade to DVI we don't want to
     576             :          * we don't want to cap the pixel clock if the DDI is not DVI.
     577             :          */
     578           0 :         if (connector_signal != SIGNAL_TYPE_DVI_DUAL_LINK &&
     579             :                         connector_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
     580           0 :                 max_pixel_clock = enc10->base.features.max_hdmi_pixel_clock;
     581             : 
     582             :         /* DVI only support RGB pixel encoding */
     583           0 :         if (crtc_timing->pixel_encoding != PIXEL_ENCODING_RGB)
     584             :                 return false;
     585             : 
     586             :         /*connect DVI via adpater's HDMI connector*/
     587           0 :         if ((connector_signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
     588           0 :                 connector_signal == SIGNAL_TYPE_HDMI_TYPE_A) &&
     589           0 :                 signal != SIGNAL_TYPE_HDMI_TYPE_A &&
     590           0 :                 crtc_timing->pix_clk_100hz > (TMDS_MAX_PIXEL_CLOCK * 10))
     591             :                 return false;
     592           0 :         if (crtc_timing->pix_clk_100hz < (TMDS_MIN_PIXEL_CLOCK * 10))
     593             :                 return false;
     594             : 
     595           0 :         if (crtc_timing->pix_clk_100hz > (max_pixel_clock * 10))
     596             :                 return false;
     597             : 
     598             :         /* DVI supports 6/8bpp single-link and 10/16bpp dual-link */
     599           0 :         switch (crtc_timing->display_color_depth) {
     600             :         case COLOR_DEPTH_666:
     601             :         case COLOR_DEPTH_888:
     602             :         break;
     603             :         case COLOR_DEPTH_101010:
     604             :         case COLOR_DEPTH_161616:
     605           0 :                 if (signal != SIGNAL_TYPE_DVI_DUAL_LINK)
     606             :                         return false;
     607             :         break;
     608             :         default:
     609             :                 return false;
     610             :         }
     611             : 
     612           0 :         return true;
     613             : }
     614             : 
     615           0 : static bool dcn10_link_encoder_validate_hdmi_output(
     616             :         const struct dcn10_link_encoder *enc10,
     617             :         const struct dc_crtc_timing *crtc_timing,
     618             :         const struct dc_edid_caps *edid_caps,
     619             :         int adjusted_pix_clk_100hz)
     620             : {
     621           0 :         enum dc_color_depth max_deep_color =
     622             :                         enc10->base.features.max_hdmi_deep_color;
     623             : 
     624             :         // check pixel clock against edid specified max TMDS clk
     625           0 :         if (edid_caps->max_tmds_clk_mhz != 0 &&
     626           0 :                         adjusted_pix_clk_100hz > edid_caps->max_tmds_clk_mhz * 10000)
     627             :                 return false;
     628             : 
     629           0 :         if (max_deep_color < crtc_timing->display_color_depth)
     630             :                 return false;
     631             : 
     632           0 :         if (crtc_timing->display_color_depth < COLOR_DEPTH_888)
     633             :                 return false;
     634           0 :         if (adjusted_pix_clk_100hz < (TMDS_MIN_PIXEL_CLOCK * 10))
     635             :                 return false;
     636             : 
     637           0 :         if ((adjusted_pix_clk_100hz == 0) ||
     638           0 :                 (adjusted_pix_clk_100hz > (enc10->base.features.max_hdmi_pixel_clock * 10)))
     639             :                 return false;
     640             : 
     641             :         /* DCE11 HW does not support 420 */
     642           0 :         if (!enc10->base.features.hdmi_ycbcr420_supported &&
     643           0 :                         crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
     644             :                 return false;
     645             : 
     646           0 :         if ((!enc10->base.features.flags.bits.HDMI_6GB_EN ||
     647           0 :                         enc10->base.ctx->dc->debug.hdmi20_disable) &&
     648             :                         adjusted_pix_clk_100hz >= 3000000)
     649             :                 return false;
     650           0 :         if (enc10->base.ctx->dc->debug.hdmi20_disable &&
     651           0 :                 crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
     652             :                 return false;
     653             :         return true;
     654             : }
     655             : 
     656           0 : bool dcn10_link_encoder_validate_dp_output(
     657             :         const struct dcn10_link_encoder *enc10,
     658             :         const struct dc_crtc_timing *crtc_timing)
     659             : {
     660           0 :         if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
     661           0 :                 if (!enc10->base.features.dp_ycbcr420_supported)
     662             :                         return false;
     663             :         }
     664             : 
     665           0 :         return true;
     666             : }
     667             : 
     668           0 : void dcn10_link_encoder_construct(
     669             :         struct dcn10_link_encoder *enc10,
     670             :         const struct encoder_init_data *init_data,
     671             :         const struct encoder_feature_support *enc_features,
     672             :         const struct dcn10_link_enc_registers *link_regs,
     673             :         const struct dcn10_link_enc_aux_registers *aux_regs,
     674             :         const struct dcn10_link_enc_hpd_registers *hpd_regs,
     675             :         const struct dcn10_link_enc_shift *link_shift,
     676             :         const struct dcn10_link_enc_mask *link_mask)
     677             : {
     678           0 :         struct bp_encoder_cap_info bp_cap_info = {0};
     679           0 :         const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
     680           0 :         enum bp_result result = BP_RESULT_OK;
     681             : 
     682           0 :         enc10->base.funcs = &dcn10_lnk_enc_funcs;
     683           0 :         enc10->base.ctx = init_data->ctx;
     684           0 :         enc10->base.id = init_data->encoder;
     685             : 
     686           0 :         enc10->base.hpd_source = init_data->hpd_source;
     687           0 :         enc10->base.connector = init_data->connector;
     688             : 
     689           0 :         enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
     690             : 
     691           0 :         enc10->base.features = *enc_features;
     692             : 
     693           0 :         enc10->base.transmitter = init_data->transmitter;
     694             : 
     695             :         /* set the flag to indicate whether driver poll the I2C data pin
     696             :          * while doing the DP sink detect
     697             :          */
     698             : 
     699             : /*      if (dal_adapter_service_is_feature_supported(as,
     700             :                 FEATURE_DP_SINK_DETECT_POLL_DATA_PIN))
     701             :                 enc10->base.features.flags.bits.
     702             :                         DP_SINK_DETECT_POLL_DATA_PIN = true;*/
     703             : 
     704           0 :         enc10->base.output_signals =
     705             :                 SIGNAL_TYPE_DVI_SINGLE_LINK |
     706             :                 SIGNAL_TYPE_DVI_DUAL_LINK |
     707             :                 SIGNAL_TYPE_LVDS |
     708             :                 SIGNAL_TYPE_DISPLAY_PORT |
     709             :                 SIGNAL_TYPE_DISPLAY_PORT_MST |
     710             :                 SIGNAL_TYPE_EDP |
     711             :                 SIGNAL_TYPE_HDMI_TYPE_A;
     712             : 
     713             :         /* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE.
     714             :          * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY.
     715             :          * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer
     716             :          * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS.
     717             :          * Prefer DIG assignment is decided by board design.
     718             :          * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design
     719             :          * and VBIOS will filter out 7 UNIPHY for DCE 8.0.
     720             :          * By this, adding DIGG should not hurt DCE 8.0.
     721             :          * This will let DCE 8.1 share DCE 8.0 as much as possible
     722             :          */
     723             : 
     724           0 :         enc10->link_regs = link_regs;
     725           0 :         enc10->aux_regs = aux_regs;
     726           0 :         enc10->hpd_regs = hpd_regs;
     727           0 :         enc10->link_shift = link_shift;
     728           0 :         enc10->link_mask = link_mask;
     729             : 
     730           0 :         switch (enc10->base.transmitter) {
     731             :         case TRANSMITTER_UNIPHY_A:
     732           0 :                 enc10->base.preferred_engine = ENGINE_ID_DIGA;
     733           0 :         break;
     734             :         case TRANSMITTER_UNIPHY_B:
     735           0 :                 enc10->base.preferred_engine = ENGINE_ID_DIGB;
     736           0 :         break;
     737             :         case TRANSMITTER_UNIPHY_C:
     738           0 :                 enc10->base.preferred_engine = ENGINE_ID_DIGC;
     739           0 :         break;
     740             :         case TRANSMITTER_UNIPHY_D:
     741           0 :                 enc10->base.preferred_engine = ENGINE_ID_DIGD;
     742           0 :         break;
     743             :         case TRANSMITTER_UNIPHY_E:
     744           0 :                 enc10->base.preferred_engine = ENGINE_ID_DIGE;
     745           0 :         break;
     746             :         case TRANSMITTER_UNIPHY_F:
     747           0 :                 enc10->base.preferred_engine = ENGINE_ID_DIGF;
     748           0 :         break;
     749             :         case TRANSMITTER_UNIPHY_G:
     750           0 :                 enc10->base.preferred_engine = ENGINE_ID_DIGG;
     751           0 :         break;
     752             :         default:
     753           0 :                 ASSERT_CRITICAL(false);
     754           0 :                 enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
     755             :         }
     756             : 
     757             :         /* default to one to mirror Windows behavior */
     758           0 :         enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
     759             : 
     760           0 :         result = bp_funcs->get_encoder_cap_info(enc10->base.ctx->dc_bios,
     761             :                                                 enc10->base.id, &bp_cap_info);
     762             : 
     763             :         /* Override features with DCE-specific values */
     764           0 :         if (result == BP_RESULT_OK) {
     765           0 :                 enc10->base.features.flags.bits.IS_HBR2_CAPABLE =
     766           0 :                                 bp_cap_info.DP_HBR2_EN;
     767           0 :                 enc10->base.features.flags.bits.IS_HBR3_CAPABLE =
     768           0 :                                 bp_cap_info.DP_HBR3_EN;
     769           0 :                 enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
     770           0 :                 enc10->base.features.flags.bits.DP_IS_USB_C =
     771           0 :                                 bp_cap_info.DP_IS_USB_C;
     772             :         } else {
     773           0 :                 DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
     774             :                                 __func__,
     775             :                                 result);
     776             :         }
     777           0 :         if (enc10->base.ctx->dc->debug.hdmi20_disable) {
     778           0 :                 enc10->base.features.flags.bits.HDMI_6GB_EN = 0;
     779             :         }
     780           0 : }
     781             : 
     782           0 : bool dcn10_link_encoder_validate_output_with_stream(
     783             :         struct link_encoder *enc,
     784             :         const struct dc_stream_state *stream)
     785             : {
     786           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
     787             :         bool is_valid;
     788             : 
     789             :         //if SCDC (340-600MHz) is disabled, set to HDMI 1.4 timing limit
     790           0 :         if (stream->sink->edid_caps.panel_patch.skip_scdc_overwrite &&
     791           0 :                 enc10->base.features.max_hdmi_pixel_clock > 300000)
     792           0 :                 enc10->base.features.max_hdmi_pixel_clock = 300000;
     793             : 
     794           0 :         switch (stream->signal) {
     795             :         case SIGNAL_TYPE_DVI_SINGLE_LINK:
     796             :         case SIGNAL_TYPE_DVI_DUAL_LINK:
     797           0 :                 is_valid = dcn10_link_encoder_validate_dvi_output(
     798             :                         enc10,
     799           0 :                         stream->link->connector_signal,
     800             :                         stream->signal,
     801             :                         &stream->timing);
     802           0 :         break;
     803             :         case SIGNAL_TYPE_HDMI_TYPE_A:
     804           0 :                 is_valid = dcn10_link_encoder_validate_hdmi_output(
     805             :                                 enc10,
     806             :                                 &stream->timing,
     807           0 :                                 &stream->sink->edid_caps,
     808           0 :                                 stream->phy_pix_clk * 10);
     809           0 :         break;
     810             :         case SIGNAL_TYPE_DISPLAY_PORT:
     811             :         case SIGNAL_TYPE_DISPLAY_PORT_MST:
     812           0 :                 is_valid = dcn10_link_encoder_validate_dp_output(
     813             :                                         enc10, &stream->timing);
     814             :         break;
     815             :         case SIGNAL_TYPE_EDP:
     816           0 :                 is_valid = (stream->timing.pixel_encoding == PIXEL_ENCODING_RGB) ? true : false;
     817           0 :         break;
     818             :         case SIGNAL_TYPE_VIRTUAL:
     819             :                 is_valid = true;
     820             :                 break;
     821             :         default:
     822           0 :                 is_valid = false;
     823           0 :         break;
     824             :         }
     825             : 
     826           0 :         return is_valid;
     827             : }
     828             : 
     829           0 : void dcn10_link_encoder_hw_init(
     830             :         struct link_encoder *enc)
     831             : {
     832           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
     833           0 :         struct bp_transmitter_control cntl = { 0 };
     834             :         enum bp_result result;
     835             : 
     836           0 :         cntl.action = TRANSMITTER_CONTROL_INIT;
     837           0 :         cntl.engine_id = ENGINE_ID_UNKNOWN;
     838           0 :         cntl.transmitter = enc10->base.transmitter;
     839           0 :         cntl.connector_obj_id = enc10->base.connector;
     840           0 :         cntl.lanes_number = LANE_COUNT_FOUR;
     841             :         cntl.coherent = false;
     842           0 :         cntl.hpd_sel = enc10->base.hpd_source;
     843             : 
     844           0 :         if (enc10->base.connector.id == CONNECTOR_ID_EDP)
     845           0 :                 cntl.signal = SIGNAL_TYPE_EDP;
     846             : 
     847           0 :         result = link_transmitter_control(enc10, &cntl);
     848             : 
     849           0 :         if (result != BP_RESULT_OK) {
     850           0 :                 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
     851             :                         __func__);
     852           0 :                 BREAK_TO_DEBUGGER();
     853           0 :                 return;
     854             :         }
     855             : 
     856           0 :         if (enc10->base.connector.id == CONNECTOR_ID_LVDS) {
     857           0 :                 cntl.action = TRANSMITTER_CONTROL_BACKLIGHT_BRIGHTNESS;
     858             : 
     859           0 :                 result = link_transmitter_control(enc10, &cntl);
     860             : 
     861           0 :                 ASSERT(result == BP_RESULT_OK);
     862             : 
     863             :         }
     864           0 :         dcn10_aux_initialize(enc10);
     865             : 
     866             :         /* reinitialize HPD.
     867             :          * hpd_initialize() will pass DIG_FE id to HW context.
     868             :          * All other routine within HW context will use fe_engine_offset
     869             :          * as DIG_FE id even caller pass DIG_FE id.
     870             :          * So this routine must be called first.
     871             :          */
     872           0 :         hpd_initialize(enc10);
     873             : }
     874             : 
     875           0 : void dcn10_link_encoder_destroy(struct link_encoder **enc)
     876             : {
     877           0 :         kfree(TO_DCN10_LINK_ENC(*enc));
     878           0 :         *enc = NULL;
     879           0 : }
     880             : 
     881           0 : void dcn10_link_encoder_setup(
     882             :         struct link_encoder *enc,
     883             :         enum signal_type signal)
     884             : {
     885           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
     886             : 
     887           0 :         switch (signal) {
     888             :         case SIGNAL_TYPE_EDP:
     889             :         case SIGNAL_TYPE_DISPLAY_PORT:
     890             :                 /* DP SST */
     891           0 :                 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 0);
     892           0 :                 break;
     893             :         case SIGNAL_TYPE_LVDS:
     894             :                 /* LVDS */
     895           0 :                 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 1);
     896           0 :                 break;
     897             :         case SIGNAL_TYPE_DVI_SINGLE_LINK:
     898             :         case SIGNAL_TYPE_DVI_DUAL_LINK:
     899             :                 /* TMDS-DVI */
     900           0 :                 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 2);
     901           0 :                 break;
     902             :         case SIGNAL_TYPE_HDMI_TYPE_A:
     903             :                 /* TMDS-HDMI */
     904           0 :                 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 3);
     905           0 :                 break;
     906             :         case SIGNAL_TYPE_DISPLAY_PORT_MST:
     907             :                 /* DP MST */
     908           0 :                 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 5);
     909           0 :                 break;
     910             :         default:
     911           0 :                 ASSERT_CRITICAL(false);
     912             :                 /* invalid mode ! */
     913           0 :                 break;
     914             :         }
     915             : 
     916           0 : }
     917             : 
     918             : /* TODO: still need depth or just pass in adjusted pixel clock? */
     919           0 : void dcn10_link_encoder_enable_tmds_output(
     920             :         struct link_encoder *enc,
     921             :         enum clock_source_id clock_source,
     922             :         enum dc_color_depth color_depth,
     923             :         enum signal_type signal,
     924             :         uint32_t pixel_clock)
     925             : {
     926           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
     927           0 :         struct bp_transmitter_control cntl = { 0 };
     928             :         enum bp_result result;
     929             : 
     930             :         /* Enable the PHY */
     931             : 
     932           0 :         cntl.action = TRANSMITTER_CONTROL_ENABLE;
     933           0 :         cntl.engine_id = enc->preferred_engine;
     934           0 :         cntl.transmitter = enc10->base.transmitter;
     935           0 :         cntl.pll_id = clock_source;
     936           0 :         cntl.signal = signal;
     937           0 :         if (cntl.signal == SIGNAL_TYPE_DVI_DUAL_LINK)
     938           0 :                 cntl.lanes_number = 8;
     939             :         else
     940           0 :                 cntl.lanes_number = 4;
     941             : 
     942           0 :         cntl.hpd_sel = enc10->base.hpd_source;
     943             : 
     944           0 :         cntl.pixel_clock = pixel_clock;
     945           0 :         cntl.color_depth = color_depth;
     946             : 
     947           0 :         result = link_transmitter_control(enc10, &cntl);
     948             : 
     949           0 :         if (result != BP_RESULT_OK) {
     950           0 :                 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
     951             :                         __func__);
     952           0 :                 BREAK_TO_DEBUGGER();
     953             :         }
     954           0 : }
     955             : 
     956           0 : void dcn10_link_encoder_enable_tmds_output_with_clk_pattern_wa(
     957             :         struct link_encoder *enc,
     958             :         enum clock_source_id clock_source,
     959             :         enum dc_color_depth color_depth,
     960             :         enum signal_type signal,
     961             :         uint32_t pixel_clock)
     962             : {
     963           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
     964             : 
     965           0 :         dcn10_link_encoder_enable_tmds_output(
     966             :                 enc, clock_source, color_depth, signal, pixel_clock);
     967             : 
     968           0 :         REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F);
     969           0 : }
     970             : 
     971             : /* enables DP PHY output */
     972           0 : void dcn10_link_encoder_enable_dp_output(
     973             :         struct link_encoder *enc,
     974             :         const struct dc_link_settings *link_settings,
     975             :         enum clock_source_id clock_source)
     976             : {
     977           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
     978           0 :         struct bp_transmitter_control cntl = { 0 };
     979             :         enum bp_result result;
     980             : 
     981             :         /* Enable the PHY */
     982             : 
     983             :         /* number_of_lanes is used for pixel clock adjust,
     984             :          * but it's not passed to asic_control.
     985             :          * We need to set number of lanes manually.
     986             :          */
     987           0 :         enc1_configure_encoder(enc10, link_settings);
     988             : 
     989           0 :         cntl.action = TRANSMITTER_CONTROL_ENABLE;
     990           0 :         cntl.engine_id = enc->preferred_engine;
     991           0 :         cntl.transmitter = enc10->base.transmitter;
     992           0 :         cntl.pll_id = clock_source;
     993           0 :         cntl.signal = SIGNAL_TYPE_DISPLAY_PORT;
     994           0 :         cntl.lanes_number = link_settings->lane_count;
     995           0 :         cntl.hpd_sel = enc10->base.hpd_source;
     996           0 :         cntl.pixel_clock = link_settings->link_rate
     997           0 :                                                 * LINK_RATE_REF_FREQ_IN_KHZ;
     998             :         /* TODO: check if undefined works */
     999           0 :         cntl.color_depth = COLOR_DEPTH_UNDEFINED;
    1000             : 
    1001           0 :         result = link_transmitter_control(enc10, &cntl);
    1002             : 
    1003           0 :         if (result != BP_RESULT_OK) {
    1004           0 :                 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
    1005             :                         __func__);
    1006           0 :                 BREAK_TO_DEBUGGER();
    1007             :         }
    1008           0 : }
    1009             : 
    1010             : /* enables DP PHY output in MST mode */
    1011           0 : void dcn10_link_encoder_enable_dp_mst_output(
    1012             :         struct link_encoder *enc,
    1013             :         const struct dc_link_settings *link_settings,
    1014             :         enum clock_source_id clock_source)
    1015             : {
    1016           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
    1017           0 :         struct bp_transmitter_control cntl = { 0 };
    1018             :         enum bp_result result;
    1019             : 
    1020             :         /* Enable the PHY */
    1021             : 
    1022             :         /* number_of_lanes is used for pixel clock adjust,
    1023             :          * but it's not passed to asic_control.
    1024             :          * We need to set number of lanes manually.
    1025             :          */
    1026           0 :         enc1_configure_encoder(enc10, link_settings);
    1027             : 
    1028           0 :         cntl.action = TRANSMITTER_CONTROL_ENABLE;
    1029           0 :         cntl.engine_id = ENGINE_ID_UNKNOWN;
    1030           0 :         cntl.transmitter = enc10->base.transmitter;
    1031           0 :         cntl.pll_id = clock_source;
    1032           0 :         cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
    1033           0 :         cntl.lanes_number = link_settings->lane_count;
    1034           0 :         cntl.hpd_sel = enc10->base.hpd_source;
    1035           0 :         cntl.pixel_clock = link_settings->link_rate
    1036           0 :                                                 * LINK_RATE_REF_FREQ_IN_KHZ;
    1037             :         /* TODO: check if undefined works */
    1038           0 :         cntl.color_depth = COLOR_DEPTH_UNDEFINED;
    1039             : 
    1040           0 :         result = link_transmitter_control(enc10, &cntl);
    1041             : 
    1042           0 :         if (result != BP_RESULT_OK) {
    1043           0 :                 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
    1044             :                         __func__);
    1045           0 :                 BREAK_TO_DEBUGGER();
    1046             :         }
    1047           0 : }
    1048             : /*
    1049             :  * @brief
    1050             :  * Disable transmitter and its encoder
    1051             :  */
    1052           0 : void dcn10_link_encoder_disable_output(
    1053             :         struct link_encoder *enc,
    1054             :         enum signal_type signal)
    1055             : {
    1056           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
    1057           0 :         struct bp_transmitter_control cntl = { 0 };
    1058             :         enum bp_result result;
    1059             : 
    1060           0 :         if (!dcn10_is_dig_enabled(enc)) {
    1061             :                 /* OF_SKIP_POWER_DOWN_INACTIVE_ENCODER */
    1062             :         /*in DP_Alt_No_Connect case, we turn off the dig already,
    1063             :         after excuation the PHY w/a sequence, not allow touch PHY any more*/
    1064           0 :                 return;
    1065             :         }
    1066             :         /* Power-down RX and disable GPU PHY should be paired.
    1067             :          * Disabling PHY without powering down RX may cause
    1068             :          * symbol lock loss, on which we will get DP Sink interrupt.
    1069             :          */
    1070             : 
    1071             :         /* There is a case for the DP active dongles
    1072             :          * where we want to disable the PHY but keep RX powered,
    1073             :          * for those we need to ignore DP Sink interrupt
    1074             :          * by checking lane count that has been set
    1075             :          * on the last do_enable_output().
    1076             :          */
    1077             : 
    1078             :         /* disable transmitter */
    1079           0 :         cntl.action = TRANSMITTER_CONTROL_DISABLE;
    1080           0 :         cntl.transmitter = enc10->base.transmitter;
    1081           0 :         cntl.hpd_sel = enc10->base.hpd_source;
    1082           0 :         cntl.signal = signal;
    1083           0 :         cntl.connector_obj_id = enc10->base.connector;
    1084             : 
    1085           0 :         result = link_transmitter_control(enc10, &cntl);
    1086             : 
    1087           0 :         if (result != BP_RESULT_OK) {
    1088           0 :                 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
    1089             :                         __func__);
    1090           0 :                 BREAK_TO_DEBUGGER();
    1091           0 :                 return;
    1092             :         }
    1093             : 
    1094             :         /* disable encoder */
    1095           0 :         if (dc_is_dp_signal(signal))
    1096           0 :                 link_encoder_disable(enc10);
    1097             : }
    1098             : 
    1099           0 : void dcn10_link_encoder_dp_set_lane_settings(
    1100             :         struct link_encoder *enc,
    1101             :         const struct dc_link_settings *link_settings,
    1102             :         const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
    1103             : {
    1104           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
    1105           0 :         union dpcd_training_lane_set training_lane_set = { { 0 } };
    1106           0 :         int32_t lane = 0;
    1107           0 :         struct bp_transmitter_control cntl = { 0 };
    1108             : 
    1109           0 :         if (!link_settings) {
    1110           0 :                 BREAK_TO_DEBUGGER();
    1111           0 :                 return;
    1112             :         }
    1113             : 
    1114           0 :         cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS;
    1115           0 :         cntl.transmitter = enc10->base.transmitter;
    1116           0 :         cntl.connector_obj_id = enc10->base.connector;
    1117           0 :         cntl.lanes_number = link_settings->lane_count;
    1118           0 :         cntl.hpd_sel = enc10->base.hpd_source;
    1119           0 :         cntl.pixel_clock = link_settings->link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
    1120             : 
    1121           0 :         for (lane = 0; lane < link_settings->lane_count; lane++) {
    1122             :                 /* translate lane settings */
    1123             : 
    1124           0 :                 training_lane_set.bits.VOLTAGE_SWING_SET =
    1125           0 :                                 lane_settings[lane].VOLTAGE_SWING;
    1126           0 :                 training_lane_set.bits.PRE_EMPHASIS_SET =
    1127           0 :                                 lane_settings[lane].PRE_EMPHASIS;
    1128             : 
    1129             :                 /* post cursor 2 setting only applies to HBR2 link rate */
    1130           0 :                 if (link_settings->link_rate == LINK_RATE_HIGH2) {
    1131             :                         /* this is passed to VBIOS
    1132             :                          * to program post cursor 2 level
    1133             :                          */
    1134           0 :                         training_lane_set.bits.POST_CURSOR2_SET =
    1135           0 :                                         lane_settings[lane].POST_CURSOR2;
    1136             :                 }
    1137             : 
    1138           0 :                 cntl.lane_select = lane;
    1139           0 :                 cntl.lane_settings = training_lane_set.raw;
    1140             : 
    1141             :                 /* call VBIOS table to set voltage swing and pre-emphasis */
    1142           0 :                 link_transmitter_control(enc10, &cntl);
    1143             :         }
    1144             : }
    1145             : 
    1146             : /* set DP PHY test and training patterns */
    1147           0 : void dcn10_link_encoder_dp_set_phy_pattern(
    1148             :         struct link_encoder *enc,
    1149             :         const struct encoder_set_dp_phy_pattern_param *param)
    1150             : {
    1151           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
    1152             : 
    1153           0 :         switch (param->dp_phy_pattern) {
    1154             :         case DP_TEST_PATTERN_TRAINING_PATTERN1:
    1155           0 :                 dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 0);
    1156           0 :                 break;
    1157             :         case DP_TEST_PATTERN_TRAINING_PATTERN2:
    1158           0 :                 dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 1);
    1159           0 :                 break;
    1160             :         case DP_TEST_PATTERN_TRAINING_PATTERN3:
    1161           0 :                 dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 2);
    1162           0 :                 break;
    1163             :         case DP_TEST_PATTERN_TRAINING_PATTERN4:
    1164           0 :                 dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 3);
    1165           0 :                 break;
    1166             :         case DP_TEST_PATTERN_D102:
    1167           0 :                 set_dp_phy_pattern_d102(enc10);
    1168           0 :                 break;
    1169             :         case DP_TEST_PATTERN_SYMBOL_ERROR:
    1170           0 :                 set_dp_phy_pattern_symbol_error(enc10);
    1171           0 :                 break;
    1172             :         case DP_TEST_PATTERN_PRBS7:
    1173           0 :                 set_dp_phy_pattern_prbs7(enc10);
    1174           0 :                 break;
    1175             :         case DP_TEST_PATTERN_80BIT_CUSTOM:
    1176           0 :                 set_dp_phy_pattern_80bit_custom(
    1177             :                         enc10, param->custom_pattern);
    1178           0 :                 break;
    1179             :         case DP_TEST_PATTERN_CP2520_1:
    1180           0 :                 set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 1);
    1181           0 :                 break;
    1182             :         case DP_TEST_PATTERN_CP2520_2:
    1183           0 :                 set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 2);
    1184           0 :                 break;
    1185             :         case DP_TEST_PATTERN_CP2520_3:
    1186           0 :                 set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 3);
    1187           0 :                 break;
    1188             :         case DP_TEST_PATTERN_VIDEO_MODE: {
    1189           0 :                 set_dp_phy_pattern_passthrough_mode(
    1190             :                         enc10, param->dp_panel_mode);
    1191           0 :                 break;
    1192             :         }
    1193             : 
    1194             :         default:
    1195             :                 /* invalid phy pattern */
    1196           0 :                 ASSERT_CRITICAL(false);
    1197           0 :                 break;
    1198             :         }
    1199           0 : }
    1200             : 
    1201             : static void fill_stream_allocation_row_info(
    1202             :         const struct link_mst_stream_allocation *stream_allocation,
    1203             :         uint32_t *src,
    1204             :         uint32_t *slots)
    1205             : {
    1206           0 :         const struct stream_encoder *stream_enc = stream_allocation->stream_enc;
    1207             : 
    1208           0 :         if (stream_enc) {
    1209           0 :                 *src = stream_enc->id;
    1210           0 :                 *slots = stream_allocation->slot_count;
    1211             :         } else {
    1212             :                 *src = 0;
    1213             :                 *slots = 0;
    1214             :         }
    1215             : }
    1216             : 
    1217             : /* programs DP MST VC payload allocation */
    1218           0 : void dcn10_link_encoder_update_mst_stream_allocation_table(
    1219             :         struct link_encoder *enc,
    1220             :         const struct link_mst_stream_allocation_table *table)
    1221             : {
    1222           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
    1223           0 :         uint32_t value0 = 0;
    1224           0 :         uint32_t value1 = 0;
    1225           0 :         uint32_t value2 = 0;
    1226           0 :         uint32_t slots = 0;
    1227           0 :         uint32_t src = 0;
    1228           0 :         uint32_t retries = 0;
    1229             : 
    1230             :         /* For CZ, there are only 3 pipes. So Virtual channel is up 3.*/
    1231             : 
    1232             :         /* --- Set MSE Stream Attribute -
    1233             :          * Setup VC Payload Table on Tx Side,
    1234             :          * Issue allocation change trigger
    1235             :          * to commit payload on both tx and rx side
    1236             :          */
    1237             : 
    1238             :         /* we should clean-up table each time */
    1239             : 
    1240           0 :         if (table->stream_count >= 1) {
    1241           0 :                 fill_stream_allocation_row_info(
    1242             :                         &table->stream_allocations[0],
    1243             :                         &src,
    1244             :                         &slots);
    1245             :         } else {
    1246             :                 src = 0;
    1247             :                 slots = 0;
    1248             :         }
    1249             : 
    1250           0 :         REG_UPDATE_2(DP_MSE_SAT0,
    1251             :                         DP_MSE_SAT_SRC0, src,
    1252             :                         DP_MSE_SAT_SLOT_COUNT0, slots);
    1253             : 
    1254           0 :         if (table->stream_count >= 2) {
    1255           0 :                 fill_stream_allocation_row_info(
    1256             :                         &table->stream_allocations[1],
    1257             :                         &src,
    1258             :                         &slots);
    1259             :         } else {
    1260             :                 src = 0;
    1261             :                 slots = 0;
    1262             :         }
    1263             : 
    1264           0 :         REG_UPDATE_2(DP_MSE_SAT0,
    1265             :                         DP_MSE_SAT_SRC1, src,
    1266             :                         DP_MSE_SAT_SLOT_COUNT1, slots);
    1267             : 
    1268           0 :         if (table->stream_count >= 3) {
    1269           0 :                 fill_stream_allocation_row_info(
    1270             :                         &table->stream_allocations[2],
    1271             :                         &src,
    1272             :                         &slots);
    1273             :         } else {
    1274             :                 src = 0;
    1275             :                 slots = 0;
    1276             :         }
    1277             : 
    1278           0 :         REG_UPDATE_2(DP_MSE_SAT1,
    1279             :                         DP_MSE_SAT_SRC2, src,
    1280             :                         DP_MSE_SAT_SLOT_COUNT2, slots);
    1281             : 
    1282           0 :         if (table->stream_count >= 4) {
    1283           0 :                 fill_stream_allocation_row_info(
    1284             :                         &table->stream_allocations[3],
    1285             :                         &src,
    1286             :                         &slots);
    1287             :         } else {
    1288             :                 src = 0;
    1289             :                 slots = 0;
    1290             :         }
    1291             : 
    1292           0 :         REG_UPDATE_2(DP_MSE_SAT1,
    1293             :                         DP_MSE_SAT_SRC3, src,
    1294             :                         DP_MSE_SAT_SLOT_COUNT3, slots);
    1295             : 
    1296             :         /* --- wait for transaction finish */
    1297             : 
    1298             :         /* send allocation change trigger (ACT) ?
    1299             :          * this step first sends the ACT,
    1300             :          * then double buffers the SAT into the hardware
    1301             :          * making the new allocation active on the DP MST mode link
    1302             :          */
    1303             : 
    1304             :         /* DP_MSE_SAT_UPDATE:
    1305             :          * 0 - No Action
    1306             :          * 1 - Update SAT with trigger
    1307             :          * 2 - Update SAT without trigger
    1308             :          */
    1309           0 :         REG_UPDATE(DP_MSE_SAT_UPDATE,
    1310             :                         DP_MSE_SAT_UPDATE, 1);
    1311             : 
    1312             :         /* wait for update to complete
    1313             :          * (i.e. DP_MSE_SAT_UPDATE field is reset to 0)
    1314             :          * then wait for the transmission
    1315             :          * of at least 16 MTP headers on immediate local link.
    1316             :          * i.e. DP_MSE_16_MTP_KEEPOUT field (read only) is reset to 0
    1317             :          * a value of 1 indicates that DP MST mode
    1318             :          * is in the 16 MTP keepout region after a VC has been added.
    1319             :          * MST stream bandwidth (VC rate) can be configured
    1320             :          * after this bit is cleared
    1321             :          */
    1322             :         do {
    1323           0 :                 udelay(10);
    1324             : 
    1325           0 :                 value0 = REG_READ(DP_MSE_SAT_UPDATE);
    1326             : 
    1327           0 :                 REG_GET(DP_MSE_SAT_UPDATE,
    1328             :                                 DP_MSE_SAT_UPDATE, &value1);
    1329             : 
    1330           0 :                 REG_GET(DP_MSE_SAT_UPDATE,
    1331             :                                 DP_MSE_16_MTP_KEEPOUT, &value2);
    1332             : 
    1333             :                 /* bit field DP_MSE_SAT_UPDATE is set to 1 already */
    1334           0 :                 if (!value1 && !value2)
    1335             :                         break;
    1336           0 :                 ++retries;
    1337           0 :         } while (retries < DP_MST_UPDATE_MAX_RETRY);
    1338           0 : }
    1339             : 
    1340           0 : void dcn10_link_encoder_connect_dig_be_to_fe(
    1341             :         struct link_encoder *enc,
    1342             :         enum engine_id engine,
    1343             :         bool connect)
    1344             : {
    1345           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
    1346             :         uint32_t field;
    1347             : 
    1348           0 :         if (engine != ENGINE_ID_UNKNOWN) {
    1349             : 
    1350           0 :                 REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &field);
    1351             : 
    1352           0 :                 if (connect)
    1353           0 :                         field |= get_frontend_source(engine);
    1354             :                 else
    1355           0 :                         field &= ~get_frontend_source(engine);
    1356             : 
    1357           0 :                 REG_UPDATE(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, field);
    1358             :         }
    1359           0 : }
    1360             : 
    1361             : 
    1362             : #define HPD_REG(reg)\
    1363             :         (enc10->hpd_regs->reg)
    1364             : 
    1365             : #define HPD_REG_READ(reg_name) \
    1366             :                 dm_read_reg(CTX, HPD_REG(reg_name))
    1367             : 
    1368             : #define HPD_REG_UPDATE_N(reg_name, n, ...)      \
    1369             :                 generic_reg_update_ex(CTX, \
    1370             :                                 HPD_REG(reg_name), \
    1371             :                                 n, __VA_ARGS__)
    1372             : 
    1373             : #define HPD_REG_UPDATE(reg_name, field, val)    \
    1374             :                 HPD_REG_UPDATE_N(reg_name, 1, \
    1375             :                                 FN(reg_name, field), val)
    1376             : 
    1377           0 : void dcn10_link_encoder_enable_hpd(struct link_encoder *enc)
    1378             : {
    1379           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
    1380             : 
    1381           0 :         HPD_REG_UPDATE(DC_HPD_CONTROL,
    1382             :                         DC_HPD_EN, 1);
    1383           0 : }
    1384             : 
    1385           0 : void dcn10_link_encoder_disable_hpd(struct link_encoder *enc)
    1386             : {
    1387           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
    1388             : 
    1389           0 :         HPD_REG_UPDATE(DC_HPD_CONTROL,
    1390             :                         DC_HPD_EN, 0);
    1391           0 : }
    1392             : 
    1393             : #define AUX_REG(reg)\
    1394             :         (enc10->aux_regs->reg)
    1395             : 
    1396             : #define AUX_REG_READ(reg_name) \
    1397             :                 dm_read_reg(CTX, AUX_REG(reg_name))
    1398             : 
    1399             : #define AUX_REG_UPDATE_N(reg_name, n, ...)      \
    1400             :                 generic_reg_update_ex(CTX, \
    1401             :                                 AUX_REG(reg_name), \
    1402             :                                 n, __VA_ARGS__)
    1403             : 
    1404             : #define AUX_REG_UPDATE(reg_name, field, val)    \
    1405             :                 AUX_REG_UPDATE_N(reg_name, 1, \
    1406             :                                 FN(reg_name, field), val)
    1407             : 
    1408             : #define AUX_REG_UPDATE_2(reg, f1, v1, f2, v2)   \
    1409             :                 AUX_REG_UPDATE_N(reg, 2,\
    1410             :                                 FN(reg, f1), v1,\
    1411             :                                 FN(reg, f2), v2)
    1412             : 
    1413           0 : void dcn10_aux_initialize(struct dcn10_link_encoder *enc10)
    1414             : {
    1415           0 :         enum hpd_source_id hpd_source = enc10->base.hpd_source;
    1416             : 
    1417           0 :         AUX_REG_UPDATE_2(AUX_CONTROL,
    1418             :                         AUX_HPD_SEL, hpd_source,
    1419             :                         AUX_LS_READ_EN, 0);
    1420             : 
    1421             :         /* 1/4 window (the maximum allowed) */
    1422           0 :         AUX_REG_UPDATE(AUX_DPHY_RX_CONTROL0,
    1423             :                         AUX_RX_RECEIVE_WINDOW, 0);
    1424           0 : }
    1425             : 
    1426           0 : enum signal_type dcn10_get_dig_mode(
    1427             :         struct link_encoder *enc)
    1428             : {
    1429           0 :         struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
    1430             :         uint32_t value;
    1431           0 :         REG_GET(DIG_BE_CNTL, DIG_MODE, &value);
    1432           0 :         switch (value) {
    1433             :         case 1:
    1434             :                 return SIGNAL_TYPE_DISPLAY_PORT;
    1435             :         case 2:
    1436             :                 return SIGNAL_TYPE_DVI_SINGLE_LINK;
    1437             :         case 3:
    1438             :                 return SIGNAL_TYPE_HDMI_TYPE_A;
    1439             :         case 5:
    1440             :                 return SIGNAL_TYPE_DISPLAY_PORT_MST;
    1441             :         default:
    1442             :                 return SIGNAL_TYPE_NONE;
    1443             :         }
    1444             :         return SIGNAL_TYPE_NONE;
    1445             : }
    1446             : 
    1447           0 : void dcn10_link_encoder_get_max_link_cap(struct link_encoder *enc,
    1448             :         struct dc_link_settings *link_settings)
    1449             : {
    1450             :         /* Set Default link settings */
    1451           0 :         struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
    1452             :                         LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
    1453             : 
    1454             :         /* Higher link settings based on feature supported */
    1455           0 :         if (enc->features.flags.bits.IS_HBR2_CAPABLE)
    1456           0 :                 max_link_cap.link_rate = LINK_RATE_HIGH2;
    1457             : 
    1458           0 :         if (enc->features.flags.bits.IS_HBR3_CAPABLE)
    1459           0 :                 max_link_cap.link_rate = LINK_RATE_HIGH3;
    1460             : 
    1461           0 :         if (enc->features.flags.bits.IS_UHBR10_CAPABLE)
    1462           0 :                 max_link_cap.link_rate = LINK_RATE_UHBR10;
    1463             : 
    1464           0 :         if (enc->features.flags.bits.IS_UHBR13_5_CAPABLE)
    1465           0 :                 max_link_cap.link_rate = LINK_RATE_UHBR13_5;
    1466             : 
    1467           0 :         if (enc->features.flags.bits.IS_UHBR20_CAPABLE)
    1468           0 :                 max_link_cap.link_rate = LINK_RATE_UHBR20;
    1469             : 
    1470           0 :         *link_settings = max_link_cap;
    1471           0 : }

Generated by: LCOV version 1.14