diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index d4d5a00671..e2e7c6e392 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -3334,7 +3334,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; } } @@ -5903,8 +5902,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 93e925073b..a670e4ab51 100644 --- a/msm/sde/sde_encoder_phys.h +++ b/msm/sde/sde_encoder_phys.h @@ -282,7 +282,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 @@ -326,7 +325,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 6ff1e7b9b2..4871d9ad5b 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -739,21 +739,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--; @@ -873,6 +867,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) { @@ -901,16 +909,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 */ @@ -2318,13 +2320,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) { @@ -3209,14 +3207,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 aa2db48efd..1b1ef3cc04 100644 --- a/msm/sde/sde_rm.c +++ b/msm/sde/sde_rm.c @@ -1526,7 +1526,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) { @@ -1545,26 +1546,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;