From 2e776ee4232cdd183c86dea55d41c157424947a9 Mon Sep 17 00:00:00 2001 From: yxj Date: Thu, 1 Nov 2012 09:52:51 +0800 Subject: [PATCH] fb rotate support --- arch/arm/mach-rk30/board-rk30-sdk.c | 11 ++++-- drivers/video/rockchip/Kconfig | 13 +++++++ drivers/video/rockchip/rk_fb.c | 58 ++++++++++++++++++++++++----- 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-rk30/board-rk30-sdk.c b/arch/arm/mach-rk30/board-rk30-sdk.c index a4252b601060..b37fa99c430c 100755 --- a/arch/arm/mach-rk30/board-rk30-sdk.c +++ b/arch/arm/mach-rk30/board-rk30-sdk.c @@ -1570,14 +1570,17 @@ static void __init rk30_reserve(void) rk30_ion_pdata.heaps[0].base = board_mem_reserve_add("ion", ION_RESERVE_SIZE); #endif #ifdef CONFIG_FB_ROCKCHIP - resource_fb[0].start = board_mem_reserve_add("fb0", RK30_FB0_MEM_SIZE); + resource_fb[0].start = board_mem_reserve_add("fb0 buf", RK30_FB0_MEM_SIZE); resource_fb[0].end = resource_fb[0].start + RK30_FB0_MEM_SIZE - 1; - #if 0 +#if 0 resource_fb[1].start = board_mem_reserve_add("ipp buf", RK30_FB0_MEM_SIZE); resource_fb[1].end = resource_fb[1].start + RK30_FB0_MEM_SIZE - 1; - resource_fb[2].start = board_mem_reserve_add("fb2", RK30_FB0_MEM_SIZE); +#endif + +#if defined(CONFIG_FB_ROTATE) || !defined(CONFIG_THREE_FB_BUFFER) + resource_fb[2].start = board_mem_reserve_add("fb2 buf", RK30_FB0_MEM_SIZE); resource_fb[2].end = resource_fb[2].start + RK30_FB0_MEM_SIZE - 1; - #endif +#endif #endif #ifdef CONFIG_VIDEO_RK29 rk30_camera_request_reserve_mem(); diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig index 1c66e0eacc03..a70c22257ee6 100755 --- a/drivers/video/rockchip/Kconfig +++ b/drivers/video/rockchip/Kconfig @@ -36,6 +36,19 @@ config NO_DUAL_DISP No dual display needed endchoice +config FB_ROTATE + bool"FB rotate support" + depends on FB_ROCKCHIP + default n + help + select y if you need rotate your screen + +config ROTATE_ORIENTATION + int "rotate orientation" + depends on FB_ROTATE + default 0 + help + select 0, 90, 180,270 according to your Mold config THREE_FB_BUFFER bool "Three fb buffer support" depends on FB_ROCKCHIP diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index 306b30cbb140..6ef5bd13cf40 100644 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -121,7 +121,30 @@ static int rk_fb_close(struct fb_info *info,int user) static void fb_copy_by_ipp(struct fb_info *dst_info, struct fb_info *src_info,int offset) { struct rk29_ipp_req ipp_req; - + + uint32_t rotation = 0; +#if defined(CONFIG_FB_ROTATE) + int orientation = orientation = 270 - CONFIG_ROTATE_ORIENTATION; + switch(orientation) + { + case 0: + rotation = IPP_ROT_0; + break; + case 90: + rotation = IPP_ROT_90; + break; + case 180: + rotation = IPP_ROT_180; + break; + case 270: + rotation = IPP_ROT_270; + break; + default: + rotation = IPP_ROT_270; + break; + + } +#endif 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; @@ -134,18 +157,35 @@ static void fb_copy_by_ipp(struct fb_info *dst_info, struct fb_info *src_info,in 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_req.flag = rotation; ipp_blit_sync(&ipp_req); } + + +#if 0 + 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); - + struct fb_info * info2 = inf->fb[2]; + struct fb_info * info = inf->fb[0]; + struct rk_lcdc_device_driver * dev_drv1 = (struct rk_lcdc_device_driver * )info2->par; + struct rk_lcdc_device_driver * dev_drv = (struct rk_lcdc_device_driver * )info->par; + struct layer_par *par = dev_drv->layer_par[1]; + struct layer_par *par2 = dev_drv1->layer_par[1]; + struct fb_var_screeninfo *var = &info->var; + u32 xvir = var->xres_virtual; + dev_drv1->xoffset = var->xoffset; // offset from virtual to visible + dev_drv1->yoffset += var->yres; + if(dev_drv1->yoffset >= 3*var->yres) + dev_drv1->yoffset = 0;++ + rk_bufferoffset_tran(dev_drv1->xoffset, dev_drv1->yoffset, xvir , par2); + fb_copy_by_ipp(info2,info,par->y_offset,par2->y_offset); + dev_drv1->pan_display(dev_drv1,1); + complete(&(dev_drv1->ipp_done)); } +#endif static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { @@ -211,7 +251,7 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 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); - #if !defined(CONFIG_THREE_FB_BUFFER) + #if defined(CONFIG_FB_ROTATE) || !defined(CONFIG_THREE_FB_BUFFER) fb_copy_by_ipp(info2,info,par->y_offset); #endif dev_drv1->pan_display(dev_drv1,layer_id); @@ -853,7 +893,7 @@ static int rk_request_fb_buffer(struct fb_info *fbi,int fb_id) } else { -#if !defined(CONFIG_THREE_FB_BUFFER) +#if defined(CONFIG_FB_ROTATE) || !defined(CONFIG_THREE_FB_BUFFER) res = platform_get_resource_byname(g_fb_pdev, IORESOURCE_MEM, "fb2 buf"); if (res == NULL) { -- 2.34.1