rk3066b lcdc: add support lut function
authorhjc <hjc@rock-chips.com>
Mon, 8 Jul 2013 03:44:24 +0000 (11:44 +0800)
committerhjc <hjc@rock-chips.com>
Mon, 8 Jul 2013 03:44:24 +0000 (11:44 +0800)
drivers/video/rockchip/lcdc/rk3066b_lcdc.c
drivers/video/rockchip/lcdc/rk3066b_lcdc.h [changed mode: 0644->0755]

index 9945b2871c10384690156803ce8e44ddcbcb4adf..bd992f46b7e9085f1b5aed236df019602a470c79 100755 (executable)
@@ -83,8 +83,11 @@ static int rk3066b_lcdc_reg_resume(struct rk3066b_lcdc_device *lcdc_dev)
 
 static int init_rk3066b_lcdc(struct rk_lcdc_device_driver *dev_drv)
 {
-       struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
+       int i=0;
+       int __iomem *c;
        int v;
+
+       struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
        
        if(lcdc_dev->id == 0) //lcdc0
        {
@@ -174,6 +177,20 @@ static int init_rk3066b_lcdc(struct rk_lcdc_device_driver *dev_drv)
              v_SCANNING_MASK(1));  //mask all interrupt in init
        LcdMskReg(lcdc_dev,FIFO_WATER_MARK,m_WIN1_FIFO_FULL_LEVEL,v_WIN1_FIFO_FULL_LEVEL(0x1e0));
        //LCDC_REG_CFG_DONE();  // write any value to  REG_CFG_DONE let config become effective
+       if(dev_drv->cur_screen->dsp_lut)                        //resume dsp lut
+       {
+               LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(0));
+               LCDC_REG_CFG_DONE();
+
+               mdelay(25); //wait for dsp lut disabled
+               for(i=0;i<256;i++)
+               {
+                       v = dev_drv->cur_screen->dsp_lut[i];
+                       c = lcdc_dev->dsp_lut_addr_base+i;
+                       writel_relaxed(v,c);
+               }
+               LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(1));//enable dsp lut
+       }
 
        rk3066b_lcdc_clk_disable(lcdc_dev);
        return 0;
@@ -593,6 +610,9 @@ static int win1_set_par(struct rk3066b_lcdc_device *lcdc_dev,rk_screen *screen,
 
 static int rk3066b_lcdc_open(struct rk_lcdc_device_driver *dev_drv,int layer_id,bool open)
 {
+       int i=0;
+       int __iomem *c;
+       int v;
        struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
 
        if((open) && (!lcdc_dev->atv_layer_cnt)) //enable clk,when first layer open
@@ -601,6 +621,22 @@ static int rk3066b_lcdc_open(struct rk_lcdc_device_driver *dev_drv,int layer_id,
                rk3066b_lcdc_reg_resume(lcdc_dev); //resume reg
                LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
                rk3066b_load_screen(dev_drv,1);
+               spin_lock(&lcdc_dev->reg_lock);
+               if(dev_drv->cur_screen->dsp_lut)                        //resume dsp lut
+               {
+                       LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(0));
+                       LCDC_REG_CFG_DONE();
+
+                       mdelay(25); //wait for dsp lut disabled
+                       for(i=0;i<256;i++)
+                       {
+                               v = dev_drv->cur_screen->dsp_lut[i];
+                               c = lcdc_dev->dsp_lut_addr_base+i;
+                               writel_relaxed(v,c);
+                       }
+                       LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(1));//enable dsp lut
+               }
+               spin_unlock(&lcdc_dev->reg_lock);
        }
        if(layer_id == 0)
        {
@@ -1044,6 +1080,9 @@ int rk3066b_lcdc_early_suspend(struct rk_lcdc_device_driver *dev_drv)
 int rk3066b_lcdc_early_resume(struct rk_lcdc_device_driver *dev_drv)
 {  
        struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
+       int i=0;
+       int __iomem *c;
+       int v;
 
        if(dev_drv->screen_ctr_info->io_enable)                 //power on
                dev_drv->screen_ctr_info->io_enable();
@@ -1060,6 +1099,21 @@ int rk3066b_lcdc_early_resume(struct rk_lcdc_device_driver *dev_drv)
        memcpy(((u8*)lcdc_dev->preg) + 0x28,((u8*)&lcdc_dev->regbak) + 0x28, 0x74);
 
        spin_lock(&lcdc_dev->reg_lock);
+
+       if(dev_drv->cur_screen->dsp_lut)                        //resume dsp lut
+       {
+               LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(0));
+               LCDC_REG_CFG_DONE();
+
+               mdelay(25); //wait for dsp lut disabled
+               for(i=0;i<256;i++)
+               {
+                       v = dev_drv->cur_screen->dsp_lut[i];
+                       c = lcdc_dev->dsp_lut_addr_base+i;
+                       writel_relaxed(v,c);
+               }
+               LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(1));//enable dsp lut
+       }
        if(lcdc_dev->atv_layer_cnt)
        {
                LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
@@ -1104,6 +1158,40 @@ static irqreturn_t rk3066b_lcdc_isr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+
+static int rk3066b_set_dsp_lut(struct rk_lcdc_device_driver *dev_drv,int *lut)
+{
+       int i=0;
+       int __iomem *c;
+       int v;
+       int ret = 0;
+
+       struct rk3066b_lcdc_device *lcdc_dev =
+                               container_of(dev_drv,struct rk3066b_lcdc_device,driver);
+       LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(0));
+       LCDC_REG_CFG_DONE();
+       msleep(25);
+       if(dev_drv->cur_screen->dsp_lut)
+       {
+               for(i=0;i<256;i++)
+               {
+                       v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
+                       c = lcdc_dev->dsp_lut_addr_base+i;
+                       writel_relaxed(v,c);
+               }
+       }
+       else
+       {
+               dev_err(dev_drv->dev,"no buffer to backup lut data!\n");
+               ret =  -1;
+       }
+       LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(1));
+       LCDC_REG_CFG_DONE();
+
+       return ret;
+}
+
+
 static struct layer_par lcdc_layer[] = {
        [0] = {
                .name           = "win0",
@@ -1136,6 +1224,7 @@ static struct rk_lcdc_device_driver lcdc_driver = {
        .fps_mgr                = rk3066b_lcdc_fps_mgr,
        .fb_get_layer           = rk3066b_fb_get_layer,
        .fb_layer_remap         = rk3066b_fb_layer_remap,
+       .set_dsp_lut            = rk3066b_set_dsp_lut,
 };
 #ifdef CONFIG_PM
 static int rk3066b_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
@@ -1227,6 +1316,8 @@ static int __devinit rk3066b_lcdc_probe (struct platform_device *pdev)
        
        lcdc_dev->preg = (LCDC_REG*)lcdc_dev->reg_vir_base;
        printk("lcdc%d:reg_phy_base = 0x%08x,reg_vir_base:0x%p\n",pdev->id,lcdc_dev->reg_phy_base, lcdc_dev->preg);
+       lcdc_dev->dsp_lut_addr_base = (lcdc_dev->reg_vir_base+DSP_LUT_ADDR);
+
        lcdc_dev->driver.dev=&pdev->dev;
        lcdc_dev->driver.screen0 = screen;
 #if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)&& (defined(CONFIG_RK610_LVDS) || defined(CONFIG_RK616_LVDS))
old mode 100644 (file)
new mode 100755 (executable)
index d150b19..27c9247
@@ -477,6 +477,9 @@ typedef volatile struct tagLCDC_REG
     unsigned int MCU_BYPASS_RPORT;         //0x200 MCU BYPASS MODE, DATA Read Only Port
 } LCDC_REG, *pLCDC_REG;
 
+#define Win2_LUT_ADDR 0x400
+#define DSP_LUT_ADDR  0x800
+
 //roate
 #define        ROTATE_0                0
 #define        ROTATE_90               90
@@ -501,6 +504,7 @@ struct rk3066b_lcdc_device{
        u32 reg_phy_base;               // physical basic address of lcdc register
        u32 len;                        // physical map length of lcdc register
        spinlock_t  reg_lock;           //one time only one process allowed to config the register
+       int __iomem *dsp_lut_addr_base;
        bool clk_on;                    //if aclk or hclk is closed ,acess to register is not allowed
        u8 atv_layer_cnt;               //active layer counter,when  atv_layer_cnt = 0,disable lcdc