drm/rockchip: vop: support mode_valid for crtc
authorMark Yao <mark.yao@rock-chips.com>
Sun, 22 Jan 2017 07:53:49 +0000 (15:53 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Sun, 5 Feb 2017 06:25:13 +0000 (14:25 +0800)
Change-Id: I51f2377c5bd4bdecf44ad31f11e4e7131c2c10c1
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
drivers/gpu/drm/rockchip/rockchip_drm_drv.h
drivers/gpu/drm/rockchip/rockchip_drm_vop.c

index 8a8d67381e74e4d5dd43527fbfb534a85d60b842..521331acbf40f646117779ed71902fe72ad77ef7 100644 (file)
@@ -45,6 +45,9 @@ struct rockchip_crtc_funcs {
        void (*wait_for_update)(struct drm_crtc *crtc);
        void (*cancel_pending_vblank)(struct drm_crtc *crtc, struct drm_file *file_priv);
        int (*debugfs_dump)(struct drm_crtc *crtc, struct seq_file *s);
+       enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,
+                                          const struct drm_display_mode *mode,
+                                          int output_type);
 };
 
 struct drm_rockchip_subdrv {
index a10cd1116ce59298933c684c9a94173c38da12fa..8066bf182ef539c70353e7ecfb957adea4441409 100644 (file)
@@ -1402,6 +1402,31 @@ static int vop_crtc_debugfs_dump(struct drm_crtc *crtc, struct seq_file *s)
        return 0;
 }
 
+static enum drm_mode_status
+vop_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode,
+                   int output_type)
+{
+       struct vop *vop = to_vop(crtc);
+       const struct vop_data *vop_data = vop->data;
+       int clock;
+
+       if (mode->hdisplay > vop_data->max_disably_output.width)
+               return MODE_BAD_HVALUE;
+       if (mode->vdisplay > vop_data->max_disably_output.height)
+               return MODE_BAD_VVALUE;
+
+       clock = clk_round_rate(vop->dclk, mode->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)
+                       return MODE_CLOCK_RANGE;
+
+       return MODE_OK;
+}
+
 static const struct rockchip_crtc_funcs private_crtc_funcs = {
        .loader_protect = vop_crtc_loader_protect,
        .enable_vblank = vop_crtc_enable_vblank,
@@ -1409,6 +1434,7 @@ static const struct rockchip_crtc_funcs private_crtc_funcs = {
        .wait_for_update = vop_crtc_wait_for_update,
        .cancel_pending_vblank = vop_crtc_cancel_pending_vblank,
        .debugfs_dump = vop_crtc_debugfs_dump,
+       .mode_valid = vop_crtc_mode_valid,
 };
 
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,