uboot/drivers/video/tegra124/dp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2011-2013, NVIDIA Corporation.
   4 * Copyright 2014 Google Inc.
   5 */
   6
   7#include <common.h>
   8#include <display.h>
   9#include <dm.h>
  10#include <div64.h>
  11#include <errno.h>
  12#include <log.h>
  13#include <video_bridge.h>
  14#include <asm/io.h>
  15#include <asm/arch-tegra/dc.h>
  16#include <linux/delay.h>
  17#include "display.h"
  18#include "edid.h"
  19#include "sor.h"
  20#include "displayport.h"
  21
  22#define DO_FAST_LINK_TRAINING           1
  23
  24struct tegra_dp_plat {
  25        ulong base;
  26};
  27
  28/**
  29 * struct tegra_dp_priv - private displayport driver info
  30 *
  31 * @dc_dev:     Display controller device that is sending the video feed
  32 */
  33struct tegra_dp_priv {
  34        struct udevice *sor;
  35        struct udevice *dc_dev;
  36        struct dpaux_ctlr *regs;
  37        u8 revision;
  38        int enabled;
  39};
  40
  41struct tegra_dp_priv dp_data;
  42
  43static inline u32 tegra_dpaux_readl(struct tegra_dp_priv *dp, u32 reg)
  44{
  45        return readl((u32 *)dp->regs + reg);
  46}
  47
  48static inline void tegra_dpaux_writel(struct tegra_dp_priv *dp, u32 reg,
  49                                      u32 val)
  50{
  51        writel(val, (u32 *)dp->regs + reg);
  52}
  53
  54static inline u32 tegra_dc_dpaux_poll_register(struct tegra_dp_priv *dp,
  55                                           u32 reg, u32 mask, u32 exp_val,
  56                                           u32 poll_interval_us,
  57                                           u32 timeout_us)
  58{
  59        u32 reg_val = 0;
  60        u32 temp = timeout_us;
  61
  62        do {
  63                udelay(poll_interval_us);
  64                reg_val = tegra_dpaux_readl(dp, reg);
  65                if (timeout_us > poll_interval_us)
  66                        timeout_us -= poll_interval_us;
  67                else
  68                        break;
  69        } while ((reg_val & mask) != exp_val);
  70
  71        if ((reg_val & mask) == exp_val)
  72                return 0;       /* success */
  73        debug("dpaux_poll_register 0x%x: timeout: (reg_val)0x%08x & (mask)0x%08x != (exp_val)0x%08x\n",
  74              reg, reg_val, mask, exp_val);
  75        return temp;
  76}
  77
  78static inline int tegra_dpaux_wait_transaction(struct tegra_dp_priv *dp)
  79{
  80        /* According to DP spec, each aux transaction needs to finish
  81           within 40ms. */
  82        if (tegra_dc_dpaux_poll_register(dp, DPAUX_DP_AUXCTL,
  83                                         DPAUX_DP_AUXCTL_TRANSACTREQ_MASK,
  84                                         DPAUX_DP_AUXCTL_TRANSACTREQ_DONE,
  85                                         100, DP_AUX_TIMEOUT_MS * 1000) != 0) {
  86                debug("dp: DPAUX transaction timeout\n");
  87                return -1;
  88        }
  89        return 0;
  90}
  91
  92static int tegra_dc_dpaux_write_chunk(struct tegra_dp_priv *dp, u32 cmd,
  93                                          u32 addr, u8 *data, u32 *size,
  94                                          u32 *aux_stat)
  95{
  96        int i;
  97        u32 reg_val;
  98        u32 timeout_retries = DP_AUX_TIMEOUT_MAX_TRIES;
  99        u32 defer_retries = DP_AUX_DEFER_MAX_TRIES;
 100        u32 temp_data;
 101
 102        if (*size > DP_AUX_MAX_BYTES)
 103                return -1;      /* only write one chunk of data */
 104
 105        /* Make sure the command is write command */
 106        switch (cmd) {
 107        case DPAUX_DP_AUXCTL_CMD_I2CWR:
 108        case DPAUX_DP_AUXCTL_CMD_MOTWR:
 109        case DPAUX_DP_AUXCTL_CMD_AUXWR:
 110                break;
 111        default:
 112                debug("dp: aux write cmd 0x%x is invalid\n", cmd);
 113                return -EINVAL;
 114        }
 115
 116        tegra_dpaux_writel(dp, DPAUX_DP_AUXADDR, addr);
 117        for (i = 0; i < DP_AUX_MAX_BYTES / 4; ++i) {
 118                memcpy(&temp_data, data, 4);
 119                tegra_dpaux_writel(dp, DPAUX_DP_AUXDATA_WRITE_W(i), temp_data);
 120                data += 4;
 121        }
 122
 123        reg_val = tegra_dpaux_readl(dp, DPAUX_DP_AUXCTL);
 124        reg_val &= ~DPAUX_DP_AUXCTL_CMD_MASK;
 125        reg_val |= cmd;
 126        reg_val &= ~DPAUX_DP_AUXCTL_CMDLEN_FIELD;
 127        reg_val |= ((*size - 1) << DPAUX_DP_AUXCTL_CMDLEN_SHIFT);
 128
 129        while ((timeout_retries > 0) && (defer_retries > 0)) {
 130                if ((timeout_retries != DP_AUX_TIMEOUT_MAX_TRIES) ||
 131                    (defer_retries != DP_AUX_DEFER_MAX_TRIES))
 132                        udelay(1);
 133
 134                reg_val |= DPAUX_DP_AUXCTL_TRANSACTREQ_PENDING;
 135                tegra_dpaux_writel(dp, DPAUX_DP_AUXCTL, reg_val);
 136
 137                if (tegra_dpaux_wait_transaction(dp))
 138                        debug("dp: aux write transaction timeout\n");
 139
 140                *aux_stat = tegra_dpaux_readl(dp, DPAUX_DP_AUXSTAT);
 141
 142                if ((*aux_stat & DPAUX_DP_AUXSTAT_TIMEOUT_ERROR_PENDING) ||
 143                    (*aux_stat & DPAUX_DP_AUXSTAT_RX_ERROR_PENDING) ||
 144                    (*aux_stat & DPAUX_DP_AUXSTAT_SINKSTAT_ERROR_PENDING) ||
 145                    (*aux_stat & DPAUX_DP_AUXSTAT_NO_STOP_ERROR_PENDING)) {
 146                        if (timeout_retries-- > 0) {
 147                                debug("dp: aux write retry (0x%x) -- %d\n",
 148                                      *aux_stat, timeout_retries);
 149                                /* clear the error bits */
 150                                tegra_dpaux_writel(dp, DPAUX_DP_AUXSTAT,
 151                                                   *aux_stat);
 152                                continue;
 153                        } else {
 154                                debug("dp: aux write got error (0x%x)\n",
 155                                      *aux_stat);
 156                                return -ETIMEDOUT;
 157                        }
 158                }
 159
 160                if ((*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_I2CDEFER) ||
 161                    (*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_DEFER)) {
 162                        if (defer_retries-- > 0) {
 163                                debug("dp: aux write defer (0x%x) -- %d\n",
 164                                      *aux_stat, defer_retries);
 165                                /* clear the error bits */
 166                                tegra_dpaux_writel(dp, DPAUX_DP_AUXSTAT,
 167                                                   *aux_stat);
 168                                continue;
 169                        } else {
 170                                debug("dp: aux write defer exceeds max retries (0x%x)\n",
 171                                      *aux_stat);
 172                                return -ETIMEDOUT;
 173                        }
 174                }
 175
 176                if ((*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_MASK) ==
 177                        DPAUX_DP_AUXSTAT_REPLYTYPE_ACK) {
 178                        *size = ((*aux_stat) & DPAUX_DP_AUXSTAT_REPLY_M_MASK);
 179                        return 0;
 180                } else {
 181                        debug("dp: aux write failed (0x%x)\n", *aux_stat);
 182                        return -EIO;
 183                }
 184        }
 185        /* Should never come to here */
 186        return -EIO;
 187}
 188
 189static int tegra_dc_dpaux_read_chunk(struct tegra_dp_priv *dp, u32 cmd,
 190                                         u32 addr, u8 *data, u32 *size,
 191                                         u32 *aux_stat)
 192{
 193        u32 reg_val;
 194        u32 timeout_retries = DP_AUX_TIMEOUT_MAX_TRIES;
 195        u32 defer_retries = DP_AUX_DEFER_MAX_TRIES;
 196
 197        if (*size > DP_AUX_MAX_BYTES) {
 198                debug("only read one chunk\n");
 199                return -EIO;    /* only read one chunk */
 200        }
 201
 202        /* Check to make sure the command is read command */
 203        switch (cmd) {
 204        case DPAUX_DP_AUXCTL_CMD_I2CRD:
 205        case DPAUX_DP_AUXCTL_CMD_I2CREQWSTAT:
 206        case DPAUX_DP_AUXCTL_CMD_MOTRD:
 207        case DPAUX_DP_AUXCTL_CMD_AUXRD:
 208                break;
 209        default:
 210                debug("dp: aux read cmd 0x%x is invalid\n", cmd);
 211                return -EIO;
 212        }
 213
 214        *aux_stat = tegra_dpaux_readl(dp, DPAUX_DP_AUXSTAT);
 215        if (!(*aux_stat & DPAUX_DP_AUXSTAT_HPD_STATUS_PLUGGED)) {
 216                debug("dp: HPD is not detected\n");
 217                return -EIO;
 218        }
 219
 220        tegra_dpaux_writel(dp, DPAUX_DP_AUXADDR, addr);
 221
 222        reg_val = tegra_dpaux_readl(dp, DPAUX_DP_AUXCTL);
 223        reg_val &= ~DPAUX_DP_AUXCTL_CMD_MASK;
 224        reg_val |= cmd;
 225        reg_val &= ~DPAUX_DP_AUXCTL_CMDLEN_FIELD;
 226        reg_val |= ((*size - 1) << DPAUX_DP_AUXCTL_CMDLEN_SHIFT);
 227        while ((timeout_retries > 0) && (defer_retries > 0)) {
 228                if ((timeout_retries != DP_AUX_TIMEOUT_MAX_TRIES) ||
 229                    (defer_retries != DP_AUX_DEFER_MAX_TRIES))
 230                        udelay(DP_DPCP_RETRY_SLEEP_NS * 2);
 231
 232                reg_val |= DPAUX_DP_AUXCTL_TRANSACTREQ_PENDING;
 233                tegra_dpaux_writel(dp, DPAUX_DP_AUXCTL, reg_val);
 234
 235                if (tegra_dpaux_wait_transaction(dp))
 236                        debug("dp: aux read transaction timeout\n");
 237
 238                *aux_stat = tegra_dpaux_readl(dp, DPAUX_DP_AUXSTAT);
 239
 240                if ((*aux_stat & DPAUX_DP_AUXSTAT_TIMEOUT_ERROR_PENDING) ||
 241                    (*aux_stat & DPAUX_DP_AUXSTAT_RX_ERROR_PENDING) ||
 242                    (*aux_stat & DPAUX_DP_AUXSTAT_SINKSTAT_ERROR_PENDING) ||
 243                    (*aux_stat & DPAUX_DP_AUXSTAT_NO_STOP_ERROR_PENDING)) {
 244                        if (timeout_retries-- > 0) {
 245                                debug("dp: aux read retry (0x%x) -- %d\n",
 246                                      *aux_stat, timeout_retries);
 247                                /* clear the error bits */
 248                                tegra_dpaux_writel(dp, DPAUX_DP_AUXSTAT,
 249                                                   *aux_stat);
 250                                continue;       /* retry */
 251                        } else {
 252                                debug("dp: aux read got error (0x%x)\n",
 253                                      *aux_stat);
 254                                return -ETIMEDOUT;
 255                        }
 256                }
 257
 258                if ((*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_I2CDEFER) ||
 259                    (*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_DEFER)) {
 260                        if (defer_retries-- > 0) {
 261                                debug("dp: aux read defer (0x%x) -- %d\n",
 262                                      *aux_stat, defer_retries);
 263                                /* clear the error bits */
 264                                tegra_dpaux_writel(dp, DPAUX_DP_AUXSTAT,
 265                                                   *aux_stat);
 266                                continue;
 267                        } else {
 268                                debug("dp: aux read defer exceeds max retries (0x%x)\n",
 269                                      *aux_stat);
 270                                return -ETIMEDOUT;
 271                        }
 272                }
 273
 274                if ((*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_MASK) ==
 275                        DPAUX_DP_AUXSTAT_REPLYTYPE_ACK) {
 276                        int i;
 277                        u32 temp_data[4];
 278
 279                        for (i = 0; i < DP_AUX_MAX_BYTES / 4; ++i)
 280                                temp_data[i] = tegra_dpaux_readl(dp,
 281                                                DPAUX_DP_AUXDATA_READ_W(i));
 282
 283                        *size = ((*aux_stat) & DPAUX_DP_AUXSTAT_REPLY_M_MASK);
 284                        memcpy(data, temp_data, *size);
 285
 286                        return 0;
 287                } else {
 288                        debug("dp: aux read failed (0x%x\n", *aux_stat);
 289                        return -EIO;
 290                }
 291        }
 292        /* Should never come to here */
 293        debug("%s: can't\n", __func__);
 294
 295        return -EIO;
 296}
 297
 298static int tegra_dc_dpaux_read(struct tegra_dp_priv *dp, u32 cmd, u32 addr,
 299                        u8 *data, u32 *size, u32 *aux_stat)
 300{
 301        u32 finished = 0;
 302        u32 cur_size;
 303        int ret = 0;
 304
 305        do {
 306                cur_size = *size - finished;
 307                if (cur_size > DP_AUX_MAX_BYTES)
 308                        cur_size = DP_AUX_MAX_BYTES;
 309
 310                ret = tegra_dc_dpaux_read_chunk(dp, cmd, addr,
 311                                                data, &cur_size, aux_stat);
 312                if (ret)
 313                        break;
 314
 315                /* cur_size should be the real size returned */
 316                addr += cur_size;
 317                data += cur_size;
 318                finished += cur_size;
 319
 320        } while (*size > finished);
 321        *size = finished;
 322
 323        return ret;
 324}
 325
 326static int tegra_dc_dp_dpcd_read(struct tegra_dp_priv *dp, u32 cmd,
 327                                 u8 *data_ptr)
 328{
 329        u32 size = 1;
 330        u32 status = 0;
 331        int ret;
 332
 333        ret = tegra_dc_dpaux_read_chunk(dp, DPAUX_DP_AUXCTL_CMD_AUXRD,
 334                                        cmd, data_ptr, &size, &status);
 335        if (ret) {
 336                debug("dp: Failed to read DPCD data. CMD 0x%x, Status 0x%x\n",
 337                      cmd, status);
 338        }
 339
 340        return ret;
 341}
 342
 343static int tegra_dc_dp_dpcd_write(struct tegra_dp_priv *dp, u32 cmd,
 344                                u8 data)
 345{
 346        u32 size = 1;
 347        u32 status = 0;
 348        int ret;
 349
 350        ret = tegra_dc_dpaux_write_chunk(dp, DPAUX_DP_AUXCTL_CMD_AUXWR,
 351                                        cmd, &data, &size, &status);
 352        if (ret) {
 353                debug("dp: Failed to write DPCD data. CMD 0x%x, Status 0x%x\n",
 354                      cmd, status);
 355        }
 356
 357        return ret;
 358}
 359
 360static int tegra_dc_i2c_aux_read(struct tegra_dp_priv *dp, u32 i2c_addr,
 361                                 u8 addr, u8 *data, u32 size, u32 *aux_stat)
 362{
 363        u32 finished = 0;
 364        int ret = 0;
 365
 366        do {
 367                u32 cur_size = min((u32)DP_AUX_MAX_BYTES, size - finished);
 368
 369                u32 len = 1;
 370                ret = tegra_dc_dpaux_write_chunk(
 371                                dp, DPAUX_DP_AUXCTL_CMD_MOTWR, i2c_addr,
 372                                &addr, &len, aux_stat);
 373                if (ret) {
 374                        debug("%s: error sending address to read.\n",
 375                              __func__);
 376                        return ret;
 377                }
 378
 379                ret = tegra_dc_dpaux_read_chunk(
 380                                dp, DPAUX_DP_AUXCTL_CMD_I2CRD, i2c_addr,
 381                                data, &cur_size, aux_stat);
 382                if (ret) {
 383                        debug("%s: error reading data.\n", __func__);
 384                        return ret;
 385                }
 386
 387                /* cur_size should be the real size returned */
 388                addr += cur_size;
 389                data += cur_size;
 390                finished += cur_size;
 391        } while (size > finished);
 392
 393        return finished;
 394}
 395
 396static void tegra_dc_dpaux_enable(struct tegra_dp_priv *dp)
 397{
 398        /* clear interrupt */
 399        tegra_dpaux_writel(dp, DPAUX_INTR_AUX, 0xffffffff);
 400        /* do not enable interrupt for now. Enable them when Isr in place */
 401        tegra_dpaux_writel(dp, DPAUX_INTR_EN_AUX, 0x0);
 402
 403        tegra_dpaux_writel(dp, DPAUX_HYBRID_PADCTL,
 404                           DPAUX_HYBRID_PADCTL_AUX_DRVZ_OHM_50 |
 405                           DPAUX_HYBRID_PADCTL_AUX_CMH_V0_70 |
 406                           0x18 << DPAUX_HYBRID_PADCTL_AUX_DRVI_SHIFT |
 407                           DPAUX_HYBRID_PADCTL_AUX_INPUT_RCV_ENABLE);
 408
 409        tegra_dpaux_writel(dp, DPAUX_HYBRID_SPARE,
 410                           DPAUX_HYBRID_SPARE_PAD_PWR_POWERUP);
 411}
 412
 413#ifdef DEBUG
 414static void tegra_dc_dp_dump_link_cfg(struct tegra_dp_priv *dp,
 415        const struct tegra_dp_link_config *link_cfg)
 416{
 417        debug("DP config: cfg_name               cfg_value\n");
 418        debug("           Lane Count             %d\n",
 419              link_cfg->max_lane_count);
 420        debug("           SupportEnhancedFraming %s\n",
 421              link_cfg->support_enhanced_framing ? "Y" : "N");
 422        debug("           Bandwidth              %d\n",
 423              link_cfg->max_link_bw);
 424        debug("           bpp                    %d\n",
 425              link_cfg->bits_per_pixel);
 426        debug("           EnhancedFraming        %s\n",
 427              link_cfg->enhanced_framing ? "Y" : "N");
 428        debug("           Scramble_enabled       %s\n",
 429              link_cfg->scramble_ena ? "Y" : "N");
 430        debug("           LinkBW                 %d\n",
 431              link_cfg->link_bw);
 432        debug("           lane_count             %d\n",
 433              link_cfg->lane_count);
 434        debug("           activespolarity        %d\n",
 435              link_cfg->activepolarity);
 436        debug("           active_count           %d\n",
 437              link_cfg->active_count);
 438        debug("           tu_size                %d\n",
 439              link_cfg->tu_size);
 440        debug("           active_frac            %d\n",
 441              link_cfg->active_frac);
 442        debug("           watermark              %d\n",
 443              link_cfg->watermark);
 444        debug("           hblank_sym             %d\n",
 445              link_cfg->hblank_sym);
 446        debug("           vblank_sym             %d\n",
 447              link_cfg->vblank_sym);
 448}
 449#endif
 450
 451static int _tegra_dp_lower_link_config(struct tegra_dp_priv *dp,
 452                                       struct tegra_dp_link_config *cfg)
 453{
 454        switch (cfg->link_bw) {
 455        case SOR_LINK_SPEED_G1_62:
 456                if (cfg->max_link_bw > SOR_LINK_SPEED_G1_62)
 457                        cfg->link_bw = SOR_LINK_SPEED_G2_7;
 458                cfg->lane_count /= 2;
 459                break;
 460        case SOR_LINK_SPEED_G2_7:
 461                cfg->link_bw = SOR_LINK_SPEED_G1_62;
 462                break;
 463        case SOR_LINK_SPEED_G5_4:
 464                if (cfg->lane_count == 1) {
 465                        cfg->link_bw = SOR_LINK_SPEED_G2_7;
 466                        cfg->lane_count = cfg->max_lane_count;
 467                } else {
 468                        cfg->lane_count /= 2;
 469                }
 470                break;
 471        default:
 472                debug("dp: Error link rate %d\n", cfg->link_bw);
 473                return -ENOLINK;
 474        }
 475
 476        return (cfg->lane_count > 0) ? 0 : -ENOLINK;
 477}
 478
 479/*
 480 * Calcuate if given cfg can meet the mode request.
 481 * Return 0 if mode is possible, -1 otherwise
 482 */
 483static int tegra_dc_dp_calc_config(struct tegra_dp_priv *dp,
 484                                   const struct display_timing *timing,
 485                                   struct tegra_dp_link_config *link_cfg)
 486{
 487        const u32       link_rate = 27 * link_cfg->link_bw * 1000 * 1000;
 488        const u64       f         = 100000;     /* precision factor */
 489        u32     num_linkclk_line; /* Number of link clocks per line */
 490        u64     ratio_f; /* Ratio of incoming to outgoing data rate */
 491        u64     frac_f;
 492        u64     activesym_f;    /* Activesym per TU */
 493        u64     activecount_f;
 494        u32     activecount;
 495        u32     activepolarity;
 496        u64     approx_value_f;
 497        u32     activefrac                = 0;
 498        u64     accumulated_error_f       = 0;
 499        u32     lowest_neg_activecount    = 0;
 500        u32     lowest_neg_activepolarity = 0;
 501        u32     lowest_neg_tusize         = 64;
 502        u32     num_symbols_per_line;
 503        u64     lowest_neg_activefrac     = 0;
 504        u64     lowest_neg_error_f        = 64 * f;
 505        u64     watermark_f;
 506        int     i;
 507        int     neg;
 508
 509        if (!link_rate || !link_cfg->lane_count || !timing->pixelclock.typ ||
 510            !link_cfg->bits_per_pixel)
 511                return -1;
 512
 513        if ((u64)timing->pixelclock.typ * link_cfg->bits_per_pixel >=
 514                (u64)link_rate * 8 * link_cfg->lane_count)
 515                return -1;
 516
 517        num_linkclk_line = (u32)(lldiv(link_rate * timing->hactive.typ,
 518                                       timing->pixelclock.typ));
 519
 520        ratio_f = (u64)timing->pixelclock.typ * link_cfg->bits_per_pixel * f;
 521        ratio_f /= 8;
 522        do_div(ratio_f, link_rate * link_cfg->lane_count);
 523
 524        for (i = 64; i >= 32; --i) {
 525                activesym_f     = ratio_f * i;
 526                activecount_f   = lldiv(activesym_f, (u32)f) * f;
 527                frac_f          = activesym_f - activecount_f;
 528                activecount     = (u32)(lldiv(activecount_f, (u32)f));
 529
 530                if (frac_f < (lldiv(f, 2))) /* fraction < 0.5 */
 531                        activepolarity = 0;
 532                else {
 533                        activepolarity = 1;
 534                        frac_f = f - frac_f;
 535                }
 536
 537                if (frac_f != 0) {
 538                        /* warning: frac_f should be 64-bit */
 539                        frac_f = lldiv(f * f, frac_f); /* 1 / fraction */
 540                        if (frac_f > (15 * f))
 541                                activefrac = activepolarity ? 1 : 15;
 542                        else
 543                                activefrac = activepolarity ?
 544                                        (u32)lldiv(frac_f, (u32)f) + 1 :
 545                                        (u32)lldiv(frac_f, (u32)f);
 546                }
 547
 548                if (activefrac == 1)
 549                        activepolarity = 0;
 550
 551                if (activepolarity == 1)
 552                        approx_value_f = activefrac ? lldiv(
 553                                (activecount_f + (activefrac * f - f) * f),
 554                                (activefrac * f)) :
 555                                activecount_f + f;
 556                else
 557                        approx_value_f = activefrac ?
 558                                activecount_f + lldiv(f, activefrac) :
 559                                activecount_f;
 560
 561                if (activesym_f < approx_value_f) {
 562                        accumulated_error_f = num_linkclk_line *
 563                                lldiv(approx_value_f - activesym_f, i);
 564                        neg = 1;
 565                } else {
 566                        accumulated_error_f = num_linkclk_line *
 567                                lldiv(activesym_f - approx_value_f, i);
 568                        neg = 0;
 569                }
 570
 571                if ((neg && (lowest_neg_error_f > accumulated_error_f)) ||
 572                    (accumulated_error_f == 0)) {
 573                        lowest_neg_error_f = accumulated_error_f;
 574                        lowest_neg_tusize = i;
 575                        lowest_neg_activecount = activecount;
 576                        lowest_neg_activepolarity = activepolarity;
 577                        lowest_neg_activefrac = activefrac;
 578
 579                        if (accumulated_error_f == 0)
 580                                break;
 581                }
 582        }
 583
 584        if (lowest_neg_activefrac == 0) {
 585                link_cfg->activepolarity = 0;
 586                link_cfg->active_count   = lowest_neg_activepolarity ?
 587                        lowest_neg_activecount : lowest_neg_activecount - 1;
 588                link_cfg->tu_size             = lowest_neg_tusize;
 589                link_cfg->active_frac    = 1;
 590        } else {
 591                link_cfg->activepolarity = lowest_neg_activepolarity;
 592                link_cfg->active_count   = (u32)lowest_neg_activecount;
 593                link_cfg->tu_size             = lowest_neg_tusize;
 594                link_cfg->active_frac    = (u32)lowest_neg_activefrac;
 595        }
 596
 597        watermark_f = lldiv(ratio_f * link_cfg->tu_size * (f - ratio_f), f);
 598        link_cfg->watermark = (u32)(lldiv(watermark_f + lowest_neg_error_f,
 599                f)) + link_cfg->bits_per_pixel / 4 - 1;
 600        num_symbols_per_line = (timing->hactive.typ *
 601                                link_cfg->bits_per_pixel) /
 602                               (8 * link_cfg->lane_count);
 603
 604        if (link_cfg->watermark > 30) {
 605                debug("dp: sor setting: unable to get a good tusize, force watermark to 30\n");
 606                link_cfg->watermark = 30;
 607                return -1;
 608        } else if (link_cfg->watermark > num_symbols_per_line) {
 609                debug("dp: sor setting: force watermark to the number of symbols in the line\n");
 610                link_cfg->watermark = num_symbols_per_line;
 611                return -1;
 612        }
 613
 614        /*
 615         * Refer to dev_disp.ref for more information.
 616         * # symbols/hblank = ((SetRasterBlankEnd.X + SetRasterSize.Width -
 617         *                      SetRasterBlankStart.X - 7) * link_clk / pclk)
 618         *                      - 3 * enhanced_framing - Y
 619         * where Y = (# lanes == 4) 3 : (# lanes == 2) ? 6 : 12
 620         */
 621        link_cfg->hblank_sym = (int)lldiv(((uint64_t)timing->hback_porch.typ +
 622                        timing->hfront_porch.typ + timing->hsync_len.typ - 7) *
 623                        link_rate, timing->pixelclock.typ) -
 624                        3 * link_cfg->enhanced_framing -
 625                        (12 / link_cfg->lane_count);
 626
 627        if (link_cfg->hblank_sym < 0)
 628                link_cfg->hblank_sym = 0;
 629
 630
 631        /*
 632         * Refer to dev_disp.ref for more information.
 633         * # symbols/vblank = ((SetRasterBlankStart.X -
 634         *                      SetRasterBlankEen.X - 25) * link_clk / pclk)
 635         *                      - Y - 1;
 636         * where Y = (# lanes == 4) 12 : (# lanes == 2) ? 21 : 39
 637         */
 638        link_cfg->vblank_sym = (int)lldiv(((uint64_t)timing->hactive.typ - 25)
 639                        * link_rate, timing->pixelclock.typ) - (36 /
 640                        link_cfg->lane_count) - 4;
 641
 642        if (link_cfg->vblank_sym < 0)
 643                link_cfg->vblank_sym = 0;
 644
 645        link_cfg->is_valid = 1;
 646#ifdef DEBUG
 647        tegra_dc_dp_dump_link_cfg(dp, link_cfg);
 648#endif
 649
 650        return 0;
 651}
 652
 653static int tegra_dc_dp_init_max_link_cfg(
 654                        const struct display_timing *timing,
 655                        struct tegra_dp_priv *dp,
 656                        struct tegra_dp_link_config *link_cfg)
 657{
 658        const int drive_current = 0x40404040;
 659        const int preemphasis = 0x0f0f0f0f;
 660        const int postcursor = 0;
 661        u8 dpcd_data;
 662        int ret;
 663
 664        ret = tegra_dc_dp_dpcd_read(dp, DP_MAX_LANE_COUNT, &dpcd_data);
 665        if (ret)
 666                return ret;
 667        link_cfg->max_lane_count = dpcd_data & DP_MAX_LANE_COUNT_MASK;
 668        link_cfg->tps3_supported = (dpcd_data &
 669                        DP_MAX_LANE_COUNT_TPS3_SUPPORTED_YES) ? 1 : 0;
 670
 671        link_cfg->support_enhanced_framing =
 672                (dpcd_data & DP_MAX_LANE_COUNT_ENHANCED_FRAMING_YES) ?
 673                1 : 0;
 674
 675        ret = tegra_dc_dp_dpcd_read(dp, DP_MAX_DOWNSPREAD, &dpcd_data);
 676        if (ret)
 677                return ret;
 678        link_cfg->downspread = (dpcd_data & DP_MAX_DOWNSPREAD_VAL_0_5_PCT) ?
 679                                1 : 0;
 680
 681        ret = tegra_dc_dp_dpcd_read(dp, NV_DPCD_TRAINING_AUX_RD_INTERVAL,
 682                                    &link_cfg->aux_rd_interval);
 683        if (ret)
 684                return ret;
 685        ret = tegra_dc_dp_dpcd_read(dp, DP_MAX_LINK_RATE,
 686                                    &link_cfg->max_link_bw);
 687        if (ret)
 688                return ret;
 689
 690        /*
 691         * Set to a high value for link training and attach.
 692         * Will be re-programmed when dp is enabled.
 693         */
 694        link_cfg->drive_current = drive_current;
 695        link_cfg->preemphasis = preemphasis;
 696        link_cfg->postcursor = postcursor;
 697
 698        ret = tegra_dc_dp_dpcd_read(dp, DP_EDP_CONFIGURATION_CAP, &dpcd_data);
 699        if (ret)
 700                return ret;
 701
 702        link_cfg->alt_scramber_reset_cap =
 703                (dpcd_data & DP_EDP_CONFIGURATION_CAP_ASC_RESET_YES) ?
 704                1 : 0;
 705        link_cfg->only_enhanced_framing =
 706                (dpcd_data & DP_EDP_CONFIGURATION_CAP_FRAMING_CHANGE_YES) ?
 707                1 : 0;
 708
 709        link_cfg->lane_count = link_cfg->max_lane_count;
 710        link_cfg->link_bw = link_cfg->max_link_bw;
 711        link_cfg->enhanced_framing = link_cfg->support_enhanced_framing;
 712        link_cfg->frame_in_ms = (1000 / 60) + 1;
 713
 714        tegra_dc_dp_calc_config(dp, timing, link_cfg);
 715        return 0;
 716}
 717
 718static int tegra_dc_dp_set_assr(struct tegra_dp_priv *priv,
 719                                struct udevice *sor, int ena)
 720{
 721        int ret;
 722
 723        u8 dpcd_data = ena ?
 724                DP_MAIN_LINK_CHANNEL_CODING_SET_ASC_RESET_ENABLE :
 725                DP_MAIN_LINK_CHANNEL_CODING_SET_ASC_RESET_DISABLE;
 726
 727        ret = tegra_dc_dp_dpcd_write(priv, DP_EDP_CONFIGURATION_SET,
 728                                     dpcd_data);
 729        if (ret)
 730                return ret;
 731
 732        /* Also reset the scrambler to 0xfffe */
 733        tegra_dc_sor_set_internal_panel(sor, ena);
 734        return 0;
 735}
 736
 737static int tegra_dp_set_link_bandwidth(struct tegra_dp_priv *dp,
 738                                       struct udevice *sor,
 739                                       u8 link_bw)
 740{
 741        tegra_dc_sor_set_link_bandwidth(sor, link_bw);
 742
 743        /* Sink side */
 744        return tegra_dc_dp_dpcd_write(dp, DP_LINK_BW_SET, link_bw);
 745}
 746
 747static int tegra_dp_set_lane_count(struct tegra_dp_priv *dp,
 748                const struct tegra_dp_link_config *link_cfg,
 749                struct udevice *sor)
 750{
 751        u8      dpcd_data;
 752        int     ret;
 753
 754        /* check if panel support enhanched_framing */
 755        dpcd_data = link_cfg->lane_count;
 756        if (link_cfg->enhanced_framing)
 757                dpcd_data |= DP_LANE_COUNT_SET_ENHANCEDFRAMING_T;
 758        ret = tegra_dc_dp_dpcd_write(dp, DP_LANE_COUNT_SET, dpcd_data);
 759        if (ret)
 760                return ret;
 761
 762        tegra_dc_sor_set_lane_count(sor, link_cfg->lane_count);
 763
 764        /* Also power down lanes that will not be used */
 765        return 0;
 766}
 767
 768static int tegra_dc_dp_link_trained(struct tegra_dp_priv *dp,
 769                                    const struct tegra_dp_link_config *cfg)
 770{
 771        u32 lane;
 772        u8 mask;
 773        u8 data;
 774        int ret;
 775
 776        for (lane = 0; lane < cfg->lane_count; ++lane) {
 777                ret = tegra_dc_dp_dpcd_read(dp, (lane / 2) ?
 778                                DP_LANE2_3_STATUS : DP_LANE0_1_STATUS,
 779                                &data);
 780                if (ret)
 781                        return ret;
 782                mask = (lane & 1) ?
 783                        NV_DPCD_STATUS_LANEXPLUS1_CR_DONE_YES |
 784                        NV_DPCD_STATUS_LANEXPLUS1_CHN_EQ_DONE_YES |
 785                        NV_DPCD_STATUS_LANEXPLUS1_SYMBOL_LOCKED_YES :
 786                        DP_LANE_CR_DONE |
 787                        DP_LANE_CHANNEL_EQ_DONE |
 788                        DP_LANE_SYMBOL_LOCKED;
 789                if ((data & mask) != mask)
 790                        return -1;
 791        }
 792        return 0;
 793}
 794
 795static int tegra_dp_channel_eq_status(struct tegra_dp_priv *dp,
 796                                      const struct tegra_dp_link_config *cfg)
 797{
 798        u32 cnt;
 799        u32 n_lanes = cfg->lane_count;
 800        u8 data;
 801        u8 ce_done = 1;
 802        int ret;
 803
 804        for (cnt = 0; cnt < n_lanes / 2; cnt++) {
 805                ret = tegra_dc_dp_dpcd_read(dp, DP_LANE0_1_STATUS + cnt, &data);
 806                if (ret)
 807                        return ret;
 808
 809                if (n_lanes == 1) {
 810                        ce_done = (data & (0x1 <<
 811                        NV_DPCD_STATUS_LANEX_CHN_EQ_DONE_SHIFT)) &&
 812                        (data & (0x1 <<
 813                        NV_DPCD_STATUS_LANEX_SYMBOL_LOCKED_SHFIT));
 814                        break;
 815                } else if (!(data & (0x1 <<
 816                                NV_DPCD_STATUS_LANEX_CHN_EQ_DONE_SHIFT)) ||
 817                           !(data & (0x1 <<
 818                                NV_DPCD_STATUS_LANEX_SYMBOL_LOCKED_SHFIT)) ||
 819                           !(data & (0x1 <<
 820                                NV_DPCD_STATUS_LANEXPLUS1_CHN_EQ_DONE_SHIFT)) ||
 821                           !(data & (0x1 <<
 822                                NV_DPCD_STATUS_LANEXPLUS1_SYMBOL_LOCKED_SHIFT)))
 823                        return -EIO;
 824        }
 825
 826        if (ce_done) {
 827                ret = tegra_dc_dp_dpcd_read(dp,
 828                                            DP_LANE_ALIGN_STATUS_UPDATED,
 829                                            &data);
 830                if (ret)
 831                        return ret;
 832                if (!(data & NV_DPCD_LANE_ALIGN_STATUS_UPDATED_DONE_YES))
 833                        ce_done = 0;
 834        }
 835
 836        return ce_done ? 0 : -EIO;
 837}
 838
 839static int tegra_dp_clock_recovery_status(struct tegra_dp_priv *dp,
 840                                         const struct tegra_dp_link_config *cfg)
 841{
 842        u32 cnt;
 843        u32 n_lanes = cfg->lane_count;
 844        u8 data_ptr;
 845        int ret;
 846
 847        for (cnt = 0; cnt < n_lanes / 2; cnt++) {
 848                ret = tegra_dc_dp_dpcd_read(dp, (DP_LANE0_1_STATUS + cnt),
 849                                            &data_ptr);
 850                if (ret)
 851                        return ret;
 852
 853                if (n_lanes == 1)
 854                        return (data_ptr & NV_DPCD_STATUS_LANEX_CR_DONE_YES) ?
 855                                1 : 0;
 856                else if (!(data_ptr & NV_DPCD_STATUS_LANEX_CR_DONE_YES) ||
 857                         !(data_ptr & (NV_DPCD_STATUS_LANEXPLUS1_CR_DONE_YES)))
 858                        return 0;
 859        }
 860
 861        return 1;
 862}
 863
 864static int tegra_dp_lt_adjust(struct tegra_dp_priv *dp, u32 pe[4], u32 vs[4],
 865                              u32 pc[4], u8 pc_supported,
 866                              const struct tegra_dp_link_config *cfg)
 867{
 868        size_t cnt;
 869        u8 data_ptr;
 870        u32 n_lanes = cfg->lane_count;
 871        int ret;
 872
 873        for (cnt = 0; cnt < n_lanes / 2; cnt++) {
 874                ret = tegra_dc_dp_dpcd_read(dp, DP_ADJUST_REQUEST_LANE0_1 + cnt,
 875                                            &data_ptr);
 876                if (ret)
 877                        return ret;
 878                pe[2 * cnt] = (data_ptr & NV_DPCD_ADJUST_REQ_LANEX_PE_MASK) >>
 879                                        NV_DPCD_ADJUST_REQ_LANEX_PE_SHIFT;
 880                vs[2 * cnt] = (data_ptr & NV_DPCD_ADJUST_REQ_LANEX_DC_MASK) >>
 881                                        NV_DPCD_ADJUST_REQ_LANEX_DC_SHIFT;
 882                pe[1 + 2 * cnt] =
 883                        (data_ptr & NV_DPCD_ADJUST_REQ_LANEXPLUS1_PE_MASK) >>
 884                                        NV_DPCD_ADJUST_REQ_LANEXPLUS1_PE_SHIFT;
 885                vs[1 + 2 * cnt] =
 886                        (data_ptr & NV_DPCD_ADJUST_REQ_LANEXPLUS1_DC_MASK) >>
 887                                        NV_DPCD_ADJUST_REQ_LANEXPLUS1_DC_SHIFT;
 888        }
 889        if (pc_supported) {
 890                ret = tegra_dc_dp_dpcd_read(dp, NV_DPCD_ADJUST_REQ_POST_CURSOR2,
 891                                            &data_ptr);
 892                if (ret)
 893                        return ret;
 894                for (cnt = 0; cnt < n_lanes; cnt++) {
 895                        pc[cnt] = (data_ptr >>
 896                        NV_DPCD_ADJUST_REQ_POST_CURSOR2_LANE_SHIFT(cnt)) &
 897                        NV_DPCD_ADJUST_REQ_POST_CURSOR2_LANE_MASK;
 898                }
 899        }
 900
 901        return 0;
 902}
 903
 904static void tegra_dp_wait_aux_training(struct tegra_dp_priv *dp,
 905                                        bool is_clk_recovery,
 906                                        const struct tegra_dp_link_config *cfg)
 907{
 908        if (!cfg->aux_rd_interval)
 909                udelay(is_clk_recovery ? 200 : 500);
 910        else
 911                mdelay(cfg->aux_rd_interval * 4);
 912}
 913
 914static void tegra_dp_tpg(struct tegra_dp_priv *dp, u32 tp, u32 n_lanes,
 915                         const struct tegra_dp_link_config *cfg)
 916{
 917        u8 data = (tp == training_pattern_disabled)
 918                ? (tp | NV_DPCD_TRAINING_PATTERN_SET_SC_DISABLED_F)
 919                : (tp | NV_DPCD_TRAINING_PATTERN_SET_SC_DISABLED_T);
 920
 921        tegra_dc_sor_set_dp_linkctl(dp->sor, 1, tp, cfg);
 922        tegra_dc_dp_dpcd_write(dp, DP_TRAINING_PATTERN_SET, data);
 923}
 924
 925static int tegra_dp_link_config(struct tegra_dp_priv *dp,
 926                                const struct tegra_dp_link_config *link_cfg)
 927{
 928        u8 dpcd_data;
 929        u32 retry;
 930        int ret;
 931
 932        if (link_cfg->lane_count == 0) {
 933                debug("dp: error: lane count is 0. Can not set link config.\n");
 934                return -ENOLINK;
 935        }
 936
 937        /* Set power state if it is not in normal level */
 938        ret = tegra_dc_dp_dpcd_read(dp, DP_SET_POWER, &dpcd_data);
 939        if (ret)
 940                return ret;
 941
 942        if (dpcd_data == DP_SET_POWER_D3) {
 943                dpcd_data = DP_SET_POWER_D0;
 944
 945                /* DP spec requires 3 retries */
 946                for (retry = 3; retry > 0; --retry) {
 947                        ret = tegra_dc_dp_dpcd_write(dp, DP_SET_POWER,
 948                                                     dpcd_data);
 949                        if (!ret)
 950                                break;
 951                        if (retry == 1) {
 952                                debug("dp: Failed to set DP panel power\n");
 953                                return ret;
 954                        }
 955                }
 956        }
 957
 958        /* Enable ASSR if possible */
 959        if (link_cfg->alt_scramber_reset_cap) {
 960                ret = tegra_dc_dp_set_assr(dp, dp->sor, 1);
 961                if (ret)
 962                        return ret;
 963        }
 964
 965        ret = tegra_dp_set_link_bandwidth(dp, dp->sor, link_cfg->link_bw);
 966        if (ret) {
 967                debug("dp: Failed to set link bandwidth\n");
 968                return ret;
 969        }
 970        ret = tegra_dp_set_lane_count(dp, link_cfg, dp->sor);
 971        if (ret) {
 972                debug("dp: Failed to set lane count\n");
 973                return ret;
 974        }
 975        tegra_dc_sor_set_dp_linkctl(dp->sor, 1, training_pattern_none,
 976                                    link_cfg);
 977
 978        return 0;
 979}
 980
 981static int tegra_dp_lower_link_config(struct tegra_dp_priv *dp,
 982                                      const struct display_timing *timing,
 983                                      struct tegra_dp_link_config *cfg)
 984{
 985        struct tegra_dp_link_config tmp_cfg;
 986        int ret;
 987
 988        tmp_cfg = *cfg;
 989        cfg->is_valid = 0;
 990
 991        ret = _tegra_dp_lower_link_config(dp, cfg);
 992        if (!ret)
 993                ret = tegra_dc_dp_calc_config(dp, timing, cfg);
 994        if (!ret)
 995                ret = tegra_dp_link_config(dp, cfg);
 996        if (ret)
 997                goto fail;
 998
 999        return 0;
1000
1001fail:
1002        *cfg = tmp_cfg;
1003        tegra_dp_link_config(dp, &tmp_cfg);
1004        return ret;
1005}
1006
1007static int tegra_dp_lt_config(struct tegra_dp_priv *dp, u32 pe[4], u32 vs[4],
1008                              u32 pc[4], const struct tegra_dp_link_config *cfg)
1009{
1010        struct udevice *sor = dp->sor;
1011        u32 n_lanes = cfg->lane_count;
1012        u8 pc_supported = cfg->tps3_supported;
1013        u32 cnt;
1014        u32 val;
1015
1016        for (cnt = 0; cnt < n_lanes; cnt++) {
1017                u32 mask = 0;
1018                u32 pe_reg, vs_reg, pc_reg;
1019                u32 shift = 0;
1020
1021                switch (cnt) {
1022                case 0:
1023                        mask = PR_LANE2_DP_LANE0_MASK;
1024                        shift = PR_LANE2_DP_LANE0_SHIFT;
1025                        break;
1026                case 1:
1027                        mask = PR_LANE1_DP_LANE1_MASK;
1028                        shift = PR_LANE1_DP_LANE1_SHIFT;
1029                        break;
1030                case 2:
1031                        mask = PR_LANE0_DP_LANE2_MASK;
1032                        shift = PR_LANE0_DP_LANE2_SHIFT;
1033                        break;
1034                case 3:
1035                        mask = PR_LANE3_DP_LANE3_MASK;
1036                        shift = PR_LANE3_DP_LANE3_SHIFT;
1037                        break;
1038                default:
1039                        debug("dp: incorrect lane cnt\n");
1040                        return -EINVAL;
1041                }
1042
1043                pe_reg = tegra_dp_pe_regs[pc[cnt]][vs[cnt]][pe[cnt]];
1044                vs_reg = tegra_dp_vs_regs[pc[cnt]][vs[cnt]][pe[cnt]];
1045                pc_reg = tegra_dp_pc_regs[pc[cnt]][vs[cnt]][pe[cnt]];
1046
1047                tegra_dp_set_pe_vs_pc(sor, mask, pe_reg << shift,
1048                                      vs_reg << shift, pc_reg << shift,
1049                                      pc_supported);
1050        }
1051
1052        tegra_dp_disable_tx_pu(dp->sor);
1053        udelay(20);
1054
1055        for (cnt = 0; cnt < n_lanes; cnt++) {
1056                u32 max_vs_flag = tegra_dp_is_max_vs(pe[cnt], vs[cnt]);
1057                u32 max_pe_flag = tegra_dp_is_max_pe(pe[cnt], vs[cnt]);
1058
1059                val = (vs[cnt] << NV_DPCD_TRAINING_LANEX_SET_DC_SHIFT) |
1060                        (max_vs_flag ?
1061                        NV_DPCD_TRAINING_LANEX_SET_DC_MAX_REACHED_T :
1062                        NV_DPCD_TRAINING_LANEX_SET_DC_MAX_REACHED_F) |
1063                        (pe[cnt] << NV_DPCD_TRAINING_LANEX_SET_PE_SHIFT) |
1064                        (max_pe_flag ?
1065                        NV_DPCD_TRAINING_LANEX_SET_PE_MAX_REACHED_T :
1066                        NV_DPCD_TRAINING_LANEX_SET_PE_MAX_REACHED_F);
1067                tegra_dc_dp_dpcd_write(dp, (DP_TRAINING_LANE0_SET + cnt), val);
1068        }
1069
1070        if (pc_supported) {
1071                for (cnt = 0; cnt < n_lanes / 2; cnt++) {
1072                        u32 max_pc_flag0 = tegra_dp_is_max_pc(pc[cnt]);
1073                        u32 max_pc_flag1 = tegra_dp_is_max_pc(pc[cnt + 1]);
1074                        val = (pc[cnt] << NV_DPCD_LANEX_SET2_PC2_SHIFT) |
1075                                (max_pc_flag0 ?
1076                                NV_DPCD_LANEX_SET2_PC2_MAX_REACHED_T :
1077                                NV_DPCD_LANEX_SET2_PC2_MAX_REACHED_F) |
1078                                (pc[cnt + 1] <<
1079                                NV_DPCD_LANEXPLUS1_SET2_PC2_SHIFT) |
1080                                (max_pc_flag1 ?
1081                                NV_DPCD_LANEXPLUS1_SET2_PC2_MAX_REACHED_T :
1082                                NV_DPCD_LANEXPLUS1_SET2_PC2_MAX_REACHED_F);
1083                        tegra_dc_dp_dpcd_write(dp,
1084                                               NV_DPCD_TRAINING_LANE0_1_SET2 +
1085                                               cnt, val);
1086                }
1087        }
1088
1089        return 0;
1090}
1091
1092static int _tegra_dp_channel_eq(struct tegra_dp_priv *dp, u32 pe[4],
1093                                u32 vs[4], u32 pc[4], u8 pc_supported,
1094                                u32 n_lanes,
1095                                const struct tegra_dp_link_config *cfg)
1096{
1097        u32 retry_cnt;
1098
1099        for (retry_cnt = 0; retry_cnt < 4; retry_cnt++) {
1100                int ret;
1101
1102                if (retry_cnt) {
1103                        ret = tegra_dp_lt_adjust(dp, pe, vs, pc, pc_supported,
1104                                                 cfg);
1105                        if (ret)
1106                                return ret;
1107                        tegra_dp_lt_config(dp, pe, vs, pc, cfg);
1108                }
1109
1110                tegra_dp_wait_aux_training(dp, false, cfg);
1111
1112                if (!tegra_dp_clock_recovery_status(dp, cfg)) {
1113                        debug("dp: CR failed in channel EQ sequence!\n");
1114                        break;
1115                }
1116
1117                if (!tegra_dp_channel_eq_status(dp, cfg))
1118                        return 0;
1119        }
1120
1121        return -EIO;
1122}
1123
1124static int tegra_dp_channel_eq(struct tegra_dp_priv *dp, u32 pe[4], u32 vs[4],
1125                               u32 pc[4],
1126                               const struct tegra_dp_link_config *cfg)
1127{
1128        u32 n_lanes = cfg->lane_count;
1129        u8 pc_supported = cfg->tps3_supported;
1130        int ret;
1131        u32 tp_src = training_pattern_2;
1132
1133        if (pc_supported)
1134                tp_src = training_pattern_3;
1135
1136        tegra_dp_tpg(dp, tp_src, n_lanes, cfg);
1137
1138        ret = _tegra_dp_channel_eq(dp, pe, vs, pc, pc_supported, n_lanes, cfg);
1139
1140        tegra_dp_tpg(dp, training_pattern_disabled, n_lanes, cfg);
1141
1142        return ret;
1143}
1144
1145static int _tegra_dp_clk_recovery(struct tegra_dp_priv *dp, u32 pe[4],
1146                                  u32 vs[4], u32 pc[4], u8 pc_supported,
1147                                  u32 n_lanes,
1148                                  const struct tegra_dp_link_config *cfg)
1149{
1150        u32 vs_temp[4];
1151        u32 retry_cnt = 0;
1152
1153        do {
1154                tegra_dp_lt_config(dp, pe, vs, pc, cfg);
1155                tegra_dp_wait_aux_training(dp, true, cfg);
1156
1157                if (tegra_dp_clock_recovery_status(dp, cfg))
1158                        return 0;
1159
1160                memcpy(vs_temp, vs, sizeof(vs_temp));
1161                tegra_dp_lt_adjust(dp, pe, vs, pc, pc_supported, cfg);
1162
1163                if (memcmp(vs_temp, vs, sizeof(vs_temp)))
1164                        retry_cnt = 0;
1165                else
1166                        ++retry_cnt;
1167        } while (retry_cnt < 5);
1168
1169        return -EIO;
1170}
1171
1172static int tegra_dp_clk_recovery(struct tegra_dp_priv *dp, u32 pe[4],
1173                                 u32 vs[4], u32 pc[4],
1174                                 const struct tegra_dp_link_config *cfg)
1175{
1176        u32 n_lanes = cfg->lane_count;
1177        u8 pc_supported = cfg->tps3_supported;
1178        int err;
1179
1180        tegra_dp_tpg(dp, training_pattern_1, n_lanes, cfg);
1181
1182        err = _tegra_dp_clk_recovery(dp, pe, vs, pc, pc_supported, n_lanes,
1183                                     cfg);
1184        if (err < 0)
1185                tegra_dp_tpg(dp, training_pattern_disabled, n_lanes, cfg);
1186
1187        return err;
1188}
1189
1190static int tegra_dc_dp_full_link_training(struct tegra_dp_priv *dp,
1191                                          const struct display_timing *timing,
1192                                          struct tegra_dp_link_config *cfg)
1193{
1194        struct udevice *sor = dp->sor;
1195        int err;
1196        u32 pe[4], vs[4], pc[4];
1197
1198        tegra_sor_precharge_lanes(sor, cfg);
1199
1200retry_cr:
1201        memset(pe, PREEMPHASIS_DISABLED, sizeof(pe));
1202        memset(vs, DRIVECURRENT_LEVEL0, sizeof(vs));
1203        memset(pc, POSTCURSOR2_LEVEL0, sizeof(pc));
1204
1205        err = tegra_dp_clk_recovery(dp, pe, vs, pc, cfg);
1206        if (err) {
1207                if (!tegra_dp_lower_link_config(dp, timing, cfg))
1208                        goto retry_cr;
1209
1210                debug("dp: clk recovery failed\n");
1211                goto fail;
1212        }
1213
1214        err = tegra_dp_channel_eq(dp, pe, vs, pc, cfg);
1215        if (err) {
1216                if (!tegra_dp_lower_link_config(dp, timing, cfg))
1217                        goto retry_cr;
1218
1219                debug("dp: channel equalization failed\n");
1220                goto fail;
1221        }
1222#ifdef DEBUG
1223        tegra_dc_dp_dump_link_cfg(dp, cfg);
1224#endif
1225        return 0;
1226
1227fail:
1228        return err;
1229}
1230
1231/*
1232 * All link training functions are ported from kernel dc driver.
1233 * See more details at drivers/video/tegra/dc/dp.c
1234 */
1235static int tegra_dc_dp_fast_link_training(struct tegra_dp_priv *dp,
1236                const struct tegra_dp_link_config *link_cfg,
1237                struct udevice *sor)
1238{
1239        u8      link_bw;
1240        u8      lane_count;
1241        u16     data16;
1242        u32     data32;
1243        u32     size;
1244        u32     status;
1245        int     j;
1246        u32     mask = 0xffff >> ((4 - link_cfg->lane_count) * 4);
1247
1248        tegra_dc_sor_set_lane_parm(sor, link_cfg);
1249        tegra_dc_dp_dpcd_write(dp, DP_MAIN_LINK_CHANNEL_CODING_SET,
1250                               DP_SET_ANSI_8B10B);
1251
1252        /* Send TP1 */
1253        tegra_dc_sor_set_dp_linkctl(sor, 1, training_pattern_1, link_cfg);
1254        tegra_dc_dp_dpcd_write(dp, DP_TRAINING_PATTERN_SET,
1255                               DP_TRAINING_PATTERN_1);
1256
1257        for (j = 0; j < link_cfg->lane_count; ++j)
1258                tegra_dc_dp_dpcd_write(dp, DP_TRAINING_LANE0_SET + j, 0x24);
1259        udelay(520);
1260
1261        size = sizeof(data16);
1262        tegra_dc_dpaux_read(dp, DPAUX_DP_AUXCTL_CMD_AUXRD,
1263                            DP_LANE0_1_STATUS, (u8 *)&data16, &size, &status);
1264        status = mask & 0x1111;
1265        if ((data16 & status) != status) {
1266                debug("dp: Link training error for TP1 (%#x, status %#x)\n",
1267                      data16, status);
1268                return -EFAULT;
1269        }
1270
1271        /* enable ASSR */
1272        tegra_dc_dp_set_assr(dp, sor, link_cfg->scramble_ena);
1273        tegra_dc_sor_set_dp_linkctl(sor, 1, training_pattern_3, link_cfg);
1274
1275        tegra_dc_dp_dpcd_write(dp, DP_TRAINING_PATTERN_SET,
1276                               link_cfg->link_bw == 20 ? 0x23 : 0x22);
1277        for (j = 0; j < link_cfg->lane_count; ++j)
1278                tegra_dc_dp_dpcd_write(dp, DP_TRAINING_LANE0_SET + j, 0x24);
1279        udelay(520);
1280
1281        size = sizeof(data32);
1282        tegra_dc_dpaux_read(dp, DPAUX_DP_AUXCTL_CMD_AUXRD, DP_LANE0_1_STATUS,
1283                            (u8 *)&data32, &size, &status);
1284        if ((data32 & mask) != (0x7777 & mask)) {
1285                debug("dp: Link training error for TP2/3 (0x%x)\n", data32);
1286                return -EFAULT;
1287        }
1288
1289        tegra_dc_sor_set_dp_linkctl(sor, 1, training_pattern_disabled,
1290                                    link_cfg);
1291        tegra_dc_dp_dpcd_write(dp, DP_TRAINING_PATTERN_SET, 0);
1292
1293        if (tegra_dc_dp_link_trained(dp, link_cfg)) {
1294                tegra_dc_sor_read_link_config(sor, &link_bw, &lane_count);
1295                debug("Fast link training failed, link bw %d, lane # %d\n",
1296                      link_bw, lane_count);
1297                return -EFAULT;
1298        }
1299
1300        debug("Fast link training succeeded, link bw %d, lane %d\n",
1301              link_cfg->link_bw, link_cfg->lane_count);
1302
1303        return 0;
1304}
1305
1306static int tegra_dp_do_link_training(struct tegra_dp_priv *dp,
1307                struct tegra_dp_link_config *link_cfg,
1308                const struct display_timing *timing,
1309                struct udevice *sor)
1310{
1311        u8      link_bw;
1312        u8      lane_count;
1313        int     ret;
1314
1315        if (DO_FAST_LINK_TRAINING) {
1316                ret = tegra_dc_dp_fast_link_training(dp, link_cfg, sor);
1317                if (ret) {
1318                        debug("dp: fast link training failed\n");
1319                } else {
1320                        /*
1321                        * set to a known-good drive setting if fast link
1322                        * succeeded. Ignore any error.
1323                        */
1324                        ret = tegra_dc_sor_set_voltage_swing(dp->sor, link_cfg);
1325                        if (ret)
1326                                debug("Failed to set voltage swing\n");
1327                }
1328        } else {
1329                ret = -ENOSYS;
1330        }
1331        if (ret) {
1332                /* Try full link training then */
1333                ret = tegra_dc_dp_full_link_training(dp, timing, link_cfg);
1334                if (ret) {
1335                        debug("dp: full link training failed\n");
1336                        return ret;
1337                }
1338        }
1339
1340        /* Everything is good; double check the link config */
1341        tegra_dc_sor_read_link_config(sor, &link_bw, &lane_count);
1342
1343        if ((link_cfg->link_bw == link_bw) &&
1344            (link_cfg->lane_count == lane_count))
1345                return 0;
1346        else
1347                return -EFAULT;
1348}
1349
1350static int tegra_dc_dp_explore_link_cfg(struct tegra_dp_priv *dp,
1351                        struct tegra_dp_link_config *link_cfg,
1352                        struct udevice *sor,
1353                        const struct display_timing *timing)
1354{
1355        struct tegra_dp_link_config temp_cfg;
1356
1357        if (!timing->pixelclock.typ || !timing->hactive.typ ||
1358            !timing->vactive.typ) {
1359                debug("dp: error mode configuration");
1360                return -EINVAL;
1361        }
1362        if (!link_cfg->max_link_bw || !link_cfg->max_lane_count) {
1363                debug("dp: error link configuration");
1364                return -EINVAL;
1365        }
1366
1367        link_cfg->is_valid = 0;
1368
1369        memcpy(&temp_cfg, link_cfg, sizeof(temp_cfg));
1370
1371        temp_cfg.link_bw = temp_cfg.max_link_bw;
1372        temp_cfg.lane_count = temp_cfg.max_lane_count;
1373
1374        /*
1375         * set to max link config
1376         */
1377        if ((!tegra_dc_dp_calc_config(dp, timing, &temp_cfg)) &&
1378            (!tegra_dp_link_config(dp, &temp_cfg)) &&
1379                (!tegra_dp_do_link_training(dp, &temp_cfg, timing, sor)))
1380                /* the max link cfg is doable */
1381                memcpy(link_cfg, &temp_cfg, sizeof(temp_cfg));
1382
1383        return link_cfg->is_valid ? 0 : -EFAULT;
1384}
1385
1386static int tegra_dp_hpd_plug(struct tegra_dp_priv *dp)
1387{
1388        const int vdd_to_hpd_delay_ms = 200;
1389        u32 val;
1390        ulong start;
1391
1392        start = get_timer(0);
1393        do {
1394                val = tegra_dpaux_readl(dp, DPAUX_DP_AUXSTAT);
1395                if (val & DPAUX_DP_AUXSTAT_HPD_STATUS_PLUGGED)
1396                        return 0;
1397                udelay(100);
1398        } while (get_timer(start) < vdd_to_hpd_delay_ms);
1399
1400        return -EIO;
1401}
1402
1403static int tegra_dc_dp_sink_out_of_sync(struct tegra_dp_priv *dp, u32 delay_ms)
1404{
1405        u8 dpcd_data;
1406        int out_of_sync;
1407        int ret;
1408
1409        debug("%s: delay=%d\n", __func__, delay_ms);
1410        mdelay(delay_ms);
1411        ret = tegra_dc_dp_dpcd_read(dp, DP_SINK_STATUS, &dpcd_data);
1412        if (ret)
1413                return ret;
1414
1415        out_of_sync = !(dpcd_data & DP_SINK_STATUS_PORT0_IN_SYNC);
1416        if (out_of_sync)
1417                debug("SINK receive port 0 out of sync, data=%x\n", dpcd_data);
1418        else
1419                debug("SINK is in synchronization\n");
1420
1421        return out_of_sync;
1422}
1423
1424static int tegra_dc_dp_check_sink(struct tegra_dp_priv *dp,
1425                                  struct tegra_dp_link_config *link_cfg,
1426                                  const struct display_timing *timing)
1427{
1428        const int max_retry = 5;
1429        int delay_frame;
1430        int retries;
1431
1432        /*
1433         * DP TCON may skip some main stream frames, thus we need to wait
1434         * some delay before reading the DPCD SINK STATUS register, starting
1435         * from 5
1436         */
1437        delay_frame = 5;
1438
1439        retries = max_retry;
1440        do {
1441                int ret;
1442
1443                if (!tegra_dc_dp_sink_out_of_sync(dp, link_cfg->frame_in_ms *
1444                                                  delay_frame))
1445                        return 0;
1446
1447                debug("%s: retries left %d\n", __func__, retries);
1448                if (!retries--) {
1449                        printf("DP: Out of sync after %d retries\n", max_retry);
1450                        return -EIO;
1451                }
1452                ret = tegra_dc_sor_detach(dp->dc_dev, dp->sor);
1453                if (ret)
1454                        return ret;
1455                if (tegra_dc_dp_explore_link_cfg(dp, link_cfg, dp->sor,
1456                                                 timing)) {
1457                        debug("dp: %s: error to configure link\n", __func__);
1458                        continue;
1459                }
1460
1461                tegra_dc_sor_set_power_state(dp->sor, 1);
1462                tegra_dc_sor_attach(dp->dc_dev, dp->sor, link_cfg, timing);
1463
1464                /* Increase delay_frame for next try in case the sink is
1465                   skipping more frames */
1466                delay_frame += 10;
1467        } while (1);
1468}
1469
1470int tegra_dp_enable(struct udevice *dev, int panel_bpp,
1471                    const struct display_timing *timing)
1472{
1473        struct tegra_dp_priv *priv = dev_get_priv(dev);
1474        struct tegra_dp_link_config slink_cfg, *link_cfg = &slink_cfg;
1475        struct udevice *sor;
1476        int data;
1477        int retry;
1478        int ret;
1479
1480        memset(link_cfg, '\0', sizeof(*link_cfg));
1481        link_cfg->is_valid = 0;
1482        link_cfg->scramble_ena = 1;
1483
1484        tegra_dc_dpaux_enable(priv);
1485
1486        if (tegra_dp_hpd_plug(priv) < 0) {
1487                debug("dp: hpd plug failed\n");
1488                return -EIO;
1489        }
1490
1491        link_cfg->bits_per_pixel = panel_bpp;
1492        if (tegra_dc_dp_init_max_link_cfg(timing, priv, link_cfg)) {
1493                debug("dp: failed to init link configuration\n");
1494                return -ENOLINK;
1495        }
1496
1497        ret = uclass_first_device(UCLASS_VIDEO_BRIDGE, &sor);
1498        if (ret || !sor) {
1499                debug("dp: failed to find SOR device: ret=%d\n", ret);
1500                return ret;
1501        }
1502        priv->sor = sor;
1503        ret = tegra_dc_sor_enable_dp(sor, link_cfg);
1504        if (ret)
1505                return ret;
1506
1507        tegra_dc_sor_set_panel_power(sor, 1);
1508
1509        /* Write power on to DPCD */
1510        data = DP_SET_POWER_D0;
1511        retry = 0;
1512        do {
1513                ret = tegra_dc_dp_dpcd_write(priv, DP_SET_POWER, data);
1514        } while ((retry++ < DP_POWER_ON_MAX_TRIES) && ret);
1515
1516        if (ret || retry >= DP_POWER_ON_MAX_TRIES) {
1517                debug("dp: failed to power on panel (0x%x)\n", ret);
1518                return -ENETUNREACH;
1519                goto error_enable;
1520        }
1521
1522        /* Confirm DP plugging status */
1523        if (!(tegra_dpaux_readl(priv, DPAUX_DP_AUXSTAT) &
1524                        DPAUX_DP_AUXSTAT_HPD_STATUS_PLUGGED)) {
1525                debug("dp: could not detect HPD\n");
1526                return -ENXIO;
1527        }
1528
1529        /* Check DP version */
1530        if (tegra_dc_dp_dpcd_read(priv, DP_DPCD_REV, &priv->revision)) {
1531                debug("dp: failed to read the revision number from sink\n");
1532                return -EIO;
1533        }
1534
1535        if (tegra_dc_dp_explore_link_cfg(priv, link_cfg, sor, timing)) {
1536                debug("dp: error configuring link\n");
1537                return -ENOMEDIUM;
1538        }
1539
1540        tegra_dc_sor_set_power_state(sor, 1);
1541        ret = tegra_dc_sor_attach(priv->dc_dev, sor, link_cfg, timing);
1542        if (ret && ret != -EEXIST)
1543                return ret;
1544
1545        /*
1546         * This takes a long time, but can apparently resolve a failure to
1547         * bring up the display correctly.
1548         */
1549        if (0) {
1550                ret = tegra_dc_dp_check_sink(priv, link_cfg, timing);
1551                if (ret)
1552                        return ret;
1553        }
1554
1555        /* Power down the unused lanes to save power - a few hundred mW */
1556        tegra_dc_sor_power_down_unused_lanes(sor, link_cfg);
1557
1558        ret = video_bridge_set_backlight(sor, 80);
1559        if (ret) {
1560                debug("dp: failed to set backlight\n");
1561                return ret;
1562        }
1563
1564        priv->enabled = true;
1565error_enable:
1566        return 0;
1567}
1568
1569static int tegra_dp_of_to_plat(struct udevice *dev)
1570{
1571        struct tegra_dp_plat *plat = dev_get_plat(dev);
1572
1573        plat->base = dev_read_addr(dev);
1574
1575        return 0;
1576}
1577
1578static int tegra_dp_read_edid(struct udevice *dev, u8 *buf, int buf_size)
1579{
1580        struct tegra_dp_priv *priv = dev_get_priv(dev);
1581        const int tegra_edid_i2c_address = 0x50;
1582        u32 aux_stat = 0;
1583
1584        tegra_dc_dpaux_enable(priv);
1585
1586        return tegra_dc_i2c_aux_read(priv, tegra_edid_i2c_address, 0, buf,
1587                                     buf_size, &aux_stat);
1588}
1589
1590static const struct dm_display_ops dp_tegra_ops = {
1591        .read_edid = tegra_dp_read_edid,
1592        .enable = tegra_dp_enable,
1593};
1594
1595static int dp_tegra_probe(struct udevice *dev)
1596{
1597        struct tegra_dp_plat *plat = dev_get_plat(dev);
1598        struct tegra_dp_priv *priv = dev_get_priv(dev);
1599        struct display_plat *disp_uc_plat = dev_get_uclass_plat(dev);
1600
1601        priv->regs = (struct dpaux_ctlr *)plat->base;
1602        priv->enabled = false;
1603
1604        /* Remember the display controller that is sending us video */
1605        priv->dc_dev = disp_uc_plat->src_dev;
1606
1607        return 0;
1608}
1609
1610static const struct udevice_id tegra_dp_ids[] = {
1611        { .compatible = "nvidia,tegra124-dpaux" },
1612        { }
1613};
1614
1615U_BOOT_DRIVER(dp_tegra) = {
1616        .name   = "dpaux_tegra",
1617        .id     = UCLASS_DISPLAY,
1618        .of_match = tegra_dp_ids,
1619        .of_to_plat = tegra_dp_of_to_plat,
1620        .probe  = dp_tegra_probe,
1621        .ops    = &dp_tegra_ops,
1622        .priv_auto      = sizeof(struct tegra_dp_priv),
1623        .plat_auto      = sizeof(struct tegra_dp_plat),
1624};
1625