Loading msm/sde/sde_connector.c +8 −0 Original line number Original line Diff line number Diff line Loading @@ -370,6 +370,7 @@ static void sde_connector_get_avail_res_info(struct drm_connector *conn, { { struct msm_drm_private *priv; struct msm_drm_private *priv; struct sde_kms *sde_kms; struct sde_kms *sde_kms; struct drm_encoder *drm_enc = NULL; if (!conn || !conn->dev || !conn->dev->dev_private) if (!conn || !conn->dev || !conn->dev->dev_private) return; return; Loading @@ -380,6 +381,13 @@ static void sde_connector_get_avail_res_info(struct drm_connector *conn, if (!sde_kms) if (!sde_kms) return; return; if (conn->state && conn->state->best_encoder) drm_enc = conn->state->best_encoder; else drm_enc = conn->encoder; sde_rm_get_resource_info(&sde_kms->rm, drm_enc, avail_res); avail_res->max_mixer_width = sde_kms->catalog->max_mixer_width; avail_res->max_mixer_width = sde_kms->catalog->max_mixer_width; } } Loading msm/sde/sde_rm.c +101 −0 Original line number Original line Diff line number Diff line Loading @@ -128,6 +128,101 @@ enum sde_rm_dbg_rsvp_stage { SDE_RM_STAGE_FINAL SDE_RM_STAGE_FINAL }; }; static void _sde_rm_inc_resource_info_lm(struct sde_rm *rm, struct msm_resource_caps_info *avail_res, struct sde_rm_hw_blk *blk) { struct sde_rm_hw_blk *blk2; const struct sde_lm_cfg *lm_cfg, *lm_cfg2; avail_res->num_lm++; lm_cfg = to_sde_hw_mixer(blk->hw)->cap; /* Check for 3d muxes by comparing paired lms */ list_for_each_entry(blk2, &rm->hw_blks[SDE_HW_BLK_LM], list) { lm_cfg2 = to_sde_hw_mixer(blk2->hw)->cap; /* * If lm2 is free, or * lm1 & lm2 reserved by same enc, check mask */ if ((!blk2->rsvp || (blk->rsvp && blk2->rsvp->enc_id == blk->rsvp->enc_id && lm_cfg->id > lm_cfg2->id)) && test_bit(lm_cfg->id, &lm_cfg2->lm_pair_mask)) avail_res->num_3dmux++; } } static void _sde_rm_dec_resource_info_lm(struct sde_rm *rm, struct msm_resource_caps_info *avail_res, struct sde_rm_hw_blk *blk) { struct sde_rm_hw_blk *blk2; const struct sde_lm_cfg *lm_cfg, *lm_cfg2; avail_res->num_lm--; lm_cfg = to_sde_hw_mixer(blk->hw)->cap; /* Check for 3d muxes by comparing paired lms */ list_for_each_entry(blk2, &rm->hw_blks[SDE_HW_BLK_LM], list) { lm_cfg2 = to_sde_hw_mixer(blk2->hw)->cap; /* If lm2 is free and lm1 is now being reserved */ if (!blk2->rsvp && test_bit(lm_cfg->id, &lm_cfg2->lm_pair_mask)) avail_res->num_3dmux--; } } static void _sde_rm_inc_resource_info(struct sde_rm *rm, struct msm_resource_caps_info *avail_res, struct sde_rm_hw_blk *blk) { enum sde_hw_blk_type type = blk->type; if (type == SDE_HW_BLK_LM) _sde_rm_inc_resource_info_lm(rm, avail_res, blk); else if (type == SDE_HW_BLK_CTL) avail_res->num_ctl++; else if (type == SDE_HW_BLK_DSC) avail_res->num_dsc++; } static void _sde_rm_dec_resource_info(struct sde_rm *rm, struct msm_resource_caps_info *avail_res, struct sde_rm_hw_blk *blk) { enum sde_hw_blk_type type = blk->type; if (type == SDE_HW_BLK_LM) _sde_rm_dec_resource_info_lm(rm, avail_res, blk); else if (type == SDE_HW_BLK_CTL) avail_res->num_ctl--; else if (type == SDE_HW_BLK_DSC) avail_res->num_dsc--; } void sde_rm_get_resource_info(struct sde_rm *rm, struct drm_encoder *drm_enc, struct msm_resource_caps_info *avail_res) { struct sde_rm_hw_blk *blk; enum sde_hw_blk_type type; struct sde_rm_rsvp rsvp; memcpy(avail_res, &rm->avail_res, sizeof(rm->avail_res)); if (!drm_enc) return; rsvp.enc_id = drm_enc->base.id; for (type = 0; type < SDE_HW_BLK_MAX; type++) list_for_each_entry(blk, &rm->hw_blks[type], list) if (blk->rsvp && blk->rsvp->enc_id == rsvp.enc_id) _sde_rm_inc_resource_info(rm, avail_res, blk); } static void _sde_rm_print_rsvps( static void _sde_rm_print_rsvps( struct sde_rm *rm, struct sde_rm *rm, enum sde_rm_dbg_rsvp_stage stage) enum sde_rm_dbg_rsvp_stage stage) Loading Loading @@ -469,6 +564,8 @@ static int _sde_rm_hw_blk_create( blk->hw = hw; blk->hw = hw; list_add_tail(&blk->list, &rm->hw_blks[type]); list_add_tail(&blk->list, &rm->hw_blks[type]); _sde_rm_inc_resource_info(rm, &rm->avail_res, blk); return 0; return 0; } } Loading Loading @@ -1770,6 +1867,8 @@ static void _sde_rm_release_rsvp( SDE_DEBUG("rel rsvp %d enc %d %d %d\n", SDE_DEBUG("rel rsvp %d enc %d %d %d\n", rsvp->seq, rsvp->enc_id, rsvp->seq, rsvp->enc_id, blk->type, blk->id); blk->type, blk->id); _sde_rm_inc_resource_info(rm, &rm->avail_res, blk); } } if (blk->rsvp_nxt == rsvp) { if (blk->rsvp_nxt == rsvp) { blk->rsvp_nxt = NULL; blk->rsvp_nxt = NULL; Loading Loading @@ -1858,6 +1957,8 @@ static int _sde_rm_commit_rsvp( if (blk->rsvp_nxt) { if (blk->rsvp_nxt) { blk->rsvp = blk->rsvp_nxt; blk->rsvp = blk->rsvp_nxt; blk->rsvp_nxt = NULL; blk->rsvp_nxt = NULL; _sde_rm_dec_resource_info(rm, &rm->avail_res, blk); } } } } } } Loading msm/sde/sde_rm.h +12 −0 Original line number Original line Diff line number Diff line Loading @@ -101,6 +101,7 @@ struct sde_rm_topology_def { * @lm_max_width: cached layer mixer maximum width * @lm_max_width: cached layer mixer maximum width * @rsvp_next_seq: sequence number for next reservation for debugging purposes * @rsvp_next_seq: sequence number for next reservation for debugging purposes * @rm_lock: resource manager mutex * @rm_lock: resource manager mutex * @avail_res: Pointer with curr available resources */ */ struct sde_rm { struct sde_rm { struct drm_device *dev; struct drm_device *dev; Loading @@ -111,6 +112,7 @@ struct sde_rm { uint32_t rsvp_next_seq; uint32_t rsvp_next_seq; struct mutex rm_lock; struct mutex rm_lock; const struct sde_rm_topology_def *topology_tbl; const struct sde_rm_topology_def *topology_tbl; struct msm_resource_caps_info avail_res; }; }; /** /** Loading Loading @@ -312,4 +314,14 @@ int sde_rm_ext_blk_create_reserve(struct sde_rm *rm, */ */ int sde_rm_ext_blk_destroy(struct sde_rm *rm, int sde_rm_ext_blk_destroy(struct sde_rm *rm, struct drm_encoder *enc); struct drm_encoder *enc); /** * sde_rm_get_resource_info - returns avail hw resource info * @mr: sde rm object * @drm_enc: drm encoder object * @avail_res: out parameter, available resource object */ void sde_rm_get_resource_info(struct sde_rm *rm, struct drm_encoder *drm_enc, struct msm_resource_caps_info *avail_res); #endif /* __SDE_RM_H__ */ #endif /* __SDE_RM_H__ */ Loading
msm/sde/sde_connector.c +8 −0 Original line number Original line Diff line number Diff line Loading @@ -370,6 +370,7 @@ static void sde_connector_get_avail_res_info(struct drm_connector *conn, { { struct msm_drm_private *priv; struct msm_drm_private *priv; struct sde_kms *sde_kms; struct sde_kms *sde_kms; struct drm_encoder *drm_enc = NULL; if (!conn || !conn->dev || !conn->dev->dev_private) if (!conn || !conn->dev || !conn->dev->dev_private) return; return; Loading @@ -380,6 +381,13 @@ static void sde_connector_get_avail_res_info(struct drm_connector *conn, if (!sde_kms) if (!sde_kms) return; return; if (conn->state && conn->state->best_encoder) drm_enc = conn->state->best_encoder; else drm_enc = conn->encoder; sde_rm_get_resource_info(&sde_kms->rm, drm_enc, avail_res); avail_res->max_mixer_width = sde_kms->catalog->max_mixer_width; avail_res->max_mixer_width = sde_kms->catalog->max_mixer_width; } } Loading
msm/sde/sde_rm.c +101 −0 Original line number Original line Diff line number Diff line Loading @@ -128,6 +128,101 @@ enum sde_rm_dbg_rsvp_stage { SDE_RM_STAGE_FINAL SDE_RM_STAGE_FINAL }; }; static void _sde_rm_inc_resource_info_lm(struct sde_rm *rm, struct msm_resource_caps_info *avail_res, struct sde_rm_hw_blk *blk) { struct sde_rm_hw_blk *blk2; const struct sde_lm_cfg *lm_cfg, *lm_cfg2; avail_res->num_lm++; lm_cfg = to_sde_hw_mixer(blk->hw)->cap; /* Check for 3d muxes by comparing paired lms */ list_for_each_entry(blk2, &rm->hw_blks[SDE_HW_BLK_LM], list) { lm_cfg2 = to_sde_hw_mixer(blk2->hw)->cap; /* * If lm2 is free, or * lm1 & lm2 reserved by same enc, check mask */ if ((!blk2->rsvp || (blk->rsvp && blk2->rsvp->enc_id == blk->rsvp->enc_id && lm_cfg->id > lm_cfg2->id)) && test_bit(lm_cfg->id, &lm_cfg2->lm_pair_mask)) avail_res->num_3dmux++; } } static void _sde_rm_dec_resource_info_lm(struct sde_rm *rm, struct msm_resource_caps_info *avail_res, struct sde_rm_hw_blk *blk) { struct sde_rm_hw_blk *blk2; const struct sde_lm_cfg *lm_cfg, *lm_cfg2; avail_res->num_lm--; lm_cfg = to_sde_hw_mixer(blk->hw)->cap; /* Check for 3d muxes by comparing paired lms */ list_for_each_entry(blk2, &rm->hw_blks[SDE_HW_BLK_LM], list) { lm_cfg2 = to_sde_hw_mixer(blk2->hw)->cap; /* If lm2 is free and lm1 is now being reserved */ if (!blk2->rsvp && test_bit(lm_cfg->id, &lm_cfg2->lm_pair_mask)) avail_res->num_3dmux--; } } static void _sde_rm_inc_resource_info(struct sde_rm *rm, struct msm_resource_caps_info *avail_res, struct sde_rm_hw_blk *blk) { enum sde_hw_blk_type type = blk->type; if (type == SDE_HW_BLK_LM) _sde_rm_inc_resource_info_lm(rm, avail_res, blk); else if (type == SDE_HW_BLK_CTL) avail_res->num_ctl++; else if (type == SDE_HW_BLK_DSC) avail_res->num_dsc++; } static void _sde_rm_dec_resource_info(struct sde_rm *rm, struct msm_resource_caps_info *avail_res, struct sde_rm_hw_blk *blk) { enum sde_hw_blk_type type = blk->type; if (type == SDE_HW_BLK_LM) _sde_rm_dec_resource_info_lm(rm, avail_res, blk); else if (type == SDE_HW_BLK_CTL) avail_res->num_ctl--; else if (type == SDE_HW_BLK_DSC) avail_res->num_dsc--; } void sde_rm_get_resource_info(struct sde_rm *rm, struct drm_encoder *drm_enc, struct msm_resource_caps_info *avail_res) { struct sde_rm_hw_blk *blk; enum sde_hw_blk_type type; struct sde_rm_rsvp rsvp; memcpy(avail_res, &rm->avail_res, sizeof(rm->avail_res)); if (!drm_enc) return; rsvp.enc_id = drm_enc->base.id; for (type = 0; type < SDE_HW_BLK_MAX; type++) list_for_each_entry(blk, &rm->hw_blks[type], list) if (blk->rsvp && blk->rsvp->enc_id == rsvp.enc_id) _sde_rm_inc_resource_info(rm, avail_res, blk); } static void _sde_rm_print_rsvps( static void _sde_rm_print_rsvps( struct sde_rm *rm, struct sde_rm *rm, enum sde_rm_dbg_rsvp_stage stage) enum sde_rm_dbg_rsvp_stage stage) Loading Loading @@ -469,6 +564,8 @@ static int _sde_rm_hw_blk_create( blk->hw = hw; blk->hw = hw; list_add_tail(&blk->list, &rm->hw_blks[type]); list_add_tail(&blk->list, &rm->hw_blks[type]); _sde_rm_inc_resource_info(rm, &rm->avail_res, blk); return 0; return 0; } } Loading Loading @@ -1770,6 +1867,8 @@ static void _sde_rm_release_rsvp( SDE_DEBUG("rel rsvp %d enc %d %d %d\n", SDE_DEBUG("rel rsvp %d enc %d %d %d\n", rsvp->seq, rsvp->enc_id, rsvp->seq, rsvp->enc_id, blk->type, blk->id); blk->type, blk->id); _sde_rm_inc_resource_info(rm, &rm->avail_res, blk); } } if (blk->rsvp_nxt == rsvp) { if (blk->rsvp_nxt == rsvp) { blk->rsvp_nxt = NULL; blk->rsvp_nxt = NULL; Loading Loading @@ -1858,6 +1957,8 @@ static int _sde_rm_commit_rsvp( if (blk->rsvp_nxt) { if (blk->rsvp_nxt) { blk->rsvp = blk->rsvp_nxt; blk->rsvp = blk->rsvp_nxt; blk->rsvp_nxt = NULL; blk->rsvp_nxt = NULL; _sde_rm_dec_resource_info(rm, &rm->avail_res, blk); } } } } } } Loading
msm/sde/sde_rm.h +12 −0 Original line number Original line Diff line number Diff line Loading @@ -101,6 +101,7 @@ struct sde_rm_topology_def { * @lm_max_width: cached layer mixer maximum width * @lm_max_width: cached layer mixer maximum width * @rsvp_next_seq: sequence number for next reservation for debugging purposes * @rsvp_next_seq: sequence number for next reservation for debugging purposes * @rm_lock: resource manager mutex * @rm_lock: resource manager mutex * @avail_res: Pointer with curr available resources */ */ struct sde_rm { struct sde_rm { struct drm_device *dev; struct drm_device *dev; Loading @@ -111,6 +112,7 @@ struct sde_rm { uint32_t rsvp_next_seq; uint32_t rsvp_next_seq; struct mutex rm_lock; struct mutex rm_lock; const struct sde_rm_topology_def *topology_tbl; const struct sde_rm_topology_def *topology_tbl; struct msm_resource_caps_info avail_res; }; }; /** /** Loading Loading @@ -312,4 +314,14 @@ int sde_rm_ext_blk_create_reserve(struct sde_rm *rm, */ */ int sde_rm_ext_blk_destroy(struct sde_rm *rm, int sde_rm_ext_blk_destroy(struct sde_rm *rm, struct drm_encoder *enc); struct drm_encoder *enc); /** * sde_rm_get_resource_info - returns avail hw resource info * @mr: sde rm object * @drm_enc: drm encoder object * @avail_res: out parameter, available resource object */ void sde_rm_get_resource_info(struct sde_rm *rm, struct drm_encoder *drm_enc, struct msm_resource_caps_info *avail_res); #endif /* __SDE_RM_H__ */ #endif /* __SDE_RM_H__ */