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

Commit 0b84c10a authored by David Collins's avatar David Collins
Browse files

regulator: cpr3-regulator: add support for max floor to ceiling range



Add support for specifying a maximum floor to ceiling voltage
range for each corner in device tree.  Use the greater of the
original floor voltage and (ceiling voltage - range) as the CPR
floor voltage at runtime.

Change-Id: Ic6b46016d355f315f23ab61813f6df3178bea3ef
Signed-off-by: default avatarDavid Collins <collinsd@codeaurora.org>
parent 06a5f474
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -284,6 +284,24 @@ Platform independent properties:
		    The list and tuples must meet the same size requirements as
		    those specified for qcom,cpr-voltage-ceiling above.

- qcom,cpr-floor-to-ceiling-max-range
	Usage:      optional
	Value type: <prop-encoded-array>
	Definition: A list of integer tuples which each define the maximum
		    allowed difference between the final floor voltage and the
		    final ceiling voltage in microvolts for each voltage corner
		    in order from lowest to highest.  A negative value may be
		    specified for an element to indicate that there is no
		    limitation of the floor to ceiling voltage range for the
		    corresponding corner.

		    In the case that the initial floor to ceiling voltage is
		    greater than the max range specified, the floor voltage will
		    be increased in order to satisfy the max range constraint.

		    The list and tuples must meet the same size requirements as
		    those specified for qcom,cpr-voltage-ceiling above.

- qcom,system-voltage
	Usage:      optional
	Value type: <prop-encoded-array>
+6 −0
Original line number Diff line number Diff line
@@ -1189,6 +1189,12 @@ static int cpr3_hmss_init_regulator(struct cpr3_regulator *vreg)

	cpr3_open_loop_voltage_as_ceiling(vreg);

	rc = cpr3_limit_floor_voltages(vreg, corner_sum, combo_offset);
	if (rc) {
		cpr3_err(vreg, "unable to limit floor voltages, rc=%d\n", rc);
		return rc;
	}

	rc = cpr3_msm8996_hmss_calculate_target_quotients(vreg, corner_sum,
			combo_offset);
	if (rc) {
+6 −0
Original line number Diff line number Diff line
@@ -534,6 +534,12 @@ static int cpr3_mmss_init_thread(struct cpr3_thread *thread)

	cpr3_open_loop_voltage_as_ceiling(vreg);

	rc = cpr3_limit_floor_voltages(vreg, corner_sum, combo_offset);
	if (rc) {
		cpr3_err(vreg, "unable to limit floor voltages, rc=%d\n", rc);
		return rc;
	}

	cpr3_mmss_print_settings(vreg);

	return 0;
+8 −0
Original line number Diff line number Diff line
@@ -434,6 +434,8 @@ int cpr3_parse_common_thread_data(struct cpr3_thread *thread);
int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl);
int cpr3_limit_open_loop_voltages(struct cpr3_regulator *vreg);
void cpr3_open_loop_voltage_as_ceiling(struct cpr3_regulator *vreg);
int cpr3_limit_floor_voltages(struct cpr3_regulator *vreg, int corner_sum,
		int combo_offset);
void cpr3_print_quots(struct cpr3_regulator *vreg);
int cpr3_adjust_fused_open_loop_voltages(struct cpr3_regulator *vreg,
		int *fuse_volt);
@@ -547,6 +549,12 @@ static inline void cpr3_open_loop_voltage_as_ceiling(
	return;
}

static inline int cpr3_limit_floor_voltages(struct cpr3_regulator *vreg,
			int corner_sum, int combo_offset)
{
	return -EPERM;
}

static inline void cpr3_print_quots(struct cpr3_regulator *vreg)
{
	return;
+53 −0
Original line number Diff line number Diff line
@@ -814,6 +814,59 @@ void cpr3_open_loop_voltage_as_ceiling(struct cpr3_regulator *vreg)
			= vreg->corner[i].open_loop_volt;
}

/**
 * cpr3_limit_floor_voltages() - raise the floor voltage of each corner so that
 *		the optional maximum floor to ceiling voltage range specified in
 *		device tree is satisfied
 * @vreg:		Pointer to the CPR3 regulator
 * @corner_sum:		The sum of the corner counts across all fuse combos
 * @combo_offset:	The array offset for the selected fuse combo
 *
 * This function also ensures that the open-loop voltage for each corner falls
 * within the final floor to ceiling voltage range.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_limit_floor_voltages(struct cpr3_regulator *vreg, int corner_sum,
				int combo_offset)
{
	char *prop = "qcom,cpr-floor-to-ceiling-max-range";
	int i, rc, floor_new;
	u32 *floor_range;

	if (!of_find_property(vreg->of_node, prop, NULL))
		return 0;

	floor_range = kcalloc(vreg->corner_count, sizeof(*floor_range),
				GFP_KERNEL);
	if (!floor_range)
		return -ENOMEM;

	rc = cpr3_parse_array_property(vreg, prop, vreg->corner_count,
					corner_sum, combo_offset, floor_range);
	if (rc)
		goto free_floor_adjust;

	for (i = 0; i < vreg->corner_count; i++) {
		if ((s32)floor_range[i] >= 0) {
			floor_new = CPR3_ROUND(vreg->corner[i].ceiling_volt
							- floor_range[i],
						vreg->thread->ctrl->step_volt);

			vreg->corner[i].floor_volt = max(floor_new,
						vreg->corner[i].floor_volt);
			if (vreg->corner[i].open_loop_volt
			    < vreg->corner[i].floor_volt)
				vreg->corner[i].open_loop_volt
					= vreg->corner[i].floor_volt;
		}
	}

free_floor_adjust:
	kfree(floor_range);
	return rc;
}

/**
 * cpr3_print_quots() - print CPR target quotients into the kernel log for
 *		debugging purposes