From 77ec03b5af6b18d5c84df4ab27f8a1f8271cb732 Mon Sep 17 00:00:00 2001 From: Wyon Bi Date: Fri, 28 Sep 2018 11:15:40 +0800 Subject: [PATCH] drm/rockchip: edp: Fix unbalanced power status Change-Id: I85f2c9b051a0933a13a709ad8eb27bc2c4a2b990 Signed-off-by: Wyon Bi --- .../gpu/drm/rockchip/analogix_dp-rockchip.c | 104 ++++++++++-------- 1 file changed, 61 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index a2ee2e023c5e..00abf3eced17 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -83,29 +83,19 @@ 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)) { + if (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 (ret) + dev_warn(dp->dev, "failed to enable vcc: %d\n", ret); } - if (!IS_ERR(dp->vccio_supply)) { + if (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; - } + if (ret) + dev_warn(dp->dev, "failed to enable vccio: %d\n", ret); } - ret = clk_prepare_enable(dp->pclk); - if (ret < 0) { - dev_err(dp->dev, "failed to enable pclk %d\n", ret); - return ret; - } + clk_prepare_enable(dp->pclk); ret = rockchip_dp_pre_init(dp); if (ret < 0) { @@ -122,9 +112,10 @@ static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data) clk_disable_unprepare(dp->pclk); - if (!IS_ERR(dp->vccio_supply)) + if (dp->vccio_supply) regulator_disable(dp->vccio_supply); - if (!IS_ERR(dp->vcc_supply)) + + if (dp->vcc_supply) regulator_disable(dp->vcc_supply); return 0; @@ -223,12 +214,48 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, return 0; } +static int rockchip_dp_drm_encoder_loader_protect(struct drm_encoder *encoder, + bool on) +{ + struct rockchip_dp_device *dp = to_dp(encoder); + int ret; + + if (on) { + if (dp->vcc_supply) { + ret = regulator_enable(dp->vcc_supply); + if (ret) + dev_warn(dp->dev, + "failed to enable vcc: %d\n", ret); + } + + if (dp->vccio_supply) { + ret = regulator_enable(dp->vccio_supply); + if (ret) + dev_warn(dp->dev, + "failed to enable vccio: %d\n", ret); + } + + clk_prepare_enable(dp->pclk); + } else { + clk_disable_unprepare(dp->pclk); + + if (dp->vccio_supply) + regulator_disable(dp->vccio_supply); + + if (dp->vcc_supply) + regulator_disable(dp->vcc_supply); + } + + return 0; +} + static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = { .mode_fixup = rockchip_dp_drm_encoder_mode_fixup, .mode_set = rockchip_dp_drm_encoder_mode_set, .enable = rockchip_dp_drm_encoder_enable, .disable = rockchip_dp_drm_encoder_nop, .atomic_check = rockchip_dp_drm_encoder_atomic_check, + .loader_protect = rockchip_dp_drm_encoder_loader_protect, }; static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder) @@ -265,35 +292,26 @@ static int rockchip_dp_init(struct rockchip_dp_device *dp) } 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); + if (PTR_ERR(dp->vcc_supply) != -ENODEV) { + ret = PTR_ERR(dp->vcc_supply); + dev_err(dev, "failed to get vcc regulator: %d\n", ret); return ret; } + + dp->vcc_supply = NULL; } - ret = clk_prepare_enable(dp->pclk); - if (ret < 0) { - dev_err(dp->dev, "failed to enable pclk %d\n", ret); - return ret; + dp->vccio_supply = devm_regulator_get_optional(dev, "vccio"); + if (IS_ERR(dp->vccio_supply)) { + if (PTR_ERR(dp->vccio_supply) != -ENODEV) { + ret = PTR_ERR(dp->vccio_supply); + dev_err(dev, "failed to get vccio regulator: %d\n", + ret); + return ret; + } + + dp->vccio_supply = NULL; } return 0;