drm/rockchip: dw-dp: support resume/suspend in mst mode

When a mst capable immediate downstream device connected,
some workqueue is used to help build and menage the
topology, write/read sidband message. To avoid some access
aux issue happen. we config phy power on when mst capable
immediate downstream device connected and config phy power
off when it becom disconnected.

When a mst capable immediate downstream device connected
and enter to suspend state, it need config phy power off.
And it need config phy power on when it enter to resume
state. This operation to guarantee phy can really power
off when suspend and really power on when resume.

Change-Id: I50e9c800c7b07ea2dd00d8728e08e9abc687378f
Signed-off-by: Zhang Yubing <yubing.zhang@rock-chips.com>
This commit is contained in:
Zhang Yubing
2024-04-11 11:03:08 +08:00
committed by Tao Huang
parent cb78fffd4e
commit f332076dfd

View File

@@ -5532,7 +5532,7 @@ static int dw_dp_remove(struct platform_device *pdev)
return 0;
}
static int __maybe_unused dw_dp_runtime_suspend(struct device *dev)
static int dw_dp_runtime_suspend(struct device *dev)
{
struct dw_dp *dp = dev_get_drvdata(dev);
@@ -5543,7 +5543,7 @@ static int __maybe_unused dw_dp_runtime_suspend(struct device *dev)
return 0;
}
static int __maybe_unused dw_dp_runtime_resume(struct device *dev)
static int dw_dp_runtime_resume(struct device *dev)
{
struct dw_dp *dp = dev_get_drvdata(dev);
@@ -5556,10 +5556,61 @@ static int __maybe_unused dw_dp_runtime_resume(struct device *dev)
return 0;
}
static int dw_dp_suspend_noirq(struct device *dev)
{
struct dw_dp *dp = dev_get_drvdata(dev);
pm_runtime_force_suspend(dev);
if (dp->is_mst)
phy_power_off(dp->phy);
return 0;
}
static int dw_dp_resume_noirq(struct device *dev)
{
struct dw_dp *dp = dev_get_drvdata(dev);
pm_runtime_force_resume(dev);
if (dp->is_mst)
phy_power_on(dp->phy);
return 0;
}
static int dw_dp_suspend(struct device *dev)
{
struct dw_dp *dp = dev_get_drvdata(dev);
if (dp->is_mst)
drm_dp_mst_topology_mgr_suspend(&dp->mst_mgr);
return 0;
}
static int dw_dp_resume(struct device *dev)
{
struct dw_dp *dp = dev_get_drvdata(dev);
int ret;
if (!dp->support_mst)
return 0;
ret = drm_dp_mst_topology_mgr_resume(&dp->mst_mgr, true);
if (ret) {
if (dp->is_mst)
phy_power_off(dp->phy);
dp->is_mst = false;
drm_dp_mst_topology_mgr_set_mst(&dp->mst_mgr, false);
}
return 0;
}
static const struct dev_pm_ops dw_dp_pm_ops = {
SET_RUNTIME_PM_OPS(dw_dp_runtime_suspend, dw_dp_runtime_resume, NULL)
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume)
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(dw_dp_suspend_noirq, dw_dp_resume_noirq)
SET_SYSTEM_SLEEP_PM_OPS(dw_dp_suspend, dw_dp_resume)
};
static const struct dw_dp_chip_data rk3588_dp[] = {