summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/msm_drv.c
diff options
context:
space:
mode:
authorArchit Taneja <architt@codeaurora.org>2017-07-28 13:47:07 +0300
committerRob Clark <robdclark@gmail.com>2017-08-02 14:53:46 +0300
commit774e39ee3572272b816f3a0b39dfdbcc70dd47f1 (patch)
tree00872a09f3cc307f4948726ee0ab3b5ba52904cf /drivers/gpu/drm/msm/msm_drv.c
parent0f379b79ab85573f2041c1eb5da9bb0bfcb4fccd (diff)
downloadlinux-774e39ee3572272b816f3a0b39dfdbcc70dd47f1.tar.xz
drm/msm/mdp5: Set up runtime PM for MDSS
MDSS represents the top level wrapper that contains MDP5, DSI, HDMI and other sub-blocks. W.r.t device heirarchy, it's the parent of all these devices. The power domain of this device is actually tied to the GDSC hw. When any sub-device enables its PD, MDSS's PD is also enabled. The suspend/resume ops enable the top level clocks that end at the MDSS boundary. For now, we're letting them all be optional, since the child devices anyway hold a ref to these clocks. Until now, we'd called a runtime_get() during probe, which ensured that the GDSC was always on. Now that we've set up runtime PM for the children devices, we can get rid of this hack. Note: that the MDSS device is the platform_device in msm_drv.c. The msm_runtime_suspend/resume ops call the funcs that enable/disable the top level MDSS clocks. This is different from MDP4, where the platform device created in msm_drv.c represents MDP4 itself. It would have been nicer to hide these differences by adding new kms funcs, but runtime PM needs to be enabled before kms is set up (i.e, msm_kms_init is called). Signed-off-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/msm_drv.c')
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index f49f6ac5585c..a19c393f7e45 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -879,8 +879,37 @@ static int msm_pm_resume(struct device *dev)
}
#endif
+#ifdef CONFIG_PM
+static int msm_runtime_suspend(struct device *dev)
+{
+ struct drm_device *ddev = dev_get_drvdata(dev);
+ struct msm_drm_private *priv = ddev->dev_private;
+
+ DBG("");
+
+ if (priv->mdss)
+ return msm_mdss_disable(priv->mdss);
+
+ return 0;
+}
+
+static int msm_runtime_resume(struct device *dev)
+{
+ struct drm_device *ddev = dev_get_drvdata(dev);
+ struct msm_drm_private *priv = ddev->dev_private;
+
+ DBG("");
+
+ if (priv->mdss)
+ return msm_mdss_enable(priv->mdss);
+
+ return 0;
+}
+#endif
+
static const struct dev_pm_ops msm_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(msm_pm_suspend, msm_pm_resume)
+ SET_RUNTIME_PM_OPS(msm_runtime_suspend, msm_runtime_resume, NULL)
};
/*