/*
 * This file is part of the coreboot project.
 *
 * Copyright 2014 Rockchip Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <arch/io.h>
#include <assert.h>
#include <console/console.h>
#include <delay.h>
#include <edid.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <soc/addressmap.h>
#include <soc/edp.h>
#include <soc/grf.h>
#include <soc/vop.h>
#include <timer.h>

#include "chip.h"

#define edp_debug(x...) do {if (0) printk(BIOS_DEBUG, x); } while (0)

static struct rk_edp rk_edp;

#define MAX_CR_LOOP 5
#define MAX_EQ_LOOP 5
#define DP_LINK_STATUS_SIZE 6

static const char *voltage_names[] = {
	"0.4V", "0.6V", "0.8V", "1.2V"
};
static const char *pre_emph_names[] = {
	"0dB", "3.5dB", "6dB", "9.5dB"
};

#define DP_VOLTAGE_MAX         DP_TRAIN_VOLTAGE_SWING_1200
#define DP_PRE_EMPHASIS_MAX    DP_TRAIN_PRE_EMPHASIS_9_5

static void rk_edp_init_refclk(struct rk_edp *edp)
{
	write32(&edp->regs->analog_ctl_2, SEL_24M);
	write32(&edp->regs->pll_reg_1, REF_CLK_24M);

	/*initial value*/
	write32(&edp->regs->pll_reg_2, LDO_OUTPUT_V_SEL_145 | KVCO_DEFALUT |
		CHG_PUMP_CUR_SEL_5US | V2L_CUR_SEL_1MA);

	write32(&edp->regs->pll_reg_3, LOCK_DET_CNT_SEL_256 |
		LOOP_FILTER_RESET | PALL_SSC_RESET | LOCK_DET_BYPASS |
		PLL_LOCK_DET_MODE | PLL_LOCK_DET_FORCE);

	write32(&edp->regs->pll_reg_5, REGULATOR_V_SEL_950MV | STANDBY_CUR_SEL |
		CHG_PUMP_INOUT_CTRL_1200MV | CHG_PUMP_INPUT_CTRL_OP);

	write32(&edp->regs->ssc_reg, SSC_OFFSET | SSC_MODE | SSC_DEPTH);

	write32(&edp->regs->tx_common, TX_SWING_PRE_EMP_MODE |
		PRE_DRIVER_PW_CTRL1 | LP_MODE_CLK_REGULATOR |
		RESISTOR_MSB_CTRL | RESISTOR_CTRL);

	write32(&edp->regs->dp_aux, DP_AUX_COMMON_MODE |
		DP_AUX_EN | AUX_TERM_50OHM);

	write32(&edp->regs->dp_bias, DP_BG_OUT_SEL | DP_DB_CUR_CTRL |
		DP_BG_SEL | DP_RESISTOR_TUNE_BG);

	write32(&edp->regs->dp_reserv2,
		CH1_CH3_SWING_EMP_CTRL | CH0_CH2_SWING_EMP_CTRL);
}

static void rk_edp_init_interrupt(struct rk_edp *edp)
{
	/* Set interrupt pin assertion polarity as high */
	write32(&edp->regs->int_ctl, INT_POL);

	/* Clear pending registers */
	write32(&edp->regs->common_int_sta_1, 0xff);
	write32(&edp->regs->common_int_sta_2, 0x4f);
	write32(&edp->regs->common_int_sta_3, 0xff);
	write32(&edp->regs->common_int_sta_4, 0x27);
	write32(&edp->regs->dp_int_sta, 0x7f);

	/* 0:mask,1: unmask */
	write32(&edp->regs->common_int_mask_1, 0x00);
	write32(&edp->regs->common_int_mask_2, 0x00);
	write32(&edp->regs->common_int_mask_3, 0x00);
	write32(&edp->regs->common_int_mask_4, 0x00);
	write32(&edp->regs->int_sta_mask, 0x00);
}

static void rk_edp_enable_sw_function(struct rk_edp *edp)
{
	clrbits_le32(&edp->regs->func_en_1, SW_FUNC_EN_N);
}

static int rk_edp_get_pll_lock_status(struct rk_edp *edp)
{
	u32 val;

	val = read32(&edp->regs->dp_debug_ctl);
	return (val & PLL_LOCK) ? DP_PLL_LOCKED : DP_PLL_UNLOCKED;
}

static void rk_edp_init_analog_func(struct rk_edp *edp)
{
	struct stopwatch sw;

	write32(&edp->regs->dp_pd, 0x00);

	write32(&edp->regs->common_int_sta_1, PLL_LOCK_CHG);

	clrbits_le32(&edp->regs->dp_debug_ctl, F_PLL_LOCK | PLL_LOCK_CTRL);

	stopwatch_init_msecs_expire(&sw, PLL_LOCK_TIMEOUT);

	while (rk_edp_get_pll_lock_status(edp) == DP_PLL_UNLOCKED) {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR, "%s: PLL is not locked\n", __func__);
			return;
		}
	}

	/* Enable Serdes FIFO function and Link symbol clock domain module */
	clrbits_le32(&edp->regs->func_en_2, SERDES_FIFO_FUNC_EN_N |
				       LS_CLK_DOMAIN_FUNC_EN_N | AUX_FUNC_EN_N |
				       SSC_FUNC_EN_N);
}

static void rk_edp_init_aux(struct rk_edp *edp)
{
	/* Clear inerrupts related to AUX channel */
	write32(&edp->regs->dp_int_sta, AUX_FUNC_EN_N);

	/* Disable AUX channel module */
	setbits_le32(&edp->regs->func_en_2, AUX_FUNC_EN_N);

	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
	write32(&edp->regs->aux_ch_defer_dtl, DEFER_CTRL_EN | DEFER_COUNT(1));

	/* Enable AUX channel module */
	clrbits_le32(&edp->regs->func_en_2, AUX_FUNC_EN_N);
}

static int rk_edp_aux_enable(struct rk_edp *edp)
{
	struct stopwatch sw;

	setbits_le32(&edp->regs->aux_ch_ctl_2, AUX_EN);
	stopwatch_init_msecs_expire(&sw, 20);
	do {
		if (!(read32(&edp->regs->aux_ch_ctl_2) & AUX_EN))
			return 0;
	} while (!stopwatch_expired(&sw));

	return -1;

}

static int rk_edp_is_aux_reply(struct rk_edp *edp)
{
	struct stopwatch sw;

	stopwatch_init_msecs_expire(&sw, 10);

	while (!(read32(&edp->regs->dp_int_sta) & RPLY_RECEIV)) {
		if (stopwatch_expired(&sw))
			return -1;
	}

	write32(&edp->regs->dp_int_sta, RPLY_RECEIV);

	return 0;
}

static int rk_edp_start_aux_transaction(struct rk_edp *edp)
{
	int val;

	/* Enable AUX CH operation */
	if (rk_edp_aux_enable(edp)) {
		edp_debug("AUX CH enable timeout!\n");
		return -1;
	}

	/* Is AUX CH command reply received? */
	if (rk_edp_is_aux_reply(edp)) {
		edp_debug("AUX CH command reply failed!\n");
		return -1;
	}

	/* Clear interrupt source for AUX CH access error */
	val = read32(&edp->regs->dp_int_sta);
	if (val & AUX_ERR) {
		write32(&edp->regs->dp_int_sta, AUX_ERR);
		return -1;
	}

	/* Check AUX CH error access status */
	val = read32(&edp->regs->dp_int_sta);
	if ((val & AUX_STATUS_MASK) != 0) {
		edp_debug("AUX CH error happens: %d\n\n",
			val & AUX_STATUS_MASK);
		return -1;
	}

	return 0;
}

static int rk_edp_dpcd_transfer(struct rk_edp *edp,
				unsigned int val_addr, u8 *data,
				unsigned int length,
				enum dpcd_request request)
{
	int val;
	int i, try_times;
	int retval = 0;
	u32 len = 0;

	while (length) {
		len = MIN(length, 16);
		for (try_times = 0; try_times < 10; try_times++) {

			/* Clear AUX CH data buffer */
			val = BUF_CLR;
			write32(&edp->regs->buf_data_ctl, val);

			/* Select DPCD device address */
			val = AUX_ADDR_7_0(val_addr);
			write32(&edp->regs->aux_addr_7_0, val);
			val = AUX_ADDR_15_8(val_addr);
			write32(&edp->regs->aux_addr_15_8, val);
			val = AUX_ADDR_19_16(val_addr);
			write32(&edp->regs->aux_addr_19_16, val);

			/*
			 * Set DisplayPort transaction and read 1 byte
			 * If bit 3 is 1, DisplayPort transaction.
			 * If Bit 3 is 0, I2C transaction.
			 */
			if (request == DPCD_WRITE) {
				val = AUX_LENGTH(len) |
					AUX_TX_COMM_DP_TRANSACTION |
					AUX_TX_COMM_WRITE;
				for (i = 0; i < len; i++)
					write32(&edp->regs->buf_data[i],
						*data++);
			} else
				val = AUX_LENGTH(len) |
					AUX_TX_COMM_DP_TRANSACTION |
					AUX_TX_COMM_READ;

			write32(&edp->regs->aux_ch_ctl_1, val);

			/* Start AUX transaction */
			retval = rk_edp_start_aux_transaction(edp);
			if (retval == 0)
				break;
			else
				printk(BIOS_WARNING, "read dpcd Aux Transaction fail!\n");

		}

		if (retval)
			return -1;

		if (request == DPCD_READ) {
			for (i = 0; i < len; i++)
				*data++ = (u8)read32(&edp->regs->buf_data[i]);
		}

		length -= len;
		val_addr += 16;
	}
	return 0;
}

static int rk_edp_dpcd_read(struct rk_edp *edp, u32 addr, u8 *values, size_t size)
{
	return rk_edp_dpcd_transfer(edp, addr, values, size, DPCD_READ);
}

static int rk_edp_dpcd_write(struct rk_edp *edp, u32 addr, u8 *values, size_t size)
{
	return rk_edp_dpcd_transfer(edp, addr, values, size, DPCD_WRITE);
}


static int rk_edp_link_power_up(struct rk_edp *edp)
{
	u8 value;
	int err;

	/* DP_SET_POWER register is only available on DPCD v1.1 and later */
	if (edp->link_train.revision < 0x11)
		return 0;

	err = rk_edp_dpcd_read(edp, DPCD_LINK_POWER_STATE, &value, 1);
	if (err < 0)
		return err;

	value &= ~DP_SET_POWER_MASK;
	value |= DP_SET_POWER_D0;

	err = rk_edp_dpcd_write(edp, DPCD_LINK_POWER_STATE, &value, 1);
	if (err < 0)
		return err;

	/*
	 * According to the DP 1.1 specification, a "Sink Device must exit the
	 * power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink
	 * Control Field" (register 0x600).
	 */
	mdelay(1);

	return 0;
}

static int rk_edp_link_configure(struct rk_edp *edp)
{
	u8 values[2];

	values[0] = edp->link_train.link_rate;
	values[1] = edp->link_train.lane_count;

	return rk_edp_dpcd_write(edp, DPCD_LINK_BW_SET, values, sizeof(values));
}

static void rk_edp_set_link_training(struct rk_edp *edp,
				     const u8 *training_values)
{
	int i;

	for (i = 0; i < edp->link_train.lane_count; i++)
		write32(&edp->regs->ln_link_trn_ctl[i], training_values[i]);
}

static u8 edp_link_status(const u8 *link_status, int r)
{
	return link_status[r - DPCD_LANE0_1_STATUS];
}

static int rk_edp_dpcd_read_link_status(struct rk_edp *edp, u8 *link_status)
{
	return rk_edp_dpcd_read(edp, DPCD_LANE0_1_STATUS, link_status,
				DP_LINK_STATUS_SIZE);
}

static u8 edp_get_lane_status(const u8 *link_status, int lane)
{
	int i = DPCD_LANE0_1_STATUS + (lane >> 1);
	int s = (lane & 1) * 4;
	u8 l = edp_link_status(link_status, i);
	return (l >> s) & 0xf;
}

static int rk_edp_clock_recovery_ok(const u8 *link_status, int lane_count)
{
	int lane;
	u8 lane_status;

	for (lane = 0; lane < lane_count; lane++) {
		lane_status = edp_get_lane_status(link_status, lane);
		if ((lane_status & DP_LANE_CR_DONE) == 0)
			return 0;
	}
	return 1;
}

static int rk_edp_channel_eq_ok(const u8 *link_status, int lane_count)
{
	u8 lane_align;
	u8 lane_status;
	int lane;

	lane_align = edp_link_status(link_status,
				    DPCD_LANE_ALIGN_STATUS_UPDATED);
	if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
		return 0;
	for (lane = 0; lane < lane_count; lane++) {
		lane_status = edp_get_lane_status(link_status, lane);
		if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
			return 0;
	}
	return 1;
}

static u8
rk_edp_get_adjust_request_voltage(const u8 *link_status, int lane)
{
	int i = DPCD_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
	int s = ((lane & 1) ?
		 DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
		 DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
	u8 l = edp_link_status(link_status, i);

	return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
}

static u8 rk_edp_get_adjust_request_pre_emphasis(const u8 *link_status,
						 int lane)
{
	int i = DPCD_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
	int s = ((lane & 1) ?
		 DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
		 DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
	u8 l = edp_link_status(link_status, i);

	return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
}

static void edp_get_adjust_train(const u8 *link_status, int lane_count,
				 u8 train_set[])
{
	u8 v = 0;
	u8 p = 0;
	int lane;

	for (lane = 0; lane < lane_count; lane++) {
		u8 this_v =
			rk_edp_get_adjust_request_voltage(link_status, lane);
		u8 this_p =
			rk_edp_get_adjust_request_pre_emphasis(link_status,
								lane);

		printk(BIOS_DEBUG, "requested signal parameters: lane %d "
					"voltage %s pre_emph %s\n", lane,
			 voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
			 pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);

		if (this_v > v)
			v = this_v;
		if (this_p > p)
			p = this_p;
	}

	if (v >= DP_VOLTAGE_MAX)
		v |= DP_TRAIN_MAX_SWING_REACHED;

	if (p >= DP_PRE_EMPHASIS_MAX)
		p |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;

	printk(BIOS_DEBUG, "using signal parameters: voltage %s pre_emph %s\n",
		  voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK)
		  >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
		  pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK)
		  >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);

	for (lane = 0; lane < 4; lane++)
		train_set[lane] = v | p;
}

static int rk_edp_link_train_cr(struct rk_edp *edp)
{
	int clock_recovery;
	u8 voltage, tries = 0;
	u8 status[DP_LINK_STATUS_SIZE];
	int i;
	u8 value;

	value = DP_TRAINING_PATTERN_1;
	write32(&edp->regs->dp_training_ptn_set, value);
	rk_edp_dpcd_write(edp, DPCD_TRAINING_PATTERN_SET, &value, 1);
	memset(edp->train_set, 0, 4);

	/* clock recovery loop */
	clock_recovery = 0;
	tries = 0;
	voltage = 0xff;

	while (1) {
		rk_edp_set_link_training(edp, edp->train_set);
		rk_edp_dpcd_write(edp, DPCD_TRAINING_LANE0_SET,
					edp->train_set,
					edp->link_train.lane_count);

		mdelay(1);

		if (rk_edp_dpcd_read_link_status(edp, status) < 0) {
			printk(BIOS_ERR, "displayport link status failed\n");
			break;
		}

		if (rk_edp_clock_recovery_ok(status,
			edp->link_train.lane_count)) {
			clock_recovery = 1;
			break;
		}

		for (i = 0; i < edp->link_train.lane_count; i++) {
			if ((edp->train_set[i] &
				DP_TRAIN_MAX_SWING_REACHED) == 0)
				break;
		}
		if (i == edp->link_train.lane_count) {
			printk(BIOS_ERR, "clock recovery reached max voltage\n");
			break;
		}

		if ((edp->train_set[0] &
			DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
			++tries;
			if (tries == MAX_CR_LOOP) {
				printk(BIOS_ERR, "clock recovery tried 5 times\n");
				break;
			}
		} else
			tries = 0;

		voltage = edp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;

		/* Compute new train_set as requested by sink */
		edp_get_adjust_train(status, edp->link_train.lane_count,
					edp->train_set);
	}
	if (!clock_recovery) {
		printk(BIOS_ERR, "clock recovery failed\n");
		return -1;
	} else {
		printk(BIOS_DEBUG, "clock recovery at voltage %d pre-emphasis %d\n",
			  edp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
			  (edp->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >>
			  DP_TRAIN_PRE_EMPHASIS_SHIFT);
		return 0;
	}
}

static int rk_edp_link_train_ce(struct rk_edp *edp)
{
	int channel_eq;
	u8 value, tries = 0;
	u8 status[DP_LINK_STATUS_SIZE];

	value = DP_TRAINING_PATTERN_2;
	write32(&edp->regs->dp_training_ptn_set, value);
	rk_edp_dpcd_write(edp, DPCD_TRAINING_PATTERN_SET, &value, 1);

	/* channel equalization loop */
	channel_eq = 0;
	for (tries = 0; tries < 5; tries++) {
		rk_edp_set_link_training(edp, edp->train_set);
		udelay(400);

		if (rk_edp_dpcd_read_link_status(edp, status) < 0) {
			printk(BIOS_ERR, "displayport link status failed\n");
			return -1;
		}

		if (rk_edp_channel_eq_ok(status,
			edp->link_train.lane_count)) {
			channel_eq = 1;
			break;
		}
		edp_get_adjust_train(status,
			edp->link_train.lane_count,
			edp->train_set);
	}

	if (!channel_eq) {
		printk(BIOS_ERR, "channel eq failed\n");
		return -1;
	} else {
		printk(BIOS_DEBUG, "channel eq at voltage %d pre-emphasis %d\n",
			  edp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
			  (edp->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
			  >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
		return 0;
	}
}

static int rk_edp_init_training(struct rk_edp *edp)
{
	u8 values[3];
	int err;

	err = rk_edp_dpcd_read(edp, DPCD_DPCD_REV, values, sizeof(values));
	if (err < 0)
		return err;

	edp->link_train.revision = values[0];
	edp->link_train.link_rate = values[1];
	edp->link_train.lane_count = values[2] & DP_MAX_LANE_COUNT_MASK;

	edp_debug("max link rate:%d.%dGps max number of lanes:%d\n",
			edp->link_train.link_rate * 27 / 100,
			edp->link_train.link_rate * 27 % 100,
			edp->link_train.lane_count);

	if ((edp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
	    (edp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
		edp_debug("Rx Max Link Rate is abnormal :%x\n",
			edp->link_train.link_rate);
		return -1;
	}

	if (edp->link_train.lane_count == 0) {
		edp_debug("Rx Max Lane count is abnormal :%x\n",
			edp->link_train.lane_count);
		return -1;
	}

	rk_edp_link_power_up(edp);
	rk_edp_link_configure(edp);
	return 0;
}

static int rk_edp_hw_link_training(struct rk_edp *edp)
{
	u32 val;
	struct stopwatch sw;

	/* Set link rate and count as you want to establish*/
	write32(&edp->regs->link_bw_set, edp->link_train.link_rate);
	write32(&edp->regs->lane_count_set, edp->link_train.lane_count);

	if (rk_edp_link_train_cr(edp))
		return -1;
	if (rk_edp_link_train_ce(edp))
		return -1;

	write32(&edp->regs->dp_hw_link_training, HW_LT_EN);
	stopwatch_init_msecs_expire(&sw, 10);
	do {
		val = read32(&edp->regs->dp_hw_link_training);
		if (!(val & HW_LT_EN))
			break;
	} while (!stopwatch_expired(&sw));
	if (val & HW_LT_ERR_CODE_MASK) {
		printk(BIOS_ERR, "edp hw link training error: %d\n",
		val >> HW_LT_ERR_CODE_SHIFT);
		return -1;
	}
	return 0;

}

static int rk_edp_select_i2c_device(struct rk_edp *edp,
				    unsigned int device_addr,
				    unsigned int val_addr)
{
	u32 val;
	int retval;

	/* Set EDID device address */
	val = device_addr;
	write32(&edp->regs->aux_addr_7_0, val);
	write32(&edp->regs->aux_addr_15_8, 0x0);
	write32(&edp->regs->aux_addr_19_16, 0x0);

	/* Set offset from base address of EDID device */
	write32(&edp->regs->buf_data[0], val_addr);

	/*
	 * Set I2C transaction and write address
	 * If bit 3 is 1, DisplayPort transaction.
	 * If Bit 3 is 0, I2C transaction.
	 */
	val = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT |
		AUX_TX_COMM_WRITE;
	write32(&edp->regs->aux_ch_ctl_1, val);

	/* Start AUX transaction */
	retval = rk_edp_start_aux_transaction(edp);
	if (retval != 0)
		edp_debug("select_i2c_device Aux Transaction fail!\n");

	return retval;
}

static int rk_edp_read_bytes_from_i2c(struct rk_edp *edp,
				      unsigned int device_addr,
				      unsigned int val_addr,
				      unsigned int count,
				      u8 edid[])
{
	u32 val;
	unsigned int i, j;
	unsigned int cur_data_idx;
	unsigned int defer = 0;
	int retval = 0;

	for (i = 0; i < count; i += 16) {
		for (j = 0; j < 10; j++) { /* try 10 times */
			/* Clear AUX CH data buffer */
			val = BUF_CLR;
			write32(&edp->regs->buf_data_ctl, val);

			/* Set normal AUX CH command */
			clrbits_le32(&edp->regs->aux_ch_ctl_2, ADDR_ONLY);

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

			/*
			 * Set I2C transaction and write data
			 * If bit 3 is 1, DisplayPort transaction.
			 * If Bit 3 is 0, I2C transaction.
			 */
			val = AUX_LENGTH(16) | AUX_TX_COMM_I2C_TRANSACTION |
				AUX_TX_COMM_READ;
			write32(&edp->regs->aux_ch_ctl_1, val);

			/* Start AUX transaction */
			retval = rk_edp_start_aux_transaction(edp);
			if (retval == 0)
				break;
			else {
				edp_debug("Aux Transaction fail!\n");
				continue;
			}

			/* Check if Rx sends defer */
			val = read32(&edp->regs->aux_rx_comm);
			if (val == AUX_RX_COMM_AUX_DEFER ||
				val == AUX_RX_COMM_I2C_DEFER) {
				edp_debug("Defer: %d\n\n", val);
				defer = 1;
			}
		}

		if (retval)
			return -1;

		for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) {
			val = read32(&edp->regs->buf_data[cur_data_idx]);
			edid[i + cur_data_idx] = (u8)val;
		}
	}

	return retval;
}

static int rk_edp_read_edid(struct rk_edp *edp, struct edid *edid)
{
	u8 buf[EDID_LENGTH * 2];
	u32 edid_size = EDID_LENGTH;
	int retval;

	/* Read EDID data */
	retval = rk_edp_read_bytes_from_i2c(edp, EDID_ADDR,
				EDID_HEADER, EDID_LENGTH,
				&buf[EDID_HEADER]);
	if (retval != 0) {
		printk(BIOS_ERR, "EDID Read failed!\n");
		return -1;
	}

	/* check if edid have extension flag, and read additional EDID data */
	if (buf[EDID_EXTENSION_FLAG]) {
		edid_size += EDID_LENGTH;
		retval = rk_edp_read_bytes_from_i2c(edp, EDID_ADDR,
					EDID_LENGTH, EDID_LENGTH,
					&buf[EDID_LENGTH]);
		if (retval != 0) {
			printk(BIOS_ERR, "EDID Read failed!\n");
			return -1;
		}
	}

	if (decode_edid(buf, edid_size, edid)) {
		printk(BIOS_ERR, "%s: Failed to decode EDID.\n",
		       __func__);
		return -1;
	}

	edp_debug("EDID Read success!\n");
	return 0;
}

static int rk_edp_set_link_train(struct rk_edp *edp)
{
	int retval;

	if (rk_edp_init_training(edp)) {
		printk(BIOS_ERR, "DP LT init failed!\n");
		return -1;
	}

	retval = rk_edp_hw_link_training(edp);

	return retval;
}

static void rk_edp_init_video(struct rk_edp *edp)
{
	u32 val;

	val = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
	write32(&edp->regs->common_int_sta_1, val);

	val = CHA_CRI(4) | CHA_CTRL;
	write32(&edp->regs->sys_ctl_2, val);

	val = VID_HRES_TH(2) | VID_VRES_TH(0);
	write32(&edp->regs->video_ctl_8, val);
}

static void rk_edp_config_video_slave_mode(struct rk_edp *edp)
{
	clrbits_le32(&edp->regs->func_en_1,
			VID_FIFO_FUNC_EN_N | VID_CAP_FUNC_EN_N);
}

static void rk_edp_set_video_cr_mn(struct rk_edp *edp,
				   enum clock_recovery_m_value_type type,
				   u32 m_value,
				   u32 n_value)
{
	u32 val;

	if (type == REGISTER_M) {
		setbits_le32(&edp->regs->sys_ctl_4, FIX_M_VID);
		val = m_value & 0xff;
		write32(&edp->regs->m_vid_0, val);
		val = (m_value >> 8) & 0xff;
		write32(&edp->regs->m_vid_1, val);
		val = (m_value >> 16) & 0xff;
		write32(&edp->regs->m_vid_2, val);

		val = n_value & 0xff;
		write32(&edp->regs->n_vid_0, val);
		val = (n_value >> 8) & 0xff;
		write32(&edp->regs->n_vid_1, val);
		val = (n_value >> 16) & 0xff;
		write32(&edp->regs->n_vid_2, val);
	} else  {
		clrbits_le32(&edp->regs->sys_ctl_4, FIX_M_VID);

		write32(&edp->regs->n_vid_0, 0x00);
		write32(&edp->regs->n_vid_1, 0x80);
		write32(&edp->regs->n_vid_2, 0x00);
	}
}

static int rk_edp_is_video_stream_clock_on(struct rk_edp *edp)
{
	u32 val;
	struct stopwatch sw;

	stopwatch_init_msecs_expire(&sw, 100);
	do {
		val = read32(&edp->regs->sys_ctl_1);

		/*must write value to update DET_STA bit status*/
		write32(&edp->regs->sys_ctl_1, val);
		val = read32(&edp->regs->sys_ctl_1);
		if (!(val & DET_STA))
			continue;

		val = read32(&edp->regs->sys_ctl_2);

		/*must write value to update CHA_STA bit status*/
		write32(&edp->regs->sys_ctl_2, val);
		val = read32(&edp->regs->sys_ctl_2);
		if (!(val & CHA_STA))
			return 0;
	} while (!stopwatch_expired(&sw));

	return -1;
}

static int rk_edp_is_video_stream_on(struct rk_edp *edp)
{
	u32 val;
	struct stopwatch sw;

	stopwatch_init_msecs_expire(&sw, 100);
	do {
		val = read32(&edp->regs->sys_ctl_3);

		/*must write value to update STRM_VALID bit status*/
		write32(&edp->regs->sys_ctl_3, val);

		val = read32(&edp->regs->sys_ctl_3);
		if (!(val & STRM_VALID))
			return 0;
	} while (!stopwatch_expired(&sw));

	return -1;
}

static int rk_edp_config_video(struct rk_edp *edp)
{
	rk_edp_config_video_slave_mode(edp);

	if (rk_edp_get_pll_lock_status(edp) == DP_PLL_UNLOCKED) {
		edp_debug("PLL is not locked yet.\n");
		return -1;
	}

	if (rk_edp_is_video_stream_clock_on(edp))
		return -1;

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

	/* For video bist, Video timing must be generated by register */
	clrbits_le32(&edp->regs->video_ctl_10, F_SEL);

	/* Disable video mute */
	clrbits_le32(&edp->regs->video_ctl_1, VIDEO_MUTE);

	/* Enable video at next frame */
	setbits_le32(&edp->regs->video_ctl_1, VIDEO_EN);

	return rk_edp_is_video_stream_on(edp);
}

static void rockchip_edp_force_hpd(struct rk_edp *edp)
{
	u32 val;

	val = read32(&edp->regs->sys_ctl_3);
	val |= (F_HPD | HPD_CTRL);
	write32(&edp->regs->sys_ctl_3, val);
}

static int rockchip_edp_get_plug_in_status(struct rk_edp *edp)
{
	u32 val;

	val = read32(&edp->regs->sys_ctl_3);
	if (val & HPD_STATUS)
		return 1;

	return 0;
}

/*
 * support edp HPD function
 * some hardware version do not support edp hdp,
 * we use 200ms to try to get the hpd single now,
 * if we can not get edp hpd single, it will delay 200ms,
 * also meet the edp power timing request, to compatible
 * all of the hardware version
 */
static void rockchip_edp_wait_hpd(struct rk_edp *edp)
{
	struct stopwatch hpd;

	stopwatch_init_msecs_expire(&hpd, 200);
	do {
		if (rockchip_edp_get_plug_in_status(edp))
			return;
		udelay(100);
	} while (!stopwatch_expired(&hpd));

	printk(BIOS_DEBUG, "do not get hpd single, force hpd\n");
	rockchip_edp_force_hpd(edp);
}

int rk_edp_get_edid(struct edid *edid)
{
	int i;
	int retval;

	/* Read EDID */
	for (i = 0; i < 3; i++) {
		retval = rk_edp_read_edid(&rk_edp, edid);
		if (retval == 0)
			break;
	}

	return retval;
}

int rk_edp_enable(void)
{
	int ret = 0;

	if (rk_edp_set_link_train(&rk_edp)) {
		printk(BIOS_ERR, "link train failed!\n");
		return -1;
	}

	rk_edp_init_video(&rk_edp);
	ret = rk_edp_config_video(&rk_edp);
	if (ret)
		printk(BIOS_ERR, "config video failed\n");

	return ret;
}

void rk_edp_init(u32 vop_id)
{
	u32 val;

	rk_edp.regs = (struct rk3288_edp_regs *)EDP_BASE;

	/* grf_edp_ref_clk_sel: from internal 24MHz or 27MHz clock */
	write32(&rk3288_grf->soc_con12, RK_SETBITS(1 << 4));

	/* select epd signal from vop0 or vop1 */
	val = (vop_id == 1) ? RK_SETBITS(1 << 5) : RK_CLRBITS(1 << 5);
	write32(&rk3288_grf->soc_con6, val);

	rockchip_edp_wait_hpd(&rk_edp);

	rk_edp_init_refclk(&rk_edp);
	rk_edp_init_interrupt(&rk_edp);
	rk_edp_enable_sw_function(&rk_edp);
	rk_edp_init_analog_func(&rk_edp);
	rk_edp_init_aux(&rk_edp);
}
