FILE
dcn35_dio_stream_encoder.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c
1/* SPDX-License-Identifier: MIT */ 2/* 3 * Copyright 2023 Advanced Micro Devices, Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 * OTHER DEALINGS IN THE SOFTWARE. 22 * 23 */ 24 25#include "dc_bios_types.h" 26#include "dcn30/dcn30_dio_stream_encoder.h" 27#include "dcn314/dcn314_dio_stream_encoder.h" 28#include "dcn32/dcn32_dio_stream_encoder.h" 29#include "dcn35_dio_stream_encoder.h" 30#include "reg_helper.h" 31#include "hw_shared.h" 32#include "link_service.h" 33#include "dpcd_defs.h" 34 35#define DC_LOGGER \ 36 enc1->base.ctx->logger 37 38#define REG(reg)\ 39 (enc1->regs->reg) 40 41#undef FN 42#define FN(reg_name, field_name) \ 43 enc1->se_shift->field_name, enc1->se_mask->field_name 44 45#define VBI_LINE_0 0 46#define HDMI_CLOCK_CHANNEL_RATE_MORE_340M 340000 47 48#define CTX \ 49 enc1->base.ctx 50/* setup stream encoder in dvi mode */ 51static void enc35_stream_encoder_dvi_set_stream_attribute( 52 struct stream_encoder *enc, 53 struct dc_crtc_timing *crtc_timing, 54 bool is_dual_link) 55{ 56 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 57 58 if (!enc->ctx->dc->debug.avoid_vbios_exec_table) { 59 struct bp_encoder_control cntl = {0}; 60 61 cntl.action = ENCODER_CONTROL_SETUP; 62 cntl.engine_id = enc1->base.id; 63 cntl.signal = is_dual_link ? 64 SIGNAL_TYPE_DVI_DUAL_LINK : SIGNAL_TYPE_DVI_SINGLE_LINK; 65 cntl.enable_dp_audio = false; 66 cntl.pixel_clock = crtc_timing->pix_clk_100hz / 10; 67 cntl.lanes_number = (is_dual_link) ? LANE_COUNT_EIGHT : LANE_COUNT_FOUR; 68 69 if (enc1->base.bp->funcs->encoder_control( 70 enc1->base.bp, &cntl) != BP_RESULT_OK) 71 return; 72 73 } else { 74 75 //Set pattern for clock channel, default vlue 0x63 does not work 76 REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F); 77 78 //DIG_BE_TMDS_DVI_MODE : TMDS-DVI mode is already set in link_encoder_setup 79 80 //DIG_SOURCE_SELECT is already set in dig_connect_to_otg 81 82 /* DIG_START is removed from the register spec */ 83 } 84 85 ASSERT(crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB); 86 ASSERT(crtc_timing->display_color_depth == COLOR_DEPTH_888); 87 enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing); 88} 89/* setup stream encoder in hdmi mode */ 90static void enc35_stream_encoder_hdmi_set_stream_attribute( 91 struct stream_encoder *enc, 92 struct dc_crtc_timing *crtc_timing, 93 int actual_pix_clk_khz, 94 bool enable_audio) 95{ 96 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 97 98 if (!enc->ctx->dc->debug.avoid_vbios_exec_table) { 99 struct bp_encoder_control cntl = {0}; 100 101 cntl.action = ENCODER_CONTROL_SETUP; 102 cntl.engine_id = enc1->base.id; 103 cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A; 104 cntl.enable_dp_audio = enable_audio; 105 cntl.pixel_clock = actual_pix_clk_khz; 106 cntl.lanes_number = LANE_COUNT_FOUR; 107 108 if (enc1->base.bp->funcs->encoder_control( 109 enc1->base.bp, &cntl) != BP_RESULT_OK) 110 return; 111 112 } else { 113 114 //Set pattern for clock channel, default vlue 0x63 does not work 115 REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F); 116 117 //DIG_BE_TMDS_HDMI_MODE : TMDS-HDMI mode is already set in link_encoder_setup 118 119 //DIG_SOURCE_SELECT is already set in dig_connect_to_otg 120 121 /* DIG_START is removed from the register spec */ 122 enc314_enable_fifo(enc); 123 } 124 125 /* Configure pixel encoding */ 126 enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing); 127 128 /* setup HDMI engine */ 129 REG_UPDATE_6(HDMI_CONTROL, 130 HDMI_PACKET_GEN_VERSION, 1, 131 HDMI_KEEPOUT_MODE, 1, 132 HDMI_DEEP_COLOR_ENABLE, 0, 133 HDMI_DATA_SCRAMBLE_EN, 0, 134 HDMI_NO_EXTRA_NULL_PACKET_FILLED, 1, 135 HDMI_CLOCK_CHANNEL_RATE, 0); 136 137 /* Configure color depth */ 138 switch (crtc_timing->display_color_depth) { 139 case COLOR_DEPTH_888: 140 REG_UPDATE(HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, 0); 141 break; 142 case COLOR_DEPTH_101010: 143 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) { 144 REG_UPDATE_2(HDMI_CONTROL, 145 HDMI_DEEP_COLOR_DEPTH, 1, 146 HDMI_DEEP_COLOR_ENABLE, 0); 147 } else { 148 REG_UPDATE_2(HDMI_CONTROL, 149 HDMI_DEEP_COLOR_DEPTH, 1, 150 HDMI_DEEP_COLOR_ENABLE, 1); 151 } 152 break; 153 case COLOR_DEPTH_121212: 154 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) { 155 REG_UPDATE_2(HDMI_CONTROL, 156 HDMI_DEEP_COLOR_DEPTH, 2, 157 HDMI_DEEP_COLOR_ENABLE, 0); 158 } else { 159 REG_UPDATE_2(HDMI_CONTROL, 160 HDMI_DEEP_COLOR_DEPTH, 2, 161 HDMI_DEEP_COLOR_ENABLE, 1); 162 } 163 break; 164 case COLOR_DEPTH_161616: 165 REG_UPDATE_2(HDMI_CONTROL, 166 HDMI_DEEP_COLOR_DEPTH, 3, 167 HDMI_DEEP_COLOR_ENABLE, 1); 168 break; 169 default: 170 break; 171 } 172 173 if (actual_pix_clk_khz >= HDMI_CLOCK_CHANNEL_RATE_MORE_340M) { 174 /* enable HDMI data scrambler 175 * HDMI_CLOCK_CHANNEL_RATE_MORE_340M 176 * Clock channel frequency is 1/4 of character rate. 177 */ 178 REG_UPDATE_2(HDMI_CONTROL, 179 HDMI_DATA_SCRAMBLE_EN, 1, 180 HDMI_CLOCK_CHANNEL_RATE, 1); 181 } else if (crtc_timing->flags.LTE_340MCSC_SCRAMBLE) { 182 183 /* TODO: New feature for DCE11, still need to implement */ 184 185 /* enable HDMI data scrambler 186 * HDMI_CLOCK_CHANNEL_FREQ_EQUAL_TO_CHAR_RATE 187 * Clock channel frequency is the same 188 * as character rate 189 */ 190 REG_UPDATE_2(HDMI_CONTROL, 191 HDMI_DATA_SCRAMBLE_EN, 1, 192 HDMI_CLOCK_CHANNEL_RATE, 0); 193 } 194 195 196 /* Enable transmission of General Control packet on every frame */ 197 REG_UPDATE_3(HDMI_VBI_PACKET_CONTROL, 198 HDMI_GC_CONT, 1, 199 HDMI_GC_SEND, 1, 200 HDMI_NULL_SEND, 1); 201 202 /* Disable Audio Content Protection packet transmission */ 203 REG_UPDATE(HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, 0); 204 205 /* following belongs to audio */ 206 /* Enable Audio InfoFrame packet transmission. */ 207 REG_UPDATE(HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, 1); 208 209 /* update double-buffered AUDIO_INFO registers immediately */ 210 ASSERT(enc->afmt); 211 enc->afmt->funcs->audio_info_immediate_update(enc->afmt); 212 213 /* Select line number on which to send Audio InfoFrame packets */ 214 REG_UPDATE(HDMI_INFOFRAME_CONTROL1, HDMI_AUDIO_INFO_LINE, 215 VBI_LINE_0 + 2); 216 217 /* set HDMI GC AVMUTE */ 218 REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, 0); 219 switch (crtc_timing->pixel_encoding) { 220 case PIXEL_ENCODING_YCBCR422: 221 REG_UPDATE(HDMI_CONTROL, TMDS_PIXEL_ENCODING, 1); 222 break; 223 default: 224 REG_UPDATE(HDMI_CONTROL, TMDS_PIXEL_ENCODING, 0); 225 break; 226 } 227 REG_UPDATE(HDMI_CONTROL, TMDS_COLOR_FORMAT, 0); 228} 229 230 231 232static void enc35_stream_encoder_enable( 233 struct stream_encoder *enc, 234 enum signal_type signal, 235 bool enable) 236{ 237 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 238 239 if (enable) { 240 switch (signal) { 241 case SIGNAL_TYPE_DVI_SINGLE_LINK: 242 case SIGNAL_TYPE_DVI_DUAL_LINK: 243 /* TMDS-DVI */ 244 REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_MODE, 2); 245 break; 246 case SIGNAL_TYPE_HDMI_TYPE_A: 247 /* TMDS-HDMI */ 248 REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_MODE, 3); 249 break; 250 case SIGNAL_TYPE_DISPLAY_PORT_MST: 251 /* DP MST */ 252 REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_MODE, 5); 253 break; 254 case SIGNAL_TYPE_EDP: 255 case SIGNAL_TYPE_DISPLAY_PORT: 256 case SIGNAL_TYPE_VIRTUAL: 257 /* DP SST */ 258 REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_MODE, 0); 259 break; 260 default: 261 /* invalid mode ! */ 262 ASSERT_CRITICAL(false); 263 } 264 } 265} 266 267static bool is_two_pixels_per_containter(const struct dc_crtc_timing *timing) 268{ 269 bool two_pix = timing->pixel_encoding == PIXEL_ENCODING_YCBCR420; 270 271 two_pix = two_pix || (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422 272 && !timing->dsc_cfg.ycbcr422_simple); 273 return two_pix; 274} 275 276static void enc35_stream_encoder_dp_unblank( 277 struct dc_link *link, 278 struct stream_encoder *enc, 279 const struct encoder_unblank_param *param) 280{ 281 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 282 283 if (param->link_settings.link_rate != LINK_RATE_UNKNOWN) { 284 uint32_t n_vid = 0x8000; 285 uint32_t m_vid; 286 uint32_t n_multiply = 0; 287 uint32_t pix_per_cycle = 0; 288 uint64_t m_vid_l = n_vid; 289 290 /* YCbCr 4:2:0 : Computed VID_M will be 2X the input rate */ 291 if (is_two_pixels_per_containter(¶m->timing) || param->opp_cnt > 1 292 || param->pix_per_cycle > 1) { 293 /*this logic should be the same in get_pixel_clock_parameters() */ 294 n_multiply = 1; 295 pix_per_cycle = 1; 296 } 297 /* M / N = Fstream / Flink 298 * m_vid / n_vid = pixel rate / link rate 299 */ 300 301 m_vid_l *= param->timing.pix_clk_100hz / 10; 302 m_vid_l = div_u64(m_vid_l, 303 param->link_settings.link_rate 304 * LINK_RATE_REF_FREQ_IN_KHZ); 305 306 m_vid = (uint32_t) m_vid_l; 307 308 /* enable auto measurement */ 309 310 REG_UPDATE(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 0); 311 312 /* auto measurement need 1 full 0x8000 symbol cycle to kick in, 313 * therefore program initial value for Mvid and Nvid 314 */ 315 316 REG_UPDATE(DP_VID_N, DP_VID_N, n_vid); 317 318 REG_UPDATE(DP_VID_M, DP_VID_M, m_vid); 319 320 REG_UPDATE_2(DP_VID_TIMING, 321 DP_VID_M_N_GEN_EN, 1, 322 DP_VID_N_MUL, n_multiply); 323 324 REG_UPDATE(DP_PIXEL_FORMAT, 325 DP_PIXEL_PER_CYCLE_PROCESSING_MODE, 326 pix_per_cycle); 327 } 328 329 /* make sure stream is disabled before resetting steer fifo */ 330 REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, false); 331 REG_WAIT(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, 0, 10, 5000); 332 333 /* DIG_START is removed from the register spec */ 334 335 /* switch DP encoder to CRTC data, but reset it the fifo first. It may happen 336 * that it overflows during mode transition, and sometimes doesn't recover. 337 */ 338 REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 1); 339 udelay(10); 340 341 REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0); 342 343 /* wait 100us for DIG/DP logic to prime 344 * (i.e. a few video lines) 345 */ 346 udelay(100); 347 348 /* the hardware would start sending video at the start of the next DP 349 * frame (i.e. rising edge of the vblank). 350 * NOTE: We used to program DP_VID_STREAM_DIS_DEFER = 2 here, but this 351 * register has no effect on enable transition! HW always makes sure 352 * VID_STREAM enable at start of next frame, and this is not 353 * programmable 354 */ 355 356 REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true); 357 358 /* 359 * DIG Resync FIFO now needs to be explicitly enabled. 360 * This should come after DP_VID_STREAM_ENABLE per HW docs. 361 */ 362 enc314_enable_fifo(enc); 363 364 link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); 365} 366 367static void enc35_stream_encoder_map_to_link( 368 struct stream_encoder *enc, 369 uint32_t stream_enc_inst, 370 uint32_t link_enc_inst) 371{ 372 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 373 374 ASSERT(stream_enc_inst < 5 && link_enc_inst < 5); 375 REG_UPDATE(STREAM_MAPPER_CONTROL, 376 DIG_STREAM_LINK_TARGET, link_enc_inst); 377} 378 379static void enc35_reset_fifo(struct stream_encoder *enc, bool reset) 380{ 381 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 382 uint32_t reset_val = reset ? 1 : 0; 383 uint32_t is_symclk_on; 384 385 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, reset_val); 386 REG_GET(DIG_FE_CLK_CNTL, DIG_FE_SYMCLK_FE_G_CLOCK_ON, &is_symclk_on); 387 388 if (is_symclk_on) 389 REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, reset_val, 10, 5000); 390 else 391 udelay(10); 392} 393 394static bool enc35_is_fifo_enabled(struct stream_encoder *enc) 395{ 396 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 397 uint32_t reset_val; 398 399 REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, &reset_val); 400 return reset_val != 0; 401} 402void enc35_disable_fifo(struct stream_encoder *enc) 403{ 404 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 405 406 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 0); 407 REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 0); 408 REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 0); 409} 410 411void enc35_enable_fifo(struct stream_encoder *enc) 412{ 413 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 414 415 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, 0x7); 416 REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 1); 417 REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 1); 418 419 enc35_reset_fifo(enc, true); 420 enc35_reset_fifo(enc, false); 421 422 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1); 423} 424 425static uint32_t enc35_get_pixels_per_cycle(struct stream_encoder *enc) 426{ 427 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 428 uint32_t value; 429 430 REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_OUTPUT_PIXEL_MODE, &value); 431 432 switch (value) { 433 case 0: 434 return 1; 435 case 1: 436 return 2; 437 default: 438 ASSERT_CRITICAL(false); 439 return 1; 440 } 441} 442 443static const struct stream_encoder_funcs dcn35_str_enc_funcs = { 444 .dp_set_odm_combine = 445 enc314_dp_set_odm_combine, 446 .dp_set_stream_attribute = 447 enc2_stream_encoder_dp_set_stream_attribute, 448 .hdmi_set_stream_attribute = 449 enc35_stream_encoder_hdmi_set_stream_attribute, 450 .dvi_set_stream_attribute = 451 enc35_stream_encoder_dvi_set_stream_attribute, 452 .set_throttled_vcp_size = 453 enc1_stream_encoder_set_throttled_vcp_size, 454 .update_hdmi_info_packets = 455 enc3_stream_encoder_update_hdmi_info_packets, 456 .stop_hdmi_info_packets = 457 enc3_stream_encoder_stop_hdmi_info_packets, 458 .update_dp_info_packets_sdp_line_num = 459 enc3_stream_encoder_update_dp_info_packets_sdp_line_num, 460 .update_dp_info_packets = 461 enc3_stream_encoder_update_dp_info_packets, 462 .stop_dp_info_packets = 463 enc1_stream_encoder_stop_dp_info_packets, 464 .dp_blank = 465 enc314_stream_encoder_dp_blank, 466 .dp_unblank = 467 enc35_stream_encoder_dp_unblank, 468 .audio_mute_control = enc3_audio_mute_control, 469 470 .dp_audio_setup = enc3_se_dp_audio_setup, 471 .dp_audio_enable = enc3_se_dp_audio_enable, 472 .dp_audio_disable = enc1_se_dp_audio_disable, 473 474 .hdmi_audio_setup = enc3_se_hdmi_audio_setup, 475 .hdmi_audio_disable = enc1_se_hdmi_audio_disable, 476 .setup_stereo_sync = enc1_setup_stereo_sync, 477 .set_avmute = enc1_stream_encoder_set_avmute, 478 .dig_connect_to_otg = enc1_dig_connect_to_otg, 479 .dig_source_otg = enc1_dig_source_otg, 480 481 .dp_get_pixel_format = enc1_stream_encoder_dp_get_pixel_format, 482 483 .enc_read_state = enc314_read_state, 484 .dp_set_dsc_config = enc314_dp_set_dsc_config, 485 .dp_set_dsc_pps_info_packet = enc3_dp_set_dsc_pps_info_packet, 486 .set_dynamic_metadata = enc2_set_dynamic_metadata, 487 .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute, 488 .enable_stream = enc35_stream_encoder_enable, 489 490 .set_input_mode = enc314_set_dig_input_mode, 491 .enable_fifo = enc35_enable_fifo, 492 .disable_fifo = enc35_disable_fifo, 493 .is_fifo_enabled = enc35_is_fifo_enabled, 494 .map_stream_to_link = enc35_stream_encoder_map_to_link, 495 .get_pixels_per_cycle = enc35_get_pixels_per_cycle, 496}; 497 498void dcn35_dio_stream_encoder_construct( 499 struct dcn10_stream_encoder *enc1, 500 struct dc_context *ctx, 501 struct dc_bios *bp, 502 enum engine_id eng_id, 503 struct vpg *vpg, 504 struct afmt *afmt, 505 const struct dcn10_stream_enc_registers *regs, 506 const struct dcn10_stream_encoder_shift *se_shift, 507 const struct dcn10_stream_encoder_mask *se_mask) 508{ 509 enc1->base.funcs = &dcn35_str_enc_funcs; 510 enc1->base.ctx = ctx; 511 enc1->base.id = eng_id; 512 enc1->base.bp = bp; 513 enc1->base.vpg = vpg; 514 enc1->base.afmt = afmt; 515 enc1->regs = regs; 516 enc1->se_shift = se_shift; 517 enc1->se_mask = se_mask; 518 enc1->base.stream_enc_inst = vpg->inst; 519} 520
~/
Read-only file preview.