Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2012-15 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  *  and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 #include <linux/delay.h>
0027 
0028 #include "dc_bios_types.h"
0029 #include "dcn20_stream_encoder.h"
0030 #include "reg_helper.h"
0031 #include "hw_shared.h"
0032 #include "inc/link_dpcd.h"
0033 #include "dpcd_defs.h"
0034 
0035 #define DC_LOGGER \
0036         enc1->base.ctx->logger
0037 
0038 #define REG(reg)\
0039     (enc1->regs->reg)
0040 
0041 #undef FN
0042 #define FN(reg_name, field_name) \
0043     enc1->se_shift->field_name, enc1->se_mask->field_name
0044 
0045 
0046 #define CTX \
0047     enc1->base.ctx
0048 
0049 
0050 static void enc2_update_hdmi_info_packet(
0051     struct dcn10_stream_encoder *enc1,
0052     uint32_t packet_index,
0053     const struct dc_info_packet *info_packet)
0054 {
0055     uint32_t cont, send, line;
0056 
0057     if (info_packet->valid) {
0058         enc1_update_generic_info_packet(
0059             enc1,
0060             packet_index,
0061             info_packet);
0062 
0063         /* enable transmission of packet(s) -
0064          * packet transmission begins on the next frame */
0065         cont = 1;
0066         /* send packet(s) every frame */
0067         send = 1;
0068         /* select line number to send packets on */
0069         line = 2;
0070     } else {
0071         cont = 0;
0072         send = 0;
0073         line = 0;
0074     }
0075 
0076     /* DP_SEC_GSP[x]_LINE_REFERENCE - keep default value REFER_TO_DP_SOF */
0077 
0078     /* choose which generic packet control to use */
0079     switch (packet_index) {
0080     case 0:
0081         REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
0082                 HDMI_GENERIC0_CONT, cont,
0083                 HDMI_GENERIC0_SEND, send);
0084         REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL1,
0085                 HDMI_GENERIC0_LINE, line);
0086         break;
0087     case 1:
0088         REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
0089                 HDMI_GENERIC1_CONT, cont,
0090                 HDMI_GENERIC1_SEND, send);
0091         REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL1,
0092                 HDMI_GENERIC1_LINE, line);
0093         break;
0094     case 2:
0095         REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
0096                 HDMI_GENERIC2_CONT, cont,
0097                 HDMI_GENERIC2_SEND, send);
0098         REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL2,
0099                 HDMI_GENERIC2_LINE, line);
0100         break;
0101     case 3:
0102         REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
0103                 HDMI_GENERIC3_CONT, cont,
0104                 HDMI_GENERIC3_SEND, send);
0105         REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL2,
0106                 HDMI_GENERIC3_LINE, line);
0107         break;
0108     case 4:
0109         REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
0110                 HDMI_GENERIC4_CONT, cont,
0111                 HDMI_GENERIC4_SEND, send);
0112         REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL3,
0113                 HDMI_GENERIC4_LINE, line);
0114         break;
0115     case 5:
0116         REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
0117                 HDMI_GENERIC5_CONT, cont,
0118                 HDMI_GENERIC5_SEND, send);
0119         REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL3,
0120                 HDMI_GENERIC5_LINE, line);
0121         break;
0122     case 6:
0123         REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
0124                 HDMI_GENERIC6_CONT, cont,
0125                 HDMI_GENERIC6_SEND, send);
0126         REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL4,
0127                 HDMI_GENERIC6_LINE, line);
0128         break;
0129     case 7:
0130         REG_UPDATE_2(HDMI_GENERIC_PACKET_CONTROL0,
0131                 HDMI_GENERIC7_CONT, cont,
0132                 HDMI_GENERIC7_SEND, send);
0133         REG_UPDATE(HDMI_GENERIC_PACKET_CONTROL4,
0134                 HDMI_GENERIC7_LINE, line);
0135         break;
0136     default:
0137         /* invalid HW packet index */
0138         DC_LOG_WARNING(
0139             "Invalid HW packet index: %s()\n",
0140             __func__);
0141         return;
0142     }
0143 }
0144 
0145 static void enc2_stream_encoder_update_hdmi_info_packets(
0146     struct stream_encoder *enc,
0147     const struct encoder_info_frame *info_frame)
0148 {
0149     struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0150 
0151     /* for bring up, disable dp double  TODO */
0152     REG_UPDATE(HDMI_DB_CONTROL, HDMI_DB_DISABLE, 1);
0153 
0154     /*Always add mandatory packets first followed by optional ones*/
0155     enc2_update_hdmi_info_packet(enc1, 0, &info_frame->avi);
0156     enc2_update_hdmi_info_packet(enc1, 1, &info_frame->hfvsif);
0157     enc2_update_hdmi_info_packet(enc1, 2, &info_frame->gamut);
0158     enc2_update_hdmi_info_packet(enc1, 3, &info_frame->vendor);
0159     enc2_update_hdmi_info_packet(enc1, 4, &info_frame->spd);
0160     enc2_update_hdmi_info_packet(enc1, 5, &info_frame->hdrsmd);
0161     enc2_update_hdmi_info_packet(enc1, 6, &info_frame->vtem);
0162 }
0163 
0164 static void enc2_stream_encoder_stop_hdmi_info_packets(
0165     struct stream_encoder *enc)
0166 {
0167     struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0168 
0169     /* stop generic packets 0,1 on HDMI */
0170     REG_SET_4(HDMI_GENERIC_PACKET_CONTROL0, 0,
0171         HDMI_GENERIC0_CONT, 0,
0172         HDMI_GENERIC0_SEND, 0,
0173         HDMI_GENERIC1_CONT, 0,
0174         HDMI_GENERIC1_SEND, 0);
0175     REG_SET_2(HDMI_GENERIC_PACKET_CONTROL1, 0,
0176         HDMI_GENERIC0_LINE, 0,
0177         HDMI_GENERIC1_LINE, 0);
0178 
0179     /* stop generic packets 2,3 on HDMI */
0180     REG_SET_4(HDMI_GENERIC_PACKET_CONTROL0, 0,
0181         HDMI_GENERIC2_CONT, 0,
0182         HDMI_GENERIC2_SEND, 0,
0183         HDMI_GENERIC3_CONT, 0,
0184         HDMI_GENERIC3_SEND, 0);
0185     REG_SET_2(HDMI_GENERIC_PACKET_CONTROL2, 0,
0186         HDMI_GENERIC2_LINE, 0,
0187         HDMI_GENERIC3_LINE, 0);
0188 
0189     /* stop generic packets 4,5 on HDMI */
0190     REG_SET_4(HDMI_GENERIC_PACKET_CONTROL0, 0,
0191         HDMI_GENERIC4_CONT, 0,
0192         HDMI_GENERIC4_SEND, 0,
0193         HDMI_GENERIC5_CONT, 0,
0194         HDMI_GENERIC5_SEND, 0);
0195     REG_SET_2(HDMI_GENERIC_PACKET_CONTROL3, 0,
0196         HDMI_GENERIC4_LINE, 0,
0197         HDMI_GENERIC5_LINE, 0);
0198 
0199     /* stop generic packets 6,7 on HDMI */
0200     REG_SET_4(HDMI_GENERIC_PACKET_CONTROL0, 0,
0201         HDMI_GENERIC6_CONT, 0,
0202         HDMI_GENERIC6_SEND, 0,
0203         HDMI_GENERIC7_CONT, 0,
0204         HDMI_GENERIC7_SEND, 0);
0205     REG_SET_2(HDMI_GENERIC_PACKET_CONTROL4, 0,
0206         HDMI_GENERIC6_LINE, 0,
0207         HDMI_GENERIC7_LINE, 0);
0208 }
0209 
0210 
0211 /* Update GSP7 SDP 128 byte long */
0212 static void enc2_update_gsp7_128_info_packet(
0213     struct dcn10_stream_encoder *enc1,
0214     const struct dc_info_packet_128 *info_packet,
0215     bool immediate_update)
0216 {
0217     uint32_t i;
0218 
0219     /* TODOFPGA Figure out a proper number for max_retries polling for lock
0220      * use 50 for now.
0221      */
0222     uint32_t max_retries = 50;
0223     const uint32_t *content = (const uint32_t *) &info_packet->sb[0];
0224 
0225     ASSERT(info_packet->hb1  == DC_DP_INFOFRAME_TYPE_PPS);
0226 
0227     /* Configure for PPS packet size (128 bytes) */
0228     REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP7_PPS, 1);
0229 
0230     /* We need turn on clock before programming AFMT block*/
0231     REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1);
0232 
0233     /* Poll dig_update_lock is not locked -> asic internal signal
0234      * assumes otg master lock will unlock it
0235      */
0236     /*REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS, 0, 10, max_retries);*/
0237 
0238     /* Wait for HW/SW GSP memory access conflict to go away */
0239     REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT,
0240             0, 10, max_retries);
0241 
0242     /* Clear HW/SW memory access conflict flag */
0243     REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT_CLR, 1);
0244 
0245     /* write generic packet header */
0246     REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_INDEX, 7);
0247     REG_SET_4(AFMT_GENERIC_HDR, 0,
0248             AFMT_GENERIC_HB0, info_packet->hb0,
0249             AFMT_GENERIC_HB1, info_packet->hb1,
0250             AFMT_GENERIC_HB2, info_packet->hb2,
0251             AFMT_GENERIC_HB3, info_packet->hb3);
0252 
0253     /* Write generic packet content 128 bytes long. Four sets are used (indexes 7
0254      * through 10) to fit 128 bytes.
0255      */
0256     for (i = 0; i < 4; i++) {
0257         uint32_t packet_index = 7 + i;
0258         REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_INDEX, packet_index);
0259 
0260         REG_WRITE(AFMT_GENERIC_0, *content++);
0261         REG_WRITE(AFMT_GENERIC_1, *content++);
0262         REG_WRITE(AFMT_GENERIC_2, *content++);
0263         REG_WRITE(AFMT_GENERIC_3, *content++);
0264         REG_WRITE(AFMT_GENERIC_4, *content++);
0265         REG_WRITE(AFMT_GENERIC_5, *content++);
0266         REG_WRITE(AFMT_GENERIC_6, *content++);
0267         REG_WRITE(AFMT_GENERIC_7, *content++);
0268     }
0269 
0270     REG_UPDATE_2(AFMT_VBI_PACKET_CONTROL1,
0271             AFMT_GENERIC7_FRAME_UPDATE, !immediate_update,
0272             AFMT_GENERIC7_IMMEDIATE_UPDATE, immediate_update);
0273 }
0274 
0275 /* Set DSC-related configuration.
0276  *   dsc_mode: 0 disables DSC, other values enable DSC in specified format
0277  *   sc_bytes_per_pixel: Bytes per pixel in u3.28 format
0278  *   dsc_slice_width: Slice width in pixels
0279  */
0280 static void enc2_dp_set_dsc_config(struct stream_encoder *enc,
0281                     enum optc_dsc_mode dsc_mode,
0282                     uint32_t dsc_bytes_per_pixel,
0283                     uint32_t dsc_slice_width)
0284 {
0285     struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0286 
0287     REG_UPDATE_2(DP_DSC_CNTL,
0288             DP_DSC_MODE, dsc_mode,
0289             DP_DSC_SLICE_WIDTH, dsc_slice_width);
0290 
0291     REG_SET(DP_DSC_BYTES_PER_PIXEL, 0,
0292         DP_DSC_BYTES_PER_PIXEL, dsc_bytes_per_pixel);
0293 }
0294 
0295 
0296 static void enc2_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
0297                     bool enable,
0298                     uint8_t *dsc_packed_pps,
0299                     bool immediate_update)
0300 {
0301     struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0302 
0303     if (enable) {
0304         struct dc_info_packet_128 pps_sdp;
0305 
0306         ASSERT(dsc_packed_pps);
0307 
0308         /* Load PPS into infoframe (SDP) registers */
0309         pps_sdp.valid = true;
0310         pps_sdp.hb0 = 0;
0311         pps_sdp.hb1 = DC_DP_INFOFRAME_TYPE_PPS;
0312         pps_sdp.hb2 = 127;
0313         pps_sdp.hb3 = 0;
0314         memcpy(&pps_sdp.sb[0], dsc_packed_pps, sizeof(pps_sdp.sb));
0315         enc2_update_gsp7_128_info_packet(enc1, &pps_sdp, immediate_update);
0316 
0317         /* Enable Generic Stream Packet 7 (GSP) transmission */
0318         //REG_UPDATE(DP_SEC_CNTL,
0319         //  DP_SEC_GSP7_ENABLE, 1);
0320 
0321         /* SW should make sure VBID[6] update line number is bigger
0322          * than PPS transmit line number
0323          */
0324         REG_UPDATE(DP_SEC_CNTL6,
0325                 DP_SEC_GSP7_LINE_NUM, 2);
0326         REG_UPDATE_2(DP_MSA_VBID_MISC,
0327                 DP_VBID6_LINE_REFERENCE, 0,
0328                 DP_VBID6_LINE_NUM, 3);
0329 
0330         /* Send PPS data at the line number specified above.
0331          * DP spec requires PPS to be sent only when it changes, however since
0332          * decoder has to be able to handle its change on every frame, we're
0333          * sending it always (i.e. on every frame) to reduce the chance it'd be
0334          * missed by decoder. If it turns out required to send PPS only when it
0335          * changes, we can use DP_SEC_GSP7_SEND register.
0336          */
0337         REG_UPDATE_2(DP_SEC_CNTL,
0338             DP_SEC_GSP7_ENABLE, 1,
0339             DP_SEC_STREAM_ENABLE, 1);
0340     } else {
0341         /* Disable Generic Stream Packet 7 (GSP) transmission */
0342         REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP7_ENABLE, 0);
0343         REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP7_PPS, 0);
0344     }
0345 }
0346 
0347 
0348 /* this function read dsc related register fields to be logged later in dcn10_log_hw_state
0349  * into a dcn_dsc_state struct.
0350  */
0351 static void enc2_read_state(struct stream_encoder *enc, struct enc_state *s)
0352 {
0353     struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0354 
0355     //if dsc is enabled, continue to read
0356     REG_GET(DP_DSC_CNTL, DP_DSC_MODE, &s->dsc_mode);
0357     if (s->dsc_mode) {
0358         REG_GET(DP_DSC_CNTL, DP_DSC_SLICE_WIDTH, &s->dsc_slice_width);
0359         REG_GET(DP_SEC_CNTL6, DP_SEC_GSP7_LINE_NUM, &s->sec_gsp_pps_line_num);
0360 
0361         REG_GET(DP_MSA_VBID_MISC, DP_VBID6_LINE_REFERENCE, &s->vbid6_line_reference);
0362         REG_GET(DP_MSA_VBID_MISC, DP_VBID6_LINE_NUM, &s->vbid6_line_num);
0363 
0364         REG_GET(DP_SEC_CNTL, DP_SEC_GSP7_ENABLE, &s->sec_gsp_pps_enable);
0365         REG_GET(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, &s->sec_stream_enable);
0366     }
0367 }
0368 
0369 /* Set Dynamic Metadata-configuration.
0370  *   enable_dme:         TRUE: enables Dynamic Metadata Enfine, FALSE: disables DME
0371  *   hubp_requestor_id:  HUBP physical instance that is the source of dynamic metadata
0372  *                       only needs to be set when enable_dme is TRUE
0373  *   dmdata_mode:        dynamic metadata packet type: DP, HDMI, or Dolby Vision
0374  *
0375  *   Ensure the OTG master update lock is set when changing DME configuration.
0376  */
0377 void enc2_set_dynamic_metadata(struct stream_encoder *enc,
0378         bool enable_dme,
0379         uint32_t hubp_requestor_id,
0380         enum dynamic_metadata_mode dmdata_mode)
0381 {
0382     struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0383 
0384     if (enable_dme) {
0385         REG_UPDATE_2(DME_CONTROL,
0386                 METADATA_HUBP_REQUESTOR_ID, hubp_requestor_id,
0387                 METADATA_STREAM_TYPE, (dmdata_mode == dmdata_dolby_vision) ? 1 : 0);
0388 
0389         /* Use default line reference DP_SOF for bringup.
0390          * Should use OTG_SOF for DRR cases
0391          */
0392         if (dmdata_mode == dmdata_dp)
0393             REG_UPDATE_3(DP_SEC_METADATA_TRANSMISSION,
0394                     DP_SEC_METADATA_PACKET_ENABLE, 1,
0395                     DP_SEC_METADATA_PACKET_LINE_REFERENCE, 0,
0396                     DP_SEC_METADATA_PACKET_LINE, 20);
0397         else {
0398             REG_UPDATE_3(HDMI_METADATA_PACKET_CONTROL,
0399                     HDMI_METADATA_PACKET_ENABLE, 1,
0400                     HDMI_METADATA_PACKET_LINE_REFERENCE, 0,
0401                     HDMI_METADATA_PACKET_LINE, 2);
0402 
0403             if (dmdata_mode == dmdata_dolby_vision)
0404                 REG_UPDATE(DIG_FE_CNTL,
0405                         DOLBY_VISION_EN, 1);
0406         }
0407 
0408         REG_UPDATE(DME_CONTROL,
0409                 METADATA_ENGINE_EN, 1);
0410     } else {
0411         REG_UPDATE(DME_CONTROL,
0412                 METADATA_ENGINE_EN, 0);
0413 
0414         if (dmdata_mode == dmdata_dp)
0415             REG_UPDATE(DP_SEC_METADATA_TRANSMISSION,
0416                     DP_SEC_METADATA_PACKET_ENABLE, 0);
0417         else {
0418             REG_UPDATE(HDMI_METADATA_PACKET_CONTROL,
0419                     HDMI_METADATA_PACKET_ENABLE, 0);
0420             REG_UPDATE(DIG_FE_CNTL,
0421                     DOLBY_VISION_EN, 0);
0422         }
0423     }
0424 }
0425 
0426 static void enc2_stream_encoder_update_dp_info_packets(
0427     struct stream_encoder *enc,
0428     const struct encoder_info_frame *info_frame)
0429 {
0430     struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0431     uint32_t dmdata_packet_enabled = 0;
0432 
0433     enc1_stream_encoder_update_dp_info_packets(enc, info_frame);
0434 
0435     /* check if dynamic metadata packet transmission is enabled */
0436     REG_GET(DP_SEC_METADATA_TRANSMISSION,
0437             DP_SEC_METADATA_PACKET_ENABLE, &dmdata_packet_enabled);
0438 
0439     if (dmdata_packet_enabled)
0440         REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
0441 }
0442 
0443 static bool is_two_pixels_per_containter(const struct dc_crtc_timing *timing)
0444 {
0445     bool two_pix = timing->pixel_encoding == PIXEL_ENCODING_YCBCR420;
0446 
0447     two_pix = two_pix || (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
0448             && !timing->dsc_cfg.ycbcr422_simple);
0449     return two_pix;
0450 }
0451 
0452 void enc2_stream_encoder_dp_unblank(
0453         struct dc_link *link,
0454         struct stream_encoder *enc,
0455         const struct encoder_unblank_param *param)
0456 {
0457     struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0458 
0459     if (param->link_settings.link_rate != LINK_RATE_UNKNOWN) {
0460         uint32_t n_vid = 0x8000;
0461         uint32_t m_vid;
0462         uint32_t n_multiply = 0;
0463         uint64_t m_vid_l = n_vid;
0464 
0465         /* YCbCr 4:2:0 : Computed VID_M will be 2X the input rate */
0466         if (is_two_pixels_per_containter(&param->timing) || param->opp_cnt > 1) {
0467             /*this logic should be the same in get_pixel_clock_parameters() */
0468             n_multiply = 1;
0469         }
0470         /* M / N = Fstream / Flink
0471          * m_vid / n_vid = pixel rate / link rate
0472          */
0473 
0474         m_vid_l *= param->timing.pix_clk_100hz / 10;
0475         m_vid_l = div_u64(m_vid_l,
0476             param->link_settings.link_rate
0477                 * LINK_RATE_REF_FREQ_IN_KHZ);
0478 
0479         m_vid = (uint32_t) m_vid_l;
0480 
0481         /* enable auto measurement */
0482 
0483         REG_UPDATE(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 0);
0484 
0485         /* auto measurement need 1 full 0x8000 symbol cycle to kick in,
0486          * therefore program initial value for Mvid and Nvid
0487          */
0488 
0489         REG_UPDATE(DP_VID_N, DP_VID_N, n_vid);
0490 
0491         REG_UPDATE(DP_VID_M, DP_VID_M, m_vid);
0492 
0493         REG_UPDATE_2(DP_VID_TIMING,
0494                 DP_VID_M_N_GEN_EN, 1,
0495                 DP_VID_N_MUL, n_multiply);
0496     }
0497 
0498     /* make sure stream is disabled before resetting steer fifo */
0499     REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, false);
0500     REG_WAIT(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, 0, 10, 5000);
0501 
0502     /* set DIG_START to 0x1 to reset FIFO */
0503     REG_UPDATE(DIG_FE_CNTL, DIG_START, 1);
0504     udelay(1);
0505 
0506     /* write 0 to take the FIFO out of reset */
0507 
0508     REG_UPDATE(DIG_FE_CNTL, DIG_START, 0);
0509 
0510     /* switch DP encoder to CRTC data, but reset it the fifo first. It may happen
0511      * that it overflows during mode transition, and sometimes doesn't recover.
0512      */
0513     REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 1);
0514     udelay(10);
0515 
0516     REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0);
0517 
0518     /* wait 100us for DIG/DP logic to prime
0519      * (i.e. a few video lines)
0520      */
0521     udelay(100);
0522 
0523     /* the hardware would start sending video at the start of the next DP
0524      * frame (i.e. rising edge of the vblank).
0525      * NOTE: We used to program DP_VID_STREAM_DIS_DEFER = 2 here, but this
0526      * register has no effect on enable transition! HW always guarantees
0527      * VID_STREAM enable at start of next frame, and this is not
0528      * programmable
0529      */
0530 
0531     REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);
0532 
0533     dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
0534 }
0535 
0536 static void enc2_dp_set_odm_combine(
0537     struct stream_encoder *enc,
0538     bool odm_combine)
0539 {
0540     struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0541 
0542     REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_COMBINE, odm_combine);
0543 }
0544 
0545 void enc2_stream_encoder_dp_set_stream_attribute(
0546     struct stream_encoder *enc,
0547     struct dc_crtc_timing *crtc_timing,
0548     enum dc_color_space output_color_space,
0549     bool use_vsc_sdp_for_colorimetry,
0550     uint32_t enable_sdp_splitting)
0551 {
0552     struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0553 
0554     enc1_stream_encoder_dp_set_stream_attribute(enc,
0555             crtc_timing,
0556             output_color_space,
0557             use_vsc_sdp_for_colorimetry,
0558             enable_sdp_splitting);
0559 
0560     REG_UPDATE(DP_SEC_FRAMING4,
0561         DP_SST_SDP_SPLITTING, enable_sdp_splitting);
0562 }
0563 
0564 uint32_t enc2_get_fifo_cal_average_level(
0565         struct stream_encoder *enc)
0566 {
0567     struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0568     uint32_t fifo_level;
0569 
0570     REG_GET(DIG_FIFO_STATUS,
0571             DIG_FIFO_CAL_AVERAGE_LEVEL, &fifo_level);
0572     return fifo_level;
0573 }
0574 
0575 static const struct stream_encoder_funcs dcn20_str_enc_funcs = {
0576     .dp_set_odm_combine =
0577         enc2_dp_set_odm_combine,
0578     .dp_set_stream_attribute =
0579         enc2_stream_encoder_dp_set_stream_attribute,
0580     .hdmi_set_stream_attribute =
0581         enc1_stream_encoder_hdmi_set_stream_attribute,
0582     .dvi_set_stream_attribute =
0583         enc1_stream_encoder_dvi_set_stream_attribute,
0584     .set_throttled_vcp_size =
0585         enc1_stream_encoder_set_throttled_vcp_size,
0586     .update_hdmi_info_packets =
0587         enc2_stream_encoder_update_hdmi_info_packets,
0588     .stop_hdmi_info_packets =
0589         enc2_stream_encoder_stop_hdmi_info_packets,
0590     .update_dp_info_packets =
0591         enc2_stream_encoder_update_dp_info_packets,
0592     .send_immediate_sdp_message =
0593         enc1_stream_encoder_send_immediate_sdp_message,
0594     .stop_dp_info_packets =
0595         enc1_stream_encoder_stop_dp_info_packets,
0596     .dp_blank =
0597         enc1_stream_encoder_dp_blank,
0598     .dp_unblank =
0599         enc2_stream_encoder_dp_unblank,
0600     .audio_mute_control = enc1_se_audio_mute_control,
0601 
0602     .dp_audio_setup = enc1_se_dp_audio_setup,
0603     .dp_audio_enable = enc1_se_dp_audio_enable,
0604     .dp_audio_disable = enc1_se_dp_audio_disable,
0605 
0606     .hdmi_audio_setup = enc1_se_hdmi_audio_setup,
0607     .hdmi_audio_disable = enc1_se_hdmi_audio_disable,
0608     .setup_stereo_sync  = enc1_setup_stereo_sync,
0609     .set_avmute = enc1_stream_encoder_set_avmute,
0610     .dig_connect_to_otg  = enc1_dig_connect_to_otg,
0611     .dig_source_otg = enc1_dig_source_otg,
0612 
0613     .dp_get_pixel_format =
0614         enc1_stream_encoder_dp_get_pixel_format,
0615 
0616     .enc_read_state = enc2_read_state,
0617     .dp_set_dsc_config = enc2_dp_set_dsc_config,
0618     .dp_set_dsc_pps_info_packet = enc2_dp_set_dsc_pps_info_packet,
0619     .set_dynamic_metadata = enc2_set_dynamic_metadata,
0620     .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
0621     .get_fifo_cal_average_level = enc2_get_fifo_cal_average_level,
0622 };
0623 
0624 void dcn20_stream_encoder_construct(
0625     struct dcn10_stream_encoder *enc1,
0626     struct dc_context *ctx,
0627     struct dc_bios *bp,
0628     enum engine_id eng_id,
0629     const struct dcn10_stream_enc_registers *regs,
0630     const struct dcn10_stream_encoder_shift *se_shift,
0631     const struct dcn10_stream_encoder_mask *se_mask)
0632 {
0633     enc1->base.funcs = &dcn20_str_enc_funcs;
0634     enc1->base.ctx = ctx;
0635     enc1->base.id = eng_id;
0636     enc1->base.bp = bp;
0637     enc1->regs = regs;
0638     enc1->se_shift = se_shift;
0639     enc1->se_mask = se_mask;
0640     enc1->base.stream_enc_inst = eng_id - ENGINE_ID_DIGA;
0641 }
0642