From 436efb403c9210c44289d1c8ba57d48658d27e55 Mon Sep 17 00:00:00 2001 From: Jayaprakash Madisetty Date: Thu, 15 Apr 2021 15:18:02 +0530 Subject: [PATCH] disp: msm: sde: modify in_clone_mode after wb_reset is done Add changes to modify the phys_enc->in_clone_mode variable post wb_reset_state since this is a shared variable used during atomic_check and atomic_commit. In current issue case, wb_atomic_check has set in_clone_mode to true in commit N, and in commit N-1 CWB is being disabled and re-sets the in_clone_mode variable to false causing pp_done timeouts in primary in commit N. Change-Id: I8159bbdb5622a351d76bdc4dba75d48df20f4365 Signed-off-by: Jayaprakash Madisetty Signed-off-by: Samantha Tran --- msm/sde/sde_crtc.c | 9 +++++---- msm/sde/sde_crtc.h | 18 ++++++++++++++++++ msm/sde/sde_encoder.c | 30 ++++++++++++++++++++++++++++++ msm/sde/sde_encoder.h | 8 ++++++++ msm/sde/sde_encoder_phys_wb.c | 12 ++++++++---- msm/sde/sde_rm.c | 2 +- 6 files changed, 70 insertions(+), 9 deletions(-) diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 695425ceac..ce8260d6eb 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -549,7 +549,7 @@ static bool sde_crtc_mode_fixup(struct drm_crtc *crtc, drm_for_each_encoder_mask(encoder, c_state->crtc->dev, c_state->encoder_mask) { - if (!sde_encoder_in_clone_mode(encoder)) { + if (!sde_crtc_state_in_clone_mode(encoder, c_state)) { encoder_valid = true; break; } @@ -868,7 +868,7 @@ static int _sde_crtc_set_crtc_roi(struct drm_crtc *crtc, * This restriction should be relaxed when Connector ROI scaling is * supported and while in clone mode. */ - if (!sde_encoder_in_clone_mode(sde_conn->encoder) && + if (!sde_crtc_state_in_clone_mode(sde_conn->encoder, state) && is_conn_roi_dirty != is_crtc_roi_dirty) { SDE_ERROR("connector/crtc rois not updated together\n"); return -EINVAL; @@ -2549,7 +2549,7 @@ void sde_crtc_prepare_commit(struct drm_crtc *crtc, dev = crtc->dev; sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(crtc->state); - SDE_EVT32_VERBOSE(DRMID(crtc)); + SDE_EVT32_VERBOSE(DRMID(crtc), cstate->cwb_enc_mask); SDE_ATRACE_BEGIN("sde_crtc_prepare_commit"); @@ -2569,6 +2569,7 @@ void sde_crtc_prepare_commit(struct drm_crtc *crtc, cstate->connectors[cstate->num_connectors++] = conn; sde_connector_prepare_fence(conn); + sde_encoder_set_clone_mode(encoder, crtc->state); } drm_connector_list_iter_end(&conn_iter); @@ -2631,7 +2632,7 @@ enum sde_intf_mode sde_crtc_get_intf_mode(struct drm_crtc *crtc, drm_for_each_encoder_mask(encoder, crtc->dev, cstate->encoder_mask) { /* continue if copy encoder is encountered */ - if (sde_encoder_in_clone_mode(encoder)) + if (sde_crtc_state_in_clone_mode(encoder, cstate)) continue; return sde_encoder_get_intf_mode(encoder); diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index ff0a6632cc..203ccd8e58 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -466,6 +466,7 @@ enum sde_crtc_dirty_flags { * @property_values: Current crtc property values * @input_fence_timeout_ns : Cached input fence timeout, in ns * @num_dim_layers: Number of dim layers + * @cwb_enc_mask : encoder mask populated during atomic_check if CWB is enabled * @dim_layer: Dim layer configs * @num_ds: Number of destination scalers to be configured * @num_ds_enabled: Number of destination scalers enabled @@ -501,6 +502,7 @@ struct sde_crtc_state { DECLARE_BITMAP(dirty, SDE_CRTC_DIRTY_MAX); uint64_t input_fence_timeout_ns; uint32_t num_dim_layers; + uint32_t cwb_enc_mask; struct sde_hw_dim_layer dim_layer[SDE_MAX_DIM_LAYERS]; uint32_t num_ds; uint32_t num_ds_enabled; @@ -880,6 +882,22 @@ static inline bool sde_crtc_atomic_check_has_modeset( return (crtc_state && drm_atomic_crtc_needs_modeset(crtc_state)); } +static inline bool sde_crtc_state_in_clone_mode(struct drm_encoder *encoder, + struct drm_crtc_state *state) +{ + struct sde_crtc_state *cstate; + + if (!state || !encoder) + return false; + + cstate = to_sde_crtc_state(state); + if (sde_encoder_in_clone_mode(encoder) || + (cstate->cwb_enc_mask & drm_encoder_mask(encoder))) + return true; + + return false; +} + /** * sde_crtc_get_secure_transition - determines the operations to be * performed before transitioning to secure state diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 45b008efd6..1591c35520 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -849,6 +849,36 @@ bool sde_encoder_is_cwb_disabling(struct drm_encoder *drm_enc, return false; } +void sde_encoder_set_clone_mode(struct drm_encoder *drm_enc, + struct drm_crtc_state *crtc_state) +{ + struct sde_encoder_virt *sde_enc; + struct sde_crtc_state *sde_crtc_state; + int i = 0; + + if (!drm_enc || !crtc_state) { + SDE_DEBUG("invalid params\n"); + return; + } + sde_enc = to_sde_encoder_virt(drm_enc); + sde_crtc_state = to_sde_crtc_state(crtc_state); + + if ((sde_enc->disp_info.intf_type != DRM_MODE_CONNECTOR_VIRTUAL) || + (!(sde_crtc_state->cwb_enc_mask & drm_encoder_mask(drm_enc)))) + return; + + for (i = 0; i < sde_enc->num_phys_encs; i++) { + struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; + + if (phys) { + phys->in_clone_mode = true; + SDE_DEBUG("enc:%d phys state:%d\n", DRMID(drm_enc), phys->enable_state); + } + } + + sde_crtc_state->cwb_enc_mask = 0; +} + static int _sde_encoder_atomic_check_phys_enc(struct sde_encoder_virt *sde_enc, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) diff --git a/msm/sde/sde_encoder.h b/msm/sde/sde_encoder.h index 6def89f3b6..0025722665 100644 --- a/msm/sde/sde_encoder.h +++ b/msm/sde/sde_encoder.h @@ -491,6 +491,14 @@ void sde_encoder_enable_recovery_event(struct drm_encoder *encoder); */ bool sde_encoder_in_clone_mode(struct drm_encoder *enc); +/** + * sde_encoder_set_clone_mode - cwb in wb phys enc is enabled. + * drm_enc: Pointer to drm encoder structure + * drm_crtc_state: Pointer to drm_crtc_state + */ +void sde_encoder_set_clone_mode(struct drm_encoder *drm_enc, + struct drm_crtc_state *crtc_state); + /* * sde_encoder_is_cwb_disabling - check if cwb encoder disable is pending * @drm_enc: Pointer to drm encoder structure diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index d123dbaa1e..fa37667638 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -653,6 +653,7 @@ static void _sde_enc_phys_wb_detect_cwb(struct sde_encoder_phys *phys_enc, struct drm_crtc_state *crtc_state) { struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc); + struct sde_crtc_state *cstate = to_sde_crtc_state(crtc_state); const struct sde_wb_cfg *wb_cfg = wb_enc->hw_wb->caps; u32 encoder_mask = 0; @@ -662,9 +663,11 @@ static void _sde_enc_phys_wb_detect_cwb(struct sde_encoder_phys *phys_enc, encoder_mask = crtc_state->encoder_mask; encoder_mask &= ~drm_encoder_mask(phys_enc->parent); } - phys_enc->in_clone_mode = encoder_mask ? true : false; - SDE_DEBUG("detect CWB(OR)DCWB - status:%d\n", phys_enc->in_clone_mode); + cstate->cwb_enc_mask = encoder_mask ? drm_encoder_mask(phys_enc->parent) : 0; + + SDE_DEBUG("detect CWB - status:%d, phys state:%d in_clone_mode:%d\n", + cstate->cwb_enc_mask, phys_enc->enable_state, phys_enc->in_clone_mode); } static int _sde_enc_phys_wb_validate_cwb(struct sde_encoder_phys *phys_enc, @@ -816,6 +819,7 @@ static int sde_encoder_phys_wb_atomic_check( struct drm_connector_state *conn_state) { struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc); + struct sde_crtc_state *cstate = to_sde_crtc_state(crtc_state); struct sde_hw_wb *hw_wb = wb_enc->hw_wb; const struct sde_wb_cfg *wb_cfg = hw_wb->caps; struct drm_framebuffer *fb; @@ -843,7 +847,7 @@ static int sde_encoder_phys_wb_atomic_check( _sde_enc_phys_wb_detect_cwb(phys_enc, crtc_state); - if (clone_mode_curr && !phys_enc->in_clone_mode) { + if (clone_mode_curr && !cstate->cwb_enc_mask) { SDE_ERROR("WB commit before CWB disable\n"); return -EINVAL; } @@ -902,7 +906,7 @@ static int sde_encoder_phys_wb_atomic_check( crtc_state->mode_changed = true; /* if in clone mode, return after cwb validation */ - if (phys_enc->in_clone_mode) { + if (cstate->cwb_enc_mask) { rc = _sde_enc_phys_wb_validate_cwb(phys_enc, crtc_state, conn_state); if (rc) diff --git a/msm/sde/sde_rm.c b/msm/sde/sde_rm.c index 82419b88b4..1fd96554bd 100644 --- a/msm/sde/sde_rm.c +++ b/msm/sde/sde_rm.c @@ -2135,7 +2135,7 @@ static int _sde_rm_populate_requirements( * found enabled. */ if ((!RM_RQ_CWB(reqs) || !RM_RQ_DCWB(reqs)) - && sde_encoder_in_clone_mode(enc)) { + && sde_crtc_state_in_clone_mode(enc, crtc_state)) { if (cfg->has_dedicated_cwb_support) reqs->top_ctrl |= BIT(SDE_RM_TOPCTL_DCWB); else