};
#endif
-#ifdef CONFIG_LCDC_RK30
-static struct resource resource_lcdc[] = {
+#ifdef CONFIG_LCDC0_RK30
+static struct resource resource_lcdc0[] = {
[0] = {
.name = "lcdc0 reg",
.start = RK30_LCDC0_PHYS,
.end = RK30_LCDC0_PHYS + RK30_LCDC0_SIZE - 1,
.flags = IORESOURCE_MEM,
},
+
[1] = {
- .name = "lcdc1 reg",
- .start = RK30_LCDC1_PHYS,
- .end = RK30_LCDC1_PHYS + RK30_LCDC1_SIZE - 1,
- .flags = IORESOURCE_MEM,
- },
- [2] = {
.name = "lcdc0 irq",
.start = IRQ_LCDC0,
.end = IRQ_LCDC0,
.flags = IORESOURCE_IRQ,
},
- [3] = {
+};
+
+static struct platform_device device_lcdc0 = {
+ .name = "rk30-lcdc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resource_lcdc0),
+ .resource = resource_lcdc0,
+};
+#endif
+#ifdef CONFIG_LCDC1_RK30
+static struct resource resource_lcdc1[] = {
+ [0] = {
+ .name = "lcdc1 reg",
+ .start = RK30_LCDC1_PHYS,
+ .end = RK30_LCDC1_PHYS + RK30_LCDC1_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
.name = "lcdc1 irq",
.start = IRQ_LCDC1,
.end = IRQ_LCDC1,
},
};
-static struct platform_device device_lcdc = {
+static struct platform_device device_lcdc1 = {
.name = "rk30-lcdc",
- .id = 4,
- .num_resources = ARRAY_SIZE(resource_lcdc),
- .resource = resource_lcdc,
+ .id = 1,
+ .num_resources = ARRAY_SIZE(resource_lcdc1),
+ .resource = resource_lcdc1,
};
#endif
#ifdef CONFIG_RK29_IPP
platform_device_register(&device_ipp);
#endif
-#ifdef CONFIG_LCDC_RK30
- platform_device_register(&device_lcdc);
+#ifdef CONFIG_LCDC0_RK30
+ platform_device_register(&device_lcdc0);
+#endif
+#ifdef CONFIG_LCDC1_RK30
+ platform_device_register(&device_lcdc1);
#endif
#ifdef CONFIG_ADC_RK30
platform_device_register(&device_adc);
config FB_ROCKCHIP
- tristate "Frame buffer support for Rockchip lcd controller"
+ tristate "Frame buffer support for Rockchip "
depends on FB
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
Framebuffer driver for rockchip based platform
config LCDC_RK30
- tristate "Frame buffer driver support for rk30 lcdc "
+ tristate "rk30 lcdc support "
depends on FB_ROCKCHIP
help
- Frame buffer driver for rk30 lcdc based boards.
+ Driver for rk30 lcdc .There are two lcd controllers on rk30
+
+config LCDC0_RK30
+ bool "lcdc0 support"
+ depends on LCDC_RK30
+ default y
+ help
+ Support rk30 lcdc0 if you say y here
+
+config LCDC1_RK30
+ bool "lcdc1 support"
+ depends on LCDC_RK30
+ default y
+ help
+ Support rk30 lcdc1 if you say y here
source "drivers/video/rockchip/rga/Kconfig"
+/*
+ * drivers/video/rockchip/chips/rk30_lcdc.c
+ *
+ * Copyright (C) 2012 ROCKCHIP, Inc.
+ *Author:yzq<yzq@rock-chips.com>
+ * yxj<yxj@rock-chips.com>
+ *This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/delay.h>
#include <linux/device.h>
#include <linux/init.h>
-#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
-#include <linux/backlight.h>
-#include <linux/timer.h>
-#include <linux/time.h>
-#include <linux/wait.h>
#include <linux/earlysuspend.h>
-#include <linux/cpufreq.h>
-#include <linux/wakelock.h>
#include <linux/fb.h>
+#include <asm/div64.h>
+#include <asm/uaccess.h>
#include <mach/board.h>
-#include <mach/pmu.h>
-#include <mach/iomux.h>
-#include <mach/gpio.h>
-#include <asm/cacheflush.h>
#include "../../display/screen/screen.h"
#include "../rk_fb.h"
#include "rk30_lcdc.h"
#define DBG(x...) do { if(unlikely(dbg_thresd)) printk(KERN_INFO x); } while (0)
-static struct platform_device * g_lcdc_pdev;
-static rk_screen * to_screen(struct rk30_lcdc_device *lcdc_dev)
+static int init_rk30_lcdc(struct rk30_lcdc_device *lcdc_dev)
{
- return &(lcdc_dev->driver->screen);
-}
-
-static int init_rk30_lcdc(struct lcdc_info *info)
-{
- struct rk30_lcdc_device * lcdc_dev = &info->lcdc0;
- struct rk30_lcdc_device * lcdc_dev1 = &info->lcdc1;
- info->lcdc0.hclk = clk_get(NULL,"hclk_lcdc0");
- info->lcdc0.aclk = clk_get(NULL,"aclk_lcdc0");
- info->lcdc0.dclk = clk_get(NULL,"dclk_lcdc0");
-
- info->lcdc1.hclk = clk_get(NULL,"hclk_lcdc1");
- info->lcdc1.aclk = clk_get(NULL,"aclk_lcdc1");
- info->lcdc1.dclk = clk_get(NULL,"dclk_lcdc1");
- if ((IS_ERR(info->lcdc0.aclk)) ||(IS_ERR(info->lcdc0.dclk)) || (IS_ERR(info->lcdc0.hclk))||
- (IS_ERR(info->lcdc1.aclk)) ||(IS_ERR(info->lcdc1.dclk)) || (IS_ERR(info->lcdc1.hclk)))
- {
- printk(KERN_ERR "failed to get lcdc_hclk source\n");
- return PTR_ERR(info->lcdc0.aclk);
- }
- clk_enable(info->lcdc0.hclk); //enable aclk for register config
- clk_enable(info->lcdc1.hclk);
-
+ if(lcdc_dev->id == 0) //lcdc0
+ {
+ lcdc_dev->hclk = clk_get(NULL,"hclk_lcdc0");
+ lcdc_dev->aclk = clk_get(NULL,"aclk_lcdc0");
+ lcdc_dev->dclk = clk_get(NULL,"dclk_lcdc0");
+ }
+ else if(lcdc_dev->id == 1)
+ {
+ lcdc_dev->hclk = clk_get(NULL,"hclk_lcdc1");
+ lcdc_dev->aclk = clk_get(NULL,"aclk_lcdc1");
+ lcdc_dev->dclk = clk_get(NULL,"dclk_lcdc1");
+ }
+ else
+ {
+ printk(KERN_ERR "invalid lcdc device!\n");
+ return -EINVAL;
+ }
+ if ((IS_ERR(lcdc_dev->aclk)) ||(IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk)))
+ {
+ printk(KERN_ERR "failed to get lcdc clk source\n");
+ }
+ clk_enable(lcdc_dev->hclk); //enable aclk for register config
LcdSetBit(lcdc_dev,DSP_CTRL0, m_LCDC_AXICLK_AUTO_ENABLE);//eanble axi-clk auto gating for low power
- LcdSetBit(lcdc_dev1,DSP_CTRL0, m_LCDC_AXICLK_AUTO_ENABLE);
+ LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01); // write any value to REG_CFG_DONE let config become effective
return 0;
}
int rk30_load_screen(struct rk30_lcdc_device*lcdc_dev, bool initscreen)
{
int ret = -EINVAL;
- rk_screen *screen = to_screen(lcdc_dev);
+ rk_screen *screen = lcdc_dev->screen;
u16 face;
u16 mcu_total, mcu_rwstart, mcu_csstart, mcu_rwend, mcu_csend;
u16 right_margin = screen->right_margin;
}
else
{
- lcdc_dev->driver->pixclock = lcdc_dev->pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
+ lcdc_dev->driver.pixclock = lcdc_dev->pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
clk_enable(lcdc_dev->dclk);
- printk("%s: dclk:%lu ",lcdc_dev->driver->name,clk_get_rate(lcdc_dev->dclk));
+ printk("%s: dclk:%lu ",lcdc_dev->driver.name,clk_get_rate(lcdc_dev->dclk));
}
if(initscreen)
{
{
screen->init();
}
- printk("%s>>>>>ok!\n",__func__);
+ printk("%s for lcdc%d ok!\n",__func__,lcdc_dev->id);
return 0;
}
//mcu_refresh(inf);
return 0;
}
-static int rk30_lcdc_blank(struct rk_lcdc_device_driver*fb_drv,int layer_id,int blank_mode)
+static int rk30_lcdc_blank(struct rk_lcdc_device_driver*lcdc_drv,int layer_id,int blank_mode)
{
- struct rk30_lcdc_device * lcdc_dev = NULL;
- struct lcdc_info * info = platform_get_drvdata(g_lcdc_pdev);
- if(!strcmp(fb_drv->name,"lcdc0"))
- {
- lcdc_dev = &(info->lcdc0);
- }
- else if(!strcmp(fb_drv->name,"lcdc1"))
- {
- lcdc_dev = &(info->lcdc1);
- }
+ struct rk30_lcdc_device * lcdc_dev = container_of(lcdc_drv,struct rk30_lcdc_device ,driver);
if(layer_id==0)
{
win0_blank(blank_mode,lcdc_dev);
u32 xact, yact, xvir, yvir, xpos, ypos;
u32 ScaleYrgbX,ScaleYrgbY, ScaleCbrX, ScaleCbrY;
- xact = par->xact; /*active (origin) picture window width/height */
+ xact = par->xact; //active (origin) picture window width/height
yact = par->yact;
- xvir = par->xvir; /* virtual resolution */
+ xvir = par->xvir; // virtual resolution
yvir = par->yvir;
xpos = par->xpos+screen->left_margin + screen->hsync_len;
ypos = par->ypos+screen->upper_margin + screen->vsync_len;
return 0;
}
-static int rk30_lcdc_set_par(struct rk_lcdc_device_driver *fb_drv,int layer_id)
+static int rk30_lcdc_set_par(struct rk_lcdc_device_driver *dev_drv,int layer_id)
{
- struct rk30_lcdc_device *lcdc_dev=NULL;
- struct lcdc_info * info = platform_get_drvdata(g_lcdc_pdev);
+ struct rk30_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk30_lcdc_device,driver);
struct layer_par *par = NULL;
- rk_screen *screen = &fb_drv->screen;
+ rk_screen *screen = lcdc_dev->screen;
if(!screen)
{
printk(KERN_ERR "screen is null!\n");
return -ENOENT;
}
- if(!strcmp(fb_drv->name,"lcdc0"))
- {
- lcdc_dev = &(info->lcdc0);
- }
- else if(!strcmp(fb_drv->name,"lcdc1"))
- {
- lcdc_dev = &(info->lcdc1);
- }
-
-
if(layer_id==0)
{
- par = &(fb_drv->layer_par[0]);
+ par = &(dev_drv->layer_par[0]);
win0_set_par(lcdc_dev,screen,par);
}
else if(layer_id==1)
{
- par = &(fb_drv->layer_par[1]);
+ par = &(dev_drv->layer_par[1]);
win1_set_par(lcdc_dev,screen,par);
}
int rk30_lcdc_pan_display(struct rk_lcdc_device_driver * dev_drv,int layer_id)
{
- struct rk30_lcdc_device *lcdc_dev=NULL;
- struct lcdc_info * info = platform_get_drvdata(g_lcdc_pdev);
+ struct rk30_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk30_lcdc_device,driver);
struct layer_par *par = NULL;
- rk_screen *screen = &dev_drv->screen;
+ rk_screen *screen = lcdc_dev->screen;
if(!screen)
{
printk(KERN_ERR "screen is null!\n");
return -ENOENT;
}
- if(!strcmp(dev_drv->name,"lcdc0"))
- {
- lcdc_dev = &(info->lcdc0);
- }
- else if(!strcmp(dev_drv->name,"lcdc1"))
- {
- lcdc_dev = &(info->lcdc1);
- }
-
if(layer_id==0)
{
return 0;
}
-int rk30_lcdc_ioctl(unsigned int cmd, unsigned long arg,struct layer_par *layer_par)
+int rk30_lcdc_ioctl(struct rk_lcdc_device_driver * dev_drv,unsigned int cmd, unsigned long arg,int layer_id)
{
+ struct rk30_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk30_lcdc_device,driver);
+ u32 panel_size[2];
+ void __user *argp = (void __user *)arg;
+ switch(cmd)
+ {
+ case FB1_IOCTL_GET_PANEL_SIZE: //get panel size
+ panel_size[0] = lcdc_dev->screen->x_res;
+ panel_size[1] = lcdc_dev->screen->y_res;
+ if(copy_to_user(argp, panel_size, 8))
+ return -EFAULT;
+ break;
+ default:
+ break;
+ }
+
return 0;
}
return 0;
}
-static struct layer_par lcdc0_layer[] = {
- [0] = {
- .name = "win0",
- .id = 0,
- .support_3d = true,
- },
- [1] = {
- .name = "win1",
- .id = 1,
- .support_3d = false,
- },
-};
-static struct layer_par lcdc1_layer[] = {
+static struct layer_par lcdc_layer[] = {
[0] = {
.name = "win0",
.id = 0,
},
};
-static struct rk_lcdc_device_driver lcdc0_driver = {
- .name = "lcdc0",
- .layer_par = lcdc0_layer,
- .num_layer = ARRAY_SIZE(lcdc0_layer),
+static struct rk_lcdc_device_driver lcdc_driver = {
+ .name = "lcdc",
+ .layer_par = lcdc_layer,
+ .num_layer = ARRAY_SIZE(lcdc_layer),
.ioctl = rk30_lcdc_ioctl,
.suspend = rk30_lcdc_suspend,
.resume = rk30_lcdc_resume,
.blank = rk30_lcdc_blank,
.pan_display = rk30_lcdc_pan_display,
};
-static struct rk_lcdc_device_driver lcdc1_driver = {
- .name = "lcdc1",
- .layer_par = lcdc1_layer,
- .num_layer = ARRAY_SIZE(lcdc1_layer),
- .ioctl = rk30_lcdc_ioctl,
- .suspend = rk30_lcdc_suspend,
- .resume = rk30_lcdc_resume,
- .set_par = rk30_lcdc_set_par,
- .blank = rk30_lcdc_blank,
- .pan_display = rk30_lcdc_pan_display,
-};
static int __devinit rk30_lcdc_probe (struct platform_device *pdev)
{
- struct lcdc_info *inf = NULL;
+ struct rk30_lcdc_device *lcdc_dev=NULL;
+ rk_screen *screen;
struct resource *res = NULL;
struct resource *mem;
+
int ret = 0;
- g_lcdc_pdev = pdev; //set g_pdev
-
/*************Malloc rk30lcdc_inf and set it to pdev for drvdata**********/
- inf = kmalloc(sizeof(struct lcdc_info), GFP_KERNEL);
- if(!inf)
+ lcdc_dev = kzalloc(sizeof(struct rk30_lcdc_device), GFP_KERNEL);
+ if(!lcdc_dev)
{
- dev_err(&pdev->dev, ">>rk30 lcdc inf kmalloc fail!");
+ dev_err(&pdev->dev, ">>rk30 lcdc device kmalloc fail!");
return -ENOMEM;
}
- memset(inf, 0, sizeof(struct lcdc_info));
- platform_set_drvdata(pdev, inf);
-
+ platform_set_drvdata(pdev, lcdc_dev);
+ lcdc_dev->id = pdev->id;
+ screen = kzalloc(sizeof(rk_screen), GFP_KERNEL);
+ if(!screen)
+ {
+ dev_err(&pdev->dev, ">>rk30 lcdc screen kmalloc fail!");
+ ret = -ENOMEM;
+ goto err0;
+ }
+ else
+ {
+ lcdc_dev->screen = screen;
+ }
/****************get lcdc0 reg *************************/
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lcdc0 reg");
+ res = platform_get_resource(pdev, IORESOURCE_MEM,0);
if (res == NULL)
{
- dev_err(&pdev->dev, "failed to get io resource for lcdc0 \n");
+ dev_err(&pdev->dev, "failed to get io resource for lcdc%d \n",lcdc_dev->id);
ret = -ENOENT;
- goto err0;
+ goto err1;
}
- inf->lcdc0.reg_phy_base = res->start;
- inf->lcdc0.len = (res->end - res->start) + 1;
- mem = request_mem_region(inf->lcdc0.reg_phy_base, inf->lcdc0.len, pdev->name);
+ lcdc_dev->reg_phy_base = res->start;
+ mem = request_mem_region(lcdc_dev->reg_phy_base, resource_size(res), pdev->name);
if (mem == NULL)
{
- dev_err(&pdev->dev, "failed to request mem region for lcdc0\n");
+ dev_err(&pdev->dev, "failed to request mem region for lcdc%d\n",lcdc_dev->id);
ret = -ENOENT;
- goto err0;
- }
- inf->lcdc0.reg_vir_base = ioremap(inf->lcdc0.reg_phy_base, inf->lcdc0.len);
- if (inf->lcdc0.reg_vir_base == NULL)
- {
- dev_err(&pdev->dev, "ioremap of lcdc0 register failed\n");
- ret = -ENXIO;
goto err1;
}
- inf->lcdc0.preg = (LCDC_REG*)inf->lcdc0.reg_vir_base;
- printk("lcdc0 reg_phy_base = 0x%08x,reg_vir_base:0x%p\n", inf->lcdc0.reg_phy_base, inf->lcdc0.preg);
- /**************** get lcdc1 reg *************************/
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lcdc1 reg");
- if (res == NULL)
- {
- dev_err(&pdev->dev, "failed to get io resource for lcdc1\n");
- ret = -ENOENT;
- goto err2;
- }
- inf->lcdc1.reg_phy_base = res->start;
- inf->lcdc1.len = (res->end - res->start) + 1;
- mem = request_mem_region(inf->lcdc1.reg_phy_base, inf->lcdc1.len, pdev->name);
- if (mem == NULL)
- {
- dev_err(&pdev->dev, "failed to request memory region of lcdc1\n");
- ret = -ENOENT;
+ lcdc_dev->reg_vir_base = ioremap(lcdc_dev->reg_phy_base, resource_size(res));
+ if (lcdc_dev->reg_vir_base == NULL)
+ {
+ dev_err(&pdev->dev, "cannot map IO\n");
+ ret = -ENXIO;
goto err2;
- }
- inf->lcdc1.reg_vir_base = ioremap(inf->lcdc1.reg_phy_base, inf->lcdc1.len);
- if (inf->lcdc1.reg_vir_base == NULL)
- {
- dev_err(&pdev->dev, "ioremap of lcdc1 register failed\n");
- ret = -ENXIO;
- goto err3;
- }
- inf->lcdc1.preg = (LCDC_REG*)inf->lcdc1.reg_vir_base;
- printk("lcdc1 reg_phy_base = 0x%08x,reg_vir_base:0x%p\n", inf->lcdc1.reg_phy_base, inf->lcdc1.preg);
- /***************** LCDC driver ********/
- inf->lcdc0.driver = &lcdc0_driver;
- inf->lcdc0.driver->dev=&pdev->dev;
- inf->lcdc1.driver = &lcdc1_driver;
- inf->lcdc1.driver->dev=&pdev->dev;
+ }
+ 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 ********/
- set_lcd_info(&inf->lcdc0.driver->screen, NULL);
- set_lcd_info(&inf->lcdc1.driver->screen, NULL);
+ set_lcd_info(screen, NULL);
+ lcdc_dev->driver.screen = screen;
/***************** INIT LCDC ********/
- ret = init_rk30_lcdc(inf);
+ ret = init_rk30_lcdc(lcdc_dev);
if(ret < 0)
{
printk(KERN_ERR "init rk30 lcdc failed!\n");
- goto err4;
+ goto err3;
}
- ret = rk30_load_screen(&inf->lcdc0,1);
+ ret = rk30_load_screen(lcdc_dev,1);
if(ret < 0)
{
printk(KERN_ERR "rk30 load screen for lcdc0 failed!\n");
- goto err4;
+ goto err3;
}
- //rk30_load_screen(&inf->lcdc1,1);
/***************** lcdc register ********/
- ret = rk_fb_register(&lcdc0_driver);
+ ret = rk_fb_register(&(lcdc_dev->driver));
if(ret < 0)
{
printk(KERN_ERR "registe fb for lcdc0 failed!\n");
- goto err4;
+ goto err3;
}
- //rk_fb_register(&lcdc1_driver);
-
- printk("rk30 lcdc probe ok!\n");
+ printk("rk30 lcdc%d probe ok!\n",lcdc_dev->id);
return 0;
-err4:
- iounmap(inf->lcdc1.reg_vir_base);
+
err3:
- release_mem_region(inf->lcdc1.reg_phy_base,inf->lcdc1.len);
+ iounmap(lcdc_dev->reg_vir_base);
err2:
- iounmap(inf->lcdc0.reg_vir_base);
+ release_mem_region(lcdc_dev->reg_phy_base,resource_size(res));
err1:
- release_mem_region(inf->lcdc0.reg_phy_base,inf->lcdc0.len);
+ kfree(screen);
err0:
platform_set_drvdata(pdev, NULL);
- kfree(inf);
+ kfree(lcdc_dev);
return ret;
}
static int __init rk30_lcdc_init(void)
{
- //wake_lock_init(&idlelock, WAKE_LOCK_IDLE, "fb");
return platform_driver_register(&rk30lcdc_driver);
}
#define CalScale(x, y) (((u32)x*0x1000)/y)
struct rk30_lcdc_device{
- struct rk_lcdc_device_driver *driver;
- /* LCDC reg base address and backup reg */
- LCDC_REG *preg;
- LCDC_REG regbak;
+ int id;
+ struct rk_lcdc_device_driver driver;
+ rk_screen *screen;
+
+ LCDC_REG *preg; // LCDC reg base address and backup reg
+ LCDC_REG regbak;
void __iomem *reg_vir_base; // virtual basic address of lcdc register
u32 reg_phy_base; // physical basic address of lcdc register
u32 pixclock;
};
-
struct lcdc_info{
/*LCD CLK*/
struct rk30_lcdc_device lcdc0;
* drivers/video/rockchip/rk_fb.c
*
* Copyright (C) 2012 ROCKCHIP, Inc.
- *
+ *Author:yzq<yzq@rock-chips.com>
+ yxj<yxj@rock-chips.com>
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
#include <linux/device.h>
#include <linux/fb.h>
#include <linux/init.h>
-#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/backlight.h>
-#include <linux/timer.h>
-#include <linux/time.h>
-#include <linux/wait.h>
#include <linux/earlysuspend.h>
-#include <linux/cpufreq.h>
-#include <linux/wakelock.h>
-
-#include <asm/io.h>
#include <asm/div64.h>
#include <asm/uaccess.h>
-#include <asm/cacheflush.h>
-
-#include <mach/iomux.h>
-#include <mach/gpio.h>
#include <mach/board.h>
-#include <mach/pmu.h>
#include "../display/screen/screen.h"
#include "rk_fb.h"
fb1 and fb3 are used for video play,the buffer is alloc by android,and
pass the phy addr to fix.smem_start by ioctl
****************************************************************************/
+
+static 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;
+}
static int rk_fb_open(struct fb_info *info,int user)
{
struct rk_fb_inf *inf = dev_get_drvdata(info->device);
struct fb_fix_screeninfo *fix = &info->fix;
int layer_id;
if(!strcmp(fix->id,"fb1")){
- dev_drv = inf->rk_lcdc_device[0];
+ dev_drv = inf->lcdc_dev_drv[0];
layer_id = 0;
dev_drv->blank(dev_drv,1,FB_BLANK_NORMAL); //when open fb1,defautl close fb0 layer win1
dev_drv->blank(dev_drv,layer_id,FB_BLANK_UNBLANK); //open fb1 layer win0
static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
{
- struct rk_fb_inf *inf = dev_get_drvdata(info->device);
struct fb_fix_screeninfo *fix = &info->fix;
- struct rk_lcdc_device_driver * dev_drv = NULL;
+ struct rk_lcdc_device_driver * dev_drv = (struct rk_lcdc_device_driver * )info->par;
struct layer_par *par = NULL;
int layer_id = 0;
u32 xoffset = var->xoffset; // offset from virtual to visible
u32 yoffset = var->yoffset;
u32 xvir = var->xres_virtual;
u8 data_format = var->nonstd&0xff;
- if(!strcmp(fix->id,"fb1")){
- dev_drv = inf->rk_lcdc_device[0];
- par = &dev_drv->layer_par[0];
- layer_id = 0;
- }else if(!strcmp(fix->id,"fb0")){
- dev_drv = inf->rk_lcdc_device[0];
- par = &dev_drv->layer_par[1];
- layer_id = 1;
- }else if(!strcmp(fix->id,"fb3")){
- dev_drv = inf->rk_lcdc_device[1];
- par = &dev_drv->layer_par[0];
- layer_id = 0;
- }else if(!strcmp(fix->id,"fb2")){
- dev_drv = inf->rk_lcdc_device[1];
- par = &dev_drv->layer_par[1];
- layer_id = 1;
- }else{
- dev_drv = inf->rk_lcdc_device[0];
- par = &dev_drv->layer_par[1];
- layer_id = 0;
+ layer_id = get_fb_layer_id(fix);
+ if(layer_id < 0)
+ {
+ return -ENODEV;
+ }
+ else
+ {
+ par = &dev_drv->layer_par[layer_id];
}
switch (par->format)
{
printk("un supported format:0x%x\n",data_format);
return -EINVAL;
}
+
dev_drv->pan_display(dev_drv,layer_id);
+
return 0;
}
-static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,
- unsigned long arg)
+static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,unsigned long arg)
{
struct rk_fb_inf *inf = dev_get_drvdata(info->device);
struct fb_fix_screeninfo *fix = &info->fix;
- struct rk_lcdc_device_driver *dev_drv = NULL;
+ struct rk_lcdc_device_driver *dev_drv = (struct rk_lcdc_device_driver * )info->par;
u32 yuv_phy[2];
- u32 panel_size[2];
void __user *argp = (void __user *)arg;
fbprintk(">>>>>> %s : cmd:0x%x \n",__FUNCTION__,cmd);
CHK_SUSPEND(inf);
- if(!strcmp(fix->id,"fb1")){
- dev_drv = inf->rk_lcdc_device[0];
- }else if(!strcmp(fix->id,"fb0")){
- dev_drv = inf->rk_lcdc_device[0];
- }else if(!strcmp(fix->id,"fb3")){
- dev_drv = inf->rk_lcdc_device[1];
- }else if(!strcmp(fix->id,"fb2")){
- dev_drv = inf->rk_lcdc_device[1];
- }else{
- dev_drv = inf->rk_lcdc_device[0];
- }
+
switch(cmd)
{
case FBIOPUT_FBPHYADD:
break;
case FBIOGET_OVERLAY_STATE:
return inf->video_mode;
- case FB1_IOCTL_GET_PANEL_SIZE: //get panel size
- panel_size[0] = dev_drv->screen.x_res;
- panel_size[1] = dev_drv->screen.y_res;
- if(copy_to_user(argp, panel_size, 8))
- return -EFAULT;
- break;
case FBIOGET_SCREEN_STATE:
case FBIOPUT_SET_CURSOR_EN:
case FBIOPUT_SET_CURSOR_POS:
case FBIOGET_IDLEFBUff_16OR32:
case FBIOSET_COMPOSE_LAYER_COUNTS:
case FBIOGET_COMPOSE_LAYER_COUNTS:
- default:
+ default:
+ dev_drv->ioctl(dev_drv,cmd,arg,0);
break;
}
return 0;
static int rk_fb_blank(int blank_mode, struct fb_info *info)
{
- struct rk_fb_inf *inf = dev_get_drvdata(info->device);
- struct rk_lcdc_device_driver *dev_drv = NULL;
- struct fb_fix_screeninfo *fix = &info->fix;
- int layer_id;
- if(!strcmp(fix->id,"fb1")){
- dev_drv = inf->rk_lcdc_device[0];
- layer_id = 0;
- }else if(!strcmp(fix->id,"fb0")){
- dev_drv = inf->rk_lcdc_device[0];
- layer_id = 1;
- }else if(!strcmp(fix->id,"fb3")){
- dev_drv = inf->rk_lcdc_device[1];
- layer_id = 0;
- }else if(!strcmp(fix->id,"fb2")){
- dev_drv = inf->rk_lcdc_device[1];
- layer_id = 1;
- }else{
- dev_drv = inf->rk_lcdc_device[0];
- layer_id = 0;
- }
- dev_drv->blank(dev_drv,layer_id,blank_mode);
+ struct rk_lcdc_device_driver *dev_drv = (struct rk_lcdc_device_driver * )info->par;
+ struct fb_fix_screeninfo *fix = &info->fix;
+ int layer_id;
+ layer_id = get_fb_layer_id(fix);
+ if(layer_id < 0)
+ {
+ return -ENODEV;
+ }
+
+ dev_drv->blank(dev_drv,layer_id,blank_mode);
- return 0;
+ return 0;
}
static int rk_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
static int rk_fb_set_par(struct fb_info *info)
{
- struct rk_fb_inf *inf = dev_get_drvdata(info->device);
struct fb_var_screeninfo *var = &info->var;
struct fb_fix_screeninfo *fix = &info->fix;
- struct rk_lcdc_device_driver * dev_drv = NULL;
+ struct rk_lcdc_device_driver * dev_drv = (struct rk_lcdc_device_driver * )info->par;
struct layer_par *par = NULL;
- rk_screen *screen = NULL;
+ rk_screen *screen =dev_drv->screen;
int layer_id = 0;
- u32 smem_len=0;
u32 cblen = 0,crlen = 0;
u16 xsize =0,ysize = 0; //winx display window height/width --->LCDC_WINx_DSP_INFO
u32 xoffset = var->xoffset; // offset from virtual to visible
u32 yvir = var->yres_virtual;
u8 data_format = var->nonstd&0xff;
- if(!strcmp(fix->id,"fb1")){
- dev_drv = inf->rk_lcdc_device[0];
- par = &dev_drv->layer_par[0];
- layer_id = 0;
- }else if(!strcmp(fix->id,"fb0")){
- dev_drv = inf->rk_lcdc_device[0];
- par = &dev_drv->layer_par[1];
- layer_id = 1;
- }else if(!strcmp(fix->id,"fb3")){
- dev_drv = inf->rk_lcdc_device[1];
- par = &dev_drv->layer_par[0];
- layer_id = 0;
- }else if(!strcmp(fix->id,"fb2")){
- dev_drv = inf->rk_lcdc_device[1];
- par = &dev_drv->layer_par[1];
- layer_id = 1;
- }else{
- dev_drv = inf->rk_lcdc_device[0];
- par = &dev_drv->layer_par[1];
- layer_id = 0;
+ layer_id = get_fb_layer_id(fix);
+ if(layer_id < 0)
+ {
+ return -ENODEV;
+ }
+ else
+ {
+ par = &dev_drv->layer_par[layer_id];
}
- screen = &dev_drv->screen;
-// printk("%s>>>>>>>%s\n",__func__,fix->id);
if((!strcmp(fix->id,"fb0"))||(!strcmp(fix->id,"fb2"))) //four ui
{
- xsize = screen->x_res;
+ xsize = screen->x_res;
ysize = screen->y_res;
}
else if((!strcmp(fix->id,"fb1"))||(!strcmp(fix->id,"fb3")))
}
#endif
- smem_len = fix->line_length * yvir + cblen + crlen;
- // map_size = PAGE_ALIGN(smem_len);
-
- //fix->smem_len = smem_len;
par->xpos = xpos;
par->ypos = ypos;
par->xsize = xsize;
unsigned transp, struct fb_info *info)
{
unsigned int val;
-// fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__);
switch (info->fix.visual) {
case FB_VISUAL_TRUECOLOR:
static int request_fb_buffer(struct fb_info *fbi,int fb_id)
{
struct resource *res;
+ struct resource *mem;
int ret = 0;
switch(fb_id)
{
dev_err(&g_fb_pdev->dev, "failed to get win0 memory \n");
ret = -ENOENT;
}
+
fbi->fix.smem_start = res->start;
fbi->fix.smem_len = res->end - res->start + 1;
+ mem = request_mem_region(res->start, resource_size(res), g_fb_pdev->name);
fbi->screen_base = ioremap(res->start, fbi->fix.smem_len);
memset(fbi->screen_base, 0, fbi->fix.smem_len);
- printk("phy:%lx\n>>vir:%p\n",fbi->fix.smem_start,fbi->screen_base);
+ printk("fb%d:phy:%lx>>vir:%p\n",fb_id,fbi->fix.smem_start,fbi->screen_base);
#ifdef CONFIG_FB_WORK_IPP
/* alloc ipp buf for rotate */
res = platform_get_resource_byname(g_fb_pdev, IORESOURCE_MEM, "ipp buf");
struct fb_info *fbi;
int i=0,ret = 0;
int lcdc_id = 0;
- if(NULL==dev_drv){
- printk("null lcdc device driver?");
- return -ENOENT;
- }
- for(i=0;i<RK30_MAX_LCDC_SUPPORT;i++){
- if(NULL==fb_inf->rk_lcdc_device[i]){
- fb_inf->rk_lcdc_device[i] = dev_drv;
- fb_inf->rk_lcdc_device[i]->id = i;
- fb_inf->num_lcdc++;
- break;
- }
- }
- if(i==RK30_MAX_LCDC_SUPPORT){
- printk("rk_fb_register lcdc out of support %d",i);
- return -ENOENT;
- }
- lcdc_id = i;
+ if(NULL==dev_drv)
+ {
+ printk("null lcdc device driver?");
+ return -ENOENT;
+ }
+ for(i=0;i<RK30_MAX_LCDC_SUPPORT;i++)
+ {
+ if(NULL==fb_inf->lcdc_dev_drv[i])
+ {
+ fb_inf->lcdc_dev_drv[i] = dev_drv;
+ fb_inf->lcdc_dev_drv[i]->id = i;
+ fb_inf->num_lcdc++;
+ break;
+ }
+ }
+ if(i==RK30_MAX_LCDC_SUPPORT)
+ {
+ printk("rk_fb_register lcdc out of support %d",i);
+ return -ENOENT;
+ }
+ lcdc_id = i;
/************fb set,one layer one fb ***********/
for(i=0;i<dev_drv->num_layer;i++)
fbi = NULL;
ret = -ENOMEM;
}
+ fbi->par = dev_drv;
fbi->var = def_var;
fbi->fix = def_fix;
sprintf(fbi->fix.id,"fb%d",fb_inf->num_fb);
- fbi->var.xres = fb_inf->rk_lcdc_device[lcdc_id]->screen.x_res;
- fbi->var.yres = fb_inf->rk_lcdc_device[lcdc_id]->screen.y_res;
+ fbi->var.xres = fb_inf->lcdc_dev_drv[lcdc_id]->screen->x_res;
+ fbi->var.yres = fb_inf->lcdc_dev_drv[lcdc_id]->screen->y_res;
fbi->var.bits_per_pixel = 16;
- fbi->var.xres_virtual = fb_inf->rk_lcdc_device[lcdc_id]->screen.x_res;
- fbi->var.yres_virtual = fb_inf->rk_lcdc_device[lcdc_id]->screen.y_res;
- fbi->var.width = fb_inf->rk_lcdc_device[lcdc_id]->screen.width;
- fbi->var.height = fb_inf->rk_lcdc_device[lcdc_id]->screen.height;
- fbi->var.pixclock =fb_inf->rk_lcdc_device[lcdc_id]->pixclock;
- fbi->var.left_margin = fb_inf->rk_lcdc_device[lcdc_id]->screen.left_margin;
- fbi->var.right_margin = fb_inf->rk_lcdc_device[lcdc_id]->screen.right_margin;
- fbi->var.upper_margin = fb_inf->rk_lcdc_device[lcdc_id]->screen.upper_margin;
- fbi->var.lower_margin = fb_inf->rk_lcdc_device[lcdc_id]->screen.lower_margin;
- fbi->var.vsync_len = fb_inf->rk_lcdc_device[lcdc_id]->screen.vsync_len;
- fbi->var.hsync_len = fb_inf->rk_lcdc_device[lcdc_id]->screen.hsync_len;
+ fbi->var.xres_virtual = fb_inf->lcdc_dev_drv[lcdc_id]->screen->x_res;
+ fbi->var.yres_virtual = fb_inf->lcdc_dev_drv[lcdc_id]->screen->y_res;
+ fbi->var.width = fb_inf->lcdc_dev_drv[lcdc_id]->screen->width;
+ fbi->var.height = fb_inf->lcdc_dev_drv[lcdc_id]->screen->height;
+ fbi->var.pixclock =fb_inf->lcdc_dev_drv[lcdc_id]->pixclock;
+ fbi->var.left_margin = fb_inf->lcdc_dev_drv[lcdc_id]->screen->left_margin;
+ fbi->var.right_margin = fb_inf->lcdc_dev_drv[lcdc_id]->screen->right_margin;
+ fbi->var.upper_margin = fb_inf->lcdc_dev_drv[lcdc_id]->screen->upper_margin;
+ fbi->var.lower_margin = fb_inf->lcdc_dev_drv[lcdc_id]->screen->lower_margin;
+ fbi->var.vsync_len = fb_inf->lcdc_dev_drv[lcdc_id]->screen->vsync_len;
+ 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->rk_lcdc_device[lcdc_id]->layer_par[i].pseudo_pal;
+ fbi->pseudo_palette = fb_inf->lcdc_dev_drv[lcdc_id]->layer_par[i].pseudo_pal;
request_fb_buffer(fbi,fb_inf->num_fb);
ret = register_framebuffer(fbi);
if(ret<0)
return -ENOENT;
}
for(i=0;i<RK30_MAX_LCDC_SUPPORT;i++){
- if(fb_inf->rk_lcdc_device[i]->id == i ){
- fb_inf->rk_lcdc_device[i] = NULL;
+ if(fb_inf->lcdc_dev_drv[i]->id == i ){
+ fb_inf->lcdc_dev_drv[i] = NULL;
fb_inf->num_lcdc--;
break;
}
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->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;
+
+ return 0;
+}
static int __devinit rk_fb_probe (struct platform_device *pdev)
{
struct rk_fb_inf *fb_inf = NULL;
};
struct rk_lcdc_device_driver{
- const char *name;
+ char name[6];
int id;
struct device *dev;
struct layer_par *layer_par;
int num_layer;
- rk_screen screen;
+ rk_screen *screen;
u32 pixclock;
- int (*ioctl)(unsigned int cmd, unsigned long arg,struct layer_par *layer_par);
+ int (*ioctl)(struct rk_lcdc_device_driver *dev_drv, unsigned int cmd,unsigned long arg,int layer_id);
int (*suspend)(struct layer_par *layer_par);
int (*resume)(struct layer_par *layer_par);
- int (*blank)(struct rk_lcdc_device_driver *rk_fb_dev_drv,int layer_id,int blank_mode);
- int (*set_par)(struct rk_lcdc_device_driver *rk_fb_dev_drv,int layer_id);
- int (*pan_display)(struct rk_lcdc_device_driver *rk_fb_dev_drv,int layer_id);
+ int (*blank)(struct rk_lcdc_device_driver *dev_drv,int layer_id,int blank_mode);
+ int (*set_par)(struct rk_lcdc_device_driver *dev_drv,int layer_id);
+ int (*pan_display)(struct rk_lcdc_device_driver *dev_drv,int layer_id);
};
struct fb_info *fb[RK_MAX_FB_SUPPORT];
int num_fb;
- struct rk_lcdc_device_driver *rk_lcdc_device[RK30_MAX_LCDC_SUPPORT];
+ struct rk_lcdc_device_driver *lcdc_dev_drv[RK30_MAX_LCDC_SUPPORT];
int num_lcdc;
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);
#endif