drm/stm: dsi: add regulator support
authorYannick Fertré <yannick.fertre@st.com>
Tue, 14 May 2019 09:35:56 +0000 (11:35 +0200)
committerBenjamin Gaignard <benjamin.gaignard@linaro.org>
Fri, 17 May 2019 10:11:31 +0000 (12:11 +0200)
Add support of regulator for the phy part of the DSI
controller.

Signed-off-by: Yannick Fertré <yannick.fertre@st.com>
Acked-by: Philippe Cornu <philippe.cornu@st.com>
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/1557826556-10079-3-git-send-email-yannick.fertre@st.com
drivers/gpu/drm/stm/dw_mipi_dsi-stm.c

index 1bef73e8c8fe93c282f52ea48d7fbf72377f8572..d8e4a146b320c6ad95c59128b35731272f7271f4 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/clk.h>
 #include <linux/iopoll.h>
 #include <linux/module.h>
+#include <linux/regulator/consumer.h>
 #include <drm/drmP.h>
 #include <drm/drm_mipi_dsi.h>
 #include <drm/bridge/dw_mipi_dsi.h>
@@ -76,6 +77,7 @@ struct dw_mipi_dsi_stm {
        u32 hw_version;
        int lane_min_kbps;
        int lane_max_kbps;
+       struct regulator *vdd_supply;
 };
 
 static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val)
@@ -314,21 +316,36 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        dsi->base = devm_ioremap_resource(dev, res);
        if (IS_ERR(dsi->base)) {
-               DRM_ERROR("Unable to get dsi registers\n");
-               return PTR_ERR(dsi->base);
+               ret = PTR_ERR(dsi->base);
+               DRM_ERROR("Unable to get dsi registers %d\n", ret);
+               return ret;
+       }
+
+       dsi->vdd_supply = devm_regulator_get(dev, "phy-dsi");
+       if (IS_ERR(dsi->vdd_supply)) {
+               ret = PTR_ERR(dsi->vdd_supply);
+               if (ret != -EPROBE_DEFER)
+                       DRM_ERROR("Failed to request regulator: %d\n", ret);
+               return ret;
+       }
+
+       ret = regulator_enable(dsi->vdd_supply);
+       if (ret) {
+               DRM_ERROR("Failed to enable regulator: %d\n", ret);
+               return ret;
        }
 
        dsi->pllref_clk = devm_clk_get(dev, "ref");
        if (IS_ERR(dsi->pllref_clk)) {
                ret = PTR_ERR(dsi->pllref_clk);
-               dev_err(dev, "Unable to get pll reference clock: %d\n", ret);
-               return ret;
+               DRM_ERROR("Unable to get pll reference clock: %d\n", ret);
+               goto err_clk_get;
        }
 
        ret = clk_prepare_enable(dsi->pllref_clk);
        if (ret) {
-               dev_err(dev, "%s: Failed to enable pllref_clk\n", __func__);
-               return ret;
+               DRM_ERROR("Failed to enable pllref_clk: %d\n", ret);
+               goto err_clk_get;
        }
 
        dw_mipi_dsi_stm_plat_data.base = dsi->base;
@@ -338,20 +355,28 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
 
        dsi->dsi = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data);
        if (IS_ERR(dsi->dsi)) {
-               DRM_ERROR("Failed to initialize mipi dsi host\n");
-               clk_disable_unprepare(dsi->pllref_clk);
-               return PTR_ERR(dsi->dsi);
+               ret = PTR_ERR(dsi->dsi);
+               DRM_ERROR("Failed to initialize mipi dsi host: %d\n", ret);
+               goto err_dsi_probe;
        }
 
        return 0;
+
+err_dsi_probe:
+       clk_disable_unprepare(dsi->pllref_clk);
+err_clk_get:
+       regulator_disable(dsi->vdd_supply);
+
+       return ret;
 }
 
 static int dw_mipi_dsi_stm_remove(struct platform_device *pdev)
 {
        struct dw_mipi_dsi_stm *dsi = platform_get_drvdata(pdev);
 
-       clk_disable_unprepare(dsi->pllref_clk);
        dw_mipi_dsi_remove(dsi->dsi);
+       clk_disable_unprepare(dsi->pllref_clk);
+       regulator_disable(dsi->vdd_supply);
 
        return 0;
 }
@@ -363,6 +388,7 @@ static int __maybe_unused dw_mipi_dsi_stm_suspend(struct device *dev)
        DRM_DEBUG_DRIVER("\n");
 
        clk_disable_unprepare(dsi->pllref_clk);
+       regulator_disable(dsi->vdd_supply);
 
        return 0;
 }
@@ -370,10 +396,22 @@ static int __maybe_unused dw_mipi_dsi_stm_suspend(struct device *dev)
 static int __maybe_unused dw_mipi_dsi_stm_resume(struct device *dev)
 {
        struct dw_mipi_dsi_stm *dsi = dw_mipi_dsi_stm_plat_data.priv_data;
+       int ret;
 
        DRM_DEBUG_DRIVER("\n");
 
-       clk_prepare_enable(dsi->pllref_clk);
+       ret = regulator_enable(dsi->vdd_supply);
+       if (ret) {
+               DRM_ERROR("Failed to enable regulator: %d\n", ret);
+               return ret;
+       }
+
+       ret = clk_prepare_enable(dsi->pllref_clk);
+       if (ret) {
+               regulator_disable(dsi->vdd_supply);
+               DRM_ERROR("Failed to enable pllref_clk: %d\n", ret);
+               return ret;
+       }
 
        return 0;
 }