[coreboot-gerrit] Patch set updated for coreboot: rockchip/*: refactor edp driver

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Sat May 7 09:03:52 CEST 2016


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14725

-gerrit

commit b61fc306efb9a0b2614cf55ab8dffa0d748c3d72
Author: Lin Huang <hl at rock-chips.com>
Date:   Mon Apr 25 18:50:55 2016 +0800

    rockchip/*: refactor edp driver
    
    rk3288 and rk3399 use same edp IP, move soc specific setting to
    soc/display, and move edp driver to common, so rk3399 can reuse
    this driver.
    
    BUG=chrome-os-partner:52460
    BRANCH=none
    TEST= test on jerry and mighty, edp panel can work
    
    Change-Id: Ie3f3e8468b2323994af8a002413bf93b3edc8026
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 64bb4b2c7ed373d9730c9aa0b0896a32164fc7ee
    Original-Change-Id: Ie5c15a81849a02d1c0457e36ed00fbe2d47961fb
    Original-Signed-off-by: Lin Huang <hl at rock-chips.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/340504
    Original-Commit-Ready: Vadim Bendebury <vbendeb at chromium.org>
    Original-Tested-by: Vadim Bendebury <vbendeb at chromium.org>
    Original-Reviewed-by: Julius Werner <jwerner at chromium.org>
---
 src/soc/rockchip/common/edp.c                 | 1016 ++++++++++++++++++++++++
 src/soc/rockchip/common/include/soc/edp.h     |  657 ++++++++++++++++
 src/soc/rockchip/rk3288/Makefile.inc          |    2 +-
 src/soc/rockchip/rk3288/display.c             |   12 +-
 src/soc/rockchip/rk3288/edp.c                 | 1021 -------------------------
 src/soc/rockchip/rk3288/include/soc/display.h |    7 +
 src/soc/rockchip/rk3288/include/soc/edp.h     |  662 ----------------
 7 files changed, 1692 insertions(+), 1685 deletions(-)

diff --git a/src/soc/rockchip/common/edp.c b/src/soc/rockchip/common/edp.c
new file mode 100644
index 0000000..90bc6e7
--- /dev/null
+++ b/src/soc/rockchip/common/edp.c
@@ -0,0 +1,1016 @@
+/*
+ * 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 <device/device.h>
+#include <edid.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <soc/addressmap.h>
+#include <soc/display.h>
+#include <soc/edp.h>
+#include <timer.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);
+		rk_edp_dpcd_write(edp, DPCD_TRAINING_LANE0_SET,
+					edp->train_set,
+					edp->link_train.lane_count);
+
+		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 address
+			 */
+			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 360ms to try to get the hpd single now,
+ * if we can not get edp hpd single, it will delay 360ms,
+ * also meet the edp power timing request, to compatible
+ * all of the hardware version
+ */
+static void rk_edp_wait_hpd(struct rk_edp *edp)
+{
+	struct stopwatch hpd;
+
+	stopwatch_init_msecs_expire(&hpd, 360);
+	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(void)
+{
+	rk_edp.regs = (struct rk_edp_regs *)EDP_BASE;
+
+	rk_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);
+}
diff --git a/src/soc/rockchip/common/include/soc/edp.h b/src/soc/rockchip/common/include/soc/edp.h
new file mode 100644
index 0000000..1721fc0
--- /dev/null
+++ b/src/soc/rockchip/common/include/soc/edp.h
@@ -0,0 +1,657 @@
+/*
+ * 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.
+ */
+
+#ifndef __RK_DP_H
+#define __RK_DP_H
+
+#include <edid.h>
+#include <stdlib.h>
+
+struct rk_edp_regs {
+	u8	res0[0x10];
+	u32	dp_tx_version;
+	u8	res1[0x4];
+	u32	func_en_1;
+	u32	func_en_2;
+	u32	video_ctl_1;
+	u32	video_ctl_2;
+	u32	video_ctl_3;
+	u32	video_ctl_4;
+	u8	res2[0xc];
+	u32	video_ctl_8;
+	u8	res3[0x4];
+	u32	video_ctl_10;
+	u32	total_line_l;
+	u32	total_line_h;
+	u32	active_line_l;
+	u32	active_line_h;
+	u32	v_f_porch;
+	u32	vsync;
+	u32	v_b_porch;
+	u32	total_pixel_l;
+	u32	total_pixel_h;
+	u32	active_pixel_l;
+	u32	active_pixel_h;
+	u32	h_f_porch_l;
+	u32	h_f_porch_h;
+	u32	hsync_l;
+	u32	hysnc_h;
+	u32	h_b_porch_l;
+	u32	h_b_porch_h;
+	u32	vid_status;
+	u32	total_line_sta_l;
+	u32	total_line_sta_h;
+	u32	active_line_sta_l;
+	u32	active_line_sta_h;
+	u32	v_f_porch_sta;
+	u32	vsync_sta;
+	u32	v_b_porch_sta;
+	u32	total_pixel_sta_l;
+	u32	total_pixel_sta_h;
+	u32	active_pixel_sta_l;
+	u32	active_pixel_sta_h;
+	u32	h_f_porch_sta_l;
+	u32	h_f_porch_sta_h;
+	u32	hsync_sta_l;
+	u32	hsync_sta_h;
+	u32	h_b_porch_sta_l;
+	u32	h_b_porch__sta_h;
+	u8      res4[0x28];
+	u32	pll_reg_1;
+	u8	res5[4];
+	u32	ssc_reg;
+	u8	res6[0xc];
+	u32	tx_common;
+	u32	tx_common2;
+	u8	res7[0x4];
+	u32	dp_aux;
+	u32	dp_bias;
+	u32	dp_test;
+	u32	dp_pd;
+	u32	dp_reserv1;
+	u32	dp_reserv2;
+	u8	res8[0x224];
+	u32	lane_map;
+	u8	res9[0x14];
+	u32	analog_ctl_2;
+	u8	res10[0x48];
+	u32	int_state;
+	u32	common_int_sta_1;
+	u32	common_int_sta_2;
+	u32	common_int_sta_3;
+	u32	common_int_sta_4;
+	u32	spdif_biphase_int_sta;
+	u8	res11[0x4];
+	u32	dp_int_sta;
+	u32	common_int_mask_1;
+	u32	common_int_mask_2;
+	u32	common_int_mask_3;
+	u32	common_int_mask_4;
+	u8	res12[0x08];
+	u32	int_sta_mask;
+	u32	int_ctl;
+	u8	res13[0x200];
+	u32	sys_ctl_1;
+	u32	sys_ctl_2;
+	u32	sys_ctl_3;
+	u32	sys_ctl_4;
+	u32	dp_vid_ctl;
+	u8	res14[0x4];
+	u32	dp_aud_ctl;
+	u8	res15[0x24];
+	u32	pkt_send_ctl;
+	u8	res16[0x4];
+	u32	dp_hdcp_ctl;
+	u8	res17[0x34];
+	u32	link_bw_set;
+	u32	lane_count_set;
+	u32	dp_training_ptn_set;
+	u32	ln_link_trn_ctl[4];
+	u8	res18[0x4];
+	u32	dp_hw_link_training;
+	u8	res19[0x1c];
+	u32	dp_debug_ctl;
+	u32	hpd_deglitch_l;
+	u32	hpd_deglitch_h;
+	u8	res20[0x14];
+	u32	dp_link_debug_ctl;
+	u8	res21[0x1c];
+	u32	m_vid_0;
+	u32	m_vid_1;
+	u32	m_vid_2;
+	u32	n_vid_0;
+	u32	n_vid_1;
+	u32	n_vid_2;
+	u32	m_vid_mon;
+	u8	res22[0x14];
+	u32	dp_video_fifo_thrd;
+	u8	res23[0x8];
+	u32	dp_audio_margin;
+	u8	res24[0x20];
+	u32	dp_m_cal_ctl;
+	u32	m_vid_gen_filter_th;
+	u8	res25[0x10];
+	u32	m_aud_gen_filter_th;
+	u8	res26[0x4];
+	u32	aux_ch_sta;
+	u32	aux_err_num;
+	u32	aux_ch_defer_dtl;
+	u32	aux_rx_comm;
+	u32	buf_data_ctl;
+	u32	aux_ch_ctl_1;
+	u32	aux_addr_7_0;
+	u32	aux_addr_15_8;
+	u32	aux_addr_19_16;
+	u32	aux_ch_ctl_2;
+	u8	res27[0x18];
+	u32	buf_data[16];
+	u32	soc_general_ctl;
+	u8	res29[0x1e0];
+	u32	pll_reg_2;
+	u32	pll_reg_3;
+	u32	pll_reg_4;
+	u8	res30[0x10];
+	u32	pll_reg_5;
+};
+check_member(rk_edp_regs, pll_reg_5, 0xa00);
+
+/* func_en_1 */
+#define VID_CAP_FUNC_EN_N			(0x1 << 6)
+#define VID_FIFO_FUNC_EN_N			(0x1 << 5)
+#define AUD_FIFO_FUNC_EN_N			(0x1 << 4)
+#define AUD_FUNC_EN_N				(0x1 << 3)
+#define HDCP_FUNC_EN_N				(0x1 << 2)
+#define SW_FUNC_EN_N				(0x1 << 0)
+
+/* func_en_2 */
+#define SSC_FUNC_EN_N				(0x1 << 7)
+#define AUX_FUNC_EN_N				(0x1 << 2)
+#define SERDES_FIFO_FUNC_EN_N			(0x1 << 1)
+#define LS_CLK_DOMAIN_FUNC_EN_N			(0x1 << 0)
+
+/* video_ctl_1 */
+#define VIDEO_EN				(0x1 << 7)
+#define VIDEO_MUTE				(0x1 << 6)
+
+/* video_ctl_2 */
+#define IN_D_RANGE_MASK				(0x1 << 7)
+#define IN_D_RANGE_SHIFT			(7)
+#define IN_D_RANGE_CEA				(0x1 << 7)
+#define IN_D_RANGE_VESA				(0x0 << 7)
+#define IN_BPC_MASK				(0x7 << 4)
+#define IN_BPC_SHIFT				(4)
+#define IN_BPC_12_BITS				(0x3 << 4)
+#define IN_BPC_10_BITS				(0x2 << 4)
+#define IN_BPC_8_BITS				(0x1 << 4)
+#define IN_BPC_6_BITS				(0x0 << 4)
+#define IN_COLOR_F_MASK				(0x3 << 0)
+#define IN_COLOR_F_SHIFT			(0)
+#define IN_COLOR_F_YCBCR444			(0x2 << 0)
+#define IN_COLOR_F_YCBCR422			(0x1 << 0)
+#define IN_COLOR_F_RGB				(0x0 << 0)
+
+/* video_ctl_3 */
+#define IN_YC_COEFFI_MASK			(0x1 << 7)
+#define IN_YC_COEFFI_SHIFT			(7)
+#define IN_YC_COEFFI_ITU709			(0x1 << 7)
+#define IN_YC_COEFFI_ITU601			(0x0 << 7)
+#define VID_CHK_UPDATE_TYPE_MASK		(0x1 << 4)
+#define VID_CHK_UPDATE_TYPE_SHIFT		(4)
+#define VID_CHK_UPDATE_TYPE_1			(0x1 << 4)
+#define VID_CHK_UPDATE_TYPE_0			(0x0 << 4)
+
+/* video_ctl_4 */
+#define BIST_EN					(0x1 << 3)
+#define BIST_WH_64				(0x1 << 2)
+#define BIST_WH_32				(0x0 << 2)
+#define BIST_TYPE_COLR_BAR			(0x0 << 0)
+#define BIST_TYPE_GRAY_BAR			(0x1 << 0)
+#define BIST_TYPE_MOBILE_BAR			(0x2 << 0)
+
+/* video_ctl_8 */
+#define VID_HRES_TH(x)				(((x) & 0xf) << 4)
+#define VID_VRES_TH(x)				(((x) & 0xf) << 0)
+
+/* video_ctl_10 */
+#define F_SEL					(0x1 << 4)
+#define INTERACE_SCAN_CFG			(0x1 << 2)
+#define INTERACD_SCAN_CFG_OFFSET		2
+#define VSYNC_POLARITY_CFG			(0x1 << 1)
+#define VSYNC_POLARITY_CFG_OFFSET		1
+#define HSYNC_POLARITY_CFG			(0x1 << 0)
+#define HSYNC_POLARITY_CFG_OFFSET		0
+
+/* dp_pd */
+#define PD_INC_BG				(0x1 << 7)
+#define PD_EXP_BG				(0x1 << 6)
+#define PD_AUX					(0x1 << 5)
+#define PD_PLL					(0x1 << 4)
+#define PD_CH3					(0x1 << 3)
+#define PD_CH2					(0x1 << 2)
+#define PD_CH1					(0x1 << 1)
+#define PD_CH0					(0x1 << 0)
+
+/* line_map */
+#define LANE3_MAP_LOGIC_LANE_0			(0x0 << 6)
+#define LANE3_MAP_LOGIC_LANE_1			(0x1 << 6)
+#define LANE3_MAP_LOGIC_LANE_2			(0x2 << 6)
+#define LANE3_MAP_LOGIC_LANE_3			(0x3 << 6)
+#define LANE2_MAP_LOGIC_LANE_0			(0x0 << 4)
+#define LANE2_MAP_LOGIC_LANE_1			(0x1 << 4)
+#define LANE2_MAP_LOGIC_LANE_2			(0x2 << 4)
+#define LANE2_MAP_LOGIC_LANE_3			(0x3 << 4)
+#define LANE1_MAP_LOGIC_LANE_0			(0x0 << 2)
+#define LANE1_MAP_LOGIC_LANE_1			(0x1 << 2)
+#define LANE1_MAP_LOGIC_LANE_2			(0x2 << 2)
+#define LANE1_MAP_LOGIC_LANE_3			(0x3 << 2)
+#define LANE0_MAP_LOGIC_LANE_0			(0x0 << 0)
+#define LANE0_MAP_LOGIC_LANE_1			(0x1 << 0)
+#define LANE0_MAP_LOGIC_LANE_2			(0x2 << 0)
+#define LANE0_MAP_LOGIC_LANE_3			(0x3 << 0)
+
+/* analog_ctl_2 */
+#define SEL_24M					(0x1 << 3)
+
+/* common_int_sta_1 */
+#define VSYNC_DET				(0x1 << 7)
+#define PLL_LOCK_CHG				(0x1 << 6)
+#define SPDIF_ERR				(0x1 << 5)
+#define SPDIF_UNSTBL				(0x1 << 4)
+#define VID_FORMAT_CHG				(0x1 << 3)
+#define AUD_CLK_CHG				(0x1 << 2)
+#define VID_CLK_CHG				(0x1 << 1)
+#define SW_INT					(0x1 << 0)
+
+/* common_int_sta_2 */
+#define ENC_EN_CHG				(0x1 << 6)
+#define HW_BKSV_RDY				(0x1 << 3)
+#define HW_SHA_DONE				(0x1 << 2)
+#define HW_AUTH_STATE_CHG			(0x1 << 1)
+#define HW_AUTH_DONE				(0x1 << 0)
+
+/* common_int_sta_3 */
+#define AFIFO_UNDER				(0x1 << 7)
+#define AFIFO_OVER				(0x1 << 6)
+#define R0_CHK_FLAG				(0x1 << 5)
+
+/* common_int_sta_4 */
+#define PSR_ACTIVE				(0x1 << 7)
+#define PSR_INACTIVE				(0x1 << 6)
+#define SPDIF_BI_PHASE_ERR			(0x1 << 5)
+#define HOTPLUG_CHG				(0x1 << 2)
+#define HPD_LOST				(0x1 << 1)
+#define PLUG					(0x1 << 0)
+
+/* dp_int_sta */
+#define INT_HPD					(0x1 << 6)
+#define HW_LT_DONE				(0x1 << 5)
+#define SINK_LOST				(0x1 << 3)
+#define LINK_LOST				(0x1 << 2)
+#define RPLY_RECEIV				(0x1 << 1)
+#define AUX_ERR					(0x1 << 0)
+
+/* int_ctl */
+#define SOFT_INT_CTRL				(0x1 << 2)
+#define INT_POL					(0x1 << 0)
+
+/* sys_ctl_1 */
+#define DET_STA					(0x1 << 2)
+#define FORCE_DET				(0x1 << 1)
+#define DET_CTRL				(0x1 << 0)
+
+/* sys_ctl_2 */
+#define CHA_CRI(x)				(((x) & 0xf) << 4)
+#define CHA_STA					(0x1 << 2)
+#define FORCE_CHA				(0x1 << 1)
+#define CHA_CTRL				(0x1 << 0)
+
+/* sys_ctl_3 */
+#define HPD_STATUS				(0x1 << 6)
+#define F_HPD					(0x1 << 5)
+#define HPD_CTRL				(0x1 << 4)
+#define HDCP_RDY				(0x1 << 3)
+#define STRM_VALID				(0x1 << 2)
+#define F_VALID					(0x1 << 1)
+#define VALID_CTRL				(0x1 << 0)
+
+/* sys_ctl_4 */
+#define FIX_M_AUD				(0x1 << 4)
+#define ENHANCED				(0x1 << 3)
+#define FIX_M_VID				(0x1 << 2)
+#define M_VID_UPDATE_CTRL			(0x3 << 0)
+
+/* pll_reg_2 */
+#define LDO_OUTPUT_V_SEL_145			(2 << 6)
+#define KVCO_DEFALUT				(1 << 4)
+#define CHG_PUMP_CUR_SEL_5US			(1 << 2)
+#define V2L_CUR_SEL_1MA				(1 << 0)
+
+/* pll_reg_3 */
+#define LOCK_DET_CNT_SEL_256			(2 << 5)
+#define LOOP_FILTER_RESET			(0 << 4)
+#define PALL_SSC_RESET				(0 << 3)
+#define LOCK_DET_BYPASS				(0 << 2)
+#define PLL_LOCK_DET_MODE			(0 << 1)
+#define PLL_LOCK_DET_FORCE			(0 << 0)
+
+/* pll_reg_5 */
+#define REGULATOR_V_SEL_950MV			(2 << 4)
+#define STANDBY_CUR_SEL				(0 << 3)
+#define CHG_PUMP_INOUT_CTRL_1200MV		(1 << 1)
+#define CHG_PUMP_INPUT_CTRL_OP			(0 << 0)
+
+/* ssc_reg */
+#define SSC_OFFSET				(0 << 6)
+#define SSC_MODE				(1 << 4)
+#define SSC_DEPTH				(9 << 0)
+
+/* tx_common */
+#define TX_SWING_PRE_EMP_MODE			(1 << 7)
+#define PRE_DRIVER_PW_CTRL1			(0 << 5)
+#define LP_MODE_CLK_REGULATOR			(0 << 4)
+#define RESISTOR_MSB_CTRL			(0 << 3)
+#define RESISTOR_CTRL				(7 << 0)
+
+/* dp_aux */
+#define DP_AUX_COMMON_MODE			(0 << 4)
+#define DP_AUX_EN				(0 << 3)
+#define AUX_TERM_50OHM				(3 << 0)
+
+/* dp_bias */
+#define DP_BG_OUT_SEL				(4 << 4)
+#define DP_DB_CUR_CTRL				(0 << 3)
+#define DP_BG_SEL				(1 << 2)
+#define DP_RESISTOR_TUNE_BG			(2 << 0)
+
+/* dp_reserv2 */
+#define CH1_CH3_SWING_EMP_CTRL			(5 << 4)
+#define CH0_CH2_SWING_EMP_CTRL			(5 << 0)
+
+/* dp_training_ptn_set */
+#define SCRAMBLING_DISABLE			(0x1 << 5)
+#define SCRAMBLING_ENABLE			(0x0 << 5)
+#define LINK_QUAL_PATTERN_SET_MASK		(0x7 << 2)
+#define LINK_QUAL_PATTERN_SET_HBR2		(0x5 << 2)
+#define LINK_QUAL_PATTERN_SET_80BIT		(0x4 << 2)
+#define LINK_QUAL_PATTERN_SET_PRBS7		(0x3 << 2)
+#define LINK_QUAL_PATTERN_SET_D10_2		(0x1 << 2)
+#define LINK_QUAL_PATTERN_SET_DISABLE		(0x0 << 2)
+#define SW_TRAINING_PATTERN_SET_MASK		(0x3 << 0)
+#define SW_TRAINING_PATTERN_SET_PTN2		(0x2 << 0)
+#define SW_TRAINING_PATTERN_SET_PTN1		(0x1 << 0)
+#define SW_TRAINING_PATTERN_SET_DISABLE		(0x0 << 0)
+
+/* dp_hw_link_training_ctl */
+#define HW_LT_ERR_CODE_MASK			0x70
+#define HW_LT_ERR_CODE_SHIFT			4
+#define HW_LT_EN				(0x1 << 0)
+
+/* dp_debug_ctl */
+#define PLL_LOCK				(0x1 << 4)
+#define F_PLL_LOCK				(0x1 << 3)
+#define PLL_LOCK_CTRL				(0x1 << 2)
+#define POLL_EN					(0x1 << 1)
+#define PN_INV					(0x1 << 0)
+
+/* aux_ch_sta */
+#define AUX_BUSY				(0x1 << 4)
+#define AUX_STATUS_MASK				(0xf << 0)
+
+/* aux_ch_defer_ctl */
+#define DEFER_CTRL_EN				(0x1 << 7)
+#define DEFER_COUNT(x)				(((x) & 0x7f) << 0)
+
+/* aux_rx_comm */
+#define AUX_RX_COMM_I2C_DEFER			(0x2 << 2)
+#define AUX_RX_COMM_AUX_DEFER			(0x2 << 0)
+
+/* buffer_data_ctl */
+#define BUF_CLR					(0x1 << 7)
+#define BUF_HAVE_DATA				(0x1 << 4)
+#define BUF_DATA_COUNT(x)			(((x) & 0xf) << 0)
+
+/* aux_ch_ctl_1 */
+#define AUX_LENGTH(x)				(((x - 1) & 0xf) << 4)
+#define AUX_TX_COMM_MASK			(0xf << 0)
+#define AUX_TX_COMM_DP_TRANSACTION		(0x1 << 3)
+#define AUX_TX_COMM_I2C_TRANSACTION		(0x0 << 3)
+#define AUX_TX_COMM_MOT				(0x1 << 2)
+#define AUX_TX_COMM_WRITE			(0x0 << 0)
+#define AUX_TX_COMM_READ			(0x1 << 0)
+
+/* aux_ch_ctl_2 */
+#define PD_AUX_IDLE				(0x1 << 3)
+#define ADDR_ONLY				(0x1 << 1)
+#define AUX_EN					(0x1 << 0)
+
+/* tx_sw_reset */
+#define RST_DP_TX				(0x1 << 0)
+
+/* analog_ctl_1 */
+#define TX_TERMINAL_CTRL_50_OHM			(0x1 << 4)
+
+/* analog_ctl_3 */
+#define DRIVE_DVDD_BIT_1_0625V			(0x4 << 5)
+#define VCO_BIT_600_MICRO			(0x5 << 0)
+
+/* pll_filter_ctl_1 */
+#define PD_RING_OSC				(0x1 << 6)
+#define AUX_TERMINAL_CTRL_37_5_OHM		(0x0 << 4)
+#define AUX_TERMINAL_CTRL_45_OHM		(0x1 << 4)
+#define AUX_TERMINAL_CTRL_50_OHM		(0x2 << 4)
+#define AUX_TERMINAL_CTRL_65_OHM		(0x3 << 4)
+#define TX_CUR1_2X				(0x1 << 2)
+#define TX_CUR_16_MA				(0x3 << 0)
+
+/* Definition for DPCD Register */
+#define DPCD_DPCD_REV				(0x0000)
+#define DPCD_MAX_LINK_RATE			(0x0001)
+#define DPCD_MAX_LANE_COUNT			(0x0002)
+#define DP_MAX_LANE_COUNT_MASK			0x1f
+#define DP_TPS3_SUPPORTED			(1 << 6)
+#define DP_ENHANCED_FRAME_CAP			(1 << 7)
+
+#define DPCD_LINK_BW_SET			(0x0100)
+#define DPCD_LANE_COUNT_SET			(0x0101)
+
+#define DPCD_TRAINING_PATTERN_SET		(0x0102)
+#define DP_TRAINING_PATTERN_DISABLE		0
+#define DP_TRAINING_PATTERN_1			1
+#define DP_TRAINING_PATTERN_2			2
+#define DP_TRAINING_PATTERN_3			3
+#define DP_TRAINING_PATTERN_MASK		0x3
+
+#define DPCD_TRAINING_LANE0_SET			(0x0103)
+#define DP_TRAIN_VOLTAGE_SWING_MASK		0x3
+#define DP_TRAIN_VOLTAGE_SWING_SHIFT		0
+#define DP_TRAIN_MAX_SWING_REACHED		(1 << 2)
+#define DP_TRAIN_VOLTAGE_SWING_400		(0 << 0)
+#define DP_TRAIN_VOLTAGE_SWING_600		(1 << 0)
+#define DP_TRAIN_VOLTAGE_SWING_800		(2 << 0)
+#define DP_TRAIN_VOLTAGE_SWING_1200		(3 << 0)
+
+#define DP_TRAIN_PRE_EMPHASIS_MASK		(3 << 3)
+#define DP_TRAIN_PRE_EMPHASIS_0			(0 << 3)
+#define DP_TRAIN_PRE_EMPHASIS_3_5		(1 << 3)
+#define DP_TRAIN_PRE_EMPHASIS_6			(2 << 3)
+#define DP_TRAIN_PRE_EMPHASIS_9_5		(3 << 3)
+
+#define DP_TRAIN_PRE_EMPHASIS_SHIFT		3
+#define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED	(1 << 5)
+
+#define DPCD_LANE0_1_STATUS			(0x0202)
+#define DPCD_LANE2_3_STATUS			(0x0203)
+#define DP_LANE_CR_DONE				(1 << 0)
+#define DP_LANE_CHANNEL_EQ_DONE			(1 << 1)
+#define DP_LANE_SYMBOL_LOCKED			(1 << 2)
+#define DP_CHANNEL_EQ_BITS			(DP_LANE_CR_DONE |\
+						DP_LANE_CHANNEL_EQ_DONE |\
+						DP_LANE_SYMBOL_LOCKED)
+
+#define DPCD_LANE_ALIGN_STATUS_UPDATED		(0x0204)
+#define DP_INTERLANE_ALIGN_DONE			(1 << 0)
+#define DP_DOWNSTREAM_PORT_STATUS_CHANGED	(1 << 6)
+#define DP_LINK_STATUS_UPDATED			(1 << 7)
+
+#define DPCD_ADJUST_REQUEST_LANE0_1		(0x0206)
+#define DPCD_ADJUST_REQUEST_LANE2_3		(0x0207)
+#define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK	0x03
+#define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT	0
+#define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK	0x0c
+#define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT	2
+#define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK	0x30
+#define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT	4
+#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK	0xc0
+#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT	6
+
+#define DPCD_TEST_REQUEST			(0x0218)
+#define DPCD_TEST_RESPONSE			(0x0260)
+#define DPCD_TEST_EDID_CHECKSUM			(0x0261)
+#define DPCD_LINK_POWER_STATE			(0x0600)
+#define DP_SET_POWER_D0				0x1
+#define DP_SET_POWER_D3				0x2
+#define DP_SET_POWER_MASK			0x3
+
+#define AUX_ADDR_7_0(x)				(((x) >> 0) & 0xff)
+#define AUX_ADDR_15_8(x)			(((x) >> 8) & 0xff)
+#define AUX_ADDR_19_16(x)			(((x) >> 16) & 0x0f)
+
+#define STREAM_ON_TIMEOUT 100
+#define PLL_LOCK_TIMEOUT 10
+#define DP_INIT_TRIES 10
+
+#define EDID_ADDR				0x50
+#define EDID_LENGTH				0x80
+#define EDID_HEADER				0x00
+#define EDID_EXTENSION_FLAG			0x7e
+
+
+enum dpcd_request {
+	DPCD_READ,
+	DPCD_WRITE,
+};
+
+enum dp_irq_type {
+	DP_IRQ_TYPE_HP_CABLE_IN,
+	DP_IRQ_TYPE_HP_CABLE_OUT,
+	DP_IRQ_TYPE_HP_CHANGE,
+	DP_IRQ_TYPE_UNKNOWN,
+};
+
+enum color_coefficient {
+	COLOR_YCBCR601,
+	COLOR_YCBCR709
+};
+
+enum dynamic_range {
+	VESA,
+	CEA
+};
+
+enum pll_status {
+	DP_PLL_UNLOCKED,
+	DP_PLL_LOCKED
+};
+
+enum clock_recovery_m_value_type {
+	CALCULATED_M,
+	REGISTER_M
+};
+
+enum video_timing_recognition_type {
+	VIDEO_TIMING_FROM_CAPTURE,
+	VIDEO_TIMING_FROM_REGISTER
+};
+
+enum pattern_set {
+	PRBS7,
+	D10_2,
+	TRAINING_PTN1,
+	TRAINING_PTN2,
+	DP_NONE
+};
+
+enum color_space {
+	CS_RGB,
+	CS_YCBCR422,
+	CS_YCBCR444
+};
+
+enum color_depth {
+	COLOR_6,
+	COLOR_8,
+	COLOR_10,
+	COLOR_12
+};
+
+enum link_rate_type {
+	LINK_RATE_1_62GBPS = 0x06,
+	LINK_RATE_2_70GBPS = 0x0a
+};
+
+enum link_lane_count_type {
+	LANE_CNT1 = 1,
+	LANE_CNT2 = 2,
+	LANE_CNT4 = 4
+};
+
+enum link_training_state {
+	LT_START,
+	LT_CLK_RECOVERY,
+	LT_EQ_TRAINING,
+	FINISHED,
+	FAILED
+};
+
+enum voltage_swing_level {
+	VOLTAGE_LEVEL_0,
+	VOLTAGE_LEVEL_1,
+	VOLTAGE_LEVEL_2,
+	VOLTAGE_LEVEL_3,
+};
+
+enum pre_emphasis_level {
+	PRE_EMPHASIS_LEVEL_0,
+	PRE_EMPHASIS_LEVEL_1,
+	PRE_EMPHASIS_LEVEL_2,
+	PRE_EMPHASIS_LEVEL_3,
+};
+
+enum analog_power_block {
+	AUX_BLOCK,
+	CH0_BLOCK,
+	CH1_BLOCK,
+	CH2_BLOCK,
+	CH3_BLOCK,
+	ANALOG_TOTAL,
+	POWER_ALL
+};
+
+struct link_train {
+	unsigned char revision;
+	u8 link_rate;
+	u8 lane_count;
+};
+
+struct rk_edp {
+	struct rk_edp_regs	*regs;
+	struct link_train	link_train;
+	u8 train_set[4];
+};
+
+int rk_edp_enable(void);
+void rk_edp_init(void);
+int rk_edp_get_edid(struct edid *edid);
+#endif
diff --git a/src/soc/rockchip/rk3288/Makefile.inc b/src/soc/rockchip/rk3288/Makefile.inc
index 1eab8f2..9d0e9c2 100644
--- a/src/soc/rockchip/rk3288/Makefile.inc
+++ b/src/soc/rockchip/rk3288/Makefile.inc
@@ -68,7 +68,7 @@ ramstage-y += gpio.c
 ramstage-y += ../common/rk808.c
 ramstage-y += ../common/pwm.c
 ramstage-y += vop.c
-ramstage-y += edp.c
+ramstage-y += ../common/edp.c
 ramstage-y += hdmi.c
 ramstage-y += display.c
 ramstage-$(CONFIG_DRIVERS_UART) += ../common/uart.c
diff --git a/src/soc/rockchip/rk3288/display.c b/src/soc/rockchip/rk3288/display.c
index 306baad..f3dfac1 100644
--- a/src/soc/rockchip/rk3288/display.c
+++ b/src/soc/rockchip/rk3288/display.c
@@ -39,6 +39,7 @@ void rk_display_init(device_t dev, u32 lcdbase,
 		unsigned long fb_size)
 {
 	struct edid edid;
+	uint32_t val;
 	struct soc_rockchip_rk3288_config *conf = dev->chip_info;
 	uint32_t lower = ALIGN_DOWN(lcdbase, MiB);
 	uint32_t upper = ALIGN_UP(lcdbase + fb_size, MiB);
@@ -58,7 +59,16 @@ void rk_display_init(device_t dev, u32 lcdbase,
 		printk(BIOS_DEBUG, "Attempting to setup EDP display.\n");
 		rkclk_configure_edp();
 		rkclk_configure_vop_aclk(conf->vop_id, 192 * MHz);
-		rk_edp_init(conf->vop_id);
+
+		/* 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 = (conf->vop_id == 1) ? RK_SETBITS(1 << 5) :
+					    RK_CLRBITS(1 << 5);
+		write32(&rk3288_grf->soc_con6, val);
+
+		rk_edp_init();
 
 		if (rk_edp_get_edid(&edid) == 0) {
 			detected_mode = VOP_MODE_EDP;
diff --git a/src/soc/rockchip/rk3288/edp.c b/src/soc/rockchip/rk3288/edp.c
deleted file mode 100644
index be93e46..0000000
--- a/src/soc/rockchip/rk3288/edp.c
+++ /dev/null
@@ -1,1021 +0,0 @@
-/*
- * 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);
-}
diff --git a/src/soc/rockchip/rk3288/include/soc/display.h b/src/soc/rockchip/rk3288/include/soc/display.h
index b01ea06..8ed2ac9 100644
--- a/src/soc/rockchip/rk3288/include/soc/display.h
+++ b/src/soc/rockchip/rk3288/include/soc/display.h
@@ -16,6 +16,13 @@
 #ifndef __SOC_ROCKCHIP_RK3288_DISPLAY_H__
 #define __SOC_ROCKCHIP_RK3288_DISPLAY_H__
 
+/*
+ * this bit select edp phy pll, this bit define different between
+ * rk3288 and rk3399 in edp phy, so implement it in soc specific code
+ */
+#define REF_CLK_24M	(0x0 << 0)
+#define REF_CLK_27M	(0x1 << 0)
+
 void rk_display_init(device_t dev, u32 lcdbase,
 		unsigned long fb_size);
 
diff --git a/src/soc/rockchip/rk3288/include/soc/edp.h b/src/soc/rockchip/rk3288/include/soc/edp.h
deleted file mode 100644
index e93980d..0000000
--- a/src/soc/rockchip/rk3288/include/soc/edp.h
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef __RK32_DP_H
-#define __RK32_DP_H
-
-#include <edid.h>
-#include <stdlib.h>
-
-struct rk3288_edp_regs {
-	u8	res0[0x10];
-	u32	dp_tx_version;
-	u8	res1[0x4];
-	u32	func_en_1;
-	u32	func_en_2;
-	u32	video_ctl_1;
-	u32	video_ctl_2;
-	u32	video_ctl_3;
-	u32	video_ctl_4;
-	u8	res2[0xc];
-	u32	video_ctl_8;
-	u8	res3[0x4];
-	u32	video_ctl_10;
-	u32	total_line_l;
-	u32	total_line_h;
-	u32	active_line_l;
-	u32	active_line_h;
-	u32	v_f_porch;
-	u32	vsync;
-	u32	v_b_porch;
-	u32	total_pixel_l;
-	u32	total_pixel_h;
-	u32	active_pixel_l;
-	u32	active_pixel_h;
-	u32	h_f_porch_l;
-	u32	h_f_porch_h;
-	u32	hsync_l;
-	u32	hysnc_h;
-	u32	h_b_porch_l;
-	u32	h_b_porch_h;
-	u32	vid_status;
-	u32	total_line_sta_l;
-	u32	total_line_sta_h;
-	u32	active_line_sta_l;
-	u32	active_line_sta_h;
-	u32	v_f_porch_sta;
-	u32	vsync_sta;
-	u32	v_b_porch_sta;
-	u32	total_pixel_sta_l;
-	u32	total_pixel_sta_h;
-	u32	active_pixel_sta_l;
-	u32	active_pixel_sta_h;
-	u32	h_f_porch_sta_l;
-	u32	h_f_porch_sta_h;
-	u32	hsync_sta_l;
-	u32	hsync_sta_h;
-	u32	h_b_porch_sta_l;
-	u32	h_b_porch__sta_h;
-	u8      res4[0x28];
-	u32	pll_reg_1;
-	u8	res5[4];
-	u32	ssc_reg;
-	u8	res6[0xc];
-	u32	tx_common;
-	u32	tx_common2;
-	u8	res7[0x4];
-	u32	dp_aux;
-	u32	dp_bias;
-	u32	dp_test;
-	u32	dp_pd;
-	u32	dp_reserv1;
-	u32	dp_reserv2;
-	u8	res8[0x224];
-	u32	lane_map;
-	u8	res9[0x14];
-	u32	analog_ctl_2;
-	u8	res10[0x48];
-	u32	int_state;
-	u32	common_int_sta_1;
-	u32	common_int_sta_2;
-	u32	common_int_sta_3;
-	u32	common_int_sta_4;
-	u32	spdif_biphase_int_sta;
-	u8	res11[0x4];
-	u32	dp_int_sta;
-	u32	common_int_mask_1;
-	u32	common_int_mask_2;
-	u32	common_int_mask_3;
-	u32	common_int_mask_4;
-	u8	res12[0x08];
-	u32	int_sta_mask;
-	u32	int_ctl;
-	u8	res13[0x200];
-	u32	sys_ctl_1;
-	u32	sys_ctl_2;
-	u32	sys_ctl_3;
-	u32	sys_ctl_4;
-	u32	dp_vid_ctl;
-	u8	res14[0x4];
-	u32	dp_aud_ctl;
-	u8	res15[0x24];
-	u32	pkt_send_ctl;
-	u8	res16[0x4];
-	u32	dp_hdcp_ctl;
-	u8	res17[0x34];
-	u32	link_bw_set;
-	u32	lane_count_set;
-	u32	dp_training_ptn_set;
-	u32	ln_link_trn_ctl[4];
-	u8	res18[0x4];
-	u32	dp_hw_link_training;
-	u8	res19[0x1c];
-	u32	dp_debug_ctl;
-	u32	hpd_deglitch_l;
-	u32	hpd_deglitch_h;
-	u8	res20[0x14];
-	u32	dp_link_debug_ctl;
-	u8	res21[0x1c];
-	u32	m_vid_0;
-	u32	m_vid_1;
-	u32	m_vid_2;
-	u32	n_vid_0;
-	u32	n_vid_1;
-	u32	n_vid_2;
-	u32	m_vid_mon;
-	u8	res22[0x14];
-	u32	dp_video_fifo_thrd;
-	u8	res23[0x8];
-	u32	dp_audio_margin;
-	u8	res24[0x20];
-	u32	dp_m_cal_ctl;
-	u32	m_vid_gen_filter_th;
-	u8	res25[0x10];
-	u32	m_aud_gen_filter_th;
-	u8	res26[0x4];
-	u32	aux_ch_sta;
-	u32	aux_err_num;
-	u32	aux_ch_defer_dtl;
-	u32	aux_rx_comm;
-	u32	buf_data_ctl;
-	u32	aux_ch_ctl_1;
-	u32	aux_addr_7_0;
-	u32	aux_addr_15_8;
-	u32	aux_addr_19_16;
-	u32	aux_ch_ctl_2;
-	u8	res27[0x18];
-	u32	buf_data[16];
-	u32	soc_general_ctl;
-	u8	res29[0x1e0];
-	u32	pll_reg_2;
-	u32	pll_reg_3;
-	u32	pll_reg_4;
-	u8	res30[0x10];
-	u32	pll_reg_5;
-};
-check_member(rk3288_edp_regs, pll_reg_5, 0xa00);
-
-/* func_en_1 */
-#define VID_CAP_FUNC_EN_N			(0x1 << 6)
-#define VID_FIFO_FUNC_EN_N			(0x1 << 5)
-#define AUD_FIFO_FUNC_EN_N			(0x1 << 4)
-#define AUD_FUNC_EN_N				(0x1 << 3)
-#define HDCP_FUNC_EN_N				(0x1 << 2)
-#define SW_FUNC_EN_N				(0x1 << 0)
-
-/* func_en_2 */
-#define SSC_FUNC_EN_N				(0x1 << 7)
-#define AUX_FUNC_EN_N				(0x1 << 2)
-#define SERDES_FIFO_FUNC_EN_N			(0x1 << 1)
-#define LS_CLK_DOMAIN_FUNC_EN_N			(0x1 << 0)
-
-/* video_ctl_1 */
-#define VIDEO_EN				(0x1 << 7)
-#define VIDEO_MUTE				(0x1 << 6)
-
-/* video_ctl_2 */
-#define IN_D_RANGE_MASK				(0x1 << 7)
-#define IN_D_RANGE_SHIFT			(7)
-#define IN_D_RANGE_CEA				(0x1 << 7)
-#define IN_D_RANGE_VESA				(0x0 << 7)
-#define IN_BPC_MASK				(0x7 << 4)
-#define IN_BPC_SHIFT				(4)
-#define IN_BPC_12_BITS				(0x3 << 4)
-#define IN_BPC_10_BITS				(0x2 << 4)
-#define IN_BPC_8_BITS				(0x1 << 4)
-#define IN_BPC_6_BITS				(0x0 << 4)
-#define IN_COLOR_F_MASK				(0x3 << 0)
-#define IN_COLOR_F_SHIFT			(0)
-#define IN_COLOR_F_YCBCR444			(0x2 << 0)
-#define IN_COLOR_F_YCBCR422			(0x1 << 0)
-#define IN_COLOR_F_RGB				(0x0 << 0)
-
-/* video_ctl_3 */
-#define IN_YC_COEFFI_MASK			(0x1 << 7)
-#define IN_YC_COEFFI_SHIFT			(7)
-#define IN_YC_COEFFI_ITU709			(0x1 << 7)
-#define IN_YC_COEFFI_ITU601			(0x0 << 7)
-#define VID_CHK_UPDATE_TYPE_MASK		(0x1 << 4)
-#define VID_CHK_UPDATE_TYPE_SHIFT		(4)
-#define VID_CHK_UPDATE_TYPE_1			(0x1 << 4)
-#define VID_CHK_UPDATE_TYPE_0			(0x0 << 4)
-
-/* video_ctl_4 */
-#define BIST_EN					(0x1 << 3)
-#define BIST_WH_64				(0x1 << 2)
-#define BIST_WH_32				(0x0 << 2)
-#define BIST_TYPE_COLR_BAR			(0x0 << 0)
-#define BIST_TYPE_GRAY_BAR			(0x1 << 0)
-#define BIST_TYPE_MOBILE_BAR			(0x2 << 0)
-
-/* video_ctl_8 */
-#define VID_HRES_TH(x)				(((x) & 0xf) << 4)
-#define VID_VRES_TH(x)				(((x) & 0xf) << 0)
-
-/* video_ctl_10 */
-#define F_SEL					(0x1 << 4)
-#define INTERACE_SCAN_CFG			(0x1 << 2)
-#define INTERACD_SCAN_CFG_OFFSET		2
-#define VSYNC_POLARITY_CFG			(0x1 << 1)
-#define VSYNC_POLARITY_CFG_OFFSET		1
-#define HSYNC_POLARITY_CFG			(0x1 << 0)
-#define HSYNC_POLARITY_CFG_OFFSET		0
-
-/* dp_pd */
-#define PD_INC_BG				(0x1 << 7)
-#define PD_EXP_BG				(0x1 << 6)
-#define PD_AUX					(0x1 << 5)
-#define PD_PLL					(0x1 << 4)
-#define PD_CH3					(0x1 << 3)
-#define PD_CH2					(0x1 << 2)
-#define PD_CH1					(0x1 << 1)
-#define PD_CH0					(0x1 << 0)
-
-/* pll_reg_1 */
-#define REF_CLK_24M				(0x1 << 1)
-#define REF_CLK_27M				(0x0 << 1)
-
-/* line_map */
-#define LANE3_MAP_LOGIC_LANE_0			(0x0 << 6)
-#define LANE3_MAP_LOGIC_LANE_1			(0x1 << 6)
-#define LANE3_MAP_LOGIC_LANE_2			(0x2 << 6)
-#define LANE3_MAP_LOGIC_LANE_3			(0x3 << 6)
-#define LANE2_MAP_LOGIC_LANE_0			(0x0 << 4)
-#define LANE2_MAP_LOGIC_LANE_1			(0x1 << 4)
-#define LANE2_MAP_LOGIC_LANE_2			(0x2 << 4)
-#define LANE2_MAP_LOGIC_LANE_3			(0x3 << 4)
-#define LANE1_MAP_LOGIC_LANE_0			(0x0 << 2)
-#define LANE1_MAP_LOGIC_LANE_1			(0x1 << 2)
-#define LANE1_MAP_LOGIC_LANE_2			(0x2 << 2)
-#define LANE1_MAP_LOGIC_LANE_3			(0x3 << 2)
-#define LANE0_MAP_LOGIC_LANE_0			(0x0 << 0)
-#define LANE0_MAP_LOGIC_LANE_1			(0x1 << 0)
-#define LANE0_MAP_LOGIC_LANE_2			(0x2 << 0)
-#define LANE0_MAP_LOGIC_LANE_3			(0x3 << 0)
-
-/* analog_ctl_2 */
-#define SEL_24M					(0x1 << 3)
-
-/* common_int_sta_1 */
-#define VSYNC_DET				(0x1 << 7)
-#define PLL_LOCK_CHG				(0x1 << 6)
-#define SPDIF_ERR				(0x1 << 5)
-#define SPDIF_UNSTBL				(0x1 << 4)
-#define VID_FORMAT_CHG				(0x1 << 3)
-#define AUD_CLK_CHG				(0x1 << 2)
-#define VID_CLK_CHG				(0x1 << 1)
-#define SW_INT					(0x1 << 0)
-
-/* common_int_sta_2 */
-#define ENC_EN_CHG				(0x1 << 6)
-#define HW_BKSV_RDY				(0x1 << 3)
-#define HW_SHA_DONE				(0x1 << 2)
-#define HW_AUTH_STATE_CHG			(0x1 << 1)
-#define HW_AUTH_DONE				(0x1 << 0)
-
-/* common_int_sta_3 */
-#define AFIFO_UNDER				(0x1 << 7)
-#define AFIFO_OVER				(0x1 << 6)
-#define R0_CHK_FLAG				(0x1 << 5)
-
-/* common_int_sta_4 */
-#define PSR_ACTIVE				(0x1 << 7)
-#define PSR_INACTIVE				(0x1 << 6)
-#define SPDIF_BI_PHASE_ERR			(0x1 << 5)
-#define HOTPLUG_CHG				(0x1 << 2)
-#define HPD_LOST				(0x1 << 1)
-#define PLUG					(0x1 << 0)
-
-/* dp_int_sta */
-#define INT_HPD					(0x1 << 6)
-#define HW_LT_DONE				(0x1 << 5)
-#define SINK_LOST				(0x1 << 3)
-#define LINK_LOST				(0x1 << 2)
-#define RPLY_RECEIV				(0x1 << 1)
-#define AUX_ERR					(0x1 << 0)
-
-/* int_ctl */
-#define SOFT_INT_CTRL				(0x1 << 2)
-#define INT_POL					(0x1 << 0)
-
-/* sys_ctl_1 */
-#define DET_STA					(0x1 << 2)
-#define FORCE_DET				(0x1 << 1)
-#define DET_CTRL				(0x1 << 0)
-
-/* sys_ctl_2 */
-#define CHA_CRI(x)				(((x) & 0xf) << 4)
-#define CHA_STA					(0x1 << 2)
-#define FORCE_CHA				(0x1 << 1)
-#define CHA_CTRL				(0x1 << 0)
-
-/* sys_ctl_3 */
-#define HPD_STATUS				(0x1 << 6)
-#define F_HPD					(0x1 << 5)
-#define HPD_CTRL				(0x1 << 4)
-#define HDCP_RDY				(0x1 << 3)
-#define STRM_VALID				(0x1 << 2)
-#define F_VALID					(0x1 << 1)
-#define VALID_CTRL				(0x1 << 0)
-
-/* sys_ctl_4 */
-#define FIX_M_AUD				(0x1 << 4)
-#define ENHANCED				(0x1 << 3)
-#define FIX_M_VID				(0x1 << 2)
-#define M_VID_UPDATE_CTRL			(0x3 << 0)
-
-/* pll_reg_2 */
-#define LDO_OUTPUT_V_SEL_145			(2 << 6)
-#define KVCO_DEFALUT				(1 << 4)
-#define CHG_PUMP_CUR_SEL_5US			(1 << 2)
-#define V2L_CUR_SEL_1MA				(1 << 0)
-
-/* pll_reg_3 */
-#define LOCK_DET_CNT_SEL_256			(2 << 5)
-#define LOOP_FILTER_RESET			(0 << 4)
-#define PALL_SSC_RESET				(0 << 3)
-#define LOCK_DET_BYPASS				(0 << 2)
-#define PLL_LOCK_DET_MODE			(0 << 1)
-#define PLL_LOCK_DET_FORCE			(0 << 0)
-
-/* pll_reg_5 */
-#define REGULATOR_V_SEL_950MV			(2 << 4)
-#define STANDBY_CUR_SEL				(0 << 3)
-#define CHG_PUMP_INOUT_CTRL_1200MV		(1 << 1)
-#define CHG_PUMP_INPUT_CTRL_OP			(0 << 0)
-
-/* ssc_reg */
-#define SSC_OFFSET				(0 << 6)
-#define SSC_MODE				(1 << 4)
-#define SSC_DEPTH				(9 << 0)
-
-/* tx_common */
-#define TX_SWING_PRE_EMP_MODE			(1 << 7)
-#define PRE_DRIVER_PW_CTRL1			(0 << 5)
-#define LP_MODE_CLK_REGULATOR			(0 << 4)
-#define RESISTOR_MSB_CTRL			(0 << 3)
-#define RESISTOR_CTRL				(7 << 0)
-
-/* dp_aux */
-#define DP_AUX_COMMON_MODE			(0 << 4)
-#define DP_AUX_EN				(0 << 3)
-#define AUX_TERM_50OHM				(3 << 0)
-
-/* dp_bias */
-#define DP_BG_OUT_SEL				(4 << 4)
-#define DP_DB_CUR_CTRL				(0 << 3)
-#define DP_BG_SEL				(1 << 2)
-#define DP_RESISTOR_TUNE_BG			(2 << 0)
-
-/* dp_reserv2 */
-#define CH1_CH3_SWING_EMP_CTRL			(5 << 4)
-#define CH0_CH2_SWING_EMP_CTRL			(5 << 0)
-
-/* dp_training_ptn_set */
-#define SCRAMBLING_DISABLE			(0x1 << 5)
-#define SCRAMBLING_ENABLE			(0x0 << 5)
-#define LINK_QUAL_PATTERN_SET_MASK		(0x7 << 2)
-#define LINK_QUAL_PATTERN_SET_HBR2		(0x5 << 2)
-#define LINK_QUAL_PATTERN_SET_80BIT		(0x4 << 2)
-#define LINK_QUAL_PATTERN_SET_PRBS7		(0x3 << 2)
-#define LINK_QUAL_PATTERN_SET_D10_2		(0x1 << 2)
-#define LINK_QUAL_PATTERN_SET_DISABLE		(0x0 << 2)
-#define SW_TRAINING_PATTERN_SET_MASK		(0x3 << 0)
-#define SW_TRAINING_PATTERN_SET_PTN2		(0x2 << 0)
-#define SW_TRAINING_PATTERN_SET_PTN1		(0x1 << 0)
-#define SW_TRAINING_PATTERN_SET_DISABLE		(0x0 << 0)
-
-/* dp_hw_link_training_ctl */
-#define HW_LT_ERR_CODE_MASK			0x70
-#define HW_LT_ERR_CODE_SHIFT			4
-#define HW_LT_EN				(0x1 << 0)
-
-/* dp_debug_ctl */
-#define PLL_LOCK				(0x1 << 4)
-#define F_PLL_LOCK				(0x1 << 3)
-#define PLL_LOCK_CTRL				(0x1 << 2)
-#define POLL_EN					(0x1 << 1)
-#define PN_INV					(0x1 << 0)
-
-/* aux_ch_sta */
-#define AUX_BUSY				(0x1 << 4)
-#define AUX_STATUS_MASK				(0xf << 0)
-
-/* aux_ch_defer_ctl */
-#define DEFER_CTRL_EN				(0x1 << 7)
-#define DEFER_COUNT(x)				(((x) & 0x7f) << 0)
-
-/* aux_rx_comm */
-#define AUX_RX_COMM_I2C_DEFER			(0x2 << 2)
-#define AUX_RX_COMM_AUX_DEFER			(0x2 << 0)
-
-/* buffer_data_ctl */
-#define BUF_CLR					(0x1 << 7)
-#define BUF_HAVE_DATA				(0x1 << 4)
-#define BUF_DATA_COUNT(x)			(((x) & 0xf) << 0)
-
-/* aux_ch_ctl_1 */
-#define AUX_LENGTH(x)				(((x - 1) & 0xf) << 4)
-#define AUX_TX_COMM_MASK			(0xf << 0)
-#define AUX_TX_COMM_DP_TRANSACTION		(0x1 << 3)
-#define AUX_TX_COMM_I2C_TRANSACTION		(0x0 << 3)
-#define AUX_TX_COMM_MOT				(0x1 << 2)
-#define AUX_TX_COMM_WRITE			(0x0 << 0)
-#define AUX_TX_COMM_READ			(0x1 << 0)
-
-/* aux_ch_ctl_2 */
-#define PD_AUX_IDLE				(0x1 << 3)
-#define ADDR_ONLY				(0x1 << 1)
-#define AUX_EN					(0x1 << 0)
-
-/* tx_sw_reset */
-#define RST_DP_TX				(0x1 << 0)
-
-/* analog_ctl_1 */
-#define TX_TERMINAL_CTRL_50_OHM			(0x1 << 4)
-
-/* analog_ctl_3 */
-#define DRIVE_DVDD_BIT_1_0625V			(0x4 << 5)
-#define VCO_BIT_600_MICRO			(0x5 << 0)
-
-/* pll_filter_ctl_1 */
-#define PD_RING_OSC				(0x1 << 6)
-#define AUX_TERMINAL_CTRL_37_5_OHM		(0x0 << 4)
-#define AUX_TERMINAL_CTRL_45_OHM		(0x1 << 4)
-#define AUX_TERMINAL_CTRL_50_OHM		(0x2 << 4)
-#define AUX_TERMINAL_CTRL_65_OHM		(0x3 << 4)
-#define TX_CUR1_2X				(0x1 << 2)
-#define TX_CUR_16_MA				(0x3 << 0)
-
-/* Definition for DPCD Register */
-#define DPCD_DPCD_REV				(0x0000)
-#define DPCD_MAX_LINK_RATE			(0x0001)
-#define DPCD_MAX_LANE_COUNT			(0x0002)
-#define DP_MAX_LANE_COUNT_MASK			0x1f
-#define DP_TPS3_SUPPORTED			(1 << 6)
-#define DP_ENHANCED_FRAME_CAP			(1 << 7)
-
-#define DPCD_LINK_BW_SET			(0x0100)
-#define DPCD_LANE_COUNT_SET			(0x0101)
-
-#define DPCD_TRAINING_PATTERN_SET		(0x0102)
-#define DP_TRAINING_PATTERN_DISABLE		0
-#define DP_TRAINING_PATTERN_1			1
-#define DP_TRAINING_PATTERN_2			2
-#define DP_TRAINING_PATTERN_3			3
-#define DP_TRAINING_PATTERN_MASK		0x3
-
-#define DPCD_TRAINING_LANE0_SET			(0x0103)
-#define DP_TRAIN_VOLTAGE_SWING_MASK		0x3
-#define DP_TRAIN_VOLTAGE_SWING_SHIFT		0
-#define DP_TRAIN_MAX_SWING_REACHED		(1 << 2)
-#define DP_TRAIN_VOLTAGE_SWING_400		(0 << 0)
-#define DP_TRAIN_VOLTAGE_SWING_600		(1 << 0)
-#define DP_TRAIN_VOLTAGE_SWING_800		(2 << 0)
-#define DP_TRAIN_VOLTAGE_SWING_1200		(3 << 0)
-
-#define DP_TRAIN_PRE_EMPHASIS_MASK		(3 << 3)
-#define DP_TRAIN_PRE_EMPHASIS_0			(0 << 3)
-#define DP_TRAIN_PRE_EMPHASIS_3_5		(1 << 3)
-#define DP_TRAIN_PRE_EMPHASIS_6			(2 << 3)
-#define DP_TRAIN_PRE_EMPHASIS_9_5		(3 << 3)
-
-#define DP_TRAIN_PRE_EMPHASIS_SHIFT		3
-#define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED	(1 << 5)
-
-#define DPCD_LANE0_1_STATUS			(0x0202)
-#define DPCD_LANE2_3_STATUS			(0x0203)
-#define DP_LANE_CR_DONE				(1 << 0)
-#define DP_LANE_CHANNEL_EQ_DONE			(1 << 1)
-#define DP_LANE_SYMBOL_LOCKED			(1 << 2)
-#define DP_CHANNEL_EQ_BITS			(DP_LANE_CR_DONE |\
-						DP_LANE_CHANNEL_EQ_DONE |\
-						DP_LANE_SYMBOL_LOCKED)
-
-#define DPCD_LANE_ALIGN_STATUS_UPDATED		(0x0204)
-#define DP_INTERLANE_ALIGN_DONE			(1 << 0)
-#define DP_DOWNSTREAM_PORT_STATUS_CHANGED	(1 << 6)
-#define DP_LINK_STATUS_UPDATED			(1 << 7)
-
-#define DPCD_ADJUST_REQUEST_LANE0_1		(0x0206)
-#define DPCD_ADJUST_REQUEST_LANE2_3		(0x0207)
-#define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK	0x03
-#define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT	0
-#define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK	0x0c
-#define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT	2
-#define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK	0x30
-#define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT	4
-#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK	0xc0
-#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT	6
-
-#define DPCD_TEST_REQUEST			(0x0218)
-#define DPCD_TEST_RESPONSE			(0x0260)
-#define DPCD_TEST_EDID_CHECKSUM			(0x0261)
-#define DPCD_LINK_POWER_STATE			(0x0600)
-#define DP_SET_POWER_D0				0x1
-#define DP_SET_POWER_D3				0x2
-#define DP_SET_POWER_MASK			0x3
-
-#define AUX_ADDR_7_0(x)				(((x) >> 0) & 0xff)
-#define AUX_ADDR_15_8(x)			(((x) >> 8) & 0xff)
-#define AUX_ADDR_19_16(x)			(((x) >> 16) & 0x0f)
-
-#define STREAM_ON_TIMEOUT 100
-#define PLL_LOCK_TIMEOUT 10
-#define DP_INIT_TRIES 10
-
-#define EDID_ADDR				0x50
-#define EDID_LENGTH				0x80
-#define EDID_HEADER				0x00
-#define EDID_EXTENSION_FLAG			0x7e
-
-
-enum dpcd_request {
-	DPCD_READ,
-	DPCD_WRITE,
-};
-
-enum dp_irq_type {
-	DP_IRQ_TYPE_HP_CABLE_IN,
-	DP_IRQ_TYPE_HP_CABLE_OUT,
-	DP_IRQ_TYPE_HP_CHANGE,
-	DP_IRQ_TYPE_UNKNOWN,
-};
-
-enum color_coefficient {
-	COLOR_YCBCR601,
-	COLOR_YCBCR709
-};
-
-enum dynamic_range {
-	VESA,
-	CEA
-};
-
-enum pll_status {
-	DP_PLL_UNLOCKED,
-	DP_PLL_LOCKED
-};
-
-enum clock_recovery_m_value_type {
-	CALCULATED_M,
-	REGISTER_M
-};
-
-enum video_timing_recognition_type {
-	VIDEO_TIMING_FROM_CAPTURE,
-	VIDEO_TIMING_FROM_REGISTER
-};
-
-enum pattern_set {
-	PRBS7,
-	D10_2,
-	TRAINING_PTN1,
-	TRAINING_PTN2,
-	DP_NONE
-};
-
-enum color_space {
-	CS_RGB,
-	CS_YCBCR422,
-	CS_YCBCR444
-};
-
-enum color_depth {
-	COLOR_6,
-	COLOR_8,
-	COLOR_10,
-	COLOR_12
-};
-
-enum link_rate_type {
-	LINK_RATE_1_62GBPS = 0x06,
-	LINK_RATE_2_70GBPS = 0x0a
-};
-
-enum link_lane_count_type {
-	LANE_CNT1 = 1,
-	LANE_CNT2 = 2,
-	LANE_CNT4 = 4
-};
-
-enum link_training_state {
-	LT_START,
-	LT_CLK_RECOVERY,
-	LT_EQ_TRAINING,
-	FINISHED,
-	FAILED
-};
-
-enum voltage_swing_level {
-	VOLTAGE_LEVEL_0,
-	VOLTAGE_LEVEL_1,
-	VOLTAGE_LEVEL_2,
-	VOLTAGE_LEVEL_3,
-};
-
-enum pre_emphasis_level {
-	PRE_EMPHASIS_LEVEL_0,
-	PRE_EMPHASIS_LEVEL_1,
-	PRE_EMPHASIS_LEVEL_2,
-	PRE_EMPHASIS_LEVEL_3,
-};
-
-enum analog_power_block {
-	AUX_BLOCK,
-	CH0_BLOCK,
-	CH1_BLOCK,
-	CH2_BLOCK,
-	CH3_BLOCK,
-	ANALOG_TOTAL,
-	POWER_ALL
-};
-
-struct link_train {
-	unsigned char revision;
-	u8 link_rate;
-	u8 lane_count;
-};
-
-struct rk_edp {
-	struct rk3288_edp_regs	*regs;
-	struct link_train	link_train;
-	u8 train_set[4];
-};
-
-int rk_edp_enable(void);
-void rk_edp_init(u32 vop_id);
-int rk_edp_get_edid(struct edid *edid);
-
-#endif



More information about the coreboot-gerrit mailing list