linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Support regulators coupling on NVIDIA Tegra20/30
@ 2019-07-25 15:18 Dmitry Osipenko
  2019-07-25 15:18 ` [PATCH v2 1/3] dt-bindings: regulator: Document regulators coupling of NVIDIA Tegra20/30 SoCs Dmitry Osipenko
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Dmitry Osipenko @ 2019-07-25 15:18 UTC (permalink / raw)
  To: Rob Herring, Thierry Reding, Peter De Schrijver, Jonathan Hunter,
	Mark Brown
  Cc: devicetree, linux-tegra, linux-kernel

Hello,

The voltage regulators need to be coupled on NVIDIA Tegra20 and Tegra30
SoCs in order to provide voltage scaling functionality in a generic way.
All necessary regulator-core patches that added support for the regulators
coupling are already have been merge into mainline kernel. This series
adds customized voltage couplers for Tegra20/30 SoCs, paving the way for
a refined CPUFreq driver that will utilize voltage scaling and other neat
features. This is a resend of a leftover patches from a previous series
[1] that was partially applied by Mark Brown. Please review, thanks in
advance!

[1] https://patchwork.ozlabs.org/project/linux-tegra/list/?series=115626

Changelog:

v2: - Some days ago OPP framework got a change that makes CPU regulator
      to be enabled at the time of CPUFreq's driver initializing OPPs.
      In a result the CPU's voltage is dropped to a minimum value on
      CPUFreq's setting up because there are no consumers at the time
      of regulator's enabling, thus CPU is getting into a big trouble.
      This problem is now resolved in the couplers code by assuming
      that min_uV=current_uV for CPU's regulator if it doesn't have
      any active consumers.

Dmitry Osipenko (3):
  dt-bindings: regulator: Document regulators coupling of NVIDIA
    Tegra20/30 SoCs
  soc/tegra: regulators: Add regulators coupler for Tegra20
  soc/tegra: regulators: Add regulators coupler for Tegra30

 .../nvidia,tegra-regulators-coupling.txt      |  65 ++++
 drivers/soc/tegra/Kconfig                     |  10 +
 drivers/soc/tegra/Makefile                    |   2 +
 drivers/soc/tegra/regulators-tegra20.c        | 364 ++++++++++++++++++
 drivers/soc/tegra/regulators-tegra30.c        | 316 +++++++++++++++
 5 files changed, 757 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt
 create mode 100644 drivers/soc/tegra/regulators-tegra20.c
 create mode 100644 drivers/soc/tegra/regulators-tegra30.c

-- 
2.22.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 1/3] dt-bindings: regulator: Document regulators coupling of NVIDIA Tegra20/30 SoCs
  2019-07-25 15:18 [PATCH v2 0/3] Support regulators coupling on NVIDIA Tegra20/30 Dmitry Osipenko
@ 2019-07-25 15:18 ` Dmitry Osipenko
  2019-08-02 14:47   ` Dmitry Osipenko
  2019-08-16 21:34   ` Rob Herring
  2019-07-25 15:18 ` [PATCH v2 2/3] soc/tegra: regulators: Add regulators coupler for Tegra20 Dmitry Osipenko
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 12+ messages in thread
From: Dmitry Osipenko @ 2019-07-25 15:18 UTC (permalink / raw)
  To: Rob Herring, Thierry Reding, Peter De Schrijver, Jonathan Hunter,
	Mark Brown
  Cc: devicetree, linux-tegra, linux-kernel

There is voltage coupling between three regulators on Tegra20 boards and
between two on Tegra30. The voltage coupling is a SoC-level feature and
thus it is mandatory and common for all of the Tegra boards.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../nvidia,tegra-regulators-coupling.txt      | 65 +++++++++++++++++++
 1 file changed, 65 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt

diff --git a/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt b/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt
new file mode 100644
index 000000000000..4bf2dbf7c6cc
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt
@@ -0,0 +1,65 @@
+NVIDIA Tegra Regulators Coupling
+================================
+
+NVIDIA Tegra SoC's have a mandatory voltage-coupling between regulators.
+Thus on Tegra20 there are 3 coupled regulators and on NVIDIA Tegra30
+there are 2.
+
+Tegra20 voltage coupling
+------------------------
+
+On Tegra20 SoC's there are 3 coupled regulators: CORE, RTC and CPU.
+The CORE and RTC voltages shall be in a range of 170mV from each other
+and they both shall be higher than the CPU voltage by at least 120mV.
+
+Tegra30 voltage coupling
+------------------------
+
+On Tegra30 SoC's there are 2 coupled regulators: CORE and CPU. The CORE
+and CPU voltages shall be in a range of 300mV from each other and CORE
+voltage shall be higher than the CPU by N mV, where N depends on the CPU
+voltage.
+
+Required properties:
+- nvidia,tegra-core-regulator: Boolean property that designates regulator
+  as the "Core domain" voltage regulator.
+- nvidia,tegra-rtc-regulator: Boolean property that designates regulator
+  as the "RTC domain" voltage regulator.
+- nvidia,tegra-cpu-regulator: Boolean property that designates regulator
+  as the "CPU domain" voltage regulator.
+
+Example:
+
+	pmic {
+		regulators {
+			core_vdd_reg: core {
+				regulator-name = "vdd_core";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-coupled-with = <&rtc_vdd_reg &cpu_vdd_reg>;
+				regulator-coupled-max-spread = <170000 550000>;
+
+				nvidia,tegra-core-regulator;
+			};
+
+			rtc_vdd_reg: rtc {
+				regulator-name = "vdd_rtc";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-coupled-with = <&core_vdd_reg &cpu_vdd_reg>;
+				regulator-coupled-max-spread = <170000 550000>;
+
+				nvidia,tegra-rtc-regulator;
+			};
+
+			cpu_vdd_reg: cpu {
+				regulator-name = "vdd_cpu";
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <1125000>;
+				regulator-coupled-with = <&core_vdd_reg &rtc_vdd_reg>;
+				regulator-coupled-max-spread = <550000 550000>;
+
+				nvidia,tegra-cpu-regulator;
+			};
+		};
+	};
-- 
2.22.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 2/3] soc/tegra: regulators: Add regulators coupler for Tegra20
  2019-07-25 15:18 [PATCH v2 0/3] Support regulators coupling on NVIDIA Tegra20/30 Dmitry Osipenko
  2019-07-25 15:18 ` [PATCH v2 1/3] dt-bindings: regulator: Document regulators coupling of NVIDIA Tegra20/30 SoCs Dmitry Osipenko
@ 2019-07-25 15:18 ` Dmitry Osipenko
  2019-07-25 15:18 ` [PATCH v2 3/3] soc/tegra: regulators: Add regulators coupler for Tegra30 Dmitry Osipenko
  2019-10-29 13:02 ` [PATCH v2 0/3] Support regulators coupling on NVIDIA Tegra20/30 Thierry Reding
  3 siblings, 0 replies; 12+ messages in thread
From: Dmitry Osipenko @ 2019-07-25 15:18 UTC (permalink / raw)
  To: Rob Herring, Thierry Reding, Peter De Schrijver, Jonathan Hunter,
	Mark Brown
  Cc: devicetree, linux-tegra, linux-kernel

Add regulators coupler for Tegra20 SoCs that performs voltage balancing
of a coupled regulators and thus provides voltage scaling functionality.

There are 3 coupled regulators on all Tegra20 SoCs: CORE, RTC and CPU.
The CORE and RTC voltages shall be in range of 170mV from each other and
they both shall be higher than the CPU voltage by at least 120mV. This
sounds like it could be handle by a generic voltage balancer, but the CORE
voltage scaling isn't implemented in any of the upstream drivers yet.
It will take quite some time and effort to hook up voltage scaling for
all of the drivers, hence we will use a custom coupler that will manage
the CPU voltage scaling for the starter.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/soc/tegra/Kconfig              |   6 +
 drivers/soc/tegra/Makefile             |   1 +
 drivers/soc/tegra/regulators-tegra20.c | 364 +++++++++++++++++++++++++
 3 files changed, 371 insertions(+)
 create mode 100644 drivers/soc/tegra/regulators-tegra20.c

diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index d98c69efb7e0..7986ab80e07a 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -14,6 +14,7 @@ config ARCH_TEGRA_2x_SOC
 	select PL310_ERRATA_769419 if CACHE_L2X0
 	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
+	select SOC_TEGRA20_VOLTAGE_COUPLER
 	select TEGRA_TIMER
 	help
 	  Support for NVIDIA Tegra AP20 and T20 processors, based on the
@@ -134,3 +135,8 @@ config SOC_TEGRA_POWERGATE_BPMP
 	def_bool y
 	depends on PM_GENERIC_DOMAINS
 	depends on TEGRA_BPMP
+
+config SOC_TEGRA20_VOLTAGE_COUPLER
+	bool "Voltage scaling support for Tegra20 SoCs"
+	depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
+
diff --git a/drivers/soc/tegra/Makefile b/drivers/soc/tegra/Makefile
index 902759fe5f4d..9f0bdd53bef8 100644
--- a/drivers/soc/tegra/Makefile
+++ b/drivers/soc/tegra/Makefile
@@ -5,3 +5,4 @@ obj-y += common.o
 obj-$(CONFIG_SOC_TEGRA_FLOWCTRL) += flowctrl.o
 obj-$(CONFIG_SOC_TEGRA_PMC) += pmc.o
 obj-$(CONFIG_SOC_TEGRA_POWERGATE_BPMP) += powergate-bpmp.o
+obj-$(CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER) += regulators-tegra20.o
diff --git a/drivers/soc/tegra/regulators-tegra20.c b/drivers/soc/tegra/regulators-tegra20.c
new file mode 100644
index 000000000000..84ea3ff316ec
--- /dev/null
+++ b/drivers/soc/tegra/regulators-tegra20.c
@@ -0,0 +1,364 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Voltage regulators coupler for NVIDIA Tegra20
+// Copyright (C) 2019 GRATE-DRIVER project
+//
+// Voltage constraints borrowed from downstream kernel sources
+// Copyright (C) 2010-2011 NVIDIA Corporation
+
+#define pr_fmt(fmt)	"tegra voltage-coupler: " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/regulator/coupler.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+struct tegra_regulator_coupler {
+	struct regulator_coupler coupler;
+	struct regulator_dev *core_rdev;
+	struct regulator_dev *cpu_rdev;
+	struct regulator_dev *rtc_rdev;
+	int core_min_uV;
+};
+
+static inline struct tegra_regulator_coupler *
+to_tegra_coupler(struct regulator_coupler *coupler)
+{
+	return container_of(coupler, struct tegra_regulator_coupler, coupler);
+}
+
+static int tegra20_core_limit(struct tegra_regulator_coupler *tegra,
+			      struct regulator_dev *core_rdev)
+{
+	int core_min_uV = 0;
+	int core_max_uV;
+	int core_cur_uV;
+	int err;
+
+	if (tegra->core_min_uV > 0)
+		return tegra->core_min_uV;
+
+	core_cur_uV = regulator_get_voltage_rdev(core_rdev);
+	if (core_cur_uV < 0)
+		return core_cur_uV;
+
+	core_max_uV = max(core_cur_uV, 1200000);
+
+	err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
+	if (err)
+		return err;
+
+	/*
+	 * Limit minimum CORE voltage to a value left from bootloader or,
+	 * if it's unreasonably low value, to the most common 1.2v or to
+	 * whatever maximum value defined via board's device-tree.
+	 */
+	tegra->core_min_uV = core_max_uV;
+
+	pr_info("core minimum voltage limited to %duV\n", tegra->core_min_uV);
+
+	return tegra->core_min_uV;
+}
+
+static int tegra20_core_rtc_max_spread(struct regulator_dev *core_rdev,
+				       struct regulator_dev *rtc_rdev)
+{
+	struct coupling_desc *c_desc = &core_rdev->coupling_desc;
+	struct regulator_dev *rdev;
+	int max_spread;
+	unsigned int i;
+
+	for (i = 1; i < c_desc->n_coupled; i++) {
+		max_spread = core_rdev->constraints->max_spread[i - 1];
+		rdev = c_desc->coupled_rdevs[i];
+
+		if (rdev == rtc_rdev && max_spread)
+			return max_spread;
+	}
+
+	pr_err_once("rtc-core max-spread is undefined in device-tree\n");
+
+	return 150000;
+}
+
+static int tegra20_core_rtc_update(struct tegra_regulator_coupler *tegra,
+				   struct regulator_dev *core_rdev,
+				   struct regulator_dev *rtc_rdev,
+				   int cpu_uV, int cpu_min_uV)
+{
+	int core_min_uV, core_max_uV = INT_MAX;
+	int rtc_min_uV, rtc_max_uV = INT_MAX;
+	int core_target_uV;
+	int rtc_target_uV;
+	int max_spread;
+	int core_uV;
+	int rtc_uV;
+	int err;
+
+	/*
+	 * RTC and CORE voltages should be no more than 170mV from each other,
+	 * CPU should be below RTC and CORE by at least 120mV. This applies
+	 * to all Tegra20 SoC's.
+	 */
+	max_spread = tegra20_core_rtc_max_spread(core_rdev, rtc_rdev);
+
+	/*
+	 * The core voltage scaling is currently not hooked up in drivers,
+	 * hence we will limit the minimum core voltage to a reasonable value.
+	 * This should be good enough for the time being.
+	 */
+	core_min_uV = tegra20_core_limit(tegra, core_rdev);
+	if (core_min_uV < 0)
+		return core_min_uV;
+
+	err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
+	if (err)
+		return err;
+
+	err = regulator_check_consumers(core_rdev, &core_min_uV, &core_max_uV,
+					PM_SUSPEND_ON);
+	if (err)
+		return err;
+
+	core_uV = regulator_get_voltage_rdev(core_rdev);
+	if (core_uV < 0)
+		return core_uV;
+
+	core_min_uV = max(cpu_min_uV + 125000, core_min_uV);
+	if (core_min_uV > core_max_uV)
+		return -EINVAL;
+
+	if (cpu_uV + 120000 > core_uV)
+		pr_err("core-cpu voltage constraint violated: %d %d\n",
+		       core_uV, cpu_uV + 120000);
+
+	rtc_uV = regulator_get_voltage_rdev(rtc_rdev);
+	if (rtc_uV < 0)
+		return rtc_uV;
+
+	if (cpu_uV + 120000 > rtc_uV)
+		pr_err("rtc-cpu voltage constraint violated: %d %d\n",
+		       rtc_uV, cpu_uV + 120000);
+
+	if (abs(core_uV - rtc_uV) > 170000)
+		pr_err("core-rtc voltage constraint violated: %d %d\n",
+		       core_uV, rtc_uV);
+
+	rtc_min_uV = max(cpu_min_uV + 125000, core_min_uV - max_spread);
+
+	err = regulator_check_voltage(rtc_rdev, &rtc_min_uV, &rtc_max_uV);
+	if (err)
+		return err;
+
+	while (core_uV != core_min_uV || rtc_uV != rtc_min_uV) {
+		if (core_uV < core_min_uV) {
+			core_target_uV = min(core_uV + max_spread, core_min_uV);
+			core_target_uV = min(rtc_uV + max_spread, core_target_uV);
+		} else {
+			core_target_uV = max(core_uV - max_spread, core_min_uV);
+			core_target_uV = max(rtc_uV - max_spread, core_target_uV);
+		}
+
+		err = regulator_set_voltage_rdev(core_rdev,
+						 core_target_uV,
+						 core_max_uV,
+						 PM_SUSPEND_ON);
+		if (err)
+			return err;
+
+		core_uV = core_target_uV;
+
+		if (rtc_uV < rtc_min_uV) {
+			rtc_target_uV = min(rtc_uV + max_spread, rtc_min_uV);
+			rtc_target_uV = min(core_uV + max_spread, rtc_target_uV);
+		} else {
+			rtc_target_uV = max(rtc_uV - max_spread, rtc_min_uV);
+			rtc_target_uV = max(core_uV - max_spread, rtc_target_uV);
+		}
+
+		err = regulator_set_voltage_rdev(rtc_rdev,
+						 rtc_target_uV,
+						 rtc_max_uV,
+						 PM_SUSPEND_ON);
+		if (err)
+			return err;
+
+		rtc_uV = rtc_target_uV;
+	}
+
+	return 0;
+}
+
+static int tegra20_core_voltage_update(struct tegra_regulator_coupler *tegra,
+				       struct regulator_dev *cpu_rdev,
+				       struct regulator_dev *core_rdev,
+				       struct regulator_dev *rtc_rdev)
+{
+	int cpu_uV;
+
+	cpu_uV = regulator_get_voltage_rdev(cpu_rdev);
+	if (cpu_uV < 0)
+		return cpu_uV;
+
+	return tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
+				       cpu_uV, cpu_uV);
+}
+
+static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra,
+				      struct regulator_dev *cpu_rdev,
+				      struct regulator_dev *core_rdev,
+				      struct regulator_dev *rtc_rdev)
+{
+	int cpu_min_uV_consumers = 0;
+	int cpu_max_uV = INT_MAX;
+	int cpu_min_uV = 0;
+	int cpu_uV;
+	int err;
+
+	err = regulator_check_voltage(cpu_rdev, &cpu_min_uV, &cpu_max_uV);
+	if (err)
+		return err;
+
+	err = regulator_check_consumers(cpu_rdev, &cpu_min_uV, &cpu_max_uV,
+					PM_SUSPEND_ON);
+	if (err)
+		return err;
+
+	err = regulator_check_consumers(cpu_rdev, &cpu_min_uV_consumers,
+					&cpu_max_uV, PM_SUSPEND_ON);
+	if (err)
+		return err;
+
+	cpu_uV = regulator_get_voltage_rdev(cpu_rdev);
+	if (cpu_uV < 0)
+		return cpu_uV;
+
+	/*
+	 * CPU's regulator may not have any consumers, hence the voltage
+	 * must not be changed in that case because CPU simply won't
+	 * survive the voltage drop if it's running on a higher frequency.
+	 */
+	if (!cpu_min_uV_consumers)
+		cpu_min_uV = cpu_uV;
+
+	if (cpu_min_uV > cpu_uV) {
+		err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
+					      cpu_uV, cpu_min_uV);
+		if (err)
+			return err;
+
+		err = regulator_set_voltage_rdev(cpu_rdev, cpu_min_uV,
+						 cpu_max_uV, PM_SUSPEND_ON);
+		if (err)
+			return err;
+	} else if (cpu_min_uV < cpu_uV)  {
+		err = regulator_set_voltage_rdev(cpu_rdev, cpu_min_uV,
+						 cpu_max_uV, PM_SUSPEND_ON);
+		if (err)
+			return err;
+
+		err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
+					      cpu_uV, cpu_min_uV);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler,
+					     struct regulator_dev *rdev,
+					     suspend_state_t state)
+{
+	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
+	struct regulator_dev *core_rdev = tegra->core_rdev;
+	struct regulator_dev *cpu_rdev = tegra->cpu_rdev;
+	struct regulator_dev *rtc_rdev = tegra->rtc_rdev;
+
+	if ((core_rdev != rdev && cpu_rdev != rdev && rtc_rdev != rdev) ||
+	    state != PM_SUSPEND_ON) {
+		pr_err("regulators are not coupled properly\n");
+		return -EINVAL;
+	}
+
+	if (rdev == cpu_rdev)
+		return tegra20_cpu_voltage_update(tegra, cpu_rdev,
+						  core_rdev, rtc_rdev);
+
+	if (rdev == core_rdev)
+		return tegra20_core_voltage_update(tegra, cpu_rdev,
+						   core_rdev, rtc_rdev);
+
+	pr_err("changing %s voltage not permitted\n", rdev_get_name(rtc_rdev));
+
+	return -EPERM;
+}
+
+static int tegra20_regulator_attach(struct regulator_coupler *coupler,
+				    struct regulator_dev *rdev)
+{
+	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
+	struct device_node *np = rdev->dev.of_node;
+
+	if (of_property_read_bool(np, "nvidia,tegra-core-regulator") &&
+	    !tegra->core_rdev) {
+		tegra->core_rdev = rdev;
+		return 0;
+	}
+
+	if (of_property_read_bool(np, "nvidia,tegra-rtc-regulator") &&
+	    !tegra->rtc_rdev) {
+		tegra->rtc_rdev = rdev;
+		return 0;
+	}
+
+	if (of_property_read_bool(np, "nvidia,tegra-cpu-regulator") &&
+	    !tegra->cpu_rdev) {
+		tegra->cpu_rdev = rdev;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int tegra20_regulator_detach(struct regulator_coupler *coupler,
+				    struct regulator_dev *rdev)
+{
+	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
+
+	if (tegra->core_rdev == rdev) {
+		tegra->core_rdev = NULL;
+		return 0;
+	}
+
+	if (tegra->rtc_rdev == rdev) {
+		tegra->rtc_rdev = NULL;
+		return 0;
+	}
+
+	if (tegra->cpu_rdev == rdev) {
+		tegra->cpu_rdev = NULL;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static struct tegra_regulator_coupler tegra20_coupler = {
+	.coupler = {
+		.attach_regulator = tegra20_regulator_attach,
+		.detach_regulator = tegra20_regulator_detach,
+		.balance_voltage = tegra20_regulator_balance_voltage,
+	},
+};
+
+static int __init tegra_regulator_coupler_init(void)
+{
+	if (!of_machine_is_compatible("nvidia,tegra20"))
+		return 0;
+
+	return regulator_coupler_register(&tegra20_coupler.coupler);
+}
+arch_initcall(tegra_regulator_coupler_init);
-- 
2.22.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 3/3] soc/tegra: regulators: Add regulators coupler for Tegra30
  2019-07-25 15:18 [PATCH v2 0/3] Support regulators coupling on NVIDIA Tegra20/30 Dmitry Osipenko
  2019-07-25 15:18 ` [PATCH v2 1/3] dt-bindings: regulator: Document regulators coupling of NVIDIA Tegra20/30 SoCs Dmitry Osipenko
  2019-07-25 15:18 ` [PATCH v2 2/3] soc/tegra: regulators: Add regulators coupler for Tegra20 Dmitry Osipenko
@ 2019-07-25 15:18 ` Dmitry Osipenko
  2019-08-02 14:05   ` Peter De Schrijver
  2019-10-29 13:02 ` [PATCH v2 0/3] Support regulators coupling on NVIDIA Tegra20/30 Thierry Reding
  3 siblings, 1 reply; 12+ messages in thread
From: Dmitry Osipenko @ 2019-07-25 15:18 UTC (permalink / raw)
  To: Rob Herring, Thierry Reding, Peter De Schrijver, Jonathan Hunter,
	Mark Brown
  Cc: devicetree, linux-tegra, linux-kernel

Add regulators coupler for Tegra30 SoCs that performs voltage balancing
of a coupled regulators and thus provides voltage scaling functionality.

There are 2 coupled regulators on all Tegra30 SoCs: CORE and CPU. The
coupled regulator voltages shall be in a range of 300mV from each other
and CORE voltage shall be higher than the CPU by N mV, where N depends
on the CPU voltage.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/soc/tegra/Kconfig              |   4 +
 drivers/soc/tegra/Makefile             |   1 +
 drivers/soc/tegra/regulators-tegra30.c | 316 +++++++++++++++++++++++++
 3 files changed, 321 insertions(+)
 create mode 100644 drivers/soc/tegra/regulators-tegra30.c

diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index 7986ab80e07a..bc86dc2f4198 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -28,6 +28,7 @@ config ARCH_TEGRA_3x_SOC
 	select PL310_ERRATA_769419 if CACHE_L2X0
 	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
+	select SOC_TEGRA30_VOLTAGE_COUPLER
 	select TEGRA_TIMER
 	help
 	  Support for NVIDIA Tegra T30 processor family, based on the
@@ -140,3 +141,6 @@ config SOC_TEGRA20_VOLTAGE_COUPLER
 	bool "Voltage scaling support for Tegra20 SoCs"
 	depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
 
+config SOC_TEGRA30_VOLTAGE_COUPLER
+	bool "Voltage scaling support for Tegra30 SoCs"
+	depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST
diff --git a/drivers/soc/tegra/Makefile b/drivers/soc/tegra/Makefile
index 9f0bdd53bef8..9c809c1814bd 100644
--- a/drivers/soc/tegra/Makefile
+++ b/drivers/soc/tegra/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_SOC_TEGRA_FLOWCTRL) += flowctrl.o
 obj-$(CONFIG_SOC_TEGRA_PMC) += pmc.o
 obj-$(CONFIG_SOC_TEGRA_POWERGATE_BPMP) += powergate-bpmp.o
 obj-$(CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER) += regulators-tegra20.o
+obj-$(CONFIG_SOC_TEGRA30_VOLTAGE_COUPLER) += regulators-tegra30.o
diff --git a/drivers/soc/tegra/regulators-tegra30.c b/drivers/soc/tegra/regulators-tegra30.c
new file mode 100644
index 000000000000..f19fccfe1a92
--- /dev/null
+++ b/drivers/soc/tegra/regulators-tegra30.c
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Voltage regulators coupler for NVIDIA Tegra30
+// Copyright (C) 2019 GRATE-DRIVER project
+//
+// Voltage constraints borrowed from downstream kernel sources
+// Copyright (C) 2010-2011 NVIDIA Corporation
+
+#define pr_fmt(fmt)	"tegra voltage-coupler: " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/regulator/coupler.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+#include <soc/tegra/fuse.h>
+
+struct tegra_regulator_coupler {
+	struct regulator_coupler coupler;
+	struct regulator_dev *core_rdev;
+	struct regulator_dev *cpu_rdev;
+	int core_min_uV;
+};
+
+static inline struct tegra_regulator_coupler *
+to_tegra_coupler(struct regulator_coupler *coupler)
+{
+	return container_of(coupler, struct tegra_regulator_coupler, coupler);
+}
+
+static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,
+			      struct regulator_dev *core_rdev)
+{
+	int core_min_uV = 0;
+	int core_max_uV;
+	int core_cur_uV;
+	int err;
+
+	if (tegra->core_min_uV > 0)
+		return tegra->core_min_uV;
+
+	core_cur_uV = regulator_get_voltage_rdev(core_rdev);
+	if (core_cur_uV < 0)
+		return core_cur_uV;
+
+	core_max_uV = max(core_cur_uV, 1200000);
+
+	err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
+	if (err)
+		return err;
+
+	/*
+	 * Limit minimum CORE voltage to a value left from bootloader or,
+	 * if it's unreasonably low value, to the most common 1.2v or to
+	 * whatever maximum value defined via board's device-tree.
+	 */
+	tegra->core_min_uV = core_max_uV;
+
+	pr_info("core minimum voltage limited to %duV\n", tegra->core_min_uV);
+
+	return tegra->core_min_uV;
+}
+
+static int tegra30_core_cpu_limit(int cpu_uV)
+{
+	if (cpu_uV < 800000)
+		return 950000;
+
+	if (cpu_uV < 900000)
+		return 1000000;
+
+	if (cpu_uV < 1000000)
+		return 1100000;
+
+	if (cpu_uV < 1100000)
+		return 1200000;
+
+	if (cpu_uV < 1250000) {
+		switch (tegra_sku_info.cpu_speedo_id) {
+		case 0 ... 1:
+		case 4:
+		case 7 ... 8:
+			return 1200000;
+
+		default:
+			return 1300000;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra,
+				  struct regulator_dev *cpu_rdev,
+				  struct regulator_dev *core_rdev)
+{
+	int core_min_uV, core_max_uV = INT_MAX;
+	int cpu_min_uV, cpu_max_uV = INT_MAX;
+	int cpu_min_uV_consumers = 0;
+	int core_min_limited_uV;
+	int core_target_uV;
+	int cpu_target_uV;
+	int core_max_step;
+	int cpu_max_step;
+	int max_spread;
+	int core_uV;
+	int cpu_uV;
+	int err;
+
+	/*
+	 * CPU voltage should not got lower than 300mV from the CORE.
+	 * CPU voltage should stay below the CORE by 100mV+, depending
+	 * by the CORE voltage. This applies to all Tegra30 SoC's.
+	 */
+	max_spread = cpu_rdev->constraints->max_spread[0];
+	cpu_max_step = cpu_rdev->constraints->max_uV_step;
+	core_max_step = core_rdev->constraints->max_uV_step;
+
+	if (!max_spread) {
+		pr_err_once("cpu-core max-spread is undefined in device-tree\n");
+		max_spread = 300000;
+	}
+
+	if (!cpu_max_step) {
+		pr_err_once("cpu max-step is undefined in device-tree\n");
+		cpu_max_step = 150000;
+	}
+
+	if (!core_max_step) {
+		pr_err_once("core max-step is undefined in device-tree\n");
+		core_max_step = 150000;
+	}
+
+	/*
+	 * The CORE voltage scaling is currently not hooked up in drivers,
+	 * hence we will limit the minimum CORE voltage to a reasonable value.
+	 * This should be good enough for the time being.
+	 */
+	core_min_uV = tegra30_core_limit(tegra, core_rdev);
+	if (core_min_uV < 0)
+		return core_min_uV;
+
+	err = regulator_check_consumers(core_rdev, &core_min_uV, &core_max_uV,
+					PM_SUSPEND_ON);
+	if (err)
+		return err;
+
+	core_uV = regulator_get_voltage_rdev(core_rdev);
+	if (core_uV < 0)
+		return core_uV;
+
+	cpu_min_uV = core_min_uV - max_spread;
+
+	err = regulator_check_consumers(cpu_rdev, &cpu_min_uV, &cpu_max_uV,
+					PM_SUSPEND_ON);
+	if (err)
+		return err;
+
+	err = regulator_check_consumers(cpu_rdev, &cpu_min_uV_consumers,
+					&cpu_max_uV, PM_SUSPEND_ON);
+	if (err)
+		return err;
+
+	err = regulator_check_voltage(cpu_rdev, &cpu_min_uV, &cpu_max_uV);
+	if (err)
+		return err;
+
+	cpu_uV = regulator_get_voltage_rdev(cpu_rdev);
+	if (cpu_uV < 0)
+		return cpu_uV;
+
+	/*
+	 * CPU's regulator may not have any consumers, hence the voltage
+	 * must not be changed in that case because CPU simply won't
+	 * survive the voltage drop if it's running on a higher frequency.
+	 */
+	if (!cpu_min_uV_consumers)
+		cpu_min_uV = cpu_uV;
+
+	/*
+	 * Bootloader shall set up voltages correctly, but if it
+	 * happens that there is a violation, then try to fix it
+	 * at first.
+	 */
+	core_min_limited_uV = tegra30_core_cpu_limit(cpu_uV);
+	if (core_min_limited_uV < 0)
+		return core_min_limited_uV;
+
+	core_min_uV = max(core_min_uV, tegra30_core_cpu_limit(cpu_min_uV));
+
+	err = regulator_check_voltage(core_rdev, &core_min_uV, &core_max_uV);
+	if (err)
+		return err;
+
+	if (core_min_limited_uV > core_uV) {
+		pr_err("core voltage constraint violated: %d %d %d\n",
+		       core_uV, core_min_limited_uV, cpu_uV);
+		goto update_core;
+	}
+
+	while (cpu_uV != cpu_min_uV || core_uV != core_min_uV) {
+		if (cpu_uV < cpu_min_uV) {
+			cpu_target_uV = min(cpu_uV + cpu_max_step, cpu_min_uV);
+		} else {
+			cpu_target_uV = max(cpu_uV - cpu_max_step, cpu_min_uV);
+			cpu_target_uV = max(core_uV - max_spread, cpu_target_uV);
+		}
+
+		err = regulator_set_voltage_rdev(cpu_rdev,
+						 cpu_target_uV,
+						 cpu_max_uV,
+						 PM_SUSPEND_ON);
+		if (err)
+			return err;
+
+		cpu_uV = cpu_target_uV;
+update_core:
+		core_min_limited_uV = tegra30_core_cpu_limit(cpu_uV);
+		if (core_min_limited_uV < 0)
+			return core_min_limited_uV;
+
+		core_target_uV = max(core_min_limited_uV, core_min_uV);
+
+		if (core_uV < core_target_uV) {
+			core_target_uV = min(core_target_uV, core_uV + core_max_step);
+			core_target_uV = min(core_target_uV, cpu_uV + max_spread);
+		} else {
+			core_target_uV = max(core_target_uV, core_uV - core_max_step);
+		}
+
+		err = regulator_set_voltage_rdev(core_rdev,
+						 core_target_uV,
+						 core_max_uV,
+						 PM_SUSPEND_ON);
+		if (err)
+			return err;
+
+		core_uV = core_target_uV;
+	}
+
+	return 0;
+}
+
+static int tegra30_regulator_balance_voltage(struct regulator_coupler *coupler,
+					     struct regulator_dev *rdev,
+					     suspend_state_t state)
+{
+	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
+	struct regulator_dev *core_rdev = tegra->core_rdev;
+	struct regulator_dev *cpu_rdev = tegra->cpu_rdev;
+
+	if ((core_rdev != rdev && cpu_rdev != rdev) || state != PM_SUSPEND_ON) {
+		pr_err("regulators are not coupled properly\n");
+		return -EINVAL;
+	}
+
+	return tegra30_voltage_update(tegra, cpu_rdev, core_rdev);
+}
+
+static int tegra30_regulator_attach(struct regulator_coupler *coupler,
+				    struct regulator_dev *rdev)
+{
+	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
+	struct device_node *np = rdev->dev.of_node;
+
+	if (of_property_read_bool(np, "nvidia,tegra-core-regulator") &&
+	    !tegra->core_rdev) {
+		tegra->core_rdev = rdev;
+		return 0;
+	}
+
+	if (of_property_read_bool(np, "nvidia,tegra-cpu-regulator") &&
+	    !tegra->cpu_rdev) {
+		tegra->cpu_rdev = rdev;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int tegra30_regulator_detach(struct regulator_coupler *coupler,
+				    struct regulator_dev *rdev)
+{
+	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
+
+	if (tegra->core_rdev == rdev) {
+		tegra->core_rdev = NULL;
+		return 0;
+	}
+
+	if (tegra->cpu_rdev == rdev) {
+		tegra->cpu_rdev = NULL;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static struct tegra_regulator_coupler tegra30_coupler = {
+	.coupler = {
+		.attach_regulator = tegra30_regulator_attach,
+		.detach_regulator = tegra30_regulator_detach,
+		.balance_voltage = tegra30_regulator_balance_voltage,
+	},
+};
+
+static int __init tegra_regulator_coupler_init(void)
+{
+	if (!of_machine_is_compatible("nvidia,tegra30"))
+		return 0;
+
+	return regulator_coupler_register(&tegra30_coupler.coupler);
+}
+arch_initcall(tegra_regulator_coupler_init);
-- 
2.22.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 3/3] soc/tegra: regulators: Add regulators coupler for Tegra30
  2019-07-25 15:18 ` [PATCH v2 3/3] soc/tegra: regulators: Add regulators coupler for Tegra30 Dmitry Osipenko
@ 2019-08-02 14:05   ` Peter De Schrijver
  2019-08-02 14:39     ` Dmitry Osipenko
  0 siblings, 1 reply; 12+ messages in thread
From: Peter De Schrijver @ 2019-08-02 14:05 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Rob Herring, Thierry Reding, Jonathan Hunter, Mark Brown,
	devicetree, linux-tegra, linux-kernel

On Thu, Jul 25, 2019 at 06:18:32PM +0300, Dmitry Osipenko wrote:
> Add regulators coupler for Tegra30 SoCs that performs voltage balancing
> of a coupled regulators and thus provides voltage scaling functionality.
> 
> There are 2 coupled regulators on all Tegra30 SoCs: CORE and CPU. The
> coupled regulator voltages shall be in a range of 300mV from each other
> and CORE voltage shall be higher than the CPU by N mV, where N depends
> on the CPU voltage.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/soc/tegra/Kconfig              |   4 +
>  drivers/soc/tegra/Makefile             |   1 +
>  drivers/soc/tegra/regulators-tegra30.c | 316 +++++++++++++++++++++++++
>  3 files changed, 321 insertions(+)
>  create mode 100644 drivers/soc/tegra/regulators-tegra30.c
> 
...

> +
> +static int tegra30_core_cpu_limit(int cpu_uV)
> +{
> +	if (cpu_uV < 800000)
> +		return 950000;
> +
> +	if (cpu_uV < 900000)
> +		return 1000000;
> +
> +	if (cpu_uV < 1000000)
> +		return 1100000;
> +
> +	if (cpu_uV < 1100000)
> +		return 1200000;
> +
> +	if (cpu_uV < 1250000) {
> +		switch (tegra_sku_info.cpu_speedo_id) {
> +		case 0 ... 1:
Aren't we supposed to add /* fall through */ here now?
> +		case 4:
> +		case 7 ... 8:
> +			return 1200000;
> +
> +		default:
> +			return 1300000;
> +		}
> +	}
> +

Other than that, this looks ok to me.

Peter.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 3/3] soc/tegra: regulators: Add regulators coupler for Tegra30
  2019-08-02 14:05   ` Peter De Schrijver
@ 2019-08-02 14:39     ` Dmitry Osipenko
  2019-08-05  8:33       ` Peter De Schrijver
  0 siblings, 1 reply; 12+ messages in thread
From: Dmitry Osipenko @ 2019-08-02 14:39 UTC (permalink / raw)
  To: Peter De Schrijver
  Cc: Rob Herring, Thierry Reding, Jonathan Hunter, Mark Brown,
	devicetree, linux-tegra, linux-kernel

02.08.2019 17:05, Peter De Schrijver пишет:
> On Thu, Jul 25, 2019 at 06:18:32PM +0300, Dmitry Osipenko wrote:
>> Add regulators coupler for Tegra30 SoCs that performs voltage balancing
>> of a coupled regulators and thus provides voltage scaling functionality.
>>
>> There are 2 coupled regulators on all Tegra30 SoCs: CORE and CPU. The
>> coupled regulator voltages shall be in a range of 300mV from each other
>> and CORE voltage shall be higher than the CPU by N mV, where N depends
>> on the CPU voltage.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/soc/tegra/Kconfig              |   4 +
>>  drivers/soc/tegra/Makefile             |   1 +
>>  drivers/soc/tegra/regulators-tegra30.c | 316 +++++++++++++++++++++++++
>>  3 files changed, 321 insertions(+)
>>  create mode 100644 drivers/soc/tegra/regulators-tegra30.c
>>
> ...
> 
>> +
>> +static int tegra30_core_cpu_limit(int cpu_uV)
>> +{
>> +	if (cpu_uV < 800000)
>> +		return 950000;
>> +
>> +	if (cpu_uV < 900000)
>> +		return 1000000;
>> +
>> +	if (cpu_uV < 1000000)
>> +		return 1100000;
>> +
>> +	if (cpu_uV < 1100000)
>> +		return 1200000;
>> +
>> +	if (cpu_uV < 1250000) {
>> +		switch (tegra_sku_info.cpu_speedo_id) {
>> +		case 0 ... 1:
> Aren't we supposed to add /* fall through */ here now?

There is no compiler warning if there is nothing in-between of the
case-switches, so annotation isn't really necessary here. Of course it
is possible to add an explicit annotation just to make clear the
fall-through intention.

>> +		case 4:
>> +		case 7 ... 8:
>> +			return 1200000;
>> +
>> +		default:
>> +			return 1300000;
>> +		}
>> +	}
>> +
> 
> Other than that, this looks ok to me.

Awesome, thank you very much! Explicit ACK will be appreciated as well.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 1/3] dt-bindings: regulator: Document regulators coupling of NVIDIA Tegra20/30 SoCs
  2019-07-25 15:18 ` [PATCH v2 1/3] dt-bindings: regulator: Document regulators coupling of NVIDIA Tegra20/30 SoCs Dmitry Osipenko
@ 2019-08-02 14:47   ` Dmitry Osipenko
  2019-08-16 21:34   ` Rob Herring
  1 sibling, 0 replies; 12+ messages in thread
From: Dmitry Osipenko @ 2019-08-02 14:47 UTC (permalink / raw)
  To: Rob Herring, Thierry Reding, Peter De Schrijver, Jonathan Hunter,
	Mark Brown
  Cc: devicetree, linux-tegra, linux-kernel

25.07.2019 18:18, Dmitry Osipenko пишет:
> There is voltage coupling between three regulators on Tegra20 boards and
> between two on Tegra30. The voltage coupling is a SoC-level feature and
> thus it is mandatory and common for all of the Tegra boards.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../nvidia,tegra-regulators-coupling.txt      | 65 +++++++++++++++++++
>  1 file changed, 65 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt
> 
> diff --git a/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt b/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt
> new file mode 100644
> index 000000000000..4bf2dbf7c6cc
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt
> @@ -0,0 +1,65 @@
> +NVIDIA Tegra Regulators Coupling
> +================================
> +
> +NVIDIA Tegra SoC's have a mandatory voltage-coupling between regulators.
> +Thus on Tegra20 there are 3 coupled regulators and on NVIDIA Tegra30
> +there are 2.
> +
> +Tegra20 voltage coupling
> +------------------------
> +
> +On Tegra20 SoC's there are 3 coupled regulators: CORE, RTC and CPU.
> +The CORE and RTC voltages shall be in a range of 170mV from each other
> +and they both shall be higher than the CPU voltage by at least 120mV.
> +
> +Tegra30 voltage coupling
> +------------------------
> +
> +On Tegra30 SoC's there are 2 coupled regulators: CORE and CPU. The CORE
> +and CPU voltages shall be in a range of 300mV from each other and CORE
> +voltage shall be higher than the CPU by N mV, where N depends on the CPU
> +voltage.
> +
> +Required properties:
> +- nvidia,tegra-core-regulator: Boolean property that designates regulator
> +  as the "Core domain" voltage regulator.
> +- nvidia,tegra-rtc-regulator: Boolean property that designates regulator
> +  as the "RTC domain" voltage regulator.
> +- nvidia,tegra-cpu-regulator: Boolean property that designates regulator
> +  as the "CPU domain" voltage regulator.
> +
> +Example:
> +
> +	pmic {
> +		regulators {
> +			core_vdd_reg: core {
> +				regulator-name = "vdd_core";
> +				regulator-min-microvolt = <950000>;
> +				regulator-max-microvolt = <1300000>;
> +				regulator-coupled-with = <&rtc_vdd_reg &cpu_vdd_reg>;
> +				regulator-coupled-max-spread = <170000 550000>;
> +
> +				nvidia,tegra-core-regulator;
> +			};
> +
> +			rtc_vdd_reg: rtc {
> +				regulator-name = "vdd_rtc";
> +				regulator-min-microvolt = <950000>;
> +				regulator-max-microvolt = <1300000>;
> +				regulator-coupled-with = <&core_vdd_reg &cpu_vdd_reg>;
> +				regulator-coupled-max-spread = <170000 550000>;
> +
> +				nvidia,tegra-rtc-regulator;
> +			};
> +
> +			cpu_vdd_reg: cpu {
> +				regulator-name = "vdd_cpu";
> +				regulator-min-microvolt = <750000>;
> +				regulator-max-microvolt = <1125000>;
> +				regulator-coupled-with = <&core_vdd_reg &rtc_vdd_reg>;
> +				regulator-coupled-max-spread = <550000 550000>;
> +
> +				nvidia,tegra-cpu-regulator;
> +			};
> +		};
> +	};
> 

Hello Rob,

Are you okay with this patch? We just need to mark the SoC voltage
regulators appropriately and regulators themselves vary from board to
board, hence this binding is not something that could be done using
YAML, I guess.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 3/3] soc/tegra: regulators: Add regulators coupler for Tegra30
  2019-08-02 14:39     ` Dmitry Osipenko
@ 2019-08-05  8:33       ` Peter De Schrijver
  2019-08-05 11:03         ` Dmitry Osipenko
  0 siblings, 1 reply; 12+ messages in thread
From: Peter De Schrijver @ 2019-08-05  8:33 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Rob Herring, Thierry Reding, Jonathan Hunter, Mark Brown,
	devicetree, linux-tegra, linux-kernel

On Fri, Aug 02, 2019 at 05:39:23PM +0300, Dmitry Osipenko wrote:
> 02.08.2019 17:05, Peter De Schrijver пишет:
> > On Thu, Jul 25, 2019 at 06:18:32PM +0300, Dmitry Osipenko wrote:
> >> Add regulators coupler for Tegra30 SoCs that performs voltage balancing
> >> of a coupled regulators and thus provides voltage scaling functionality.
> >>
> >> There are 2 coupled regulators on all Tegra30 SoCs: CORE and CPU. The
> >> coupled regulator voltages shall be in a range of 300mV from each other
> >> and CORE voltage shall be higher than the CPU by N mV, where N depends
> >> on the CPU voltage.
> >>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  drivers/soc/tegra/Kconfig              |   4 +
> >>  drivers/soc/tegra/Makefile             |   1 +
> >>  drivers/soc/tegra/regulators-tegra30.c | 316 +++++++++++++++++++++++++
> >>  3 files changed, 321 insertions(+)
> >>  create mode 100644 drivers/soc/tegra/regulators-tegra30.c
> >>
> > ...
> > 
> >> +
> >> +static int tegra30_core_cpu_limit(int cpu_uV)
> >> +{
> >> +	if (cpu_uV < 800000)
> >> +		return 950000;
> >> +
> >> +	if (cpu_uV < 900000)
> >> +		return 1000000;
> >> +
> >> +	if (cpu_uV < 1000000)
> >> +		return 1100000;
> >> +
> >> +	if (cpu_uV < 1100000)
> >> +		return 1200000;
> >> +
> >> +	if (cpu_uV < 1250000) {
> >> +		switch (tegra_sku_info.cpu_speedo_id) {
> >> +		case 0 ... 1:
> > Aren't we supposed to add /* fall through */ here now?
> 
> There is no compiler warning if there is nothing in-between of the
> case-switches, so annotation isn't really necessary here. Of course it
> is possible to add an explicit annotation just to make clear the
> fall-through intention.
> 

Ah. Ok. Whatever you want then :)

> >> +		case 4:
> >> +		case 7 ... 8:
> >> +			return 1200000;
> >> +
> >> +		default:
> >> +			return 1300000;
> >> +		}
> >> +	}
> >> +
> > 
> > Other than that, this looks ok to me.
> 
> Awesome, thank you very much! Explicit ACK will be appreciated as well.

Acked-By: Peter De Schrijver <pdeschrijver@nvidia.com>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 3/3] soc/tegra: regulators: Add regulators coupler for Tegra30
  2019-08-05  8:33       ` Peter De Schrijver
@ 2019-08-05 11:03         ` Dmitry Osipenko
  2019-08-06  7:30           ` Peter De Schrijver
  0 siblings, 1 reply; 12+ messages in thread
From: Dmitry Osipenko @ 2019-08-05 11:03 UTC (permalink / raw)
  To: Peter De Schrijver
  Cc: Rob Herring, Thierry Reding, Jonathan Hunter, Mark Brown,
	devicetree, linux-tegra, linux-kernel

05.08.2019 11:33, Peter De Schrijver пишет:
> On Fri, Aug 02, 2019 at 05:39:23PM +0300, Dmitry Osipenko wrote:
>> 02.08.2019 17:05, Peter De Schrijver пишет:
>>> On Thu, Jul 25, 2019 at 06:18:32PM +0300, Dmitry Osipenko wrote:
>>>> Add regulators coupler for Tegra30 SoCs that performs voltage balancing
>>>> of a coupled regulators and thus provides voltage scaling functionality.
>>>>
>>>> There are 2 coupled regulators on all Tegra30 SoCs: CORE and CPU. The
>>>> coupled regulator voltages shall be in a range of 300mV from each other
>>>> and CORE voltage shall be higher than the CPU by N mV, where N depends
>>>> on the CPU voltage.
>>>>
>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>> ---
>>>>  drivers/soc/tegra/Kconfig              |   4 +
>>>>  drivers/soc/tegra/Makefile             |   1 +
>>>>  drivers/soc/tegra/regulators-tegra30.c | 316 +++++++++++++++++++++++++
>>>>  3 files changed, 321 insertions(+)
>>>>  create mode 100644 drivers/soc/tegra/regulators-tegra30.c
>>>>
>>> ...
>>>
>>>> +
>>>> +static int tegra30_core_cpu_limit(int cpu_uV)
>>>> +{
>>>> +	if (cpu_uV < 800000)
>>>> +		return 950000;
>>>> +
>>>> +	if (cpu_uV < 900000)
>>>> +		return 1000000;
>>>> +
>>>> +	if (cpu_uV < 1000000)
>>>> +		return 1100000;
>>>> +
>>>> +	if (cpu_uV < 1100000)
>>>> +		return 1200000;
>>>> +
>>>> +	if (cpu_uV < 1250000) {
>>>> +		switch (tegra_sku_info.cpu_speedo_id) {
>>>> +		case 0 ... 1:
>>> Aren't we supposed to add /* fall through */ here now?
>>
>> There is no compiler warning if there is nothing in-between of the
>> case-switches, so annotation isn't really necessary here. Of course it
>> is possible to add an explicit annotation just to make clear the
>> fall-through intention.
>>
> 
> Ah. Ok. Whatever you want then :)

I'll add the comments if there will be a need to re-spin this series.

>>>> +		case 4:
>>>> +		case 7 ... 8:
>>>> +			return 1200000;
>>>> +
>>>> +		default:
>>>> +			return 1300000;
>>>> +		}
>>>> +	}
>>>> +
>>>
>>> Other than that, this looks ok to me.
>>
>> Awesome, thank you very much! Explicit ACK will be appreciated as well.
> 
> Acked-By: Peter De Schrijver <pdeschrijver@nvidia.com>

Thank you again! Could you please also clarify whether the ACK is for
this patch only or for all of three patches?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 3/3] soc/tegra: regulators: Add regulators coupler for Tegra30
  2019-08-05 11:03         ` Dmitry Osipenko
@ 2019-08-06  7:30           ` Peter De Schrijver
  0 siblings, 0 replies; 12+ messages in thread
From: Peter De Schrijver @ 2019-08-06  7:30 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Rob Herring, Thierry Reding, Jonathan Hunter, Mark Brown,
	devicetree, linux-tegra, linux-kernel

On Mon, Aug 05, 2019 at 02:03:29PM +0300, Dmitry Osipenko wrote:
> 05.08.2019 11:33, Peter De Schrijver пишет:
> > On Fri, Aug 02, 2019 at 05:39:23PM +0300, Dmitry Osipenko wrote:
> >> 02.08.2019 17:05, Peter De Schrijver пишет:
> >>> On Thu, Jul 25, 2019 at 06:18:32PM +0300, Dmitry Osipenko wrote:
> >>>> Add regulators coupler for Tegra30 SoCs that performs voltage balancing
> >>>> of a coupled regulators and thus provides voltage scaling functionality.
> >>>>
> >>>> There are 2 coupled regulators on all Tegra30 SoCs: CORE and CPU. The
> >>>> coupled regulator voltages shall be in a range of 300mV from each other
> >>>> and CORE voltage shall be higher than the CPU by N mV, where N depends
> >>>> on the CPU voltage.
> >>>>
> >>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >>>> ---
> >>>>  drivers/soc/tegra/Kconfig              |   4 +
> >>>>  drivers/soc/tegra/Makefile             |   1 +
> >>>>  drivers/soc/tegra/regulators-tegra30.c | 316 +++++++++++++++++++++++++
> >>>>  3 files changed, 321 insertions(+)
> >>>>  create mode 100644 drivers/soc/tegra/regulators-tegra30.c
> >>>>
> >>> ...
> >>>
> >>>> +
> >>>> +static int tegra30_core_cpu_limit(int cpu_uV)
> >>>> +{
> >>>> +	if (cpu_uV < 800000)
> >>>> +		return 950000;
> >>>> +
> >>>> +	if (cpu_uV < 900000)
> >>>> +		return 1000000;
> >>>> +
> >>>> +	if (cpu_uV < 1000000)
> >>>> +		return 1100000;
> >>>> +
> >>>> +	if (cpu_uV < 1100000)
> >>>> +		return 1200000;
> >>>> +
> >>>> +	if (cpu_uV < 1250000) {
> >>>> +		switch (tegra_sku_info.cpu_speedo_id) {
> >>>> +		case 0 ... 1:
> >>> Aren't we supposed to add /* fall through */ here now?
> >>
> >> There is no compiler warning if there is nothing in-between of the
> >> case-switches, so annotation isn't really necessary here. Of course it
> >> is possible to add an explicit annotation just to make clear the
> >> fall-through intention.
> >>
> > 
> > Ah. Ok. Whatever you want then :)
> 
> I'll add the comments if there will be a need to re-spin this series.
> 
> >>>> +		case 4:
> >>>> +		case 7 ... 8:
> >>>> +			return 1200000;
> >>>> +
> >>>> +		default:
> >>>> +			return 1300000;
> >>>> +		}
> >>>> +	}
> >>>> +
> >>>
> >>> Other than that, this looks ok to me.
> >>
> >> Awesome, thank you very much! Explicit ACK will be appreciated as well.
> > 
> > Acked-By: Peter De Schrijver <pdeschrijver@nvidia.com>

All of them.

Peter.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 1/3] dt-bindings: regulator: Document regulators coupling of NVIDIA Tegra20/30 SoCs
  2019-07-25 15:18 ` [PATCH v2 1/3] dt-bindings: regulator: Document regulators coupling of NVIDIA Tegra20/30 SoCs Dmitry Osipenko
  2019-08-02 14:47   ` Dmitry Osipenko
@ 2019-08-16 21:34   ` Rob Herring
  1 sibling, 0 replies; 12+ messages in thread
From: Rob Herring @ 2019-08-16 21:34 UTC (permalink / raw)
  To: Dmitry Osipenko; +Cc: devicetree, linux-tegra, linux-kernel

On Thu, 25 Jul 2019 18:18:30 +0300, Dmitry Osipenko wrote:
> There is voltage coupling between three regulators on Tegra20 boards and
> between two on Tegra30. The voltage coupling is a SoC-level feature and
> thus it is mandatory and common for all of the Tegra boards.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../nvidia,tegra-regulators-coupling.txt      | 65 +++++++++++++++++++
>  1 file changed, 65 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 0/3] Support regulators coupling on NVIDIA Tegra20/30
  2019-07-25 15:18 [PATCH v2 0/3] Support regulators coupling on NVIDIA Tegra20/30 Dmitry Osipenko
                   ` (2 preceding siblings ...)
  2019-07-25 15:18 ` [PATCH v2 3/3] soc/tegra: regulators: Add regulators coupler for Tegra30 Dmitry Osipenko
@ 2019-10-29 13:02 ` Thierry Reding
  3 siblings, 0 replies; 12+ messages in thread
From: Thierry Reding @ 2019-10-29 13:02 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Rob Herring, Peter De Schrijver, Jonathan Hunter, Mark Brown,
	devicetree, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1634 bytes --]

On Thu, Jul 25, 2019 at 06:18:29PM +0300, Dmitry Osipenko wrote:
> Hello,
> 
> The voltage regulators need to be coupled on NVIDIA Tegra20 and Tegra30
> SoCs in order to provide voltage scaling functionality in a generic way.
> All necessary regulator-core patches that added support for the regulators
> coupling are already have been merge into mainline kernel. This series
> adds customized voltage couplers for Tegra20/30 SoCs, paving the way for
> a refined CPUFreq driver that will utilize voltage scaling and other neat
> features. This is a resend of a leftover patches from a previous series
> [1] that was partially applied by Mark Brown. Please review, thanks in
> advance!
> 
> [1] https://patchwork.ozlabs.org/project/linux-tegra/list/?series=115626
> 
> Changelog:
> 
> v2: - Some days ago OPP framework got a change that makes CPU regulator
>       to be enabled at the time of CPUFreq's driver initializing OPPs.
>       In a result the CPU's voltage is dropped to a minimum value on
>       CPUFreq's setting up because there are no consumers at the time
>       of regulator's enabling, thus CPU is getting into a big trouble.
>       This problem is now resolved in the couplers code by assuming
>       that min_uV=current_uV for CPU's regulator if it doesn't have
>       any active consumers.
> 
> Dmitry Osipenko (3):
>   dt-bindings: regulator: Document regulators coupling of NVIDIA
>     Tegra20/30 SoCs
>   soc/tegra: regulators: Add regulators coupler for Tegra20
>   soc/tegra: regulators: Add regulators coupler for Tegra30

All three patches applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2019-10-29 13:02 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-25 15:18 [PATCH v2 0/3] Support regulators coupling on NVIDIA Tegra20/30 Dmitry Osipenko
2019-07-25 15:18 ` [PATCH v2 1/3] dt-bindings: regulator: Document regulators coupling of NVIDIA Tegra20/30 SoCs Dmitry Osipenko
2019-08-02 14:47   ` Dmitry Osipenko
2019-08-16 21:34   ` Rob Herring
2019-07-25 15:18 ` [PATCH v2 2/3] soc/tegra: regulators: Add regulators coupler for Tegra20 Dmitry Osipenko
2019-07-25 15:18 ` [PATCH v2 3/3] soc/tegra: regulators: Add regulators coupler for Tegra30 Dmitry Osipenko
2019-08-02 14:05   ` Peter De Schrijver
2019-08-02 14:39     ` Dmitry Osipenko
2019-08-05  8:33       ` Peter De Schrijver
2019-08-05 11:03         ` Dmitry Osipenko
2019-08-06  7:30           ` Peter De Schrijver
2019-10-29 13:02 ` [PATCH v2 0/3] Support regulators coupling on NVIDIA Tegra20/30 Thierry Reding

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).