drm/rockchip: vop: support DRM_MODE_FLAG_DBLCLK
authorMark Yao <mark.yao@rock-chips.com>
Fri, 24 Feb 2017 02:56:43 +0000 (10:56 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Fri, 24 Feb 2017 10:33:52 +0000 (18:33 +0800)
Change-Id: I604e6ba32a2ac3a6569d341d23f9a3368f921120
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
drivers/gpu/drm/rockchip/rockchip_vop_reg.c

index 808021568563dd22d3583479c63f0e59fa975ced..64132449431d75f7b63d1bb92623cfebf7fc7f01 100644 (file)
@@ -1398,6 +1398,7 @@ vop_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode,
 {
        struct vop *vop = to_vop(crtc);
        const struct vop_data *vop_data = vop->data;
+       int request_clock = mode->clock;
        int clock;
 
        if (mode->hdisplay > vop_data->max_disably_output.width)
@@ -1405,13 +1406,16 @@ vop_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode,
        if (mode->vdisplay > vop_data->max_disably_output.height)
                return MODE_BAD_VVALUE;
 
-       clock = clk_round_rate(vop->dclk, mode->clock * 1000) / 1000;
+       if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+               request_clock *= 2;
+       clock = clk_round_rate(vop->dclk, request_clock * 1000) / 1000;
+
        /*
         * Hdmi or DisplayPort request a Accurate clock.
         */
        if (output_type == DRM_MODE_CONNECTOR_HDMIA ||
            output_type == DRM_MODE_CONNECTOR_DisplayPort)
-               if (clock != mode->clock)
+               if (clock != request_clock)
                        return MODE_CLOCK_RANGE;
 
        return MODE_OK;
@@ -1433,13 +1437,16 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
 {
        struct vop *vop = to_vop(crtc);
        const struct vop_data *vop_data = vop->data;
+       int request_clock = mode->clock;
 
        if (mode->hdisplay > vop_data->max_disably_output.width ||
            mode->vdisplay > vop_data->max_disably_output.height)
                return false;
 
-       adjusted_mode->clock =
-               clk_round_rate(vop->dclk, mode->clock * 1000) / 1000;
+       if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+               request_clock *= 2;
+       adjusted_mode->crtc_clock =
+               clk_round_rate(vop->dclk, request_clock * 1000) / 1000;
 
        return true;
 }
@@ -1549,7 +1556,10 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
                VOP_CTRL_SET(vop, p2i_en, 0);
        }
 
-       clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
+       VOP_CTRL_SET(vop, core_dclk_div,
+                    !!(adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK));
+
+       clk_set_rate(vop->dclk, adjusted_mode->crtc_clock * 1000);
 
        vop_cfg_done(vop);
        /*
index 11e950891114d5073ec16b957b614931e8417f41..1899e458ca308775aab4afac8a726204e3d46d42 100644 (file)
@@ -187,7 +187,7 @@ static const struct vop_ctrl rk3288_ctrl_data = {
        .post_lb_mode = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 18, 3, 2, -1),
        .global_regdone_en = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 11, 3, 2, -1),
        .overlay_mode = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 16, 3, 2, -1),
-       .core_dclk_div = VOP_REG_VER(RK3288_SYS_CTRL, 0x1, 4, 3, 4, -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),
        .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
        .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),