/*
 * Copyright (C) 2012 Samsung Electronics
 *
 * Author: Donghwa Lee <dh09.lee@samsung.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <config.h>
#include <dm.h>
#include <common.h>
#include <display.h>
#include <fdtdec.h>
#include <libfdt.h>
#include <malloc.h>
#include <video_bridge.h>
#include <linux/compat.h>
#include <linux/err.h>
#include <asm/arch/clk.h>
#include <asm/arch/cpu.h>
#include <asm/arch/dp_info.h>
#include <asm/arch/dp.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/power.h>

#include "exynos_dp_lowlevel.h"

DECLARE_GLOBAL_DATA_PTR;

static void exynos_dp_disp_info(struct edp_disp_info *disp_info)
{
	disp_info->h_total = disp_info->h_res + disp_info->h_sync_width +
		disp_info->h_back_porch + disp_info->h_front_porch;
	disp_info->v_total = disp_info->v_res + disp_info->v_sync_width +
		disp_info->v_back_porch + disp_info->v_front_porch;

	return;
}

static int exynos_dp_init_dp(struct exynos_dp *regs)
{
	int ret;
	exynos_dp_reset(regs);

	/* SW defined function Normal operation */
	exynos_dp_enable_sw_func(regs, DP_ENABLE);

	ret = exynos_dp_init_analog_func(regs);
	if (ret != EXYNOS_DP_SUCCESS)
		return ret;

	exynos_dp_init_hpd(regs);
	exynos_dp_init_aux(regs);

	return ret;
}

static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data)
{
	int i;
	unsigned char sum = 0;

	for (i = 0; i < EDID_BLOCK_LENGTH; i++)
		sum = sum + edid_data[i];

	return sum;
}

static unsigned int exynos_dp_read_edid(struct exynos_dp *regs)
{
	unsigned char edid[EDID_BLOCK_LENGTH * 2];
	unsigned int extend_block = 0;
	unsigned char sum;
	unsigned char test_vector;
	int retval;

	/*
	 * EDID device address is 0x50.
	 * However, if necessary, you must have set upper address
	 * into E-EDID in I2C device, 0x30.
	 */

	/* Read Extension Flag, Number of 128-byte EDID extension blocks */
	exynos_dp_read_byte_from_i2c(regs, I2C_EDID_DEVICE_ADDR,
				     EDID_EXTENSION_FLAG, &extend_block);

	if (extend_block > 0) {
		printf("DP EDID data includes a single extension!\n");

		/* Read EDID data */
		retval = exynos_dp_read_bytes_from_i2c(regs,
						I2C_EDID_DEVICE_ADDR,
						EDID_HEADER_PATTERN,
						EDID_BLOCK_LENGTH,
						&edid[EDID_HEADER_PATTERN]);
		if (retval != 0) {
			printf("DP EDID Read failed!\n");
			return -1;
		}
		sum = exynos_dp_calc_edid_check_sum(edid);
		if (sum != 0) {
			printf("DP EDID bad checksum!\n");
			return -1;
		}

		/* Read additional EDID data */
		retval = exynos_dp_read_bytes_from_i2c(regs,
				I2C_EDID_DEVICE_ADDR,
				EDID_BLOCK_LENGTH,
				EDID_BLOCK_LENGTH,
				&edid[EDID_BLOCK_LENGTH]);
		if (retval != 0) {
			printf("DP EDID Read failed!\n");
			return -1;
		}
		sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
		if (sum != 0) {
			printf("DP EDID bad checksum!\n");
			return -1;
		}

		exynos_dp_read_byte_from_dpcd(regs, DPCD_TEST_REQUEST,
					      &test_vector);
		if (test_vector & DPCD_TEST_EDID_READ) {
			exynos_dp_write_byte_to_dpcd(regs,
				DPCD_TEST_EDID_CHECKSUM,
				edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
			exynos_dp_write_byte_to_dpcd(regs,
				DPCD_TEST_RESPONSE,
				DPCD_TEST_EDID_CHECKSUM_WRITE);
		}
	} else {
		debug("DP EDID data does not include any extensions.\n");

		/* Read EDID data */
		retval = exynos_dp_read_bytes_from_i2c(regs,
				I2C_EDID_DEVICE_ADDR,
				EDID_HEADER_PATTERN,
				EDID_BLOCK_LENGTH,
				&edid[EDID_HEADER_PATTERN]);

		if (retval != 0) {
			printf("DP EDID Read failed!\n");
			return -1;
		}
		sum = exynos_dp_calc_edid_check_sum(edid);
		if (sum != 0) {
			printf("DP EDID bad checksum!\n");
			return -1;
		}

		exynos_dp_read_byte_from_dpcd(regs, DPCD_TEST_REQUEST,
			&test_vector);
		if (test_vector & DPCD_TEST_EDID_READ) {
			exynos_dp_write_byte_to_dpcd(regs,
				DPCD_TEST_EDID_CHECKSUM, edid[EDID_CHECKSUM]);
			exynos_dp_write_byte_to_dpcd(regs,
				DPCD_TEST_RESPONSE,
				DPCD_TEST_EDID_CHECKSUM_WRITE);
		}
	}

	debug("DP EDID Read success!\n");

	return 0;
}

static unsigned int exynos_dp_handle_edid(struct exynos_dp *regs,
					  struct exynos_dp_priv *priv)
{
	unsigned char buf[12];
	unsigned int ret;
	unsigned char temp;
	unsigned char retry_cnt;
	unsigned char dpcd_rev[16];
	unsigned char lane_bw[16];
	unsigned char lane_cnt[16];

	memset(dpcd_rev, 0, 16);
	memset(lane_bw, 0, 16);
	memset(lane_cnt, 0, 16);
	memset(buf, 0, 12);

	retry_cnt = 5;
	while (retry_cnt) {
		/* Read DPCD 0x0000-0x000b */
		ret = exynos_dp_read_bytes_from_dpcd(regs, DPCD_DPCD_REV, 12,
						     buf);
		if (ret != EXYNOS_DP_SUCCESS) {
			if (retry_cnt == 0) {
				printf("DP read_byte_from_dpcd() failed\n");
				return ret;
			}
			retry_cnt--;
		} else
			break;
	}

	/* */
	temp = buf[DPCD_DPCD_REV];
	if (temp == DP_DPCD_REV_10 || temp == DP_DPCD_REV_11)
		priv->dpcd_rev = temp;
	else {
		printf("DP Wrong DPCD Rev : %x\n", temp);
		return -ENODEV;
	}

	temp = buf[DPCD_MAX_LINK_RATE];
	if (temp == DP_LANE_BW_1_62 || temp == DP_LANE_BW_2_70)
		priv->lane_bw = temp;
	else {
		printf("DP Wrong MAX LINK RATE : %x\n", temp);
		return -EINVAL;
	}

	/* Refer VESA Display Port Standard Ver1.1a Page 120 */
	if (priv->dpcd_rev == DP_DPCD_REV_11) {
		temp = buf[DPCD_MAX_LANE_COUNT] & 0x1f;
		if (buf[DPCD_MAX_LANE_COUNT] & 0x80)
			priv->dpcd_efc = 1;
		else
			priv->dpcd_efc = 0;
	} else {
		temp = buf[DPCD_MAX_LANE_COUNT];
		priv->dpcd_efc = 0;
	}

	if (temp == DP_LANE_CNT_1 || temp == DP_LANE_CNT_2 ||
			temp == DP_LANE_CNT_4) {
		priv->lane_cnt = temp;
	} else {
		printf("DP Wrong MAX LANE COUNT : %x\n", temp);
		return -EINVAL;
	}

	ret = exynos_dp_read_edid(regs);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP exynos_dp_read_edid() failed\n");
		return -EINVAL;
	}

	return ret;
}

static void exynos_dp_init_training(struct exynos_dp *regs)
{
	/*
	 * MACRO_RST must be applied after the PLL_LOCK to avoid
	 * the DP inter pair skew issue for at least 10 us
	 */
	exynos_dp_reset_macro(regs);

	/* All DP analog module power up */
	exynos_dp_set_analog_power_down(regs, POWER_ALL, 0);
}

static unsigned int exynos_dp_link_start(struct exynos_dp *regs,
					 struct exynos_dp_priv *priv)
{
	unsigned char buf[5];
	unsigned int ret = 0;

	debug("DP: %s was called\n", __func__);

	priv->lt_info.lt_status = DP_LT_CR;
	priv->lt_info.ep_loop = 0;
	priv->lt_info.cr_loop[0] = 0;
	priv->lt_info.cr_loop[1] = 0;
	priv->lt_info.cr_loop[2] = 0;
	priv->lt_info.cr_loop[3] = 0;

		/* Set sink to D0 (Sink Not Ready) mode. */
	ret = exynos_dp_write_byte_to_dpcd(regs, DPCD_SINK_POWER_STATE,
					   DPCD_SET_POWER_STATE_D0);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP write_dpcd_byte failed\n");
		return ret;
	}

	/* Set link rate and count as you want to establish */
	exynos_dp_set_link_bandwidth(regs, priv->lane_bw);
	exynos_dp_set_lane_count(regs, priv->lane_cnt);

	/* Setup RX configuration */
	buf[0] = priv->lane_bw;
	buf[1] = priv->lane_cnt;

	ret = exynos_dp_write_bytes_to_dpcd(regs, DPCD_LINK_BW_SET, 2, buf);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP write_dpcd_byte failed\n");
		return ret;
	}

	exynos_dp_set_lane_pre_emphasis(regs, PRE_EMPHASIS_LEVEL_0,
			priv->lane_cnt);

	/* Set training pattern 1 */
	exynos_dp_set_training_pattern(regs, TRAINING_PTN1);

	/* Set RX training pattern */
	buf[0] = DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1;

	buf[1] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 |
		DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0;
	buf[2] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 |
		DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0;
	buf[3] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 |
		DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0;
	buf[4] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 |
		DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0;

	ret = exynos_dp_write_bytes_to_dpcd(regs, DPCD_TRAINING_PATTERN_SET,
					    5, buf);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP write_dpcd_byte failed\n");
		return ret;
	}

	return ret;
}

static unsigned int exynos_dp_training_pattern_dis(struct exynos_dp *regs)
{
	unsigned int ret = EXYNOS_DP_SUCCESS;

	exynos_dp_set_training_pattern(regs, DP_NONE);

	ret = exynos_dp_write_byte_to_dpcd(regs, DPCD_TRAINING_PATTERN_SET,
					   DPCD_TRAINING_PATTERN_DISABLED);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP request_link_training_req failed\n");
		return -EAGAIN;
	}

	return ret;
}

static unsigned int exynos_dp_enable_rx_to_enhanced_mode(
		struct exynos_dp *regs, unsigned char enable)
{
	unsigned char data;
	unsigned int ret = EXYNOS_DP_SUCCESS;

	ret = exynos_dp_read_byte_from_dpcd(regs, DPCD_LANE_COUNT_SET,
					    &data);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP read_from_dpcd failed\n");
		return -EAGAIN;
	}

	if (enable)
		data = DPCD_ENHANCED_FRAME_EN | DPCD_LN_COUNT_SET(data);
	else
		data = DPCD_LN_COUNT_SET(data);

	ret = exynos_dp_write_byte_to_dpcd(regs, DPCD_LANE_COUNT_SET, data);
	if (ret != EXYNOS_DP_SUCCESS) {
			printf("DP write_to_dpcd failed\n");
			return -EAGAIN;

	}

	return ret;
}

static unsigned int exynos_dp_set_enhanced_mode(struct exynos_dp *regs,
						unsigned char enhance_mode)
{
	unsigned int ret = EXYNOS_DP_SUCCESS;

	ret = exynos_dp_enable_rx_to_enhanced_mode(regs, enhance_mode);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP rx_enhance_mode failed\n");
		return -EAGAIN;
	}

	exynos_dp_enable_enhanced_mode(regs, enhance_mode);

	return ret;
}

static int exynos_dp_read_dpcd_lane_stat(struct exynos_dp *regs,
					 struct exynos_dp_priv *priv,
					 unsigned char *status)
{
	unsigned int ret, i;
	unsigned char buf[2];
	unsigned char lane_stat[DP_LANE_CNT_4] = {0,};
	unsigned char shift_val[DP_LANE_CNT_4] = {0,};

	shift_val[0] = 0;
	shift_val[1] = 4;
	shift_val[2] = 0;
	shift_val[3] = 4;

	ret = exynos_dp_read_bytes_from_dpcd(regs, DPCD_LANE0_1_STATUS, 2,
					     buf);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP read lane status failed\n");
		return ret;
	}

	for (i = 0; i < priv->lane_cnt; i++) {
		lane_stat[i] = (buf[(i / 2)] >> shift_val[i]) & 0x0f;
		if (lane_stat[0] != lane_stat[i]) {
			printf("Wrong lane status\n");
			return -EINVAL;
		}
	}

	*status = lane_stat[0];

	return ret;
}

static unsigned int exynos_dp_read_dpcd_adj_req(struct exynos_dp *regs,
		unsigned char lane_num, unsigned char *sw, unsigned char *em)
{
	unsigned int ret = EXYNOS_DP_SUCCESS;
	unsigned char buf;
	unsigned int dpcd_addr;
	unsigned char shift_val[DP_LANE_CNT_4] = {0, 4, 0, 4};

	/* lane_num value is used as array index, so this range 0 ~ 3 */
	dpcd_addr = DPCD_ADJUST_REQUEST_LANE0_1 + (lane_num / 2);

	ret = exynos_dp_read_byte_from_dpcd(regs, dpcd_addr, &buf);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP read adjust request failed\n");
		return -EAGAIN;
	}

	*sw = ((buf >> shift_val[lane_num]) & 0x03);
	*em = ((buf >> shift_val[lane_num]) & 0x0c) >> 2;

	return ret;
}

static int exynos_dp_equalizer_err_link(struct exynos_dp *regs,
					struct exynos_dp_priv *priv)
{
	int ret;

	ret = exynos_dp_training_pattern_dis(regs);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP training_pattern_disable() failed\n");
		priv->lt_info.lt_status = DP_LT_FAIL;
	}

	ret = exynos_dp_set_enhanced_mode(regs, priv->dpcd_efc);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP set_enhanced_mode() failed\n");
		priv->lt_info.lt_status = DP_LT_FAIL;
	}

	return ret;
}

static int exynos_dp_reduce_link_rate(struct exynos_dp *regs,
				      struct exynos_dp_priv *priv)
{
	int ret;

	if (priv->lane_bw == DP_LANE_BW_2_70) {
		priv->lane_bw = DP_LANE_BW_1_62;
		printf("DP Change lane bw to 1.62Gbps\n");
		priv->lt_info.lt_status = DP_LT_START;
		ret = EXYNOS_DP_SUCCESS;
	} else {
		ret = exynos_dp_training_pattern_dis(regs);
		if (ret != EXYNOS_DP_SUCCESS)
			printf("DP training_patter_disable() failed\n");

		ret = exynos_dp_set_enhanced_mode(regs, priv->dpcd_efc);
		if (ret != EXYNOS_DP_SUCCESS)
			printf("DP set_enhanced_mode() failed\n");

		priv->lt_info.lt_status = DP_LT_FAIL;
	}

	return ret;
}

static unsigned int exynos_dp_process_clock_recovery(struct exynos_dp *regs,
					struct exynos_dp_priv *priv)
{
	unsigned int ret = EXYNOS_DP_SUCCESS;
	unsigned char lane_stat;
	unsigned char lt_ctl_val[DP_LANE_CNT_4] = {0, };
	unsigned int i;
	unsigned char adj_req_sw;
	unsigned char adj_req_em;
	unsigned char buf[5];

	debug("DP: %s was called\n", __func__);
	mdelay(1);

	ret = exynos_dp_read_dpcd_lane_stat(regs, priv, &lane_stat);
	if (ret != EXYNOS_DP_SUCCESS) {
			printf("DP read lane status failed\n");
			priv->lt_info.lt_status = DP_LT_FAIL;
			return ret;
	}

	if (lane_stat & DP_LANE_STAT_CR_DONE) {
		debug("DP clock Recovery training succeed\n");
		exynos_dp_set_training_pattern(regs, TRAINING_PTN2);

		for (i = 0; i < priv->lane_cnt; i++) {
			ret = exynos_dp_read_dpcd_adj_req(regs, i,
						&adj_req_sw, &adj_req_em);
			if (ret != EXYNOS_DP_SUCCESS) {
				priv->lt_info.lt_status = DP_LT_FAIL;
				return ret;
			}

			lt_ctl_val[i] = 0;
			lt_ctl_val[i] = adj_req_em << 3 | adj_req_sw;

			if ((adj_req_sw == VOLTAGE_LEVEL_3)
				|| (adj_req_em == PRE_EMPHASIS_LEVEL_3)) {
				lt_ctl_val[i] |= MAX_DRIVE_CURRENT_REACH_3 |
					MAX_PRE_EMPHASIS_REACH_3;
			}
			exynos_dp_set_lanex_pre_emphasis(regs,
							 lt_ctl_val[i], i);
		}

		buf[0] =  DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_2;
		buf[1] = lt_ctl_val[0];
		buf[2] = lt_ctl_val[1];
		buf[3] = lt_ctl_val[2];
		buf[4] = lt_ctl_val[3];

		ret = exynos_dp_write_bytes_to_dpcd(regs,
				DPCD_TRAINING_PATTERN_SET, 5, buf);
		if (ret != EXYNOS_DP_SUCCESS) {
			printf("DP write training pattern1 failed\n");
			priv->lt_info.lt_status = DP_LT_FAIL;
			return ret;
		} else
			priv->lt_info.lt_status = DP_LT_ET;
	} else {
		for (i = 0; i < priv->lane_cnt; i++) {
			lt_ctl_val[i] = exynos_dp_get_lanex_pre_emphasis(
						regs, i);
				ret = exynos_dp_read_dpcd_adj_req(regs, i,
						&adj_req_sw, &adj_req_em);
			if (ret != EXYNOS_DP_SUCCESS) {
				printf("DP read adj req failed\n");
				priv->lt_info.lt_status = DP_LT_FAIL;
				return ret;
			}

			if ((adj_req_sw == VOLTAGE_LEVEL_3) ||
					(adj_req_em == PRE_EMPHASIS_LEVEL_3))
				ret = exynos_dp_reduce_link_rate(regs,
								 priv);

			if ((DRIVE_CURRENT_SET_0_GET(lt_ctl_val[i]) ==
						adj_req_sw) &&
				(PRE_EMPHASIS_SET_0_GET(lt_ctl_val[i]) ==
						adj_req_em)) {
				priv->lt_info.cr_loop[i]++;
				if (priv->lt_info.cr_loop[i] == MAX_CR_LOOP)
					ret = exynos_dp_reduce_link_rate(
							regs, priv);
			}

			lt_ctl_val[i] = 0;
			lt_ctl_val[i] = adj_req_em << 3 | adj_req_sw;

			if ((adj_req_sw == VOLTAGE_LEVEL_3) ||
					(adj_req_em == PRE_EMPHASIS_LEVEL_3)) {
				lt_ctl_val[i] |= MAX_DRIVE_CURRENT_REACH_3 |
					MAX_PRE_EMPHASIS_REACH_3;
			}
			exynos_dp_set_lanex_pre_emphasis(regs,
							 lt_ctl_val[i], i);
		}

		ret = exynos_dp_write_bytes_to_dpcd(regs,
				DPCD_TRAINING_LANE0_SET, 4, lt_ctl_val);
		if (ret != EXYNOS_DP_SUCCESS) {
			printf("DP write training pattern2 failed\n");
			priv->lt_info.lt_status = DP_LT_FAIL;
			return ret;
		}
	}

	return ret;
}

static unsigned int exynos_dp_process_equalizer_training(
		struct exynos_dp *regs, struct exynos_dp_priv *priv)
{
	unsigned int ret = EXYNOS_DP_SUCCESS;
	unsigned char lane_stat, adj_req_sw, adj_req_em, i;
	unsigned char lt_ctl_val[DP_LANE_CNT_4] = {0,};
	unsigned char interlane_aligned = 0;
	unsigned char f_bw;
	unsigned char f_lane_cnt;
	unsigned char sink_stat;

	mdelay(1);

	ret = exynos_dp_read_dpcd_lane_stat(regs, priv, &lane_stat);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP read lane status failed\n");
		priv->lt_info.lt_status = DP_LT_FAIL;
		return ret;
	}

	debug("DP lane stat : %x\n", lane_stat);

	if (lane_stat & DP_LANE_STAT_CR_DONE) {
		ret = exynos_dp_read_byte_from_dpcd(regs,
						    DPCD_LN_ALIGN_UPDATED,
						    &sink_stat);
		if (ret != EXYNOS_DP_SUCCESS) {
			priv->lt_info.lt_status = DP_LT_FAIL;

			return ret;
		}

		interlane_aligned = (sink_stat & DPCD_INTERLANE_ALIGN_DONE);

		for (i = 0; i < priv->lane_cnt; i++) {
			ret = exynos_dp_read_dpcd_adj_req(regs, i,
					&adj_req_sw, &adj_req_em);
			if (ret != EXYNOS_DP_SUCCESS) {
				printf("DP read adj req 1 failed\n");
				priv->lt_info.lt_status = DP_LT_FAIL;

				return ret;
			}

			lt_ctl_val[i] = 0;
			lt_ctl_val[i] = adj_req_em << 3 | adj_req_sw;

			if ((adj_req_sw == VOLTAGE_LEVEL_3) ||
				(adj_req_em == PRE_EMPHASIS_LEVEL_3)) {
				lt_ctl_val[i] |= MAX_DRIVE_CURRENT_REACH_3;
				lt_ctl_val[i] |= MAX_PRE_EMPHASIS_REACH_3;
			}
		}

		if (((lane_stat&DP_LANE_STAT_CE_DONE) &&
			(lane_stat&DP_LANE_STAT_SYM_LOCK))
			&& (interlane_aligned == DPCD_INTERLANE_ALIGN_DONE)) {
			debug("DP Equalizer training succeed\n");

			f_bw = exynos_dp_get_link_bandwidth(regs);
			f_lane_cnt = exynos_dp_get_lane_count(regs);

			debug("DP final BandWidth : %x\n", f_bw);
			debug("DP final Lane Count : %x\n", f_lane_cnt);

			priv->lt_info.lt_status = DP_LT_FINISHED;

			exynos_dp_equalizer_err_link(regs, priv);

		} else {
			priv->lt_info.ep_loop++;

			if (priv->lt_info.ep_loop > MAX_EQ_LOOP) {
				if (priv->lane_bw == DP_LANE_BW_2_70) {
					ret = exynos_dp_reduce_link_rate(
							regs, priv);
				} else {
					priv->lt_info.lt_status =
								DP_LT_FAIL;
					exynos_dp_equalizer_err_link(regs,
								     priv);
				}
			} else {
				for (i = 0; i < priv->lane_cnt; i++)
					exynos_dp_set_lanex_pre_emphasis(
						regs, lt_ctl_val[i], i);

				ret = exynos_dp_write_bytes_to_dpcd(regs,
						DPCD_TRAINING_LANE0_SET,
						4, lt_ctl_val);
				if (ret != EXYNOS_DP_SUCCESS) {
					printf("DP set lt pattern failed\n");
					priv->lt_info.lt_status =
								DP_LT_FAIL;
					exynos_dp_equalizer_err_link(regs,
								     priv);
				}
			}
		}
	} else if (priv->lane_bw == DP_LANE_BW_2_70) {
		ret = exynos_dp_reduce_link_rate(regs, priv);
	} else {
		priv->lt_info.lt_status = DP_LT_FAIL;
		exynos_dp_equalizer_err_link(regs, priv);
	}

	return ret;
}

static unsigned int exynos_dp_sw_link_training(struct exynos_dp *regs,
					       struct exynos_dp_priv *priv)
{
	unsigned int ret = 0;
	int training_finished;

	/* Turn off unnecessary lane */
	if (priv->lane_cnt == 1)
		exynos_dp_set_analog_power_down(regs, CH1_BLOCK, 1);

	training_finished = 0;

	priv->lt_info.lt_status = DP_LT_START;

	/* Process here */
	while (!training_finished) {
		switch (priv->lt_info.lt_status) {
		case DP_LT_START:
			ret = exynos_dp_link_start(regs, priv);
			if (ret != EXYNOS_DP_SUCCESS) {
				printf("DP LT:link start failed\n");
				return ret;
			}
			break;
		case DP_LT_CR:
			ret = exynos_dp_process_clock_recovery(regs,
							       priv);
			if (ret != EXYNOS_DP_SUCCESS) {
				printf("DP LT:clock recovery failed\n");
				return ret;
			}
			break;
		case DP_LT_ET:
			ret = exynos_dp_process_equalizer_training(regs,
								   priv);
			if (ret != EXYNOS_DP_SUCCESS) {
				printf("DP LT:equalizer training failed\n");
				return ret;
			}
			break;
		case DP_LT_FINISHED:
			training_finished = 1;
			break;
		case DP_LT_FAIL:
			return -1;
		}
	}

	return ret;
}

static unsigned int exynos_dp_set_link_train(struct exynos_dp *regs,
					     struct exynos_dp_priv *priv)
{
	unsigned int ret;

	exynos_dp_init_training(regs);

	ret = exynos_dp_sw_link_training(regs, priv);
	if (ret != EXYNOS_DP_SUCCESS)
		printf("DP dp_sw_link_training() failed\n");

	return ret;
}

static void exynos_dp_enable_scramble(struct exynos_dp *regs,
				      unsigned int enable)
{
	unsigned char data;

	if (enable) {
		exynos_dp_enable_scrambling(regs, DP_ENABLE);

		exynos_dp_read_byte_from_dpcd(regs,
					      DPCD_TRAINING_PATTERN_SET, &data);
		exynos_dp_write_byte_to_dpcd(regs, DPCD_TRAINING_PATTERN_SET,
			(u8)(data & ~DPCD_SCRAMBLING_DISABLED));
	} else {
		exynos_dp_enable_scrambling(regs, DP_DISABLE);
		exynos_dp_read_byte_from_dpcd(regs,
					      DPCD_TRAINING_PATTERN_SET, &data);
		exynos_dp_write_byte_to_dpcd(regs, DPCD_TRAINING_PATTERN_SET,
			(u8)(data | DPCD_SCRAMBLING_DISABLED));
	}
}

static unsigned int exynos_dp_config_video(struct exynos_dp *regs,
					   struct exynos_dp_priv *priv)
{
	unsigned int ret = 0;
	unsigned int retry_cnt;

	mdelay(1);

	if (priv->video_info.master_mode) {
		printf("DP does not support master mode\n");
		return -ENODEV;
	} else {
		/* debug slave */
		exynos_dp_config_video_slave_mode(regs,
						  &priv->video_info);
	}

	exynos_dp_set_video_color_format(regs, &priv->video_info);

	if (priv->video_info.bist_mode) {
		if (exynos_dp_config_video_bist(regs, priv) != 0)
			return -1;
	}

	ret = exynos_dp_get_pll_lock_status(regs);
	if (ret != PLL_LOCKED) {
		printf("DP PLL is not locked yet\n");
		return -EIO;
	}

	if (priv->video_info.master_mode == 0) {
		retry_cnt = 10;
		while (retry_cnt) {
			ret = exynos_dp_is_slave_video_stream_clock_on(regs);
			if (ret != EXYNOS_DP_SUCCESS) {
				if (retry_cnt == 0) {
					printf("DP stream_clock_on failed\n");
					return ret;
				}
				retry_cnt--;
				mdelay(1);
			} else
				break;
		}
	}

	/* Set to use the register calculated M/N video */
	exynos_dp_set_video_cr_mn(regs, CALCULATED_M, 0, 0);

	/* For video bist, Video timing must be generated by register */
	exynos_dp_set_video_timing_mode(regs, VIDEO_TIMING_FROM_CAPTURE);

	/* Enable video bist */
	if (priv->video_info.bist_pattern != COLOR_RAMP &&
		priv->video_info.bist_pattern != BALCK_WHITE_V_LINES &&
		priv->video_info.bist_pattern != COLOR_SQUARE)
		exynos_dp_enable_video_bist(regs,
					    priv->video_info.bist_mode);
	else
		exynos_dp_enable_video_bist(regs, DP_DISABLE);

	/* Disable video mute */
	exynos_dp_enable_video_mute(regs, DP_DISABLE);

	/* Configure video Master or Slave mode */
	exynos_dp_enable_video_master(regs,
				      priv->video_info.master_mode);

	/* Enable video */
	exynos_dp_start_video(regs);

	if (priv->video_info.master_mode == 0) {
		retry_cnt = 100;
		while (retry_cnt) {
			ret = exynos_dp_is_video_stream_on(regs);
			if (ret != EXYNOS_DP_SUCCESS) {
				if (retry_cnt == 0) {
					printf("DP Timeout of video stream\n");
					return ret;
				}
				retry_cnt--;
				mdelay(5);
			} else
				break;
		}
	}

	return ret;
}

static int exynos_dp_ofdata_to_platdata(struct udevice *dev)
{
	struct exynos_dp_priv *priv = dev_get_priv(dev);
	const void *blob = gd->fdt_blob;
	unsigned int node = dev->of_offset;
	fdt_addr_t addr;

	addr = dev_get_addr(dev);
	if (addr == FDT_ADDR_T_NONE) {
		debug("Can't get the DP base address\n");
		return -EINVAL;
	}
	priv->regs = (struct exynos_dp *)addr;
	priv->disp_info.h_res = fdtdec_get_int(blob, node,
							"samsung,h-res", 0);
	priv->disp_info.h_sync_width = fdtdec_get_int(blob, node,
						"samsung,h-sync-width", 0);
	priv->disp_info.h_back_porch = fdtdec_get_int(blob, node,
						"samsung,h-back-porch", 0);
	priv->disp_info.h_front_porch = fdtdec_get_int(blob, node,
						"samsung,h-front-porch", 0);
	priv->disp_info.v_res = fdtdec_get_int(blob, node,
						"samsung,v-res", 0);
	priv->disp_info.v_sync_width = fdtdec_get_int(blob, node,
						"samsung,v-sync-width", 0);
	priv->disp_info.v_back_porch = fdtdec_get_int(blob, node,
						"samsung,v-back-porch", 0);
	priv->disp_info.v_front_porch = fdtdec_get_int(blob, node,
						"samsung,v-front-porch", 0);
	priv->disp_info.v_sync_rate = fdtdec_get_int(blob, node,
						"samsung,v-sync-rate", 0);

	priv->lt_info.lt_status = fdtdec_get_int(blob, node,
						"samsung,lt-status", 0);

	priv->video_info.master_mode = fdtdec_get_int(blob, node,
						"samsung,master-mode", 0);
	priv->video_info.bist_mode = fdtdec_get_int(blob, node,
						"samsung,bist-mode", 0);
	priv->video_info.bist_pattern = fdtdec_get_int(blob, node,
						"samsung,bist-pattern", 0);
	priv->video_info.h_sync_polarity = fdtdec_get_int(blob, node,
						"samsung,h-sync-polarity", 0);
	priv->video_info.v_sync_polarity = fdtdec_get_int(blob, node,
						"samsung,v-sync-polarity", 0);
	priv->video_info.interlaced = fdtdec_get_int(blob, node,
						"samsung,interlaced", 0);
	priv->video_info.color_space = fdtdec_get_int(blob, node,
						"samsung,color-space", 0);
	priv->video_info.dynamic_range = fdtdec_get_int(blob, node,
						"samsung,dynamic-range", 0);
	priv->video_info.ycbcr_coeff = fdtdec_get_int(blob, node,
						"samsung,ycbcr-coeff", 0);
	priv->video_info.color_depth = fdtdec_get_int(blob, node,
						"samsung,color-depth", 0);
	return 0;
}

static int exynos_dp_bridge_init(struct udevice *dev)
{
	const int max_tries = 10;
	int num_tries;
	int ret;

	debug("%s\n", __func__);
	ret = video_bridge_attach(dev);
	if (ret) {
		debug("video bridge init failed: %d\n", ret);
		return ret;
	}

	/*
	 * We need to wait for 90ms after bringing up the bridge since there
	 * is a phantom "high" on the HPD chip during its bootup.  The phantom
	 * high comes within 7ms of de-asserting PD and persists for at least
	 * 15ms.  The real high comes roughly 50ms after PD is de-asserted. The
	 * phantom high makes it hard for us to know when the NXP chip is up.
	 */
	mdelay(90);

	for (num_tries = 0; num_tries < max_tries; num_tries++) {
		/* Check HPD. If it's high, or we don't have it, all is well */
		ret = video_bridge_check_attached(dev);
		if (!ret || ret == -ENOENT)
			return 0;

		debug("%s: eDP bridge failed to come up; try %d of %d\n",
		      __func__, num_tries, max_tries);
	}

	/* Immediately go into bridge reset if the hp line is not high */
	return -EIO;
}

static int exynos_dp_bridge_setup(const void *blob)
{
	const int max_tries = 2;
	int num_tries;
	struct udevice *dev;
	int ret;

	/* Configure I2C registers for Parade bridge */
	ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &dev);
	if (ret) {
		debug("video bridge init failed: %d\n", ret);
		return ret;
	}

	if (strncmp(dev->driver->name, "parade", 6)) {
		/* Mux HPHPD to the special hotplug detect mode */
		exynos_pinmux_config(PERIPH_ID_DPHPD, 0);
	}

	for (num_tries = 0; num_tries < max_tries; num_tries++) {
		ret = exynos_dp_bridge_init(dev);
		if (!ret)
			return 0;
		if (num_tries == max_tries - 1)
			break;

		/*
		* If we're here, the bridge chip failed to initialise.
		* Power down the bridge in an attempt to reset.
		*/
		video_bridge_set_active(dev, false);

		/*
		* Arbitrarily wait 300ms here with DP_N low.  Don't know for
		* sure how long we should wait, but we're being paranoid.
		*/
		mdelay(300);
	}

	return ret;
}
int exynos_dp_enable(struct udevice *dev, int panel_bpp,
		     const struct display_timing *timing)
{
	struct exynos_dp_priv *priv = dev_get_priv(dev);
	struct exynos_dp *regs = priv->regs;
	unsigned int ret;

	debug("%s: start\n", __func__);
	exynos_dp_disp_info(&priv->disp_info);

	ret = exynos_dp_bridge_setup(gd->fdt_blob);
	if (ret && ret != -ENODEV)
		printf("LCD bridge failed to enable: %d\n", ret);

	exynos_dp_phy_ctrl(1);

	ret = exynos_dp_init_dp(regs);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP exynos_dp_init_dp() failed\n");
		return ret;
	}

	ret = exynos_dp_handle_edid(regs, priv);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("EDP handle_edid fail\n");
		return ret;
	}

	ret = exynos_dp_set_link_train(regs, priv);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP link training fail\n");
		return ret;
	}

	exynos_dp_enable_scramble(regs, DP_ENABLE);
	exynos_dp_enable_rx_to_enhanced_mode(regs, DP_ENABLE);
	exynos_dp_enable_enhanced_mode(regs, DP_ENABLE);

	exynos_dp_set_link_bandwidth(regs, priv->lane_bw);
	exynos_dp_set_lane_count(regs, priv->lane_cnt);

	exynos_dp_init_video(regs);
	ret = exynos_dp_config_video(regs, priv);
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("Exynos DP init failed\n");
		return ret;
	}

	debug("Exynos DP init done\n");

	return ret;
}


static const struct dm_display_ops exynos_dp_ops = {
	.enable = exynos_dp_enable,
};

static const struct udevice_id exynos_dp_ids[] = {
	{ .compatible = "samsung,exynos5-dp" },
	{ }
};

U_BOOT_DRIVER(exynos_dp) = {
	.name	= "eexynos_dp",
	.id	= UCLASS_DISPLAY,
	.of_match = exynos_dp_ids,
	.ops	= &exynos_dp_ops,
	.ofdata_to_platdata	= exynos_dp_ofdata_to_platdata,
	.priv_auto_alloc_size	= sizeof(struct exynos_dp_priv),
};
