diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 126ab8456ebf..9741a62a5138 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -371,6 +371,7 @@ static void sde_connector_get_avail_res_info(struct drm_connector *conn, struct msm_drm_private *priv; struct sde_kms *sde_kms; struct drm_encoder *drm_enc = NULL; + struct msm_display_info display_info; if (!conn || !conn->dev || !conn->dev->dev_private) return; @@ -381,12 +382,17 @@ static void sde_connector_get_avail_res_info(struct drm_connector *conn, if (!sde_kms) return; + memset(&display_info, 0, sizeof(display_info)); + 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); + sde_connector_get_info(conn, &display_info); + + sde_rm_get_resource_info(&sde_kms->rm, drm_enc, avail_res, + display_info.display_type); avail_res->max_mixer_width = sde_kms->catalog->max_mixer_width; } diff --git a/msm/sde/sde_rm.c b/msm/sde/sde_rm.c index cc99e40537a5..46fbd2cd3614 100644 --- a/msm/sde/sde_rm.c +++ b/msm/sde/sde_rm.c @@ -203,17 +203,36 @@ static void _sde_rm_dec_resource_info(struct sde_rm *rm, void sde_rm_get_resource_info(struct sde_rm *rm, struct drm_encoder *drm_enc, - struct msm_resource_caps_info *avail_res) + struct msm_resource_caps_info *avail_res, + int display_type) { struct sde_rm_hw_blk *blk; enum sde_hw_blk_type type; struct sde_rm_rsvp rsvp; + const struct sde_lm_cfg *lm_cfg; + mutex_lock(&rm->rm_lock); memcpy(avail_res, &rm->avail_res, sizeof(rm->avail_res)); + /** + * Layer Mixers which are primary display, secondary + * display preferred and are available must not be provided + * for connectors which are neither primary nor secondary. + */ + if (display_type != SDE_CONNECTOR_PRIMARY && + display_type != SDE_CONNECTOR_SECONDARY) { + list_for_each_entry(blk, &rm->hw_blks[SDE_HW_BLK_LM], list) { + lm_cfg = to_sde_hw_mixer(blk->hw)->cap; + if (!blk->rsvp && (lm_cfg->features & + (BIT(SDE_DISP_PRIMARY_PREF) + | BIT(SDE_DISP_SECONDARY_PREF)))) + avail_res->num_lm--; + } + } + if (!drm_enc) - return; + goto end; rsvp.enc_id = drm_enc->base.id; @@ -221,6 +240,9 @@ void sde_rm_get_resource_info(struct sde_rm *rm, 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); +end: + mutex_unlock(&rm->rm_lock); + return; } static void _sde_rm_print_rsvps( diff --git a/msm/sde/sde_rm.h b/msm/sde/sde_rm.h index ea5a0e6a3020..a397b0dc35dc 100644 --- a/msm/sde/sde_rm.h +++ b/msm/sde/sde_rm.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #ifndef __SDE_RM_H__ @@ -323,8 +323,10 @@ int sde_rm_ext_blk_destroy(struct sde_rm *rm, * @mr: sde rm object * @drm_enc: drm encoder object * @avail_res: out parameter, available resource object + * @display_type: type of the display in usage */ void sde_rm_get_resource_info(struct sde_rm *rm, struct drm_encoder *drm_enc, - struct msm_resource_caps_info *avail_res); + struct msm_resource_caps_info *avail_res, + int display_type); #endif /* __SDE_RM_H__ */