Commit a8db4324 authored by Stefan Agner's avatar Stefan Agner

drm/fsl-dcu: implement suspend/resume using atomic helpers

Use the drm_atomic_helper_suspend() and drm_atomic_helper_resume()
helpers to implement subsystem-level suspend/resume. This replaces
the (non-functional) regmap cache based suspend resume functionality.
Signed-off-by: default avatarStefan Agner <stefan@agner.ch>
parent ff09b41f
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/console.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
#include <linux/mm.h> #include <linux/mm.h>
...@@ -22,6 +23,7 @@ ...@@ -22,6 +23,7 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_cma_helper.h> #include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
...@@ -42,10 +44,8 @@ static const struct regmap_config fsl_dcu_regmap_config = { ...@@ -42,10 +44,8 @@ static const struct regmap_config fsl_dcu_regmap_config = {
.reg_bits = 32, .reg_bits = 32,
.reg_stride = 4, .reg_stride = 4,
.val_bits = 32, .val_bits = 32,
.cache_type = REGCACHE_FLAT,
.volatile_reg = fsl_dcu_drm_is_volatile_reg, .volatile_reg = fsl_dcu_drm_is_volatile_reg,
.max_register = 0x11fc,
}; };
static int fsl_dcu_drm_irq_init(struct drm_device *dev) static int fsl_dcu_drm_irq_init(struct drm_device *dev)
...@@ -229,9 +229,25 @@ static int fsl_dcu_drm_pm_suspend(struct device *dev) ...@@ -229,9 +229,25 @@ static int fsl_dcu_drm_pm_suspend(struct device *dev)
if (!fsl_dev) if (!fsl_dev)
return 0; return 0;
disable_irq(fsl_dev->irq);
drm_kms_helper_poll_disable(fsl_dev->drm); drm_kms_helper_poll_disable(fsl_dev->drm);
regcache_cache_only(fsl_dev->regmap, true);
regcache_mark_dirty(fsl_dev->regmap); console_lock();
drm_fbdev_cma_set_suspend(fsl_dev->fbdev, 1);
console_unlock();
fsl_dev->state = drm_atomic_helper_suspend(fsl_dev->drm);
if (IS_ERR(fsl_dev->state)) {
console_lock();
drm_fbdev_cma_set_suspend(fsl_dev->fbdev, 0);
console_unlock();
drm_kms_helper_poll_enable(fsl_dev->drm);
enable_irq(fsl_dev->irq);
return PTR_ERR(fsl_dev->state);
}
clk_disable_unprepare(fsl_dev->pix_clk);
clk_disable_unprepare(fsl_dev->clk); clk_disable_unprepare(fsl_dev->clk);
return 0; return 0;
...@@ -251,9 +267,21 @@ static int fsl_dcu_drm_pm_resume(struct device *dev) ...@@ -251,9 +267,21 @@ static int fsl_dcu_drm_pm_resume(struct device *dev)
return ret; return ret;
} }
ret = clk_prepare_enable(fsl_dev->pix_clk);
if (ret < 0) {
dev_err(dev, "failed to enable pix clk\n");
return ret;
}
fsl_dcu_drm_init_planes(fsl_dev->drm);
drm_atomic_helper_resume(fsl_dev->drm, fsl_dev->state);
console_lock();
drm_fbdev_cma_set_suspend(fsl_dev->fbdev, 0);
console_unlock();
drm_kms_helper_poll_enable(fsl_dev->drm); drm_kms_helper_poll_enable(fsl_dev->drm);
regcache_cache_only(fsl_dev->regmap, false); enable_irq(fsl_dev->irq);
regcache_sync(fsl_dev->regmap);
return 0; return 0;
} }
......
...@@ -194,6 +194,7 @@ struct fsl_dcu_drm_device { ...@@ -194,6 +194,7 @@ struct fsl_dcu_drm_device {
struct drm_encoder encoder; struct drm_encoder encoder;
struct fsl_dcu_drm_connector connector; struct fsl_dcu_drm_connector connector;
const struct fsl_dcu_soc_data *soc; const struct fsl_dcu_soc_data *soc;
struct drm_atomic_state *state;
}; };
void fsl_dcu_fbdev_init(struct drm_device *dev); void fsl_dcu_fbdev_init(struct drm_device *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment