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

Commit f1c02c5d authored by David Collins's avatar David Collins
Browse files

regulator: cpr3-regulator: add support for system supply voltage requests



Add support for setting the voltage of the system-supply
regulator when the voltage of the vdd-supply regulator is scaled.
The vdd-supply regulator may optionally depend upon the
system-supply regulator.  For example, the system-supply could be
configured as the VDD_CX or VDD_MX supply in order to satisfy
hardware requirements.

Change-Id: I652ddc9cf80d531de49d6fa5028d8974d65bc51c
Signed-off-by: default avatarDavid Collins <collinsd@codeaurora.org>
parent 4ca83ef2
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -56,6 +56,14 @@ Platform independent properties:
	Definition: phandle of the underlying regulator device that is managed
		    by this CPR controller.

- system-supply
	Usage:      optional
	Value type: <phandle>
	Definition: phandle of the system-level regulator device which the
		    vdd-supply depends upon.  Requests for this regulator must
		    be made before increasing the vdd-supply voltage and after
		    decreasing the vdd-supply voltage.

- clocks
	Usage:      required
	Value type: <prop-encoded-array>
@@ -276,6 +284,16 @@ Platform independent properties:
		    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>
	Definition: A list of integer tuples which each define the system-supply
		    voltage in microvolts or corners or levels for each voltage
		    corner in order from lowest to highest.

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

- qcom,corner-frequencies
	Usage:      required
	Value type: <prop-encoded-array>
+44 −0
Original line number Diff line number Diff line
@@ -948,6 +948,7 @@ static int cpr3_regulator_scale_vdd_voltage(struct cpr3_controller *ctrl,
	}

	if (new_volt < last_volt) {
		/* Decreasing VDD voltage */
		rc = cpr3_regulator_config_ldo(ctrl, aggr_corner->floor_volt,
					       last_max_volt, last_volt);
		if (rc) {
@@ -955,6 +956,17 @@ static int cpr3_regulator_scale_vdd_voltage(struct cpr3_controller *ctrl,
				 rc);
			return rc;
		}
	} else {
		/* Increasing VDD voltage */
		if (ctrl->system_regulator) {
			rc = regulator_set_voltage(ctrl->system_regulator,
				aggr_corner->system_volt, INT_MAX);
			if (rc) {
				cpr3_err(ctrl, "regulator_set_voltage(system) == %d failed, rc=%d\n",
					aggr_corner->system_volt, rc);
				return rc;
			}
		}
	}

	/*
@@ -972,6 +984,7 @@ static int cpr3_regulator_scale_vdd_voltage(struct cpr3_controller *ctrl,
	}

	if (new_volt >= last_volt) {
		/* Increasing VDD voltage */
		rc = cpr3_regulator_config_ldo(ctrl, aggr_corner->floor_volt,
					       max_volt, new_volt);
		if (rc) {
@@ -979,6 +992,17 @@ static int cpr3_regulator_scale_vdd_voltage(struct cpr3_controller *ctrl,
				 rc);
			return rc;
		}
	} else {
		/* Decreasing VDD voltage */
		if (ctrl->system_regulator) {
			rc = regulator_set_voltage(ctrl->system_regulator,
				aggr_corner->system_volt, INT_MAX);
			if (rc) {
				cpr3_err(ctrl, "regulator_set_voltage(system) == %d failed, rc=%d\n",
					aggr_corner->system_volt, rc);
				return rc;
			}
		}
	}

	return 0;
@@ -1008,6 +1032,8 @@ static void cpr3_regulator_aggregate_corners(struct cpr3_corner *aggr_corner,
		= max(aggr_corner->last_volt, corner->last_volt);
	aggr_corner->open_loop_volt
		= max(aggr_corner->open_loop_volt, corner->open_loop_volt);
	aggr_corner->system_volt
		= max(aggr_corner->system_volt, corner->system_volt);
	aggr_corner->irq_en |= corner->irq_en;

	if (aggr_quot) {
@@ -1357,6 +1383,15 @@ static int cpr3_regulator_enable(struct regulator_dev *rdev)

	mutex_lock(&ctrl->lock);

	if (ctrl->system_regulator) {
		rc = regulator_enable(ctrl->system_regulator);
		if (rc) {
			cpr3_err(ctrl, "regulator_enable(system) failed, rc=%d\n",
				rc);
			goto done;
		}
	}

	rc = regulator_enable(ctrl->vdd_regulator);
	if (rc) {
		cpr3_err(vreg, "regulator_enable(vdd) failed, rc=%d\n", rc);
@@ -1449,6 +1484,15 @@ static int cpr3_regulator_disable(struct regulator_dev *rdev)
		goto done;
	}

	if (ctrl->system_regulator) {
		rc = regulator_disable(ctrl->system_regulator);
		if (rc) {
			cpr3_err(ctrl, "regulator_disable(system) failed, rc=%d\n",
				rc);
			goto done;
		}
	}

	cpr3_debug(vreg, "Disabled\n");
done:
	mutex_unlock(&ctrl->lock);
+6 −0
Original line number Diff line number Diff line
@@ -58,6 +58,8 @@ struct cpr3_fuse_param {
 *			microvolts
 * @last_volt:		Last known settled CPR closed-loop voltage which is used
 *			when switching to a new corner
 * @system_volt:	The system-supply voltage in microvolts or corners or
 *			levels
 * @proc_freq:		Processor frequency in Hertz (only used by platform
 *			specific CPR3 driver for interpolation)
 * @cpr_fuse_corner:	Fused corner index associated with this virtual corner
@@ -83,6 +85,7 @@ struct cpr3_corner {
	int			ceiling_volt;
	int			open_loop_volt;
	int			last_volt;
	int			system_volt;
	u32			proc_freq;
	int			cpr_fuse_corner;
	u32			target_quot[CPR3_RO_COUNT];
@@ -261,6 +264,8 @@ enum cpr3_count_mode {
 *			all of the threads associated with the controller
 * @vdd_regulator:	Pointer to the VDD supply regulator which this CPR3
 *			controller manages
 * @system_regulator:	Pointer to the optional system-supply regulator upon
 *			which the VDD supply regulator depends.
 * @vdd_limit_regulator: Pointer to the VDD supply limit regulator which is used
 *			for hardware closed-loop in order specify ceiling and
 *			floor voltage limits (platform specific)
@@ -347,6 +352,7 @@ struct cpr3_controller {
	int			sensor_count;
	struct mutex		lock;
	struct regulator	*vdd_regulator;
	struct regulator	*system_regulator;
	struct regulator	*vdd_limit_regulator;
	struct clk		*core_clk;
	struct clk		*iface_clk;
+22 −0
Original line number Diff line number Diff line
@@ -478,6 +478,16 @@ int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg,
		}
	}

	/* Load optional system-supply voltages */
	if (of_find_property(vreg->of_node, "qcom,system-voltage", NULL)) {
		rc = cpr3_parse_array_property(vreg, "qcom,system-voltage",
			vreg->corner_count, *corner_sum, *combo_offset, temp);
		if (rc)
			goto free_temp;
		for (i = 0; i < vreg->corner_count; i++)
			vreg->corner[i].system_volt = temp[i];
	}

	rc = cpr3_parse_array_property(vreg, "qcom,corner-frequencies",
			vreg->corner_count, *corner_sum, *combo_offset, temp);
	if (rc)
@@ -732,6 +742,18 @@ int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl)
		return rc;
	}

	ctrl->system_regulator = devm_regulator_get_optional(ctrl->dev,
								"system");
	if (IS_ERR(ctrl->system_regulator)) {
		rc = PTR_ERR(ctrl->system_regulator);
		if (rc != -EPROBE_DEFER) {
			rc = 0;
			ctrl->system_regulator = NULL;
		} else {
			return rc;
		}
	}

	return rc;
}