From: Liu Ying Date: Mon, 9 Sep 2019 21:49:07 +0000 (-0400) Subject: MLK-22573-1 gpu: imx: dpu: common: Initialize Store9 when necessary X-Git-Tag: rel_imx_4.19.35_1.1.0~57 X-Git-Url: https://git.somdevices.com/?a=commitdiff_plain;h=27d6d07942bef74d758d38b0bc15f8610424c041;p=linux.git MLK-22573-1 gpu: imx: dpu: common: Initialize Store9 when necessary The bit DIV0 of register STORE9_STATIC is used as a control bit to fix the unsynchronization issue bewteen two display streams in FrameGen side-by-side mode, which is introduced from an ECO operation for the display controller. The bit has to be one when the side-by-side mode is enabled. And, it has to be zero when the mode is disabled, otherwise, a single display stream cannot startup correctly. As Store9 is a part of blit engine, the rest bits of the register should also be initialized before any regular blit. Currently, we need to do the initialization at driver probe stage and system resume stage at least. Since we have the DPU KMS driver and DPU blit engine DRM driver, the initialization needs to be done only in the DPU common driver so that the register won't be overwritten accidentally by the two drivers with each other. We see the overwriting issue at the system resume stage because the blit engine driver resumes relatively late and it initializes the register blindly by writing the bit to zero, thus the display controller cannot be resumed correctly in FrameGen side-by-side mode and content ExtDst shadow load done event from the slave stream won't come. Signed-off-by: Liu Ying (cherry picked from commit e90a6a917e3f5d7087e0de5616b6e8a055906767) --- diff --git a/drivers/gpu/imx/dpu/dpu-common.c b/drivers/gpu/imx/dpu/dpu-common.c index 774e2a271f59..8be27ccda136 100644 --- a/drivers/gpu/imx/dpu/dpu-common.c +++ b/drivers/gpu/imx/dpu/dpu-common.c @@ -843,6 +843,7 @@ _dpu_submodules_init(struct dpu_soc *dpu, struct platform_device *pdev) _DPU_UNITS_INIT(hs); _DPU_UNITS_INIT(lb); _DPU_UNITS_INIT(sig); + _DPU_UNITS_INIT(st); _DPU_UNITS_INIT(tcon); _DPU_UNITS_INIT(vs); diff --git a/drivers/gpu/imx/dpu/dpu-prv.h b/drivers/gpu/imx/dpu/dpu-prv.h index b23e317d727d..42cf8a4495dc 100644 --- a/drivers/gpu/imx/dpu/dpu-prv.h +++ b/drivers/gpu/imx/dpu/dpu-prv.h @@ -282,6 +282,7 @@ _DECLARE_DPU_UNIT_INIT_FUNC(fw); _DECLARE_DPU_UNIT_INIT_FUNC(hs); _DECLARE_DPU_UNIT_INIT_FUNC(lb); _DECLARE_DPU_UNIT_INIT_FUNC(sig); +_DECLARE_DPU_UNIT_INIT_FUNC(st); _DECLARE_DPU_UNIT_INIT_FUNC(tcon); _DECLARE_DPU_UNIT_INIT_FUNC(vs); diff --git a/drivers/gpu/imx/dpu/dpu-store.c b/drivers/gpu/imx/dpu/dpu-store.c index a70bfc2e5394..985fa8b429be 100644 --- a/drivers/gpu/imx/dpu/dpu-store.c +++ b/drivers/gpu/imx/dpu/dpu-store.c @@ -20,6 +20,8 @@ #include "dpu-prv.h" #define PIXENGCFG_STATIC 0x8 +#define DIV(n) (((n) & 0xFF) << 16) +#define DIV_RESET 0x80 struct dpu_store { void __iomem *pec_base; @@ -104,6 +106,23 @@ void dpu_st_put(struct dpu_store *st) } EXPORT_SYMBOL_GPL(dpu_st_put); +void _dpu_st_init(struct dpu_soc *dpu, unsigned int id) +{ + struct dpu_store *st; + int i; + + for (i = 0; i < ARRAY_SIZE(st_ids); i++) + if (st_ids[i] == id) + break; + + if (WARN_ON(i == ARRAY_SIZE(st_ids))) + return; + + st = dpu->st_priv[i]; + + dpu_pec_st_write(st, SHDEN | DIV(DIV_RESET), PIXENGCFG_STATIC); +} + int dpu_st_init(struct dpu_soc *dpu, unsigned int id, unsigned long pec_base, unsigned long base) { @@ -136,5 +155,7 @@ int dpu_st_init(struct dpu_soc *dpu, unsigned int id, mutex_init(&st->mutex); + _dpu_st_init(dpu, id); + return 0; }