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

Commit 8bfca258 authored by David Collins's avatar David Collins
Browse files

regulator: cpr3-hmss-regulator: add support for CBF voltage offset fuses



Add support for the CBF open-loop/closed-loop voltage offset
fuses found on MSM8996-Pro chips.  These fuses define independent
open-loop voltages and closed-loop target quotients for the power
cluster and CBF clock which share CPR hardware thread 0.  This
independent fusing ensures optimal VDD supply voltage for all
power cluster, performance cluster, CBF corner combinations.

Change-Id: I2e309d683f853f8bd9fd4eb6d12b05c32c7aaf26
CRs-Fixed: 980901
Signed-off-by: default avatarDavid Collins <collinsd@codeaurora.org>
parent 2d22d761
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -209,6 +209,13 @@ HMSS specific properties:
		    given regulator type.  For HMSS the maximum supported value
		    is 2.

- qcom,is-cbf-regulator
	Usage:      optional
	Value type: <empty>
	Definition: Boolean flag which indicates that the CPR3 regulator
		    corresponds to the CBF clock domain.  Special fuses are
		    defined for the CBF CPR3 regulator on MSM8996-Pro chips.

- qcom,ldo-min-headroom-voltage
	Usage:      required if vdd-threadN-ldo-supply is specified for the
		    CPR3 thread containing this CPR3 regulator and this CPR3
@@ -418,6 +425,7 @@ apcc_cpr: cpr3-ctrl@99e8000 {
			regulator-name = "apc0_cbf_corner";
			regulator-min-microvolt = <1>;
			regulator-max-microvolt = <10>;
			qcom,is-cbf-regulator;

			qcom,cpr-pd-bypass-mask = <0x18>;
			qcom,cpr-fuse-corners = <5>;
+95 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@
 *			interpolation
 * @speed_bin:		Application processor speed bin fuse parameter value for
 *			the given chip
 * @cbf_voltage_offset:	Voltage margin offset for the CBF regulator used on
 *			MSM8996-Pro chips.
 * @cpr_fusing_rev:	CPR fusing revision fuse parameter value
 * @redundant_fusing:	Redundant fusing select fuse parameter value
 * @limitation:		CPR limitation select fuse parameter value
@@ -71,6 +73,7 @@ struct cpr3_msm8996_hmss_fuses {
	u64	init_voltage[MSM8996_HMSS_FUSE_CORNERS];
	u64	target_quot[MSM8996_HMSS_FUSE_CORNERS];
	u64	quot_offset[MSM8996_HMSS_FUSE_CORNERS];
	u64	cbf_voltage_offset[MSM8996_HMSS_FUSE_CORNERS];
	u64	speed_bin;
	u64	cpr_fusing_rev;
	u64	redundant_fusing;
@@ -324,6 +327,15 @@ msm8996_hmss_aging_init_quot_diff_param[] = {
	{},
};

static const struct cpr3_fuse_param
msm8996pro_hmss_voltage_offset_param[MSM8996_HMSS_FUSE_CORNERS][4] = {
	{{68, 50, 52}, {41, 63, 63}, {} },
	{{62, 30, 31}, {62, 63, 63}, {66, 45, 45}, {} },
	{{61, 35, 36}, {61, 62, 63}, {} },
	{{61, 26, 26}, {61, 32, 34}, {} },
	{{61, 22, 25}, {} },
};

#define MSM8996PRO_SOC_ID			4

/*
@@ -391,6 +403,8 @@ static const int msm8996_vdd_mx_fuse_ret_volt[] = {

#define MSM8996_HMSS_FUSE_STEP_VOLT		10000
#define MSM8996_HMSS_VOLTAGE_FUSE_SIZE		6
#define MSM8996PRO_HMSS_CBF_FUSE_STEP_VOLT	10000
#define MSM8996PRO_HMSS_CBF_VOLTAGE_FUSE_SIZE	4
#define MSM8996_HMSS_QUOT_OFFSET_SCALE		5
#define MSM8996_HMSS_AGING_INIT_QUOT_DIFF_SCALE	2
#define MSM8996_HMSS_AGING_INIT_QUOT_DIFF_SIZE	6
@@ -406,6 +420,23 @@ static const int msm8996_vdd_mx_fuse_ret_volt[] = {
#define MSM8996_HMSS_AGING_SENSOR_ID		11
#define MSM8996_HMSS_AGING_BYPASS_MASK0		(GENMASK(7, 0) & ~BIT(3))

/**
 * cpr3_msm8996_hmss_use_voltage_offset_fuse() - return if this part utilizes
 *		voltage offset fuses or not
 * @vreg:		Pointer to the CPR3 regulator
 *
 * Return: true if this part utilizes voltage offset fuses, else false
 */
static inline bool cpr3_msm8996_hmss_use_voltage_offset_fuse(
					struct cpr3_regulator *vreg)
{
	struct cpr3_msm8996_hmss_fuses *fuse = vreg->platform_fuses;

	return vreg->thread->ctrl->soc_revision == MSM8996PRO_SOC_ID
	       && fuse->cpr_fusing_rev >= 2
	       && of_property_read_bool(vreg->of_node, "qcom,is-cbf-regulator");
}

/**
 * cpr3_msm8996_hmss_read_fuse_data() - load HMSS specific fuse parameter values
 * @vreg:		Pointer to the CPR3 regulator
@@ -570,6 +601,49 @@ static int cpr3_msm8996_hmss_read_fuse_data(struct cpr3_regulator *vreg)
	vreg->fuse_corner_count	= MSM8996_HMSS_FUSE_CORNERS;
	vreg->platform_fuses	= fuse;

	if (cpr3_msm8996_hmss_use_voltage_offset_fuse(vreg)) {
		for (i = 0; i < MSM8996_HMSS_FUSE_CORNERS; i++) {
			rc = cpr3_read_fuse_param(base,
				msm8996pro_hmss_voltage_offset_param[i],
				&fuse->cbf_voltage_offset[i]);
			if (rc) {
				cpr3_err(vreg, "Unable to read fuse-corner %d CBF voltage offset fuse, rc=%d\n",
					i, rc);
				return rc;
			}
		}
	}

	return 0;
}

/**
 * cpr3_hmss_apply_fused_voltage_offset() - adjust the fused voltages for each
 *		fuse corner according to voltage offset fuse values
 * @vreg:		Pointer to the CPR3 regulator
 * @fuse_volt:		Pointer to an array of the fused voltage values; must
 *			have length equal to vreg->fuse_corner_count
 *
 * Voltage values in fuse_volt are modified in place.
 *
 * Return: 0 on success, errno on failure
 */
static int cpr3_hmss_apply_fused_voltage_offset(struct cpr3_regulator *vreg,
		int *fuse_volt)
{
	struct cpr3_msm8996_hmss_fuses *fuse = vreg->platform_fuses;
	int i;

	if (!cpr3_msm8996_hmss_use_voltage_offset_fuse(vreg))
		return 0;

	for (i = 0; i < vreg->fuse_corner_count; i++)
		fuse_volt[i] += cpr3_convert_open_loop_voltage_fuse(
					0,
					MSM8996PRO_HMSS_CBF_FUSE_STEP_VOLT,
					fuse->cbf_voltage_offset[i],
					MSM8996PRO_HMSS_CBF_VOLTAGE_FUSE_SIZE);

	return 0;
}

@@ -654,6 +728,20 @@ static int cpr3_msm8996_hmss_calculate_open_loop_voltages(
				fuse_volt[i]);
	}

	if (cpr3_msm8996_hmss_use_voltage_offset_fuse(vreg)) {
		rc = cpr3_hmss_apply_fused_voltage_offset(vreg, fuse_volt);
		if (rc) {
			cpr3_err(vreg, "could not apply CBF voltage offsets, rc=%d\n",
				rc);
			goto done;
		}

		for (i = 0; i < vreg->fuse_corner_count; i++)
			cpr3_info(vreg, "fused %6s: CBF offset open-loop=%7d uV\n",
					cpr3_msm8996_hmss_fuse_corner_name[i],
					fuse_volt[i]);
	}

	rc = cpr3_adjust_fused_open_loop_voltages(vreg, fuse_volt);
	if (rc) {
		cpr3_err(vreg, "fused open-loop voltage adjustment failed, rc=%d\n",
@@ -868,6 +956,13 @@ static int cpr3_msm8996_hmss_calculate_target_quotients(
		goto done;
	}

	rc = cpr3_hmss_apply_fused_voltage_offset(vreg, volt_adjust_fuse);
	if (rc) {
		cpr3_err(vreg, "could not apply CBF voltage offsets, rc=%d\n",
			rc);
		goto done;
	}

	if (!allow_interpolation) {
		/* Use fused target quotients for lower frequencies. */
		return cpr3_msm8996_hmss_set_no_interpolation_quotients(vreg,