Skip to content

Commit ca8199f

Browse files
Kalyan Thotarobclark
authored andcommitted
drm/msm/dpu: ensure device suspend happens during PM sleep
"The PM core always increments the runtime usage counter before calling the ->suspend() callback and decrements it after calling the ->resume() callback" DPU and DSI are managed as runtime devices. When suspend is triggered, PM core adds a refcount on all the devices and calls device suspend, since usage count is already incremented, runtime suspend was not getting called and it kept the clocks on which resulted in target not entering into XO shutdown. Add changes to force suspend on runtime devices during pm sleep. Changes in v1: - Remove unnecessary checks in the function _dpu_kms_disable_dpu (Rob Clark). Changes in v2: - Avoid using suspend_late to reset the usagecount as suspend_late might not be called during suspend call failures (Doug). Changes in v3: - Use force suspend instead of managing device usage_count via runtime put and get API's to trigger callbacks (Doug). Changes in v4: - Check the return values of pm_runtime_force_suspend and pm_runtime_force_resume API's and pass appropriately (Doug). Changes in v5: - With v4 patch, test cycle has uncovered issues in device resume. On bubs: cmd tx failures were seen as SW is sending panel off commands when the dsi resources are turned off. Upon suspend, DRM driver will issue a NULL composition to the dpu, followed by turning off all the HW blocks. v5 changes will serialize the NULL commit and resource unwinding by handling them under PM prepare and PM complete phases there by ensuring that clks are on when panel off commands are being processed. Changes in v6: - Use drm_mode_config_helper_suspend/resume() instead of legacy API drm_atomic_helper_suspend/resume() (Doug). Trigger runtime callbacks from the suspend/resume call to turn off the resources. Changes in v7: - Add "__maybe_unused" to the functions to avoid compilation failures. Cleanup unnecessary configs (Doug). Signed-off-by: Kalyan Thota <[email protected]> Reviewed-by: Douglas Anderson <[email protected]> Signed-off-by: Rob Clark <[email protected]>
1 parent 08af476 commit ca8199f

File tree

3 files changed

+35
-36
lines changed

3 files changed

+35
-36
lines changed

drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,8 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev)
11151115

11161116
static const struct dev_pm_ops dpu_pm_ops = {
11171117
SET_RUNTIME_PM_OPS(dpu_runtime_suspend, dpu_runtime_resume, NULL)
1118+
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1119+
pm_runtime_force_resume)
11181120
};
11191121

11201122
static const struct of_device_id dpu_dt_match[] = {

drivers/gpu/drm/msm/dsi/dsi.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ static const struct of_device_id dt_match[] = {
161161

162162
static const struct dev_pm_ops dsi_pm_ops = {
163163
SET_RUNTIME_PM_OPS(msm_dsi_runtime_suspend, msm_dsi_runtime_resume, NULL)
164+
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
165+
pm_runtime_force_resume)
164166
};
165167

166168
static struct platform_driver dsi_driver = {

drivers/gpu/drm/msm/msm_drv.c

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,75 +1039,70 @@ static struct drm_driver msm_driver = {
10391039
.patchlevel = MSM_VERSION_PATCHLEVEL,
10401040
};
10411041

1042-
#ifdef CONFIG_PM_SLEEP
1043-
static int msm_pm_suspend(struct device *dev)
1042+
static int __maybe_unused msm_runtime_suspend(struct device *dev)
10441043
{
10451044
struct drm_device *ddev = dev_get_drvdata(dev);
10461045
struct msm_drm_private *priv = ddev->dev_private;
1046+
struct msm_mdss *mdss = priv->mdss;
10471047

1048-
if (WARN_ON(priv->pm_state))
1049-
drm_atomic_state_put(priv->pm_state);
1048+
DBG("");
10501049

1051-
priv->pm_state = drm_atomic_helper_suspend(ddev);
1052-
if (IS_ERR(priv->pm_state)) {
1053-
int ret = PTR_ERR(priv->pm_state);
1054-
DRM_ERROR("Failed to suspend dpu, %d\n", ret);
1055-
return ret;
1056-
}
1050+
if (mdss && mdss->funcs)
1051+
return mdss->funcs->disable(mdss);
10571052

10581053
return 0;
10591054
}
10601055

1061-
static int msm_pm_resume(struct device *dev)
1056+
static int __maybe_unused msm_runtime_resume(struct device *dev)
10621057
{
10631058
struct drm_device *ddev = dev_get_drvdata(dev);
10641059
struct msm_drm_private *priv = ddev->dev_private;
1065-
int ret;
1060+
struct msm_mdss *mdss = priv->mdss;
10661061

1067-
if (WARN_ON(!priv->pm_state))
1068-
return -ENOENT;
1062+
DBG("");
10691063

1070-
ret = drm_atomic_helper_resume(ddev, priv->pm_state);
1071-
if (!ret)
1072-
priv->pm_state = NULL;
1064+
if (mdss && mdss->funcs)
1065+
return mdss->funcs->enable(mdss);
10731066

1074-
return ret;
1067+
return 0;
10751068
}
1076-
#endif
10771069

1078-
#ifdef CONFIG_PM
1079-
static int msm_runtime_suspend(struct device *dev)
1070+
static int __maybe_unused msm_pm_suspend(struct device *dev)
10801071
{
1081-
struct drm_device *ddev = dev_get_drvdata(dev);
1082-
struct msm_drm_private *priv = ddev->dev_private;
1083-
struct msm_mdss *mdss = priv->mdss;
10841072

1085-
DBG("");
1073+
if (pm_runtime_suspended(dev))
1074+
return 0;
10861075

1087-
if (mdss && mdss->funcs)
1088-
return mdss->funcs->disable(mdss);
1076+
return msm_runtime_suspend(dev);
1077+
}
10891078

1090-
return 0;
1079+
static int __maybe_unused msm_pm_resume(struct device *dev)
1080+
{
1081+
if (pm_runtime_suspended(dev))
1082+
return 0;
1083+
1084+
return msm_runtime_resume(dev);
10911085
}
10921086

1093-
static int msm_runtime_resume(struct device *dev)
1087+
static int __maybe_unused msm_pm_prepare(struct device *dev)
10941088
{
10951089
struct drm_device *ddev = dev_get_drvdata(dev);
1096-
struct msm_drm_private *priv = ddev->dev_private;
1097-
struct msm_mdss *mdss = priv->mdss;
10981090

1099-
DBG("");
1091+
return drm_mode_config_helper_suspend(ddev);
1092+
}
11001093

1101-
if (mdss && mdss->funcs)
1102-
return mdss->funcs->enable(mdss);
1094+
static void __maybe_unused msm_pm_complete(struct device *dev)
1095+
{
1096+
struct drm_device *ddev = dev_get_drvdata(dev);
11031097

1104-
return 0;
1098+
drm_mode_config_helper_resume(ddev);
11051099
}
1106-
#endif
11071100

11081101
static const struct dev_pm_ops msm_pm_ops = {
11091102
SET_SYSTEM_SLEEP_PM_OPS(msm_pm_suspend, msm_pm_resume)
11101103
SET_RUNTIME_PM_OPS(msm_runtime_suspend, msm_runtime_resume, NULL)
1104+
.prepare = msm_pm_prepare,
1105+
.complete = msm_pm_complete,
11111106
};
11121107

11131108
/*

0 commit comments

Comments
 (0)