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 <jmadiset@codeaurora.org>
Signed-off-by: Samantha Tran <samtran@codeaurora.org>
This commit is contained in:
Jayaprakash Madisetty
2021-04-15 15:18:02 +05:30
committed by Samantha Tran
parent 7d0890d337
commit 436efb403c
6 changed files with 70 additions and 9 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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