Merge remote-tracking branch 'kernel-2.6.32/develop' into develop-2.6.36
[firefly-linux-kernel-4.4.55.git] / drivers / video / rk29_fb.c
old mode 100755 (executable)
new mode 100644 (file)
index 6ab2226..e36f6e2
@@ -243,7 +243,31 @@ typedef enum _TRSP_MODE
     TRSP_MASK,
     TRSP_INVAL
 } TRSP_MODE;
+#ifdef FB_WIMO_FLAG
+struct wimo_fb_info{
+       unsigned long bitperpixel;
+       unsigned long mode;
+       unsigned long xaff;
+       unsigned long yaff;
+       unsigned long xpos;
+       unsigned long ypos;
+       unsigned long xsize;
+       unsigned long ysize;
+       unsigned long src_y;
+       unsigned long src_uv;
+       unsigned long dst_width;
+       unsigned long dst_height;
+       //struct mutex fb_lock;
+       volatile unsigned long fb_lock;
 
+       
+};
+struct wimo_fb_info wimo_info;
+unsigned char* ui_buffer;
+unsigned char* ui_buffer_map;
+//unsigned char* overlay_buffer;
+//unsigned char* overlay_buffer_map;
+#endif
 
 struct platform_device *g_pdev = NULL;
 //static int win1fb_set_par(struct fb_info *info);
@@ -257,10 +281,13 @@ struct platform_device *g_pdev = NULL;
 #else
 #define CHK_SUSPEND(inf)
 #endif
+static DECLARE_WAIT_QUEUE_HEAD(fb0_wait_queue);     
+static volatile int idle_condition = 1;              //1:idel, 0:busy
 
 static DECLARE_WAIT_QUEUE_HEAD(wq);
 static int wq_condition = 0;
 static int wq_condition2 = 0;
+static int fb1_open_init = 0;
 #if ANDROID_USE_THREE_BUFS
 static int new_frame_seted = 1;
 #endif
@@ -270,6 +297,39 @@ static struct wake_lock idlelock; /* only for fb */
 static bool has_set_rotate; 
 static u32 last_yuv_phy[2] = {0,0};
 #endif
+int fb0_first_buff_bits = 32;
+int fb0_second_buff_bits = 32;
+int fb_compose_layer_count = 0;
+static BLOCKING_NOTIFIER_HEAD(rk29fb_notifier_list);
+int rk29fb_register_notifier(struct notifier_block *nb)
+{
+       int ret = 0;
+       if (g_pdev) {
+               struct rk29fb_inf *inf = platform_get_drvdata(g_pdev);
+               if (inf) {
+                       if (inf->cur_screen && inf->cur_screen->type == SCREEN_HDMI)
+                               nb->notifier_call(nb, RK29FB_EVENT_HDMI_ON, inf->cur_screen);
+                       if (inf->fb1 && inf->fb1->par) {
+                               struct win0_par *par = inf->fb1->par;
+                               if (par->refcount)
+                                       nb->notifier_call(nb, RK29FB_EVENT_FB1_ON, inf->cur_screen);
+                       }
+               }
+       }
+       ret = blocking_notifier_chain_register(&rk29fb_notifier_list, nb);
+
+       return ret;
+}
+
+int rk29fb_unregister_notifier(struct notifier_block *nb)
+{
+       return blocking_notifier_chain_unregister(&rk29fb_notifier_list, nb);
+}
+
+static int rk29fb_notify(struct rk29fb_inf *inf, unsigned long event)
+{
+       return blocking_notifier_call_chain(&rk29fb_notifier_list, event, inf->cur_screen);
+}
 
 int mcu_do_refresh(struct rk29fb_inf *inf)
 {
@@ -637,7 +697,7 @@ void load_screen(struct fb_info *info, bool initscreen)
     {
         printk(KERN_ERR ">>>>>> set lcdc dclk failed\n");
     }
-    
+    inf->fb0->var.pixclock = inf->fb1->var.pixclock = div_u64(1000000000000llu, clk_get_rate(inf->dclk));
     if(initscreen)
     {
         ret = clk_set_parent(inf->aclk, inf->aclk_parent);
@@ -974,11 +1034,14 @@ static int win0_blank(int blank_mode, struct fb_info *info)
     {
     case FB_BLANK_UNBLANK:
         LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE(1));
-       LcdWrReg(inf, REG_CFG_DONE, 0x01);
+           LcdWrReg(inf, REG_CFG_DONE, 0x01);
         break;
+    case FB_BLANK_NORMAL:
+         LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE(0));
+            break;
     default:
         LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE(0));
-       LcdWrReg(inf, REG_CFG_DONE, 0x01);
+           LcdWrReg(inf, REG_CFG_DONE, 0x01);
 #ifdef CONFIG_DDR_RECONFIG
        msleep(40);
 #endif
@@ -1019,21 +1082,22 @@ static int win0_set_par(struct fb_info *info)
 
        CHK_SUSPEND(inf);
 
-    if(((var->rotate == 270)||(var->rotate == 90) || (var->rotate == 180)) && (inf->video_mode))
+    if((var->rotate%360!=0)&& (inf->video_mode))
     {
       #ifdef CONFIG_FB_ROTATE_VIDEO  
-    //    if(xact > screen->x_res)
+        if(xact > screen->x_res)
         {
             xact = screen->x_res;       /* visible resolution       */
             yact = screen->y_res;
             xvir = screen->x_res;       /* virtual resolution       */
             yvir = screen->y_res;
-        }  // else   {            
-       //     xact = var->yres;               /* visible resolution       */
-       //     yact = var->xres;
-       //     xvir = var->yres_virtual;       /* virtual resolution       */
-       //     yvir = var->xres_virtual;
-      //  }
+        }   else   {            
+            xact = var->xres;               /* visible resolution       */
+            yact = var->yres;
+            xvir = var->xres_virtual;       /* virtual resolution       */
+            yvir = var->yres_virtual;
+                       printk("xact=%d yact =%d \n",xact,yact);
+        }
       #else //CONFIG_FB_ROTATE_VIDEO
         printk("LCDC not support rotate!\n");
         return -EINVAL;
@@ -1146,17 +1210,79 @@ static int win1_blank(int blank_mode, struct fb_info *info)
     {
     case FB_BLANK_UNBLANK:
         LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE, v_W1_ENABLE(1));
+        LcdWrReg(inf, REG_CFG_DONE, 0x01);
         break;
+    case FB_BLANK_NORMAL:
+         LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE, v_W1_ENABLE(0));
+            break;
     default:
         LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE, v_W1_ENABLE(0));
+        LcdWrReg(inf, REG_CFG_DONE, 0x01);
         break;
     }
-    LcdWrReg(inf, REG_CFG_DONE, 0x01);
+    
 
        mcu_refresh(inf);
     return 0;
 }
 
+
+#ifdef CONFIG_CLOSE_WIN1_DYNAMIC 
+static void win1_check_work_func(struct work_struct *work)
+{
+    struct rk29fb_inf *inf = platform_get_drvdata(g_pdev);
+    struct fb_info *fb0_inf = inf->fb0;
+     struct fb_var_screeninfo *var = &fb0_inf->var;
+    int i=0;
+    int *p = NULL;
+    int blank_data,total_data;
+    int format = 0;
+    u16 xres_virtual = fb0_inf->var.xres_virtual;      //virtual screen size
+    u16 xpos_virtual = fb0_inf->var.xoffset;           //visiable offset in virtual screen
+    u16 ypos_virtual = fb0_inf->var.yoffset;
+
+    int offset = 0;//(ypos_virtual*xres_virtual + xpos_virtual)*((inf->fb0_color_deepth || fb0_inf->var.bits_per_pixel==32)? 4:2)/4;  
+    switch(var->bits_per_pixel)
+    {
+        case 16: 
+            format = 1;
+            offset = (ypos_virtual*xres_virtual + xpos_virtual)*(inf->fb0_color_deepth ? 4:2);
+            if(ypos_virtual == 3*var->yres && inf->fb0_color_deepth)
+                offset -= var->yres * var->xres *2;
+            break;
+        default:
+            format = 0;
+            offset = (ypos_virtual*xres_virtual + xpos_virtual)*4;            
+            if(ypos_virtual >= 2*var->yres)
+            {
+                format = 1;
+                if(ypos_virtual == 3*var->yres)
+                {            
+                    offset -= var->yres * var->xres *2;
+                }
+            }
+            break;
+    }
+    p = (u32)fb0_inf->screen_base + offset; 
+    blank_data = (inf->fb0_color_deepth==32) ? 0xff000000 : 0;
+    total_data = fb0_inf->var.xres * fb0_inf->var.yres / (format+1);
+    
+   // printk("var->bits_per_pixel=%d,ypos_virtual=%d, var->yres=%d,offset=%d,total_data=%d\n",var->bits_per_pixel,ypos_virtual,var->yres,offset,total_data);
+    
+    for(i=0; i < total_data; i++)
+    {
+        if(*p++ != blank_data) 
+        {
+            //printk("win1 have no 0 data in %d, total %d\n",i,total_data);
+            return;
+        }            
+    }
+
+    win1_blank(FB_BLANK_POWERDOWN, fb0_inf);
+   // printk("%s close win1!\n",__func__);
+}
+static DECLARE_DELAYED_WORK(rk29_win1_check_work, win1_check_work_func);
+#endif
 static int win1_set_par(struct fb_info *info)
 {
     struct rk29fb_inf *inf = dev_get_drvdata(info->device);
@@ -1167,15 +1293,24 @@ static int win1_set_par(struct fb_info *info)
        u32 addr;
        u16 xres_virtual,xpos,ypos;
        u8 trspval,trspmode;
+ #ifdef CONFIG_CLOSE_WIN1_DYNAMIC   
+    cancel_delayed_work_sync(&rk29_win1_check_work);
+ #endif   
     if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
-        && !((screen->x_res>1280) && (var->bits_per_pixel == 32)))
+           #ifndef     CONFIG_FB_SCALING_OSD_1080P
+            && !((screen->x_res>1280) && (var->bits_per_pixel == 32))
+               #endif
+               )
     {
         hdmi_set_fbscale(info);
-    }else  if(((screen->x_res==1920) ))
-       {
+    }
+               #ifndef CONFIG_FB_SCALING_OSD_1080P
+               else  if(((screen->x_res==1920) ))
+    {
        if(hdmi_get_fbscale() < 100)
                        par->ypos -=screen->y_res * (100-hdmi_get_fbscale()) / 200;
        }
+               #endif
     //u32 offset=0, addr=0, map_size=0, smem_len=0;
     addr=0;
     xres_virtual = 0;      //virtual screen size
@@ -1189,11 +1324,14 @@ static int win1_set_par(struct fb_info *info)
     trspmode = TRSP_CLOSE;
     trspval = 0;
 
-    //fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+    fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
 
    #ifdef CONFIG_FB_SCALING_OSD
-    if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
-        && !((screen->x_res>1280) && (var->bits_per_pixel == 32)))
+    if(((screen->x_res != var->xres) || (screen->y_res != var->yres)) 
+        #ifndef        CONFIG_FB_SCALING_OSD_1080P
+            && (screen->x_res<=1280)
+               #endif
+               )
     {
         addr = fix->mmio_start + par->y_offset* hdmi_get_fbscale()/100;
         xres_virtual = screen->x_res* hdmi_get_fbscale()/100;      //virtual screen size
@@ -1204,7 +1342,7 @@ static int win1_set_par(struct fb_info *info)
         addr = fix->smem_start + par->y_offset;
         xres_virtual = var->xres_virtual;      //virtual screen size
     }
-    LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE|m_W1_FORMAT, v_W1_ENABLE(1)|v_W1_FORMAT(par->format));
+    LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE|m_W1_FORMAT, v_W1_ENABLE(fb1_open_init?0:1)|v_W1_FORMAT(par->format));
 
     xpos += (screen->left_margin + screen->hsync_len);
     ypos += (screen->upper_margin + screen->vsync_len);
@@ -1236,6 +1374,10 @@ static int win1_set_par(struct fb_info *info)
     }
 
        LcdWrReg(inf, REG_CFG_DONE, 0x01);
+    
+#ifdef CONFIG_CLOSE_WIN1_DYNAMIC 
+    schedule_delayed_work(&rk29_win1_check_work, msecs_to_jiffies(5000));
+#endif
 
     return 0;
 }
@@ -1250,8 +1392,11 @@ static int win1_pan( struct fb_info *info )
     #ifdef CONFIG_FB_SCALING_OSD
     struct rk29fb_screen *screen = inf->cur_screen;
     struct fb_var_screeninfo *var = &info->var;
-    if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
-        && !((screen->x_res>1280) && (var->bits_per_pixel == 32)))
+    if(((screen->x_res != var->xres) || (screen->y_res != var->yres)) 
+        #ifndef        CONFIG_FB_SCALING_OSD_1080P
+            && (screen->x_res<=1280)
+               #endif
+               )
     {
         addr = fix1->mmio_start + par->y_offset* hdmi_get_fbscale()/100;
     }
@@ -1310,7 +1455,7 @@ static int fb0_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
     }
 
     if( (var->xoffset+var->xres)>var->xres_virtual ||
-        (var->yoffset+var->yres)>var->yres_virtual )
+        (var->yoffset+var->yres)>var->yres_virtual*2 )
     {
         printk(">>>>>> fb0_check_var fail 2!!! \n");
         printk(">>>>>> (%d+%d)>%d || ", var->xoffset,var->xres,var->xres_virtual);
@@ -1352,9 +1497,12 @@ static int fb0_set_par(struct fb_info *info)
 #ifdef CONFIG_FB_SCALING_OSD
     struct rk29_ipp_req ipp_req;
     u32 dstoffset=0;
+       memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
 #endif
 
     fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
+       wait_event_interruptible(fb0_wait_queue, idle_condition);
+       idle_condition = 0;
 
     inf->setFlag = 0;
        CHK_SUSPEND(inf);
@@ -1368,6 +1516,11 @@ static int fb0_set_par(struct fb_info *info)
     {
     case 16:    // rgb565
         par->format = 1;
+         if( ypos_virtual == 0)
+            fb0_first_buff_bits = 16;
+        else
+            fb0_second_buff_bits = 16;
+
         //fix->line_length = 2 * xres_virtual;
         fix->line_length = (inf->fb0_color_deepth ? 4:2) * xres_virtual;   //32bit and 16bit change
 
@@ -1377,17 +1530,38 @@ static int fb0_set_par(struct fb_info *info)
         ipp_req.dst0.fmt = IPP_RGB_565;
         #endif
         offset = (ypos_virtual*xres_virtual + xpos_virtual)*(inf->fb0_color_deepth ? 4:2);
+        if(ypos_virtual == 3*var->yres && inf->fb0_color_deepth)
+            offset -= var->yres * var->xres *2;
         break;
     case 32:    // rgb888
     default:
         par->format = 0;
+         if( ypos_virtual == 0)
+            fb0_first_buff_bits = 32;
+        else
+            fb0_second_buff_bits = 32;
         fix->line_length = 4 * xres_virtual;
         #ifdef CONFIG_FB_SCALING_OSD
-        dstoffset = ((ypos_virtual*screen->y_res/var->yres) *screen->x_res + (xpos_virtual*screen->x_res)/var->xres )*4;
+        dstoffset = ((ypos_virtual*screen->y_res/var->yres) *screen->x_res + (xpos_virtual*screen->x_res)/var->xres )*4;       
+
         ipp_req.src0.fmt = IPP_XRGB_8888;
         ipp_req.dst0.fmt = IPP_XRGB_8888;
         #endif
         offset = (ypos_virtual*xres_virtual + xpos_virtual)*4;
+        
+        if(ypos_virtual >= 2*var->yres)
+        {
+            par->format = 1;
+            #ifdef CONFIG_FB_SCALING_OSD
+            dstoffset = (((ypos_virtual-2*var->yres)*screen->y_res/var->yres) *screen->x_res + (xpos_virtual*screen->x_res)/var->xres )*4;
+            ipp_req.src0.fmt = IPP_RGB_565;
+            ipp_req.dst0.fmt = IPP_RGB_565;
+            #endif
+            if(ypos_virtual == 3*var->yres)
+            {            
+                offset -= var->yres * var->xres *2;
+            }
+        }
         break;
     }
 
@@ -1414,8 +1588,11 @@ static int fb0_set_par(struct fb_info *info)
     if(inf->video_mode == 1)
     {
         #ifdef CONFIG_FB_SCALING_OSD
-        if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
-        && !((screen->x_res>1280) && (var->bits_per_pixel == 32)))
+        if(((screen->x_res != var->xres) || (screen->y_res != var->yres)) 
+               #ifndef CONFIG_FB_SCALING_OSD_1080P
+            && (screen->x_res<=1280)
+               #endif
+               )
         {
             par->xpos = 0;
             par->ypos = 0;
@@ -1458,6 +1635,8 @@ static int fb0_set_par(struct fb_info *info)
         win0_set_par(info);
     }
     inf->setFlag = 1;
+       idle_condition = 1;
+       wake_up_interruptible_sync(&fb0_wait_queue);
     return 0;
 }
 
@@ -1476,6 +1655,7 @@ static int fb0_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
     struct fb_fix_screeninfo *fix = &info->fix;
     struct rk29_ipp_req ipp_req;
     u32 dstoffset = 0;
+       memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
    #endif
        //fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
 
@@ -1496,6 +1676,8 @@ static int fb0_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
         ipp_req.dst0.fmt = IPP_RGB_565;
         #endif
         offset = (ypos_virtual*var1->xres_virtual + xpos_virtual)*(inf->fb0_color_deepth ? 4:2);
+        if(ypos_virtual == 3*var->yres && inf->fb0_color_deepth)
+            offset -= var->yres * var->xres *2;
         break;
     case 32:    // rgb888
         #ifdef CONFIG_FB_SCALING_OSD
@@ -1504,6 +1686,19 @@ static int fb0_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
         ipp_req.dst0.fmt = IPP_XRGB_8888;
         #endif
         offset = (ypos_virtual*var1->xres_virtual + xpos_virtual)*4;
+        if(ypos_virtual >= 2*var->yres)
+        {
+            par->format = 1;
+            #ifdef CONFIG_FB_SCALING_OSD
+               dstoffset = (((ypos_virtual-2*var->yres)*screen->y_res/var->yres) *screen->x_res + (xpos_virtual*screen->x_res)/var->xres )*4;
+            ipp_req.src0.fmt = IPP_RGB_565;
+            ipp_req.dst0.fmt = IPP_RGB_565;
+            #endif
+            if(ypos_virtual == 3*var->yres)
+            {            
+                offset -= var->yres * var->xres *2;
+            }
+        }
         break;
     default:
         return -EINVAL;
@@ -1512,8 +1707,11 @@ static int fb0_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
     if(inf->video_mode == 1)
     {
         #ifdef CONFIG_FB_SCALING_OSD
-        if(((screen->x_res != var->xres) || (screen->y_res != var->yres))
-        && !((screen->x_res>1280) && (var->bits_per_pixel == 32)))
+        if(((screen->x_res != var->xres) || (screen->y_res != var->yres)) 
+        #ifndef        CONFIG_FB_SCALING_OSD_1080P
+            && (screen->x_res<=1280)
+               #endif
+               )
         {
             par->y_offset = dstoffset;
 
@@ -1557,6 +1755,184 @@ static int fb0_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
     return 0;
 }
 
+#ifdef FB_WIMO_FLAG
+unsigned long temp_vv;
+static int frame_num = 0;
+static int wimo_set_buff(struct fb_info *info,unsigned long *temp)
+{
+       struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+
+       ui_buffer = temp[0];
+       ui_buffer_map = ioremap(temp[0],temp[1]);
+       if(ui_buffer_map == NULL)
+       {
+               printk("can't map a buffer for ui\n");
+               return -EFAULT;
+       }
+
+       printk("ui_buffer %x  ",ui_buffer_map);
+       memset(&wimo_info,0,sizeof(wimo_info) );
+      wimo_info.mode = inf->video_mode;
+//     wimo_info.bitperpixel = var->bits_per_pixel;            
+    
+
+       wimo_info.dst_width = (temp[2] + 15) & 0xfff0;
+       wimo_info.dst_height = (temp[3] + 15) & 0xfff0;
+}
+static int wimo_get_buff(struct fb_info *info)
+{
+       
+       struct rk29_ipp_req overlay_req;
+       struct rk29_ipp_req overlay_req_1;
+       struct rk29fb_inf *inf = dev_get_drvdata(info->device);
+       int ret;
+       memset(&overlay_req, 0 , sizeof(overlay_req));
+       memset(&overlay_req_1, 0 , sizeof(overlay_req_1));
+       
+       if(inf->video_mode == 0 )
+       {
+               struct win0_par *par = info->par;
+               wimo_info.xpos = 0;
+               wimo_info.ypos = 0;
+               wimo_info.xsize = 0;
+               wimo_info.ysize = 0;
+               wimo_info.mode = 0;
+               if(par->format == 1)
+                       wimo_info.bitperpixel = 16;
+               else
+                       wimo_info.bitperpixel =32;// wimo_info.bitperpixel_fb1;
+               overlay_req.src0.YrgbMst = info->fix.smem_start + par->y_offset;//info->screen_base + par->y_offset;//info_buffer[8];
+               overlay_req.src0.CbrMst = info->fix.smem_start + par->y_offset + wimo_info.dst_width * wimo_info.dst_height;//dst_width*dst_height;//+ par->y_offset + dst_width*dst_height;//info_buffer[9];
+               overlay_req.src0.w = wimo_info.dst_width ;//dst_width;//info_buffer[2];
+               overlay_req.src0.h = wimo_info.dst_height ;//dst_height;//info_buffer[3];
+               overlay_req.src0.fmt = (wimo_info.bitperpixel == 16) ? 1 : 0;//3;
+               overlay_req.dst0.YrgbMst = ui_buffer;//overlay_buffer + info_buffer[4] + info_buffer[5] * dst_width;
+               overlay_req.dst0.CbrMst = ui_buffer + wimo_info.dst_width * wimo_info.dst_height;//dst_width*dst_height;//(unsigned char*) overlay_buffer + dst_width*dst_height +info_buffer[4] + (  info_buffer[5] * dst_width) / 2;// info_buffer[6] * info_buffer[7];
+               overlay_req.dst0.w = wimo_info.dst_width ;//dst_width;//info_buffer[6];
+               overlay_req.dst0.h = wimo_info.dst_height ;//dst_height;//info_buffer[7];
+               overlay_req.dst0.fmt = (wimo_info.bitperpixel== 16) ? 1 : 0;//3;3;
+               overlay_req.deinterlace_enable = 0;
+               overlay_req.timeout = 1000000;
+               overlay_req.src_vir_w = wimo_info.dst_width ;//dst_width;//info_buffer[2];
+               overlay_req.dst_vir_w = wimo_info.dst_width ;//dst_width;
+               overlay_req.flag = IPP_ROT_0;
+               ipp_blit_sync(&overlay_req);
+               
+               ret = 0;
+       }       
+       else
+       {
+
+               int err = 0;
+               static int wimo_time = 0;
+               unsigned long *overlay_buffer_map_temp;
+               unsigned long *map_temp;
+               unsigned long sign_memset = 0;
+               struct fb_var_screeninfo *var = &inf->fb1->var;
+               struct win0_par *par = inf->fb1->par;
+               wimo_info.mode = 1;
+       //      printk("overlay setbuffer in\n");
+       //      mutex_lock(&wimo_info.fb_lock);
+               wimo_info.fb_lock = 1;
+               {
+                       wimo_info.xaff = var->xres;
+                       wimo_info.yaff = var->yres;
+                       if((wimo_info.xpos != par->xpos) ||(wimo_info.ypos != par->ypos)||(wimo_info.xsize != par->xsize) ||(wimo_info.ysize != par->ysize))
+                       {
+                               wimo_info.xpos = par->xpos;
+                               wimo_info.ypos = par->ypos;
+                               wimo_info.xsize = par->xsize;
+                               wimo_info.ysize = par->ysize;
+                               sign_memset = 1;
+                               memset(ui_buffer_map,0,wimo_info.dst_height * wimo_info.dst_width);//dst_width*dst_height);
+                               memset(ui_buffer_map + wimo_info.dst_height * wimo_info.dst_width, 0x80,wimo_info.dst_height * wimo_info.dst_width / 2);//dst_width*dst_height,0x80,dst_width*dst_height/2);
+                               printk("wimo_info.xpos %d wimo_info.ypos %d wimo_info.xsize %d wimo_info.ysize %d\n",wimo_info.xpos, wimo_info.ypos, wimo_info.xsize, wimo_info.ysize );
+                       }
+               }
+               //printk("wimo_info.xpos %d wimo_info.ypos %d wimo_info.xsize %d wimo_info.ysize %d\n",wimo_info.xpos, wimo_info.ypos, wimo_info.xsize, wimo_info.ysize );
+               if(wimo_info.xaff * 3 < wimo_info.xsize || wimo_info.yaff * 3 < wimo_info.ysize)// 3time or bigger scale up
+               {
+                       unsigned long mid_width, mid_height;
+                       struct rk29_ipp_req overlay_req_1;
+                       if(wimo_info.xaff * 3 < wimo_info.xsize)
+                               mid_width = wimo_info.xaff * 3;
+                       else
+                               mid_width = wimo_info.xsize;
+                       
+                       if(wimo_info.yaff * 3 < wimo_info.ysize)
+                               mid_height =  wimo_info.yaff * 3;
+                       else
+                               mid_height = wimo_info.ysize;
+                       overlay_req.src0.YrgbMst = wimo_info.src_y;//info_buffer[8];
+                       overlay_req.src0.CbrMst = wimo_info.src_uv;//info_buffer[9];
+                       overlay_req.src0.w = wimo_info.xaff;// info_buffer[2];
+                       overlay_req.src0.h = wimo_info.yaff;// info_buffer[3];
+                       overlay_req.src0.fmt = 3;
+                       overlay_req.dst0.YrgbMst = ui_buffer + 2048000 ;//info_buffer[4] + info_buffer[5] * dst_width;   //С³ß´çƬԴÐèÒª2´Î·Å´ó£¬ËùÒÔ½«bufferµÄºó°ë¶ÎÓÃÓÚ»º´æ
+                       overlay_req.dst0.CbrMst = (unsigned char*) ui_buffer + mid_height * mid_width + 2048000;
+               
+                       overlay_req.dst0.w = mid_width;//info_buffer[6];
+                       overlay_req.dst0.h = mid_height;//info_buffer[7];
+                       overlay_req.dst0.fmt = 3;
+                       overlay_req.timeout = 100000;
+                       overlay_req.src_vir_w = wimo_info.xaff;//info_buffer[2];
+                       overlay_req.dst_vir_w = mid_width;//dst_width;
+                       overlay_req.flag = IPP_ROT_0;
+
+                       overlay_req_1.src0.YrgbMst = ui_buffer + 2048000;
+                       overlay_req_1.src0.CbrMst = (unsigned char*) ui_buffer + mid_height * mid_width + 2048000;
+                       overlay_req_1.src0.w = mid_width;
+                       overlay_req_1.src0.h = mid_height;// info_buffer[3];
+                       overlay_req_1.src0.fmt = 3;
+                       overlay_req_1.dst0.YrgbMst = ui_buffer + ((wimo_info.xpos + 1)&0xfffe) + wimo_info.ypos * wimo_info.dst_width;//info_buffer[4] + info_buffer[5] * dst_width;
+                       overlay_req_1.dst0.CbrMst =(unsigned char*) ui_buffer + wimo_info.dst_width * wimo_info.dst_height + ((wimo_info.xpos + 1)&0xfffe) + ( wimo_info.ypos  / 2)* wimo_info.dst_width ;
+                       
+                       overlay_req_1.dst0.w = wimo_info.xsize;//info_buffer[6];
+                       overlay_req_1.dst0.h = wimo_info.ysize;//info_buffer[7];
+                       overlay_req_1.dst0.fmt = 3;
+                       overlay_req_1.timeout = 100000;
+                       overlay_req_1.src_vir_w = mid_width;//info_buffer[2];
+                       overlay_req_1.dst_vir_w = wimo_info.dst_width;//dst_width;
+                       overlay_req_1.flag = IPP_ROT_0;
+                       
+
+                       err = ipp_blit_sync(&overlay_req);
+                       dmac_flush_range(ui_buffer_map,ui_buffer_map + wimo_info.dst_height * wimo_info.dst_width * 3/2);//dst_width*dst_height*3/2);
+                       err = ipp_blit_sync(&overlay_req_1);
+       
+               }
+               else
+               {
+                       overlay_req.src0.YrgbMst = wimo_info.src_y;//info_buffer[8];
+                       overlay_req.src0.CbrMst = wimo_info.src_uv;//info_buffer[9];
+                       overlay_req.src0.w = wimo_info.xaff;// info_buffer[2];
+                       overlay_req.src0.h = wimo_info.yaff;// info_buffer[3];
+                       overlay_req.src0.fmt = 3;
+                       overlay_req.dst0.YrgbMst = ui_buffer + ((wimo_info.xpos + 1)&0xfffe) + wimo_info.ypos * wimo_info.dst_width;//info_buffer[4] + info_buffer[5] * dst_width;
+                       overlay_req.dst0.CbrMst =(unsigned char*) ui_buffer + wimo_info.dst_width * wimo_info.dst_height + ((wimo_info.xpos + 1)&0xfffe) + ( wimo_info.ypos  / 2)* wimo_info.dst_width ;
+                       
+                       overlay_req.dst0.w = wimo_info.xsize;//wimo_info.xsize;//wimo_info.xaff;// wimo_info.xsize;//info_buffer[6];
+                       overlay_req.dst0.h = (wimo_info.ysize + 1) & 0xfffe;//(wimo_info.ysize + 1) & 0xfffe;//wimo_info.yaff;//(wimo_info.ysize + 1) & 0xfffe;//info_buffer[7];
+                       overlay_req.dst0.fmt = 3;
+                       overlay_req.timeout = 100000;
+                       overlay_req.src_vir_w = wimo_info.xaff;//info_buffer[2];
+                       overlay_req.dst_vir_w = wimo_info.dst_width;//wimo_info.dst_width;//wimo_info.yaff;//wimo_info.dst_width;//dst_width;
+                       overlay_req.flag = IPP_ROT_0;
+                       
+                       dmac_flush_range(ui_buffer_map,ui_buffer_map + wimo_info.dst_height * wimo_info.dst_width * 3/2);//dst_width*dst_height*3/2);
+                       err = ipp_blit_sync(&overlay_req);
+               
+               }
+       //      printk("overlay setbuffer exit\n");
+               ret = 1;
+               wimo_info.fb_lock = 0;
+       }
+       
+               
+       return ret;
+}
+#endif
 static int fb0_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 {
     struct rk29fb_inf *inf = dev_get_drvdata(info->device);
@@ -1577,6 +1953,25 @@ static int fb0_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
         inf->fb0_color_deepth = arg;
 
            break;
+       case FBIOGET_16OR32:
+           return  inf->fb0_color_deepth;
+       case FBIOGET_IDLEFBUff_16OR32:
+        if(info->var.yoffset == 0)
+        {
+            return fb0_second_buff_bits;
+        }
+        else
+        {
+            return fb0_first_buff_bits;
+        }
+    case FBIOSET_COMPOSE_LAYER_COUNTS:
+        fb_compose_layer_count = arg;
+        break;
+
+    case FBIOGET_COMPOSE_LAYER_COUNTS:
+        
+        return fb_compose_layer_count;
+        
        case FBIOPUT_FBPHYADD:
         return info->fix.smem_start;
     case FBIOGET_OVERLAY_STATE:
@@ -1620,7 +2015,7 @@ static int fb0_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
                {
             u32 panel_size[2];
                        //struct rk29fb_inf *inf = dev_get_drvdata(info->device);
-             if(inf->fb1->var.rotate == 270) {
+             if((inf->fb1->var.rotate &0x1ff ) == 270) {
                 panel_size[0] = inf->cur_screen->y_res; //inf->cur_screen->y_res; change for hdmi video size
                 panel_size[1] = inf->cur_screen->x_res;
             } else {
@@ -1636,6 +2031,52 @@ static int fb0_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
             if(copy_to_user((void*)arg, &en, 4))  return -EFAULT;
             break;
                }
+#ifdef FB_WIMO_FLAG
+       case FB0_IOCTL_SET_BUF:
+               {
+                       unsigned long temp[4];
+                       copy_from_user(temp, (void*)arg, 20);
+                       wimo_set_buff( info,temp);
+                       
+               }
+               break;
+       case FB0_IOCTL_CLOSE_BUF:
+               {
+                       if(ui_buffer != NULL && ui_buffer_map !=NULL )
+                       {
+                               iounmap(ui_buffer_map);
+                               ui_buffer_map = 0;
+                               ui_buffer = 0;
+                               memset(&wimo_info,0,sizeof(wimo_info));
+                       }
+                       else
+                               printk("somethint wrong with wimo in close");
+                               
+               }
+               break;
+       
+       case FB0_IOCTL_COPY_CURBUF:
+               {
+                       unsigned long temp_data[3];
+                       copy_from_user(&temp_vv, (void*)arg, 4);
+                       if(ui_buffer != NULL && ui_buffer_map !=NULL )
+                       {
+                               temp_data[1] = wimo_get_buff(info);
+                               temp_data[0] = wimo_info.bitperpixel;
+                               
+                       }
+                       else
+                       {
+                               temp_data[1] = 1;
+                               temp_data[0] = wimo_info.bitperpixel;
+                               printk("somethint wrong with wimo in getbuf");
+                       }
+                       temp_data[2] = frame_num++;
+                       //printk("FB0_IOCTL_COPY_CURBUF %d %d %d\n",temp_data[0],temp_data[1],temp_data[2]);
+                       copy_to_user((void*)arg, &temp_data, 12);
+                       break;
+               }
+#endif
    default:
         break;
     }
@@ -1665,7 +2106,7 @@ static int fb1_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        struct hdmi *hdmi = get_hdmi_struct(0);
 #endif
 
-    if((var->rotate == 270)||(var->rotate == 90)) {
+    if((var->rotate & 0x1ff) == 90 ||(var->rotate &0x1ff)== 270) {
       #ifdef CONFIG_FB_ROTATE_VIDEO
         xlcd = screen->y_res;
         ylcd = screen->x_res;
@@ -1757,7 +2198,7 @@ static int fb1_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
         return -EINVAL;
     }
 
-    if((var->rotate == 270)||(var->rotate == 90))
+    if((var->rotate & 0x1ff ) == 90 ||(var->rotate & 0x1ff ) == 270)
      {
          yres = var->xres;
      }
@@ -1820,9 +2261,8 @@ static int fb1_set_par(struct fb_info *info)
    // u32 uv_addr = var->reserved[4];
 
     fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
-
-       CHK_SUSPEND(inf);
-    if((var->rotate == 270)||(var->rotate == 90))
+       CHK_SUSPEND(inf);
+    if((var->rotate & 0x1ff ) == 90 || (var->rotate & 0x1ff ) == 270)
     {
         #ifdef CONFIG_FB_ROTATE_VIDEO
         xpos = (var->nonstd>>20) & 0xfff;      //visiable pos in panel
@@ -1924,7 +2364,7 @@ static int fb1_set_par(struct fb_info *info)
                struct rk29_ipp_req ipp_req;
                static u32 dstoffset = 0;
                static int fb_index = 0;
-               
+               memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
                yuv_phy[0] = last_yuv_phy[0];
                yuv_phy[1] = last_yuv_phy[1];
                yuv_phy[0] += par->y_offset;
@@ -1935,6 +2375,7 @@ static int fb1_set_par(struct fb_info *info)
         if(var->rotate%360 != 0)
         #endif
                        {
+                #ifdef CONFIG_FB_ROTATE_VIDEO 
                                dstoffset = (dstoffset+1)%2;
                                ipp_req.src0.fmt = 3;
                                ipp_req.src0.YrgbMst = yuv_phy[0];
@@ -1945,35 +2386,115 @@ static int fb1_set_par(struct fb_info *info)
                                ipp_req.src_vir_w= (var->xres + 15) & (~15);
                                ipp_req.dst_vir_w=screen->x_res;
 
-                               ipp_req.dst0.fmt = 3;
-                               ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
-                               ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
-                               //   if(var->xres > screen->x_res)
-                               //   {
-                                       ipp_req.dst0.w = var->xres;
-                                       ipp_req.dst0.h = var->yres;
-                               //  }   else    {
-                               //        ipp_req.dst0.w = var->yres;
-                               //        ipp_req.dst0.h = var->xres;
-                               //   }
-                               //ipp_req.src_vir_w = ipp_req.src0.w;
-                               //ipp_req.dst_vir_w = ipp_req.dst0.w;
+                ipp_req.dst0.fmt = 3;
+                               #ifdef CONFIG_FB_MIRROR_X_Y
+                               if((var->rotate & 0x1ff)!=0 &&(var->rotate&(X_MIRROR|Y_MIRROR))!= 0 )
+                               {
+                               ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*4;
+                               ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*5;
+                                }
+                               else
+                               {
+                                       ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
+                                       ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
+
+                               }
+                               if(var->xres > screen->x_res)
+                                  {
+                                       ipp_req.dst0.w = screen->x_res;
+                                       ipp_req.dst0.h = screen->y_res;
+                                 }   else      {
+                                         ipp_req.dst0.w = var->xres;
+                                         ipp_req.dst0.h = var->yres;
+                                  }
+                                ipp_req.dst_vir_w = (ipp_req.dst0.w + 15) & (~15);
                                ipp_req.timeout = 100;
-                               if(var->rotate == 90)
+                               if((var->rotate & 0x1ff) == 90)
                                        ipp_req.flag = IPP_ROT_90;
-                else if (var->rotate == 180)
+                else if ((var->rotate & 0x1ff) == 180)
                                        ipp_req.flag = IPP_ROT_180;
-                               else if(var->rotate == 270)
+                               else if((var->rotate & 0x1ff) == 270)
                                        ipp_req.flag = IPP_ROT_270;
+                               else if((var->rotate & X_MIRROR) == X_MIRROR )
+                                       ipp_req.flag = IPP_ROT_X_FLIP;
+                               else if((var->rotate & Y_MIRROR) == Y_MIRROR)
+                                       ipp_req.flag = IPP_ROT_Y_FLIP;
                                //ipp_do_blit(&ipp_req);
                                ipp_blit_sync(&ipp_req);
-                               fbprintk("yaddr=0x%x,uvaddr=0x%x\n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
                                yuv_phy[0] = ipp_req.dst0.YrgbMst;
-                               yuv_phy[1] = ipp_req.dst0.CbrMst;        
-                               fix->smem_start = yuv_phy[0];
-                               fix->mmio_start = yuv_phy[1];
-                       }
-               else
+                               yuv_phy[1] = ipp_req.dst0.CbrMst;
+                               if((var->rotate & 0x1ff)!=0 &&(var->rotate&(X_MIRROR|Y_MIRROR))!= 0 )
+                               {
+                                       memset(&ipp_req,0,sizeof(struct rk29_ipp_req));
+                                       
+                                       if((var->rotate & X_MIRROR) == X_MIRROR)
+                                               ipp_req.flag = IPP_ROT_X_FLIP;
+                                       else if((var->rotate & Y_MIRROR) == Y_MIRROR)
+                                               ipp_req.flag = IPP_ROT_Y_FLIP;
+                                       else 
+                                               printk(">>>>>> %d rotate is not support!\n",var->rotate);
+                                       
+                                 if(var->xres > screen->x_res)
+                                  {
+                                       ipp_req.dst0.w = screen->x_res;
+                                       ipp_req.dst0.h = screen->y_res;
+                                 }   else      {
+                                         ipp_req.dst0.w = var->xres;
+                                         ipp_req.dst0.h = var->yres;
+                                  }
+                                       ipp_req.src0.fmt = 3;
+                                       ipp_req.src0.YrgbMst = yuv_phy[0];
+                                       ipp_req.src0.CbrMst = yuv_phy[1];
+                                       ipp_req.src0.w = ipp_req.dst0.w;
+                                       ipp_req.src0.h = ipp_req.dst0.h;
+                               
+                                       ipp_req.src_vir_w= (ipp_req.dst0.w + 15) & (~15);
+                                       ipp_req.dst_vir_w= (ipp_req.dst0.w + 15) & (~15);
+
+                                       ipp_req.dst0.fmt = 3;
+                                       ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
+                                       ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
+
+                                       ipp_req.timeout = 100;
+                                       ipp_blit_sync(&ipp_req);
+                                       yuv_phy[0] = ipp_req.dst0.YrgbMst;
+                                       yuv_phy[1] = ipp_req.dst0.CbrMst;
+                       }
+                fbprintk("yaddr=0x%x,uvaddr=0x%x\n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
+                               #else
+                               ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
+                ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
+                if(var->xres > screen->x_res)
+                {
+                    ipp_req.dst0.w = screen->x_res;
+                    ipp_req.dst0.h = screen->y_res;
+                }   else  {
+                                       ipp_req.dst0.w = var->xres;
+                                       ipp_req.dst0.h = var->yres;
+
+                }
+                ipp_req.dst_vir_w = (ipp_req.dst0.w + 15) & (~15);
+                ipp_req.timeout = 100;
+                if(var->rotate == 90)
+                    ipp_req.flag = IPP_ROT_90;
+                else if(var->rotate == 180)
+                    ipp_req.flag = IPP_ROT_180;
+                else if(var->rotate == 270)
+                    ipp_req.flag = IPP_ROT_270;
+                //ipp_do_blit(&ipp_req);
+                ipp_blit_sync(&ipp_req);
+                               
+                fbprintk("yaddr=0x%x,uvaddr=0x%x\n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
+                yuv_phy[0] = ipp_req.dst0.YrgbMst;
+                yuv_phy[1] = ipp_req.dst0.CbrMst; 
+                               #endif
+                fix->smem_start = yuv_phy[0];
+                fix->mmio_start = yuv_phy[1];
+                #else //CONFIG_FB_ROTATE_VIDEO
+                printk("LCDC not support rotate!\n");
+                #endif
+            }
+            else
                        {
                        
                                fix->smem_start = yuv_phy[0];
@@ -2019,6 +2540,7 @@ int fb1_open(struct fb_info *info, int user)
 {
     struct rk29fb_inf *inf = dev_get_drvdata(info->device);
     struct win0_par *par = info->par;
+       struct rk29fb_screen *screen = inf->cur_screen;
 
     fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
 
@@ -2037,9 +2559,12 @@ int fb1_open(struct fb_info *info, int user)
         return -EACCES;
     } else {
         par->refcount++;
+        win0_blank(FB_BLANK_NORMAL, info);
+               if(screen->x_res>1280)
+               fb1_open_init=1;
         fb0_set_par(inf->fb0);
-        fb0_pan_display(&inf->fb0->var, inf->fb0);
-        win0_blank(FB_BLANK_POWERDOWN, info);
+        fb1_open_init=0;
+           rk29fb_notify(inf, RK29FB_EVENT_FB1_ON);
         return 0;
     }
 }
@@ -2060,12 +2585,10 @@ int fb1_release(struct fb_info *info, int user)
         inf->video_mode = 0;
         par->par_seted = 0;
         par->addr_seted = 0;
-        //win0_blank(FB_BLANK_POWERDOWN, info);
-        fb0_set_par(inf->fb0);
-        fb0_pan_display(&inf->fb0->var, inf->fb0);
-        win1_blank(FB_BLANK_POWERDOWN, info);
-        // wait for lcdc stop access memory
-        //msleep(50);
+        win1_blank(FB_BLANK_NORMAL, info);
+
+        //if(inf->cur_screen->type != SCREEN_HDMI)
+            fb0_set_par(inf->fb0);
 
         // unmap memory
         info->screen_base = 0;
@@ -2073,6 +2596,10 @@ int fb1_release(struct fb_info *info, int user)
         info->fix.smem_len = 0;
                // clean the var param
                memset(var0, 0, sizeof(struct fb_var_screeninfo));
+           rk29fb_notify(inf, RK29FB_EVENT_FB1_OFF);
+        #ifdef CONFIG_CLOSE_WIN1_DYNAMIC   
+         cancel_delayed_work_sync(&rk29_win1_check_work);
+        #endif  
     }
 
     return 0;
@@ -2090,7 +2617,7 @@ static int fb1_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
      struct rk29fb_screen *screen = inf->cur_screen;
      struct rk29_ipp_req ipp_req;
      static u32 dstoffset = 0;
-     
+    memset(&ipp_req, 0, sizeof(struct rk29_ipp_req)); 
 #endif
 
        fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
@@ -2103,7 +2630,7 @@ static int fb1_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
     case FB1_IOCTL_GET_PANEL_SIZE:    //get panel size
         {
             u32 panel_size[2];
-             if((var->rotate == 270)||(var->rotate == 90)) {
+             if((var->rotate & 0x1ff) == 270 ||(var->rotate & 0x1ff) == 90) {
                 panel_size[0] = inf->panel1_info.y_res; //inf->cur_screen->y_res; change for hdmi video size
                 panel_size[1] = inf->panel1_info.x_res;
             } else {
@@ -2118,6 +2645,14 @@ static int fb1_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
     case FB1_IOCTL_SET_YUV_ADDR:    //set y&uv address to register direct
         {
             u32 yuv_phy[2];
+#ifdef FB_WIMO_FLAG
+       //      printk("FB1_IOCTL_SET_YUV_ADDR1 \n");
+       //      while(wimo_info.fb_lock)
+       //              {
+       //              msleep(10);
+       //              }
+       //      printk("FB1_IOCTL_SET_YUV_ADDR 2\n");
+#endif
             if (copy_from_user(yuv_phy, argp, 8))
                            return -EFAULT;
 #ifdef CONFIG_FB_ROTATE_VIDEO 
@@ -2132,6 +2667,11 @@ static int fb1_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
             fix0->mmio_start = yuv_phy[1];
             yuv_phy[0] += par->y_offset;
             yuv_phy[1] += par->c_offset;
+#ifdef FB_WIMO_FLAG
+             wimo_info.src_y = yuv_phy[0]; 
+             wimo_info.src_uv = yuv_phy[1]; 
+               
+#endif
          
             #if 0
                if((var->rotate == 90) ||(var->rotate == 270))
@@ -2144,24 +2684,99 @@ static int fb1_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
                 ipp_req.src0.fmt = 3;
                 ipp_req.src0.YrgbMst = yuv_phy[0];
                 ipp_req.src0.CbrMst = yuv_phy[1];
-                 ipp_req.src0.w = var->xres ;
+                   ipp_req.src0.w = var->xres ;
                 ipp_req.src0.h = var->yres ;
-                ipp_req.src_vir_w= (var->xres + 15) & (~15);
-                ipp_req.dst_vir_w=screen->x_res;
+                       ipp_req.src_vir_w= (var->xres + 15) & (~15);
+                       ipp_req.dst_vir_w=screen->x_res;
 
                 ipp_req.dst0.fmt = 3;
-                ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
+                               #ifdef CONFIG_FB_MIRROR_X_Y
+                               if((var->rotate & 0x1ff)!=0 &&(var->rotate&(X_MIRROR|Y_MIRROR))!= 0 )
+                               {
+                               ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*4;
+                               ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*5;
+                                }
+                               else
+                               {
+                                       ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
+                                       ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
+
+                               }
+                               if(var->xres > screen->x_res)
+                                  {
+                                       ipp_req.dst0.w = screen->x_res;
+                                       ipp_req.dst0.h = screen->y_res;
+                                 }   else      {
+                                         ipp_req.dst0.w = var->xres;
+                                         ipp_req.dst0.h = var->yres;
+                                  }
+                                ipp_req.dst_vir_w = (ipp_req.dst0.w + 15) & (~15);
+                               ipp_req.timeout = 100;
+                               if((var->rotate & 0x1ff) == 90)
+                                       ipp_req.flag = IPP_ROT_90;
+                else if ((var->rotate & 0x1ff) == 180)
+                                       ipp_req.flag = IPP_ROT_180;
+                               else if((var->rotate & 0x1ff) == 270)
+                                       ipp_req.flag = IPP_ROT_270;
+                               else if((var->rotate & X_MIRROR) == X_MIRROR )
+                                       ipp_req.flag = IPP_ROT_X_FLIP;
+                               else if((var->rotate & Y_MIRROR) == Y_MIRROR)
+                                       ipp_req.flag = IPP_ROT_Y_FLIP;
+                               //ipp_do_blit(&ipp_req);
+                               ipp_blit_sync(&ipp_req);
+                               yuv_phy[0] = ipp_req.dst0.YrgbMst;
+                               yuv_phy[1] = ipp_req.dst0.CbrMst;
+                               if((var->rotate & 0x1ff)!=0 &&(var->rotate&(X_MIRROR|Y_MIRROR))!= 0 )
+                               {
+                                       memset(&ipp_req,0,sizeof(struct rk29_ipp_req));
+                                       
+                                       if((var->rotate & X_MIRROR) == X_MIRROR)
+                                               ipp_req.flag = IPP_ROT_X_FLIP;
+                                       else if((var->rotate & Y_MIRROR) == Y_MIRROR)
+                                               ipp_req.flag = IPP_ROT_Y_FLIP;
+                                       else 
+                                               printk(">>>>>> %d rotate is not support!\n",var->rotate);
+                                       
+                                 if(var->xres > screen->x_res)
+                                  {
+                                       ipp_req.dst0.w = screen->x_res;
+                                       ipp_req.dst0.h = screen->y_res;
+                                 }   else      {
+                                         ipp_req.dst0.w = var->xres;
+                                         ipp_req.dst0.h = var->yres;
+                                  }
+                                       ipp_req.src0.fmt = 3;
+                                       ipp_req.src0.YrgbMst = yuv_phy[0];
+                                       ipp_req.src0.CbrMst = yuv_phy[1];
+                                       ipp_req.src0.w = ipp_req.dst0.w;
+                                       ipp_req.src0.h = ipp_req.dst0.h;
+                               
+                                       ipp_req.src_vir_w= (ipp_req.dst0.w + 15) & (~15);
+                                       ipp_req.dst_vir_w= (ipp_req.dst0.w + 15) & (~15);
+
+                                       ipp_req.dst0.fmt = 3;
+                                       ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
+                                       ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
+
+                                       ipp_req.timeout = 100;
+                                       ipp_blit_sync(&ipp_req);
+                                       yuv_phy[0] = ipp_req.dst0.YrgbMst;
+                                       yuv_phy[1] = ipp_req.dst0.CbrMst;
+                       }
+                fbprintk("yaddr=0x%x,uvaddr=0x%x\n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
+                               #else
+                               ipp_req.dst0.YrgbMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*2*dstoffset;
                 ipp_req.dst0.CbrMst = inf->fb0->fix.mmio_start + screen->x_res*screen->y_res*(2*dstoffset+1);
-             //   if(var->xres > screen->x_res)
-             //   {
+                if(var->xres > screen->x_res)
+                {
                     ipp_req.dst0.w = screen->x_res;
                     ipp_req.dst0.h = screen->y_res;
-              //  }   else  {
-              //      ipp_req.dst0.w = var->yres;
-             //       ipp_req.dst0.h = var->xres;
-             //   }
-               // ipp_req.src_vir_w = ipp_req.src0.w;
-               // ipp_req.dst_vir_w = ipp_req.dst0.w;
+                }   else  {
+                                       ipp_req.dst0.w = var->xres;
+                                       ipp_req.dst0.h = var->yres;
+
+                }
+                ipp_req.dst_vir_w = (ipp_req.dst0.w + 15) & (~15);
                 ipp_req.timeout = 100;
                 if(var->rotate == 90)
                     ipp_req.flag = IPP_ROT_90;
@@ -2171,9 +2786,11 @@ static int fb1_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
                     ipp_req.flag = IPP_ROT_270;
                 //ipp_do_blit(&ipp_req);
                 ipp_blit_sync(&ipp_req);
+                               
                 fbprintk("yaddr=0x%x,uvaddr=0x%x\n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
                 yuv_phy[0] = ipp_req.dst0.YrgbMst;
-                yuv_phy[1] = ipp_req.dst0.CbrMst;    
+                yuv_phy[1] = ipp_req.dst0.CbrMst; 
+                               #endif
                 fix0->smem_start = yuv_phy[0];
                 fix0->mmio_start = yuv_phy[1];
                 #else //CONFIG_FB_ROTATE_VIDEO
@@ -2206,10 +2823,27 @@ static int fb1_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
       #ifdef CONFIG_FB_ROTATE_VIDEO 
                //zyc add
        has_set_rotate = true;
-        if(arg == 0 || arg==180)
-            var->rotate = arg;    
-        else if (arg == 90 || arg==270)
-            var->rotate = arg;  
+               #ifdef CONFIG_FB_MIRROR_X_Y
+        if( ((arg&0x1ff)%90) == 0 && ( arg&(~0xfff))==0 )
+                       {
+                       if( (arg&(  X_MIRROR | Y_MIRROR ) )== (X_MIRROR | Y_MIRROR) )
+                               var->rotate = ROTATE_180;
+                       else if((arg&( ROTATE_90 | X_MIRROR | Y_MIRROR ) )== ( ROTATE_90 | X_MIRROR | Y_MIRROR))
+                               var->rotate = ROTATE_270;
+                       else if((arg&( ROTATE_180 | X_MIRROR | Y_MIRROR ) )== ( ROTATE_180 | X_MIRROR | Y_MIRROR))
+                               var->rotate = ROTATE_90;
+                       else if((arg&( ROTATE_270 | X_MIRROR | Y_MIRROR ) )== ( ROTATE_270 | X_MIRROR | Y_MIRROR))
+                               var->rotate = ROTATE_0;
+                       else
+               #else 
+               if(arg == ROTATE_0 || arg==ROTATE_90 || arg == ROTATE_180 || arg==ROTATE_270)
+               {
+               #endif
+                               var->rotate = arg;
+               }
+               else
+                       printk(">>>>>> %d rotate is not support!\n",(int)arg);
+       
       #else //CONFIG_FB_ROTATE_VIDEO
         printk("LCDC not support rotate!\n");
       #endif
@@ -2299,6 +2933,7 @@ int FB_Switch_Screen( struct rk29fb_screen *screen, u32 enable )
     fb0_set_par(inf->fb0);
     LcdMskReg(inf, DSP_CTRL1, m_BLACK_MODE,  v_BLACK_MODE(0));
     LcdWrReg(inf, REG_CFG_DONE, 0x01);
+    rk29fb_notify(inf, enable ? RK29FB_EVENT_HDMI_ON : RK29FB_EVENT_HDMI_OFF);
     return 0;
 }
 
@@ -2432,6 +3067,10 @@ static void rk29fb_early_suspend(struct early_suspend *h)
         return;
     }
 
+#ifdef CONFIG_CLOSE_WIN1_DYNAMIC   
+     cancel_delayed_work_sync(&rk29_win1_check_work);
+#endif  
+
     if((inf->cur_screen != &inf->panel2_info) && mach_info->io_disable)  // close lcd pwr when output screen is lcd
        mach_info->io_disable();  //close lcd out 
 
@@ -2440,6 +3079,7 @@ static void rk29fb_early_suspend(struct early_suspend *h)
                fbprintk(">>>>>> power down the screen! \n");
                inf->cur_screen->standby(1);
        }
+       LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE | m_W1_ENABLE, v_W0_ENABLE(0) | v_W1_ENABLE(0));
 
     LcdMskReg(inf, DSP_CTRL0, m_HSYNC_POLARITY | m_VSYNC_POLARITY | m_DEN_POLARITY ,
        v_HSYNC_POLARITY(1) | v_VSYNC_POLARITY(1) | v_DEN_POLARITY(1) );
@@ -2464,7 +3104,7 @@ static void rk29fb_early_suspend(struct early_suspend *h)
         if(inf->clk){
             clk_disable(inf->aclk);
         }
-        clk_disable(inf->pd_display);
+        //clk_disable(inf->pd_display);
 
                inf->in_suspend = 1;
        }
@@ -2489,7 +3129,7 @@ static void rk29fb_early_resume(struct early_suspend *h)
        {
            inf->in_suspend = 0;
        fbprintk(">>>>>> enable the lcdc clk! \n");
-        clk_enable(inf->pd_display);
+       // clk_enable(inf->pd_display);
         clk_enable(inf->aclk_disp_matrix);
         clk_enable(inf->hclk_cpu_display);
         clk_enable(inf->clk);
@@ -2531,7 +3171,7 @@ static struct suspend_info suspend_info = {
 };
 #endif
 struct fb_info *g_fb0_inf = NULL;  //add cym@rk 20101027 for charger logo
-static int __init rk29fb_probe (struct platform_device *pdev)
+static int __devinit rk29fb_probe (struct platform_device *pdev)
 {
     struct rk29fb_inf *inf = NULL;
     struct resource *res = NULL;
@@ -2633,7 +3273,7 @@ static int __init rk29fb_probe (struct platform_device *pdev)
     inf->fb0->var.yres_virtual = screen->y_res;
     inf->fb0->var.width = screen->width;
     inf->fb0->var.height = screen->height;
-    inf->fb0->var.pixclock = screen->pixclock;
+    //inf->fb0->var.pixclock = div_u64(1000000000000llu, screen->pixclock);
     inf->fb0->var.left_margin = screen->left_margin;
     inf->fb0->var.right_margin = screen->right_margin;
     inf->fb0->var.upper_margin = screen->upper_margin;
@@ -2722,7 +3362,7 @@ static int __init rk29fb_probe (struct platform_device *pdev)
     inf->fb1->var.yres_virtual = screen->y_res;
     inf->fb1->var.width = screen->width;
     inf->fb1->var.height = screen->height;
-    inf->fb1->var.pixclock = screen->pixclock;
+    //inf->fb1->var.pixclock = div_u64(1000000000000llu, screen->pixclock);
     inf->fb1->var.left_margin = screen->left_margin;
     inf->fb1->var.right_margin = screen->right_margin;
     inf->fb1->var.upper_margin = screen->upper_margin;
@@ -2887,7 +3527,7 @@ release_drvdata:
        return ret;
 }
 
-static int rk29fb_remove(struct platform_device *pdev)
+static int __devexit rk29fb_remove(struct platform_device *pdev)
 {
     struct rk29fb_inf *inf = platform_get_drvdata(pdev);
     struct fb_info *info = NULL;
@@ -3012,7 +3652,7 @@ static void rk29fb_shutdown(struct platform_device *pdev)
 
 static struct platform_driver rk29fb_driver = {
        .probe          = rk29fb_probe,
-       .remove         = rk29fb_remove,
+       .remove         = __devexit_p(rk29fb_remove),
        .driver         = {
                .name   = "rk29-fb",
                .owner  = THIS_MODULE,