From: yxj Date: Wed, 26 Feb 2014 07:12:23 +0000 (+0800) Subject: rk32 edp:add bist/hw link traing support X-Git-Tag: firefly_0821_release~6186 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7aefc71b1752322b78ec2e616a66f68063026edf;p=firefly-linux-kernel-4.4.55.git rk32 edp:add bist/hw link traing support --- diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 371865ff545a..e9435f4b57ff 100755 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -170,6 +170,7 @@ rockchip,check-idle = <1>; status = "disabled"; }; + i2c5: i2c@ff170000 { compatible = "rockchip,rk30-i2c"; @@ -186,6 +187,12 @@ status = "disabled"; }; + edp: edp@ff970000 { + compatible = "rockchip,rk32-edp"; + reg = <0xff970000 0x4000>; + interrupts = ; + status = "disabled"; + } adc: adc@ff100000 { compatible = "rockchip,saradc"; reg = <0xff100000 0x100>; @@ -202,7 +209,7 @@ compatible = "rockchip,rga"; reg = <0xff920000 0x1000>; interrupts = ; - clock-names = "hclk_rga", "aclk_rga"; + clock-names = "hclk_rga", "aclk_rga"; status = "disabled"; }; diff --git a/drivers/video/rockchip/transmitter/dpcd_edid.h b/drivers/video/rockchip/transmitter/dpcd_edid.h index 405283e41aff..23968a94ba6b 100644 --- a/drivers/video/rockchip/transmitter/dpcd_edid.h +++ b/drivers/video/rockchip/transmitter/dpcd_edid.h @@ -3,8 +3,8 @@ #include "../../edid.h" #define DPCD_REV 0x00 -#define DPCD_MAX_LINK_RATE 0x01 -#define DPCD_MAX_LANE_CNT 0x02 +#define DPCD_MAX_LINK_RATE 0x01 +#define DPCD_MAX_LANE_CNT 0x02 #define DPCD_MAX_DOWNSPREAD 0x03 #define DPCD_NORP 0x04 @@ -120,7 +120,7 @@ #define EDID_EXTENSION_FLAG 0x7e #define EDID_CHECKSUM 0x7f -static unsigned char edp_calc_edid_check_sum(unsigned char *edid_data) +static unsigned char inline edp_calc_edid_check_sum(unsigned char *edid_data) { int i; unsigned char sum = 0; diff --git a/drivers/video/rockchip/transmitter/rk32_dp.c b/drivers/video/rockchip/transmitter/rk32_dp.c index edf2e0167496..a321b4389b0d 100644 --- a/drivers/video/rockchip/transmitter/rk32_dp.c +++ b/drivers/video/rockchip/transmitter/rk32_dp.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "rk32_dp.h" #include "../../../arch/arm/mach-rockchip/iomap.h" #include "../../../arch/arm/mach-rockchip/grf.h" @@ -32,7 +31,7 @@ #include #endif -/*#define BIST_MODE*/ +/*#define EDP_BIST_MODE*/ static int rk32_edp_init_edp(struct rk32_edp *edp) { @@ -70,20 +69,9 @@ 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; -} - 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 +84,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,39 +95,33 @@ 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; } /* 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]); + retval = rk32_edp_read_bytes_from_i2c(edp, 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); + retval = rk32_edp_read_byte_from_dpcd(edp, DPCD_TEST_REQUEST, + &test_vector); if (retval < 0) { dev_err(edp->dev, "DPCD EDID Read failed!\n"); return retval; @@ -148,14 +129,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"); @@ -166,24 +147,20 @@ static int rk32_edp_read_edid(struct rk32_edp *edp) dev_info(edp->dev, "EDID data does not include any extensions.\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; } - retval = rk32_edp_read_byte_from_dpcd(edp, - DPCD_ADDR_TEST_REQUEST, - &test_vector); + retval = rk32_edp_read_byte_from_dpcd(edp,DPCD_TEST_REQUEST, + &test_vector); if (retval < 0) { dev_err(edp->dev, "DPCD EDID Read failed!\n"); return retval; @@ -191,14 +168,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"); @@ -218,8 +195,7 @@ 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; @@ -240,13 +216,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 +230,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)); } @@ -280,7 +256,7 @@ static int rk32_edp_is_enhanced_mode_available(struct rk32_edp *edp) 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; @@ -323,7 +299,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 +344,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 +358,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 +375,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 +387,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 +526,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 +539,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 +566,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 +575,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 +590,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 +634,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 +669,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 +681,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 +690,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 +748,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) { @@ -802,7 +778,7 @@ static int rk32_edp_get_max_rx_bandwidth(struct rk32_edp *edp, * 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; @@ -821,7 +797,7 @@ 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; @@ -849,7 +825,11 @@ static int rk32_edp_init_training(struct rk32_edp *edp, retval = rk32_edp_get_max_rx_lane_count(edp, &edp->link_train.lane_count); if (retval < 0) return retval; - + 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", @@ -911,6 +891,32 @@ static int rk32_edp_sw_link_training(struct rk32_edp *edp) return retval; } + +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); + mdelay(1); + 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; + +} static int rk32_edp_set_link_train(struct rk32_edp *edp, u32 count, u32 bwtype) @@ -920,10 +926,11 @@ static int rk32_edp_set_link_train(struct rk32_edp *edp, retval = rk32_edp_init_training(edp, count, bwtype); if (retval < 0) dev_err(edp->dev, "DP LT init failed!\n"); - +#if 0 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; } @@ -1008,13 +1015,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 +1029,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; @@ -1037,11 +1044,11 @@ static int rk32_edp_enable_scramble(struct rk32_edp *edp, bool enable) return 0; } -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; - dev_err(edp->dev, "rk32_edp_irq_handler\n"); + dev_info(edp->dev, "rk32_edp_isr\n"); return IRQ_HANDLED; } @@ -1090,7 +1097,7 @@ edp_phy_init: /* 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"); + dev_err(edp->dev, "link train failed\n"); goto out; } @@ -1100,12 +1107,16 @@ edp_phy_init: rk32_edp_set_lane_count(edp, edp->video_info.lane_count); rk32_edp_set_link_bandwidth(edp, edp->video_info.link_rate); +#ifdef EDP_BIST_MODE + rk32_edp_bist_cfg(edp); +#else rk32_edp_init_video(edp); ret = rk32_edp_config_video(edp, &edp->video_info); if (ret) { dev_err(edp->dev, "unable to config video\n"); goto out; } +#endif return 0; @@ -1147,7 +1158,7 @@ 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"); @@ -1170,7 +1181,11 @@ static int rk32_edp_probe(struct platform_device *pdev) edp->video_info.link_rate = LINK_RATE_2_70GBPS; 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); @@ -1179,8 +1194,13 @@ static int rk32_edp_probe(struct platform_device *pdev) 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); + 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; + } + rk32_edp_init(edp); dev_info(&pdev->dev, "rk32 edp driver probe success\n"); diff --git a/drivers/video/rockchip/transmitter/rk32_dp.h b/drivers/video/rockchip/transmitter/rk32_dp.h index 3f426e91acf0..de5632ff6d25 100644 --- a/drivers/video/rockchip/transmitter/rk32_dp.h +++ b/drivers/video/rockchip/transmitter/rk32_dp.h @@ -1,5 +1,7 @@ #ifndef __RK32_DP_H #define __RK32_DP_H +#include +#include "dpcd_edid.h" #define DP_VERSION 0x10 @@ -68,6 +70,24 @@ #define VSYNC_POLARITY_CFG (0x1 << 1) #define HSYNC_POLARITY_CFG (0x1 << 0) +#define TOTAL_LINE_CFG_L 0x48 +#define TOTAL_LINE_CFG_H 0x4c +#define ATV_LINE_CFG_L 0x50 +#define ATV_LINE_CFG_H 0x54 +#define VF_PORCH_REG 0x58 +#define VSYNC_CFG_REG 0x5c +#define VB_PORCH_REG 0x60 +#define TOTAL_PIXELL_REG 0x64 +#define TOTAL_PIXELH_REG 0x68 +#define ATV_PIXELL_REG 0x6c +#define ATV_PIXELH_REG 0x70 +#define HF_PORCHL_REG 0x74 +#define HF_PORCHH_REG 0x78 +#define HSYNC_CFGL_REG 0x7c +#define HSYNC_CFGH_REG 0x80 +#define HB_PORCHL_REG 0x84 +#define HB_PORCHH_REG 0x88 + #define PLL_REG_1 0xfc #define REF_CLK_24M (0x01 << 1) #define REF_CLK_27M (0x0 << 1) @@ -212,6 +232,7 @@ #define LN3_LINK_TRAINING_CTL 0x698 #define HW_LT_CTL 0x6a0 +#define HW_LT_ERR_CODE_MASK 0x70 #define HW_LT_EN (0x1 << 0) #define DEBUG_CTL 0x6C0 @@ -247,9 +268,6 @@ #define DEFER_COUNT(x) (((x) & 0x7f) << 0) #define AUX_RX_COMM 0x78C -#define AUX_RX_COMM_I2C_DEFER (0x2 << 2) -#define AUX_RX_COMM_AUX_DEFER (0x2 << 0) - #define BUFFER_DATA_CTL 0x790 #define BUF_CLR (0x1 << 7) #define BUF_HAVE_DATA (0x1 << 4) @@ -338,90 +356,9 @@ -/* AUX_ADDR_7_0 */ -#define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff) - -/* AUX_ADDR_15_8 */ -#define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff) - -/* AUX_ADDR_19_16 */ -#define AUX_ADDR_19_16(x) (((x) >> 16) & 0x0f) - - -/* I2C EDID Chip ID, Slave Address */ -#define I2C_EDID_DEVICE_ADDR 0x50 -#define I2C_E_EDID_DEVICE_ADDR 0x30 - -#define EDID_BLOCK_LENGTH 0x80 -#define EDID_HEADER_PATTERN 0x00 -#define EDID_EXTENSION_FLAG 0x7e -#define EDID_CHECKSUM 0x7f - - -/* Definition for DPCD Register */ -#define DPCD_ADDR_DPCD_REV 0x0000 -#define DPCD_ADDR_MAX_LINK_RATE 0x0001 -#define DPCD_ADDR_MAX_LANE_COUNT 0x0002 -#define DPCD_ADDR_LINK_BW_SET 0x0100 -#define DPCD_ADDR_LANE_COUNT_SET 0x0101 -#define DPCD_ADDR_TRAINING_PATTERN_SET 0x0102 -#define DPCD_ADDR_TRAINING_LANE0_SET 0x0103 -#define DPCD_ADDR_LANE0_1_STATUS 0x0202 -#define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED 0x0204 -#define DPCD_ADDR_ADJUST_REQUEST_LANE0_1 0x0206 -#define DPCD_ADDR_ADJUST_REQUEST_LANE2_3 0x0207 -#define DPCD_ADDR_TEST_REQUEST 0x0218 -#define DPCD_ADDR_TEST_RESPONSE 0x0260 -#define DPCD_ADDR_TEST_EDID_CHECKSUM 0x0261 -#define DPCD_ADDR_SINK_POWER_STATE 0x0600 - -/* DPCD_ADDR_MAX_LANE_COUNT */ -#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) -#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) - -/* DPCD_ADDR_LANE_COUNT_SET */ -#define DPCD_ENHANCED_FRAME_EN (0x1 << 7) -#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f) - -/* DPCD_ADDR_TRAINING_PATTERN_SET */ -#define DPCD_SCRAMBLING_DISABLED (0x1 << 5) -#define DPCD_SCRAMBLING_ENABLED (0x0 << 5) -#define DPCD_TRAINING_PATTERN_2 (0x2 << 0) -#define DPCD_TRAINING_PATTERN_1 (0x1 << 0) -#define DPCD_TRAINING_PATTERN_DISABLED (0x0 << 0) - -/* DPCD_ADDR_TRAINING_LANE0_SET */ -#define DPCD_MAX_PRE_EMPHASIS_REACHED (0x1 << 5) -#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3) -#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3) -#define DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 (0x0 << 3) -#define DPCD_MAX_SWING_REACHED (0x1 << 2) -#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0) -#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3) -#define DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0 (0x0 << 0) - -/* DPCD_ADDR_LANE0_1_STATUS */ -#define DPCD_LANE_SYMBOL_LOCKED (0x1 << 2) -#define DPCD_LANE_CHANNEL_EQ_DONE (0x1 << 1) -#define DPCD_LANE_CR_DONE (0x1 << 0) -#define DPCD_CHANNEL_EQ_BITS (DPCD_LANE_CR_DONE| \ - DPCD_LANE_CHANNEL_EQ_DONE|\ - DPCD_LANE_SYMBOL_LOCKED) - -/* DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED */ -#define DPCD_LINK_STATUS_UPDATED (0x1 << 7) -#define DPCD_DOWNSTREAM_PORT_STATUS_CHANGED (0x1 << 6) -#define DPCD_INTERLANE_ALIGN_DONE (0x1 << 0) - -/* DPCD_ADDR_TEST_REQUEST */ -#define DPCD_TEST_EDID_READ (0x1 << 2) - -/* DPCD_ADDR_TEST_RESPONSE */ -#define DPCD_TEST_EDID_CHECKSUM_WRITE (0x1 << 2) - -/* DPCD_ADDR_SINK_POWER_STATE */ -#define DPCD_SET_POWER_STATE_D0 (0x1 << 0) -#define DPCD_SET_POWER_STATE_D4 (0x2 << 0) + + + #define DP_TIMEOUT_LOOP_CNT 100 #define MAX_CR_LOOP 5 @@ -549,10 +486,12 @@ struct link_train { struct rk32_edp { struct device *dev; void __iomem *regs; + unsigned int irq; struct clk *clk_edp; struct clk *clk_24m; struct link_train link_train; struct video_info video_info; + struct rk_screen screen; int enabled; }; @@ -644,6 +583,8 @@ void rk32_edp_config_video_slave_mode(struct rk32_edp *edp, void rk32_edp_enable_scrambling(struct rk32_edp *edp); void rk32_edp_disable_scrambling(struct rk32_edp *edp); void rk32_edp_rx_control(struct rk32_edp *edp, bool enable); - - +int rk32_edp_bist_cfg(struct rk32_edp *edp); +void rk32_edp_hw_link_training_en(struct rk32_edp * edp); +int rk32_edp_get_hw_lt_status(struct rk32_edp *edp); +int rk32_edp_wait_hw_lt_done(struct rk32_edp *edp); #endif diff --git a/drivers/video/rockchip/transmitter/rk32_dp_reg.c b/drivers/video/rockchip/transmitter/rk32_dp_reg.c index 30e620946d68..ae9c218b12b8 100644 --- a/drivers/video/rockchip/transmitter/rk32_dp_reg.c +++ b/drivers/video/rockchip/transmitter/rk32_dp_reg.c @@ -70,7 +70,7 @@ void rk32_edp_init_analog_param(struct rk32_edp *edp) #ifndef CONFIG_RK_FPGA val = (REF_CLK_FROM_INTER << 16) | REF_CLK_FROM_INTER; - writel_relaxed(val,RK_GRF_VIRT + GRF_SOC_CON12); + writel_relaxed(val,RK_GRF_VIRT + RK3288_GRF_SOC_CON12); #endif val = SEL_24M; @@ -764,6 +764,36 @@ void rk32_edp_get_link_bandwidth(struct rk32_edp *edp, u32 *bwtype) *bwtype = val; } +void rk32_edp_hw_link_training_en(struct rk32_edp * edp) +{ + u32 val; + val = HW_LT_EN; + writel(val, edp->regs + HW_LT_CTL); +} + +int rk32_edp_wait_hw_lt_done(struct rk32_edp *edp) +{ + u32 val; +#if 0 + val = readl(edp->regs + HW_LT_CTL); + return val&0x01; +#else + val = readl(edp->regs + DP_INT_STA); + if (val&HW_LT_DONE) { + writel(val,edp->regs + DP_INT_STA); + return 0; + } + else + return 1; +#endif +} + +int rk32_edp_get_hw_lt_status(struct rk32_edp * edp) +{ + u32 val; + val = readl(edp->regs + HW_LT_CTL); + return (val & HW_LT_ERR_CODE_MASK) >> 4; +} void rk32_edp_set_lane_count(struct rk32_edp *edp, u32 count) { u32 val; @@ -1017,6 +1047,7 @@ int rk32_edp_is_slave_video_stream_clock_on(struct rk32_edp *edp) return 0; } + void rk32_edp_set_video_cr_mn(struct rk32_edp *edp, enum clock_recovery_m_value_type type, u32 m_value, @@ -1067,6 +1098,70 @@ void rk32_edp_set_video_timing_mode(struct rk32_edp *edp, u32 type) } } +int rk32_edp_bist_cfg(struct rk32_edp *edp) +{ + struct video_info *video_info = &edp->video_info; + struct rk_screen *screen = &edp->screen; + u16 x_total ,y_total, x_act; + u32 val; + x_total = screen->mode.left_margin + screen->mode.right_margin + + screen->mode.xres + screen->mode.hsync_len; + y_total = screen->mode.upper_margin + screen->mode.lower_margin + + screen->mode.yres + screen->mode.vsync_len; + x_act = screen->mode.xres; + rk32_edp_set_video_cr_mn(edp, CALCULATED_M, 0, 0); + rk32_edp_set_video_color_format(edp, video_info->color_depth, + video_info->color_space, + video_info->dynamic_range, + video_info->ycbcr_coeff); + val = y_total & 0xff; + writel(val, edp->regs + TOTAL_LINE_CFG_L); + val = (y_total >> 8); + writel(val, edp->regs + TOTAL_LINE_CFG_H); + val = (screen->mode.yres & 0xff); + writel(val, edp->regs + ATV_LINE_CFG_L); + val = (screen->mode.yres >> 8); + writel(val, edp->regs + ATV_LINE_CFG_H); + val = screen->mode.lower_margin; + writel(val, edp->regs + VF_PORCH_REG); + val = screen->mode.vsync_len; + writel(val, edp->regs + VSYNC_CFG_REG); + val = screen->mode.upper_margin; + writel(val, edp->regs + VB_PORCH_REG); + val = x_total & 0xff; + writel(val, edp->regs + TOTAL_PIXELL_REG); + val = x_total >> 8; + writel(val, edp->regs + TOTAL_PIXELH_REG); + val = (x_act & 0xff); + writel(val, edp->regs + ATV_PIXELL_REG); + val = (x_act >> 8); + writel(val, edp->regs + ATV_PIXELH_REG); + val = screen->mode.right_margin & 0xff; + writel(val, edp->regs + HF_PORCHL_REG); + val = screen->mode.right_margin >> 8; + writel(val, edp->regs + HF_PORCHH_REG); + val = screen->mode.hsync_len & 0xff; + writel(val, edp->regs + HSYNC_CFGL_REG); + val = screen->mode.hsync_len >> 8; + writel(val, edp->regs + HSYNC_CFGH_REG); + val = screen->mode.left_margin & 0xff; + writel(val, edp->regs + HB_PORCHL_REG); + val = screen->mode.left_margin >> 8; + writel(val, edp->regs + HB_PORCHH_REG); + + val = BIST_EN; + writel(val, edp->regs + VIDEO_CTL_4); + + val = readl(edp->regs + VIDEO_CTL_10); + val &= ~F_SEL; + writel(val, edp->regs + VIDEO_CTL_10); + + rk32_edp_start_video(edp); + + return 0; + +} + void rk32_edp_enable_video_master(struct rk32_edp *edp, bool enable) { /*u32 val; @@ -1115,7 +1210,7 @@ void rk32_edp_config_video_slave_mode(struct rk32_edp *edp, u32 val; val = readl(edp->regs + FUNC_EN_1); - val &= ~(VID_FIFO_FUNC_EN_N); + val &= ~(VID_FIFO_FUNC_EN_N | VID_CAP_FUNC_EN_N); writel(val, edp->regs + FUNC_EN_1); val = readl(edp->regs + VIDEO_CTL_10);