From 8b8fbfbeef7eac8ab954588131e170c546463cdf Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Thu, 23 May 2019 10:53:12 -0700 Subject: [PATCH] disp: msm: sde: fix rm/kms for handling all cont-splash cases Fix resource and splash buffer handling in resource manager and sde_kms to support continuous splash to be enabled/disabled independently in multiple built-in display usecase. Change-Id: I446ea9b08a794e2b053c37f55b31e51404bbcf71 Signed-off-by: Veera Sundaram Sankaran --- msm/sde/sde_encoder.c | 3 -- msm/sde/sde_encoder_phys.h | 2 -- msm/sde/sde_hw_mdss.h | 2 -- msm/sde/sde_kms.c | 71 +++++++++++++++++++++----------------- msm/sde/sde_rm.c | 23 ++---------- 5 files changed, 42 insertions(+), 59 deletions(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 9f18b09830..c8cf0ddbf2 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -3294,7 +3294,6 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) for (i = 0; i < sde_enc->num_phys_encs; i++) { if (sde_enc->phys_encs[i]) { sde_enc->phys_encs[i]->cont_splash_enabled = false; - sde_enc->phys_encs[i]->cont_splash_single_flush = 0; sde_enc->phys_encs[i]->connector = NULL; } } @@ -5854,8 +5853,6 @@ int sde_encoder_update_caps_for_cont_splash(struct drm_encoder *encoder, /* update connector for master and slave phys encoders */ phys->connector = conn; phys->cont_splash_enabled = true; - phys->cont_splash_single_flush = - splash_display->single_flush_en; phys->hw_pp = sde_enc->hw_pp[i]; if (phys->ops.cont_splash_mode_set) diff --git a/msm/sde/sde_encoder_phys.h b/msm/sde/sde_encoder_phys.h index e43eefc6f9..1ec83ae89e 100644 --- a/msm/sde/sde_encoder_phys.h +++ b/msm/sde/sde_encoder_phys.h @@ -281,7 +281,6 @@ struct sde_encoder_irq { * @pending_kickoff_wq: Wait queue for blocking until kickoff completes * @irq: IRQ tracking structures * @has_intf_te: Interface TE configuration support - * @cont_splash_single_flush Variable to check if single flush is enabled. * @cont_splash_enabled: Variable to store continuous splash settings. * @in_clone_mode Indicates if encoder is in clone mode ref@CWB * @vfp_cached: cached vertical front porch to be used for @@ -324,7 +323,6 @@ struct sde_encoder_phys { wait_queue_head_t pending_kickoff_wq; struct sde_encoder_irq irq[INTR_IDX_MAX]; bool has_intf_te; - u32 cont_splash_single_flush; bool cont_splash_enabled; bool in_clone_mode; int vfp_cached; diff --git a/msm/sde/sde_hw_mdss.h b/msm/sde/sde_hw_mdss.h index 4694e1abc3..d4f52f2ba0 100644 --- a/msm/sde/sde_hw_mdss.h +++ b/msm/sde/sde_hw_mdss.h @@ -591,7 +591,6 @@ struct sde_sspp_index_info { * struct sde_splash_data - Struct contains details of resources and hw blocks * used in continuous splash on a specific display. * @cont_splash_enabled: Stores the cont_splash status (enabled/disabled) - * @single_flush_en: Stores if the single flush is enabled * @encoder: Pointer to the drm encoder object used for this display * @splash: Pointer to struct sde_splash_mem used for this display * @ctl_ids: Stores the valid MDSS ctl block ids for the current mode @@ -605,7 +604,6 @@ struct sde_sspp_index_info { */ struct sde_splash_display { bool cont_splash_enabled; - bool single_flush_en; struct drm_encoder *encoder; struct sde_splash_mem *splash; u8 ctl_ids[MAX_DATA_PATH_PER_DSIPLAY]; diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 019308404d..773b9503da 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -735,21 +735,15 @@ static int _sde_kms_splash_mem_put(struct sde_kms *sde_kms, struct msm_mmu *mmu = NULL; int rc = 0; - if (!sde_kms) - return -EINVAL; - - if (!sde_kms->aspace[0]) { - SDE_ERROR("aspace not found for sde kms node\n"); + if (!sde_kms || !sde_kms->aspace[0] || !sde_kms->aspace[0]->mmu) { + SDE_ERROR("invalid params\n"); return -EINVAL; } mmu = sde_kms->aspace[0]->mmu; - if (!mmu) { - SDE_ERROR("mmu not found for aspace\n"); - return -EINVAL; - } - if (!splash || !mmu->funcs || !mmu->funcs->one_to_one_unmap) + if (!splash || !splash->ref_cnt || + !mmu || !mmu->funcs || !mmu->funcs->one_to_one_unmap) return -EINVAL; splash->ref_cnt--; @@ -869,6 +863,20 @@ static void sde_kms_commit(struct msm_kms *kms, SDE_ATRACE_END("sde_kms_commit"); } +static void _sde_kms_free_splash_region(struct sde_kms *sde_kms, + struct sde_splash_display *splash_display) +{ + if (!sde_kms || !splash_display || + !sde_kms->splash_data.num_splash_displays) + return; + + _sde_kms_splash_mem_put(sde_kms, splash_display->splash); + sde_kms->splash_data.num_splash_displays--; + SDE_DEBUG("cont_splash handoff done, remaining:%d\n", + sde_kms->splash_data.num_splash_displays); + memset(splash_display, 0x0, sizeof(struct sde_splash_display)); +} + static void _sde_kms_release_splash_resource(struct sde_kms *sde_kms, struct drm_crtc *crtc) { @@ -897,16 +905,10 @@ static void _sde_kms_release_splash_resource(struct sde_kms *sde_kms, if (i >= MAX_DSI_DISPLAYS) return; - _sde_kms_splash_mem_put(sde_kms, splash_display->splash); - if (splash_display->cont_splash_enabled) { sde_encoder_update_caps_for_cont_splash(splash_display->encoder, splash_display, false); - splash_display->cont_splash_enabled = false; - sde_kms->splash_data.num_splash_displays--; - SDE_DEBUG("cont_splash handoff done for dpy:%d remaining:%d\n", - i, sde_kms->splash_data.num_splash_displays); - memset(splash_display, 0x0, sizeof(struct sde_splash_display)); + _sde_kms_free_splash_region(sde_kms, splash_display); } /* remove the votes if all displays are done with splash */ @@ -2314,13 +2316,9 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms) return rc; } - if (sde_kms->dsi_display_count != - sde_kms->splash_data.num_splash_displays) { - SDE_ERROR("mismatch - displays:%d vs splash-displays:%d\n", - sde_kms->dsi_display_count, - sde_kms->splash_data.num_splash_displays); - return rc; - } + DRM_INFO("cont_splash enabled in %d of %d display(s)\n", + sde_kms->splash_data.num_splash_displays, + sde_kms->dsi_display_count); /* dsi */ for (i = 0; i < sde_kms->dsi_display_count; ++i) { @@ -3205,14 +3203,23 @@ static int _sde_kms_hw_init_blocks(struct sde_kms *sde_kms, * splash memory is found & release resources on any error * in finding display hw config in splash */ - if (sde_kms->splash_data.num_splash_regions && - sde_rm_cont_splash_res_init(priv, &sde_kms->rm, - &sde_kms->splash_data, - sde_kms->catalog)) { - SDE_DEBUG("freeing continuous splash resources\n"); - _sde_kms_unmap_all_splash_regions(sde_kms); - memset(&sde_kms->splash_data, 0x0, - sizeof(struct sde_splash_data)); + if (sde_kms->splash_data.num_splash_regions) { + struct sde_splash_display *display; + int ret, display_count = + sde_kms->splash_data.num_splash_displays; + + ret = sde_rm_cont_splash_res_init(priv, &sde_kms->rm, + &sde_kms->splash_data, sde_kms->catalog); + + for (i = 0; i < display_count; i++) { + display = &sde_kms->splash_data.splash_display[i]; + /* + * free splash region on resource init failure and + * cont-splash disabled case + */ + if (!display->cont_splash_enabled || ret) + _sde_kms_free_splash_region(sde_kms, display); + } } sde_kms->hw_mdp = sde_rm_get_mdp(&sde_kms->rm); diff --git a/msm/sde/sde_rm.c b/msm/sde/sde_rm.c index 91fadd197a..7125f9aa14 100644 --- a/msm/sde/sde_rm.c +++ b/msm/sde/sde_rm.c @@ -1467,7 +1467,8 @@ int sde_rm_cont_splash_res_init(struct msm_drm_private *priv, hw_mdp = sde_rm_get_mdp(rm); sde_rm_init_hw_iter(&iter_c, 0, SDE_HW_BLK_CTL); - while (_sde_rm_get_hw_locked(rm, &iter_c)) { + while (_sde_rm_get_hw_locked(rm, &iter_c) + && (index < splash_data->num_splash_displays)) { struct sde_hw_ctl *ctl = to_sde_hw_ctl(iter_c.blk->hw); if (!ctl->ops.get_ctl_intf) { @@ -1486,26 +1487,8 @@ int sde_rm_cont_splash_res_init(struct msm_drm_private *priv, splash_display->cont_splash_enabled = true; splash_display->ctl_ids[splash_display->ctl_cnt++] = iter_c.blk->id; - - if (hw_mdp && hw_mdp->ops.get_split_flush_status) { - splash_display->single_flush_en = - hw_mdp->ops.get_split_flush_status( - hw_mdp); - } - - if (!splash_display->single_flush_en || - (iter_c.blk->id != CTL_0)) - index++; - - if (index >= ARRAY_SIZE(splash_data->splash_display)) - break; } - } - - if (index != splash_data->num_splash_displays) { - SDE_DEBUG("mismatch active displays vs actually enabled :%d/%d", - splash_data->num_splash_displays, index); - return -EINVAL; + index++; } return 0;