u32 uv_addr;
y_addr = par->smem_start + par->y_offset;
uv_addr = par->cbr_start + par->c_offset;
- DBG(2,KERN_INFO "%s:y_addr:0x%x>>uv_addr:0x%x\n",__func__,y_addr,uv_addr);
+ DBG(2,KERN_INFO "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",lcdc_dev->id,__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);
u32 uv_addr;
y_addr = par->smem_start + par->y_offset;
uv_addr = par->cbr_start + par->c_offset;
- DBG(2,KERN_INFO "%s>>y_addr:0x%x>>uv_addr:0x%x\n",__func__,y_addr,uv_addr);
+ DBG(2,KERN_INFO "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",lcdc_dev->id,__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);
par = dev_drv->layer_par[1];
win1_display(lcdc_dev,par);
}
- if((dev_drv->first_frame) && (dev_drv->id == 0)) //this is the first frame of the system ,enable frame start interrupt
+ if((dev_drv->first_frame)) //this is the first frame of the system ,enable frame start interrupt
{
dev_drv->first_frame = 0;
LcdMskReg(lcdc_dev,INT_STATUS,m_FRM_START_INT_CLEAR |m_FRM_START_INT_EN ,
}
- if(!dev_drv->id) //only sync for lcdc0
+ spin_lock_irqsave(&dev_drv->cpl_lock,flags);
+ init_completion(&dev_drv->frame_done);
+ spin_unlock_irqrestore(&dev_drv->cpl_lock,flags);
+ timeout = wait_for_completion_interruptible_timeout(&dev_drv->frame_done,msecs_to_jiffies(25));
+ if(!timeout)
{
- spin_lock_irqsave(&dev_drv->cpl_lock,flags);
- init_completion(&dev_drv->frame_done);
- spin_unlock_irqrestore(&dev_drv->cpl_lock,flags);
- timeout = wait_for_completion_interruptible_timeout(&dev_drv->frame_done,msecs_to_jiffies(25));
- if(!timeout)
- {
- printk(KERN_ERR "wait for new frame start time out!\n");
- return -ETIMEDOUT;
- }
- else if(timeout < 0)
- {
- return timeout;
- }
+ printk(KERN_ERR "wait for new frame start time out!\n");
+ return -ETIMEDOUT;
+ }
+ else if(timeout < 0)
+ {
+ return timeout;
}
+
return 0;
}
LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01);
return 0;
}
-
static irqreturn_t rk30_lcdc_isr(int irq, void *dev_id)
{
struct rk30_lcdc_device *lcdc_dev = (struct rk30_lcdc_device *)dev_id;
#include <asm/div64.h>
#include <asm/uaccess.h>
#include<linux/rk_fb.h>
+#include <plat/ipp.h>
#include "hdmi/rk_hdmi.h"
#if 1
#define CHK_SUSPEND(drv) \
- if(atomic_dec_and_test(&drv->in_suspend)) { \
+ if(atomic_read(&drv->in_suspend)) { \
printk(">>>>>> fb is in suspend! return! \n"); \
return -EPERM; \
}
return 0;
}
+static void fb_copy_by_ipp(struct fb_info *dst_info, struct fb_info *src_info,int offset)
+{
+ struct rk29_ipp_req ipp_req;
+ u32 dstoffset = 0;
+ memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
+ ipp_req.src0.YrgbMst = src_info->fix.smem_start + offset;
+ ipp_req.src0.w = src_info->var.xres;
+ ipp_req.src0.h = src_info->var.yres;
+
+ ipp_req.dst0.YrgbMst = dst_info->fix.smem_start + offset;
+ ipp_req.dst0.w = src_info->var.xres;
+ ipp_req.dst0.h = src_info->var.yres;
+
+ ipp_req.src_vir_w = src_info->var.xres_virtual;
+ ipp_req.dst_vir_w = src_info->var.xres_virtual;
+ ipp_req.timeout = 100;
+ ipp_req.flag = IPP_ROT_0;
+ ipp_blit_sync(&ipp_req);
+
+}
+static void hdmi_post_work(struct work_struct *work)
+{
+
+ struct rk_fb_inf *inf = container_of(to_delayed_work(work), struct rk_fb_inf, delay_work);
+ struct rk_lcdc_device_driver * dev_drv = inf->lcdc_dev_drv[1];
+ dev_drv->pan_display(dev_drv,1);
+
+}
static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
{
u32 yoffset = var->yoffset;
u32 xvir = var->xres_virtual;
u8 data_format = var->nonstd&0xff;
- layer_id = get_fb_layer_id(fix);
- #if defined(CONFIG_HDMI_RK30)
- if(hdmi_get_hotplug())
- {
- if(inf->num_fb >= 2)
- {
- info2 = inf->fb[2];
- dev_drv1 = (struct rk_lcdc_device_driver * )info2->par;
- }
- }
- #endif
CHK_SUSPEND(dev_drv);
+ layer_id = get_fb_layer_id(fix);
if(layer_id < 0)
{
return -ENODEV;
else
{
par = dev_drv->layer_par[layer_id];
- if(dev_drv1)
- {
- par2 = dev_drv1->layer_par[layer_id];
- }
}
switch (par->format)
{
}
#if defined(CONFIG_HDMI_RK30)
- if(hdmi_get_hotplug())
- {
- par2->y_offset = par->y_offset;
- dev_drv1->pan_display(dev_drv1,layer_id);
- }
+ #if defined(CONFIG_DUAL_DISP_IN_KERNEL)
+ if(hdmi_get_hotplug())
+ {
+ if(inf->num_fb >= 2)
+ {
+ info2 = inf->fb[2];
+ dev_drv1 = (struct rk_lcdc_device_driver * )info2->par;
+ par2 = dev_drv1->layer_par[layer_id];
+ par2->y_offset = par->y_offset;
+ //memcpy(info2->screen_base+par2->y_offset,info->screen_base+par->y_offset,
+ // var->xres*var->yres*var->bits_per_pixel>>3);
+ fb_copy_by_ipp(info2,info,par->y_offset);
+ dev_drv1->pan_display(dev_drv1,layer_id);
+ //queue_delayed_work(inf->workqueue, &inf->delay_work,0);
+ }
+ }
+ #endif
#endif
dev_drv->pan_display(dev_drv,layer_id);
return 0;
{
struct rk_lcdc_device_driver *dev_drv = (struct rk_lcdc_device_driver * )info->par;
CHK_SUSPEND(dev_drv);
-
- if( 0==var->xres_virtual || 0==var->yres_virtual ||
+ if( 0==var->xres_virtual || 0==var->yres_virtual ||
0==var->xres || 0==var->yres || var->xres<16 ||
((16!=var->bits_per_pixel)&&(32!=var->bits_per_pixel)) )
{
var->pixclock = dev_drv->pixclock;
CHK_SUSPEND(dev_drv);
#if defined(CONFIG_HDMI_RK30)
- if(hdmi_get_hotplug())
- {
- if(inf->num_fb >= 2)
+ #if defined(CONFIG_DUAL_DISP_IN_KERNEL)
+ if(hdmi_get_hotplug())
{
- info2 = inf->fb[2];
- dev_drv1 = (struct rk_lcdc_device_driver * )info2->par;
+ if(inf->num_fb >= 2)
+ {
+ info2 = inf->fb[2];
+ dev_drv1 = (struct rk_lcdc_device_driver * )info2->par;
+ }
}
- }
+ #endif
#endif
layer_id = get_fb_layer_id(fix);
if(layer_id < 0)
par->yvir = var->yres_virtual;
#if defined(CONFIG_HDMI_RK30)
- if(hdmi_get_hotplug())
- {
- par2->xact = par->xact;
- par2->yact = par->yact;
- par2->format = par->format;
- dev_drv1->set_par(dev_drv1,layer_id);
- }
+ #if defined(CONFIG_DUAL_DISP_IN_KERNEL)
+ if(hdmi_get_hotplug())
+ {
+ par2->xact = par->xact;
+ par2->yact = par->yact;
+ par2->format = par->format;
+ dev_drv1->set_par(dev_drv1,layer_id);
+ }
+ #endif
#endif
dev_drv->set_par(dev_drv,layer_id);
{
struct rk_fb_inf *inf = platform_get_drvdata(g_fb_pdev);
struct fb_info *info = NULL;
+ struct fb_info *pmy_info = NULL;
struct rk_lcdc_device_driver * dev_drv = NULL;
struct fb_var_screeninfo *pmy_var = NULL; //var for primary screen
struct fb_var_screeninfo *hdmi_var = NULL;
hdmi_var->xres = pmy_var->xres;
hdmi_var->yres = pmy_var->yres;
hdmi_var->nonstd = pmy_var->nonstd;
- hdmi_fix->smem_start = pmy_fix->smem_start;
+ //hdmi_fix->smem_start = pmy_fix->smem_start;
dev_drv = (struct rk_lcdc_device_driver * )info->par;
ret = dev_drv->load_screen(dev_drv,1);
ret = info->fbops->fb_open(info,1);
ret = info->fbops->fb_set_par(info);
-
+ #if defined(CONFIG_DUAL_DISP_IN_KERNEL)
+ pmy_info = inf->fb[0];
+ pmy_info->fbops->fb_pan_display(pmy_var,pmy_info);
+ #endif
}
static int rk_request_fb_buffer(struct fb_info *fbi,int fb_id)
fb_inf->mach_info = mach_info;
if(mach_info->io_init)
mach_info->io_init(NULL);
+#if defined(CONFIG_HDMI_RK30)
+ #if defined(CONFIG_DUAL_DISP_IN_KERNEL)
+ fb_inf->workqueue = create_singlethread_workqueue("hdmi_post");
+ INIT_DELAYED_WORK(&(fb_inf->delay_work), hdmi_post_work);
+ #endif
+#endif
+
#ifdef CONFIG_HAS_EARLYSUSPEND
suspend_info.inf = fb_inf;
register_early_suspend(&suspend_info.early_suspend);