diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 16ca653405..fbee58b6b5 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -342,6 +342,15 @@ bool sde_encoder_is_primary_display(struct drm_encoder *drm_enc) SDE_CONNECTOR_PRIMARY); } +bool sde_encoder_is_built_in_display(struct drm_encoder *drm_enc) +{ + struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); + + return sde_enc && + (sde_enc->disp_info.display_type == SDE_CONNECTOR_PRIMARY || + sde_enc->disp_info.display_type == SDE_CONNECTOR_SECONDARY); +} + bool sde_encoder_is_dsi_display(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); diff --git a/msm/sde/sde_encoder.h b/msm/sde/sde_encoder.h index 6c7604a837..eaf1eb24c7 100644 --- a/msm/sde/sde_encoder.h +++ b/msm/sde/sde_encoder.h @@ -512,15 +512,23 @@ bool sde_encoder_is_cwb_disabling(struct drm_encoder *drm_enc, * sde_encoder_is_primary_display - checks if underlying display is primary * display or not. * @drm_enc: Pointer to drm encoder structure - * @Return: true if it is primary display. false if secondary display + * @Return: true if it is primary display. false otherwise */ bool sde_encoder_is_primary_display(struct drm_encoder *enc); +/** + * sde_encoder_is_built_in_display - checks if underlying display is built in + * display or not. + * @drm_enc: Pointer to drm encoder structure + * @Return: true if it is a built in display. false otherwise + */ +bool sde_encoder_is_built_in_display(struct drm_encoder *enc); + /** * sde_encoder_is_dsi_display - checks if underlying display is DSI * display or not. * @drm_enc: Pointer to drm encoder structure - * @Return: true if it is primary display. false if secondary display + * @Return: true if it is a dsi display. false otherwise */ bool sde_encoder_is_dsi_display(struct drm_encoder *enc); diff --git a/msm/sde/sde_rm.c b/msm/sde/sde_rm.c index 07dab42016..a594ca30f0 100644 --- a/msm/sde/sde_rm.c +++ b/msm/sde/sde_rm.c @@ -277,19 +277,40 @@ void sde_rm_get_resource_info(struct sde_rm *rm, struct sde_rm_hw_blk *blk; enum sde_hw_blk_type type; struct sde_rm_rsvp rsvp; + const struct sde_lm_cfg *lm_cfg; + bool is_built_in, is_pref; + u32 lm_pref = (BIT(SDE_DISP_PRIMARY_PREF) | BIT(SDE_DISP_SECONDARY_PREF)); + /* Get all currently available resources */ memcpy(avail_res, &rm->avail_res, sizeof(rm->avail_res)); if (!drm_enc) return; + is_built_in = sde_encoder_is_built_in_display(drm_enc); + 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) + for (type = 0; type < SDE_HW_BLK_MAX; type++) { + list_for_each_entry(blk, &rm->hw_blks[type], list) { + /* Add back resources allocated to the given encoder */ if (blk->rsvp && blk->rsvp->enc_id == rsvp.enc_id) _sde_rm_inc_resource_info(rm, avail_res, blk); + + /** + * Remove unallocated preferred lms that cannot reserved + * by non built-in displays. + */ + if (type == SDE_HW_BLK_LM) { + lm_cfg = to_sde_hw_mixer(blk->hw)->cap; + is_pref = lm_cfg->features & lm_pref; + + if (!blk->rsvp && !is_built_in && is_pref) + _sde_rm_dec_resource_info(rm, avail_res, blk); + } + } + } } static void _sde_rm_print_rsvps(