From: hjc Date: Sat, 15 Mar 2014 08:30:49 +0000 (+0800) Subject: rk3288 lcdc: X-Git-Tag: firefly_0821_release~6069 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7f782836ee87be258cd38f6e5de438d7686a8917;p=firefly-linux-kernel-4.4.55.git rk3288 lcdc: 1.add suspend and resume func; 2.add x and y mirror func; 3.rename some unresonable define. --- diff --git a/arch/arm/boot/dts/rk3288-fpga.dts b/arch/arm/boot/dts/rk3288-fpga.dts index 3192bcad71b5..576bda47accc 100755 --- a/arch/arm/boot/dts/rk3288-fpga.dts +++ b/arch/arm/boot/dts/rk3288-fpga.dts @@ -198,24 +198,27 @@ compatible = "rockchip,screen"; }; - lcdc0: lcdc@ff940000 { + lcdc1: lcdc@ff940000 { compatible = "rockchip,rk3288-lcdc"; rockchip,prop = ; rochchip,pwr18 = <0>; reg = <0xff940000 0x10000>; interrupts = ; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&lcdc0_lcdc>; + pinctrl-1 = <&lcdc0_gpio>; status = "disabled"; }; - lcdc1: lcdc@ff930000 { + lcdc0: lcdc@ff930000 { compatible = "rockchip,rk3288-lcdc"; rockchip,prop = ; rockchip,pwr18 = <0>; reg = <0xff930000 0x10000>; interrupts = ; - pinctrl-names = "default", "gpio"; - pinctrl-0 = <&lcdc0_lcdc>; - pinctrl-1 = <&lcdc0_gpio>; + //pinctrl-names = "default", "gpio"; + //pinctrl-0 = <&lcdc0_lcdc>; + //pinctrl-1 = <&lcdc0_gpio>; status = "disabled"; }; @@ -537,8 +540,30 @@ &lcdc0 { status = "okay"; + power_ctr: power_ctr { + rockchip,debug = <0>; + rockchip,mirror = ; + /*lcd_en:lcd_en { + rockchip,power_type = ; + gpios = <&gpio7 GPIO_A3 GPIO_ACTIVE_HIGH>; + rockchip,delay = <10>; + }; + + + lcd_cs:lcd_cs { + rockchip,power_type = ; + rockchip,delay = <10>; + }; + + lcd_rst:lcd_rst { + rockchip,power_type = ; + gpios = <&gpio3 GPIO_D6 GPIO_ACTIVE_HIGH>; + rockchip,delay = <5>; + };*/ + + }; }; &lcdc1 { - status = "okay"; + status = "disable"; }; diff --git a/drivers/video/rockchip/lcdc/rk3288_lcdc.c b/drivers/video/rockchip/lcdc/rk3288_lcdc.c index 731788392b23..e157ae088875 100755 --- a/drivers/video/rockchip/lcdc/rk3288_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk3288_lcdc.c @@ -53,18 +53,10 @@ module_param(dbg_thresd, int, S_IRUGO | S_IWUSR); static int rk3288_lcdc_get_id(u32 phy_base) { if (cpu_is_rk3288()) { - if (phy_base == 0xff940000)/*vop lite*/ -#ifdef CONFIG_RK_FPGA - return 1; -#else + if (phy_base == 0xff930000)/*vop big*/ return 0; -#endif - else if (phy_base == 0xff930000)/*vop big*/ -#ifdef CONFIG_RK_FPGA - return 0; -#else + else if (phy_base == 0xff940000)/*vop lit*/ return 1; -#endif else return -EINVAL; } else { @@ -318,9 +310,9 @@ static int rk3288_lcdc_post_cfg(struct rk_lcdc_driver *dev_drv) screen->mode.hsync_len+screen->mode.left_margin; post_dsp_hact_end = post_dsp_hact_st + screen->post_xsize; }else{ - post_dsp_hact_st = h_total - screen->post_dsp_stx - - screen->mode.hsync_len-screen->mode.left_margin; - post_dsp_hact_end = post_dsp_hact_st - screen->post_xsize; + post_dsp_hact_end = h_total - screen->mode.right_margin - + - screen->post_dsp_stx; + post_dsp_hact_st = post_dsp_hact_end - screen->post_xsize; } if((screen->post_xsize < x_res)&&(screen->post_xsize != 0)){ post_hsd_en = 1; @@ -343,9 +335,9 @@ static int rk3288_lcdc_post_cfg(struct rk_lcdc_driver *dev_drv) screen->mode.vsync_len+screen->mode.upper_margin; post_dsp_vact_end = post_dsp_vact_st + screen->post_ysize; }else{ - post_dsp_vact_st = v_total - screen->post_dsp_sty - - screen->mode.vsync_len-screen->mode.upper_margin; - post_dsp_vact_end = post_dsp_vact_st - screen->post_ysize; + post_dsp_vact_end = v_total - screen->mode.lower_margin - + - screen->post_dsp_sty; + post_dsp_hact_st = post_dsp_vact_end - screen->post_ysize; } if((screen->post_ysize < y_res)&&(screen->post_ysize != 0)){ post_vsd_en = 1; @@ -423,6 +415,8 @@ static int rk3288_lcdc_clr_key_cfg(struct rk_lcdc_driver *dev_drv) lcdc_writel(lcdc_dev, WIN3_COLOR_KEY, key_val); break; default: + printk(KERN_WARNING "%s:un support win num:%d\n", + __func__,i); break; } } @@ -935,7 +929,7 @@ static int rk3288_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) m_DSP_DEN_POL | m_DSP_DCLK_POL | m_DSP_BG_SWAP | m_DSP_RB_SWAP | m_DSP_RG_SWAP | m_DSP_DELTA_SWAP | m_DSP_DUMMY_SWAP | m_DSP_OUT_ZERO | m_DSP_BLANK_EN | - m_DSP_BLACK_EN; + m_DSP_BLACK_EN | m_DSP_X_MIR_EN | m_DSP_Y_MIR_EN; val = v_DSP_OUT_MODE(face) | v_DSP_HSYNC_POL(screen->pin_hsync) | v_DSP_VSYNC_POL(screen->pin_vsync) | v_DSP_DEN_POL(screen->pin_den) | v_DSP_DCLK_POL(screen->pin_dclk) | @@ -943,7 +937,8 @@ static int rk3288_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) v_DSP_RG_SWAP(screen->swap_rg) | v_DSP_DELTA_SWAP(screen->swap_delta) | v_DSP_DUMMY_SWAP(screen->swap_dumy) | v_DSP_OUT_ZERO(0) | - v_DSP_BLANK_EN(0) | v_DSP_BLACK_EN(0);; + v_DSP_BLANK_EN(0) | v_DSP_BLACK_EN(0) | + v_DSP_X_MIR_EN(screen->x_mirror) | v_DSP_Y_MIR_EN(screen->y_mirror); lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val); mask = m_DSP_BG_BLUE | m_DSP_BG_GREEN | m_DSP_BG_RED; @@ -984,7 +979,8 @@ static int rk3288_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen) screen->ft = 1000 / fps; dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ", lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps); - + if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable) + dev_drv->trsm_ops->enable(); if (screen->init) screen->init(); #endif @@ -1538,6 +1534,8 @@ static int rk3288_lcdc_cal_scl_fac(struct rk_lcdc_win *win) win->cbr_vsu_mode = SCALE_UP_BIL; break; default: + printk(KERN_WARNING "%s:un supported win_lb_mode:%d\n", + __func__,win->win_lb_mode); break; } DBG(1,"yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n", @@ -1564,10 +1562,14 @@ static int rk3288_lcdc_cal_scl_fac(struct rk_lcdc_win *win) yrgb_xscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW); break; default : + printk(KERN_WARNING "%s:un supported yrgb_hsd_mode:%d\n", + __func__,win->yrgb_hsd_mode); break; } break; default : + printk(KERN_WARNING "%s:un supported yrgb_hor_scl_mode:%d\n", + __func__,win->yrgb_hor_scl_mode); break; } /*win->yrgb_hor_scl_mode*/ @@ -1590,6 +1592,8 @@ static int rk3288_lcdc_cal_scl_fac(struct rk_lcdc_win *win) yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH, yrgb_dstH); break; default : + printk(KERN_WARNING "%s:un supported yrgb_vsu_mode:%d\n", + __func__,win->yrgb_vsu_mode); break; } break; @@ -1614,10 +1618,14 @@ static int rk3288_lcdc_cal_scl_fac(struct rk_lcdc_win *win) yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH, yrgb_dstH); break; default: + printk(KERN_WARNING "%s:un supported yrgb_vsd_mode:%d\n", + __func__,win->yrgb_vsd_mode); break; } /*win->yrgb_vsd_mode*/ break; default : + printk(KERN_WARNING "%s:un supported yrgb_ver_scl_mode:%d\n", + __func__,win->yrgb_ver_scl_mode); break; } win->scale_yrgb_x = yrgb_xscl_factor; @@ -1646,10 +1654,14 @@ static int rk3288_lcdc_cal_scl_fac(struct rk_lcdc_win *win) cbcr_xscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW); break; default : + printk(KERN_WARNING "%s:un supported cbr_hsd_mode:%d\n", + __func__,win->cbr_hsd_mode); break; } break; default : + printk(KERN_WARNING "%s:un supported cbr_hor_scl_mode:%d\n", + __func__,win->cbr_hor_scl_mode); break; } /*win->cbr_hor_scl_mode*/ @@ -1672,6 +1684,8 @@ static int rk3288_lcdc_cal_scl_fac(struct rk_lcdc_win *win) cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH, cbcr_dstH); break; default : + printk(KERN_WARNING "%s:un supported cbr_vsu_mode:%d\n", + __func__,win->cbr_vsu_mode); break; } break; @@ -1696,10 +1710,14 @@ static int rk3288_lcdc_cal_scl_fac(struct rk_lcdc_win *win) cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH, cbcr_dstH); break; default : + printk(KERN_WARNING "%s:un supported cbr_vsd_mode:%d\n", + __func__,win->cbr_vsd_mode); break; } break; default : + printk(KERN_WARNING "%s:un supported cbr_ver_scl_mode:%d\n", + __func__,win->cbr_ver_scl_mode); break; } win->scale_cbcr_x = cbcr_xscl_factor; @@ -1883,9 +1901,17 @@ static int win2_set_par(struct lcdc_device *lcdc_dev, win->area[i].dsp_stx = win->area[i].xpos + screen->mode.left_margin + screen->mode.hsync_len; - win->area[i].dsp_sty = win->area[i].ypos + - screen->mode.upper_margin + - screen->mode.vsync_len;; + if (screen->y_mirror == 1) { + win->area[i].dsp_sty = screen->mode.yres - + win->area[i].ypos - + win->area[i].ysize + + screen->mode.upper_margin + + screen->mode.vsync_len; + } else { + win->area[i].dsp_sty = win->area[i].ypos + + screen->mode.upper_margin + + screen->mode.vsync_len; + } } } spin_unlock(&lcdc_dev->reg_lock); @@ -1930,9 +1956,17 @@ static int win3_set_par(struct lcdc_device *lcdc_dev, win->area[i].dsp_stx = win->area[i].xpos + screen->mode.left_margin + screen->mode.hsync_len; - win->area[i].dsp_sty = win->area[i].ypos + - screen->mode.upper_margin + - screen->mode.vsync_len;; + if (screen->y_mirror == 1) { + win->area[i].dsp_sty = screen->mode.yres - + win->area[i].ypos - + win->area[i].ysize + + screen->mode.upper_margin + + screen->mode.vsync_len; + } else { + win->area[i].dsp_sty = win->area[i].ypos + + screen->mode.upper_margin + + screen->mode.vsync_len; + } } } spin_unlock(&lcdc_dev->reg_lock); @@ -2031,17 +2065,20 @@ static int rk3288_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv) { struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); - if (dev_drv->screen0->standby) - dev_drv->screen0->standby(1); - if (dev_drv->screen_ctr_info->io_disable) - dev_drv->screen_ctr_info->io_disable(); + if (dev_drv->suspend_flag) + return 0; + dev_drv->suspend_flag = 1; flush_kthread_worker(&dev_drv->update_regs_worker); - rk3288_lcdc_disable_irq(lcdc_dev); + if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable) + dev_drv->trsm_ops->disable(); + spin_lock(&lcdc_dev->reg_lock); if (likely(lcdc_dev->clk_on)) { lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN, - v_DSP_BLANK_EN(1)); + v_DSP_BLANK_EN(1)); + lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_FS_INTR_CLR | m_LINE_FLAG_INTR_CLR, + v_FS_INTR_CLR(1) | v_LINE_FLAG_INTR_CLR(1)); lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO, v_DSP_OUT_ZERO(1)); lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN, @@ -2053,6 +2090,7 @@ static int rk3288_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv) return 0; } rk3288_lcdc_clk_disable(lcdc_dev); + rk_disp_pwr_disable(dev_drv); return 0; } @@ -2064,8 +2102,9 @@ static int rk3288_lcdc_early_resume(struct rk_lcdc_driver *dev_drv) int __iomem *c; int v; - if (dev_drv->screen_ctr_info->io_enable) - dev_drv->screen_ctr_info->io_enable(); + if (!dev_drv->suspend_flag) + return 0; + rk_disp_pwr_enable(dev_drv); dev_drv->suspend_flag = 0; if (lcdc_dev->atv_layer_cnt) { @@ -2098,8 +2137,9 @@ static int rk3288_lcdc_early_resume(struct rk_lcdc_driver *dev_drv) spin_unlock(&lcdc_dev->reg_lock); } - if (dev_drv->screen0->standby) - dev_drv->screen0->standby(0); + if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable) + dev_drv->trsm_ops->enable(); + return 0; } @@ -3135,19 +3175,11 @@ static int rk3288_lcdc_probe(struct platform_device *pdev) return ret; } #ifdef USE_ION_MMU -#ifdef CONFIG_RK_FPGA if(lcdc_dev->id == 0){ strcpy(dev_drv->mmu_dts_name, "iommu,vopb_mmu"); }else{ strcpy(dev_drv->mmu_dts_name, "iommu,vopl_mmu"); } -#else - if(lcdc_dev->id == 0){ - strcpy(dev_drv->mmu_dts_name, "iommu,vopl_mmu"); - }else{ - strcpy(dev_drv->mmu_dts_name, "iommu,vopb_mmu"); - } -#endif #endif ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id); diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index ac8ab17fb421..792a4f5b0358 100755 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -135,6 +135,8 @@ int rk_fb_pixel_width(int data_format) pixel_width = 1*8; break; default: + printk(KERN_WARNING "%s:un supported format:0x%x\n", + __func__,data_format); return -EINVAL; } return pixel_width; @@ -170,7 +172,8 @@ static int rk_fb_data_fmt(int data_format,int bits_per_pixel) fb_data_fmt = YUV444; break; default: - printk("%s:un supported format:0x%x\n",__func__,data_format); + printk(KERN_WARNING "%s:un supported format:0x%x\n", + __func__,data_format); return -EINVAL; } }else{ @@ -182,6 +185,8 @@ static int rk_fb_data_fmt(int data_format,int bits_per_pixel) fb_data_fmt = RGB565; break; default: + printk(KERN_WARNING "%s:un supported bits_per_pixel:%d\n", + __func__,bits_per_pixel); break; } } @@ -201,6 +206,7 @@ int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv) enum of_gpio_flags flags; u32 val = 0; u32 debug = 0; + u32 mirror = 0; int ret; INIT_LIST_HEAD(&dev_drv->pwrlist_head); @@ -237,6 +243,22 @@ int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv) list_add_tail(&pwr_ctr->list, &dev_drv->pwrlist_head); } + of_property_read_u32(root, "rockchip,mirror", &mirror); + + if (mirror == NO_MIRROR) { + dev_drv->cur_screen->x_mirror = 0; + dev_drv->cur_screen->y_mirror = 0; + } else if (mirror == X_MIRROR) { + dev_drv->cur_screen->x_mirror = 1; + dev_drv->cur_screen->y_mirror = 0; + } else if (mirror == Y_MIRROR) { + dev_drv->cur_screen->x_mirror = 0; + dev_drv->cur_screen->y_mirror = 1; + } else if(mirror == X_Y_MIRROR) { + dev_drv->cur_screen->x_mirror = 1; + dev_drv->cur_screen->y_mirror = 1; + } + of_property_read_u32(root, "rockchip,debug", &debug); if (debug) { @@ -761,6 +783,7 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) int win_id = 0, extend_win_id = 0; struct rk_lcdc_win *extend_win = NULL; struct rk_lcdc_win *win = NULL; + struct rk_screen *screen = dev_drv->cur_screen; int fb_id = 0; @@ -777,7 +800,7 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) u32 stride_32bit_2; u32 stride_128bit_1; u32 stride_128bit_2; - u16 uv_x_off,uv_y_off; + u16 uv_x_off,uv_y_off,dsp_height,uv_y_act; u8 is_pic_yuv=0; win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id); @@ -803,6 +826,7 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) stride = stride_32bit_1;//default rgb fix->line_length = stride; + dsp_height = win->area[0].ysize; switch (win->format){ case YUV422: @@ -812,6 +836,7 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) uv_x_off = xoffset >> 1 ;// uv_y_off = yoffset;//0 fix->line_length = stride; + uv_y_act = dsp_height>>1; break; case YUV420://420sp is_pic_yuv = 1; @@ -820,6 +845,7 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) uv_x_off = xoffset; uv_y_off = yoffset >> 1; fix->line_length = stride; + uv_y_act = dsp_height>>1; break; case YUV444: is_pic_yuv = 1; @@ -828,44 +854,51 @@ static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) uv_x_off = xoffset*2; uv_y_off = yoffset; fix->line_length = stride<<2; + uv_y_act = dsp_height; break; default: break; } // x y mirror ,jump line - win->area[0].y_offset = yoffset*stride+xoffset*pixel_width/8; - if(is_pic_yuv == 1){ - win->area[0].c_offset = uv_y_off*uv_stride+uv_x_off*pixel_width/8; + if (screen->y_mirror == 1) { + if (screen->interlace == 1) { + win->area[0].y_offset = yoffset*stride*2 + + ((win->area[0].yact-1)*2+1)*stride + + xoffset*pixel_width/8; + } else { + win->area[0].y_offset = yoffset*stride + + (win->area[0].yact-1)*stride + + xoffset*pixel_width/8; + } + } else { + if (screen->interlace == 1) { + win->area[0].y_offset = yoffset*stride*2+xoffset*pixel_width/8; + } else { + win->area[0].y_offset = yoffset*stride+xoffset*pixel_width/8; + } } - - switch (win->format) { - case XBGR888: - case ARGB888: - case ABGR888: - win->area[0].y_offset=(yoffset*xvir + xoffset)*4;//win->y_offset = (yoffset*xvir + xoffset)*4; - break; - case RGB888: - win->area[0].y_offset = (yoffset*xvir + xoffset)*3; - break; - case RGB565: - win->area[0].y_offset = (yoffset*xvir + xoffset)*2; - break; - case YUV422: - win->area[0].y_offset = yoffset*xvir + xoffset; - win->area[0].c_offset = win->area[0].y_offset; - break; - case YUV420: - win->area[0].y_offset = yoffset*xvir + xoffset; - win->area[0].c_offset = (yoffset>>1)*xvir + xoffset; - break; - case YUV444: - win->area[0].y_offset = yoffset*xvir + xoffset; - win->area[0].c_offset = yoffset*2*xvir + (xoffset<<1); - break; - default: - break; + if (is_pic_yuv == 1) { + if(screen->y_mirror == 1) { + if (screen->interlace == 1) { + win->area[0].c_offset = uv_y_off*uv_stride*2 + + ((uv_y_act-1)*2+1)*uv_stride + + uv_x_off*pixel_width/8; + } else { + win->area[0].c_offset = uv_y_off*uv_stride + + (uv_y_act - 1)*uv_stride + + uv_x_off*pixel_width/8; + } + } else { + if (screen->interlace == 1) { + win->area[0].c_offset = uv_y_off*uv_stride*2+uv_x_off*pixel_width/8; + } else { + win->area[0].c_offset = uv_y_off*uv_stride+uv_x_off*pixel_width/8; + } + } } + + win->area[0].smem_start = fix->smem_start; win->area[0].cbr_start = fix->smem_start + xvir * yvir; win->state=1; @@ -1141,7 +1174,8 @@ static int rk_fb_set_win_buffer(struct fb_info *info, struct rk_fb *rk_fb = dev_get_drvdata(info->device); //struct fb_var_screeninfo *var = &info->var; struct fb_fix_screeninfo *fix = &info->fix; - //struct rk_lcdc_driver * dev_drv = (struct rk_lcdc_driver * )info->par; + struct rk_lcdc_driver * dev_drv = (struct rk_lcdc_driver * )info->par; + struct rk_screen *screen = dev_drv->cur_screen; int i,j,ion_fd,acq_fence_fd; u32 xvir,yvir; @@ -1158,14 +1192,13 @@ static int rk_fb_set_win_buffer(struct fb_info *info, u32 stride_32bit_2; u32 stride_128bit_1; u32 stride_128bit_2; - u16 uv_x_off,uv_y_off; + u16 uv_x_off,uv_y_off,uv_y_act,dsp_height; u8 is_pic_yuv=0; u8 ppixel_a=0,global_a=0; #ifdef USE_ION_MMU struct dma_buf *buf; #else ion_phys_addr_t phy_addr; - size_t len; #endif reg_win_data->area_num = 0; if(win_par->area_par[0].phy_addr == 0){ @@ -1238,7 +1271,8 @@ static int rk_fb_set_win_buffer(struct fb_info *info, reg_win_data->z_order = win_par->z_order; reg_win_data->win_id = win_par->win_id; - for(i=0;iarea_num;i++){ + for(i=0;iarea_num;i++){ + dsp_height = reg_win_data->reg_area_data[i].ysize; reg_win_data->reg_area_data[i].xpos = win_par->area_par[i].xpos;//visiable pos in panel reg_win_data->reg_area_data[i].ypos = win_par->area_par[i].ypos; @@ -1270,9 +1304,31 @@ static int rk_fb_set_win_buffer(struct fb_info *info, fix->line_length = stride; reg_win_data->reg_area_data[i].y_vir_stride = stride >> 2; // x y mirror ,jump line - reg_win_data->reg_area_data[i].y_offset = yoffset*stride+xoffset*pixel_width/8; + //reg_win_data->reg_area_data[i].y_offset = yoffset*stride+xoffset*pixel_width/8; + if (screen->y_mirror == 1) { + if (screen->interlace == 1) { + reg_win_data->reg_area_data[i].y_offset = + yoffset*stride*2 + + ((reg_win_data->reg_area_data[i].yact-1)*2+1)*stride + + xoffset*pixel_width/8; + } else { + reg_win_data->reg_area_data[i].y_offset = + yoffset*stride + + (reg_win_data->reg_area_data[i].yact-1)*stride + + xoffset*pixel_width/8; + } + } else { + if (screen->interlace == 1) { + reg_win_data->reg_area_data[i].y_offset = + yoffset*stride*2 + xoffset*pixel_width/8; + } else { + reg_win_data->reg_area_data[i].y_offset = + yoffset*stride + xoffset*pixel_width/8; + } + } + } - switch (fb_data_fmt){ + switch (fb_data_fmt) { case YUV422: is_pic_yuv = 1; stride = stride_32bit_1; @@ -1280,6 +1336,7 @@ static int rk_fb_set_win_buffer(struct fb_info *info, uv_x_off = xoffset >> 1 ;// uv_y_off = yoffset;//0 fix->line_length = stride; + uv_y_act = dsp_height>>1; break; case YUV420://420sp is_pic_yuv = 1; @@ -1288,6 +1345,7 @@ static int rk_fb_set_win_buffer(struct fb_info *info, uv_x_off = xoffset; uv_y_off = yoffset >> 1; fix->line_length = stride; + uv_y_act = dsp_height>>1; break; case YUV444: is_pic_yuv = 1; @@ -1296,17 +1354,37 @@ static int rk_fb_set_win_buffer(struct fb_info *info, uv_x_off = xoffset*2; uv_y_off = yoffset; fix->line_length = stride<<2; + uv_y_act = dsp_height; break; default: break; } if(is_pic_yuv == 1){ reg_win_data->reg_area_data[0].cbr_start = - reg_win_data->reg_area_data[0].smem_start + xvir*yvir; - reg_win_data->reg_area_data[0].c_offset = - uv_y_off*uv_stride+uv_x_off*pixel_width/8; + reg_win_data->reg_area_data[0].smem_start + xvir*yvir; reg_win_data->reg_area_data[0].uv_vir_stride = - uv_stride >> 2; + uv_stride >> 2; + if(screen->y_mirror == 1){ + if(screen->interlace == 1){ + reg_win_data->reg_area_data[0].c_offset = + uv_y_off*uv_stride*2 + + ((uv_y_act-1)*2+1)*uv_stride + + uv_x_off*pixel_width/8; + }else{ + reg_win_data->reg_area_data[0].c_offset = + uv_y_off*uv_stride + + (uv_y_act - 1)*uv_stride + + uv_x_off*pixel_width/8; + } + }else{ + if(screen->interlace == 1){ + reg_win_data->reg_area_data[0].c_offset = + uv_y_off*uv_stride*2+uv_x_off*pixel_width/8; + }else{ + reg_win_data->reg_area_data[0].c_offset = + uv_y_off*uv_stride+uv_x_off*pixel_width/8; + } + } } return 0; #ifdef USE_ION_MMU @@ -1795,7 +1873,7 @@ static int rk_fb_set_par(struct fb_info *info) u32 stride_32bit_2; u32 stride_128bit_1; u32 stride_128bit_2; - u16 uv_x_off,uv_y_off; + u16 uv_x_off,uv_y_off,dsp_height,uv_y_act; u8 is_pic_yuv=0; var->pixclock = dev_drv->pixclock; @@ -1847,7 +1925,7 @@ if (rk_fb->disp_mode != DUAL) { stride = stride_32bit_1;//default rgb fix->line_length = stride; - + dsp_height = win->area[0].ysize; switch (fb_data_fmt){ case YUV422: is_pic_yuv = 1; @@ -1857,6 +1935,7 @@ if (rk_fb->disp_mode != DUAL) { uv_y_off = yoffset;//0 fix->line_length = stride; cblen = crlen = (xvir*yvir)>>1; + uv_y_act = dsp_height; break; case YUV420://420sp is_pic_yuv = 1; @@ -1866,6 +1945,7 @@ if (rk_fb->disp_mode != DUAL) { uv_y_off = yoffset >> 1; fix->line_length = stride; cblen = crlen = (xvir*yvir)>>2; + uv_y_act = dsp_height>>1; break; case YUV444: is_pic_yuv = 1; @@ -1875,16 +1955,50 @@ if (rk_fb->disp_mode != DUAL) { uv_y_off = yoffset; fix->line_length = stride<<2; cblen = crlen = (xvir*yvir); + uv_y_act = dsp_height; break; default: break; } // x y mirror ,jump line - win->area[0].y_offset = yoffset*stride+xoffset*pixel_width/8; - if(is_pic_yuv == 1){ - win->area[0].c_offset = uv_y_off*uv_stride+uv_x_off*pixel_width/8; + if (screen->y_mirror == 1) { + if (screen->interlace == 1) { + win->area[0].y_offset = yoffset*stride*2 + + ((win->area[0].yact-1)*2+1)*stride + + xoffset*pixel_width/8; + } else { + win->area[0].y_offset = yoffset*stride + + (win->area[0].yact-1)*stride + + xoffset*pixel_width/8; + } + }else{ + if (screen->interlace == 1) { + win->area[0].y_offset = yoffset*stride*2+xoffset*pixel_width/8; + } else { + win->area[0].y_offset = yoffset*stride+xoffset*pixel_width/8; + } } + if (is_pic_yuv == 1) { + if (screen->y_mirror == 1) { + if (screen->interlace == 1) { + win->area[0].c_offset = uv_y_off*uv_stride*2 + + ((uv_y_act-1)*2+1)*uv_stride + + uv_x_off*pixel_width/8; + } else { + win->area[0].c_offset = uv_y_off*uv_stride + + (uv_y_act - 1)*uv_stride + + uv_x_off*pixel_width/8; + } + } else { + if (screen->interlace == 1) { + win->area[0].c_offset = uv_y_off*uv_stride*2+uv_x_off*pixel_width/8; + } else { + win->area[0].c_offset = uv_y_off*uv_stride+uv_x_off*pixel_width/8; + } + } + } + win->format = fb_data_fmt; win->area[0].y_vir_stride = stride>>2; win->area[0].uv_vir_stride = uv_stride>>2; diff --git a/include/dt-bindings/rkfb/rk_fb.h b/include/dt-bindings/rkfb/rk_fb.h old mode 100644 new mode 100755 index dfa9be99ebf6..4eaf4220654d --- a/include/dt-bindings/rkfb/rk_fb.h +++ b/include/dt-bindings/rkfb/rk_fb.h @@ -36,6 +36,13 @@ #define LVDS_8BIT_2 1 #define LVDS_8BIT_3 2 #define LVDS_6BIT 3 + +#define NO_MIRROR 0 +#define X_MIRROR 1 +#define Y_MIRROR 2 +#define X_Y_MIRROR 3 + + /* lvds connect config * * LVDS_8BIT_1 LVDS_8BIT_2 LVDS_8BIT_3 LVDS_6BIT diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index 7886ef848260..dbfc6c787a69 100755 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -77,6 +77,13 @@ #define RK_LF_STATUS_NC 0xfe #define RK_LF_MAX_TIMEOUT (1600000UL << 6) //>0.64s + +/*for x y mirror*/ +#define NO_MIRROR 0 +#define X_MIRROR 1 +#define Y_MIRROR 2 +#define X_Y_MIRROR 3 + /*#define USE_ION_MMU 1*/ #if defined(CONFIG_ION_ROCKCHIP) extern struct ion_client *rockchip_ion_client_create(const char * name); @@ -252,7 +259,7 @@ struct rk_lcdc_post_cfg{ u32 ysize; }; -struct rk_lcdc_area{ +struct rk_lcdc_win_area{ bool state; u32 y_offset; /*yuv/rgb offset -->LCDC_WINx_YRGB_MSTx*/ u32 c_offset; /*cb cr offset--->LCDC_WINx_CBR_MSTx*/ @@ -321,7 +328,7 @@ struct rk_lcdc_win { u32 g_alpha_val; u32 color_key_val; - struct rk_lcdc_area area[RK_WIN_MAX_AREA]; + struct rk_lcdc_win_area area[RK_WIN_MAX_AREA]; struct rk_lcdc_post_cfg post_cfg; };