From: yxj Date: Wed, 8 Aug 2012 14:19:05 +0000 (+0800) Subject: rkfb : layer and fb map soc independently ,add sys node for fb and layer remap X-Git-Tag: firefly_0821_release~8912^2~30 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=cd8286834147da92be4ded7a746a6f8e79fc9ce1;p=firefly-linux-kernel-4.4.55.git rkfb : layer and fb map soc independently ,add sys node for fb and layer remap --- diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index a07940b493a2..2711cdcde8fc 100644 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -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; diff --git a/drivers/video/rockchip/rkfb_sysfs.c b/drivers/video/rockchip/rkfb_sysfs.c index 46bd7720a47b..92309a3ef7e7 100644 --- a/drivers/video/rockchip/rkfb_sysfs.c +++ b/drivers/video/rockchip/rkfb_sysfs.c @@ -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) diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index 1b8663626f45..9c1aa1518bbd 100644 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -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); };