Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f1d2311 authored by Nilaan Gunabalachandran's avatar Nilaan Gunabalachandran
Browse files

drm/msm/sde: CCN Cleanup for sde_hw_catalog



Add changes in the sde hw_catalog to reduce
Cyclomatic Complexity Number to less than thirty.

Change-Id: Ic818468674f190155569ed4cfbcce57c8c8e4bb7
Signed-off-by: default avatarNilaan Gunabalachandran <ngunabal@codeaurora.org>
parent a4bc63cf
Loading
Loading
Loading
Loading
+400 −324
Original line number Diff line number Diff line
@@ -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);
@@ -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++) {
@@ -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++) {
@@ -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",
@@ -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;
@@ -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;
@@ -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) {
@@ -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:
@@ -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])
@@ -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) {
@@ -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) {
@@ -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;
@@ -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;
@@ -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;
@@ -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: