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 <victor.liu@nxp.com>
(cherry picked from commit
e90a6a917e3f5d7087e0de5616b6e8a055906767)
_DPU_UNITS_INIT(hs);
_DPU_UNITS_INIT(lb);
_DPU_UNITS_INIT(sig);
+ _DPU_UNITS_INIT(st);
_DPU_UNITS_INIT(tcon);
_DPU_UNITS_INIT(vs);
_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);
#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;
}
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)
{
mutex_init(&st->mutex);
+ _dpu_st_init(dpu, id);
+
return 0;
}