aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Stuebner <heiko.stuebner@cherry.de>2024-01-10 19:42:25 +0100
committerQuentin Schulz <quentin.schulz@theobroma-systems.com>2024-01-18 17:49:55 +0000
commit7d41c01fae7b061d0e507b0a349b032db8f0c97d (patch)
tree28e6455646486e32153795924ee23048727f54e5
parentcedd86e9a592ed3c052dad3ee016b1f8e9e2e525 (diff)
TSD: drm/rockchip: dw-dp: call phy init and exit functions
The dw-dp connected to for example the rk3588's typec phys cannot really detect the monitor presence on its own. Instead the phy manually sets the hotplug state according to the detected usb altmode. For this the phy needs to write to the dp-section of the vo0-grf. When dp clocks are not running this will cause an SERROR exception, so the phy should only do that when the dp controller has probed. So use phy_init and phy_exit calls from the phy-API to tell the phy something is using it. Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
-rw-r--r--drivers/gpu/drm/rockchip/dw-dp.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/gpu/drm/rockchip/dw-dp.c b/drivers/gpu/drm/rockchip/dw-dp.c
index 66522bfb7e77..9db69b4136e0 100644
--- a/drivers/gpu/drm/rockchip/dw-dp.c
+++ b/drivers/gpu/drm/rockchip/dw-dp.c
@@ -4009,6 +4009,14 @@ static int dw_dp_parse_dt(struct dw_dp *dp)
return 0;
}
+static void dw_dp_exit_phy(void *data)
+{
+ struct dw_dp *dp = data;
+
+ phy_exit(dp->phy);
+ cancel_work_sync(&dp->hpd_work);
+}
+
static int dw_dp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -4170,6 +4178,14 @@ static int dw_dp_probe(struct platform_device *pdev)
dw_dp_hdcp_init(dp);
+ ret = phy_init(dp->phy);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(dev, dw_dp_exit_phy, dp);
+ if (ret)
+ return ret;
+
return component_add(dev, &dw_dp_component_ops);
}
@@ -4178,7 +4194,6 @@ static int dw_dp_remove(struct platform_device *pdev)
struct dw_dp *dp = platform_get_drvdata(pdev);
component_del(dp->dev, &dw_dp_component_ops);
- cancel_work_sync(&dp->hpd_work);
return 0;
}