|
@@ -11,6 +11,7 @@
|
|
|
|
|
|
#include <linux/clk.h>
|
|
|
#include <linux/clk-provider.h>
|
|
|
+#include <linux/console.h>
|
|
|
#include <linux/io.h>
|
|
|
#include <linux/mfd/syscon.h>
|
|
|
#include <linux/mm.h>
|
|
@@ -22,6 +23,7 @@
|
|
|
#include <linux/regmap.h>
|
|
|
|
|
|
#include <drm/drmP.h>
|
|
|
+#include <drm/drm_atomic_helper.h>
|
|
|
#include <drm/drm_crtc_helper.h>
|
|
|
#include <drm/drm_fb_cma_helper.h>
|
|
|
#include <drm/drm_gem_cma_helper.h>
|
|
@@ -42,10 +44,8 @@ static const struct regmap_config fsl_dcu_regmap_config = {
|
|
|
.reg_bits = 32,
|
|
|
.reg_stride = 4,
|
|
|
.val_bits = 32,
|
|
|
- .cache_type = REGCACHE_FLAT,
|
|
|
|
|
|
.volatile_reg = fsl_dcu_drm_is_volatile_reg,
|
|
|
- .max_register = 0x11fc,
|
|
|
};
|
|
|
|
|
|
static int fsl_dcu_drm_irq_init(struct drm_device *dev)
|
|
@@ -229,11 +229,26 @@ static int fsl_dcu_drm_pm_suspend(struct device *dev)
|
|
|
if (!fsl_dev)
|
|
|
return 0;
|
|
|
|
|
|
+ disable_irq(fsl_dev->irq);
|
|
|
drm_kms_helper_poll_disable(fsl_dev->drm);
|
|
|
- regcache_cache_only(fsl_dev->regmap, true);
|
|
|
- regcache_mark_dirty(fsl_dev->regmap);
|
|
|
- clk_disable(fsl_dev->clk);
|
|
|
- clk_unprepare(fsl_dev->clk);
|
|
|
+
|
|
|
+ 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);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -246,21 +261,27 @@ static int fsl_dcu_drm_pm_resume(struct device *dev)
|
|
|
if (!fsl_dev)
|
|
|
return 0;
|
|
|
|
|
|
- ret = clk_enable(fsl_dev->clk);
|
|
|
+ ret = clk_prepare_enable(fsl_dev->clk);
|
|
|
if (ret < 0) {
|
|
|
dev_err(dev, "failed to enable dcu clk\n");
|
|
|
- clk_unprepare(fsl_dev->clk);
|
|
|
return ret;
|
|
|
}
|
|
|
- ret = clk_prepare(fsl_dev->clk);
|
|
|
+
|
|
|
+ ret = clk_prepare_enable(fsl_dev->pix_clk);
|
|
|
if (ret < 0) {
|
|
|
- dev_err(dev, "failed to prepare dcu clk\n");
|
|
|
+ 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);
|
|
|
- regcache_cache_only(fsl_dev->regmap, false);
|
|
|
- regcache_sync(fsl_dev->regmap);
|
|
|
+ enable_irq(fsl_dev->irq);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -274,12 +295,14 @@ static const struct fsl_dcu_soc_data fsl_dcu_ls1021a_data = {
|
|
|
.name = "ls1021a",
|
|
|
.total_layer = 16,
|
|
|
.max_layer = 4,
|
|
|
+ .layer_regs = LS1021A_LAYER_REG_NUM,
|
|
|
};
|
|
|
|
|
|
static const struct fsl_dcu_soc_data fsl_dcu_vf610_data = {
|
|
|
.name = "vf610",
|
|
|
.total_layer = 64,
|
|
|
.max_layer = 6,
|
|
|
+ .layer_regs = VF610_LAYER_REG_NUM,
|
|
|
};
|
|
|
|
|
|
static const struct of_device_id fsl_dcu_of_match[] = {
|