From 6199db7ccc92169f51eb7ef8c924c8b1e45769df Mon Sep 17 00:00:00 2001 From: Wyon Bi Date: Wed, 11 Nov 2020 15:08:35 +0800 Subject: [PATCH] drm/bridge: analogix_dp: power on phy before aux transfer Signed-off-by: Wyon Bi Change-Id: Ie83f914ac149a9384dc0ca529fb3a88c8d3ac845 --- .../drm/bridge/analogix/analogix_dp_core.c | 6 ++--- .../drm/bridge/analogix/analogix_dp_core.h | 3 +++ .../gpu/drm/bridge/analogix/analogix_dp_reg.c | 24 ++++++++++++++++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 0de2f6987ef6..0224f091ed75 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1204,7 +1204,7 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp) if (dp->plat_data->power_on_start) dp->plat_data->power_on_start(dp->plat_data); - phy_power_on(dp->phy); + analogix_dp_phy_power_on(dp); ret = analogix_dp_init_dp(dp); if (ret) @@ -1234,7 +1234,7 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp) return 0; out_dp_init: - phy_power_off(dp->phy); + analogix_dp_phy_power_off(dp); if (dp->plat_data->power_off) dp->plat_data->power_off(dp->plat_data); clk_disable_unprepare(dp->clock); @@ -1286,7 +1286,7 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) dp->plat_data->power_off(dp->plat_data); analogix_dp_set_analog_power_down(dp, POWER_ALL, 1); - phy_power_off(dp->phy); + analogix_dp_phy_power_off(dp); clk_disable_unprepare(dp->clock); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index e447dba5d9ea..829dead7b572 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -177,6 +177,7 @@ struct analogix_dp_device { struct video_info video_info; struct link_train link_train; struct phy *phy; + bool phy_enabled; int dpms_mode; struct gpio_desc *hpd_gpiod; bool force_hpd; @@ -249,5 +250,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, void analogix_dp_set_video_format(struct analogix_dp_device *dp); void analogix_dp_video_bist_enable(struct analogix_dp_device *dp); bool analogix_dp_ssc_supported(struct analogix_dp_device *dp); +void analogix_dp_phy_power_on(struct analogix_dp_device *dp); +void analogix_dp_phy_power_off(struct analogix_dp_device *dp); #endif /* _ANALOGIX_DP_CORE_H */ diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index 16e6ba2bafad..1244800a9f09 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -1087,6 +1087,26 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, return 0; } +void analogix_dp_phy_power_on(struct analogix_dp_device *dp) +{ + if (dp->phy_enabled) + return; + + phy_power_on(dp->phy); + + dp->phy_enabled = true; +} + +void analogix_dp_phy_power_off(struct analogix_dp_device *dp) +{ + if (!dp->phy_enabled) + return; + + phy_power_off(dp->phy); + + dp->phy_enabled = false; +} + ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, struct drm_dp_aux_msg *msg) { @@ -1102,8 +1122,10 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, return -E2BIG; reg = analogix_dp_read(dp, ANALOGIX_DP_FUNC_EN_2); - if (reg & AUX_FUNC_EN_N) + if (reg & AUX_FUNC_EN_N) { + analogix_dp_phy_power_on(dp); analogix_dp_init_aux(dp); + } /* Clear AUX CH data buffer */ reg = BUF_CLR;