diff --git a/msm/sde/sde_color_processing.c b/msm/sde/sde_color_processing.c index 7edf5ebf1f..11ab6d2154 100644 --- a/msm/sde/sde_color_processing.c +++ b/msm/sde/sde_color_processing.c @@ -1291,6 +1291,47 @@ static void _sde_cp_crtc_install_immutable_property(struct drm_crtc *crtc, feature, val); _sde_cp_crtc_attach_property(&prop_attach); } + +static void _sde_cp_crtc_install_bitmask_property(struct drm_crtc *crtc, + char *name, u32 feature, bool immutable, + const struct drm_prop_enum_list *list, u32 enum_sz, + u64 supported_bits) +{ + struct drm_property *prop; + struct sde_cp_node *prop_node = NULL; + struct msm_drm_private *priv; + struct sde_cp_prop_attach prop_attach; + int flags = immutable ? DRM_MODE_PROP_IMMUTABLE : 0; + uint64_t val = 0; + + if (feature >= SDE_CP_CRTC_MAX_FEATURES) { + DRM_ERROR("invalid feature %d max %d\n", feature, + SDE_CP_CRTC_MAX_FEATURES); + return; + } + + prop_node = kzalloc(sizeof(*prop_node), GFP_KERNEL); + if (!prop_node) + return; + + priv = crtc->dev->dev_private; + prop = priv->cp_property[feature]; + + if (!prop) { + prop = drm_property_create_bitmask(crtc->dev, flags, name, list, + enum_sz, supported_bits); + if (!prop) { + DRM_ERROR("property create failed: %s\n", name); + kfree(prop_node); + return; + } + priv->cp_property[feature] = prop; + } + + INIT_PROP_ATTACH(&prop_attach, crtc, prop, prop_node, feature, val); + _sde_cp_crtc_attach_property(&prop_attach); +} + static void _sde_cp_crtc_install_range_property(struct drm_crtc *crtc, char *name, u32 feature, @@ -2184,6 +2225,44 @@ static int _sde_cp_crtc_set_range_prop( return ret; } +void sde_cp_crtc_refresh_status_properties(struct drm_crtc *crtc) +{ + struct sde_crtc *sde_crtc = NULL; + int i = 0; + struct sde_hw_dspp *hw_dspp = NULL; + struct msm_drm_private *priv; + struct drm_property *prop; + u64 val = 0; + + if (!crtc) { + DRM_ERROR("invalid crtc %pKn", crtc); + return; + } + + sde_crtc = to_sde_crtc(crtc); + if (!sde_crtc) { + DRM_ERROR("invalid sde_crtc %pK\n", sde_crtc); + return; + } + + priv = crtc->dev->dev_private; + prop = priv->cp_property[SDE_CP_CRTC_DSPP_DEMURA_BOOT_PLANE]; + if (!prop) + return; + + for (i = 0; i < sde_crtc->num_mixers; i++) { + u32 status = 0; + + hw_dspp = sde_crtc->mixers[i].hw_dspp; + if (hw_dspp && hw_dspp->ops.demura_read_plane_status) { + hw_dspp->ops.demura_read_plane_status(hw_dspp, &status); + if (status != DEM_FETCH_DMA_INVALID) + val |= 1 << status; + } + } + drm_object_property_set_value(&crtc->base, prop, val); +} + int sde_cp_crtc_set_property(struct drm_crtc *crtc, struct drm_crtc_state *state, struct drm_property *property, @@ -3029,6 +3108,10 @@ static void _dspp_demura_install_property(struct drm_crtc *crtc) _sde_cp_crtc_install_range_property(crtc, "SDE_DEMURA_BACKLIGHT_V1", SDE_CP_CRTC_DSPP_DEMURA_BACKLIGHT, 0, 1024, 0); + _sde_cp_crtc_install_bitmask_property(crtc, "SDE_DEMURA_BOOT_PLANE_V1", + SDE_CP_CRTC_DSPP_DEMURA_BOOT_PLANE, true, + sde_demura_fetch_planes, + ARRAY_SIZE(sde_demura_fetch_planes), 0xf); break; default: DRM_ERROR("version %d not supported\n", version); diff --git a/msm/sde/sde_color_processing.h b/msm/sde/sde_color_processing.h index 6dd94ba9d9..3903b03cc6 100644 --- a/msm/sde/sde_color_processing.h +++ b/msm/sde/sde_color_processing.h @@ -104,6 +104,7 @@ enum sde_cp_crtc_features { SDE_CP_CRTC_DSPP_SPR_INIT, SDE_CP_CRTC_DSPP_DEMURA_INIT, SDE_CP_CRTC_DSPP_DEMURA_BACKLIGHT, + SDE_CP_CRTC_DSPP_DEMURA_BOOT_PLANE, SDE_CP_CRTC_DSPP_MAX, /* DSPP features end */ @@ -161,6 +162,14 @@ void sde_cp_crtc_install_properties(struct drm_crtc *crtc); */ void sde_cp_crtc_destroy_properties(struct drm_crtc *crtc); +/** + * sde_cp_crtc_refresh_status_properties(): Updates color processing + * properties reflecting the status + * of the crtc. + * @crtc: Pointer to crtc. + */ +void sde_cp_crtc_refresh_status_properties(struct drm_crtc *crtc); + /** * sde_cp_crtc_set_property: Set a color processing property * for a crtc. diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index e4c3029d0a..957b1b2a83 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -7228,6 +7228,7 @@ void sde_crtc_update_cont_splash_settings(struct drm_crtc *crtc) } _sde_crtc_setup_mixers(crtc); + sde_cp_crtc_refresh_status_properties(crtc); crtc->enabled = true; /* update core clk value for initial state with cont-splash */ diff --git a/msm/sde/sde_hw_color_proc_common_v4.h b/msm/sde/sde_hw_color_proc_common_v4.h index 104aaf521b..9c22beaf17 100644 --- a/msm/sde/sde_hw_color_proc_common_v4.h +++ b/msm/sde/sde_hw_color_proc_common_v4.h @@ -1,12 +1,39 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved. */ #ifndef _SDE_HW_COLOR_PROC_COMMON_V4_H_ #define _SDE_HW_COLOR_PROC_COMMON_V4_H_ #include "sde_hw_mdss.h" +/* + * DEMURA fetch planes + * @DEM_FETCH_DMA1_RECT0 Demura data fetched from DMA plane 1 rectangle 0 + * @DEM_FETCH_DMA1_RECT1 Demura data fetched from DMA plane 1 rectangle 1 + * @DEM_FETCH_DMA3_RECT0 Demura data fetched from DMA plane 3 rectangle 0 + * @DEM_FETCH_DMA3_RECT1 Demura data fetched from DMA plane 3 rectangle 1 + * @DEM_FETCH_DMA_INVALID Invalid DMA plane for fetching Demmura data + */ +enum demura_fetch_planes { + DEM_FETCH_DMA1_RECT0 = 0, + DEM_FETCH_DMA1_RECT1, + DEM_FETCH_DMA3_RECT0, + DEM_FETCH_DMA3_RECT1, + DEM_FETCH_DMA_INVALID, +}; + +/** + * struct sde_demura_fetch_planes - drm prop enun struct containing bit + * mask enum properties and values + */ +static const struct drm_prop_enum_list sde_demura_fetch_planes[] = { + {DEM_FETCH_DMA1_RECT0, "demura_dma1_rect0"}, + {DEM_FETCH_DMA1_RECT1, "demura_dma1_rect1"}, + {DEM_FETCH_DMA3_RECT0, "demura_dma3_rect0"}, + {DEM_FETCH_DMA3_RECT1, "demura_dma3_rect1"}, +}; + #define GAMUT_TABLE_SEL_OFF 0x4 #define GAMUT_UPPER_COLOR_OFF 0x8 #define GAMUT_LOWER_COLOR_OFF 0xc diff --git a/msm/sde/sde_hw_color_proc_v4.c b/msm/sde/sde_hw_color_proc_v4.c index f48193cc1f..6972e8ab2f 100644 --- a/msm/sde/sde_hw_color_proc_v4.c +++ b/msm/sde/sde_hw_color_proc_v4.c @@ -398,19 +398,20 @@ void sde_ltm_read_intr_status(struct sde_hw_dspp *ctx, u32 *status) SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->ltm.base + 0x58, clear); } -void sde_demura_backlight_cfg(struct sde_hw_dspp *dspp, u64 val) +void sde_demura_backlight_cfg(struct sde_hw_dspp *ctx, u64 val) { u32 demura_base; u32 backlight; - if (!dspp) { - DRM_ERROR("invalid parameter ctx %pK", dspp); + if (!ctx) { + DRM_ERROR("invalid parameter ctx %pK", ctx); return; } - demura_base = dspp->cap->sblk->demura.base; + + demura_base = ctx->cap->sblk->demura.base; backlight = (val & REG_MASK(11)); backlight |= ((val & REG_MASK_SHIFT(11, 32)) >> 16); - SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->demura.base + 0x8, + SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->demura.base + 0x8, backlight); } @@ -608,3 +609,30 @@ void sde_setup_fp16_unmultv1(struct sde_hw_pipe *ctx, SDE_REG_WRITE(&ctx->hw, unmult_base, unmult); } + +void sde_demura_read_plane_status(struct sde_hw_dspp *ctx, u32 *status) +{ + u32 demura_base; + u32 value; + + if (!ctx) { + DRM_ERROR("invalid parameter ctx %pK", ctx); + return; + } + + demura_base = ctx->cap->sblk->demura.base; + value = SDE_REG_READ(&ctx->hw, demura_base + 0x4); + if (!(value & 0x4)) { + *status = DEM_FETCH_DMA_INVALID; + } else if (ctx->idx == DSPP_0) { + if (value & 0x80000000) + *status = DEM_FETCH_DMA1_RECT0; + else + *status = DEM_FETCH_DMA3_RECT0; + } else { + if (value & 0x80000000) + *status = DEM_FETCH_DMA1_RECT1; + else + *status = DEM_FETCH_DMA3_RECT1; + } +} diff --git a/msm/sde/sde_hw_color_proc_v4.h b/msm/sde/sde_hw_color_proc_v4.h index 8c00b4b80b..64d0083c56 100644 --- a/msm/sde/sde_hw_color_proc_v4.h +++ b/msm/sde/sde_hw_color_proc_v4.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved. */ #ifndef _SDE_HW_COLOR_PROC_V4_H_ #define _SDE_HW_COLOR_PROC_V4_H_ @@ -74,10 +74,17 @@ void sde_ltm_read_intr_status(struct sde_hw_dspp *dspp, u32 *status); /** * sde_demura_backlight_cfg - api to set backlight for demura - * @dspp: pointer to dspp object + * @ctx: pointer to dspp object * @val: value of backlight */ -void sde_demura_backlight_cfg(struct sde_hw_dspp *dspp, u64 val); +void sde_demura_backlight_cfg(struct sde_hw_dspp *ctx, u64 val); + +/** + * sde_demura_read_plane_status - api to read demura plane fetch setup. + * @ctx: pointer to dspp object. + * @status: Currently present plane. Reported as a demura_fetch_planes value. + */ +void sde_demura_read_plane_status(struct sde_hw_dspp *ctx, u32 *status); /** * sde_setup_fp16_cscv1 - api to set FP16 CSC cp block diff --git a/msm/sde/sde_hw_dspp.c b/msm/sde/sde_hw_dspp.c index 9f533b0fd3..e413ca8229 100644 --- a/msm/sde/sde_hw_dspp.c +++ b/msm/sde/sde_hw_dspp.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ #include @@ -328,7 +328,9 @@ static void dspp_demura(struct sde_hw_dspp *c) if (!ret) { c->ops.setup_demura_cfg = reg_dmav1_setup_demurav1; c->ops.setup_demura_backlight_cfg = - sde_demura_backlight_cfg; + sde_demura_backlight_cfg; + c->ops.demura_read_plane_status = + sde_demura_read_plane_status; } } } diff --git a/msm/sde/sde_hw_dspp.h b/msm/sde/sde_hw_dspp.h index 8b4946415a..a3b03289ff 100644 --- a/msm/sde/sde_hw_dspp.h +++ b/msm/sde/sde_hw_dspp.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ #ifndef _SDE_HW_DSPP_H @@ -276,6 +276,13 @@ struct sde_hw_dspp_ops { * @status: Pointer to configuration. */ void (*setup_demura_backlight_cfg)(struct sde_hw_dspp *ctx, u64 val); + + /** + * demura_read_plane_status - Query demura plane status + * @ctx: Pointer to dspp context + * @status: Demura plane used by DSPP. demura_fetch_planes enum value. + */ + void (*demura_read_plane_status)(struct sde_hw_dspp *ctx, u32 *status); }; /**