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