rk32-lcdc: improve the cabc function

This commit is contained in:
zwl
2014-06-05 08:51:57 +08:00
parent 0fc71500f8
commit e957da03a7
5 changed files with 63 additions and 28 deletions

View File

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

View File

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

View File

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

View File

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

View File

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