static int dbg_thresd = 0;
+module_param(dbg_thresd, int, S_IRUGO|S_IWUSR);
#define DBG(x...) do { if(unlikely(dbg_thresd)) printk(KERN_INFO x); } while (0)
u16 right_margin = screen->right_margin;
u16 lower_margin = screen->lower_margin;
u16 x_res = screen->x_res, y_res = screen->y_res;
- u32 aclk_rate = 150000000;
// set the rgb or mcu
screen->init();
}
printk("%s>>>>>ok!\n",__func__);
+ return 0;
}
static int mcu_refresh(struct rk30_lcdc_device *lcdc_dev)
return 0;
}
+static int win0_display(struct rk30_lcdc_device *lcdc_dev,struct layer_par *par )
+{
+ u32 y_addr;
+ u32 uv_addr;
+ y_addr = par->smem_start + par->y_offset;
+ uv_addr = par->cbr_start + par->c_offset;
+ DBG(KERN_INFO "%s:y_addr:0x%x>>uv_addr:0x%x\n",__func__,y_addr,uv_addr);
+ LcdWrReg(lcdc_dev, WIN0_YRGB_MST0, y_addr);
+ LcdWrReg(lcdc_dev,WIN0_CBR_MST0,uv_addr);
+ LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01); // write any value to REG_CFG_DONE let config become effective
+ return 0;
+
+}
+
+static int win1_display(struct rk30_lcdc_device *lcdc_dev,struct layer_par *par )
+{
+ u32 y_addr;
+ u32 uv_addr;
+ y_addr = par->smem_start + par->y_offset;
+ uv_addr = par->cbr_start + par->c_offset;
+ DBG(KERN_INFO "%s>>y_addr:0x%x>>uv_addr:0x%x\n",__func__,y_addr,uv_addr);
+ LcdWrReg(lcdc_dev, WIN1_YRGB_MST, y_addr);
+ LcdWrReg(lcdc_dev,WIN1_CBR_MST,uv_addr);
+ LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01);
+
+ return 0;
+}
+
static int win0_set_par(struct rk30_lcdc_device *lcdc_dev,rk_screen *screen,
struct layer_par *par )
{
u32 xact, yact, xvir, yvir, xpos, ypos;
u32 ScaleYrgbX,ScaleYrgbY, ScaleCbrX, ScaleCbrY;
- u32 y_addr,uv_addr;
-
+
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;
- y_addr = par->smem_start + par->y_offset;
- uv_addr = par->cbr_start + par->c_offset;
+
ScaleYrgbX = CalScale(xact, par->xsize); //both RGB and yuv need this two factor
ScaleYrgbY = CalScale(yact, par->ysize);
break;
}
- DBG("%s>>format:%d>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>ypos:%d>>y_addr:0x%x>>uv_addr:0x%x\n",
- __func__,par->format,xact,yact,par->xsize,par->ysize,xvir,yvir,ypos,y_addr,uv_addr);
- LcdWrReg(lcdc_dev, WIN0_YRGB_MST0, y_addr);
- LcdWrReg(lcdc_dev,WIN0_CBR_MST0,uv_addr);
+ DBG("%s>>format:%d>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>ypos:%d>>\n",
+ __func__,par->format,xact,yact,par->xsize,par->ysize,xvir,yvir,ypos);
LcdMskReg(lcdc_dev,SYS_CTRL1, m_W0_FORMAT , v_W0_FORMAT(par->format)); //(inf->video_mode==0)
LcdWrReg(lcdc_dev, WIN0_ACT_INFO,v_ACT_WIDTH(xact) | v_ACT_HEIGHT(yact));
LcdWrReg(lcdc_dev, WIN0_DSP_ST, v_DSP_STX(xpos) | v_DSP_STY(ypos));
LcdWrReg(lcdc_dev, WIN0_VIR,v_RGB888_VIRWIDTH(xvir));
break;
}
-
- LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01);
return 0;
{
u32 xact, yact, xvir, yvir, xpos, ypos;
u32 ScaleYrgbX,ScaleYrgbY, ScaleCbrX, ScaleCbrY;
- u32 y_addr,uv_addr;
- xact = par->xact; /* visible resolution */
+
+ xact = par->xact;
yact = par->yact;
- xvir = par->xvir; /* virtual resolution */
+ xvir = par->xvir;
yvir = par->yvir;
xpos = par->xpos+screen->left_margin + screen->hsync_len;
ypos = par->ypos+screen->upper_margin + screen->vsync_len;
- y_addr = par->smem_start + par->y_offset;
- uv_addr = par->cbr_start + par->c_offset;
ScaleYrgbX = CalScale(xact, par->xsize);
ScaleYrgbY = CalScale(yact, par->ysize);
- DBG("%s>>format:%d>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>ypos:%d>>y_addr:0x%x>>uv_addr:0x%x\n",
- __func__,par->format,xact,yact,par->xsize,par->ysize,xvir,yvir,ypos,y_addr,uv_addr);
+ DBG("%s>>format:%d>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>ypos:%d>>\n",
+ __func__,par->format,xact,yact,par->xsize,par->ysize,xvir,yvir,ypos);
switch (par->format)
{
case YUV422:// yuv422
LcdWrReg(lcdc_dev, WIN1_SCL_FACTOR_YRGB, v_X_SCL_FACTOR(ScaleYrgbX) | v_Y_SCL_FACTOR(ScaleYrgbY));
LcdWrReg(lcdc_dev, WIN1_SCL_FACTOR_CBR, v_X_SCL_FACTOR(ScaleCbrX) | v_Y_SCL_FACTOR(ScaleCbrY));
LcdMskReg(lcdc_dev, SYS_CTRL1, m_W1_EN|m_W1_FORMAT, v_W1_EN(1)|v_W1_FORMAT(par->format));
- LcdWrReg(lcdc_dev, WIN1_YRGB_MST, y_addr);
- LcdWrReg(lcdc_dev,WIN1_CBR_MST,uv_addr);
LcdWrReg(lcdc_dev, WIN1_ACT_INFO,v_ACT_WIDTH(xact) | v_ACT_HEIGHT(yact));
LcdWrReg(lcdc_dev, WIN1_DSP_ST,v_DSP_STX(xpos) | v_DSP_STY(ypos));
LcdWrReg(lcdc_dev, WIN1_DSP_INFO,v_DSP_WIDTH(par->xsize) | v_DSP_HEIGHT(par->ysize));
LcdWrReg(lcdc_dev, WIN1_VIR,v_RGB888_VIRWIDTH(xvir));
break;
}
-
- LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01);
-
+
return 0;
}
static int rk30_lcdc_set_par(struct rk_lcdc_device_driver *fb_drv,int layer_id)
{
struct rk30_lcdc_device *lcdc_dev=NULL;
- struct layer_par *par = &fb_drv->layer_par[0];
- rk_screen *screen = &fb_drv->screen;
struct lcdc_info * info = platform_get_drvdata(g_lcdc_pdev);
+ struct layer_par *par = NULL;
+ rk_screen *screen = &fb_drv->screen;
+ if(!screen)
+ {
+ printk(KERN_ERR "screen is null!\n");
+ return -ENOENT;
+ }
if(!strcmp(fb_drv->name,"lcdc0"))
{
lcdc_dev = &(info->lcdc0);
lcdc_dev = &(info->lcdc1);
}
- if(!screen)
- {
- printk(KERN_ERR "screen is null!\n");
- }
+
if(layer_id==0)
{
- win0_set_par(lcdc_dev,screen,par);
+ par = &(fb_drv->layer_par[0]);
+ win0_set_par(lcdc_dev,screen,par);
}
else if(layer_id==1)
{
- win1_set_par(lcdc_dev,screen,&(fb_drv->layer_par[1]));
+ par = &(fb_drv->layer_par[1]);
+ win1_set_par(lcdc_dev,screen,par);
}
return 0;
}
-
-int rk30_lcdc_pan(struct rk_lcdc_device_driver * dev_drv,int layer_id)
+
+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 layer_par *par = NULL;
+ rk_screen *screen = &dev_drv->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)
+ {
+ par = &(dev_drv->layer_par[0]);
+ win0_display(lcdc_dev,par);
+ }
+ else if(layer_id==1)
+ {
+ par = &(dev_drv->layer_par[1]);
+ win1_display(lcdc_dev,par);
+ }
return 0;
}
.ioctl = rk30_lcdc_ioctl,
.suspend = rk30_lcdc_suspend,
.resume = rk30_lcdc_resume,
- .set_par = rk30_lcdc_set_par,
- .blank = rk30_lcdc_blank,
- .pan = rk30_lcdc_pan,
+ .set_par = rk30_lcdc_set_par,
+ .blank = rk30_lcdc_blank,
+ .pan_display = rk30_lcdc_pan_display,
};
static struct rk_lcdc_device_driver lcdc1_driver = {
.name = "lcdc1",
.ioctl = rk30_lcdc_ioctl,
.suspend = rk30_lcdc_suspend,
.resume = rk30_lcdc_resume,
- .set_par = rk30_lcdc_set_par,
- .blank = rk30_lcdc_blank,
- .pan = rk30_lcdc_pan,
+ .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)
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 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;
+ }
+ switch (par->format)
+ {
+ case ARGB888:
+ par->y_offset = (yoffset*xvir + xoffset)*4;
+ break;
+ case RGB888:
+ par->y_offset = (yoffset*xvir + xoffset)*3;
+ break;
+ case RGB565:
+ par->y_offset = (yoffset*xvir + xoffset)*2;
+ break;
+ case YUV422:
+ par->y_offset = yoffset*xvir + xoffset;
+ par->c_offset = par->y_offset;
+ break;
+ case YUV420:
+ par->y_offset = yoffset*xvir + xoffset;
+ par->c_offset = (yoffset>>1)*xvir + xoffset;
+ break;
+ case YUV444 : // yuv444
+ par->y_offset = yoffset*xvir + xoffset;
+ par->c_offset = yoffset*2*xvir +(xoffset<<1);
+ break;
+ default:
+ 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,
switch (data_format)
{
case HAL_PIXEL_FORMAT_RGBA_8888 : // rgb
+ case HAL_PIXEL_FORMAT_RGBX_8888:
par->format = ARGB888;
fix->line_length = 4 * xvir;
par->y_offset = (yoffset*xvir + xoffset)*4;
break;
- case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_RGB_888 :
par->format = RGB888;
- fix->line_length = 4 * xvir;
- par->y_offset = (yoffset*xvir + xoffset)*4;
+ fix->line_length = 3 * xvir;
+ par->y_offset = (yoffset*xvir + xoffset)*3;
break;
case HAL_PIXEL_FORMAT_RGB_565: //RGB565
par->format = RGB565;
fbi->fix.smem_len = res->end - res->start + 1;
fbi->screen_base = ioremap(res->start, fbi->fix.smem_len);
memset(fbi->screen_base, 0, fbi->fix.smem_len);
- printk("phy:%x\n>>vir:%x\n",fbi->fix.smem_start,fbi->screen_base);
+ printk("phy:%lx\n>>vir:%p\n",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");
fb_set_cmap(&fb_inf->fb[fb_inf->num_fb-2]->cmap, fb_inf->fb[fb_inf->num_fb-2]);
fb_show_logo(fb_inf->fb[fb_inf->num_fb-2], FB_ROTATE_UR);
fb_inf->fb[fb_inf->num_fb-2]->fbops->fb_blank(FB_BLANK_UNBLANK, fb_inf->fb[fb_inf->num_fb-2]);
+ fb_inf->fb[fb_inf->num_fb-2]->fbops->fb_pan_display(&(fb_inf->fb[fb_inf->num_fb-2]->var), fb_inf->fb[fb_inf->num_fb-2]);
}
#endif
return 0;