transp: { offset: 0, length: 0, },
};
+struct win_set {
+ volatile u32 y_offset;
+ volatile u32 c_offset;
+};
+
struct win0_par {
- u32 refcount;
- u32 pseudo_pal[16];
- u32 y_offset;
- u32 uv_offset;
+ u32 refcount;
+ u32 pseudo_pal[16];
+ u32 y_offset;
+ u32 c_offset;
u32 xpos; //size in panel
u32 ypos;
u32 xsize; //start point in panel
u32 ysize;
u32 format;
+ struct rw_semaphore sem;
+ wait_queue_head_t wait;
+ struct win_set mirror;
+ struct win_set displ;
+ struct win_set done;
+
u8 par_seted;
u8 addr_seted;
};
+/*
struct win1_par {
u32 refcount;
u32 pseudo_pal[16];
u32 format;
u32 addr_offset;
};
+*/
struct rk29fb_inf {
struct fb_info *fb1;
struct platform_device *g_pdev = NULL;
-static int win1fb_set_par(struct fb_info *info);
+//static int win1fb_set_par(struct fb_info *info);
#if 0
#define CHK_SUSPEND(inf) \
clk_set_parent(inf->dclk, inf->dclk_divider);
clk_set_parent(inf->aclk, inf->aclk_parent);
- fbprintk(">>>>>> set lcdc dclk need %d HZ, clk_parent = %d hz \n ", screen->pixclock, clk_rate);
+ fbprintk(">>>>>> set lcdc dclk need %d HZ, clk_parent = %d hz \n ", screen->pixclock, screen->lcdc_aclk);
ret = clk_set_rate(inf->dclk_divider, screen->pixclock);
if(ret)
u32 yact = var->yres;
u32 xvir = var->xres_virtual; /* virtual resolution */
u32 yvir = var->yres_virtual;
- u32 xact_st = var->xoffset; /* offset from virtual to visible */
- u32 yact_st = var->yoffset; /* resolution */
+ //u32 xact_st = var->xoffset; /* offset from virtual to visible */
+ //u32 yact_st = var->yoffset; /* resolution */
u32 xpos = par->xpos;
u32 ypos = par->ypos;
// calculate the display phy address
y_addr = fix->smem_start + par->y_offset;
- uv_addr = fix->mmio_start + par->uv_offset;
+ uv_addr = fix->mmio_start + par->c_offset;
ScaleYrgbX = CalScaleW0(xact, par->xsize);
ScaleYrgbY = CalScaleW0(yact, par->ysize);
CHK_SUSPEND(inf);
y_addr = fix0->smem_start + par->y_offset;//y_offset;
- uv_addr = fix0->mmio_start + par->uv_offset ;//uv_offset;
+ uv_addr = fix0->mmio_start + par->c_offset ;//c_offset;
LcdWrReg(inf, WIN0_YRGB_MST, y_addr);
LcdWrReg(inf, WIN0_CBR_MST, uv_addr);
struct rk29fb_screen *screen = inf->cur_screen;
struct win0_par *par = info->par;
- u32 offset=0, addr=0, map_size=0, smem_len=0;
+ //u32 offset=0, addr=0, map_size=0, smem_len=0;
+ u32 addr=0;
u16 xres_virtual = var->xres_virtual; //virtual screen size
- u16 xpos_virtual = var->xoffset; //visiable offset in virtual screen
- u16 ypos_virtual = var->yoffset;
+ //u16 xpos_virtual = var->xoffset; //visiable offset in virtual screen
+ //u16 ypos_virtual = var->yoffset;
u16 xpos = par->xpos; //visiable offset in panel
u16 ypos = par->ypos;
static int win1_pan( struct fb_info *info )
{
struct rk29fb_inf *inf = dev_get_drvdata(info->device);
- struct fb_var_screeninfo *var1 = &info->var;
+ //struct fb_var_screeninfo *var1 = &info->var;
struct fb_fix_screeninfo *fix1 = &info->fix;
struct win0_par *par = info->par;
struct rk29fb_screen *screen = inf->cur_screen;
struct win0_par *par = info->par;
- u8 format = 0;
- u32 offset=0, addr=0, map_size=0, smem_len=0;
+ //u8 format = 0;
+ //u32 offset=0, addr=0, map_size=0, smem_len=0;
+ u32 offset=0, smem_len=0;
u16 xres_virtual = var->xres_virtual; //virtual screen size
u16 xpos_virtual = var->xoffset; //visiable offset in virtual screen
u16 ypos_virtual = var->yoffset;
- u16 xpos = (screen->x_res - var->xres)/2; //visiable offset in panel
- u16 ypos = (screen->y_res - var->yres)/2;
- u16 xsize = screen->x_res; //visiable size in panel
- u16 ysize = screen->y_res;
- u8 trspmode = TRSP_CLOSE;
- u8 trspval = 0;
+ //u16 xpos = (screen->x_res - var->xres)/2; //visiable offset in panel
+ //u16 ypos = (screen->y_res - var->yres)/2;
+ //u16 xsize = screen->x_res; //visiable size in panel
+ //u16 ysize = screen->y_res;
+ //u8 trspmode = TRSP_CLOSE;
+ //u8 trspval = 0;
//fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__);
}
smem_len = fix->line_length * var->yres_virtual;
- map_size = PAGE_ALIGN(smem_len);
+ //map_size = PAGE_ALIGN(smem_len);
if (smem_len > fix->smem_len) // buffer need realloc
{
{
struct rk29fb_inf *inf = dev_get_drvdata(info->device);
struct fb_var_screeninfo *var1 = &info->var;
- struct fb_fix_screeninfo *fix1 = &info->fix;
+ //struct fb_fix_screeninfo *fix1 = &info->fix;
struct win0_par *par = info->par;
u32 offset = 0;
u8 format = 0;
u32 cblen=0, crlen=0, map_size=0, smem_len=0;
- u32 xact = var->xres; /* visible resolution */
- u32 yact = var->yres;
+ //u32 xact = var->xres; /* visible resolution */
+ //u32 yact = var->yres;
u32 xvir = var->xres_virtual; /* virtual resolution */
u32 yvir = var->yres_virtual;
u32 xact_st = var->xoffset; /* offset from virtual to visible */
u16 xsize = (var->grayscale>>8) & 0xfff; //visiable size in panel
u16 ysize = (var->grayscale>>20) & 0xfff;
- u32 ScaleYrgbX=0x1000,ScaleYrgbY=0x1000;
- u32 ScaleCbrX=0x1000, ScaleCbrY=0x1000;
+ //u32 ScaleYrgbX=0x1000,ScaleYrgbY=0x1000;
+ //u32 ScaleCbrX=0x1000, ScaleCbrY=0x1000;
u8 data_format = var->nonstd&0x0f;
u32 win0_en = var->reserved[2];
xsize = (xsize * screen->x_res) / inf->panel1_info.x_res;
ysize = (ysize * screen->y_res) / inf->panel1_info.y_res;
- /* calculate y_offset,uv_offset,line_length,cblen and crlen */
+ /* calculate y_offset,c_offset,line_length,cblen and crlen */
switch (data_format)
{
case 0: // rgb
fix->line_length = xvir;
cblen = crlen = (xvir*yvir)/2;
par->y_offset = yact_st*xvir + xact_st;
- par->uv_offset = yact_st*xvir + xact_st;
+ par->c_offset = yact_st*xvir + xact_st;
break;
case 2: // yuv4200
format = 3;
cblen = crlen = (xvir*yvir)/4;
par->y_offset = yact_st*xvir + xact_st;
- par->uv_offset = (yact_st/2)*xvir + xact_st;
+ par->c_offset = (yact_st/2)*xvir + xact_st;
break;
case 3: // yuv4201
format = 4;
fix->line_length = xvir;
par->y_offset = (yact_st/2)*2*xvir + (xact_st)*2;
- par->uv_offset = (yact_st/2)*xvir + xact_st;
+ par->c_offset = (yact_st/2)*xvir + xact_st;
cblen = crlen = (xvir*yvir)/4;
break;
case 4: // none
format = 5;
fix->line_length = xvir;
par->y_offset = yact_st*xvir + xact_st;
- par->uv_offset = yact_st*2*xvir + xact_st*2;
+ par->c_offset = yact_st*2*xvir + xact_st*2;
cblen = crlen = (xvir*yvir);
break;
default:
case FB1_IOCTL_SET_YUV_ADDR: //set y&uv address to register direct
{
u32 yuv_phy[2];
+ int ret = 0;
if (copy_from_user(yuv_phy, argp, 8))
return -EFAULT;
yuv_phy[0] += par->y_offset;
- yuv_phy[1] += par->uv_offset;
+ yuv_phy[1] += par->c_offset;
LcdWrReg(inf, WIN0_YRGB_MST, yuv_phy[0]);
LcdWrReg(inf, WIN0_CBR_MST, yuv_phy[1]);
// enable win0 after the win0 par is seted
par->addr_seted = 1;
if(par->par_seted) {
+ if (par->mirror.c_offset) {
+ ret = wait_event_interruptible_timeout(par->wait,
+ (0 == par->mirror.c_offset), HZ/20);
+ if (ret <= 0)
+ break;
+ }
+
+ down_write(&par->sem);
LcdMskReg(inf, SYS_CONFIG, m_W0_ENABLE, v_W0_ENABLE(1));
mcu_refresh(inf);
+ par->mirror.y_offset = yuv_phy[0];
+ par->mirror.c_offset = yuv_phy[1];
+ //printk("0x%.8x 0x%.8x mirror\n", par->mirror.y_offset, par->mirror.c_offset);
+ up_write(&par->sem);
}
}
break;
{
struct platform_device *pdev = (struct platform_device*)dev_id;
struct rk29fb_inf *inf = platform_get_drvdata(pdev);
+ struct win0_par *par = (struct win0_par *)inf->fb1->par;
if(!inf)
return IRQ_HANDLED;
}
}
+ if(waitqueue_active(&par->wait)) {
+ down_write(&par->sem);
+ if (par->mirror.c_offset == 0)
+ printk("error: no new buffer to display\n");
+
+ par->done.y_offset = par->displ.y_offset;
+ par->done.c_offset = par->displ.c_offset;
+ par->displ.y_offset = par->mirror.y_offset;
+ par->displ.c_offset = par->mirror.c_offset;
+ par->mirror.y_offset = 0;
+ par->mirror.c_offset = 0;
+
+ //printk("0x%.8x 0x%.8x displaying\n", par->displ.y_offset, par->displ.c_offset);
+ //printk("0x%.8x 0x%.8x done\n", par->done.y_offset, par->done.c_offset);
+
+ up_write(&par->sem);
+ wake_up_interruptible(&par->wait);
+ }
+
wq_condition = 1;
wake_up_interruptible(&wq);
struct resource *mem = NULL;
struct rk29fb_info *mach_info = NULL;
struct rk29fb_screen *screen = NULL;
+ struct win0_par* par = NULL;
int irq = 0;
int ret = 0;
goto release_win1fb;
}
+ par = (struct win0_par*)inf->fb0->par;
strcpy(inf->fb0->fix.id, "fb0");
inf->fb0->fix.type = FB_TYPE_PACKED_PIXELS;
inf->fb0->fix.type_aux = 0;
inf->fb0->fbops = &fb0_ops;
inf->fb0->flags = FBINFO_FLAG_DEFAULT;
- inf->fb0->pseudo_palette = ((struct win0_par*)inf->fb0->par)->pseudo_pal;
+ inf->fb0->pseudo_palette = par->pseudo_pal;
inf->fb0->screen_base = 0;
- memset(inf->fb0->par, 0, sizeof(struct win0_par));
+ memset(par, 0, sizeof(struct win0_par));
+
ret = fb_alloc_cmap(&inf->fb0->cmap, 256, 0);
if (ret < 0)
goto release_cmap;
goto release_win0fb;
}
+ par = (struct win0_par*)inf->fb1->par;
+
strcpy(inf->fb1->fix.id, "fb1");
inf->fb1->fix.type = FB_TYPE_PACKED_PIXELS;
inf->fb1->fix.type_aux = 0;
inf->fb1->fbops = &fb1_ops;
inf->fb1->flags = FBINFO_FLAG_DEFAULT;
- inf->fb1->pseudo_palette = ((struct win0_par*)inf->fb1->par)->pseudo_pal;
+ inf->fb1->pseudo_palette = par->pseudo_pal;
inf->fb1->screen_base = 0;
- memset(inf->fb1->par, 0, sizeof(struct win0_par));
+ memset(par, 0, sizeof(struct win0_par));
+
+ init_rwsem(&par->sem);
+ init_waitqueue_head(&par->wait);
/* Init all lcdc and lcd before register_framebuffer. */
/* because after register_framebuffer, the win1fb_check_par and winfb_set_par execute immediately */