drm/msm/sde: reset ubwc static config during enable
Reset the top level ubwc static registers during encoder
enable so that it's restored during suspend/resume and
idle power collapse scenarios.
CRs-Fixed: 2040994
Change-Id: I7a39f194dbb8b4964c866e013dce5fe747c091e2
Signed-off-by: Clarence Ip <cip@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index 742ea20..94420ed 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -831,6 +831,8 @@
static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
{
struct sde_encoder_virt *sde_enc = NULL;
+ struct msm_drm_private *priv;
+ struct sde_kms *sde_kms;
int i = 0;
int ret = 0;
@@ -846,6 +848,13 @@
}
sde_enc = to_sde_encoder_virt(drm_enc);
+ priv = drm_enc->dev->dev_private;
+ sde_kms = to_sde_kms(priv->kms);
+
+ if (!sde_kms) {
+ SDE_ERROR("invalid sde_kms\n");
+ return;
+ }
SDE_DEBUG_ENC(sde_enc, "\n");
SDE_EVT32(DRMID(drm_enc));
@@ -877,6 +886,12 @@
else if (sde_enc->cur_master->ops.enable)
sde_enc->cur_master->ops.enable(sde_enc->cur_master);
+ if (sde_enc->cur_master && sde_enc->cur_master->hw_mdptop &&
+ sde_enc->cur_master->hw_mdptop->ops.reset_ubwc)
+ sde_enc->cur_master->hw_mdptop->ops.reset_ubwc(
+ sde_enc->cur_master->hw_mdptop,
+ sde_kms->catalog);
+
if (_sde_is_dsc_enabled(sde_enc)) {
ret = _sde_encoder_dsc_setup(sde_enc);
if (ret)
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_top.c b/drivers/gpu/drm/msm/sde/sde_hw_top.c
index b20b3bc..3ba7a51 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_top.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_top.c
@@ -210,6 +210,22 @@
SDE_REG_WRITE(c, DCE_SEL, dce_sel);
}
+void sde_hw_reset_ubwc(struct sde_hw_mdp *mdp, struct sde_mdss_cfg *m)
+{
+ struct sde_hw_blk_reg_map c;
+
+ if (!mdp || !m)
+ return;
+
+ if (!IS_UBWC_20_SUPPORTED(m->ubwc_version))
+ return;
+
+ /* force blk offset to zero to access beginning of register region */
+ c = mdp->hw;
+ c.blk_off = 0x0;
+ SDE_REG_WRITE(&c, UBWC_STATIC, m->mdp[0].ubwc_static);
+}
+
static void _setup_mdp_ops(struct sde_hw_mdp_ops *ops,
unsigned long cap)
{
@@ -220,6 +236,7 @@
ops->get_danger_status = sde_hw_get_danger_status;
ops->get_safe_status = sde_hw_get_safe_status;
ops->setup_dce = sde_hw_setup_dce;
+ ops->reset_ubwc = sde_hw_reset_ubwc;
}
static const struct sde_mdp_cfg *_top_offset(enum sde_mdp mdp,
@@ -243,25 +260,6 @@
return ERR_PTR(-EINVAL);
}
-static inline void _sde_hw_mdptop_init_ubwc(void __iomem *addr,
- const struct sde_mdss_cfg *m)
-{
- struct sde_hw_blk_reg_map hw;
-
- if (!addr || !m)
- return;
-
- if (!IS_UBWC_20_SUPPORTED(m->ubwc_version))
- return;
-
- memset(&hw, 0, sizeof(hw));
- hw.base_off = addr;
- hw.blk_off = 0x0;
- hw.hwversion = m->hwversion;
- hw.log_mask = SDE_DBG_MASK_TOP;
- SDE_REG_WRITE(&hw, UBWC_STATIC, m->mdp[0].ubwc_static);
-}
-
struct sde_hw_mdp *sde_hw_mdptop_init(enum sde_mdp idx,
void __iomem *addr,
const struct sde_mdss_cfg *m)
@@ -294,8 +292,6 @@
mdp->hw.xin_id);
sde_dbg_set_sde_top_offset(mdp->hw.blk_off);
- _sde_hw_mdptop_init_ubwc(addr, m);
-
return mdp;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_top.h b/drivers/gpu/drm/msm/sde/sde_hw_top.h
index 9cb0c55..7511358 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_top.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_top.h
@@ -148,6 +148,13 @@
*/
void (*get_safe_status)(struct sde_hw_mdp *mdp,
struct sde_danger_safe_status *status);
+
+ /**
+ * reset_ubwc - reset top level UBWC configuration
+ * @mdp: mdp top context driver
+ * @m: pointer to mdss catalog data
+ */
+ void (*reset_ubwc)(struct sde_hw_mdp *mdp, struct sde_mdss_cfg *m);
};
struct sde_hw_mdp {