Merge "disp: msm: sde: support fps based qos setting"

This commit is contained in:
qctecmdr 2020-03-03 13:40:02 -08:00 • committed by Gerrit - the friendly Code Review server
commit 8a690a0b80
9 changed files with 258 additions and 569 deletions

View file

@ -136,25 +136,6 @@ static void sde_encoder_phys_wb_set_qos_remap(
sde_vbif_set_qos_remap(phys_enc->sde_kms, &qos_params);
}
static u64 _sde_encoder_phys_wb_get_qos_lut(const struct sde_qos_lut_tbl *tbl,
u32 total_fl)
{
int i;
if (!tbl || !tbl->nentry || !tbl->entries)
return 0;
for (i = 0; i < tbl->nentry; i++)
if (total_fl <= tbl->entries[i].fl)
return tbl->entries[i].lut;
/* if last fl is zero, use as default */
if (!tbl->entries[i-1].fl)
return tbl->entries[i-1].lut;
return 0;
}
/**
* sde_encoder_phys_wb_set_qos - set QoS/danger/safe LUTs for writeback
* @phys_enc: Pointer to physical encoder
@ -163,14 +144,14 @@ static void sde_encoder_phys_wb_set_qos(struct sde_encoder_phys *phys_enc)
{
struct sde_encoder_phys_wb *wb_enc;
struct sde_hw_wb *hw_wb;
struct sde_hw_wb_qos_cfg qos_cfg;
struct sde_mdss_cfg *catalog;
struct sde_hw_wb_qos_cfg qos_cfg = {0};
struct sde_perf_cfg *perf;
u32 fps_index = 0, lut_index, index, frame_rate, qos_count;
if (!phys_enc || !phys_enc->sde_kms || !phys_enc->sde_kms->catalog) {
SDE_ERROR("invalid parameter(s)\n");
return;
}
catalog = phys_enc->sde_kms->catalog;
wb_enc = to_sde_encoder_phys_wb(phys_enc);
if (!wb_enc->hw_wb) {
@ -178,35 +159,38 @@ static void sde_encoder_phys_wb_set_qos(struct sde_encoder_phys *phys_enc)
return;
}
perf = &phys_enc->sde_kms->catalog->perf;
frame_rate = phys_enc->cached_mode.vrefresh;
hw_wb = wb_enc->hw_wb;
qos_count = perf->qos_refresh_count;
while (qos_count && perf->qos_refresh_rate) {
if (frame_rate >= perf->qos_refresh_rate[qos_count - 1]) {
fps_index = qos_count - 1;
break;
}
qos_count--;
}
memset(&qos_cfg, 0, sizeof(struct sde_hw_wb_qos_cfg));
qos_cfg.danger_safe_en = true;
qos_cfg.danger_lut =
catalog->perf.danger_lut_tbl[SDE_QOS_LUT_USAGE_NRT];
if (phys_enc->in_clone_mode)
qos_cfg.safe_lut = (u32) _sde_encoder_phys_wb_get_qos_lut(
&catalog->perf.sfe_lut_tbl[SDE_QOS_LUT_USAGE_CWB], 0);
lut_index = SDE_QOS_LUT_USAGE_CWB;
else
qos_cfg.safe_lut = (u32) _sde_encoder_phys_wb_get_qos_lut(
&catalog->perf.sfe_lut_tbl[SDE_QOS_LUT_USAGE_NRT], 0);
lut_index = SDE_QOS_LUT_USAGE_NRT;
index = (fps_index * SDE_QOS_LUT_USAGE_MAX) + lut_index;
if (phys_enc->in_clone_mode)
qos_cfg.creq_lut = _sde_encoder_phys_wb_get_qos_lut(
&catalog->perf.qos_lut_tbl[SDE_QOS_LUT_USAGE_CWB], 0);
else
qos_cfg.creq_lut = _sde_encoder_phys_wb_get_qos_lut(
&catalog->perf.qos_lut_tbl[SDE_QOS_LUT_USAGE_NRT], 0);
qos_cfg.danger_lut = perf->danger_lut[index];
qos_cfg.safe_lut = (u32) perf->safe_lut[index];
qos_cfg.creq_lut = perf->creq_lut[index];
if (hw_wb->ops.setup_danger_safe_lut)
hw_wb->ops.setup_danger_safe_lut(hw_wb, &qos_cfg);
SDE_DEBUG("wb_enc:%d hw idx:%d fps:%d mode:%d luts[0x%x,0x%x 0x%llx]\n",
DRMID(phys_enc->parent), hw_wb->idx - WB_0,
frame_rate, phys_enc->in_clone_mode,
qos_cfg.danger_lut, qos_cfg.safe_lut, qos_cfg.creq_lut);
if (hw_wb->ops.setup_creq_lut)
hw_wb->ops.setup_creq_lut(hw_wb, &qos_cfg);
if (hw_wb->ops.setup_qos_ctrl)
hw_wb->ops.setup_qos_ctrl(hw_wb, &qos_cfg);
if (hw_wb->ops.setup_qos_lut)
hw_wb->ops.setup_qos_lut(hw_wb, &qos_cfg);
}
/**

View file

@ -213,25 +213,27 @@ enum {
PERF_DOWNSCALING_PREFILL_LINES,
PERF_XTRA_PREFILL_LINES,
PERF_AMORTIZABLE_THRESHOLD,
PERF_DANGER_LUT,
PERF_SAFE_LUT_LINEAR,
PERF_SAFE_LUT_MACROTILE,
PERF_SAFE_LUT_NRT,
PERF_SAFE_LUT_CWB,
PERF_QOS_LUT_LINEAR,
PERF_QOS_LUT_MACROTILE,
PERF_QOS_LUT_NRT,
PERF_QOS_LUT_CWB,
PERF_NUM_MNOC_PORTS,
PERF_AXI_BUS_WIDTH,
PERF_CDP_SETTING,
PERF_CPU_MASK,
PERF_CPU_DMA_LATENCY,
PERF_QOS_LUT_MACROTILE_QSEED,
PERF_SAFE_LUT_MACROTILE_QSEED,
PERF_NUM_MNOC_PORTS,
PERF_AXI_BUS_WIDTH,
PERF_PROP_MAX,
};
enum {
QOS_REFRESH_RATES,
QOS_DANGER_LUT,
QOS_SAFE_LUT,
QOS_CREQ_LUT_LINEAR,
QOS_CREQ_LUT_MACROTILE,
QOS_CREQ_LUT_NRT,
QOS_CREQ_LUT_CWB,
QOS_CREQ_LUT_MACROTILE_QSEED,
QOS_CREQ_LUT_LINEAR_QSEED,
QOS_PROP_MAX,
};
enum {
SSPP_OFF,
SSPP_SIZE,
@ -566,37 +568,34 @@ static struct sde_prop_type sde_perf_prop[] = {
false, PROP_TYPE_U32},
{PERF_AMORTIZABLE_THRESHOLD, "qcom,sde-amortizable-threshold",
false, PROP_TYPE_U32},
{PERF_DANGER_LUT, "qcom,sde-danger-lut", false, PROP_TYPE_U32_ARRAY},
{PERF_SAFE_LUT_LINEAR, "qcom,sde-safe-lut-linear", false,
PROP_TYPE_U32_ARRAY},
{PERF_SAFE_LUT_MACROTILE, "qcom,sde-safe-lut-macrotile", false,
PROP_TYPE_U32_ARRAY},
{PERF_SAFE_LUT_NRT, "qcom,sde-safe-lut-nrt", false,
PROP_TYPE_U32_ARRAY},
{PERF_SAFE_LUT_CWB, "qcom,sde-safe-lut-cwb", false,
PROP_TYPE_U32_ARRAY},
{PERF_QOS_LUT_LINEAR, "qcom,sde-qos-lut-linear", false,
PROP_TYPE_U32_ARRAY},
{PERF_QOS_LUT_MACROTILE, "qcom,sde-qos-lut-macrotile", false,
PROP_TYPE_U32_ARRAY},
{PERF_QOS_LUT_NRT, "qcom,sde-qos-lut-nrt", false,
PROP_TYPE_U32_ARRAY},
{PERF_QOS_LUT_CWB, "qcom,sde-qos-lut-cwb", false,
PROP_TYPE_U32_ARRAY},
{PERF_NUM_MNOC_PORTS, "qcom,sde-num-mnoc-ports",
false, PROP_TYPE_U32},
{PERF_AXI_BUS_WIDTH, "qcom,sde-axi-bus-width",
false, PROP_TYPE_U32},
{PERF_CDP_SETTING, "qcom,sde-cdp-setting", false,
PROP_TYPE_U32_ARRAY},
{PERF_CPU_MASK, "qcom,sde-qos-cpu-mask", false, PROP_TYPE_U32},
{PERF_CPU_DMA_LATENCY, "qcom,sde-qos-cpu-dma-latency", false,
PROP_TYPE_U32},
{PERF_QOS_LUT_MACROTILE_QSEED, "qcom,sde-qos-lut-macrotile-qseed",
};
static struct sde_prop_type sde_qos_prop[] = {
{QOS_REFRESH_RATES, "qcom,sde-qos-refresh-rates", false,
PROP_TYPE_U32_ARRAY},
{QOS_DANGER_LUT, "qcom,sde-danger-lut", false, PROP_TYPE_U32_ARRAY},
{QOS_SAFE_LUT, "qcom,sde-safe-lut", false, PROP_TYPE_U32_ARRAY},
{QOS_CREQ_LUT_LINEAR, "qcom,sde-qos-lut-linear", false,
PROP_TYPE_U32_ARRAY},
{QOS_CREQ_LUT_MACROTILE, "qcom,sde-qos-lut-macrotile", false,
PROP_TYPE_U32_ARRAY},
{QOS_CREQ_LUT_NRT, "qcom,sde-qos-lut-nrt", false,
PROP_TYPE_U32_ARRAY},
{QOS_CREQ_LUT_CWB, "qcom,sde-qos-lut-cwb", false,
PROP_TYPE_U32_ARRAY},
{QOS_CREQ_LUT_MACROTILE_QSEED, "qcom,sde-qos-lut-macrotile-qseed",
false, PROP_TYPE_U32_ARRAY},
{PERF_SAFE_LUT_MACROTILE_QSEED, "qcom,sde-safe-lut-macrotile-qseed",
{QOS_CREQ_LUT_LINEAR_QSEED, "qcom,sde-qos-lut-linear-qseed",
false, PROP_TYPE_U32_ARRAY},
{PERF_NUM_MNOC_PORTS, "qcom,sde-num-mnoc-ports",
false, PROP_TYPE_U32},
{PERF_AXI_BUS_WIDTH, "qcom,sde-axi-bus-width",
false, PROP_TYPE_U32},
};
static struct sde_prop_type sspp_prop[] = {
@ -3830,172 +3829,111 @@ static int _sde_perf_parse_dt_validate(struct device_node *np, int *prop_count)
if (rc)
return rc;
rc = _validate_dt_entry(np, &sde_perf_prop[PERF_DANGER_LUT], 1,
&prop_count[PERF_DANGER_LUT], NULL);
if (rc)
return rc;
rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_LINEAR], 1,
&prop_count[PERF_SAFE_LUT_LINEAR], NULL);
if (rc)
return rc;
rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_MACROTILE], 1,
&prop_count[PERF_SAFE_LUT_MACROTILE], NULL);
if (rc)
return rc;
rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_NRT], 1,
&prop_count[PERF_SAFE_LUT_NRT], NULL);
if (rc)
return rc;
rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_CWB], 1,
&prop_count[PERF_SAFE_LUT_CWB], NULL);
if (rc)
return rc;
rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_LINEAR], 1,
&prop_count[PERF_QOS_LUT_LINEAR], NULL);
if (rc)
return rc;
rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_MACROTILE], 1,
&prop_count[PERF_QOS_LUT_MACROTILE], NULL);
if (rc)
return rc;
rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_NRT], 1,
&prop_count[PERF_QOS_LUT_NRT], NULL);
if (rc)
return rc;
rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_CWB], 1,
&prop_count[PERF_QOS_LUT_CWB], NULL);
if (rc)
return rc;
rc = _validate_dt_entry(np, &sde_perf_prop[PERF_CDP_SETTING], 1,
&prop_count[PERF_CDP_SETTING], NULL);
if (rc)
return rc;
rc = _validate_dt_entry(np,
&sde_perf_prop[PERF_QOS_LUT_MACROTILE_QSEED], 1,
&prop_count[PERF_QOS_LUT_MACROTILE_QSEED], NULL);
if (rc)
return rc;
rc = _validate_dt_entry(np,
&sde_perf_prop[PERF_SAFE_LUT_MACROTILE_QSEED], 1,
&prop_count[PERF_SAFE_LUT_MACROTILE_QSEED], NULL);
return rc;
}
static int _sde_perf_parse_dt_cfg_qos(struct sde_mdss_cfg *cfg, int *prop_count,
static int _sde_qos_parse_dt_cfg(struct sde_mdss_cfg *cfg, int *prop_count,
struct sde_prop_value *prop_value, bool *prop_exists)
{
int j, k;
int i, j;
u32 qos_count = 1, index;
if (prop_exists[PERF_DANGER_LUT] && prop_count[PERF_DANGER_LUT] <=
SDE_QOS_LUT_USAGE_MAX) {
for (j = 0; j < prop_count[PERF_DANGER_LUT]; j++) {
cfg->perf.danger_lut_tbl[j] =
if (prop_exists[QOS_REFRESH_RATES]) {
qos_count = prop_count[QOS_REFRESH_RATES];
cfg->perf.qos_refresh_rate = kcalloc(qos_count,
sizeof(u32), GFP_KERNEL);
if (!cfg->perf.qos_refresh_rate)
goto end;
for (j = 0; j < qos_count; j++) {
cfg->perf.qos_refresh_rate[j] =
PROP_VALUE_ACCESS(prop_value,
PERF_DANGER_LUT, j);
SDE_DEBUG("danger usage:%d lut:0x%x\n",
j, cfg->perf.danger_lut_tbl[j]);
QOS_REFRESH_RATES, j);
SDE_DEBUG("qos usage:%d refresh rate:0x%x\n",
j, cfg->perf.qos_refresh_rate[j]);
}
}
cfg->perf.qos_refresh_count = qos_count;
cfg->perf.danger_lut = kcalloc(qos_count,
sizeof(u64) * SDE_QOS_LUT_USAGE_MAX, GFP_KERNEL);
cfg->perf.safe_lut = kcalloc(qos_count,
sizeof(u64) * SDE_QOS_LUT_USAGE_MAX, GFP_KERNEL);
cfg->perf.creq_lut = kcalloc(qos_count,
sizeof(u64) * SDE_QOS_LUT_USAGE_MAX, GFP_KERNEL);
if (!cfg->perf.creq_lut || !cfg->perf.safe_lut || !cfg->perf.danger_lut)
goto end;
if (prop_exists[QOS_DANGER_LUT] &&
prop_count[QOS_DANGER_LUT] >= (SDE_QOS_LUT_USAGE_MAX * qos_count)) {
for (i = 0; i < prop_count[QOS_DANGER_LUT]; i++) {
cfg->perf.danger_lut[i] =
PROP_VALUE_ACCESS(prop_value,
QOS_DANGER_LUT, i);
SDE_DEBUG("danger usage:%i lut:0x%x\n",
i, cfg->perf.danger_lut[i]);
}
}
for (j = 0; j < SDE_QOS_LUT_USAGE_MAX; j++) {
static const u32 safe_key[SDE_QOS_LUT_USAGE_MAX] = {
[SDE_QOS_LUT_USAGE_LINEAR] =
PERF_SAFE_LUT_LINEAR,
[SDE_QOS_LUT_USAGE_MACROTILE] =
PERF_SAFE_LUT_MACROTILE,
[SDE_QOS_LUT_USAGE_NRT] =
PERF_SAFE_LUT_NRT,
[SDE_QOS_LUT_USAGE_CWB] =
PERF_SAFE_LUT_CWB,
[SDE_QOS_LUT_USAGE_MACROTILE_QSEED] =
PERF_SAFE_LUT_MACROTILE_QSEED,
};
const u32 entry_size = 2;
int m, count;
int key = safe_key[j];
if (!prop_exists[key])
continue;
count = prop_count[key] / entry_size;
cfg->perf.sfe_lut_tbl[j].entries = kcalloc(count,
sizeof(struct sde_qos_lut_entry), GFP_KERNEL);
if (!cfg->perf.sfe_lut_tbl[j].entries)
return -ENOMEM;
for (k = 0, m = 0; k < count; k++, m += entry_size) {
u64 lut_lo;
cfg->perf.sfe_lut_tbl[j].entries[k].fl =
PROP_VALUE_ACCESS(prop_value, key, m);
lut_lo = PROP_VALUE_ACCESS(prop_value, key, m + 1);
cfg->perf.sfe_lut_tbl[j].entries[k].lut = lut_lo;
SDE_DEBUG("safe usage:%d.%d fl:%d lut:0x%llx\n",
j, k,
cfg->perf.sfe_lut_tbl[j].entries[k].fl,
cfg->perf.sfe_lut_tbl[j].entries[k].lut);
if (prop_exists[QOS_SAFE_LUT] &&
prop_count[QOS_SAFE_LUT] >= (SDE_QOS_LUT_USAGE_MAX * qos_count)) {
for (i = 0; i < prop_count[QOS_SAFE_LUT]; i++) {
cfg->perf.safe_lut[i] =
PROP_VALUE_ACCESS(prop_value,
QOS_SAFE_LUT, i);
SDE_DEBUG("safe usage:%d lut:0x%x\n",
i, cfg->perf.safe_lut[i]);
}
cfg->perf.sfe_lut_tbl[j].nentry = count;
}
for (j = 0; j < SDE_QOS_LUT_USAGE_MAX; j++) {
for (i = 0; i < SDE_QOS_LUT_USAGE_MAX; i++) {
static const u32 prop_key[SDE_QOS_LUT_USAGE_MAX] = {
[SDE_QOS_LUT_USAGE_LINEAR] =
PERF_QOS_LUT_LINEAR,
QOS_CREQ_LUT_LINEAR,
[SDE_QOS_LUT_USAGE_MACROTILE] =
PERF_QOS_LUT_MACROTILE,
QOS_CREQ_LUT_MACROTILE,
[SDE_QOS_LUT_USAGE_NRT] =
PERF_QOS_LUT_NRT,
QOS_CREQ_LUT_NRT,
[SDE_QOS_LUT_USAGE_CWB] =
PERF_QOS_LUT_CWB,
QOS_CREQ_LUT_CWB,
[SDE_QOS_LUT_USAGE_MACROTILE_QSEED] =
PERF_QOS_LUT_MACROTILE_QSEED,
QOS_CREQ_LUT_MACROTILE_QSEED,
[SDE_QOS_LUT_USAGE_LINEAR_QSEED] =
QOS_CREQ_LUT_LINEAR_QSEED,
};
const u32 entry_size = 3;
int m, count;
int key = prop_key[j];
int key = prop_key[i];
u64 lut_hi, lut_lo;
if (!prop_exists[key])
continue;
count = prop_count[key] / entry_size;
cfg->perf.qos_lut_tbl[j].entries = kcalloc(count,
sizeof(struct sde_qos_lut_entry), GFP_KERNEL);
if (!cfg->perf.qos_lut_tbl[j].entries)
return -ENOMEM;
for (k = 0, m = 0; k < count; k++, m += entry_size) {
u64 lut_hi, lut_lo;
cfg->perf.qos_lut_tbl[j].entries[k].fl =
PROP_VALUE_ACCESS(prop_value, key, m);
lut_hi = PROP_VALUE_ACCESS(prop_value, key, m + 1);
lut_lo = PROP_VALUE_ACCESS(prop_value, key, m + 2);
cfg->perf.qos_lut_tbl[j].entries[k].lut =
for (j = 0; j < qos_count; j++) {
lut_hi = PROP_VALUE_ACCESS(prop_value, key,
(j * 2) + 0);
lut_lo = PROP_VALUE_ACCESS(prop_value, key,
(j * 2) + 1);
index = (j * SDE_QOS_LUT_USAGE_MAX) + i;
cfg->perf.creq_lut[index] =
(lut_hi << 32) | lut_lo;
SDE_DEBUG("usage:%d.%d fl:%d lut:0x%llx\n",
j, k,
cfg->perf.qos_lut_tbl[j].entries[k].fl,
cfg->perf.qos_lut_tbl[j].entries[k].lut);
SDE_DEBUG("creq usage:%d lut:0x%llx\n",
index, cfg->perf.creq_lut[index]);
}
cfg->perf.qos_lut_tbl[j].nentry = count;
}
return 0;
end:
kfree(cfg->perf.qos_refresh_rate);
kfree(cfg->perf.creq_lut);
kfree(cfg->perf.danger_lut);
kfree(cfg->perf.safe_lut);
return -ENOMEM;
}
static void _sde_perf_parse_dt_cfg_populate(struct sde_mdss_cfg *cfg,
@ -4104,11 +4042,6 @@ static int _sde_perf_parse_dt_cfg(struct device_node *np,
_sde_perf_parse_dt_cfg_populate(cfg, prop_count, prop_value,
prop_exists);
rc = _sde_perf_parse_dt_cfg_qos(cfg, prop_count, prop_value,
prop_exists);
if (rc)
return rc;
if (prop_exists[PERF_CDP_SETTING]) {
const u32 prop_size = 2;
u32 count = prop_count[PERF_CDP_SETTING] / prop_size;
@ -4179,6 +4112,43 @@ end:
return rc;
}
static int sde_qos_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
{
int rc, prop_count[QOS_PROP_MAX];
struct sde_prop_value *prop_value = NULL;
bool prop_exists[QOS_PROP_MAX];
if (!cfg) {
SDE_ERROR("invalid argument\n");
rc = -EINVAL;
goto end;
}
prop_value = kzalloc(QOS_PROP_MAX *
sizeof(struct sde_prop_value), GFP_KERNEL);
if (!prop_value) {
rc = -ENOMEM;
goto end;
}
rc = _validate_dt_entry(np, sde_qos_prop, ARRAY_SIZE(sde_qos_prop),
prop_count, NULL);
if (rc)
goto freeprop;
rc = _read_dt_entry(np, sde_qos_prop, ARRAY_SIZE(sde_qos_prop),
prop_count, prop_exists, prop_value);
if (rc)
goto freeprop;
rc = _sde_qos_parse_dt_cfg(cfg, prop_count, prop_value, prop_exists);
freeprop:
kfree(prop_value);
end:
return rc;
}
static int sde_parse_merge_3d_dt(struct device_node *np,
struct sde_mdss_cfg *sde_cfg)
{
@ -4472,7 +4442,6 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
sde_cfg->sui_misr_supported = true;
sde_cfg->sui_block_xin_mask = 0x3F71;
sde_cfg->has_sui_blendstage = true;
sde_cfg->has_qos_fl_nocalc = true;
sde_cfg->has_3d_merge_reset = true;
sde_cfg->has_decimation = true;
sde_cfg->vbif_disable_inner_outer_shareable = true;
@ -4499,7 +4468,6 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
sde_cfg->has_decimation = true;
sde_cfg->sui_block_xin_mask = 0x2EE1;
sde_cfg->has_sui_blendstage = true;
sde_cfg->has_qos_fl_nocalc = true;
sde_cfg->has_3d_merge_reset = true;
sde_cfg->has_hdr = true;
sde_cfg->has_vig_p010 = true;
@ -4517,7 +4485,6 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
sde_cfg->sui_misr_supported = true;
sde_cfg->sui_block_xin_mask = 0xE71;
sde_cfg->has_sui_blendstage = true;
sde_cfg->has_qos_fl_nocalc = true;
sde_cfg->has_3d_merge_reset = true;
sde_cfg->vbif_disable_inner_outer_shareable = true;
} else if (IS_KONA_TARGET(hw_rev)) {
@ -4533,7 +4500,6 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
sde_cfg->sui_misr_supported = true;
sde_cfg->sui_block_xin_mask = 0x3F71;
sde_cfg->has_sui_blendstage = true;
sde_cfg->has_qos_fl_nocalc = true;
sde_cfg->has_3d_merge_reset = true;
sde_cfg->has_hdr = true;
sde_cfg->has_hdr_plus = true;
@ -4555,7 +4521,6 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
sde_cfg->sui_misr_supported = true;
sde_cfg->sui_block_xin_mask = 0xE71;
sde_cfg->has_sui_blendstage = true;
sde_cfg->has_qos_fl_nocalc = true;
sde_cfg->has_3d_merge_reset = true;
sde_cfg->has_hdr = true;
sde_cfg->has_hdr_plus = true;
@ -4647,10 +4612,6 @@ static int _sde_hardware_post_caps(struct sde_mdss_cfg *sde_cfg,
sde_cfg->sspp[i].sblk->maxvdeciexp);
}
if (sde_cfg->has_qos_fl_nocalc)
set_bit(SDE_PERF_SSPP_QOS_FL_NOCALC,
&sde_cfg->sspp[i].perf_features);
/*
* set sec-ui blocked SSPP feature flag based on blocked
* xin-mask if sec-ui-misr feature is enabled;
@ -4728,10 +4689,10 @@ void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg)
kfree(sde_cfg->limit_cfg[i].value_cfg);
}
for (i = 0; i < SDE_QOS_LUT_USAGE_MAX; i++) {
kfree(sde_cfg->perf.sfe_lut_tbl[i].entries);
kfree(sde_cfg->perf.qos_lut_tbl[i].entries);
}
kfree(sde_cfg->perf.qos_refresh_rate);
kfree(sde_cfg->perf.danger_lut);
kfree(sde_cfg->perf.safe_lut);
kfree(sde_cfg->perf.creq_lut);
kfree(sde_cfg->dma_formats);
kfree(sde_cfg->cursor_formats);
@ -4771,6 +4732,10 @@ struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev)
if (rc)
goto end;
rc = sde_qos_parse_dt(np, sde_cfg);
if (rc)
goto end;
rc = sde_rot_parse_dt(np, sde_cfg);
if (rc)
goto end;

View file

@ -270,7 +270,6 @@ enum {
* @SDE_PERF_SSPP_TS_PREFILL Supports prefill with traffic shaper
* @SDE_PERF_SSPP_TS_PREFILL_REC1 Supports prefill with traffic shaper multirec
* @SDE_PERF_SSPP_CDP Supports client driven prefetch
* @SDE_PERF_SSPP_QOS_FL_NOCALC Avoid fill level calc for QoS/danger/safe
* @SDE_PERF_SSPP_SYS_CACHE, SSPP supports system cache
* @SDE_PERF_SSPP_UIDLE, sspp supports uidle
* @SDE_PERF_SSPP_MAX Maximum value
@ -281,7 +280,6 @@ enum {
SDE_PERF_SSPP_TS_PREFILL,
SDE_PERF_SSPP_TS_PREFILL_REC1,
SDE_PERF_SSPP_CDP,
SDE_PERF_SSPP_QOS_FL_NOCALC,
SDE_PERF_SSPP_SYS_CACHE,
SDE_PERF_SSPP_UIDLE,
SDE_PERF_SSPP_MAX
@ -640,29 +638,10 @@ enum sde_qos_lut_usage {
SDE_QOS_LUT_USAGE_NRT,
SDE_QOS_LUT_USAGE_CWB,
SDE_QOS_LUT_USAGE_MACROTILE_QSEED,
SDE_QOS_LUT_USAGE_LINEAR_QSEED,
SDE_QOS_LUT_USAGE_MAX,
};
/**
* struct sde_qos_lut_entry - define QoS LUT table entry
* @fl: fill level, or zero on last entry to indicate default lut
* @lut: lut to use if equal to or less than fill level
*/
struct sde_qos_lut_entry {
u32 fl;
u64 lut;
};
/**
* struct sde_qos_lut_tbl - define QoS LUT table
* @nentry: number of entry in this table
* @entries: Pointer to table entries
*/
struct sde_qos_lut_tbl {
u32 nentry;
struct sde_qos_lut_entry *entries;
};
/**
* struct sde_sspp_sub_blks : SSPP sub-blocks
* @maxdwnscale: max downscale ratio supported(without DECIMATION)
@ -1302,9 +1281,11 @@ struct sde_sc_cfg {
* @downscaling_prefill_lines downscaling latency in lines
* @amortizable_theshold minimum y position for traffic shaping prefill
* @min_prefill_lines minimum pipeline latency in lines
* @danger_lut_tbl: LUT tables for danger signals
* @sfe_lut_tbl: LUT tables for safe signals
* @qos_lut_tbl: LUT tables for QoS signals
* @danger_lut: liner, linear_qseed, macrotile, etc. danger luts
* @sfe_lut: linear, macrotile, macrotile_qseed, etc. safe luts
* @creq_lut: linear, macrotile, non_realtime, cwb, etc. creq luts
* @qos_refresh_count: total refresh count for possible different luts
* @qos_refresh_rate: different refresh rates for luts
* @cdp_cfg cdp use case configurations
* @cpu_mask: pm_qos cpu mask value
* @cpu_dma_latency: pm_qos cpu dma latency value
@ -1330,9 +1311,11 @@ struct sde_perf_cfg {
u32 downscaling_prefill_lines;
u32 amortizable_threshold;
u32 min_prefill_lines;
u32 danger_lut_tbl[SDE_QOS_LUT_USAGE_MAX];
struct sde_qos_lut_tbl sfe_lut_tbl[SDE_QOS_LUT_USAGE_MAX];
struct sde_qos_lut_tbl qos_lut_tbl[SDE_QOS_LUT_USAGE_MAX];
u64 *danger_lut;
u64 *safe_lut;
u64 *creq_lut;
u32 qos_refresh_count;
u32 *qos_refresh_rate;
struct sde_perf_cdp_cfg cdp_cfg[SDE_PERF_CDP_USAGE_MAX];
u32 cpu_mask;
u32 cpu_dma_latency;
@ -1422,7 +1405,6 @@ struct sde_limit_cfg {
* @has_qsync Supports qsync feature
* @has_3d_merge_reset Supports 3D merge reset
* @has_decimation Supports decimation
* @has_qos_fl_nocalc flag to indicate QoS fill level needs no calculation
* @has_mixer_combined_alpha Mixer has single register for FG & BG alpha
* @vbif_disable_inner_outer_shareable VBIF requires disabling shareables
* @inline_disable_const_clr Disable constant color during inline rotate
@ -1483,7 +1465,6 @@ struct sde_mdss_cfg {
bool has_qsync;
bool has_3d_merge_reset;
bool has_decimation;
bool has_qos_fl_nocalc;
bool has_mixer_combined_alpha;
bool vbif_disable_inner_outer_shareable;
bool inline_disable_const_clr;

View file

@ -841,7 +841,7 @@ static void sde_hw_sspp_setup_solidfill(struct sde_hw_pipe *ctx, u32 color, enum
color);
}
static void sde_hw_sspp_setup_danger_safe_lut(struct sde_hw_pipe *ctx,
static void sde_hw_sspp_setup_qos_lut(struct sde_hw_pipe *ctx,
struct sde_hw_pipe_qos_cfg *cfg)
{
u32 idx;
@ -851,15 +851,6 @@ static void sde_hw_sspp_setup_danger_safe_lut(struct sde_hw_pipe *ctx,
SDE_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, cfg->danger_lut);
SDE_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, cfg->safe_lut);
}
static void sde_hw_sspp_setup_creq_lut(struct sde_hw_pipe *ctx,
struct sde_hw_pipe_qos_cfg *cfg)
{
u32 idx;
if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
return;
if (ctx->cap && test_bit(SDE_PERF_SSPP_QOS_8LVL,
&ctx->cap->perf_features)) {
@ -1230,9 +1221,8 @@ static void _setup_layer_ops(struct sde_hw_pipe *c,
c->ops.setup_excl_rect = _sde_hw_sspp_setup_excl_rect;
if (test_bit(SDE_PERF_SSPP_QOS, &features)) {
c->ops.setup_danger_safe_lut =
sde_hw_sspp_setup_danger_safe_lut;
c->ops.setup_creq_lut = sde_hw_sspp_setup_creq_lut;
c->ops.setup_qos_lut =
sde_hw_sspp_setup_qos_lut;
c->ops.setup_qos_ctrl = sde_hw_sspp_setup_qos_ctrl;
}

View file

@ -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.
*/
#ifndef _SDE_HW_SSPP_H
@ -460,21 +460,12 @@ struct sde_hw_sspp_ops {
enum sde_sspp_multirect_index idx);
/**
* setup_danger_safe_lut - setup danger safe LUTs
* setup_qos_lut - setup danger, safe, creq LUTs
* @ctx: Pointer to pipe context
* @cfg: Pointer to pipe QoS configuration
*
*/
void (*setup_danger_safe_lut)(struct sde_hw_pipe *ctx,
struct sde_hw_pipe_qos_cfg *cfg);
/**
* setup_creq_lut - setup CREQ LUT
* @ctx: Pointer to pipe context
* @cfg: Pointer to pipe QoS configuration
*
*/
void (*setup_creq_lut)(struct sde_hw_pipe *ctx,
void (*setup_qos_lut)(struct sde_hw_pipe *ctx,
struct sde_hw_pipe_qos_cfg *cfg);
/**

View file

@ -81,13 +81,14 @@ static void _sde_hw_cwb_ctrl_init(struct sde_mdss_cfg *m,
u32 blk_off;
char name[64] = {0};
if (b) {
b->base_off = addr;
b->blk_off = m->cwb_blk_off;
b->length = 0x20;
b->hwversion = m->hwversion;
b->log_mask = SDE_DBG_MASK_WB;
}
if (!b)
return;
b->base_off = addr;
b->blk_off = m->cwb_blk_off;
b->length = 0x20;
b->hwversion = m->hwversion;
b->log_mask = SDE_DBG_MASK_WB;
for (i = 0; i < m->pingpong_count; i++) {
snprintf(name, sizeof(name), "cwb%d", i);
@ -207,33 +208,7 @@ static void sde_hw_wb_roi(struct sde_hw_wb *ctx, struct sde_hw_wb_cfg *wb)
SDE_REG_WRITE(c, WB_OUT_SIZE, out_size);
}
static void sde_hw_wb_setup_danger_safe_lut(struct sde_hw_wb *ctx,
struct sde_hw_wb_qos_cfg *cfg)
{
struct sde_hw_blk_reg_map *c = &ctx->hw;
if (!ctx || !cfg)
return;
SDE_REG_WRITE(c, WB_DANGER_LUT, cfg->danger_lut);
SDE_REG_WRITE(c, WB_SAFE_LUT, cfg->safe_lut);
}
static void sde_hw_wb_setup_creq_lut(struct sde_hw_wb *ctx,
struct sde_hw_wb_qos_cfg *cfg)
{
struct sde_hw_blk_reg_map *c = &ctx->hw;
if (!ctx || !cfg)
return;
if (ctx->caps && test_bit(SDE_WB_QOS_8LVL, &ctx->caps->features)) {
SDE_REG_WRITE(c, WB_CREQ_LUT_0, cfg->creq_lut);
SDE_REG_WRITE(c, WB_CREQ_LUT_1, cfg->creq_lut >> 32);
}
}
static void sde_hw_wb_setup_qos_ctrl(struct sde_hw_wb *ctx,
static void sde_hw_wb_setup_qos_lut(struct sde_hw_wb *ctx,
struct sde_hw_wb_qos_cfg *cfg)
{
struct sde_hw_blk_reg_map *c = &ctx->hw;
@ -242,6 +217,14 @@ static void sde_hw_wb_setup_qos_ctrl(struct sde_hw_wb *ctx,
if (!ctx || !cfg)
return;
SDE_REG_WRITE(c, WB_DANGER_LUT, cfg->danger_lut);
SDE_REG_WRITE(c, WB_SAFE_LUT, cfg->safe_lut);
if (ctx->caps && test_bit(SDE_WB_QOS_8LVL, &ctx->caps->features)) {
SDE_REG_WRITE(c, WB_CREQ_LUT_0, cfg->creq_lut);
SDE_REG_WRITE(c, WB_CREQ_LUT_1, cfg->creq_lut >> 32);
}
if (cfg->danger_safe_en)
qos_ctrl |= WB_QOS_CTRL_DANGER_SAFE_EN;
@ -318,12 +301,8 @@ static void _setup_wb_ops(struct sde_hw_wb_ops *ops,
if (test_bit(SDE_WB_XY_ROI_OFFSET, &features))
ops->setup_roi = sde_hw_wb_roi;
if (test_bit(SDE_WB_QOS, &features)) {
ops->setup_danger_safe_lut =
sde_hw_wb_setup_danger_safe_lut;
ops->setup_creq_lut = sde_hw_wb_setup_creq_lut;
ops->setup_qos_ctrl = sde_hw_wb_setup_qos_ctrl;
}
if (test_bit(SDE_WB_QOS, &features))
ops->setup_qos_lut = sde_hw_wb_setup_qos_lut;
if (test_bit(SDE_WB_CDP, &features))
ops->setup_cdp = sde_hw_wb_setup_cdp;

View file

@ -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.
*/
#ifndef _SDE_HW_WB_H
@ -89,27 +89,11 @@ struct sde_hw_wb_ops {
struct sde_hw_wb_cfg *wb);
/**
* setup_danger_safe_lut - setup danger safe LUTs
* setup_qos_lut - setup danger, safe, creq, etc. LUTs
* @ctx: Pointer to pipe context
* @cfg: Pointer to pipe QoS configuration
*/
void (*setup_danger_safe_lut)(struct sde_hw_wb *ctx,
struct sde_hw_wb_qos_cfg *cfg);
/**
* setup_creq_lut - setup CREQ LUT
* @ctx: Pointer to pipe context
* @cfg: Pointer to pipe QoS configuration
*/
void (*setup_creq_lut)(struct sde_hw_wb *ctx,
struct sde_hw_wb_qos_cfg *cfg);
/**
* setup_qos_ctrl - setup QoS control
* @ctx: Pointer to pipe context
* @cfg: Pointer to pipe QoS configuration
*/
void (*setup_qos_ctrl)(struct sde_hw_wb *ctx,
void (*setup_qos_lut)(struct sde_hw_wb *ctx,
struct sde_hw_wb_qos_cfg *cfg);
/**

View file

@ -235,248 +235,88 @@ void sde_plane_setup_src_split_order(struct drm_plane *plane,
}
/**
* _sde_plane_calc_fill_level - calculate fill level of the given source format
* @plane: Pointer to drm plane
* @fmt: Pointer to source buffer format
* @src_wdith: width of source buffer
* Return: fill level corresponding to the source buffer/format or 0 if error
*/
static inline int _sde_plane_calc_fill_level(struct drm_plane *plane,
const struct sde_format *fmt, u32 src_width)
{
struct sde_plane *psde, *tmp;
struct sde_plane_state *pstate;
u32 fixed_buff_size;
u32 total_fl;
u32 hflip_bytes;
u32 unused_space;
if (!plane || !fmt || !plane->state || !src_width || !fmt->bpp) {
SDE_ERROR("invalid arguments\n");
return 0;
}
psde = to_sde_plane(plane);
if (psde->perf_features & BIT(SDE_PERF_SSPP_QOS_FL_NOCALC))
return 0;
pstate = to_sde_plane_state(plane->state);
fixed_buff_size = psde->pipe_sblk->pixel_ram_size;
list_for_each_entry(tmp, &psde->mplane_list, mplane_list) {
if (!sde_plane_enabled(tmp->base.state))
continue;
SDE_DEBUG("plane%d/%d src_width:%d/%d\n",
psde->base.base.id, tmp->base.base.id,
src_width, tmp->pipe_cfg.src_rect.w);
src_width = max_t(u32, src_width, tmp->pipe_cfg.src_rect.w);
}
if ((pstate->rotation & DRM_MODE_REFLECT_X) &&
SDE_FORMAT_IS_LINEAR(fmt))
hflip_bytes = (src_width + 32) * fmt->bpp;
else
hflip_bytes = 0;
if (fmt->fetch_planes == SDE_PLANE_PSEUDO_PLANAR) {
unused_space = 23 * 128;
if (fmt->chroma_sample == SDE_CHROMA_420) {
/* NV12 */
total_fl = (fixed_buff_size / 2 - hflip_bytes -
unused_space) / ((src_width + 32) * fmt->bpp);
} else {
/* non NV12 */
total_fl = (fixed_buff_size / 2 - hflip_bytes -
unused_space) * 2 / ((src_width + 32) *
fmt->bpp);
}
} else {
unused_space = 6 * 128;
if (pstate->multirect_mode == SDE_SSPP_MULTIRECT_PARALLEL) {
total_fl = (fixed_buff_size / 2 - hflip_bytes -
unused_space) * 2 / ((src_width + 32) *
fmt->bpp);
} else {
total_fl = (fixed_buff_size - hflip_bytes -
unused_space) * 2 / ((src_width + 32) *
fmt->bpp);
}
}
SDE_DEBUG("plane%u: pnum:%d fmt: %4.4s w:%u hf:%d us:%d fl:%u\n",
plane->base.id, psde->pipe - SSPP_VIG0,
(char *)&fmt->base.pixel_format,
src_width, hflip_bytes, unused_space, total_fl);
return total_fl;
}
/**
* _sde_plane_get_qos_lut - get LUT mapping based on fill level
* @tbl: Pointer to LUT table
* @total_fl: fill level
* Return: LUT setting corresponding to the fill level
*/
static u64 _sde_plane_get_qos_lut(const struct sde_qos_lut_tbl *tbl,
u32 total_fl)
{
int i;
if (!tbl || !tbl->nentry || !tbl->entries)
return 0;
for (i = 0; i < tbl->nentry; i++)
if (total_fl <= tbl->entries[i].fl)
return tbl->entries[i].lut;
/* if last fl is zero, use as default */
if (!tbl->entries[i-1].fl)
return tbl->entries[i-1].lut;
return 0;
}
/**
* _sde_plane_set_qos_lut - set QoS LUT of the given plane
* _sde_plane_set_qos_lut - set danger, safe and creq LUT of the given plane
* @plane: Pointer to drm plane
* @crtc: Pointer to drm crtc to find refresh rate on mode
* @fb: Pointer to framebuffer associated with the given plane
*/
static void _sde_plane_set_qos_lut(struct drm_plane *plane,
struct drm_crtc *crtc,
struct drm_framebuffer *fb)
{
struct sde_plane *psde;
const struct sde_format *fmt = NULL;
u64 qos_lut;
u32 total_fl = 0, lut_usage;
u32 frame_rate, qos_count, fps_index = 0, lut_index, index;
struct sde_perf_cfg *perf;
struct sde_plane_state *pstate;
if (!plane || !fb) {
SDE_ERROR("invalid arguments plane %d fb %d\n",
!plane, !fb);
SDE_ERROR("invalid arguments\n");
return;
}
psde = to_sde_plane(plane);
pstate = to_sde_plane_state(plane->state);
if (!psde->pipe_hw || !psde->pipe_sblk || !psde->catalog) {
SDE_ERROR("invalid arguments\n");
return;
} else if (!psde->pipe_hw->ops.setup_creq_lut) {
} else if (!psde->pipe_hw->ops.setup_qos_lut) {
return;
}
frame_rate = crtc->mode.vrefresh;
perf = &psde->catalog->perf;
qos_count = perf->qos_refresh_count;
while (qos_count && perf->qos_refresh_rate) {
if (frame_rate >= perf->qos_refresh_rate[qos_count - 1]) {
fps_index = qos_count - 1;
break;
}
qos_count--;
}
if (!psde->is_rt_pipe) {
lut_usage = SDE_QOS_LUT_USAGE_NRT;
lut_index = SDE_QOS_LUT_USAGE_NRT;
} else {
fmt = sde_get_sde_format_ext(
fb->format->format,
fb->modifier);
total_fl = _sde_plane_calc_fill_level(plane, fmt,
psde->pipe_cfg.src_rect.w);
if (fmt && SDE_FORMAT_IS_LINEAR(fmt))
lut_usage = SDE_QOS_LUT_USAGE_LINEAR;
else if (psde->features & BIT(SDE_SSPP_SCALER_QSEED3) ||
psde->features & BIT(SDE_SSPP_SCALER_QSEED3LITE))
lut_usage = SDE_QOS_LUT_USAGE_MACROTILE_QSEED;
if (fmt && SDE_FORMAT_IS_LINEAR(fmt) &&
pstate->scaler3_cfg.enable)
lut_index = SDE_QOS_LUT_USAGE_LINEAR_QSEED;
else if (fmt && SDE_FORMAT_IS_LINEAR(fmt))
lut_index = SDE_QOS_LUT_USAGE_LINEAR;
else if (pstate->scaler3_cfg.enable)
lut_index = SDE_QOS_LUT_USAGE_MACROTILE_QSEED;
else
lut_usage = SDE_QOS_LUT_USAGE_MACROTILE;
lut_index = SDE_QOS_LUT_USAGE_MACROTILE;
}
qos_lut = _sde_plane_get_qos_lut(
&psde->catalog->perf.qos_lut_tbl[lut_usage], total_fl);
psde->pipe_qos_cfg.creq_lut = qos_lut;
index = (fps_index * SDE_QOS_LUT_USAGE_MAX) + lut_index;
psde->pipe_qos_cfg.danger_lut = perf->danger_lut[index];
psde->pipe_qos_cfg.safe_lut = perf->safe_lut[index];
psde->pipe_qos_cfg.creq_lut = perf->creq_lut[index];
trace_sde_perf_set_qos_luts(psde->pipe - SSPP_VIG0,
(fmt) ? fmt->base.pixel_format : 0,
psde->is_rt_pipe, total_fl, qos_lut, lut_usage);
SDE_DEBUG("plane%u: pnum:%d fmt: %4.4s rt:%d fl:%u lut:0x%llx\n",
plane->base.id,
psde->pipe - SSPP_VIG0,
fmt ? (char *)&fmt->base.pixel_format : NULL,
psde->is_rt_pipe, total_fl, qos_lut);
psde->pipe_hw->ops.setup_creq_lut(psde->pipe_hw, &psde->pipe_qos_cfg);
}
/**
* _sde_plane_set_panic_lut - set danger/safe LUT of the given plane
* @plane: Pointer to drm plane
* @fb: Pointer to framebuffer associated with the given plane
*/
static void _sde_plane_set_danger_lut(struct drm_plane *plane,
struct drm_framebuffer *fb)
{
struct sde_plane *psde;
const struct sde_format *fmt = NULL;
u32 danger_lut, safe_lut;
u32 total_fl = 0, lut_usage;
if (!plane || !fb) {
SDE_ERROR("invalid arguments\n");
return;
}
psde = to_sde_plane(plane);
if (!psde->pipe_hw || !psde->pipe_sblk || !psde->catalog) {
SDE_ERROR("invalid arguments\n");
return;
} else if (!psde->pipe_hw->ops.setup_danger_safe_lut) {
return;
}
if (!psde->is_rt_pipe) {
danger_lut = psde->catalog->perf.danger_lut_tbl
[SDE_QOS_LUT_USAGE_NRT];
lut_usage = SDE_QOS_LUT_USAGE_NRT;
} else {
fmt = sde_get_sde_format_ext(
fb->format->format,
fb->modifier);
total_fl = _sde_plane_calc_fill_level(plane, fmt,
psde->pipe_cfg.src_rect.w);
if (fmt && SDE_FORMAT_IS_LINEAR(fmt)) {
danger_lut = psde->catalog->perf.danger_lut_tbl
[SDE_QOS_LUT_USAGE_LINEAR];
lut_usage = SDE_QOS_LUT_USAGE_LINEAR;
} else if (psde->features & BIT(SDE_SSPP_SCALER_QSEED3)) {
danger_lut = psde->catalog->perf.danger_lut_tbl
[SDE_QOS_LUT_USAGE_MACROTILE_QSEED];
lut_usage = SDE_QOS_LUT_USAGE_MACROTILE_QSEED;
} else {
danger_lut = psde->catalog->perf.danger_lut_tbl
[SDE_QOS_LUT_USAGE_MACROTILE];
lut_usage = SDE_QOS_LUT_USAGE_MACROTILE;
}
}
safe_lut = (u32) _sde_plane_get_qos_lut(
&psde->catalog->perf.sfe_lut_tbl[lut_usage], total_fl);
psde->pipe_qos_cfg.danger_lut = danger_lut;
psde->pipe_qos_cfg.safe_lut = safe_lut;
trace_sde_perf_set_danger_luts(psde->pipe - SSPP_VIG0,
(fmt) ? fmt->base.pixel_format : 0,
(fmt) ? fmt->fetch_mode : 0,
psde->pipe_qos_cfg.danger_lut,
psde->pipe_qos_cfg.safe_lut);
psde->pipe_qos_cfg.safe_lut,
psde->pipe_qos_cfg.creq_lut);
SDE_DEBUG("plane%u: pnum:%d fmt:%4.4s mode:%d fl:%d luts[0x%x,0x%x]\n",
SDE_DEBUG(
"plane%u: pnum:%d fmt:%4.4s fps:%d mode:%d luts[0x%x,0x%x 0x%llx]\n",
plane->base.id,
psde->pipe - SSPP_VIG0,
fmt ? (char *)&fmt->base.pixel_format : NULL,
fmt ? fmt->fetch_mode : -1, total_fl,
fmt ? (char *)&fmt->base.pixel_format : NULL, frame_rate,
fmt ? fmt->fetch_mode : -1,
psde->pipe_qos_cfg.danger_lut,
psde->pipe_qos_cfg.safe_lut);
psde->pipe_qos_cfg.safe_lut,
psde->pipe_qos_cfg.creq_lut);
psde->pipe_hw->ops.setup_danger_safe_lut(psde->pipe_hw,
&psde->pipe_qos_cfg);
psde->pipe_hw->ops.setup_qos_lut(psde->pipe_hw, &psde->pipe_qos_cfg);
}
/**
@ -3202,8 +3042,7 @@ static void _sde_plane_update_properties(struct drm_plane *plane,
psde->pipe_hw->ops.setup_sharpening)
_sde_plane_update_sharpening(psde);
_sde_plane_set_qos_lut(plane, fb);
_sde_plane_set_danger_lut(plane, fb);
_sde_plane_set_qos_lut(plane, crtc, fb);
if (plane->type != DRM_PLANE_TYPE_CURSOR) {
_sde_plane_set_qos_ctrl(plane, true, SDE_PLANE_QOS_PANIC_CTRL);

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
*/
#if !defined(_SDE_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
@ -16,41 +16,16 @@
#define TRACE_INCLUDE_FILE sde_trace
TRACE_EVENT(sde_perf_set_qos_luts,
TP_PROTO(u32 pnum, u32 fmt, bool rt, u32 fl,
u32 lut, u32 lut_usage),
TP_ARGS(pnum, fmt, rt, fl, lut, lut_usage),
TP_STRUCT__entry(
__field(u32, pnum)
__field(u32, fmt)
__field(bool, rt)
__field(u32, fl)
__field(u64, lut)
__field(u32, lut_usage)
),
TP_fast_assign(
__entry->pnum = pnum;
__entry->fmt = fmt;
__entry->rt = rt;
__entry->fl = fl;
__entry->lut = lut;
__entry->lut_usage = lut_usage;
),
TP_printk("pnum=%d fmt=0x%x rt=%d fl=%d lut=0x%llx lut_usage=%d",
__entry->pnum, __entry->fmt,
__entry->rt, __entry->fl,
__entry->lut, __entry->lut_usage)
);
TRACE_EVENT(sde_perf_set_danger_luts,
TP_PROTO(u32 pnum, u32 fmt, u32 mode, u32 danger_lut,
u32 safe_lut),
TP_ARGS(pnum, fmt, mode, danger_lut, safe_lut),
u32 safe_lut, u64 creq_lut),
TP_ARGS(pnum, fmt, mode, danger_lut, safe_lut, creq_lut),
TP_STRUCT__entry(
__field(u32, pnum)
__field(u32, fmt)
__field(u32, mode)
__field(u32, danger_lut)
__field(u32, safe_lut)
__field(u64, creq_lut)
),
TP_fast_assign(
__entry->pnum = pnum;
@ -58,11 +33,12 @@ TRACE_EVENT(sde_perf_set_danger_luts,
__entry->mode = mode;
__entry->danger_lut = danger_lut;
__entry->safe_lut = safe_lut;
__entry->creq_lut = creq_lut;
),
TP_printk("pnum=%d fmt=0x%x mode=%d luts[0x%x, 0x%x]",
TP_printk("pnum=%d fmt=0x%x mode=%d luts[0x%x, 0x%x 0x%llx]",
__entry->pnum, __entry->fmt,
__entry->mode, __entry->danger_lut,
__entry->safe_lut)
__entry->safe_lut, __entry->creq_lut)
);
TRACE_EVENT(sde_perf_set_ot,