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

Commit 16daa3f1 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

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

parents d385332d b4979683
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
@@ -490,15 +490,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) {
@@ -538,13 +540,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);
@@ -670,11 +699,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");
@@ -761,7 +790,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);

@@ -780,6 +809,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);