diff options
author | Yannick Fertré <yannick.fertre@st.com> | 2019-06-03 11:32:02 +0300 |
---|---|---|
committer | Benjamin Gaignard <benjamin.gaignard@linaro.org> | 2019-06-07 15:45:22 +0300 |
commit | 35ab6cfbf21178d4dd93d1fe4cb1416c1d6b566d (patch) | |
tree | bacdb0f3003ae4a1d59520587780151940d7d6c3 /drivers/gpu/drm/stm/drv.c | |
parent | 630bec0c16ee0a003d5f1f55f228b7a495c1d938 (diff) | |
download | linux-35ab6cfbf21178d4dd93d1fe4cb1416c1d6b566d.tar.xz |
drm/stm: support runtime power management
This patch enables runtime power management (runtime PM) support for
the display controller. pm_runtime_enable() and pm_runtime_disable()
are added during ltdc load and unload respectively.
pm_runtime_get_sync() and pm_runtime_put_sync() are added for ltdc
register access.
Signed-off-by: Yannick Fertré <yannick.fertre@st.com>
Acked-by: Philippe Cornu <philippe.cornu@st.com>
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/1559550722-14091-1-git-send-email-yannick.fertre@st.com
Diffstat (limited to 'drivers/gpu/drm/stm/drv.c')
-rw-r--r-- | drivers/gpu/drm/stm/drv.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index 5834ef56fbaa..5659572151a8 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -12,6 +12,7 @@ #include <linux/dma-mapping.h> #include <linux/module.h> #include <linux/of_platform.h> +#include <linux/pm_runtime.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> @@ -135,14 +136,15 @@ static __maybe_unused int drv_suspend(struct device *dev) struct ltdc_device *ldev = ddev->dev_private; struct drm_atomic_state *state; - drm_kms_helper_poll_disable(ddev); + if (WARN_ON(!ldev->suspend_state)) + return -ENOENT; + state = drm_atomic_helper_suspend(ddev); - if (IS_ERR(state)) { - drm_kms_helper_poll_enable(ddev); + if (IS_ERR(state)) return PTR_ERR(state); - } + ldev->suspend_state = state; - ltdc_suspend(ddev); + pm_runtime_force_suspend(dev); return 0; } @@ -151,16 +153,41 @@ static __maybe_unused int drv_resume(struct device *dev) { struct drm_device *ddev = dev_get_drvdata(dev); struct ltdc_device *ldev = ddev->dev_private; + int ret; - ltdc_resume(ddev); - drm_atomic_helper_resume(ddev, ldev->suspend_state); - drm_kms_helper_poll_enable(ddev); + pm_runtime_force_resume(dev); + ret = drm_atomic_helper_resume(ddev, ldev->suspend_state); + if (ret) { + pm_runtime_force_suspend(dev); + ldev->suspend_state = NULL; + return ret; + } return 0; } +static __maybe_unused int drv_runtime_suspend(struct device *dev) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + + DRM_DEBUG_DRIVER("\n"); + ltdc_suspend(ddev); + + return 0; +} + +static __maybe_unused int drv_runtime_resume(struct device *dev) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + + DRM_DEBUG_DRIVER("\n"); + return ltdc_resume(ddev); +} + static const struct dev_pm_ops drv_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(drv_suspend, drv_resume) + SET_RUNTIME_PM_OPS(drv_runtime_suspend, + drv_runtime_resume, NULL) }; static int stm_drm_platform_probe(struct platform_device *pdev) |