From 708f0ec159b6b03febae04a00eee77c7b492768b Mon Sep 17 00:00:00 2001 From: yxj Date: Fri, 13 Apr 2012 14:49:38 +0800 Subject: [PATCH] rk30fb :fix a bug in rk30_lcdc.c lcdc0 and lcdc1 use separate rk_lcdc_device_driver instance fix wrong define for rk30_lcdc_resume --- drivers/video/rockchip/chips/rk30_lcdc.c | 21 ++--- drivers/video/rockchip/rk_fb.c | 107 +++++++++++++++-------- include/linux/rk_fb.h | 12 +-- 3 files changed, 86 insertions(+), 54 deletions(-) diff --git a/drivers/video/rockchip/chips/rk30_lcdc.c b/drivers/video/rockchip/chips/rk30_lcdc.c index 458e14104d96..def25b9dfa92 100644 --- a/drivers/video/rockchip/chips/rk30_lcdc.c +++ b/drivers/video/rockchip/chips/rk30_lcdc.c @@ -474,12 +474,12 @@ static int rk30_lcdc_set_par(struct rk_lcdc_device_driver *dev_drv,int layer_id) } if(layer_id==0) { - par = &(dev_drv->layer_par[0]); + par = dev_drv->layer_par[0]; win0_set_par(lcdc_dev,screen,par); } else if(layer_id==1) { - par = &(dev_drv->layer_par[1]); + par = dev_drv->layer_par[1]; win1_set_par(lcdc_dev,screen,par); } @@ -500,12 +500,12 @@ int rk30_lcdc_pan_display(struct rk_lcdc_device_driver * dev_drv,int layer_id) } if(layer_id==0) { - par = &(dev_drv->layer_par[0]); + par = dev_drv->layer_par[0]; win0_display(lcdc_dev,par); } else if(layer_id==1) { - par = &(dev_drv->layer_par[1]); + par = dev_drv->layer_par[1]; win1_display(lcdc_dev,par); } if(dev_drv->first_frame) //this is the first frame of the system ,enable frame start interrupt @@ -596,7 +596,7 @@ static struct layer_par lcdc_layer[] = { static struct rk_lcdc_device_driver lcdc_driver = { .name = "lcdc", - .layer_par = lcdc_layer, + .def_layer_par = lcdc_layer, .num_layer = ARRAY_SIZE(lcdc_layer), .open = rk30_lcdc_open, .init_lcdc = init_rk30_lcdc, @@ -617,26 +617,25 @@ static int rk30_lcdc_suspend(struct platform_device *pdev, pm_message_t state) clk_disable(lcdc_dev->dclk); clk_disable(lcdc_dev->hclk); clk_disable(lcdc_dev->aclk); - printk("%s>>>>\n",__func__); return 0; } static int rk30_lcdc_resume(struct platform_device *pdev) { struct rk30_lcdc_device *lcdc_dev = platform_get_drvdata(pdev); + clk_enable(lcdc_dev->hclk); clk_enable(lcdc_dev->dclk); clk_enable(lcdc_dev->aclk); usleep_range(10*1000, 10*1000); memcpy((u8*)lcdc_dev->preg, (u8*)&lcdc_dev->regbak, 0xc4); //resume reg usleep_range(40*1000, 40*1000); - printk("%s>>>>\n",__func__); return 0; } #else #define rk30_lcdc_suspend NULL -#define rk30_lcddc_resume NULL +#define rk30_lcdc_resume NULL #endif static int __devinit rk30_lcdc_probe (struct platform_device *pdev) @@ -694,13 +693,9 @@ static int __devinit rk30_lcdc_probe (struct platform_device *pdev) lcdc_dev->preg = (LCDC_REG*)lcdc_dev->reg_vir_base; printk("lcdc%d:reg_phy_base = 0x%08x,reg_vir_base:0x%p\n",pdev->id,lcdc_dev->reg_phy_base, lcdc_dev->preg); - init_lcdc_device_driver(&lcdc_driver,&(lcdc_dev->driver),lcdc_dev->id); lcdc_dev->driver.dev=&pdev->dev; - - /***************** set lcdc screen ********/ lcdc_dev->driver.screen = screen; - /***************** lcdc register ********/ lcdc_dev->irq = platform_get_irq(pdev, 0); if(lcdc_dev->irq < 0) { @@ -714,7 +709,7 @@ static int __devinit rk30_lcdc_probe (struct platform_device *pdev) ret = -EBUSY; goto err3; } - ret = rk_fb_register(&(lcdc_dev->driver)); + ret = rk_fb_register(&(lcdc_dev->driver),&lcdc_driver,lcdc_dev->id); if(ret < 0) { printk(KERN_ERR "registe fb for lcdc0 failed!\n"); diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index 52d27971dbd9..480115c19761 100644 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -145,7 +145,7 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) } else { - par = &dev_drv->layer_par[layer_id]; + par = dev_drv->layer_par[layer_id]; } switch (par->format) { @@ -347,7 +347,7 @@ static int rk_fb_set_par(struct fb_info *info) } else { - par = &dev_drv->layer_par[layer_id]; + par = dev_drv->layer_par[layer_id]; } if((!strcmp(fix->id,"fb0"))||(!strcmp(fix->id,"fb2"))) //four ui { @@ -599,7 +599,69 @@ static int rk_release_fb_buffer(struct fb_info *fbi) return 0; } -int rk_fb_register(struct rk_lcdc_device_driver *dev_drv) +static int init_layer_par(struct rk_lcdc_device_driver *dev_drv) +{ + int i; + struct layer_par * def_par = NULL; + int num_par = dev_drv->num_layer; + for(i = 0; i < num_par; i++) + { + struct layer_par *par = NULL; + par = kzalloc(sizeof(struct layer_par), GFP_KERNEL); + if(!par) + { + printk(KERN_ERR "kzmalloc for layer_par fail!"); + return -ENOMEM; + + } + def_par = &dev_drv->def_layer_par[i]; + strcpy(par->name,def_par->name); + par->id = def_par->id; + par->support_3d = def_par->support_3d; + dev_drv->layer_par[i] = par; + } + + return 0; + + +} + + +static int init_lcdc_device_driver(struct rk_lcdc_device_driver *dev_drv, + struct rk_lcdc_device_driver *def_drv,int id) +{ + if(!def_drv) + { + printk(KERN_ERR "default lcdc device driver is null!\n"); + return -EINVAL; + } + if(!dev_drv) + { + printk(KERN_ERR "lcdc device driver is null!\n"); + return -EINVAL; + } + sprintf(dev_drv->name, "lcdc%d",id); + dev_drv->open = def_drv->open; + dev_drv->init_lcdc = def_drv->init_lcdc; + dev_drv->ioctl = def_drv->ioctl; + dev_drv->blank = def_drv->blank; + dev_drv->set_par = def_drv->set_par; + dev_drv->pan_display = def_drv->pan_display; + dev_drv->suspend = def_drv->suspend; + dev_drv->resume = def_drv->resume; + dev_drv->load_screen = def_drv->load_screen; + dev_drv->def_layer_par = def_drv->def_layer_par; + dev_drv->num_layer = def_drv->num_layer; + init_layer_par(dev_drv); + init_completion(&dev_drv->frame_done); + spin_lock_init(&dev_drv->cpl_lock); + dev_drv->first_frame = 1; + + return 0; +} + +int rk_fb_register(struct rk_lcdc_device_driver *dev_drv, + struct rk_lcdc_device_driver *def_drv,int id) { struct rk_fb_inf *fb_inf = platform_get_drvdata(g_fb_pdev); struct fb_info *fbi; @@ -626,6 +688,7 @@ int rk_fb_register(struct rk_lcdc_device_driver *dev_drv) return -ENOENT; } lcdc_id = i; + init_lcdc_device_driver(dev_drv, def_drv,id); set_lcd_info(dev_drv->screen, fb_inf->mach_info->lcd_info); dev_drv->init_lcdc(dev_drv); dev_drv->load_screen(dev_drv,1); @@ -660,7 +723,7 @@ int rk_fb_register(struct rk_lcdc_device_driver *dev_drv) fbi->var.hsync_len = fb_inf->lcdc_dev_drv[lcdc_id]->screen->hsync_len; fbi->fbops = &fb_ops; fbi->flags = FBINFO_FLAG_DEFAULT; - fbi->pseudo_palette = fb_inf->lcdc_dev_drv[lcdc_id]->layer_par[i].pseudo_pal; + fbi->pseudo_palette = fb_inf->lcdc_dev_drv[lcdc_id]->layer_par[i]->pseudo_pal; rk_request_fb_buffer(fbi,fb_inf->num_fb); ret = register_framebuffer(fbi); if(ret<0) @@ -700,6 +763,11 @@ int rk_fb_unregister(struct rk_lcdc_device_driver *dev_drv) return -ENOENT; } + for(i = 0; i < fb_num; i++) + { + kfree(dev_drv->layer_par[i]); + } + for(i=fb_index_base;i<(fb_index_base+fb_num);i++) { fbi = fb_inf->fb[i]; @@ -712,37 +780,6 @@ int rk_fb_unregister(struct rk_lcdc_device_driver *dev_drv) return 0; } -int init_lcdc_device_driver(struct rk_lcdc_device_driver *def_drv, - struct rk_lcdc_device_driver *dev_drv,int id) -{ - if(!def_drv) - { - printk(KERN_ERR "default lcdc device driver is null!\n"); - return -EINVAL; - } - if(!dev_drv) - { - printk(KERN_ERR "lcdc device driver is null!\n"); - return -EINVAL; - } - sprintf(dev_drv->name, "lcdc%d",id); - dev_drv->layer_par = def_drv->layer_par; - dev_drv->num_layer = def_drv->num_layer; - dev_drv->open = def_drv->open; - dev_drv->init_lcdc = def_drv->init_lcdc; - dev_drv->ioctl = def_drv->ioctl; - dev_drv->blank = def_drv->blank; - dev_drv->set_par = def_drv->set_par; - dev_drv->pan_display = def_drv->pan_display; - dev_drv->suspend = def_drv->suspend; - dev_drv->resume = def_drv->resume; - dev_drv->load_screen = def_drv->load_screen; - init_completion(&dev_drv->frame_done); - spin_lock_init(&dev_drv->cpl_lock); - dev_drv->first_frame = 1; - - return 0; -} #ifdef CONFIG_HAS_EARLYSUSPEND diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index 919b8c939587..e7c20b75d098 100644 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -160,7 +160,7 @@ typedef enum _TRSP_MODE } TRSP_MODE; struct layer_par { - const char *name; + char name[5]; int id; bool state; //on or off u32 pseudo_pal[16]; @@ -187,7 +187,8 @@ struct rk_lcdc_device_driver{ int id; struct device *dev; - struct layer_par *layer_par; + struct layer_par *layer_par[RK_MAX_FB_SUPPORT]; + struct layer_par *def_layer_par; int num_layer; int fb_index_base; //the first fb index of the lcdc device rk_screen *screen; @@ -222,10 +223,9 @@ struct rk_fb_inf { int video_mode; //when play video set it to 1 }; -extern int rk_fb_register(struct rk_lcdc_device_driver *fb_device_driver); -extern int rk_fb_unregister(struct rk_lcdc_device_driver *fb_device_driver); -extern int init_lcdc_device_driver(struct rk_lcdc_device_driver *def_drv, - struct rk_lcdc_device_driver *dev_drv,int id); +extern int rk_fb_register(struct rk_lcdc_device_driver *dev_drv, + struct rk_lcdc_device_driver *def_drv,int id); +extern int rk_fb_unregister(struct rk_lcdc_device_driver *dev_drv); extern int get_fb_layer_id(struct fb_fix_screeninfo *fix); extern struct rk_lcdc_device_driver * rk_get_lcdc_drv(char *name); extern int rkfb_create_sysfs(struct fb_info *fbi); -- 2.34.1