Merge "disp: msm: sde: add support for new dspp flush" into display-kernel.lnx.5.4
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
bb0ca40080
@@ -1,6 +1,6 @@
|
||||
// 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__
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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 {
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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 {
|
||||
@@ -404,6 +413,7 @@ enum {
|
||||
SDE_CTL_PRIMARY_PREF,
|
||||
SDE_CTL_ACTIVE_CFG,
|
||||
SDE_CTL_UIDLE,
|
||||
SDE_CTL_UNIFIED_DSPP_FLUSH,
|
||||
SDE_CTL_MAX
|
||||
};
|
||||
|
||||
|
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
};
|
||||
|
@@ -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
|
||||
@@ -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;
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -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
|
||||
|
Reference in New Issue
Block a user