rkfb : layer and fb map soc independently ,add sys node for fb and layer remap

This commit is contained in:
yxj
2012-08-08 22:19:05 +08:00
parent 2870dd639e
commit cd82868341
3 changed files with 81 additions and 27 deletions

View 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;

View 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)

View 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);
};