From 9eb60d701bb9a960ac6dd5361caa2e7d6d2a4655 Mon Sep 17 00:00:00 2001 From: zyw Date: Wed, 30 Mar 2011 16:47:59 +0800 Subject: [PATCH] scale-up UI when HDMI play video use ipp --- arch/arm/configs/rk29_sdk_defconfig | 26 ++-- arch/arm/mach-rk29/board-rk29sdk.c | 17 ++- drivers/video/Kconfig | 5 + drivers/video/rk29_fb.c | 186 ++++++++++++++++++++++------ 4 files changed, 186 insertions(+), 48 deletions(-) diff --git a/arch/arm/configs/rk29_sdk_defconfig b/arch/arm/configs/rk29_sdk_defconfig index fbb82a7f11be..77cdc188873a 100755 --- a/arch/arm/configs/rk29_sdk_defconfig +++ b/arch/arm/configs/rk29_sdk_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.32.27 -# Fri Mar 4 17:07:23 2011 +# Wed Mar 30 16:40:55 2011 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_HAVE_SCHED_CLOCK=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -202,6 +203,7 @@ CONFIG_MACH_RK29SDK=y # CONFIG_MACH_RK29_AIGO is not set # CONFIG_MACH_RK29_MALATA is not set # CONFIG_MACH_RK29_PHONESDK is not set +# CONFIG_MACH_RK29_A22 is not set CONFIG_RK29_MEM_SIZE_M=512 # @@ -800,11 +802,7 @@ CONFIG_KEYS_RK29=y # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_XPT2046_SPI_NOCHOOSE=y -# CONFIG_TOUCHSCREEN_XPT2046_SPI is not set -# CONFIG_TOUCHSCREEN_XPT2046_CBN_SPI is not set -# CONFIG_TOUCHSCREEN_XPT2046_320X480_SPI is not set -# CONFIG_TOUCHSCREEN_XPT2046_320X480_CBN_SPI is not set +# CONFIG_TOUCHSCREEN_ILI2102_IIC is not set # CONFIG_TOUCHSCREEN_IT7250 is not set # CONFIG_TOUCHSCREEN_AD7879_I2C is not set # CONFIG_TOUCHSCREEN_AD7879 is not set @@ -833,12 +831,18 @@ CONFIG_EETI_EGALAX_MAX_X=1087 CONFIG_EETI_EGALAX_MAX_Y=800 # CONFIG_EETI_EGALAX_DEBUG is not set # CONFIG_TOUCHSCREEN_IT7260 is not set +# CONFIG_TOUCHSCREEN_GT801_IIC is not set # CONFIG_INPUT_MISC is not set CONFIG_INPUT_GPIO=y + +# +# Magnetometer sensors +# +# CONFIG_COMPASS_AK8975 is not set +# CONFIG_COMPASS_AK8973 is not set CONFIG_G_SENSOR_DEVICE=y # CONFIG_GS_MMA7660 is not set CONFIG_GS_MMA8452=y -# CONFIG_GS_FIH is not set # CONFIG_INPUT_JOGBALL is not set # @@ -1063,6 +1067,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y CONFIG_SOC_CAMERA=y # CONFIG_SOC_CAMERA_MT9M001 is not set # CONFIG_SOC_CAMERA_MT9M111 is not set +# CONFIG_SOC_CAMERA_MT9M112 is not set # CONFIG_SOC_CAMERA_MT9T031 is not set # CONFIG_SOC_CAMERA_MT9P111 is not set # CONFIG_SOC_CAMERA_MT9D112 is not set @@ -1181,6 +1186,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_RK2818 is not set CONFIG_FB_RK29=y +CONFIG_FB_WORK_IPP=y # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set @@ -1205,13 +1211,19 @@ CONFIG_DISPLAY_SUPPORT=y # CONFIG_LCD_TJ048NC01CA is not set # CONFIG_LCD_HL070VM4AU is not set # CONFIG_LCD_HSD070IDW1 is not set +# CONFIG_LCD_RGB_TFT480800_25_E is not set CONFIG_LCD_HSD100PXN=y # CONFIG_LCD_B101AW06 is not set +# CONFIG_LCD_LS035Y8DX02A is not set # CONFIG_LCD_A060SE02 is not set # CONFIG_LCD_S1D13521 is not set # CONFIG_LCD_NT35582 is not set # CONFIG_LCD_NT35580 is not set +# CONFIG_LCD_IPS1P5680_V1_E is not set +# CONFIG_LCD_MCU_TFT480800_25_E is not set +# CONFIG_LCD_ILI9803_CPT4_3 is not set # CONFIG_LCD_ANX7150_720P is not set +# CONFIG_LCD_AT070TNA2 is not set # # HDMI support diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c index 19db75d1f673..68455afb20ee 100755 --- a/arch/arm/mach-rk29/board-rk29sdk.c +++ b/arch/arm/mach-rk29/board-rk29sdk.c @@ -70,14 +70,19 @@ #define MEM_CAMIPP_SIZE 0 #endif #define MEM_FB_SIZE (3*SZ_2M) - +#ifdef CONFIG_FB_WORK_IPP +#define MEM_FBIPP_SIZE SZ_8M //1920 x 1080 x 2 x 2 //RGB565 = x2;RGB888 = x4 +#else +#define MEM_FBIPP_SIZE 0 +#endif #define PMEM_GPU_BASE ((u32)RK29_SDRAM_PHYS + SDRAM_SIZE - PMEM_GPU_SIZE) #define PMEM_UI_BASE (PMEM_GPU_BASE - PMEM_UI_SIZE) #define PMEM_VPU_BASE (PMEM_UI_BASE - PMEM_VPU_SIZE) #define PMEM_CAM_BASE (PMEM_VPU_BASE - PMEM_CAM_SIZE) #define MEM_CAMIPP_BASE (PMEM_CAM_BASE - MEM_CAMIPP_SIZE) #define MEM_FB_BASE (MEM_CAMIPP_BASE - MEM_FB_SIZE) -#define LINUX_SIZE (MEM_FB_BASE - RK29_SDRAM_PHYS) +#define MEM_FBIPP_BASE (MEM_FB_BASE - MEM_FBIPP_SIZE) +#define LINUX_SIZE (MEM_FBIPP_BASE - RK29_SDRAM_PHYS) #define PREALLOC_WLAN_SEC_NUM 4 #define PREALLOC_WLAN_BUF_NUM 160 @@ -234,6 +239,14 @@ static struct resource rk29_fb_resource[] = { .end = MEM_FB_BASE + MEM_FB_SIZE - 1, .flags = IORESOURCE_MEM, }, + #ifdef CONFIG_FB_WORK_IPP + [3] = { + .name = "win1 ipp buf", + .start = MEM_FBIPP_BASE, + .end = MEM_FBIPP_BASE + MEM_FBIPP_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + #endif }; /*platform_device*/ diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 69339f4ab77f..7f0a29e872c5 100755 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1945,6 +1945,11 @@ config FB_RK29 ---help--- Framebuffer driver for RK29 Platform,select it if you using rk29 +config FB_WORK_IPP + bool "fb use ipp to scale-up UI when video" + depends on FB_RK29 + ---help--- + this function be used scale-up UI when video, it only support RGB565 UI config FB_SM501 tristate "Silicon Motion SM501 framebuffer support" diff --git a/drivers/video/rk29_fb.c b/drivers/video/rk29_fb.c index 84544dccd47f..99b49e4582bb 100755 --- a/drivers/video/rk29_fb.c +++ b/drivers/video/rk29_fb.c @@ -55,7 +55,7 @@ #include #include #include -//#include +#include #include "./display/screen/screen.h" @@ -284,12 +284,12 @@ void set_lcd_pin(struct platform_device *pdev, int enable) if(display_on != INVALID_GPIO) { gpio_direction_output(display_on, 0); - gpio_set_value(display_on, enable ? display_on_pol : !display_on_pol); + gpio_set_value(display_on, enable ? display_on_pol : !display_on_pol); } if(lcd_standby != INVALID_GPIO) { gpio_direction_output(lcd_standby, 0); - gpio_set_value(lcd_standby, enable ? lcd_standby_pol : !lcd_standby_pol); + gpio_set_value(lcd_standby, enable ? lcd_standby_pol : !lcd_standby_pol); } } @@ -1146,15 +1146,14 @@ static int win1_blank(int blank_mode, struct fb_info *info) static int win1_set_par(struct fb_info *info) { struct rk29fb_inf *inf = dev_get_drvdata(info->device); - struct fb_var_screeninfo *var = &info->var; struct fb_fix_screeninfo *fix = &info->fix; struct rk29fb_screen *screen = inf->cur_screen; struct win0_par *par = info->par; + struct fb_var_screeninfo *var = &info->var; //u32 offset=0, addr=0, map_size=0, smem_len=0; u32 addr=0; - - u16 xres_virtual = var->xres_virtual; //virtual screen size + u16 xres_virtual = 0; //virtual screen size //u16 xpos_virtual = var->xoffset; //visiable offset in virtual screen //u16 ypos_virtual = var->yoffset; @@ -1167,8 +1166,19 @@ static int win1_set_par(struct fb_info *info) //fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__); - addr = fix->smem_start + par->y_offset; - + #ifdef CONFIG_FB_WORK_IPP + if(((screen->x_res != var->xres) || (screen->y_res != var->yres)) + && !((screen->x_res>1280) && (var->bits_per_pixel == 32))) + { + addr = fix->mmio_start + par->y_offset; + xres_virtual = screen->x_res; //virtual screen size + } + else + #endif + { + addr = fix->smem_start + par->y_offset; + xres_virtual = var->xres_virtual; //virtual screen size + } LcdMskReg(inf, SYS_CONFIG, m_W1_ENABLE|m_W1_FORMAT, v_W1_ENABLE(1)|v_W1_FORMAT(par->format)); xpos += (screen->left_margin + screen->hsync_len); @@ -1208,17 +1218,23 @@ 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_fix_screeninfo *fix1 = &info->fix; struct win0_par *par = info->par; - u32 addr = 0; - //fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__); - - CHK_SUSPEND(inf); - - addr = fix1->smem_start + par->y_offset; + #ifdef CONFIG_FB_WORK_IPP + struct rk29fb_screen *screen = inf->cur_screen; + struct fb_var_screeninfo *var = &info->var; + if(((screen->x_res != var->xres) || (screen->y_res != var->yres)) + && !((screen->x_res>1280) && (var->bits_per_pixel == 32))) + { + addr = fix1->mmio_start + par->y_offset; + } + else + #endif + { + addr = fix1->smem_start + par->y_offset; + } //fbprintk("info->screen_base = %8x ; fix1->smem_len = %d , addr = %8x\n",(u32)info->screen_base, fix1->smem_len, addr); @@ -1303,40 +1319,46 @@ 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; - u32 offset=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; +#ifdef CONFIG_FB_WORK_IPP + struct rk29_ipp_req ipp_req; + u32 dstoffset=0; +#endif - //fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__); + fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__); CHK_SUSPEND(inf); if(inf->fb0_color_deepth)var->bits_per_pixel=inf->fb0_color_deepth; + #if !defined(CONFIG_FB_WORK_IPP) if((inf->video_mode == 1)&&(screen->y_res < var->yres))ypos_virtual += (var->yres-screen->y_res); + #endif switch(var->bits_per_pixel) { case 16: // rgb565 par->format = 1; fix->line_length = 2 * xres_virtual; + #ifdef CONFIG_FB_WORK_IPP + dstoffset = ((ypos_virtual*screen->y_res/var->yres) *screen->x_res + (xpos_virtual*screen->x_res)/var->xres )*2; + ipp_req.src0.fmt = IPP_RGB_565; + ipp_req.dst0.fmt = IPP_RGB_565; + #endif offset = (ypos_virtual*xres_virtual + xpos_virtual)*(inf->fb0_color_deepth ? 4:2); break; case 32: // rgb888 default: par->format = 0; fix->line_length = 4 * xres_virtual; + #ifdef CONFIG_FB_WORK_IPP + dstoffset = ((ypos_virtual*screen->y_res/var->yres) *screen->x_res + (xpos_virtual*screen->x_res)/var->xres )*4; + ipp_req.src0.fmt = IPP_XRGB_8888; + ipp_req.dst0.fmt = IPP_XRGB_8888; + #endif offset = (ypos_virtual*xres_virtual + xpos_virtual)*4; break; } @@ -1349,7 +1371,7 @@ static int fb0_set_par(struct fb_info *info) printk("%s sorry!!! win1 buf is not enough\n",__FUNCTION__); } - par->y_offset = offset; + par->addr_seted = 1; #if ANDROID_USE_THREE_BUFS if(0==new_frame_seted) { @@ -1361,14 +1383,43 @@ static int fb0_set_par(struct fb_info *info) if(inf->video_mode == 1) { - par->xpos = (screen->x_res >= var->xres)?((screen->x_res - var->xres)/2):0; //visiable offset in panel - par->ypos = (screen->y_res >= var->yres)?(screen->y_res - var->yres):0; - par->xsize = var->xres; //visiable size in panel - par->ysize = (screen->y_res >= var->yres) ? var->yres : screen->y_res; + #ifdef CONFIG_FB_WORK_IPP + if(((screen->x_res != var->xres) || (screen->y_res != var->yres)) + && !((screen->x_res>1280) && (var->bits_per_pixel == 32))) + { + par->xpos = 0; + par->ypos = 0; + par->xsize = screen->x_res; + par->ysize = screen->y_res; + par->y_offset = dstoffset; + + ipp_req.src0.YrgbMst = fix->smem_start + offset; + ipp_req.src0.w = var->xres; + ipp_req.src0.h = var->yres; + + ipp_req.dst0.YrgbMst = fix->mmio_start + dstoffset; + ipp_req.dst0.w = screen->x_res; + ipp_req.dst0.h = screen->y_res; + + ipp_req.src_vir_w = ipp_req.src0.w; + ipp_req.dst_vir_w = ipp_req.dst0.w; + ipp_req.timeout = 100; + ipp_req.flag = IPP_ROT_0; + ipp_do_blit(&ipp_req); + }else + #endif + { + par->y_offset = offset; + par->xpos = (screen->x_res >= var->xres)?((screen->x_res - var->xres)/2):0; //visiable offset in panel + par->ypos = (screen->y_res >= var->yres)?(screen->y_res - var->yres):0; + par->xsize = var->xres; //visiable size in panel + par->ysize = (screen->y_res >= var->yres) ? var->yres : screen->y_res; + } win1_set_par(info); } else { + par->y_offset = offset; par->xpos = 0; par->ypos = 0; par->xsize = screen->x_res; @@ -1381,39 +1432,83 @@ static int fb0_set_par(struct fb_info *info) 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 win0_par *par = info->par; + struct rk29fb_screen *screen = inf->cur_screen; + struct win0_par *par = info->par; u32 offset = 0; - + u16 ypos_virtual = var->yoffset; + u16 xpos_virtual = var->xoffset; + #ifdef CONFIG_FB_WORK_IPP + struct fb_fix_screeninfo *fix = &info->fix; + struct rk29_ipp_req ipp_req; + u32 dstoffset = 0 + #endif //fbprintk(">>>>>> %s : %s \n", __FILE__, __FUNCTION__); CHK_SUSPEND(inf); + if(inf->fb0_color_deepth)var->bits_per_pixel=inf->fb0_color_deepth; + #if !defined(CONFIG_FB_WORK_IPP) + if((inf->video_mode == 1)&&(screen->y_res < var->yres))ypos_virtual += (var->yres-screen->y_res); + #endif switch(var1->bits_per_pixel) { case 16: // rgb565 var->xoffset = (var->xoffset) & (~0x1); - offset = (var->yoffset*var1->xres_virtual + var->xoffset)*(inf->fb0_color_deepth ? 4:2); + #ifdef CONFIG_FB_WORK_IPP + dstoffset = ((ypos_virtual*screen->y_res/var->yres) *screen->x_res + (xpos_virtual*screen->x_res)/var->xres) * 2; + ipp_req.src0.fmt = IPP_RGB_565; + ipp_req.dst0.fmt = IPP_RGB_565; + #endif + offset = (ypos_virtual*var1->xres_virtual + xpos_virtual)*(inf->fb0_color_deepth ? 4:2); break; case 32: // rgb888 - offset = (var->yoffset*var1->xres_virtual + var->xoffset)*4; + #ifdef CONFIG_FB_WORK_IPP + dstoffset = ((ypos_virtual*screen->y_res/var->yres) *screen->x_res + (xpos_virtual*screen->x_res)/var->xres )*4; + ipp_req.src0.fmt = IPP_XRGB_8888; + ipp_req.dst0.fmt = IPP_XRGB_8888; + #endif + offset = (ypos_virtual*var1->xres_virtual + xpos_virtual)*4; break; default: return -EINVAL; } -// par->y_offset = offset; - if(inf->video_mode == 1) { + #ifdef CONFIG_FB_WORK_IPP + if(((screen->x_res != var->xres) || (screen->y_res != var->yres)) + && !((screen->x_res>1280) && (var->bits_per_pixel == 32))) + { + par->y_offset = dstoffset; + + ipp_req.src0.YrgbMst = fix->smem_start + offset; + ipp_req.src0.w = var->xres; + ipp_req.src0.h = var->yres; + + ipp_req.dst0.YrgbMst = fix->mmio_start + dstoffset; + ipp_req.dst0.w = screen->x_res; + ipp_req.dst0.h = screen->y_res; + + ipp_req.src_vir_w = ipp_req.src0.w; + ipp_req.dst_vir_w = ipp_req.dst0.w; + ipp_req.timeout = 100; + ipp_req.flag = IPP_ROT_0; + ipp_do_blit(&ipp_req); + win1_pan(info); + return 0; + }else + #endif + par->y_offset = offset; win1_pan(info); } else { + par->y_offset = offset; win0_pan(info); } // flush end when wq_condition=1 in mcu panel, but not in rgb panel @@ -2336,6 +2431,19 @@ static int __init rk29fb_probe (struct platform_device *pdev) inf->fb0->screen_base = ioremap(res->start, inf->fb0->fix.smem_len); memset(inf->fb0->screen_base, 0, inf->fb0->fix.smem_len); + #ifdef CONFIG_FB_WORK_IPP + /* alloc win1 ipp buf */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "win1 ipp buf"); + if (res == NULL) + { + dev_err(&pdev->dev, "failed to get win1 ipp memory \n"); + ret = -ENOENT; + goto release_win1fb; + } + inf->fb0->fix.mmio_start = res->start; + inf->fb0->fix.mmio_len = res->end - res->start + 1; + #endif + /* Prepare win0 info */ fbprintk(">> Prepare win0 info \n"); inf->fb1 = framebuffer_alloc(sizeof(struct win0_par), &pdev->dev); -- 2.34.1