From 93581efceefe9e3e30af70d88abe2d899046fd2a Mon Sep 17 00:00:00 2001 From: Damon Ding Date: Thu, 6 Feb 2025 16:07:00 +0800 Subject: [PATCH] drm/bridge: analogix_dp: support for switching the eDP/DP mode Since the Analogix IP can support both eDP v1.3 and DP v1.2, it is sensible to first check whether the last bridge is connected to a panel in order to determine and pass on the eDP/DP submodes to the PHY, which can help separate the eDP/DP configurations in the PHY driver. Change-Id: I86e1c52e15f9348ff9524caaa159f92e5c6fc5de Signed-off-by: Damon Ding --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 12 ++++++++++++ drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 2 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 6 +++++- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 1 + include/drm/bridge/analogix_dp.h | 1 + 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index d253ebcf3ce4..7fddfb841d23 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -1685,6 +1686,8 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge, struct analogix_dp_device *dp = bridge->driver_private; struct drm_encoder *encoder = dp->encoder; struct drm_connector *connector = NULL; + struct drm_bridge *last_bridge; + struct drm_panel *panel = NULL; int ret = 0; if (!bridge->encoder) { @@ -1692,6 +1695,9 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge, return -ENODEV; } + if (!dp->plat_data->panel) + dp->dp_mode = true; + if (dp->plat_data->bridge) { ret = drm_bridge_attach(bridge->encoder, dp->plat_data->bridge, bridge, dp->plat_data->skip_connector ? @@ -1700,6 +1706,12 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge, DRM_ERROR("Failed to attach external bridge: %d\n", ret); return ret; } + + last_bridge = list_last_entry(&bridge->encoder->bridge_chain, + struct drm_bridge, chain_node); + ret = drm_of_find_panel_or_bridge(last_bridge->of_node, 1, -1, &panel, NULL); + if (!ret && panel) + dp->dp_mode = false; } if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index 915bf6969ca1..8b1da11064bd 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -209,6 +209,8 @@ struct analogix_dp_device { u32 split_area; const struct analogix_dp_output_format *output_fmt; + + bool dp_mode; }; /* analogix_dp_reg.c */ diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index 5b58f8219ccc..810b5a2f6041 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -1103,9 +1103,13 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, int analogix_dp_phy_power_on(struct analogix_dp_device *dp) { + int submode = PHY_SUBMODE_EDP; int ret; - ret = phy_set_mode(dp->phy, PHY_MODE_DP); + if (dp->plat_data->support_dp_mode && dp->dp_mode) + submode = PHY_SUBMODE_DP; + + ret = phy_set_mode_ext(dp->phy, PHY_MODE_DP, submode); if (ret) { dev_err(dp->dev, "phy_set_mode failed: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index bffb4fcf78ff..4b7537e64185 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -748,6 +748,7 @@ static int rockchip_dp_probe(struct platform_device *pdev) dp->adp = ERR_PTR(-ENODEV); dp->data = &dp_data[id]; dp->plat_data.ssc = dp->data->ssc; + dp->plat_data.support_dp_mode = dp->data->support_dp_mode; dp->plat_data.max_bpc = dp->data->max_bpc ? dp->data->max_bpc : 8; dp->plat_data.panel = panel; dp->plat_data.dev_type = dp->data->chip_type; diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index 100558e56d17..35484105d7f0 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -43,6 +43,7 @@ struct analogix_dp_plat_data { struct drm_connector *connector; bool skip_connector; bool ssc; + bool support_dp_mode; bool split_mode; bool dual_channel_mode;