rk3288 lcdc:
authorhjc <hjc@rock-chips.com>
Sat, 15 Mar 2014 08:30:49 +0000 (16:30 +0800)
committerhjc <hjc@rock-chips.com>
Sat, 15 Mar 2014 10:31:00 +0000 (18:31 +0800)
1.add suspend and resume func;
2.add x and y mirror func;
3.rename some unresonable define.

arch/arm/boot/dts/rk3288-fpga.dts
drivers/video/rockchip/lcdc/rk3288_lcdc.c
drivers/video/rockchip/rk_fb.c
include/dt-bindings/rkfb/rk_fb.h [changed mode: 0644->0755]
include/linux/rk_fb.h

index 3192bcad71b5b70a73ba392be91dc409d4b6768e..576bda47acccf47f02f0ffa6475cd21e53bd64bb 100755 (executable)
                        compatible = "rockchip,screen";
        };
 
-       lcdc0: lcdc@ff940000 {
+       lcdc1: lcdc@ff940000 {
                compatible = "rockchip,rk3288-lcdc";
                rockchip,prop = <PRMRY>;
                rochchip,pwr18 = <0>;
                reg = <0xff940000 0x10000>;
                interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+               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 = <EXTEND>;
                rockchip,pwr18 = <0>;
                reg = <0xff930000 0x10000>;
                interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
-               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";
        };
 
 
 &lcdc0 {
        status = "okay";
+       power_ctr: power_ctr {
+               rockchip,debug = <0>;
+               rockchip,mirror = <NO_MIRROR>;
+               /*lcd_en:lcd_en {
+                       rockchip,power_type = <GPIO>;
+                       gpios = <&gpio7 GPIO_A3 GPIO_ACTIVE_HIGH>;
+                       rockchip,delay = <10>;
+               };
+
+                          
+               lcd_cs:lcd_cs {
+                       rockchip,power_type = <REGULATOR>;
+                       rockchip,delay = <10>;
+               };
+
+               lcd_rst:lcd_rst {
+                       rockchip,power_type = <GPIO>;
+                       gpios = <&gpio3 GPIO_D6 GPIO_ACTIVE_HIGH>;
+                       rockchip,delay = <5>;
+               };*/
+
+       };
 };
 
 &lcdc1 {
-       status = "okay";
+       status = "disable";
 };
index 731788392b23ddc131485c4a1fde4b2e2f53cf8e..e157ae088875c8a6e555b0c12c45c87a8b7eccc6 100755 (executable)
@@ -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);
index ac8ab17fb42152694c4ab06e86788fa56f1d8868..792a4f5b035831660977dcfc79cbfbc82a4deac7 100755 (executable)
@@ -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;i<reg_win_data->area_num;i++){  
+       for(i=0;i<reg_win_data->area_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;
old mode 100644 (file)
new mode 100755 (executable)
index dfa9be9..4eaf422
 #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
index 7886ef848260aea33ed2c28d1c917f99b0cb2dd8..dbfc6c787a69ab3128a52788b449cba3728356a2 100755 (executable)
 #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;
 };