root/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. enc2_update_hdmi_info_packet
  2. enc2_stream_encoder_update_hdmi_info_packets
  3. enc2_stream_encoder_stop_hdmi_info_packets
  4. enc2_update_gsp7_128_info_packet
  5. enc2_dp_set_dsc_config
  6. enc2_dp_set_dsc_pps_info_packet
  7. enc2_read_state
  8. enc2_set_dynamic_metadata
  9. enc2_stream_encoder_update_dp_info_packets
  10. is_two_pixels_per_containter
  11. enc2_stream_encoder_dp_unblank
  12. enc2_dp_set_odm_combine
  13. enc2_stream_encoder_dp_set_stream_attribute
  14. dcn20_stream_encoder_construct

   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, 5, &info_frame->hfvsif);
 156         enc2_update_hdmi_info_packet(enc1, 2, &info_frame->gamut);
 157         enc2_update_hdmi_info_packet(enc1, 1, &info_frame->vendor);
 158         enc2_update_hdmi_info_packet(enc1, 3, &info_frame->spd);
 159         enc2_update_hdmi_info_packet(enc1, 4, &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 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
 209 
 210 /* Update GSP7 SDP 128 byte long */
 211 static void enc2_update_gsp7_128_info_packet(
 212         struct dcn10_stream_encoder *enc1,
 213         const struct dc_info_packet_128 *info_packet)
 214 {
 215         uint32_t i;
 216 
 217         /* TODOFPGA Figure out a proper number for max_retries polling for lock
 218          * use 50 for now.
 219          */
 220         uint32_t max_retries = 50;
 221         const uint32_t *content = (const uint32_t *) &info_packet->sb[0];
 222 
 223         ASSERT(info_packet->hb1  == DC_DP_INFOFRAME_TYPE_PPS);
 224 
 225         /* Configure for PPS packet size (128 bytes) */
 226         REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP7_PPS, 1);
 227 
 228         /* We need turn on clock before programming AFMT block*/
 229         REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1);
 230 
 231         /* Poll dig_update_lock is not locked -> asic internal signal
 232          * assumes otg master lock will unlock it
 233          */
 234         /*REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS, 0, 10, max_retries);*/
 235 
 236         /* Wait for HW/SW GSP memory access conflict to go away */
 237         REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT,
 238                         0, 10, max_retries);
 239 
 240         /* Clear HW/SW memory access conflict flag */
 241         REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT_CLR, 1);
 242 
 243         /* write generic packet header */
 244         REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_INDEX, 7);
 245         REG_SET_4(AFMT_GENERIC_HDR, 0,
 246                         AFMT_GENERIC_HB0, info_packet->hb0,
 247                         AFMT_GENERIC_HB1, info_packet->hb1,
 248                         AFMT_GENERIC_HB2, info_packet->hb2,
 249                         AFMT_GENERIC_HB3, info_packet->hb3);
 250 
 251         /* Write generic packet content 128 bytes long. Four sets are used (indexes 7
 252          * through 10) to fit 128 bytes.
 253          */
 254         for (i = 0; i < 4; i++) {
 255                 uint32_t packet_index = 7 + i;
 256                 REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_INDEX, packet_index);
 257 
 258                 REG_WRITE(AFMT_GENERIC_0, *content++);
 259                 REG_WRITE(AFMT_GENERIC_1, *content++);
 260                 REG_WRITE(AFMT_GENERIC_2, *content++);
 261                 REG_WRITE(AFMT_GENERIC_3, *content++);
 262                 REG_WRITE(AFMT_GENERIC_4, *content++);
 263                 REG_WRITE(AFMT_GENERIC_5, *content++);
 264                 REG_WRITE(AFMT_GENERIC_6, *content++);
 265                 REG_WRITE(AFMT_GENERIC_7, *content++);
 266         }
 267 
 268         REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_FRAME_UPDATE, 1);
 269 }
 270 
 271 /* Set DSC-related configuration.
 272  *   dsc_mode: 0 disables DSC, other values enable DSC in specified format
 273  *   sc_bytes_per_pixel: Bytes per pixel in u3.28 format
 274  *   dsc_slice_width: Slice width in pixels
 275  */
 276 static void enc2_dp_set_dsc_config(struct stream_encoder *enc,
 277                                         enum optc_dsc_mode dsc_mode,
 278                                         uint32_t dsc_bytes_per_pixel,
 279                                         uint32_t dsc_slice_width)
 280 {
 281         struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 282 
 283         REG_UPDATE_2(DP_DSC_CNTL,
 284                         DP_DSC_MODE, dsc_mode,
 285                         DP_DSC_SLICE_WIDTH, dsc_slice_width);
 286 
 287         REG_SET(DP_DSC_BYTES_PER_PIXEL, 0,
 288                 DP_DSC_BYTES_PER_PIXEL, dsc_bytes_per_pixel);
 289 }
 290 
 291 
 292 static void enc2_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
 293                                         bool enable,
 294                                         uint8_t *dsc_packed_pps)
 295 {
 296         struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 297 
 298         if (enable) {
 299                 struct dc_info_packet_128 pps_sdp;
 300 
 301                 ASSERT(dsc_packed_pps);
 302 
 303                 /* Load PPS into infoframe (SDP) registers */
 304                 pps_sdp.valid = true;
 305                 pps_sdp.hb0 = 0;
 306                 pps_sdp.hb1 = DC_DP_INFOFRAME_TYPE_PPS;
 307                 pps_sdp.hb2 = 127;
 308                 pps_sdp.hb3 = 0;
 309                 memcpy(&pps_sdp.sb[0], dsc_packed_pps, sizeof(pps_sdp.sb));
 310                 enc2_update_gsp7_128_info_packet(enc1, &pps_sdp);
 311 
 312                 /* Enable Generic Stream Packet 7 (GSP) transmission */
 313                 //REG_UPDATE(DP_SEC_CNTL,
 314                 //      DP_SEC_GSP7_ENABLE, 1);
 315 
 316                 /* SW should make sure VBID[6] update line number is bigger
 317                  * than PPS transmit line number
 318                  */
 319                 REG_UPDATE(DP_SEC_CNTL6,
 320                                 DP_SEC_GSP7_LINE_NUM, 2);
 321                 REG_UPDATE_2(DP_MSA_VBID_MISC,
 322                                 DP_VBID6_LINE_REFERENCE, 0,
 323                                 DP_VBID6_LINE_NUM, 3);
 324 
 325                 /* Send PPS data at the line number specified above.
 326                  * DP spec requires PPS to be sent only when it changes, however since
 327                  * decoder has to be able to handle its change on every frame, we're
 328                  * sending it always (i.e. on every frame) to reduce the chance it'd be
 329                  * missed by decoder. If it turns out required to send PPS only when it
 330                  * changes, we can use DP_SEC_GSP7_SEND register.
 331                  */
 332                 REG_UPDATE_2(DP_SEC_CNTL,
 333                         DP_SEC_GSP7_ENABLE, 1,
 334                         DP_SEC_STREAM_ENABLE, 1);
 335         } else {
 336                 /* Disable Generic Stream Packet 7 (GSP) transmission */
 337                 REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP7_ENABLE, 0);
 338                 REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP7_PPS, 0);
 339         }
 340 }
 341 
 342 
 343 /* this function read dsc related register fields to be logged later in dcn10_log_hw_state
 344  * into a dcn_dsc_state struct.
 345  */
 346 static void enc2_read_state(struct stream_encoder *enc, struct enc_state *s)
 347 {
 348         struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 349 
 350         //if dsc is enabled, continue to read
 351         REG_GET(DP_DSC_CNTL, DP_DSC_MODE, &s->dsc_mode);
 352         if (s->dsc_mode) {
 353                 REG_GET(DP_DSC_CNTL, DP_DSC_SLICE_WIDTH, &s->dsc_slice_width);
 354                 REG_GET(DP_SEC_CNTL6, DP_SEC_GSP7_LINE_NUM, &s->sec_gsp_pps_line_num);
 355 
 356                 REG_GET(DP_MSA_VBID_MISC, DP_VBID6_LINE_REFERENCE, &s->vbid6_line_reference);
 357                 REG_GET(DP_MSA_VBID_MISC, DP_VBID6_LINE_NUM, &s->vbid6_line_num);
 358 
 359                 REG_GET(DP_SEC_CNTL, DP_SEC_GSP7_ENABLE, &s->sec_gsp_pps_enable);
 360                 REG_GET(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, &s->sec_stream_enable);
 361         }
 362 }
 363 #endif
 364 
 365 /* Set Dynamic Metadata-configuration.
 366  *   enable_dme:         TRUE: enables Dynamic Metadata Enfine, FALSE: disables DME
 367  *   hubp_requestor_id:  HUBP physical instance that is the source of dynamic metadata
 368  *                       only needs to be set when enable_dme is TRUE
 369  *   dmdata_mode:        dynamic metadata packet type: DP, HDMI, or Dolby Vision
 370  *
 371  *   Ensure the OTG master update lock is set when changing DME configuration.
 372  */
 373 void enc2_set_dynamic_metadata(struct stream_encoder *enc,
 374                 bool enable_dme,
 375                 uint32_t hubp_requestor_id,
 376                 enum dynamic_metadata_mode dmdata_mode)
 377 {
 378         struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 379 
 380         if (enable_dme) {
 381                 REG_UPDATE_2(DME_CONTROL,
 382                                 METADATA_HUBP_REQUESTOR_ID, hubp_requestor_id,
 383                                 METADATA_STREAM_TYPE, (dmdata_mode == dmdata_dolby_vision) ? 1 : 0);
 384 
 385                 /* Use default line reference DP_SOF for bringup.
 386                  * Should use OTG_SOF for DRR cases
 387                  */
 388                 if (dmdata_mode == dmdata_dp)
 389                         REG_UPDATE_3(DP_SEC_METADATA_TRANSMISSION,
 390                                         DP_SEC_METADATA_PACKET_ENABLE, 1,
 391                                         DP_SEC_METADATA_PACKET_LINE_REFERENCE, 0,
 392                                         DP_SEC_METADATA_PACKET_LINE, 20);
 393                 else {
 394                         REG_UPDATE_3(HDMI_METADATA_PACKET_CONTROL,
 395                                         HDMI_METADATA_PACKET_ENABLE, 1,
 396                                         HDMI_METADATA_PACKET_LINE_REFERENCE, 0,
 397                                         HDMI_METADATA_PACKET_LINE, 2);
 398 
 399                         if (dmdata_mode == dmdata_dolby_vision)
 400                                 REG_UPDATE(DIG_FE_CNTL,
 401                                                 DOLBY_VISION_EN, 1);
 402                 }
 403 
 404                 REG_UPDATE(DME_CONTROL,
 405                                 METADATA_ENGINE_EN, 1);
 406         } else {
 407                 REG_UPDATE(DME_CONTROL,
 408                                 METADATA_ENGINE_EN, 0);
 409 
 410                 if (dmdata_mode == dmdata_dp)
 411                         REG_UPDATE(DP_SEC_METADATA_TRANSMISSION,
 412                                         DP_SEC_METADATA_PACKET_ENABLE, 0);
 413                 else {
 414                         REG_UPDATE(HDMI_METADATA_PACKET_CONTROL,
 415                                         HDMI_METADATA_PACKET_ENABLE, 0);
 416                         REG_UPDATE(DIG_FE_CNTL,
 417                                         DOLBY_VISION_EN, 0);
 418                 }
 419         }
 420 }
 421 
 422 static void enc2_stream_encoder_update_dp_info_packets(
 423         struct stream_encoder *enc,
 424         const struct encoder_info_frame *info_frame)
 425 {
 426         struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 427         uint32_t dmdata_packet_enabled = 0;
 428 
 429         enc1_stream_encoder_update_dp_info_packets(enc, info_frame);
 430 
 431         /* check if dynamic metadata packet transmission is enabled */
 432         REG_GET(DP_SEC_METADATA_TRANSMISSION,
 433                         DP_SEC_METADATA_PACKET_ENABLE, &dmdata_packet_enabled);
 434 
 435         if (dmdata_packet_enabled)
 436                 REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
 437 }
 438 
 439 static bool is_two_pixels_per_containter(const struct dc_crtc_timing *timing)
 440 {
 441         bool two_pix = timing->pixel_encoding == PIXEL_ENCODING_YCBCR420;
 442 
 443 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
 444         two_pix = two_pix || (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
 445                         && !timing->dsc_cfg.ycbcr422_simple);
 446 #endif
 447         return two_pix;
 448 }
 449 
 450 void enc2_stream_encoder_dp_unblank(
 451                 struct stream_encoder *enc,
 452                 const struct encoder_unblank_param *param)
 453 {
 454         struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 455 
 456         if (param->link_settings.link_rate != LINK_RATE_UNKNOWN) {
 457                 uint32_t n_vid = 0x8000;
 458                 uint32_t m_vid;
 459                 uint32_t n_multiply = 0;
 460                 uint64_t m_vid_l = n_vid;
 461 
 462                 /* YCbCr 4:2:0 : Computed VID_M will be 2X the input rate */
 463                 if (is_two_pixels_per_containter(&param->timing) || param->opp_cnt > 1) {
 464                         /*this logic should be the same in get_pixel_clock_parameters() */
 465                         n_multiply = 1;
 466                 }
 467                 /* M / N = Fstream / Flink
 468                  * m_vid / n_vid = pixel rate / link rate
 469                  */
 470 
 471                 m_vid_l *= param->timing.pix_clk_100hz / 10;
 472                 m_vid_l = div_u64(m_vid_l,
 473                         param->link_settings.link_rate
 474                                 * LINK_RATE_REF_FREQ_IN_KHZ);
 475 
 476                 m_vid = (uint32_t) m_vid_l;
 477 
 478                 /* enable auto measurement */
 479 
 480                 REG_UPDATE(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 0);
 481 
 482                 /* auto measurement need 1 full 0x8000 symbol cycle to kick in,
 483                  * therefore program initial value for Mvid and Nvid
 484                  */
 485 
 486                 REG_UPDATE(DP_VID_N, DP_VID_N, n_vid);
 487 
 488                 REG_UPDATE(DP_VID_M, DP_VID_M, m_vid);
 489 
 490                 REG_UPDATE_2(DP_VID_TIMING,
 491                                 DP_VID_M_N_GEN_EN, 1,
 492                                 DP_VID_N_MUL, n_multiply);
 493         }
 494 
 495         /* make sure stream is disabled before resetting steer fifo */
 496         REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, false);
 497         REG_WAIT(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, 0, 10, 5000);
 498 
 499         /* set DIG_START to 0x1 to reset FIFO */
 500         REG_UPDATE(DIG_FE_CNTL, DIG_START, 1);
 501         udelay(1);
 502 
 503         /* write 0 to take the FIFO out of reset */
 504 
 505         REG_UPDATE(DIG_FE_CNTL, DIG_START, 0);
 506 
 507         /* switch DP encoder to CRTC data, but reset it the fifo first. It may happen
 508          * that it overflows during mode transition, and sometimes doesn't recover.
 509          */
 510         REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 1);
 511         udelay(10);
 512 
 513         REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0);
 514 
 515         /* wait 100us for DIG/DP logic to prime
 516          * (i.e. a few video lines)
 517          */
 518         udelay(100);
 519 
 520         /* the hardware would start sending video at the start of the next DP
 521          * frame (i.e. rising edge of the vblank).
 522          * NOTE: We used to program DP_VID_STREAM_DIS_DEFER = 2 here, but this
 523          * register has no effect on enable transition! HW always guarantees
 524          * VID_STREAM enable at start of next frame, and this is not
 525          * programmable
 526          */
 527 
 528         REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);
 529 }
 530 
 531 static void enc2_dp_set_odm_combine(
 532         struct stream_encoder *enc,
 533         bool odm_combine)
 534 {
 535         struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 536 
 537         REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_COMBINE, odm_combine);
 538 }
 539 
 540 void enc2_stream_encoder_dp_set_stream_attribute(
 541         struct stream_encoder *enc,
 542         struct dc_crtc_timing *crtc_timing,
 543         enum dc_color_space output_color_space,
 544         uint32_t enable_sdp_splitting)
 545 {
 546         struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 547 
 548         enc1_stream_encoder_dp_set_stream_attribute(enc, crtc_timing, output_color_space, enable_sdp_splitting);
 549 
 550         REG_UPDATE(DP_SEC_FRAMING4,
 551                 DP_SST_SDP_SPLITTING, enable_sdp_splitting);
 552 }
 553 
 554 static const struct stream_encoder_funcs dcn20_str_enc_funcs = {
 555         .dp_set_odm_combine =
 556                 enc2_dp_set_odm_combine,
 557         .dp_set_stream_attribute =
 558                 enc2_stream_encoder_dp_set_stream_attribute,
 559         .hdmi_set_stream_attribute =
 560                 enc1_stream_encoder_hdmi_set_stream_attribute,
 561         .dvi_set_stream_attribute =
 562                 enc1_stream_encoder_dvi_set_stream_attribute,
 563         .set_mst_bandwidth =
 564                 enc1_stream_encoder_set_mst_bandwidth,
 565         .update_hdmi_info_packets =
 566                 enc2_stream_encoder_update_hdmi_info_packets,
 567         .stop_hdmi_info_packets =
 568                 enc2_stream_encoder_stop_hdmi_info_packets,
 569         .update_dp_info_packets =
 570                 enc2_stream_encoder_update_dp_info_packets,
 571         .stop_dp_info_packets =
 572                 enc1_stream_encoder_stop_dp_info_packets,
 573         .dp_blank =
 574                 enc1_stream_encoder_dp_blank,
 575         .dp_unblank =
 576                 enc2_stream_encoder_dp_unblank,
 577         .audio_mute_control = enc1_se_audio_mute_control,
 578 
 579         .dp_audio_setup = enc1_se_dp_audio_setup,
 580         .dp_audio_enable = enc1_se_dp_audio_enable,
 581         .dp_audio_disable = enc1_se_dp_audio_disable,
 582 
 583         .hdmi_audio_setup = enc1_se_hdmi_audio_setup,
 584         .hdmi_audio_disable = enc1_se_hdmi_audio_disable,
 585         .setup_stereo_sync  = enc1_setup_stereo_sync,
 586         .set_avmute = enc1_stream_encoder_set_avmute,
 587         .dig_connect_to_otg  = enc1_dig_connect_to_otg,
 588         .dig_source_otg = enc1_dig_source_otg,
 589 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
 590         .enc_read_state = enc2_read_state,
 591         .dp_set_dsc_config = enc2_dp_set_dsc_config,
 592         .dp_set_dsc_pps_info_packet = enc2_dp_set_dsc_pps_info_packet,
 593 #endif
 594         .set_dynamic_metadata = enc2_set_dynamic_metadata,
 595         .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
 596 };
 597 
 598 void dcn20_stream_encoder_construct(
 599         struct dcn10_stream_encoder *enc1,
 600         struct dc_context *ctx,
 601         struct dc_bios *bp,
 602         enum engine_id eng_id,
 603         const struct dcn10_stream_enc_registers *regs,
 604         const struct dcn10_stream_encoder_shift *se_shift,
 605         const struct dcn10_stream_encoder_mask *se_mask)
 606 {
 607         enc1->base.funcs = &dcn20_str_enc_funcs;
 608         enc1->base.ctx = ctx;
 609         enc1->base.id = eng_id;
 610         enc1->base.bp = bp;
 611         enc1->regs = regs;
 612         enc1->se_shift = se_shift;
 613         enc1->se_mask = se_mask;
 614 }
 615 

/* [<][>][^][v][top][bottom][index][help] */