From: zwl Date: Thu, 5 Jun 2014 00:51:57 +0000 (+0800) Subject: rk32-lcdc: improve the cabc function X-Git-Tag: firefly_0821_release~5187 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e957da03a710c8ba5b145a0028bc82aa443f325b;p=firefly-linux-kernel-4.4.55.git rk32-lcdc: improve the cabc function --- diff --git a/drivers/video/rockchip/lcdc/rk3288_lcdc.c b/drivers/video/rockchip/lcdc/rk3288_lcdc.c index 7fbd4c72305e..c20b3f2a75f6 100755 --- a/drivers/video/rockchip/lcdc/rk3288_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk3288_lcdc.c @@ -293,7 +293,7 @@ static void lcdc_read_reg_defalut_cfg(struct lcdc_device *lcdc_dev) /********do basic init*********/ static int rk3288_lcdc_pre_init(struct rk_lcdc_driver *dev_drv) { - int v,i; + int v; u32 mask,val; struct lcdc_device *lcdc_dev = container_of(dev_drv, struct @@ -3119,42 +3119,60 @@ static int rk3288_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,unsigned int return 0; } -static int rk3288_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv,int mode) +static struct lcdc_cabc_mode cabc_mode[5] = { +/* pixel_num, stage_up, stage_down */ + {5, 2, 2}, /*mode 1*/ + {10, 2, 2}, /*mode 2*/ + {15, 2, 2}, /*mode 3*/ + {20, 2, 2}, /*mode 4*/ + {20, 128, 0}, /*mode 5*/ +}; + +static int rk3288_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv, int mode) { struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); struct rk_screen *screen = dev_drv->cur_screen; - int total_pixel,calc_pixel,stage_up,stage_down; - u32 mask=0, val=0; - - u32 cabc_mode[5][3]={ - /*num ,up, down*/ - {2, 10, 10}, /*mode 1*/ - {4, 10, 10}, /*mode 2*/ - {6, 10, 10}, /*mode 3*/ - {8, 10, 10}, /*mode 4*/ - {10, 10, 10}, /*mode 5*/ - }; - /*iomux connect to vop or pwm*/ - if(mode == 0){ - DBG(3,"close cabc\n"); + int total_pixel, calc_pixel, stage_up, stage_down; + u32 mask = 0, val = 0; + + dev_drv->cabc_mode = mode; + + /* iomux connect to vop or pwm */ + if (mode == 0) { /* select rk pwm */ + DBG(3, "close cabc and select rk pwm\n"); val = 0x30001; - writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_GPIO7A_IOMUX);/*pwm sel*/ - lcdc_set_bit(lcdc_dev, SYS_CTRL, 0<<23);/*disable auto gating*/ - mask = m_CABC_EN; - val = v_CABC_EN(0); - lcdc_set_bit(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN); - /*lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);*/ + writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_GPIO7A_IOMUX); + spin_lock(&lcdc_dev->reg_lock); + if(lcdc_dev->clk_on) { + lcdc_msk_reg(lcdc_dev, CABC_CTRL0, m_CABC_EN, v_CABC_EN(0)); + lcdc_cfg_done(lcdc_dev); + } + spin_unlock(&lcdc_dev->reg_lock); + return 0; + } else if (mode == 99) { /* select vop pwm */ + DBG(3, "close cabc and select vop pwm\n"); + val = (dev_drv->id == 0) ? 0x30002 : 0x30003; + writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_GPIO7A_IOMUX); + spin_lock(&lcdc_dev->reg_lock); + if(lcdc_dev->clk_on) { + lcdc_msk_reg(lcdc_dev, CABC_CTRL0, m_CABC_EN, v_CABC_EN(0)); + lcdc_cfg_done(lcdc_dev); + } + spin_unlock(&lcdc_dev->reg_lock); return 0; + } else { + val = (dev_drv->id == 0) ? 0x30002 : 0x30003; + writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_GPIO7A_IOMUX); } + total_pixel = screen->mode.xres * screen->mode.yres; - calc_pixel = total_pixel * (100 - cabc_mode[mode-1][0])/100; - stage_up = cabc_mode[mode-1][1]; - stage_down = cabc_mode[mode-1][2]; + calc_pixel = total_pixel * (100 - cabc_mode[mode - 1].pixel_num) / 100; + stage_up = cabc_mode[mode - 1].stage_up; + stage_down = cabc_mode[mode - 1].stage_down; spin_lock(&lcdc_dev->reg_lock); - if(lcdc_dev->clk_on){ - lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val); + if(lcdc_dev->clk_on) { mask = m_CABC_TOTAL_NUM | m_CABC_STAGE_DOWN; val = v_CABC_TOTAL_NUM(total_pixel) | v_CABC_STAGE_DOWN(stage_down); lcdc_msk_reg(lcdc_dev, CABC_CTRL1, mask, val); @@ -3167,8 +3185,7 @@ static int rk3288_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv,int mode) lcdc_cfg_done(lcdc_dev); } spin_unlock(&lcdc_dev->reg_lock); - val = 0x30003; - writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_GPIO7A_IOMUX);/*pwm sel*/ + return 0; } /* @@ -3479,6 +3496,11 @@ static int rk3288_lcdc_parse_dt(struct lcdc_device *lcdc_dev) else lcdc_dev->prop = val; + if (of_property_read_u32(np, "rockchip,cabc_mode", &val)) + lcdc_dev->driver.cabc_mode = 0; /* default set close cabc */ + else + lcdc_dev->driver.cabc_mode = val; + if (of_property_read_u32(np, "rockchip,pwr18", &val)) lcdc_dev->pwr18 = false; /*default set it as 3.xv power supply */ else diff --git a/drivers/video/rockchip/lcdc/rk3288_lcdc.h b/drivers/video/rockchip/lcdc/rk3288_lcdc.h index ca9af3e101c1..21e02ad2a7c5 100755 --- a/drivers/video/rockchip/lcdc/rk3288_lcdc.h +++ b/drivers/video/rockchip/lcdc/rk3288_lcdc.h @@ -1348,6 +1348,12 @@ struct alpha_config{ enum factor_mode dst_factor_mode; /*win0_dst_factor_m0*/ }; +struct lcdc_cabc_mode { + char pixel_num; /* pixel precent number */ + char stage_up; /* up stride */ + char stage_down; /* down stride */ +}; + static inline void lcdc_writel(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 index 64a1e9bbe199..f6f7099858ea 100755 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -3238,6 +3238,7 @@ static int init_lcdc_device_driver(struct rk_fb *rk_fb, dev_drv->first_frame = 1; rk_disp_pwr_ctr_parse_dt(dev_drv); if (dev_drv->prop == PRMRY) { + dev_drv->ops->set_dsp_cabc(dev_drv, dev_drv->cabc_mode); rk_fb_set_prmry_screen(screen); rk_fb_get_prmry_screen(screen); } diff --git a/drivers/video/rockchip/rkfb_sysfs.c b/drivers/video/rockchip/rkfb_sysfs.c index 49ffe6394bf9..c3c8d9e08afd 100755 --- a/drivers/video/rockchip/rkfb_sysfs.c +++ b/drivers/video/rockchip/rkfb_sysfs.c @@ -294,7 +294,12 @@ static ssize_t set_dsp_lut(struct device *dev, struct device_attribute *attr, static ssize_t show_dsp_cabc(struct device *dev, struct device_attribute *attr, char *buf) { + struct fb_info *fbi = dev_get_drvdata(dev); + struct rk_lcdc_driver *dev_drv = + (struct rk_lcdc_driver *)fbi->par; + return snprintf(buf, PAGE_SIZE, "cabc mode=%d\n", + dev_drv->cabc_mode); return 0; } diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index 3693a222d3e7..a425055a2207 100755 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -537,6 +537,7 @@ struct rk_lcdc_driver { struct sw_sync_timeline *timeline; int timeline_max; int suspend_flag; + int cabc_mode; struct list_head update_regs_list; struct mutex update_regs_list_lock; struct kthread_worker update_regs_worker;