diff --git a/msm/msm_drv.h b/msm/msm_drv.h index 4286b764f9..7d235538c0 100644 --- a/msm/msm_drv.h +++ b/msm/msm_drv.h @@ -849,6 +849,7 @@ struct msm_mode_info { * @num_ctl number of ctl available * @num_3dmux number of 3d mux available * @max_mixer_width: max width supported by layer mixer + * @merge_3d_mask: bitmap of available 3d mux resource */ struct msm_resource_caps_info { uint32_t num_lm_in_use; @@ -858,6 +859,7 @@ struct msm_resource_caps_info { uint32_t num_ctl; uint32_t num_3dmux; uint32_t max_mixer_width; + unsigned long merge_3d_mask; }; /** diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 436c8d1c86..bae8a8f357 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -2232,7 +2232,7 @@ static int sde_mixer_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_c struct sde_lm_cfg *mixer; struct sde_lm_sub_blks *sblk; int pp_count, dspp_count, ds_count, mixer_count; - u32 pp_idx, dspp_idx, ds_idx; + u32 pp_idx, dspp_idx, ds_idx, merge_3d_idx; u32 mixer_base; struct device_node *snp = NULL; struct sde_dt_props *props, *blend_props, *blocks_props = NULL; @@ -2273,8 +2273,8 @@ static int sde_mixer_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_c goto put_blocks; } - for (i = 0, mixer_count = 0, pp_idx = 0, dspp_idx = 0, - ds_idx = 0; i < off_count; i++) { + for (i = 0, mixer_count = 0, pp_idx = 0, dspp_idx = 0, ds_idx = 0, + merge_3d_idx = 0; i < off_count; i++) { const char *disp_pref = NULL; const char *cwb_pref = NULL; const char *dcwb_pref = NULL; @@ -2348,6 +2348,7 @@ static int sde_mixer_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_c mixer->dspp = dspp_count > 0 ? dspp_idx + DSPP_0 : DSPP_MAX; mixer->ds = ds_count > 0 ? ds_idx + DS_0 : DS_MAX; + mixer->merge_3d = merge_3d_idx + MERGE_3D_0; pp_count--; dspp_count--; ds_count--; @@ -2356,6 +2357,12 @@ static int sde_mixer_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_c ds_idx++; mixer_count++; + /* + * Since each 3dmux is assigned to a pair of LM, + * increment this idx only at even LM counts + */ + if ((mixer_count & 1) == 0) + merge_3d_idx++; sblk->gc.id = SDE_MIXER_GC; if (blocks_props && blocks_props->exists[MIXER_GC_PROP]) { diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index da049a26ac..58eb8d7a8d 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -1348,6 +1348,7 @@ struct sde_sspp_cfg { * @dspp: ID of connected DSPP, DSPP_MAX if unsupported * @pingpong: ID of connected PingPong, PINGPONG_MAX if unsupported * @ds: ID of connected DS, DS_MAX if unsupported + * @merge_3d: ID of connected 3d MUX * @dummy_mixer: identifies dcwb mixer is considered dummy * @lm_pair_mask: Bitmask of LMs that can be controlled by same CTL */ @@ -1357,6 +1358,7 @@ struct sde_lm_cfg { u32 dspp; u32 pingpong; u32 ds; + u32 merge_3d; bool dummy_mixer; unsigned long lm_pair_mask; }; diff --git a/msm/sde/sde_rm.c b/msm/sde/sde_rm.c index cbe5d3ea17..751ccedf97 100644 --- a/msm/sde/sde_rm.c +++ b/msm/sde/sde_rm.c @@ -213,23 +213,23 @@ static void _sde_rm_inc_resource_info_lm(struct sde_rm *rm, 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 the paired lm is free, or is reserved by the same encoder + * set the bit for the 3d mux associated with the lm + * counting these set bits will give an accurate count of available 3dmux */ - if ((!blk2->rsvp || (blk->rsvp && - blk2->rsvp->enc_id == blk->rsvp->enc_id - && lm_cfg->id > lm_cfg2->id)) && + if ((!blk2->rsvp || (blk->rsvp && blk2->rsvp->enc_id == blk->rsvp->enc_id)) && test_bit(lm_cfg->id, &lm_cfg2->lm_pair_mask)) - avail_res->num_3dmux++; + set_bit(lm_cfg->merge_3d, &avail_res->merge_3d_mask); } + + avail_res->num_3dmux = hweight_long(avail_res->merge_3d_mask); } 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; + const struct sde_lm_cfg *lm_cfg; lm_cfg = to_sde_hw_mixer(blk->hw)->cap; @@ -239,14 +239,12 @@ static void _sde_rm_dec_resource_info_lm(struct sde_rm *rm, avail_res->num_lm--; - /* 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--; - } + /* + * Clear the bit for the 3d mux associated with the lm + * counting these set bits will give an accurate count of available 3dmux + */ + clear_bit(lm_cfg->merge_3d, &avail_res->merge_3d_mask); + avail_res->num_3dmux = hweight_long(avail_res->merge_3d_mask); } static void _sde_rm_inc_resource_info(struct sde_rm *rm,