linux/drivers/gpu/drm/radeon/atombios_dp.c
<<
>>
Prefs
   1/*
   2 * Copyright 2007-8 Advanced Micro Devices, Inc.
   3 * Copyright 2008 Red Hat Inc.
   4 *
   5 * Permission is hereby granted, free of charge, to any person obtaining a
   6 * copy of this software and associated documentation files (the "Software"),
   7 * to deal in the Software without restriction, including without limitation
   8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   9 * and/or sell copies of the Software, and to permit persons to whom the
  10 * Software is furnished to do so, subject to the following conditions:
  11 *
  12 * The above copyright notice and this permission notice shall be included in
  13 * all copies or substantial portions of the Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21 * OTHER DEALINGS IN THE SOFTWARE.
  22 *
  23 * Authors: Dave Airlie
  24 *          Alex Deucher
  25 */
  26#include "drmP.h"
  27#include "radeon_drm.h"
  28#include "radeon.h"
  29
  30#include "atom.h"
  31#include "atom-bits.h"
  32#include "drm_dp_helper.h"
  33
  34/* move these to drm_dp_helper.c/h */
  35#define DP_LINK_CONFIGURATION_SIZE 9
  36#define DP_LINK_STATUS_SIZE        6
  37#define DP_DPCD_SIZE               8
  38
  39static char *voltage_names[] = {
  40        "0.4V", "0.6V", "0.8V", "1.2V"
  41};
  42static char *pre_emph_names[] = {
  43        "0dB", "3.5dB", "6dB", "9.5dB"
  44};
  45
  46static const int dp_clocks[] = {
  47        54000,  /* 1 lane, 1.62 Ghz */
  48        90000,  /* 1 lane, 2.70 Ghz */
  49        108000, /* 2 lane, 1.62 Ghz */
  50        180000, /* 2 lane, 2.70 Ghz */
  51        216000, /* 4 lane, 1.62 Ghz */
  52        360000, /* 4 lane, 2.70 Ghz */
  53};
  54
  55static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int);
  56
  57/* common helper functions */
  58static int dp_lanes_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
  59{
  60        int i;
  61        u8 max_link_bw;
  62        u8 max_lane_count;
  63
  64        if (!dpcd)
  65                return 0;
  66
  67        max_link_bw = dpcd[DP_MAX_LINK_RATE];
  68        max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
  69
  70        switch (max_link_bw) {
  71        case DP_LINK_BW_1_62:
  72        default:
  73                for (i = 0; i < num_dp_clocks; i++) {
  74                        if (i % 2)
  75                                continue;
  76                        switch (max_lane_count) {
  77                        case 1:
  78                                if (i > 1)
  79                                        return 0;
  80                                break;
  81                        case 2:
  82                                if (i > 3)
  83                                        return 0;
  84                                break;
  85                        case 4:
  86                        default:
  87                                break;
  88                        }
  89                        if (dp_clocks[i] > mode_clock) {
  90                                if (i < 2)
  91                                        return 1;
  92                                else if (i < 4)
  93                                        return 2;
  94                                else
  95                                        return 4;
  96                        }
  97                }
  98                break;
  99        case DP_LINK_BW_2_7:
 100                for (i = 0; i < num_dp_clocks; i++) {
 101                        switch (max_lane_count) {
 102                        case 1:
 103                                if (i > 1)
 104                                        return 0;
 105                                break;
 106                        case 2:
 107                                if (i > 3)
 108                                        return 0;
 109                                break;
 110                        case 4:
 111                        default:
 112                                break;
 113                        }
 114                        if (dp_clocks[i] > mode_clock) {
 115                                if (i < 2)
 116                                        return 1;
 117                                else if (i < 4)
 118                                        return 2;
 119                                else
 120                                        return 4;
 121                        }
 122                }
 123                break;
 124        }
 125
 126        return 0;
 127}
 128
 129static int dp_link_clock_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
 130{
 131        int i;
 132        u8 max_link_bw;
 133        u8 max_lane_count;
 134
 135        if (!dpcd)
 136                return 0;
 137
 138        max_link_bw = dpcd[DP_MAX_LINK_RATE];
 139        max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
 140
 141        switch (max_link_bw) {
 142        case DP_LINK_BW_1_62:
 143        default:
 144                for (i = 0; i < num_dp_clocks; i++) {
 145                        if (i % 2)
 146                                continue;
 147                        switch (max_lane_count) {
 148                        case 1:
 149                                if (i > 1)
 150                                        return 0;
 151                                break;
 152                        case 2:
 153                                if (i > 3)
 154                                        return 0;
 155                                break;
 156                        case 4:
 157                        default:
 158                                break;
 159                        }
 160                        if (dp_clocks[i] > mode_clock)
 161                                return 162000;
 162                }
 163                break;
 164        case DP_LINK_BW_2_7:
 165                for (i = 0; i < num_dp_clocks; i++) {
 166                        switch (max_lane_count) {
 167                        case 1:
 168                                if (i > 1)
 169                                        return 0;
 170                                break;
 171                        case 2:
 172                                if (i > 3)
 173                                        return 0;
 174                                break;
 175                        case 4:
 176                        default:
 177                                break;
 178                        }
 179                        if (dp_clocks[i] > mode_clock)
 180                                return (i % 2) ? 270000 : 162000;
 181                }
 182        }
 183
 184        return 0;
 185}
 186
 187int dp_mode_valid(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
 188{
 189        int lanes = dp_lanes_for_mode_clock(dpcd, mode_clock);
 190        int dp_clock = dp_link_clock_for_mode_clock(dpcd, mode_clock);
 191
 192        if ((lanes == 0) || (dp_clock == 0))
 193                return MODE_CLOCK_HIGH;
 194
 195        return MODE_OK;
 196}
 197
 198static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r)
 199{
 200        return link_status[r - DP_LANE0_1_STATUS];
 201}
 202
 203static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE],
 204                             int lane)
 205{
 206        int i = DP_LANE0_1_STATUS + (lane >> 1);
 207        int s = (lane & 1) * 4;
 208        u8 l = dp_link_status(link_status, i);
 209        return (l >> s) & 0xf;
 210}
 211
 212static bool dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE],
 213                                 int lane_count)
 214{
 215        int lane;
 216        u8 lane_status;
 217
 218        for (lane = 0; lane < lane_count; lane++) {
 219                lane_status = dp_get_lane_status(link_status, lane);
 220                if ((lane_status & DP_LANE_CR_DONE) == 0)
 221                        return false;
 222        }
 223        return true;
 224}
 225
 226static bool dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE],
 227                             int lane_count)
 228{
 229        u8 lane_align;
 230        u8 lane_status;
 231        int lane;
 232
 233        lane_align = dp_link_status(link_status,
 234                                    DP_LANE_ALIGN_STATUS_UPDATED);
 235        if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
 236                return false;
 237        for (lane = 0; lane < lane_count; lane++) {
 238                lane_status = dp_get_lane_status(link_status, lane);
 239                if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
 240                        return false;
 241        }
 242        return true;
 243}
 244
 245static u8 dp_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE],
 246                                        int lane)
 247
 248{
 249        int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
 250        int s = ((lane & 1) ?
 251                 DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
 252                 DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
 253        u8 l = dp_link_status(link_status, i);
 254
 255        return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
 256}
 257
 258static u8 dp_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE],
 259                                             int lane)
 260{
 261        int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
 262        int s = ((lane & 1) ?
 263                 DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
 264                 DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
 265        u8 l = dp_link_status(link_status, i);
 266
 267        return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
 268}
 269
 270/* XXX fix me -- chip specific */
 271#define DP_VOLTAGE_MAX         DP_TRAIN_VOLTAGE_SWING_1200
 272static u8 dp_pre_emphasis_max(u8 voltage_swing)
 273{
 274        switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
 275        case DP_TRAIN_VOLTAGE_SWING_400:
 276                return DP_TRAIN_PRE_EMPHASIS_6;
 277        case DP_TRAIN_VOLTAGE_SWING_600:
 278                return DP_TRAIN_PRE_EMPHASIS_6;
 279        case DP_TRAIN_VOLTAGE_SWING_800:
 280                return DP_TRAIN_PRE_EMPHASIS_3_5;
 281        case DP_TRAIN_VOLTAGE_SWING_1200:
 282        default:
 283                return DP_TRAIN_PRE_EMPHASIS_0;
 284        }
 285}
 286
 287static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
 288                                int lane_count,
 289                                u8 train_set[4])
 290{
 291        u8 v = 0;
 292        u8 p = 0;
 293        int lane;
 294
 295        for (lane = 0; lane < lane_count; lane++) {
 296                u8 this_v = dp_get_adjust_request_voltage(link_status, lane);
 297                u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane);
 298
 299                DRM_DEBUG_KMS("requested signal parameters: lane %d voltage %s pre_emph %s\n",
 300                          lane,
 301                          voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
 302                          pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
 303
 304                if (this_v > v)
 305                        v = this_v;
 306                if (this_p > p)
 307                        p = this_p;
 308        }
 309
 310        if (v >= DP_VOLTAGE_MAX)
 311                v = DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED;
 312
 313        if (p >= dp_pre_emphasis_max(v))
 314                p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 315
 316        DRM_DEBUG_KMS("using signal parameters: voltage %s pre_emph %s\n",
 317                  voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
 318                  pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
 319
 320        for (lane = 0; lane < 4; lane++)
 321                train_set[lane] = v | p;
 322}
 323
 324union aux_channel_transaction {
 325        PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1;
 326        PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2;
 327};
 328
 329/* radeon aux chan functions */
 330bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
 331                           int num_bytes, u8 *read_byte,
 332                           u8 read_buf_len, u8 delay)
 333{
 334        struct drm_device *dev = chan->dev;
 335        struct radeon_device *rdev = dev->dev_private;
 336        union aux_channel_transaction args;
 337        int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
 338        unsigned char *base;
 339        int retry_count = 0;
 340
 341        memset(&args, 0, sizeof(args));
 342
 343        base = (unsigned char *)rdev->mode_info.atom_context->scratch;
 344
 345retry:
 346        memcpy(base, req_bytes, num_bytes);
 347
 348        args.v1.lpAuxRequest = 0;
 349        args.v1.lpDataOut = 16;
 350        args.v1.ucDataOutLen = 0;
 351        args.v1.ucChannelID = chan->rec.i2c_id;
 352        args.v1.ucDelay = delay / 10;
 353        if (ASIC_IS_DCE4(rdev))
 354                args.v2.ucHPD_ID = chan->rec.hpd;
 355
 356        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 357
 358        if (args.v1.ucReplyStatus && !args.v1.ucDataOutLen) {
 359                if (args.v1.ucReplyStatus == 0x20 && retry_count++ < 10)
 360                        goto retry;
 361                DRM_DEBUG_KMS("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n",
 362                          req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
 363                          chan->rec.i2c_id, args.v1.ucReplyStatus, retry_count);
 364                return false;
 365        }
 366
 367        if (args.v1.ucDataOutLen && read_byte && read_buf_len) {
 368                if (read_buf_len < args.v1.ucDataOutLen) {
 369                        DRM_ERROR("Buffer to small for return answer %d %d\n",
 370                                  read_buf_len, args.v1.ucDataOutLen);
 371                        return false;
 372                }
 373                {
 374                        int len = min(read_buf_len, args.v1.ucDataOutLen);
 375                        memcpy(read_byte, base + 16, len);
 376                }
 377        }
 378        return true;
 379}
 380
 381bool radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, uint16_t address,
 382                                uint8_t send_bytes, uint8_t *send)
 383{
 384        struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
 385        u8 msg[20];
 386        u8 msg_len, dp_msg_len;
 387        bool ret;
 388
 389        dp_msg_len = 4;
 390        msg[0] = address;
 391        msg[1] = address >> 8;
 392        msg[2] = AUX_NATIVE_WRITE << 4;
 393        dp_msg_len += send_bytes;
 394        msg[3] = (dp_msg_len << 4) | (send_bytes - 1);
 395
 396        if (send_bytes > 16)
 397                return false;
 398
 399        memcpy(&msg[4], send, send_bytes);
 400        msg_len = 4 + send_bytes;
 401        ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, NULL, 0, 0);
 402        return ret;
 403}
 404
 405bool radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, uint16_t address,
 406                               uint8_t delay, uint8_t expected_bytes,
 407                               uint8_t *read_p)
 408{
 409        struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
 410        u8 msg[20];
 411        u8 msg_len, dp_msg_len;
 412        bool ret = false;
 413        msg_len = 4;
 414        dp_msg_len = 4;
 415        msg[0] = address;
 416        msg[1] = address >> 8;
 417        msg[2] = AUX_NATIVE_READ << 4;
 418        msg[3] = (dp_msg_len) << 4;
 419        msg[3] |= expected_bytes - 1;
 420
 421        ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, read_p, expected_bytes, delay);
 422        return ret;
 423}
 424
 425/* radeon dp functions */
 426static u8 radeon_dp_encoder_service(struct radeon_device *rdev, int action, int dp_clock,
 427                                    uint8_t ucconfig, uint8_t lane_num)
 428{
 429        DP_ENCODER_SERVICE_PARAMETERS args;
 430        int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
 431
 432        memset(&args, 0, sizeof(args));
 433        args.ucLinkClock = dp_clock / 10;
 434        args.ucConfig = ucconfig;
 435        args.ucAction = action;
 436        args.ucLaneNum = lane_num;
 437        args.ucStatus = 0;
 438
 439        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 440        return args.ucStatus;
 441}
 442
 443u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
 444{
 445        struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
 446        struct drm_device *dev = radeon_connector->base.dev;
 447        struct radeon_device *rdev = dev->dev_private;
 448
 449        return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
 450                                         dig_connector->dp_i2c_bus->rec.i2c_id, 0);
 451}
 452
 453bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
 454{
 455        struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
 456        u8 msg[25];
 457        int ret;
 458
 459        ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, 0, 8, msg);
 460        if (ret) {
 461                memcpy(dig_connector->dpcd, msg, 8);
 462                {
 463                        int i;
 464                        DRM_DEBUG_KMS("DPCD: ");
 465                        for (i = 0; i < 8; i++)
 466                                DRM_DEBUG_KMS("%02x ", msg[i]);
 467                        DRM_DEBUG_KMS("\n");
 468                }
 469                return true;
 470        }
 471        dig_connector->dpcd[0] = 0;
 472        return false;
 473}
 474
 475void radeon_dp_set_link_config(struct drm_connector *connector,
 476                               struct drm_display_mode *mode)
 477{
 478        struct radeon_connector *radeon_connector;
 479        struct radeon_connector_atom_dig *dig_connector;
 480
 481        if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) &&
 482            (connector->connector_type != DRM_MODE_CONNECTOR_eDP))
 483                return;
 484
 485        radeon_connector = to_radeon_connector(connector);
 486        if (!radeon_connector->con_priv)
 487                return;
 488        dig_connector = radeon_connector->con_priv;
 489
 490        dig_connector->dp_clock =
 491                dp_link_clock_for_mode_clock(dig_connector->dpcd, mode->clock);
 492        dig_connector->dp_lane_count =
 493                dp_lanes_for_mode_clock(dig_connector->dpcd, mode->clock);
 494}
 495
 496int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
 497                                struct drm_display_mode *mode)
 498{
 499        struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
 500
 501        return dp_mode_valid(dig_connector->dpcd, mode->clock);
 502}
 503
 504static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector,
 505                                    u8 link_status[DP_LINK_STATUS_SIZE])
 506{
 507        int ret;
 508        ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, 100,
 509                                        DP_LINK_STATUS_SIZE, link_status);
 510        if (!ret) {
 511                DRM_ERROR("displayport link status failed\n");
 512                return false;
 513        }
 514
 515        DRM_DEBUG_KMS("link status %02x %02x %02x %02x %02x %02x\n",
 516                  link_status[0], link_status[1], link_status[2],
 517                  link_status[3], link_status[4], link_status[5]);
 518        return true;
 519}
 520
 521bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
 522{
 523        struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
 524        u8 link_status[DP_LINK_STATUS_SIZE];
 525
 526        if (!atom_dp_get_link_status(radeon_connector, link_status))
 527                return false;
 528        if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count))
 529                return false;
 530        return true;
 531}
 532
 533static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state)
 534{
 535        struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
 536
 537        if (dig_connector->dpcd[0] >= 0x11) {
 538                radeon_dp_aux_native_write(radeon_connector, DP_SET_POWER, 1,
 539                                           &power_state);
 540        }
 541}
 542
 543static void dp_set_downspread(struct radeon_connector *radeon_connector, u8 downspread)
 544{
 545        radeon_dp_aux_native_write(radeon_connector, DP_DOWNSPREAD_CTRL, 1,
 546                                   &downspread);
 547}
 548
 549static void dp_set_link_bw_lanes(struct radeon_connector *radeon_connector,
 550                                 u8 link_configuration[DP_LINK_CONFIGURATION_SIZE])
 551{
 552        radeon_dp_aux_native_write(radeon_connector, DP_LINK_BW_SET, 2,
 553                                   link_configuration);
 554}
 555
 556static void dp_update_dpvs_emph(struct radeon_connector *radeon_connector,
 557                                struct drm_encoder *encoder,
 558                                u8 train_set[4])
 559{
 560        struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
 561        int i;
 562
 563        for (i = 0; i < dig_connector->dp_lane_count; i++)
 564                atombios_dig_transmitter_setup(encoder,
 565                                               ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH,
 566                                               i, train_set[i]);
 567
 568        radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_LANE0_SET,
 569                                   dig_connector->dp_lane_count, train_set);
 570}
 571
 572static void dp_set_training(struct radeon_connector *radeon_connector,
 573                            u8 training)
 574{
 575        radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_PATTERN_SET,
 576                                   1, &training);
 577}
 578
 579void dp_link_train(struct drm_encoder *encoder,
 580                   struct drm_connector *connector)
 581{
 582        struct drm_device *dev = encoder->dev;
 583        struct radeon_device *rdev = dev->dev_private;
 584        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 585        struct radeon_encoder_atom_dig *dig;
 586        struct radeon_connector *radeon_connector;
 587        struct radeon_connector_atom_dig *dig_connector;
 588        int enc_id = 0;
 589        bool clock_recovery, channel_eq;
 590        u8 link_status[DP_LINK_STATUS_SIZE];
 591        u8 link_configuration[DP_LINK_CONFIGURATION_SIZE];
 592        u8 tries, voltage;
 593        u8 train_set[4];
 594        int i;
 595
 596        if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) &&
 597            (connector->connector_type != DRM_MODE_CONNECTOR_eDP))
 598                return;
 599
 600        if (!radeon_encoder->enc_priv)
 601                return;
 602        dig = radeon_encoder->enc_priv;
 603
 604        radeon_connector = to_radeon_connector(connector);
 605        if (!radeon_connector->con_priv)
 606                return;
 607        dig_connector = radeon_connector->con_priv;
 608
 609        if (dig->dig_encoder)
 610                enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
 611        else
 612                enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
 613        if (dig->linkb)
 614                enc_id |= ATOM_DP_CONFIG_LINK_B;
 615        else
 616                enc_id |= ATOM_DP_CONFIG_LINK_A;
 617
 618        memset(link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
 619        if (dig_connector->dp_clock == 270000)
 620                link_configuration[0] = DP_LINK_BW_2_7;
 621        else
 622                link_configuration[0] = DP_LINK_BW_1_62;
 623        link_configuration[1] = dig_connector->dp_lane_count;
 624        if (dig_connector->dpcd[0] >= 0x11)
 625                link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
 626
 627        /* power up the sink */
 628        dp_set_power(radeon_connector, DP_SET_POWER_D0);
 629        /* disable the training pattern on the sink */
 630        dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
 631        /* set link bw and lanes on the sink */
 632        dp_set_link_bw_lanes(radeon_connector, link_configuration);
 633        /* disable downspread on the sink */
 634        dp_set_downspread(radeon_connector, 0);
 635        if (ASIC_IS_DCE4(rdev)) {
 636                /* start training on the source */
 637                atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START);
 638                /* set training pattern 1 on the source */
 639                atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1);
 640        } else {
 641                /* start training on the source */
 642                radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START,
 643                                          dig_connector->dp_clock, enc_id, 0);
 644                /* set training pattern 1 on the source */
 645                radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
 646                                          dig_connector->dp_clock, enc_id, 0);
 647        }
 648
 649        /* set initial vs/emph */
 650        memset(train_set, 0, 4);
 651        udelay(400);
 652        /* set training pattern 1 on the sink */
 653        dp_set_training(radeon_connector, DP_TRAINING_PATTERN_1);
 654
 655        dp_update_dpvs_emph(radeon_connector, encoder, train_set);
 656
 657        /* clock recovery loop */
 658        clock_recovery = false;
 659        tries = 0;
 660        voltage = 0xff;
 661        for (;;) {
 662                udelay(100);
 663                if (!atom_dp_get_link_status(radeon_connector, link_status))
 664                        break;
 665
 666                if (dp_clock_recovery_ok(link_status, dig_connector->dp_lane_count)) {
 667                        clock_recovery = true;
 668                        break;
 669                }
 670
 671                for (i = 0; i < dig_connector->dp_lane_count; i++) {
 672                        if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
 673                                break;
 674                }
 675                if (i == dig_connector->dp_lane_count) {
 676                        DRM_ERROR("clock recovery reached max voltage\n");
 677                        break;
 678                }
 679
 680                if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
 681                        ++tries;
 682                        if (tries == 5) {
 683                                DRM_ERROR("clock recovery tried 5 times\n");
 684                                break;
 685                        }
 686                } else
 687                        tries = 0;
 688
 689                voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 690
 691                /* Compute new train_set as requested by sink */
 692                dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set);
 693                dp_update_dpvs_emph(radeon_connector, encoder, train_set);
 694        }
 695        if (!clock_recovery)
 696                DRM_ERROR("clock recovery failed\n");
 697        else
 698                DRM_DEBUG_KMS("clock recovery at voltage %d pre-emphasis %d\n",
 699                          train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
 700                          (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >>
 701                          DP_TRAIN_PRE_EMPHASIS_SHIFT);
 702
 703
 704        /* set training pattern 2 on the sink */
 705        dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2);
 706        /* set training pattern 2 on the source */
 707        if (ASIC_IS_DCE4(rdev))
 708                atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2);
 709        else
 710                radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
 711                                          dig_connector->dp_clock, enc_id, 1);
 712
 713        /* channel equalization loop */
 714        tries = 0;
 715        channel_eq = false;
 716        for (;;) {
 717                udelay(400);
 718                if (!atom_dp_get_link_status(radeon_connector, link_status))
 719                        break;
 720
 721                if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count)) {
 722                        channel_eq = true;
 723                        break;
 724                }
 725
 726                /* Try 5 times */
 727                if (tries > 5) {
 728                        DRM_ERROR("channel eq failed: 5 tries\n");
 729                        break;
 730                }
 731
 732                /* Compute new train_set as requested by sink */
 733                dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set);
 734                dp_update_dpvs_emph(radeon_connector, encoder, train_set);
 735
 736                tries++;
 737        }
 738
 739        if (!channel_eq)
 740                DRM_ERROR("channel eq failed\n");
 741        else
 742                DRM_DEBUG_KMS("channel eq at voltage %d pre-emphasis %d\n",
 743                          train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
 744                          (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
 745                          >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
 746
 747        /* disable the training pattern on the sink */
 748        dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
 749
 750        /* disable the training pattern on the source */
 751        if (ASIC_IS_DCE4(rdev))
 752                atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
 753        else
 754                radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
 755                                          dig_connector->dp_clock, enc_id, 0);
 756}
 757
 758int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
 759                         uint8_t write_byte, uint8_t *read_byte)
 760{
 761        struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
 762        struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter;
 763        int ret = 0;
 764        uint16_t address = algo_data->address;
 765        uint8_t msg[5];
 766        uint8_t reply[2];
 767        int msg_len, dp_msg_len;
 768        int reply_bytes;
 769
 770        /* Set up the command byte */
 771        if (mode & MODE_I2C_READ)
 772                msg[2] = AUX_I2C_READ << 4;
 773        else
 774                msg[2] = AUX_I2C_WRITE << 4;
 775
 776        if (!(mode & MODE_I2C_STOP))
 777                msg[2] |= AUX_I2C_MOT << 4;
 778
 779        msg[0] = address;
 780        msg[1] = address >> 8;
 781
 782        reply_bytes = 1;
 783
 784        msg_len = 4;
 785        dp_msg_len = 3;
 786        switch (mode) {
 787        case MODE_I2C_WRITE:
 788                msg[4] = write_byte;
 789                msg_len++;
 790                dp_msg_len += 2;
 791                break;
 792        case MODE_I2C_READ:
 793                dp_msg_len += 1;
 794                break;
 795        default:
 796                break;
 797        }
 798
 799        msg[3] = (dp_msg_len) << 4;
 800        ret = radeon_process_aux_ch(auxch, msg, msg_len, reply, reply_bytes, 0);
 801
 802        if (ret) {
 803                if (read_byte)
 804                        *read_byte = reply[0];
 805                return reply_bytes;
 806        }
 807        return -EREMOTEIO;
 808}
 809
 810