// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2015 Google, Inc
 * Copyright 2014 Rockchip Inc.
 */

#include <clk.h>
#include <display.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <edid.h>
#include <log.h>
#include <malloc.h>
#include <panel.h>
#include <regmap.h>
#include <reset.h>
#include <syscon.h>
#include <asm/gpio.h>
#include <asm/arch-rockchip/clock.h>
#include <asm/arch-rockchip/hardware.h>
#include <asm/arch-rockchip/edp_rk3288.h>
#include <asm/arch-rockchip/grf_rk3288.h>
#include <asm/arch-rockchip/grf_rk3399.h>

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

static const char * const voltage_names[] = {
	"0.4V", "0.6V", "0.8V", "1.2V"
};
static const char * const 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

#define RK3288_GRF_SOC_CON6	0x025c
#define RK3288_GRF_SOC_CON12	0x0274
#define RK3399_GRF_SOC_CON20	0x6250
#define RK3399_GRF_SOC_CON25	0x6264

enum rockchip_dp_types {
	RK3288_DP = 0,
	RK3399_EDP
};

struct rockchip_dp_data {
	unsigned long reg_vop_big_little;
	unsigned long reg_vop_big_little_sel;
	unsigned long reg_ref_clk_sel;
	unsigned long ref_clk_sel_bit;
	enum rockchip_dp_types chip_type;
};

struct rk_edp_priv {
	struct rk3288_edp *regs;
	void *grf;
	struct udevice *panel;
	struct link_train link_train;
	u8 train_set[4];
};

static void rk_edp_init_refclk(struct rk3288_edp *regs, enum rockchip_dp_types chip_type)
{
	writel(SEL_24M, &regs->analog_ctl_2);
	u32 reg;

	reg = REF_CLK_24M;
	if (chip_type == RK3288_DP)
		reg ^= REF_CLK_MASK;
	writel(reg, &regs->pll_reg_1);


	writel(LDO_OUTPUT_V_SEL_145 | KVCO_DEFALUT | CHG_PUMP_CUR_SEL_5US |
	       V2L_CUR_SEL_1MA, &regs->pll_reg_2);

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

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

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

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

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

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

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

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

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

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

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

static bool rk_edp_get_pll_locked(struct rk3288_edp *regs)
{
	u32 val;

	val = readl(&regs->dp_debug_ctl);

	return val & PLL_LOCK;
}

static int rk_edp_init_analog_func(struct rk3288_edp *regs)
{
	ulong start;

	writel(0x00, &regs->dp_pd);
	writel(PLL_LOCK_CHG, &regs->common_int_sta_1);

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

	start = get_timer(0);
	while (!rk_edp_get_pll_locked(regs)) {
		if (get_timer(start) > PLL_LOCK_TIMEOUT) {
			printf("%s: PLL is not locked\n", __func__);
			return -ETIMEDOUT;
		}
	}

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

	return 0;
}

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

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

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

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

static int rk_edp_aux_enable(struct rk3288_edp *regs)
{
	ulong start;

	setbits_le32(&regs->aux_ch_ctl_2, AUX_EN);
	start = get_timer(0);
	do {
		if (!(readl(&regs->aux_ch_ctl_2) & AUX_EN))
			return 0;
	} while (get_timer(start) < 20);

	return -ETIMEDOUT;
}

static int rk_edp_is_aux_reply(struct rk3288_edp *regs)
{
	ulong start;

	start = get_timer(0);
	while (!(readl(&regs->dp_int_sta) & RPLY_RECEIV)) {
		if (get_timer(start) > 10)
			return -ETIMEDOUT;
	}

	writel(RPLY_RECEIV, &regs->dp_int_sta);

	return 0;
}

static int rk_edp_start_aux_transaction(struct rk3288_edp *regs)
{
	int val, ret;

	/* Enable AUX CH operation */
	ret = rk_edp_aux_enable(regs);
	if (ret) {
		debug("AUX CH enable timeout!\n");
		return ret;
	}

	/* Is AUX CH command reply received? */
	if (rk_edp_is_aux_reply(regs)) {
		debug("AUX CH command reply failed!\n");
		return ret;
	}

	/* Clear interrupt source for AUX CH access error */
	val = readl(&regs->dp_int_sta);
	if (val & AUX_ERR) {
		writel(AUX_ERR, &regs->dp_int_sta);
		return -EIO;
	}

	/* Check AUX CH error access status */
	val = readl(&regs->dp_int_sta);
	if (val & AUX_STATUS_MASK) {
		debug("AUX CH error happens: %d\n\n", val & AUX_STATUS_MASK);
		return -EIO;
	}

	return 0;
}

static int rk_edp_dpcd_transfer(struct rk3288_edp *regs,
				unsigned int val_addr, u8 *in_data,
				unsigned int length,
				enum dpcd_request request)
{
	int val;
	int i, try_times;
	u8 *data;
	int ret = 0;
	u32 len = 0;

	while (length) {
		len = min(length, 16U);
		for (try_times = 0; try_times < 10; try_times++) {
			data = in_data;
			/* Clear AUX CH data buffer */
			writel(BUF_CLR, &regs->buf_data_ctl);

			/* Select DPCD device address */
			writel(AUX_ADDR_7_0(val_addr), &regs->aux_addr_7_0);
			writel(AUX_ADDR_15_8(val_addr), &regs->aux_addr_15_8);
			writel(AUX_ADDR_19_16(val_addr), &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.
			 */
			if (request == DPCD_WRITE) {
				val = AUX_LENGTH(len) |
					AUX_TX_COMM_DP_TRANSACTION |
					AUX_TX_COMM_WRITE;
				for (i = 0; i < len; i++)
					writel(*data++, &regs->buf_data[i]);
			} else
				val = AUX_LENGTH(len) |
					AUX_TX_COMM_DP_TRANSACTION |
					AUX_TX_COMM_READ;

			writel(val, &regs->aux_ch_ctl_1);

			/* Start AUX transaction */
			ret = rk_edp_start_aux_transaction(regs);
			if (ret == 0)
				break;
			else
				printf("read dpcd Aux Transaction fail!\n");
		}

		if (ret)
			return ret;

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

		length -= len;
		val_addr += len;
		in_data += len;
	}

	return 0;
}

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

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


static int rk_edp_link_power_up(struct rk_edp_priv *edp)
{
	u8 value;
	int ret;

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

	ret = rk_edp_dpcd_read(edp->regs, DPCD_LINK_POWER_STATE, &value, 1);
	if (ret)
		return ret;

	value &= ~DP_SET_POWER_MASK;
	value |= DP_SET_POWER_D0;

	ret = rk_edp_dpcd_write(edp->regs, DPCD_LINK_POWER_STATE, &value, 1);
	if (ret)
		return ret;

	/*
	 * 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_priv *edp)
{
	u8 values[2];

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

	return rk_edp_dpcd_write(edp->regs, DPCD_LINK_BW_SET, values,
				 sizeof(values));
}

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

	for (i = 0; i < edp->link_train.lane_count; i++)
		writel(training_values[i], &edp->regs->ln_link_trn_ctl[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_priv *edp,
					u8 *link_status)
{
	return rk_edp_dpcd_read(edp->regs, 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(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 -EIO;
	}

	return 0;
}

static int rk_edp_channel_eq(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))
		return -EIO;
	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 -EIO;
	}

	return 0;
}

static uint 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 uint 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[])
{
	uint v = 0;
	uint p = 0;
	int lane;

	for (lane = 0; lane < lane_count; lane++) {
		uint this_v, this_p;

		this_v = rk_edp_get_adjust_request_voltage(link_status, lane);
		this_p = rk_edp_get_adjust_request_pre_emphasis(link_status,
								lane);

		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;

	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_priv *edp)
{
	struct rk3288_edp *regs = edp->regs;
	int clock_recovery;
	uint voltage, tries = 0;
	u8 status[DP_LINK_STATUS_SIZE];
	int i, ret;
	u8 value;

	value = DP_TRAINING_PATTERN_1;
	writel(value, &regs->dp_training_ptn_set);
	ret = rk_edp_dpcd_write(regs, DPCD_TRAINING_PATTERN_SET, &value, 1);
	if (ret)
		return ret;
	memset(edp->train_set, '\0', sizeof(edp->train_set));

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

	while (1) {
		rk_edp_set_link_training(edp, edp->train_set);
		ret = rk_edp_dpcd_write(regs, DPCD_TRAINING_LANE0_SET,
					edp->train_set,
					edp->link_train.lane_count);
		if (ret)
			return ret;

		mdelay(1);

		ret = rk_edp_dpcd_read_link_status(edp, status);
		if (ret) {
			printf("displayport link status failed, ret=%d\n", ret);
			break;
		}

		clock_recovery = rk_edp_clock_recovery(status,
						edp->link_train.lane_count);
		if (!clock_recovery)
			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) {
			printf("clock recovery reached max voltage\n");
			break;
		}

		if ((edp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) ==
				voltage) {
			if (++tries == MAX_CR_LOOP) {
				printf("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) {
		printf("clock recovery failed: %d\n", clock_recovery);
		return clock_recovery;
	} else {
		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_priv *edp)
{
	struct rk3288_edp *regs = edp->regs;
	int channel_eq;
	u8 value;
	int tries;
	u8 status[DP_LINK_STATUS_SIZE];
	int ret;

	value = DP_TRAINING_PATTERN_2;
	writel(value, &regs->dp_training_ptn_set);
	ret = rk_edp_dpcd_write(regs, DPCD_TRAINING_PATTERN_SET, &value, 1);
	if (ret)
		return ret;

	/* channel equalization loop */
	channel_eq = 0;
	for (tries = 0; tries < 5; tries++) {
		rk_edp_set_link_training(edp, edp->train_set);
		ret = rk_edp_dpcd_write(regs, DPCD_TRAINING_LANE0_SET,
					edp->train_set,
					edp->link_train.lane_count);
		if (ret)
			return ret;

		udelay(400);

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

		channel_eq = rk_edp_channel_eq(status,
					       edp->link_train.lane_count);
		if (!channel_eq)
			break;
		edp_get_adjust_train(status, edp->link_train.lane_count,
				     edp->train_set);
	}

	if (channel_eq) {
		printf("channel eq failed, ret=%d\n", channel_eq);
		return channel_eq;
	}

	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_priv *edp)
{
	u8 values[3];
	int ret;

	ret = rk_edp_dpcd_read(edp->regs, DPCD_DPCD_REV, values,
			       sizeof(values));
	if (ret < 0)
		return ret;

	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;

	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)) {
		debug("Rx Max Link Rate is abnormal :%x\n",
		      edp->link_train.link_rate);
		return -EPERM;
	}

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

	ret = rk_edp_link_power_up(edp);
	if (ret)
		return ret;

	return rk_edp_link_configure(edp);
}

static int rk_edp_hw_link_training(struct rk_edp_priv *edp)
{
	ulong start;
	u32 val;
	int ret;

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

	ret = rk_edp_link_train_cr(edp);
	if (ret)
		return ret;
	ret = rk_edp_link_train_ce(edp);
	if (ret)
		return ret;

	writel(HW_LT_EN, &edp->regs->dp_hw_link_training);
	start = get_timer(0);
	do {
		val = readl(&edp->regs->dp_hw_link_training);
		if (!(val & HW_LT_EN))
			break;
	} while (get_timer(start) < 10);

	if (val & HW_LT_ERR_CODE_MASK) {
		printf("edp hw link training error: %d\n",
		       val >> HW_LT_ERR_CODE_SHIFT);
		return -EIO;
	}

	return 0;
}

static int rk_edp_select_i2c_device(struct rk3288_edp *regs,
				    unsigned int device_addr,
				    unsigned int val_addr)
{
	int ret;

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

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

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

	/* Start AUX transaction */
	ret = rk_edp_start_aux_transaction(regs);
	if (ret != 0) {
		debug("select_i2c_device Aux Transaction fail!\n");
		return ret;
	}

	return 0;
}

static int rk_edp_i2c_read(struct rk3288_edp *regs, 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 ret = 0;

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

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

			/*
			 * If Rx sends defer, Tx sends only reads
			 * request without sending addres
			 */
			if (!defer) {
				ret = rk_edp_select_i2c_device(regs,
							       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.
			 */
			writel(AUX_LENGTH(16) | AUX_TX_COMM_I2C_TRANSACTION |
			       AUX_TX_COMM_READ, &regs->aux_ch_ctl_1);

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

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

		if (ret)
			return ret;

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

	return 0;
}

static int rk_edp_set_link_train(struct rk_edp_priv *edp)
{
	int ret;

	ret = rk_edp_init_training(edp);
	if (ret) {
		printf("DP LT init failed!\n");
		return ret;
	}

	ret = rk_edp_hw_link_training(edp);
	if (ret)
		return ret;

	return 0;
}

static void rk_edp_init_video(struct rk3288_edp *regs)
{
	writel(VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG,
	       &regs->common_int_sta_1);
	writel(CHA_CRI(4) | CHA_CTRL, &regs->sys_ctl_2);
	writel(VID_HRES_TH(2) | VID_VRES_TH(0), &regs->video_ctl_8);
}

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

static void rk_edp_set_video_cr_mn(struct rk3288_edp *regs,
				   enum clock_recovery_m_value_type type,
				   u32 m_value,
				   u32 n_value)
{
	if (type == REGISTER_M) {
		setbits_le32(&regs->sys_ctl_4, FIX_M_VID);
		writel(m_value & 0xff, &regs->m_vid_0);
		writel((m_value >> 8) & 0xff, &regs->m_vid_1);
		writel((m_value >> 16) & 0xff, &regs->m_vid_2);

		writel(n_value & 0xf, &regs->n_vid_0);
		writel((n_value >> 8) & 0xff, &regs->n_vid_1);
		writel((n_value >> 16) & 0xff, &regs->n_vid_2);
	} else {
		clrbits_le32(&regs->sys_ctl_4, FIX_M_VID);

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

static int rk_edp_is_video_stream_clock_on(struct rk3288_edp *regs)
{
	ulong start;
	u32 val;

	start = get_timer(0);
	do {
		val = readl(&regs->sys_ctl_1);

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

		val = readl(&regs->sys_ctl_2);

		/* must write value to update CHA_STA bit status */
		writel(val, &regs->sys_ctl_2);
		val = readl(&regs->sys_ctl_2);
		if (!(val & CHA_STA))
			return 0;

	} while (get_timer(start) < 100);

	return -ETIMEDOUT;
}

static int rk_edp_is_video_stream_on(struct rk_edp_priv *edp)
{
	ulong start;
	u32 val;

	start = get_timer(0);
	do {
		val = readl(&edp->regs->sys_ctl_3);

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

		val = readl(&edp->regs->sys_ctl_3);
		if (!(val & STRM_VALID))
			return 0;
	} while (get_timer(start) < 100);

	return -ETIMEDOUT;
}

static int rk_edp_config_video(struct rk_edp_priv *edp)
{
	int ret;

	rk_edp_config_video_slave_mode(edp->regs);

	if (!rk_edp_get_pll_locked(edp->regs)) {
		debug("PLL is not locked yet.\n");
		return -ETIMEDOUT;
	}

	ret = rk_edp_is_video_stream_clock_on(edp->regs);
	if (ret)
		return ret;

	/* Set to use the register calculated M/N video */
	rk_edp_set_video_cr_mn(edp->regs, 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_priv *edp)
{
	setbits_le32(&edp->regs->sys_ctl_3, F_HPD | HPD_CTRL);
}

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

	val = readl(&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_priv *edp)
{
	ulong start;

	start = get_timer(0);
	do {
		if (rockchip_edp_get_plug_in_status(edp))
			return;
		udelay(100);
	} while (get_timer(start) < 200);

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

static int rk_edp_enable(struct udevice *dev, int panel_bpp,
			 const struct display_timing *edid)
{
	struct rk_edp_priv *priv = dev_get_priv(dev);
	int ret = 0;

	ret = rk_edp_set_link_train(priv);
	if (ret) {
		printf("link train failed!\n");
		return ret;
	}

	rk_edp_init_video(priv->regs);
	ret = rk_edp_config_video(priv);
	if (ret) {
		printf("config video failed\n");
		return ret;
	}
	ret = panel_enable_backlight(priv->panel);
	if (ret) {
		debug("%s: backlight error: %d\n", __func__, ret);
		return ret;
	}

	return 0;
}

static int rk_edp_read_edid(struct udevice *dev, u8 *buf, int buf_size)
{
	struct rk_edp_priv *priv = dev_get_priv(dev);
	u32 edid_size = EDID_LENGTH;
	int ret;
	int i;

	for (i = 0; i < 3; i++) {
		ret = rk_edp_i2c_read(priv->regs, EDID_ADDR, EDID_HEADER,
				      EDID_LENGTH, &buf[EDID_HEADER]);
		if (ret) {
			debug("EDID read failed\n");
			continue;
		}

		/*
		 * check if the EDID has an extension flag, and read additional
		 * EDID data if needed
		 */
		if (buf[EDID_EXTENSION_FLAG]) {
			edid_size += EDID_LENGTH;
			ret = rk_edp_i2c_read(priv->regs, EDID_ADDR,
					      EDID_LENGTH, EDID_LENGTH,
					      &buf[EDID_LENGTH]);
			if (ret) {
				debug("EDID Read failed!\n");
				continue;
			}
		}
		goto done;
	}

	/* After 3 attempts, give up */
	return ret;

done:
	return edid_size;
}

static int rk_edp_of_to_plat(struct udevice *dev)
{
	struct rk_edp_priv *priv = dev_get_priv(dev);

	priv->regs = dev_read_addr_ptr(dev);
	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);

	return 0;
}

static int rk_edp_remove(struct udevice *dev)
{
	struct rk_edp_priv *priv = dev_get_priv(dev);
	struct rk3288_edp *regs = priv->regs;

	setbits_le32(&regs->video_ctl_1, VIDEO_MUTE);
	clrbits_le32(&regs->video_ctl_1, VIDEO_EN);
	clrbits_le32(&regs->sys_ctl_3, F_HPD | HPD_CTRL);
	setbits_le32(&regs->func_en_1, SW_FUNC_EN_N);

	return 0;
}

static int rk_edp_probe(struct udevice *dev)
{
	struct display_plat *uc_plat = dev_get_uclass_plat(dev);
	struct rk_edp_priv *priv = dev_get_priv(dev);
	struct rk3288_edp *regs = priv->regs;
	struct rockchip_dp_data *edp_data = (struct rockchip_dp_data *)dev_get_driver_data(dev);
	struct reset_ctl dp_rst;

	struct clk clk;
	int ret;

	ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, "rockchip,panel",
					   &priv->panel);
	if (ret) {
		debug("%s: Cannot find panel for '%s' (ret=%d)\n", __func__,
		      dev->name, ret);
		return ret;
	}

	ret = reset_get_by_name(dev, "dp", &dp_rst);
	if (ret) {
		ret = reset_get_by_name(dev, "edp", &dp_rst);
		if (ret) {
			dev_err(dev, "failed to get dp reset (ret=%d)\n", ret);
			return ret;
		}
	}

	ret = reset_assert(&dp_rst);
	if (ret) {
		dev_err(dev, "failed to assert dp reset (ret=%d)\n", ret);
		return ret;
	}
	udelay(20);

	ret = reset_deassert(&dp_rst);
	if (ret) {
		dev_err(dev, "failed to deassert dp reset (ret=%d)\n", ret);
		return ret;
	}

	int vop_id = uc_plat->source_id;
	debug("%s, uc_plat=%p, vop_id=%u\n", __func__, uc_plat, vop_id);

	if (edp_data->chip_type == RK3288_DP) {
		ret = clk_get_by_index(dev, 1, &clk);
		if (ret >= 0)
			ret = clk_set_rate(&clk, 0);
		if (ret) {
			debug("%s: Failed to set EDP clock: ret=%d\n", __func__, ret);
			return ret;
		}
	}
	ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
	if (ret >= 0)
		ret = clk_set_rate(&clk, 192000000);
	if (ret < 0) {
		debug("%s: Failed to set clock in source device '%s': ret=%d\n",
		      __func__, uc_plat->src_dev->name, ret);
		return ret;
	}

	/* grf_edp_ref_clk_sel: from internal 24MHz or 27MHz clock */
	rk_setreg(priv->grf + edp_data->reg_ref_clk_sel,
		  edp_data->ref_clk_sel_bit);

	/* select epd signal from vop0 or vop1 */
	rk_clrsetreg(priv->grf + edp_data->reg_vop_big_little,
		     edp_data->reg_vop_big_little_sel,
		     (vop_id == 1) ? edp_data->reg_vop_big_little_sel : 0);

	rockchip_edp_wait_hpd(priv);

	rk_edp_init_refclk(regs, edp_data->chip_type);
	rk_edp_init_interrupt(regs);
	rk_edp_enable_sw_function(regs);
	ret = rk_edp_init_analog_func(regs);
	if (ret)
		return ret;
	rk_edp_init_aux(regs);

	return 0;
}

static const struct dm_display_ops dp_rockchip_ops = {
	.read_edid = rk_edp_read_edid,
	.enable = rk_edp_enable,
};

static const struct rockchip_dp_data rk3399_edp = {
	.reg_vop_big_little = RK3399_GRF_SOC_CON20,
	.reg_vop_big_little_sel = BIT(5),
	.reg_ref_clk_sel = RK3399_GRF_SOC_CON25,
	.ref_clk_sel_bit = BIT(11),
	.chip_type = RK3399_EDP,
};

static const struct rockchip_dp_data rk3288_dp = {
	.reg_vop_big_little = RK3288_GRF_SOC_CON6,
	.reg_vop_big_little_sel = BIT(5),
	.reg_ref_clk_sel = RK3288_GRF_SOC_CON12,
	.ref_clk_sel_bit = BIT(4),
	.chip_type = RK3288_DP,
};

static const struct udevice_id rockchip_dp_ids[] = {
	{ .compatible = "rockchip,rk3288-dp", .data = (ulong)&rk3288_dp },
	{ .compatible = "rockchip,rk3288-edp", .data = (ulong)&rk3288_dp },
	{ .compatible = "rockchip,rk3399-edp", .data = (ulong)&rk3399_edp },
	{ }
};

U_BOOT_DRIVER(dp_rockchip) = {
	.name	= "edp_rockchip",
	.id	= UCLASS_DISPLAY,
	.of_match = rockchip_dp_ids,
	.ops	= &dp_rockchip_ops,
	.of_to_plat	= rk_edp_of_to_plat,
	.probe	= rk_edp_probe,
	.remove	= rk_edp_remove,
	.priv_auto	= sizeof(struct rk_edp_priv),
};
