diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index 5b0c838e69..7298fc7a9e 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -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); } /** diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index b87269a52f..2a23278de0 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -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, @@ -562,37 +564,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[] = { @@ -3814,172 +3813,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, @@ -4088,11 +4026,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; @@ -4163,6 +4096,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) { @@ -4456,7 +4426,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; @@ -4483,7 +4452,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; @@ -4501,7 +4469,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)) { @@ -4517,7 +4484,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; @@ -4539,7 +4505,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; @@ -4631,10 +4596,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; @@ -4712,10 +4673,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); @@ -4755,6 +4716,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; diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index f7754840a6..2b0008974e 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -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; diff --git a/msm/sde/sde_hw_sspp.c b/msm/sde/sde_hw_sspp.c index cb3b0e7a58..ecc5487637 100644 --- a/msm/sde/sde_hw_sspp.c +++ b/msm/sde/sde_hw_sspp.c @@ -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; } diff --git a/msm/sde/sde_hw_sspp.h b/msm/sde/sde_hw_sspp.h index 5f06ec42e2..46b93fe399 100644 --- a/msm/sde/sde_hw_sspp.h +++ b/msm/sde/sde_hw_sspp.h @@ -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); /** diff --git a/msm/sde/sde_hw_wb.c b/msm/sde/sde_hw_wb.c index 277c1d7325..72b79e82c9 100644 --- a/msm/sde/sde_hw_wb.c +++ b/msm/sde/sde_hw_wb.c @@ -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; diff --git a/msm/sde/sde_hw_wb.h b/msm/sde/sde_hw_wb.h index 0f02a14b5a..a6c95cc5eb 100644 --- a/msm/sde/sde_hw_wb.h +++ b/msm/sde/sde_hw_wb.h @@ -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); /** diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 450a04258a..edfd96bcfc 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -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); diff --git a/msm/sde/sde_trace.h b/msm/sde/sde_trace.h index df6bd15073..fbfa9aa552 100644 --- a/msm/sde/sde_trace.h +++ b/msm/sde/sde_trace.h @@ -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,