Loading msm/sde/sde_color_processing.c +64 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "%s: " fmt, __func__ Loading Loading @@ -1252,6 +1252,68 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, list_del_init(&prop_node->dirty_list); } static const int dspp_feature_to_sub_blk_tbl[SDE_CP_CRTC_MAX_FEATURES] = { [SDE_CP_CRTC_DSPP_IGC] = SDE_DSPP_IGC, [SDE_CP_CRTC_DSPP_PCC] = SDE_DSPP_PCC, [SDE_CP_CRTC_DSPP_GC] = SDE_DSPP_GC, [SDE_CP_CRTC_DSPP_HSIC] = SDE_DSPP_HSIC, [SDE_CP_CRTC_DSPP_MEMCOL_SKIN] = SDE_DSPP_MEMCOLOR, [SDE_CP_CRTC_DSPP_MEMCOL_SKY] = SDE_DSPP_MEMCOLOR, [SDE_CP_CRTC_DSPP_MEMCOL_FOLIAGE] = SDE_DSPP_MEMCOLOR, [SDE_CP_CRTC_DSPP_MEMCOL_PROT] = SDE_DSPP_MEMCOLOR, [SDE_CP_CRTC_DSPP_SIXZONE] = SDE_DSPP_SIXZONE, [SDE_CP_CRTC_DSPP_GAMUT] = SDE_DSPP_GAMUT, [SDE_CP_CRTC_DSPP_DITHER] = SDE_DSPP_DITHER, [SDE_CP_CRTC_DSPP_HIST_CTRL] = SDE_DSPP_HIST, [SDE_CP_CRTC_DSPP_HIST_IRQ] = SDE_DSPP_HIST, [SDE_CP_CRTC_DSPP_AD] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_VLUT] = SDE_DSPP_VLUT, [SDE_CP_CRTC_DSPP_AD_MODE] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_INIT] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_CFG] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_INPUT] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_ASSERTIVENESS] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_BACKLIGHT] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_STRENGTH] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_ROI] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_LTM] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_INIT] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_ROI] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_HIST_CTL] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_HIST_THRESH] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_SET_BUF] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_QUEUE_BUF] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_QUEUE_BUF2] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_QUEUE_BUF3] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_VLUT] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_MAX] = SDE_DSPP_MAX, [SDE_CP_CRTC_LM_GC] = SDE_DSPP_MAX, }; void sde_cp_dspp_flush_helper(struct sde_crtc *sde_crtc, u32 feature) { u32 i, sub_blk, num_mixers; enum sde_dspp dspp; struct sde_hw_ctl *ctl; if (!sde_crtc || feature >= SDE_CP_CRTC_MAX_FEATURES) { SDE_ERROR("invalid args: sde_crtc %s for feature %d", sde_crtc ? "valid" : "invalid", feature); return; } num_mixers = sde_crtc->num_mixers; sub_blk = dspp_feature_to_sub_blk_tbl[feature]; for (i = 0; i < num_mixers; i++) { ctl = sde_crtc->mixers[i].hw_ctl; dspp = sde_crtc->mixers[i].hw_dspp->idx; if (ctl && ctl->ops.update_bitmask_dspp_subblk) ctl->ops.update_bitmask_dspp_subblk( ctl, dspp, sub_blk, true); } } void sde_cp_crtc_apply_properties(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc = NULL; Loading Loading @@ -1299,6 +1361,7 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc) list_for_each_entry_safe(prop_node, n, &sde_crtc->dirty_list, dirty_list) { sde_cp_crtc_setfeature(prop_node, sde_crtc); sde_cp_dspp_flush_helper(sde_crtc, prop_node->feature); /* Set the flush flag to true */ if (prop_node->is_dspp_feature) set_dspp_flush = true; Loading msm/sde/sde_hw_catalog.c +3 −0 Original line number Diff line number Diff line Loading @@ -1742,6 +1742,9 @@ static int sde_ctl_parse_dt(struct device_node *np, set_bit(SDE_CTL_ACTIVE_CFG, &ctl->features); if (IS_SDE_UIDLE_REV_100(sde_cfg->uidle_cfg.uidle_rev)) set_bit(SDE_CTL_UIDLE, &ctl->features); if (SDE_HW_MAJOR(sde_cfg->hwversion) >= SDE_HW_MAJOR(SDE_HW_VER_700)) set_bit(SDE_CTL_UNIFIED_DSPP_FLUSH, &ctl->features); } end: kfree(prop_value); Loading msm/sde/sde_hw_catalog.h +10 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,10 @@ enum { * @SDE_DSPP_VLUT PA VLUT block * @SDE_DSPP_AD AD block * @SDE_DSPP_LTM LTM block * @SDE_DSPP_SPR SPR block * @SDE_DSPP_DEMURA Demura block * @SDE_DSPP_RC RC block * @SDE_DSPP_SB SB LUT DMA * @SDE_DSPP_MAX maximum value */ enum { Loading @@ -329,6 +333,10 @@ enum { SDE_DSPP_VLUT, SDE_DSPP_AD, SDE_DSPP_LTM, SDE_DSPP_SPR, SDE_DSPP_DEMURA, SDE_DSPP_RC, SDE_DSPP_SB, SDE_DSPP_MAX }; Loading Loading @@ -396,6 +404,7 @@ enum { * @SDE_CTL_ACTIVE_CFG CTL configuration is specified using active * blocks * @SDE_CTL_UIDLE CTL supports uidle * @SDE_CTL_UNIFIED_DSPP_FLUSH CTL supports only one flush bit for DSPP * @SDE_CTL_MAX */ enum { Loading @@ -404,6 +413,7 @@ enum { SDE_CTL_PRIMARY_PREF, SDE_CTL_ACTIVE_CFG, SDE_CTL_UIDLE, SDE_CTL_UNIFIED_DSPP_FLUSH, SDE_CTL_MAX }; Loading msm/sde/sde_hw_ctl.c +90 −2 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #define CTL_INTF_FLUSH 0x110 #define CTL_CDM_FLUSH 0x114 #define CTL_PERIPH_FLUSH 0x128 #define CTL_DSPP_0_FLUSH 0x13c #define CTL_INTF_MASTER 0x134 #define CTL_UIDLE_ACTIVE 0x138 Loading Loading @@ -153,6 +154,28 @@ static const u32 cdm_flush_tbl[CDM_MAX] = {SDE_NONE, 0}; static const u32 cwb_flush_tbl[CWB_MAX] = {SDE_NONE, SDE_NONE, 1, 2, 3, 4, 5}; /** * list of DSPP sub-blk flush bits in CTL_DSPP_x_FLUSH */ static const u32 dspp_sub_blk_flush_tbl[SDE_DSPP_MAX] = { [SDE_DSPP_IGC] = 2, [SDE_DSPP_PCC] = 4, [SDE_DSPP_GC] = 5, [SDE_DSPP_HSIC] = 0, [SDE_DSPP_MEMCOLOR] = 0, [SDE_DSPP_SIXZONE] = 0, [SDE_DSPP_GAMUT] = 3, [SDE_DSPP_DITHER] = 0, [SDE_DSPP_HIST] = 0, [SDE_DSPP_VLUT] = 1, [SDE_DSPP_AD] = 0, [SDE_DSPP_LTM] = 7, [SDE_DSPP_SPR] = 8, [SDE_DSPP_DEMURA] = 9, [SDE_DSPP_RC] = 10, [SDE_DSPP_SB] = 31, }; /** * struct ctl_sspp_stage_reg_map: Describes bit layout for a sspp stage cfg * @ext: Index to indicate LAYER_x_EXT id for given sspp Loading Loading @@ -195,6 +218,7 @@ sspp_reg_cfg_tbl[SSPP_MAX][CTL_SSPP_MAX_RECTS] = { #define MERGE_3D_IDX 23 #define CDM_IDX 26 #define CWB_IDX 28 #define DSPP_IDX 29 #define PERIPH_IDX 30 #define INTF_IDX 31 Loading Loading @@ -234,6 +258,18 @@ static int _mixer_stages(const struct sde_lm_cfg *mixer, int count, return stages; } static inline bool _is_dspp_flush_pending(struct sde_hw_ctl *ctx) { int i; for (i = 0; i < CTL_MAX_DSPP_COUNT; i++) { if (ctx->flush.pending_dspp_flush_masks[i]) return true; } return false; } static inline int sde_hw_ctl_trigger_start(struct sde_hw_ctl *ctx) { if (!ctx) Loading Loading @@ -585,6 +621,8 @@ static inline int sde_hw_ctl_update_pending_flush_v1( struct sde_hw_ctl *ctx, struct sde_ctl_flush_cfg *cfg) { int i; if (!ctx || !cfg) return -EINVAL; Loading @@ -597,9 +635,50 @@ static inline int sde_hw_ctl_update_pending_flush_v1( cfg->pending_merge_3d_flush_mask; ctx->flush.pending_cwb_flush_mask |= cfg->pending_cwb_flush_mask; ctx->flush.pending_periph_flush_mask |= cfg->pending_periph_flush_mask; for (i = 0; i < CTL_MAX_DSPP_COUNT; i++) ctx->flush.pending_dspp_flush_masks[i] |= cfg->pending_dspp_flush_masks[i]; return 0; } static inline int sde_hw_ctl_update_bitmask_dspp_subblk(struct sde_hw_ctl *ctx, enum sde_dspp dspp, u32 sub_blk, bool enable) { if (!ctx || dspp < DSPP_0 || dspp >= DSPP_MAX || sub_blk < SDE_DSPP_IGC || sub_blk >= SDE_DSPP_MAX) { SDE_ERROR("invalid args - ctx %s, dspp %d sub_block %d\n", ctx ? "valid" : "invalid", dspp, sub_blk); return -EINVAL; } UPDATE_MASK(ctx->flush.pending_dspp_flush_masks[dspp - DSPP_0], dspp_sub_blk_flush_tbl[sub_blk], enable); if (_is_dspp_flush_pending(ctx)) UPDATE_MASK(ctx->flush.pending_flush_mask, DSPP_IDX, 1); else UPDATE_MASK(ctx->flush.pending_flush_mask, DSPP_IDX, 0); return 0; } static inline void _sde_hw_ctl_write_dspp_flushes(struct sde_hw_ctl *ctx) { int i; bool has_dspp_flushes = ctx->caps->features & BIT(SDE_CTL_UNIFIED_DSPP_FLUSH); if (!has_dspp_flushes) return; for (i = 0; i < CTL_MAX_DSPP_COUNT; i++) { u32 pending = ctx->flush.pending_dspp_flush_masks[i]; if (pending) SDE_REG_WRITE(&ctx->hw, CTL_DSPP_0_FLUSH + (i * 4), pending); } } static inline int sde_hw_ctl_trigger_flush_v1(struct sde_hw_ctl *ctx) { if (!ctx) Loading @@ -626,6 +705,8 @@ static inline int sde_hw_ctl_trigger_flush_v1(struct sde_hw_ctl *ctx) if (ctx->flush.pending_flush_mask & BIT(PERIPH_IDX)) SDE_REG_WRITE(&ctx->hw, CTL_PERIPH_FLUSH, ctx->flush.pending_periph_flush_mask); if (ctx->flush.pending_flush_mask & BIT(DSPP_IDX)) _sde_hw_ctl_write_dspp_flushes(ctx); SDE_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->flush.pending_flush_mask); return 0; Loading Loading @@ -1323,11 +1404,18 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, ops->get_staged_sspp = sde_hw_ctl_get_staged_sspp; ops->update_bitmask_sspp = sde_hw_ctl_update_bitmask_sspp; ops->update_bitmask_mixer = sde_hw_ctl_update_bitmask_mixer; ops->update_bitmask_dspp = sde_hw_ctl_update_bitmask_dspp; ops->update_bitmask_dspp_pavlut = sde_hw_ctl_update_bitmask_dspp_pavlut; ops->reg_dma_flush = sde_hw_reg_dma_flush; ops->get_start_state = sde_hw_ctl_get_start_state; if (cap & BIT(SDE_CTL_UNIFIED_DSPP_FLUSH)) { ops->update_bitmask_dspp_subblk = sde_hw_ctl_update_bitmask_dspp_subblk; } else { ops->update_bitmask_dspp = sde_hw_ctl_update_bitmask_dspp; ops->update_bitmask_dspp_pavlut = sde_hw_ctl_update_bitmask_dspp_pavlut; } if (cap & BIT(SDE_CTL_UIDLE)) ops->uidle_enable = sde_hw_ctl_uidle_enable; }; Loading msm/sde/sde_hw_ctl.h +15 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #include "sde_hw_blk.h" #define INVALID_CTL_STATUS 0xfffff88e #define CTL_MAX_DSPP_COUNT (DSPP_MAX - DSPP_0) /** * sde_ctl_mode_sel: Interface mode selection Loading Loading @@ -129,6 +130,7 @@ struct sde_hw_intf_cfg_v1 { * @pending_merge_3d_flush_mask: pending 3d merge block flush * @pending_cwb_flush_mask: pending flush for concurrent writeback * @pending_periph_flush_mask: pending flush for peripheral module * @pending_dspp_flush_masks: pending flush masks for sub-blks of each DSPP */ struct sde_ctl_flush_cfg { u32 pending_flush_mask; Loading @@ -139,6 +141,7 @@ struct sde_ctl_flush_cfg { u32 pending_merge_3d_flush_mask; u32 pending_cwb_flush_mask; u32 pending_periph_flush_mask; u32 pending_dspp_flush_masks[CTL_MAX_DSPP_COUNT]; }; /** Loading Loading @@ -331,6 +334,18 @@ struct sde_hw_ctl_ops { int (*update_bitmask_dspp_pavlut)(struct sde_hw_ctl *ctx, enum sde_dspp blk, bool enable); /** * Program DSPP sub block specific bit of dspp flush register. * @ctx : ctl path ctx pointer * @dspp : HW block ID of dspp block * @sub_blk : enum of DSPP sub block to flush * @enable : true to enable, 0 to disable * * This API is for CTL with DSPP flush hierarchy registers. */ int (*update_bitmask_dspp_subblk)(struct sde_hw_ctl *ctx, enum sde_dspp dspp, u32 sub_blk, bool enable); /** * update_bitmask_sspp: updates mask corresponding to sspp * @blk : blk id Loading Loading
msm/sde/sde_color_processing.c +64 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "%s: " fmt, __func__ Loading Loading @@ -1252,6 +1252,68 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, list_del_init(&prop_node->dirty_list); } static const int dspp_feature_to_sub_blk_tbl[SDE_CP_CRTC_MAX_FEATURES] = { [SDE_CP_CRTC_DSPP_IGC] = SDE_DSPP_IGC, [SDE_CP_CRTC_DSPP_PCC] = SDE_DSPP_PCC, [SDE_CP_CRTC_DSPP_GC] = SDE_DSPP_GC, [SDE_CP_CRTC_DSPP_HSIC] = SDE_DSPP_HSIC, [SDE_CP_CRTC_DSPP_MEMCOL_SKIN] = SDE_DSPP_MEMCOLOR, [SDE_CP_CRTC_DSPP_MEMCOL_SKY] = SDE_DSPP_MEMCOLOR, [SDE_CP_CRTC_DSPP_MEMCOL_FOLIAGE] = SDE_DSPP_MEMCOLOR, [SDE_CP_CRTC_DSPP_MEMCOL_PROT] = SDE_DSPP_MEMCOLOR, [SDE_CP_CRTC_DSPP_SIXZONE] = SDE_DSPP_SIXZONE, [SDE_CP_CRTC_DSPP_GAMUT] = SDE_DSPP_GAMUT, [SDE_CP_CRTC_DSPP_DITHER] = SDE_DSPP_DITHER, [SDE_CP_CRTC_DSPP_HIST_CTRL] = SDE_DSPP_HIST, [SDE_CP_CRTC_DSPP_HIST_IRQ] = SDE_DSPP_HIST, [SDE_CP_CRTC_DSPP_AD] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_VLUT] = SDE_DSPP_VLUT, [SDE_CP_CRTC_DSPP_AD_MODE] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_INIT] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_CFG] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_INPUT] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_ASSERTIVENESS] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_BACKLIGHT] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_STRENGTH] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_AD_ROI] = SDE_DSPP_AD, [SDE_CP_CRTC_DSPP_LTM] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_INIT] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_ROI] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_HIST_CTL] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_HIST_THRESH] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_SET_BUF] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_QUEUE_BUF] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_QUEUE_BUF2] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_QUEUE_BUF3] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_LTM_VLUT] = SDE_DSPP_LTM, [SDE_CP_CRTC_DSPP_MAX] = SDE_DSPP_MAX, [SDE_CP_CRTC_LM_GC] = SDE_DSPP_MAX, }; void sde_cp_dspp_flush_helper(struct sde_crtc *sde_crtc, u32 feature) { u32 i, sub_blk, num_mixers; enum sde_dspp dspp; struct sde_hw_ctl *ctl; if (!sde_crtc || feature >= SDE_CP_CRTC_MAX_FEATURES) { SDE_ERROR("invalid args: sde_crtc %s for feature %d", sde_crtc ? "valid" : "invalid", feature); return; } num_mixers = sde_crtc->num_mixers; sub_blk = dspp_feature_to_sub_blk_tbl[feature]; for (i = 0; i < num_mixers; i++) { ctl = sde_crtc->mixers[i].hw_ctl; dspp = sde_crtc->mixers[i].hw_dspp->idx; if (ctl && ctl->ops.update_bitmask_dspp_subblk) ctl->ops.update_bitmask_dspp_subblk( ctl, dspp, sub_blk, true); } } void sde_cp_crtc_apply_properties(struct drm_crtc *crtc) { struct sde_crtc *sde_crtc = NULL; Loading Loading @@ -1299,6 +1361,7 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc) list_for_each_entry_safe(prop_node, n, &sde_crtc->dirty_list, dirty_list) { sde_cp_crtc_setfeature(prop_node, sde_crtc); sde_cp_dspp_flush_helper(sde_crtc, prop_node->feature); /* Set the flush flag to true */ if (prop_node->is_dspp_feature) set_dspp_flush = true; Loading
msm/sde/sde_hw_catalog.c +3 −0 Original line number Diff line number Diff line Loading @@ -1742,6 +1742,9 @@ static int sde_ctl_parse_dt(struct device_node *np, set_bit(SDE_CTL_ACTIVE_CFG, &ctl->features); if (IS_SDE_UIDLE_REV_100(sde_cfg->uidle_cfg.uidle_rev)) set_bit(SDE_CTL_UIDLE, &ctl->features); if (SDE_HW_MAJOR(sde_cfg->hwversion) >= SDE_HW_MAJOR(SDE_HW_VER_700)) set_bit(SDE_CTL_UNIFIED_DSPP_FLUSH, &ctl->features); } end: kfree(prop_value); Loading
msm/sde/sde_hw_catalog.h +10 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,10 @@ enum { * @SDE_DSPP_VLUT PA VLUT block * @SDE_DSPP_AD AD block * @SDE_DSPP_LTM LTM block * @SDE_DSPP_SPR SPR block * @SDE_DSPP_DEMURA Demura block * @SDE_DSPP_RC RC block * @SDE_DSPP_SB SB LUT DMA * @SDE_DSPP_MAX maximum value */ enum { Loading @@ -329,6 +333,10 @@ enum { SDE_DSPP_VLUT, SDE_DSPP_AD, SDE_DSPP_LTM, SDE_DSPP_SPR, SDE_DSPP_DEMURA, SDE_DSPP_RC, SDE_DSPP_SB, SDE_DSPP_MAX }; Loading Loading @@ -396,6 +404,7 @@ enum { * @SDE_CTL_ACTIVE_CFG CTL configuration is specified using active * blocks * @SDE_CTL_UIDLE CTL supports uidle * @SDE_CTL_UNIFIED_DSPP_FLUSH CTL supports only one flush bit for DSPP * @SDE_CTL_MAX */ enum { Loading @@ -404,6 +413,7 @@ enum { SDE_CTL_PRIMARY_PREF, SDE_CTL_ACTIVE_CFG, SDE_CTL_UIDLE, SDE_CTL_UNIFIED_DSPP_FLUSH, SDE_CTL_MAX }; Loading
msm/sde/sde_hw_ctl.c +90 −2 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #define CTL_INTF_FLUSH 0x110 #define CTL_CDM_FLUSH 0x114 #define CTL_PERIPH_FLUSH 0x128 #define CTL_DSPP_0_FLUSH 0x13c #define CTL_INTF_MASTER 0x134 #define CTL_UIDLE_ACTIVE 0x138 Loading Loading @@ -153,6 +154,28 @@ static const u32 cdm_flush_tbl[CDM_MAX] = {SDE_NONE, 0}; static const u32 cwb_flush_tbl[CWB_MAX] = {SDE_NONE, SDE_NONE, 1, 2, 3, 4, 5}; /** * list of DSPP sub-blk flush bits in CTL_DSPP_x_FLUSH */ static const u32 dspp_sub_blk_flush_tbl[SDE_DSPP_MAX] = { [SDE_DSPP_IGC] = 2, [SDE_DSPP_PCC] = 4, [SDE_DSPP_GC] = 5, [SDE_DSPP_HSIC] = 0, [SDE_DSPP_MEMCOLOR] = 0, [SDE_DSPP_SIXZONE] = 0, [SDE_DSPP_GAMUT] = 3, [SDE_DSPP_DITHER] = 0, [SDE_DSPP_HIST] = 0, [SDE_DSPP_VLUT] = 1, [SDE_DSPP_AD] = 0, [SDE_DSPP_LTM] = 7, [SDE_DSPP_SPR] = 8, [SDE_DSPP_DEMURA] = 9, [SDE_DSPP_RC] = 10, [SDE_DSPP_SB] = 31, }; /** * struct ctl_sspp_stage_reg_map: Describes bit layout for a sspp stage cfg * @ext: Index to indicate LAYER_x_EXT id for given sspp Loading Loading @@ -195,6 +218,7 @@ sspp_reg_cfg_tbl[SSPP_MAX][CTL_SSPP_MAX_RECTS] = { #define MERGE_3D_IDX 23 #define CDM_IDX 26 #define CWB_IDX 28 #define DSPP_IDX 29 #define PERIPH_IDX 30 #define INTF_IDX 31 Loading Loading @@ -234,6 +258,18 @@ static int _mixer_stages(const struct sde_lm_cfg *mixer, int count, return stages; } static inline bool _is_dspp_flush_pending(struct sde_hw_ctl *ctx) { int i; for (i = 0; i < CTL_MAX_DSPP_COUNT; i++) { if (ctx->flush.pending_dspp_flush_masks[i]) return true; } return false; } static inline int sde_hw_ctl_trigger_start(struct sde_hw_ctl *ctx) { if (!ctx) Loading Loading @@ -585,6 +621,8 @@ static inline int sde_hw_ctl_update_pending_flush_v1( struct sde_hw_ctl *ctx, struct sde_ctl_flush_cfg *cfg) { int i; if (!ctx || !cfg) return -EINVAL; Loading @@ -597,9 +635,50 @@ static inline int sde_hw_ctl_update_pending_flush_v1( cfg->pending_merge_3d_flush_mask; ctx->flush.pending_cwb_flush_mask |= cfg->pending_cwb_flush_mask; ctx->flush.pending_periph_flush_mask |= cfg->pending_periph_flush_mask; for (i = 0; i < CTL_MAX_DSPP_COUNT; i++) ctx->flush.pending_dspp_flush_masks[i] |= cfg->pending_dspp_flush_masks[i]; return 0; } static inline int sde_hw_ctl_update_bitmask_dspp_subblk(struct sde_hw_ctl *ctx, enum sde_dspp dspp, u32 sub_blk, bool enable) { if (!ctx || dspp < DSPP_0 || dspp >= DSPP_MAX || sub_blk < SDE_DSPP_IGC || sub_blk >= SDE_DSPP_MAX) { SDE_ERROR("invalid args - ctx %s, dspp %d sub_block %d\n", ctx ? "valid" : "invalid", dspp, sub_blk); return -EINVAL; } UPDATE_MASK(ctx->flush.pending_dspp_flush_masks[dspp - DSPP_0], dspp_sub_blk_flush_tbl[sub_blk], enable); if (_is_dspp_flush_pending(ctx)) UPDATE_MASK(ctx->flush.pending_flush_mask, DSPP_IDX, 1); else UPDATE_MASK(ctx->flush.pending_flush_mask, DSPP_IDX, 0); return 0; } static inline void _sde_hw_ctl_write_dspp_flushes(struct sde_hw_ctl *ctx) { int i; bool has_dspp_flushes = ctx->caps->features & BIT(SDE_CTL_UNIFIED_DSPP_FLUSH); if (!has_dspp_flushes) return; for (i = 0; i < CTL_MAX_DSPP_COUNT; i++) { u32 pending = ctx->flush.pending_dspp_flush_masks[i]; if (pending) SDE_REG_WRITE(&ctx->hw, CTL_DSPP_0_FLUSH + (i * 4), pending); } } static inline int sde_hw_ctl_trigger_flush_v1(struct sde_hw_ctl *ctx) { if (!ctx) Loading @@ -626,6 +705,8 @@ static inline int sde_hw_ctl_trigger_flush_v1(struct sde_hw_ctl *ctx) if (ctx->flush.pending_flush_mask & BIT(PERIPH_IDX)) SDE_REG_WRITE(&ctx->hw, CTL_PERIPH_FLUSH, ctx->flush.pending_periph_flush_mask); if (ctx->flush.pending_flush_mask & BIT(DSPP_IDX)) _sde_hw_ctl_write_dspp_flushes(ctx); SDE_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->flush.pending_flush_mask); return 0; Loading Loading @@ -1323,11 +1404,18 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, ops->get_staged_sspp = sde_hw_ctl_get_staged_sspp; ops->update_bitmask_sspp = sde_hw_ctl_update_bitmask_sspp; ops->update_bitmask_mixer = sde_hw_ctl_update_bitmask_mixer; ops->update_bitmask_dspp = sde_hw_ctl_update_bitmask_dspp; ops->update_bitmask_dspp_pavlut = sde_hw_ctl_update_bitmask_dspp_pavlut; ops->reg_dma_flush = sde_hw_reg_dma_flush; ops->get_start_state = sde_hw_ctl_get_start_state; if (cap & BIT(SDE_CTL_UNIFIED_DSPP_FLUSH)) { ops->update_bitmask_dspp_subblk = sde_hw_ctl_update_bitmask_dspp_subblk; } else { ops->update_bitmask_dspp = sde_hw_ctl_update_bitmask_dspp; ops->update_bitmask_dspp_pavlut = sde_hw_ctl_update_bitmask_dspp_pavlut; } if (cap & BIT(SDE_CTL_UIDLE)) ops->uidle_enable = sde_hw_ctl_uidle_enable; }; Loading
msm/sde/sde_hw_ctl.h +15 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #include "sde_hw_blk.h" #define INVALID_CTL_STATUS 0xfffff88e #define CTL_MAX_DSPP_COUNT (DSPP_MAX - DSPP_0) /** * sde_ctl_mode_sel: Interface mode selection Loading Loading @@ -129,6 +130,7 @@ struct sde_hw_intf_cfg_v1 { * @pending_merge_3d_flush_mask: pending 3d merge block flush * @pending_cwb_flush_mask: pending flush for concurrent writeback * @pending_periph_flush_mask: pending flush for peripheral module * @pending_dspp_flush_masks: pending flush masks for sub-blks of each DSPP */ struct sde_ctl_flush_cfg { u32 pending_flush_mask; Loading @@ -139,6 +141,7 @@ struct sde_ctl_flush_cfg { u32 pending_merge_3d_flush_mask; u32 pending_cwb_flush_mask; u32 pending_periph_flush_mask; u32 pending_dspp_flush_masks[CTL_MAX_DSPP_COUNT]; }; /** Loading Loading @@ -331,6 +334,18 @@ struct sde_hw_ctl_ops { int (*update_bitmask_dspp_pavlut)(struct sde_hw_ctl *ctx, enum sde_dspp blk, bool enable); /** * Program DSPP sub block specific bit of dspp flush register. * @ctx : ctl path ctx pointer * @dspp : HW block ID of dspp block * @sub_blk : enum of DSPP sub block to flush * @enable : true to enable, 0 to disable * * This API is for CTL with DSPP flush hierarchy registers. */ int (*update_bitmask_dspp_subblk)(struct sde_hw_ctl *ctx, enum sde_dspp dspp, u32 sub_blk, bool enable); /** * update_bitmask_sspp: updates mask corresponding to sspp * @blk : blk id Loading