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

#include <dm.h>
#include <display.h>
#include <fdtdec.h>
#include <log.h>
#include <asm/global_data.h>
#include <linux/delay.h>
#include <linux/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_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;

	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;

	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;
	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;
	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;
	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_of_to_plat(struct udevice *dev)
{
	struct exynos_dp_priv *priv = dev_get_priv(dev);
	const void *blob = gd->fdt_blob;
	unsigned int node = dev_of_offset(dev);
	fdt_addr_t addr;

	addr = dev_read_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	= "exynos_dp",
	.id	= UCLASS_DISPLAY,
	.of_match = exynos_dp_ids,
	.ops	= &exynos_dp_ops,
	.of_to_plat	= exynos_dp_of_to_plat,
	.priv_auto	= sizeof(struct exynos_dp_priv),
};
