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

Commit f673cdc5 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "regulator: cpr-regulator: add support for target quotient unpacking"

parents 9afe89cb 1531214f
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -176,6 +176,16 @@ Optional properties:
				array are ordered from lowest voltage corner to highest voltage corner.
				If this property is not present, then all target quotient fuse values
				are assumed to be the default length of 12 bits.
- qcom,cpr-fuse-target-quot-scale:	Array of doubles which defines the scaling coefficients to decode
				the target quotients of each fuse corner.  The first element in each
				double represents the offset to add to the scaled quotient.  The second
				element represents the multiplier to scale the quotient by.  For example,
				given a tuple <A B>, quot_decoded = A + (B * quot_raw).
				The doubles in the array are ordered from lowest voltage corner to highest
				voltage corner.  This property must contain a number of doubles equal to
				the value of qcom,cpr-fuse-corners.  If this property is not present,
				then all target quotient parameters are assumed to have an offset of 0
				and a multiplier of 1 (i.e. no decoding needed).
- qcom,cpr-enable:		Present: CPR enabled by default.
				Not Present: CPR disable by default.
- qcom,cpr-fuse-cond-min-volt-sel:	Array of 5 elements to indicate where to read the bits,  what value to
@@ -410,6 +420,10 @@ Example:
				<1 1 2 4 12>,
				<2 1 2 4 10>,
				<5 1 2 4 14>;
		qcom,cpr-fuse-target-quot-scale =
				<0 1>,
				<0 1>,
				<0 1>;
		qcom,cpr-quot-adjust-scaling-factor-max = <650>;
		qcom,cpr-fuse-init-voltage =
				<27 36 6 0>,
+44 −1
Original line number Diff line number Diff line
@@ -1886,6 +1886,11 @@ free_arrays:
	return rc;
}

struct cpr_quot_scale {
	u32 offset;
	u32 multiplier;
};

static int cpr_init_cpr_efuse(struct platform_device *pdev,
				     struct cpr_regulator *cpr_vreg)
{
@@ -1903,6 +1908,7 @@ static int cpr_init_cpr_efuse(struct platform_device *pdev,
	u64 fuse_bits, fuse_bits_2;
	u32 *quot_adjust;
	u32 *target_quot_size;
	struct cpr_quot_scale *quot_scale;

	len = cpr_vreg->num_fuse_corners + 1;

@@ -1910,9 +1916,10 @@ static int cpr_init_cpr_efuse(struct platform_device *pdev,
	bp_ro_sel = kzalloc(len * sizeof(*bp_ro_sel), GFP_KERNEL);
	quot_adjust = kzalloc(len * sizeof(*quot_adjust), GFP_KERNEL);
	target_quot_size = kzalloc(len * sizeof(*target_quot_size), GFP_KERNEL);
	quot_scale = kzalloc(len * sizeof(*quot_scale), GFP_KERNEL);

	if (bp_target_quot == NULL || bp_ro_sel == NULL || quot_adjust == NULL
	    || target_quot_size == NULL) {
	    || target_quot_size == NULL || quot_scale == NULL) {
		pr_err("Could not allocate memory for fuse parsing arrays\n");
		rc = -ENOMEM;
		goto error;
@@ -1973,6 +1980,38 @@ static int cpr_init_cpr_efuse(struct platform_device *pdev,
			target_quot_size[i] = CPR_FUSE_TARGET_QUOT_BITS;
	}

	if (of_property_read_bool(of_node, "qcom,cpr-fuse-target-quot-scale")) {
		for (i = 0; i < cpr_vreg->num_fuse_corners; i++) {
			rc = of_property_read_u32_index(of_node,
				"qcom,cpr-fuse-target-quot-scale", i * 2,
				&quot_scale[i + CPR_FUSE_CORNER_MIN].offset);
			if (rc < 0) {
				pr_err("error while reading qcom,cpr-fuse-target-quot-scale: rc=%d\n",
					rc);
				goto error;
			}

			rc = of_property_read_u32_index(of_node,
				"qcom,cpr-fuse-target-quot-scale", i * 2 + 1,
			       &quot_scale[i + CPR_FUSE_CORNER_MIN].multiplier);
			if (rc < 0) {
				pr_err("error while reading qcom,cpr-fuse-target-quot-scale: rc=%d\n",
					rc);
				goto error;
			}
		}
	} else {
		/*
		 * In the default case, target quotients require no scaling so
		 * use offset = 0, multiplier = 1.
		 */
		for (i = CPR_FUSE_CORNER_MIN; i <= cpr_vreg->num_fuse_corners;
		     i++) {
			quot_scale[i].offset = 0;
			quot_scale[i].multiplier = 1;
		}
	}

	rc = of_property_read_u32_array(of_node, ro_sel_str,
		&bp_ro_sel[CPR_FUSE_CORNER_MIN], cpr_vreg->num_fuse_corners);
	if (rc < 0) {
@@ -2075,6 +2114,9 @@ static int cpr_init_cpr_efuse(struct platform_device *pdev,
			= cpr_read_efuse_param(cpr_vreg, cpr_fuse_row[0],
				bp_target_quot[i], target_quot_size[i],
				cpr_fuse_row[1]);
		/* Unpack the target quotient by scaling. */
		cpr_vreg->cpr_fuse_target_quot[i] *= quot_scale[i].multiplier;
		cpr_vreg->cpr_fuse_target_quot[i] += quot_scale[i].offset;
		pr_info("Corner[%d]: ro_sel = %d, target quot = %d\n", i,
			cpr_vreg->cpr_fuse_ro_sel[i],
			cpr_vreg->cpr_fuse_target_quot[i]);
@@ -2138,6 +2180,7 @@ error:
	kfree(bp_ro_sel);
	kfree(quot_adjust);
	kfree(target_quot_size);
	kfree(quot_scale);

	return rc;
}