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