Loading drivers/gpu/drm/msm/sde/sde_hw_catalog.c +400 −324 Original line number Diff line number Diff line Loading @@ -2606,85 +2606,10 @@ static int sde_uidle_parse_dt(struct device_node *np, return 0; } static int sde_vbif_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) static int _sde_vbif_populate_ot_parsing(struct sde_vbif_cfg *vbif, struct sde_prop_value *prop_value, int *prop_count) { int rc, prop_count[VBIF_PROP_MAX], i, j, k; struct sde_prop_value *prop_value = NULL; bool prop_exists[VBIF_PROP_MAX]; u32 off_count, vbif_len; struct sde_vbif_cfg *vbif; if (!sde_cfg) { SDE_ERROR("invalid argument\n"); rc = -EINVAL; goto end; } prop_value = kzalloc(VBIF_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; } rc = _validate_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count, &off_count); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_RD_LIMIT], 1, &prop_count[VBIF_DYNAMIC_OT_RD_LIMIT], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_WR_LIMIT], 1, &prop_count[VBIF_DYNAMIC_OT_WR_LIMIT], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_RT_REMAP], 1, &prop_count[VBIF_QOS_RT_REMAP], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_NRT_REMAP], 1, &prop_count[VBIF_QOS_NRT_REMAP], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_0], 1, &prop_count[VBIF_MEMTYPE_0], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_1], 1, &prop_count[VBIF_MEMTYPE_1], NULL); if (rc) goto end; sde_cfg->vbif_count = off_count; rc = _read_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count, prop_exists, prop_value); if (rc) goto end; vbif_len = PROP_VALUE_ACCESS(prop_value, VBIF_LEN, 0); if (!prop_exists[VBIF_LEN]) vbif_len = DEFAULT_SDE_HW_BLOCK_LEN; for (i = 0; i < off_count; i++) { vbif = sde_cfg->vbif + i; vbif->base = PROP_VALUE_ACCESS(prop_value, VBIF_OFF, i); vbif->len = vbif_len; vbif->id = VBIF_0 + PROP_VALUE_ACCESS(prop_value, VBIF_ID, i); snprintf(vbif->name, SDE_HW_BLK_NAME_LEN, "vbif_%u", vbif->id - VBIF_0); SDE_DEBUG("vbif:%d\n", vbif->id - VBIF_0); vbif->xin_halt_timeout = VBIF_XIN_HALT_TIMEOUT; int j, k; vbif->default_ot_rd_limit = PROP_VALUE_ACCESS(prop_value, VBIF_DEFAULT_OT_RD_LIMIT, 0); Loading @@ -2705,10 +2630,8 @@ static int sde_vbif_parse_dt(struct device_node *np, vbif->dynamic_ot_rd_tbl.count, sizeof(struct sde_vbif_dynamic_ot_cfg), GFP_KERNEL); if (!vbif->dynamic_ot_rd_tbl.cfg) { rc = -ENOMEM; goto end; } if (!vbif->dynamic_ot_rd_tbl.cfg) return -ENOMEM; } for (j = 0, k = 0; j < vbif->dynamic_ot_rd_tbl.count; j++) { Loading @@ -2732,10 +2655,8 @@ static int sde_vbif_parse_dt(struct device_node *np, vbif->dynamic_ot_wr_tbl.count, sizeof(struct sde_vbif_dynamic_ot_cfg), GFP_KERNEL); if (!vbif->dynamic_ot_wr_tbl.cfg) { rc = -ENOMEM; goto end; } if (!vbif->dynamic_ot_wr_tbl.cfg) return -ENOMEM; } for (j = 0, k = 0; j < vbif->dynamic_ot_wr_tbl.count; j++) { Loading @@ -2755,6 +2676,15 @@ static int sde_vbif_parse_dt(struct device_node *np, vbif->dynamic_ot_wr_tbl.count) set_bit(SDE_VBIF_QOS_OTLIM, &vbif->features); return 0; } static int _sde_vbif_populate_qos_parsing(struct sde_mdss_cfg *sde_cfg, struct sde_vbif_cfg *vbif, struct sde_prop_value *prop_value, int *prop_count) { int j; vbif->qos_rt_tbl.npriority_lvl = prop_count[VBIF_QOS_RT_REMAP]; SDE_DEBUG("qos_rt_tbl.npriority_lvl=%u\n", Loading @@ -2763,10 +2693,8 @@ static int sde_vbif_parse_dt(struct device_node *np, vbif->qos_rt_tbl.priority_lvl = kcalloc( vbif->qos_rt_tbl.npriority_lvl, sizeof(u32), GFP_KERNEL); if (!vbif->qos_rt_tbl.priority_lvl) { rc = -ENOMEM; goto end; } if (!vbif->qos_rt_tbl.priority_lvl) return -ENOMEM; } else if (vbif->qos_rt_tbl.npriority_lvl) { vbif->qos_rt_tbl.npriority_lvl = 0; vbif->qos_rt_tbl.priority_lvl = NULL; Loading @@ -2790,10 +2718,8 @@ static int sde_vbif_parse_dt(struct device_node *np, vbif->qos_nrt_tbl.priority_lvl = kcalloc( vbif->qos_nrt_tbl.npriority_lvl, sizeof(u32), GFP_KERNEL); if (!vbif->qos_nrt_tbl.priority_lvl) { rc = -ENOMEM; goto end; } if (!vbif->qos_nrt_tbl.priority_lvl) return -ENOMEM; } else if (vbif->qos_nrt_tbl.npriority_lvl) { vbif->qos_nrt_tbl.npriority_lvl = 0; vbif->qos_nrt_tbl.priority_lvl = NULL; Loading @@ -2812,6 +2738,35 @@ static int sde_vbif_parse_dt(struct device_node *np, vbif->qos_nrt_tbl.npriority_lvl) set_bit(SDE_VBIF_QOS_REMAP, &vbif->features); return 0; } static int _sde_vbif_populate(struct sde_mdss_cfg *sde_cfg, struct sde_vbif_cfg *vbif, struct sde_prop_value *prop_value, int *prop_count, u32 vbif_len, int i) { int j, k, rc; vbif = sde_cfg->vbif + i; vbif->base = PROP_VALUE_ACCESS(prop_value, VBIF_OFF, i); vbif->len = vbif_len; vbif->id = VBIF_0 + PROP_VALUE_ACCESS(prop_value, VBIF_ID, i); snprintf(vbif->name, SDE_HW_BLK_NAME_LEN, "vbif_%u", vbif->id - VBIF_0); SDE_DEBUG("vbif:%d\n", vbif->id - VBIF_0); vbif->xin_halt_timeout = VBIF_XIN_HALT_TIMEOUT; rc = _sde_vbif_populate_ot_parsing(vbif, prop_value, prop_count); if (rc) return rc; rc = _sde_vbif_populate_qos_parsing(sde_cfg, vbif, prop_value, prop_count); if (rc) return rc; vbif->memtype_count = prop_count[VBIF_MEMTYPE_0] + prop_count[VBIF_MEMTYPE_1]; if (vbif->memtype_count > MAX_XIN_COUNT) { Loading @@ -2824,6 +2779,83 @@ static int sde_vbif_parse_dt(struct device_node *np, for (j = 0; j < prop_count[VBIF_MEMTYPE_1]; j++) vbif->memtype[k++] = PROP_VALUE_ACCESS( prop_value, VBIF_MEMTYPE_1, j); return 0; } static int sde_vbif_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) { int rc, prop_count[VBIF_PROP_MAX], i; struct sde_prop_value *prop_value = NULL; bool prop_exists[VBIF_PROP_MAX]; u32 off_count, vbif_len; struct sde_vbif_cfg *vbif; if (!sde_cfg) { SDE_ERROR("invalid argument\n"); rc = -EINVAL; goto end; } prop_value = kzalloc(VBIF_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; } rc = _validate_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count, &off_count); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_RD_LIMIT], 1, &prop_count[VBIF_DYNAMIC_OT_RD_LIMIT], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_WR_LIMIT], 1, &prop_count[VBIF_DYNAMIC_OT_WR_LIMIT], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_RT_REMAP], 1, &prop_count[VBIF_QOS_RT_REMAP], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_NRT_REMAP], 1, &prop_count[VBIF_QOS_NRT_REMAP], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_0], 1, &prop_count[VBIF_MEMTYPE_0], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_1], 1, &prop_count[VBIF_MEMTYPE_1], NULL); if (rc) goto end; sde_cfg->vbif_count = off_count; rc = _read_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count, prop_exists, prop_value); if (rc) goto end; vbif_len = PROP_VALUE_ACCESS(prop_value, VBIF_LEN, 0); if (!prop_exists[VBIF_LEN]) vbif_len = DEFAULT_SDE_HW_BLOCK_LEN; for (i = 0; i < off_count; i++) { rc = _sde_vbif_populate(sde_cfg, vbif, prop_value, prop_count, vbif_len, i); if (rc) goto end; } end: Loading Loading @@ -2934,57 +2966,9 @@ static int sde_pp_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) return rc; } static int sde_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) static int _sde_parse_prop_check(struct sde_mdss_cfg *cfg, bool prop_exists[SDE_PROP_MAX], struct sde_prop_value *prop_value) { int rc, i, dma_rc, len, prop_count[SDE_PROP_MAX]; struct sde_prop_value *prop_value = NULL; bool prop_exists[SDE_PROP_MAX]; const char *type; u32 major_version; if (!cfg) { SDE_ERROR("invalid argument\n"); rc = -EINVAL; goto end; } prop_value = kzalloc(SDE_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; } rc = _validate_dt_entry(np, sde_prop, ARRAY_SIZE(sde_prop), prop_count, &len); if (rc) goto end; rc = _validate_dt_entry(np, &sde_prop[SEC_SID_MASK], 1, &prop_count[SEC_SID_MASK], NULL); if (rc) goto end; rc = _read_dt_entry(np, sde_prop, ARRAY_SIZE(sde_prop), prop_count, prop_exists, prop_value); if (rc) goto end; cfg->mdss_count = 1; cfg->mdss[0].base = MDSS_BASE_OFFSET; cfg->mdss[0].id = MDP_TOP; snprintf(cfg->mdss[0].name, SDE_HW_BLK_NAME_LEN, "mdss_%u", cfg->mdss[0].id - MDP_TOP); cfg->mdp_count = 1; cfg->mdp[0].id = MDP_TOP; snprintf(cfg->mdp[0].name, SDE_HW_BLK_NAME_LEN, "top_%u", cfg->mdp[0].id - MDP_TOP); cfg->mdp[0].base = PROP_VALUE_ACCESS(prop_value, SDE_OFF, 0); cfg->mdp[0].len = PROP_VALUE_ACCESS(prop_value, SDE_LEN, 0); if (!prop_exists[SDE_LEN]) cfg->mdp[0].len = DEFAULT_SDE_HW_BLOCK_LEN; cfg->max_sspp_linewidth = PROP_VALUE_ACCESS(prop_value, SSPP_LINEWIDTH, 0); if (!prop_exists[SSPP_LINEWIDTH]) Loading Loading @@ -3035,23 +3019,77 @@ static int sde_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) cfg->mdp[0].smart_panel_align_mode = PROP_VALUE_ACCESS(prop_value, SMART_PANEL_ALIGN_MODE, 0); major_version = SDE_HW_MAJOR(cfg->hwversion); if (major_version < SDE_HW_MAJOR(SDE_HW_VER_500)) set_bit(SDE_MDP_VSYNC_SEL, &cfg->mdp[0].features); if (prop_exists[SEC_SID_MASK]) { cfg->sec_sid_mask_count = prop_count[SEC_SID_MASK]; for (i = 0; i < cfg->sec_sid_mask_count; i++) cfg->sec_sid_mask[i] = PROP_VALUE_ACCESS(prop_value, SEC_SID_MASK, i); return 0; } rc = of_property_read_string(np, sde_prop[QSEED_TYPE].prop_name, &type); if (!rc && !strcmp(type, "qseedv3")) { cfg->qseed_type = SDE_SSPP_SCALER_QSEED3; } else if (!rc && !strcmp(type, "qseedv3lite")) { cfg->qseed_type = SDE_SSPP_SCALER_QSEED3LITE; static int sde_top_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) { int rc, i, dma_rc, len, prop_count[SDE_PROP_MAX]; struct sde_prop_value *prop_value = NULL; bool prop_exists[SDE_PROP_MAX]; const char *type; u32 major_version; if (!cfg) { SDE_ERROR("invalid argument\n"); return -EINVAL; } prop_value = kzalloc(SDE_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) return -ENOMEM; rc = _validate_dt_entry(np, sde_prop, ARRAY_SIZE(sde_prop), prop_count, &len); if (rc) goto end; rc = _validate_dt_entry(np, &sde_prop[SEC_SID_MASK], 1, &prop_count[SEC_SID_MASK], NULL); if (rc) goto end; rc = _read_dt_entry(np, sde_prop, ARRAY_SIZE(sde_prop), prop_count, prop_exists, prop_value); if (rc) goto end; cfg->mdss_count = 1; cfg->mdss[0].base = MDSS_BASE_OFFSET; cfg->mdss[0].id = MDP_TOP; snprintf(cfg->mdss[0].name, SDE_HW_BLK_NAME_LEN, "mdss_%u", cfg->mdss[0].id - MDP_TOP); cfg->mdp_count = 1; cfg->mdp[0].id = MDP_TOP; snprintf(cfg->mdp[0].name, SDE_HW_BLK_NAME_LEN, "top_%u", cfg->mdp[0].id - MDP_TOP); cfg->mdp[0].base = PROP_VALUE_ACCESS(prop_value, SDE_OFF, 0); cfg->mdp[0].len = PROP_VALUE_ACCESS(prop_value, SDE_LEN, 0); if (!prop_exists[SDE_LEN]) cfg->mdp[0].len = DEFAULT_SDE_HW_BLOCK_LEN; rc = _sde_parse_prop_check(cfg, prop_exists, prop_value); if (rc) SDE_ERROR("sde parse property check failed\n"); major_version = SDE_HW_MAJOR(cfg->hwversion); if (major_version < SDE_HW_MAJOR(SDE_HW_VER_500)) set_bit(SDE_MDP_VSYNC_SEL, &cfg->mdp[0].features); if (prop_exists[SEC_SID_MASK]) { cfg->sec_sid_mask_count = prop_count[SEC_SID_MASK]; for (i = 0; i < cfg->sec_sid_mask_count; i++) cfg->sec_sid_mask[i] = PROP_VALUE_ACCESS(prop_value, SEC_SID_MASK, i); } rc = of_property_read_string(np, sde_prop[QSEED_TYPE].prop_name, &type); if (!rc && !strcmp(type, "qseedv3")) { cfg->qseed_type = SDE_SSPP_SCALER_QSEED3; } else if (!rc && !strcmp(type, "qseedv3lite")) { cfg->qseed_type = SDE_SSPP_SCALER_QSEED3LITE; } else if (!rc && !strcmp(type, "qseedv2")) { cfg->qseed_type = SDE_SSPP_SCALER_QSEED2; } else if (rc) { Loading Loading @@ -3132,178 +3170,82 @@ static int sde_parse_reg_dma_dt(struct device_node *np, return 0; } static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) static int _sde_perf_parse_dt_validate(struct device_node *np, int *prop_count) { int rc, len, prop_count[PERF_PROP_MAX]; struct sde_prop_value *prop_value = NULL; bool prop_exists[PERF_PROP_MAX]; const char *str = NULL; int j, k; if (!cfg) { SDE_ERROR("invalid argument\n"); rc = -EINVAL; goto end; } prop_value = kzalloc(PERF_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; } int rc, len; rc = _validate_dt_entry(np, sde_perf_prop, ARRAY_SIZE(sde_perf_prop), prop_count, &len); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_DANGER_LUT], 1, &prop_count[PERF_DANGER_LUT], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_LINEAR], 1, &prop_count[PERF_SAFE_LUT_LINEAR], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_MACROTILE], 1, &prop_count[PERF_SAFE_LUT_MACROTILE], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_NRT], 1, &prop_count[PERF_SAFE_LUT_NRT], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_CWB], 1, &prop_count[PERF_SAFE_LUT_CWB], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_LINEAR], 1, &prop_count[PERF_QOS_LUT_LINEAR], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_MACROTILE], 1, &prop_count[PERF_QOS_LUT_MACROTILE], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_NRT], 1, &prop_count[PERF_QOS_LUT_NRT], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_CWB], 1, &prop_count[PERF_QOS_LUT_CWB], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_CDP_SETTING], 1, &prop_count[PERF_CDP_SETTING], NULL); if (rc) goto freeprop; 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) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_MACROTILE_QSEED], 1, &prop_count[PERF_SAFE_LUT_MACROTILE_QSEED], NULL); if (rc) goto freeprop; rc = _read_dt_entry(np, sde_perf_prop, ARRAY_SIZE(sde_perf_prop), prop_count, prop_exists, prop_value); if (rc) goto freeprop; cfg->perf.max_bw_low = prop_exists[PERF_MAX_BW_LOW] ? PROP_VALUE_ACCESS(prop_value, PERF_MAX_BW_LOW, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.max_bw_high = prop_exists[PERF_MAX_BW_HIGH] ? PROP_VALUE_ACCESS(prop_value, PERF_MAX_BW_HIGH, 0) : DEFAULT_MAX_BW_HIGH; cfg->perf.min_core_ib = prop_exists[PERF_MIN_CORE_IB] ? PROP_VALUE_ACCESS(prop_value, PERF_MIN_CORE_IB, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.min_llcc_ib = prop_exists[PERF_MIN_LLCC_IB] ? PROP_VALUE_ACCESS(prop_value, PERF_MIN_LLCC_IB, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.min_dram_ib = prop_exists[PERF_MIN_DRAM_IB] ? PROP_VALUE_ACCESS(prop_value, PERF_MIN_DRAM_IB, 0) : DEFAULT_MAX_BW_LOW; /* * The following performance parameters (e.g. core_ib_ff) are * mapped directly as device tree string constants. */ rc = of_property_read_string(np, sde_perf_prop[PERF_CORE_IB_FF].prop_name, &str); cfg->perf.core_ib_ff = rc ? DEFAULT_CORE_IB_FF : str; rc = of_property_read_string(np, sde_perf_prop[PERF_CORE_CLK_FF].prop_name, &str); cfg->perf.core_clk_ff = rc ? DEFAULT_CORE_CLK_FF : str; rc = of_property_read_string(np, sde_perf_prop[PERF_COMP_RATIO_RT].prop_name, &str); cfg->perf.comp_ratio_rt = rc ? DEFAULT_COMP_RATIO_RT : str; rc = of_property_read_string(np, sde_perf_prop[PERF_COMP_RATIO_NRT].prop_name, &str); cfg->perf.comp_ratio_nrt = rc ? DEFAULT_COMP_RATIO_NRT : str; rc = 0; return rc; } cfg->perf.undersized_prefill_lines = prop_exists[PERF_UNDERSIZED_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_UNDERSIZED_PREFILL_LINES, 0) : DEFAULT_UNDERSIZED_PREFILL_LINES; cfg->perf.xtra_prefill_lines = prop_exists[PERF_XTRA_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_XTRA_PREFILL_LINES, 0) : DEFAULT_XTRA_PREFILL_LINES; cfg->perf.dest_scale_prefill_lines = prop_exists[PERF_DEST_SCALE_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_DEST_SCALE_PREFILL_LINES, 0) : DEFAULT_DEST_SCALE_PREFILL_LINES; cfg->perf.macrotile_prefill_lines = prop_exists[PERF_MACROTILE_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_MACROTILE_PREFILL_LINES, 0) : DEFAULT_MACROTILE_PREFILL_LINES; cfg->perf.yuv_nv12_prefill_lines = prop_exists[PERF_YUV_NV12_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_YUV_NV12_PREFILL_LINES, 0) : DEFAULT_YUV_NV12_PREFILL_LINES; cfg->perf.linear_prefill_lines = prop_exists[PERF_LINEAR_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_LINEAR_PREFILL_LINES, 0) : DEFAULT_LINEAR_PREFILL_LINES; cfg->perf.downscaling_prefill_lines = prop_exists[PERF_DOWNSCALING_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_DOWNSCALING_PREFILL_LINES, 0) : DEFAULT_DOWNSCALING_PREFILL_LINES; cfg->perf.amortizable_threshold = prop_exists[PERF_AMORTIZABLE_THRESHOLD] ? PROP_VALUE_ACCESS(prop_value, PERF_AMORTIZABLE_THRESHOLD, 0) : DEFAULT_AMORTIZABLE_THRESHOLD; static int _sde_perf_parse_dt_cfg_qos(struct sde_mdss_cfg *cfg, int *prop_count, struct sde_prop_value *prop_value, bool *prop_exists) { int j, k; if (prop_exists[PERF_DANGER_LUT] && prop_count[PERF_DANGER_LUT] <= SDE_QOS_LUT_USAGE_MAX) { Loading Loading @@ -3340,10 +3282,8 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) 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) { rc = -ENOMEM; goto freeprop; } if (!cfg->perf.sfe_lut_tbl[j].entries) return -ENOMEM; for (k = 0, m = 0; k < count; k++, m += entry_size) { u64 lut_lo; Loading Loading @@ -3384,10 +3324,8 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) 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) { rc = -ENOMEM; goto freeprop; } 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; Loading @@ -3406,6 +3344,110 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) cfg->perf.qos_lut_tbl[j].nentry = count; } return 0; } static void _sde_perf_parse_dt_cfg_populate(struct sde_mdss_cfg *cfg, int *prop_count, struct sde_prop_value *prop_value, bool *prop_exists) { cfg->perf.max_bw_low = prop_exists[PERF_MAX_BW_LOW] ? PROP_VALUE_ACCESS(prop_value, PERF_MAX_BW_LOW, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.max_bw_high = prop_exists[PERF_MAX_BW_HIGH] ? PROP_VALUE_ACCESS(prop_value, PERF_MAX_BW_HIGH, 0) : DEFAULT_MAX_BW_HIGH; cfg->perf.min_core_ib = prop_exists[PERF_MIN_CORE_IB] ? PROP_VALUE_ACCESS(prop_value, PERF_MIN_CORE_IB, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.min_llcc_ib = prop_exists[PERF_MIN_LLCC_IB] ? PROP_VALUE_ACCESS(prop_value, PERF_MIN_LLCC_IB, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.min_dram_ib = prop_exists[PERF_MIN_DRAM_IB] ? PROP_VALUE_ACCESS(prop_value, PERF_MIN_DRAM_IB, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.undersized_prefill_lines = prop_exists[PERF_UNDERSIZED_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_UNDERSIZED_PREFILL_LINES, 0) : DEFAULT_UNDERSIZED_PREFILL_LINES; cfg->perf.xtra_prefill_lines = prop_exists[PERF_XTRA_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_XTRA_PREFILL_LINES, 0) : DEFAULT_XTRA_PREFILL_LINES; cfg->perf.dest_scale_prefill_lines = prop_exists[PERF_DEST_SCALE_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_DEST_SCALE_PREFILL_LINES, 0) : DEFAULT_DEST_SCALE_PREFILL_LINES; cfg->perf.macrotile_prefill_lines = prop_exists[PERF_MACROTILE_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_MACROTILE_PREFILL_LINES, 0) : DEFAULT_MACROTILE_PREFILL_LINES; cfg->perf.yuv_nv12_prefill_lines = prop_exists[PERF_YUV_NV12_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_YUV_NV12_PREFILL_LINES, 0) : DEFAULT_YUV_NV12_PREFILL_LINES; cfg->perf.linear_prefill_lines = prop_exists[PERF_LINEAR_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_LINEAR_PREFILL_LINES, 0) : DEFAULT_LINEAR_PREFILL_LINES; cfg->perf.downscaling_prefill_lines = prop_exists[PERF_DOWNSCALING_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_DOWNSCALING_PREFILL_LINES, 0) : DEFAULT_DOWNSCALING_PREFILL_LINES; cfg->perf.amortizable_threshold = prop_exists[PERF_AMORTIZABLE_THRESHOLD] ? PROP_VALUE_ACCESS(prop_value, PERF_AMORTIZABLE_THRESHOLD, 0) : DEFAULT_AMORTIZABLE_THRESHOLD; } static int _sde_perf_parse_dt_cfg(struct device_node *np, struct sde_mdss_cfg *cfg, int *prop_count, struct sde_prop_value *prop_value, bool *prop_exists) { int rc, j; const char *str = NULL; /* * The following performance parameters (e.g. core_ib_ff) are * mapped directly as device tree string constants. */ rc = of_property_read_string(np, sde_perf_prop[PERF_CORE_IB_FF].prop_name, &str); cfg->perf.core_ib_ff = rc ? DEFAULT_CORE_IB_FF : str; rc = of_property_read_string(np, sde_perf_prop[PERF_CORE_CLK_FF].prop_name, &str); cfg->perf.core_clk_ff = rc ? DEFAULT_CORE_CLK_FF : str; rc = of_property_read_string(np, sde_perf_prop[PERF_COMP_RATIO_RT].prop_name, &str); cfg->perf.comp_ratio_rt = rc ? DEFAULT_COMP_RATIO_RT : str; rc = of_property_read_string(np, sde_perf_prop[PERF_COMP_RATIO_NRT].prop_name, &str); cfg->perf.comp_ratio_nrt = rc ? DEFAULT_COMP_RATIO_NRT : str; rc = 0; _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; Loading Loading @@ -3436,6 +3478,40 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) PROP_VALUE_ACCESS(prop_value, PERF_CPU_DMA_LATENCY, 0) : DEFAULT_CPU_DMA_LATENCY; return 0; } static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) { int rc, prop_count[PERF_PROP_MAX]; struct sde_prop_value *prop_value = NULL; bool prop_exists[PERF_PROP_MAX]; if (!cfg) { SDE_ERROR("invalid argument\n"); rc = -EINVAL; goto end; } prop_value = kzalloc(PERF_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; } rc = _sde_perf_parse_dt_validate(np, prop_count); if (rc) goto freeprop; rc = _read_dt_entry(np, sde_perf_prop, ARRAY_SIZE(sde_perf_prop), prop_count, prop_exists, prop_value); if (rc) goto freeprop; rc = _sde_perf_parse_dt_cfg(np, cfg, prop_count, prop_value, prop_exists); freeprop: kfree(prop_value); end: Loading Loading
drivers/gpu/drm/msm/sde/sde_hw_catalog.c +400 −324 Original line number Diff line number Diff line Loading @@ -2606,85 +2606,10 @@ static int sde_uidle_parse_dt(struct device_node *np, return 0; } static int sde_vbif_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) static int _sde_vbif_populate_ot_parsing(struct sde_vbif_cfg *vbif, struct sde_prop_value *prop_value, int *prop_count) { int rc, prop_count[VBIF_PROP_MAX], i, j, k; struct sde_prop_value *prop_value = NULL; bool prop_exists[VBIF_PROP_MAX]; u32 off_count, vbif_len; struct sde_vbif_cfg *vbif; if (!sde_cfg) { SDE_ERROR("invalid argument\n"); rc = -EINVAL; goto end; } prop_value = kzalloc(VBIF_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; } rc = _validate_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count, &off_count); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_RD_LIMIT], 1, &prop_count[VBIF_DYNAMIC_OT_RD_LIMIT], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_WR_LIMIT], 1, &prop_count[VBIF_DYNAMIC_OT_WR_LIMIT], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_RT_REMAP], 1, &prop_count[VBIF_QOS_RT_REMAP], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_NRT_REMAP], 1, &prop_count[VBIF_QOS_NRT_REMAP], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_0], 1, &prop_count[VBIF_MEMTYPE_0], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_1], 1, &prop_count[VBIF_MEMTYPE_1], NULL); if (rc) goto end; sde_cfg->vbif_count = off_count; rc = _read_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count, prop_exists, prop_value); if (rc) goto end; vbif_len = PROP_VALUE_ACCESS(prop_value, VBIF_LEN, 0); if (!prop_exists[VBIF_LEN]) vbif_len = DEFAULT_SDE_HW_BLOCK_LEN; for (i = 0; i < off_count; i++) { vbif = sde_cfg->vbif + i; vbif->base = PROP_VALUE_ACCESS(prop_value, VBIF_OFF, i); vbif->len = vbif_len; vbif->id = VBIF_0 + PROP_VALUE_ACCESS(prop_value, VBIF_ID, i); snprintf(vbif->name, SDE_HW_BLK_NAME_LEN, "vbif_%u", vbif->id - VBIF_0); SDE_DEBUG("vbif:%d\n", vbif->id - VBIF_0); vbif->xin_halt_timeout = VBIF_XIN_HALT_TIMEOUT; int j, k; vbif->default_ot_rd_limit = PROP_VALUE_ACCESS(prop_value, VBIF_DEFAULT_OT_RD_LIMIT, 0); Loading @@ -2705,10 +2630,8 @@ static int sde_vbif_parse_dt(struct device_node *np, vbif->dynamic_ot_rd_tbl.count, sizeof(struct sde_vbif_dynamic_ot_cfg), GFP_KERNEL); if (!vbif->dynamic_ot_rd_tbl.cfg) { rc = -ENOMEM; goto end; } if (!vbif->dynamic_ot_rd_tbl.cfg) return -ENOMEM; } for (j = 0, k = 0; j < vbif->dynamic_ot_rd_tbl.count; j++) { Loading @@ -2732,10 +2655,8 @@ static int sde_vbif_parse_dt(struct device_node *np, vbif->dynamic_ot_wr_tbl.count, sizeof(struct sde_vbif_dynamic_ot_cfg), GFP_KERNEL); if (!vbif->dynamic_ot_wr_tbl.cfg) { rc = -ENOMEM; goto end; } if (!vbif->dynamic_ot_wr_tbl.cfg) return -ENOMEM; } for (j = 0, k = 0; j < vbif->dynamic_ot_wr_tbl.count; j++) { Loading @@ -2755,6 +2676,15 @@ static int sde_vbif_parse_dt(struct device_node *np, vbif->dynamic_ot_wr_tbl.count) set_bit(SDE_VBIF_QOS_OTLIM, &vbif->features); return 0; } static int _sde_vbif_populate_qos_parsing(struct sde_mdss_cfg *sde_cfg, struct sde_vbif_cfg *vbif, struct sde_prop_value *prop_value, int *prop_count) { int j; vbif->qos_rt_tbl.npriority_lvl = prop_count[VBIF_QOS_RT_REMAP]; SDE_DEBUG("qos_rt_tbl.npriority_lvl=%u\n", Loading @@ -2763,10 +2693,8 @@ static int sde_vbif_parse_dt(struct device_node *np, vbif->qos_rt_tbl.priority_lvl = kcalloc( vbif->qos_rt_tbl.npriority_lvl, sizeof(u32), GFP_KERNEL); if (!vbif->qos_rt_tbl.priority_lvl) { rc = -ENOMEM; goto end; } if (!vbif->qos_rt_tbl.priority_lvl) return -ENOMEM; } else if (vbif->qos_rt_tbl.npriority_lvl) { vbif->qos_rt_tbl.npriority_lvl = 0; vbif->qos_rt_tbl.priority_lvl = NULL; Loading @@ -2790,10 +2718,8 @@ static int sde_vbif_parse_dt(struct device_node *np, vbif->qos_nrt_tbl.priority_lvl = kcalloc( vbif->qos_nrt_tbl.npriority_lvl, sizeof(u32), GFP_KERNEL); if (!vbif->qos_nrt_tbl.priority_lvl) { rc = -ENOMEM; goto end; } if (!vbif->qos_nrt_tbl.priority_lvl) return -ENOMEM; } else if (vbif->qos_nrt_tbl.npriority_lvl) { vbif->qos_nrt_tbl.npriority_lvl = 0; vbif->qos_nrt_tbl.priority_lvl = NULL; Loading @@ -2812,6 +2738,35 @@ static int sde_vbif_parse_dt(struct device_node *np, vbif->qos_nrt_tbl.npriority_lvl) set_bit(SDE_VBIF_QOS_REMAP, &vbif->features); return 0; } static int _sde_vbif_populate(struct sde_mdss_cfg *sde_cfg, struct sde_vbif_cfg *vbif, struct sde_prop_value *prop_value, int *prop_count, u32 vbif_len, int i) { int j, k, rc; vbif = sde_cfg->vbif + i; vbif->base = PROP_VALUE_ACCESS(prop_value, VBIF_OFF, i); vbif->len = vbif_len; vbif->id = VBIF_0 + PROP_VALUE_ACCESS(prop_value, VBIF_ID, i); snprintf(vbif->name, SDE_HW_BLK_NAME_LEN, "vbif_%u", vbif->id - VBIF_0); SDE_DEBUG("vbif:%d\n", vbif->id - VBIF_0); vbif->xin_halt_timeout = VBIF_XIN_HALT_TIMEOUT; rc = _sde_vbif_populate_ot_parsing(vbif, prop_value, prop_count); if (rc) return rc; rc = _sde_vbif_populate_qos_parsing(sde_cfg, vbif, prop_value, prop_count); if (rc) return rc; vbif->memtype_count = prop_count[VBIF_MEMTYPE_0] + prop_count[VBIF_MEMTYPE_1]; if (vbif->memtype_count > MAX_XIN_COUNT) { Loading @@ -2824,6 +2779,83 @@ static int sde_vbif_parse_dt(struct device_node *np, for (j = 0; j < prop_count[VBIF_MEMTYPE_1]; j++) vbif->memtype[k++] = PROP_VALUE_ACCESS( prop_value, VBIF_MEMTYPE_1, j); return 0; } static int sde_vbif_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) { int rc, prop_count[VBIF_PROP_MAX], i; struct sde_prop_value *prop_value = NULL; bool prop_exists[VBIF_PROP_MAX]; u32 off_count, vbif_len; struct sde_vbif_cfg *vbif; if (!sde_cfg) { SDE_ERROR("invalid argument\n"); rc = -EINVAL; goto end; } prop_value = kzalloc(VBIF_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; } rc = _validate_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count, &off_count); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_RD_LIMIT], 1, &prop_count[VBIF_DYNAMIC_OT_RD_LIMIT], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_WR_LIMIT], 1, &prop_count[VBIF_DYNAMIC_OT_WR_LIMIT], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_RT_REMAP], 1, &prop_count[VBIF_QOS_RT_REMAP], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_NRT_REMAP], 1, &prop_count[VBIF_QOS_NRT_REMAP], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_0], 1, &prop_count[VBIF_MEMTYPE_0], NULL); if (rc) goto end; rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_1], 1, &prop_count[VBIF_MEMTYPE_1], NULL); if (rc) goto end; sde_cfg->vbif_count = off_count; rc = _read_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count, prop_exists, prop_value); if (rc) goto end; vbif_len = PROP_VALUE_ACCESS(prop_value, VBIF_LEN, 0); if (!prop_exists[VBIF_LEN]) vbif_len = DEFAULT_SDE_HW_BLOCK_LEN; for (i = 0; i < off_count; i++) { rc = _sde_vbif_populate(sde_cfg, vbif, prop_value, prop_count, vbif_len, i); if (rc) goto end; } end: Loading Loading @@ -2934,57 +2966,9 @@ static int sde_pp_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) return rc; } static int sde_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) static int _sde_parse_prop_check(struct sde_mdss_cfg *cfg, bool prop_exists[SDE_PROP_MAX], struct sde_prop_value *prop_value) { int rc, i, dma_rc, len, prop_count[SDE_PROP_MAX]; struct sde_prop_value *prop_value = NULL; bool prop_exists[SDE_PROP_MAX]; const char *type; u32 major_version; if (!cfg) { SDE_ERROR("invalid argument\n"); rc = -EINVAL; goto end; } prop_value = kzalloc(SDE_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; } rc = _validate_dt_entry(np, sde_prop, ARRAY_SIZE(sde_prop), prop_count, &len); if (rc) goto end; rc = _validate_dt_entry(np, &sde_prop[SEC_SID_MASK], 1, &prop_count[SEC_SID_MASK], NULL); if (rc) goto end; rc = _read_dt_entry(np, sde_prop, ARRAY_SIZE(sde_prop), prop_count, prop_exists, prop_value); if (rc) goto end; cfg->mdss_count = 1; cfg->mdss[0].base = MDSS_BASE_OFFSET; cfg->mdss[0].id = MDP_TOP; snprintf(cfg->mdss[0].name, SDE_HW_BLK_NAME_LEN, "mdss_%u", cfg->mdss[0].id - MDP_TOP); cfg->mdp_count = 1; cfg->mdp[0].id = MDP_TOP; snprintf(cfg->mdp[0].name, SDE_HW_BLK_NAME_LEN, "top_%u", cfg->mdp[0].id - MDP_TOP); cfg->mdp[0].base = PROP_VALUE_ACCESS(prop_value, SDE_OFF, 0); cfg->mdp[0].len = PROP_VALUE_ACCESS(prop_value, SDE_LEN, 0); if (!prop_exists[SDE_LEN]) cfg->mdp[0].len = DEFAULT_SDE_HW_BLOCK_LEN; cfg->max_sspp_linewidth = PROP_VALUE_ACCESS(prop_value, SSPP_LINEWIDTH, 0); if (!prop_exists[SSPP_LINEWIDTH]) Loading Loading @@ -3035,23 +3019,77 @@ static int sde_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) cfg->mdp[0].smart_panel_align_mode = PROP_VALUE_ACCESS(prop_value, SMART_PANEL_ALIGN_MODE, 0); major_version = SDE_HW_MAJOR(cfg->hwversion); if (major_version < SDE_HW_MAJOR(SDE_HW_VER_500)) set_bit(SDE_MDP_VSYNC_SEL, &cfg->mdp[0].features); if (prop_exists[SEC_SID_MASK]) { cfg->sec_sid_mask_count = prop_count[SEC_SID_MASK]; for (i = 0; i < cfg->sec_sid_mask_count; i++) cfg->sec_sid_mask[i] = PROP_VALUE_ACCESS(prop_value, SEC_SID_MASK, i); return 0; } rc = of_property_read_string(np, sde_prop[QSEED_TYPE].prop_name, &type); if (!rc && !strcmp(type, "qseedv3")) { cfg->qseed_type = SDE_SSPP_SCALER_QSEED3; } else if (!rc && !strcmp(type, "qseedv3lite")) { cfg->qseed_type = SDE_SSPP_SCALER_QSEED3LITE; static int sde_top_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) { int rc, i, dma_rc, len, prop_count[SDE_PROP_MAX]; struct sde_prop_value *prop_value = NULL; bool prop_exists[SDE_PROP_MAX]; const char *type; u32 major_version; if (!cfg) { SDE_ERROR("invalid argument\n"); return -EINVAL; } prop_value = kzalloc(SDE_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) return -ENOMEM; rc = _validate_dt_entry(np, sde_prop, ARRAY_SIZE(sde_prop), prop_count, &len); if (rc) goto end; rc = _validate_dt_entry(np, &sde_prop[SEC_SID_MASK], 1, &prop_count[SEC_SID_MASK], NULL); if (rc) goto end; rc = _read_dt_entry(np, sde_prop, ARRAY_SIZE(sde_prop), prop_count, prop_exists, prop_value); if (rc) goto end; cfg->mdss_count = 1; cfg->mdss[0].base = MDSS_BASE_OFFSET; cfg->mdss[0].id = MDP_TOP; snprintf(cfg->mdss[0].name, SDE_HW_BLK_NAME_LEN, "mdss_%u", cfg->mdss[0].id - MDP_TOP); cfg->mdp_count = 1; cfg->mdp[0].id = MDP_TOP; snprintf(cfg->mdp[0].name, SDE_HW_BLK_NAME_LEN, "top_%u", cfg->mdp[0].id - MDP_TOP); cfg->mdp[0].base = PROP_VALUE_ACCESS(prop_value, SDE_OFF, 0); cfg->mdp[0].len = PROP_VALUE_ACCESS(prop_value, SDE_LEN, 0); if (!prop_exists[SDE_LEN]) cfg->mdp[0].len = DEFAULT_SDE_HW_BLOCK_LEN; rc = _sde_parse_prop_check(cfg, prop_exists, prop_value); if (rc) SDE_ERROR("sde parse property check failed\n"); major_version = SDE_HW_MAJOR(cfg->hwversion); if (major_version < SDE_HW_MAJOR(SDE_HW_VER_500)) set_bit(SDE_MDP_VSYNC_SEL, &cfg->mdp[0].features); if (prop_exists[SEC_SID_MASK]) { cfg->sec_sid_mask_count = prop_count[SEC_SID_MASK]; for (i = 0; i < cfg->sec_sid_mask_count; i++) cfg->sec_sid_mask[i] = PROP_VALUE_ACCESS(prop_value, SEC_SID_MASK, i); } rc = of_property_read_string(np, sde_prop[QSEED_TYPE].prop_name, &type); if (!rc && !strcmp(type, "qseedv3")) { cfg->qseed_type = SDE_SSPP_SCALER_QSEED3; } else if (!rc && !strcmp(type, "qseedv3lite")) { cfg->qseed_type = SDE_SSPP_SCALER_QSEED3LITE; } else if (!rc && !strcmp(type, "qseedv2")) { cfg->qseed_type = SDE_SSPP_SCALER_QSEED2; } else if (rc) { Loading Loading @@ -3132,178 +3170,82 @@ static int sde_parse_reg_dma_dt(struct device_node *np, return 0; } static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) static int _sde_perf_parse_dt_validate(struct device_node *np, int *prop_count) { int rc, len, prop_count[PERF_PROP_MAX]; struct sde_prop_value *prop_value = NULL; bool prop_exists[PERF_PROP_MAX]; const char *str = NULL; int j, k; if (!cfg) { SDE_ERROR("invalid argument\n"); rc = -EINVAL; goto end; } prop_value = kzalloc(PERF_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; } int rc, len; rc = _validate_dt_entry(np, sde_perf_prop, ARRAY_SIZE(sde_perf_prop), prop_count, &len); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_DANGER_LUT], 1, &prop_count[PERF_DANGER_LUT], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_LINEAR], 1, &prop_count[PERF_SAFE_LUT_LINEAR], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_MACROTILE], 1, &prop_count[PERF_SAFE_LUT_MACROTILE], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_NRT], 1, &prop_count[PERF_SAFE_LUT_NRT], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_CWB], 1, &prop_count[PERF_SAFE_LUT_CWB], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_LINEAR], 1, &prop_count[PERF_QOS_LUT_LINEAR], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_MACROTILE], 1, &prop_count[PERF_QOS_LUT_MACROTILE], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_NRT], 1, &prop_count[PERF_QOS_LUT_NRT], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_CWB], 1, &prop_count[PERF_QOS_LUT_CWB], NULL); if (rc) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_CDP_SETTING], 1, &prop_count[PERF_CDP_SETTING], NULL); if (rc) goto freeprop; 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) goto freeprop; return rc; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT_MACROTILE_QSEED], 1, &prop_count[PERF_SAFE_LUT_MACROTILE_QSEED], NULL); if (rc) goto freeprop; rc = _read_dt_entry(np, sde_perf_prop, ARRAY_SIZE(sde_perf_prop), prop_count, prop_exists, prop_value); if (rc) goto freeprop; cfg->perf.max_bw_low = prop_exists[PERF_MAX_BW_LOW] ? PROP_VALUE_ACCESS(prop_value, PERF_MAX_BW_LOW, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.max_bw_high = prop_exists[PERF_MAX_BW_HIGH] ? PROP_VALUE_ACCESS(prop_value, PERF_MAX_BW_HIGH, 0) : DEFAULT_MAX_BW_HIGH; cfg->perf.min_core_ib = prop_exists[PERF_MIN_CORE_IB] ? PROP_VALUE_ACCESS(prop_value, PERF_MIN_CORE_IB, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.min_llcc_ib = prop_exists[PERF_MIN_LLCC_IB] ? PROP_VALUE_ACCESS(prop_value, PERF_MIN_LLCC_IB, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.min_dram_ib = prop_exists[PERF_MIN_DRAM_IB] ? PROP_VALUE_ACCESS(prop_value, PERF_MIN_DRAM_IB, 0) : DEFAULT_MAX_BW_LOW; /* * The following performance parameters (e.g. core_ib_ff) are * mapped directly as device tree string constants. */ rc = of_property_read_string(np, sde_perf_prop[PERF_CORE_IB_FF].prop_name, &str); cfg->perf.core_ib_ff = rc ? DEFAULT_CORE_IB_FF : str; rc = of_property_read_string(np, sde_perf_prop[PERF_CORE_CLK_FF].prop_name, &str); cfg->perf.core_clk_ff = rc ? DEFAULT_CORE_CLK_FF : str; rc = of_property_read_string(np, sde_perf_prop[PERF_COMP_RATIO_RT].prop_name, &str); cfg->perf.comp_ratio_rt = rc ? DEFAULT_COMP_RATIO_RT : str; rc = of_property_read_string(np, sde_perf_prop[PERF_COMP_RATIO_NRT].prop_name, &str); cfg->perf.comp_ratio_nrt = rc ? DEFAULT_COMP_RATIO_NRT : str; rc = 0; return rc; } cfg->perf.undersized_prefill_lines = prop_exists[PERF_UNDERSIZED_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_UNDERSIZED_PREFILL_LINES, 0) : DEFAULT_UNDERSIZED_PREFILL_LINES; cfg->perf.xtra_prefill_lines = prop_exists[PERF_XTRA_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_XTRA_PREFILL_LINES, 0) : DEFAULT_XTRA_PREFILL_LINES; cfg->perf.dest_scale_prefill_lines = prop_exists[PERF_DEST_SCALE_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_DEST_SCALE_PREFILL_LINES, 0) : DEFAULT_DEST_SCALE_PREFILL_LINES; cfg->perf.macrotile_prefill_lines = prop_exists[PERF_MACROTILE_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_MACROTILE_PREFILL_LINES, 0) : DEFAULT_MACROTILE_PREFILL_LINES; cfg->perf.yuv_nv12_prefill_lines = prop_exists[PERF_YUV_NV12_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_YUV_NV12_PREFILL_LINES, 0) : DEFAULT_YUV_NV12_PREFILL_LINES; cfg->perf.linear_prefill_lines = prop_exists[PERF_LINEAR_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_LINEAR_PREFILL_LINES, 0) : DEFAULT_LINEAR_PREFILL_LINES; cfg->perf.downscaling_prefill_lines = prop_exists[PERF_DOWNSCALING_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_DOWNSCALING_PREFILL_LINES, 0) : DEFAULT_DOWNSCALING_PREFILL_LINES; cfg->perf.amortizable_threshold = prop_exists[PERF_AMORTIZABLE_THRESHOLD] ? PROP_VALUE_ACCESS(prop_value, PERF_AMORTIZABLE_THRESHOLD, 0) : DEFAULT_AMORTIZABLE_THRESHOLD; static int _sde_perf_parse_dt_cfg_qos(struct sde_mdss_cfg *cfg, int *prop_count, struct sde_prop_value *prop_value, bool *prop_exists) { int j, k; if (prop_exists[PERF_DANGER_LUT] && prop_count[PERF_DANGER_LUT] <= SDE_QOS_LUT_USAGE_MAX) { Loading Loading @@ -3340,10 +3282,8 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) 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) { rc = -ENOMEM; goto freeprop; } if (!cfg->perf.sfe_lut_tbl[j].entries) return -ENOMEM; for (k = 0, m = 0; k < count; k++, m += entry_size) { u64 lut_lo; Loading Loading @@ -3384,10 +3324,8 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) 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) { rc = -ENOMEM; goto freeprop; } 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; Loading @@ -3406,6 +3344,110 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) cfg->perf.qos_lut_tbl[j].nentry = count; } return 0; } static void _sde_perf_parse_dt_cfg_populate(struct sde_mdss_cfg *cfg, int *prop_count, struct sde_prop_value *prop_value, bool *prop_exists) { cfg->perf.max_bw_low = prop_exists[PERF_MAX_BW_LOW] ? PROP_VALUE_ACCESS(prop_value, PERF_MAX_BW_LOW, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.max_bw_high = prop_exists[PERF_MAX_BW_HIGH] ? PROP_VALUE_ACCESS(prop_value, PERF_MAX_BW_HIGH, 0) : DEFAULT_MAX_BW_HIGH; cfg->perf.min_core_ib = prop_exists[PERF_MIN_CORE_IB] ? PROP_VALUE_ACCESS(prop_value, PERF_MIN_CORE_IB, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.min_llcc_ib = prop_exists[PERF_MIN_LLCC_IB] ? PROP_VALUE_ACCESS(prop_value, PERF_MIN_LLCC_IB, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.min_dram_ib = prop_exists[PERF_MIN_DRAM_IB] ? PROP_VALUE_ACCESS(prop_value, PERF_MIN_DRAM_IB, 0) : DEFAULT_MAX_BW_LOW; cfg->perf.undersized_prefill_lines = prop_exists[PERF_UNDERSIZED_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_UNDERSIZED_PREFILL_LINES, 0) : DEFAULT_UNDERSIZED_PREFILL_LINES; cfg->perf.xtra_prefill_lines = prop_exists[PERF_XTRA_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_XTRA_PREFILL_LINES, 0) : DEFAULT_XTRA_PREFILL_LINES; cfg->perf.dest_scale_prefill_lines = prop_exists[PERF_DEST_SCALE_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_DEST_SCALE_PREFILL_LINES, 0) : DEFAULT_DEST_SCALE_PREFILL_LINES; cfg->perf.macrotile_prefill_lines = prop_exists[PERF_MACROTILE_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_MACROTILE_PREFILL_LINES, 0) : DEFAULT_MACROTILE_PREFILL_LINES; cfg->perf.yuv_nv12_prefill_lines = prop_exists[PERF_YUV_NV12_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_YUV_NV12_PREFILL_LINES, 0) : DEFAULT_YUV_NV12_PREFILL_LINES; cfg->perf.linear_prefill_lines = prop_exists[PERF_LINEAR_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_LINEAR_PREFILL_LINES, 0) : DEFAULT_LINEAR_PREFILL_LINES; cfg->perf.downscaling_prefill_lines = prop_exists[PERF_DOWNSCALING_PREFILL_LINES] ? PROP_VALUE_ACCESS(prop_value, PERF_DOWNSCALING_PREFILL_LINES, 0) : DEFAULT_DOWNSCALING_PREFILL_LINES; cfg->perf.amortizable_threshold = prop_exists[PERF_AMORTIZABLE_THRESHOLD] ? PROP_VALUE_ACCESS(prop_value, PERF_AMORTIZABLE_THRESHOLD, 0) : DEFAULT_AMORTIZABLE_THRESHOLD; } static int _sde_perf_parse_dt_cfg(struct device_node *np, struct sde_mdss_cfg *cfg, int *prop_count, struct sde_prop_value *prop_value, bool *prop_exists) { int rc, j; const char *str = NULL; /* * The following performance parameters (e.g. core_ib_ff) are * mapped directly as device tree string constants. */ rc = of_property_read_string(np, sde_perf_prop[PERF_CORE_IB_FF].prop_name, &str); cfg->perf.core_ib_ff = rc ? DEFAULT_CORE_IB_FF : str; rc = of_property_read_string(np, sde_perf_prop[PERF_CORE_CLK_FF].prop_name, &str); cfg->perf.core_clk_ff = rc ? DEFAULT_CORE_CLK_FF : str; rc = of_property_read_string(np, sde_perf_prop[PERF_COMP_RATIO_RT].prop_name, &str); cfg->perf.comp_ratio_rt = rc ? DEFAULT_COMP_RATIO_RT : str; rc = of_property_read_string(np, sde_perf_prop[PERF_COMP_RATIO_NRT].prop_name, &str); cfg->perf.comp_ratio_nrt = rc ? DEFAULT_COMP_RATIO_NRT : str; rc = 0; _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; Loading Loading @@ -3436,6 +3478,40 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) PROP_VALUE_ACCESS(prop_value, PERF_CPU_DMA_LATENCY, 0) : DEFAULT_CPU_DMA_LATENCY; return 0; } static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) { int rc, prop_count[PERF_PROP_MAX]; struct sde_prop_value *prop_value = NULL; bool prop_exists[PERF_PROP_MAX]; if (!cfg) { SDE_ERROR("invalid argument\n"); rc = -EINVAL; goto end; } prop_value = kzalloc(PERF_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) { rc = -ENOMEM; goto end; } rc = _sde_perf_parse_dt_validate(np, prop_count); if (rc) goto freeprop; rc = _read_dt_entry(np, sde_perf_prop, ARRAY_SIZE(sde_perf_prop), prop_count, prop_exists, prop_value); if (rc) goto freeprop; rc = _sde_perf_parse_dt_cfg(np, cfg, prop_count, prop_value, prop_exists); freeprop: kfree(prop_value); end: Loading