Loading drivers/gpu/drm/msm/sde/sde_crtc.c +21 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,20 @@ static inline struct sde_kms *_sde_crtc_get_kms(struct drm_crtc *crtc) return to_sde_kms(priv->kms); } static inline struct drm_encoder *_sde_crtc_get_encoder(struct drm_crtc *crtc) { struct drm_encoder *enc; struct list_head *encoder_list; encoder_list = &crtc->dev->mode_config.encoder_list; list_for_each_entry(enc, encoder_list, head) if (enc->crtc == crtc) return enc; return NULL; } static inline int _sde_crtc_power_enable(struct sde_crtc *sde_crtc, bool enable) { struct drm_crtc *crtc; Loading Loading @@ -3045,6 +3059,8 @@ static void sde_crtc_destroy_state(struct drm_crtc *crtc, { struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; struct drm_encoder *enc; struct sde_kms *sde_kms; if (!crtc || !state) { SDE_ERROR("invalid argument(s)\n"); Loading @@ -3053,9 +3069,14 @@ static void sde_crtc_destroy_state(struct drm_crtc *crtc, sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(state); enc = _sde_crtc_get_encoder(crtc); sde_kms = _sde_crtc_get_kms(crtc); SDE_DEBUG("crtc%d\n", crtc->base.id); if (sde_kms && enc) sde_rm_release(&sde_kms->rm, enc, true); __drm_atomic_helper_crtc_destroy_state(state); /* destroy value helper */ Loading drivers/gpu/drm/msm/sde/sde_encoder.c +1 −1 Original line number Diff line number Diff line Loading @@ -3167,7 +3167,7 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) SDE_DEBUG_ENC(sde_enc, "encoder disabled\n"); sde_rm_release(&sde_kms->rm, drm_enc); sde_rm_release(&sde_kms->rm, drm_enc, false); } void sde_encoder_helper_phys_disable(struct sde_encoder_phys *phys_enc, Loading drivers/gpu/drm/msm/sde/sde_rm.c +50 −15 Original line number Diff line number Diff line Loading @@ -18,7 +18,8 @@ #include "sde_hw_dsc.h" #define RESERVED_BY_OTHER(h, r) \ ((h)->rsvp && ((h)->rsvp->enc_id != (r)->enc_id)) (((h)->rsvp && ((h)->rsvp->enc_id != (r)->enc_id)) ||\ ((h)->rsvp_nxt && ((h)->rsvp_nxt->enc_id != (r)->enc_id))) #define RM_RQ_LOCK(r) ((r)->top_ctrl & BIT(SDE_RM_TOPCTL_RESERVE_LOCK)) #define RM_RQ_CLEAR(r) ((r)->top_ctrl & BIT(SDE_RM_TOPCTL_RESERVE_CLEAR)) Loading Loading @@ -1452,6 +1453,30 @@ static struct sde_rm_rsvp *_sde_rm_get_rsvp( return NULL; } static struct sde_rm_rsvp *_sde_rm_get_rsvp_nxt( struct sde_rm *rm, struct drm_encoder *enc) { struct sde_rm_rsvp *i, *j; if (list_empty(&rm->rsvps)) return NULL; list_for_each_entry(i, &rm->rsvps, list) if (i->enc_id == enc->base.id) break; j = i; list_for_each_entry_continue(j, &rm->rsvps, list) if (j->enc_id == enc->base.id) break; if (i && j && (i->seq != j->seq)) return j; return NULL; } static struct drm_connector *_sde_rm_get_connector( struct drm_encoder *enc) { Loading Loading @@ -1539,7 +1564,7 @@ static void _sde_rm_release_rsvp( kfree(rsvp); } void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc) void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc, bool nxt) { struct sde_rm_rsvp *rsvp; struct drm_connector *conn; Loading @@ -1552,15 +1577,20 @@ void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc) mutex_lock(&rm->rm_lock); if (nxt) rsvp = _sde_rm_get_rsvp_nxt(rm, enc); else rsvp = _sde_rm_get_rsvp(rm, enc); if (!rsvp) { SDE_ERROR("failed to find rsvp for enc %d\n", enc->base.id); SDE_ERROR("failed to find rsvp for enc %d, nxt %d", enc->base.id, nxt); goto end; } conn = _sde_rm_get_connector(enc); if (!conn) { SDE_ERROR("failed to get connector for enc %d\n", enc->base.id); SDE_ERROR("failed to get connector for enc %d, nxt %d", enc->base.id, nxt); goto end; } Loading Loading @@ -1651,6 +1681,12 @@ int sde_rm_reserve( _sde_rm_print_rsvps(rm, SDE_RM_STAGE_BEGIN); rsvp_cur = _sde_rm_get_rsvp(rm, enc); rsvp_nxt = _sde_rm_get_rsvp_nxt(rm, enc); if (!test_only && rsvp_nxt) goto commit_rsvp; ret = _sde_rm_populate_requirements(rm, enc, crtc_state, conn_state, &reqs); if (ret) { Loading @@ -1675,8 +1711,6 @@ int sde_rm_reserve( goto end; } rsvp_cur = _sde_rm_get_rsvp(rm, enc); /* * User can request that we clear out any reservation during the * atomic_check phase by using this CLEAR bit Loading @@ -1696,30 +1730,31 @@ int sde_rm_reserve( _sde_rm_print_rsvps(rm, SDE_RM_STAGE_AFTER_RSVPNEXT); if (ret) { SDE_ERROR("failed to reserve hw resources: %d\n", ret); SDE_ERROR("failed to reserve hw resources: %d, test_only %d\n", ret, test_only); _sde_rm_release_rsvp(rm, rsvp_nxt, conn_state->connector); goto end; } else if (test_only && !RM_RQ_LOCK(&reqs)) { /* * Normally, if test_only, test the reservation and then undo * However, if the user requests LOCK, then keep the reservation * made during the atomic_check phase. */ SDE_DEBUG("test_only: discard test rsvp[s%de%d]\n", SDE_DEBUG("test_only: rsvp[s%de%d]\n", rsvp_nxt->seq, rsvp_nxt->enc_id); _sde_rm_release_rsvp(rm, rsvp_nxt, conn_state->connector); goto end; } else { if (test_only && RM_RQ_LOCK(&reqs)) SDE_DEBUG("test_only & LOCK: lock rsvp[s%de%d]\n", rsvp_nxt->seq, rsvp_nxt->enc_id); } commit_rsvp: _sde_rm_release_rsvp(rm, rsvp_cur, conn_state->connector); ret = _sde_rm_commit_rsvp(rm, rsvp_nxt, conn_state); } _sde_rm_print_rsvps(rm, SDE_RM_STAGE_FINAL); end: _sde_rm_print_rsvps(rm, SDE_RM_STAGE_FINAL); mutex_unlock(&rm->rm_lock); return ret; Loading drivers/gpu/drm/msm/sde/sde_rm.h +3 −2 Original line number Diff line number Diff line Loading @@ -184,13 +184,14 @@ int sde_rm_reserve(struct sde_rm *rm, bool test_only); /** * sde_rm_reserve - Given the encoder for the display chain, release any * sde_rm_release - Given the encoder for the display chain, release any * HW blocks previously reserved for that use case. * @rm: SDE Resource Manager handle * @enc: DRM Encoder handle * @nxt: Choose option to release rsvp_nxt * @Return: 0 on Success otherwise -ERROR */ void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc); void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc, bool nxt); /** * sde_rm_get_mdp - Retrieve HW block for MDP TOP. Loading Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +21 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,20 @@ static inline struct sde_kms *_sde_crtc_get_kms(struct drm_crtc *crtc) return to_sde_kms(priv->kms); } static inline struct drm_encoder *_sde_crtc_get_encoder(struct drm_crtc *crtc) { struct drm_encoder *enc; struct list_head *encoder_list; encoder_list = &crtc->dev->mode_config.encoder_list; list_for_each_entry(enc, encoder_list, head) if (enc->crtc == crtc) return enc; return NULL; } static inline int _sde_crtc_power_enable(struct sde_crtc *sde_crtc, bool enable) { struct drm_crtc *crtc; Loading Loading @@ -3045,6 +3059,8 @@ static void sde_crtc_destroy_state(struct drm_crtc *crtc, { struct sde_crtc *sde_crtc; struct sde_crtc_state *cstate; struct drm_encoder *enc; struct sde_kms *sde_kms; if (!crtc || !state) { SDE_ERROR("invalid argument(s)\n"); Loading @@ -3053,9 +3069,14 @@ static void sde_crtc_destroy_state(struct drm_crtc *crtc, sde_crtc = to_sde_crtc(crtc); cstate = to_sde_crtc_state(state); enc = _sde_crtc_get_encoder(crtc); sde_kms = _sde_crtc_get_kms(crtc); SDE_DEBUG("crtc%d\n", crtc->base.id); if (sde_kms && enc) sde_rm_release(&sde_kms->rm, enc, true); __drm_atomic_helper_crtc_destroy_state(state); /* destroy value helper */ Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +1 −1 Original line number Diff line number Diff line Loading @@ -3167,7 +3167,7 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) SDE_DEBUG_ENC(sde_enc, "encoder disabled\n"); sde_rm_release(&sde_kms->rm, drm_enc); sde_rm_release(&sde_kms->rm, drm_enc, false); } void sde_encoder_helper_phys_disable(struct sde_encoder_phys *phys_enc, Loading
drivers/gpu/drm/msm/sde/sde_rm.c +50 −15 Original line number Diff line number Diff line Loading @@ -18,7 +18,8 @@ #include "sde_hw_dsc.h" #define RESERVED_BY_OTHER(h, r) \ ((h)->rsvp && ((h)->rsvp->enc_id != (r)->enc_id)) (((h)->rsvp && ((h)->rsvp->enc_id != (r)->enc_id)) ||\ ((h)->rsvp_nxt && ((h)->rsvp_nxt->enc_id != (r)->enc_id))) #define RM_RQ_LOCK(r) ((r)->top_ctrl & BIT(SDE_RM_TOPCTL_RESERVE_LOCK)) #define RM_RQ_CLEAR(r) ((r)->top_ctrl & BIT(SDE_RM_TOPCTL_RESERVE_CLEAR)) Loading Loading @@ -1452,6 +1453,30 @@ static struct sde_rm_rsvp *_sde_rm_get_rsvp( return NULL; } static struct sde_rm_rsvp *_sde_rm_get_rsvp_nxt( struct sde_rm *rm, struct drm_encoder *enc) { struct sde_rm_rsvp *i, *j; if (list_empty(&rm->rsvps)) return NULL; list_for_each_entry(i, &rm->rsvps, list) if (i->enc_id == enc->base.id) break; j = i; list_for_each_entry_continue(j, &rm->rsvps, list) if (j->enc_id == enc->base.id) break; if (i && j && (i->seq != j->seq)) return j; return NULL; } static struct drm_connector *_sde_rm_get_connector( struct drm_encoder *enc) { Loading Loading @@ -1539,7 +1564,7 @@ static void _sde_rm_release_rsvp( kfree(rsvp); } void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc) void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc, bool nxt) { struct sde_rm_rsvp *rsvp; struct drm_connector *conn; Loading @@ -1552,15 +1577,20 @@ void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc) mutex_lock(&rm->rm_lock); if (nxt) rsvp = _sde_rm_get_rsvp_nxt(rm, enc); else rsvp = _sde_rm_get_rsvp(rm, enc); if (!rsvp) { SDE_ERROR("failed to find rsvp for enc %d\n", enc->base.id); SDE_ERROR("failed to find rsvp for enc %d, nxt %d", enc->base.id, nxt); goto end; } conn = _sde_rm_get_connector(enc); if (!conn) { SDE_ERROR("failed to get connector for enc %d\n", enc->base.id); SDE_ERROR("failed to get connector for enc %d, nxt %d", enc->base.id, nxt); goto end; } Loading Loading @@ -1651,6 +1681,12 @@ int sde_rm_reserve( _sde_rm_print_rsvps(rm, SDE_RM_STAGE_BEGIN); rsvp_cur = _sde_rm_get_rsvp(rm, enc); rsvp_nxt = _sde_rm_get_rsvp_nxt(rm, enc); if (!test_only && rsvp_nxt) goto commit_rsvp; ret = _sde_rm_populate_requirements(rm, enc, crtc_state, conn_state, &reqs); if (ret) { Loading @@ -1675,8 +1711,6 @@ int sde_rm_reserve( goto end; } rsvp_cur = _sde_rm_get_rsvp(rm, enc); /* * User can request that we clear out any reservation during the * atomic_check phase by using this CLEAR bit Loading @@ -1696,30 +1730,31 @@ int sde_rm_reserve( _sde_rm_print_rsvps(rm, SDE_RM_STAGE_AFTER_RSVPNEXT); if (ret) { SDE_ERROR("failed to reserve hw resources: %d\n", ret); SDE_ERROR("failed to reserve hw resources: %d, test_only %d\n", ret, test_only); _sde_rm_release_rsvp(rm, rsvp_nxt, conn_state->connector); goto end; } else if (test_only && !RM_RQ_LOCK(&reqs)) { /* * Normally, if test_only, test the reservation and then undo * However, if the user requests LOCK, then keep the reservation * made during the atomic_check phase. */ SDE_DEBUG("test_only: discard test rsvp[s%de%d]\n", SDE_DEBUG("test_only: rsvp[s%de%d]\n", rsvp_nxt->seq, rsvp_nxt->enc_id); _sde_rm_release_rsvp(rm, rsvp_nxt, conn_state->connector); goto end; } else { if (test_only && RM_RQ_LOCK(&reqs)) SDE_DEBUG("test_only & LOCK: lock rsvp[s%de%d]\n", rsvp_nxt->seq, rsvp_nxt->enc_id); } commit_rsvp: _sde_rm_release_rsvp(rm, rsvp_cur, conn_state->connector); ret = _sde_rm_commit_rsvp(rm, rsvp_nxt, conn_state); } _sde_rm_print_rsvps(rm, SDE_RM_STAGE_FINAL); end: _sde_rm_print_rsvps(rm, SDE_RM_STAGE_FINAL); mutex_unlock(&rm->rm_lock); return ret; Loading
drivers/gpu/drm/msm/sde/sde_rm.h +3 −2 Original line number Diff line number Diff line Loading @@ -184,13 +184,14 @@ int sde_rm_reserve(struct sde_rm *rm, bool test_only); /** * sde_rm_reserve - Given the encoder for the display chain, release any * sde_rm_release - Given the encoder for the display chain, release any * HW blocks previously reserved for that use case. * @rm: SDE Resource Manager handle * @enc: DRM Encoder handle * @nxt: Choose option to release rsvp_nxt * @Return: 0 on Success otherwise -ERROR */ void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc); void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc, bool nxt); /** * sde_rm_get_mdp - Retrieve HW block for MDP TOP. Loading