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

Commit be9c3671 authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

regulator: cpr-regulator: support CPR closed loop based on the fuse version



In some SoCs, CPR closed loop should not be enabled for certain
CPR fusing revisions. Currently, there is no support to disable the
closed loop operation based on the fuse version. Add support for that
through qcom,cpr-allowed property.

The above property is tied with qcom,cpr-fuse-version-map property
so that this can be supported well for a particular fuse revision or
PVS bin or speed bin.

Change-Id: I7d315d0d739d60d755f2d3c40f4568c3c5f42bc9
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 0e13b804
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -263,6 +263,16 @@ Optional properties:
				that matches against the fuse values read from hardware will be used.
				This property is used by several properties to provide an index into
				their lists.
- qcom,cpr-allowed:		Integer values that specifies whether the closed loop CPR is allowed or
				not for a particular fuse revision. If the qcom,cpr-fuse-version-map
				property is specified, then qcom,cpr-allowed must contain the same number
				of integers as that of the number of tuples in qcom,cpr-fuse-version-map.
				If the integer value has a value 0 for a particular fuse revision, then it
				is treated as if the closed loop operation is disabled in the fuse. If the
				integer value has a value 1 for a particular fuse revision, then the closed
				loop operation is enabled for that fuse revision. If nothing is specified
				for a particular fuse revision, then the closed loop operation is enabled
				for that fuse revision by default.
- qcom,cpr-quotient-adjustment:	Array of integer tuples of target quotient adjustments to add to the fused
				quotients of each fuse corner.  The elements in a tuple are ordered from
				lowest voltage corner to highest voltage corner.  Each tuple must be of
@@ -718,6 +728,10 @@ Example:
			<0 0 0 100 0 0 0 0 0 0 0 0>,
			<0 0 0 0 0 0 0 0 0 0 0 (-300)>,
			<0 0 0 (-60) 0 0 0 0 0 0 0 0>;
		qcom,cpr-allowed =
			<0>,
			<1>,
			<1>;

		qcom,fuse-remap-base-row = <1000>;
		qcom,fuse-remap-source =
+52 −1
Original line number Diff line number Diff line
@@ -2774,6 +2774,57 @@ static int cpr_adjust_target_quots(struct platform_device *pdev,
	return rc;
}

static int cpr_check_allowed(struct platform_device *pdev,
					struct cpr_regulator *cpr_vreg)
{
	struct device_node *of_node = pdev->dev.of_node;
	char *allow_str = "qcom,cpr-allowed";
	int rc = 0, count;
	int tuple_count, tuple_match;
	u32 allow_status;

	if (!of_find_property(of_node, allow_str, &count))
		/* CPR is allowed for all fuse revisions. */
		return 0;

	count /= sizeof(u32);
	if (cpr_vreg->cpr_fuse_map_count) {
		if (cpr_vreg->cpr_fuse_map_match == FUSE_MAP_NO_MATCH)
			/* No matching index to use for CPR allowed. */
			return 0;
		tuple_count = cpr_vreg->cpr_fuse_map_count;
		tuple_match = cpr_vreg->cpr_fuse_map_match;
	} else {
		tuple_count = 1;
		tuple_match = 0;
	}

	if (count != tuple_count) {
		cpr_err(cpr_vreg, "%s count=%d is invalid\n", allow_str,
			count);
		return -EINVAL;
	}

	rc = of_property_read_u32_index(of_node, allow_str, tuple_match,
		&allow_status);
	if (rc) {
		cpr_err(cpr_vreg, "could not read %s index %u, rc=%d\n",
			allow_str, tuple_match, rc);
		return rc;
	}

	if (!allow_status)
		cpr_vreg->cpr_fuse_disable = true;
	else
		cpr_vreg->cpr_fuse_disable = false;

	cpr_info(cpr_vreg, "CPR closed loop is %s for fuse revision %d\n",
		cpr_vreg->cpr_fuse_disable ? "disabled" : "enabled",
		cpr_vreg->cpr_fuse_revision);

	return rc;
}

static int cpr_init_cpr_efuse(struct platform_device *pdev,
				     struct cpr_regulator *cpr_vreg)
{
@@ -3038,7 +3089,7 @@ static int cpr_init_cpr_efuse(struct platform_device *pdev,
			cpr_err(cpr_vreg, "invalid quotient values; permanently disabling CPR\n");
		}
	}

	rc = cpr_check_allowed(pdev, cpr_vreg);

error:
	kfree(bp_target_quot);