Merge "disp: msm: sde: add uidle fill level scaling"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
9c97572e9e
@@ -155,7 +155,8 @@
|
||||
#define SDE_UIDLE_FAL10_TARGET_IDLE 50
|
||||
#define SDE_UIDLE_FAL1_TARGET_IDLE 40
|
||||
#define SDE_UIDLE_FAL1_MAX_THRESHOLD 15
|
||||
#define SDE_UIDLE_REV102_FAL1_MAX_THRESHOLD 255
|
||||
#define SDE_UIDLE_FAL1_MAX_THRESHOLD_EXT_REV_102 255
|
||||
#define SDE_UIDLE_FAL1_MAX_THRESHOLD_EXT_REV_103 255
|
||||
#define SDE_UIDLE_FAL10_THRESHOLD_60 12
|
||||
#define SDE_UIDLE_FAL10_THRESHOLD_90 13
|
||||
#define SDE_UIDLE_MAX_DWNSCALE 1500
|
||||
@@ -1838,8 +1839,11 @@ static void sde_sspp_set_features(struct sde_mdss_cfg *sde_cfg,
|
||||
&sspp->perf_features);
|
||||
}
|
||||
|
||||
if (sde_cfg->uidle_cfg.uidle_rev)
|
||||
if (sde_cfg->uidle_cfg.uidle_rev) {
|
||||
set_bit(SDE_PERF_SSPP_UIDLE, &sspp->perf_features);
|
||||
if (sde_cfg->uidle_cfg.uidle_rev >= SDE_UIDLE_VERSION_1_0_3)
|
||||
set_bit(SDE_PERF_SSPP_UIDLE_FILL_LVL_SCALE, &sspp->perf_features);
|
||||
}
|
||||
|
||||
if (sde_cfg->sc_cfg[SDE_SYS_CACHE_DISP].has_sys_cache)
|
||||
set_bit(SDE_PERF_SSPP_SYS_CACHE, &sspp->perf_features);
|
||||
@@ -4756,42 +4760,40 @@ static void _sde_hw_setup_uidle(struct sde_uidle_cfg *uidle_cfg)
|
||||
if (!uidle_cfg->uidle_rev)
|
||||
return;
|
||||
|
||||
if ((IS_SDE_UIDLE_REV_102(uidle_cfg->uidle_rev)) ||
|
||||
(IS_SDE_UIDLE_REV_101(uidle_cfg->uidle_rev)) ||
|
||||
(IS_SDE_UIDLE_REV_100(uidle_cfg->uidle_rev))) {
|
||||
uidle_cfg->fal10_exit_cnt = SDE_UIDLE_FAL10_EXIT_CNT;
|
||||
uidle_cfg->fal10_exit_danger = SDE_UIDLE_FAL10_EXIT_DANGER;
|
||||
uidle_cfg->fal10_danger = SDE_UIDLE_FAL10_DANGER;
|
||||
uidle_cfg->fal10_target_idle_time = SDE_UIDLE_FAL10_TARGET_IDLE;
|
||||
uidle_cfg->fal1_target_idle_time = SDE_UIDLE_FAL1_TARGET_IDLE;
|
||||
uidle_cfg->max_dwnscale = SDE_UIDLE_MAX_DWNSCALE;
|
||||
uidle_cfg->debugfs_ctrl = true;
|
||||
uidle_cfg->fal1_max_threshold = SDE_UIDLE_FAL1_MAX_THRESHOLD;
|
||||
uidle_cfg->fal10_exit_cnt = SDE_UIDLE_FAL10_EXIT_CNT;
|
||||
uidle_cfg->fal10_exit_danger = SDE_UIDLE_FAL10_EXIT_DANGER;
|
||||
uidle_cfg->fal10_danger = SDE_UIDLE_FAL10_DANGER;
|
||||
uidle_cfg->fal10_target_idle_time = SDE_UIDLE_FAL10_TARGET_IDLE;
|
||||
uidle_cfg->fal1_target_idle_time = SDE_UIDLE_FAL1_TARGET_IDLE;
|
||||
uidle_cfg->max_dwnscale = SDE_UIDLE_MAX_DWNSCALE;
|
||||
uidle_cfg->debugfs_ctrl = true;
|
||||
uidle_cfg->fal1_max_threshold = SDE_UIDLE_FAL1_MAX_THRESHOLD;
|
||||
|
||||
if (IS_SDE_UIDLE_REV_100(uidle_cfg->uidle_rev)) {
|
||||
uidle_cfg->fal10_threshold =
|
||||
SDE_UIDLE_FAL10_THRESHOLD_60;
|
||||
uidle_cfg->max_fps = SDE_UIDLE_MAX_FPS_60;
|
||||
} else if (IS_SDE_UIDLE_REV_101(uidle_cfg->uidle_rev)) {
|
||||
set_bit(SDE_UIDLE_QACTIVE_OVERRIDE,
|
||||
&uidle_cfg->features);
|
||||
uidle_cfg->fal10_threshold =
|
||||
SDE_UIDLE_FAL10_THRESHOLD_90;
|
||||
uidle_cfg->max_fps = SDE_UIDLE_MAX_FPS_90;
|
||||
} else if (IS_SDE_UIDLE_REV_102(uidle_cfg->uidle_rev)) {
|
||||
set_bit(SDE_UIDLE_QACTIVE_OVERRIDE,
|
||||
&uidle_cfg->features);
|
||||
uidle_cfg->fal10_threshold =
|
||||
SDE_UIDLE_FAL10_THRESHOLD_90;
|
||||
uidle_cfg->max_fps = SDE_UIDLE_MAX_FPS_90;
|
||||
uidle_cfg->max_fal1_fps = SDE_UIDLE_MAX_FPS_240;
|
||||
uidle_cfg->fal1_max_threshold =
|
||||
SDE_UIDLE_REV102_FAL1_MAX_THRESHOLD;
|
||||
}
|
||||
} else {
|
||||
pr_err("invalid uidle rev:0x%x, disabling uidle\n",
|
||||
uidle_cfg->uidle_rev);
|
||||
uidle_cfg->uidle_rev = 0;
|
||||
if (IS_SDE_UIDLE_REV_100(uidle_cfg->uidle_rev)) {
|
||||
uidle_cfg->fal10_threshold =
|
||||
SDE_UIDLE_FAL10_THRESHOLD_60;
|
||||
uidle_cfg->max_fps = SDE_UIDLE_MAX_FPS_60;
|
||||
} else if (IS_SDE_UIDLE_REV_101(uidle_cfg->uidle_rev)) {
|
||||
set_bit(SDE_UIDLE_QACTIVE_OVERRIDE,
|
||||
&uidle_cfg->features);
|
||||
uidle_cfg->fal10_threshold =
|
||||
SDE_UIDLE_FAL10_THRESHOLD_90;
|
||||
uidle_cfg->max_fps = SDE_UIDLE_MAX_FPS_90;
|
||||
} else if (IS_SDE_UIDLE_REV_102(uidle_cfg->uidle_rev)) {
|
||||
set_bit(SDE_UIDLE_QACTIVE_OVERRIDE,
|
||||
&uidle_cfg->features);
|
||||
uidle_cfg->fal10_threshold =
|
||||
SDE_UIDLE_FAL10_THRESHOLD_90;
|
||||
uidle_cfg->max_fps = SDE_UIDLE_MAX_FPS_90;
|
||||
uidle_cfg->max_fal1_fps = SDE_UIDLE_MAX_FPS_240;
|
||||
uidle_cfg->fal1_max_threshold =
|
||||
SDE_UIDLE_FAL1_MAX_THRESHOLD_EXT_REV_102;
|
||||
} else if (IS_SDE_UIDLE_REV_103(uidle_cfg->uidle_rev)) {
|
||||
set_bit(SDE_UIDLE_QACTIVE_OVERRIDE, &uidle_cfg->features);
|
||||
uidle_cfg->max_fps = SDE_UIDLE_MAX_FPS_240;
|
||||
uidle_cfg->max_fal1_fps = SDE_UIDLE_MAX_FPS_240;
|
||||
uidle_cfg->fal1_max_threshold = SDE_UIDLE_FAL1_MAX_THRESHOLD_EXT_REV_103;
|
||||
uidle_cfg->fal10_threshold = SDE_UIDLE_FAL10_THRESHOLD_60;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5146,7 +5148,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
|
||||
sde_cfg->ts_prefill_rev = 2;
|
||||
sde_cfg->ctl_rev = SDE_CTL_CFG_VERSION_1_0_0;
|
||||
sde_cfg->true_inline_rot_rev = SDE_INLINE_ROT_VERSION_2_0_1;
|
||||
sde_cfg->uidle_cfg.uidle_rev = SDE_UIDLE_VERSION_1_0_2;
|
||||
sde_cfg->uidle_cfg.uidle_rev = SDE_UIDLE_VERSION_1_0_3;
|
||||
sde_cfg->mdss_hw_block_size = 0x158;
|
||||
sde_cfg->demura_supported[SSPP_DMA1][0] = 0;
|
||||
sde_cfg->demura_supported[SSPP_DMA1][1] = 1;
|
||||
|
@@ -148,6 +148,7 @@
|
||||
#define SDE_UIDLE_VERSION_1_0_0 0x100
|
||||
#define SDE_UIDLE_VERSION_1_0_1 0x101
|
||||
#define SDE_UIDLE_VERSION_1_0_2 0x102
|
||||
#define SDE_UIDLE_VERSION_1_0_3 0x103
|
||||
|
||||
#define IS_SDE_UIDLE_REV_100(rev) \
|
||||
((rev) == SDE_UIDLE_VERSION_1_0_0)
|
||||
@@ -155,6 +156,8 @@
|
||||
((rev) == SDE_UIDLE_VERSION_1_0_1)
|
||||
#define IS_SDE_UIDLE_REV_102(rev) \
|
||||
((rev) == SDE_UIDLE_VERSION_1_0_2)
|
||||
#define IS_SDE_UIDLE_REV_103(rev) \
|
||||
((rev) == SDE_UIDLE_VERSION_1_0_3)
|
||||
|
||||
#define SDE_UIDLE_MAJOR(rev) ((rev) >> 8)
|
||||
|
||||
@@ -345,6 +348,7 @@ enum {
|
||||
* @SDE_PERF_SSPP_CDP Supports client driven prefetch
|
||||
* @SDE_PERF_SSPP_SYS_CACHE, SSPP supports system cache
|
||||
* @SDE_PERF_SSPP_UIDLE, sspp supports uidle
|
||||
* @SDE_PERF_SSPP_UIDLE_FILL_LVL_SCALE, sspp supports uidle fill level scaling
|
||||
* @SDE_PERF_SSPP_MAX Maximum value
|
||||
*/
|
||||
enum {
|
||||
@@ -355,6 +359,7 @@ enum {
|
||||
SDE_PERF_SSPP_CDP,
|
||||
SDE_PERF_SSPP_SYS_CACHE,
|
||||
SDE_PERF_SSPP_UIDLE,
|
||||
SDE_PERF_SSPP_UIDLE_FILL_LVL_SCALE,
|
||||
SDE_PERF_SSPP_MAX
|
||||
};
|
||||
|
||||
|
@@ -46,6 +46,7 @@
|
||||
|
||||
#define SSPP_UIDLE_CTRL_VALUE 0x1f0
|
||||
#define SSPP_UIDLE_CTRL_VALUE_REC1 0x1f4
|
||||
#define SSPP_FILL_LEVEL_SCALE 0x1f8
|
||||
|
||||
/* SSPP_DGM */
|
||||
#define SSPP_DGM_0 0x9F0
|
||||
@@ -1167,6 +1168,22 @@ static void sde_hw_sspp_setup_sys_cache(struct sde_hw_pipe *ctx,
|
||||
SDE_REG_WRITE(&ctx->hw, SSPP_SYS_CACHE_MODE + idx, val);
|
||||
}
|
||||
|
||||
static void sde_hw_sspp_setup_uidle_fill_scale(struct sde_hw_pipe *ctx,
|
||||
struct sde_hw_pipe_uidle_cfg *cfg)
|
||||
{
|
||||
u32 idx, fill_lvl;
|
||||
|
||||
if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
|
||||
return;
|
||||
|
||||
/* duplicate the v1 scale values for V2 and fal10 exit */
|
||||
fill_lvl = cfg->fill_level_scale & 0xF;
|
||||
fill_lvl |= (cfg->fill_level_scale & 0xF) << 8;
|
||||
fill_lvl |= (cfg->fill_level_scale & 0xF) << 16;
|
||||
|
||||
SDE_REG_WRITE(&ctx->hw, SSPP_FILL_LEVEL_SCALE + idx, fill_lvl);
|
||||
}
|
||||
|
||||
static void sde_hw_sspp_setup_uidle(struct sde_hw_pipe *ctx,
|
||||
struct sde_hw_pipe_uidle_cfg *cfg,
|
||||
enum sde_sspp_multirect_index index)
|
||||
@@ -1501,8 +1518,11 @@ static void _setup_layer_ops(struct sde_hw_pipe *c,
|
||||
if (test_bit(SDE_PERF_SSPP_CDP, &perf_features))
|
||||
c->ops.setup_cdp = sde_hw_sspp_setup_cdp;
|
||||
|
||||
if (test_bit(SDE_PERF_SSPP_UIDLE, &perf_features))
|
||||
if (test_bit(SDE_PERF_SSPP_UIDLE, &perf_features)) {
|
||||
c->ops.setup_uidle = sde_hw_sspp_setup_uidle;
|
||||
if (test_bit(SDE_PERF_SSPP_UIDLE_FILL_LVL_SCALE, &perf_features))
|
||||
c->ops.setup_uidle_fill_scale = sde_hw_sspp_setup_uidle_fill_scale;
|
||||
}
|
||||
|
||||
_setup_layer_ops_colorproc(c, features, is_virtual_pipe);
|
||||
|
||||
|
@@ -265,6 +265,7 @@ struct sde_hw_pipe_sc_cfg {
|
||||
* @fal10_exit_threshold: number of lines to indicate fal_10_exit is okay
|
||||
* @fal10_threshold: number of lines where fal_10_is okay
|
||||
* @fal1_threshold: number of lines where fal_1 is okay
|
||||
* @fill_level_scale: scale factor on the fal10 threshold
|
||||
*/
|
||||
struct sde_hw_pipe_uidle_cfg {
|
||||
u32 enable;
|
||||
@@ -272,6 +273,7 @@ struct sde_hw_pipe_uidle_cfg {
|
||||
u32 fal10_exit_threshold;
|
||||
u32 fal10_threshold;
|
||||
u32 fal1_threshold;
|
||||
u32 fill_level_scale;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -534,6 +536,14 @@ struct sde_hw_sspp_ops {
|
||||
struct sde_hw_pipe_uidle_cfg *cfg,
|
||||
enum sde_sspp_multirect_index index);
|
||||
|
||||
/**
|
||||
* setup_uidle_fill_scale - set uidle fill scale factor
|
||||
* @ctx: Pointer to pipe context
|
||||
* @cfg: Pointer to uidle configuration
|
||||
*/
|
||||
void (*setup_uidle_fill_scale)(struct sde_hw_pipe *ctx,
|
||||
struct sde_hw_pipe_uidle_cfg *cfg);
|
||||
|
||||
/**
|
||||
* setup_ts_prefill - setup prefill traffic shaper
|
||||
* @ctx: Pointer to pipe context
|
||||
|
@@ -2942,6 +2942,28 @@ static void _sde_plane_setup_uidle(struct drm_crtc *crtc,
|
||||
psde->catalog->uidle_cfg.fal1_max_threshold);
|
||||
cfg.fal_allowed_threshold = fal10_threshold +
|
||||
(fal10_target_idle_time_ns*1000/line_time*2)/1000;
|
||||
cfg.fill_level_scale = 0;
|
||||
|
||||
/*
|
||||
* if uidle fill scale is supported, determing the scale value
|
||||
* and adjust fal10 thresholds to their scaled values.
|
||||
* fal1 thresholds and fal_allowed are not scaled.
|
||||
*/
|
||||
if (psde->pipe_hw->ops.setup_uidle_fill_scale) {
|
||||
u32 fl_require0 = psde->catalog->qos_target_time_ns / line_time * 2;
|
||||
u32 fl_require = max(fal10_threshold * 1000, fl_require0);
|
||||
u32 fl_scale = fl_require / fal10_threshold;
|
||||
u32 fal10_threshold_noscale;
|
||||
|
||||
cfg.fill_level_scale = (fl_scale <= 1) ? 0 : (32 / fl_scale);
|
||||
|
||||
if (cfg.fill_level_scale) {
|
||||
fal10_threshold_noscale = fal10_threshold *
|
||||
32/cfg.fill_level_scale;
|
||||
cfg.fal_allowed_threshold = fal10_threshold_noscale +
|
||||
(fal10_target_idle_time_ns * 1000 / line_time * 2) / 1000;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SDE_ERROR("invalid settings, will disable UIDLE %d %d %d %d\n",
|
||||
line_time, fal10_threshold, fal10_target_idle_time_ns,
|
||||
@@ -2950,9 +2972,10 @@ static void _sde_plane_setup_uidle(struct drm_crtc *crtc,
|
||||
}
|
||||
|
||||
SDE_DEBUG_PLANE(psde,
|
||||
"tholds: fal10=%d fal10_exit=%d fal1=%d fal_allowed=%d\n",
|
||||
"tholds: fal10=%d fal10_exit=%d fal1=%d fal_allowed=%d fill_scale=%d\n",
|
||||
cfg.fal10_threshold, cfg.fal10_exit_threshold,
|
||||
cfg.fal1_threshold, cfg.fal_allowed_threshold);
|
||||
cfg.fal1_threshold, cfg.fal_allowed_threshold,
|
||||
cfg.fill_level_scale);
|
||||
SDE_DEBUG_PLANE(psde,
|
||||
"times: line:%d fal1_idle:%d fal10_idle:%d dwnscale:%d\n",
|
||||
line_time, fal1_target_idle_time_ns,
|
||||
@@ -2961,7 +2984,10 @@ static void _sde_plane_setup_uidle(struct drm_crtc *crtc,
|
||||
SDE_EVT32_VERBOSE(cfg.enable,
|
||||
cfg.fal10_threshold, cfg.fal10_exit_threshold,
|
||||
cfg.fal1_threshold, cfg.fal_allowed_threshold,
|
||||
psde->catalog->uidle_cfg.max_dwnscale);
|
||||
cfg.fill_level_scale, psde->catalog->uidle_cfg.max_dwnscale);
|
||||
|
||||
if (psde->pipe_hw->ops.setup_uidle_fill_scale)
|
||||
psde->pipe_hw->ops.setup_uidle_fill_scale(psde->pipe_hw, &cfg);
|
||||
|
||||
psde->pipe_hw->ops.setup_uidle(
|
||||
psde->pipe_hw, &cfg,
|
||||
|
Reference in New Issue
Block a user