summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c')
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index f80c116018b5..093a60b5d2d3 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -283,6 +283,9 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
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;
@@ -331,15 +334,27 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
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);
@@ -368,6 +383,8 @@ unref:
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;
@@ -379,6 +396,7 @@ static int fsl_dcu_drm_remove(struct platform_device *pdev)
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;