Linux Audio

Check our new training course

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