rk32-lcdc: improve the cabc function
authorzwl <zwl@rock-chips.com>
Thu, 5 Jun 2014 00:51:57 +0000 (08:51 +0800)
committerzwl <zwl@rock-chips.com>
Thu, 5 Jun 2014 00:52:16 +0000 (08:52 +0800)
drivers/video/rockchip/lcdc/rk3288_lcdc.c
drivers/video/rockchip/lcdc/rk3288_lcdc.h
drivers/video/rockchip/rk_fb.c
drivers/video/rockchip/rkfb_sysfs.c
include/linux/rk_fb.h

index 7fbd4c72305e41d12888848b264237f460cf352f..c20b3f2a75f6644347b2f16cb01e3ccaa1bb2a3d 100755 (executable)
@@ -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
index ca9af3e101c1cd692ad3a892fb151292c1031979..21e02ad2a7c550181d64f287e34eb38c184d1cd0 100755 (executable)
@@ -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;     
index 64a1e9bbe199685a46c5d01a135f2ae1c1a63f6d..f6f7099858ea3f8e1631e061509984577a19b249 100755 (executable)
@@ -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);
        }
index 49ffe6394bf975e2017b3fe1b3371f2ff7939e69..c3c8d9e08afd39844acb346530b92b61bf8439f9 100755 (executable)
@@ -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;
 }
 
index 3693a222d3e7d5bf2742e739296ab4f60533ac14..a425055a2207e9cfc7783d87cb5c72cbbc6af111 100755 (executable)
@@ -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;