rk312x:lcdc: add config output_domain(RGB/YUV) and modify BCSH CSC config
authorzwl <zwl@rockchips.com>
Thu, 21 Aug 2014 14:24:09 +0000 (22:24 +0800)
committerzwl <zwl@rockchips.com>
Thu, 21 Aug 2014 14:24:09 +0000 (22:24 +0800)
drivers/video/rockchip/lcdc/rk312x_lcdc.c
drivers/video/rockchip/lcdc/rk312x_lcdc.h
drivers/video/rockchip/rk_fb.c
include/linux/rk_fb.h

index f2b8be9e8512c1dceba58ba6518f1af0fc0ddd94..5fa0dfed2bd2c37c85c48e2aab237c82f46f4075 100755 (executable)
@@ -235,9 +235,10 @@ static int rk312x_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
 static void lcdc_layer_csc_mode(struct lcdc_device *lcdc_dev,
                                      struct rk_lcdc_win *win)
 {
-       struct rk_screen *screen = lcdc_dev->driver.cur_screen;
+       struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
+       struct rk_screen *screen = dev_drv->cur_screen;
 
-       if (lcdc_dev->overlay_mode == VOP_YUV_DOMAIN) {
+       if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
                switch (win->fmt_cfg) {
                case VOP_FORMAT_ARGB888:
                case VOP_FORMAT_RGB888:
@@ -259,7 +260,7 @@ static void lcdc_layer_csc_mode(struct lcdc_device *lcdc_dev,
                        lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN1_CSC_MODE,
                                     v_WIN1_CSC_MODE(win->csc_mode));
                }
-       } else if (lcdc_dev->overlay_mode == VOP_RGB_DOMAIN) {
+       } else if (dev_drv->overlay_mode == VOP_RGB_DOMAIN) {
                switch (win->fmt_cfg) {
                case VOP_FORMAT_YCBCR420:
                        if (win->id  == 0) {
@@ -283,7 +284,7 @@ static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
 
        if (win->state == 1) {
                if (lcdc_dev->soc_type == VOP_RK312X)
-                       lcdc_layer_csc_mode(lcdc_dev,win);
+                       lcdc_layer_csc_mode(lcdc_dev, win);
 
                if (win->id == 0) {
                        mask = m_WIN0_EN | m_WIN0_FORMAT | m_WIN0_RB_SWAP;
@@ -828,7 +829,8 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                                 mask = m_RGB_DCLK_EN | m_RGB_DCLK_INVERT;
                                val = v_RGB_DCLK_EN(1) | v_RGB_DCLK_INVERT(0);
                                 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
-                               lcdc_dev->overlay_mode = VOP_RGB_DOMAIN;
+                               dev_drv->overlay_mode = VOP_RGB_DOMAIN;
+                               dev_drv->output_domain = OUTPUT_RGB_DOMAIN;
                         }
                         break;
                 case SCREEN_LVDS:
@@ -836,7 +838,8 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                                 mask = m_LVDS_DCLK_EN | m_LVDS_DCLK_INVERT;
                                val = v_LVDS_DCLK_EN(1) | v_LVDS_DCLK_INVERT(1);
                                 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
-                               lcdc_dev->overlay_mode = VOP_RGB_DOMAIN;
+                               dev_drv->overlay_mode = VOP_RGB_DOMAIN;
+                               dev_drv->output_domain = OUTPUT_RGB_DOMAIN;
                         }
                         break;
                 case SCREEN_MIPI:
@@ -844,7 +847,8 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                                 mask = m_MIPI_DCLK_EN | m_MIPI_DCLK_INVERT;
                                val = v_MIPI_DCLK_EN(1) | v_MIPI_DCLK_INVERT(0);
                                 lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
-                               lcdc_dev->overlay_mode = VOP_RGB_DOMAIN;
+                               dev_drv->overlay_mode = VOP_RGB_DOMAIN;
+                               dev_drv->output_domain = OUTPUT_RGB_DOMAIN;
                         }
                         break;
                case SCREEN_HDMI:
@@ -859,7 +863,10 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                        }
                        lcdc_msk_reg(lcdc_dev, AXI_BUS_CTRL, mask, val);
                         if (lcdc_dev->soc_type == VOP_RK312X) {
-                               lcdc_dev->overlay_mode = VOP_YUV_DOMAIN;
+                               if (dev_drv->output_domain == OUTPUT_YUV_DOMAIN)
+                                       dev_drv->overlay_mode = VOP_YUV_DOMAIN;
+                               else
+                                       dev_drv->overlay_mode = VOP_RGB_DOMAIN;
                                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
                                              m_SW_UV_OFFSET_EN,
                                              v_SW_UV_OFFSET_EN(0));
@@ -897,7 +904,7 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                                return -1;
                        }
                         if (lcdc_dev->soc_type == VOP_RK312X) {
-                               lcdc_dev->overlay_mode = VOP_YUV_DOMAIN;
+                               dev_drv->overlay_mode = VOP_YUV_DOMAIN;
                                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,
                                              m_SW_UV_OFFSET_EN,
                                              v_SW_UV_OFFSET_EN(1));
@@ -960,7 +967,7 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                                break;
                        }
                        lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_SW_OVERLAY_MODE,
-                                    v_SW_OVERLAY_MODE(lcdc_dev->overlay_mode));
+                                    v_SW_OVERLAY_MODE(dev_drv->overlay_mode));
                 }
 
                mask = m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL |
@@ -1637,12 +1644,22 @@ static int rk312x_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
                lcdc_cfg_done(lcdc_dev);
        }
 
-       if (lcdc_dev->overlay_mode == VOP_YUV_DOMAIN) {
-               lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_R2Y_CSC_MODE,
-                            v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_BYPASS));
-       } else {
-               lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_R2Y_CSC_MODE,
-                            v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG));
+       if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
+               if (dev_drv->output_domain == OUTPUT_YUV_DOMAIN)        /* bypass */
+                       lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_Y2R_EN,
+                                       v_BCSH_Y2R_EN(0));
+               else    /* YUV2RGB */
+                       lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
+                                       m_BCSH_Y2R_EN | m_BCSH_Y2R_CSC_MODE,
+                                       v_BCSH_Y2R_EN(1) | v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG));
+       } else {        /* overlay_mode=VOP_RGB_DOMAIN */
+               if (dev_drv->output_domain == OUTPUT_RGB_DOMAIN)        /* bypass */
+                       lcdc_msk_reg(lcdc_dev, BCSH_CTRL, m_BCSH_R2Y_EN,
+                                       v_BCSH_R2Y_EN(0));
+               else    /* RGB2YUV */
+                       lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
+                                       m_BCSH_R2Y_EN | m_BCSH_R2Y_CSC_MODE,
+                                       v_BCSH_R2Y_EN(1) | v_BCSH_R2Y_CSC_MODE(VOP_Y2R_CSC_MPEG));
        }
 
        spin_unlock(&lcdc_dev->reg_lock);
index 92cd5400c1c399c269e866e0a3596f460255c0da..8422303fb2b583040174f9d14449f17d44f23c81 100755 (executable)
@@ -415,7 +415,7 @@ enum _VOP_SOC_TYPE {
        #define v_BCSH_EN(x)            BITS_MASK(x, 1, 0)
         #define v_BCSH_R2Y_CSC_MODE(x)  BITS_MASK(x, 1, 1)       /* rk312x */
        #define v_BCSH_OUT_MODE(x)      BITS_MASK(x, 3, 2)
-       #define v_BCSH_CSC_MODE(x)      BITS_MASK(x, 3, 4)
+       #define v_BCSH_Y2R_CSC_MODE(x)  BITS_MASK(x, 3, 4)
         #define v_BCSH_Y2R_EN(x)        BITS_MASK(x, 1, 6)       /* rk312x */
         #define v_BCSH_R2Y_EN(x)        BITS_MASK(x, 1, 7)       /* rk312x */
 
@@ -688,7 +688,6 @@ struct lcdc_device {
         u32 s_pixclock;
 
        u32 standby;                    /* 1:standby,0:work */
-       u16 overlay_mode;
 };
 
 static inline void lcdc_writel(struct lcdc_device *lcdc_dev, u32 offset, u32 v)
index a2065a9a079276243627d71c5633ca0d7c809920..4aa72e57430d3128ed0bf6a5751c2b1000a65ab9 100755 (executable)
@@ -3247,8 +3247,12 @@ int rk_fb_switch_screen(struct rk_screen *screen, int enable, int lcdc_id)
                 * switch lcdc screen to primary screen size that may
                 * used for MID, when hdmi remove if disp mode is ONE DUAL
                 */
-               if (primary_screen.type != SCREEN_HDMI)
+               if (primary_screen.type != SCREEN_HDMI) {
+                       dev_drv->output_domain = OUTPUT_RGB_DOMAIN;
                        rk_fb_set_screen_scaler(&primary_screen, 0);
+               } else {
+                       dev_drv->output_domain = OUTPUT_YUV_DOMAIN;
+               }
        } else {
                dev_drv = rk_get_lcdc_drv(name);
                if (dev_drv == NULL) {
index 4388a8646423b8b8ded62e4caac382345d8edf27..b99acfdee3a948d6d4b284f9c0c432e841480c84 100755 (executable)
@@ -227,9 +227,14 @@ enum fb_win_map_order {
 
 enum
 {
-    SCALE_NONE = 0x0,
-    SCALE_UP   = 0x1,
-    SCALE_DOWN = 0x2
+       SCALE_NONE = 0x0,
+       SCALE_UP   = 0x1,
+       SCALE_DOWN = 0x2
+};
+
+enum dsp_out_domain {
+       OUTPUT_RGB_DOMAIN = 0x0,
+       OUTPUT_YUV_DOMAIN,
 };
 
 typedef enum {
@@ -547,6 +552,9 @@ struct rk_lcdc_driver {
        struct rk_screen *cur_screen;   //screen0 is primary screen ,like lcd panel,screen1 is  extend screen,like hdmi
        u32 pixclock;
        u16 rotate_mode;
+       u16 cabc_mode;
+       u16 overlay_mode;
+       u16 output_domain;
 
        char fb0_win_id;
        char fb1_win_id;
@@ -571,7 +579,6 @@ struct rk_lcdc_driver {
        struct sw_sync_timeline *timeline;
        int                     timeline_max;
        int                     suspend_flag;
-       int                     cabc_mode;
        struct list_head        update_regs_list;
        struct mutex            update_regs_list_lock;
        struct kthread_worker   update_regs_worker;