diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index ddd6b1f14d..561a0baa51 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -5249,6 +5249,7 @@ static int _sde_hardware_post_caps(struct sde_mdss_cfg *sde_cfg, sde_cfg->min_display_height = MIN_DISPLAY_HEIGHT; sde_cfg->min_display_width = MIN_DISPLAY_WIDTH; + sde_cfg->max_cwb = min_t(u32, sde_cfg->wb_count, MAX_CWB_SESSIONS); rc = _sde_hw_dnsc_blur_filter_caps(sde_cfg); diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index 63432cbb01..a261480570 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -106,6 +106,7 @@ #define MAX_XIN_COUNT 16 #define SSPP_SUBBLK_COUNT_MAX 2 +#define MAX_CWB_SESSIONS 1 #define SDE_CTL_CFG_VERSION_1_0_0 0x100 #define MAX_INTF_PER_CTL_V1 2 @@ -1806,6 +1807,7 @@ struct sde_perf_cfg { * @max_dsc_width max dsc line width * @max_mixer_width max layer mixer line width * @max_mixer_blendstages max layer mixer blend stages (z orders) + * @max_cwb max number of cwb supported * @vbif_qos_nlvl number of vbif QoS priority levels * @qos_target_time_ns normalized qos target time for line-based qos * @macrotile_mode UBWC parameter for macro tile channel distribution @@ -1915,6 +1917,7 @@ struct sde_mdss_cfg { u32 max_dsc_width; u32 max_mixer_width; u32 max_mixer_blendstages; + u32 max_cwb; /* Configs */ u32 vbif_qos_nlvl; diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index b585376096..302aea6e48 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -2968,7 +2968,6 @@ static int sde_kms_check_vm_request(struct msm_kms *kms, return rc; } - static int sde_kms_check_secure_transition(struct msm_kms *kms, struct drm_atomic_state *state) { @@ -3083,6 +3082,44 @@ static void sde_kms_vm_res_release(struct msm_kms *kms, sde_vm_unlock(sde_kms); } +static int sde_kms_check_cwb_concurreny(struct msm_kms *kms, + struct drm_atomic_state *state) +{ + struct sde_kms *sde_kms; + struct drm_crtc *crtc; + struct drm_crtc_state *old_crtc_state, *new_crtc_state; + struct drm_encoder *encoder; + struct sde_crtc_state *cstate; + int i = 0, cnt = 0, max_cwb = 0; + + if (!kms || !state) { + SDE_ERROR("invalid arguments\n"); + return -EINVAL; + } + + sde_kms = to_sde_kms(kms); + max_cwb = sde_kms->catalog->max_cwb; + if (!max_cwb) + return 0; + + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + cstate = to_sde_crtc_state(new_crtc_state); + drm_for_each_encoder_mask(encoder, crtc->dev, cstate->cwb_enc_mask) { + cnt++; + SDE_DEBUG("crtc%d has cwb%d attached to it\n", crtc->base.id, + encoder->base.id); + } + + if (cnt > max_cwb) { + SDE_ERROR("found %d cwb in the atomic state, max supported %d\n", + cnt, max_cwb); + return -EOPNOTSUPP; + } + } + + return 0; +} + static int sde_kms_atomic_check(struct msm_kms *kms, struct drm_atomic_state *state) { @@ -3123,6 +3160,11 @@ static int sde_kms_atomic_check(struct msm_kms *kms, if (ret) goto vm_clean_up; + + ret = sde_kms_check_cwb_concurreny(kms, state); + if (ret) + goto vm_clean_up; + goto end; vm_clean_up: