Home | History | Annotate | Line # | Download | only in dcn20
      1 /*	$NetBSD: amdgpu_dcn20_stream_encoder.c,v 1.2 2021/12/18 23:45:03 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_dcn20_stream_encoder.c,v 1.2 2021/12/18 23:45:03 riastradh Exp $");
     30 
     31 #include <linux/delay.h>
     32 
     33 #include "dc_bios_types.h"
     34 #include "dcn20_stream_encoder.h"
     35 #include "reg_helper.h"
     36 #include "hw_shared.h"
     37 
     38 #define DC_LOGGER \
     39 		enc1->base.ctx->logger
     40 
     41 
     42 #define REG(reg)\
     43 	(enc1->regs->reg)
     44 
     45 #undef FN
     46 #define FN(reg_name, field_name) \
     47 	enc1->se_shift->field_name, enc1->se_mask->field_name
     48 
     49 
     50 #define CTX \
     51 	enc1->base.ctx
     52 
     53 
     54 static void enc2_update_hdmi_info_packet(
     55 	struct dcn10_stream_encoder *enc1,
     56 	uint32_t packet_index,
     57 	const struct dc_info_packet *info_packet)
     58 {
     59 	uint32_t cont, send, line;
     60 
     61 	if (info_packet->valid) {
     62 		enc1_update_generic_info_packet(
     63 			enc1,
     64 			packet_index,
     65 			info_packet);
     66 
     67 		/* enable transmission of packet(s) -
     68 		 * packet transmission begins on the next frame */
     69 		cont = 1;
     70 		/* send packet(s) every frame */
     71 		send = 1;
     72 		/* select line number to send packets on */
     73 		line = 2;
     74 	} else {
     75 		cont = 0;
     76 		send = 0;
     77 		line = 0;
     78 	}
     79 
     80 	/* DP_SEC_GSP[x]_LINE_REFERENCE - keep default value REFER_TO_DP_SOF */
     81 
     82 	/* choose which generic packet control to use */
     83 	switch (packet_index) {
     84 	case 0:
     85 		REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
     86 				HDMI_GENERIC0_CONT, cont,
     87 				HDMI_GENERIC0_SEND, send);
     88 		REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL1,
     89 				HDMI_GENERIC0_LINE, line);
     90 		break;
     91 	case 1:
     92 		REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
     93 				HDMI_GENERIC1_CONT, cont,
     94 				HDMI_GENERIC1_SEND, send);
     95 		REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL1,
     96 				HDMI_GENERIC1_LINE, line);
     97 		break;
     98 	case 2:
     99 		REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
    100 				HDMI_GENERIC2_CONT, cont,
    101 				HDMI_GENERIC2_SEND, send);
    102 		REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL2,
    103 				HDMI_GENERIC2_LINE, line);
    104 		break;
    105 	case 3:
    106 		REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
    107 				HDMI_GENERIC3_CONT, cont,
    108 				HDMI_GENERIC3_SEND, send);
    109 		REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL2,
    110 				HDMI_GENERIC3_LINE, line);
    111 		break;
    112 	case 4:
    113 		REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
    114 				HDMI_GENERIC4_CONT, cont,
    115 				HDMI_GENERIC4_SEND, send);
    116 		REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL3,
    117 				HDMI_GENERIC4_LINE, line);
    118 		break;
    119 	case 5:
    120 		REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
    121 				HDMI_GENERIC5_CONT, cont,
    122 				HDMI_GENERIC5_SEND, send);
    123 		REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL3,
    124 				HDMI_GENERIC5_LINE, line);
    125 		break;
    126 	case 6:
    127 		REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
    128 				HDMI_GENERIC6_CONT, cont,
    129 				HDMI_GENERIC6_SEND, send);
    130 		REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL4,
    131 				HDMI_GENERIC6_LINE, line);
    132 		break;
    133 	case 7:
    134 		REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
    135 				HDMI_GENERIC7_CONT, cont,
    136 				HDMI_GENERIC7_SEND, send);
    137 		REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL4,
    138 				HDMI_GENERIC7_LINE, line);
    139 		break;
    140 	default:
    141 		/* invalid HW packet index */
    142 		DC_LOG_WARNING(
    143 			"Invalid HW packet index: %s()\n",
    144 			__func__);
    145 		return;
    146 	}
    147 }
    148 
    149 static void enc2_stream_encoder_update_hdmi_info_packets(
    150 	struct stream_encoder *enc,
    151 	const struct encoder_info_frame *info_frame)
    152 {
    153 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
    154 
    155 	/* for bring up, disable dp double  TODO */
    156 	REG_UPDATE(HDMI_DB_CONTROL, HDMI_DB_DISABLE, 1);
    157 
    158 	/*Always add mandatory packets first followed by optional ones*/
    159 	enc2_update_hdmi_info_packet(enc1, 0, &info_frame->avi);
    160 	enc2_update_hdmi_info_packet(enc1, 5, &info_frame->hfvsif);
    161 	enc2_update_hdmi_info_packet(enc1, 2, &info_frame->gamut);
    162 	enc2_update_hdmi_info_packet(enc1, 1, &info_frame->vendor);
    163 	enc2_update_hdmi_info_packet(enc1, 3, &info_frame->spd);
    164 	enc2_update_hdmi_info_packet(enc1, 4, &info_frame->hdrsmd);
    165 }
    166 
    167 static void enc2_stream_encoder_stop_hdmi_info_packets(
    168 	struct stream_encoder *enc)
    169 {
    170 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
    171 
    172 	/* stop generic packets 0,1 on HDMI */
    173 	REG_SET_4(HDMI_GENERIC_PACKET_CONTROL0, 0,
    174 		HDMI_GENERIC0_CONT, 0,
    175 		HDMI_GENERIC0_SEND, 0,
    176 		HDMI_GENERIC1_CONT, 0,
    177 		HDMI_GENERIC1_SEND, 0);
    178 	REG_SET_2(HDMI_GENERIC_PACKET_CONTROL1, 0,
    179 		HDMI_GENERIC0_LINE, 0,
    180 		HDMI_GENERIC1_LINE, 0);
    181 
    182 	/* stop generic packets 2,3 on HDMI */
    183 	REG_SET_4(HDMI_GENERIC_PACKET_CONTROL0, 0,
    184 		HDMI_GENERIC2_CONT, 0,
    185 		HDMI_GENERIC2_SEND, 0,
    186 		HDMI_GENERIC3_CONT, 0,
    187 		HDMI_GENERIC3_SEND, 0);
    188 	REG_SET_2(HDMI_GENERIC_PACKET_CONTROL2, 0,
    189 		HDMI_GENERIC2_LINE, 0,
    190 		HDMI_GENERIC3_LINE, 0);
    191 
    192 	/* stop generic packets 4,5 on HDMI */
    193 	REG_SET_4(HDMI_GENERIC_PACKET_CONTROL0, 0,
    194 		HDMI_GENERIC4_CONT, 0,
    195 		HDMI_GENERIC4_SEND, 0,
    196 		HDMI_GENERIC5_CONT, 0,
    197 		HDMI_GENERIC5_SEND, 0);
    198 	REG_SET_2(HDMI_GENERIC_PACKET_CONTROL3, 0,
    199 		HDMI_GENERIC4_LINE, 0,
    200 		HDMI_GENERIC5_LINE, 0);
    201 
    202 	/* stop generic packets 6,7 on HDMI */
    203 	REG_SET_4(HDMI_GENERIC_PACKET_CONTROL0, 0,
    204 		HDMI_GENERIC6_CONT, 0,
    205 		HDMI_GENERIC6_SEND, 0,
    206 		HDMI_GENERIC7_CONT, 0,
    207 		HDMI_GENERIC7_SEND, 0);
    208 	REG_SET_2(HDMI_GENERIC_PACKET_CONTROL4, 0,
    209 		HDMI_GENERIC6_LINE, 0,
    210 		HDMI_GENERIC7_LINE, 0);
    211 }
    212 
    213 
    214 /* Update GSP7 SDP 128 byte long */
    215 static void enc2_update_gsp7_128_info_packet(
    216 	struct dcn10_stream_encoder *enc1,
    217 	const struct dc_info_packet_128 *info_packet)
    218 {
    219 	uint32_t i;
    220 
    221 	/* TODOFPGA Figure out a proper number for max_retries polling for lock
    222 	 * use 50 for now.
    223 	 */
    224 	uint32_t max_retries = 50;
    225 	const uint32_t *content = (const uint32_t *) &info_packet->sb[0];
    226 
    227 	ASSERT(info_packet->hb1  == DC_DP_INFOFRAME_TYPE_PPS);
    228 
    229 	/* Configure for PPS packet size (128 bytes) */
    230 	REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP7_PPS, 1);
    231 
    232 	/* We need turn on clock before programming AFMT block*/
    233 	REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1);
    234 
    235 	/* Poll dig_update_lock is not locked -> asic internal signal
    236 	 * assumes otg master lock will unlock it
    237 	 */
    238 	/*REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS, 0, 10, max_retries);*/
    239 
    240 	/* Wait for HW/SW GSP memory access conflict to go away */
    241 	REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT,
    242 			0, 10, max_retries);
    243 
    244 	/* Clear HW/SW memory access conflict flag */
    245 	REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT_CLR, 1);
    246 
    247 	/* write generic packet header */
    248 	REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_INDEX, 7);
    249 	REG_SET_4(AFMT_GENERIC_HDR, 0,
    250 			AFMT_GENERIC_HB0, info_packet->hb0,
    251 			AFMT_GENERIC_HB1, info_packet->hb1,
    252 			AFMT_GENERIC_HB2, info_packet->hb2,
    253 			AFMT_GENERIC_HB3, info_packet->hb3);
    254 
    255 	/* Write generic packet content 128 bytes long. Four sets are used (indexes 7
    256 	 * through 10) to fit 128 bytes.
    257 	 */
    258 	for (i = 0; i < 4; i++) {
    259 		uint32_t packet_index = 7 + i;
    260 		REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_INDEX, packet_index);
    261 
    262 		REG_WRITE(AFMT_GENERIC_0, *content++);
    263 		REG_WRITE(AFMT_GENERIC_1, *content++);
    264 		REG_WRITE(AFMT_GENERIC_2, *content++);
    265 		REG_WRITE(AFMT_GENERIC_3, *content++);
    266 		REG_WRITE(AFMT_GENERIC_4, *content++);
    267 		REG_WRITE(AFMT_GENERIC_5, *content++);
    268 		REG_WRITE(AFMT_GENERIC_6, *content++);
    269 		REG_WRITE(AFMT_GENERIC_7, *content++);
    270 	}
    271 
    272 	REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_FRAME_UPDATE, 1);
    273 }
    274 
    275 /* Set DSC-related configuration.
    276  *   dsc_mode: 0 disables DSC, other values enable DSC in specified format
    277  *   sc_bytes_per_pixel: Bytes per pixel in u3.28 format
    278  *   dsc_slice_width: Slice width in pixels
    279  */
    280 static void enc2_dp_set_dsc_config(struct stream_encoder *enc,
    281 					enum optc_dsc_mode dsc_mode,
    282 					uint32_t dsc_bytes_per_pixel,
    283 					uint32_t dsc_slice_width)
    284 {
    285 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
    286 
    287 	REG_UPDATE_2(DP_DSC_CNTL,
    288 			DP_DSC_MODE, dsc_mode,
    289 			DP_DSC_SLICE_WIDTH, dsc_slice_width);
    290 
    291 	REG_SET(DP_DSC_BYTES_PER_PIXEL, 0,
    292 		DP_DSC_BYTES_PER_PIXEL, dsc_bytes_per_pixel);
    293 }
    294 
    295 
    296 static void enc2_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
    297 					bool enable,
    298 					uint8_t *dsc_packed_pps)
    299 {
    300 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
    301 
    302 	if (enable) {
    303 		struct dc_info_packet_128 pps_sdp;
    304 
    305 		ASSERT(dsc_packed_pps);
    306 
    307 		/* Load PPS into infoframe (SDP) registers */
    308 		pps_sdp.valid = true;
    309 		pps_sdp.hb0 = 0;
    310 		pps_sdp.hb1 = DC_DP_INFOFRAME_TYPE_PPS;
    311 		pps_sdp.hb2 = 127;
    312 		pps_sdp.hb3 = 0;
    313 		memcpy(&pps_sdp.sb[0], dsc_packed_pps, sizeof(pps_sdp.sb));
    314 		enc2_update_gsp7_128_info_packet(enc1, &pps_sdp);
    315 
    316 		/* Enable Generic Stream Packet 7 (GSP) transmission */
    317 		//REG_UPDATE(DP_SEC_CNTL,
    318 		//	DP_SEC_GSP7_ENABLE, 1);
    319 
    320 		/* SW should make sure VBID[6] update line number is bigger
    321 		 * than PPS transmit line number
    322 		 */
    323 		REG_UPDATE(DP_SEC_CNTL6,
    324 				DP_SEC_GSP7_LINE_NUM, 2);
    325 		REG_UPDATE_2(DP_MSA_VBID_MISC,
    326 				DP_VBID6_LINE_REFERENCE, 0,
    327 				DP_VBID6_LINE_NUM, 3);
    328 
    329 		/* Send PPS data at the line number specified above.
    330 		 * DP spec requires PPS to be sent only when it changes, however since
    331 		 * decoder has to be able to handle its change on every frame, we're
    332 		 * sending it always (i.e. on every frame) to reduce the chance it'd be
    333 		 * missed by decoder. If it turns out required to send PPS only when it
    334 		 * changes, we can use DP_SEC_GSP7_SEND register.
    335 		 */
    336 		REG_UPDATE_2(DP_SEC_CNTL,
    337 			DP_SEC_GSP7_ENABLE, 1,
    338 			DP_SEC_STREAM_ENABLE, 1);
    339 	} else {
    340 		/* Disable Generic Stream Packet 7 (GSP) transmission */
    341 		REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP7_ENABLE, 0);
    342 		REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP7_PPS, 0);
    343 	}
    344 }
    345 
    346 
    347 /* this function read dsc related register fields to be logged later in dcn10_log_hw_state
    348  * into a dcn_dsc_state struct.
    349  */
    350 static void enc2_read_state(struct stream_encoder *enc, struct enc_state *s)
    351 {
    352 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
    353 
    354 	//if dsc is enabled, continue to read
    355 	REG_GET(DP_DSC_CNTL, DP_DSC_MODE, &s->dsc_mode);
    356 	if (s->dsc_mode) {
    357 		REG_GET(DP_DSC_CNTL, DP_DSC_SLICE_WIDTH, &s->dsc_slice_width);
    358 		REG_GET(DP_SEC_CNTL6, DP_SEC_GSP7_LINE_NUM, &s->sec_gsp_pps_line_num);
    359 
    360 		REG_GET(DP_MSA_VBID_MISC, DP_VBID6_LINE_REFERENCE, &s->vbid6_line_reference);
    361 		REG_GET(DP_MSA_VBID_MISC, DP_VBID6_LINE_NUM, &s->vbid6_line_num);
    362 
    363 		REG_GET(DP_SEC_CNTL, DP_SEC_GSP7_ENABLE, &s->sec_gsp_pps_enable);
    364 		REG_GET(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, &s->sec_stream_enable);
    365 	}
    366 }
    367 
    368 /* Set Dynamic Metadata-configuration.
    369  *   enable_dme:         TRUE: enables Dynamic Metadata Enfine, FALSE: disables DME
    370  *   hubp_requestor_id:  HUBP physical instance that is the source of dynamic metadata
    371  *                       only needs to be set when enable_dme is TRUE
    372  *   dmdata_mode:        dynamic metadata packet type: DP, HDMI, or Dolby Vision
    373  *
    374  *   Ensure the OTG master update lock is set when changing DME configuration.
    375  */
    376 void enc2_set_dynamic_metadata(struct stream_encoder *enc,
    377 		bool enable_dme,
    378 		uint32_t hubp_requestor_id,
    379 		enum dynamic_metadata_mode dmdata_mode)
    380 {
    381 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
    382 
    383 	if (enable_dme) {
    384 		REG_UPDATE_2(DME_CONTROL,
    385 				METADATA_HUBP_REQUESTOR_ID, hubp_requestor_id,
    386 				METADATA_STREAM_TYPE, (dmdata_mode == dmdata_dolby_vision) ? 1 : 0);
    387 
    388 		/* Use default line reference DP_SOF for bringup.
    389 		 * Should use OTG_SOF for DRR cases
    390 		 */
    391 		if (dmdata_mode == dmdata_dp)
    392 			REG_UPDATE_3(DP_SEC_METADATA_TRANSMISSION,
    393 					DP_SEC_METADATA_PACKET_ENABLE, 1,
    394 					DP_SEC_METADATA_PACKET_LINE_REFERENCE, 0,
    395 					DP_SEC_METADATA_PACKET_LINE, 20);
    396 		else {
    397 			REG_UPDATE_3(HDMI_METADATA_PACKET_CONTROL,
    398 					HDMI_METADATA_PACKET_ENABLE, 1,
    399 					HDMI_METADATA_PACKET_LINE_REFERENCE, 0,
    400 					HDMI_METADATA_PACKET_LINE, 2);
    401 
    402 			if (dmdata_mode == dmdata_dolby_vision)
    403 				REG_UPDATE(DIG_FE_CNTL,
    404 						DOLBY_VISION_EN, 1);
    405 		}
    406 
    407 		REG_UPDATE(DME_CONTROL,
    408 				METADATA_ENGINE_EN, 1);
    409 	} else {
    410 		REG_UPDATE(DME_CONTROL,
    411 				METADATA_ENGINE_EN, 0);
    412 
    413 		if (dmdata_mode == dmdata_dp)
    414 			REG_UPDATE(DP_SEC_METADATA_TRANSMISSION,
    415 					DP_SEC_METADATA_PACKET_ENABLE, 0);
    416 		else {
    417 			REG_UPDATE(HDMI_METADATA_PACKET_CONTROL,
    418 					HDMI_METADATA_PACKET_ENABLE, 0);
    419 			REG_UPDATE(DIG_FE_CNTL,
    420 					DOLBY_VISION_EN, 0);
    421 		}
    422 	}
    423 }
    424 
    425 static void enc2_stream_encoder_update_dp_info_packets(
    426 	struct stream_encoder *enc,
    427 	const struct encoder_info_frame *info_frame)
    428 {
    429 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
    430 	uint32_t dmdata_packet_enabled = 0;
    431 
    432 	enc1_stream_encoder_update_dp_info_packets(enc, info_frame);
    433 
    434 	/* check if dynamic metadata packet transmission is enabled */
    435 	REG_GET(DP_SEC_METADATA_TRANSMISSION,
    436 			DP_SEC_METADATA_PACKET_ENABLE, &dmdata_packet_enabled);
    437 
    438 	if (dmdata_packet_enabled)
    439 		REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
    440 }
    441 
    442 static bool is_two_pixels_per_containter(const struct dc_crtc_timing *timing)
    443 {
    444 	bool two_pix = timing->pixel_encoding == PIXEL_ENCODING_YCBCR420;
    445 
    446 	two_pix = two_pix || (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
    447 			&& !timing->dsc_cfg.ycbcr422_simple);
    448 	return two_pix;
    449 }
    450 
    451 void enc2_stream_encoder_dp_unblank(
    452 		struct stream_encoder *enc,
    453 		const struct encoder_unblank_param *param)
    454 {
    455 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
    456 
    457 	if (param->link_settings.link_rate != LINK_RATE_UNKNOWN) {
    458 		uint32_t n_vid = 0x8000;
    459 		uint32_t m_vid;
    460 		uint32_t n_multiply = 0;
    461 		uint64_t m_vid_l = n_vid;
    462 
    463 		/* YCbCr 4:2:0 : Computed VID_M will be 2X the input rate */
    464 		if (is_two_pixels_per_containter(&param->timing) || param->opp_cnt > 1) {
    465 			/*this logic should be the same in get_pixel_clock_parameters() */
    466 			n_multiply = 1;
    467 		}
    468 		/* M / N = Fstream / Flink
    469 		 * m_vid / n_vid = pixel rate / link rate
    470 		 */
    471 
    472 		m_vid_l *= param->timing.pix_clk_100hz / 10;
    473 		m_vid_l = div_u64(m_vid_l,
    474 			param->link_settings.link_rate
    475 				* LINK_RATE_REF_FREQ_IN_KHZ);
    476 
    477 		m_vid = (uint32_t) m_vid_l;
    478 
    479 		/* enable auto measurement */
    480 
    481 		REG_UPDATE(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 0);
    482 
    483 		/* auto measurement need 1 full 0x8000 symbol cycle to kick in,
    484 		 * therefore program initial value for Mvid and Nvid
    485 		 */
    486 
    487 		REG_UPDATE(DP_VID_N, DP_VID_N, n_vid);
    488 
    489 		REG_UPDATE(DP_VID_M, DP_VID_M, m_vid);
    490 
    491 		REG_UPDATE_2(DP_VID_TIMING,
    492 				DP_VID_M_N_GEN_EN, 1,
    493 				DP_VID_N_MUL, n_multiply);
    494 	}
    495 
    496 	/* make sure stream is disabled before resetting steer fifo */
    497 	REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, false);
    498 	REG_WAIT(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, 0, 10, 5000);
    499 
    500 	/* set DIG_START to 0x1 to reset FIFO */
    501 	REG_UPDATE(DIG_FE_CNTL, DIG_START, 1);
    502 	udelay(1);
    503 
    504 	/* write 0 to take the FIFO out of reset */
    505 
    506 	REG_UPDATE(DIG_FE_CNTL, DIG_START, 0);
    507 
    508 	/* switch DP encoder to CRTC data, but reset it the fifo first. It may happen
    509 	 * that it overflows during mode transition, and sometimes doesn't recover.
    510 	 */
    511 	REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 1);
    512 	udelay(10);
    513 
    514 	REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0);
    515 
    516 	/* wait 100us for DIG/DP logic to prime
    517 	 * (i.e. a few video lines)
    518 	 */
    519 	udelay(100);
    520 
    521 	/* the hardware would start sending video at the start of the next DP
    522 	 * frame (i.e. rising edge of the vblank).
    523 	 * NOTE: We used to program DP_VID_STREAM_DIS_DEFER = 2 here, but this
    524 	 * register has no effect on enable transition! HW always guarantees
    525 	 * VID_STREAM enable at start of next frame, and this is not
    526 	 * programmable
    527 	 */
    528 
    529 	REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);
    530 }
    531 
    532 static void enc2_dp_set_odm_combine(
    533 	struct stream_encoder *enc,
    534 	bool odm_combine)
    535 {
    536 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
    537 
    538 	REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_COMBINE, odm_combine);
    539 }
    540 
    541 void enc2_stream_encoder_dp_set_stream_attribute(
    542 	struct stream_encoder *enc,
    543 	struct dc_crtc_timing *crtc_timing,
    544 	enum dc_color_space output_color_space,
    545 	bool use_vsc_sdp_for_colorimetry,
    546 	uint32_t enable_sdp_splitting)
    547 {
    548 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
    549 
    550 	enc1_stream_encoder_dp_set_stream_attribute(enc,
    551 			crtc_timing,
    552 			output_color_space,
    553 			use_vsc_sdp_for_colorimetry,
    554 			enable_sdp_splitting);
    555 
    556 	REG_UPDATE(DP_SEC_FRAMING4,
    557 		DP_SST_SDP_SPLITTING, enable_sdp_splitting);
    558 }
    559 
    560 static const struct stream_encoder_funcs dcn20_str_enc_funcs = {
    561 	.dp_set_odm_combine =
    562 		enc2_dp_set_odm_combine,
    563 	.dp_set_stream_attribute =
    564 		enc2_stream_encoder_dp_set_stream_attribute,
    565 	.hdmi_set_stream_attribute =
    566 		enc1_stream_encoder_hdmi_set_stream_attribute,
    567 	.dvi_set_stream_attribute =
    568 		enc1_stream_encoder_dvi_set_stream_attribute,
    569 	.set_mst_bandwidth =
    570 		enc1_stream_encoder_set_mst_bandwidth,
    571 	.update_hdmi_info_packets =
    572 		enc2_stream_encoder_update_hdmi_info_packets,
    573 	.stop_hdmi_info_packets =
    574 		enc2_stream_encoder_stop_hdmi_info_packets,
    575 	.update_dp_info_packets =
    576 		enc2_stream_encoder_update_dp_info_packets,
    577 	.send_immediate_sdp_message =
    578 		enc1_stream_encoder_send_immediate_sdp_message,
    579 	.stop_dp_info_packets =
    580 		enc1_stream_encoder_stop_dp_info_packets,
    581 	.dp_blank =
    582 		enc1_stream_encoder_dp_blank,
    583 	.dp_unblank =
    584 		enc2_stream_encoder_dp_unblank,
    585 	.audio_mute_control = enc1_se_audio_mute_control,
    586 
    587 	.dp_audio_setup = enc1_se_dp_audio_setup,
    588 	.dp_audio_enable = enc1_se_dp_audio_enable,
    589 	.dp_audio_disable = enc1_se_dp_audio_disable,
    590 
    591 	.hdmi_audio_setup = enc1_se_hdmi_audio_setup,
    592 	.hdmi_audio_disable = enc1_se_hdmi_audio_disable,
    593 	.setup_stereo_sync  = enc1_setup_stereo_sync,
    594 	.set_avmute = enc1_stream_encoder_set_avmute,
    595 	.dig_connect_to_otg  = enc1_dig_connect_to_otg,
    596 	.dig_source_otg = enc1_dig_source_otg,
    597 
    598 	.dp_get_pixel_format =
    599 		enc1_stream_encoder_dp_get_pixel_format,
    600 
    601 	.enc_read_state = enc2_read_state,
    602 	.dp_set_dsc_config = enc2_dp_set_dsc_config,
    603 	.dp_set_dsc_pps_info_packet = enc2_dp_set_dsc_pps_info_packet,
    604 	.set_dynamic_metadata = enc2_set_dynamic_metadata,
    605 	.hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
    606 };
    607 
    608 void dcn20_stream_encoder_construct(
    609 	struct dcn10_stream_encoder *enc1,
    610 	struct dc_context *ctx,
    611 	struct dc_bios *bp,
    612 	enum engine_id eng_id,
    613 	const struct dcn10_stream_enc_registers *regs,
    614 	const struct dcn10_stream_encoder_shift *se_shift,
    615 	const struct dcn10_stream_encoder_mask *se_mask)
    616 {
    617 	enc1->base.funcs = &dcn20_str_enc_funcs;
    618 	enc1->base.ctx = ctx;
    619 	enc1->base.id = eng_id;
    620 	enc1->base.bp = bp;
    621 	enc1->regs = regs;
    622 	enc1->se_shift = se_shift;
    623 	enc1->se_mask = se_mask;
    624 }
    625 
    626