linux/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
<<
>>
Prefs
   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 "reg_helper.h"
  27
  28#include "core_types.h"
  29#include "link_encoder.h"
  30#include "dcn10_link_encoder.h"
  31#include "stream_encoder.h"
  32#include "i2caux_interface.h"
  33#include "dc_bios_types.h"
  34
  35#include "gpio_service_interface.h"
  36
  37#define CTX \
  38        enc10->base.ctx
  39#define DC_LOGGER \
  40        enc10->base.ctx->logger
  41
  42#define REG(reg)\
  43        (enc10->link_regs->reg)
  44
  45#undef FN
  46#define FN(reg_name, field_name) \
  47        enc10->link_shift->field_name, enc10->link_mask->field_name
  48
  49
  50/*
  51 * @brief
  52 * Trigger Source Select
  53 * ASIC-dependent, actual values for register programming
  54 */
  55#define DCN10_DIG_FE_SOURCE_SELECT_INVALID 0x0
  56#define DCN10_DIG_FE_SOURCE_SELECT_DIGA 0x1
  57#define DCN10_DIG_FE_SOURCE_SELECT_DIGB 0x2
  58#define DCN10_DIG_FE_SOURCE_SELECT_DIGC 0x4
  59#define DCN10_DIG_FE_SOURCE_SELECT_DIGD 0x08
  60#define DCN10_DIG_FE_SOURCE_SELECT_DIGE 0x10
  61#define DCN10_DIG_FE_SOURCE_SELECT_DIGF 0x20
  62#define DCN10_DIG_FE_SOURCE_SELECT_DIGG 0x40
  63
  64enum {
  65        DP_MST_UPDATE_MAX_RETRY = 50
  66};
  67
  68static const struct link_encoder_funcs dcn10_lnk_enc_funcs = {
  69        .validate_output_with_stream =
  70                dcn10_link_encoder_validate_output_with_stream,
  71        .hw_init = dcn10_link_encoder_hw_init,
  72        .setup = dcn10_link_encoder_setup,
  73        .enable_tmds_output = dcn10_link_encoder_enable_tmds_output,
  74        .enable_dp_output = dcn10_link_encoder_enable_dp_output,
  75        .enable_dp_mst_output = dcn10_link_encoder_enable_dp_mst_output,
  76        .disable_output = dcn10_link_encoder_disable_output,
  77        .dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings,
  78        .dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern,
  79        .update_mst_stream_allocation_table =
  80                dcn10_link_encoder_update_mst_stream_allocation_table,
  81        .psr_program_dp_dphy_fast_training =
  82                        dcn10_psr_program_dp_dphy_fast_training,
  83        .psr_program_secondary_packet = dcn10_psr_program_secondary_packet,
  84        .connect_dig_be_to_fe = dcn10_link_encoder_connect_dig_be_to_fe,
  85        .enable_hpd = dcn10_link_encoder_enable_hpd,
  86        .disable_hpd = dcn10_link_encoder_disable_hpd,
  87        .is_dig_enabled = dcn10_is_dig_enabled,
  88        .destroy = dcn10_link_encoder_destroy
  89};
  90
  91static enum bp_result link_transmitter_control(
  92        struct dcn10_link_encoder *enc10,
  93        struct bp_transmitter_control *cntl)
  94{
  95        enum bp_result result;
  96        struct dc_bios *bp = enc10->base.ctx->dc_bios;
  97
  98        result = bp->funcs->transmitter_control(bp, cntl);
  99
 100        return result;
 101}
 102
 103static void enable_phy_bypass_mode(
 104        struct dcn10_link_encoder *enc10,
 105        bool enable)
 106{
 107        /* This register resides in DP back end block;
 108         * transmitter is used for the offset
 109         */
 110        REG_UPDATE(DP_DPHY_CNTL, DPHY_BYPASS, enable);
 111
 112}
 113
 114static void disable_prbs_symbols(
 115        struct dcn10_link_encoder *enc10,
 116        bool disable)
 117{
 118        /* This register resides in DP back end block;
 119         * transmitter is used for the offset
 120         */
 121        REG_UPDATE_4(DP_DPHY_CNTL,
 122                        DPHY_ATEST_SEL_LANE0, disable,
 123                        DPHY_ATEST_SEL_LANE1, disable,
 124                        DPHY_ATEST_SEL_LANE2, disable,
 125                        DPHY_ATEST_SEL_LANE3, disable);
 126}
 127
 128static void disable_prbs_mode(
 129        struct dcn10_link_encoder *enc10)
 130{
 131        REG_UPDATE(DP_DPHY_PRBS_CNTL, DPHY_PRBS_EN, 0);
 132}
 133
 134static void program_pattern_symbols(
 135        struct dcn10_link_encoder *enc10,
 136        uint16_t pattern_symbols[8])
 137{
 138        /* This register resides in DP back end block;
 139         * transmitter is used for the offset
 140         */
 141        REG_SET_3(DP_DPHY_SYM0, 0,
 142                        DPHY_SYM1, pattern_symbols[0],
 143                        DPHY_SYM2, pattern_symbols[1],
 144                        DPHY_SYM3, pattern_symbols[2]);
 145
 146        /* This register resides in DP back end block;
 147         * transmitter is used for the offset
 148         */
 149        REG_SET_3(DP_DPHY_SYM1, 0,
 150                        DPHY_SYM4, pattern_symbols[3],
 151                        DPHY_SYM5, pattern_symbols[4],
 152                        DPHY_SYM6, pattern_symbols[5]);
 153
 154        /* This register resides in DP back end block;
 155         * transmitter is used for the offset
 156         */
 157        REG_SET_2(DP_DPHY_SYM2, 0,
 158                        DPHY_SYM7, pattern_symbols[6],
 159                        DPHY_SYM8, pattern_symbols[7]);
 160}
 161
 162static void set_dp_phy_pattern_d102(
 163        struct dcn10_link_encoder *enc10)
 164{
 165        /* Disable PHY Bypass mode to setup the test pattern */
 166        enable_phy_bypass_mode(enc10, false);
 167
 168        /* For 10-bit PRBS or debug symbols
 169         * please use the following sequence:
 170         *
 171         * Enable debug symbols on the lanes
 172         */
 173        disable_prbs_symbols(enc10, true);
 174
 175        /* Disable PRBS mode */
 176        disable_prbs_mode(enc10);
 177
 178        /* Program debug symbols to be output */
 179        {
 180                uint16_t pattern_symbols[8] = {
 181                        0x2AA, 0x2AA, 0x2AA, 0x2AA,
 182                        0x2AA, 0x2AA, 0x2AA, 0x2AA
 183                };
 184
 185                program_pattern_symbols(enc10, pattern_symbols);
 186        }
 187
 188        /* Enable phy bypass mode to enable the test pattern */
 189
 190        enable_phy_bypass_mode(enc10, true);
 191}
 192
 193static void set_link_training_complete(
 194        struct dcn10_link_encoder *enc10,
 195        bool complete)
 196{
 197        /* This register resides in DP back end block;
 198         * transmitter is used for the offset
 199         */
 200        REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, complete);
 201
 202}
 203
 204void dcn10_link_encoder_set_dp_phy_pattern_training_pattern(
 205        struct link_encoder *enc,
 206        uint32_t index)
 207{
 208        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
 209        /* Write Training Pattern */
 210
 211        REG_WRITE(DP_DPHY_TRAINING_PATTERN_SEL, index);
 212
 213        /* Set HW Register Training Complete to false */
 214
 215        set_link_training_complete(enc10, false);
 216
 217        /* Disable PHY Bypass mode to output Training Pattern */
 218
 219        enable_phy_bypass_mode(enc10, false);
 220
 221        /* Disable PRBS mode */
 222        disable_prbs_mode(enc10);
 223}
 224
 225static void setup_panel_mode(
 226        struct dcn10_link_encoder *enc10,
 227        enum dp_panel_mode panel_mode)
 228{
 229        uint32_t value;
 230
 231        ASSERT(REG(DP_DPHY_INTERNAL_CTRL));
 232        value = REG_READ(DP_DPHY_INTERNAL_CTRL);
 233
 234        switch (panel_mode) {
 235        case DP_PANEL_MODE_EDP:
 236                value = 0x1;
 237                break;
 238        case DP_PANEL_MODE_SPECIAL:
 239                value = 0x11;
 240                break;
 241        default:
 242                value = 0x0;
 243                break;
 244        }
 245
 246        REG_WRITE(DP_DPHY_INTERNAL_CTRL, value);
 247}
 248
 249static void set_dp_phy_pattern_symbol_error(
 250        struct dcn10_link_encoder *enc10)
 251{
 252        /* Disable PHY Bypass mode to setup the test pattern */
 253        enable_phy_bypass_mode(enc10, false);
 254
 255        /* program correct panel mode*/
 256        setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
 257
 258        /* A PRBS23 pattern is used for most DP electrical measurements. */
 259
 260        /* Enable PRBS symbols on the lanes */
 261        disable_prbs_symbols(enc10, false);
 262
 263        /* For PRBS23 Set bit DPHY_PRBS_SEL=1 and Set bit DPHY_PRBS_EN=1 */
 264        REG_UPDATE_2(DP_DPHY_PRBS_CNTL,
 265                        DPHY_PRBS_SEL, 1,
 266                        DPHY_PRBS_EN, 1);
 267
 268        /* Enable phy bypass mode to enable the test pattern */
 269        enable_phy_bypass_mode(enc10, true);
 270}
 271
 272static void set_dp_phy_pattern_prbs7(
 273        struct dcn10_link_encoder *enc10)
 274{
 275        /* Disable PHY Bypass mode to setup the test pattern */
 276        enable_phy_bypass_mode(enc10, false);
 277
 278        /* A PRBS7 pattern is used for most DP electrical measurements. */
 279
 280        /* Enable PRBS symbols on the lanes */
 281        disable_prbs_symbols(enc10, false);
 282
 283        /* For PRBS7 Set bit DPHY_PRBS_SEL=0 and Set bit DPHY_PRBS_EN=1 */
 284        REG_UPDATE_2(DP_DPHY_PRBS_CNTL,
 285                        DPHY_PRBS_SEL, 0,
 286                        DPHY_PRBS_EN, 1);
 287
 288        /* Enable phy bypass mode to enable the test pattern */
 289        enable_phy_bypass_mode(enc10, true);
 290}
 291
 292static void set_dp_phy_pattern_80bit_custom(
 293        struct dcn10_link_encoder *enc10,
 294        const uint8_t *pattern)
 295{
 296        /* Disable PHY Bypass mode to setup the test pattern */
 297        enable_phy_bypass_mode(enc10, false);
 298
 299        /* Enable debug symbols on the lanes */
 300
 301        disable_prbs_symbols(enc10, true);
 302
 303        /* Enable PHY bypass mode to enable the test pattern */
 304        /* TODO is it really needed ? */
 305
 306        enable_phy_bypass_mode(enc10, true);
 307
 308        /* Program 80 bit custom pattern */
 309        {
 310                uint16_t pattern_symbols[8];
 311
 312                pattern_symbols[0] =
 313                        ((pattern[1] & 0x03) << 8) | pattern[0];
 314                pattern_symbols[1] =
 315                        ((pattern[2] & 0x0f) << 6) | ((pattern[1] >> 2) & 0x3f);
 316                pattern_symbols[2] =
 317                        ((pattern[3] & 0x3f) << 4) | ((pattern[2] >> 4) & 0x0f);
 318                pattern_symbols[3] =
 319                        (pattern[4] << 2) | ((pattern[3] >> 6) & 0x03);
 320                pattern_symbols[4] =
 321                        ((pattern[6] & 0x03) << 8) | pattern[5];
 322                pattern_symbols[5] =
 323                        ((pattern[7] & 0x0f) << 6) | ((pattern[6] >> 2) & 0x3f);
 324                pattern_symbols[6] =
 325                        ((pattern[8] & 0x3f) << 4) | ((pattern[7] >> 4) & 0x0f);
 326                pattern_symbols[7] =
 327                        (pattern[9] << 2) | ((pattern[8] >> 6) & 0x03);
 328
 329                program_pattern_symbols(enc10, pattern_symbols);
 330        }
 331
 332        /* Enable phy bypass mode to enable the test pattern */
 333
 334        enable_phy_bypass_mode(enc10, true);
 335}
 336
 337static void set_dp_phy_pattern_hbr2_compliance_cp2520_2(
 338        struct dcn10_link_encoder *enc10,
 339        unsigned int cp2520_pattern)
 340{
 341
 342        /* previously there is a register DP_HBR2_EYE_PATTERN
 343         * that is enabled to get the pattern.
 344         * But it does not work with the latest spec change,
 345         * so we are programming the following registers manually.
 346         *
 347         * The following settings have been confirmed
 348         * by Nick Chorney and Sandra Liu
 349         */
 350
 351        /* Disable PHY Bypass mode to setup the test pattern */
 352
 353        enable_phy_bypass_mode(enc10, false);
 354
 355        /* Setup DIG encoder in DP SST mode */
 356        enc10->base.funcs->setup(&enc10->base, SIGNAL_TYPE_DISPLAY_PORT);
 357
 358        /* ensure normal panel mode. */
 359        setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
 360
 361        /* no vbid after BS (SR)
 362         * DP_LINK_FRAMING_CNTL changed history Sandra Liu
 363         * 11000260 / 11000104 / 110000FC
 364         */
 365        REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
 366                        DP_IDLE_BS_INTERVAL, 0xFC,
 367                        DP_VBID_DISABLE, 1,
 368                        DP_VID_ENHANCED_FRAME_MODE, 1);
 369
 370        /* swap every BS with SR */
 371        REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0);
 372
 373        /* select cp2520 patterns */
 374        if (REG(DP_DPHY_HBR2_PATTERN_CONTROL))
 375                REG_UPDATE(DP_DPHY_HBR2_PATTERN_CONTROL,
 376                                DP_DPHY_HBR2_PATTERN_CONTROL, cp2520_pattern);
 377        else
 378                /* pre-DCE11 can only generate CP2520 pattern 2 */
 379                ASSERT(cp2520_pattern == 2);
 380
 381        /* set link training complete */
 382        set_link_training_complete(enc10, true);
 383
 384        /* disable video stream */
 385        REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0);
 386
 387        /* Disable PHY Bypass mode to setup the test pattern */
 388        enable_phy_bypass_mode(enc10, false);
 389}
 390
 391static void set_dp_phy_pattern_passthrough_mode(
 392        struct dcn10_link_encoder *enc10,
 393        enum dp_panel_mode panel_mode)
 394{
 395        /* program correct panel mode */
 396        setup_panel_mode(enc10, panel_mode);
 397
 398        /* restore LINK_FRAMING_CNTL and DPHY_SCRAMBLER_BS_COUNT
 399         * in case we were doing HBR2 compliance pattern before
 400         */
 401        REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
 402                        DP_IDLE_BS_INTERVAL, 0x2000,
 403                        DP_VBID_DISABLE, 0,
 404                        DP_VID_ENHANCED_FRAME_MODE, 1);
 405
 406        REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0x1FF);
 407
 408        /* set link training complete */
 409        set_link_training_complete(enc10, true);
 410
 411        /* Disable PHY Bypass mode to setup the test pattern */
 412        enable_phy_bypass_mode(enc10, false);
 413
 414        /* Disable PRBS mode */
 415        disable_prbs_mode(enc10);
 416}
 417
 418/* return value is bit-vector */
 419static uint8_t get_frontend_source(
 420        enum engine_id engine)
 421{
 422        switch (engine) {
 423        case ENGINE_ID_DIGA:
 424                return DCN10_DIG_FE_SOURCE_SELECT_DIGA;
 425        case ENGINE_ID_DIGB:
 426                return DCN10_DIG_FE_SOURCE_SELECT_DIGB;
 427        case ENGINE_ID_DIGC:
 428                return DCN10_DIG_FE_SOURCE_SELECT_DIGC;
 429        case ENGINE_ID_DIGD:
 430                return DCN10_DIG_FE_SOURCE_SELECT_DIGD;
 431        case ENGINE_ID_DIGE:
 432                return DCN10_DIG_FE_SOURCE_SELECT_DIGE;
 433        case ENGINE_ID_DIGF:
 434                return DCN10_DIG_FE_SOURCE_SELECT_DIGF;
 435        case ENGINE_ID_DIGG:
 436                return DCN10_DIG_FE_SOURCE_SELECT_DIGG;
 437        default:
 438                ASSERT_CRITICAL(false);
 439                return DCN10_DIG_FE_SOURCE_SELECT_INVALID;
 440        }
 441}
 442
 443void configure_encoder(
 444        struct dcn10_link_encoder *enc10,
 445        const struct dc_link_settings *link_settings)
 446{
 447        /* set number of lanes */
 448        REG_SET(DP_CONFIG, 0,
 449                        DP_UDI_LANES, link_settings->lane_count - LANE_COUNT_ONE);
 450
 451        /* setup scrambler */
 452        REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1);
 453}
 454
 455void dcn10_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
 456                        bool exit_link_training_required)
 457{
 458        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
 459
 460        if (exit_link_training_required)
 461                REG_UPDATE(DP_DPHY_FAST_TRAINING,
 462                                DPHY_RX_FAST_TRAINING_CAPABLE, 1);
 463        else {
 464                REG_UPDATE(DP_DPHY_FAST_TRAINING,
 465                                DPHY_RX_FAST_TRAINING_CAPABLE, 0);
 466                /*In DCE 11, we are able to pre-program a Force SR register
 467                 * to be able to trigger SR symbol after 5 idle patterns
 468                 * transmitted. Upon PSR Exit, DMCU can trigger
 469                 * DPHY_LOAD_BS_COUNT_START = 1. Upon writing 1 to
 470                 * DPHY_LOAD_BS_COUNT_START and the internal counter
 471                 * reaches DPHY_LOAD_BS_COUNT, the next BS symbol will be
 472                 * replaced by SR symbol once.
 473                 */
 474
 475                REG_UPDATE(DP_DPHY_BS_SR_SWAP_CNTL, DPHY_LOAD_BS_COUNT, 0x5);
 476        }
 477}
 478
 479void dcn10_psr_program_secondary_packet(struct link_encoder *enc,
 480                        unsigned int sdp_transmit_line_num_deadline)
 481{
 482        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
 483
 484        REG_UPDATE_2(DP_SEC_CNTL1,
 485                DP_SEC_GSP0_LINE_NUM, sdp_transmit_line_num_deadline,
 486                DP_SEC_GSP0_PRIORITY, 1);
 487}
 488
 489bool dcn10_is_dig_enabled(struct link_encoder *enc)
 490{
 491        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
 492        uint32_t value;
 493
 494        REG_GET(DIG_BE_EN_CNTL, DIG_ENABLE, &value);
 495        return value;
 496}
 497
 498static void link_encoder_disable(struct dcn10_link_encoder *enc10)
 499{
 500        /* reset training pattern */
 501        REG_SET(DP_DPHY_TRAINING_PATTERN_SEL, 0,
 502                        DPHY_TRAINING_PATTERN_SEL, 0);
 503
 504        /* reset training complete */
 505        REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0);
 506
 507        /* reset panel mode */
 508        setup_panel_mode(enc10, DP_PANEL_MODE_DEFAULT);
 509}
 510
 511static void hpd_initialize(
 512        struct dcn10_link_encoder *enc10)
 513{
 514        /* Associate HPD with DIG_BE */
 515        enum hpd_source_id hpd_source = enc10->base.hpd_source;
 516
 517        REG_UPDATE(DIG_BE_CNTL, DIG_HPD_SELECT, hpd_source);
 518}
 519
 520bool dcn10_link_encoder_validate_dvi_output(
 521        const struct dcn10_link_encoder *enc10,
 522        enum signal_type connector_signal,
 523        enum signal_type signal,
 524        const struct dc_crtc_timing *crtc_timing)
 525{
 526        uint32_t max_pixel_clock = TMDS_MAX_PIXEL_CLOCK;
 527
 528        if (signal == SIGNAL_TYPE_DVI_DUAL_LINK)
 529                max_pixel_clock *= 2;
 530
 531        /* This handles the case of HDMI downgrade to DVI we don't want to
 532         * we don't want to cap the pixel clock if the DDI is not DVI.
 533         */
 534        if (connector_signal != SIGNAL_TYPE_DVI_DUAL_LINK &&
 535                        connector_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
 536                max_pixel_clock = enc10->base.features.max_hdmi_pixel_clock;
 537
 538        /* DVI only support RGB pixel encoding */
 539        if (crtc_timing->pixel_encoding != PIXEL_ENCODING_RGB)
 540                return false;
 541
 542        /*connect DVI via adpater's HDMI connector*/
 543        if ((connector_signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
 544                connector_signal == SIGNAL_TYPE_HDMI_TYPE_A) &&
 545                signal != SIGNAL_TYPE_HDMI_TYPE_A &&
 546                crtc_timing->pix_clk_khz > TMDS_MAX_PIXEL_CLOCK)
 547                return false;
 548        if (crtc_timing->pix_clk_khz < TMDS_MIN_PIXEL_CLOCK)
 549                return false;
 550
 551        if (crtc_timing->pix_clk_khz > max_pixel_clock)
 552                return false;
 553
 554        /* DVI supports 6/8bpp single-link and 10/16bpp dual-link */
 555        switch (crtc_timing->display_color_depth) {
 556        case COLOR_DEPTH_666:
 557        case COLOR_DEPTH_888:
 558        break;
 559        case COLOR_DEPTH_101010:
 560        case COLOR_DEPTH_161616:
 561                if (signal != SIGNAL_TYPE_DVI_DUAL_LINK)
 562                        return false;
 563        break;
 564        default:
 565                return false;
 566        }
 567
 568        return true;
 569}
 570
 571static bool dcn10_link_encoder_validate_hdmi_output(
 572        const struct dcn10_link_encoder *enc10,
 573        const struct dc_crtc_timing *crtc_timing,
 574        int adjusted_pix_clk_khz)
 575{
 576        enum dc_color_depth max_deep_color =
 577                        enc10->base.features.max_hdmi_deep_color;
 578
 579        if (max_deep_color < crtc_timing->display_color_depth)
 580                return false;
 581
 582        if (crtc_timing->display_color_depth < COLOR_DEPTH_888)
 583                return false;
 584        if (adjusted_pix_clk_khz < TMDS_MIN_PIXEL_CLOCK)
 585                return false;
 586
 587        if ((adjusted_pix_clk_khz == 0) ||
 588                (adjusted_pix_clk_khz > enc10->base.features.max_hdmi_pixel_clock))
 589                return false;
 590
 591        /* DCE11 HW does not support 420 */
 592        if (!enc10->base.features.hdmi_ycbcr420_supported &&
 593                        crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
 594                return false;
 595
 596        if (!enc10->base.features.flags.bits.HDMI_6GB_EN &&
 597                adjusted_pix_clk_khz >= 300000)
 598                return false;
 599        if (enc10->base.ctx->dc->debug.hdmi20_disable &&
 600                crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
 601                return false;
 602        return true;
 603}
 604
 605bool dcn10_link_encoder_validate_dp_output(
 606        const struct dcn10_link_encoder *enc10,
 607        const struct dc_crtc_timing *crtc_timing)
 608{
 609        if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
 610                if (!enc10->base.features.dp_ycbcr420_supported)
 611                        return false;
 612        }
 613
 614        return true;
 615}
 616
 617void dcn10_link_encoder_construct(
 618        struct dcn10_link_encoder *enc10,
 619        const struct encoder_init_data *init_data,
 620        const struct encoder_feature_support *enc_features,
 621        const struct dcn10_link_enc_registers *link_regs,
 622        const struct dcn10_link_enc_aux_registers *aux_regs,
 623        const struct dcn10_link_enc_hpd_registers *hpd_regs,
 624        const struct dcn10_link_enc_shift *link_shift,
 625        const struct dcn10_link_enc_mask *link_mask)
 626{
 627        struct bp_encoder_cap_info bp_cap_info = {0};
 628        const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
 629        enum bp_result result = BP_RESULT_OK;
 630
 631        enc10->base.funcs = &dcn10_lnk_enc_funcs;
 632        enc10->base.ctx = init_data->ctx;
 633        enc10->base.id = init_data->encoder;
 634
 635        enc10->base.hpd_source = init_data->hpd_source;
 636        enc10->base.connector = init_data->connector;
 637
 638        enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
 639
 640        enc10->base.features = *enc_features;
 641
 642        enc10->base.transmitter = init_data->transmitter;
 643
 644        /* set the flag to indicate whether driver poll the I2C data pin
 645         * while doing the DP sink detect
 646         */
 647
 648/*      if (dal_adapter_service_is_feature_supported(as,
 649                FEATURE_DP_SINK_DETECT_POLL_DATA_PIN))
 650                enc10->base.features.flags.bits.
 651                        DP_SINK_DETECT_POLL_DATA_PIN = true;*/
 652
 653        enc10->base.output_signals =
 654                SIGNAL_TYPE_DVI_SINGLE_LINK |
 655                SIGNAL_TYPE_DVI_DUAL_LINK |
 656                SIGNAL_TYPE_LVDS |
 657                SIGNAL_TYPE_DISPLAY_PORT |
 658                SIGNAL_TYPE_DISPLAY_PORT_MST |
 659                SIGNAL_TYPE_EDP |
 660                SIGNAL_TYPE_HDMI_TYPE_A;
 661
 662        /* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE.
 663         * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY.
 664         * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer
 665         * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS.
 666         * Prefer DIG assignment is decided by board design.
 667         * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design
 668         * and VBIOS will filter out 7 UNIPHY for DCE 8.0.
 669         * By this, adding DIGG should not hurt DCE 8.0.
 670         * This will let DCE 8.1 share DCE 8.0 as much as possible
 671         */
 672
 673        enc10->link_regs = link_regs;
 674        enc10->aux_regs = aux_regs;
 675        enc10->hpd_regs = hpd_regs;
 676        enc10->link_shift = link_shift;
 677        enc10->link_mask = link_mask;
 678
 679        switch (enc10->base.transmitter) {
 680        case TRANSMITTER_UNIPHY_A:
 681                enc10->base.preferred_engine = ENGINE_ID_DIGA;
 682        break;
 683        case TRANSMITTER_UNIPHY_B:
 684                enc10->base.preferred_engine = ENGINE_ID_DIGB;
 685        break;
 686        case TRANSMITTER_UNIPHY_C:
 687                enc10->base.preferred_engine = ENGINE_ID_DIGC;
 688        break;
 689        case TRANSMITTER_UNIPHY_D:
 690                enc10->base.preferred_engine = ENGINE_ID_DIGD;
 691        break;
 692        case TRANSMITTER_UNIPHY_E:
 693                enc10->base.preferred_engine = ENGINE_ID_DIGE;
 694        break;
 695        case TRANSMITTER_UNIPHY_F:
 696                enc10->base.preferred_engine = ENGINE_ID_DIGF;
 697        break;
 698        case TRANSMITTER_UNIPHY_G:
 699                enc10->base.preferred_engine = ENGINE_ID_DIGG;
 700        break;
 701        default:
 702                ASSERT_CRITICAL(false);
 703                enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
 704        }
 705
 706        /* default to one to mirror Windows behavior */
 707        enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
 708
 709        result = bp_funcs->get_encoder_cap_info(enc10->base.ctx->dc_bios,
 710                                                enc10->base.id, &bp_cap_info);
 711
 712        /* Override features with DCE-specific values */
 713        if (result == BP_RESULT_OK) {
 714                enc10->base.features.flags.bits.IS_HBR2_CAPABLE =
 715                                bp_cap_info.DP_HBR2_EN;
 716                enc10->base.features.flags.bits.IS_HBR3_CAPABLE =
 717                                bp_cap_info.DP_HBR3_EN;
 718                enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
 719        } else {
 720                DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
 721                                __func__,
 722                                result);
 723        }
 724        if (enc10->base.ctx->dc->debug.hdmi20_disable) {
 725                enc10->base.features.flags.bits.HDMI_6GB_EN = 0;
 726        }
 727}
 728
 729bool dcn10_link_encoder_validate_output_with_stream(
 730        struct link_encoder *enc,
 731        const struct dc_stream_state *stream)
 732{
 733        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
 734        bool is_valid;
 735
 736        switch (stream->signal) {
 737        case SIGNAL_TYPE_DVI_SINGLE_LINK:
 738        case SIGNAL_TYPE_DVI_DUAL_LINK:
 739                is_valid = dcn10_link_encoder_validate_dvi_output(
 740                        enc10,
 741                        stream->sink->link->connector_signal,
 742                        stream->signal,
 743                        &stream->timing);
 744        break;
 745        case SIGNAL_TYPE_HDMI_TYPE_A:
 746                is_valid = dcn10_link_encoder_validate_hdmi_output(
 747                                enc10,
 748                                &stream->timing,
 749                                stream->phy_pix_clk);
 750        break;
 751        case SIGNAL_TYPE_DISPLAY_PORT:
 752        case SIGNAL_TYPE_DISPLAY_PORT_MST:
 753                is_valid = dcn10_link_encoder_validate_dp_output(
 754                                        enc10, &stream->timing);
 755        break;
 756        case SIGNAL_TYPE_EDP:
 757                is_valid = (stream->timing.pixel_encoding == PIXEL_ENCODING_RGB) ? true : false;
 758        break;
 759        case SIGNAL_TYPE_VIRTUAL:
 760                is_valid = true;
 761                break;
 762        default:
 763                is_valid = false;
 764        break;
 765        }
 766
 767        return is_valid;
 768}
 769
 770void dcn10_link_encoder_hw_init(
 771        struct link_encoder *enc)
 772{
 773        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
 774        struct bp_transmitter_control cntl = { 0 };
 775        enum bp_result result;
 776
 777        cntl.action = TRANSMITTER_CONTROL_INIT;
 778        cntl.engine_id = ENGINE_ID_UNKNOWN;
 779        cntl.transmitter = enc10->base.transmitter;
 780        cntl.connector_obj_id = enc10->base.connector;
 781        cntl.lanes_number = LANE_COUNT_FOUR;
 782        cntl.coherent = false;
 783        cntl.hpd_sel = enc10->base.hpd_source;
 784
 785        if (enc10->base.connector.id == CONNECTOR_ID_EDP)
 786                cntl.signal = SIGNAL_TYPE_EDP;
 787
 788        result = link_transmitter_control(enc10, &cntl);
 789
 790        if (result != BP_RESULT_OK) {
 791                DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
 792                        __func__);
 793                BREAK_TO_DEBUGGER();
 794                return;
 795        }
 796
 797        if (enc10->base.connector.id == CONNECTOR_ID_LVDS) {
 798                cntl.action = TRANSMITTER_CONTROL_BACKLIGHT_BRIGHTNESS;
 799
 800                result = link_transmitter_control(enc10, &cntl);
 801
 802                ASSERT(result == BP_RESULT_OK);
 803
 804        }
 805        dcn10_aux_initialize(enc10);
 806
 807        /* reinitialize HPD.
 808         * hpd_initialize() will pass DIG_FE id to HW context.
 809         * All other routine within HW context will use fe_engine_offset
 810         * as DIG_FE id even caller pass DIG_FE id.
 811         * So this routine must be called first.
 812         */
 813        hpd_initialize(enc10);
 814}
 815
 816void dcn10_link_encoder_destroy(struct link_encoder **enc)
 817{
 818        kfree(TO_DCN10_LINK_ENC(*enc));
 819        *enc = NULL;
 820}
 821
 822void dcn10_link_encoder_setup(
 823        struct link_encoder *enc,
 824        enum signal_type signal)
 825{
 826        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
 827
 828        switch (signal) {
 829        case SIGNAL_TYPE_EDP:
 830        case SIGNAL_TYPE_DISPLAY_PORT:
 831                /* DP SST */
 832                REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 0);
 833                break;
 834        case SIGNAL_TYPE_LVDS:
 835                /* LVDS */
 836                REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 1);
 837                break;
 838        case SIGNAL_TYPE_DVI_SINGLE_LINK:
 839        case SIGNAL_TYPE_DVI_DUAL_LINK:
 840                /* TMDS-DVI */
 841                REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 2);
 842                break;
 843        case SIGNAL_TYPE_HDMI_TYPE_A:
 844                /* TMDS-HDMI */
 845                REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 3);
 846                break;
 847        case SIGNAL_TYPE_DISPLAY_PORT_MST:
 848                /* DP MST */
 849                REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 5);
 850                break;
 851        default:
 852                ASSERT_CRITICAL(false);
 853                /* invalid mode ! */
 854                break;
 855        }
 856
 857}
 858
 859/* TODO: still need depth or just pass in adjusted pixel clock? */
 860void dcn10_link_encoder_enable_tmds_output(
 861        struct link_encoder *enc,
 862        enum clock_source_id clock_source,
 863        enum dc_color_depth color_depth,
 864        enum signal_type signal,
 865        uint32_t pixel_clock)
 866{
 867        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
 868        struct bp_transmitter_control cntl = { 0 };
 869        enum bp_result result;
 870
 871        /* Enable the PHY */
 872
 873        cntl.action = TRANSMITTER_CONTROL_ENABLE;
 874        cntl.engine_id = enc->preferred_engine;
 875        cntl.transmitter = enc10->base.transmitter;
 876        cntl.pll_id = clock_source;
 877        cntl.signal = signal;
 878        if (cntl.signal == SIGNAL_TYPE_DVI_DUAL_LINK)
 879                cntl.lanes_number = 8;
 880        else
 881                cntl.lanes_number = 4;
 882
 883        cntl.hpd_sel = enc10->base.hpd_source;
 884
 885        cntl.pixel_clock = pixel_clock;
 886        cntl.color_depth = color_depth;
 887
 888        result = link_transmitter_control(enc10, &cntl);
 889
 890        if (result != BP_RESULT_OK) {
 891                DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
 892                        __func__);
 893                BREAK_TO_DEBUGGER();
 894        }
 895}
 896
 897/* enables DP PHY output */
 898void dcn10_link_encoder_enable_dp_output(
 899        struct link_encoder *enc,
 900        const struct dc_link_settings *link_settings,
 901        enum clock_source_id clock_source)
 902{
 903        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
 904        struct bp_transmitter_control cntl = { 0 };
 905        enum bp_result result;
 906
 907        /* Enable the PHY */
 908
 909        /* number_of_lanes is used for pixel clock adjust,
 910         * but it's not passed to asic_control.
 911         * We need to set number of lanes manually.
 912         */
 913        configure_encoder(enc10, link_settings);
 914
 915        cntl.action = TRANSMITTER_CONTROL_ENABLE;
 916        cntl.engine_id = enc->preferred_engine;
 917        cntl.transmitter = enc10->base.transmitter;
 918        cntl.pll_id = clock_source;
 919        cntl.signal = SIGNAL_TYPE_DISPLAY_PORT;
 920        cntl.lanes_number = link_settings->lane_count;
 921        cntl.hpd_sel = enc10->base.hpd_source;
 922        cntl.pixel_clock = link_settings->link_rate
 923                                                * LINK_RATE_REF_FREQ_IN_KHZ;
 924        /* TODO: check if undefined works */
 925        cntl.color_depth = COLOR_DEPTH_UNDEFINED;
 926
 927        result = link_transmitter_control(enc10, &cntl);
 928
 929        if (result != BP_RESULT_OK) {
 930                DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
 931                        __func__);
 932                BREAK_TO_DEBUGGER();
 933        }
 934}
 935
 936/* enables DP PHY output in MST mode */
 937void dcn10_link_encoder_enable_dp_mst_output(
 938        struct link_encoder *enc,
 939        const struct dc_link_settings *link_settings,
 940        enum clock_source_id clock_source)
 941{
 942        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
 943        struct bp_transmitter_control cntl = { 0 };
 944        enum bp_result result;
 945
 946        /* Enable the PHY */
 947
 948        /* number_of_lanes is used for pixel clock adjust,
 949         * but it's not passed to asic_control.
 950         * We need to set number of lanes manually.
 951         */
 952        configure_encoder(enc10, link_settings);
 953
 954        cntl.action = TRANSMITTER_CONTROL_ENABLE;
 955        cntl.engine_id = ENGINE_ID_UNKNOWN;
 956        cntl.transmitter = enc10->base.transmitter;
 957        cntl.pll_id = clock_source;
 958        cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
 959        cntl.lanes_number = link_settings->lane_count;
 960        cntl.hpd_sel = enc10->base.hpd_source;
 961        cntl.pixel_clock = link_settings->link_rate
 962                                                * LINK_RATE_REF_FREQ_IN_KHZ;
 963        /* TODO: check if undefined works */
 964        cntl.color_depth = COLOR_DEPTH_UNDEFINED;
 965
 966        result = link_transmitter_control(enc10, &cntl);
 967
 968        if (result != BP_RESULT_OK) {
 969                DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
 970                        __func__);
 971                BREAK_TO_DEBUGGER();
 972        }
 973}
 974/*
 975 * @brief
 976 * Disable transmitter and its encoder
 977 */
 978void dcn10_link_encoder_disable_output(
 979        struct link_encoder *enc,
 980        enum signal_type signal)
 981{
 982        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
 983        struct bp_transmitter_control cntl = { 0 };
 984        enum bp_result result;
 985
 986        if (!dcn10_is_dig_enabled(enc)) {
 987                /* OF_SKIP_POWER_DOWN_INACTIVE_ENCODER */
 988        /*in DP_Alt_No_Connect case, we turn off the dig already,
 989        after excuation the PHY w/a sequence, not allow touch PHY any more*/
 990                return;
 991        }
 992        /* Power-down RX and disable GPU PHY should be paired.
 993         * Disabling PHY without powering down RX may cause
 994         * symbol lock loss, on which we will get DP Sink interrupt.
 995         */
 996
 997        /* There is a case for the DP active dongles
 998         * where we want to disable the PHY but keep RX powered,
 999         * for those we need to ignore DP Sink interrupt
1000         * by checking lane count that has been set
1001         * on the last do_enable_output().
1002         */
1003
1004        /* disable transmitter */
1005        cntl.action = TRANSMITTER_CONTROL_DISABLE;
1006        cntl.transmitter = enc10->base.transmitter;
1007        cntl.hpd_sel = enc10->base.hpd_source;
1008        cntl.signal = signal;
1009        cntl.connector_obj_id = enc10->base.connector;
1010
1011        result = link_transmitter_control(enc10, &cntl);
1012
1013        if (result != BP_RESULT_OK) {
1014                DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1015                        __func__);
1016                BREAK_TO_DEBUGGER();
1017                return;
1018        }
1019
1020        /* disable encoder */
1021        if (dc_is_dp_signal(signal))
1022                link_encoder_disable(enc10);
1023}
1024
1025void dcn10_link_encoder_dp_set_lane_settings(
1026        struct link_encoder *enc,
1027        const struct link_training_settings *link_settings)
1028{
1029        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1030        union dpcd_training_lane_set training_lane_set = { { 0 } };
1031        int32_t lane = 0;
1032        struct bp_transmitter_control cntl = { 0 };
1033
1034        if (!link_settings) {
1035                BREAK_TO_DEBUGGER();
1036                return;
1037        }
1038
1039        cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS;
1040        cntl.transmitter = enc10->base.transmitter;
1041        cntl.connector_obj_id = enc10->base.connector;
1042        cntl.lanes_number = link_settings->link_settings.lane_count;
1043        cntl.hpd_sel = enc10->base.hpd_source;
1044        cntl.pixel_clock = link_settings->link_settings.link_rate *
1045                                                LINK_RATE_REF_FREQ_IN_KHZ;
1046
1047        for (lane = 0; lane < link_settings->link_settings.lane_count; lane++) {
1048                /* translate lane settings */
1049
1050                training_lane_set.bits.VOLTAGE_SWING_SET =
1051                        link_settings->lane_settings[lane].VOLTAGE_SWING;
1052                training_lane_set.bits.PRE_EMPHASIS_SET =
1053                        link_settings->lane_settings[lane].PRE_EMPHASIS;
1054
1055                /* post cursor 2 setting only applies to HBR2 link rate */
1056                if (link_settings->link_settings.link_rate == LINK_RATE_HIGH2) {
1057                        /* this is passed to VBIOS
1058                         * to program post cursor 2 level
1059                         */
1060                        training_lane_set.bits.POST_CURSOR2_SET =
1061                                link_settings->lane_settings[lane].POST_CURSOR2;
1062                }
1063
1064                cntl.lane_select = lane;
1065                cntl.lane_settings = training_lane_set.raw;
1066
1067                /* call VBIOS table to set voltage swing and pre-emphasis */
1068                link_transmitter_control(enc10, &cntl);
1069        }
1070}
1071
1072/* set DP PHY test and training patterns */
1073void dcn10_link_encoder_dp_set_phy_pattern(
1074        struct link_encoder *enc,
1075        const struct encoder_set_dp_phy_pattern_param *param)
1076{
1077        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1078
1079        switch (param->dp_phy_pattern) {
1080        case DP_TEST_PATTERN_TRAINING_PATTERN1:
1081                dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 0);
1082                break;
1083        case DP_TEST_PATTERN_TRAINING_PATTERN2:
1084                dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 1);
1085                break;
1086        case DP_TEST_PATTERN_TRAINING_PATTERN3:
1087                dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 2);
1088                break;
1089        case DP_TEST_PATTERN_TRAINING_PATTERN4:
1090                dcn10_link_encoder_set_dp_phy_pattern_training_pattern(enc, 3);
1091                break;
1092        case DP_TEST_PATTERN_D102:
1093                set_dp_phy_pattern_d102(enc10);
1094                break;
1095        case DP_TEST_PATTERN_SYMBOL_ERROR:
1096                set_dp_phy_pattern_symbol_error(enc10);
1097                break;
1098        case DP_TEST_PATTERN_PRBS7:
1099                set_dp_phy_pattern_prbs7(enc10);
1100                break;
1101        case DP_TEST_PATTERN_80BIT_CUSTOM:
1102                set_dp_phy_pattern_80bit_custom(
1103                        enc10, param->custom_pattern);
1104                break;
1105        case DP_TEST_PATTERN_CP2520_1:
1106                set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 1);
1107                break;
1108        case DP_TEST_PATTERN_CP2520_2:
1109                set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 2);
1110                break;
1111        case DP_TEST_PATTERN_CP2520_3:
1112                set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc10, 3);
1113                break;
1114        case DP_TEST_PATTERN_VIDEO_MODE: {
1115                set_dp_phy_pattern_passthrough_mode(
1116                        enc10, param->dp_panel_mode);
1117                break;
1118        }
1119
1120        default:
1121                /* invalid phy pattern */
1122                ASSERT_CRITICAL(false);
1123                break;
1124        }
1125}
1126
1127static void fill_stream_allocation_row_info(
1128        const struct link_mst_stream_allocation *stream_allocation,
1129        uint32_t *src,
1130        uint32_t *slots)
1131{
1132        const struct stream_encoder *stream_enc = stream_allocation->stream_enc;
1133
1134        if (stream_enc) {
1135                *src = stream_enc->id;
1136                *slots = stream_allocation->slot_count;
1137        } else {
1138                *src = 0;
1139                *slots = 0;
1140        }
1141}
1142
1143/* programs DP MST VC payload allocation */
1144void dcn10_link_encoder_update_mst_stream_allocation_table(
1145        struct link_encoder *enc,
1146        const struct link_mst_stream_allocation_table *table)
1147{
1148        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1149        uint32_t value0 = 0;
1150        uint32_t value1 = 0;
1151        uint32_t value2 = 0;
1152        uint32_t slots = 0;
1153        uint32_t src = 0;
1154        uint32_t retries = 0;
1155
1156        /* For CZ, there are only 3 pipes. So Virtual channel is up 3.*/
1157
1158        /* --- Set MSE Stream Attribute -
1159         * Setup VC Payload Table on Tx Side,
1160         * Issue allocation change trigger
1161         * to commit payload on both tx and rx side
1162         */
1163
1164        /* we should clean-up table each time */
1165
1166        if (table->stream_count >= 1) {
1167                fill_stream_allocation_row_info(
1168                        &table->stream_allocations[0],
1169                        &src,
1170                        &slots);
1171        } else {
1172                src = 0;
1173                slots = 0;
1174        }
1175
1176        REG_UPDATE_2(DP_MSE_SAT0,
1177                        DP_MSE_SAT_SRC0, src,
1178                        DP_MSE_SAT_SLOT_COUNT0, slots);
1179
1180        if (table->stream_count >= 2) {
1181                fill_stream_allocation_row_info(
1182                        &table->stream_allocations[1],
1183                        &src,
1184                        &slots);
1185        } else {
1186                src = 0;
1187                slots = 0;
1188        }
1189
1190        REG_UPDATE_2(DP_MSE_SAT0,
1191                        DP_MSE_SAT_SRC1, src,
1192                        DP_MSE_SAT_SLOT_COUNT1, slots);
1193
1194        if (table->stream_count >= 3) {
1195                fill_stream_allocation_row_info(
1196                        &table->stream_allocations[2],
1197                        &src,
1198                        &slots);
1199        } else {
1200                src = 0;
1201                slots = 0;
1202        }
1203
1204        REG_UPDATE_2(DP_MSE_SAT1,
1205                        DP_MSE_SAT_SRC2, src,
1206                        DP_MSE_SAT_SLOT_COUNT2, slots);
1207
1208        if (table->stream_count >= 4) {
1209                fill_stream_allocation_row_info(
1210                        &table->stream_allocations[3],
1211                        &src,
1212                        &slots);
1213        } else {
1214                src = 0;
1215                slots = 0;
1216        }
1217
1218        REG_UPDATE_2(DP_MSE_SAT1,
1219                        DP_MSE_SAT_SRC3, src,
1220                        DP_MSE_SAT_SLOT_COUNT3, slots);
1221
1222        /* --- wait for transaction finish */
1223
1224        /* send allocation change trigger (ACT) ?
1225         * this step first sends the ACT,
1226         * then double buffers the SAT into the hardware
1227         * making the new allocation active on the DP MST mode link
1228         */
1229
1230        /* DP_MSE_SAT_UPDATE:
1231         * 0 - No Action
1232         * 1 - Update SAT with trigger
1233         * 2 - Update SAT without trigger
1234         */
1235        REG_UPDATE(DP_MSE_SAT_UPDATE,
1236                        DP_MSE_SAT_UPDATE, 1);
1237
1238        /* wait for update to complete
1239         * (i.e. DP_MSE_SAT_UPDATE field is reset to 0)
1240         * then wait for the transmission
1241         * of at least 16 MTP headers on immediate local link.
1242         * i.e. DP_MSE_16_MTP_KEEPOUT field (read only) is reset to 0
1243         * a value of 1 indicates that DP MST mode
1244         * is in the 16 MTP keepout region after a VC has been added.
1245         * MST stream bandwidth (VC rate) can be configured
1246         * after this bit is cleared
1247         */
1248        do {
1249                udelay(10);
1250
1251                value0 = REG_READ(DP_MSE_SAT_UPDATE);
1252
1253                REG_GET(DP_MSE_SAT_UPDATE,
1254                                DP_MSE_SAT_UPDATE, &value1);
1255
1256                REG_GET(DP_MSE_SAT_UPDATE,
1257                                DP_MSE_16_MTP_KEEPOUT, &value2);
1258
1259                /* bit field DP_MSE_SAT_UPDATE is set to 1 already */
1260                if (!value1 && !value2)
1261                        break;
1262                ++retries;
1263        } while (retries < DP_MST_UPDATE_MAX_RETRY);
1264}
1265
1266void dcn10_link_encoder_connect_dig_be_to_fe(
1267        struct link_encoder *enc,
1268        enum engine_id engine,
1269        bool connect)
1270{
1271        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1272        uint32_t field;
1273
1274        if (engine != ENGINE_ID_UNKNOWN) {
1275
1276                REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &field);
1277
1278                if (connect)
1279                        field |= get_frontend_source(engine);
1280                else
1281                        field &= ~get_frontend_source(engine);
1282
1283                REG_UPDATE(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, field);
1284        }
1285}
1286
1287
1288#define HPD_REG(reg)\
1289        (enc10->hpd_regs->reg)
1290
1291#define HPD_REG_READ(reg_name) \
1292                dm_read_reg(CTX, HPD_REG(reg_name))
1293
1294#define HPD_REG_UPDATE_N(reg_name, n, ...)      \
1295                generic_reg_update_ex(CTX, \
1296                                HPD_REG(reg_name), \
1297                                HPD_REG_READ(reg_name), \
1298                                n, __VA_ARGS__)
1299
1300#define HPD_REG_UPDATE(reg_name, field, val)    \
1301                HPD_REG_UPDATE_N(reg_name, 1, \
1302                                FN(reg_name, field), val)
1303
1304void dcn10_link_encoder_enable_hpd(struct link_encoder *enc)
1305{
1306        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1307
1308        HPD_REG_UPDATE(DC_HPD_CONTROL,
1309                        DC_HPD_EN, 1);
1310}
1311
1312void dcn10_link_encoder_disable_hpd(struct link_encoder *enc)
1313{
1314        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
1315
1316        HPD_REG_UPDATE(DC_HPD_CONTROL,
1317                        DC_HPD_EN, 0);
1318}
1319
1320
1321#define AUX_REG(reg)\
1322        (enc10->aux_regs->reg)
1323
1324#define AUX_REG_READ(reg_name) \
1325                dm_read_reg(CTX, AUX_REG(reg_name))
1326
1327#define AUX_REG_UPDATE_N(reg_name, n, ...)      \
1328                generic_reg_update_ex(CTX, \
1329                                AUX_REG(reg_name), \
1330                                AUX_REG_READ(reg_name), \
1331                                n, __VA_ARGS__)
1332
1333#define AUX_REG_UPDATE(reg_name, field, val)    \
1334                AUX_REG_UPDATE_N(reg_name, 1, \
1335                                FN(reg_name, field), val)
1336
1337#define AUX_REG_UPDATE_2(reg, f1, v1, f2, v2)   \
1338                AUX_REG_UPDATE_N(reg, 2,\
1339                                FN(reg, f1), v1,\
1340                                FN(reg, f2), v2)
1341
1342void dcn10_aux_initialize(struct dcn10_link_encoder *enc10)
1343{
1344        enum hpd_source_id hpd_source = enc10->base.hpd_source;
1345
1346        AUX_REG_UPDATE_2(AUX_CONTROL,
1347                        AUX_HPD_SEL, hpd_source,
1348                        AUX_LS_READ_EN, 0);
1349
1350        /* 1/4 window (the maximum allowed) */
1351        AUX_REG_UPDATE(AUX_DPHY_RX_CONTROL0,
1352                        AUX_RX_RECEIVE_WINDOW, 1);
1353}
1354