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

Commit 1ea70848 authored by Wu Fenglin's avatar Wu Fenglin Committed by Ke Liu
Browse files

msm: cpr-regulator: modify the dts definition for cond-min-volt



Previously, cpr-cond-min-volt-fuse defined the fuse row number and the
value used to compare with the whole row efuse value. The cpr-regulator
driver would then conditionally apply a higher CPR floor voltage for all
voltage corners if the efuse value differed from the expected value.

However, only a subset of the bits in the efuse are used for the
cond-min-volt feature. If any of the other bits in the fuse are set, then
the cpr-regulator driver incorrectly applies the higher floor voltage even
if the cond-min-volt bits are set correctly.

Modify the cpr-regulator driver and the cpr-regulator device tree
properties so that only specific bits in the fuse are compared to the
expected value. If the value of the cond-min-volt bits in the fuse is
not equal to the value defined in device tree, then set the MIN_VOLTAGE
flag.

Change-Id: I7de04e17dfa93fcb638e29a1dcc5e9072de26cb8
Signed-off-by: default avatarWu Fenglin <fenglinw@codeaurora.org>
Signed-off-by: default avatarKe Liu <keliu@codeaurora.org>
parent 4f11ea43
Loading
Loading
Loading
Loading
+18 −12
Original line number Diff line number Diff line
@@ -147,17 +147,22 @@ Optional properties:
					is present, and vise versa.
- qti,cpr-enable:		Present: CPR enabled by default.
				Not Present: CPR disable by default.
- qti,cpr-cond-min-voltage:	Minimum voltage in microvolts for SVS, NOM and TURBO mode
				if the fuse defined in qti,cpr-cond-min-volt-fuse has not be programmed with the expected data.
- qti,cpr-cond-min-volt-fuse:	Array of row number of fuse, data in that row and reading method.
				This property can be used to capture hardware requirements determined
				by the value of the mem-accel fuse. It should have index and value like this:
				 [0]: the fuse row number
				 [1]: high 32 bits of the expected data in that row.
				 [2]: low 32 bits of the expected data in that row.
				 [3]: reading method, 0 for direct reading or 1 for SCM reading


- qti,cpr-fuse-cond-min-volt-sel:	Array of 5 elements to indicate where to read the bits,  what value to
				compare with in order to decide if the conditional minimum apc voltage needs
				to be applied and the fuse reading method.
				The 5 elements with index[0..4] are:
				[0] => the fuse row number;
				[1] => LSB bit position of the bits;
				[2] => number of the bits;
				[3] => the expected data to read;
				[4] => fuse reading method, 0 for direct reading or 1 for SCM reading;
				When the value of the fuse bits specified by first 3 elements is not equal to
				the value in 4th element, then set the apc voltage for all parts running
				at each voltage corner to be not lower than the voltage defined
				using "qti,cpr-cond-min-voltage".
- qti,cpr-cond-min-voltage:	Minimum voltage in microvolts for SVS, NOM and TURBO mode if the fuse bits
				defined in qti,cpr-fuse-cond-min-volt-sel have not been programmed with the
				expected data. This is required if cpr-fuse-cond-min-volt-sel is present.
Example:
	apc_vreg_corner: regulator@f9018000 {
		status = "okay";
@@ -211,6 +216,7 @@ Example:
		qti,cpr-fuse-redun-row = <139 1>;
		qti,cpr-fuse-redun-target-quot = <24 12 0>;
		qti,cpr-fuse-redun-ro-sel = <46 36 39>;
		qti,cpr-cond-min-volt-fuse = <54 0xc100 0x0 1>;
		qti,cpr-fuse-cond-min-volt-sel = <54 42 6 7 1>;
		qti,cpr-cond-min-voltage = <1140000>;
	};
+1 −1
Original line number Diff line number Diff line
@@ -82,8 +82,8 @@
		qti,cpr-fuse-redun-ro-sel = <46 36 39>;

		qti,cpr-enable;
		qti,cpr-fuse-cond-min-volt-sel = <54 42 6 7 1>;
		qti,cpr-cond-min-voltage = <1140000>;
		qti,cpr-cond-min-volt-fuse = <54 0xc100 0x0 1>;
	};
};

+22 −24
Original line number Diff line number Diff line
@@ -974,23 +974,25 @@ static int cpr_config(struct cpr_regulator *cpr_vreg)
	return 0;
}

static int cpr_is_fuse_redundant(struct cpr_regulator *cpr_vreg,
					 u32 redun_sel[5])
static int cpr_fuse_is_setting_expected(struct cpr_regulator *cpr_vreg,
					u32 sel_array[5])
{
	u64 fuse_bits;
	int redundant;
	u32 ret;

	fuse_bits = cpr_read_efuse_row(cpr_vreg, redun_sel[0], redun_sel[4]);
	fuse_bits = (fuse_bits >> redun_sel[1]) & ((1 << redun_sel[2]) - 1);
	if (fuse_bits == redun_sel[3])
		redundant = 1;
	fuse_bits = cpr_read_efuse_row(cpr_vreg, sel_array[0], sel_array[4]);
	ret = (fuse_bits >> sel_array[1]) & ((1 << sel_array[2]) - 1);
	if (ret == sel_array[3])
		ret = 1;
	else
		redundant = 0;
		ret = 0;

	pr_info("[row:%d] = 0x%llx @%d:%d = %d?: redundant=%d\n",
		redun_sel[0], fuse_bits,
		redun_sel[1], redun_sel[2], redun_sel[3], redundant);
	return redundant;
	pr_info("[row:%d] = 0x%llx @%d:%d == %d ?: %s\n",
			sel_array[0], fuse_bits,
			sel_array[1], sel_array[2],
			sel_array[3],
			(ret == 1) ? "yes" : "no");
	return ret;
}

static int cpr_pvs_init(struct platform_device *pdev,
@@ -1011,7 +1013,7 @@ static int cpr_pvs_init(struct platform_device *pdev,
		return rc;
	}

	redundant = cpr_is_fuse_redundant(cpr_vreg, pvs_fuse_redun_sel);
	redundant = cpr_fuse_is_setting_expected(cpr_vreg, pvs_fuse_redun_sel);

	if (redundant) {
		rc = of_property_read_u32_array(of_node, "qti,pvs-fuse-redun",
@@ -1166,7 +1168,7 @@ static int cpr_init_cpr_efuse(struct platform_device *pdev,
		return rc;
	}

	redundant = cpr_is_fuse_redundant(cpr_vreg, cpr_fuse_redun_sel);
	redundant = cpr_fuse_is_setting_expected(cpr_vreg, cpr_fuse_redun_sel);

	if (redundant) {
		rc = of_property_read_u32_array(of_node,
@@ -1471,21 +1473,17 @@ static void cpr_parse_cond_min_volt_fuse(struct cpr_regulator *cpr_vreg,
						struct device_node *of_node)
{
	int rc;
	u32 fuse[4];
	u64 blown_data, fuse_data;

	u32 fuse_sel[5];
	/*
	 * Restrict all pvs corner voltages to a minimum value of
	 * qti,cpr-cond-min-voltage if the fuse defined in
	 * qti,cpr-cond-min-volt-fuse does not read back with the expected
	 * value.
	 * qti,cpr-fuse-cond-min-volt-sel does not read back with
	 * the expected value.
	 */
	rc = of_property_read_u32_array(of_node, "qti,cpr-cond-min-volt-fuse",
					fuse, 4);
	rc = of_property_read_u32_array(of_node,
			"qti,cpr-fuse-cond-min-volt-sel", fuse_sel, 5);
	if (!rc) {
		blown_data = cpr_read_efuse_row(cpr_vreg, fuse[0], fuse[3]);
		fuse_data = ((u64)fuse[1] << 32) | fuse[2];
		if (blown_data != fuse_data)
		if (!cpr_fuse_is_setting_expected(cpr_vreg, fuse_sel))
			cpr_vreg->flags |= FLAGS_SET_MIN_VOLTAGE;
	}
}