rkfb : layer and fb map soc independently ,add sys node for fb and layer remap
authoryxj <yxj@rock-chips.com>
Wed, 8 Aug 2012 14:19:05 +0000 (22:19 +0800)
committeryxj <yxj@rock-chips.com>
Wed, 8 Aug 2012 14:21:04 +0000 (22:21 +0800)
drivers/video/rockchip/rk_fb.c
drivers/video/rockchip/rkfb_sysfs.c
include/linux/rk_fb.h

index a07940b493a223ca0ee703c79630d6d20e99fd9c..2711cdcde8fc482e61afbd04d312a465fef6047a 100644 (file)
@@ -62,25 +62,7 @@ defautl:we alloc three buffer,one for fb0 and fb2 display ui,one for ipp rotate
         pass the phy addr to fix.smem_start by ioctl
 ****************************************************************************/
 
-int get_fb_layer_id(struct fb_fix_screeninfo *fix)
-{
-       int layer_id;
-       if(!strcmp(fix->id,"fb1")||!strcmp(fix->id,"fb3"))
-       {
-               layer_id = 0;
-       }
-       else if(!strcmp(fix->id,"fb0")||!strcmp(fix->id,"fb2"))
-       {
-               layer_id = 1;
-       }
-       else
-       {
-               printk(KERN_ERR "unsupported %s",fix->id);
-               layer_id = -ENODEV;
-       }
 
-       return layer_id;
-}
 
 /**********************************************************************
 this is for hdmi
@@ -103,7 +85,7 @@ static int rk_fb_open(struct fb_info *info,int user)
     struct rk_lcdc_device_driver * dev_drv = (struct rk_lcdc_device_driver * )info->par;
     int layer_id;
   
-    layer_id = get_fb_layer_id(&info->fix);
+    layer_id = dev_drv->fb_get_layer(dev_drv,info->fix.id);
     if(dev_drv->layer_par[layer_id]->state)
     {
        return 0;    // if this layer aready opened ,no need to reopen
@@ -178,7 +160,7 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
        u32 xvir = var->xres_virtual;
        u8 data_format = var->nonstd&0xff;
        
-       layer_id = get_fb_layer_id(fix);
+       layer_id = dev_drv->fb_get_layer(dev_drv,info->fix.id);
        if(layer_id < 0)
        {
                return  -ENODEV;
@@ -246,7 +228,7 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,unsigned long arg)
        struct fb_fix_screeninfo *fix = &info->fix;
        struct rk_lcdc_device_driver *dev_drv = (struct rk_lcdc_device_driver * )info->par;
        u32 yuv_phy[2];
-       int layer_id = get_fb_layer_id(&info->fix);
+       int  layer_id = dev_drv->fb_get_layer(dev_drv,info->fix.id);
        int enable; // enable fb:1 enable;0 disable 
        int ovl;        //overlay:0 win1 on the top of win0;1,win0 on the top of win1
        int num_buf; //buffer_number
@@ -315,7 +297,7 @@ static int rk_fb_blank(int blank_mode, struct fb_info *info)
        struct fb_fix_screeninfo *fix = &info->fix;
        int layer_id;
        
-       layer_id = get_fb_layer_id(fix);
+       layer_id = dev_drv->fb_get_layer(dev_drv,info->fix.id);
        if(layer_id < 0)
        {
                return  -ENODEV;
@@ -388,7 +370,7 @@ static int rk_fb_set_par(struct fb_info *info)
                        }
                #endif 
        #endif
-       layer_id = get_fb_layer_id(fix);
+       layer_id = dev_drv->fb_get_layer(dev_drv,info->fix.id);
        if(layer_id < 0)
        {
                return  -ENODEV;
@@ -642,7 +624,7 @@ int rk_fb_switch_screen(rk_screen *screen ,int enable ,int lcdc_id)
                info = inf->fb[2];
        }
 
-       layer_id = get_fb_layer_id(&info->fix);
+        layer_id = dev_drv->fb_get_layer(dev_drv,info->fix.id);
        if(!enable)
        {
                if(dev_drv->layer_par[layer_id]->state) 
@@ -874,9 +856,13 @@ static int init_lcdc_device_driver(struct rk_lcdc_device_driver *dev_drv,
        dev_drv->get_disp_info  = def_drv->get_disp_info;
        dev_drv->ovl_mgr        = def_drv->ovl_mgr;
        dev_drv->fps_mgr        = def_drv->fps_mgr;
+       dev_drv->fb_get_layer   = def_drv->fb_get_layer;
+       dev_drv->fb_layer_remap = def_drv->fb_layer_remap;
        init_layer_par(dev_drv);
        init_completion(&dev_drv->frame_done);
        spin_lock_init(&dev_drv->cpl_lock);
+       mutex_init(&dev_drv->fb_win_id_mutex);
+       dev_drv->fb_layer_remap(dev_drv,FB_DEFAULT_ORDER); //102
        dev_drv->first_frame = 1;
        
        return 0;
index 46bd7720a47b6834cc7eca4ad024eaa371af8bc5..92309a3ef7e73a13560d279e36a8f871dd9883d2 100644 (file)
@@ -56,7 +56,7 @@ static ssize_t show_disp_info(struct device *dev,
        struct fb_info *fbi = dev_get_drvdata(dev);
        struct rk_lcdc_device_driver * dev_drv = 
                (struct rk_lcdc_device_driver * )fbi->par;
-       int layer_id = get_fb_layer_id(&fbi->fix);
+       int layer_id = dev_drv->fb_get_layer(dev_drv,fbi->fix.id);
        if(dev_drv->get_disp_info)
                dev_drv->get_disp_info(dev_drv,layer_id);
 
@@ -86,7 +86,7 @@ static ssize_t show_fb_state(struct device *dev,
        struct fb_info *fbi = dev_get_drvdata(dev);
        struct rk_lcdc_device_driver * dev_drv = 
                (struct rk_lcdc_device_driver * )fbi->par;
-       int layer_id = get_fb_layer_id(&fbi->fix);
+       int layer_id = dev_drv->fb_get_layer(dev_drv,fbi->fix.id);
        int state = dev_drv->get_layer_state(dev_drv,layer_id);
        return snprintf(buf, PAGE_SIZE, "%s\n",state?"enabled":"disabled");
        
@@ -97,7 +97,7 @@ static ssize_t set_fb_state(struct device *dev,struct device_attribute *attr,
        struct fb_info *fbi = dev_get_drvdata(dev);
        struct rk_lcdc_device_driver * dev_drv = 
                (struct rk_lcdc_device_driver * )fbi->par;
-       int layer_id = get_fb_layer_id(&fbi->fix);
+       int layer_id = dev_drv->fb_get_layer(dev_drv,fbi->fix.id);
        int state;
        int ret;
        ret = kstrtoint(buf, 0, &state);
@@ -188,6 +188,55 @@ static ssize_t set_fps(struct device *dev,struct device_attribute *attr,
        return count;
 }
 
+static ssize_t show_fb_win_map(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       int ret;
+       struct fb_info *fbi = dev_get_drvdata(dev);
+       struct rk_lcdc_device_driver * dev_drv = 
+               (struct rk_lcdc_device_driver * )fbi->par;
+
+       mutex_lock(&dev_drv->fb_win_id_mutex);
+       ret = snprintf(buf, PAGE_SIZE,"fb0:win%d\nfb1:win%d\nfb2:win%d\n",dev_drv->fb0_win_id,dev_drv->fb1_win_id,
+               dev_drv->fb2_win_id);
+       mutex_unlock(&dev_drv->fb_win_id_mutex);
+
+       return ret;
+       
+}
+
+static ssize_t set_fb_win_map(struct device *dev,struct device_attribute *attr,
+       const char *buf, size_t count)
+{
+       struct fb_info *fbi = dev_get_drvdata(dev);
+       struct rk_lcdc_device_driver * dev_drv = 
+               (struct rk_lcdc_device_driver * )fbi->par;
+       int order;
+       int ret;
+       ret = kstrtoint(buf, 0, &order);
+       if((order != FB0_WIN2_FB1_WIN1_FB2_WIN0) && (order != FB0_WIN1_FB1_WIN2_FB2_WIN0 ) &&
+          (order != FB0_WIN2_FB1_WIN0_FB2_WIN1) && (order != FB0_WIN0_FB1_WIN2_FB2_WIN1 ) &&
+          (order != FB0_WIN0_FB1_WIN1_FB2_WIN2) && (order != FB0_WIN1_FB1_WIN0_FB2_WIN2 ))
+       {
+               printk(KERN_ERR "un support map\nyou can use the following order: \
+                       \n201:\nfb0-win1\nfb1-win0\nfb2-win2\n                     \
+                       \n210:\nfb0-win0\nfb1-win1\nfb2-win2\n                    \
+                       \n120:\nfb0-win0\nfb1-win2\nfb2-win1\n                    \
+                       \n102:\nfb0-win2\nfb1-win0\nfb2-win1\n                     \
+                       \n021:\nfb0-win1\nfb1-win2\nfb2-win0\n                     \
+                       \n012:\nfb0-win2\nfb1-win1\nfb2-win0\n");
+               return count;
+       }
+       else
+       {
+               dev_drv->fb_layer_remap(dev_drv,order);
+       }
+
+       return count;
+       
+       
+}
+
 static struct device_attribute rkfb_attrs[] = {
        __ATTR(phys_addr, S_IRUGO, show_phys, NULL),
        __ATTR(virt_addr, S_IRUGO, show_virt, NULL),
@@ -196,6 +245,7 @@ static struct device_attribute rkfb_attrs[] = {
        __ATTR(enable, S_IRUGO | S_IWUSR, show_fb_state, set_fb_state),
        __ATTR(overlay, S_IRUGO | S_IWUSR, show_overlay, set_overlay),
        __ATTR(fps, S_IRUGO | S_IWUSR, show_fps, set_fps),
+       __ATTR(map, S_IRUGO | S_IWUSR, show_fb_win_map, set_fb_win_map),
 };
 
 int rkfb_create_sysfs(struct fb_info *fbi)
index 1b8663626f45ae7c8fdf5f1e6ebc94d719efdfbc..9c1aa1518bbda8af55e9a6e12ff8bdd0cfdbc02b 100644 (file)
@@ -142,6 +142,16 @@ enum data_format{
        YUV444,
 };
 
+enum fb_win_map_order{
+       FB_DEFAULT_ORDER           = 0,
+       FB0_WIN2_FB1_WIN1_FB2_WIN0 = 012,
+       FB0_WIN1_FB1_WIN2_FB2_WIN0 = 021, 
+       FB0_WIN2_FB1_WIN0_FB2_WIN1 = 102,
+       FB0_WIN0_FB1_WIN2_FB2_WIN1 = 120,
+       FB0_WIN0_FB1_WIN1_FB2_WIN2 = 210,
+       FB0_WIN1_FB1_WIN0_FB2_WIN2 = 201,       
+};
+
 struct rk_fb_rgb {
        struct fb_bitfield      red;
        struct fb_bitfield      green;
@@ -196,6 +206,12 @@ struct rk_lcdc_device_driver{
        rk_screen *screen;
        u32 pixclock;
 
+       
+        char fb0_win_id;
+        char fb1_win_id;
+        char fb2_win_id;
+        struct mutex fb_win_id_mutex;
+       
        struct completion  frame_done;            //sync for pan_display,whe we set a new frame address to lcdc register,we must make sure the frame begain to display
        spinlock_t  cpl_lock;                    //lock for completion  frame done
        int first_frame ;
@@ -214,6 +230,8 @@ struct rk_lcdc_device_driver{
        int (*get_layer_state)(struct rk_lcdc_device_driver *dev_drv,int layer_id);
        int (*ovl_mgr)(struct rk_lcdc_device_driver *dev_drv,int swap,bool set);  //overlay manager
        int (*fps_mgr)(struct rk_lcdc_device_driver *dev_drv,int fps,bool set);
+       int (*fb_get_layer)(struct rk_lcdc_device_driver *dev_drv,const char *id);                                      //find layer for fb
+       int (*fb_layer_remap)(struct rk_lcdc_device_driver *dev_drv,enum fb_win_map_order order);
        
 };