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

Commit 7f18f389 authored by David Collins's avatar David Collins Committed by Gerrit - the friendly Code Review server
Browse files

regulator: cpr3-regulator: add support for open-loop voltage min difference



Add support for the qcom,cpr-open-loop-voltage-min-diff device
tree property which specifies the minimum allowed open-loop
voltage difference between adjacent CPR voltage corners.  This
property can be used to specifically allow open-loop voltage
monotonicity to be violated for selected corners.

Change-Id: Ib3c20ff882326a3550827f8acc1ac844530e60ba
Signed-off-by: default avatarDavid Collins <collinsd@codeaurora.org>
parent c42ac2ee
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -379,6 +379,39 @@ Platform independent properties:
		    single tuple may only be specified if all of the corner
		    counts in qcom,cpr-corners are the same.

- qcom,cpr-open-loop-voltage-min-diff
	Usage:      optional; only meaningful if the
		    qcom,cpr-open-loop-voltage-adjustment property is specified
	Value type: <prop-encoded-array>
	Definition: A list of integer tuples which each define the minimum
		    allowed open-loop voltage difference in microvolts between
		    each voltage corner and the one immediately preceding it.
		    The elements in a tuple are ordered from the lowest to the
		    highest corner.  The value specified for the first corner is
		    ignored since there is no corner before it.

		    Negative voltage values may be specified for this property.
		    A negative value means that the open-loop voltage of a
		    corner may be lower than that of the preceding corner.

		    The minimum difference is enforced after the open-loop
		    voltage values have been interpolated for intermediate
		    corners and after adjustments have been applied.

		    The list must contain either qcom,cpr-fuse-combos number of
		    tuples in which case the tuples are matched to fuse
		    combinations 1-to-1 or the list must contain exactly 1 tuple
		    which is used regardless of the fuse combination found on a
		    given chip.

		    Each tuple must be of the length defined in the
		    corresponding element of the qcom,cpr-corners property.  A
		    single tuple may only be specified if all of the corner
		    counts in qcom,cpr-corners are the same.

		    If this property is not specified, then the minimum
		    difference is assumed to be 0 uV for all corners.

- qcom,cpr-closed-loop-voltage-fuse-adjustment
	Usage:      optional
	Value type: <prop-encoded-array>
+30 −11
Original line number Diff line number Diff line
@@ -961,8 +961,8 @@ done:
int cpr3_adjust_open_loop_voltages(struct cpr3_regulator *vreg, int corner_sum,
		int combo_offset)
{
	int i, rc, prev_volt;
	int *volt_adjust;
	int i, rc, prev_volt, min_volt;
	int *volt_adjust, *volt_diff;

	if (!of_find_property(vreg->of_node,
			"qcom,cpr-open-loop-voltage-adjustment", NULL)) {
@@ -972,8 +972,11 @@ int cpr3_adjust_open_loop_voltages(struct cpr3_regulator *vreg, int corner_sum,

	volt_adjust = kcalloc(vreg->corner_count, sizeof(*volt_adjust),
				GFP_KERNEL);
	if (!volt_adjust)
		return -ENOMEM;
	volt_diff = kcalloc(vreg->corner_count, sizeof(*volt_diff), GFP_KERNEL);
	if (!volt_adjust || !volt_diff) {
		rc = -ENOMEM;
		goto done;
	}

	rc = cpr3_parse_array_property(vreg,
		"qcom,cpr-open-loop-voltage-adjustment",
@@ -993,20 +996,36 @@ int cpr3_adjust_open_loop_voltages(struct cpr3_regulator *vreg, int corner_sum,
		}
	}

	/* Ensure that open-loop voltages increase monotonically */
	if (of_find_property(vreg->of_node,
			"qcom,cpr-open-loop-voltage-min-diff", NULL)) {
		rc = cpr3_parse_array_property(vreg,
			"qcom,cpr-open-loop-voltage-min-diff",
			vreg->corner_count, corner_sum, combo_offset,
			volt_diff);
		if (rc) {
			cpr3_err(vreg, "could not load minimum open-loop voltage differences, rc=%d\n",
				rc);
			goto done;
		}
	}

	/*
	 * Ensure that open-loop voltages increase monotonically with respect
	 * to configurable minimum allowed differences.
	 */
	for (i = 1; i < vreg->corner_count; i++) {
		if (vreg->corner[i].open_loop_volt
		    < vreg->corner[i - 1].open_loop_volt) {
			cpr3_info(vreg, "adjusted corner %d open-loop voltage=%d uV < corner %d voltage=%d uV; overriding: corner %d voltage=%d\n",
		min_volt = vreg->corner[i - 1].open_loop_volt + volt_diff[i];
		if (vreg->corner[i].open_loop_volt < min_volt) {
			cpr3_info(vreg, "adjusted corner %d open-loop voltage=%d uV < corner %d voltage=%d uV + min diff=%d uV; overriding: corner %d voltage=%d\n",
				i, vreg->corner[i].open_loop_volt,
				i - 1, vreg->corner[i - 1].open_loop_volt,
				i, vreg->corner[i - 1].open_loop_volt);
			vreg->corner[i].open_loop_volt
				= vreg->corner[i - 1].open_loop_volt;
				volt_diff[i], i, min_volt);
			vreg->corner[i].open_loop_volt = min_volt;
		}
	}

done:
	kfree(volt_diff);
	kfree(volt_adjust);
	return rc;
}