struct drm_device *dev = crtc->dev;
        struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
        struct drm_display_mode *mode = &crtc->state->mode;
-       unsigned int hbp, hfp, hsw, vbp, vfp, vsw, div, index, pol = 0;
-       unsigned long dcuclk;
+       unsigned int hbp, hfp, hsw, vbp, vfp, vsw, index, pol = 0;
 
        index = drm_crtc_index(crtc);
-       dcuclk = clk_get_rate(fsl_dev->pix_clk);
-       div = dcuclk / mode->clock / 1000;
+       clk_set_rate(fsl_dev->pix_clk, mode->clock * 1000);
 
        /* Configure timings: */
        hbp = mode->htotal - mode->hsync_end;
        regmap_write(fsl_dev->regmap, DCU_DISP_SIZE,
                     DCU_DISP_SIZE_DELTA_Y(mode->vdisplay) |
                     DCU_DISP_SIZE_DELTA_X(mode->hdisplay));
-       regmap_write(fsl_dev->regmap, DCU_DIV_RATIO, div);
        regmap_write(fsl_dev->regmap, DCU_SYN_POL, pol);
        regmap_write(fsl_dev->regmap, DCU_BGND, DCU_BGND_R(0) |
                     DCU_BGND_G(0) | DCU_BGND_B(0));
 
        struct resource *res;
        void __iomem *base;
        struct drm_driver *driver = &fsl_dcu_drm_driver;
+       struct clk *pix_clk_in;
+       char pix_clk_name[32];
+       const char *pix_clk_in_name;
        const struct of_device_id *id;
        int ret;
 
                return ret;
        }
 
-       fsl_dev->pix_clk = devm_clk_get(dev, "pix");
+       pix_clk_in = devm_clk_get(dev, "pix");
+       if (IS_ERR(pix_clk_in)) {
+               /* legancy binding, use dcu clock as pixel clock input */
+               pix_clk_in = fsl_dev->clk;
+       }
+
+       pix_clk_in_name = __clk_get_name(pix_clk_in);
+       snprintf(pix_clk_name, sizeof(pix_clk_name), "%s_pix", pix_clk_in_name);
+       fsl_dev->pix_clk = clk_register_divider(dev, pix_clk_name,
+                       pix_clk_in_name, 0, base + DCU_DIV_RATIO,
+                       0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL);
        if (IS_ERR(fsl_dev->pix_clk)) {
-               /* legancy binding, use dcu clock as pixel clock */
-               fsl_dev->pix_clk = fsl_dev->clk;
+               dev_err(dev, "failed to register pix clk\n");
+               ret = PTR_ERR(fsl_dev->pix_clk);
+               goto disable_clk;
        }
+
        ret = clk_prepare_enable(fsl_dev->pix_clk);
        if (ret < 0) {
                dev_err(dev, "failed to enable pix clk\n");
-               goto disable_clk;
+               goto unregister_pix_clk;
        }
 
        drm = drm_dev_alloc(driver, dev);
        drm_dev_unref(drm);
 disable_pix_clk:
        clk_disable_unprepare(fsl_dev->pix_clk);
+unregister_pix_clk:
+       clk_unregister(fsl_dev->pix_clk);
 disable_clk:
        clk_disable_unprepare(fsl_dev->clk);
        return ret;
 
        clk_disable_unprepare(fsl_dev->clk);
        clk_disable_unprepare(fsl_dev->pix_clk);
+       clk_unregister(fsl_dev->pix_clk);
        drm_put_dev(fsl_dev->drm);
 
        return 0;