rk32 edp: reset edp after switch to 24M clk

This commit is contained in:
yxj
2014-03-25 22:05:19 +08:00
parent 0c0f397f30
commit 87893bfdca
3 changed files with 77 additions and 76 deletions

View File

@@ -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;
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);

View File

@@ -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

View File

@@ -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;
}