rk3188 lcdc:support_wait_frame_start_in_config_done
authoryxj <yxj@rock-chips.com>
Sat, 2 Feb 2013 09:32:48 +0000 (17:32 +0800)
committeryxj <yxj@rock-chips.com>
Sat, 2 Feb 2013 09:33:49 +0000 (17:33 +0800)
drivers/video/rockchip/lcdc/rk3188_lcdc.c
include/linux/rk_fb.h

index 78441a2a0939aa6df2eb42ff2a3c8a793a68de0f..8716fcb59b1ef8a01579ae8b17951f404ad0bb49 100644 (file)
@@ -825,6 +825,8 @@ static int rk3188_lcdc_ioctl(struct rk_lcdc_device_driver *dev_drv, unsigned int
        u32 panel_size[2];
        void __user *argp = (void __user *)arg;
        int enable;
+       unsigned long flags;
+       int timeout;
        switch(cmd)
        {
                case RK_FBIOGET_PANEL_SIZE:    //get panel size
@@ -834,7 +836,21 @@ static int rk3188_lcdc_ioctl(struct rk_lcdc_device_driver *dev_drv, unsigned int
                                return -EFAULT;
                        break;
                case RK_FBIOSET_CONFIG_DONE:
+                       if (copy_from_user(&(dev_drv->wait_fs),argp,sizeof(dev_drv->wait_fs)))
+                               return -EFAULT;
                        lcdc_cfg_done(lcdc_dev);
+                       if(dev_drv->wait_fs)
+                       {
+                               spin_lock_irqsave(&dev_drv->cpl_lock,flags);
+                               init_completion(&dev_drv->frame_done);
+                               spin_unlock_irqrestore(&dev_drv->cpl_lock,flags);
+                               timeout = wait_for_completion_timeout(&dev_drv->frame_done,msecs_to_jiffies(dev_drv->cur_screen->ft+5));
+                               if(!timeout&&(!dev_drv->frame_done.done))
+                               {
+                                       printk(KERN_ERR "wait for new frame start time out!\n");
+                                       return -ETIMEDOUT;
+                               }
+                       }
                        break;
                default:
                        break;
@@ -1227,14 +1243,12 @@ static irqreturn_t rk3188_lcdc_isr(int irq, void *dev_id)
        
        lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR, v_FS_INT_CLEAR(1));
 
-#if defined(WAIT_FOR_SYNC)
-       if(lcdc_dev->driver.num_buf < 3)  //three buffer ,no need to wait for sync
+       if(lcdc_dev->driver.wait_fs)  //three buffer ,no need to wait for sync
        {
                spin_lock(&(lcdc_dev->driver.cpl_lock));
                complete(&(lcdc_dev->driver.frame_done));
                spin_unlock(&(lcdc_dev->driver.cpl_lock));
        }
-#endif
        lcdc_dev->driver.vsync_info.timestamp = timestamp;
        wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
        
index 8c7982e73dca12fb0706f7c385e3ec9b0ef3bfb8..45e23f6b58406b356f053036e95ed1ef0965de05 100644 (file)
@@ -239,6 +239,7 @@ struct rk_lcdc_device_driver{
        spinlock_t  cpl_lock;                    //lock for completion  frame done
        int first_frame ;
        struct rk_fb_vsync       vsync_info;
+       int wait_fs;                            //wait for new frame start in kernel
        
        struct rk29fb_info *screen_ctr_info;
        int (*open)(struct rk_lcdc_device_driver *dev_drv,int layer_id,bool open);