drm/rockchip: analogix_dp: add supports for regulators in edp IP
authorRandy Li <ayaka@soulik.info>
Sat, 22 Oct 2016 19:18:53 +0000 (03:18 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 27 Apr 2017 11:28:37 +0000 (19:28 +0800)
I found if eDP_AVDD_1V0 and eDP_AVDD_1V8 are not been power at
RK3288, once trying to enable the pclk clock, the kernel would dead.
This patch would try to enable them first.

The eDP_AVDD_1V8 is used for eDP phy, and the eDP_AVDD_1V0 are used
both for eDP phy and controller.

Change-Id: I4e8a34609d5b292d7da77385ff15bebbf258090c
Signed-off-by: Randy Li <ayaka@soulik.info>
Signed-off-by: Randy Li <randy.li@rock-chips.com>
Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c

index f996e0d7be0b2c855db193400c0ce80e4cd53ac6..ecb63962b4ff309a90a17b7b472526e2a8eefd2c 100644 (file)
@@ -29,6 +29,10 @@ Required properties:
     Port 0: contained 2 endpoints, connecting to the output of vop.
     Port 1: contained 1 endpoint, connecting to the input of panel.
 
+Optional properties
+- vcc-supply: Regulator for eDP_AVDD_1V0.
+- vccio-supply: Regulator for eDP_AVDD_1V8.
+
 For the below properties, please refer to Analogix DP binding document:
  * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
 - phys (required)
index 810676cc72c72af9a17dd43e3a2026e7df895191..635b1ff23366f3c73b184240a0edde8d67b2d191 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/of_device.h>
 #include <linux/of_graph.h>
 #include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
 #include <linux/reset.h>
 #include <linux/clk.h>
 
@@ -59,6 +60,8 @@ struct rockchip_dp_device {
        struct clk               *pclk;
        struct regmap            *grf;
        struct reset_control     *rst;
+       struct regulator         *vcc_supply;
+       struct regulator         *vccio_supply;
 
        const struct rockchip_dp_chip_data *data;
 
@@ -79,6 +82,24 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
        struct rockchip_dp_device *dp = to_dp(plat_data);
        int ret;
 
+       if (!IS_ERR(dp->vcc_supply)) {
+               ret = regulator_enable(dp->vcc_supply);
+               if (ret) {
+                       dev_err(dp->dev,
+                               "failed to enable vcc regulator: %d\n", ret);
+                       return ret;
+               }
+       }
+
+       if (!IS_ERR(dp->vccio_supply)) {
+               ret = regulator_enable(dp->vccio_supply);
+               if (ret) {
+                       dev_err(dp->dev,
+                               "failed to enable vccio regulator: %d\n", ret);
+                       return ret;
+               }
+       }
+
        ret = clk_prepare_enable(dp->pclk);
        if (ret < 0) {
                dev_err(dp->dev, "failed to enable pclk %d\n", ret);
@@ -100,6 +121,11 @@ static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
 
        clk_disable_unprepare(dp->pclk);
 
+       if (!IS_ERR(dp->vccio_supply))
+               regulator_disable(dp->vccio_supply);
+       if (!IS_ERR(dp->vcc_supply))
+               regulator_disable(dp->vcc_supply);
+
        return 0;
 }
 
@@ -232,6 +258,32 @@ static int rockchip_dp_init(struct rockchip_dp_device *dp)
                return PTR_ERR(dp->rst);
        }
 
+       dp->vcc_supply = devm_regulator_get_optional(dev, "vcc");
+       dp->vccio_supply = devm_regulator_get_optional(dev, "vccio");
+
+       if (IS_ERR(dp->vcc_supply)) {
+               dev_err(dev, "failed to get vcc regulator: %ld\n",
+                       PTR_ERR(dp->vcc_supply));
+       } else {
+               ret = regulator_enable(dp->vcc_supply);
+               if (ret) {
+                       dev_err(dev,
+                               "failed to enable vcc regulator: %d\n", ret);
+                       return ret;
+               }
+       }
+       if (IS_ERR(dp->vccio_supply)) {
+               dev_err(dev, "failed to get vccio regulator: %ld\n",
+                       PTR_ERR(dp->vccio_supply));
+       } else {
+               ret = regulator_enable(dp->vccio_supply);
+               if (ret) {
+                       dev_err(dev,
+                               "failed to enable vccio regulator: %d\n", ret);
+                       return ret;
+               }
+       }
+
        ret = clk_prepare_enable(dp->pclk);
        if (ret < 0) {
                dev_err(dp->dev, "failed to enable pclk %d\n", ret);