From 87893bfdca82c362e767de64f266234d5e071244 Mon Sep 17 00:00:00 2001 From: yxj Date: Tue, 25 Mar 2014 22:05:19 +0800 Subject: [PATCH] rk32 edp: reset edp after switch to 24M clk --- drivers/video/rockchip/transmitter/rk32_dp.c | 102 +++++++----------- drivers/video/rockchip/transmitter/rk32_dp.h | 11 +- .../video/rockchip/transmitter/rk32_dp_reg.c | 36 +++++-- 3 files changed, 75 insertions(+), 74 deletions(-) diff --git a/drivers/video/rockchip/transmitter/rk32_dp.c b/drivers/video/rockchip/transmitter/rk32_dp.c index e7e4f6b1d87b..bd1a8f5bd0ae 100644 --- a/drivers/video/rockchip/transmitter/rk32_dp.c +++ b/drivers/video/rockchip/transmitter/rk32_dp.c @@ -38,7 +38,7 @@ static int rk32_edp_init_edp(struct rk32_edp *edp) { struct rk_screen *screen = &edp->screen; u32 val = 0; - + int i= 0; screen->lcdc_id = 1; if (screen->lcdc_id == 1) /*select lcdc*/ val = EDP_SEL_VOP_LIT | (EDP_SEL_VOP_LIT << 16); @@ -52,7 +52,13 @@ static int rk32_edp_init_edp(struct rk32_edp *edp) val = 0x80008000; writel_relaxed(val, RK_CRU_VIRT + 0x0d0); - + + val = 0x80008000; + writel_relaxed(val, RK_CRU_VIRT + 0x01d0); + mdelay(12); + val = 0x80000000; + writel_relaxed(val, RK_CRU_VIRT + 0x01d0); + mdelay(12); rk32_edp_reset(edp); rk32_edp_init_refclk(edp); rk32_edp_init_interrupt(edp); @@ -825,9 +831,7 @@ static int rk32_edp_get_max_rx_lane_count(struct rk32_edp *edp, return 0; } -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; @@ -839,12 +843,7 @@ static int rk32_edp_init_training(struct rk32_edp *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; 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, @@ -852,25 +851,24 @@ static int rk32_edp_init_training(struct rk32_edp *edp, 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; } @@ -920,7 +918,7 @@ static int rk32_edp_hw_link_training(struct rk32_edp *edp) 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); + mdelay(10); val = rk32_edp_wait_hw_lt_done(edp); while (val) { if (cnt-- <= 0) { @@ -937,13 +935,11 @@ static int rk32_edp_hw_link_training(struct rk32_edp *edp) return val; } -static int rk32_edp_set_link_train(struct rk32_edp *edp, - u32 count, - u32 bwtype) +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 0 @@ -1067,29 +1063,26 @@ static int rk32_edp_enable_scramble(struct rk32_edp *edp, bool enable) static irqreturn_t rk32_edp_isr(int irq, void *arg) { struct rk32_edp *edp = arg; + enum dp_irq_type irq_type; - //dev_info(edp->dev, "rk32_edp_isr\n"); + irq_type = rk32_edp_get_irq_type(edp); + return IRQ_HANDLED; } static int rk32_edp_enable(void) { int ret = 0; - int retry = 0; + int i; struct rk32_edp *edp = rk32_edp; - if (edp->enabled) - goto out; - - edp->enabled = 1; + clk_enable(edp->pclk); clk_enable(edp->clk_edp); clk_enable(edp->clk_24m); -edp_phy_init: - rk32_edp_init_edp(edp); - ret = rk32_edp_handle_edid(edp); + /*ret = rk32_edp_handle_edid(edp); if (ret) { dev_err(edp->dev, "unable to handle edid\n"); //goto out; @@ -1107,50 +1100,35 @@ edp_phy_init: dev_err(edp->dev, "unable to set enhanced mode\n"); //goto out; } - rk32_edp_enable_enhanced_mode(edp, 0); + rk32_edp_enable_enhanced_mode(edp, 1);*/ - /* Link Training */ - ret = rk32_edp_set_link_train(edp, LANE_CNT4, LINK_RATE_1_62GBPS); - if (ret) { - dev_err(edp->dev, "link train failed\n"); - //goto out; - } + 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->video_info.lane_count); - rk32_edp_set_link_bandwidth(edp, edp->video_info.link_rate); + rk32_edp_set_lane_count(edp, edp->link_train.lane_count); + rk32_edp_set_link_bandwidth(edp, edp->link_train.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) { + if (ret) dev_err(edp->dev, "unable to config video\n"); - //goto out; - } #endif - 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 int rk32_edp_disable(void ) { struct rk32_edp *edp = rk32_edp; - if (!edp->enabled) - return 0; - - edp->enabled = 0; - rk32_edp_reset(edp); rk32_edp_analog_power_ctr(edp, 0); diff --git a/drivers/video/rockchip/transmitter/rk32_dp.h b/drivers/video/rockchip/transmitter/rk32_dp.h index 2bfae746bbdb..649d4d9e77bd 100644 --- a/drivers/video/rockchip/transmitter/rk32_dp.h +++ b/drivers/video/rockchip/transmitter/rk32_dp.h @@ -385,6 +385,14 @@ #define GRF_EDP_SECURE_EN (1 << 3) #define EDP_SEL_VOP_LIT (1 << 5) #define GRF_EDP_REF_CLK_SEL_INTER (1 << 4) + +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 @@ -514,7 +522,6 @@ struct rk32_edp { struct video_info video_info; struct rk_screen screen; struct fb_monspecs specs; - int enabled; }; @@ -609,4 +616,6 @@ 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); +enum dp_irq_type rk32_edp_get_irq_type(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 f8e3db775d7d..eb2a54145572 100644 --- a/drivers/video/rockchip/transmitter/rk32_dp_reg.c +++ b/drivers/video/rockchip/transmitter/rk32_dp_reg.c @@ -95,7 +95,7 @@ void rk32_edp_init_refclk(struct rk32_edp *edp) writel(val, edp->regs + SSC_REG); val = 0x87; writel(val, edp->regs + TX_REG_COMMON); - val = 0x13; + val = 0x03; writel(val, edp->regs + DP_AUX); val = 0x46; writel(val, edp->regs + DP_BIAS); @@ -175,12 +175,7 @@ void rk32_edp_reset(struct rk32_edp *edp) u32 val; //writel(RST_DP_TX, edp->regs + TX_SW_RST); - /*val = 0x80008000; - writel_relaxed(val, RK_CRU_VIRT + 0x01d0); - mdelay(12); - val = 0x80000000; - writel_relaxed(val, RK_CRU_VIRT + 0x01d0); - mdelay(12);*/ + rk32_edp_stop_video(edp); rk32_edp_enable_video_mute(edp, 0); @@ -270,7 +265,7 @@ void rk32_edp_analog_power_ctr(struct rk32_edp *edp, bool enable) void rk32_edp_init_analog_func(struct rk32_edp *edp) { u32 val; - + int wt = 0; rk32_edp_analog_power_ctr(edp, 1); val = PLL_LOCK_CHG; @@ -281,7 +276,6 @@ void rk32_edp_init_analog_func(struct rk32_edp *edp) writel(val, edp->regs + DEBUG_CTL); /* Power up PLL */ - int wt = 0; while (wt < 100) { if (rk32_edp_get_pll_lock_status(edp) == DP_PLL_UNLOCKED) dev_warn(edp->dev, "edp pll unlocked.....\n"); @@ -290,13 +284,13 @@ void rk32_edp_init_analog_func(struct rk32_edp *edp) break; } wt++; - msleep(50); + udelay(5); } /* Enable Serdes FIFO function and Link symbol clock domain module */ val = readl(edp->regs + FUNC_EN_2); val &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N - | AUX_FUNC_EN_N); + | AUX_FUNC_EN_N | SSC_FUNC_EN_N); writel(val, edp->regs + FUNC_EN_2); } @@ -1292,3 +1286,23 @@ void rk32_edp_disable_scrambling(struct rk32_edp *edp) val |= SCRAMBLING_DISABLE; writel(val, edp->regs + TRAINING_PTN_SET); } + +enum dp_irq_type rk32_edp_get_irq_type(struct rk32_edp *edp) +{ + u32 val; + + /* Parse hotplug interrupt status register */ + val = readl(edp->regs + COMMON_INT_STA_4); + + if (val & PLUG) + return DP_IRQ_TYPE_HP_CABLE_IN; + + if (val & HPD_LOST) + return DP_IRQ_TYPE_HP_CABLE_OUT; + + if (val & HOTPLUG_CHG) + return DP_IRQ_TYPE_HP_CHANGE; + + return DP_IRQ_TYPE_UNKNOWN; +} + -- 2.34.1