From f946219084de710802a0279bc19c798e6ec1e389 Mon Sep 17 00:00:00 2001 From: Prabhanjan Kandula Date: Wed, 17 Jun 2020 00:54:06 -0700 Subject: [PATCH] disp: msm: sde: update sspp multi rect programming Current SDE driver allows staging of rect1 only configuration. When a real plane is disabled sspp multi rect configuration is not updated. This can lead to iommu faults and ping pong timeouts as framebuffer of disabled plane is unmapped. This change fixes it by updating multi rect config accordingly when a plane is disabled. Change-Id: I67ae45ad0e607184c7fc49f4b220220ba1d8a2ae Signed-off-by: Prabhanjan Kandula --- msm/sde/sde_hw_sspp.c | 14 ++++++++++---- msm/sde/sde_hw_sspp.h | 6 ++++-- msm/sde/sde_plane.c | 18 ++++++++++++------ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/msm/sde/sde_hw_sspp.c b/msm/sde/sde_hw_sspp.c index f8f254c46c..35c8f5d8d7 100644 --- a/msm/sde/sde_hw_sspp.c +++ b/msm/sde/sde_hw_sspp.c @@ -193,7 +193,8 @@ static inline int _sspp_subblk_offset(struct sde_hw_pipe *ctx, return rc; } -static void sde_hw_sspp_setup_multirect(struct sde_hw_pipe *ctx, +static void sde_hw_sspp_update_multirect(struct sde_hw_pipe *ctx, + bool enable, enum sde_sspp_multirect_index index, enum sde_sspp_multirect_mode mode) { @@ -212,8 +213,13 @@ static void sde_hw_sspp_setup_multirect(struct sde_hw_pipe *ctx, mode_mask = 0; } else { mode_mask = SDE_REG_READ(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx); - mode_mask |= index; - if (mode == SDE_SSPP_MULTIRECT_TIME_MX) + + if (enable) + mode_mask |= index; + else + mode_mask &= ~index; + + if (enable && (mode == SDE_SSPP_MULTIRECT_TIME_MX)) mode_mask |= BIT(2); else mode_mask &= ~BIT(2); @@ -1232,7 +1238,7 @@ static void _setup_layer_ops(struct sde_hw_pipe *c, } if (sde_hw_sspp_multirect_enabled(c->cap)) - c->ops.setup_multirect = sde_hw_sspp_setup_multirect; + c->ops.update_multirect = sde_hw_sspp_update_multirect; if (test_bit(SDE_SSPP_SCALER_QSEED3, &features) || test_bit(SDE_SSPP_SCALER_QSEED3LITE, &features)) { diff --git a/msm/sde/sde_hw_sspp.h b/msm/sde/sde_hw_sspp.h index 286c500a4e..f562ceb0ab 100644 --- a/msm/sde/sde_hw_sspp.h +++ b/msm/sde/sde_hw_sspp.h @@ -370,13 +370,15 @@ struct sde_hw_sspp_ops { enum sde_sspp_multirect_index index); /** - * setup_multirect - setup multirect configuration + * update_multirect - update multirect configuration * @ctx: Pointer to pipe context + * @enable: Boolean to indicate enable or disable of given config * @index: rectangle index in multirect * @mode: parallel fetch / time multiplex multirect mode */ - void (*setup_multirect)(struct sde_hw_pipe *ctx, + void (*update_multirect)(struct sde_hw_pipe *ctx, + bool enable, enum sde_sspp_multirect_index index, enum sde_sspp_multirect_mode mode); diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 3135963c88..3e9cc16e85 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -3026,9 +3026,11 @@ static void _sde_plane_update_roi_config(struct drm_plane *plane, &pstate->excl_rect, pstate->multirect_index); - if (psde->pipe_hw->ops.setup_multirect) - psde->pipe_hw->ops.setup_multirect( + /* enable multirect config of corresponding rect */ + if (psde->pipe_hw->ops.update_multirect) + psde->pipe_hw->ops.update_multirect( psde->pipe_hw, + true, pstate->multirect_index, pstate->multirect_mode); } @@ -3283,6 +3285,7 @@ static void _sde_plane_atomic_disable(struct drm_plane *plane, struct sde_plane *psde; struct drm_plane_state *state; struct sde_plane_state *pstate; + u32 multirect_index = SDE_SSPP_RECT_0; if (!plane) { SDE_ERROR("invalid plane\n"); @@ -3304,10 +3307,13 @@ static void _sde_plane_atomic_disable(struct drm_plane *plane, pstate->pending = true; - if (is_sde_plane_virtual(plane) && - psde->pipe_hw && psde->pipe_hw->ops.setup_multirect) - psde->pipe_hw->ops.setup_multirect(psde->pipe_hw, - SDE_SSPP_RECT_SOLO, SDE_SSPP_MULTIRECT_NONE); + if (is_sde_plane_virtual(plane)) + multirect_index = SDE_SSPP_RECT_1; + + /* disable multirect config of corresponding rect */ + if (psde->pipe_hw && psde->pipe_hw->ops.update_multirect) + psde->pipe_hw->ops.update_multirect(psde->pipe_hw, false, + multirect_index, SDE_SSPP_MULTIRECT_TIME_MX); } static void sde_plane_atomic_update(struct drm_plane *plane,