linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/6] NVIDIA Tegra core power domain driver and OPP helper
@ 2021-03-14 16:48 Dmitry Osipenko
  2021-03-14 16:48 ` [PATCH v4 1/6] soc/tegra: Add devm_tegra_core_dev_init_opp_table() Dmitry Osipenko
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Dmitry Osipenko @ 2021-03-14 16:48 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Mark Brown, Paul Fertser,
	Rob Herring, Matt Merhar, Peter Geis, Nicolas Chauvet,
	Viresh Kumar, Stephen Boyd, Michał Mirosław,
	Krzysztof Kozlowski
  Cc: devicetree, linux-tegra, linux-pm, linux-kernel

Hello,

This series adds Core power domain driver for NVIDIA Tegra SoCs and a
common OPP helper which initializes OPP table specifically for Tegra
drivers. The patches depend on the ongoing series [1] which adds
resource-managed OPP API.

[1] https://patchwork.kernel.org/project/linux-pm/list/?series=447801

NVIDIA Tegra SoCs have a dedicated "Core" power domain to which
majority of SoC peripherals belong. The core domain is connected to
a dedicated voltage rail, which is exposed as a voltage regulator to
the Linux kernel. Adding support for power management (i.e. voltage
scaling) of the Core domain allows to significantly improve power
consumption of the Tegra chip.

In particular this PM work solves the overheating problem on Tegra30
devices. It allows Ouya Tegra30 game console to run at 40C during system
idle in oppose to going over 60C. Matt Merhar collected temperature stats
on his Ouya [2] which show a very significant improvement.

[2] https://imgur.com/a/z4NDWqk

Changelog:

v4: - Rebased on top of a new version of the OPP patches [1].

    - Fixed new DT binding warning which was reported by the bot for v3.

v3: - This series is a continuation of [3][4]. I factored out and grouped
      these soc/tegra patches since they have a common dependency on the
      OPP API patches [1] and the rest of PM patches depend on this series.

      [3] https://lore.kernel.org/lkml/20201217180638.22748-1-digetx@gmail.com/
      [4] https://lore.kernel.org/linux-pm/20210121191410.13781-1-digetx@gmail.com/

    - Added locking around regulators syncing, which was previously done by
      the OPP core, but then we (me and Viresh) figured out that it will be
      better to do it within the PD driver.

    - The Core-PD driver now restores the boot voltage level before
      shutdown/reboot, which may help some devices not to hang on reboot,
      like Nexus 7 for example.

    - Added r-b from Ulf Hansson to "regulators: Support Core domain state
      syncing" patch, which he gave to v2.

    - It should be cleaner to add the Core OPP tables and power domain to
      the device-trees once all drivers will get the PM support, so this
      series adds the driver and the binding for now.

    - Added t-b from Paul Fertser, who tested the complete patchset on his
      AC100 netbook and helped to spot compatibility problem with older DTBs
      in the patch that will add PM support to the GPU driver.

    - The DT binding now follows the power-domain spec, which was suggested
      by Krzysztof Kozlowski in his comment to v2.


Dmitry Osipenko (6):
  soc/tegra: Add devm_tegra_core_dev_init_opp_table()
  soc/tegra: Add CONFIG_SOC_TEGRA_COMMON and select PM_OPP by default
  dt-bindings: power: tegra: Add binding for core power domain
  soc/tegra: Introduce core power domain driver
  soc/tegra: regulators: Support Core domain state syncing
  soc/tegra: pmc: Link children power domains to the parent domain

 .../power/nvidia,tegra20-core-domain.yaml     |  51 ++++++
 drivers/soc/tegra/Kconfig                     |  19 +++
 drivers/soc/tegra/Makefile                    |   1 +
 drivers/soc/tegra/common.c                    | 137 ++++++++++++++++
 drivers/soc/tegra/core-power-domain.c         | 153 ++++++++++++++++++
 drivers/soc/tegra/pmc.c                       |  16 ++
 drivers/soc/tegra/regulators-tegra20.c        |  19 ++-
 drivers/soc/tegra/regulators-tegra30.c        |  18 ++-
 include/soc/tegra/common.h                    |  36 +++++
 9 files changed, 448 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
 create mode 100644 drivers/soc/tegra/core-power-domain.c

-- 
2.30.2


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

* [PATCH v4 1/6] soc/tegra: Add devm_tegra_core_dev_init_opp_table()
  2021-03-14 16:48 [PATCH v4 0/6] NVIDIA Tegra core power domain driver and OPP helper Dmitry Osipenko
@ 2021-03-14 16:48 ` Dmitry Osipenko
  2021-03-18 10:27   ` Dmitry Osipenko
  2021-03-14 16:48 ` [PATCH v4 2/6] soc/tegra: Add CONFIG_SOC_TEGRA_COMMON and select PM_OPP by default Dmitry Osipenko
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Dmitry Osipenko @ 2021-03-14 16:48 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Mark Brown, Paul Fertser,
	Rob Herring, Matt Merhar, Peter Geis, Nicolas Chauvet,
	Viresh Kumar, Stephen Boyd, Michał Mirosław,
	Krzysztof Kozlowski
  Cc: devicetree, linux-tegra, linux-pm, linux-kernel

Add common helper which initializes OPP table for Tegra SoC core devices.

Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart@gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/soc/tegra/common.c | 137 +++++++++++++++++++++++++++++++++++++
 include/soc/tegra/common.h |  30 ++++++++
 2 files changed, 167 insertions(+)

diff --git a/drivers/soc/tegra/common.c b/drivers/soc/tegra/common.c
index 3dc54f59cafe..bdcf314b46c1 100644
--- a/drivers/soc/tegra/common.c
+++ b/drivers/soc/tegra/common.c
@@ -3,9 +3,16 @@
  * Copyright (C) 2014 NVIDIA CORPORATION.  All rights reserved.
  */
 
+#define dev_fmt(fmt)	"tegra-soc: " fmt
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/export.h>
 #include <linux/of.h>
+#include <linux/pm_opp.h>
 
 #include <soc/tegra/common.h>
+#include <soc/tegra/fuse.h>
 
 static const struct of_device_id tegra_machine_match[] = {
 	{ .compatible = "nvidia,tegra20", },
@@ -31,3 +38,133 @@ bool soc_is_tegra(void)
 
 	return match != NULL;
 }
+
+static int tegra_core_dev_init_opp_state(struct device *dev)
+{
+	struct dev_pm_opp *opp;
+	unsigned long rate;
+	struct clk *clk;
+	int err;
+
+	clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(clk)) {
+		dev_err(dev, "failed to get clk: %pe\n", clk);
+		return PTR_ERR(clk);
+	}
+
+	/*
+	 * If voltage regulator presents, then we could select the fastest
+	 * clock rate, but driver doesn't support power management and
+	 * frequency scaling yet, hence the top freq OPP will vote for a
+	 * very high voltage that will produce lot's of heat.  Let's select
+	 * OPP for the current/default rate for now.
+	 *
+	 * Clock rate should be pre-initialized (i.e. it's non-zero) either
+	 * by clock driver or by assigned clocks in a device-tree.
+	 */
+	rate = clk_get_rate(clk);
+	if (!rate) {
+		dev_err(dev, "failed to get clk rate\n");
+		return -EINVAL;
+	}
+
+	/* find suitable OPP for the clock rate and supportable by hardware */
+	opp = dev_pm_opp_find_freq_ceil(dev, &rate);
+
+	/*
+	 * dev_pm_opp_set_rate() doesn't search for a floor clock rate and it
+	 * will error out if default clock rate is too high, i.e. unsupported
+	 * by a SoC hardware version.  Hence will find floor rate by ourselves.
+	 */
+	if (opp == ERR_PTR(-ERANGE))
+		opp = dev_pm_opp_find_freq_floor(dev, &rate);
+
+	err = PTR_ERR_OR_ZERO(opp);
+	if (err) {
+		dev_err(dev, "failed to get OPP for %ld Hz: %d\n",
+			rate, err);
+		return err;
+	}
+
+	dev_pm_opp_put(opp);
+
+	/*
+	 * First dummy rate-set initializes voltage vote by setting voltage
+	 * in accordance to the clock rate.  We need to do this because some
+	 * drivers currently don't support power management and clock is
+	 * permanently enabled.
+	 */
+	err = dev_pm_opp_set_rate(dev, rate);
+	if (err) {
+		dev_err(dev, "failed to initialize OPP clock: %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+/**
+ * devm_tegra_core_dev_init_opp_table() - initialize OPP table
+ * @dev: device for which OPP table is initialized
+ * @params: pointer to the OPP table configuration
+ *
+ * This function will initialize OPP table and sync OPP state of a Tegra SoC
+ * core device.
+ *
+ * Return: 0 on success or errorno.
+ */
+int devm_tegra_core_dev_init_opp_table(struct device *dev,
+				       struct tegra_core_opp_params *params)
+{
+	u32 hw_version;
+	int err;
+
+	err = devm_pm_opp_set_clkname(dev, NULL);
+	if (err) {
+		dev_err(dev, "failed to set OPP clk: %d\n", err);
+		return err;
+	}
+
+	/* Tegra114+ doesn't support OPP yet */
+	if (!of_machine_is_compatible("nvidia,tegra20") &&
+	    !of_machine_is_compatible("nvidia,tegra30"))
+		return -ENODEV;
+
+	if (of_machine_is_compatible("nvidia,tegra20"))
+		hw_version = BIT(tegra_sku_info.soc_process_id);
+	else
+		hw_version = BIT(tegra_sku_info.soc_speedo_id);
+
+	err = devm_pm_opp_set_supported_hw(dev, &hw_version, 1);
+	if (err) {
+		dev_err(dev, "failed to set OPP supported HW: %d\n", err);
+		return err;
+	}
+
+	/*
+	 * Older device-trees have an empty OPP table, hence we will get
+	 * -ENODEV from devm_pm_opp_of_add_table() for the older DTBs.
+	 *
+	 * The OPP table presence also varies per-device and depending
+	 * on a SoC generation, hence -ENODEV is expected to happen for
+	 * the newer DTs as well.
+	 */
+	err = devm_pm_opp_of_add_table(dev);
+	if (err) {
+		if (err == -ENODEV)
+			dev_err_once(dev, "OPP table not found, please update device-tree\n");
+		else
+			dev_err(dev, "failed to add OPP table: %d\n", err);
+
+		return err;
+	}
+
+	if (params->init_state) {
+		err = tegra_core_dev_init_opp_state(dev);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(devm_tegra_core_dev_init_opp_table);
diff --git a/include/soc/tegra/common.h b/include/soc/tegra/common.h
index 98027a76ce3d..e8eab13aa199 100644
--- a/include/soc/tegra/common.h
+++ b/include/soc/tegra/common.h
@@ -6,6 +6,36 @@
 #ifndef __SOC_TEGRA_COMMON_H__
 #define __SOC_TEGRA_COMMON_H__
 
+#include <linux/errno.h>
+#include <linux/types.h>
+
+struct device;
+
+/**
+ * Tegra SoC core device OPP table configuration
+ *
+ * @init_state: pre-initialize OPP state of a device
+ */
+struct tegra_core_opp_params {
+	bool init_state;
+};
+
+#ifdef CONFIG_ARCH_TEGRA
 bool soc_is_tegra(void);
+int devm_tegra_core_dev_init_opp_table(struct device *dev,
+				       struct tegra_core_opp_params *params);
+#else
+static inline bool soc_is_tegra(void)
+{
+	return false;
+}
+
+static inline int
+devm_tegra_core_dev_init_opp_table(struct device *dev,
+				   struct tegra_core_opp_params *params)
+{
+	return -ENODEV;
+}
+#endif
 
 #endif /* __SOC_TEGRA_COMMON_H__ */
-- 
2.30.2


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

* [PATCH v4 2/6] soc/tegra: Add CONFIG_SOC_TEGRA_COMMON and select PM_OPP by default
  2021-03-14 16:48 [PATCH v4 0/6] NVIDIA Tegra core power domain driver and OPP helper Dmitry Osipenko
  2021-03-14 16:48 ` [PATCH v4 1/6] soc/tegra: Add devm_tegra_core_dev_init_opp_table() Dmitry Osipenko
@ 2021-03-14 16:48 ` Dmitry Osipenko
  2021-03-14 16:48 ` [PATCH v4 3/6] dt-bindings: power: tegra: Add binding for core power domain Dmitry Osipenko
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Dmitry Osipenko @ 2021-03-14 16:48 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Mark Brown, Paul Fertser,
	Rob Herring, Matt Merhar, Peter Geis, Nicolas Chauvet,
	Viresh Kumar, Stephen Boyd, Michał Mirosław,
	Krzysztof Kozlowski
  Cc: devicetree, linux-tegra, linux-pm, linux-kernel

Add new Kconfig SOC_TEGRA_COMMON option which selects configuration
options that are common for all Tegra SoCs. Select PM_OPP by default
since from now on OPPs will be used by Tegra drivers which present on
all SoC generations, like display controller driver for example.

Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart@gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/soc/tegra/Kconfig | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index 976dee036470..bcd61ae59ba3 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -13,6 +13,7 @@ config ARCH_TEGRA_2x_SOC
 	select PINCTRL_TEGRA20
 	select PL310_ERRATA_727915 if CACHE_L2X0
 	select PL310_ERRATA_769419 if CACHE_L2X0
+	select SOC_TEGRA_COMMON
 	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
 	select SOC_TEGRA20_VOLTAGE_COUPLER
@@ -27,6 +28,7 @@ config ARCH_TEGRA_3x_SOC
 	select ARM_ERRATA_764369 if SMP
 	select PINCTRL_TEGRA30
 	select PL310_ERRATA_769419 if CACHE_L2X0
+	select SOC_TEGRA_COMMON
 	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
 	select SOC_TEGRA30_VOLTAGE_COUPLER
@@ -40,6 +42,7 @@ config ARCH_TEGRA_114_SOC
 	select ARM_ERRATA_798181 if SMP
 	select HAVE_ARM_ARCH_TIMER
 	select PINCTRL_TEGRA114
+	select SOC_TEGRA_COMMON
 	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
 	select TEGRA_TIMER
@@ -51,6 +54,7 @@ config ARCH_TEGRA_124_SOC
 	bool "Enable support for Tegra124 family"
 	select HAVE_ARM_ARCH_TIMER
 	select PINCTRL_TEGRA124
+	select SOC_TEGRA_COMMON
 	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
 	select TEGRA_TIMER
@@ -66,6 +70,7 @@ if ARM64
 config ARCH_TEGRA_132_SOC
 	bool "NVIDIA Tegra132 SoC"
 	select PINCTRL_TEGRA124
+	select SOC_TEGRA_COMMON
 	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
 	help
@@ -77,6 +82,7 @@ config ARCH_TEGRA_132_SOC
 config ARCH_TEGRA_210_SOC
 	bool "NVIDIA Tegra210 SoC"
 	select PINCTRL_TEGRA210
+	select SOC_TEGRA_COMMON
 	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
 	select TEGRA_TIMER
@@ -99,6 +105,7 @@ config ARCH_TEGRA_186_SOC
 	select TEGRA_BPMP
 	select TEGRA_HSP_MBOX
 	select TEGRA_IVC
+	select SOC_TEGRA_COMMON
 	select SOC_TEGRA_PMC
 	help
 	  Enable support for the NVIDIA Tegar186 SoC. The Tegra186 features a
@@ -115,6 +122,7 @@ config ARCH_TEGRA_194_SOC
 	select TEGRA_BPMP
 	select TEGRA_HSP_MBOX
 	select TEGRA_IVC
+	select SOC_TEGRA_COMMON
 	select SOC_TEGRA_PMC
 	help
 	  Enable support for the NVIDIA Tegra194 SoC.
@@ -125,6 +133,7 @@ config ARCH_TEGRA_234_SOC
 	select TEGRA_BPMP
 	select TEGRA_HSP_MBOX
 	select TEGRA_IVC
+	select SOC_TEGRA_COMMON
 	select SOC_TEGRA_PMC
 	help
 	  Enable support for the NVIDIA Tegra234 SoC.
@@ -132,6 +141,10 @@ config ARCH_TEGRA_234_SOC
 endif
 endif
 
+config SOC_TEGRA_COMMON
+	bool
+	select PM_OPP
+
 config SOC_TEGRA_FUSE
 	def_bool y
 	depends on ARCH_TEGRA
-- 
2.30.2


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

* [PATCH v4 3/6] dt-bindings: power: tegra: Add binding for core power domain
  2021-03-14 16:48 [PATCH v4 0/6] NVIDIA Tegra core power domain driver and OPP helper Dmitry Osipenko
  2021-03-14 16:48 ` [PATCH v4 1/6] soc/tegra: Add devm_tegra_core_dev_init_opp_table() Dmitry Osipenko
  2021-03-14 16:48 ` [PATCH v4 2/6] soc/tegra: Add CONFIG_SOC_TEGRA_COMMON and select PM_OPP by default Dmitry Osipenko
@ 2021-03-14 16:48 ` Dmitry Osipenko
  2021-03-23 22:48   ` Rob Herring
  2021-03-14 16:48 ` [PATCH v4 4/6] soc/tegra: Introduce core power domain driver Dmitry Osipenko
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Dmitry Osipenko @ 2021-03-14 16:48 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Mark Brown, Paul Fertser,
	Rob Herring, Matt Merhar, Peter Geis, Nicolas Chauvet,
	Viresh Kumar, Stephen Boyd, Michał Mirosław,
	Krzysztof Kozlowski
  Cc: devicetree, linux-tegra, linux-pm, linux-kernel

All NVIDIA Tegra SoCs have a core power domain where majority of hardware
blocks reside. Add binding for the core power domain.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../power/nvidia,tegra20-core-domain.yaml     | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml

diff --git a/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml b/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
new file mode 100644
index 000000000000..4692489d780a
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/nvidia,tegra20-core-domain.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra Core Power Domain
+
+maintainers:
+  - Dmitry Osipenko <digetx@gmail.com>
+  - Jon Hunter <jonathanh@nvidia.com>
+  - Thierry Reding <thierry.reding@gmail.com>
+
+allOf:
+  - $ref: power-domain.yaml#
+
+properties:
+  compatible:
+    enum:
+      - nvidia,tegra20-core-domain
+      - nvidia,tegra30-core-domain
+
+  operating-points-v2:
+    description:
+      Should contain level, voltages and opp-supported-hw property.
+      The supported-hw is a bitfield indicating SoC speedo or process
+      ID mask.
+
+  "#power-domain-cells":
+    const: 0
+
+  power-supply:
+    description:
+      Phandle to voltage regulator connected to the SoC Core power rail.
+
+required:
+  - compatible
+  - operating-points-v2
+  - "#power-domain-cells"
+  - power-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    power-domain {
+        compatible = "nvidia,tegra20-core-domain";
+        operating-points-v2 = <&opp_table>;
+        power-supply = <&regulator>;
+        #power-domain-cells = <0>;
+    };
-- 
2.30.2


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

* [PATCH v4 4/6] soc/tegra: Introduce core power domain driver
  2021-03-14 16:48 [PATCH v4 0/6] NVIDIA Tegra core power domain driver and OPP helper Dmitry Osipenko
                   ` (2 preceding siblings ...)
  2021-03-14 16:48 ` [PATCH v4 3/6] dt-bindings: power: tegra: Add binding for core power domain Dmitry Osipenko
@ 2021-03-14 16:48 ` Dmitry Osipenko
  2021-03-14 16:48 ` [PATCH v4 5/6] soc/tegra: regulators: Support Core domain state syncing Dmitry Osipenko
  2021-03-14 16:48 ` [PATCH v4 6/6] soc/tegra: pmc: Link children power domains to the parent domain Dmitry Osipenko
  5 siblings, 0 replies; 15+ messages in thread
From: Dmitry Osipenko @ 2021-03-14 16:48 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Mark Brown, Paul Fertser,
	Rob Herring, Matt Merhar, Peter Geis, Nicolas Chauvet,
	Viresh Kumar, Stephen Boyd, Michał Mirosław,
	Krzysztof Kozlowski
  Cc: devicetree, linux-tegra, linux-pm, linux-kernel

NVIDIA Tegra SoCs have multiple power domains, each domain corresponds
to an external SoC power rail. Core power domain covers vast majority of
hardware blocks within a Tegra SoC. The voltage of a power domain should
be set to a value which satisfies all devices within a power domain. Add
driver for the core power domain which manages the voltage state of the
domain. This allows us to support a system-wide DVFS on Tegra.

Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart@gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/soc/tegra/Kconfig             |   6 +
 drivers/soc/tegra/Makefile            |   1 +
 drivers/soc/tegra/core-power-domain.c | 153 ++++++++++++++++++++++++++
 include/soc/tegra/common.h            |   6 +
 4 files changed, 166 insertions(+)
 create mode 100644 drivers/soc/tegra/core-power-domain.c

diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index bcd61ae59ba3..fccbc168dd87 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -16,6 +16,7 @@ config ARCH_TEGRA_2x_SOC
 	select SOC_TEGRA_COMMON
 	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
+	select SOC_TEGRA_CORE_POWER_DOMAIN
 	select SOC_TEGRA20_VOLTAGE_COUPLER
 	select TEGRA_TIMER
 	help
@@ -31,6 +32,7 @@ config ARCH_TEGRA_3x_SOC
 	select SOC_TEGRA_COMMON
 	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
+	select SOC_TEGRA_CORE_POWER_DOMAIN
 	select SOC_TEGRA30_VOLTAGE_COUPLER
 	select TEGRA_TIMER
 	help
@@ -170,3 +172,7 @@ config SOC_TEGRA20_VOLTAGE_COUPLER
 config SOC_TEGRA30_VOLTAGE_COUPLER
 	bool "Voltage scaling support for Tegra30 SoCs"
 	depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST
+
+config SOC_TEGRA_CORE_POWER_DOMAIN
+	bool
+	select PM_GENERIC_DOMAINS
diff --git a/drivers/soc/tegra/Makefile b/drivers/soc/tegra/Makefile
index 9c809c1814bd..8f1294f954b4 100644
--- a/drivers/soc/tegra/Makefile
+++ b/drivers/soc/tegra/Makefile
@@ -7,3 +7,4 @@ 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
+obj-$(CONFIG_SOC_TEGRA_CORE_POWER_DOMAIN) += core-power-domain.o
diff --git a/drivers/soc/tegra/core-power-domain.c b/drivers/soc/tegra/core-power-domain.c
new file mode 100644
index 000000000000..c118933d4252
--- /dev/null
+++ b/drivers/soc/tegra/core-power-domain.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVIDIA Tegra SoC Core Power Domain Driver
+ */
+
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+
+#include <soc/tegra/common.h>
+
+static struct lock_class_key tegra_core_domain_lock_class;
+static bool tegra_core_domain_state_synced;
+static DEFINE_MUTEX(tegra_core_lock);
+
+bool tegra_soc_core_domain_state_synced(void)
+{
+	return tegra_core_domain_state_synced;
+}
+
+static int tegra_genpd_set_performance_state(struct generic_pm_domain *genpd,
+					     unsigned int level)
+{
+	struct dev_pm_opp *opp;
+	int err;
+
+	opp = dev_pm_opp_find_level_ceil(&genpd->dev, &level);
+	if (IS_ERR(opp)) {
+		dev_err(&genpd->dev, "failed to find OPP for level %u: %pe\n",
+			level, opp);
+		return PTR_ERR(opp);
+	}
+
+	mutex_lock(&tegra_core_lock);
+	err = dev_pm_opp_set_opp(&genpd->dev, opp);
+	mutex_unlock(&tegra_core_lock);
+
+	dev_pm_opp_put(opp);
+
+	if (err) {
+		dev_err(&genpd->dev, "failed to set voltage to %duV: %d\n",
+			level, err);
+		return err;
+	}
+
+	return 0;
+}
+
+static unsigned int
+tegra_genpd_opp_to_performance_state(struct generic_pm_domain *genpd,
+				     struct dev_pm_opp *opp)
+{
+	return dev_pm_opp_get_level(opp);
+}
+
+static int tegra_core_domain_probe(struct platform_device *pdev)
+{
+	struct generic_pm_domain *genpd;
+	const char *rname = "power";
+	int err;
+
+	genpd = devm_kzalloc(&pdev->dev, sizeof(*genpd), GFP_KERNEL);
+	if (!genpd)
+		return -ENOMEM;
+
+	genpd->name = pdev->dev.of_node->name;
+	genpd->set_performance_state = tegra_genpd_set_performance_state;
+	genpd->opp_to_performance_state = tegra_genpd_opp_to_performance_state;
+
+	err = devm_pm_opp_set_regulators(&pdev->dev, &rname, 1);
+	if (err)
+		return dev_err_probe(&pdev->dev, err,
+				     "failed to set OPP regulator\n");
+
+	err = pm_genpd_init(genpd, NULL, false);
+	if (err) {
+		dev_err(&pdev->dev, "failed to init genpd: %d\n", err);
+		return err;
+	}
+
+	/*
+	 * We have a "PMC -> Core" hierarchy of the power domains where
+	 * PMC needs to resume and change performance (voltage) of the
+	 * Core domain from the PMC GENPD on/off callbacks, hence we need
+	 * to annotate the lock in order to remove confusion from the
+	 * lockdep checker when a nested access happens.
+	 */
+	lockdep_set_class(&genpd->mlock, &tegra_core_domain_lock_class);
+
+	err = of_genpd_add_provider_simple(pdev->dev.of_node, genpd);
+	if (err) {
+		dev_err(&pdev->dev, "failed to add genpd: %d\n", err);
+		goto remove_genpd;
+	}
+
+	return 0;
+
+remove_genpd:
+	pm_genpd_remove(genpd);
+
+	return err;
+}
+
+static void tegra_core_domain_set_synced(struct device *dev, bool synced)
+{
+	int err;
+
+	tegra_core_domain_state_synced = synced;
+
+	mutex_lock(&tegra_core_lock);
+	err = dev_pm_opp_sync_regulators(dev);
+	mutex_unlock(&tegra_core_lock);
+
+	if (err)
+		dev_err(dev, "failed to sync regulators: %d\n", err);
+}
+
+static void tegra_core_domain_sync_state(struct device *dev)
+{
+	tegra_core_domain_set_synced(dev, true);
+}
+
+static void tegra_core_domain_shutdown(struct platform_device *pdev)
+{
+	/*
+	 * Ensure that core voltage is at a level suitable for boot-up
+	 * before system is rebooted, which may be important for some
+	 * devices if regulators aren't reset on reboot. This is usually
+	 * the case if PMC soft-reboot is used.
+	 */
+	tegra_core_domain_set_synced(&pdev->dev, false);
+}
+
+static const struct of_device_id tegra_core_domain_match[] = {
+	{ .compatible = "nvidia,tegra20-core-domain", },
+	{ .compatible = "nvidia,tegra30-core-domain", },
+	{ }
+};
+
+static struct platform_driver tegra_core_domain_driver = {
+	.driver = {
+		.name = "tegra-core-power",
+		.of_match_table = tegra_core_domain_match,
+		.suppress_bind_attrs = true,
+		.sync_state = tegra_core_domain_sync_state,
+	},
+	.probe = tegra_core_domain_probe,
+	.shutdown = tegra_core_domain_shutdown,
+};
+builtin_platform_driver(tegra_core_domain_driver);
diff --git a/include/soc/tegra/common.h b/include/soc/tegra/common.h
index e8eab13aa199..9a4ac3af2401 100644
--- a/include/soc/tegra/common.h
+++ b/include/soc/tegra/common.h
@@ -22,6 +22,7 @@ struct tegra_core_opp_params {
 
 #ifdef CONFIG_ARCH_TEGRA
 bool soc_is_tegra(void);
+bool tegra_soc_core_domain_state_synced(void);
 int devm_tegra_core_dev_init_opp_table(struct device *dev,
 				       struct tegra_core_opp_params *params);
 #else
@@ -30,6 +31,11 @@ static inline bool soc_is_tegra(void)
 	return false;
 }
 
+static inline bool tegra_soc_core_domain_state_synced(void)
+{
+	return false;
+}
+
 static inline int
 devm_tegra_core_dev_init_opp_table(struct device *dev,
 				   struct tegra_core_opp_params *params)
-- 
2.30.2


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

* [PATCH v4 5/6] soc/tegra: regulators: Support Core domain state syncing
  2021-03-14 16:48 [PATCH v4 0/6] NVIDIA Tegra core power domain driver and OPP helper Dmitry Osipenko
                   ` (3 preceding siblings ...)
  2021-03-14 16:48 ` [PATCH v4 4/6] soc/tegra: Introduce core power domain driver Dmitry Osipenko
@ 2021-03-14 16:48 ` Dmitry Osipenko
  2021-03-14 16:48 ` [PATCH v4 6/6] soc/tegra: pmc: Link children power domains to the parent domain Dmitry Osipenko
  5 siblings, 0 replies; 15+ messages in thread
From: Dmitry Osipenko @ 2021-03-14 16:48 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Mark Brown, Paul Fertser,
	Rob Herring, Matt Merhar, Peter Geis, Nicolas Chauvet,
	Viresh Kumar, Stephen Boyd, Michał Mirosław,
	Krzysztof Kozlowski
  Cc: devicetree, linux-tegra, linux-pm, linux-kernel

The core voltage shall not drop until state of Core domain is synced,
i.e. all device drivers that use Core domain are loaded and ready.

Support Core domain state syncing. The Core domain driver invokes the
core-regulator voltage syncing once the state of domain is synced, at
this point the Core voltage is allowed to go lower than the level left
after bootloader.

Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart@gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/soc/tegra/regulators-tegra20.c | 19 ++++++++++++++++++-
 drivers/soc/tegra/regulators-tegra30.c | 18 +++++++++++++++++-
 2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/tegra/regulators-tegra20.c b/drivers/soc/tegra/regulators-tegra20.c
index 367a71a3cd10..e2c11d442591 100644
--- a/drivers/soc/tegra/regulators-tegra20.c
+++ b/drivers/soc/tegra/regulators-tegra20.c
@@ -16,6 +16,8 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 
+#include <soc/tegra/common.h>
+
 struct tegra_regulator_coupler {
 	struct regulator_coupler coupler;
 	struct regulator_dev *core_rdev;
@@ -38,6 +40,21 @@ static int tegra20_core_limit(struct tegra_regulator_coupler *tegra,
 	int core_cur_uV;
 	int err;
 
+	/*
+	 * Tegra20 SoC has critical DVFS-capable devices that are
+	 * permanently-active or active at a boot time, like EMC
+	 * (DRAM controller) or Display controller for example.
+	 *
+	 * The voltage of a CORE SoC power domain shall not be dropped below
+	 * a minimum level, which is determined by device's clock rate.
+	 * This means that we can't fully allow CORE voltage scaling until
+	 * the state of all DVFS-critical CORE devices is synced.
+	 */
+	if (tegra_soc_core_domain_state_synced()) {
+		pr_info_once("voltage state synced\n");
+		return 0;
+	}
+
 	if (tegra->core_min_uV > 0)
 		return tegra->core_min_uV;
 
@@ -58,7 +75,7 @@ static int tegra20_core_limit(struct tegra_regulator_coupler *tegra,
 	 */
 	tegra->core_min_uV = core_max_uV;
 
-	pr_info("core minimum voltage limited to %duV\n", tegra->core_min_uV);
+	pr_info("core voltage initialized to %duV\n", tegra->core_min_uV);
 
 	return tegra->core_min_uV;
 }
diff --git a/drivers/soc/tegra/regulators-tegra30.c b/drivers/soc/tegra/regulators-tegra30.c
index 0e776b20f625..42d675b79fa3 100644
--- a/drivers/soc/tegra/regulators-tegra30.c
+++ b/drivers/soc/tegra/regulators-tegra30.c
@@ -16,6 +16,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 
+#include <soc/tegra/common.h>
 #include <soc/tegra/fuse.h>
 
 struct tegra_regulator_coupler {
@@ -39,6 +40,21 @@ static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,
 	int core_cur_uV;
 	int err;
 
+	/*
+	 * Tegra30 SoC has critical DVFS-capable devices that are
+	 * permanently-active or active at a boot time, like EMC
+	 * (DRAM controller) or Display controller for example.
+	 *
+	 * The voltage of a CORE SoC power domain shall not be dropped below
+	 * a minimum level, which is determined by device's clock rate.
+	 * This means that we can't fully allow CORE voltage scaling until
+	 * the state of all DVFS-critical CORE devices is synced.
+	 */
+	if (tegra_soc_core_domain_state_synced()) {
+		pr_info_once("voltage state synced\n");
+		return 0;
+	}
+
 	if (tegra->core_min_uV > 0)
 		return tegra->core_min_uV;
 
@@ -59,7 +75,7 @@ static int tegra30_core_limit(struct tegra_regulator_coupler *tegra,
 	 */
 	tegra->core_min_uV = core_max_uV;
 
-	pr_info("core minimum voltage limited to %duV\n", tegra->core_min_uV);
+	pr_info("core voltage initialized to %duV\n", tegra->core_min_uV);
 
 	return tegra->core_min_uV;
 }
-- 
2.30.2


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

* [PATCH v4 6/6] soc/tegra: pmc: Link children power domains to the parent domain
  2021-03-14 16:48 [PATCH v4 0/6] NVIDIA Tegra core power domain driver and OPP helper Dmitry Osipenko
                   ` (4 preceding siblings ...)
  2021-03-14 16:48 ` [PATCH v4 5/6] soc/tegra: regulators: Support Core domain state syncing Dmitry Osipenko
@ 2021-03-14 16:48 ` Dmitry Osipenko
  5 siblings, 0 replies; 15+ messages in thread
From: Dmitry Osipenko @ 2021-03-14 16:48 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Mark Brown, Paul Fertser,
	Rob Herring, Matt Merhar, Peter Geis, Nicolas Chauvet,
	Viresh Kumar, Stephen Boyd, Michał Mirosław,
	Krzysztof Kozlowski
  Cc: devicetree, linux-tegra, linux-pm, linux-kernel

The Core domain is a parent of PMC power domains, hence PMC domains
should be set up as a sub-domains of the parent (Core) domain if
"power-domains" phandle presents in a device-tree node of PMC domain.

This allows to propagate GENPD performance changes to the parent Core
domain if performance change is applied to a PMC domain.

Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart@gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/soc/tegra/pmc.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 84ab27d85d92..ba8407819397 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -1283,6 +1283,7 @@ static int tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
 static int tegra_powergate_init(struct tegra_pmc *pmc,
 				struct device_node *parent)
 {
+	struct of_phandle_args child_args, parent_args;
 	struct device_node *np, *child;
 	int err = 0;
 
@@ -1296,6 +1297,21 @@ static int tegra_powergate_init(struct tegra_pmc *pmc,
 			of_node_put(child);
 			break;
 		}
+
+		if (of_parse_phandle_with_args(child, "power-domains",
+					       "#power-domain-cells",
+					       0, &parent_args))
+			continue;
+
+		child_args.np = child;
+		child_args.args_count = 0;
+
+		err = of_genpd_add_subdomain(&parent_args, &child_args);
+		of_node_put(parent_args.np);
+		if (err) {
+			of_node_put(child);
+			break;
+		}
 	}
 
 	of_node_put(np);
-- 
2.30.2


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

* Re: [PATCH v4 1/6] soc/tegra: Add devm_tegra_core_dev_init_opp_table()
  2021-03-14 16:48 ` [PATCH v4 1/6] soc/tegra: Add devm_tegra_core_dev_init_opp_table() Dmitry Osipenko
@ 2021-03-18 10:27   ` Dmitry Osipenko
  2021-03-18 10:32     ` Viresh Kumar
  0 siblings, 1 reply; 15+ messages in thread
From: Dmitry Osipenko @ 2021-03-18 10:27 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Mark Brown, Paul Fertser,
	Rob Herring, Matt Merhar, Peter Geis, Nicolas Chauvet,
	Viresh Kumar, Stephen Boyd, Michał Mirosław,
	Krzysztof Kozlowski
  Cc: devicetree, linux-tegra, linux-pm, linux-kernel

14.03.2021 19:48, Dmitry Osipenko пишет:
> Add common helper which initializes OPP table for Tegra SoC core devices.
> 
> Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
> Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
> Tested-by: Nicolas Chauvet <kwizart@gmail.com> # PAZ00 T20 and TK1 T124
> Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/soc/tegra/common.c | 137 +++++++++++++++++++++++++++++++++++++
>  include/soc/tegra/common.h |  30 ++++++++
>  2 files changed, 167 insertions(+)

Viresh, do you think it will be possible to take this patch via the OPP
tree along with the devres patches if Thierry will give an ack? This
will allow us to start adding power management support to Tegra drivers
once 5.13 will be released.

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

* Re: [PATCH v4 1/6] soc/tegra: Add devm_tegra_core_dev_init_opp_table()
  2021-03-18 10:27   ` Dmitry Osipenko
@ 2021-03-18 10:32     ` Viresh Kumar
  2021-03-18 10:37       ` Dmitry Osipenko
  0 siblings, 1 reply; 15+ messages in thread
From: Viresh Kumar @ 2021-03-18 10:32 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Mark Brown, Paul Fertser,
	Rob Herring, Matt Merhar, Peter Geis, Nicolas Chauvet,
	Viresh Kumar, Stephen Boyd, Michał Mirosław,
	Krzysztof Kozlowski, devicetree, linux-tegra, linux-pm,
	linux-kernel

On 18-03-21, 13:27, Dmitry Osipenko wrote:
> 14.03.2021 19:48, Dmitry Osipenko пишет:
> > Add common helper which initializes OPP table for Tegra SoC core devices.
> > 
> > Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
> > Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
> > Tested-by: Nicolas Chauvet <kwizart@gmail.com> # PAZ00 T20 and TK1 T124
> > Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30
> > Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> > ---
> >  drivers/soc/tegra/common.c | 137 +++++++++++++++++++++++++++++++++++++
> >  include/soc/tegra/common.h |  30 ++++++++
> >  2 files changed, 167 insertions(+)
> 
> Viresh, do you think it will be possible to take this patch via the OPP
> tree along with the devres patches if Thierry will give an ack? This
> will allow us to start adding power management support to Tegra drivers
> once 5.13 will be released.

I can do that.. OR

I can give an immutable to Thierry over which he can base these patches..

-- 
viresh

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

* Re: [PATCH v4 1/6] soc/tegra: Add devm_tegra_core_dev_init_opp_table()
  2021-03-18 10:32     ` Viresh Kumar
@ 2021-03-18 10:37       ` Dmitry Osipenko
  2021-03-31 15:45         ` Dmitry Osipenko
  0 siblings, 1 reply; 15+ messages in thread
From: Dmitry Osipenko @ 2021-03-18 10:37 UTC (permalink / raw)
  To: Viresh Kumar, Thierry Reding
  Cc: Jonathan Hunter, Mark Brown, Paul Fertser, Rob Herring,
	Matt Merhar, Peter Geis, Nicolas Chauvet, Viresh Kumar,
	Stephen Boyd, Michał Mirosław, Krzysztof Kozlowski,
	devicetree, linux-tegra, linux-pm, linux-kernel

18.03.2021 13:32, Viresh Kumar пишет:
> On 18-03-21, 13:27, Dmitry Osipenko wrote:
>> 14.03.2021 19:48, Dmitry Osipenko пишет:
>>> Add common helper which initializes OPP table for Tegra SoC core devices.
>>>
>>> Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
>>> Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
>>> Tested-by: Nicolas Chauvet <kwizart@gmail.com> # PAZ00 T20 and TK1 T124
>>> Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30
>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>> ---
>>>  drivers/soc/tegra/common.c | 137 +++++++++++++++++++++++++++++++++++++
>>>  include/soc/tegra/common.h |  30 ++++++++
>>>  2 files changed, 167 insertions(+)
>>
>> Viresh, do you think it will be possible to take this patch via the OPP
>> tree along with the devres patches if Thierry will give an ack? This
>> will allow us to start adding power management support to Tegra drivers
>> once 5.13 will be released.
> 
> I can do that.. OR
> 
> I can give an immutable to Thierry over which he can base these patches..
> 

Thank you!

Thierry, please let us know if you're okay with this patch and what
variant you prefer more.

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

* Re: [PATCH v4 3/6] dt-bindings: power: tegra: Add binding for core power domain
  2021-03-14 16:48 ` [PATCH v4 3/6] dt-bindings: power: tegra: Add binding for core power domain Dmitry Osipenko
@ 2021-03-23 22:48   ` Rob Herring
  2021-03-23 23:01     ` Dmitry Osipenko
  0 siblings, 1 reply; 15+ messages in thread
From: Rob Herring @ 2021-03-23 22:48 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Mark Brown, Paul Fertser,
	Matt Merhar, Peter Geis, Nicolas Chauvet, Viresh Kumar,
	Stephen Boyd, Michał Mirosław, Krzysztof Kozlowski,
	devicetree, linux-tegra, linux-pm, linux-kernel

On Sun, Mar 14, 2021 at 07:48:07PM +0300, Dmitry Osipenko wrote:
> All NVIDIA Tegra SoCs have a core power domain where majority of hardware
> blocks reside. Add binding for the core power domain.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../power/nvidia,tegra20-core-domain.yaml     | 51 +++++++++++++++++++
>  1 file changed, 51 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
> 
> diff --git a/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml b/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
> new file mode 100644
> index 000000000000..4692489d780a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
> @@ -0,0 +1,51 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/power/nvidia,tegra20-core-domain.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NVIDIA Tegra Core Power Domain
> +
> +maintainers:
> +  - Dmitry Osipenko <digetx@gmail.com>
> +  - Jon Hunter <jonathanh@nvidia.com>
> +  - Thierry Reding <thierry.reding@gmail.com>
> +
> +allOf:
> +  - $ref: power-domain.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - nvidia,tegra20-core-domain
> +      - nvidia,tegra30-core-domain
> +
> +  operating-points-v2:
> +    description:
> +      Should contain level, voltages and opp-supported-hw property.
> +      The supported-hw is a bitfield indicating SoC speedo or process
> +      ID mask.
> +
> +  "#power-domain-cells":
> +    const: 0
> +
> +  power-supply:
> +    description:
> +      Phandle to voltage regulator connected to the SoC Core power rail.
> +
> +required:
> +  - compatible
> +  - operating-points-v2
> +  - "#power-domain-cells"
> +  - power-supply
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    power-domain {
> +        compatible = "nvidia,tegra20-core-domain";
> +        operating-points-v2 = <&opp_table>;
> +        power-supply = <&regulator>;
> +        #power-domain-cells = <0>;

AFAICT, there's no way to access this 'hardware'?

> +    };
> -- 
> 2.30.2
> 

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

* Re: [PATCH v4 3/6] dt-bindings: power: tegra: Add binding for core power domain
  2021-03-23 22:48   ` Rob Herring
@ 2021-03-23 23:01     ` Dmitry Osipenko
  2021-03-25 14:49       ` Thierry Reding
  0 siblings, 1 reply; 15+ messages in thread
From: Dmitry Osipenko @ 2021-03-23 23:01 UTC (permalink / raw)
  To: Rob Herring
  Cc: Thierry Reding, Jonathan Hunter, Mark Brown, Paul Fertser,
	Matt Merhar, Peter Geis, Nicolas Chauvet, Viresh Kumar,
	Stephen Boyd, Michał Mirosław, Krzysztof Kozlowski,
	devicetree, linux-tegra, linux-pm, linux-kernel

24.03.2021 01:48, Rob Herring пишет:
> On Sun, Mar 14, 2021 at 07:48:07PM +0300, Dmitry Osipenko wrote:
>> All NVIDIA Tegra SoCs have a core power domain where majority of hardware
>> blocks reside. Add binding for the core power domain.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  .../power/nvidia,tegra20-core-domain.yaml     | 51 +++++++++++++++++++
>>  1 file changed, 51 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml b/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
>> new file mode 100644
>> index 000000000000..4692489d780a
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
>> @@ -0,0 +1,51 @@
>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/power/nvidia,tegra20-core-domain.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: NVIDIA Tegra Core Power Domain
>> +
>> +maintainers:
>> +  - Dmitry Osipenko <digetx@gmail.com>
>> +  - Jon Hunter <jonathanh@nvidia.com>
>> +  - Thierry Reding <thierry.reding@gmail.com>
>> +
>> +allOf:
>> +  - $ref: power-domain.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - nvidia,tegra20-core-domain
>> +      - nvidia,tegra30-core-domain
>> +
>> +  operating-points-v2:
>> +    description:
>> +      Should contain level, voltages and opp-supported-hw property.
>> +      The supported-hw is a bitfield indicating SoC speedo or process
>> +      ID mask.
>> +
>> +  "#power-domain-cells":
>> +    const: 0
>> +
>> +  power-supply:
>> +    description:
>> +      Phandle to voltage regulator connected to the SoC Core power rail.
>> +
>> +required:
>> +  - compatible
>> +  - operating-points-v2
>> +  - "#power-domain-cells"
>> +  - power-supply
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    power-domain {
>> +        compatible = "nvidia,tegra20-core-domain";
>> +        operating-points-v2 = <&opp_table>;
>> +        power-supply = <&regulator>;
>> +        #power-domain-cells = <0>;
> 
> AFAICT, there's no way to access this 'hardware'?
correct

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

* Re: [PATCH v4 3/6] dt-bindings: power: tegra: Add binding for core power domain
  2021-03-23 23:01     ` Dmitry Osipenko
@ 2021-03-25 14:49       ` Thierry Reding
  2021-03-25 17:38         ` Dmitry Osipenko
  0 siblings, 1 reply; 15+ messages in thread
From: Thierry Reding @ 2021-03-25 14:49 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Rob Herring, Jonathan Hunter, Mark Brown, Paul Fertser,
	Matt Merhar, Peter Geis, Nicolas Chauvet, Viresh Kumar,
	Stephen Boyd, Michał Mirosław, Krzysztof Kozlowski,
	devicetree, linux-tegra, linux-pm, linux-kernel

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

On Wed, Mar 24, 2021 at 02:01:29AM +0300, Dmitry Osipenko wrote:
> 24.03.2021 01:48, Rob Herring пишет:
> > On Sun, Mar 14, 2021 at 07:48:07PM +0300, Dmitry Osipenko wrote:
> >> All NVIDIA Tegra SoCs have a core power domain where majority of hardware
> >> blocks reside. Add binding for the core power domain.
> >>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  .../power/nvidia,tegra20-core-domain.yaml     | 51 +++++++++++++++++++
> >>  1 file changed, 51 insertions(+)
> >>  create mode 100644 Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
> >>
> >> diff --git a/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml b/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
> >> new file mode 100644
> >> index 000000000000..4692489d780a
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
> >> @@ -0,0 +1,51 @@
> >> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> >> +%YAML 1.2
> >> +---
> >> +$id: http://devicetree.org/schemas/power/nvidia,tegra20-core-domain.yaml#
> >> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >> +
> >> +title: NVIDIA Tegra Core Power Domain
> >> +
> >> +maintainers:
> >> +  - Dmitry Osipenko <digetx@gmail.com>
> >> +  - Jon Hunter <jonathanh@nvidia.com>
> >> +  - Thierry Reding <thierry.reding@gmail.com>
> >> +
> >> +allOf:
> >> +  - $ref: power-domain.yaml#
> >> +
> >> +properties:
> >> +  compatible:
> >> +    enum:
> >> +      - nvidia,tegra20-core-domain
> >> +      - nvidia,tegra30-core-domain
> >> +
> >> +  operating-points-v2:
> >> +    description:
> >> +      Should contain level, voltages and opp-supported-hw property.
> >> +      The supported-hw is a bitfield indicating SoC speedo or process
> >> +      ID mask.
> >> +
> >> +  "#power-domain-cells":
> >> +    const: 0
> >> +
> >> +  power-supply:
> >> +    description:
> >> +      Phandle to voltage regulator connected to the SoC Core power rail.
> >> +
> >> +required:
> >> +  - compatible
> >> +  - operating-points-v2
> >> +  - "#power-domain-cells"
> >> +  - power-supply
> >> +
> >> +additionalProperties: false
> >> +
> >> +examples:
> >> +  - |
> >> +    power-domain {
> >> +        compatible = "nvidia,tegra20-core-domain";
> >> +        operating-points-v2 = <&opp_table>;
> >> +        power-supply = <&regulator>;
> >> +        #power-domain-cells = <0>;
> > 
> > AFAICT, there's no way to access this 'hardware'?
> correct

To avoid exposing this "virtual" device in device tree, could this
instead be modelled as a child node of the PMC node? We already expose a
couple of generic power domains that way on Tegra210 and later, so
perhaps some of that infrastructure can be reused? I suppose given that
this is different from the standard powergate domains that we expose so
far, this may need a different implementation, but from a device tree
bindings point of view it could fit in with that.

Thierry

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

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

* Re: [PATCH v4 3/6] dt-bindings: power: tegra: Add binding for core power domain
  2021-03-25 14:49       ` Thierry Reding
@ 2021-03-25 17:38         ` Dmitry Osipenko
  0 siblings, 0 replies; 15+ messages in thread
From: Dmitry Osipenko @ 2021-03-25 17:38 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Jonathan Hunter, Mark Brown, Paul Fertser,
	Matt Merhar, Peter Geis, Nicolas Chauvet, Viresh Kumar,
	Stephen Boyd, Michał Mirosław, Krzysztof Kozlowski,
	devicetree, linux-tegra, linux-pm, linux-kernel

25.03.2021 17:49, Thierry Reding пишет:
> On Wed, Mar 24, 2021 at 02:01:29AM +0300, Dmitry Osipenko wrote:
>> 24.03.2021 01:48, Rob Herring пишет:
>>> On Sun, Mar 14, 2021 at 07:48:07PM +0300, Dmitry Osipenko wrote:
>>>> All NVIDIA Tegra SoCs have a core power domain where majority of hardware
>>>> blocks reside. Add binding for the core power domain.
>>>>
>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>> ---
>>>>  .../power/nvidia,tegra20-core-domain.yaml     | 51 +++++++++++++++++++
>>>>  1 file changed, 51 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml b/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
>>>> new file mode 100644
>>>> index 000000000000..4692489d780a
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/power/nvidia,tegra20-core-domain.yaml
>>>> @@ -0,0 +1,51 @@
>>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/power/nvidia,tegra20-core-domain.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: NVIDIA Tegra Core Power Domain
>>>> +
>>>> +maintainers:
>>>> +  - Dmitry Osipenko <digetx@gmail.com>
>>>> +  - Jon Hunter <jonathanh@nvidia.com>
>>>> +  - Thierry Reding <thierry.reding@gmail.com>
>>>> +
>>>> +allOf:
>>>> +  - $ref: power-domain.yaml#
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    enum:
>>>> +      - nvidia,tegra20-core-domain
>>>> +      - nvidia,tegra30-core-domain
>>>> +
>>>> +  operating-points-v2:
>>>> +    description:
>>>> +      Should contain level, voltages and opp-supported-hw property.
>>>> +      The supported-hw is a bitfield indicating SoC speedo or process
>>>> +      ID mask.
>>>> +
>>>> +  "#power-domain-cells":
>>>> +    const: 0
>>>> +
>>>> +  power-supply:
>>>> +    description:
>>>> +      Phandle to voltage regulator connected to the SoC Core power rail.
>>>> +
>>>> +required:
>>>> +  - compatible
>>>> +  - operating-points-v2
>>>> +  - "#power-domain-cells"
>>>> +  - power-supply
>>>> +
>>>> +additionalProperties: false
>>>> +
>>>> +examples:
>>>> +  - |
>>>> +    power-domain {
>>>> +        compatible = "nvidia,tegra20-core-domain";
>>>> +        operating-points-v2 = <&opp_table>;
>>>> +        power-supply = <&regulator>;
>>>> +        #power-domain-cells = <0>;
>>>
>>> AFAICT, there's no way to access this 'hardware'?
>> correct
> 
> To avoid exposing this "virtual" device in device tree, could this
> instead be modelled as a child node of the PMC node? We already expose a
> couple of generic power domains that way on Tegra210 and later, so
> perhaps some of that infrastructure can be reused? I suppose given that
> this is different from the standard powergate domains that we expose so
> far, this may need a different implementation, but from a device tree
> bindings point of view it could fit in with that.

At a quick glance this should be too troublesome because OPP and regulator frameworks require a proper/real backing device.

Perhaps we could either turn the whole PMC into a core-domain or add a virtual device as a child of PMC, like this:

diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 79364cdafeab..717273048caf 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -850,6 +850,12 @@ pd_mpe: mpe {
 				#power-domain-cells = <0>;
 			};
 		};
+
+		pd_core: core-domain {
+			compatible = "nvidia,tegra20-core-domain";
+			operating-points-v2 = <&core_opp_table>;
+			#power-domain-cells = <0>;
+		};
 	};
 
 	mc: memory-controller@7000f000 {

but then this is still a virtual device, although in a bit nicer way.

It feels like yours suggestion might result in a hardware description that is closer to reality since PMC controls fan out of all power rails within SoC.

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

* Re: [PATCH v4 1/6] soc/tegra: Add devm_tegra_core_dev_init_opp_table()
  2021-03-18 10:37       ` Dmitry Osipenko
@ 2021-03-31 15:45         ` Dmitry Osipenko
  0 siblings, 0 replies; 15+ messages in thread
From: Dmitry Osipenko @ 2021-03-31 15:45 UTC (permalink / raw)
  To: Viresh Kumar, Thierry Reding
  Cc: Jonathan Hunter, Mark Brown, Paul Fertser, Rob Herring,
	Matt Merhar, Peter Geis, Nicolas Chauvet, Viresh Kumar,
	Stephen Boyd, Michał Mirosław, Krzysztof Kozlowski,
	devicetree, linux-tegra, linux-pm, linux-kernel

18.03.2021 13:37, Dmitry Osipenko пишет:
> 18.03.2021 13:32, Viresh Kumar пишет:
>> On 18-03-21, 13:27, Dmitry Osipenko wrote:
>>> 14.03.2021 19:48, Dmitry Osipenko пишет:
>>>> Add common helper which initializes OPP table for Tegra SoC core devices.
>>>>
>>>> Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
>>>> Tested-by: Paul Fertser <fercerpav@gmail.com> # PAZ00 T20
>>>> Tested-by: Nicolas Chauvet <kwizart@gmail.com> # PAZ00 T20 and TK1 T124
>>>> Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30
>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>> ---
>>>>  drivers/soc/tegra/common.c | 137 +++++++++++++++++++++++++++++++++++++
>>>>  include/soc/tegra/common.h |  30 ++++++++
>>>>  2 files changed, 167 insertions(+)
>>>
>>> Viresh, do you think it will be possible to take this patch via the OPP
>>> tree along with the devres patches if Thierry will give an ack? This
>>> will allow us to start adding power management support to Tegra drivers
>>> once 5.13 will be released.
>>
>> I can do that.. OR
>>
>> I can give an immutable to Thierry over which he can base these patches..
>>
> 
> Thank you!
> 
> Thierry, please let us know if you're okay with this patch and what
> variant you prefer more.
> 

It's a bit too late now for 5.13, so I'll re-send this patch later on
for 5.14 separately and along with other patches that will make use of
this new helper.

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

end of thread, other threads:[~2021-03-31 15:46 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-14 16:48 [PATCH v4 0/6] NVIDIA Tegra core power domain driver and OPP helper Dmitry Osipenko
2021-03-14 16:48 ` [PATCH v4 1/6] soc/tegra: Add devm_tegra_core_dev_init_opp_table() Dmitry Osipenko
2021-03-18 10:27   ` Dmitry Osipenko
2021-03-18 10:32     ` Viresh Kumar
2021-03-18 10:37       ` Dmitry Osipenko
2021-03-31 15:45         ` Dmitry Osipenko
2021-03-14 16:48 ` [PATCH v4 2/6] soc/tegra: Add CONFIG_SOC_TEGRA_COMMON and select PM_OPP by default Dmitry Osipenko
2021-03-14 16:48 ` [PATCH v4 3/6] dt-bindings: power: tegra: Add binding for core power domain Dmitry Osipenko
2021-03-23 22:48   ` Rob Herring
2021-03-23 23:01     ` Dmitry Osipenko
2021-03-25 14:49       ` Thierry Reding
2021-03-25 17:38         ` Dmitry Osipenko
2021-03-14 16:48 ` [PATCH v4 4/6] soc/tegra: Introduce core power domain driver Dmitry Osipenko
2021-03-14 16:48 ` [PATCH v4 5/6] soc/tegra: regulators: Support Core domain state syncing Dmitry Osipenko
2021-03-14 16:48 ` [PATCH v4 6/6] soc/tegra: pmc: Link children power domains to the parent domain Dmitry Osipenko

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).