Loading drivers/gpu/drm/msm/sde/sde_rm.c +44 −16 Original line number Diff line number Diff line Loading @@ -175,7 +175,7 @@ void sde_rm_init_hw_iter( iter->type = type; } bool sde_rm_get_hw(struct sde_rm *rm, struct sde_rm_hw_iter *i) static bool _sde_rm_get_hw_locked(struct sde_rm *rm, struct sde_rm_hw_iter *i) { struct list_head *blk_list; Loading Loading @@ -217,6 +217,17 @@ bool sde_rm_get_hw(struct sde_rm *rm, struct sde_rm_hw_iter *i) return false; } bool sde_rm_get_hw(struct sde_rm *rm, struct sde_rm_hw_iter *i) { bool ret; mutex_lock(&rm->rm_lock); ret = _sde_rm_get_hw_locked(rm, i); mutex_unlock(&rm->rm_lock); return ret; } static void _sde_rm_hw_destroy(enum sde_hw_blk_type type, void *hw) { switch (type) { Loading Loading @@ -288,6 +299,8 @@ int sde_rm_destroy(struct sde_rm *rm) sde_hw_mdp_destroy(rm->hw_mdp); rm->hw_mdp = NULL; mutex_destroy(&rm->rm_lock); return 0; } Loading Loading @@ -390,6 +403,9 @@ int sde_rm_init(struct sde_rm *rm, /* Clear, setup lists */ memset(rm, 0, sizeof(*rm)); mutex_init(&rm->rm_lock); INIT_LIST_HEAD(&rm->rsvps); for (type = 0; type < SDE_HW_BLK_MAX; type++) INIT_LIST_HEAD(&rm->hw_blks[type]); Loading Loading @@ -584,7 +600,7 @@ static bool _sde_rm_check_lm_and_get_connected_blks( if (lm_cfg->dspp != DSPP_MAX) { sde_rm_init_hw_iter(&iter, 0, SDE_HW_BLK_DSPP); while (sde_rm_get_hw(rm, &iter)) { while (_sde_rm_get_hw_locked(rm, &iter)) { if (iter.blk->id == lm_cfg->dspp) { *dspp = iter.blk; break; Loading @@ -605,7 +621,7 @@ static bool _sde_rm_check_lm_and_get_connected_blks( } sde_rm_init_hw_iter(&iter, 0, SDE_HW_BLK_PINGPONG); while (sde_rm_get_hw(rm, &iter)) { while (_sde_rm_get_hw_locked(rm, &iter)) { if (iter.blk->id == lm_cfg->pingpong) { *pp = iter.blk; break; Loading Loading @@ -656,7 +672,7 @@ static int _sde_rm_reserve_lms( /* Find a primary mixer */ sde_rm_init_hw_iter(&iter_i, 0, SDE_HW_BLK_LM); while (lm_count != reqs->topology->num_lm && sde_rm_get_hw(rm, &iter_i)) { _sde_rm_get_hw_locked(rm, &iter_i)) { memset(&lm, 0, sizeof(lm)); memset(&dspp, 0, sizeof(dspp)); memset(&pp, 0, sizeof(pp)); Loading @@ -675,7 +691,7 @@ static int _sde_rm_reserve_lms( sde_rm_init_hw_iter(&iter_j, 0, SDE_HW_BLK_LM); while (lm_count != reqs->topology->num_lm && sde_rm_get_hw(rm, &iter_j)) { _sde_rm_get_hw_locked(rm, &iter_j)) { if (iter_i.blk == iter_j.blk) continue; Loading Loading @@ -711,7 +727,7 @@ static int _sde_rm_reserve_lms( /* reserve a free PINGPONG_SLAVE block */ rc = -ENAVAIL; sde_rm_init_hw_iter(&iter_i, 0, SDE_HW_BLK_PINGPONG); while (sde_rm_get_hw(rm, &iter_i)) { while (_sde_rm_get_hw_locked(rm, &iter_i)) { struct sde_pingpong_cfg *pp_cfg = (struct sde_pingpong_cfg *) (iter_i.blk->catalog); Loading Loading @@ -742,7 +758,7 @@ static int _sde_rm_reserve_ctls( memset(&ctls, 0, sizeof(ctls)); sde_rm_init_hw_iter(&iter, 0, SDE_HW_BLK_CTL); while (sde_rm_get_hw(rm, &iter)) { while (_sde_rm_get_hw_locked(rm, &iter)) { unsigned long caps; bool has_split_display, has_ppsplit; Loading Loading @@ -793,7 +809,7 @@ static int _sde_rm_reserve_dsc( sde_rm_init_hw_iter(&iter, 0, SDE_HW_BLK_DSC); while (sde_rm_get_hw(rm, &iter)) { while (_sde_rm_get_hw_locked(rm, &iter)) { if (RESERVED_BY_OTHER(iter.blk, rsvp)) continue; Loading @@ -820,7 +836,7 @@ static int _sde_rm_reserve_cdm( struct sde_cdm_cfg *cdm; sde_rm_init_hw_iter(&iter, 0, SDE_HW_BLK_CDM); while (sde_rm_get_hw(rm, &iter)) { while (_sde_rm_get_hw_locked(rm, &iter)) { bool match = false; if (RESERVED_BY_OTHER(iter.blk, rsvp)) Loading Loading @@ -865,7 +881,7 @@ static int _sde_rm_reserve_intf_or_wb( /* Find the block entry in the rm, and note the reservation */ sde_rm_init_hw_iter(&iter, 0, type); while (sde_rm_get_hw(rm, &iter)) { while (_sde_rm_get_hw_locked(rm, &iter)) { if (iter.blk->id != id) continue; Loading Loading @@ -1071,7 +1087,7 @@ static struct drm_connector *_sde_rm_get_connector( * @rm: KMS handle * @rsvp: RSVP pointer to release and release resources for */ void _sde_rm_release_rsvp( static void _sde_rm_release_rsvp( struct sde_rm *rm, struct sde_rm_rsvp *rsvp, struct drm_connector *conn) Loading Loading @@ -1123,16 +1139,18 @@ void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc) return; } mutex_lock(&rm->rm_lock); rsvp = _sde_rm_get_rsvp(rm, enc); if (!rsvp) { SDE_ERROR("failed to find rsvp for enc %d\n", enc->base.id); return; goto end; } conn = _sde_rm_get_connector(enc); if (!conn) { SDE_ERROR("failed to get connector for enc %d\n", enc->base.id); return; goto end; } top_ctrl = sde_connector_get_property(conn->state, Loading @@ -1152,6 +1170,9 @@ void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc) CONNECTOR_PROP_TOPOLOGY_NAME, SDE_RM_TOPOLOGY_NONE); } end: mutex_unlock(&rm->rm_lock); } static int _sde_rm_commit_rsvp( Loading Loading @@ -1219,13 +1240,15 @@ int sde_rm_reserve( crtc_state->crtc->base.id, test_only); SDE_EVT32(enc->base.id, conn_state->connector->base.id); mutex_lock(&rm->rm_lock); _sde_rm_print_rsvps(rm, SDE_RM_STAGE_BEGIN); ret = _sde_rm_populate_requirements(rm, enc, crtc_state, conn_state, &reqs); if (ret) { SDE_ERROR("failed to populate hw requirements\n"); return ret; goto end; } /* Loading @@ -1240,8 +1263,10 @@ int sde_rm_reserve( * replace the current with the next. */ rsvp_nxt = kzalloc(sizeof(*rsvp_nxt), GFP_KERNEL); if (!rsvp_nxt) return -ENOMEM; if (!rsvp_nxt) { ret = -ENOMEM; goto end; } rsvp_cur = _sde_rm_get_rsvp(rm, enc); Loading Loading @@ -1293,5 +1318,8 @@ int sde_rm_reserve( _sde_rm_print_rsvps(rm, SDE_RM_STAGE_FINAL); end: mutex_unlock(&rm->rm_lock); return ret; } drivers/gpu/drm/msm/sde/sde_rm.h +2 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ enum sde_rm_topology_control { * @hw_mdp: hardware object for mdp_top * @lm_max_width: cached layer mixer maximum width * @rsvp_next_seq: sequence number for next reservation for debugging purposes * @rm_lock: resource manager mutex */ struct sde_rm { struct drm_device *dev; Loading @@ -80,6 +81,7 @@ struct sde_rm { struct sde_hw_mdp *hw_mdp; uint32_t lm_max_width; uint32_t rsvp_next_seq; struct mutex rm_lock; }; /** Loading Loading
drivers/gpu/drm/msm/sde/sde_rm.c +44 −16 Original line number Diff line number Diff line Loading @@ -175,7 +175,7 @@ void sde_rm_init_hw_iter( iter->type = type; } bool sde_rm_get_hw(struct sde_rm *rm, struct sde_rm_hw_iter *i) static bool _sde_rm_get_hw_locked(struct sde_rm *rm, struct sde_rm_hw_iter *i) { struct list_head *blk_list; Loading Loading @@ -217,6 +217,17 @@ bool sde_rm_get_hw(struct sde_rm *rm, struct sde_rm_hw_iter *i) return false; } bool sde_rm_get_hw(struct sde_rm *rm, struct sde_rm_hw_iter *i) { bool ret; mutex_lock(&rm->rm_lock); ret = _sde_rm_get_hw_locked(rm, i); mutex_unlock(&rm->rm_lock); return ret; } static void _sde_rm_hw_destroy(enum sde_hw_blk_type type, void *hw) { switch (type) { Loading Loading @@ -288,6 +299,8 @@ int sde_rm_destroy(struct sde_rm *rm) sde_hw_mdp_destroy(rm->hw_mdp); rm->hw_mdp = NULL; mutex_destroy(&rm->rm_lock); return 0; } Loading Loading @@ -390,6 +403,9 @@ int sde_rm_init(struct sde_rm *rm, /* Clear, setup lists */ memset(rm, 0, sizeof(*rm)); mutex_init(&rm->rm_lock); INIT_LIST_HEAD(&rm->rsvps); for (type = 0; type < SDE_HW_BLK_MAX; type++) INIT_LIST_HEAD(&rm->hw_blks[type]); Loading Loading @@ -584,7 +600,7 @@ static bool _sde_rm_check_lm_and_get_connected_blks( if (lm_cfg->dspp != DSPP_MAX) { sde_rm_init_hw_iter(&iter, 0, SDE_HW_BLK_DSPP); while (sde_rm_get_hw(rm, &iter)) { while (_sde_rm_get_hw_locked(rm, &iter)) { if (iter.blk->id == lm_cfg->dspp) { *dspp = iter.blk; break; Loading @@ -605,7 +621,7 @@ static bool _sde_rm_check_lm_and_get_connected_blks( } sde_rm_init_hw_iter(&iter, 0, SDE_HW_BLK_PINGPONG); while (sde_rm_get_hw(rm, &iter)) { while (_sde_rm_get_hw_locked(rm, &iter)) { if (iter.blk->id == lm_cfg->pingpong) { *pp = iter.blk; break; Loading Loading @@ -656,7 +672,7 @@ static int _sde_rm_reserve_lms( /* Find a primary mixer */ sde_rm_init_hw_iter(&iter_i, 0, SDE_HW_BLK_LM); while (lm_count != reqs->topology->num_lm && sde_rm_get_hw(rm, &iter_i)) { _sde_rm_get_hw_locked(rm, &iter_i)) { memset(&lm, 0, sizeof(lm)); memset(&dspp, 0, sizeof(dspp)); memset(&pp, 0, sizeof(pp)); Loading @@ -675,7 +691,7 @@ static int _sde_rm_reserve_lms( sde_rm_init_hw_iter(&iter_j, 0, SDE_HW_BLK_LM); while (lm_count != reqs->topology->num_lm && sde_rm_get_hw(rm, &iter_j)) { _sde_rm_get_hw_locked(rm, &iter_j)) { if (iter_i.blk == iter_j.blk) continue; Loading Loading @@ -711,7 +727,7 @@ static int _sde_rm_reserve_lms( /* reserve a free PINGPONG_SLAVE block */ rc = -ENAVAIL; sde_rm_init_hw_iter(&iter_i, 0, SDE_HW_BLK_PINGPONG); while (sde_rm_get_hw(rm, &iter_i)) { while (_sde_rm_get_hw_locked(rm, &iter_i)) { struct sde_pingpong_cfg *pp_cfg = (struct sde_pingpong_cfg *) (iter_i.blk->catalog); Loading Loading @@ -742,7 +758,7 @@ static int _sde_rm_reserve_ctls( memset(&ctls, 0, sizeof(ctls)); sde_rm_init_hw_iter(&iter, 0, SDE_HW_BLK_CTL); while (sde_rm_get_hw(rm, &iter)) { while (_sde_rm_get_hw_locked(rm, &iter)) { unsigned long caps; bool has_split_display, has_ppsplit; Loading Loading @@ -793,7 +809,7 @@ static int _sde_rm_reserve_dsc( sde_rm_init_hw_iter(&iter, 0, SDE_HW_BLK_DSC); while (sde_rm_get_hw(rm, &iter)) { while (_sde_rm_get_hw_locked(rm, &iter)) { if (RESERVED_BY_OTHER(iter.blk, rsvp)) continue; Loading @@ -820,7 +836,7 @@ static int _sde_rm_reserve_cdm( struct sde_cdm_cfg *cdm; sde_rm_init_hw_iter(&iter, 0, SDE_HW_BLK_CDM); while (sde_rm_get_hw(rm, &iter)) { while (_sde_rm_get_hw_locked(rm, &iter)) { bool match = false; if (RESERVED_BY_OTHER(iter.blk, rsvp)) Loading Loading @@ -865,7 +881,7 @@ static int _sde_rm_reserve_intf_or_wb( /* Find the block entry in the rm, and note the reservation */ sde_rm_init_hw_iter(&iter, 0, type); while (sde_rm_get_hw(rm, &iter)) { while (_sde_rm_get_hw_locked(rm, &iter)) { if (iter.blk->id != id) continue; Loading Loading @@ -1071,7 +1087,7 @@ static struct drm_connector *_sde_rm_get_connector( * @rm: KMS handle * @rsvp: RSVP pointer to release and release resources for */ void _sde_rm_release_rsvp( static void _sde_rm_release_rsvp( struct sde_rm *rm, struct sde_rm_rsvp *rsvp, struct drm_connector *conn) Loading Loading @@ -1123,16 +1139,18 @@ void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc) return; } mutex_lock(&rm->rm_lock); rsvp = _sde_rm_get_rsvp(rm, enc); if (!rsvp) { SDE_ERROR("failed to find rsvp for enc %d\n", enc->base.id); return; goto end; } conn = _sde_rm_get_connector(enc); if (!conn) { SDE_ERROR("failed to get connector for enc %d\n", enc->base.id); return; goto end; } top_ctrl = sde_connector_get_property(conn->state, Loading @@ -1152,6 +1170,9 @@ void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc) CONNECTOR_PROP_TOPOLOGY_NAME, SDE_RM_TOPOLOGY_NONE); } end: mutex_unlock(&rm->rm_lock); } static int _sde_rm_commit_rsvp( Loading Loading @@ -1219,13 +1240,15 @@ int sde_rm_reserve( crtc_state->crtc->base.id, test_only); SDE_EVT32(enc->base.id, conn_state->connector->base.id); mutex_lock(&rm->rm_lock); _sde_rm_print_rsvps(rm, SDE_RM_STAGE_BEGIN); ret = _sde_rm_populate_requirements(rm, enc, crtc_state, conn_state, &reqs); if (ret) { SDE_ERROR("failed to populate hw requirements\n"); return ret; goto end; } /* Loading @@ -1240,8 +1263,10 @@ int sde_rm_reserve( * replace the current with the next. */ rsvp_nxt = kzalloc(sizeof(*rsvp_nxt), GFP_KERNEL); if (!rsvp_nxt) return -ENOMEM; if (!rsvp_nxt) { ret = -ENOMEM; goto end; } rsvp_cur = _sde_rm_get_rsvp(rm, enc); Loading Loading @@ -1293,5 +1318,8 @@ int sde_rm_reserve( _sde_rm_print_rsvps(rm, SDE_RM_STAGE_FINAL); end: mutex_unlock(&rm->rm_lock); return ret; }
drivers/gpu/drm/msm/sde/sde_rm.h +2 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ enum sde_rm_topology_control { * @hw_mdp: hardware object for mdp_top * @lm_max_width: cached layer mixer maximum width * @rsvp_next_seq: sequence number for next reservation for debugging purposes * @rm_lock: resource manager mutex */ struct sde_rm { struct drm_device *dev; Loading @@ -80,6 +81,7 @@ struct sde_rm { struct sde_hw_mdp *hw_mdp; uint32_t lm_max_width; uint32_t rsvp_next_seq; struct mutex rm_lock; }; /** Loading