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:

committed by
Samantha Tran

parent
7d0890d337
commit
436efb403c
@@ -549,7 +549,7 @@ static bool sde_crtc_mode_fixup(struct drm_crtc *crtc,
|
|||||||
|
|
||||||
drm_for_each_encoder_mask(encoder, c_state->crtc->dev,
|
drm_for_each_encoder_mask(encoder, c_state->crtc->dev,
|
||||||
c_state->encoder_mask) {
|
c_state->encoder_mask) {
|
||||||
if (!sde_encoder_in_clone_mode(encoder)) {
|
if (!sde_crtc_state_in_clone_mode(encoder, c_state)) {
|
||||||
encoder_valid = true;
|
encoder_valid = true;
|
||||||
break;
|
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
|
* This restriction should be relaxed when Connector ROI scaling is
|
||||||
* supported and while in clone mode.
|
* 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) {
|
is_conn_roi_dirty != is_crtc_roi_dirty) {
|
||||||
SDE_ERROR("connector/crtc rois not updated together\n");
|
SDE_ERROR("connector/crtc rois not updated together\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -2549,7 +2549,7 @@ void sde_crtc_prepare_commit(struct drm_crtc *crtc,
|
|||||||
dev = crtc->dev;
|
dev = crtc->dev;
|
||||||
sde_crtc = to_sde_crtc(crtc);
|
sde_crtc = to_sde_crtc(crtc);
|
||||||
cstate = to_sde_crtc_state(crtc->state);
|
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");
|
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;
|
cstate->connectors[cstate->num_connectors++] = conn;
|
||||||
sde_connector_prepare_fence(conn);
|
sde_connector_prepare_fence(conn);
|
||||||
|
sde_encoder_set_clone_mode(encoder, crtc->state);
|
||||||
}
|
}
|
||||||
drm_connector_list_iter_end(&conn_iter);
|
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,
|
drm_for_each_encoder_mask(encoder, crtc->dev,
|
||||||
cstate->encoder_mask) {
|
cstate->encoder_mask) {
|
||||||
/* continue if copy encoder is encountered */
|
/* continue if copy encoder is encountered */
|
||||||
if (sde_encoder_in_clone_mode(encoder))
|
if (sde_crtc_state_in_clone_mode(encoder, cstate))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return sde_encoder_get_intf_mode(encoder);
|
return sde_encoder_get_intf_mode(encoder);
|
||||||
|
@@ -466,6 +466,7 @@ enum sde_crtc_dirty_flags {
|
|||||||
* @property_values: Current crtc property values
|
* @property_values: Current crtc property values
|
||||||
* @input_fence_timeout_ns : Cached input fence timeout, in ns
|
* @input_fence_timeout_ns : Cached input fence timeout, in ns
|
||||||
* @num_dim_layers: Number of dim layers
|
* @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
|
* @dim_layer: Dim layer configs
|
||||||
* @num_ds: Number of destination scalers to be configured
|
* @num_ds: Number of destination scalers to be configured
|
||||||
* @num_ds_enabled: Number of destination scalers enabled
|
* @num_ds_enabled: Number of destination scalers enabled
|
||||||
@@ -501,6 +502,7 @@ struct sde_crtc_state {
|
|||||||
DECLARE_BITMAP(dirty, SDE_CRTC_DIRTY_MAX);
|
DECLARE_BITMAP(dirty, SDE_CRTC_DIRTY_MAX);
|
||||||
uint64_t input_fence_timeout_ns;
|
uint64_t input_fence_timeout_ns;
|
||||||
uint32_t num_dim_layers;
|
uint32_t num_dim_layers;
|
||||||
|
uint32_t cwb_enc_mask;
|
||||||
struct sde_hw_dim_layer dim_layer[SDE_MAX_DIM_LAYERS];
|
struct sde_hw_dim_layer dim_layer[SDE_MAX_DIM_LAYERS];
|
||||||
uint32_t num_ds;
|
uint32_t num_ds;
|
||||||
uint32_t num_ds_enabled;
|
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));
|
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
|
* sde_crtc_get_secure_transition - determines the operations to be
|
||||||
* performed before transitioning to secure state
|
* performed before transitioning to secure state
|
||||||
|
@@ -849,6 +849,36 @@ bool sde_encoder_is_cwb_disabling(struct drm_encoder *drm_enc,
|
|||||||
return false;
|
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,
|
static int _sde_encoder_atomic_check_phys_enc(struct sde_encoder_virt *sde_enc,
|
||||||
struct drm_crtc_state *crtc_state,
|
struct drm_crtc_state *crtc_state,
|
||||||
struct drm_connector_state *conn_state)
|
struct drm_connector_state *conn_state)
|
||||||
|
@@ -491,6 +491,14 @@ void sde_encoder_enable_recovery_event(struct drm_encoder *encoder);
|
|||||||
*/
|
*/
|
||||||
bool sde_encoder_in_clone_mode(struct drm_encoder *enc);
|
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
|
* sde_encoder_is_cwb_disabling - check if cwb encoder disable is pending
|
||||||
* @drm_enc: Pointer to drm encoder structure
|
* @drm_enc: Pointer to drm encoder structure
|
||||||
|
@@ -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 drm_crtc_state *crtc_state)
|
||||||
{
|
{
|
||||||
struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc);
|
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;
|
const struct sde_wb_cfg *wb_cfg = wb_enc->hw_wb->caps;
|
||||||
u32 encoder_mask = 0;
|
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 = crtc_state->encoder_mask;
|
||||||
encoder_mask &= ~drm_encoder_mask(phys_enc->parent);
|
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,
|
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 drm_connector_state *conn_state)
|
||||||
{
|
{
|
||||||
struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc);
|
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;
|
struct sde_hw_wb *hw_wb = wb_enc->hw_wb;
|
||||||
const struct sde_wb_cfg *wb_cfg = hw_wb->caps;
|
const struct sde_wb_cfg *wb_cfg = hw_wb->caps;
|
||||||
struct drm_framebuffer *fb;
|
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);
|
_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");
|
SDE_ERROR("WB commit before CWB disable\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -902,7 +906,7 @@ static int sde_encoder_phys_wb_atomic_check(
|
|||||||
crtc_state->mode_changed = true;
|
crtc_state->mode_changed = true;
|
||||||
|
|
||||||
/* if in clone mode, return after cwb validation */
|
/* 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,
|
rc = _sde_enc_phys_wb_validate_cwb(phys_enc, crtc_state,
|
||||||
conn_state);
|
conn_state);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@@ -2135,7 +2135,7 @@ static int _sde_rm_populate_requirements(
|
|||||||
* found enabled.
|
* found enabled.
|
||||||
*/
|
*/
|
||||||
if ((!RM_RQ_CWB(reqs) || !RM_RQ_DCWB(reqs))
|
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)
|
if (cfg->has_dedicated_cwb_support)
|
||||||
reqs->top_ctrl |= BIT(SDE_RM_TOPCTL_DCWB);
|
reqs->top_ctrl |= BIT(SDE_RM_TOPCTL_DCWB);
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user