From 5d2c0e06ed34f97cc1c28ca737ef0554c668214d Mon Sep 17 00:00:00 2001 From: Wyon bi Date: Wed, 12 Jan 2022 10:41:34 +0800 Subject: [PATCH] drm/bridge: analogix_dp: Set link power state Signed-off-by: Wyon bi Change-Id: I4f651cb18231c87a1d5848d16308876e49d13b4f --- .../drm/bridge/analogix/analogix_dp_core.c | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 9b72804010fb..127e4f9f7df7 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -984,6 +984,52 @@ static int analogix_dp_fast_link_train_detection(struct analogix_dp_device *dp) return 0; } +static int analogix_dp_link_power_up(struct analogix_dp_device *dp) +{ + u8 value; + int ret; + + if (dp->dpcd[DP_DPCD_REV] < 0x11) + return 0; + + ret = drm_dp_dpcd_readb(&dp->aux, DP_SET_POWER, &value); + if (ret < 0) + return ret; + + value &= ~DP_SET_POWER_MASK; + value |= DP_SET_POWER_D0; + + ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value); + if (ret < 0) + return ret; + + usleep_range(1000, 2000); + + return 0; +} + +static int analogix_dp_link_power_down(struct analogix_dp_device *dp) +{ + u8 value; + int ret; + + if (dp->dpcd[DP_DPCD_REV] < 0x11) + return 0; + + ret = drm_dp_dpcd_readb(&dp->aux, DP_SET_POWER, &value); + if (ret < 0) + return ret; + + value &= ~DP_SET_POWER_MASK; + value |= DP_SET_POWER_D3; + + ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value); + if (ret < 0) + return ret; + + return 0; +} + static int analogix_dp_commit(struct analogix_dp_device *dp) { struct video_info *video = &dp->video_info; @@ -995,6 +1041,12 @@ static int analogix_dp_commit(struct analogix_dp_device *dp) return ret; } + ret = analogix_dp_link_power_up(dp); + if (ret) { + dev_err(dp->dev, "failed to power up link: %d\n", ret); + return ret; + } + if (device_property_read_bool(dp->dev, "panel-self-test")) return drm_dp_dpcd_writeb(&dp->aux, DP_EDP_CONFIGURATION_SET, DP_PANEL_SELF_TEST_ENABLE); @@ -1445,6 +1497,9 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) } } + if (!analogix_dp_get_plug_in_status(dp)) + analogix_dp_link_power_down(dp); + disable_irq(dp->irq); if (dp->plat_data->power_off)