From d3d3f808d4b527acd72f8bdc6fee8407d3a67af5 Mon Sep 17 00:00:00 2001 From: Abhijit Kulkarni Date: Fri, 14 Jun 2019 10:26:15 -0700 Subject: [PATCH] disp: msm: sde: use pp dsc api only if hw supports This change checks the capabilities of pingpong block to check if it needs to call the pingpong api to enable or disable the dsc. Certain hw versions do not have support in pingpong block to enable/disable the dsc instead the dsc block itself have the hooks to control the DSC. Change-Id: I17dd45479cc33ff2e81f6a6e5a5a8704562dfd24 Signed-off-by: Abhijit Kulkarni --- msm/sde/sde_encoder.c | 13 ++++++++++--- msm/sde/sde_encoder_dce.c | 12 ++++++------ msm/sde/sde_hw_catalog.c | 20 ++++++++++++-------- msm/sde/sde_hw_pingpong.c | 19 ++++++++++++++----- msm/sde/sde_hw_pingpong.h | 6 ++++++ 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 1e1559dc..78b2d5ce 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -2161,7 +2161,9 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, /* Get PP for DSC configuration */ for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { - sde_enc->hw_dsc_pp[i] = NULL; + struct sde_hw_pingpong *pp = NULL; + unsigned long features = 0; + if (!sde_enc->hw_dsc[i]) continue; @@ -2169,8 +2171,13 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, request_hw.type = SDE_HW_BLK_PINGPONG; if (!sde_rm_request_hw_blk(&sde_kms->rm, &request_hw)) break; - sde_enc->hw_dsc_pp[i] = - (struct sde_hw_pingpong *) request_hw.hw; + pp = (struct sde_hw_pingpong *) request_hw.hw; + features = pp->ops.get_hw_caps(pp); + + if (test_bit(SDE_PINGPONG_DSC, &features)) + sde_enc->hw_dsc_pp[i] = pp; + else + sde_enc->hw_dsc_pp[i] = NULL; } for (i = 0; i < sde_enc->num_phys_encs; i++) { diff --git a/msm/sde/sde_encoder_dce.c b/msm/sde/sde_encoder_dce.c index 7ce71e34..9e481877 100644 --- a/msm/sde/sde_encoder_dce.c +++ b/msm/sde/sde_encoder_dce.c @@ -188,9 +188,9 @@ static void _dce_dsc_pipe_cfg(struct sde_hw_dsc *hw_dsc, return; } - if (!dsc || !hw_dsc || !hw_pp || !hw_dsc_pp) { - SDE_ERROR("invalid params %d %d %d %d\n", !dsc, !hw_dsc, - !hw_pp, !hw_dsc_pp); + if (!dsc || !hw_dsc || !hw_pp) { + SDE_ERROR("invalid params %d %d %d\n", !dsc, !hw_dsc, + !hw_pp); return; } @@ -200,13 +200,13 @@ static void _dce_dsc_pipe_cfg(struct sde_hw_dsc *hw_dsc, if (hw_dsc->ops.dsc_config_thresh) hw_dsc->ops.dsc_config_thresh(hw_dsc, dsc); - if (hw_dsc_pp->ops.setup_dsc) + if (hw_dsc_pp && hw_dsc_pp->ops.setup_dsc) hw_dsc_pp->ops.setup_dsc(hw_dsc_pp); if (hw_dsc->ops.bind_pingpong_blk) hw_dsc->ops.bind_pingpong_blk(hw_dsc, true, hw_pp->idx); - if (hw_dsc_pp->ops.enable_dsc) + if (hw_dsc_pp && hw_dsc_pp->ops.enable_dsc) hw_dsc_pp->ops.enable_dsc(hw_dsc_pp); } @@ -335,7 +335,7 @@ static int _dce_dsc_setup(struct sde_encoder_virt *sde_enc, hw_dsc[i] = sde_enc->hw_dsc[i]; hw_dsc_pp[i] = sde_enc->hw_dsc_pp[i]; - if (!hw_pp[i] || !hw_dsc[i] || !hw_dsc_pp[i]) { + if (!hw_pp[i] || !hw_dsc[i]) { SDE_ERROR_DCE(sde_enc, "invalid params for DSC\n"); SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, dsc_common_mode, i, active); diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 93426953..60ba1ba2 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -3181,6 +3181,7 @@ static int sde_pp_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) if (rc) goto end; + major_version = SDE_HW_MAJOR(sde_cfg->hwversion); for (i = 0; i < off_count; i++) { pp = sde_cfg->pingpong + i; sblk = kzalloc(sizeof(*sblk), GFP_KERNEL); @@ -3202,7 +3203,6 @@ static int sde_pp_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) snprintf(sblk->te.name, SDE_HW_BLK_NAME_LEN, "te_%u", pp->id - PINGPONG_0); - major_version = SDE_HW_MAJOR(sde_cfg->hwversion); if (major_version < SDE_HW_MAJOR(SDE_HW_VER_500)) set_bit(SDE_PINGPONG_TE, &pp->features); @@ -3218,16 +3218,20 @@ static int sde_pp_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) if (PROP_VALUE_ACCESS(prop_value, PP_SLAVE, i)) set_bit(SDE_PINGPONG_SLAVE, &pp->features); - sblk->dsc.base = PROP_VALUE_ACCESS(prop_value, DSC_OFF, i); - if (sblk->dsc.base) { - sblk->dsc.id = SDE_PINGPONG_DSC; - snprintf(sblk->dsc.name, SDE_HW_BLK_NAME_LEN, "dsc_%u", - pp->id - PINGPONG_0); - set_bit(SDE_PINGPONG_DSC, &pp->features); + if (major_version < SDE_HW_MAJOR(SDE_HW_VER_700)) { + sblk->dsc.base = PROP_VALUE_ACCESS(prop_value, + DSC_OFF, i); + if (sblk->dsc.base) { + sblk->dsc.id = SDE_PINGPONG_DSC; + snprintf(sblk->dsc.name, SDE_HW_BLK_NAME_LEN, + "dsc_%u", + pp->id - PINGPONG_0); + set_bit(SDE_PINGPONG_DSC, &pp->features); + } } sblk->dither.base = PROP_VALUE_ACCESS(prop_value, DITHER_OFF, - i); + i); if (sblk->dither.base) { sblk->dither.id = SDE_PINGPONG_DITHER; snprintf(sblk->dither.name, SDE_HW_BLK_NAME_LEN, diff --git a/msm/sde/sde_hw_pingpong.c b/msm/sde/sde_hw_pingpong.c index e7f92eaf..d49a7895 100644 --- a/msm/sde/sde_hw_pingpong.c +++ b/msm/sde/sde_hw_pingpong.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 @@ -459,11 +459,18 @@ static void sde_hw_pp_reset_3d_merge_mode(struct sde_hw_pingpong *pp) if (pp->merge_3d && pp->merge_3d->ops.reset_blend_mode) pp->merge_3d->ops.reset_blend_mode(pp->merge_3d); } + +static unsigned long sde_hw_pp_get_caps(struct sde_hw_pingpong *pp) +{ + return !pp ? 0 : pp->caps->features; +} + static void _setup_pingpong_ops(struct sde_hw_pingpong_ops *ops, const struct sde_pingpong_cfg *hw_cap) { u32 version = 0; + ops->get_hw_caps = sde_hw_pp_get_caps; if (hw_cap->features & BIT(SDE_PINGPONG_TE)) { ops->setup_tearcheck = sde_hw_pp_setup_te_config; ops->enable_tearcheck = sde_hw_pp_enable_te; @@ -475,10 +482,12 @@ static void _setup_pingpong_ops(struct sde_hw_pingpong_ops *ops, ops->poll_timeout_wr_ptr = sde_hw_pp_poll_timeout_wr_ptr; ops->get_line_count = sde_hw_pp_get_line_count; } - ops->setup_dsc = sde_hw_pp_setup_dsc; - ops->enable_dsc = sde_hw_pp_dsc_enable; - ops->disable_dsc = sde_hw_pp_dsc_disable; - ops->get_dsc_status = sde_hw_pp_get_dsc_status; + if (hw_cap->features & BIT(SDE_PINGPONG_DSC)) { + ops->setup_dsc = sde_hw_pp_setup_dsc; + ops->enable_dsc = sde_hw_pp_dsc_enable; + ops->disable_dsc = sde_hw_pp_dsc_disable; + ops->get_dsc_status = sde_hw_pp_get_dsc_status; + } version = SDE_COLOR_PROCESS_MAJOR(hw_cap->sblk->dither.version); switch (version) { diff --git a/msm/sde/sde_hw_pingpong.h b/msm/sde/sde_hw_pingpong.h index 32866708..91760432 100644 --- a/msm/sde/sde_hw_pingpong.h +++ b/msm/sde/sde_hw_pingpong.h @@ -32,6 +32,7 @@ struct sde_hw_dsc_cfg { * @disable_dsc : disables DSC encoder * @setup_dither : function to program the dither hw block * @get_line_count: obtain current vertical line counter + * @get_hw_caps: returns features supported by this pp block */ struct sde_hw_pingpong_ops { /** @@ -126,6 +127,11 @@ struct sde_hw_pingpong_ops { * reset 3d blend configuration */ void (*reset_3d_mode)(struct sde_hw_pingpong *pp); + + /** + * get PP features supported by this instance + */ + unsigned long (*get_hw_caps)(struct sde_hw_pingpong *pp); }; struct sde_hw_merge_3d_ops {