drm/rockchip: support YUV420 output mode
authorMark Yao <mark.yao@rock-chips.com>
Wed, 1 Mar 2017 01:58:34 +0000 (09:58 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Tue, 7 Mar 2017 01:59:28 +0000 (09:59 +0800)
Change-Id: I7b991c544df6da81be93d84febe59fc5089895ca
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
drivers/gpu/drm/rockchip/rockchip_drm_vop.h
drivers/gpu/drm/rockchip/rockchip_vop_reg.c

index 886534175f5f314ab2174b6e583ea8d3ed4999be..1e1832248ef4c12d490d920de2017795628bf3ee 100644 (file)
@@ -359,6 +359,17 @@ static enum vop_data_format vop_convert_format(uint32_t format)
        }
 }
 
+static bool is_yuv_output(uint32_t bus_format)
+{
+       switch (bus_format) {
+       case MEDIA_BUS_FMT_YUV8_1X24:
+       case MEDIA_BUS_FMT_YUV10_1X30:
+               return true;
+       default:
+               return false;
+       }
+}
+
 static bool is_yuv_support(uint32_t format)
 {
        switch (format) {
@@ -628,15 +639,18 @@ static int vop_csc_atomic_check(struct drm_crtc *crtc,
 {
        struct vop *vop = to_vop(crtc);
        struct drm_atomic_state *state = crtc_state->state;
+       struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
        const struct vop_csc_table *csc_table = vop->data->csc_table;
        struct drm_plane_state *pstate;
        struct drm_plane *plane;
-       bool is_yuv;
+       bool is_input_yuv, is_output_yuv;
        int ret;
 
        if (!csc_table)
                return 0;
 
+       is_output_yuv = is_yuv_output(s->bus_format);
+
        drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
                struct vop_plane_state *vop_plane_state;
 
@@ -647,12 +661,12 @@ static int vop_csc_atomic_check(struct drm_crtc *crtc,
 
                if (!pstate->fb)
                        continue;
-               is_yuv = is_yuv_support(pstate->fb->pixel_format);
+               is_input_yuv = is_yuv_support(pstate->fb->pixel_format);
 
                /*
                 * TODO: force set input and output csc mode.
                 */
-               ret = vop_csc_setup(csc_table, is_yuv, false,
+               ret = vop_csc_setup(csc_table, is_input_yuv, is_output_yuv,
                                    CSC_BT709, CSC_BT709,
                                    &vop_plane_state->y2r_table,
                                    &vop_plane_state->r2r_table,
@@ -1525,18 +1539,27 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
        case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
                val = DITHER_DOWN_EN(1) | DITHER_DOWN_MODE(RGB888_TO_RGB666);
                break;
+       case MEDIA_BUS_FMT_YUV8_1X24:
+               val = DITHER_DOWN_EN(0) | PRE_DITHER_DOWN_EN(1);
+               break;
+       case MEDIA_BUS_FMT_YUV10_1X30:
+               val = DITHER_DOWN_EN(0) | PRE_DITHER_DOWN_EN(0);
+               break;
        case MEDIA_BUS_FMT_RGB888_1X24:
        default:
                val = DITHER_DOWN_EN(0) | PRE_DITHER_DOWN_EN(0);
                break;
        }
+
        if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA)
                val |= PRE_DITHER_DOWN_EN(0);
        else
                val |= PRE_DITHER_DOWN_EN(1);
        val |= DITHER_DOWN_MODE_SEL(DITHER_DOWN_ALLEGRO);
        VOP_CTRL_SET(vop, dither_down, val);
-
+       VOP_CTRL_SET(vop, dclk_ddr,
+                    s->output_mode == ROCKCHIP_OUT_MODE_YUV420 ? 1 : 0);
+       VOP_CTRL_SET(vop, overlay_mode, is_yuv_output(s->bus_format));
        VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len);
        val = hact_st << 16;
        val |= hact_end;
index be27293a9dab12820a7fc0a3ef2825aadc7a8c53..8f4e702902bfdbd572faef3302c8d4f266ba14ba 100644 (file)
@@ -92,6 +92,7 @@ struct vop_ctrl {
        struct vop_reg dsp_layer_sel;
        struct vop_reg overlay_mode;
        struct vop_reg core_dclk_div;
+       struct vop_reg dclk_ddr;
        struct vop_reg p2i_en;
        struct vop_reg rgb_en;
        struct vop_reg edp_en;
@@ -208,6 +209,11 @@ enum {
        VOP_CSC_R2R_BT709_TO_2020,
 };
 
+enum _vop_overlay_mode {
+       VOP_RGB_DOMAIN,
+       VOP_YUV_DOMAIN
+};
+
 struct vop_win_phy {
        const struct vop_scl_regs *scl;
        const uint32_t *data_formats;
@@ -323,11 +329,12 @@ struct vop_data {
 /*
  * display output interface supported by rockchip lcdc
  */
-#define ROCKCHIP_OUT_MODE_P888 0
-#define ROCKCHIP_OUT_MODE_P666 1
-#define ROCKCHIP_OUT_MODE_P565 2
+#define ROCKCHIP_OUT_MODE_P888         0
+#define ROCKCHIP_OUT_MODE_P666         1
+#define ROCKCHIP_OUT_MODE_P565         2
+#define ROCKCHIP_OUT_MODE_YUV420       14
 /* for use special outface */
-#define ROCKCHIP_OUT_MODE_AAAA 15
+#define ROCKCHIP_OUT_MODE_AAAA         15
 
 #define ROCKCHIP_OUT_MODE_TYPE(x)      ((x) >> 16)
 #define ROCKCHIP_OUT_MODE(x)           ((x) & 0xffff)
index b4cee84650f486ac50d3ee9a0f1d34d3ed92a49a..2b627c951afbc3fd2b32fa46d791c87f03e13eb4 100644 (file)
@@ -189,6 +189,7 @@ static const struct vop_ctrl rk3288_ctrl_data = {
        .overlay_mode = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 16, 3, 2, -1),
        .core_dclk_div = VOP_REG_VER(RK3399_DSP_CTRL0, 0x1, 4, 3, 4, -1),
        .p2i_en = VOP_REG_VER(RK3399_DSP_CTRL0, 0x1, 5, 3, 4, -1),
+       .dclk_ddr = VOP_REG_VER(RK3399_DSP_CTRL0, 0x1, 8, 3, 4, -1),
        .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
        .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
        .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),