rk3368 lcdc: reset lcdc when switch screen video mode

Signed-off-by: hjc <hjc@rock-chips.com>
This commit is contained in:
hjc
2015-04-09 11:27:15 +08:00
parent 71fb032a4f
commit 336b5c3ebb
3 changed files with 89 additions and 7 deletions

View File

@@ -817,6 +817,7 @@
compatible = "rockchip,rk3368-lcdc";
rockchip,grf = <&grf>;
rockchip,pmugrf = <&pmugrf>;
rockchip,cru = <&cru>;
rockchip,prop = <PRMRY>;
rockchip,pwr18 = <0>;
rockchip,iommu-enabled = <0>;

View File

@@ -1720,6 +1720,60 @@ static int rk3368_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst,
return 0;
}
static int lcdc_reset(struct rk_lcdc_driver *dev_drv, bool initscreen)
{
struct lcdc_device *lcdc_dev =
container_of(dev_drv, struct lcdc_device, driver);
u32 mask, val;
u32 v;
/*printk("0407:standby=%d,initscreen=%d,dev_drv->first_frame=%d\n",
lcdc_dev->standby,initscreen,dev_drv->first_frame);*/
if (!lcdc_dev->standby && initscreen && (dev_drv->first_frame != 1)) {
mdelay(150);
mask = m_WIN0_EN;
val = v_WIN0_EN(0);
lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val);
lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask, val);
mask = m_WIN2_EN | m_WIN2_MST0_EN |
m_WIN2_MST1_EN |
m_WIN2_MST2_EN | m_WIN2_MST3_EN;
val = v_WIN2_EN(0) | v_WIN2_MST0_EN(0) |
v_WIN2_MST1_EN(0) |
v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask, val);
lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask, val);
mask = m_HDMI_OUT_EN;
val = v_HDMI_OUT_EN(0);
lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
lcdc_cfg_done(lcdc_dev);
mdelay(50);
writel_relaxed(0, lcdc_dev->regs + REG_CFG_DONE);
if (dev_drv->iommu_enabled) {
if (dev_drv->mmu_dev)
rockchip_iovmm_deactivate(dev_drv->dev);
}
lcdc_cru_writel(lcdc_dev->cru_base, 0x0318,
(1 << 4) | (1 << 5) | (1 << 6) |
(1 << 20) | (1 << 21) | (1 << 22));
udelay(100);
v = lcdc_cru_readl(lcdc_dev->cru_base, 0x0318);
pr_info("cru read = 0x%x\n", v);
lcdc_cru_writel(lcdc_dev->cru_base, 0x0318,
(0 << 4) | (0 << 5) | (0 << 6) |
(1 << 20) | (1 << 21) | (1 << 22));
mdelay(100);
if (dev_drv->iommu_enabled) {
if (dev_drv->mmu_dev)
rockchip_iovmm_activate(dev_drv->dev);
}
mdelay(50);
rk3368_lcdc_reg_restore(lcdc_dev);
mdelay(50);
}
return 0;
}
static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
{
@@ -1734,12 +1788,16 @@ static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
spin_lock(&lcdc_dev->reg_lock);
if (likely(lcdc_dev->clk_on)) {
dev_drv->overlay_mode = VOP_RGB_DOMAIN;
#if 0
if (!lcdc_dev->standby && !initscreen) {
lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
v_STANDBY_EN(1));
lcdc_cfg_done(lcdc_dev);
mdelay(50);
}
#else
lcdc_reset(dev_drv, initscreen);
#endif
switch (screen->face) {
case OUT_P565:
face = OUT_P565;
@@ -1917,7 +1975,9 @@ static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
}
spin_unlock(&lcdc_dev->reg_lock);
rk3368_lcdc_set_dclk(dev_drv, 1);
if (screen->type != SCREEN_HDMI && dev_drv->trsm_ops &&
if (screen->type != SCREEN_HDMI &&
screen->type != SCREEN_TVOUT &&
dev_drv->trsm_ops &&
dev_drv->trsm_ops->enable)
dev_drv->trsm_ops->enable();
if (screen->init)
@@ -2072,7 +2132,7 @@ static int rk3368_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
rockchip_clear_system_status(sys_status);
#endif
} */
dev_drv->first_frame = 0;
return 0;
}
@@ -2184,11 +2244,6 @@ static int rk3368_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
return -EINVAL;
}
/*this is the first frame of the system ,enable frame start interrupt */
if ((dev_drv->first_frame)) {
dev_drv->first_frame = 0;
rk3368_lcdc_enable_irq(dev_drv);
}
#if defined(WAIT_FOR_SYNC)
spin_lock_irqsave(&dev_drv->cpl_lock, flags);
init_completion(&dev_drv->frame_done);
@@ -4624,6 +4679,13 @@ static int rk3368_lcdc_probe(struct platform_device *pdev)
return PTR_ERR(lcdc_dev->pmugrf_base);
}
lcdc_dev->cru_base =
syscon_regmap_lookup_by_phandle(np, "rockchip,cru");
if (IS_ERR(lcdc_dev->cru_base)) {
dev_err(&pdev->dev, "can't find lcdc cru_base property\n");
return PTR_ERR(lcdc_dev->cru_base);
}
lcdc_dev->id = 0;
dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
dev_drv = &lcdc_dev->driver;

View File

@@ -1744,6 +1744,7 @@ struct lcdc_device {
u32 reg_phy_base; /* physical basic address of lcdc register*/
struct regmap *grf_base;
struct regmap *pmugrf_base;
struct regmap *cru_base;
u32 len; /* physical map length of lcdc register*/
/*one time only one process allowed to config the register*/
spinlock_t reg_lock;
@@ -1879,6 +1880,24 @@ static inline int lcdc_grf_writel(struct regmap *base,
return 0;
}
static inline int lcdc_cru_writel(struct regmap *base,
u32 offset, u32 val)
{
regmap_write(base, offset, val);
dsb(sy);
return 0;
}
static inline int lcdc_cru_readl(struct regmap *base,
u32 offset)
{
u32 v;
regmap_read(base, offset, &v);
return v;
}
#define CUBIC_PRECISE 0
#define CUBIC_SPLINE 1
#define CUBIC_CATROM 2