From 772ad0907ac34c6e1e7cbb131bde7b7704f20e57 Mon Sep 17 00:00:00 2001 From: yxj Date: Tue, 28 Feb 2012 18:23:28 +0800 Subject: [PATCH] rk30 fb: add interface to show image directly in kernel add ARGB888 support,enable RB swap --- drivers/video/rockchip/chips/rk30_lcdc.c | 81 +++++++++++++----------- drivers/video/rockchip/rk_fb.c | 25 +++++++- 2 files changed, 69 insertions(+), 37 deletions(-) diff --git a/drivers/video/rockchip/chips/rk30_lcdc.c b/drivers/video/rockchip/chips/rk30_lcdc.c index 9b9eec63f621..e9f7e5c65f52 100644 --- a/drivers/video/rockchip/chips/rk30_lcdc.c +++ b/drivers/video/rockchip/chips/rk30_lcdc.c @@ -287,6 +287,7 @@ static int win0_set_par(struct rk30_lcdc_device *lcdc_dev,rk_screen *screen, y_addr = par->smem_start + par->y_offset; switch (par->format) { + case ARGB888: case RGB888: case RGB565: ScaleYrgbX = CalScale(xact, par->xsize); @@ -305,6 +306,7 @@ static int win0_set_par(struct rk30_lcdc_device *lcdc_dev,rk_screen *screen, ScaleCbrY = CalScale(yact, par->ysize); break; default: + printk("un support format!\n"); break; } @@ -320,20 +322,22 @@ static int win0_set_par(struct rk30_lcdc_device *lcdc_dev,rk_screen *screen, switch(par->format) { case ARGB888: - LcdMskReg(lcdc_dev, WIN0_VIR, m_WORDLO, v_ARGB888_VIRWIDTH(xvir)); + LcdWrReg(lcdc_dev, WIN0_VIR,v_ARGB888_VIRWIDTH(xvir)); + LcdMskReg(lcdc_dev,SYS_CTRL1,m_W0_RGB_RB_SWAP,v_W1_RGB_RB_SWAP(1)); break; case RGB888: //rgb888 - LcdMskReg(lcdc_dev, WIN0_VIR, m_WORDLO, v_RGB888_VIRWIDTH(xvir)); + LcdWrReg(lcdc_dev, WIN0_VIR,v_RGB888_VIRWIDTH(xvir)); + LcdMskReg(lcdc_dev,SYS_CTRL1,m_W0_RGB_RB_SWAP,v_W1_RGB_RB_SWAP(1)); break; case RGB565: //rgb565 - LcdMskReg(lcdc_dev, WIN0_VIR, m_WORDLO, v_RGB565_VIRWIDTH(xvir)); + LcdWrReg(lcdc_dev, WIN0_VIR,v_RGB565_VIRWIDTH(xvir)); break; case YUV422: case YUV420: - LcdMskReg(lcdc_dev, WIN0_VIR, m_WORDLO,v_YUV_VIRWIDTH(xvir)); + LcdWrReg(lcdc_dev, WIN0_VIR,v_YUV_VIRWIDTH(xvir)); break; default: - LcdMskReg(lcdc_dev, WIN0_VIR, m_WORDLO, v_RGB888_VIRWIDTH(xvir)); + LcdWrReg(lcdc_dev, WIN0_VIR,v_RGB888_VIRWIDTH(xvir)); break; } @@ -360,33 +364,36 @@ static int win1_set_par(struct rk30_lcdc_device *lcdc_dev,rk_screen *screen, DBG("%s>>format:%d>>>xact:%d>>yact:%d>>xvir:%d>>yvir:%d>>ypos:%d>>xsize:%d>>ysize:%d>>y_addr:0x%x\n", __func__,par->format,xact,yact,xvir,yvir,ypos,par->xsize,par->ysize,addr); - switch (par->format) - { - 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); - break; - case YUV420: // yuv420 - ScaleCbrX= CalScale(xact/2, par->xsize); - ScaleCbrY = CalScale(yact/2, par->ysize); - break; - case YUV444:// yuv444 - ScaleCbrX= CalScale(xact, par->xsize); - ScaleCbrY = CalScale(yact, par->ysize); - break; - default: - break; + 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); + break; + case YUV420: // yuv420 + ScaleCbrX= CalScale(xact/2, par->xsize); + ScaleCbrY = CalScale(yact/2, par->ysize); + break; + case YUV444:// yuv444 + ScaleCbrX= CalScale(xact, par->xsize); + ScaleCbrY = CalScale(yact, par->ysize); + break; + default: + printk("%s>>un support format!\n",__func__); + break; } - - 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)); + + 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, addr); + LcdWrReg(lcdc_dev, WIN0_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)); // enable win1 color key and set the color to black(rgb=0) @@ -394,20 +401,22 @@ static int win1_set_par(struct rk30_lcdc_device *lcdc_dev,rk_screen *screen, switch(par->format) { case ARGB888: - LcdMskReg(lcdc_dev, WIN1_VIR, m_WORDLO, v_ARGB888_VIRWIDTH(xvir)); + LcdWrReg(lcdc_dev, WIN1_VIR,v_ARGB888_VIRWIDTH(xvir)); + LcdMskReg(lcdc_dev,SYS_CTRL1,m_W1_RGB_RB_SWAP,v_W1_RGB_RB_SWAP(1)); break; case RGB888: //rgb888 - LcdMskReg(lcdc_dev, WIN1_VIR, m_WORDLO, v_RGB888_VIRWIDTH(xvir)); + LcdWrReg(lcdc_dev, WIN1_VIR,v_RGB888_VIRWIDTH(xvir)); + LcdMskReg(lcdc_dev,SYS_CTRL1,m_W1_RGB_RB_SWAP,v_W1_RGB_RB_SWAP(1)); break; case RGB565: //rgb565 - LcdMskReg(lcdc_dev, WIN1_VIR, m_WORDLO, v_RGB565_VIRWIDTH(xvir)); + LcdWrReg(lcdc_dev, WIN1_VIR,v_RGB565_VIRWIDTH(xvir)); break; case YUV422: case YUV420: - LcdMskReg(lcdc_dev, WIN1_VIR, m_WORDLO,v_YUV_VIRWIDTH(xvir)); + LcdWrReg(lcdc_dev, WIN1_VIR,v_YUV_VIRWIDTH(xvir)); break; default: - LcdMskReg(lcdc_dev, WIN1_VIR, m_WORDLO, v_RGB888_VIRWIDTH(xvir)); + LcdWrReg(lcdc_dev, WIN1_VIR,v_RGB888_VIRWIDTH(xvir)); break; } @@ -437,11 +446,11 @@ static int rk30_lcdc_set_par(struct rk_lcdc_device_driver *fb_drv,int layer_id) } if(layer_id==0) { - win0_set_par(lcdc_dev,screen,par); + win0_set_par(lcdc_dev,screen,par); } else if(layer_id==1) { - win1_set_par(lcdc_dev,screen,&(fb_drv->layer_par[1])); + win1_set_par(lcdc_dev,screen,&(fb_drv->layer_par[1])); } return 0; diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index dcc5578227d1..b79bee5cf325 100644 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -303,7 +303,10 @@ static int rk_fb_set_par(struct fb_info *info) par->y_offset = (yoffset*xvir + xoffset)*2; break; case 32: // rgb888 - par->format = RGB888; + if(var->transp.length) //we need ditinguish ARGB888 and RGB888 + par->format = ARGB888; //in some register,they have different configration + else + par->format = RGB888; fix->line_length = 4 * xvir; par->y_offset = (yoffset*xvir + xoffset)*4; break; @@ -426,6 +429,26 @@ static struct fb_fix_screeninfo def_fix = { }; + +/***************************************************************** +this two function is for other module that in the kernel which +need show image directly through fb +fb_id:we have 4 fb here,default we use fb0 for ui display +*******************************************************************/ +struct fb_info * rk_get_fb(int fb_id) +{ + struct rk_fb_inf *inf = platform_get_drvdata(g_fb_pdev); + struct fb_info *fb = inf->fb[fb_id]; + return fb; +} +EXPORT_SYMBOL(get_fb); + +void rk_direct_fb_show(struct fb_info * fbi) +{ + rk_fb_set_par(fbi); +} +EXPORT_SYMBOL(direct_fb_show); + static int request_fb_buffer(struct fb_info *fbi,int fb_id) { struct resource *res; -- 2.34.1