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