From 45fc9741541c6053a34f2eafe6bd7836aaef3510 Mon Sep 17 00:00:00 2001 From: yxj Date: Mon, 5 Mar 2012 17:58:52 +0800 Subject: [PATCH] rk30 fb:add yuv support --- drivers/video/rockchip/chips/rk30_lcdc.c | 15 +++-- drivers/video/rockchip/rk_fb.c | 79 +++++++++++++----------- drivers/video/rockchip/rk_fb.h | 3 +- 3 files changed, 52 insertions(+), 45 deletions(-) diff --git a/drivers/video/rockchip/chips/rk30_lcdc.c b/drivers/video/rockchip/chips/rk30_lcdc.c index af4c5a5819b7..2e5f17843dba 100644 --- a/drivers/video/rockchip/chips/rk30_lcdc.c +++ b/drivers/video/rockchip/chips/rk30_lcdc.c @@ -285,14 +285,12 @@ static int win0_set_par(struct rk30_lcdc_device *lcdc_dev,rk_screen *screen, 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); switch (par->format) { - case ARGB888: - case RGB888: - case RGB565: - ScaleYrgbX = CalScale(xact, par->xsize); - ScaleYrgbY = CalScale(yact, par->ysize); - break; case YUV422:// yuv422 ScaleCbrX= CalScale((xact/2), par->xsize); ScaleCbrY = CalScale(yact, par->ysize); @@ -310,9 +308,10 @@ static int win0_set_par(struct rk30_lcdc_device *lcdc_dev,rk_screen *screen, break; } - DBG("%s>>format:%d>>>xact:%d>>yact:%d>>xvir:%d>>yvir:%d>>ypos:%d>>y_addr:0x%x\n", - __func__,par->format,xact,yact,xvir,yvir,ypos,y_addr); + 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); 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)); diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index 6010f020d775..ff0aa8b16b69 100644 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -87,10 +87,17 @@ defautl:we alloc three buffer,one for fb0 and fb2 display ui,one for ipp rotate static int rk_fb_open(struct fb_info *info,int user) { 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; + 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 inf->video_mode = 1; } + return 0; @@ -109,41 +116,40 @@ static int rk_fb_release(struct fb_info *info,int user) 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); - u32 yuv_phy[2]; - fbprintk(">>>>>> %s : cmd:0x%x \n",__FUNCTION__,cmd); - + struct rk_fb_inf *inf = dev_get_drvdata(info->device); + struct fb_fix_screeninfo *fix = &info->fix; + u32 yuv_phy[2]; + fbprintk(">>>>>> %s : cmd:0x%x \n",__FUNCTION__,cmd); CHK_SUSPEND(inf); - - switch(cmd) - { - case FB0_IOCTL_STOP_TIMER_FLUSH: //stop timer flush mcu panel after android is runing - break; - case FBIOPUT_16OR32: - break; - case FBIOGET_16OR32: - break; - case FBIOGET_IDLEFBUff_16OR32: - case FBIOSET_COMPOSE_LAYER_COUNTS: - break; - case FBIOGET_COMPOSE_LAYER_COUNTS: - case FBIOPUT_FBPHYADD: - return info->fix.smem_start; - case FB1_IOCTL_SET_YUV_ADDR: - if (copy_from_user(yuv_phy, arg, 8)) - return -EFAULT; - info->fix.smem_start = yuv_phy[0]; - info->fix.mmio_start = yuv_phy[1]; - break; - case FBIOGET_OVERLAY_STATE: - return inf->video_mode; - case FBIOGET_SCREEN_STATE: - case FBIOPUT_SET_CURSOR_EN: - case FBIOPUT_SET_CURSOR_POS: - case FBIOPUT_SET_CURSOR_IMG: - case FBIOPUT_SET_CURSOR_CMAP: - case FBIOPUT_GET_CURSOR_RESOLUTION: - case FBIOPUT_GET_CURSOR_EN: + + switch(cmd) + { + case FBIOPUT_FBPHYADD: + return info->fix.smem_start; + case FB1_IOCTL_SET_YUV_ADDR: //when in video mode, buff alloc by android + if((!strcmp(fix->id,"fb1"))||(!strcmp(fix->id,"fb3"))) + { + if (copy_from_user(yuv_phy, arg, 8)) + return -EFAULT; + info->fix.smem_start = yuv_phy[0]; //four y + info->fix.mmio_start = yuv_phy[1]; //four uv + } + break; + case FBIOGET_OVERLAY_STATE: + return inf->video_mode; + case FBIOGET_SCREEN_STATE: + case FBIOPUT_SET_CURSOR_EN: + case FBIOPUT_SET_CURSOR_POS: + case FBIOPUT_SET_CURSOR_IMG: + case FBIOPUT_SET_CURSOR_CMAP: + case FBIOPUT_GET_CURSOR_RESOLUTION: + case FBIOPUT_GET_CURSOR_EN: + case FB0_IOCTL_STOP_TIMER_FLUSH: //stop timer flush mcu panel after android is runing + case FBIOPUT_16OR32: + case FBIOGET_16OR32: + case FBIOGET_IDLEFBUff_16OR32: + case FBIOSET_COMPOSE_LAYER_COUNTS: + case FBIOGET_COMPOSE_LAYER_COUNTS: default: break; } @@ -300,7 +306,7 @@ static int rk_fb_set_par(struct fb_info *info) layer_id = 0; } 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; @@ -342,7 +348,7 @@ static int rk_fb_set_par(struct fb_info *info) par->y_offset = yoffset*xvir + xoffset; par->c_offset = par->y_offset; break; - case 2: // yuv4200 + case 2: // YUV420 par->format = YUV420; fix->line_length = xvir; cblen = crlen = (xvir*yvir)>>2; @@ -371,6 +377,7 @@ static int rk_fb_set_par(struct fb_info *info) par->ysize = ysize; par->smem_start =fix->smem_start; + par->cbr_start = fix->mmio_start; par->xact = var->xres; par->yact = var->yres; par->xres_virtual = xvir; // virtuail resolution diff --git a/drivers/video/rockchip/rk_fb.h b/drivers/video/rockchip/rk_fb.h index cd0db101cd45..8906b8d87c8e 100644 --- a/drivers/video/rockchip/rk_fb.h +++ b/drivers/video/rockchip/rk_fb.h @@ -63,8 +63,8 @@ enum data_format{ ARGB888 = 0, RGB888, RGB565, + YUV420 = 4, YUV422, - YUV420, YUV444, }; @@ -101,6 +101,7 @@ struct layer_par { u16 xres_virtual; u16 yres_virtual; unsigned long smem_start; + unsigned long cbr_start; // Cbr memory start address enum data_format format; bool support_3d; -- 2.34.1