Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2012-15 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 #include "reg_helper.h"
0027 
0028 #include "core_types.h"
0029 #include "link_encoder.h"
0030 #include "dcn10_link_encoder.h"
0031 #include "stream_encoder.h"
0032 #include "i2caux_interface.h"
0033 #include "dc_bios_types.h"
0034 
0035 #include "gpio_service_interface.h"
0036 
0037 #define CTX \
0038     enc10->base.ctx
0039 #define DC_LOGGER \
0040     enc10->base.ctx->logger
0041 
0042 #define REG(reg)\
0043     (enc10->link_regs->reg)
0044 
0045 #undef FN
0046 #define FN(reg_name, field_name) \
0047     enc10->link_shift->field_name, enc10->link_mask->field_name
0048 
0049 
0050 /*
0051  * @brief
0052  * Trigger Source Select
0053  * ASIC-dependent, actual values for register programming
0054  */
0055 #define DCN10_DIG_FE_SOURCE_SELECT_INVALID 0x0
0056 #define DCN10_DIG_FE_SOURCE_SELECT_DIGA 0x1
0057 #define DCN10_DIG_FE_SOURCE_SELECT_DIGB 0x2
0058 #define DCN10_DIG_FE_SOURCE_SELECT_DIGC 0x4
0059 #define DCN10_DIG_FE_SOURCE_SELECT_DIGD 0x08
0060 #define DCN10_DIG_FE_SOURCE_SELECT_DIGE 0x10
0061 #define DCN10_DIG_FE_SOURCE_SELECT_DIGF 0x20
0062 #define DCN10_DIG_FE_SOURCE_SELECT_DIGG 0x40
0063 
0064 enum {
0065     DP_MST_UPDATE_MAX_RETRY = 50
0066 };
0067 
0068 static const struct link_encoder_funcs dcn10_lnk_enc_funcs = {
0069     .validate_output_with_stream =
0070         dcn10_link_encoder_validate_output_with_stream,
0071     .hw_init = dcn10_link_encoder_hw_init,
0072     .setup = dcn10_link_encoder_setup,
0073     .enable_tmds_output = dcn10_link_encoder_enable_tmds_output,
0074     .enable_dp_output = dcn10_link_encoder_enable_dp_output,
0075     .enable_dp_mst_output = dcn10_link_encoder_enable_dp_mst_output,
0076     .disable_output = dcn10_link_encoder_disable_output,
0077     .dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings,
0078     .dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern,
0079     .update_mst_stream_allocation_table =
0080         dcn10_link_encoder_update_mst_stream_allocation_table,
0081     .psr_program_dp_dphy_fast_training =
0082             dcn10_psr_program_dp_dphy_fast_training,
0083     .psr_program_secondary_packet = dcn10_psr_program_secondary_packet,
0084     .connect_dig_be_to_fe = dcn10_link_encoder_connect_dig_be_to_fe,
0085     .enable_hpd = dcn10_link_encoder_enable_hpd,
0086     .disable_hpd = dcn10_link_encoder_disable_hpd,
0087     .is_dig_enabled = dcn10_is_dig_enabled,
0088     .get_dig_frontend = dcn10_get_dig_frontend,
0089     .get_dig_mode = dcn10_get_dig_mode,
0090     .destroy = dcn10_link_encoder_destroy,
0091     .get_max_link_cap = dcn10_link_encoder_get_max_link_cap,
0092 };
0093 
0094 static enum bp_result link_transmitter_control(
0095     struct dcn10_link_encoder *enc10,
0096     struct bp_transmitter_control *cntl)
0097 {
0098     enum bp_result result;
0099     struct dc_bios *bp = enc10->base.ctx->dc_bios;
0100 
0101     result = bp->funcs->transmitter_control(bp, cntl);
0102 
0103     return result;
0104 }
0105 
0106 static void enable_phy_bypass_mode(
0107     struct dcn10_link_encoder *enc10,
0108     bool enable)
0109 {
0110     /* This register resides in DP back end block;
0111      * transmitter is used for the offset
0112      */
0113     REG_UPDATE(DP_DPHY_CNTL, DPHY_BYPASS, enable);
0114 
0115 }
0116 
0117 static void disable_prbs_symbols(
0118     struct dcn10_link_encoder *enc10,
0119     bool disable)
0120 {
0121     /* This register resides in DP back end block;
0122      * transmitter is used for the offset
0123      */
0124     REG_UPDATE_4(DP_DPHY_CNTL,
0125             DPHY_ATEST_SEL_LANE0, disable,
0126             DPHY_ATEST_SEL_LANE1, disable,
0127             DPHY_ATEST_SEL_LANE2, disable,
0128             DPHY_ATEST_SEL_LANE3, disable);
0129 }
0130 
0131 static void disable_prbs_mode(
0132     struct dcn10_link_encoder *enc10)
0133 {
0134     REG_UPDATE(DP_DPHY_PRBS_CNTL, DPHY_PRBS_EN, 0);
0135 }
0136 
0137 static void program_pattern_symbols(
0138     struct dcn10_link_encoder *enc10,
0139     uint16_t pattern_symbols[8])
0140 {
0141     /* This register resides in DP back end block;
0142      * transmitter is used for the offset
0143      */
0144     REG_SET_3(DP_DPHY_SYM0, 0,
0145             DPHY_SYM1, pattern_symbols[0],
0146             DPHY_SYM2, pattern_symbols[1],
0147             DPHY_SYM3, pattern_symbols[2]);
0148 
0149     /* This register resides in DP back end block;
0150      * transmitter is used for the offset
0151      */
0152     REG_SET_3(DP_DPHY_SYM1, 0,
0153             DPHY_SYM4, pattern_symbols[3],
0154             DPHY_SYM5, pattern_symbols[4],
0155             DPHY_SYM6, pattern_symbols[5]);
0156 
0157     /* This register resides in DP back end block;
0158      * transmitter is used for the offset
0159      */
0160     REG_SET_2(DP_DPHY_SYM2, 0,
0161             DPHY_SYM7, pattern_symbols[6],
0162             DPHY_SYM8, pattern_symbols[7]);
0163 }
0164 
0165 static void set_dp_phy_pattern_d102(
0166     struct dcn10_link_encoder *enc10)
0167 {
0168     /* Disable PHY Bypass mode to setup the test pattern */
0169     enable_phy_bypass_mode(enc10, false);
0170 
0171     /* For 10-bit PRBS or debug symbols
0172      * please use the following sequence:
0173      *
0174      * Enable debug symbols on the lanes
0175      */
0176     disable_prbs_symbols(enc10, true);
0177 
0178     /* Disable PRBS mode */
0179     disable_prbs_mode(enc10);
0180 
0181     /* Program debug symbols to be output */
0182     {
0183         uint16_t pattern_symbols[8] = {
0184             0x2AA, 0x2AA, 0x2AA, 0x2AA,
0185             0x2AA, 0x2AA, 0x2AA, 0x2AA
0186         };
0187 
0188         program_pattern_symbols(enc10, pattern_symbols);
0189     }
0190 
0191     /* Enable phy bypass mode to enable the test pattern */
0192 
0193     enable_phy_bypass_mode(enc10, true);
0194 }
0195 
0196 static void set_link_training_complete(
0197     struct dcn10_link_encoder *enc10,
0198     bool complete)
0199 {
0200     /* This register resides in DP back end block;
0201      * transmitter is used for the offset
0202      */
0203     REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, complete);
0204 
0205 }
0206 
0207 void dcn10_link_encoder_set_dp_phy_pattern_training_pattern(
0208     struct link_encoder *enc,
0209     uint32_t index)
0210 {
0211     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0212     /* Write Training Pattern */
0213 
0214     REG_WRITE(DP_DPHY_TRAINING_PATTERN_SEL, index);
0215 
0216     /* Set HW Register Training Complete to false */
0217 
0218     set_link_training_complete(enc10, false);
0219 
0220     /* Disable PHY Bypass mode to output Training Pattern */
0221 
0222     enable_phy_bypass_mode(enc10, false);
0223 
0224     /* Disable PRBS mode */
0225     disable_prbs_mode(enc10);
0226 }
0227 
0228 static void setup_panel_mode(
0229     struct dcn10_link_encoder *enc10,
0230     enum dp_panel_mode panel_mode)
0231 {
0232     uint32_t value;
0233 
0234     if (!REG(DP_DPHY_INTERNAL_CTRL))
0235         return;
0236 
0237     value = REG_READ(DP_DPHY_INTERNAL_CTRL);
0238 
0239     switch (panel_mode) {
0240     case DP_PANEL_MODE_EDP:
0241         value = 0x1;
0242         break;
0243     case DP_PANEL_MODE_SPECIAL:
0244         value = 0x11;
0245         break;
0246     default:
0247         value = 0x0;
0248         break;
0249     }
0250 
0251     REG_WRITE(DP_DPHY_INTERNAL_CTRL, value);
0252 }
0253 
0254 static void set_dp_phy_pattern_symbol_error(
0255     struct dcn10_link_encoder *enc10)
0256 {
0257     /* Disable PHY Bypass mode to setup the test pattern */
0258     enable_phy_bypass_mode(enc10, false);
0259 
0260     /* program correct panel mode*/
0261     setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
0262 
0263     /* A PRBS23 pattern is used for most DP electrical measurements. */
0264 
0265     /* Enable PRBS symbols on the lanes */
0266     disable_prbs_symbols(enc10, false);
0267 
0268     /* For PRBS23 Set bit DPHY_PRBS_SEL=1 and Set bit DPHY_PRBS_EN=1 */
0269     REG_UPDATE_2(DP_DPHY_PRBS_CNTL,
0270             DPHY_PRBS_SEL, 1,
0271             DPHY_PRBS_EN, 1);
0272 
0273     /* Enable phy bypass mode to enable the test pattern */
0274     enable_phy_bypass_mode(enc10, true);
0275 }
0276 
0277 static void set_dp_phy_pattern_prbs7(
0278     struct dcn10_link_encoder *enc10)
0279 {
0280     /* Disable PHY Bypass mode to setup the test pattern */
0281     enable_phy_bypass_mode(enc10, false);
0282 
0283     /* A PRBS7 pattern is used for most DP electrical measurements. */
0284 
0285     /* Enable PRBS symbols on the lanes */
0286     disable_prbs_symbols(enc10, false);
0287 
0288     /* For PRBS7 Set bit DPHY_PRBS_SEL=0 and Set bit DPHY_PRBS_EN=1 */
0289     REG_UPDATE_2(DP_DPHY_PRBS_CNTL,
0290             DPHY_PRBS_SEL, 0,
0291             DPHY_PRBS_EN, 1);
0292 
0293     /* Enable phy bypass mode to enable the test pattern */
0294     enable_phy_bypass_mode(enc10, true);
0295 }
0296 
0297 static void set_dp_phy_pattern_80bit_custom(
0298     struct dcn10_link_encoder *enc10,
0299     const uint8_t *pattern)
0300 {
0301     /* Disable PHY Bypass mode to setup the test pattern */
0302     enable_phy_bypass_mode(enc10, false);
0303 
0304     /* Enable debug symbols on the lanes */
0305 
0306     disable_prbs_symbols(enc10, true);
0307 
0308     /* Enable PHY bypass mode to enable the test pattern */
0309     /* TODO is it really needed ? */
0310 
0311     enable_phy_bypass_mode(enc10, true);
0312 
0313     /* Program 80 bit custom pattern */
0314     {
0315         uint16_t pattern_symbols[8];
0316 
0317         pattern_symbols[0] =
0318             ((pattern[1] & 0x03) << 8) | pattern[0];
0319         pattern_symbols[1] =
0320             ((pattern[2] & 0x0f) << 6) | ((pattern[1] >> 2) & 0x3f);
0321         pattern_symbols[2] =
0322             ((pattern[3] & 0x3f) << 4) | ((pattern[2] >> 4) & 0x0f);
0323         pattern_symbols[3] =
0324             (pattern[4] << 2) | ((pattern[3] >> 6) & 0x03);
0325         pattern_symbols[4] =
0326             ((pattern[6] & 0x03) << 8) | pattern[5];
0327         pattern_symbols[5] =
0328             ((pattern[7] & 0x0f) << 6) | ((pattern[6] >> 2) & 0x3f);
0329         pattern_symbols[6] =
0330             ((pattern[8] & 0x3f) << 4) | ((pattern[7] >> 4) & 0x0f);
0331         pattern_symbols[7] =
0332             (pattern[9] << 2) | ((pattern[8] >> 6) & 0x03);
0333 
0334         program_pattern_symbols(enc10, pattern_symbols);
0335     }
0336 
0337     /* Enable phy bypass mode to enable the test pattern */
0338 
0339     enable_phy_bypass_mode(enc10, true);
0340 }
0341 
0342 static void set_dp_phy_pattern_hbr2_compliance_cp2520_2(
0343     struct dcn10_link_encoder *enc10,
0344     unsigned int cp2520_pattern)
0345 {
0346 
0347     /* previously there is a register DP_HBR2_EYE_PATTERN
0348      * that is enabled to get the pattern.
0349      * But it does not work with the latest spec change,
0350      * so we are programming the following registers manually.
0351      *
0352      * The following settings have been confirmed
0353      * by Nick Chorney and Sandra Liu
0354      */
0355 
0356     /* Disable PHY Bypass mode to setup the test pattern */
0357 
0358     enable_phy_bypass_mode(enc10, false);
0359 
0360     /* Setup DIG encoder in DP SST mode */
0361     enc10->base.funcs->setup(&enc10->base, SIGNAL_TYPE_DISPLAY_PORT);
0362 
0363     /* ensure normal panel mode. */
0364     setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
0365 
0366     /* no vbid after BS (SR)
0367      * DP_LINK_FRAMING_CNTL changed history Sandra Liu
0368      * 11000260 / 11000104 / 110000FC
0369      */
0370     REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
0371             DP_IDLE_BS_INTERVAL, 0xFC,
0372             DP_VBID_DISABLE, 1,
0373             DP_VID_ENHANCED_FRAME_MODE, 1);
0374 
0375     /* swap every BS with SR */
0376     REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0);
0377 
0378     /* select cp2520 patterns */
0379     if (REG(DP_DPHY_HBR2_PATTERN_CONTROL))
0380         REG_UPDATE(DP_DPHY_HBR2_PATTERN_CONTROL,
0381                 DP_DPHY_HBR2_PATTERN_CONTROL, cp2520_pattern);
0382     else
0383         /* pre-DCE11 can only generate CP2520 pattern 2 */
0384         ASSERT(cp2520_pattern == 2);
0385 
0386     /* set link training complete */
0387     set_link_training_complete(enc10, true);
0388 
0389     /* disable video stream */
0390     REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0);
0391 
0392     /* Disable PHY Bypass mode to setup the test pattern */
0393     enable_phy_bypass_mode(enc10, false);
0394 }
0395 
0396 static void set_dp_phy_pattern_passthrough_mode(
0397     struct dcn10_link_encoder *enc10,
0398     enum dp_panel_mode panel_mode)
0399 {
0400     /* program correct panel mode */
0401     setup_panel_mode(enc10, panel_mode);
0402 
0403     /* restore LINK_FRAMING_CNTL and DPHY_SCRAMBLER_BS_COUNT
0404      * in case we were doing HBR2 compliance pattern before
0405      */
0406     REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
0407             DP_IDLE_BS_INTERVAL, 0x2000,
0408             DP_VBID_DISABLE, 0,
0409             DP_VID_ENHANCED_FRAME_MODE, 1);
0410 
0411     REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0x1FF);
0412 
0413     /* set link training complete */
0414     set_link_training_complete(enc10, true);
0415 
0416     /* Disable PHY Bypass mode to setup the test pattern */
0417     enable_phy_bypass_mode(enc10, false);
0418 
0419     /* Disable PRBS mode */
0420     disable_prbs_mode(enc10);
0421 }
0422 
0423 /* return value is bit-vector */
0424 static uint8_t get_frontend_source(
0425     enum engine_id engine)
0426 {
0427     switch (engine) {
0428     case ENGINE_ID_DIGA:
0429         return DCN10_DIG_FE_SOURCE_SELECT_DIGA;
0430     case ENGINE_ID_DIGB:
0431         return DCN10_DIG_FE_SOURCE_SELECT_DIGB;
0432     case ENGINE_ID_DIGC:
0433         return DCN10_DIG_FE_SOURCE_SELECT_DIGC;
0434     case ENGINE_ID_DIGD:
0435         return DCN10_DIG_FE_SOURCE_SELECT_DIGD;
0436     case ENGINE_ID_DIGE:
0437         return DCN10_DIG_FE_SOURCE_SELECT_DIGE;
0438     case ENGINE_ID_DIGF:
0439         return DCN10_DIG_FE_SOURCE_SELECT_DIGF;
0440     case ENGINE_ID_DIGG:
0441         return DCN10_DIG_FE_SOURCE_SELECT_DIGG;
0442     default:
0443         ASSERT_CRITICAL(false);
0444         return DCN10_DIG_FE_SOURCE_SELECT_INVALID;
0445     }
0446 }
0447 
0448 unsigned int dcn10_get_dig_frontend(struct link_encoder *enc)
0449 {
0450     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0451     int32_t value;
0452     enum engine_id result;
0453 
0454     REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &value);
0455 
0456     switch (value) {
0457     case DCN10_DIG_FE_SOURCE_SELECT_DIGA:
0458         result = ENGINE_ID_DIGA;
0459         break;
0460     case DCN10_DIG_FE_SOURCE_SELECT_DIGB:
0461         result = ENGINE_ID_DIGB;
0462         break;
0463     case DCN10_DIG_FE_SOURCE_SELECT_DIGC:
0464         result = ENGINE_ID_DIGC;
0465         break;
0466     case DCN10_DIG_FE_SOURCE_SELECT_DIGD:
0467         result = ENGINE_ID_DIGD;
0468         break;
0469     case DCN10_DIG_FE_SOURCE_SELECT_DIGE:
0470         result = ENGINE_ID_DIGE;
0471         break;
0472     case DCN10_DIG_FE_SOURCE_SELECT_DIGF:
0473         result = ENGINE_ID_DIGF;
0474         break;
0475     case DCN10_DIG_FE_SOURCE_SELECT_DIGG:
0476         result = ENGINE_ID_DIGG;
0477         break;
0478     default:
0479         // invalid source select DIG
0480         result = ENGINE_ID_UNKNOWN;
0481     }
0482 
0483     return result;
0484 
0485 }
0486 
0487 void enc1_configure_encoder(
0488     struct dcn10_link_encoder *enc10,
0489     const struct dc_link_settings *link_settings)
0490 {
0491     /* set number of lanes */
0492     REG_SET(DP_CONFIG, 0,
0493             DP_UDI_LANES, link_settings->lane_count - LANE_COUNT_ONE);
0494 
0495     /* setup scrambler */
0496     REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1);
0497 }
0498 
0499 void dcn10_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
0500             bool exit_link_training_required)
0501 {
0502     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0503 
0504     if (exit_link_training_required)
0505         REG_UPDATE(DP_DPHY_FAST_TRAINING,
0506                 DPHY_RX_FAST_TRAINING_CAPABLE, 1);
0507     else {
0508         REG_UPDATE(DP_DPHY_FAST_TRAINING,
0509                 DPHY_RX_FAST_TRAINING_CAPABLE, 0);
0510         /*In DCE 11, we are able to pre-program a Force SR register
0511          * to be able to trigger SR symbol after 5 idle patterns
0512          * transmitted. Upon PSR Exit, DMCU can trigger
0513          * DPHY_LOAD_BS_COUNT_START = 1. Upon writing 1 to
0514          * DPHY_LOAD_BS_COUNT_START and the internal counter
0515          * reaches DPHY_LOAD_BS_COUNT, the next BS symbol will be
0516          * replaced by SR symbol once.
0517          */
0518 
0519         REG_UPDATE(DP_DPHY_BS_SR_SWAP_CNTL, DPHY_LOAD_BS_COUNT, 0x5);
0520     }
0521 }
0522 
0523 void dcn10_psr_program_secondary_packet(struct link_encoder *enc,
0524             unsigned int sdp_transmit_line_num_deadline)
0525 {
0526     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0527 
0528     REG_UPDATE_2(DP_SEC_CNTL1,
0529         DP_SEC_GSP0_LINE_NUM, sdp_transmit_line_num_deadline,
0530         DP_SEC_GSP0_PRIORITY, 1);
0531 }
0532 
0533 bool dcn10_is_dig_enabled(struct link_encoder *enc)
0534 {
0535     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0536     uint32_t value;
0537 
0538     REG_GET(DIG_BE_EN_CNTL, DIG_ENABLE, &value);
0539     return value;
0540 }
0541 
0542 static void link_encoder_disable(struct dcn10_link_encoder *enc10)
0543 {
0544     /* reset training pattern */
0545     REG_SET(DP_DPHY_TRAINING_PATTERN_SEL, 0,
0546             DPHY_TRAINING_PATTERN_SEL, 0);
0547 
0548     /* reset training complete */
0549     REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0);
0550 
0551     /* reset panel mode */
0552     setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
0553 }
0554 
0555 static void hpd_initialize(
0556     struct dcn10_link_encoder *enc10)
0557 {
0558     /* Associate HPD with DIG_BE */
0559     enum hpd_source_id hpd_source = enc10->base.hpd_source;
0560 
0561     REG_UPDATE(DIG_BE_CNTL, DIG_HPD_SELECT, hpd_source);
0562 }
0563 
0564 bool dcn10_link_encoder_validate_dvi_output(
0565     const struct dcn10_link_encoder *enc10,
0566     enum signal_type connector_signal,
0567     enum signal_type signal,
0568     const struct dc_crtc_timing *crtc_timing)
0569 {
0570     uint32_t max_pixel_clock = TMDS_MAX_PIXEL_CLOCK;
0571 
0572     if (signal == SIGNAL_TYPE_DVI_DUAL_LINK)
0573         max_pixel_clock *= 2;
0574 
0575     /* This handles the case of HDMI downgrade to DVI we don't want to
0576      * we don't want to cap the pixel clock if the DDI is not DVI.
0577      */
0578     if (connector_signal != SIGNAL_TYPE_DVI_DUAL_LINK &&
0579             connector_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
0580         max_pixel_clock = enc10->base.features.max_hdmi_pixel_clock;
0581 
0582     /* DVI only support RGB pixel encoding */
0583     if (crtc_timing->pixel_encoding != PIXEL_ENCODING_RGB)
0584         return false;
0585 
0586     /*connect DVI via adpater's HDMI connector*/
0587     if ((connector_signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
0588         connector_signal == SIGNAL_TYPE_HDMI_TYPE_A) &&
0589         signal != SIGNAL_TYPE_HDMI_TYPE_A &&
0590         crtc_timing->pix_clk_100hz > (TMDS_MAX_PIXEL_CLOCK * 10))
0591         return false;
0592     if (crtc_timing->pix_clk_100hz < (TMDS_MIN_PIXEL_CLOCK * 10))
0593         return false;
0594 
0595     if (crtc_timing->pix_clk_100hz > (max_pixel_clock * 10))
0596         return false;
0597 
0598     /* DVI supports 6/8bpp single-link and 10/16bpp dual-link */
0599     switch (crtc_timing->display_color_depth) {
0600     case COLOR_DEPTH_666:
0601     case COLOR_DEPTH_888:
0602     break;
0603     case COLOR_DEPTH_101010:
0604     case COLOR_DEPTH_161616:
0605         if (signal != SIGNAL_TYPE_DVI_DUAL_LINK)
0606             return false;
0607     break;
0608     default:
0609         return false;
0610     }
0611 
0612     return true;
0613 }
0614 
0615 static bool dcn10_link_encoder_validate_hdmi_output(
0616     const struct dcn10_link_encoder *enc10,
0617     const struct dc_crtc_timing *crtc_timing,
0618     const struct dc_edid_caps *edid_caps,
0619     int adjusted_pix_clk_100hz)
0620 {
0621     enum dc_color_depth max_deep_color =
0622             enc10->base.features.max_hdmi_deep_color;
0623 
0624     // check pixel clock against edid specified max TMDS clk
0625     if (edid_caps->max_tmds_clk_mhz != 0 &&
0626             adjusted_pix_clk_100hz > edid_caps->max_tmds_clk_mhz * 10000)
0627         return false;
0628 
0629     if (max_deep_color < crtc_timing->display_color_depth)
0630         return false;
0631 
0632     if (crtc_timing->display_color_depth < COLOR_DEPTH_888)
0633         return false;
0634     if (adjusted_pix_clk_100hz < (TMDS_MIN_PIXEL_CLOCK * 10))
0635         return false;
0636 
0637     if ((adjusted_pix_clk_100hz == 0) ||
0638         (adjusted_pix_clk_100hz > (enc10->base.features.max_hdmi_pixel_clock * 10)))
0639         return false;
0640 
0641     /* DCE11 HW does not support 420 */
0642     if (!enc10->base.features.hdmi_ycbcr420_supported &&
0643             crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
0644         return false;
0645 
0646     if ((!enc10->base.features.flags.bits.HDMI_6GB_EN ||
0647             enc10->base.ctx->dc->debug.hdmi20_disable) &&
0648             adjusted_pix_clk_100hz >= 3000000)
0649         return false;
0650     if (enc10->base.ctx->dc->debug.hdmi20_disable &&
0651         crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
0652         return false;
0653     return true;
0654 }
0655 
0656 bool dcn10_link_encoder_validate_dp_output(
0657     const struct dcn10_link_encoder *enc10,
0658     const struct dc_crtc_timing *crtc_timing)
0659 {
0660     if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
0661         if (!enc10->base.features.dp_ycbcr420_supported)
0662             return false;
0663     }
0664 
0665     return true;
0666 }
0667 
0668 void dcn10_link_encoder_construct(
0669     struct dcn10_link_encoder *enc10,
0670     const struct encoder_init_data *init_data,
0671     const struct encoder_feature_support *enc_features,
0672     const struct dcn10_link_enc_registers *link_regs,
0673     const struct dcn10_link_enc_aux_registers *aux_regs,
0674     const struct dcn10_link_enc_hpd_registers *hpd_regs,
0675     const struct dcn10_link_enc_shift *link_shift,
0676     const struct dcn10_link_enc_mask *link_mask)
0677 {
0678     struct bp_encoder_cap_info bp_cap_info = {0};
0679     const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
0680     enum bp_result result = BP_RESULT_OK;
0681 
0682     enc10->base.funcs = &dcn10_lnk_enc_funcs;
0683     enc10->base.ctx = init_data->ctx;
0684     enc10->base.id = init_data->encoder;
0685 
0686     enc10->base.hpd_source = init_data->hpd_source;
0687     enc10->base.connector = init_data->connector;
0688 
0689     enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
0690 
0691     enc10->base.features = *enc_features;
0692 
0693     enc10->base.transmitter = init_data->transmitter;
0694 
0695     /* set the flag to indicate whether driver poll the I2C data pin
0696      * while doing the DP sink detect
0697      */
0698 
0699 /*  if (dal_adapter_service_is_feature_supported(as,
0700         FEATURE_DP_SINK_DETECT_POLL_DATA_PIN))
0701         enc10->base.features.flags.bits.
0702             DP_SINK_DETECT_POLL_DATA_PIN = true;*/
0703 
0704     enc10->base.output_signals =
0705         SIGNAL_TYPE_DVI_SINGLE_LINK |
0706         SIGNAL_TYPE_DVI_DUAL_LINK |
0707         SIGNAL_TYPE_LVDS |
0708         SIGNAL_TYPE_DISPLAY_PORT |
0709         SIGNAL_TYPE_DISPLAY_PORT_MST |
0710         SIGNAL_TYPE_EDP |
0711         SIGNAL_TYPE_HDMI_TYPE_A;
0712 
0713     /* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE.
0714      * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY.
0715      * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer
0716      * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS.
0717      * Prefer DIG assignment is decided by board design.
0718      * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design
0719      * and VBIOS will filter out 7 UNIPHY for DCE 8.0.
0720      * By this, adding DIGG should not hurt DCE 8.0.
0721      * This will let DCE 8.1 share DCE 8.0 as much as possible
0722      */
0723 
0724     enc10->link_regs = link_regs;
0725     enc10->aux_regs = aux_regs;
0726     enc10->hpd_regs = hpd_regs;
0727     enc10->link_shift = link_shift;
0728     enc10->link_mask = link_mask;
0729 
0730     switch (enc10->base.transmitter) {
0731     case TRANSMITTER_UNIPHY_A:
0732         enc10->base.preferred_engine = ENGINE_ID_DIGA;
0733     break;
0734     case TRANSMITTER_UNIPHY_B:
0735         enc10->base.preferred_engine = ENGINE_ID_DIGB;
0736     break;
0737     case TRANSMITTER_UNIPHY_C:
0738         enc10->base.preferred_engine = ENGINE_ID_DIGC;
0739     break;
0740     case TRANSMITTER_UNIPHY_D:
0741         enc10->base.preferred_engine = ENGINE_ID_DIGD;
0742     break;
0743     case TRANSMITTER_UNIPHY_E:
0744         enc10->base.preferred_engine = ENGINE_ID_DIGE;
0745     break;
0746     case TRANSMITTER_UNIPHY_F:
0747         enc10->base.preferred_engine = ENGINE_ID_DIGF;
0748     break;
0749     case TRANSMITTER_UNIPHY_G:
0750         enc10->base.preferred_engine = ENGINE_ID_DIGG;
0751     break;
0752     default:
0753         ASSERT_CRITICAL(false);
0754         enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
0755     }
0756 
0757     /* default to one to mirror Windows behavior */
0758     enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
0759 
0760     result = bp_funcs->get_encoder_cap_info(enc10->base.ctx->dc_bios,
0761                         enc10->base.id, &bp_cap_info);
0762 
0763     /* Override features with DCE-specific values */
0764     if (result == BP_RESULT_OK) {
0765         enc10->base.features.flags.bits.IS_HBR2_CAPABLE =
0766                 bp_cap_info.DP_HBR2_EN;
0767         enc10->base.features.flags.bits.IS_HBR3_CAPABLE =
0768                 bp_cap_info.DP_HBR3_EN;
0769         enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
0770         enc10->base.features.flags.bits.DP_IS_USB_C =
0771                 bp_cap_info.DP_IS_USB_C;
0772     } else {
0773         DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
0774                 __func__,
0775                 result);
0776     }
0777     if (enc10->base.ctx->dc->debug.hdmi20_disable) {
0778         enc10->base.features.flags.bits.HDMI_6GB_EN = 0;
0779     }
0780 }
0781 
0782 bool dcn10_link_encoder_validate_output_with_stream(
0783     struct link_encoder *enc,
0784     const struct dc_stream_state *stream)
0785 {
0786     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0787     bool is_valid;
0788 
0789     //if SCDC (340-600MHz) is disabled, set to HDMI 1.4 timing limit
0790     if (stream->sink->edid_caps.panel_patch.skip_scdc_overwrite &&
0791         enc10->base.features.max_hdmi_pixel_clock > 300000)
0792         enc10->base.features.max_hdmi_pixel_clock = 300000;
0793 
0794     switch (stream->signal) {
0795     case SIGNAL_TYPE_DVI_SINGLE_LINK:
0796     case SIGNAL_TYPE_DVI_DUAL_LINK:
0797         is_valid = dcn10_link_encoder_validate_dvi_output(
0798             enc10,
0799             stream->link->connector_signal,
0800             stream->signal,
0801             &stream->timing);
0802     break;
0803     case SIGNAL_TYPE_HDMI_TYPE_A:
0804         is_valid = dcn10_link_encoder_validate_hdmi_output(
0805                 enc10,
0806                 &stream->timing,
0807                 &stream->sink->edid_caps,
0808                 stream->phy_pix_clk * 10);
0809     break;
0810     case SIGNAL_TYPE_DISPLAY_PORT:
0811     case SIGNAL_TYPE_DISPLAY_PORT_MST:
0812         is_valid = dcn10_link_encoder_validate_dp_output(
0813                     enc10, &stream->timing);
0814     break;
0815     case SIGNAL_TYPE_EDP:
0816         is_valid = (stream->timing.pixel_encoding == PIXEL_ENCODING_RGB) ? true : false;
0817     break;
0818     case SIGNAL_TYPE_VIRTUAL:
0819         is_valid = true;
0820         break;
0821     default:
0822         is_valid = false;
0823     break;
0824     }
0825 
0826     return is_valid;
0827 }
0828 
0829 void dcn10_link_encoder_hw_init(
0830     struct link_encoder *enc)
0831 {
0832     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0833     struct bp_transmitter_control cntl = { 0 };
0834     enum bp_result result;
0835 
0836     cntl.action = TRANSMITTER_CONTROL_INIT;
0837     cntl.engine_id = ENGINE_ID_UNKNOWN;
0838     cntl.transmitter = enc10->base.transmitter;
0839     cntl.connector_obj_id = enc10->base.connector;
0840     cntl.lanes_number = LANE_COUNT_FOUR;
0841     cntl.coherent = false;
0842     cntl.hpd_sel = enc10->base.hpd_source;
0843 
0844     if (enc10->base.connector.id == CONNECTOR_ID_EDP)
0845         cntl.signal = SIGNAL_TYPE_EDP;
0846 
0847     result = link_transmitter_control(enc10, &cntl);
0848 
0849     if (result != BP_RESULT_OK) {
0850         DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
0851             __func__);
0852         BREAK_TO_DEBUGGER();
0853         return;
0854     }
0855 
0856     if (enc10->base.connector.id == CONNECTOR_ID_LVDS) {
0857         cntl.action = TRANSMITTER_CONTROL_BACKLIGHT_BRIGHTNESS;
0858 
0859         result = link_transmitter_control(enc10, &cntl);
0860 
0861         ASSERT(result == BP_RESULT_OK);
0862 
0863     }
0864     dcn10_aux_initialize(enc10);
0865 
0866     /* reinitialize HPD.
0867      * hpd_initialize() will pass DIG_FE id to HW context.
0868      * All other routine within HW context will use fe_engine_offset
0869      * as DIG_FE id even caller pass DIG_FE id.
0870      * So this routine must be called first.
0871      */
0872     hpd_initialize(enc10);
0873 }
0874 
0875 void dcn10_link_encoder_destroy(struct link_encoder **enc)
0876 {
0877     kfree(TO_DCN10_LINK_ENC(*enc));
0878     *enc = NULL;
0879 }
0880 
0881 void dcn10_link_encoder_setup(
0882     struct link_encoder *enc,
0883     enum signal_type signal)
0884 {
0885     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0886 
0887     switch (signal) {
0888     case SIGNAL_TYPE_EDP:
0889     case SIGNAL_TYPE_DISPLAY_PORT:
0890         /* DP SST */
0891         REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 0);
0892         break;
0893     case SIGNAL_TYPE_LVDS:
0894         /* LVDS */
0895         REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 1);
0896         break;
0897     case SIGNAL_TYPE_DVI_SINGLE_LINK:
0898     case SIGNAL_TYPE_DVI_DUAL_LINK:
0899         /* TMDS-DVI */
0900         REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 2);
0901         break;
0902     case SIGNAL_TYPE_HDMI_TYPE_A:
0903         /* TMDS-HDMI */
0904         REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 3);
0905         break;
0906     case SIGNAL_TYPE_DISPLAY_PORT_MST:
0907         /* DP MST */
0908         REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 5);
0909         break;
0910     default:
0911         ASSERT_CRITICAL(false);
0912         /* invalid mode ! */
0913         break;
0914     }
0915 
0916 }
0917 
0918 /* TODO: still need depth or just pass in adjusted pixel clock? */
0919 void dcn10_link_encoder_enable_tmds_output(
0920     struct link_encoder *enc,
0921     enum clock_source_id clock_source,
0922     enum dc_color_depth color_depth,
0923     enum signal_type signal,
0924     uint32_t pixel_clock)
0925 {
0926     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0927     struct bp_transmitter_control cntl = { 0 };
0928     enum bp_result result;
0929 
0930     /* Enable the PHY */
0931 
0932     cntl.action = TRANSMITTER_CONTROL_ENABLE;
0933     cntl.engine_id = enc->preferred_engine;
0934     cntl.transmitter = enc10->base.transmitter;
0935     cntl.pll_id = clock_source;
0936     cntl.signal = signal;
0937     if (cntl.signal == SIGNAL_TYPE_DVI_DUAL_LINK)
0938         cntl.lanes_number = 8;
0939     else
0940         cntl.lanes_number = 4;
0941 
0942     cntl.hpd_sel = enc10->base.hpd_source;
0943 
0944     cntl.pixel_clock = pixel_clock;
0945     cntl.color_depth = color_depth;
0946 
0947     result = link_transmitter_control(enc10, &cntl);
0948 
0949     if (result != BP_RESULT_OK) {
0950         DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
0951             __func__);
0952         BREAK_TO_DEBUGGER();
0953     }
0954 }
0955 
0956 void dcn10_link_encoder_enable_tmds_output_with_clk_pattern_wa(
0957     struct link_encoder *enc,
0958     enum clock_source_id clock_source,
0959     enum dc_color_depth color_depth,
0960     enum signal_type signal,
0961     uint32_t pixel_clock)
0962 {
0963     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0964 
0965     dcn10_link_encoder_enable_tmds_output(
0966         enc, clock_source, color_depth, signal, pixel_clock);
0967 
0968     REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F);
0969 }
0970 
0971 /* enables DP PHY output */
0972 void dcn10_link_encoder_enable_dp_output(
0973     struct link_encoder *enc,
0974     const struct dc_link_settings *link_settings,
0975     enum clock_source_id clock_source)
0976 {
0977     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0978     struct bp_transmitter_control cntl = { 0 };
0979     enum bp_result result;
0980 
0981     /* Enable the PHY */
0982 
0983     /* number_of_lanes is used for pixel clock adjust,
0984      * but it's not passed to asic_control.
0985      * We need to set number of lanes manually.
0986      */
0987     enc1_configure_encoder(enc10, link_settings);
0988 
0989     cntl.action = TRANSMITTER_CONTROL_ENABLE;
0990     cntl.engine_id = enc->preferred_engine;
0991     cntl.transmitter = enc10->base.transmitter;
0992     cntl.pll_id = clock_source;
0993     cntl.signal = SIGNAL_TYPE_DISPLAY_PORT;
0994     cntl.lanes_number = link_settings->lane_count;
0995     cntl.hpd_sel = enc10->base.hpd_source;
0996     cntl.pixel_clock = link_settings->link_rate
0997                         * LINK_RATE_REF_FREQ_IN_KHZ;
0998     /* TODO: check if undefined works */
0999     cntl.color_depth = COLOR_DEPTH_UNDEFINED;
1000 
1001     result = link_transmitter_control(enc10, &cntl);
1002 
1003     if (result != BP_RESULT_OK) {
1004         DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1005             __func__);
1006         BREAK_TO_DEBUGGER();
1007     }
1008 }
1009 
1010 /* enables DP PHY output in MST mode */
1011 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     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1017     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     enc1_configure_encoder(enc10, link_settings);
1027 
1028     cntl.action = TRANSMITTER_CONTROL_ENABLE;
1029     cntl.engine_id = ENGINE_ID_UNKNOWN;
1030     cntl.transmitter = enc10->base.transmitter;
1031     cntl.pll_id = clock_source;
1032     cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
1033     cntl.lanes_number = link_settings->lane_count;
1034     cntl.hpd_sel = enc10->base.hpd_source;
1035     cntl.pixel_clock = link_settings->link_rate
1036                         * LINK_RATE_REF_FREQ_IN_KHZ;
1037     /* TODO: check if undefined works */
1038     cntl.color_depth = COLOR_DEPTH_UNDEFINED;
1039 
1040     result = link_transmitter_control(enc10, &cntl);
1041 
1042     if (result != BP_RESULT_OK) {
1043         DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1044             __func__);
1045         BREAK_TO_DEBUGGER();
1046     }
1047 }
1048 /*
1049  * @brief
1050  * Disable transmitter and its encoder
1051  */
1052 void dcn10_link_encoder_disable_output(
1053     struct link_encoder *enc,
1054     enum signal_type signal)
1055 {
1056     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1057     struct bp_transmitter_control cntl = { 0 };
1058     enum bp_result result;
1059 
1060     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         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     cntl.action = TRANSMITTER_CONTROL_DISABLE;
1080     cntl.transmitter = enc10->base.transmitter;
1081     cntl.hpd_sel = enc10->base.hpd_source;
1082     cntl.signal = signal;
1083     cntl.connector_obj_id = enc10->base.connector;
1084 
1085     result = link_transmitter_control(enc10, &cntl);
1086 
1087     if (result != BP_RESULT_OK) {
1088         DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1089             __func__);
1090         BREAK_TO_DEBUGGER();
1091         return;
1092     }
1093 
1094     /* disable encoder */
1095     if (dc_is_dp_signal(signal))
1096         link_encoder_disable(enc10);
1097 }
1098 
1099 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     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1105     union dpcd_training_lane_set training_lane_set = { { 0 } };
1106     int32_t lane = 0;
1107     struct bp_transmitter_control cntl = { 0 };
1108 
1109     if (!link_settings) {
1110         BREAK_TO_DEBUGGER();
1111         return;
1112     }
1113 
1114     cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS;
1115     cntl.transmitter = enc10->base.transmitter;
1116     cntl.connector_obj_id = enc10->base.connector;
1117     cntl.lanes_number = link_settings->lane_count;
1118     cntl.hpd_sel = enc10->base.hpd_source;
1119     cntl.pixel_clock = link_settings->link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
1120 
1121     for (lane = 0; lane < link_settings->lane_count; lane++) {
1122         /* translate lane settings */
1123 
1124         training_lane_set.bits.VOLTAGE_SWING_SET =
1125                 lane_settings[lane].VOLTAGE_SWING;
1126         training_lane_set.bits.PRE_EMPHASIS_SET =
1127                 lane_settings[lane].PRE_EMPHASIS;
1128 
1129         /* post cursor 2 setting only applies to HBR2 link rate */
1130         if (link_settings->link_rate == LINK_RATE_HIGH2) {
1131             /* this is passed to VBIOS
1132              * to program post cursor 2 level
1133              */
1134             training_lane_set.bits.POST_CURSOR2_SET =
1135                     lane_settings[lane].POST_CURSOR2;
1136         }
1137 
1138         cntl.lane_select = lane;
1139         cntl.lane_settings = training_lane_set.raw;
1140 
1141         /* call VBIOS table to set voltage swing and pre-emphasis */
1142         link_transmitter_control(enc10, &cntl);
1143     }
1144 }
1145 
1146 /* set DP PHY test and training patterns */
1147 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     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1152 
1153     switch (param->dp_phy_pattern) {
1154     case DP_TEST_PATTERN_TRAINING_PATTERN1:
1155         dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 0);
1156         break;
1157     case DP_TEST_PATTERN_TRAINING_PATTERN2:
1158         dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 1);
1159         break;
1160     case DP_TEST_PATTERN_TRAINING_PATTERN3:
1161         dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 2);
1162         break;
1163     case DP_TEST_PATTERN_TRAINING_PATTERN4:
1164         dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 3);
1165         break;
1166     case DP_TEST_PATTERN_D102:
1167         set_dp_phy_pattern_d102(enc10);
1168         break;
1169     case DP_TEST_PATTERN_SYMBOL_ERROR:
1170         set_dp_phy_pattern_symbol_error(enc10);
1171         break;
1172     case DP_TEST_PATTERN_PRBS7:
1173         set_dp_phy_pattern_prbs7(enc10);
1174         break;
1175     case DP_TEST_PATTERN_80BIT_CUSTOM:
1176         set_dp_phy_pattern_80bit_custom(
1177             enc10, param->custom_pattern);
1178         break;
1179     case DP_TEST_PATTERN_CP2520_1:
1180         set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 1);
1181         break;
1182     case DP_TEST_PATTERN_CP2520_2:
1183         set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 2);
1184         break;
1185     case DP_TEST_PATTERN_CP2520_3:
1186         set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 3);
1187         break;
1188     case DP_TEST_PATTERN_VIDEO_MODE: {
1189         set_dp_phy_pattern_passthrough_mode(
1190             enc10, param->dp_panel_mode);
1191         break;
1192     }
1193 
1194     default:
1195         /* invalid phy pattern */
1196         ASSERT_CRITICAL(false);
1197         break;
1198     }
1199 }
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     const struct stream_encoder *stream_enc = stream_allocation->stream_enc;
1207 
1208     if (stream_enc) {
1209         *src = stream_enc->id;
1210         *slots = stream_allocation->slot_count;
1211     } else {
1212         *src = 0;
1213         *slots = 0;
1214     }
1215 }
1216 
1217 /* programs DP MST VC payload allocation */
1218 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     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1223     uint32_t value0 = 0;
1224     uint32_t value1 = 0;
1225     uint32_t value2 = 0;
1226     uint32_t slots = 0;
1227     uint32_t src = 0;
1228     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     if (table->stream_count >= 1) {
1241         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     REG_UPDATE_2(DP_MSE_SAT0,
1251             DP_MSE_SAT_SRC0, src,
1252             DP_MSE_SAT_SLOT_COUNT0, slots);
1253 
1254     if (table->stream_count >= 2) {
1255         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     REG_UPDATE_2(DP_MSE_SAT0,
1265             DP_MSE_SAT_SRC1, src,
1266             DP_MSE_SAT_SLOT_COUNT1, slots);
1267 
1268     if (table->stream_count >= 3) {
1269         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     REG_UPDATE_2(DP_MSE_SAT1,
1279             DP_MSE_SAT_SRC2, src,
1280             DP_MSE_SAT_SLOT_COUNT2, slots);
1281 
1282     if (table->stream_count >= 4) {
1283         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     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     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         udelay(10);
1324 
1325         value0 = REG_READ(DP_MSE_SAT_UPDATE);
1326 
1327         REG_GET(DP_MSE_SAT_UPDATE,
1328                 DP_MSE_SAT_UPDATE, &value1);
1329 
1330         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         if (!value1 && !value2)
1335             break;
1336         ++retries;
1337     } while (retries < DP_MST_UPDATE_MAX_RETRY);
1338 }
1339 
1340 void dcn10_link_encoder_connect_dig_be_to_fe(
1341     struct link_encoder *enc,
1342     enum engine_id engine,
1343     bool connect)
1344 {
1345     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1346     uint32_t field;
1347 
1348     if (engine != ENGINE_ID_UNKNOWN) {
1349 
1350         REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &field);
1351 
1352         if (connect)
1353             field |= get_frontend_source(engine);
1354         else
1355             field &= ~get_frontend_source(engine);
1356 
1357         REG_UPDATE(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, field);
1358     }
1359 }
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 void dcn10_link_encoder_enable_hpd(struct link_encoder *enc)
1378 {
1379     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1380 
1381     HPD_REG_UPDATE(DC_HPD_CONTROL,
1382             DC_HPD_EN, 1);
1383 }
1384 
1385 void dcn10_link_encoder_disable_hpd(struct link_encoder *enc)
1386 {
1387     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1388 
1389     HPD_REG_UPDATE(DC_HPD_CONTROL,
1390             DC_HPD_EN, 0);
1391 }
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 void dcn10_aux_initialize(struct dcn10_link_encoder *enc10)
1414 {
1415     enum hpd_source_id hpd_source = enc10->base.hpd_source;
1416 
1417     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     AUX_REG_UPDATE(AUX_DPHY_RX_CONTROL0,
1423             AUX_RX_RECEIVE_WINDOW, 0);
1424 }
1425 
1426 enum signal_type dcn10_get_dig_mode(
1427     struct link_encoder *enc)
1428 {
1429     struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1430     uint32_t value;
1431     REG_GET(DIG_BE_CNTL, DIG_MODE, &value);
1432     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 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     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     if (enc->features.flags.bits.IS_HBR2_CAPABLE)
1456         max_link_cap.link_rate = LINK_RATE_HIGH2;
1457 
1458     if (enc->features.flags.bits.IS_HBR3_CAPABLE)
1459         max_link_cap.link_rate = LINK_RATE_HIGH3;
1460 
1461     if (enc->features.flags.bits.IS_UHBR10_CAPABLE)
1462         max_link_cap.link_rate = LINK_RATE_UHBR10;
1463 
1464     if (enc->features.flags.bits.IS_UHBR13_5_CAPABLE)
1465         max_link_cap.link_rate = LINK_RATE_UHBR13_5;
1466 
1467     if (enc->features.flags.bits.IS_UHBR20_CAPABLE)
1468         max_link_cap.link_rate = LINK_RATE_UHBR20;
1469 
1470     *link_settings = max_link_cap;
1471 }