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

#include <config.h>
#include <common.h>
#include <linux/err.h>
#include <asm/arch/cpu.h>
#include <asm/arch/dp_info.h>
#include <asm/arch/dp.h>
#include <fdtdec.h>
#include <libfdt.h>

/* Declare global data pointer */
DECLARE_GLOBAL_DATA_PTR;

struct exynos_dp *dp_regs;

void exynos_dp_set_base_addr(void)
{
#ifdef CONFIG_OF_CONTROL
	unsigned int node = fdtdec_next_compatible(gd->fdt_blob,
					0, COMPAT_SAMSUNG_EXYNOS5_DP);
	if (node <= 0)
		debug("exynos_dp: Can't get device node for dp\n");

	dp_regs = (struct exynos_dp *)fdtdec_get_addr(gd->fdt_blob,
								node, "reg");
	if (dp_regs == NULL)
		debug("Can't get the DP base address\n");
#else
	dp_regs = (struct exynos_dp *)samsung_get_base_dp();
#endif
}

static void exynos_dp_enable_video_input(unsigned int enable)
{
	unsigned int reg;

	reg = readl(&dp_regs->video_ctl1);
	reg &= ~VIDEO_EN_MASK;

	/* enable video input*/
	if (enable)
		reg |= VIDEO_EN_MASK;

	writel(reg, &dp_regs->video_ctl1);

	return;
}

void exynos_dp_enable_video_bist(unsigned int enable)
{
	/*enable video bist*/
	unsigned int reg;

	reg = readl(&dp_regs->video_ctl4);
	reg &= ~VIDEO_BIST_MASK;

	/*enable video bist*/
	if (enable)
		reg |= VIDEO_BIST_MASK;

	writel(reg, &dp_regs->video_ctl4);

	return;
}

void exynos_dp_enable_video_mute(unsigned int enable)
{
	unsigned int reg;

	reg = readl(&dp_regs->video_ctl1);
	reg &= ~(VIDEO_MUTE_MASK);
	if (enable)
		reg |= VIDEO_MUTE_MASK;

	writel(reg, &dp_regs->video_ctl1);

	return;
}


static void exynos_dp_init_analog_param(void)
{
	unsigned int reg;

	/*
	 * Set termination
	 * Normal bandgap, Normal swing, Tx terminal registor 61 ohm
	 * 24M Phy clock, TX digital logic power is 100:1.0625V
	 */
	reg = SEL_BG_NEW_BANDGAP | TX_TERMINAL_CTRL_61_OHM |
		SWING_A_30PER_G_NORMAL;
	writel(reg, &dp_regs->analog_ctl1);

	reg = SEL_24M | TX_DVDD_BIT_1_0625V;
	writel(reg, &dp_regs->analog_ctl2);

	/*
	 * Set power source for internal clk driver to 1.0625v.
	 * Select current reference of TX driver current to 00:Ipp/2+Ic/2.
	 * Set VCO range of PLL +- 0uA
	 */
	reg = DRIVE_DVDD_BIT_1_0625V | SEL_CURRENT_DEFAULT | VCO_BIT_000_MICRO;
	writel(reg, &dp_regs->analog_ctl3);

	/*
	 * Set AUX TX terminal resistor to 102 ohm
	 * Set AUX channel amplitude control
	*/
	reg = PD_RING_OSC | AUX_TERMINAL_CTRL_52_OHM | TX_CUR1_2X | TX_CUR_4_MA;
	writel(reg, &dp_regs->pll_filter_ctl1);

	/*
	 * PLL loop filter bandwidth
	 * For 2.7Gbps: 175KHz, For 1.62Gbps: 234KHz
	 * PLL digital power select: 1.2500V
	 */
	reg = CH3_AMP_0_MV | CH2_AMP_0_MV | CH1_AMP_0_MV | CH0_AMP_0_MV;

	writel(reg, &dp_regs->amp_tuning_ctl);

	/*
	 * PLL loop filter bandwidth
	 * For 2.7Gbps: 175KHz, For 1.62Gbps: 234KHz
	 * PLL digital power select: 1.1250V
	 */
	reg = DP_PLL_LOOP_BIT_DEFAULT | DP_PLL_REF_BIT_1_1250V;
	writel(reg, &dp_regs->pll_ctl);
}

static void exynos_dp_init_interrupt(void)
{
	/* Set interrupt registers to initial states */

	/*
	 * Disable interrupt
	 * INT pin assertion polarity. It must be configured
	 * correctly according to ICU setting.
	 * 1 = assert high, 0 = assert low
	 */
	writel(INT_POL, &dp_regs->int_ctl);

	/* Clear pending regisers */
	writel(0xff, &dp_regs->common_int_sta1);
	writel(0xff, &dp_regs->common_int_sta2);
	writel(0xff, &dp_regs->common_int_sta3);
	writel(0xff, &dp_regs->common_int_sta4);
	writel(0xff, &dp_regs->int_sta);

	/* 0:mask,1: unmask */
	writel(0x00, &dp_regs->int_sta_mask1);
	writel(0x00, &dp_regs->int_sta_mask2);
	writel(0x00, &dp_regs->int_sta_mask3);
	writel(0x00, &dp_regs->int_sta_mask4);
	writel(0x00, &dp_regs->int_sta_mask);
}

void exynos_dp_reset(void)
{
	unsigned int reg_func_1;

	/*dp tx sw reset*/
	writel(RESET_DP_TX, &dp_regs->tx_sw_reset);

	exynos_dp_enable_video_input(DP_DISABLE);
	exynos_dp_enable_video_bist(DP_DISABLE);
	exynos_dp_enable_video_mute(DP_DISABLE);

	/* software reset */
	reg_func_1 = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
		AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
		HDCP_FUNC_EN_N | SW_FUNC_EN_N;

	writel(reg_func_1, &dp_regs->func_en1);
	writel(reg_func_1, &dp_regs->func_en2);

	mdelay(1);

	exynos_dp_init_analog_param();
	exynos_dp_init_interrupt();

	return;
}

void exynos_dp_enable_sw_func(unsigned int enable)
{
	unsigned int reg;

	reg = readl(&dp_regs->func_en1);
	reg &= ~(SW_FUNC_EN_N);

	if (!enable)
		reg |= SW_FUNC_EN_N;

	writel(reg, &dp_regs->func_en1);

	return;
}

unsigned int exynos_dp_set_analog_power_down(unsigned int block, u32 enable)
{
	unsigned int reg;

	reg = readl(&dp_regs->phy_pd);
	switch (block) {
	case AUX_BLOCK:
		reg &= ~(AUX_PD);
		if (enable)
			reg |= AUX_PD;
		break;
	case CH0_BLOCK:
		reg &= ~(CH0_PD);
		if (enable)
			reg |= CH0_PD;
		break;
	case CH1_BLOCK:
		reg &= ~(CH1_PD);
		if (enable)
			reg |= CH1_PD;
		break;
	case CH2_BLOCK:
		reg &= ~(CH2_PD);
		if (enable)
			reg |= CH2_PD;
		break;
	case CH3_BLOCK:
		reg &= ~(CH3_PD);
		if (enable)
			reg |= CH3_PD;
		break;
	case ANALOG_TOTAL:
		reg &= ~PHY_PD;
		if (enable)
			reg |= PHY_PD;
		break;
	case POWER_ALL:
		reg &= ~(PHY_PD | AUX_PD | CH0_PD | CH1_PD | CH2_PD |
			CH3_PD);
		if (enable)
			reg |= (PHY_PD | AUX_PD | CH0_PD | CH1_PD |
				CH2_PD | CH3_PD);
		break;
	default:
		printf("DP undefined block number : %d\n",  block);
		return -1;
	}

	writel(reg, &dp_regs->phy_pd);

	return 0;
}

unsigned int exynos_dp_get_pll_lock_status(void)
{
	unsigned int reg;

	reg = readl(&dp_regs->debug_ctl);

	if (reg & PLL_LOCK)
		return PLL_LOCKED;
	else
		return PLL_UNLOCKED;
}

static void exynos_dp_set_pll_power(unsigned int enable)
{
	unsigned int reg;

	reg = readl(&dp_regs->pll_ctl);
	reg &= ~(DP_PLL_PD);

	if (!enable)
		reg |= DP_PLL_PD;

	writel(reg, &dp_regs->pll_ctl);
}

int exynos_dp_init_analog_func(void)
{
	int ret = EXYNOS_DP_SUCCESS;
	unsigned int retry_cnt = 10;
	unsigned int reg;

	/*Power On All Analog block */
	exynos_dp_set_analog_power_down(POWER_ALL, DP_DISABLE);

	reg = PLL_LOCK_CHG;
	writel(reg, &dp_regs->common_int_sta1);

	reg = readl(&dp_regs->debug_ctl);
	reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
	writel(reg, &dp_regs->debug_ctl);

	/*Assert DP PLL Reset*/
	reg = readl(&dp_regs->pll_ctl);
	reg |= DP_PLL_RESET;
	writel(reg, &dp_regs->pll_ctl);

	mdelay(1);

	/*Deassert DP PLL Reset*/
	reg = readl(&dp_regs->pll_ctl);
	reg &= ~(DP_PLL_RESET);
	writel(reg, &dp_regs->pll_ctl);

	exynos_dp_set_pll_power(DP_ENABLE);

	while (exynos_dp_get_pll_lock_status() == PLL_UNLOCKED) {
		mdelay(1);
		retry_cnt--;
		if (retry_cnt == 0) {
			printf("DP dp's pll lock failed : retry : %d\n",
					retry_cnt);
			return -EINVAL;
		}
	}

	debug("dp's pll lock success(%d)\n", retry_cnt);

	/* Enable Serdes FIFO function and Link symbol clock domain module */
	reg = readl(&dp_regs->func_en2);
	reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
		| AUX_FUNC_EN_N);
	writel(reg, &dp_regs->func_en2);

	return ret;
}

void exynos_dp_init_hpd(void)
{
	unsigned int reg;

	/* Clear interrupts releated to Hot Plug Dectect */
	reg = HOTPLUG_CHG | HPD_LOST | PLUG;
	writel(reg, &dp_regs->common_int_sta4);

	reg = INT_HPD;
	writel(reg, &dp_regs->int_sta);

	reg = readl(&dp_regs->sys_ctl3);
	reg &= ~(F_HPD | HPD_CTRL);
	writel(reg, &dp_regs->sys_ctl3);

	return;
}

static inline void exynos_dp_reset_aux(void)
{
	unsigned int reg;

	/* Disable AUX channel module */
	reg = readl(&dp_regs->func_en2);
	reg |= AUX_FUNC_EN_N;
	writel(reg, &dp_regs->func_en2);

	return;
}

void exynos_dp_init_aux(void)
{
	unsigned int reg;

	/* Clear inerrupts related to AUX channel */
	reg = RPLY_RECEIV | AUX_ERR;
	writel(reg, &dp_regs->int_sta);

	exynos_dp_reset_aux();

	/* Disable AUX transaction H/W retry */
	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(3)|
		AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
	writel(reg, &dp_regs->aux_hw_retry_ctl);

	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
	reg = DEFER_CTRL_EN | DEFER_COUNT(1);
	writel(reg, &dp_regs->aux_ch_defer_ctl);

	/* Enable AUX channel module */
	reg = readl(&dp_regs->func_en2);
	reg &= ~AUX_FUNC_EN_N;
	writel(reg, &dp_regs->func_en2);

	return;
}

void exynos_dp_config_interrupt(void)
{
	unsigned int reg;

	/* 0: mask, 1: unmask */
	reg = COMMON_INT_MASK_1;
	writel(reg, &dp_regs->common_int_mask1);

	reg = COMMON_INT_MASK_2;
	writel(reg, &dp_regs->common_int_mask2);

	reg = COMMON_INT_MASK_3;
	writel(reg, &dp_regs->common_int_mask3);

	reg = COMMON_INT_MASK_4;
	writel(reg, &dp_regs->common_int_mask4);

	reg = INT_STA_MASK;
	writel(reg, &dp_regs->int_sta_mask);

	return;
}

unsigned int exynos_dp_get_plug_in_status(void)
{
	unsigned int reg;

	reg = readl(&dp_regs->sys_ctl3);
	if (reg & HPD_STATUS)
		return 0;

	return -1;
}

unsigned int exynos_dp_detect_hpd(void)
{
	int timeout_loop = DP_TIMEOUT_LOOP_COUNT;

	mdelay(2);

	while (exynos_dp_get_plug_in_status() != 0) {
		if (timeout_loop == 0)
			return -EINVAL;
		mdelay(10);
		timeout_loop--;
	}

	return EXYNOS_DP_SUCCESS;
}

unsigned int exynos_dp_start_aux_transaction(void)
{
	unsigned int reg;
	unsigned int ret = 0;
	unsigned int retry_cnt;

	/* Enable AUX CH operation */
	reg = readl(&dp_regs->aux_ch_ctl2);
	reg |= AUX_EN;
	writel(reg, &dp_regs->aux_ch_ctl2);

	retry_cnt = 10;
	while (retry_cnt) {
		reg = readl(&dp_regs->int_sta);
		if (!(reg & RPLY_RECEIV)) {
			if (retry_cnt == 0) {
				printf("DP Reply Timeout!!\n");
				ret = -EAGAIN;
				return ret;
			}
			mdelay(1);
			retry_cnt--;
		} else
			break;
	}

	/* Clear interrupt source for AUX CH command reply */
	writel(reg, &dp_regs->int_sta);

	/* Clear interrupt source for AUX CH access error */
	reg = readl(&dp_regs->int_sta);
	if (reg & AUX_ERR) {
		printf("DP Aux Access Error\n");
		writel(AUX_ERR, &dp_regs->int_sta);
		ret = -EAGAIN;
		return ret;
	}

	/* Check AUX CH error access status */
	reg = readl(&dp_regs->aux_ch_sta);
	if ((reg & AUX_STATUS_MASK) != 0) {
		debug("DP AUX CH error happens: %x\n", reg & AUX_STATUS_MASK);
		ret = -EAGAIN;
		return ret;
	}

	return EXYNOS_DP_SUCCESS;
}

unsigned int exynos_dp_write_byte_to_dpcd(unsigned int reg_addr,
				unsigned char data)
{
	unsigned int reg, ret;

	/* Clear AUX CH data buffer */
	reg = BUF_CLR;
	writel(reg, &dp_regs->buffer_data_ctl);

	/* Select DPCD device address */
	reg = AUX_ADDR_7_0(reg_addr);
	writel(reg, &dp_regs->aux_addr_7_0);
	reg = AUX_ADDR_15_8(reg_addr);
	writel(reg, &dp_regs->aux_addr_15_8);
	reg = AUX_ADDR_19_16(reg_addr);
	writel(reg, &dp_regs->aux_addr_19_16);

	/* Write data buffer */
	reg = (unsigned int)data;
	writel(reg, &dp_regs->buf_data0);

	/*
	 * Set DisplayPort transaction and write 1 byte
	 * If bit 3 is 1, DisplayPort transaction.
	 * If Bit 3 is 0, I2C transaction.
	 */
	reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
	writel(reg, &dp_regs->aux_ch_ctl1);

	/* Start AUX transaction */
	ret = exynos_dp_start_aux_transaction();
	if (ret != EXYNOS_DP_SUCCESS) {
		printf("DP Aux transaction failed\n");
		return ret;
	}

	return ret;
}

unsigned int exynos_dp_read_byte_from_dpcd(unsigned int reg_addr,
		unsigned char *data)
{
	unsigned int reg;
	int retval;

	/* Clear AUX CH data buffer */
	reg = BUF_CLR;
	writel(reg, &dp_regs->buffer_data_ctl);

	/* Select DPCD device address */
	reg = AUX_ADDR_7_0(reg_addr);
	writel(reg, &dp_regs->aux_addr_7_0);
	reg = AUX_ADDR_15_8(reg_addr);
	writel(reg, &dp_regs->aux_addr_15_8);
	reg = AUX_ADDR_19_16(reg_addr);
	writel(reg, &dp_regs->aux_addr_19_16);

	/*
	 * Set DisplayPort transaction and read 1 byte
	 * If bit 3 is 1, DisplayPort transaction.
	 * If Bit 3 is 0, I2C transaction.
	 */
	reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
	writel(reg, &dp_regs->aux_ch_ctl1);

	/* Start AUX transaction */
	retval = exynos_dp_start_aux_transaction();
	if (!retval)
		debug("DP Aux Transaction fail!\n");

	/* Read data buffer */
	reg = readl(&dp_regs->buf_data0);
	*data = (unsigned char)(reg & 0xff);

	return retval;
}

unsigned int exynos_dp_write_bytes_to_dpcd(unsigned int reg_addr,
				unsigned int count,
				unsigned char data[])
{
	unsigned int reg;
	unsigned int start_offset;
	unsigned int cur_data_count;
	unsigned int cur_data_idx;
	unsigned int retry_cnt;
	unsigned int ret = 0;

	/* Clear AUX CH data buffer */
	reg = BUF_CLR;
	writel(reg, &dp_regs->buffer_data_ctl);

	start_offset = 0;
	while (start_offset < count) {
		/* Buffer size of AUX CH is 16 * 4bytes */
		if ((count - start_offset) > 16)
			cur_data_count = 16;
		else
			cur_data_count = count - start_offset;

		retry_cnt = 5;
		while (retry_cnt) {
			/* Select DPCD device address */
			reg = AUX_ADDR_7_0(reg_addr + start_offset);
			writel(reg, &dp_regs->aux_addr_7_0);
			reg = AUX_ADDR_15_8(reg_addr + start_offset);
			writel(reg, &dp_regs->aux_addr_15_8);
			reg = AUX_ADDR_19_16(reg_addr + start_offset);
			writel(reg, &dp_regs->aux_addr_19_16);

			for (cur_data_idx = 0; cur_data_idx < cur_data_count;
					cur_data_idx++) {
				reg = data[start_offset + cur_data_idx];
				writel(reg, (unsigned int)&dp_regs->buf_data0 +
						(4 * cur_data_idx));
			}
			/*
			* Set DisplayPort transaction and write
			* If bit 3 is 1, DisplayPort transaction.
			* If Bit 3 is 0, I2C transaction.
			*/
			reg = AUX_LENGTH(cur_data_count) |
				AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
			writel(reg, &dp_regs->aux_ch_ctl1);

			/* Start AUX transaction */
			ret = exynos_dp_start_aux_transaction();
			if (ret != EXYNOS_DP_SUCCESS) {
				if (retry_cnt == 0) {
					printf("DP Aux Transaction failed\n");
					return ret;
				}
				retry_cnt--;
			} else
				break;
		}
		start_offset += cur_data_count;
	}

	return ret;
}

unsigned int exynos_dp_read_bytes_from_dpcd(unsigned int reg_addr,
				unsigned int count,
				unsigned char data[])
{
	unsigned int reg;
	unsigned int start_offset;
	unsigned int cur_data_count;
	unsigned int cur_data_idx;
	unsigned int retry_cnt;
	unsigned int ret = 0;

	/* Clear AUX CH data buffer */
	reg = BUF_CLR;
	writel(reg, &dp_regs->buffer_data_ctl);

	start_offset = 0;
	while (start_offset < count) {
		/* Buffer size of AUX CH is 16 * 4bytes */
		if ((count - start_offset) > 16)
			cur_data_count = 16;
		else
			cur_data_count = count - start_offset;

		retry_cnt = 5;
		while (retry_cnt) {
			/* Select DPCD device address */
			reg = AUX_ADDR_7_0(reg_addr + start_offset);
			writel(reg, &dp_regs->aux_addr_7_0);
			reg = AUX_ADDR_15_8(reg_addr + start_offset);
			writel(reg, &dp_regs->aux_addr_15_8);
			reg = AUX_ADDR_19_16(reg_addr + start_offset);
			writel(reg, &dp_regs->aux_addr_19_16);
			/*
			 * Set DisplayPort transaction and read
			 * If bit 3 is 1, DisplayPort transaction.
			 * If Bit 3 is 0, I2C transaction.
			 */
			reg = AUX_LENGTH(cur_data_count) |
				AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
			writel(reg, &dp_regs->aux_ch_ctl1);

			/* Start AUX transaction */
			ret = exynos_dp_start_aux_transaction();
			if (ret != EXYNOS_DP_SUCCESS) {
				if (retry_cnt == 0) {
					printf("DP Aux Transaction failed\n");
					return ret;
				}
				retry_cnt--;
			} else
				break;
		}

		for (cur_data_idx = 0; cur_data_idx < cur_data_count;
				cur_data_idx++) {
			reg = readl((unsigned int)&dp_regs->buf_data0 +
					4 * cur_data_idx);
			data[start_offset + cur_data_idx] = (unsigned char)reg;
		}

		start_offset += cur_data_count;
	}

	return ret;
}

int exynos_dp_select_i2c_device(unsigned int device_addr,
				unsigned int reg_addr)
{
	unsigned int reg;
	int retval;

	/* Set EDID device address */
	reg = device_addr;
	writel(reg, &dp_regs->aux_addr_7_0);
	writel(0x0, &dp_regs->aux_addr_15_8);
	writel(0x0, &dp_regs->aux_addr_19_16);

	/* Set offset from base address of EDID device */
	writel(reg_addr, &dp_regs->buf_data0);

	/*
	 * Set I2C transaction and write address
	 * If bit 3 is 1, DisplayPort transaction.
	 * If Bit 3 is 0, I2C transaction.
	 */
	reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT |
		AUX_TX_COMM_WRITE;
	writel(reg, &dp_regs->aux_ch_ctl1);

	/* Start AUX transaction */
	retval = exynos_dp_start_aux_transaction();
	if (retval != 0)
		printf("%s: DP Aux Transaction fail!\n", __func__);

	return retval;
}

int exynos_dp_read_byte_from_i2c(unsigned int device_addr,
				unsigned int reg_addr,
				unsigned int *data)
{
	unsigned int reg;
	int i;
	int retval;

	for (i = 0; i < 10; i++) {
		/* Clear AUX CH data buffer */
		reg = BUF_CLR;
		writel(reg, &dp_regs->buffer_data_ctl);

		/* Select EDID device */
		retval = exynos_dp_select_i2c_device(device_addr, reg_addr);
		if (retval != 0) {
			printf("DP Select EDID device fail. retry !\n");
			continue;
		}

		/*
		 * Set I2C transaction and read data
		 * If bit 3 is 1, DisplayPort transaction.
		 * If Bit 3 is 0, I2C transaction.
		 */
		reg = AUX_TX_COMM_I2C_TRANSACTION |
			AUX_TX_COMM_READ;
		writel(reg, &dp_regs->aux_ch_ctl1);

		/* Start AUX transaction */
		retval = exynos_dp_start_aux_transaction();
		if (retval != EXYNOS_DP_SUCCESS)
			printf("%s: DP Aux Transaction fail!\n", __func__);
	}

	/* Read data */
	if (retval == 0)
		*data = readl(&dp_regs->buf_data0);

	return retval;
}

int exynos_dp_read_bytes_from_i2c(unsigned int device_addr,
		unsigned int reg_addr, unsigned int count, unsigned char edid[])
{
	unsigned int reg;
	unsigned int i, j;
	unsigned int cur_data_idx;
	unsigned int defer = 0;
	int retval = 0;

	for (i = 0; i < count; i += 16) { /* use 16 burst */
		for (j = 0; j < 100; j++) {
			/* Clear AUX CH data buffer */
			reg = BUF_CLR;
			writel(reg, &dp_regs->buffer_data_ctl);

			/* Set normal AUX CH command */
			reg = readl(&dp_regs->aux_ch_ctl2);
			reg &= ~ADDR_ONLY;
			writel(reg, &dp_regs->aux_ch_ctl2);

			/*
			 * If Rx sends defer, Tx sends only reads
			 * request without sending addres
			 */
			if (!defer)
				retval =
					exynos_dp_select_i2c_device(device_addr,
							reg_addr + i);
			else
				defer = 0;

			if (retval == EXYNOS_DP_SUCCESS) {
				/*
				 * Set I2C transaction and write data
				 * If bit 3 is 1, DisplayPort transaction.
				 * If Bit 3 is 0, I2C transaction.
				 */
				reg = AUX_LENGTH(16) |
					AUX_TX_COMM_I2C_TRANSACTION |
					AUX_TX_COMM_READ;
				writel(reg, &dp_regs->aux_ch_ctl1);

				/* Start AUX transaction */
				retval = exynos_dp_start_aux_transaction();
				if (retval == 0)
					break;
				else
					printf("DP Aux Transaction fail!\n");
			}
			/* Check if Rx sends defer */
			reg = readl(&dp_regs->aux_rx_comm);
			if (reg == AUX_RX_COMM_AUX_DEFER ||
				reg == AUX_RX_COMM_I2C_DEFER) {
				printf("DP Defer: %d\n\n", reg);
				defer = 1;
			}
		}

		for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) {
			reg = readl((unsigned int)&dp_regs->buf_data0
						 + 4 * cur_data_idx);
			edid[i + cur_data_idx] = (unsigned char)reg;
		}
	}

	return retval;
}

void exynos_dp_reset_macro(void)
{
	unsigned int reg;

	reg = readl(&dp_regs->phy_test);
	reg |= MACRO_RST;
	writel(reg, &dp_regs->phy_test);

	/* 10 us is the minimum Macro reset time. */
	mdelay(1);

	reg &= ~MACRO_RST;
	writel(reg, &dp_regs->phy_test);
}

void exynos_dp_set_link_bandwidth(unsigned char bwtype)
{
	unsigned int reg;

	reg = (unsigned int)bwtype;

	 /* Set bandwidth to 2.7G or 1.62G */
	if ((bwtype == DP_LANE_BW_1_62) || (bwtype == DP_LANE_BW_2_70))
		writel(reg, &dp_regs->link_bw_set);
}

unsigned char exynos_dp_get_link_bandwidth(void)
{
	unsigned char ret;
	unsigned int reg;

	reg = readl(&dp_regs->link_bw_set);
	ret = (unsigned char)reg;

	return ret;
}

void exynos_dp_set_lane_count(unsigned char count)
{
	unsigned int reg;

	reg = (unsigned int)count;

	if ((count == DP_LANE_CNT_1) || (count == DP_LANE_CNT_2) ||
			(count == DP_LANE_CNT_4))
		writel(reg, &dp_regs->lane_count_set);
}

unsigned int exynos_dp_get_lane_count(void)
{
	unsigned int reg;

	reg = readl(&dp_regs->lane_count_set);

	return reg;
}

unsigned char exynos_dp_get_lanex_pre_emphasis(unsigned char lanecnt)
{
	unsigned int reg_list[DP_LANE_CNT_4] = {
		(unsigned int)&dp_regs->ln0_link_training_ctl,
		(unsigned int)&dp_regs->ln1_link_training_ctl,
		(unsigned int)&dp_regs->ln2_link_training_ctl,
		(unsigned int)&dp_regs->ln3_link_training_ctl,
	};

	return readl(reg_list[lanecnt]);
}

void exynos_dp_set_lanex_pre_emphasis(unsigned char request_val,
		unsigned char lanecnt)
{
	unsigned int reg_list[DP_LANE_CNT_4] = {
		(unsigned int)&dp_regs->ln0_link_training_ctl,
		(unsigned int)&dp_regs->ln1_link_training_ctl,
		(unsigned int)&dp_regs->ln2_link_training_ctl,
		(unsigned int)&dp_regs->ln3_link_training_ctl,
	};

	writel(request_val, reg_list[lanecnt]);
}

void exynos_dp_set_lane_pre_emphasis(unsigned int level, unsigned char lanecnt)
{
	unsigned char i;
	unsigned int reg;
	unsigned int reg_list[DP_LANE_CNT_4] = {
		(unsigned int)&dp_regs->ln0_link_training_ctl,
		(unsigned int)&dp_regs->ln1_link_training_ctl,
		(unsigned int)&dp_regs->ln2_link_training_ctl,
		(unsigned int)&dp_regs->ln3_link_training_ctl,
	};
	unsigned int reg_shift[DP_LANE_CNT_4] = {
		PRE_EMPHASIS_SET_0_SHIFT,
		PRE_EMPHASIS_SET_1_SHIFT,
		PRE_EMPHASIS_SET_2_SHIFT,
		PRE_EMPHASIS_SET_3_SHIFT
	};

	for (i = 0; i < lanecnt; i++) {
		reg = level << reg_shift[i];
		writel(reg, reg_list[i]);
	}
}

void exynos_dp_set_training_pattern(unsigned int pattern)
{
	unsigned int reg = 0;

	switch (pattern) {
	case PRBS7:
		reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
		break;
	case D10_2:
		reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
		break;
	case TRAINING_PTN1:
		reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
		break;
	case TRAINING_PTN2:
		reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
		break;
	case DP_NONE:
		reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_DISABLE |
			SW_TRAINING_PATTERN_SET_NORMAL;
		break;
	default:
		break;
	}

	writel(reg, &dp_regs->training_ptn_set);
}

void exynos_dp_enable_enhanced_mode(unsigned char enable)
{
	unsigned int reg;

	reg = readl(&dp_regs->sys_ctl4);
	reg &= ~ENHANCED;

	if (enable)
		reg |= ENHANCED;

	writel(reg, &dp_regs->sys_ctl4);
}

void exynos_dp_enable_scrambling(unsigned int enable)
{
	unsigned int reg;

	reg = readl(&dp_regs->training_ptn_set);
	reg &= ~(SCRAMBLING_DISABLE);

	if (!enable)
		reg |= SCRAMBLING_DISABLE;

	writel(reg, &dp_regs->training_ptn_set);
}

int exynos_dp_init_video(void)
{
	unsigned int reg;

	/* Clear VID_CLK_CHG[1] and VID_FORMAT_CHG[3] and VSYNC_DET[7] */
	reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
	writel(reg, &dp_regs->common_int_sta1);

	/* I_STRM__CLK detect : DE_CTL : Auto detect */
	reg &= ~DET_CTRL;
	writel(reg, &dp_regs->sys_ctl1);

	return 0;
}

void exynos_dp_config_video_slave_mode(struct edp_video_info *video_info)
{
	unsigned int reg;

	/* Video Slave mode setting */
	reg = readl(&dp_regs->func_en1);
	reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
	reg |= MASTER_VID_FUNC_EN_N;
	writel(reg, &dp_regs->func_en1);

	/* Configure Interlaced for slave mode video */
	reg = readl(&dp_regs->video_ctl10);
	reg &= ~INTERACE_SCAN_CFG;
	reg |= (video_info->interlaced << INTERACE_SCAN_CFG_SHIFT);
	writel(reg, &dp_regs->video_ctl10);

	/* Configure V sync polarity for slave mode video */
	reg = readl(&dp_regs->video_ctl10);
	reg &= ~VSYNC_POLARITY_CFG;
	reg |= (video_info->v_sync_polarity << V_S_POLARITY_CFG_SHIFT);
	writel(reg, &dp_regs->video_ctl10);

	/* Configure H sync polarity for slave mode video */
	reg = readl(&dp_regs->video_ctl10);
	reg &= ~HSYNC_POLARITY_CFG;
	reg |= (video_info->h_sync_polarity << H_S_POLARITY_CFG_SHIFT);
	writel(reg, &dp_regs->video_ctl10);

	/*Set video mode to slave mode */
	reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
	writel(reg, &dp_regs->soc_general_ctl);
}

void exynos_dp_set_video_color_format(struct edp_video_info *video_info)
{
	unsigned int reg;

	/* Configure the input color depth, color space, dynamic range */
	reg = (video_info->dynamic_range << IN_D_RANGE_SHIFT) |
		(video_info->color_depth << IN_BPC_SHIFT) |
		(video_info->color_space << IN_COLOR_F_SHIFT);
	writel(reg, &dp_regs->video_ctl2);

	/* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
	reg = readl(&dp_regs->video_ctl3);
	reg &= ~IN_YC_COEFFI_MASK;
	if (video_info->ycbcr_coeff)
		reg |= IN_YC_COEFFI_ITU709;
	else
		reg |= IN_YC_COEFFI_ITU601;
	writel(reg, &dp_regs->video_ctl3);
}

int exynos_dp_config_video_bist(struct edp_device_info *edp_info)
{
	unsigned int reg;
	unsigned int bist_type = 0;
	struct edp_video_info video_info = edp_info->video_info;

	/* For master mode, you don't need to set the video format */
	if (video_info.master_mode == 0) {
		writel(TOTAL_LINE_CFG_L(edp_info->disp_info.v_total),
				&dp_regs->total_ln_cfg_l);
		writel(TOTAL_LINE_CFG_H(edp_info->disp_info.v_total),
				&dp_regs->total_ln_cfg_h);
		writel(ACTIVE_LINE_CFG_L(edp_info->disp_info.v_res),
				&dp_regs->active_ln_cfg_l);
		writel(ACTIVE_LINE_CFG_H(edp_info->disp_info.v_res),
				&dp_regs->active_ln_cfg_h);
		writel(edp_info->disp_info.v_sync_width,
				&dp_regs->vsw_cfg);
		writel(edp_info->disp_info.v_back_porch,
				&dp_regs->vbp_cfg);
		writel(edp_info->disp_info.v_front_porch,
				&dp_regs->vfp_cfg);

		writel(TOTAL_PIXEL_CFG_L(edp_info->disp_info.h_total),
				&dp_regs->total_pix_cfg_l);
		writel(TOTAL_PIXEL_CFG_H(edp_info->disp_info.h_total),
				&dp_regs->total_pix_cfg_h);
		writel(ACTIVE_PIXEL_CFG_L(edp_info->disp_info.h_res),
				&dp_regs->active_pix_cfg_l);
		writel(ACTIVE_PIXEL_CFG_H(edp_info->disp_info.h_res),
				&dp_regs->active_pix_cfg_h);
		writel(H_F_PORCH_CFG_L(edp_info->disp_info.h_front_porch),
				&dp_regs->hfp_cfg_l);
		writel(H_F_PORCH_CFG_H(edp_info->disp_info.h_front_porch),
				&dp_regs->hfp_cfg_h);
		writel(H_SYNC_PORCH_CFG_L(edp_info->disp_info.h_sync_width),
				&dp_regs->hsw_cfg_l);
		writel(H_SYNC_PORCH_CFG_H(edp_info->disp_info.h_sync_width),
				&dp_regs->hsw_cfg_h);
		writel(H_B_PORCH_CFG_L(edp_info->disp_info.h_back_porch),
				&dp_regs->hbp_cfg_l);
		writel(H_B_PORCH_CFG_H(edp_info->disp_info.h_back_porch),
				&dp_regs->hbp_cfg_h);

		/*
		 * Set SLAVE_I_SCAN_CFG[2], VSYNC_P_CFG[1],
		 * HSYNC_P_CFG[0] properly
		 */
		reg = (video_info.interlaced << INTERACE_SCAN_CFG_SHIFT |
			video_info.v_sync_polarity << V_S_POLARITY_CFG_SHIFT |
			video_info.h_sync_polarity << H_S_POLARITY_CFG_SHIFT);
		writel(reg, &dp_regs->video_ctl10);
	}

	/* BIST color bar width set--set to each bar is 32 pixel width */
	switch (video_info.bist_pattern) {
	case COLORBAR_32:
		bist_type = BIST_WIDTH_BAR_32_PIXEL |
			  BIST_TYPE_COLOR_BAR;
		break;
	case COLORBAR_64:
		bist_type = BIST_WIDTH_BAR_64_PIXEL |
			  BIST_TYPE_COLOR_BAR;
		break;
	case WHITE_GRAY_BALCKBAR_32:
		bist_type = BIST_WIDTH_BAR_32_PIXEL |
			  BIST_TYPE_WHITE_GRAY_BLACK_BAR;
		break;
	case WHITE_GRAY_BALCKBAR_64:
		bist_type = BIST_WIDTH_BAR_64_PIXEL |
			  BIST_TYPE_WHITE_GRAY_BLACK_BAR;
		break;
	case MOBILE_WHITEBAR_32:
		bist_type = BIST_WIDTH_BAR_32_PIXEL |
			  BIST_TYPE_MOBILE_WHITE_BAR;
		break;
	case MOBILE_WHITEBAR_64:
		bist_type = BIST_WIDTH_BAR_64_PIXEL |
			  BIST_TYPE_MOBILE_WHITE_BAR;
		break;
	default:
		return -1;
	}

	reg = bist_type;
	writel(reg, &dp_regs->video_ctl4);

	return 0;
}

unsigned int exynos_dp_is_slave_video_stream_clock_on(void)
{
	unsigned int reg;

	/* Update Video stream clk detect status */
	reg = readl(&dp_regs->sys_ctl1);
	writel(reg, &dp_regs->sys_ctl1);

	reg = readl(&dp_regs->sys_ctl1);

	if (!(reg & DET_STA)) {
		debug("DP Input stream clock not detected.\n");
		return -EIO;
	}

	return EXYNOS_DP_SUCCESS;
}

void exynos_dp_set_video_cr_mn(unsigned int type, unsigned int m_value,
		unsigned int n_value)
{
	unsigned int reg;

	if (type == REGISTER_M) {
		reg = readl(&dp_regs->sys_ctl4);
		reg |= FIX_M_VID;
		writel(reg, &dp_regs->sys_ctl4);
		reg = M_VID0_CFG(m_value);
		writel(reg, &dp_regs->m_vid0);
		reg = M_VID1_CFG(m_value);
		writel(reg, &dp_regs->m_vid1);
		reg = M_VID2_CFG(m_value);
		writel(reg, &dp_regs->m_vid2);

		reg = N_VID0_CFG(n_value);
		writel(reg, &dp_regs->n_vid0);
		reg = N_VID1_CFG(n_value);
		writel(reg, &dp_regs->n_vid1);
		reg = N_VID2_CFG(n_value);
		writel(reg, &dp_regs->n_vid2);
	} else  {
		reg = readl(&dp_regs->sys_ctl4);
		reg &= ~FIX_M_VID;
		writel(reg, &dp_regs->sys_ctl4);
	}
}

void exynos_dp_set_video_timing_mode(unsigned int type)
{
	unsigned int reg;

	reg = readl(&dp_regs->video_ctl10);
	reg &= ~FORMAT_SEL;

	if (type != VIDEO_TIMING_FROM_CAPTURE)
		reg |= FORMAT_SEL;

	writel(reg, &dp_regs->video_ctl10);
}

void exynos_dp_enable_video_master(unsigned int enable)
{
	unsigned int reg;

	reg = readl(&dp_regs->soc_general_ctl);
	if (enable) {
		reg &= ~VIDEO_MODE_MASK;
		reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
	} else {
		reg &= ~VIDEO_MODE_MASK;
		reg |= VIDEO_MODE_SLAVE_MODE;
	}

	writel(reg, &dp_regs->soc_general_ctl);
}

void exynos_dp_start_video(void)
{
	unsigned int reg;

	/* Enable Video input and disable Mute */
	reg = readl(&dp_regs->video_ctl1);
	reg |= VIDEO_EN;
	writel(reg, &dp_regs->video_ctl1);
}

unsigned int exynos_dp_is_video_stream_on(void)
{
	unsigned int reg;

	/* Update STRM_VALID */
	reg = readl(&dp_regs->sys_ctl3);
	writel(reg, &dp_regs->sys_ctl3);

	reg = readl(&dp_regs->sys_ctl3);
	if (!(reg & STRM_VALID))
		return -EIO;

	return EXYNOS_DP_SUCCESS;
}
