]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
drm: xilinx: crtc: Change the order of CCF API calls
authorHyun Kwon <hyun.kwon@xilinx.com>
Thu, 26 Jan 2017 22:02:42 +0000 (14:02 -0800)
committerMichal Simek <michal.simek@xilinx.com>
Fri, 3 Feb 2017 09:44:36 +0000 (10:44 +0100)
The clock should be disabled/unprepared before calling
set_rate() operations. Change the calling sequence accordingly.

Signed-off-by: Hyun Kwon <hyun.kwon@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/gpu/drm/xilinx/xilinx_drm_crtc.c

index bebdc7d9a80e0c7b4085db4b1dc834363c0932d5..3c853b6fe0d456c9fe06122f3d5b9656927886fc 100644 (file)
@@ -42,6 +42,7 @@ struct xilinx_drm_crtc {
        struct xilinx_cresample *cresample;
        struct xilinx_rgb2yuv *rgb2yuv;
        struct clk *pixel_clock;
+       bool pixel_clock_enabled;
        struct xilinx_vtc *vtc;
        struct xilinx_drm_plane_manager *plane_manager;
        int dpms;
@@ -128,6 +129,11 @@ static int xilinx_drm_crtc_mode_set(struct drm_crtc *base_crtc,
        long diff;
        int ret;
 
+       if (crtc->pixel_clock_enabled) {
+               clk_disable_unprepare(crtc->pixel_clock);
+               crtc->pixel_clock_enabled = false;
+       }
+
        /* set pixel clock */
        ret = clk_set_rate(crtc->pixel_clock, adjusted_mode->clock * 1000);
        if (ret) {
@@ -140,6 +146,16 @@ static int xilinx_drm_crtc_mode_set(struct drm_crtc *base_crtc,
                DRM_DEBUG_KMS("actual pixel clock rate(%d) is off by %ld\n",
                                adjusted_mode->clock, diff);
 
+       if (!crtc->pixel_clock_enabled) {
+               ret = clk_prepare_enable(crtc->pixel_clock);
+               if (ret) {
+                       DRM_ERROR("failed to enable a pixel clock\n");
+                       crtc->pixel_clock_enabled = false;
+                       return ret;
+               }
+       }
+       crtc->pixel_clock_enabled = true;
+
        if (crtc->vtc) {
                /* set video timing */
                vm.hactive = adjusted_mode->hdisplay;
@@ -258,7 +274,10 @@ void xilinx_drm_crtc_destroy(struct drm_crtc *base_crtc)
        if (crtc->dp_sub)
                xilinx_drm_dp_sub_put(crtc->dp_sub);
 
-       clk_disable_unprepare(crtc->pixel_clock);
+       if (crtc->pixel_clock_enabled) {
+               clk_disable_unprepare(crtc->pixel_clock);
+               crtc->pixel_clock_enabled = false;
+       }
 
        xilinx_drm_plane_remove_manager(crtc->plane_manager);
 }
@@ -511,9 +530,11 @@ struct drm_crtc *xilinx_drm_crtc_create(struct drm_device *drm)
 
        ret = clk_prepare_enable(crtc->pixel_clock);
        if (ret) {
-               DRM_DEBUG_KMS("failed to prepare/enable clock\n");
+               DRM_ERROR("failed to enable a pixel clock\n");
+               crtc->pixel_clock_enabled = false;
                goto err_plane;
        }
+       crtc->pixel_clock_enabled = true;
 
        sub_node = of_parse_phandle(drm->dev->of_node, "xlnx,vtc", 0);
        if (sub_node) {
@@ -522,7 +543,7 @@ struct drm_crtc *xilinx_drm_crtc_create(struct drm_device *drm)
                if (IS_ERR(crtc->vtc)) {
                        DRM_ERROR("failed to probe video timing controller\n");
                        ret = PTR_ERR(crtc->vtc);
-                       goto err_plane;
+                       goto err_pixel_clk;
                }
        }
 
@@ -531,7 +552,7 @@ struct drm_crtc *xilinx_drm_crtc_create(struct drm_device *drm)
                ret = PTR_ERR(crtc->dp_sub);
                if (ret != -EPROBE_DEFER)
                        DRM_ERROR("failed to get a dp_sub\n");
-               goto err_plane;
+               goto err_pixel_clk;
        }
 
        crtc->dpms = DRM_MODE_DPMS_OFF;
@@ -541,12 +562,17 @@ struct drm_crtc *xilinx_drm_crtc_create(struct drm_device *drm)
                                        NULL, &xilinx_drm_crtc_funcs, NULL);
        if (ret) {
                DRM_ERROR("failed to initialize crtc\n");
-               goto err_plane;
+               goto err_pixel_clk;
        }
        drm_crtc_helper_add(&crtc->base, &xilinx_drm_crtc_helper_funcs);
 
        return &crtc->base;
 
+err_pixel_clk:
+       if (crtc->pixel_clock_enabled) {
+               clk_disable_unprepare(crtc->pixel_clock);
+               crtc->pixel_clock_enabled = false;
+       }
 err_plane:
        xilinx_drm_plane_remove_manager(crtc->plane_manager);
        return ERR_PTR(ret);