linux/drivers/gpu/drm/exynos/exynos_dp_core.c
<<
>>
Prefs
   1/*
   2 * Samsung SoC DP (Display Port) interface driver.
   3 *
   4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
   5 * Author: Jingoo Han <jg1.han@samsung.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of the GNU General Public License as published by the
   9 * Free Software Foundation; either version 2 of the License, or (at your
  10 * option) any later version.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/platform_device.h>
  15#include <linux/err.h>
  16#include <linux/clk.h>
  17#include <linux/io.h>
  18#include <linux/interrupt.h>
  19#include <linux/delay.h>
  20#include <linux/of.h>
  21#include <linux/of_gpio.h>
  22#include <linux/gpio.h>
  23#include <linux/component.h>
  24#include <linux/phy/phy.h>
  25#include <video/of_display_timing.h>
  26#include <video/of_videomode.h>
  27
  28#include <drm/drmP.h>
  29#include <drm/drm_crtc.h>
  30#include <drm/drm_crtc_helper.h>
  31#include <drm/bridge/ptn3460.h>
  32
  33#include "exynos_drm_drv.h"
  34#include "exynos_dp_core.h"
  35
  36#define ctx_from_connector(c)   container_of(c, struct exynos_dp_device, \
  37                                        connector)
  38
  39struct bridge_init {
  40        struct i2c_client *client;
  41        struct device_node *node;
  42};
  43
  44static int exynos_dp_init_dp(struct exynos_dp_device *dp)
  45{
  46        exynos_dp_reset(dp);
  47
  48        exynos_dp_swreset(dp);
  49
  50        exynos_dp_init_analog_param(dp);
  51        exynos_dp_init_interrupt(dp);
  52
  53        /* SW defined function Normal operation */
  54        exynos_dp_enable_sw_function(dp);
  55
  56        exynos_dp_config_interrupt(dp);
  57        exynos_dp_init_analog_func(dp);
  58
  59        exynos_dp_init_hpd(dp);
  60        exynos_dp_init_aux(dp);
  61
  62        return 0;
  63}
  64
  65static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
  66{
  67        int timeout_loop = 0;
  68
  69        while (exynos_dp_get_plug_in_status(dp) != 0) {
  70                timeout_loop++;
  71                if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
  72                        dev_err(dp->dev, "failed to get hpd plug status\n");
  73                        return -ETIMEDOUT;
  74                }
  75                usleep_range(10, 11);
  76        }
  77
  78        return 0;
  79}
  80
  81static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data)
  82{
  83        int i;
  84        unsigned char sum = 0;
  85
  86        for (i = 0; i < EDID_BLOCK_LENGTH; i++)
  87                sum = sum + edid_data[i];
  88
  89        return sum;
  90}
  91
  92static int exynos_dp_read_edid(struct exynos_dp_device *dp)
  93{
  94        unsigned char edid[EDID_BLOCK_LENGTH * 2];
  95        unsigned int extend_block = 0;
  96        unsigned char sum;
  97        unsigned char test_vector;
  98        int retval;
  99
 100        /*
 101         * EDID device address is 0x50.
 102         * However, if necessary, you must have set upper address
 103         * into E-EDID in I2C device, 0x30.
 104         */
 105
 106        /* Read Extension Flag, Number of 128-byte EDID extension blocks */
 107        retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
 108                                EDID_EXTENSION_FLAG,
 109                                &extend_block);
 110        if (retval)
 111                return retval;
 112
 113        if (extend_block > 0) {
 114                dev_dbg(dp->dev, "EDID data includes a single extension!\n");
 115
 116                /* Read EDID data */
 117                retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
 118                                                EDID_HEADER_PATTERN,
 119                                                EDID_BLOCK_LENGTH,
 120                                                &edid[EDID_HEADER_PATTERN]);
 121                if (retval != 0) {
 122                        dev_err(dp->dev, "EDID Read failed!\n");
 123                        return -EIO;
 124                }
 125                sum = exynos_dp_calc_edid_check_sum(edid);
 126                if (sum != 0) {
 127                        dev_err(dp->dev, "EDID bad checksum!\n");
 128                        return -EIO;
 129                }
 130
 131                /* Read additional EDID data */
 132                retval = exynos_dp_read_bytes_from_i2c(dp,
 133                                I2C_EDID_DEVICE_ADDR,
 134                                EDID_BLOCK_LENGTH,
 135                                EDID_BLOCK_LENGTH,
 136                                &edid[EDID_BLOCK_LENGTH]);
 137                if (retval != 0) {
 138                        dev_err(dp->dev, "EDID Read failed!\n");
 139                        return -EIO;
 140                }
 141                sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
 142                if (sum != 0) {
 143                        dev_err(dp->dev, "EDID bad checksum!\n");
 144                        return -EIO;
 145                }
 146
 147                exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
 148                                        &test_vector);
 149                if (test_vector & DP_TEST_LINK_EDID_READ) {
 150                        exynos_dp_write_byte_to_dpcd(dp,
 151                                DP_TEST_EDID_CHECKSUM,
 152                                edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
 153                        exynos_dp_write_byte_to_dpcd(dp,
 154                                DP_TEST_RESPONSE,
 155                                DP_TEST_EDID_CHECKSUM_WRITE);
 156                }
 157        } else {
 158                dev_info(dp->dev, "EDID data does not include any extensions.\n");
 159
 160                /* Read EDID data */
 161                retval = exynos_dp_read_bytes_from_i2c(dp,
 162                                I2C_EDID_DEVICE_ADDR,
 163                                EDID_HEADER_PATTERN,
 164                                EDID_BLOCK_LENGTH,
 165                                &edid[EDID_HEADER_PATTERN]);
 166                if (retval != 0) {
 167                        dev_err(dp->dev, "EDID Read failed!\n");
 168                        return -EIO;
 169                }
 170                sum = exynos_dp_calc_edid_check_sum(edid);
 171                if (sum != 0) {
 172                        dev_err(dp->dev, "EDID bad checksum!\n");
 173                        return -EIO;
 174                }
 175
 176                exynos_dp_read_byte_from_dpcd(dp,
 177                        DP_TEST_REQUEST,
 178                        &test_vector);
 179                if (test_vector & DP_TEST_LINK_EDID_READ) {
 180                        exynos_dp_write_byte_to_dpcd(dp,
 181                                DP_TEST_EDID_CHECKSUM,
 182                                edid[EDID_CHECKSUM]);
 183                        exynos_dp_write_byte_to_dpcd(dp,
 184                                DP_TEST_RESPONSE,
 185                                DP_TEST_EDID_CHECKSUM_WRITE);
 186                }
 187        }
 188
 189        dev_err(dp->dev, "EDID Read success!\n");
 190        return 0;
 191}
 192
 193static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
 194{
 195        u8 buf[12];
 196        int i;
 197        int retval;
 198
 199        /* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */
 200        retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV,
 201                                12, buf);
 202        if (retval)
 203                return retval;
 204
 205        /* Read EDID */
 206        for (i = 0; i < 3; i++) {
 207                retval = exynos_dp_read_edid(dp);
 208                if (!retval)
 209                        break;
 210        }
 211
 212        return retval;
 213}
 214
 215static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
 216                                                bool enable)
 217{
 218        u8 data;
 219
 220        exynos_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data);
 221
 222        if (enable)
 223                exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
 224                        DP_LANE_COUNT_ENHANCED_FRAME_EN |
 225                        DPCD_LANE_COUNT_SET(data));
 226        else
 227                exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
 228                        DPCD_LANE_COUNT_SET(data));
 229}
 230
 231static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp)
 232{
 233        u8 data;
 234        int retval;
 235
 236        exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data);
 237        retval = DPCD_ENHANCED_FRAME_CAP(data);
 238
 239        return retval;
 240}
 241
 242static void exynos_dp_set_enhanced_mode(struct exynos_dp_device *dp)
 243{
 244        u8 data;
 245
 246        data = exynos_dp_is_enhanced_mode_available(dp);
 247        exynos_dp_enable_rx_to_enhanced_mode(dp, data);
 248        exynos_dp_enable_enhanced_mode(dp, data);
 249}
 250
 251static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
 252{
 253        exynos_dp_set_training_pattern(dp, DP_NONE);
 254
 255        exynos_dp_write_byte_to_dpcd(dp,
 256                DP_TRAINING_PATTERN_SET,
 257                DP_TRAINING_PATTERN_DISABLE);
 258}
 259
 260static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
 261                                        int pre_emphasis, int lane)
 262{
 263        switch (lane) {
 264        case 0:
 265                exynos_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
 266                break;
 267        case 1:
 268                exynos_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
 269                break;
 270
 271        case 2:
 272                exynos_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
 273                break;
 274
 275        case 3:
 276                exynos_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
 277                break;
 278        }
 279}
 280
 281static int exynos_dp_link_start(struct exynos_dp_device *dp)
 282{
 283        u8 buf[4];
 284        int lane, lane_count, pll_tries, retval;
 285
 286        lane_count = dp->link_train.lane_count;
 287
 288        dp->link_train.lt_state = CLOCK_RECOVERY;
 289        dp->link_train.eq_loop = 0;
 290
 291        for (lane = 0; lane < lane_count; lane++)
 292                dp->link_train.cr_loop[lane] = 0;
 293
 294        /* Set link rate and count as you want to establish*/
 295        exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
 296        exynos_dp_set_lane_count(dp, dp->link_train.lane_count);
 297
 298        /* Setup RX configuration */
 299        buf[0] = dp->link_train.link_rate;
 300        buf[1] = dp->link_train.lane_count;
 301        retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET,
 302                                2, buf);
 303        if (retval)
 304                return retval;
 305
 306        /* Set TX pre-emphasis to minimum */
 307        for (lane = 0; lane < lane_count; lane++)
 308                exynos_dp_set_lane_lane_pre_emphasis(dp,
 309                        PRE_EMPHASIS_LEVEL_0, lane);
 310
 311        /* Wait for PLL lock */
 312        pll_tries = 0;
 313        while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
 314                if (pll_tries == DP_TIMEOUT_LOOP_COUNT) {
 315                        dev_err(dp->dev, "Wait for PLL lock timed out\n");
 316                        return -ETIMEDOUT;
 317                }
 318
 319                pll_tries++;
 320                usleep_range(90, 120);
 321        }
 322
 323        /* Set training pattern 1 */
 324        exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
 325
 326        /* Set RX training pattern */
 327        retval = exynos_dp_write_byte_to_dpcd(dp,
 328                        DP_TRAINING_PATTERN_SET,
 329                        DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1);
 330        if (retval)
 331                return retval;
 332
 333        for (lane = 0; lane < lane_count; lane++)
 334                buf[lane] = DP_TRAIN_PRE_EMPHASIS_0 |
 335                            DP_TRAIN_VOLTAGE_SWING_400;
 336
 337        retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
 338                        lane_count, buf);
 339
 340        return retval;
 341}
 342
 343static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
 344{
 345        int shift = (lane & 1) * 4;
 346        u8 link_value = link_status[lane>>1];
 347
 348        return (link_value >> shift) & 0xf;
 349}
 350
 351static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
 352{
 353        int lane;
 354        u8 lane_status;
 355
 356        for (lane = 0; lane < lane_count; lane++) {
 357                lane_status = exynos_dp_get_lane_status(link_status, lane);
 358                if ((lane_status & DP_LANE_CR_DONE) == 0)
 359                        return -EINVAL;
 360        }
 361        return 0;
 362}
 363
 364static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
 365                                int lane_count)
 366{
 367        int lane;
 368        u8 lane_status;
 369
 370        if ((link_align & DP_INTERLANE_ALIGN_DONE) == 0)
 371                return -EINVAL;
 372
 373        for (lane = 0; lane < lane_count; lane++) {
 374                lane_status = exynos_dp_get_lane_status(link_status, lane);
 375                lane_status &= DP_CHANNEL_EQ_BITS;
 376                if (lane_status != DP_CHANNEL_EQ_BITS)
 377                        return -EINVAL;
 378        }
 379
 380        return 0;
 381}
 382
 383static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2],
 384                                                        int lane)
 385{
 386        int shift = (lane & 1) * 4;
 387        u8 link_value = adjust_request[lane>>1];
 388
 389        return (link_value >> shift) & 0x3;
 390}
 391
 392static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
 393                                        u8 adjust_request[2],
 394                                        int lane)
 395{
 396        int shift = (lane & 1) * 4;
 397        u8 link_value = adjust_request[lane>>1];
 398
 399        return ((link_value >> shift) & 0xc) >> 2;
 400}
 401
 402static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
 403                                        u8 training_lane_set, int lane)
 404{
 405        switch (lane) {
 406        case 0:
 407                exynos_dp_set_lane0_link_training(dp, training_lane_set);
 408                break;
 409        case 1:
 410                exynos_dp_set_lane1_link_training(dp, training_lane_set);
 411                break;
 412
 413        case 2:
 414                exynos_dp_set_lane2_link_training(dp, training_lane_set);
 415                break;
 416
 417        case 3:
 418                exynos_dp_set_lane3_link_training(dp, training_lane_set);
 419                break;
 420        }
 421}
 422
 423static unsigned int exynos_dp_get_lane_link_training(
 424                                struct exynos_dp_device *dp,
 425                                int lane)
 426{
 427        u32 reg;
 428
 429        switch (lane) {
 430        case 0:
 431                reg = exynos_dp_get_lane0_link_training(dp);
 432                break;
 433        case 1:
 434                reg = exynos_dp_get_lane1_link_training(dp);
 435                break;
 436        case 2:
 437                reg = exynos_dp_get_lane2_link_training(dp);
 438                break;
 439        case 3:
 440                reg = exynos_dp_get_lane3_link_training(dp);
 441                break;
 442        default:
 443                WARN_ON(1);
 444                return 0;
 445        }
 446
 447        return reg;
 448}
 449
 450static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
 451{
 452        exynos_dp_training_pattern_dis(dp);
 453        exynos_dp_set_enhanced_mode(dp);
 454
 455        dp->link_train.lt_state = FAILED;
 456}
 457
 458static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
 459                                        u8 adjust_request[2])
 460{
 461        int lane, lane_count;
 462        u8 voltage_swing, pre_emphasis, training_lane;
 463
 464        lane_count = dp->link_train.lane_count;
 465        for (lane = 0; lane < lane_count; lane++) {
 466                voltage_swing = exynos_dp_get_adjust_request_voltage(
 467                                                adjust_request, lane);
 468                pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
 469                                                adjust_request, lane);
 470                training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
 471                                DPCD_PRE_EMPHASIS_SET(pre_emphasis);
 472
 473                if (voltage_swing == VOLTAGE_LEVEL_3)
 474                        training_lane |= DP_TRAIN_MAX_SWING_REACHED;
 475                if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
 476                        training_lane |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 477
 478                dp->link_train.training_lane[lane] = training_lane;
 479        }
 480}
 481
 482static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 483{
 484        int lane, lane_count, retval;
 485        u8 voltage_swing, pre_emphasis, training_lane;
 486        u8 link_status[2], adjust_request[2];
 487
 488        usleep_range(100, 101);
 489
 490        lane_count = dp->link_train.lane_count;
 491
 492        retval =  exynos_dp_read_bytes_from_dpcd(dp,
 493                        DP_LANE0_1_STATUS, 2, link_status);
 494        if (retval)
 495                return retval;
 496
 497        retval =  exynos_dp_read_bytes_from_dpcd(dp,
 498                        DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
 499        if (retval)
 500                return retval;
 501
 502        if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
 503                /* set training pattern 2 for EQ */
 504                exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
 505
 506                retval = exynos_dp_write_byte_to_dpcd(dp,
 507                                DP_TRAINING_PATTERN_SET,
 508                                DP_LINK_SCRAMBLING_DISABLE |
 509                                DP_TRAINING_PATTERN_2);
 510                if (retval)
 511                        return retval;
 512
 513                dev_info(dp->dev, "Link Training Clock Recovery success\n");
 514                dp->link_train.lt_state = EQUALIZER_TRAINING;
 515        } else {
 516                for (lane = 0; lane < lane_count; lane++) {
 517                        training_lane = exynos_dp_get_lane_link_training(
 518                                                        dp, lane);
 519                        voltage_swing = exynos_dp_get_adjust_request_voltage(
 520                                                        adjust_request, lane);
 521                        pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
 522                                                        adjust_request, lane);
 523
 524                        if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
 525                                        voltage_swing &&
 526                            DPCD_PRE_EMPHASIS_GET(training_lane) ==
 527                                        pre_emphasis)
 528                                dp->link_train.cr_loop[lane]++;
 529
 530                        if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP ||
 531                            voltage_swing == VOLTAGE_LEVEL_3 ||
 532                            pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
 533                                dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n",
 534                                        dp->link_train.cr_loop[lane],
 535                                        voltage_swing, pre_emphasis);
 536                                exynos_dp_reduce_link_rate(dp);
 537                                return -EIO;
 538                        }
 539                }
 540        }
 541
 542        exynos_dp_get_adjust_training_lane(dp, adjust_request);
 543
 544        for (lane = 0; lane < lane_count; lane++)
 545                exynos_dp_set_lane_link_training(dp,
 546                        dp->link_train.training_lane[lane], lane);
 547
 548        retval = exynos_dp_write_bytes_to_dpcd(dp,
 549                        DP_TRAINING_LANE0_SET, lane_count,
 550                        dp->link_train.training_lane);
 551        if (retval)
 552                return retval;
 553
 554        return retval;
 555}
 556
 557static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 558{
 559        int lane, lane_count, retval;
 560        u32 reg;
 561        u8 link_align, link_status[2], adjust_request[2];
 562
 563        usleep_range(400, 401);
 564
 565        lane_count = dp->link_train.lane_count;
 566
 567        retval = exynos_dp_read_bytes_from_dpcd(dp,
 568                        DP_LANE0_1_STATUS, 2, link_status);
 569        if (retval)
 570                return retval;
 571
 572        if (exynos_dp_clock_recovery_ok(link_status, lane_count)) {
 573                exynos_dp_reduce_link_rate(dp);
 574                return -EIO;
 575        }
 576
 577        retval = exynos_dp_read_bytes_from_dpcd(dp,
 578                        DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
 579        if (retval)
 580                return retval;
 581
 582        retval = exynos_dp_read_byte_from_dpcd(dp,
 583                        DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
 584        if (retval)
 585                return retval;
 586
 587        exynos_dp_get_adjust_training_lane(dp, adjust_request);
 588
 589        if (!exynos_dp_channel_eq_ok(link_status, link_align, lane_count)) {
 590                /* traing pattern Set to Normal */
 591                exynos_dp_training_pattern_dis(dp);
 592
 593                dev_info(dp->dev, "Link Training success!\n");
 594
 595                exynos_dp_get_link_bandwidth(dp, &reg);
 596                dp->link_train.link_rate = reg;
 597                dev_dbg(dp->dev, "final bandwidth = %.2x\n",
 598                        dp->link_train.link_rate);
 599
 600                exynos_dp_get_lane_count(dp, &reg);
 601                dp->link_train.lane_count = reg;
 602                dev_dbg(dp->dev, "final lane count = %.2x\n",
 603                        dp->link_train.lane_count);
 604
 605                /* set enhanced mode if available */
 606                exynos_dp_set_enhanced_mode(dp);
 607                dp->link_train.lt_state = FINISHED;
 608
 609                return 0;
 610        }
 611
 612        /* not all locked */
 613        dp->link_train.eq_loop++;
 614
 615        if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
 616                dev_err(dp->dev, "EQ Max loop\n");
 617                exynos_dp_reduce_link_rate(dp);
 618                return -EIO;
 619        }
 620
 621        for (lane = 0; lane < lane_count; lane++)
 622                exynos_dp_set_lane_link_training(dp,
 623                        dp->link_train.training_lane[lane], lane);
 624
 625        retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
 626                        lane_count, dp->link_train.training_lane);
 627
 628        return retval;
 629}
 630
 631static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
 632                                        u8 *bandwidth)
 633{
 634        u8 data;
 635
 636        /*
 637         * For DP rev.1.1, Maximum link rate of Main Link lanes
 638         * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
 639         */
 640        exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
 641        *bandwidth = data;
 642}
 643
 644static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
 645                                        u8 *lane_count)
 646{
 647        u8 data;
 648
 649        /*
 650         * For DP rev.1.1, Maximum number of Main Link lanes
 651         * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
 652         */
 653        exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data);
 654        *lane_count = DPCD_MAX_LANE_COUNT(data);
 655}
 656
 657static void exynos_dp_init_training(struct exynos_dp_device *dp,
 658                        enum link_lane_count_type max_lane,
 659                        enum link_rate_type max_rate)
 660{
 661        /*
 662         * MACRO_RST must be applied after the PLL_LOCK to avoid
 663         * the DP inter pair skew issue for at least 10 us
 664         */
 665        exynos_dp_reset_macro(dp);
 666
 667        /* Initialize by reading RX's DPCD */
 668        exynos_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
 669        exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
 670
 671        if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
 672           (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
 673                dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
 674                        dp->link_train.link_rate);
 675                dp->link_train.link_rate = LINK_RATE_1_62GBPS;
 676        }
 677
 678        if (dp->link_train.lane_count == 0) {
 679                dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n",
 680                        dp->link_train.lane_count);
 681                dp->link_train.lane_count = (u8)LANE_COUNT1;
 682        }
 683
 684        /* Setup TX lane count & rate */
 685        if (dp->link_train.lane_count > max_lane)
 686                dp->link_train.lane_count = max_lane;
 687        if (dp->link_train.link_rate > max_rate)
 688                dp->link_train.link_rate = max_rate;
 689
 690        /* All DP analog module power up */
 691        exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
 692}
 693
 694static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
 695{
 696        int retval = 0, training_finished = 0;
 697
 698        dp->link_train.lt_state = START;
 699
 700        /* Process here */
 701        while (!retval && !training_finished) {
 702                switch (dp->link_train.lt_state) {
 703                case START:
 704                        retval = exynos_dp_link_start(dp);
 705                        if (retval)
 706                                dev_err(dp->dev, "LT link start failed!\n");
 707                        break;
 708                case CLOCK_RECOVERY:
 709                        retval = exynos_dp_process_clock_recovery(dp);
 710                        if (retval)
 711                                dev_err(dp->dev, "LT CR failed!\n");
 712                        break;
 713                case EQUALIZER_TRAINING:
 714                        retval = exynos_dp_process_equalizer_training(dp);
 715                        if (retval)
 716                                dev_err(dp->dev, "LT EQ failed!\n");
 717                        break;
 718                case FINISHED:
 719                        training_finished = 1;
 720                        break;
 721                case FAILED:
 722                        return -EREMOTEIO;
 723                }
 724        }
 725        if (retval)
 726                dev_err(dp->dev, "eDP link training failed (%d)\n", retval);
 727
 728        return retval;
 729}
 730
 731static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
 732                                u32 count,
 733                                u32 bwtype)
 734{
 735        int i;
 736        int retval;
 737
 738        for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) {
 739                exynos_dp_init_training(dp, count, bwtype);
 740                retval = exynos_dp_sw_link_training(dp);
 741                if (retval == 0)
 742                        break;
 743
 744                usleep_range(100, 110);
 745        }
 746
 747        return retval;
 748}
 749
 750static int exynos_dp_config_video(struct exynos_dp_device *dp)
 751{
 752        int retval = 0;
 753        int timeout_loop = 0;
 754        int done_count = 0;
 755
 756        exynos_dp_config_video_slave_mode(dp);
 757
 758        exynos_dp_set_video_color_format(dp);
 759
 760        if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
 761                dev_err(dp->dev, "PLL is not locked yet.\n");
 762                return -EINVAL;
 763        }
 764
 765        for (;;) {
 766                timeout_loop++;
 767                if (exynos_dp_is_slave_video_stream_clock_on(dp) == 0)
 768                        break;
 769                if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
 770                        dev_err(dp->dev, "Timeout of video streamclk ok\n");
 771                        return -ETIMEDOUT;
 772                }
 773
 774                usleep_range(1, 2);
 775        }
 776
 777        /* Set to use the register calculated M/N video */
 778        exynos_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);
 779
 780        /* For video bist, Video timing must be generated by register */
 781        exynos_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE);
 782
 783        /* Disable video mute */
 784        exynos_dp_enable_video_mute(dp, 0);
 785
 786        /* Configure video slave mode */
 787        exynos_dp_enable_video_master(dp, 0);
 788
 789        /* Enable video */
 790        exynos_dp_start_video(dp);
 791
 792        timeout_loop = 0;
 793
 794        for (;;) {
 795                timeout_loop++;
 796                if (exynos_dp_is_video_stream_on(dp) == 0) {
 797                        done_count++;
 798                        if (done_count > 10)
 799                                break;
 800                } else if (done_count) {
 801                        done_count = 0;
 802                }
 803                if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
 804                        dev_err(dp->dev, "Timeout of video streamclk ok\n");
 805                        return -ETIMEDOUT;
 806                }
 807
 808                usleep_range(1000, 1001);
 809        }
 810
 811        if (retval != 0)
 812                dev_err(dp->dev, "Video stream is not detected!\n");
 813
 814        return retval;
 815}
 816
 817static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable)
 818{
 819        u8 data;
 820
 821        if (enable) {
 822                exynos_dp_enable_scrambling(dp);
 823
 824                exynos_dp_read_byte_from_dpcd(dp,
 825                        DP_TRAINING_PATTERN_SET,
 826                        &data);
 827                exynos_dp_write_byte_to_dpcd(dp,
 828                        DP_TRAINING_PATTERN_SET,
 829                        (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
 830        } else {
 831                exynos_dp_disable_scrambling(dp);
 832
 833                exynos_dp_read_byte_from_dpcd(dp,
 834                        DP_TRAINING_PATTERN_SET,
 835                        &data);
 836                exynos_dp_write_byte_to_dpcd(dp,
 837                        DP_TRAINING_PATTERN_SET,
 838                        (u8)(data | DP_LINK_SCRAMBLING_DISABLE));
 839        }
 840}
 841
 842static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
 843{
 844        struct exynos_dp_device *dp = arg;
 845
 846        enum dp_irq_type irq_type;
 847
 848        irq_type = exynos_dp_get_irq_type(dp);
 849        switch (irq_type) {
 850        case DP_IRQ_TYPE_HP_CABLE_IN:
 851                dev_dbg(dp->dev, "Received irq - cable in\n");
 852                schedule_work(&dp->hotplug_work);
 853                exynos_dp_clear_hotplug_interrupts(dp);
 854                break;
 855        case DP_IRQ_TYPE_HP_CABLE_OUT:
 856                dev_dbg(dp->dev, "Received irq - cable out\n");
 857                exynos_dp_clear_hotplug_interrupts(dp);
 858                break;
 859        case DP_IRQ_TYPE_HP_CHANGE:
 860                /*
 861                 * We get these change notifications once in a while, but there
 862                 * is nothing we can do with them. Just ignore it for now and
 863                 * only handle cable changes.
 864                 */
 865                dev_dbg(dp->dev, "Received irq - hotplug change; ignoring.\n");
 866                exynos_dp_clear_hotplug_interrupts(dp);
 867                break;
 868        default:
 869                dev_err(dp->dev, "Received irq - unknown type!\n");
 870                break;
 871        }
 872        return IRQ_HANDLED;
 873}
 874
 875static void exynos_dp_hotplug(struct work_struct *work)
 876{
 877        struct exynos_dp_device *dp;
 878        int ret;
 879
 880        dp = container_of(work, struct exynos_dp_device, hotplug_work);
 881
 882        ret = exynos_dp_detect_hpd(dp);
 883        if (ret) {
 884                /* Cable has been disconnected, we're done */
 885                return;
 886        }
 887
 888        ret = exynos_dp_handle_edid(dp);
 889        if (ret) {
 890                dev_err(dp->dev, "unable to handle edid\n");
 891                return;
 892        }
 893
 894        ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
 895                                        dp->video_info->link_rate);
 896        if (ret) {
 897                dev_err(dp->dev, "unable to do link train\n");
 898                return;
 899        }
 900
 901        exynos_dp_enable_scramble(dp, 1);
 902        exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
 903        exynos_dp_enable_enhanced_mode(dp, 1);
 904
 905        exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
 906        exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
 907
 908        exynos_dp_init_video(dp);
 909        ret = exynos_dp_config_video(dp);
 910        if (ret)
 911                dev_err(dp->dev, "unable to config video\n");
 912}
 913
 914static enum drm_connector_status exynos_dp_detect(
 915                                struct drm_connector *connector, bool force)
 916{
 917        return connector_status_connected;
 918}
 919
 920static void exynos_dp_connector_destroy(struct drm_connector *connector)
 921{
 922}
 923
 924static struct drm_connector_funcs exynos_dp_connector_funcs = {
 925        .dpms = drm_helper_connector_dpms,
 926        .fill_modes = drm_helper_probe_single_connector_modes,
 927        .detect = exynos_dp_detect,
 928        .destroy = exynos_dp_connector_destroy,
 929};
 930
 931static int exynos_dp_get_modes(struct drm_connector *connector)
 932{
 933        struct exynos_dp_device *dp = ctx_from_connector(connector);
 934        struct drm_display_mode *mode;
 935
 936        mode = drm_mode_create(connector->dev);
 937        if (!mode) {
 938                DRM_ERROR("failed to create a new display mode.\n");
 939                return 0;
 940        }
 941
 942        drm_display_mode_from_videomode(&dp->panel.vm, mode);
 943        mode->width_mm = dp->panel.width_mm;
 944        mode->height_mm = dp->panel.height_mm;
 945        connector->display_info.width_mm = mode->width_mm;
 946        connector->display_info.height_mm = mode->height_mm;
 947
 948        mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
 949        drm_mode_set_name(mode);
 950        drm_mode_probed_add(connector, mode);
 951
 952        return 1;
 953}
 954
 955static struct drm_encoder *exynos_dp_best_encoder(
 956                        struct drm_connector *connector)
 957{
 958        struct exynos_dp_device *dp = ctx_from_connector(connector);
 959
 960        return dp->encoder;
 961}
 962
 963static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
 964        .get_modes = exynos_dp_get_modes,
 965        .best_encoder = exynos_dp_best_encoder,
 966};
 967
 968static bool find_bridge(const char *compat, struct bridge_init *bridge)
 969{
 970        bridge->client = NULL;
 971        bridge->node = of_find_compatible_node(NULL, NULL, compat);
 972        if (!bridge->node)
 973                return false;
 974
 975        bridge->client = of_find_i2c_device_by_node(bridge->node);
 976        if (!bridge->client)
 977                return false;
 978
 979        return true;
 980}
 981
 982/* returns the number of bridges attached */
 983static int exynos_drm_attach_lcd_bridge(struct drm_device *dev,
 984                struct drm_encoder *encoder)
 985{
 986        struct bridge_init bridge;
 987        int ret;
 988
 989        if (find_bridge("nxp,ptn3460", &bridge)) {
 990                ret = ptn3460_init(dev, encoder, bridge.client, bridge.node);
 991                if (!ret)
 992                        return 1;
 993        }
 994        return 0;
 995}
 996
 997static int exynos_dp_create_connector(struct exynos_drm_display *display,
 998                                struct drm_encoder *encoder)
 999{
1000        struct exynos_dp_device *dp = display->ctx;
1001        struct drm_connector *connector = &dp->connector;
1002        int ret;
1003
1004        dp->encoder = encoder;
1005
1006        /* Pre-empt DP connector creation if there's a bridge */
1007        ret = exynos_drm_attach_lcd_bridge(dp->drm_dev, encoder);
1008        if (ret)
1009                return 0;
1010
1011        connector->polled = DRM_CONNECTOR_POLL_HPD;
1012
1013        ret = drm_connector_init(dp->drm_dev, connector,
1014                        &exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
1015        if (ret) {
1016                DRM_ERROR("Failed to initialize connector with drm\n");
1017                return ret;
1018        }
1019
1020        drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
1021        drm_sysfs_connector_add(connector);
1022        drm_mode_connector_attach_encoder(connector, encoder);
1023
1024        return 0;
1025}
1026
1027static void exynos_dp_phy_init(struct exynos_dp_device *dp)
1028{
1029        if (dp->phy) {
1030                phy_power_on(dp->phy);
1031        } else if (dp->phy_addr) {
1032                u32 reg;
1033
1034                reg = __raw_readl(dp->phy_addr);
1035                reg |= dp->enable_mask;
1036                __raw_writel(reg, dp->phy_addr);
1037        }
1038}
1039
1040static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
1041{
1042        if (dp->phy) {
1043                phy_power_off(dp->phy);
1044        } else if (dp->phy_addr) {
1045                u32 reg;
1046
1047                reg = __raw_readl(dp->phy_addr);
1048                reg &= ~(dp->enable_mask);
1049                __raw_writel(reg, dp->phy_addr);
1050        }
1051}
1052
1053static void exynos_dp_poweron(struct exynos_dp_device *dp)
1054{
1055        if (dp->dpms_mode == DRM_MODE_DPMS_ON)
1056                return;
1057
1058        clk_prepare_enable(dp->clock);
1059        exynos_dp_phy_init(dp);
1060        exynos_dp_init_dp(dp);
1061        enable_irq(dp->irq);
1062}
1063
1064static void exynos_dp_poweroff(struct exynos_dp_device *dp)
1065{
1066        if (dp->dpms_mode != DRM_MODE_DPMS_ON)
1067                return;
1068
1069        disable_irq(dp->irq);
1070        flush_work(&dp->hotplug_work);
1071        exynos_dp_phy_exit(dp);
1072        clk_disable_unprepare(dp->clock);
1073}
1074
1075static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
1076{
1077        struct exynos_dp_device *dp = display->ctx;
1078
1079        switch (mode) {
1080        case DRM_MODE_DPMS_ON:
1081                exynos_dp_poweron(dp);
1082                break;
1083        case DRM_MODE_DPMS_STANDBY:
1084        case DRM_MODE_DPMS_SUSPEND:
1085        case DRM_MODE_DPMS_OFF:
1086                exynos_dp_poweroff(dp);
1087                break;
1088        default:
1089                break;
1090        }
1091        dp->dpms_mode = mode;
1092}
1093
1094static struct exynos_drm_display_ops exynos_dp_display_ops = {
1095        .create_connector = exynos_dp_create_connector,
1096        .dpms = exynos_dp_dpms,
1097};
1098
1099static struct exynos_drm_display exynos_dp_display = {
1100        .type = EXYNOS_DISPLAY_TYPE_LCD,
1101        .ops = &exynos_dp_display_ops,
1102};
1103
1104static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
1105{
1106        struct device_node *dp_node = dev->of_node;
1107        struct video_info *dp_video_config;
1108
1109        dp_video_config = devm_kzalloc(dev,
1110                                sizeof(*dp_video_config), GFP_KERNEL);
1111        if (!dp_video_config)
1112                return ERR_PTR(-ENOMEM);
1113
1114        dp_video_config->h_sync_polarity =
1115                of_property_read_bool(dp_node, "hsync-active-high");
1116
1117        dp_video_config->v_sync_polarity =
1118                of_property_read_bool(dp_node, "vsync-active-high");
1119
1120        dp_video_config->interlaced =
1121                of_property_read_bool(dp_node, "interlaced");
1122
1123        if (of_property_read_u32(dp_node, "samsung,color-space",
1124                                &dp_video_config->color_space)) {
1125                dev_err(dev, "failed to get color-space\n");
1126                return ERR_PTR(-EINVAL);
1127        }
1128
1129        if (of_property_read_u32(dp_node, "samsung,dynamic-range",
1130                                &dp_video_config->dynamic_range)) {
1131                dev_err(dev, "failed to get dynamic-range\n");
1132                return ERR_PTR(-EINVAL);
1133        }
1134
1135        if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
1136                                &dp_video_config->ycbcr_coeff)) {
1137                dev_err(dev, "failed to get ycbcr-coeff\n");
1138                return ERR_PTR(-EINVAL);
1139        }
1140
1141        if (of_property_read_u32(dp_node, "samsung,color-depth",
1142                                &dp_video_config->color_depth)) {
1143                dev_err(dev, "failed to get color-depth\n");
1144                return ERR_PTR(-EINVAL);
1145        }
1146
1147        if (of_property_read_u32(dp_node, "samsung,link-rate",
1148                                &dp_video_config->link_rate)) {
1149                dev_err(dev, "failed to get link-rate\n");
1150                return ERR_PTR(-EINVAL);
1151        }
1152
1153        if (of_property_read_u32(dp_node, "samsung,lane-count",
1154                                &dp_video_config->lane_count)) {
1155                dev_err(dev, "failed to get lane-count\n");
1156                return ERR_PTR(-EINVAL);
1157        }
1158
1159        return dp_video_config;
1160}
1161
1162static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
1163{
1164        struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
1165        u32 phy_base;
1166        int ret = 0;
1167
1168        dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
1169        if (!dp_phy_node) {
1170                dp->phy = devm_phy_get(dp->dev, "dp");
1171                return PTR_ERR_OR_ZERO(dp->phy);
1172        }
1173
1174        if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
1175                dev_err(dp->dev, "failed to get reg for dptx-phy\n");
1176                ret = -EINVAL;
1177                goto err;
1178        }
1179
1180        if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
1181                                &dp->enable_mask)) {
1182                dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n");
1183                ret = -EINVAL;
1184                goto err;
1185        }
1186
1187        dp->phy_addr = ioremap(phy_base, SZ_4);
1188        if (!dp->phy_addr) {
1189                dev_err(dp->dev, "failed to ioremap dp-phy\n");
1190                ret = -ENOMEM;
1191                goto err;
1192        }
1193
1194err:
1195        of_node_put(dp_phy_node);
1196
1197        return ret;
1198}
1199
1200static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
1201{
1202        int ret;
1203
1204        ret = of_get_videomode(dp->dev->of_node, &dp->panel.vm,
1205                        OF_USE_NATIVE_MODE);
1206        if (ret) {
1207                DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
1208                return ret;
1209        }
1210        return 0;
1211}
1212
1213static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
1214{
1215        struct platform_device *pdev = to_platform_device(dev);
1216        struct drm_device *drm_dev = data;
1217        struct resource *res;
1218        struct exynos_dp_device *dp;
1219        unsigned int irq_flags;
1220
1221        int ret = 0;
1222
1223        dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
1224                                GFP_KERNEL);
1225        if (!dp)
1226                return -ENOMEM;
1227
1228        dp->dev = &pdev->dev;
1229        dp->dpms_mode = DRM_MODE_DPMS_OFF;
1230
1231        dp->video_info = exynos_dp_dt_parse_pdata(&pdev->dev);
1232        if (IS_ERR(dp->video_info))
1233                return PTR_ERR(dp->video_info);
1234
1235        ret = exynos_dp_dt_parse_phydata(dp);
1236        if (ret)
1237                return ret;
1238
1239        ret = exynos_dp_dt_parse_panel(dp);
1240        if (ret)
1241                return ret;
1242
1243        dp->clock = devm_clk_get(&pdev->dev, "dp");
1244        if (IS_ERR(dp->clock)) {
1245                dev_err(&pdev->dev, "failed to get clock\n");
1246                return PTR_ERR(dp->clock);
1247        }
1248
1249        clk_prepare_enable(dp->clock);
1250
1251        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1252
1253        dp->reg_base = devm_ioremap_resource(&pdev->dev, res);
1254        if (IS_ERR(dp->reg_base))
1255                return PTR_ERR(dp->reg_base);
1256
1257        dp->hpd_gpio = of_get_named_gpio(dev->of_node, "samsung,hpd-gpio", 0);
1258
1259        if (gpio_is_valid(dp->hpd_gpio)) {
1260                /*
1261                 * Set up the hotplug GPIO from the device tree as an interrupt.
1262                 * Simply specifying a different interrupt in the device tree
1263                 * doesn't work since we handle hotplug rather differently when
1264                 * using a GPIO.  We also need the actual GPIO specifier so
1265                 * that we can get the current state of the GPIO.
1266                 */
1267                ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN,
1268                                            "hpd_gpio");
1269                if (ret) {
1270                        dev_err(&pdev->dev, "failed to get hpd gpio\n");
1271                        return ret;
1272                }
1273                dp->irq = gpio_to_irq(dp->hpd_gpio);
1274                irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
1275        } else {
1276                dp->hpd_gpio = -ENODEV;
1277                dp->irq = platform_get_irq(pdev, 0);
1278                irq_flags = 0;
1279        }
1280
1281        if (dp->irq == -ENXIO) {
1282                dev_err(&pdev->dev, "failed to get irq\n");
1283                return -ENODEV;
1284        }
1285
1286        INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
1287
1288        exynos_dp_phy_init(dp);
1289
1290        exynos_dp_init_dp(dp);
1291
1292        ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
1293                        irq_flags, "exynos-dp", dp);
1294        if (ret) {
1295                dev_err(&pdev->dev, "failed to request irq\n");
1296                return ret;
1297        }
1298        disable_irq(dp->irq);
1299
1300        dp->drm_dev = drm_dev;
1301        exynos_dp_display.ctx = dp;
1302
1303        platform_set_drvdata(pdev, &exynos_dp_display);
1304
1305        return exynos_drm_create_enc_conn(drm_dev, &exynos_dp_display);
1306}
1307
1308static void exynos_dp_unbind(struct device *dev, struct device *master,
1309                                void *data)
1310{
1311        struct exynos_drm_display *display = dev_get_drvdata(dev);
1312        struct exynos_dp_device *dp = display->ctx;
1313        struct drm_encoder *encoder = dp->encoder;
1314
1315        exynos_dp_dpms(display, DRM_MODE_DPMS_OFF);
1316
1317        encoder->funcs->destroy(encoder);
1318        drm_connector_cleanup(&dp->connector);
1319}
1320
1321static const struct component_ops exynos_dp_ops = {
1322        .bind   = exynos_dp_bind,
1323        .unbind = exynos_dp_unbind,
1324};
1325
1326static int exynos_dp_probe(struct platform_device *pdev)
1327{
1328        int ret;
1329
1330        ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
1331                                        exynos_dp_display.type);
1332        if (ret)
1333                return ret;
1334
1335        ret = component_add(&pdev->dev, &exynos_dp_ops);
1336        if (ret)
1337                exynos_drm_component_del(&pdev->dev,
1338                                                EXYNOS_DEVICE_TYPE_CONNECTOR);
1339
1340        return ret;
1341}
1342
1343static int exynos_dp_remove(struct platform_device *pdev)
1344{
1345        component_del(&pdev->dev, &exynos_dp_ops);
1346        exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
1347
1348        return 0;
1349}
1350
1351#ifdef CONFIG_PM_SLEEP
1352static int exynos_dp_suspend(struct device *dev)
1353{
1354        struct platform_device *pdev = to_platform_device(dev);
1355        struct exynos_drm_display *display = platform_get_drvdata(pdev);
1356
1357        exynos_dp_dpms(display, DRM_MODE_DPMS_OFF);
1358        return 0;
1359}
1360
1361static int exynos_dp_resume(struct device *dev)
1362{
1363        struct platform_device *pdev = to_platform_device(dev);
1364        struct exynos_drm_display *display = platform_get_drvdata(pdev);
1365
1366        exynos_dp_dpms(display, DRM_MODE_DPMS_ON);
1367        return 0;
1368}
1369#endif
1370
1371static const struct dev_pm_ops exynos_dp_pm_ops = {
1372        SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
1373};
1374
1375static const struct of_device_id exynos_dp_match[] = {
1376        { .compatible = "samsung,exynos5-dp" },
1377        {},
1378};
1379
1380struct platform_driver dp_driver = {
1381        .probe          = exynos_dp_probe,
1382        .remove         = exynos_dp_remove,
1383        .driver         = {
1384                .name   = "exynos-dp",
1385                .owner  = THIS_MODULE,
1386                .pm     = &exynos_dp_pm_ops,
1387                .of_match_table = exynos_dp_match,
1388        },
1389};
1390
1391MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
1392MODULE_DESCRIPTION("Samsung SoC DP Driver");
1393MODULE_LICENSE("GPL");
1394