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

Commit a407b856 authored by Ke Liu's avatar Ke Liu
Browse files

msm: cpr-regulator: add support for conditional minimum voltage



Certain targets have VDD_APC minimum voltage constraints which are
imposed if the mem-accel fuse has not been programmed. Add two new
device tree properties to capture the row offset and expected value
of the mem-accel fuse as well as to capture the minimum VDD_APC voltage
to enforce if the mem-accel fuse has not been programmed with the
expected value.

CRs-Fixed: 580585
Change-Id: Ifd770b33d74b2bc9cf37dd2b1817e1424a5ee8f3
Signed-off-by: default avatarKe Liu <keliu@codeaurora.org>
parent 6bca069b
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -147,6 +147,15 @@ Optional properties:
					is present, and vise versa.
- qti,cpr-enable:		Present: CPR enabled by default.
				Not Present: CPR disable by default.
- qti,cpr-cond-min-voltage:	Minimum voltage in microvolts for SVS, NOM and TURBO mode
				if the fuse defined in qti,cpr-cond-min-volt-fuse has not be programmed with the expected data.
- qti,cpr-cond-min-volt-fuse:	Array of row number of fuse, data in that row and reading method.
				This property can be used to capture hardware requirements determined
				by the value of the mem-accel fuse. It should have index and value like this:
				 [0]: the fuse row number
				 [1]: high 32 bits of the expected data in that row.
				 [2]: low 32 bits of the expected data in that row.
				 [3]: reading method, 0 for direct reading or 1 for SCM reading


Example:
@@ -202,5 +211,6 @@ Example:
		qti,cpr-fuse-redun-row = <139 1>;
		qti,cpr-fuse-redun-target-quot = <24 12 0>;
		qti,cpr-fuse-redun-ro-sel = <46 36 39>;
		qti,cpr-cond-min-volt-fuse = <54 0xc100 0x0 1>;
	};
+40 −1
Original line number Diff line number Diff line
@@ -138,6 +138,8 @@

#define BYTES_PER_FUSE_ROW		8

#define FLAGS_SET_MIN_VOLTAGE		BIT(1)

enum voltage_change_dir {
	NO_CHANGE,
	DOWN,
@@ -209,6 +211,7 @@ struct cpr_regulator {
	u32		gcnt_time_us;
	u32		vdd_apc_step_up_limit;
	u32		vdd_apc_step_down_limit;
	u32		flags;
};

#define CPR_DEBUG_MASK_IRQ	BIT(0)
@@ -1464,11 +1467,35 @@ static void cpr_efuse_free(struct cpr_regulator *cpr_vreg)
	iounmap(cpr_vreg->efuse_base);
}

static void cpr_parse_cond_min_volt_fuse(struct cpr_regulator *cpr_vreg,
						struct device_node *of_node)
{
	int rc;
	u32 fuse[4];
	u64 blown_data, fuse_data;

	/*
	 * Restrict all pvs corner voltages to a minimum value of
	 * qti,cpr-cond-min-voltage if the fuse defined in
	 * qti,cpr-cond-min-volt-fuse does not read back with the expected
	 * value.
	 */
	rc = of_property_read_u32_array(of_node, "qti,cpr-cond-min-volt-fuse",
					fuse, 4);
	if (!rc) {
		blown_data = cpr_read_efuse_row(cpr_vreg, fuse[0], fuse[3]);
		fuse_data = ((u64)fuse[1] << 32) | fuse[2];
		if (blown_data == fuse_data)
			cpr_vreg->flags |= FLAGS_SET_MIN_VOLTAGE;
	}
}

static int cpr_voltage_plan_init(struct platform_device *pdev,
					struct cpr_regulator *cpr_vreg)
{
	struct device_node *of_node = pdev->dev.of_node;
	int rc, i;
	int rc, i, j;
	u32 min_uv = 0;

	rc = of_property_read_u32_array(of_node,
		"qti,pvs-corner-ceiling-slow",
@@ -1497,6 +1524,18 @@ static int cpr_voltage_plan_init(struct platform_device *pdev,
		return rc;
	}

	cpr_parse_cond_min_volt_fuse(cpr_vreg, of_node);

	if (cpr_vreg->flags & FLAGS_SET_MIN_VOLTAGE) {
		of_property_read_u32(of_node, "qti,cpr-cond-min-voltage",
					&min_uv);

		for (i = APC_PVS_SLOW; i < NUM_APC_PVS; i++)
			for (j = CPR_CORNER_SVS; j < CPR_CORNER_MAX; j++)
				if (cpr_vreg->pvs_corner_v[i][j] < min_uv)
					cpr_vreg->pvs_corner_v[i][j] = min_uv;
	}

	/* Set ceiling max and use it for APC_PVS_NO */
	cpr_vreg->ceiling_max =
		cpr_vreg->pvs_corner_v[APC_PVS_SLOW][CPR_CORNER_TURBO];