mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
Merge "disp: msm: sde: support fps based qos setting"
This commit is contained in:
commit
8a690a0b80
9 changed files with 258 additions and 569 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue