mirror of
https://github.com/torvalds/linux.git
synced 2026-06-09 23:23:53 +02:00
rk29: rk29_fb:
change video overlay ioctrl to block interface
This commit is contained in:
parent
adb6ec9aaa
commit
39f8a16842
|
|
@ -95,21 +95,33 @@ static struct rk29fb_rgb def_rgb_16 = {
|
|||
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];
|
||||
|
|
@ -121,6 +133,7 @@ struct win1_par {
|
|||
u32 format;
|
||||
u32 addr_offset;
|
||||
};
|
||||
*/
|
||||
|
||||
struct rk29fb_inf {
|
||||
struct fb_info *fb1;
|
||||
|
|
@ -186,7 +199,7 @@ typedef enum _TRSP_MODE
|
|||
|
||||
|
||||
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) \
|
||||
|
|
@ -587,7 +600,7 @@ void load_screen(struct fb_info *info, bool initscreen)
|
|||
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)
|
||||
|
|
@ -827,8 +840,8 @@ static int win0_set_par(struct fb_info *info)
|
|||
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;
|
||||
|
||||
|
|
@ -844,7 +857,7 @@ static int win0_set_par(struct fb_info *info)
|
|||
|
||||
// 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);
|
||||
|
|
@ -923,7 +936,7 @@ static int win0_pan( struct fb_info *info )
|
|||
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);
|
||||
|
|
@ -967,12 +980,13 @@ static int win1_set_par(struct fb_info *info)
|
|||
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;
|
||||
|
|
@ -1023,7 +1037,7 @@ static int win1_set_par(struct fb_info *info)
|
|||
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;
|
||||
|
||||
|
|
@ -1117,20 +1131,21 @@ static int fb0_set_par(struct fb_info *info)
|
|||
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__);
|
||||
|
||||
|
|
@ -1152,7 +1167,7 @@ static int fb0_set_par(struct fb_info *info)
|
|||
}
|
||||
|
||||
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
|
||||
{
|
||||
|
|
@ -1186,7 +1201,7 @@ static int fb0_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
|||
{
|
||||
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;
|
||||
|
|
@ -1375,8 +1390,8 @@ static int fb1_set_par(struct fb_info *info)
|
|||
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 */
|
||||
|
|
@ -1387,8 +1402,8 @@ static int fb1_set_par(struct fb_info *info)
|
|||
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];
|
||||
|
|
@ -1404,7 +1419,7 @@ static int fb1_set_par(struct fb_info *info)
|
|||
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
|
||||
|
|
@ -1429,7 +1444,7 @@ static int fb1_set_par(struct fb_info *info)
|
|||
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;
|
||||
|
|
@ -1437,14 +1452,14 @@ static int fb1_set_par(struct fb_info *info)
|
|||
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
|
||||
|
|
@ -1452,7 +1467,7 @@ static int fb1_set_par(struct fb_info *info)
|
|||
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:
|
||||
|
|
@ -1567,11 +1582,12 @@ static int fb1_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
|
|||
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]);
|
||||
|
|
@ -1579,8 +1595,20 @@ static int fb1_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
|
|||
// 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;
|
||||
|
|
@ -1664,6 +1692,7 @@ static irqreturn_t rk29fb_irq(int irq, void *dev_id)
|
|||
{
|
||||
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;
|
||||
|
||||
|
|
@ -1706,6 +1735,25 @@ static irqreturn_t rk29fb_irq(int irq, void *dev_id)
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -1814,6 +1862,7 @@ static int __init rk29fb_probe (struct platform_device *pdev)
|
|||
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;
|
||||
|
||||
|
|
@ -1885,6 +1934,7 @@ static int __init rk29fb_probe (struct platform_device *pdev)
|
|||
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;
|
||||
|
|
@ -1924,10 +1974,11 @@ static int __init rk29fb_probe (struct platform_device *pdev)
|
|||
|
||||
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;
|
||||
|
|
@ -1956,6 +2007,8 @@ static int __init rk29fb_probe (struct platform_device *pdev)
|
|||
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;
|
||||
|
|
@ -1995,10 +2048,13 @@ static int __init rk29fb_probe (struct platform_device *pdev)
|
|||
|
||||
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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user