Loading msm/msm_atomic.c +4 −53 Original line number Diff line number Diff line Loading @@ -142,50 +142,16 @@ static void msm_atomic_wait_for_commit_done( } } static bool msm_disable_outputs_for_clone_conn(struct drm_device *dev, struct drm_atomic_state *old_state) { struct drm_connector *connector; struct drm_connector_state *old_conn_state; struct drm_crtc_state *old_crtc_state; struct drm_crtc *crtc = NULL; int i; bool clone_state = false; for_each_old_connector_in_state(old_state, connector, old_conn_state, i) { if (!old_conn_state->crtc) continue; old_crtc_state = drm_atomic_get_old_crtc_state(old_state, old_conn_state->crtc); if (!old_crtc_state->active || !old_conn_state->crtc->state->connectors_changed || (!_msm_seamless_for_conn(connector, old_conn_state, false) && (connector->connector_type != DRM_MODE_CONNECTOR_VIRTUAL))) return false; if (crtc) clone_state = (crtc == old_conn_state->crtc) ? true : false; crtc = old_conn_state->crtc; } return clone_state; } static void msm_disable_connector_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) { struct drm_connector *connector; struct drm_connector_state *old_conn_state; struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state; int i; SDE_ATRACE_BEGIN("msm_disable"); for_each_old_connector_in_state(old_state, connector, old_conn_state, i) { const struct drm_encoder_helper_funcs *funcs; Loading Loading @@ -238,18 +204,6 @@ msm_disable_connector_outputs(struct drm_device *dev, drm_bridge_post_disable(encoder->bridge); } } static void msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) { struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state; int i; SDE_ATRACE_BEGIN("msm_disable"); if (!msm_disable_outputs_for_clone_conn(dev, old_state)) msm_disable_connector_outputs(dev, old_state); for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) { const struct drm_crtc_helper_funcs *funcs; Loading Loading @@ -568,9 +522,6 @@ static void complete_commit(struct msm_commit *c) kms->funcs->complete_commit(kms, state); if (msm_disable_outputs_for_clone_conn(dev, state)) msm_disable_connector_outputs(dev, state); drm_atomic_state_put(state); commit_destroy(c); Loading msm/sde/sde_encoder.c +23 −0 Original line number Diff line number Diff line Loading @@ -756,6 +756,29 @@ bool sde_encoder_in_clone_mode(struct drm_encoder *drm_enc) return false; } bool sde_encoder_is_cwb_disabling(struct drm_encoder *drm_enc, struct drm_crtc *crtc) { struct sde_encoder_virt *sde_enc; int i; if (!drm_enc) return false; sde_enc = to_sde_encoder_virt(drm_enc); if (sde_enc->disp_info.intf_type != DRM_MODE_CONNECTOR_VIRTUAL) return false; for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (sde_encoder_phys_is_cwb_disabling(phys, crtc)) return true; } return false; } 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) Loading msm/sde/sde_encoder.h +9 −0 Original line number Diff line number Diff line Loading @@ -495,6 +495,15 @@ void sde_encoder_recovery_events_handler(struct drm_encoder *encoder, */ bool sde_encoder_in_clone_mode(struct drm_encoder *enc); /* * sde_encoder_is_cwb_disabling - check if cwb encoder disable is pending * @drm_enc: Pointer to drm encoder structure * @drm_crtc: Pointer to drm crtc structure * @Return: true if cwb encoder disable is pending */ bool sde_encoder_is_cwb_disabling(struct drm_encoder *drm_enc, struct drm_crtc *drm_crtc); /** * sde_encoder_is_primary_display - checks if underlying display is primary * display or not. Loading msm/sde/sde_encoder_phys.h +20 −0 Original line number Diff line number Diff line Loading @@ -641,6 +641,26 @@ static inline enum sde_3d_blend_mode sde_encoder_helper_get_3d_blend_mode( return BLEND_3D_NONE; } /** * sde_encoder_phys_is_cwb_disabling - Check if CWB encoder attached to this * CRTC and it is in SDE_ENC_DISABLING state. * @phys_enc: Pointer to physical encoder structure * @crtc: drm crtc * @Return: true if cwb encoder is in disabling state */ static inline bool sde_encoder_phys_is_cwb_disabling( struct sde_encoder_phys *phys, struct drm_crtc *crtc) { struct sde_encoder_phys_wb *wb_enc; if (!phys || !phys->in_clone_mode || phys->enable_state != SDE_ENC_DISABLING) return false; wb_enc = container_of(phys, struct sde_encoder_phys_wb, base); return (wb_enc->crtc == crtc) ? true : false; } /** * sde_encoder_helper_split_config - split display configuration helper function * This helper function may be used by physical encoders to configure Loading msm/sde/sde_encoder_phys_wb.c +47 −23 Original line number Diff line number Diff line Loading @@ -1074,7 +1074,8 @@ static void _sde_encoder_phys_wb_frame_done_helper(void *arg, bool frame_error) SDE_DEBUG("[wb:%d,%u]\n", hw_wb->idx - WB_0, wb_enc->frame_count); /* don't notify upper layer for internal commit */ if (phys_enc->enable_state == SDE_ENC_DISABLING) if (phys_enc->enable_state == SDE_ENC_DISABLING && !phys_enc->in_clone_mode) goto complete; if (phys_enc->parent_ops.handle_frame_done && Loading Loading @@ -1272,6 +1273,31 @@ static bool _sde_encoder_phys_wb_is_idle( return ret; } static void _sde_encoder_phys_wb_reset_state( struct sde_encoder_phys *phys_enc) { struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc); /* * frame count and kickoff count are only used for debug purpose. Frame * count can be more than kickoff count at the end of disable call due * to extra frame_done wait. It does not cause any issue because * frame_done wait is based on retire_fence count. Leaving these * counters for debugging purpose. */ if (wb_enc->frame_count != wb_enc->kickoff_count) { SDE_EVT32(DRMID(phys_enc->parent), WBID(wb_enc), wb_enc->kickoff_count, wb_enc->frame_count, phys_enc->in_clone_mode); wb_enc->frame_count = wb_enc->kickoff_count; } phys_enc->enable_state = SDE_ENC_DISABLED; wb_enc->crtc = NULL; phys_enc->hw_cdm = NULL; phys_enc->hw_ctl = NULL; phys_enc->in_clone_mode = false; } static int _sde_encoder_phys_wb_wait_for_commit_done( struct sde_encoder_phys *phys_enc, bool is_disable) Loading Loading @@ -1358,7 +1384,17 @@ static int _sde_encoder_phys_wb_wait_for_commit_done( static int sde_encoder_phys_wb_wait_for_commit_done( struct sde_encoder_phys *phys_enc) { return _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, false); int rc; if (phys_enc->enable_state == SDE_ENC_DISABLING && phys_enc->in_clone_mode) { rc = _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, true); _sde_encoder_phys_wb_reset_state(phys_enc); } else { rc = _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, false); } return rc; } static int sde_encoder_phys_wb_wait_for_tx_complete( Loading Loading @@ -1625,6 +1661,8 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc) SDE_DEBUG("[wait_for_done: wb:%d, frame:%u, kickoff:%u]\n", hw_wb->idx - WB_0, wb_enc->frame_count, wb_enc->kickoff_count); if (!phys_enc->in_clone_mode || !wb_enc->crtc->state->active) _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, true); if (!phys_enc->hw_ctl || !phys_enc->parent || Loading @@ -1633,11 +1671,14 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc) goto exit; } /* avoid reset frame for CWB */ if (phys_enc->in_clone_mode) { _sde_encoder_phys_wb_setup_cwb(phys_enc, false); _sde_encoder_phys_wb_update_cwb_flush(phys_enc, false); phys_enc->in_clone_mode = false; phys_enc->enable_state = SDE_ENC_DISABLING; if (wb_enc->crtc->state->active) return; goto exit; } Loading Loading @@ -1670,24 +1711,7 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc) sde_encoder_phys_wb_irq_ctrl(phys_enc, false); exit: /* * frame count and kickoff count are only used for debug purpose. Frame * count can be more than kickoff count at the end of disable call due * to extra frame_done wait. It does not cause any issue because * frame_done wait is based on retire_fence count. Leaving these * counters for debugging purpose. */ if (wb_enc->frame_count != wb_enc->kickoff_count) { SDE_EVT32(DRMID(phys_enc->parent), WBID(wb_enc), wb_enc->kickoff_count, wb_enc->frame_count, phys_enc->in_clone_mode); wb_enc->frame_count = wb_enc->kickoff_count; } phys_enc->enable_state = SDE_ENC_DISABLED; wb_enc->crtc = NULL; phys_enc->hw_cdm = NULL; phys_enc->hw_ctl = NULL; _sde_encoder_phys_wb_reset_state(phys_enc); } /** Loading Loading
msm/msm_atomic.c +4 −53 Original line number Diff line number Diff line Loading @@ -142,50 +142,16 @@ static void msm_atomic_wait_for_commit_done( } } static bool msm_disable_outputs_for_clone_conn(struct drm_device *dev, struct drm_atomic_state *old_state) { struct drm_connector *connector; struct drm_connector_state *old_conn_state; struct drm_crtc_state *old_crtc_state; struct drm_crtc *crtc = NULL; int i; bool clone_state = false; for_each_old_connector_in_state(old_state, connector, old_conn_state, i) { if (!old_conn_state->crtc) continue; old_crtc_state = drm_atomic_get_old_crtc_state(old_state, old_conn_state->crtc); if (!old_crtc_state->active || !old_conn_state->crtc->state->connectors_changed || (!_msm_seamless_for_conn(connector, old_conn_state, false) && (connector->connector_type != DRM_MODE_CONNECTOR_VIRTUAL))) return false; if (crtc) clone_state = (crtc == old_conn_state->crtc) ? true : false; crtc = old_conn_state->crtc; } return clone_state; } static void msm_disable_connector_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) { struct drm_connector *connector; struct drm_connector_state *old_conn_state; struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state; int i; SDE_ATRACE_BEGIN("msm_disable"); for_each_old_connector_in_state(old_state, connector, old_conn_state, i) { const struct drm_encoder_helper_funcs *funcs; Loading Loading @@ -238,18 +204,6 @@ msm_disable_connector_outputs(struct drm_device *dev, drm_bridge_post_disable(encoder->bridge); } } static void msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) { struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state; int i; SDE_ATRACE_BEGIN("msm_disable"); if (!msm_disable_outputs_for_clone_conn(dev, old_state)) msm_disable_connector_outputs(dev, old_state); for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) { const struct drm_crtc_helper_funcs *funcs; Loading Loading @@ -568,9 +522,6 @@ static void complete_commit(struct msm_commit *c) kms->funcs->complete_commit(kms, state); if (msm_disable_outputs_for_clone_conn(dev, state)) msm_disable_connector_outputs(dev, state); drm_atomic_state_put(state); commit_destroy(c); Loading
msm/sde/sde_encoder.c +23 −0 Original line number Diff line number Diff line Loading @@ -756,6 +756,29 @@ bool sde_encoder_in_clone_mode(struct drm_encoder *drm_enc) return false; } bool sde_encoder_is_cwb_disabling(struct drm_encoder *drm_enc, struct drm_crtc *crtc) { struct sde_encoder_virt *sde_enc; int i; if (!drm_enc) return false; sde_enc = to_sde_encoder_virt(drm_enc); if (sde_enc->disp_info.intf_type != DRM_MODE_CONNECTOR_VIRTUAL) return false; for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (sde_encoder_phys_is_cwb_disabling(phys, crtc)) return true; } return false; } 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) Loading
msm/sde/sde_encoder.h +9 −0 Original line number Diff line number Diff line Loading @@ -495,6 +495,15 @@ void sde_encoder_recovery_events_handler(struct drm_encoder *encoder, */ bool sde_encoder_in_clone_mode(struct drm_encoder *enc); /* * sde_encoder_is_cwb_disabling - check if cwb encoder disable is pending * @drm_enc: Pointer to drm encoder structure * @drm_crtc: Pointer to drm crtc structure * @Return: true if cwb encoder disable is pending */ bool sde_encoder_is_cwb_disabling(struct drm_encoder *drm_enc, struct drm_crtc *drm_crtc); /** * sde_encoder_is_primary_display - checks if underlying display is primary * display or not. Loading
msm/sde/sde_encoder_phys.h +20 −0 Original line number Diff line number Diff line Loading @@ -641,6 +641,26 @@ static inline enum sde_3d_blend_mode sde_encoder_helper_get_3d_blend_mode( return BLEND_3D_NONE; } /** * sde_encoder_phys_is_cwb_disabling - Check if CWB encoder attached to this * CRTC and it is in SDE_ENC_DISABLING state. * @phys_enc: Pointer to physical encoder structure * @crtc: drm crtc * @Return: true if cwb encoder is in disabling state */ static inline bool sde_encoder_phys_is_cwb_disabling( struct sde_encoder_phys *phys, struct drm_crtc *crtc) { struct sde_encoder_phys_wb *wb_enc; if (!phys || !phys->in_clone_mode || phys->enable_state != SDE_ENC_DISABLING) return false; wb_enc = container_of(phys, struct sde_encoder_phys_wb, base); return (wb_enc->crtc == crtc) ? true : false; } /** * sde_encoder_helper_split_config - split display configuration helper function * This helper function may be used by physical encoders to configure Loading
msm/sde/sde_encoder_phys_wb.c +47 −23 Original line number Diff line number Diff line Loading @@ -1074,7 +1074,8 @@ static void _sde_encoder_phys_wb_frame_done_helper(void *arg, bool frame_error) SDE_DEBUG("[wb:%d,%u]\n", hw_wb->idx - WB_0, wb_enc->frame_count); /* don't notify upper layer for internal commit */ if (phys_enc->enable_state == SDE_ENC_DISABLING) if (phys_enc->enable_state == SDE_ENC_DISABLING && !phys_enc->in_clone_mode) goto complete; if (phys_enc->parent_ops.handle_frame_done && Loading Loading @@ -1272,6 +1273,31 @@ static bool _sde_encoder_phys_wb_is_idle( return ret; } static void _sde_encoder_phys_wb_reset_state( struct sde_encoder_phys *phys_enc) { struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc); /* * frame count and kickoff count are only used for debug purpose. Frame * count can be more than kickoff count at the end of disable call due * to extra frame_done wait. It does not cause any issue because * frame_done wait is based on retire_fence count. Leaving these * counters for debugging purpose. */ if (wb_enc->frame_count != wb_enc->kickoff_count) { SDE_EVT32(DRMID(phys_enc->parent), WBID(wb_enc), wb_enc->kickoff_count, wb_enc->frame_count, phys_enc->in_clone_mode); wb_enc->frame_count = wb_enc->kickoff_count; } phys_enc->enable_state = SDE_ENC_DISABLED; wb_enc->crtc = NULL; phys_enc->hw_cdm = NULL; phys_enc->hw_ctl = NULL; phys_enc->in_clone_mode = false; } static int _sde_encoder_phys_wb_wait_for_commit_done( struct sde_encoder_phys *phys_enc, bool is_disable) Loading Loading @@ -1358,7 +1384,17 @@ static int _sde_encoder_phys_wb_wait_for_commit_done( static int sde_encoder_phys_wb_wait_for_commit_done( struct sde_encoder_phys *phys_enc) { return _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, false); int rc; if (phys_enc->enable_state == SDE_ENC_DISABLING && phys_enc->in_clone_mode) { rc = _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, true); _sde_encoder_phys_wb_reset_state(phys_enc); } else { rc = _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, false); } return rc; } static int sde_encoder_phys_wb_wait_for_tx_complete( Loading Loading @@ -1625,6 +1661,8 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc) SDE_DEBUG("[wait_for_done: wb:%d, frame:%u, kickoff:%u]\n", hw_wb->idx - WB_0, wb_enc->frame_count, wb_enc->kickoff_count); if (!phys_enc->in_clone_mode || !wb_enc->crtc->state->active) _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, true); if (!phys_enc->hw_ctl || !phys_enc->parent || Loading @@ -1633,11 +1671,14 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc) goto exit; } /* avoid reset frame for CWB */ if (phys_enc->in_clone_mode) { _sde_encoder_phys_wb_setup_cwb(phys_enc, false); _sde_encoder_phys_wb_update_cwb_flush(phys_enc, false); phys_enc->in_clone_mode = false; phys_enc->enable_state = SDE_ENC_DISABLING; if (wb_enc->crtc->state->active) return; goto exit; } Loading Loading @@ -1670,24 +1711,7 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc) sde_encoder_phys_wb_irq_ctrl(phys_enc, false); exit: /* * frame count and kickoff count are only used for debug purpose. Frame * count can be more than kickoff count at the end of disable call due * to extra frame_done wait. It does not cause any issue because * frame_done wait is based on retire_fence count. Leaving these * counters for debugging purpose. */ if (wb_enc->frame_count != wb_enc->kickoff_count) { SDE_EVT32(DRMID(phys_enc->parent), WBID(wb_enc), wb_enc->kickoff_count, wb_enc->frame_count, phys_enc->in_clone_mode); wb_enc->frame_count = wb_enc->kickoff_count; } phys_enc->enable_state = SDE_ENC_DISABLED; wb_enc->crtc = NULL; phys_enc->hw_cdm = NULL; phys_enc->hw_ctl = NULL; _sde_encoder_phys_wb_reset_state(phys_enc); } /** Loading