From 7ec167829a2f4b4f701e77e00e5b05ed6d1e89f1 Mon Sep 17 00:00:00 2001 From: Huang Jiachai Date: Fri, 18 Dec 2015 18:00:35 +0800 Subject: [PATCH] video: rockchip: lcdc: 3368: add support rk3366 Change-Id: I7e6137418b18c58c53f958089527635ac62eb887 Signed-off-by: Huang Jiachai --- drivers/video/rockchip/lcdc/rk3368_lcdc.c | 386 ++++++++++------------ drivers/video/rockchip/lcdc/rk3368_lcdc.h | 178 ++++++++-- 2 files changed, 320 insertions(+), 244 deletions(-) diff --git a/drivers/video/rockchip/lcdc/rk3368_lcdc.c b/drivers/video/rockchip/lcdc/rk3368_lcdc.c index 7463bec207b5..63f9a7afe726 100644 --- a/drivers/video/rockchip/lcdc/rk3368_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk3368_lcdc.c @@ -81,16 +81,6 @@ static struct rk_lcdc_win lcdc_win[] = { static int rk3368_lcdc_set_bcsh(struct rk_lcdc_driver *dev_drv, bool enable); -void __weak rk_pwm_set(int bl_pwm_period, int bl_pwm_duty) -{ - pr_info("If you want to use CABC, this func need implement at pwm\n"); -} - -void __weak rk_pwm_get(int *bl_pwm_period, int *bl_pwm_duty) -{ - pr_info("If you want to use CABC, this func need implement at pwm\n"); -} - /*#define WAIT_FOR_SYNC 1*/ u32 rk3368_get_hard_ware_vskiplines(u32 srch, u32 dsth) { @@ -198,6 +188,15 @@ static int __maybe_unused rk3368_lcdc_disable_irq(struct lcdc_device *lcdc_dev) { u32 mask, val; + u32 intr_en_reg, intr_clr_reg; + + if (lcdc_dev->soc_type == VOP_FULL_RK3366) { + intr_clr_reg = INTR_CLEAR_RK3366; + intr_en_reg = INTR_EN_RK3366; + } else { + intr_clr_reg = INTR_CLEAR_RK3368; + intr_en_reg = INTR_EN_RK3368; + } spin_lock(&lcdc_dev->reg_lock); if (likely(lcdc_dev->clk_on)) { @@ -216,7 +215,7 @@ static int __maybe_unused v_WIN3_EMPTY_INTR_EN(0) | v_HWC_EMPTY_INTR_EN(0) | v_POST_BUF_EMPTY_INTR_EN(0) | v_PWM_GEN_INTR_EN(0) | v_DSP_HOLD_VALID_INTR_EN(0); - lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val); + lcdc_msk_reg(lcdc_dev, intr_en_reg, mask, val); mask = m_FS_INTR_CLR | m_FS_NEW_INTR_CLR | m_ADDR_SAME_INTR_CLR | m_LINE_FLAG0_INTR_CLR | @@ -233,7 +232,7 @@ static int __maybe_unused v_WIN3_EMPTY_INTR_CLR(1) | v_HWC_EMPTY_INTR_CLR(1) | v_POST_BUF_EMPTY_INTR_CLR(1) | v_PWM_GEN_INTR_CLR(1) | v_DSP_HOLD_VALID_INTR_CLR(1); - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, mask, val); + lcdc_msk_reg(lcdc_dev, intr_clr_reg, mask, val); lcdc_cfg_done(lcdc_dev); spin_unlock(&lcdc_dev->reg_lock); } else { @@ -362,6 +361,9 @@ static void lcdc_read_reg_defalut_cfg(struct lcdc_device *lcdc_dev) for (reg = 0; reg < SCAN_LINE_NUM; reg += 4) { val = lcdc_readl_backup(lcdc_dev, reg); switch (reg) { + case VERSION_INFO: + lcdc_dev->soc_type = val; + break; case WIN0_ACT_INFO: win0->area[0].xact = (val & m_WIN0_ACT_WIDTH) + 1; win0->area[0].yact = @@ -432,7 +434,7 @@ static void lcdc_read_reg_defalut_cfg(struct lcdc_device *lcdc_dev) /********do basic init*********/ static int rk3368_lcdc_pre_init(struct rk_lcdc_driver *dev_drv) { - u32 mask, val, v; + u32 mask, val; struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); if (lcdc_dev->pre_init) @@ -460,28 +462,20 @@ static int rk3368_lcdc_pre_init(struct rk_lcdc_driver *dev_drv) /*backup reg config at uboot */ lcdc_read_reg_defalut_cfg(lcdc_dev); - if (lcdc_dev->pwr18 == 1) { - v = 0x00200020; /*bit5: 1,1.8v;0,3.3v*/ - lcdc_grf_writel(lcdc_dev->pmugrf_base, - PMUGRF_SOC_CON0_VOP, v); - } else { - v = 0x00200000; /*bit5: 1,1.8v;0,3.3v*/ + if (lcdc_dev->soc_type == VOP_FULL_RK3366) + lcdc_grf_writel(lcdc_dev->grf_base, RK3366_GRF_IO_VSEL, + RK3366_GRF_VOP_IOVOL_SEL(lcdc_dev->pwr18)); + else lcdc_grf_writel(lcdc_dev->pmugrf_base, - PMUGRF_SOC_CON0_VOP, v); - } - /*lcdc_writel(lcdc_dev, CABC_GAUSS_LINE0_0, 0x15110903); - lcdc_writel(lcdc_dev, CABC_GAUSS_LINE0_1, 0x00030911); - lcdc_writel(lcdc_dev, CABC_GAUSS_LINE1_0, 0x1a150b04); - lcdc_writel(lcdc_dev, CABC_GAUSS_LINE1_1, 0x00040b15); - lcdc_writel(lcdc_dev, CABC_GAUSS_LINE2_0, 0x15110903); - lcdc_writel(lcdc_dev, CABC_GAUSS_LINE2_1, 0x00030911);*/ - - lcdc_writel(lcdc_dev, CABC_GAUSS_LINE0_0, 0x40000000); - lcdc_writel(lcdc_dev, CABC_GAUSS_LINE0_1, 0x0); - lcdc_writel(lcdc_dev, CABC_GAUSS_LINE1_0, 0x80000000); - lcdc_writel(lcdc_dev, CABC_GAUSS_LINE1_1, 0x0); - lcdc_writel(lcdc_dev, CABC_GAUSS_LINE2_0, 0x40000000); - lcdc_writel(lcdc_dev, CABC_GAUSS_LINE2_1, 0x0); + PMUGRF_SOC_CON0_VOP, + RK3368_GRF_VOP_IOVOL_SEL(lcdc_dev->pwr18)); + + lcdc_writel(lcdc_dev,CABC_GAUSS_LINE0_0,0x15110903); + lcdc_writel(lcdc_dev,CABC_GAUSS_LINE0_1,0x00030911); + lcdc_writel(lcdc_dev,CABC_GAUSS_LINE1_0,0x1a150b04); + lcdc_writel(lcdc_dev,CABC_GAUSS_LINE1_1,0x00040b15); + lcdc_writel(lcdc_dev,CABC_GAUSS_LINE2_0,0x15110903); + lcdc_writel(lcdc_dev,CABC_GAUSS_LINE2_1,0x00030911); lcdc_writel(lcdc_dev, FRC_LOWER01_0, 0x12844821); lcdc_writel(lcdc_dev, FRC_LOWER01_1, 0x21488412); @@ -717,9 +711,6 @@ static int rk3368_lcdc_alpha_cfg(struct rk_lcdc_driver *dev_drv, int win_id) global_alpha = (win->g_alpha_val == 0) ? 0 : 1; alpha_config.src_global_alpha_val = win->g_alpha_val; win->alpha_mode = AB_SRC_OVER; - /*printk("%s,alpha_mode=%d,alpha_en=%d,ppixel_a=%d,gla_a=%d\n", - __func__,win->alpha_mode,win->alpha_en,ppixel_alpha, - global_alpha); */ switch (win->alpha_mode) { case AB_USER_DEFINE: break; @@ -1626,6 +1617,12 @@ static int rk3368_config_timing(struct rk_lcdc_driver *dev_drv) u16 h_total, v_total; u16 vact_end_f1, vact_st_f1, vs_end_f1, vs_st_f1; u32 frame_time; + u32 line_flag_reg; + + if (lcdc_dev->soc_type == VOP_FULL_RK3366) + line_flag_reg = LINE_FLAG_RK3366; + else + line_flag_reg = LINE_FLAG_RK3368; h_total = hsync_len + left_margin + x_res + right_margin; v_total = vsync_len + upper_margin + y_res + lower_margin; @@ -1706,7 +1703,7 @@ static int rk3368_config_timing(struct rk_lcdc_driver *dev_drv) v_DSP_LINE_FLAG0_NUM(vact_end_f1) | v_DSP_LINE_FLAG1_NUM(vact_end_f1 - EARLY_TIME * v_total / frame_time); - lcdc_msk_reg(lcdc_dev, LINE_FLAG, mask, val); + lcdc_msk_reg(lcdc_dev, line_flag_reg, mask, val); } else { mask = m_DSP_VS_PW | m_DSP_VTOTAL; val = v_DSP_VS_PW(vsync_len) | v_DSP_VTOTAL(v_total); @@ -1753,7 +1750,7 @@ static int rk3368_config_timing(struct rk_lcdc_driver *dev_drv) val = v_DSP_LINE_FLAG0_NUM(vsync_len + upper_margin + y_res) | v_DSP_LINE_FLAG1_NUM(vsync_len + upper_margin + y_res - EARLY_TIME * v_total / frame_time); - lcdc_msk_reg(lcdc_dev, LINE_FLAG, mask, val); + lcdc_msk_reg(lcdc_dev, line_flag_reg, mask, val); } rk3368_lcdc_post_cfg(dev_drv); return 0; @@ -1870,8 +1867,6 @@ static int lcdc_reset(struct rk_lcdc_driver *dev_drv, bool initscreen) container_of(dev_drv, struct lcdc_device, driver); u32 mask, val; u32 __maybe_unused 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; @@ -1926,7 +1921,6 @@ static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) { u16 face = 0; u16 dclk_ddr = 0; - u32 v = 0; struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); struct rk_screen *screen = dev_drv->cur_screen; @@ -2037,8 +2031,14 @@ static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) v_RGB_LVDS_VSYNC_POL(screen->pin_vsync) | v_RGB_LVDS_DEN_POL(screen->pin_den) | v_RGB_LVDS_DCLK_POL(screen->pin_dclk); - v = 1 << 15 | (1 << (15 + 16)); - + if (lcdc_dev->soc_type == VOP_FULL_RK3366) { + lcdc_grf_writel(lcdc_dev->grf_base, + RK3366_GRF_SOC_CON5, + RGB_SOURCE_SEL(dev_drv->id)); + lcdc_grf_writel(lcdc_dev->grf_base, + RK3366_GRF_SOC_CON0, + RGB_DATA_PLANA); + } break; case SCREEN_LVDS: mask = m_RGB_OUT_EN; @@ -2050,10 +2050,12 @@ static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) v_RGB_LVDS_VSYNC_POL(screen->pin_vsync) | v_RGB_LVDS_DEN_POL(screen->pin_den) | v_RGB_LVDS_DCLK_POL(screen->pin_dclk); - v = 0 << 15 | (1 << (15 + 16)); + if (lcdc_dev->soc_type == VOP_FULL_RK3366) + lcdc_grf_writel(lcdc_dev->grf_base, + RK3366_GRF_SOC_CON0, + LVDS_SOURCE_SEL(dev_drv->id)); break; case SCREEN_HDMI: - /*face = OUT_RGB_AAA;*/ if (screen->color_mode == COLOR_RGB) dev_drv->overlay_mode = VOP_RGB_DOMAIN; else @@ -2067,6 +2069,11 @@ static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) v_HDMI_VSYNC_POL(screen->pin_vsync) | v_HDMI_DEN_POL(screen->pin_den) | v_HDMI_DCLK_POL(screen->pin_dclk); + if (lcdc_dev->soc_type == VOP_FULL_RK3366) { + lcdc_grf_writel(lcdc_dev->grf_base, + RK3366_GRF_SOC_CON0, + HDMI_SOURCE_SEL(dev_drv->id)); + } break; case SCREEN_MIPI: mask = m_MIPI_OUT_EN | m_RGB_OUT_EN; @@ -2078,6 +2085,11 @@ static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) v_MIPI_VSYNC_POL(screen->pin_vsync) | v_MIPI_DEN_POL(screen->pin_den) | v_MIPI_DCLK_POL(screen->pin_dclk); + if (lcdc_dev->soc_type == VOP_FULL_RK3366) { + lcdc_grf_writel(lcdc_dev->grf_base, + RK3366_GRF_SOC_CON0, + MIPI_SOURCE_SEL(dev_drv->id)); + } break; case SCREEN_DUAL_MIPI: mask = m_MIPI_OUT_EN | m_DOUB_CHANNEL_EN | @@ -2109,11 +2121,6 @@ static int rk3368_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) } /*hsync vsync den dclk polo,dither */ lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val); -#ifndef CONFIG_RK_FPGA - /*writel_relaxed(v, RK_GRF_VIRT + rk3368_GRF_SOC_CON7); - move to lvds driver*/ - /*GRF_SOC_CON7 bit[15]:0->dsi/lvds mode,1->ttl mode */ -#endif mask = m_DSP_OUT_MODE | m_DSP_DCLK_DDR | m_DSP_BG_SWAP | m_DSP_RB_SWAP | m_DSP_RG_SWAP | m_DSP_DELTA_SWAP | m_DSP_DUMMY_SWAP | m_DSP_OUT_ZERO | m_DSP_BLANK_EN | @@ -2204,19 +2211,27 @@ static int rk3368_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv) struct lcdc_device, driver); u32 mask, val; /*struct rk_screen *screen = dev_drv->cur_screen; */ + u32 intr_en_reg, intr_clr_reg; + + if (lcdc_dev->soc_type == VOP_FULL_RK3366) { + intr_clr_reg = INTR_CLEAR_RK3366; + intr_en_reg = INTR_EN_RK3366; + } else { + intr_clr_reg = INTR_CLEAR_RK3368; + intr_en_reg = INTR_EN_RK3368; + } mask = m_FS_INTR_CLR | m_FS_NEW_INTR_CLR | m_LINE_FLAG0_INTR_CLR | m_LINE_FLAG1_INTR_CLR; val = v_FS_INTR_CLR(1) | v_FS_NEW_INTR_CLR(1) | v_LINE_FLAG0_INTR_CLR(1) | v_LINE_FLAG1_INTR_CLR(1); - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, mask, val); + lcdc_msk_reg(lcdc_dev, intr_clr_reg, mask, val); mask = m_FS_INTR_EN | m_LINE_FLAG0_INTR_EN | m_BUS_ERROR_INTR_EN | m_LINE_FLAG1_INTR_EN; val = v_FS_INTR_EN(1) | v_LINE_FLAG0_INTR_EN(1) | v_BUS_ERROR_INTR_EN(1) | v_LINE_FLAG1_INTR_EN(0); - lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val); - + lcdc_msk_reg(lcdc_dev, intr_en_reg, mask, val); #ifdef LCDC_IRQ_EMPTY_DEBUG mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN | m_WIN2_EMPTY_INTR_EN | @@ -2226,7 +2241,7 @@ static int rk3368_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv) v_WIN2_EMPTY_INTR_EN(1) | v_WIN3_EMPTY_INTR_EN(1) | v_HWC_EMPTY_INTR_EN(1) | v_POST_BUF_EMPTY_INTR_EN(1) | v_PWM_GEN_INTR_EN(1); - lcdc_msk_reg(lcdc_dev, INTR_EN, mask, val); + lcdc_msk_reg(lcdc_dev, intr_en_reg, mask, val); #endif return 0; } @@ -2276,9 +2291,6 @@ static int rk3368_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id, if (dev_drv->cur_screen->dsp_lut) rk3368_lcdc_set_lut(dev_drv, dev_drv->cur_screen->dsp_lut); - if ((dev_drv->cur_screen->cabc_lut) && dev_drv->cabc_mode) - rk3368_set_cabc_lut(dev_drv, - dev_drv->cur_screen->cabc_lut); spin_unlock(&lcdc_dev->reg_lock); } @@ -3306,6 +3318,13 @@ static int rk3368_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv) { struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); + u32 intr_clr_reg; + + if (lcdc_dev->soc_type == VOP_FULL_RK3366) + intr_clr_reg = INTR_CLEAR_RK3366; + else + intr_clr_reg = INTR_CLEAR_RK3368; + if (dev_drv->suspend_flag) return 0; /* close the backlight */ @@ -3326,7 +3345,7 @@ static int rk3368_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv) lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN, v_DSP_BLANK_EN(1)); lcdc_msk_reg(lcdc_dev, - INTR_CLEAR, m_FS_INTR_CLR | m_LINE_FLAG0_INTR_CLR, + intr_clr_reg, m_FS_INTR_CLR | m_LINE_FLAG0_INTR_CLR, v_FS_INTR_CLR(1) | v_LINE_FLAG0_INTR_CLR(1)); lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO, v_DSP_OUT_ZERO(1)); @@ -4151,42 +4170,6 @@ static int rk3368_lcdc_config_done(struct rk_lcdc_driver *dev_drv) return 0; } -static int rk3368_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open) -{ - struct lcdc_device *lcdc_dev = - container_of(dev_drv, struct lcdc_device, driver); - spin_lock(&lcdc_dev->reg_lock); - lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN, - v_DIRECT_PATH_EN(open)); - lcdc_cfg_done(lcdc_dev); - spin_unlock(&lcdc_dev->reg_lock); - return 0; -} - -static int rk3368_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id) -{ - struct lcdc_device *lcdc_dev = container_of(dev_drv, - struct lcdc_device, driver); - spin_lock(&lcdc_dev->reg_lock); - lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_SEL, - v_DIRECT_PATCH_SEL(win_id)); - lcdc_cfg_done(lcdc_dev); - spin_unlock(&lcdc_dev->reg_lock); - return 0; -} - -static int rk3368_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv) -{ - struct lcdc_device *lcdc_dev = - container_of(dev_drv, struct lcdc_device, driver); - int ovl; - - spin_lock(&lcdc_dev->reg_lock); - ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN); - spin_unlock(&lcdc_dev->reg_lock); - return ovl; -} - static int rk3368_lcdc_set_irq_to_cpu(struct rk_lcdc_driver *dev_drv, int enable) { @@ -4203,16 +4186,25 @@ int rk3368_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv) { struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); - u32 int_reg; + u32 int_reg_val; int ret; + u32 intr_status_reg, intr_clear_reg; + + if (lcdc_dev->soc_type == VOP_FULL_RK3366) { + intr_status_reg = INTR_STATUS_RK3366; + intr_clear_reg = INTR_CLEAR_RK3366; + } else { + intr_status_reg = INTR_STATUS_RK3368; + intr_clear_reg = INTR_CLEAR_RK3368; + } if (lcdc_dev->clk_on && (!dev_drv->suspend_flag)) { - int_reg = lcdc_readl(lcdc_dev, INTR_STATUS); - if (int_reg & m_LINE_FLAG0_INTR_STS) { + int_reg_val = lcdc_readl(lcdc_dev, intr_status_reg); + if (int_reg_val & m_LINE_FLAG0_INTR_STS) { lcdc_dev->driver.frame_time.last_framedone_t = lcdc_dev->driver.frame_time.framedone_t; lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0); - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, + lcdc_msk_reg(lcdc_dev, intr_clear_reg, m_LINE_FLAG0_INTR_CLR, v_LINE_FLAG0_INTR_CLR(1)); ret = RK_LF_STATUS_FC; @@ -4247,51 +4239,30 @@ static int rk3368_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv, spin_unlock(&lcdc_dev->reg_lock); return 0; } -static u32 pwm_period_hpr, pwm_duty_lpr; -static u32 cabc_status; - -int rk3368_lcdc_update_pwm(int bl_pwm_period, int bl_pwm_duty) -{ - pwm_period_hpr = bl_pwm_period; - pwm_duty_lpr = bl_pwm_duty; - /*pr_info("bl_pwm_period_hpr = 0x%x, bl_pwm_duty_lpr = 0x%x\n", - bl_pwm_period, bl_pwm_duty);*/ - return 0; -} - -int rk3368_lcdc_cabc_status(void) -{ - return cabc_status; -} static int rk3368_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv, int mode, int calc, int up, int down, int global) { struct lcdc_device *lcdc_dev = - container_of(dev_drv, struct lcdc_device, driver); + container_of(dev_drv, struct lcdc_device, driver); struct rk_screen *screen = dev_drv->cur_screen; u32 total_pixel, calc_pixel, stage_up, stage_down; - u32 pixel_num, global_su; - u32 stage_up_rec, stage_down_rec, global_su_rec, gamma_global_su_rec; - u32 mask = 0, val = 0, cabc_en = 0; + u32 pixel_num, global_dn; + u32 mask = 0, val = 0; int *cabc_lut = NULL; - if (!screen->cabc_lut) { + if (screen->type == SCREEN_HDMI && screen->type == SCREEN_TVOUT) { + pr_err("screen type is %d, not support cabc\n", screen->type); + return 0; + } else if (!screen->cabc_lut) { pr_err("screen cabc lut not config, so not open cabc\n"); return 0; } else { cabc_lut = screen->cabc_lut; } - if (!screen->cabc_gamma_base) { - pr_err("screen cabc_gamma_base no config, so not open cabc\n"); - return 0; - } - dev_drv->cabc_mode = mode; - cabc_en = (mode > 0) ? 1 : 0; - rk3368_lcdc_get_backlight_device(dev_drv); - if (cabc_en == 0) { + if (mode == 0) { spin_lock(&lcdc_dev->reg_lock); if (lcdc_dev->clk_on) { lcdc_msk_reg(lcdc_dev, CABC_CTRL0, @@ -4299,60 +4270,51 @@ static int rk3368_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv, lcdc_cfg_done(lcdc_dev); } pr_info("mode = 0, close cabc\n"); - rk_pwm_set(pwm_period_hpr, pwm_duty_lpr); - cabc_status = 0; + dev_drv->cabc_mode = mode; spin_unlock(&lcdc_dev->reg_lock); return 0; } - if (cabc_status == 0) { /*get from pwm*/ + if (dev_drv->cabc_mode == 0) rk3368_set_cabc_lut(dev_drv, dev_drv->cur_screen->cabc_lut); - rk_pwm_get(&pwm_period_hpr, &pwm_duty_lpr); - pr_info("pwm_period_hpr=0x%x, pwm_duty_lpr=0x%x\n", - pwm_period_hpr, pwm_duty_lpr); - } total_pixel = screen->mode.xres * screen->mode.yres; pixel_num = 1000 - calc; calc_pixel = (total_pixel * pixel_num) / 1000; stage_up = up; stage_down = down; - global_su = global; + global_dn = global; pr_info("enable cabc:mode=%d, calc=%d, up=%d, down=%d, global=%d\n", - mode, calc, stage_up, stage_down, global_su); - - stage_up_rec = 256 * 256 / stage_up; - stage_down_rec = 256 * 256 / stage_down; - global_su_rec = (256 * 256 / global_su); - gamma_global_su_rec = cabc_lut[global_su_rec]; + mode, calc, stage_up, stage_down, global_dn); spin_lock(&lcdc_dev->reg_lock); if (lcdc_dev->clk_on) { - mask = m_CABC_CALC_PIXEL_NUM | m_CABC_EN; - val = v_CABC_CALC_PIXEL_NUM(calc_pixel) | - v_CABC_EN(cabc_en); + mask = m_CABC_EN | m_CABC_HANDLE_EN | m_PWM_CONFIG_MODE | + m_CABC_CALC_PIXEL_NUM; + val = v_CABC_EN(1) | v_CABC_HANDLE_EN(1) | + v_PWM_CONFIG_MODE(STAGE_BY_STAGE) | + v_CABC_CALC_PIXEL_NUM(calc_pixel); lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val); - mask = m_CABC_TOTAL_PIXEL_NUM | m_CABC_LUT_EN; - val = v_CABC_TOTAL_PIXEL_NUM(total_pixel) | v_CABC_LUT_EN(1); + mask = m_CABC_LUT_EN | m_CABC_TOTAL_PIXEL_NUM; + val = v_CABC_LUT_EN(1) | v_CABC_TOTAL_PIXEL_NUM(total_pixel); lcdc_msk_reg(lcdc_dev, CABC_CTRL1, mask, val); - mask = m_CABC_STAGE_UP | m_CABC_STAGE_UP_REC | - m_CABC_GLOBAL_SU_LIMIT_EN | m_CABC_GLOBAL_SU_REC; - val = v_CABC_STAGE_UP(stage_up) | - v_CABC_STAGE_UP_REC(stage_up_rec) | - v_CABC_GLOBAL_SU_LIMIT_EN(1) | - v_CABC_GLOBAL_SU_REC(gamma_global_su_rec); + mask = m_CABC_STAGE_DOWN | m_CABC_STAGE_UP | + m_CABC_STAGE_MODE | m_MAX_SCALE_CFG_VALUE | + m_MAX_SCALE_CFG_ENABLE; + val = v_CABC_STAGE_DOWN(stage_down) | + v_CABC_STAGE_UP(stage_up) | + v_CABC_STAGE_MODE(0) | v_MAX_SCALE_CFG_VALUE(1) | + v_MAX_SCALE_CFG_ENABLE(0); lcdc_msk_reg(lcdc_dev, CABC_CTRL2, mask, val); - mask = m_CABC_STAGE_DOWN | m_CABC_STAGE_DOWN_REC | - m_CABC_GLOBAL_SU; - val = v_CABC_STAGE_DOWN(stage_down) | - v_CABC_STAGE_DOWN_REC(stage_down_rec) | - v_CABC_GLOBAL_SU(global_su); + mask = m_CABC_GLOBAL_DN | m_CABC_GLOBAL_DN_LIMIT_EN; + val = v_CABC_GLOBAL_DN(global_dn) | + v_CABC_GLOBAL_DN_LIMIT_EN(1); lcdc_msk_reg(lcdc_dev, CABC_CTRL3, mask, val); lcdc_cfg_done(lcdc_dev); + dev_drv->cabc_mode = mode; } - cabc_status = 1; spin_unlock(&lcdc_dev->reg_lock); return 0; @@ -4423,21 +4385,27 @@ static int rk3368_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv, if (lcdc_dev->clk_on) { switch (mode) { case BRIGHTNESS: - /*from 0 to 255,typical is 128 */ - if (value < 0x80) - value += 0x80; - else if (value >= 0x80) - value = value - 0x80; + /*user: from 0 to 255,typical is 128, + *vop,6bit: from 0 to 64, typical is 32*/ + value /= 4; + if (value < 0x20) + value += 0x20; + else if (value >= 0x20) + value = value - 0x20; mask = m_BCSH_BRIGHTNESS; val = v_BCSH_BRIGHTNESS(value); break; case CONTRAST: - /*from 0 to 510,typical is 256 */ + /*user: from 0 to 510,typical is 256 + *vop,9bit, from 0 to 511,typical is 256*/ + value = 512 - value; mask = m_BCSH_CONTRAST; val = v_BCSH_CONTRAST(value); break; case SAT_CON: - /*from 0 to 1015,typical is 256 */ + /*from 0 to 1024,typical is 512 + *vop,9bit, from 0 to 512, typical is 256*/ + value /= 2; mask = m_BCSH_SAT_CON; val = v_BCSH_SAT_CON(value); break; @@ -4464,10 +4432,11 @@ static int rk3368_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv, switch (mode) { case BRIGHTNESS: val &= m_BCSH_BRIGHTNESS; - if (val > 0x80) - val -= 0x80; + if (val >= 0x20) + val -= 0x20; else - val += 0x80; + val += 0x20; + val <<= 2; break; case CONTRAST: val &= m_BCSH_CONTRAST; @@ -4476,6 +4445,7 @@ static int rk3368_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv, case SAT_CON: val &= m_BCSH_SAT_CON; val >>= 20; + val <<= 1; break; default: break; @@ -4721,9 +4691,6 @@ static struct rk_lcdc_drv_ops lcdc_drv_ops = { .set_dsp_lut = rk3368_lcdc_set_lut, .set_cabc_lut = rk3368_set_cabc_lut, .poll_vblank = rk3368_lcdc_poll_vblank, - .dpi_open = rk3368_lcdc_dpi_open, - .dpi_win_sel = rk3368_lcdc_dpi_win_sel, - .dpi_status = rk3368_lcdc_dpi_status, .get_dsp_addr = rk3368_lcdc_get_dsp_addr, .set_dsp_cabc = rk3368_lcdc_set_dsp_cabc, .set_dsp_bcsh_hue = rk3368_lcdc_set_bcsh_hue, @@ -4746,32 +4713,39 @@ static struct rk_lcdc_drv_ops lcdc_drv_ops = { static int rk3368_lcdc_parse_irq(struct lcdc_device *lcdc_dev, unsigned int intr_status) { + u32 intr_clr_reg; + + if (lcdc_dev->soc_type == VOP_FULL_RK3366) + intr_clr_reg = INTR_CLEAR_RK3366; + else + intr_clr_reg = INTR_CLEAR_RK3368; + if (intr_status & m_WIN0_EMPTY_INTR_STS) { - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN0_EMPTY_INTR_CLR, + lcdc_msk_reg(lcdc_dev, intr_clr_reg, m_WIN0_EMPTY_INTR_CLR, v_WIN0_EMPTY_INTR_CLR(1)); dev_warn(lcdc_dev->dev, "win0 empty irq!"); } else if (intr_status & m_WIN1_EMPTY_INTR_STS) { - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN1_EMPTY_INTR_CLR, + lcdc_msk_reg(lcdc_dev, intr_clr_reg, m_WIN1_EMPTY_INTR_CLR, v_WIN1_EMPTY_INTR_CLR(1)); dev_warn(lcdc_dev->dev, "win1 empty irq!"); } else if (intr_status & m_WIN2_EMPTY_INTR_STS) { - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN2_EMPTY_INTR_CLR, + lcdc_msk_reg(lcdc_dev, intr_clr_reg, m_WIN2_EMPTY_INTR_CLR, v_WIN2_EMPTY_INTR_CLR(1)); dev_warn(lcdc_dev->dev, "win2 empty irq!"); } else if (intr_status & m_WIN3_EMPTY_INTR_STS) { - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_WIN3_EMPTY_INTR_CLR, + lcdc_msk_reg(lcdc_dev, intr_clr_reg, m_WIN3_EMPTY_INTR_CLR, v_WIN3_EMPTY_INTR_CLR(1)); dev_warn(lcdc_dev->dev, "win3 empty irq!"); } else if (intr_status & m_HWC_EMPTY_INTR_STS) { - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_HWC_EMPTY_INTR_CLR, + lcdc_msk_reg(lcdc_dev, intr_clr_reg, m_HWC_EMPTY_INTR_CLR, v_HWC_EMPTY_INTR_CLR(1)); dev_warn(lcdc_dev->dev, "HWC empty irq!"); } else if (intr_status & m_POST_BUF_EMPTY_INTR_STS) { - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_POST_BUF_EMPTY_INTR_CLR, + lcdc_msk_reg(lcdc_dev, intr_clr_reg, m_POST_BUF_EMPTY_INTR_CLR, v_POST_BUF_EMPTY_INTR_CLR(1)); dev_warn(lcdc_dev->dev, "post buf empty irq!"); } else if (intr_status & m_PWM_GEN_INTR_STS) { - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_PWM_GEN_INTR_CLR, + lcdc_msk_reg(lcdc_dev, intr_clr_reg, m_PWM_GEN_INTR_CLR, v_PWM_GEN_INTR_CLR(1)); dev_warn(lcdc_dev->dev, "PWM gen irq!"); } @@ -4784,18 +4758,24 @@ static irqreturn_t rk3368_lcdc_isr(int irq, void *dev_id) struct lcdc_device *lcdc_dev = (struct lcdc_device *)dev_id; ktime_t timestamp = ktime_get(); u32 intr_status; - u32 scale_global_limit, scale_global_limit_reg; - u32 cabc_pwm_lut_value, lut_val; - int pwm_plus; - int *cabc_gamma_base = NULL; u32 line_scane_num, dsp_vs_st_f1; struct rk_screen *screen = lcdc_dev->driver.cur_screen; + u32 intr_en_reg, intr_clr_reg, intr_status_reg; - intr_status = lcdc_readl(lcdc_dev, INTR_STATUS); + if (lcdc_dev->soc_type == VOP_FULL_RK3366) { + intr_status_reg = INTR_STATUS_RK3366; + intr_clr_reg = INTR_CLEAR_RK3366; + intr_en_reg = INTR_EN_RK3366; + } else { + intr_status_reg = INTR_STATUS_RK3368; + intr_clr_reg = INTR_CLEAR_RK3368; + intr_en_reg = INTR_EN_RK3368; + } + intr_status = lcdc_readl(lcdc_dev, intr_status_reg); if (intr_status & m_FS_INTR_STS) { timestamp = ktime_get(); - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_FS_INTR_CLR, + lcdc_msk_reg(lcdc_dev, intr_clr_reg, m_FS_INTR_CLR, v_FS_INTR_CLR(1)); line_scane_num = lcdc_readl(lcdc_dev, SCAN_LINE_NUM) & 0x1fff; dsp_vs_st_f1 = lcdc_readl(lcdc_dev, DSP_VS_ST_END_F1) >> 16; @@ -4817,41 +4797,18 @@ static irqreturn_t rk3368_lcdc_isr(int irq, void *dev_id) lcdc_dev->driver.frame_time.last_framedone_t = lcdc_dev->driver.frame_time.framedone_t; lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0); - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_LINE_FLAG0_INTR_CLR, + lcdc_msk_reg(lcdc_dev, intr_clr_reg, m_LINE_FLAG0_INTR_CLR, v_LINE_FLAG0_INTR_CLR(1)); - - if (cabc_status == 1) { - cabc_gamma_base = - lcdc_dev->driver.cur_screen->cabc_gamma_base; - scale_global_limit = lcdc_readl(lcdc_dev, CABC_DEBUG2); - scale_global_limit_reg = scale_global_limit; - scale_global_limit >>= 16; - scale_global_limit &= 0xff; - - if (lcdc_dev->driver.cabc_pwm_pol == 1) {/*negative*/ - pwm_plus = pwm_period_hpr - pwm_duty_lpr; - lut_val = cabc_gamma_base[scale_global_limit]; - cabc_pwm_lut_value = - pwm_period_hpr - - ((lut_val * pwm_plus) >> 16); - } else {/*positive*/ - pwm_plus = pwm_duty_lpr; - cabc_pwm_lut_value = - cabc_gamma_base[scale_global_limit] * - pwm_plus >> 16; - } - rk_pwm_set(pwm_period_hpr, cabc_pwm_lut_value); - } } else if (intr_status & m_LINE_FLAG1_INTR_STS) { /*line flag1 */ - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_LINE_FLAG1_INTR_CLR, + lcdc_msk_reg(lcdc_dev, intr_clr_reg, m_LINE_FLAG1_INTR_CLR, v_LINE_FLAG1_INTR_CLR(1)); } else if (intr_status & m_FS_NEW_INTR_STS) { /*new frame start */ - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_FS_NEW_INTR_CLR, + lcdc_msk_reg(lcdc_dev, intr_clr_reg, m_FS_NEW_INTR_CLR, v_FS_NEW_INTR_CLR(1)); } else if (intr_status & m_BUS_ERROR_INTR_STS) { - lcdc_msk_reg(lcdc_dev, INTR_CLEAR, m_BUS_ERROR_INTR_CLR, + lcdc_msk_reg(lcdc_dev, intr_clr_reg, m_BUS_ERROR_INTR_CLR, v_BUS_ERROR_INTR_CLR(1)); dev_warn(lcdc_dev->dev, "bus error!"); } @@ -4992,13 +4949,13 @@ static int rk3368_lcdc_probe(struct platform_device *pdev) syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); if (IS_ERR(lcdc_dev->grf_base)) { dev_err(&pdev->dev, "can't find lcdc grf property\n"); - return PTR_ERR(lcdc_dev->grf_base); + lcdc_dev->grf_base = NULL; } lcdc_dev->pmugrf_base = syscon_regmap_lookup_by_phandle(np, "rockchip,pmugrf"); if (IS_ERR(lcdc_dev->pmugrf_base)) { dev_err(&pdev->dev, "can't find lcdc pmu grf property\n"); - return PTR_ERR(lcdc_dev->pmugrf_base); + lcdc_dev->pmugrf_base = NULL; } lcdc_dev->cru_base = @@ -5086,6 +5043,7 @@ static void rk3368_lcdc_shutdown(struct platform_device *pdev) #if defined(CONFIG_OF) static const struct of_device_id rk3368_lcdc_dt_ids[] = { {.compatible = "rockchip,rk3368-lcdc",}, + {.compatible = "rockchip,rk3366-lcdc-big",}, {} }; #endif diff --git a/drivers/video/rockchip/lcdc/rk3368_lcdc.h b/drivers/video/rockchip/lcdc/rk3368_lcdc.h index 440e0cc2332b..5bffabb0e8c1 100755 --- a/drivers/video/rockchip/lcdc/rk3368_lcdc.h +++ b/drivers/video/rockchip/lcdc/rk3368_lcdc.h @@ -39,9 +39,13 @@ #define IEP_REG_DONE (IEP_CFG_DONE(1) | IEP_CFG_DONE_WMSK(1)) #define FBDC_REG_DONE (FBDC_CFG_DONE(1) | FBDC_CFG_DONE_WMSK(1)) #define SYS_REG_DONE (SYS_CFG_DONE(1) | SYS_CFG_DONE_WMSK(1)) + #define VERSION_INFO (0x0004) #define m_RTL_VERSION (0xffff<<0) #define m_FPGA_VERSION (0xffff<<16) +#define VOP_FULL_RK3368 0x03021223 +#define VOP_FULL_RK3366 0x03045635 + #define SYS_CTRL (0x0008) #define v_DIRECT_PATH_EN(x) (((x)&1)<<0) #define v_DIRECT_PATCH_SEL(x) (((x)&3)<<1) @@ -93,6 +97,7 @@ #define v_NOC_WIN_QOS(x) (((x)&0x3)<<10) #define v_AXI_MAX_OUTSTANDING_EN(x) (((x)&0x1)<<12) #define v_AXI_OUTSTANDING_MAX_NUM(x) (((x)&0x1f)<<13) +#define v_NOC_HURRY_W_MODE(x) (((x)&0x3)<<20) #define m_NOC_HURRY_EN (0x1<<0) #define m_NOC_HURRY_VALUE (0x3<<1) @@ -101,6 +106,7 @@ #define m_NOC_WIN_QOS (0x3<<10) #define m_AXI_MAX_OUTSTANDING_EN (0x1<<12) #define m_AXI_OUTSTANDING_MAX_NUM (0x1f<<13) +#define m_NOC_HURRY_W_MODE (0x3<<20) #define DSP_CTRL0 (0x0010) #define v_DSP_OUT_MODE(x) (((x)&0x0f)<<0) @@ -233,13 +239,15 @@ #define m_MCU_BYPASS (1<<30) #define m_MCU_TYPE ((u32)1<<31) -#define LINE_FLAG (0x0020) +#define LINE_FLAG_RK3368 (0x0020)/*rk3368*/ +#define LINE_FLAG_RK3366 (0x02a0)/*rk3366*/ #define m_DSP_LINE_FLAG0_NUM (0x1fff<<0) #define m_DSP_LINE_FLAG1_NUM (0x1fff<<16) #define v_DSP_LINE_FLAG0_NUM(x) (((x)&0x1fff)<<0) #define v_DSP_LINE_FLAG1_NUM(x) (((x)&0x1fff)<<16) -#define INTR_EN (0x0024) +#define INTR_EN_RK3368 (0x0024)/*for rk3368*/ +#define INTR_EN_RK3366 (0x0280)/*for rk3366*/ #define v_FS_INTR_EN(x) ((((x)&1)<<0) | ((1<<(0+16)))) #define v_FS_NEW_INTR_EN(x) ((((x)&1)<<1) | ((1<<(1+16)))) #define v_ADDR_SAME_INTR_EN(x) ((((x)&1)<<2) | ((1<<(2+16)))) @@ -254,6 +262,8 @@ #define v_POST_BUF_EMPTY_INTR_EN(x) ((((x)&1)<<11) | ((1<<(11+16)))) #define v_PWM_GEN_INTR_EN(x) ((((x)&1)<<12) | ((1<<(12+16)))) #define v_DSP_HOLD_VALID_INTR_EN(x) ((((x)&1)<<13) | ((1<<(13+16)))) +#define v_INTR_MMU_EN(x) ((((x)&1)<<14) | ((1<<(14+16))))/*rk3366*/ +#define v_INTR_DMA_FINISH_EN(x) ((((x)&1)<<15) | ((1<<(15+16))))/*rk3366*/ #define m_FS_INTR_EN ((1<<0) | ((1<<(0+16)))) #define m_FS_NEW_INTR_EN ((1<<1) | ((1<<(1+16)))) @@ -269,8 +279,11 @@ #define m_POST_BUF_EMPTY_INTR_EN ((1<<11) | ((1<<(11+16)))) #define m_PWM_GEN_INTR_EN ((1<<12) | ((1<<(12+16)))) #define m_DSP_HOLD_VALID_INTR_EN ((1<<13) | ((1<<(13+16)))) +#define m_INTR_MMU_EN ((1<<14) | ((1<<(14+16))))/*rk3366*/ +#define m_INTR_DMA_FINISH_EN ((1<<15) | ((1<<(15+16))))/*rk3366*/ -#define INTR_CLEAR (0x0028) +#define INTR_CLEAR_RK3368 (0x0028)/*rk3368*/ +#define INTR_CLEAR_RK3366 (0x0284)/*rk3366*/ #define v_FS_INTR_CLR(x) ((((x)&1)<<0) | (1<<(0+16))) #define v_FS_NEW_INTR_CLR(x) ((((x)&1)<<1) | (1<<(1+16))) #define v_ADDR_SAME_INTR_CLR(x) ((((x)&1)<<2) | (1<<(2+16))) @@ -285,6 +298,8 @@ #define v_POST_BUF_EMPTY_INTR_CLR(x) ((((x)&1)<<11) | (1<<(11+16))) #define v_PWM_GEN_INTR_CLR(x) ((((x)&1)<<12) | (1<<(12+16))) #define v_DSP_HOLD_VALID_INTR_CLR(x) ((((x)&1)<<13) | (1<<(13+16))) +#define v_INTR_MMU_CLR(x) ((((x)&1)<<14) | ((1<<(14+16))))/*rk3366*/ +#define v_INTR_DMA_FINISH_CLR(x) ((((x)&1)<<15) | ((1<<(15+16))))/*rk3366*/ #define m_FS_INTR_CLR ((1<<0) | ((1<<(0+16)))) #define m_FS_NEW_INTR_CLR ((1<<1) | ((1<<(1+16)))) @@ -300,8 +315,11 @@ #define m_POST_BUF_EMPTY_INTR_CLR ((1<<11) | ((1<<(11+16)))) #define m_PWM_GEN_INTR_CLR ((1<<12) | ((1<<(12+16)))) #define m_DSP_HOLD_VALID_INTR_CLR ((1<<13) | ((1<<(13+16)))) +#define m_INTR_MMU_CLEAR ((1<<14) | ((1<<(14+16))))/*rk3366*/ +#define m_INTR_DMA_FINISH_CLEAR ((1<<15) | ((1<<(15+16))))/*rk3366*/ -#define INTR_STATUS (0x002c) +#define INTR_STATUS_RK3368 (0x002c)/*rk3366*/ +#define INTR_STATUS_RK3366 (0x0288)/*rk3366*/ #define m_FS_INTR_STS (1<<0) #define m_FS_NEW_INTR_STS (1<<1) #define m_ADDR_SAME_INTR_STS (1<<2) @@ -316,6 +334,8 @@ #define m_POST_BUF_EMPTY_INTR_STS (1<<11) #define m_PWM_GEN_INTR_STS (1<<12) #define m_DSP_HOLD_VALID_INTR_STS (1<<13) +#define m_INTR_MMU_STS (1<<14)/*rk3366*/ +#define m_INTR_DMA_FINISH_STS (1<<15)/*rk3366*/ #define m_FS_INTR_RAWSTS (1<<(0+16)) #define m_FS_NEW_INTR_RAWSTS (1<<(1+16)) @@ -332,6 +352,57 @@ #define m_PWM_GEN_INTR_RAWSTS (1<<(12+16)) #define m_DSP_HOLD_VALID_INTR_RAWSTS (1<<(13+16)) +#define INTR_RAW_STATUS_RK3366 (0x028c)/*rk3366*/ +#define m_FS_INTR_RAWSTS_RK3366 (1<<0)/*rk3366*/ +#define m_FS_NEW_INTR_RAWSTS_RK3366 (1<<1)/*rk3366*/ +#define m_ADDR_SAME_INTR_RAWSTS_RK3366 (1<<2)/*rk3366*/ +#define m_LINE_FLAG0_INTR_RAWSTS_RK3366 (1<<3)/*rk3366*/ +#define m_LINE_FLAG1_INTR_RAWSTS_RK3366 (1<<4)/*rk3366*/ +#define m_BUS_ERROR_INTR_RAWSTS_RK3366 (1<<5)/*rk3366*/ +#define m_WIN0_EMPTY_INTR_RAWSTS_RK3366 (1<<6)/*rk3366*/ +#define m_WIN1_EMPTY_INTR_RAWSTS_RK3366 (1<<7)/*rk3366*/ +#define m_WIN2_EMPTY_INTR_RAWSTS_RK3366 (1<<8)/*rk3366*/ +#define m_WIN3_EMPTY_INTR_RAWSTS_RK3366 (1<<9)/*rk3366*/ +#define m_HWC_EMPTY_INTR_RAWSTS_RK3366 (1<<10)/*rk3366*/ +#define m_POST_BUF_EMPTY_INTR_RAWSTS_RK3366 (1<<11)/*rk3366*/ +#define m_PWM_GEN_INTR_RAWSTS_RK3366 (1<<12)/*rk3366*/ +#define m_DSP_HOLD_VALID_INTR_RAWSTS_RK3366 (1<<13)/*rk3366*/ +#define m_INTR_MMU_RAWSTS_RK3366 (1<<14)/*rk3366*/ +#define m_INTR_DMA_FINISH_RAWSTS_RK3366 (1<<15)/*rk3366*/ + +/********************rk3366 write back register************************/ +#define WB_CTRL0 (0x0020) +#define v_WB_EN(x) (((x)&0x1)<<0) +#define v_WB_FMT(x) (((x)&0x7)<<1) +#define v_WB_DITHER_EN(x) (((x)&0x1)<<4) +#define v_WB_RGB2YUV_EN(x) (((x)&0x1)<<5) +#define v_WB_RGB2YUV_MODE(x) (((x)&0x1)<<6) +#define v_WB_XPSD_BIL_EN(x) (((x)&0x1)<<7) +#define v_WB_YTHROW_EN(x) (((x)&0x1)<<8) +#define v_WB_YTHROW_MODE(x) (((x)&0x1)<<9) +#define v_WB_HANDSHAKE_MODE(x) (((x)&0x1)<<11) +#define v_WB_YRGB_ID(x) (((x)&0xf)<<24) +#define v_WB_UI_ID(x) (((x)&0xf)<<28) +#define m_WB_EN(x) (0x1<<0) +#define m_WB_FMT(x) (0x7<<1) +#define m_WB_DITHER_EN(x) (0x1<<4) +#define m_WB_RGB2YUV_EN(x) (0x1<<5) +#define m_WB_RGB2YUV_MODE(x) (0x1<<6) +#define m_WB_XPSD_BIL_EN(x) (0x1<<7) +#define m_WB_YTHROW_EN(x) (0x1<<8) +#define m_WB_YTHROW_MODE(x) (0x1<<9) +#define m_WB_HANDSHAKE_MODE(x) (0x1<<11) +#define m_WB_YRGB_ID(x) (0xf<<24) +#define m_WB_UI_ID(x) (0xf<<28) +#define WB_CTRL1 (0x0024) +#define v_WB_WIDTH(x) (((x)&0xfff)<<0) +#define v_WB_XPSD_BIL_FACTOR(x) (((x)&0x3fff)<<16) +#define m_WB_WIDTH (0xfff<<0) +#define m_WB_XPSD_BIL_FACTOR (0x3fff<<16) +#define WB_YRGB_MST (0x0028) +#define WB_CBR_MST (0x002c) +/********************rk3366 write back register************************/ + /*win0 register*/ #define WIN0_CTRL0 (0x0030) #define v_WIN0_EN(x) (((x)&1)<<0) @@ -1251,11 +1322,11 @@ #define m_BCSH_COLOR_BAR_V (0xff<<24) #define BCSH_BCS (0x01b4) -#define v_BCSH_BRIGHTNESS(x) (((x)&0xff)<<0) +#define v_BCSH_BRIGHTNESS(x) (((x)&0x3f)<<0) #define v_BCSH_CONTRAST(x) (((x)&0x1ff)<<8) #define v_BCSH_SAT_CON(x) (((x)&0x3ff)<<20) #define v_BCSH_OUT_MODE(x) (((x)&0x3)<<30) -#define m_BCSH_BRIGHTNESS (0xff<<0) +#define m_BCSH_BRIGHTNESS (0x3f<<0) #define m_BCSH_CONTRAST (0x1ff<<8) #define m_BCSH_SAT_CON (0x3ff<<20) #define m_BCSH_OUT_MODE ((u32)0x3<<30) @@ -1279,34 +1350,38 @@ #define CABC_CTRL0 (0x01c0) #define v_CABC_EN(x) (((x)&1)<<0) -#define v_CABC_CALC_PIXEL_NUM(x) (((x)&0xffffff)<<1) +#define v_PWM_CONFIG_MODE(x) (((x)&3)<<1) +#define v_CABC_HANDLE_EN(x) (((x)&1)<<3) +#define v_CABC_CALC_PIXEL_NUM(x) (((x)&0x7fffff)<<4) #define m_CABC_EN (1<<0) -#define m_CABC_CALC_PIXEL_NUM (0xffffff<<1) - +#define m_PWM_CONFIG_MODE (3<<1) +#define m_CABC_HANDLE_EN (1<<3) +#define m_CABC_CALC_PIXEL_NUM (0x7fffff<<4) #define CABC_CTRL1 (0x01c4) #define v_CABC_LUT_EN(x) (((x)&1)<<0) -#define v_CABC_TOTAL_PIXEL_NUM(x) (((x)&0xffffff)<<1) +#define v_CABC_TOTAL_PIXEL_NUM(x) (((x)&0x7fffff)<<4) #define m_CABC_LUT_EN (1<<0) -#define m_CABC_TOTAL_PIXEL_NUM (0xffffff<<1) +#define m_CABC_TOTAL_PIXEL_NUM (0x7fffff<<4) #define CABC_CTRL2 (0x01c8) -#define v_CABC_STAGE_UP_REC(x) (((x)&0xff)<<0) -#define m_CABC_STAGE_UP_REC (0xff<<0) +#define v_CABC_STAGE_DOWN(x) (((x)&0xff)<<0) #define v_CABC_STAGE_UP(x) (((x)&0x1ff)<<8) +#define v_CABC_STAGE_MODE(x) (((x)&1)<<19) +#define v_MAX_SCALE_CFG_VALUE(x) (((x)&0x1ff)<<20) +#define v_MAX_SCALE_CFG_ENABLE(x) (((x)&1)<<31) +#define m_CABC_STAGE_DOWN (0xff<<0) #define m_CABC_STAGE_UP (0x1ff<<8) -#define v_CABC_GLOBAL_SU_LIMIT_EN(x) (((x)&0x1)<<23) -#define m_CABC_GLOBAL_SU_LIMIT_EN (0x1<<23) -#define v_CABC_GLOBAL_SU_REC(x) (((x)&0xff)<<24) -#define m_CABC_GLOBAL_SU_REC (0xff<<24) +#define m_CABC_STAGE_MODE (1<<19) +#define m_MAX_SCALE_CFG_VALUE (0x1ff<<20) +#define m_MAX_SCALE_CFG_ENABLE (1<<31) #define CABC_CTRL3 (0x01cc) -#define v_CABC_STAGE_DOWN(x) (((x)&0xff)<<0) -#define m_CABC_STAGE_DOWN (0xff<<0) -#define v_CABC_STAGE_DOWN_REC(x) (((x)&0x1ff)<<8) -#define m_CABC_STAGE_DOWN_REC (0x1ff<<8) -#define v_CABC_GLOBAL_SU(x) (((x)&0x1ff)<<23) -#define m_CABC_GLOBAL_SU (0x1ff<<23) +#define v_CABC_GLOBAL_DN(x) (((x)&0xff)<<0) +#define v_CABC_GLOBAL_DN_LIMIT_EN(x) (((x)&1)<<8) +#define m_CABC_GLOBAL_DN (0xff<<0) +#define m_CABC_GLOBAL_DN_LIMIT_EN (1<<8) + #define CABC_GAUSS_LINE0_0 (0x01d0) #define v_CABC_T_LINE0_0(x) (((x)&0xff)<<0) #define v_CABC_T_LINE0_1(x) (((x)&0xff)<<8) @@ -1509,7 +1584,22 @@ #define v_RD_LATENCY_SAMP_NUM_CH0(x) (((x)&0xFFFFFF)<<0) #define m_RD_LATENCY_SAMP_NUM_CH0 (0xFFFFFF<<0) -#define WIN0_DSP_BG (0x260) +#define VOP_STATUS 0x000002a4 +#define v_VOP_DSP_VCNT(x) (((x)&0x1FFF)<<0) +#define v_VOP_MMU_IDLE(x) (((x)&0x1)<<16) +#define v_DMA_STOP_VALID(x) (((x)&0x1)<<17) +#define m_VOP_DSP_VCNT (0x1FFF<<0) +#define m_VOP_MMU_IDLE (0x1<<16) +#define m_DMA_STOP_VALID (0x1<<17) + +#define BLANKING_VALUE 0x02a8 +#define v_BLANKING_VALUE(x) (((x)&0xFFFFFF)<<0) +#define v_BLANKING_VALUE_CONFIG_EN(x) (((x)&0x1)<<24) +#define m_BLANKING_VALUE (0xFFFFFF<<0) +#define m_BLANKING_VALUE_CONFIG_EN (0x1<<24) + +#define WIN0_DSP_BG_RK3368 (0x260) +#define WIN0_DSP_BG_RK3366 (0x2b0)/*rk3366*/ #define v_WIN0_DSP_BG_BLUE(x) (((x)&0xff)<<0) #define v_WIN0_DSP_BG_GREEN(x) (((x)&0xff)<<8) #define v_WIN0_DSP_BG_RED(x) (((x)&0xff)<<16) @@ -1519,7 +1609,8 @@ #define m_WIN0_DSP_BG_RED (0xff<<16) #define m_WIN0_DSP_BG_EN (0x1<<31) -#define WIN1_DSP_BG (0x264) +#define WIN1_DSP_BG_RK3368 (0x264) +#define WIN1_DSP_BG_RK3366 (0x2b4)/*rk3366*/ #define v_WIN1_DSP_BG_BLUE(x) (((x)&0xff)<<0) #define v_WIN1_DSP_BG_GREEN(x) (((x)&0xff)<<8) #define v_WIN1_DSP_BG_RED(x) (((x)&0xff)<<16) @@ -1529,7 +1620,8 @@ #define m_WIN1_DSP_BG_RED (0xff<<16) #define m_WIN1_DSP_BG_EN (0x1<<31) -#define WIN2_DSP_BG (0x268) +#define WIN2_DSP_BG_RK3368 (0x268) +#define WIN2_DSP_BG_RK3366 (0x2b8)/*rk3366*/ #define v_WIN2_DSP_BG_BLUE(x) (((x)&0xff)<<0) #define v_WIN2_DSP_BG_GREEN(x) (((x)&0xff)<<8) #define v_WIN2_DSP_BG_RED(x) (((x)&0xff)<<16) @@ -1539,7 +1631,8 @@ #define m_WIN2_DSP_BG_RED (0xff<<16) #define m_WIN2_DSP_BG_EN (0x1<<31) -#define WIN3_DSP_BG (0x26c) +#define WIN3_DSP_BG_RK3368 (0x26c) +#define WIN3_DSP_BG_RK3366 (0x2bC)/*rk3366*/ #define v_WIN3_DSP_BG_BLUE(x) (((x)&0xff)<<0) #define v_WIN3_DSP_BG_GREEN(x) (((x)&0xff)<<8) #define v_WIN3_DSP_BG_RED(x) (((x)&0xff)<<16) @@ -1642,11 +1735,26 @@ #define PMUGRF_SOC_CON0_VOP (0x0100) +#define RK3366_GRF_SOC_CON0 (0x0400) +#define RK3366_GRF_SOC_CON5 (0x0414) #define OUT_CCIR656_MODE_0 5 #define OUT_CCIR656_MODE_1 6 #define OUT_CCIR656_MODE_2 7 +#define VOP_SOURCE_SEL(id, shift) ((id << shift) | 1 << (shift + 16)) +#define RGB_SOURCE_SEL(id) VOP_SOURCE_SEL(id, 3) +#define LVDS_SOURCE_SEL(id) VOP_SOURCE_SEL(id, 0) +#define MIPI_SOURCE_SEL(id) VOP_SOURCE_SEL(id, 2) +#define HDMI_SOURCE_SEL(id) VOP_SOURCE_SEL(id, 1) + +#define RGB_DATA_PLANA ((2 << 6) | (3 << (6 + 16))) +#define RGB_DATA_PLANB ((3 << 6) | (3 << (6 + 16))) + +#define RK3366_GRF_IO_VSEL 0x0900 +#define RK3366_GRF_VOP_IOVOL_SEL(x) (((x) << 0) | (1 << (0 + 16))) +#define RK3368_GRF_VOP_IOVOL_SEL(x) (((x) << 5) | (1 << (5 + 16))) + enum lb_mode { LB_YUV_3840X5 = 0x0, LB_YUV_2560X8 = 0x1, @@ -1738,8 +1846,15 @@ enum _vop_overlay_mode { VOP_YUV_DOMAIN }; +enum cabc_stage_mode { + LAST_FRAME_PWM_VAL = 0x0, + CUR_FRAME_PWM_VAL = 0x1, + STAGE_BY_STAGE = 0x2 +}; + struct lcdc_device { int id; + u32 soc_type; struct rk_lcdc_driver driver; struct device *dev; struct rk_screen *screen; @@ -1866,7 +1981,8 @@ static inline void lcdc_msk_reg(struct lcdc_device *lcdc_dev, (*_pv) &= (~msk); (*_pv) |= v; writel_relaxed(*_pv, lcdc_dev->regs + offset); - if (offset == INTR_CLEAR) + if (((lcdc_dev->soc_type == VOP_FULL_RK3366) && (offset == INTR_CLEAR_RK3366)) || + ((lcdc_dev->soc_type == VOP_FULL_RK3368) && (offset == INTR_CLEAR_RK3368))) (*_pv) &= 0; } @@ -1879,7 +1995,8 @@ static inline void lcdc_cfg_done(struct lcdc_device *lcdc_dev) static inline int lcdc_grf_writel(struct regmap *base, u32 offset, u32 val) { - regmap_write(base, offset, val); + if (base) + regmap_write(base, offset, val); dsb(sy); return 0; @@ -1888,7 +2005,8 @@ static inline int lcdc_grf_writel(struct regmap *base, static inline int lcdc_cru_writel(struct regmap *base, u32 offset, u32 val) { - regmap_write(base, offset, val); + if (base) + regmap_write(base, offset, val); dsb(sy); return 0; -- 2.34.1