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

Commit 1e04840b authored by David Collins's avatar David Collins
Browse files

clk: qcom: clk-cpu-osm: remove CPR revision check from MX supply voting



Remove the CPR fusing revision check from the logic which
determines if a given frequency requires the MX supply at
Nominal or Turbo voltage level.  This is needed as some later
revision parts may require MX at Turbo for high frequencies.

Also, make MX supply voting optional.

Change-Id: I5c5ac1aaa756197e68f5077ff8baaf94e513aab7
Signed-off-by: default avatarDavid Collins <collinsd@codeaurora.org>
parent d9f72f76
Loading
Loading
Loading
Loading
+12 −14
Original line number Diff line number Diff line
@@ -21,27 +21,27 @@ Properties:
	Usage:      required
	Value type: <stringlist>
	Definition: Address names. Must be "osm_l3_base", "osm_pwrcl_base",
		    "osm_perfcl_base", and "cpr_rc".
		    "osm_perfcl_base".
		    Must be specified in the same order as the corresponding
		    addresses are specified in the reg property.

- qcom,mx-turbo-freq
	Usage:      optional
	Value type: <array>
	Definition: List of frequencies for the 3 clock domains (following the
		    order of L3, power, and performance clusters) that denote
		    the lowest rate that requires a TURBO vote on the MX rail.

- vdd_l3_mx_ao-supply
	Usage:      required
	Usage:      required if qcom,mx-turbo-freq is specified
	Value type: <phandle>
	Definition: Phandle to the MX active-only regulator device.

- vdd_pwrcl_mx_ao-supply
	Usage:      required
	Usage:      required if qcom,mx-turbo-freq is specified
	Value type: <phandle>
	Definition: Phandle to the MX active-only regulator device.

- qcom,mx-turbo-freq
	Usage:      required
	Value type: <array>
	Definition: List of frequencies for the 3 clock domains (following the
		    order of L3, power, and performance clusters) that denote
		    the lowest rate that requires a TURBO vote on the MX rail.

- l3-devs
	Usage: optional
	Value type: <phandle>
@@ -63,10 +63,8 @@ Example:
		compatible = "qcom,clk-cpu-osm";
		reg = <0x17d41000 0x1400>,
			<0x17d43000 0x1400>,
			<0x17d45800 0x1400>,
			<0x784248 0x4>;
		reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base",
							"cpr_rc";
			<0x17d45800 0x1400>;
		reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base";
		vdd_l3_mx_ao-supply = <&pm8998_s6_level_ao>;
		vdd_pwrcl_mx_ao-supply = <&pm8998_s6_level_ao>;

+3 −5
Original line number Diff line number Diff line
@@ -1034,14 +1034,12 @@
		compatible = "qcom,clk-cpu-osm-sdm670";
		reg = <0x17d41000 0x1400>,
			<0x17d43000 0x1400>,
			<0x17d45800 0x1400>,
			<0x784248 0x4>;
		reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base",
				"cpr_rc";
			<0x17d45800 0x1400>;
		reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base";
		vdd_l3_mx_ao-supply = <&pm660l_s1_level_ao>;
		vdd_pwrcl_mx_ao-supply = <&pm660l_s1_level_ao>;

		qcom,mx-turbo-freq = <1478400000 1689600000 3300000001>;
		qcom,mx-turbo-freq = <3300000001 3300000001 3300000001>;
		l3-devs = <&l3_cpu0 &l3_cpu6>;

		clock-names = "xo_ao";
+0 −6
Original line number Diff line number Diff line
@@ -81,12 +81,6 @@

&clock_cpucc {
	compatible = "qcom,clk-cpu-osm-v2";
	reg = <0x17d41000 0x1400>,
		<0x17d43000 0x1400>,
		<0x17d45800 0x1400>,
		<0x78425c 0x4>;
	reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base",
							"cpr_rc";
};

&pcie1 {
+2 −4
Original line number Diff line number Diff line
@@ -1229,10 +1229,8 @@
		compatible = "qcom,clk-cpu-osm";
		reg = <0x17d41000 0x1400>,
			<0x17d43000 0x1400>,
			<0x17d45800 0x1400>,
			<0x784248 0x4>;
		reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base",
							"cpr_rc";
			<0x17d45800 0x1400>;
		reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base";
		vdd_l3_mx_ao-supply = <&pm8998_s6_level_ao>;
		vdd_pwrcl_mx_ao-supply = <&pm8998_s6_level_ao>;

+58 −70
Original line number Diff line number Diff line
@@ -55,9 +55,6 @@
#define VOLT_REG			0x114
#define CORE_DCVS_CTRL			0xbc

#define EFUSE_SHIFT(v1)			((v1) ? 3 : 2)
#define EFUSE_MASK			0x7

#define DCVS_PERF_STATE_DESIRED_REG_0_V1	0x780
#define DCVS_PERF_STATE_DESIRED_REG_0_V2	0x920
#define DCVS_PERF_STATE_DESIRED_REG(n, v1) \
@@ -94,7 +91,6 @@ struct clk_osm {
	u32 prev_cycle_counter;
	u32 max_core_count;
	u32 mx_turbo_freq;
	unsigned int cpr_rc;
};

static bool is_sdm845v1;
@@ -979,8 +975,7 @@ static int clk_osm_read_lut(struct platform_device *pdev, struct clk_osm *c)
			return -ENOMEM;

		for (i = 0; i < j; i++) {
			if (c->osm_table[i].frequency < c->mx_turbo_freq ||
								(c->cpr_rc > 1))
			if (c->osm_table[i].frequency < c->mx_turbo_freq)
				vdd->vdd_uv[i] = RPMH_REGULATOR_LEVEL_NOM;
			else
				vdd->vdd_uv[i] = RPMH_REGULATOR_LEVEL_TURBO;
@@ -1071,19 +1066,68 @@ static void clk_cpu_osm_driver_sdm670_fixup(void)
	perfcl_clk.max_core_count = 2;
}

/* Request MX supply if configured in device tree */
static int clk_cpu_osm_request_mx_supply(struct device *dev)
{
	u32 *array;
	int rc;

	if (!of_find_property(dev->of_node, "qcom,mx-turbo-freq", NULL)) {
		osm_clks_init[l3_clk.cluster_num].vdd_class = NULL;
		osm_clks_init[pwrcl_clk.cluster_num].vdd_class = NULL;
		return 0;
	}

	vdd_l3_mx_ao.regulator[0] = devm_regulator_get(dev, "vdd_l3_mx_ao");
	if (IS_ERR(vdd_l3_mx_ao.regulator[0])) {
		rc = PTR_ERR(vdd_l3_mx_ao.regulator[0]);
		if (rc != -EPROBE_DEFER)
			dev_err(dev, "Unable to get vdd_l3_mx_ao regulator, rc=%d\n",
				rc);
		return rc;
	}

	vdd_pwrcl_mx_ao.regulator[0] = devm_regulator_get(dev,
							"vdd_pwrcl_mx_ao");
	if (IS_ERR(vdd_pwrcl_mx_ao.regulator[0])) {
		rc = PTR_ERR(vdd_pwrcl_mx_ao.regulator[0]);
		if (rc != -EPROBE_DEFER)
			dev_err(dev, "Unable to get vdd_pwrcl_mx_ao regulator, rc=%d\n",
				rc);
		return rc;
	}

	array = kcalloc(MAX_CLUSTER_CNT, sizeof(*array), GFP_KERNEL);
	if (!array)
		return -ENOMEM;

	rc = of_property_read_u32_array(dev->of_node, "qcom,mx-turbo-freq",
					array, MAX_CLUSTER_CNT);
	if (rc) {
		dev_err(dev, "unable to read qcom,mx-turbo-freq property, rc=%d\n",
			rc);
		kfree(array);
		return rc;
	}

	l3_clk.mx_turbo_freq = array[l3_clk.cluster_num];
	pwrcl_clk.mx_turbo_freq = array[pwrcl_clk.cluster_num];
	perfcl_clk.mx_turbo_freq = array[perfcl_clk.cluster_num];

	kfree(array);

	return 0;
}

static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
{
	int rc = 0, i, cpu;
	bool is_sdm670 = false;
	u32 *array;
	u32 val, pte_efuse;
	void __iomem *vbase;
	u32 val;
	int num_clks = ARRAY_SIZE(osm_qcom_clk_hws);
	struct clk *ext_xo_clk, *clk;
	struct clk_osm *osm_clk;
	struct device *dev = &pdev->dev;
	struct clk_onecell_data *clk_data;
	struct resource *res;
	struct cpu_cycle_counter_cb cb = {
		.get_cpu_cycle_counter = clk_osm_get_cpu_cycle_counter,
	};
@@ -1103,68 +1147,12 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
					"qcom,clk-cpu-osm");

	if (of_device_is_compatible(pdev->dev.of_node,
					 "qcom,clk-cpu-osm-sdm670")) {
		is_sdm670 = true;
					 "qcom,clk-cpu-osm-sdm670"))
		clk_cpu_osm_driver_sdm670_fixup();
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cpr_rc");
	if (res) {
		vbase = devm_ioremap(&pdev->dev, res->start,
						resource_size(res));
		if (!vbase) {
			dev_err(&pdev->dev, "Unable to map in cpr_rc base\n");
			return -ENOMEM;
		}
		pte_efuse = readl_relaxed(vbase);
		l3_clk.cpr_rc = pwrcl_clk.cpr_rc = perfcl_clk.cpr_rc =
			((pte_efuse >> EFUSE_SHIFT(is_sdm845v1 | is_sdm670))
							& EFUSE_MASK);
		pr_info("LOCAL_CPR_RC: %u\n", l3_clk.cpr_rc);
		devm_iounmap(&pdev->dev, vbase);
	} else {
		dev_err(&pdev->dev,
			"Unable to get platform resource for cpr_rc\n");
		return -ENOMEM;
	}

	vdd_l3_mx_ao.regulator[0] = devm_regulator_get(&pdev->dev,
						"vdd_l3_mx_ao");
	if (IS_ERR(vdd_l3_mx_ao.regulator[0])) {
		if (PTR_ERR(vdd_l3_mx_ao.regulator[0]) != -EPROBE_DEFER)
			dev_err(&pdev->dev,
				"Unable to get vdd_l3_mx_ao regulator\n");
		return PTR_ERR(vdd_l3_mx_ao.regulator[0]);
	}

	vdd_pwrcl_mx_ao.regulator[0] = devm_regulator_get(&pdev->dev,
						"vdd_pwrcl_mx_ao");
	if (IS_ERR(vdd_pwrcl_mx_ao.regulator[0])) {
		if (PTR_ERR(vdd_pwrcl_mx_ao.regulator[0]) != -EPROBE_DEFER)
			dev_err(&pdev->dev,
				"Unable to get vdd_pwrcl_mx_ao regulator\n");
		return PTR_ERR(vdd_pwrcl_mx_ao.regulator[0]);
	}

	array = devm_kcalloc(&pdev->dev, MAX_CLUSTER_CNT, sizeof(*array),
							GFP_KERNEL);
	if (!array)
		return -ENOMEM;

	rc = of_property_read_u32_array(pdev->dev.of_node, "qcom,mx-turbo-freq",
							array, MAX_CLUSTER_CNT);
	if (rc) {
		dev_err(&pdev->dev, "unable to find qcom,mx-turbo-freq property, rc=%d\n",
							rc);
		devm_kfree(&pdev->dev, array);
	rc = clk_cpu_osm_request_mx_supply(dev);
	if (rc)
		return rc;
	}

	l3_clk.mx_turbo_freq = array[l3_clk.cluster_num];
	pwrcl_clk.mx_turbo_freq = array[pwrcl_clk.cluster_num];
	perfcl_clk.mx_turbo_freq = array[perfcl_clk.cluster_num];

	devm_kfree(&pdev->dev, array);

	clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data),
								GFP_KERNEL);