From e99063c7a380635ff794dad5a0bbe29956e14811 Mon Sep 17 00:00:00 2001 From: Krishna Manikandan Date: Fri, 29 Nov 2019 14:36:49 +0530 Subject: [PATCH] disp: msm: stage layer with zorder 0 as base layer Add support to stage layer with zorder 0 as base layer and stage borderfill only during null commit. Change-Id: I54356c1b7834227cc3da00c211e71ac5816ce51a Signed-off-by: Krishna Manikandan --- msm/sde/sde_crtc.c | 32 ++++++++++++++++++++++++++------ msm/sde/sde_hw_catalog.c | 3 +++ msm/sde/sde_hw_catalog.h | 2 ++ msm/sde/sde_hw_ctl.c | 6 ++++-- msm/sde/sde_hw_lm.c | 5 ++++- msm/sde/sde_plane.c | 5 ++++- 6 files changed, 43 insertions(+), 10 deletions(-) diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index d66b02abf5ca..e2ef6908ea4a 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -2479,7 +2479,7 @@ static void _sde_crtc_set_dim_layer_v1(struct sde_crtc_state *cstate, user_cfg = &dim_layer_v1.layer_cfg[i]; dim_layer[i].flags = user_cfg->flags; - dim_layer[i].stage = user_cfg->stage + SDE_STAGE_0; + dim_layer[i].stage = user_cfg->stage; dim_layer[i].rect.x = user_cfg->rect.x1; dim_layer[i].rect.y = user_cfg->rect.y1; @@ -4122,7 +4122,7 @@ static void sde_crtc_enable(struct drm_crtc *crtc, /* no input validation - caller API has all the checks */ static int _sde_crtc_excl_dim_layer_check(struct drm_crtc_state *state, - struct plane_state pstates[], int cnt) + struct plane_state pstates[], int cnt, bool base_layer_staged) { struct sde_crtc_state *cstate = to_sde_crtc_state(state); struct drm_display_mode *mode = &state->adjusted_mode; @@ -4149,6 +4149,8 @@ static int _sde_crtc_excl_dim_layer_check(struct drm_crtc_state *state, mode->vdisplay); rc = -E2BIG; goto end; + } else if (!base_layer_staged) { + cstate->dim_layer[i].stage += SDE_STAGE_0; } } @@ -4241,9 +4243,12 @@ static int _sde_crtc_check_secure_blend_config(struct drm_crtc *crtc, int sec_stage = cnt ? pstates[0].sde_pstate->stage : cstate->dim_layer[0].stage; + if (!sde_kms->catalog->has_base_layer) + sec_stage -= SDE_STAGE_0; + if ((!cnt && !cstate->num_dim_layers) || (sde_kms->catalog->sui_supported_blendstage - != (sec_stage - SDE_STAGE_0))) { + != sec_stage)) { SDE_ERROR( "crtc%d: empty cnt%d/dim%d or bad stage%d\n", DRMID(crtc), cnt, @@ -4429,7 +4434,7 @@ static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc, /* check dim layer stage with every plane */ for (i = 0; i < cstate->num_dim_layers; i++) { if (cstate->dim_layer[i].stage == - (pstates[*cnt].stage + SDE_STAGE_0)) { + pstates[*cnt].stage) { SDE_ERROR( "plane:%d/dim_layer:%i-same stage:%d\n", plane->base.id, i, @@ -4505,10 +4510,21 @@ static int _sde_crtc_check_zpos(struct drm_crtc_state *state, { int rc = 0, i, z_pos; u32 zpos_cnt = 0; + struct drm_crtc *crtc; + struct sde_kms *kms; + + crtc = &sde_crtc->base; + kms = _sde_crtc_get_kms(crtc); + + if (!kms || !kms->catalog) { + SDE_ERROR("Invalid kms\n"); + return -EINVAL; + } sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL); - rc = _sde_crtc_excl_dim_layer_check(state, pstates, cnt); + rc = _sde_crtc_excl_dim_layer_check(state, pstates, cnt, + kms->catalog->has_base_layer); if (rc) return rc; @@ -4544,7 +4560,11 @@ static int _sde_crtc_check_zpos(struct drm_crtc_state *state, zpos_cnt++; } - pstates[i].sde_pstate->stage = z_pos + SDE_STAGE_0; + if (!kms->catalog->has_base_layer) + pstates[i].sde_pstate->stage = z_pos + SDE_STAGE_0; + else + pstates[i].sde_pstate->stage = z_pos; + SDE_DEBUG("%s: zpos %d", sde_crtc->name, z_pos); } return rc; diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index f7e2b6b4559e..c4961537f562 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -194,6 +194,7 @@ enum sde_prop { PIPE_ORDER_VERSION, SEC_SID_MASK, SDE_LIMITS, + BASE_LAYER, SDE_PROP_MAX, }; @@ -547,6 +548,7 @@ static struct sde_prop_type sde_prop[] = { PROP_TYPE_U32}, {SEC_SID_MASK, "qcom,sde-secure-sid-mask", false, PROP_TYPE_U32_ARRAY}, {SDE_LIMITS, "qcom,sde-limits", false, PROP_TYPE_NODE}, + {BASE_LAYER, "qcom,sde-mixer-stage-base-layer", false, PROP_TYPE_BOOL}, }; static struct sde_prop_type sde_perf_prop[] = { @@ -3854,6 +3856,7 @@ static int sde_top_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) cfg->has_idle_pc = PROP_VALUE_ACCESS(prop_value, IDLE_PC, 0); cfg->pipe_order_type = PROP_VALUE_ACCESS(prop_value, PIPE_ORDER_VERSION, 0); + cfg->has_base_layer = PROP_VALUE_ACCESS(prop_value, BASE_LAYER, 0); rc = sde_limit_parse_dt(np, cfg); if (rc) diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index 63ac8caea907..db0418c85e13 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -1417,6 +1417,7 @@ struct sde_limit_cfg { * @vbif_disable_inner_outer_shareable VBIF requires disabling shareables * @inline_disable_const_clr Disable constant color during inline rotate * @dither_luma_mode_support Enables dither luma mode + * @has_base_layer Supports staging layer as base layer * @sc_cfg: system cache configuration * @uidle_cfg Settings for uidle feature * @sui_misr_supported indicate if secure-ui-misr is supported @@ -1478,6 +1479,7 @@ struct sde_mdss_cfg { bool vbif_disable_inner_outer_shareable; bool inline_disable_const_clr; bool dither_luma_mode_support; + bool has_base_layer; struct sde_sc_cfg sc_cfg; diff --git a/msm/sde/sde_hw_ctl.c b/msm/sde/sde_hw_ctl.c index e8022ba3d276..27b43a1a9165 100644 --- a/msm/sde/sde_hw_ctl.c +++ b/msm/sde/sde_hw_ctl.c @@ -830,8 +830,6 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, else pipes_per_stage = 1; - mixercfg = CTL_MIXER_BORDER_OUT; /* always set BORDER_OUT */ - if (!stage_cfg) goto exit; @@ -942,6 +940,10 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, } exit: + if ((!mixercfg && !mixercfg_ext && !mixercfg_ext2 && !mixercfg_ext3) || + (stage_cfg && !stage_cfg->stage[0][0])) + mixercfg |= CTL_MIXER_BORDER_OUT; + SDE_REG_WRITE(c, CTL_LAYER(lm), mixercfg); SDE_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg_ext); SDE_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg_ext2); diff --git a/msm/sde/sde_hw_lm.c b/msm/sde/sde_hw_lm.c index fdae00b3ec03..240b4c4938e9 100644 --- a/msm/sde/sde_hw_lm.c +++ b/msm/sde/sde_hw_lm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include @@ -197,6 +197,9 @@ static void sde_hw_lm_setup_dim_layer(struct sde_hw_mixer *ctx, int stage_off; u32 val = 0, alpha = 0; + if (dim_layer->stage == SDE_STAGE_BASE) + return; + stage_off = _stage_offset(ctx, dim_layer->stage); if (stage_off < 0) { SDE_ERROR("invalid stage_off:%d for dim layer\n", stage_off); diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 03955979cec6..50845af5bc96 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -3464,7 +3464,10 @@ static void _sde_plane_install_properties(struct drm_plane *plane, if (catalog->mixer_count && catalog->mixer[0].sblk->maxblendstages) { zpos_max = catalog->mixer[0].sblk->maxblendstages - 1; - if (zpos_max > SDE_STAGE_MAX - SDE_STAGE_0 - 1) + if (catalog->has_base_layer && + (zpos_max > SDE_STAGE_MAX - 1)) + zpos_max = SDE_STAGE_MAX - 1; + else if (zpos_max > SDE_STAGE_MAX - SDE_STAGE_0 - 1) zpos_max = SDE_STAGE_MAX - SDE_STAGE_0 - 1; } } else if (plane->type != DRM_PLANE_TYPE_PRIMARY) {