rk mipi: fixed the bug of set_bits in rk32_mipi_dsi.c.
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / transmitter / rk32_dp.c
index edf2e0167496fbfda7e857870ef6d3d1298a03e6..51461f1af80b8724e3b889e889ffee0400eb7da5 100644 (file)
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
-#include <linux/rk_fb.h>
+#include <linux/rockchip/iomap.h>
+#include <linux/rockchip/grf.h>
 #include "rk32_dp.h"
-#include "../../../arch/arm/mach-rockchip/iomap.h"
-#include "../../../arch/arm/mach-rockchip/grf.h"
 
 #if defined(CONFIG_OF)
 #include <linux/of.h>
 #endif
 
-/*#define BIST_MODE*/
+#if defined(CONFIG_DEBUG_FS)
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#endif
+
+/*#define EDP_BIST_MODE*/
+/*#define SW_LT*/
+static struct rk32_edp *rk32_edp;
+
+static int rk32_edp_clk_enable(struct rk32_edp *edp)
+{
+       if (!edp->clk_on) {
+               clk_prepare_enable(edp->pd);
+               clk_prepare_enable(edp->pclk);
+               clk_prepare_enable(edp->clk_edp);
+               clk_prepare_enable(edp->clk_24m);
+               edp->clk_on = true;
+       }
+
+       return 0;
+}
+
+static int rk32_edp_clk_disable(struct rk32_edp *edp)
+{
+       if (edp->clk_on) {
+               clk_disable_unprepare(edp->pclk);
+               clk_disable_unprepare(edp->clk_edp);
+               clk_disable_unprepare(edp->clk_24m);
+               clk_disable_unprepare(edp->pd);
+               edp->clk_on = false;
+       }
+
+       return 0;
+}
+
+static int rk32_edp_pre_init(void)
+{
+       u32 val;
+       val = GRF_EDP_REF_CLK_SEL_INTER | (GRF_EDP_REF_CLK_SEL_INTER << 16);
+       writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_SOC_CON12);
+
+       val = 0x80008000;
+       writel_relaxed(val, RK_CRU_VIRT + 0x0d0); /*select 24m*/
+       dsb();
+       val = 0x80008000;
+       writel_relaxed(val, RK_CRU_VIRT + 0x01d0); /*reset edp*/
+       dsb();
+       udelay(1);
+       val = 0x80000000;
+       writel_relaxed(val, RK_CRU_VIRT + 0x01d0);
+       dsb();
+       udelay(1);
+       return 0;
+}
 
 static int rk32_edp_init_edp(struct rk32_edp *edp)
 {
+       struct rk_screen *screen = &edp->screen;
+       u32 val = 0;
+
+       rk_fb_get_prmry_screen(screen);
+       if (screen->lcdc_id == 1)  /*select lcdc*/
+               val = EDP_SEL_VOP_LIT | (EDP_SEL_VOP_LIT << 16);
+       else
+               val = EDP_SEL_VOP_LIT << 16;
+       writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_SOC_CON6);
+
        rk32_edp_reset(edp);
-       rk32_edp_init_analog_param(edp);
+       rk32_edp_init_refclk(edp);
        rk32_edp_init_interrupt(edp);
-
        rk32_edp_enable_sw_function(edp);
-
        rk32_edp_init_analog_func(edp);
-
        rk32_edp_init_hpd(edp);
        rk32_edp_init_aux(edp);
 
        return 0;
 }
 
+#if 0
 static int rk32_edp_detect_hpd(struct rk32_edp *edp)
 {
        int timeout_loop = 0;
@@ -69,21 +130,10 @@ static int rk32_edp_detect_hpd(struct rk32_edp *edp)
 
        return 0;
 }
-
-static unsigned char rk32_edp_calc_edid_check_sum(unsigned char *edid_data)
-{
-       int i;
-       unsigned char sum = 0;
-
-       for (i = 0; i < EDID_BLOCK_LENGTH; i++)
-               sum = sum + edid_data[i];
-
-       return sum;
-}
-
+#endif
 static int rk32_edp_read_edid(struct rk32_edp *edp)
 {
-       unsigned char edid[EDID_BLOCK_LENGTH * 2];
+       unsigned char edid[EDID_LENGTH * 2];
        unsigned int extend_block = 0;
        unsigned char sum;
        unsigned char test_vector;
@@ -96,9 +146,8 @@ static int rk32_edp_read_edid(struct rk32_edp *edp)
         */
 
        /* Read Extension Flag, Number of 128-byte EDID extension blocks */
-       retval = rk32_edp_read_byte_from_i2c(edp, I2C_EDID_DEVICE_ADDR,
-                               EDID_EXTENSION_FLAG,
-                               &extend_block);
+       retval = rk32_edp_read_byte_from_i2c(edp,
+               EDID_ADDR, EDID_EXTENSION_FLAG, &extend_block);
        if (retval < 0) {
                dev_err(edp->dev, "EDID extension flag failed!\n");
                return -EIO;
@@ -108,15 +157,14 @@ static int rk32_edp_read_edid(struct rk32_edp *edp)
                dev_dbg(edp->dev, "EDID data includes a single extension!\n");
 
                /* Read EDID data */
-               retval = rk32_edp_read_bytes_from_i2c(edp, I2C_EDID_DEVICE_ADDR,
-                                               EDID_HEADER_PATTERN,
-                                               EDID_BLOCK_LENGTH,
-                                               &edid[EDID_HEADER_PATTERN]);
+               retval = rk32_edp_read_bytes_from_i2c(edp,
+                               EDID_ADDR, EDID_HEADER,
+                               EDID_LENGTH, &edid[EDID_HEADER]);
                if (retval != 0) {
                        dev_err(edp->dev, "EDID Read failed!\n");
                        return -EIO;
                }
-               sum = rk32_edp_calc_edid_check_sum(edid);
+               sum = edp_calc_edid_check_sum(edid);
                if (sum != 0) {
                        dev_warn(edp->dev, "EDID bad checksum!\n");
                        return 0;
@@ -124,23 +172,20 @@ static int rk32_edp_read_edid(struct rk32_edp *edp)
 
                /* Read additional EDID data */
                retval = rk32_edp_read_bytes_from_i2c(edp,
-                               I2C_EDID_DEVICE_ADDR,
-                               EDID_BLOCK_LENGTH,
-                               EDID_BLOCK_LENGTH,
-                               &edid[EDID_BLOCK_LENGTH]);
+                               EDID_ADDR, EDID_LENGTH,
+                               EDID_LENGTH, &edid[EDID_LENGTH]);
                if (retval != 0) {
                        dev_err(edp->dev, "EDID Read failed!\n");
                        return -EIO;
                }
-               sum = rk32_edp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
+               sum = edp_calc_edid_check_sum(&edid[EDID_LENGTH]);
                if (sum != 0) {
                        dev_warn(edp->dev, "EDID bad checksum!\n");
                        return 0;
                }
 
                retval = rk32_edp_read_byte_from_dpcd(edp,
-                               DPCD_ADDR_TEST_REQUEST,
-                               &test_vector);
+                               DPCD_TEST_REQUEST, &test_vector);
                if (retval < 0) {
                        dev_err(edp->dev, "DPCD EDID Read failed!\n");
                        return retval;
@@ -148,14 +193,14 @@ static int rk32_edp_read_edid(struct rk32_edp *edp)
 
                if (test_vector & DPCD_TEST_EDID_READ) {
                        retval = rk32_edp_write_byte_to_dpcd(edp,
-                                       DPCD_ADDR_TEST_EDID_CHECKSUM,
-                                       edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
+                                       DPCD_TEST_EDID_CHECKSUM,
+                                       edid[EDID_LENGTH + EDID_CHECKSUM]);
                        if (retval < 0) {
                                dev_err(edp->dev, "DPCD EDID Write failed!\n");
                                return retval;
                        }
                        retval = rk32_edp_write_byte_to_dpcd(edp,
-                                       DPCD_ADDR_TEST_RESPONSE,
+                                       DPCD_TEST_RESPONSE,
                                        DPCD_TEST_EDID_CHECKSUM_WRITE);
                        if (retval < 0) {
                                dev_err(edp->dev, "DPCD EDID checksum failed!\n");
@@ -167,23 +212,20 @@ static int rk32_edp_read_edid(struct rk32_edp *edp)
 
                /* Read EDID data */
                retval = rk32_edp_read_bytes_from_i2c(edp,
-                               I2C_EDID_DEVICE_ADDR,
-                               EDID_HEADER_PATTERN,
-                               EDID_BLOCK_LENGTH,
-                               &edid[EDID_HEADER_PATTERN]);
+                               EDID_ADDR, EDID_HEADER,
+                               EDID_LENGTH, &edid[EDID_HEADER]);
                if (retval != 0) {
                        dev_err(edp->dev, "EDID Read failed!\n");
                        return -EIO;
                }
-               sum = rk32_edp_calc_edid_check_sum(edid);
+               sum = edp_calc_edid_check_sum(edid);
                if (sum != 0) {
                        dev_warn(edp->dev, "EDID bad checksum!\n");
                        return 0;
                }
 
                retval = rk32_edp_read_byte_from_dpcd(edp,
-                               DPCD_ADDR_TEST_REQUEST,
-                               &test_vector);
+                               DPCD_TEST_REQUEST, &test_vector);
                if (retval < 0) {
                        dev_err(edp->dev, "DPCD EDID Read failed!\n");
                        return retval;
@@ -191,14 +233,14 @@ static int rk32_edp_read_edid(struct rk32_edp *edp)
 
                if (test_vector & DPCD_TEST_EDID_READ) {
                        retval = rk32_edp_write_byte_to_dpcd(edp,
-                                       DPCD_ADDR_TEST_EDID_CHECKSUM,
+                                       DPCD_TEST_EDID_CHECKSUM,
                                        edid[EDID_CHECKSUM]);
                        if (retval < 0) {
                                dev_err(edp->dev, "DPCD EDID Write failed!\n");
                                return retval;
                        }
                        retval = rk32_edp_write_byte_to_dpcd(edp,
-                                       DPCD_ADDR_TEST_RESPONSE,
+                                       DPCD_TEST_RESPONSE,
                                        DPCD_TEST_EDID_CHECKSUM_WRITE);
                        if (retval < 0) {
                                dev_err(edp->dev, "DPCD EDID checksum failed!\n");
@@ -206,11 +248,12 @@ static int rk32_edp_read_edid(struct rk32_edp *edp)
                        }
                }
        }
-
+       fb_edid_to_monspecs(edid, &edp->specs);
        dev_err(edp->dev, "EDID Read success!\n");
        return 0;
 }
 
+#if 0
 static int rk32_edp_handle_edid(struct rk32_edp *edp)
 {
        u8 buf[12];
@@ -218,11 +261,12 @@ static int rk32_edp_handle_edid(struct rk32_edp *edp)
        int retval;
 
        /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */
-       retval = rk32_edp_read_bytes_from_dpcd(edp, DPCD_ADDR_DPCD_REV,
-                                       12, buf);
+       retval = rk32_edp_read_bytes_from_dpcd(edp, DPCD_REV, 12, buf);
        if (retval < 0)
                return retval;
 
+       for (i = 0; i < 12; i++)
+               dev_info(edp->dev, "%d:>>0x%02x\n", i, buf[i]);
        /* Read EDID */
        for (i = 0; i < 3; i++) {
                retval = rk32_edp_read_edid(edp);
@@ -233,6 +277,7 @@ static int rk32_edp_handle_edid(struct rk32_edp *edp)
        return retval;
 }
 
+
 static int rk32_edp_enable_rx_to_enhanced_mode(struct rk32_edp *edp,
                                                bool enable)
 {
@@ -240,13 +285,13 @@ static int rk32_edp_enable_rx_to_enhanced_mode(struct rk32_edp *edp,
        int retval;
 
        retval = rk32_edp_read_byte_from_dpcd(edp,
-                       DPCD_ADDR_LANE_COUNT_SET, &data);
+                       DPCD_LANE_CNT_SET, &data);
        if (retval < 0)
                return retval;
 
        if (enable) {
                retval = rk32_edp_write_byte_to_dpcd(edp,
-                               DPCD_ADDR_LANE_COUNT_SET,
+                               DPCD_LANE_CNT_SET,
                                DPCD_ENHANCED_FRAME_EN |
                                DPCD_LANE_COUNT_SET(data));
        } else {
@@ -254,7 +299,7 @@ static int rk32_edp_enable_rx_to_enhanced_mode(struct rk32_edp *edp,
                                DPCD_ADDR_CONFIGURATION_SET, 0);*/
 
                retval = rk32_edp_write_byte_to_dpcd(edp,
-                               DPCD_ADDR_LANE_COUNT_SET,
+                               DPCD_LANE_CNT_SET,
                                DPCD_LANE_COUNT_SET(data));
        }
 
@@ -274,19 +319,21 @@ void rk32_edp_rx_control(struct rk32_edp *edp, bool enable)
        }*/
 }
 
+
 static int rk32_edp_is_enhanced_mode_available(struct rk32_edp *edp)
 {
        u8 data;
        int retval;
 
        retval = rk32_edp_read_byte_from_dpcd(edp,
-                       DPCD_ADDR_MAX_LANE_COUNT, &data);
+                       DPCD_MAX_LANE_CNT, &data);
        if (retval < 0)
                return retval;
 
        return DPCD_ENHANCED_FRAME_CAP(data);
 }
 
+
 static void rk32_edp_disable_rx_zmux(struct rk32_edp *edp)
 {
        /*rk32_edp_write_byte_to_dpcd(edp,
@@ -315,7 +362,9 @@ static int rk32_edp_set_enhanced_mode(struct rk32_edp *edp)
 
        return 0;
 }
+#endif
 
+#if defined(SW_LT)
 static int rk32_edp_training_pattern_dis(struct rk32_edp *edp)
 {
        int retval;
@@ -323,7 +372,7 @@ static int rk32_edp_training_pattern_dis(struct rk32_edp *edp)
        rk32_edp_set_training_pattern(edp, DP_NONE);
 
        retval = rk32_edp_write_byte_to_dpcd(edp,
-                       DPCD_ADDR_TRAINING_PATTERN_SET,
+                       DPCD_TRAINING_PATTERN_SET,
                        DPCD_TRAINING_PATTERN_DISABLED);
        if (retval < 0)
                return retval;
@@ -368,7 +417,7 @@ static int rk32_edp_link_start(struct rk32_edp *edp)
                edp->link_train.cr_loop[lane] = 0;
 
        /* Set sink to D0 (Sink Not Ready) mode. */
-       retval = rk32_edp_write_byte_to_dpcd(edp, DPCD_ADDR_SINK_POWER_STATE,
+       retval = rk32_edp_write_byte_to_dpcd(edp, DPCD_SINK_POWER_STATE,
                                DPCD_SET_POWER_STATE_D0);
        if (retval < 0) {
                dev_err(edp->dev, "failed to set sink device to D0!\n");
@@ -382,7 +431,7 @@ static int rk32_edp_link_start(struct rk32_edp *edp)
        /* Setup RX configuration */
        buf[0] = edp->link_train.link_rate;
        buf[1] = edp->link_train.lane_count;
-       retval = rk32_edp_write_bytes_to_dpcd(edp, DPCD_ADDR_LINK_BW_SET,
+       retval = rk32_edp_write_bytes_to_dpcd(edp, DPCD_LINK_BW_SET,
                                        2, buf);
        if (retval < 0) {
                dev_err(edp->dev, "failed to set bandwidth and lane count!\n");
@@ -399,7 +448,7 @@ static int rk32_edp_link_start(struct rk32_edp *edp)
 
        /* Set RX training pattern */
        retval = rk32_edp_write_byte_to_dpcd(edp,
-                       DPCD_ADDR_TRAINING_PATTERN_SET,
+                       DPCD_TRAINING_PATTERN_SET,
                        DPCD_SCRAMBLING_DISABLED |
                        DPCD_TRAINING_PATTERN_1);
        if (retval < 0) {
@@ -411,7 +460,7 @@ static int rk32_edp_link_start(struct rk32_edp *edp)
                buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
                            DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
        retval = rk32_edp_write_bytes_to_dpcd(edp,
-                       DPCD_ADDR_TRAINING_LANE0_SET,
+                       DPCD_TRAINING_LANE0_SET,
                        lane_count, buf);
        if (retval < 0) {
                dev_err(edp->dev, "failed to set training lane!\n");
@@ -550,7 +599,7 @@ static int rk32_edp_process_clock_recovery(struct rk32_edp *edp)
        lane_count = edp->link_train.lane_count;
 
        retval = rk32_edp_read_bytes_from_dpcd(edp,
-                       DPCD_ADDR_LANE0_1_STATUS,
+                       DPCD_LANE0_1_STATUS,
                        2, link_status);
        if (retval < 0) {
                dev_err(edp->dev, "failed to read lane status!\n");
@@ -563,7 +612,7 @@ static int rk32_edp_process_clock_recovery(struct rk32_edp *edp)
 
                for (lane = 0; lane < lane_count; lane++) {
                        retval = rk32_edp_read_bytes_from_dpcd(edp,
-                                       DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+                                       DPCD_ADJUST_REQUEST_LANE0_1,
                                        2, adjust_request);
                        if (retval < 0) {
                                dev_err(edp->dev, "failed to read adjust request!\n");
@@ -590,7 +639,7 @@ static int rk32_edp_process_clock_recovery(struct rk32_edp *edp)
                }
 
                retval = rk32_edp_write_byte_to_dpcd(edp,
-                               DPCD_ADDR_TRAINING_PATTERN_SET,
+                               DPCD_TRAINING_PATTERN_SET,
                                DPCD_SCRAMBLING_DISABLED |
                                DPCD_TRAINING_PATTERN_2);
                if (retval < 0) {
@@ -599,7 +648,7 @@ static int rk32_edp_process_clock_recovery(struct rk32_edp *edp)
                }
 
                retval = rk32_edp_write_bytes_to_dpcd(edp,
-                               DPCD_ADDR_TRAINING_LANE0_SET,
+                               DPCD_TRAINING_LANE0_SET,
                                lane_count,
                                edp->link_train.training_lane);
                if (retval < 0) {
@@ -614,7 +663,7 @@ static int rk32_edp_process_clock_recovery(struct rk32_edp *edp)
                        training_lane = rk32_edp_get_lane_link_training(
                                                        edp, lane);
                        retval = rk32_edp_read_bytes_from_dpcd(edp,
-                                       DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+                                       DPCD_ADJUST_REQUEST_LANE0_1,
                                        2, adjust_request);
                        if (retval < 0) {
                                dev_err(edp->dev, "failed to read adjust request!\n");
@@ -658,7 +707,7 @@ static int rk32_edp_process_clock_recovery(struct rk32_edp *edp)
                }
 
                retval = rk32_edp_write_bytes_to_dpcd(edp,
-                               DPCD_ADDR_TRAINING_LANE0_SET,
+                               DPCD_TRAINING_LANE0_SET,
                                lane_count,
                                edp->link_train.training_lane);
                if (retval < 0) {
@@ -693,7 +742,7 @@ static int rk32_edp_process_equalizer_training(struct rk32_edp *edp)
        lane_count = edp->link_train.lane_count;
 
        retval = rk32_edp_read_bytes_from_dpcd(edp,
-                       DPCD_ADDR_LANE0_1_STATUS,
+                       DPCD_LANE0_1_STATUS,
                        2, link_status);
        if (retval < 0) {
                dev_err(edp->dev, "failed to read lane status!\n");
@@ -705,7 +754,7 @@ static int rk32_edp_process_equalizer_training(struct rk32_edp *edp)
                link_align[1] = link_status[1];
 
                retval = rk32_edp_read_byte_from_dpcd(edp,
-                               DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED,
+                               DPCD_LANE_ALIGN_STATUS_UPDATED,
                                &link_align[2]);
                if (retval < 0) {
                        dev_err(edp->dev, "failed to read lane aligne status!\n");
@@ -714,7 +763,7 @@ static int rk32_edp_process_equalizer_training(struct rk32_edp *edp)
 
                for (lane = 0; lane < lane_count; lane++) {
                        retval = rk32_edp_read_bytes_from_dpcd(edp,
-                                       DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+                                       DPCD_ADJUST_REQUEST_LANE0_1,
                                        2, adjust_request);
                        if (retval < 0) {
                                dev_err(edp->dev, "failed to read adjust request!\n");
@@ -772,7 +821,7 @@ static int rk32_edp_process_equalizer_training(struct rk32_edp *edp)
                                        lane);
 
                        retval = rk32_edp_write_bytes_to_dpcd(edp,
-                                       DPCD_ADDR_TRAINING_LANE0_SET,
+                                       DPCD_TRAINING_LANE0_SET,
                                        lane_count,
                                        edp->link_train.training_lane);
                        if (retval < 0) {
@@ -790,24 +839,25 @@ reduce_link_rate:
        rk32_edp_reduce_link_rate(edp);
        return -EIO;
 }
-
+#endif
 static int rk32_edp_get_max_rx_bandwidth(struct rk32_edp *edp,
                                        u8 *bandwidth)
 {
        u8 data;
-       int retval;
+       int retval = 0;
 
        /*
         * For DP rev.1.1, Maximum link rate of Main Link lanes
         * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
         */
        retval = rk32_edp_read_byte_from_dpcd(edp,
-                       DPCD_ADDR_MAX_LINK_RATE, &data);
+                       DPCD_MAX_LINK_RATE, &data);
        if (retval < 0)
-               return retval;
+               *bandwidth = 0;
+       else
+               *bandwidth = data;
+       return retval;
 
-       *bandwidth = data;
-       return 0;
 }
 
 static int rk32_edp_get_max_rx_lane_count(struct rk32_edp *edp,
@@ -821,17 +871,15 @@ static int rk32_edp_get_max_rx_lane_count(struct rk32_edp *edp,
         * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
         */
        retval = rk32_edp_read_byte_from_dpcd(edp,
-                       DPCD_ADDR_MAX_LANE_COUNT, &data);
+                       DPCD_MAX_LANE_CNT, &data);
        if (retval < 0)
-               return retval;
-
-       *lane_count = DPCD_MAX_LANE_COUNT(data);
-       return 0;
+               *lane_count = 0;
+       else
+               *lane_count = DPCD_MAX_LANE_COUNT(data);
+       return retval;
 }
 
-static int rk32_edp_init_training(struct rk32_edp *edp,
-                       enum link_lane_count_type max_lane,
-                       u32 max_rate)
+static int rk32_edp_init_training(struct rk32_edp *edp)
 {
        int retval;
 
@@ -841,40 +889,41 @@ static int rk32_edp_init_training(struct rk32_edp *edp,
         */
        rk32_edp_reset_macro(edp);
 
-       
-       retval = rk32_edp_get_max_rx_bandwidth(edp, &edp->link_train.link_rate);
-       if (retval < 0)
-               return retval;
 
-       retval = rk32_edp_get_max_rx_lane_count(edp, &edp->link_train.lane_count);
-       if (retval < 0)
-               return retval;
+       retval = rk32_edp_get_max_rx_bandwidth(edp,
+                               &edp->link_train.link_rate);
+       retval = rk32_edp_get_max_rx_lane_count(edp,
+                               &edp->link_train.lane_count);
+       dev_info(edp->dev, "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)) {
-               dev_err(edp->dev, "Rx Max Link Rate is abnormal :%x !\n",
-                       edp->link_train.link_rate);
-               edp->link_train.link_rate = LINK_RATE_1_62GBPS;
+               dev_warn(edp->dev, "Rx Max Link Rate is abnormal :%x !"
+                       "use default link rate:%d.%dGps\n",
+                       edp->link_train.link_rate,
+                       edp->video_info.link_rate*27/100,
+                       edp->video_info.link_rate*27%100);
+               edp->link_train.link_rate = edp->video_info.link_rate;
        }
 
        if (edp->link_train.lane_count == 0) {
-               dev_err(edp->dev, "Rx Max Lane count is abnormal :%x !\n",
-                       edp->link_train.lane_count);
-               edp->link_train.lane_count = (u8)LANE_CNT1;
+               dev_err(edp->dev, "Rx Max Lane count is abnormal :%x !"
+                       "use default lanes:%d\n",
+                       edp->link_train.lane_count,
+                       edp->video_info.lane_count);
+               edp->link_train.lane_count = edp->video_info.lane_count;
        }
 
-       
-       if (edp->link_train.lane_count > max_lane)
-               edp->link_train.lane_count = max_lane;
-       if (edp->link_train.link_rate > max_rate)
-               edp->link_train.link_rate = max_rate;
-
-       
        rk32_edp_analog_power_ctr(edp, 1);
 
+
        return 0;
 }
 
+#if defined(SW_LT)
 static int rk32_edp_sw_link_training(struct rk32_edp *edp)
 {
        int retval = 0;
@@ -911,19 +960,45 @@ static int rk32_edp_sw_link_training(struct rk32_edp *edp)
        return retval;
 }
 
-static int rk32_edp_set_link_train(struct rk32_edp *edp,
-                               u32 count,
-                               u32 bwtype)
+#else
+static int rk32_edp_hw_link_training(struct rk32_edp *edp)
+{
+       u32 cnt = 50;
+       u32 val;
+       /* Set link rate and count as you want to establish*/
+       rk32_edp_set_link_bandwidth(edp, edp->link_train.link_rate);
+       rk32_edp_set_lane_count(edp, edp->link_train.lane_count);
+       rk32_edp_hw_link_training_en(edp);
+       val = rk32_edp_wait_hw_lt_done(edp);
+       while (val) {
+               if (cnt-- <= 0) {
+                       dev_err(edp->dev, "hw lt timeout");
+                       return -ETIMEDOUT;
+               }
+               mdelay(1);
+               val = rk32_edp_wait_hw_lt_done(edp);
+       }
+
+       val = rk32_edp_get_hw_lt_status(edp);
+       if (val)
+               dev_err(edp->dev, "hw lt err:%d\n", val);
+       return val;
+
+}
+#endif
+
+static int rk32_edp_set_link_train(struct rk32_edp *edp)
 {
        int retval;
 
-       retval = rk32_edp_init_training(edp, count, bwtype);
+       retval = rk32_edp_init_training(edp);
        if (retval < 0)
                dev_err(edp->dev, "DP LT init failed!\n");
-
+#if defined(SW_LT)
        retval = rk32_edp_sw_link_training(edp);
-       if (retval < 0)
-               dev_err(edp->dev, "DP LT failed!\n");
+#else
+       retval = rk32_edp_hw_link_training(edp);
+#endif
 
        return retval;
 }
@@ -956,15 +1031,16 @@ static int rk32_edp_config_video(struct rk32_edp *edp,
                        return -ETIMEDOUT;
                }
 
-               usleep_range(1, 1);
+               udelay(1);
        }
 
        /* Set to use the register calculated M/N video */
        rk32_edp_set_video_cr_mn(edp, CALCULATED_M, 0, 0);
 
        /* For video bist, Video timing must be generated by register */
+#ifndef EDP_BIST_MODE
        rk32_edp_set_video_timing_mode(edp, VIDEO_TIMING_FROM_CAPTURE);
-
+#endif
        /* Disable video mute */
        rk32_edp_enable_video_mute(edp, 0);
 
@@ -990,7 +1066,7 @@ static int rk32_edp_config_video(struct rk32_edp *edp,
                        return -ETIMEDOUT;
                }
 
-               usleep_range(1000, 1000);
+               mdelay(1);
        }
 
        if (retval != 0)
@@ -999,6 +1075,7 @@ static int rk32_edp_config_video(struct rk32_edp *edp,
        return retval;
 }
 
+#if 0
 static int rk32_edp_enable_scramble(struct rk32_edp *edp, bool enable)
 {
        u8 data;
@@ -1008,13 +1085,13 @@ static int rk32_edp_enable_scramble(struct rk32_edp *edp, bool enable)
                rk32_edp_enable_scrambling(edp);
 
                retval = rk32_edp_read_byte_from_dpcd(edp,
-                               DPCD_ADDR_TRAINING_PATTERN_SET,
+                               DPCD_TRAINING_PATTERN_SET,
                                &data);
                if (retval < 0)
                        return retval;
 
                retval = rk32_edp_write_byte_to_dpcd(edp,
-                               DPCD_ADDR_TRAINING_PATTERN_SET,
+                               DPCD_TRAINING_PATTERN_SET,
                                (u8)(data & ~DPCD_SCRAMBLING_DISABLED));
                if (retval < 0)
                        return retval;
@@ -1022,13 +1099,13 @@ static int rk32_edp_enable_scramble(struct rk32_edp *edp, bool enable)
                rk32_edp_disable_scrambling(edp);
 
                retval = rk32_edp_read_byte_from_dpcd(edp,
-                               DPCD_ADDR_TRAINING_PATTERN_SET,
+                               DPCD_TRAINING_PATTERN_SET,
                                &data);
                if (retval < 0)
                        return retval;
 
                retval = rk32_edp_write_byte_to_dpcd(edp,
-                               DPCD_ADDR_TRAINING_PATTERN_SET,
+                               DPCD_TRAINING_PATTERN_SET,
                                (u8)(data | DPCD_SCRAMBLING_DISABLED));
                if (retval < 0)
                        return retval;
@@ -1036,118 +1113,208 @@ static int rk32_edp_enable_scramble(struct rk32_edp *edp, bool enable)
 
        return 0;
 }
+#endif
 
-static irqreturn_t rk32_edp_irq_handler(int irq, void *arg)
+static irqreturn_t rk32_edp_isr(int irq, void *arg)
 {
        struct rk32_edp *edp = arg;
+       enum dp_irq_type irq_type;
 
-       dev_err(edp->dev, "rk32_edp_irq_handler\n");
+       irq_type = rk32_edp_get_irq_type(edp);
+       switch (irq_type) {
+       case DP_IRQ_TYPE_HP_CABLE_IN:
+               dev_info(edp->dev, "Received irq - cable in\n");
+               rk32_edp_clear_hotplug_interrupts(edp);
+               break;
+       case DP_IRQ_TYPE_HP_CABLE_OUT:
+               dev_info(edp->dev, "Received irq - cable out\n");
+               rk32_edp_clear_hotplug_interrupts(edp);
+               break;
+       case DP_IRQ_TYPE_HP_CHANGE:
+               /*
+                * We get these change notifications once in a while, but there
+                * is nothing we can do with them. Just ignore it for now and
+                * only handle cable changes.
+                */
+               dev_info(edp->dev, "Received irq - hotplug change; ignoring.\n");
+               rk32_edp_clear_hotplug_interrupts(edp);
+               break;
+       default:
+               dev_err(edp->dev, "Received irq - unknown type!\n");
+               break;
+       }
        return IRQ_HANDLED;
 }
 
-static int rk32_edp_enable(struct rk32_edp *edp)
+static int rk32_edp_enable(void)
 {
        int ret = 0;
-       int retry = 0;
-
-       if (edp->enabled)
-               goto out;
+       struct rk32_edp *edp = rk32_edp;
 
-       edp->enabled = 1;
-       clk_prepare_enable(edp->clk_edp);
-       clk_prepare_enable(edp->clk_24m);
-edp_phy_init:
 
-       
+       rk32_edp_clk_enable(edp);
+       rk32_edp_pre_init();
        rk32_edp_init_edp(edp);
-
-       
-       ret = rk32_edp_handle_edid(edp);
+       enable_irq(edp->irq);
+       /*ret = rk32_edp_handle_edid(edp);
        if (ret) {
                dev_err(edp->dev, "unable to handle edid\n");
-               goto out;
+               //goto out;
        }
 
-       rk32_edp_disable_rx_zmux(edp);
 
-       
        ret = rk32_edp_enable_scramble(edp, 0);
        if (ret) {
                dev_err(edp->dev, "unable to set scramble\n");
-               goto out;
+               //goto out;
        }
 
        ret = rk32_edp_enable_rx_to_enhanced_mode(edp, 0);
        if (ret) {
                dev_err(edp->dev, "unable to set enhanced mode\n");
-               goto out;
-       }
-       rk32_edp_enable_enhanced_mode(edp, 0);
-
-       
-       rk32_edp_rx_control(edp,0);
-
-       /* Link Training */
-       ret = rk32_edp_set_link_train(edp, LANE_CNT4, LINK_RATE_2_70GBPS);
-       if (ret) {
-               dev_err(edp->dev, "unable to do link train\n");
-               goto out;
+               //goto out;
        }
+       rk32_edp_enable_enhanced_mode(edp, 1);*/
 
-       /* Rx data enable */
-       rk32_edp_rx_control(edp,1);
-
-       rk32_edp_set_lane_count(edp, edp->video_info.lane_count);
-       rk32_edp_set_link_bandwidth(edp, edp->video_info.link_rate);
+       ret = rk32_edp_set_link_train(edp);
+       if (ret)
+               dev_err(edp->dev, "link train failed!\n");
+       else
+               dev_info(edp->dev, "link training success.\n");
 
+       rk32_edp_set_lane_count(edp, edp->link_train.lane_count);
+       rk32_edp_set_link_bandwidth(edp, edp->link_train.link_rate);
        rk32_edp_init_video(edp);
+
+#ifdef EDP_BIST_MODE
+       rk32_edp_bist_cfg(edp);
+#endif
        ret = rk32_edp_config_video(edp, &edp->video_info);
-       if (ret) {
+       if (ret)
                dev_err(edp->dev, "unable to config video\n");
-               goto out;
-       }
 
-       return 0;
+       return ret;
 
-out:
 
-       if (retry < 3) {
-               retry++;
-               goto edp_phy_init;
-       }
-       
-       dev_err(edp->dev, "DP LT exceeds max retry count");
 
-       return ret;
 }
-       
-static void rk32_edp_disable(struct rk32_edp *edp)
-{
-       if (!edp->enabled)
-               return ;
 
-       edp->enabled = 0;
+static int  rk32_edp_disable(void)
+{
+       struct rk32_edp *edp = rk32_edp;
 
+       disable_irq(edp->irq);
        rk32_edp_reset(edp);
        rk32_edp_analog_power_ctr(edp, 0);
+       rk32_edp_clk_disable(edp);
+
+       return 0;
+}
+
+
+static struct rk_fb_trsm_ops trsm_edp_ops = {
+       .enable = rk32_edp_enable,
+       .disable = rk32_edp_disable,
+};
+
+
+#if defined(CONFIG_DEBUG_FS)
+
+static int edp_dpcd_debugfs_show(struct seq_file *s, void *v)
+{
+       int i = 0;
+       unsigned char buf[12];
+       struct rk32_edp *edp = s->private;
+       if (!edp) {
+               dev_err(edp->dev, "no edp device!\n");
+               return -ENODEV;
+       }
+
+
+       rk32_edp_read_bytes_from_dpcd(edp,
+                       DPCD_SYMBOL_ERR_CONUT_LANE0, 12, buf);
+       for (i = 0; i < 12; i++)
+               seq_printf(s, "0x%02x>>0x%02x\n", 0x210 + i, buf[i]);
+       return 0;
+}
 
-       clk_disable(edp->clk_24m);
-       clk_disable(edp->clk_edp);
+static ssize_t edp_dpcd_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+{ 
+       return count;
 }
 
+static int edp_edid_debugfs_show(struct seq_file *s, void *v)
+{
+       struct rk32_edp *edp = s->private;
+       if (!edp) {
+               dev_err(edp->dev, "no edp device!\n");
+               return -ENODEV;
+       }
+       rk32_edp_read_edid(edp);
+       seq_puts(s, "edid");
+       return 0;
+}
 
+static ssize_t edp_edid_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+{ 
+       struct rk32_edp *edp =  ((struct seq_file *)file->private_data)->private;
+       if (!edp) {
+               dev_err(edp->dev, "no edp device!\n");
+               return -ENODEV;
+       }
+       rk32_edp_disable();
+       rk32_edp_enable();
+       return count;
+}
 
-static void rk32_edp_init(struct rk32_edp *edp)
+static int edp_reg_debugfs_show(struct seq_file *s, void *v)
 {
+       int i = 0;
+       struct rk32_edp *edp = s->private;
+       if (!edp) {
+               dev_err(edp->dev, "no edp device!\n");
+               return -ENODEV;
+       }
 
-       rk32_edp_enable(edp);
+       for (i = 0; i < 0x284; i++) {
+               if (!(i%4))
+                       seq_printf(s, "\n%08x:  ", i*4);
+               seq_printf(s, "%08x ", readl(edp->regs + i*4));
+       }
+       return 0;
 }
+
+static ssize_t edp_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+{ 
+       return count;
+}
+
+#define EDP_DEBUG_ENTRY(name) \
+static int edp_##name##_debugfs_open(struct inode *inode, struct file *file) \
+{ \
+       return single_open(file, edp_##name##_debugfs_show, inode->i_private); \
+} \
+\
+static const struct file_operations edp_##name##_debugfs_fops = { \
+       .owner = THIS_MODULE, \
+       .open = edp_##name##_debugfs_open, \
+       .read = seq_read, \
+       .write = edp_##name##_write,    \
+       .llseek = seq_lseek, \
+       .release = single_release, \
+}
+
+EDP_DEBUG_ENTRY(dpcd); 
+EDP_DEBUG_ENTRY(edid);
+EDP_DEBUG_ENTRY(reg);
+#endif
+
 static int rk32_edp_probe(struct platform_device *pdev)
 {
        struct rk32_edp *edp;
        struct resource *res;
        struct device_node *np = pdev->dev.of_node;
-       u32 version;
+       int ret;
 
        if (!np) {
                dev_err(&pdev->dev, "Missing device tree node.\n");
@@ -1168,20 +1335,76 @@ static int rk32_edp_probe(struct platform_device *pdev)
        edp->video_info.ycbcr_coeff     = COLOR_YCBCR601;
        edp->video_info.color_depth     = COLOR_8;
 
-       edp->video_info.link_rate       = LINK_RATE_2_70GBPS;
+       edp->video_info.link_rate       = LINK_RATE_1_62GBPS;
        edp->video_info.lane_count      = LANE_CNT4;
-       
+       rk_fb_get_prmry_screen(&edp->screen);
+       if (edp->screen.type != SCREEN_EDP) {
+               dev_err(&pdev->dev, "screen is not edp!\n");
+               return -EINVAL;
+       }
        platform_set_drvdata(pdev, edp);
        dev_set_name(edp->dev, "rk32-edp");
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        edp->regs = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(edp->regs)) {
                dev_err(&pdev->dev, "ioremap reg failed\n");
                return PTR_ERR(edp->regs);
        }
-       version = readl_relaxed(edp->regs + DP_VERSION);
-       dev_info(&pdev->dev, "edp version:0x%08x\n", version);
-       rk32_edp_init(edp);
+
+       edp->pd = devm_clk_get(&pdev->dev, "pd_edp");
+       if (IS_ERR(edp->pd))
+               dev_err(&pdev->dev, "cannot get pd\n");
+       edp->clk_edp = devm_clk_get(&pdev->dev, "clk_edp");
+       if (IS_ERR(edp->clk_edp)) {
+               dev_err(&pdev->dev, "cannot get clk_edp\n");
+               return PTR_ERR(edp->clk_edp);
+       }
+
+       edp->clk_24m = devm_clk_get(&pdev->dev, "clk_edp_24m");
+       if (IS_ERR(edp->clk_24m)) {
+               dev_err(&pdev->dev, "cannot get clk_edp_24m\n");
+               return PTR_ERR(edp->clk_24m);
+       }
+
+       edp->pclk = devm_clk_get(&pdev->dev, "pclk_edp");
+       if (IS_ERR(edp->pclk)) {
+               dev_err(&pdev->dev, "cannot get pclk\n");
+               return PTR_ERR(edp->pclk);
+       }
+       rk32_edp_clk_enable(edp);
+       if (!support_uboot_display())
+               rk32_edp_pre_init();
+       edp->irq = platform_get_irq(pdev, 0);
+       if (edp->irq < 0) {
+               dev_err(&pdev->dev, "cannot find IRQ\n");
+               return edp->irq;
+       }
+       ret = devm_request_irq(&pdev->dev, edp->irq, rk32_edp_isr, 0,
+                       dev_name(&pdev->dev), edp);
+       if (ret) {
+               dev_err(&pdev->dev, "cannot claim IRQ %d\n", edp->irq);
+               return ret;
+       }
+       disable_irq_nosync(edp->irq);
+       if (!support_uboot_display())
+               rk32_edp_clk_disable(edp);
+       rk32_edp = edp;
+       rk_fb_trsm_ops_register(&trsm_edp_ops, SCREEN_EDP);
+#if defined(CONFIG_DEBUG_FS)
+       edp->debugfs_dir = debugfs_create_dir("edp", NULL);
+       if (IS_ERR(edp->debugfs_dir)) {
+               dev_err(edp->dev, "failed to create debugfs dir for edp!\n");
+       } else {
+               debugfs_create_file("dpcd", S_IRUSR, edp->debugfs_dir,
+                                       edp, &edp_dpcd_debugfs_fops);
+               debugfs_create_file("edid", S_IRUSR, edp->debugfs_dir,
+                                       edp, &edp_edid_debugfs_fops);
+               debugfs_create_file("reg", S_IRUSR, edp->debugfs_dir,
+                                       edp, &edp_reg_debugfs_fops);
+       }
+
+#endif
        dev_info(&pdev->dev, "rk32 edp driver probe success\n");
 
        return 0;
@@ -1194,7 +1417,7 @@ static void rk32_edp_shutdown(struct platform_device *pdev)
 
 #if defined(CONFIG_OF)
 static const struct of_device_id rk32_edp_dt_ids[] = {
-       {.compatible = "rockchip, rk32-edp",},
+       {.compatible = "rockchip,rk32-edp",},
        {}
 };