From: hjc Date: Fri, 12 Dec 2014 07:01:28 +0000 (+0800) Subject: rk3368 lcdc: support win mirror and update NO_DUAL mode X-Git-Tag: firefly_0821_release~4158^2~533 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=cd1569d3fbc317c58a9352591a163cf8830d1523;p=firefly-linux-kernel-4.4.55.git rk3368 lcdc: support win mirror and update NO_DUAL mode Signed-off-by: hjc --- diff --git a/drivers/video/rockchip/lcdc/rk3368_lcdc.c b/drivers/video/rockchip/lcdc/rk3368_lcdc.c index 2340d65b5f22..f07ce79d6f43 100644 --- a/drivers/video/rockchip/lcdc/rk3368_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk3368_lcdc.c @@ -40,7 +40,7 @@ #if defined(CONFIG_HAS_EARLYSUSPEND) #include #endif -#define CONFIG_RK_FPGA 1 +/*#define CONFIG_RK_FPGA 1*/ static int dbg_thresd; module_param(dbg_thresd, int, S_IRUGO | S_IWUSR); @@ -331,7 +331,7 @@ static void lcdc_read_reg_defalut_cfg(struct lcdc_device *lcdc_dev) spin_lock(&lcdc_dev->reg_lock); for (reg = 0; reg < FRC_LOWER11_1; reg += 4) { - val = lcdc_readl(lcdc_dev, reg); + val = lcdc_readl_backup(lcdc_dev, reg); switch (reg) { case WIN0_ACT_INFO: win0->area[0].xact = (val & m_WIN0_ACT_WIDTH) + 1; @@ -396,7 +396,6 @@ static int rk3368_lcdc_pre_init(struct rk_lcdc_driver *dev_drv) lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc"); lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc"); lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc"); - lcdc_dev->pll_sclk = devm_clk_get(lcdc_dev->dev, "sclk_pll"); lcdc_dev->pd = devm_clk_get(lcdc_dev->dev, "pd_lcdc"); if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) || @@ -1396,7 +1395,6 @@ static int __maybe_unused rk3368_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv) if (!lcdc_dev->iommu_status && dev_drv->mmu_dev) { lcdc_dev->iommu_status = 1; rockchip_iovmm_activate(dev_drv->dev); - rk312x_lcdc_mmu_en(dev_drv); } } #endif @@ -1412,11 +1410,6 @@ static int rk3368_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv) #ifdef CONFIG_RK_FPGA return 0; #endif - /*set pll */ - ret = clk_set_rate(lcdc_dev->pll_sclk, screen->mode.pixclock); - if (ret) - dev_err(dev_drv->dev, "set lcdc%d pll_sclk failed\n", - lcdc_dev->id); ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);/*set pll */ if (ret) @@ -1606,7 +1599,8 @@ static void rk3368_lcdc_bcsh_path_sel(struct rk_lcdc_driver *dev_drv) /* bypass --need check,if bcsh close? */ if (dev_drv->output_color == COLOR_RGB) { bcsh_ctrl = lcdc_readl(lcdc_dev, BCSH_CTRL); - if ((bcsh_ctrl & m_BCSH_EN) == 1)/*bcsh enabled */ + if (((bcsh_ctrl & m_BCSH_EN) == 1) || + (dev_drv->bcsh.enable == 1))/*bcsh enabled */ lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_R2Y_EN | m_BCSH_Y2R_EN, @@ -1888,15 +1882,13 @@ static int rk3368_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id, { struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); -#ifndef CONFIG_RK_FPGA +#if 0/*ndef CONFIG_RK_FPGA*/ int sys_status = (dev_drv->id == 0) ? SYS_STATUS_LCDC0 : SYS_STATUS_LCDC1; #endif /*enable clk,when first layer open */ if ((open) && (!lcdc_dev->atv_layer_cnt)) { -#ifndef CONFIG_RK_FPGA - rockchip_set_system_status(sys_status); -#endif + /*rockchip_set_system_status(sys_status);*/ rk3368_lcdc_pre_init(dev_drv); rk3368_lcdc_clk_enable(lcdc_dev); #if defined(CONFIG_ROCKCHIP_IOMMU) @@ -2516,6 +2508,44 @@ static int rk3368_lcdc_cal_scl_fac(struct rk_lcdc_win *win) return 0; } +static int dsp_x_pos(int mirror_en, struct rk_screen *screen, + struct rk_lcdc_win_area *area) +{ + int pos; + + if (screen->x_mirror && mirror_en) + pr_err("not support both win and global mirror\n"); + + if ((!mirror_en) && (!screen->x_mirror)) + pos = area->xpos + screen->mode.left_margin + + screen->mode.hsync_len; + else + pos = screen->mode.xres - area->xpos - + area->xsize + screen->mode.left_margin + + screen->mode.hsync_len; + + return pos; +} + +static int dsp_y_pos(int mirror_en, struct rk_screen *screen, + struct rk_lcdc_win_area *area) +{ + int pos; + + if (screen->y_mirror && mirror_en) + pr_err("not support both win and global mirror\n"); + + if ((!mirror_en) && (!screen->y_mirror)) + pos = area->ypos + screen->mode.upper_margin + + screen->mode.vsync_len; + else + pos = screen->mode.yres - area->ypos - + area->ysize + screen->mode.upper_margin + + screen->mode.vsync_len; + + return pos; +} + static int win_0_1_set_par(struct lcdc_device *lcdc_dev, struct rk_screen *screen, struct rk_lcdc_win *win) { @@ -2523,19 +2553,9 @@ static int win_0_1_set_par(struct lcdc_device *lcdc_dev, u8 fmt_cfg = 0, swap_rb; char fmt[9] = "NULL"; - if (!win->mirror_en) { - xpos = win->area[0].xpos + screen->mode.left_margin + - screen->mode.hsync_len; - ypos = win->area[0].ypos + screen->mode.upper_margin + - screen->mode.vsync_len; - } else { - xpos = screen->mode.xres - win->area[0].xpos - - win->area[0].xsize + - screen->mode.left_margin + screen->mode.hsync_len; - ypos = screen->mode.yres - win->area[0].ypos - - win->area[0].ysize + screen->mode.upper_margin + - screen->mode.vsync_len; - } + xpos = dsp_x_pos(win->mirror_en, screen, &win->area[0]); + ypos = dsp_y_pos(win->mirror_en, screen, &win->area[0]); + spin_lock(&lcdc_dev->reg_lock); if (likely(lcdc_dev->clk_on)) { rk3368_lcdc_cal_scl_fac(win); /*fac,lb,gt2,gt4 */ @@ -2627,6 +2647,8 @@ static int win_2_3_set_par(struct lcdc_device *lcdc_dev, u8 fmt_cfg, swap_rb; char fmt[9] = "NULL"; + if (win->mirror_en) + pr_err("win[%d] not support y mirror\n", win->id); spin_lock(&lcdc_dev->reg_lock); if (likely(lcdc_dev->clk_on)) { DBG(2, "lcdc[%d]:win[%d]>>\n>\n", lcdc_dev->id, win->id); @@ -2656,19 +2678,12 @@ static int win_2_3_set_par(struct lcdc_device *lcdc_dev, } win->area[i].fmt_cfg = fmt_cfg; win->area[i].swap_rb = swap_rb; - win->area[i].dsp_stx = win->area[i].xpos + - screen->mode.left_margin + screen->mode.hsync_len; - if (screen->y_mirror == 1) { - win->area[i].dsp_sty = screen->mode.yres - - win->area[i].ypos - - win->area[i].ysize + - screen->mode.upper_margin + - screen->mode.vsync_len; - } else { - win->area[i].dsp_sty = win->area[i].ypos + - screen->mode.upper_margin + - screen->mode.vsync_len; - } + win->area[i].dsp_stx = + dsp_x_pos(win->mirror_en, screen, + &win->area[i]); + win->area[i].dsp_sty = + dsp_y_pos(win->mirror_en, screen, + &win->area[i]); DBG(2, "fmt:%s:xsize:%d>>ysize:%d>>xpos:%d>>ypos:%d\n", get_format_string(win->area[i].format, fmt), @@ -2844,7 +2859,7 @@ static int rk3368_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv) flush_kthread_worker(&dev_drv->update_regs_worker); for (reg = MMU_DTE_ADDR; reg <= MMU_AUTO_GATING; reg += 4) - lcdc_readl(lcdc_dev, reg); + lcdc_readl_backup(lcdc_dev, reg); if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable) dev_drv->trsm_ops->disable(); @@ -3504,13 +3519,7 @@ static int rk3368_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps, screen->mode.xres + screen->mode.hsync_len; dev_drv->pixclock = div_u64(ft, x_total * y_total); dotclk = div_u64(1000000000000llu, dev_drv->pixclock); - ret = clk_set_rate(lcdc_dev->pll_sclk, dotclk); /*set pll */ - if (ret) - dev_err(dev_drv->dev, - "set lcdc%d pll_sclk failed\n", lcdc_dev->id); - ret = clk_set_rate(lcdc_dev->dclk, dotclk); - /*SET NEW PLL FOR RK3368 */ } pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk)); @@ -3993,16 +4002,18 @@ static int rk3368_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open) spin_lock(&lcdc_dev->reg_lock); if (lcdc_dev->clk_on) { - rk3368_lcdc_bcsh_path_sel(dev_drv); if (open) { lcdc_writel(lcdc_dev, BCSH_COLOR_BAR, 0x1); lcdc_writel(lcdc_dev, BCSH_BCS, 0xd0010000); lcdc_writel(lcdc_dev, BCSH_H, 0x01000000); + dev_drv->bcsh.enable = 1; } else { mask = m_BCSH_EN; val = v_BCSH_EN(0); lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val); + dev_drv->bcsh.enable = 0; } + rk3368_lcdc_bcsh_path_sel(dev_drv); lcdc_cfg_done(lcdc_dev); } spin_unlock(&lcdc_dev->reg_lock); @@ -4044,15 +4055,7 @@ static int rk3368_lcdc_dsp_black(struct rk_lcdc_driver *dev_drv, int enable) struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); - rk3368_lcdc_get_backlight_device(dev_drv); - if (enable) { - /* close the backlight */ - if (lcdc_dev->backlight) { - lcdc_dev->backlight->props.power = FB_BLANK_POWERDOWN; - backlight_update_status(lcdc_dev->backlight); - } -#if 1 spin_lock(&lcdc_dev->reg_lock); if (likely(lcdc_dev->clk_on)) { lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLACK_EN, @@ -4060,11 +4063,7 @@ static int rk3368_lcdc_dsp_black(struct rk_lcdc_driver *dev_drv, int enable) lcdc_cfg_done(lcdc_dev); } spin_unlock(&lcdc_dev->reg_lock); -#endif - if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable) - dev_drv->trsm_ops->disable(); } else { -#if 1 spin_lock(&lcdc_dev->reg_lock); if (likely(lcdc_dev->clk_on)) { lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLACK_EN, @@ -4073,7 +4072,29 @@ static int rk3368_lcdc_dsp_black(struct rk_lcdc_driver *dev_drv, int enable) lcdc_cfg_done(lcdc_dev); } spin_unlock(&lcdc_dev->reg_lock); -#endif + } + + return 0; +} + + +static int rk3368_lcdc_backlight_close(struct rk_lcdc_driver *dev_drv, + int enable) +{ + struct lcdc_device *lcdc_dev = + container_of(dev_drv, struct lcdc_device, driver); + + rk3368_lcdc_get_backlight_device(dev_drv); + + if (enable) { + /* close the backlight */ + if (lcdc_dev->backlight) { + lcdc_dev->backlight->props.power = FB_BLANK_POWERDOWN; + backlight_update_status(lcdc_dev->backlight); + } + if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable) + dev_drv->trsm_ops->disable(); + } else { if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable) dev_drv->trsm_ops->enable(); msleep(100); @@ -4121,6 +4142,7 @@ static struct rk_lcdc_drv_ops lcdc_drv_ops = { .cfg_done = rk3368_lcdc_config_done, .set_irq_to_cpu = rk3368_lcdc_set_irq_to_cpu, .dsp_black = rk3368_lcdc_dsp_black, + .backlight_close = rk3368_lcdc_backlight_close, .mmu_en = rk3368_lcdc_mmu_en, }; diff --git a/drivers/video/rockchip/lcdc/rk3368_lcdc.h b/drivers/video/rockchip/lcdc/rk3368_lcdc.h index 7008cf6c6113..8acccacf19d9 100644 --- a/drivers/video/rockchip/lcdc/rk3368_lcdc.h +++ b/drivers/video/rockchip/lcdc/rk3368_lcdc.h @@ -1794,6 +1794,14 @@ static inline void lcdc_writel(struct lcdc_device *lcdc_dev, u32 offset, u32 v) } static inline u32 lcdc_readl(struct lcdc_device *lcdc_dev, u32 offset) +{ + u32 v; + + v = readl_relaxed(lcdc_dev->regs + offset); + return v; +} + +static inline u32 lcdc_readl_backup(struct lcdc_device *lcdc_dev, u32 offset) { u32 v; u32 *_pv = (u32 *)lcdc_dev->regsbak; diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c old mode 100755 new mode 100644 index be3e5cf80c4b..83a078244a1f --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -3574,6 +3574,12 @@ int rk_fb_switch_screen(struct rk_screen *screen, int enable, int lcdc_id) dev_drv->ops->dsp_black(dev_drv, 1); if (dev_drv->ops->set_screen_scaler) dev_drv->ops->set_screen_scaler(dev_drv, dev_drv->screen0, 0); + } else if (rk_fb->disp_mode == NO_DUAL) { + if ((dev_drv->ops->backlight_close) && + (rk_fb->disp_policy != DISPLAY_POLICY_BOX)) + dev_drv->ops->backlight_close(dev_drv, 1); + if (dev_drv->ops->dsp_black) + dev_drv->ops->dsp_black(dev_drv, 1); } if (!enable) { @@ -3599,6 +3605,9 @@ int rk_fb_switch_screen(struct rk_screen *screen, int enable, int lcdc_id) if (dev_drv->ops->dsp_black) dev_drv->ops->dsp_black(dev_drv, 0); + if ((dev_drv->ops->backlight_close) && + (rk_fb->disp_policy != DISPLAY_POLICY_BOX)) + dev_drv->ops->backlight_close(dev_drv, 0); } else if (rk_fb->num_lcdc > 1) { /* If there is more than one lcdc device, we disable the layer which attached to this device */ @@ -3662,11 +3671,14 @@ int rk_fb_switch_screen(struct rk_screen *screen, int enable, int lcdc_id) dev_drv->uboot_logo = 0; } hdmi_switch_complete = 1; - if (rk_fb->disp_mode == ONE_DUAL) { + if ((rk_fb->disp_mode == ONE_DUAL) || (rk_fb->disp_mode == NO_DUAL)) { if (dev_drv->ops->set_screen_scaler) dev_drv->ops->set_screen_scaler(dev_drv, dev_drv->screen0, 1); if (dev_drv->ops->dsp_black) dev_drv->ops->dsp_black(dev_drv, 0); + if ((dev_drv->ops->backlight_close) && + (rk_fb->disp_policy != DISPLAY_POLICY_BOX)) + dev_drv->ops->backlight_close(dev_drv, 0); } return 0; } diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h old mode 100755 new mode 100644 index e6331e8b234e..c4da932d07d8 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -458,6 +458,7 @@ struct rk_lcdc_drv_ops { int (*set_overscan) (struct rk_lcdc_driver *dev_drv, struct overscan *overscan); int (*dsp_black) (struct rk_lcdc_driver *dev_drv, int enable); + int (*backlight_close)(struct rk_lcdc_driver *dev_drv, int enable); }; struct rk_fb_area_par {