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

Commit b4979683 authored by Tianyi Gou's avatar Tianyi Gou
Browse files

msm: clock-krait-8974: Add support to read SVS PVS bin



On some targets, the PVS table is split into SVS freq table and
the turbo freq table. Add the support to read the SVS PVS bin and
construct the complete PVS table.

Change-Id: I5a30d295efa8d0cf0a74747f29c39ca5c3faa3d4
Signed-off-by: default avatarTianyi Gou <tgou@codeaurora.org>
parent 2f04273d
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@ Required properties:
- reg-names:		Names of the bases for the above registers. Expected
			bases are:
			"hfpll_l2_clk", "hfpll0_clk", ... "hfpllN_clk", "efuse",
			"meas"
			"efuse_svs", "meas"
- cpuX-supply:		The regulator powering the CPUX.
- l2-dig-supply:	The regulator powering the L2 digital logic.
- hfpll-dig-supply:	The regulator powering the HFPLL digital domains.
@@ -44,6 +44,8 @@ Optional properties:
			bits in the user control register.
- qcom,pvs-config-ver:
			The version of the data in qcom,speedX-pvsY-bin-vZ.
- qcom,svs-fmax:
			The max frequency for the SVS voltage for Krait.

Example:
	qcom,clock-krait@f9016000 {
@@ -53,10 +55,11 @@ Example:
			<0xf909a000 0x20>,
			<0xf90aa000 0x20>,
			<0xf90ba000 0x20>,
			<0xfc4b8458 0x04>,
			<0xfc4b80b0 0x08>;
		reg-names = "hfpll_l2_clk", "hfpll0_clk",
				"hfpll1_clk", "hfpll2_clk",
				"hfpll3_clk", "efuse";
				"hfpll3_clk", "efuse", "efuse_svs";
		cpu0-supply = <&krait0_vreg>;
		cpu1-supply = <&krait1_vreg>;
		cpu2-supply = <&krait2_vreg>;
@@ -70,6 +73,8 @@ Example:
			< 1036800000 5 /* normal */	>,
			< 1728000000 7 /* super_turbo */>;

		qcom,svs-fmax = <883200000>;

		qcom,avs-tbl =
			<  300000000 0xfa70054 >,
			< 1574400000 0xfa70100 >;
+95 −6
Original line number Diff line number Diff line
@@ -491,15 +491,17 @@ static struct clk *cpu_clk[] = {
};

static void get_krait_bin_format_b(struct platform_device *pdev,
					int *speed, int *pvs, int *pvs_ver)
			int *speed, int *pvs, int *svs_pvs, int *pvs_ver)
{
	u32 pte_efuse, redundant_sel;
	struct resource *res;
	void __iomem *base;
	void __iomem *base_svs;

	*speed = 0;
	*pvs = 0;
	*pvs_ver = 0;
	*svs_pvs = -1;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse");
	if (!res) {
@@ -539,13 +541,40 @@ static void get_krait_bin_format_b(struct platform_device *pdev,
		*speed = 0;
	}

	/* Check SVS PVS bin */
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse_svs");
	if (res) {
		base_svs = devm_ioremap(&pdev->dev, res->start,
					resource_size(res));
		/* Read the svs pvs value if status bit 28 is valid (set) */
		if (!base_svs) {
			*svs_pvs = 0;
			dev_warn(&pdev->dev,
			 "Unable to read svs efuse data. Defaulting to 0!\n");
		} else {
			pte_efuse = readl_relaxed(base_svs);
			/*
			 * Read the svs pvs value if status bit 28 is valid
			 * 4 bits of SVS PVS are in efuse register bits 27-24
			 */
			if (pte_efuse & BIT(28))
				*svs_pvs = (pte_efuse >> 24) & 0xF;

			devm_iounmap(&pdev->dev, base_svs);
		}
	}

	/* Check PVS_BLOW_STATUS */
	pte_efuse = readl_relaxed(base + 0x4) & BIT(21);
	if (pte_efuse) {
		dev_info(&pdev->dev, "PVS bin: %d\n", *pvs);
		if (*svs_pvs >= 0)
			dev_info(&pdev->dev, "SVS PVS bin: %d\n", *svs_pvs);

	} else {
		dev_warn(&pdev->dev, "PVS bin not set. Defaulting to 0!\n");
		*pvs = 0;
		*svs_pvs = -1;
	}

	dev_info(&pdev->dev, "PVS version: %d\n", *pvs_ver);
@@ -671,11 +700,11 @@ static int clock_krait_8974_driver_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct clk *c;
	int speed, pvs, pvs_ver, config_ver, rows, cpu;
	unsigned long *freq, cur_rate, aux_rate;
	int speed, pvs, svs_pvs, pvs_ver, config_ver, rows, cpu, svs_row = 0;
	unsigned long *freq, *svs_freq, cur_rate, aux_rate;
	struct resource *res;
	int *uv, *ua;
	u32 *dscr, vco_mask, config_val;
	int *uv, *ua, *svs_uv, *svs_ua;
	u32 *dscr, vco_mask, config_val, svs_fmax;
	int ret;

	vdd_l2.regulator[0] = devm_regulator_get(dev, "l2-dig");
@@ -762,7 +791,7 @@ static int clock_krait_8974_driver_probe(struct platform_device *pdev)
		dev_info(&pdev->dev, "PVS config version: %d\n", config_ver);
	}

	get_krait_bin_format_b(pdev, &speed, &pvs, &pvs_ver);
	get_krait_bin_format_b(pdev, &speed, &pvs, &svs_pvs, &pvs_ver);
	snprintf(table_name, ARRAY_SIZE(table_name),
			"qcom,speed%d-pvs%d-bin-v%d", speed, pvs, pvs_ver);

@@ -781,6 +810,66 @@ static int clock_krait_8974_driver_probe(struct platform_device *pdev)
			pvs = 0;
			rows = ret;
		}
	} else if (svs_pvs >= 0) {
		/* Find the split freq for svs fmax */
		ret = of_property_read_u32(dev->of_node, "qcom,svs-fmax",
		     &svs_fmax);
		if (ret) {
			dev_err(dev, "Unable to find krait fmax for svs\n");
			return ret;
		}

		/* Find the svs fmax freq row */
		while ((svs_row < rows) && (freq[svs_row] != svs_fmax))
			svs_row++;

		if (svs_row == rows) {
			dev_err(dev, "Invalid krait fmax for svs\n");
			return -EINVAL;
		}

		snprintf(table_name, ARRAY_SIZE(table_name),
			"qcom,speed%d-pvs%d-bin-v%d", speed, svs_pvs, pvs_ver);

		rows = parse_tbl(dev, table_name, 3,
			(u32 **) &svs_freq, (u32 **) &svs_uv, (u32 **) &svs_ua);
		if (rows > 0) {
			/* Use the svs voltage data for svs freqs */
			while (svs_row >= 0) {
				uv[svs_row] = svs_uv[svs_row];
				svs_row--;
			}

			devm_kfree(dev, svs_freq);
			devm_kfree(dev, svs_uv);
			devm_kfree(dev, svs_ua);
		} else {
			/* Fall back to most conservative svs pvs table */
			dev_err(dev, "Unable to load svs voltage plan %s!\n",
				table_name);

			snprintf(table_name, ARRAY_SIZE(table_name),
			"qcom,speed0-pvs0-bin-v%d", pvs_ver);

			rows = parse_tbl(dev, table_name, 3,
				(u32 **) &svs_freq, (u32 **) &svs_uv,
				(u32 **) &svs_ua);
			if (rows < 0) {
				dev_err(dev, "Unable to load safe voltage plan.\n");
				return rows;
			} else {
				dev_info(dev, "Safe svs voltage plan loaded.\n");

				while (svs_row >= 0) {
					uv[svs_row] = svs_uv[svs_row];
					svs_row--;
				}

				devm_kfree(dev, svs_freq);
				devm_kfree(dev, svs_uv);
				devm_kfree(dev, svs_ua);
			}
		}
	}

	krait_update_uv(uv, rows, pvs ? 25000 : 0);