Skip to contentSkip to conversation

NVIDIA Tegra memory and power management changes for 5.14

PATCH Superseded Dmitry Osipenko 3 participants 21 messages May 20, 2021 – May 22, 2021

Subsystems (5)

v1 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

cover NVIDIA Tegra memory and power management changes for 5.14

This series is a continuation of the previous patches that I previously tried to separate into smaller subsets, but all these patches are actually very dependent on each other and I was messing up the dependencies because there are too many of them and it's too difficult to keep them all in sync. So I merged the patches into a single series again.

This series:

1. Adds CPU/core voltage bump before system is rebooted.
2. Adds new devm_tegra_core_dev_init_opp_table() helper and switches Tegra memory drivers to use it.
3. Adds compile-testing support to the Tegra memory drivers.
4. Adds Tegra SoC core power domain support.

I'll send the GPU/clk/video-dec/OPP-tables patches that will update power management of the corresponding drivers and enable core voltage scaling on T20/30 once this series will be merged.

Changelog:

v1: - Merged previous patches into this single series.

- Added ack from Rob Herring to the core domain DT binding patch.

- Implemented suggestions that were given by Krzysztof Kozlowski:

- Factored out soc_is_tegra() stub into standalone patch.
- Updated tags of the "Fix compilation warnings on 64bit platforms" patch, added reported-by from lkp robot and removed suggested-by from Nathan Chancellor.
- Switched to use use BIT() macro.

- Added r-b from Krzysztof Kozlowski to "Enable compile testing for all drivers" patch.

- Added r-b from Nathan Chancellor.

- Dropped voltage floor/ceiling from devm_tegra_core_dev_init_opp_table() since only memory drivers now need to initialize voltage vote and they don't need floor/ceil. This was suggested by Viresh Kumar.

Dmitry Osipenko (13):
regulator: core: Add regulator_sync_voltage_rdev() soc/tegra: regulators: Bump voltages on system reboot soc/tegra: Add stub for soc_is_tegra()
soc/tegra: Add devm_tegra_core_dev_init_opp_table() soc/tegra: fuse: Add stubs needed for compile-testing
clk: tegra: Add stubs needed for compile-testing
memory: tegra: Fix compilation warnings on 64bit platforms
memory: tegra: Enable compile testing for all drivers
memory: tegra20-emc: Use devm_tegra_core_dev_init_opp_table()
memory: tegra30-emc: Use devm_tegra_core_dev_init_opp_table()
dt-bindings: soc: tegra-pmc: Document core power domain soc/tegra: pmc: Add core power domain
soc/tegra: regulators: Support core domain state syncing

 .../arm/tegra/nvidia,tegra20-pmc.yaml         |  35 +++++
 drivers/memory/tegra/Kconfig                  |  16 +-
 drivers/memory/tegra/tegra124-emc.c           |   4 +-
 drivers/memory/tegra/tegra20-emc.c            |  48 +-----
 drivers/memory/tegra/tegra30-emc.c            |  52 +------
 drivers/regulator/core.c                      |  23 +++
 drivers/soc/tegra/Kconfig                     |  14 ++
 drivers/soc/tegra/common.c                    |  97 ++++++++++++
 drivers/soc/tegra/pmc.c                       | 143 ++++++++++++++++++
 drivers/soc/tegra/regulators-tegra20.c        |  94 +++++++++++-
 drivers/soc/tegra/regulators-tegra30.c        |  96 +++++++++++-
 include/linux/clk/tegra.h                     |  28 +++-
 include/linux/regulator/driver.h              |   1 +
 include/soc/tegra/common.h                    |  38 +++++
 include/soc/tegra/fuse.h                      |  20 ++-
 15 files changed, 600 insertions(+), 109 deletions(-)
Signature · 1 line
2.30.2
#1 lore raw

PATCH 1/13 regulator: core: Add regulator_sync_voltage_rdev()

Some NVIDIA Tegra devices use a CPU soft-reset method for the reboot and in this case we need to restore the coupled voltages to the state that is suitable for hardware during boot. Add new regulator_sync_voltage_rdev() helper which is needed by regulator drivers in order to sync voltage of a coupled regulators.

---
 drivers/regulator/core.c         | 23 +++++++++++++++++++++++
 include/linux/regulator/driver.h |  1 +
 2 files changed, 24 insertions(+)
drivers/regulator/core.c +23 -0
index f192bf19492e..ead0b6d2af45 100644
@@ -4105,6 +4105,29 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
 }
 EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel);
 
+int regulator_sync_voltage_rdev(struct regulator_dev *rdev)
+{
+	int ret;
+
+	regulator_lock(rdev);
+
+	if (!rdev->desc->ops->set_voltage &&
+	    !rdev->desc->ops->set_voltage_sel) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* balance only, if regulator is coupled */
+	if (rdev->coupling_desc.n_coupled > 1)
+		ret = regulator_balance_voltage(rdev, PM_SUSPEND_ON);
+	else
+		ret = -EOPNOTSUPP;
+
+out:
+	regulator_unlock(rdev);
+	return ret;
+}
+
 /**
  * regulator_sync_voltage - re-apply last regulator output voltage
  * @regulator: regulator source
include/linux/regulator/driver.h +1 -0
index 4ea520c248e9..35e5a611db81 100644
@@ -540,6 +540,7 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
 int regulator_get_current_limit_regmap(struct regulator_dev *rdev);
 void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
 int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay);
+int regulator_sync_voltage_rdev(struct regulator_dev *rdev);
 
 /*
  * Helper functions intended to be used by regulator drivers prior registering
Signature · 1 line
2.30.2
#2 lore raw

PATCH 2/13 soc/tegra: regulators: Bump voltages on system reboot

In reply to Dmitry Osipenko

Ensure that SoC voltages are at a level suitable for a system reboot. This is important for some devices that use CPU reset method for the rebooting. SoC CPU and core voltages now are be restored to a level that is suitable for rebooting. This patch fixes hang on reboot on Asus Transformer TF101, it was also reported as fixing some of reboot issues on Toshiba AC100.

---
 drivers/soc/tegra/regulators-tegra20.c | 75 ++++++++++++++++++++++++-
 drivers/soc/tegra/regulators-tegra30.c | 78 +++++++++++++++++++++++++-
 2 files changed, 151 insertions(+), 2 deletions(-)
drivers/soc/tegra/regulators-tegra20.c +74 -1
index 367a71a3cd10..3479be5ee494 100644
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
+#include <linux/reboot.h>
 #include <linux/regulator/coupler.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
@@ -21,7 +22,10 @@ struct tegra_regulator_coupler {
 	struct regulator_dev *core_rdev;
 	struct regulator_dev *cpu_rdev;
 	struct regulator_dev *rtc_rdev;
-	int core_min_uV;
+	struct notifier_block reboot_notifier;
+	int core_min_uV, cpu_min_uV;
+	bool sys_reboot_mode_req;
+	bool sys_reboot_mode;
 };
 
 static inline struct tegra_regulator_coupler *
@@ -242,6 +246,10 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra,
 	if (cpu_uV < 0)
 		return cpu_uV;
 
+	/* store boot voltage level */
+	if (!tegra->cpu_min_uV)
+		tegra->cpu_min_uV = 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
@@ -250,6 +258,10 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra,
 	if (!cpu_min_uV_consumers)
 		cpu_min_uV = cpu_uV;
 
+	/* restore boot voltage level */
+	if (tegra->sys_reboot_mode)
+		cpu_min_uV = max(cpu_min_uV, tegra->cpu_min_uV);
+
 	if (cpu_min_uV > cpu_uV) {
 		err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
 					      cpu_uV, cpu_min_uV);
@@ -290,6 +302,8 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler,
 		return -EINVAL;
 	}
 
+	tegra->sys_reboot_mode = READ_ONCE(tegra->sys_reboot_mode_req);
+
 	if (rdev == cpu_rdev)
 		return tegra20_cpu_voltage_update(tegra, cpu_rdev,
 						  core_rdev, rtc_rdev);
@@ -303,6 +317,51 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler,
 	return -EPERM;
 }
 
+static int tegra20_regulator_prepare_reboot(struct tegra_regulator_coupler *tegra,
+					    bool sys_reboot_mode)
+{
+	int err;
+
+	if (!tegra->core_rdev || !tegra->rtc_rdev || !tegra->cpu_rdev)
+		return 0;
+
+	WRITE_ONCE(tegra->sys_reboot_mode_req, true);
+
+	/*
+	 * Some devices use CPU soft-reboot method and in this case we
+	 * should ensure that voltages are sane for the reboot by restoring
+	 * the minimum boot levels.
+	 */
+	err = regulator_sync_voltage_rdev(tegra->cpu_rdev);
+	if (err)
+		return err;
+
+	err = regulator_sync_voltage_rdev(tegra->core_rdev);
+	if (err)
+		return err;
+
+	WRITE_ONCE(tegra->sys_reboot_mode_req, sys_reboot_mode);
+
+	return 0;
+}
+
+static int tegra20_regulator_reboot(struct notifier_block *notifier,
+				    unsigned long event, void *cmd)
+{
+	struct tegra_regulator_coupler *tegra;
+	int ret;
+
+	if (event != SYS_RESTART)
+		return NOTIFY_DONE;
+
+	tegra = container_of(notifier, struct tegra_regulator_coupler,
+			     reboot_notifier);
+
+	ret = tegra20_regulator_prepare_reboot(tegra, true);
+
+	return notifier_from_errno(ret);
+}
+
 static int tegra20_regulator_attach(struct regulator_coupler *coupler,
 				    struct regulator_dev *rdev)
 {
@@ -335,6 +394,14 @@ static int tegra20_regulator_detach(struct regulator_coupler *coupler,
 {
 	struct tegra_regulator_coupler *tegra = to_tegra_coupler(coupler);
 
+	/*
+	 * We don't expect regulators to be decoupled during reboot,
+	 * this may race with the reboot handler and shouldn't ever
+	 * happen in practice.
+	 */
+	if (WARN_ON_ONCE(system_state > SYSTEM_RUNNING))
+		return -EPERM;
+
 	if (tegra->core_rdev == rdev) {
 		tegra->core_rdev = NULL;
 		return 0;
@@ -359,13 +426,19 @@ static struct tegra_regulator_coupler tegra20_coupler = {
 		.detach_regulator = tegra20_regulator_detach,
 		.balance_voltage = tegra20_regulator_balance_voltage,
 	},
+	.reboot_notifier.notifier_call = tegra20_regulator_reboot,
 };
 
 static int __init tegra_regulator_coupler_init(void)
 {
+	int err;
+
 	if (!of_machine_is_compatible("nvidia,tegra20"))
 		return 0;
 
+	err = register_reboot_notifier(&tegra20_coupler.reboot_notifier);
+	WARN_ON(err);
+
 	return regulator_coupler_register(&tegra20_coupler.coupler);
 }
 arch_initcall(tegra_regulator_coupler_init);
drivers/soc/tegra/regulators-tegra30.c +77 -1

130 lines not on this page · raw message

Signature · 1 line
2.30.2
#3 lore raw

PATCH 3/13 soc/tegra: Add stub for soc_is_tegra()

In reply to Dmitry Osipenko

Add stub required for compile-testing of drivers.

---
 include/soc/tegra/common.h | 9 +++++++++
 1 file changed, 9 insertions(+)
include/soc/tegra/common.h +9 -0
index 98027a76ce3d..744280ecab5f 100644
@@ -6,6 +6,15 @@
 #ifndef __SOC_TEGRA_COMMON_H__
 #define __SOC_TEGRA_COMMON_H__
 
+#include <linux/types.h>
+
+#ifdef CONFIG_ARCH_TEGRA
 bool soc_is_tegra(void);
+#else
+static inline bool soc_is_tegra(void)
+{
+	return false;
+}
+#endif
 
 #endif /* __SOC_TEGRA_COMMON_H__ */
Signature · 1 line
2.30.2
#4 lore raw

PATCH 4/13 soc/tegra: Add devm_tegra_core_dev_init_opp_table()

In reply to Dmitry Osipenko

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

---
 drivers/soc/tegra/common.c | 97 ++++++++++++++++++++++++++++++++++++++
 include/soc/tegra/common.h | 22 +++++++++
 2 files changed, 119 insertions(+)
drivers/soc/tegra/common.c +97 -0
index 3dc54f59cafe..cd33e99249c3 100644
@@ -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,93 @@ bool soc_is_tegra(void)
 
 	return match != NULL;
 }
+
+static int tegra_core_dev_init_opp_state(struct device *dev)
+{
+	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);
+	}
+
+	rate = clk_get_rate(clk);
+	if (!rate) {
+		dev_err(dev, "failed to get clk rate\n");
+		return -EINVAL;
+	}
+
+	/* first dummy rate-setting initializes voltage vote */
+	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, we will get
+	 * -ENODEV from devm_pm_opp_of_add_table() in this case.
+	 */
+	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);
include/soc/tegra/common.h +22 -0
index 744280ecab5f..af41ad80ec21 100644
@@ -6,15 +6,37 @@
 #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__ */
Signature · 1 line
2.30.2
#5 lore raw

PATCH 5/13 soc/tegra: fuse: Add stubs needed for compile-testing

In reply to Dmitry Osipenko

Add missing stubs that will allow Tegra memory driver to be compile-tested by kernel build bots.

---
 include/soc/tegra/fuse.h | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)
include/soc/tegra/fuse.h +17 -3
index 78cbc787a4dc..990701f788bc 100644
@@ -52,14 +52,28 @@ struct tegra_sku_info {
 	enum tegra_revision revision;
 };
 
+#ifdef CONFIG_ARCH_TEGRA
+extern struct tegra_sku_info tegra_sku_info;
 u32 tegra_read_straps(void);
 u32 tegra_read_ram_code(void);
 int tegra_fuse_readl(unsigned long offset, u32 *value);
-
-#ifdef CONFIG_ARCH_TEGRA
-extern struct tegra_sku_info tegra_sku_info;
 #else
 static struct tegra_sku_info tegra_sku_info __maybe_unused;
+
+static inline u32 tegra_read_straps(void)
+{
+	return 0;
+}
+
+static inline u32 tegra_read_ram_code(void)
+{
+	return 0;
+}
+
+static inline int tegra_fuse_readl(unsigned long offset, u32 *value)
+{
+	return -ENODEV;
+}
 #endif
 
 struct device *tegra_soc_device_register(void);
Signature · 1 line
2.30.2
#6 lore raw

PATCH 6/13 clk: tegra: Add stubs needed for compile-testing

In reply to Dmitry Osipenko

Add stubs needed for compile-testing of Tegra memory drivers.

---
 include/linux/clk/tegra.h | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)
include/linux/clk/tegra.h +24 -4
index f7ff722a03dd..d540b2879c26 100644
@@ -144,17 +144,37 @@ typedef long (tegra20_clk_emc_round_cb)(unsigned long rate,
 					unsigned long min_rate,
 					unsigned long max_rate,
 					void *arg);
+typedef int (tegra124_emc_prepare_timing_change_cb)(struct tegra_emc *emc,
+						    unsigned long rate);
+typedef void (tegra124_emc_complete_timing_change_cb)(struct tegra_emc *emc,
+						      unsigned long rate);
 
+#ifdef CONFIG_ARCH_TEGRA
 void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb,
 					void *cb_arg);
 int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same);
 
-typedef int (tegra124_emc_prepare_timing_change_cb)(struct tegra_emc *emc,
-						    unsigned long rate);
-typedef void (tegra124_emc_complete_timing_change_cb)(struct tegra_emc *emc,
-						      unsigned long rate);
 void tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb,
 				    tegra124_emc_complete_timing_change_cb *complete_cb);
+#else
+static inline void
+tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb,
+				   void *cb_arg)
+{
+}
+
+static inline int
+tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same)
+{
+	return 0;
+}
+
+static inline void
+tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb,
+			       tegra124_emc_complete_timing_change_cb *complete_cb)
+{
+}
+#endif
 
 struct tegra210_clk_emc_config {
 	unsigned long rate;
Signature · 1 line
2.30.2
#7 lore raw

PATCH 7/13 memory: tegra: Fix compilation warnings on 64bit platforms

In reply to Dmitry Osipenko

Fix compilation warning on 64bit platforms caused by implicit promotion of 32bit signed integer to a 64bit unsigned value which happens after enabling compile-testing of the EMC drivers.

---
 drivers/memory/tegra/tegra124-emc.c | 4 ++--
 drivers/memory/tegra/tegra30-emc.c  | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/memory/tegra/tegra124-emc.c +2 -2
index 5699d909abc2..a21ca8e0841a 100644
@@ -272,8 +272,8 @@
 #define EMC_PUTERM_ADJ				0x574
 
 #define DRAM_DEV_SEL_ALL			0
-#define DRAM_DEV_SEL_0				(2 << 30)
-#define DRAM_DEV_SEL_1				(1 << 30)
+#define DRAM_DEV_SEL_0				BIT(31)
+#define DRAM_DEV_SEL_1				BIT(30)
 
 #define EMC_CFG_POWER_FEATURES_MASK		\
 	(EMC_CFG_DYN_SREF | EMC_CFG_DRAM_ACPD | EMC_CFG_DRAM_CLKSTOP_SR | \
drivers/memory/tegra/tegra30-emc.c +2 -2
index 829f6d673c96..a2f2738ccb94 100644
@@ -150,8 +150,8 @@
 #define EMC_SELF_REF_CMD_ENABLED		BIT(0)
 
 #define DRAM_DEV_SEL_ALL			(0 << 30)
-#define DRAM_DEV_SEL_0				(2 << 30)
-#define DRAM_DEV_SEL_1				(1 << 30)
+#define DRAM_DEV_SEL_0				BIT(31)
+#define DRAM_DEV_SEL_1				BIT(30)
 #define DRAM_BROADCAST(num) \
 	((num) > 1 ? DRAM_DEV_SEL_ALL : DRAM_DEV_SEL_0)
 
Signature · 1 line
2.30.2
Reviewed-by on v1 7/13
#8 lore raw

Re: [PATCH v1 07/13] memory: tegra: Fix compilation warnings on 64bit platforms

Quoted 4 lines · Dmitry Osipenko

Fix compilation warning on 64bit platforms caused by implicit promotion of 32bit signed integer to a 64bit unsigned value which happens after enabling compile-testing of the EMC drivers.

Quoted 8 lines
---
 drivers/memory/tegra/tegra124-emc.c | 4 ++--
 drivers/memory/tegra/tegra30-emc.c  | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

Let me know if I should take the memory part.

Best regards,
Krzysztof

#9 lore raw

PATCH 8/13 memory: tegra: Enable compile testing for all drivers

In reply to Dmitry Osipenko

Enable compile testing for all Tegra memory drivers.

---
 drivers/memory/tegra/Kconfig | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/memory/tegra/Kconfig +10 -6
index a70967a56e52..c63ffa74ab94 100644
@@ -2,16 +2,18 @@
 config TEGRA_MC
 	bool "NVIDIA Tegra Memory Controller support"
 	default y
-	depends on ARCH_TEGRA
+	depends on ARCH_TEGRA || COMPILE_TEST
 	select INTERCONNECT
 	help
 	  This driver supports the Memory Controller (MC) hardware found on
 	  NVIDIA Tegra SoCs.
 
+if TEGRA_MC
+
 config TEGRA20_EMC
 	tristate "NVIDIA Tegra20 External Memory Controller driver"
 	default y
-	depends on TEGRA_MC && ARCH_TEGRA_2x_SOC
+	depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
 	select DEVFREQ_GOV_SIMPLE_ONDEMAND
 	select PM_DEVFREQ
 	help
@@ -23,7 +25,7 @@ config TEGRA20_EMC
 config TEGRA30_EMC
 	tristate "NVIDIA Tegra30 External Memory Controller driver"
 	default y
-	depends on TEGRA_MC && ARCH_TEGRA_3x_SOC
+	depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST
 	select PM_OPP
 	help
 	  This driver is for the External Memory Controller (EMC) found on
@@ -34,8 +36,8 @@ config TEGRA30_EMC
 config TEGRA124_EMC
 	tristate "NVIDIA Tegra124 External Memory Controller driver"
 	default y
-	depends on TEGRA_MC && ARCH_TEGRA_124_SOC
-	select TEGRA124_CLK_EMC
+	depends on ARCH_TEGRA_124_SOC || COMPILE_TEST
+	select TEGRA124_CLK_EMC if ARCH_TEGRA
 	select PM_OPP
 	help
 	  This driver is for the External Memory Controller (EMC) found on
@@ -49,10 +51,12 @@ config TEGRA210_EMC_TABLE
 
 config TEGRA210_EMC
 	tristate "NVIDIA Tegra210 External Memory Controller driver"
-	depends on TEGRA_MC && ARCH_TEGRA_210_SOC
+	depends on ARCH_TEGRA_210_SOC || COMPILE_TEST
 	select TEGRA210_EMC_TABLE
 	help
 	  This driver is for the External Memory Controller (EMC) found on
 	  Tegra210 chips. The EMC controls the external DRAM on the board.
 	  This driver is required to change memory timings / clock rate for
 	  external memory.
+
+endif
Signature · 1 line
2.30.2
#10 lore raw

Re: [PATCH v1 08/13] memory: tegra: Enable compile testing for all drivers

I love your patch! Yet something to improve:

Hi Dmitry,

I love your patch! Yet something to improve:

[auto build test ERROR on regulator/for-next]
[also build test ERROR on robh/for-next v5.13-rc2 next-20210521] [cannot apply to tegra/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Osipenko/NVIDIA-Tegra-memory-and-power-management-changes-for-5-14/20210522-190541
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next
config: arm-randconfig-r014-20210522 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/19cc71cefb806ede6b171f67bc4143b3f34a44b7
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Dmitry-Osipenko/NVIDIA-Tegra-memory-and-power-management-changes-for-5-14/20210522-190541 git checkout 19cc71cefb806ede6b171f67bc4143b3f34a44b7
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

kernel/softirq.o: in function `spawn_ksoftirqd':
softirq.c:(.init.text+0x14): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o softirq.c:(.init.text+0x34): relocation truncated to fit: R_ARM_PC24 against symbol __cpuhp_setup_state' defined in .text section in kernel/cpu.o softirq.c:(.init.text+0x3c): relocation truncated to fit: R_ARM_PC24 against symbol smpboot_register_percpu_thread' defined in .text section in kernel/smpboot.o softirq.c:(.init.text+0x58): relocation truncated to fit: R_ARM_PC24 against symbol ftrace_likely_update' defined in .text section in kernel/trace/trace_branch.o kernel/softirq.o: in function `softirq_init':
softirq.c:(.init.text+0xb0): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o kernel/softirq.o: in function early_irq_init':
softirq.c:(.init.text+0x100): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o kernel/softirq.o: in function arch_probe_nr_irqs':
softirq.c:(.init.text+0x11c): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o kernel/softirq.o: in function arch_early_irq_init':
softirq.c:(.init.text+0x138): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o init/main.o: in function set_reset_devices':
main.c:(.init.text+0x10): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o init/main.o: in function debug_kernel':
main.c:(.init.text+0x38): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o init/main.o: in function quiet_kernel':
main.c:(.init.text+0x64): additional relocation overflows omitted from the output
arm-linux-gnueabi-ld: drivers/memory/tegra/tegra20-emc.o: in function `tegra_emc_probe':
tegra20-emc.c:(.text+0x14f8): undefined reference to `clk_set_rate_range'
arm-linux-gnueabi-ld: drivers/memory/tegra/tegra30-emc.o: in function `tegra_emc_resume':

>> tegra30-emc.c:(.text+0xf8): undefined reference to `clk_rate_exclusive_put'
   arm-linux-gnueabi-ld: drivers/memory/tegra/tegra30-emc.o: in function `tegra_emc_suspend':
>> tegra30-emc.c:(.text+0x240): undefined reference to `clk_rate_exclusive_get'
   arm-linux-gnueabi-ld: drivers/memory/tegra/tegra30-emc.o: in function `tegra_emc_probe':
   tegra30-emc.c:(.text+0x2374): undefined reference to `clk_set_rate_range'
   arm-linux-gnueabi-ld: drivers/memory/tegra/tegra124-emc.o: in function `tegra_emc_probe':
>> tegra124-emc.c:(.text+0x12b0): undefined reference to `clk_set_rate_range'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#11 lore raw

Re: [PATCH v1 08/13] memory: tegra: Enable compile testing for all drivers

22.05.2021 19:39, kernel test robot пишет:

Quoted 52 lines

Hi Dmitry,

I love your patch! Yet something to improve:

[auto build test ERROR on regulator/for-next]
[also build test ERROR on robh/for-next v5.13-rc2 next-20210521] [cannot apply to tegra/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Osipenko/NVIDIA-Tegra-memory-and-power-management-changes-for-5-14/20210522-190541
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next
config: arm-randconfig-r014-20210522 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/19cc71cefb806ede6b171f67bc4143b3f34a44b7
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Dmitry-Osipenko/NVIDIA-Tegra-memory-and-power-management-changes-for-5-14/20210522-190541 git checkout 19cc71cefb806ede6b171f67bc4143b3f34a44b7
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

kernel/softirq.o: in function `spawn_ksoftirqd':
softirq.c:(.init.text+0x14): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o softirq.c:(.init.text+0x34): relocation truncated to fit: R_ARM_PC24 against symbol __cpuhp_setup_state' defined in .text section in kernel/cpu.o softirq.c:(.init.text+0x3c): relocation truncated to fit: R_ARM_PC24 against symbol smpboot_register_percpu_thread' defined in .text section in kernel/smpboot.o softirq.c:(.init.text+0x58): relocation truncated to fit: R_ARM_PC24 against symbol ftrace_likely_update' defined in .text section in kernel/trace/trace_branch.o kernel/softirq.o: in function `softirq_init':
softirq.c:(.init.text+0xb0): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o kernel/softirq.o: in function early_irq_init':
softirq.c:(.init.text+0x100): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o kernel/softirq.o: in function arch_probe_nr_irqs':
softirq.c:(.init.text+0x11c): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o kernel/softirq.o: in function arch_early_irq_init':
softirq.c:(.init.text+0x138): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o init/main.o: in function set_reset_devices':
main.c:(.init.text+0x10): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o init/main.o: in function debug_kernel':
main.c:(.init.text+0x38): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o init/main.o: in function quiet_kernel':
main.c:(.init.text+0x64): additional relocation overflows omitted from the output
arm-linux-gnueabi-ld: drivers/memory/tegra/tegra20-emc.o: in function `tegra_emc_probe':
tegra20-emc.c:(.text+0x14f8): undefined reference to `clk_set_rate_range'
arm-linux-gnueabi-ld: drivers/memory/tegra/tegra30-emc.o: in function `tegra_emc_resume':

Quoted 7 lines
Quoted 1 line
Quoted 1 line

tegra30-emc.c:(.text+0xf8): undefined reference to `clk_rate_exclusive_put'

arm-linux-gnueabi-ld: drivers/memory/tegra/tegra30-emc.o: in function `tegra_emc_suspend':

Quoted 1 line
Quoted 1 line

tegra30-emc.c:(.text+0x240): undefined reference to `clk_rate_exclusive_get'

arm-linux-gnueabi-ld: drivers/memory/tegra/tegra30-emc.o: in function `tegra_emc_probe':
tegra30-emc.c:(.text+0x2374): undefined reference to `clk_set_rate_range'
arm-linux-gnueabi-ld: drivers/memory/tegra/tegra124-emc.o: in function `tegra_emc_probe':

Quoted 1 line
Quoted 1 line

tegra124-emc.c:(.text+0x12b0): undefined reference to `clk_set_rate_range'

This missing clock symbols issue come over and over again for those ancient platforms that select CONFIG_HAVE_CLK, but not implement it fully. I think the best option will be to disable compile-testing for !HAVE_LEGACY_CLK, any objections?

#12 lore raw

Re: [PATCH v1 08/13] memory: tegra: Enable compile testing for all drivers

22.05.2021 20:12, Dmitry Osipenko пишет:

Quoted 59 lines

22.05.2021 19:39, kernel test robot пишет:

Quoted 58 lines

Hi Dmitry,

I love your patch! Yet something to improve:

[auto build test ERROR on regulator/for-next]
[also build test ERROR on robh/for-next v5.13-rc2 next-20210521] [cannot apply to tegra/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Osipenko/NVIDIA-Tegra-memory-and-power-management-changes-for-5-14/20210522-190541
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next
config: arm-randconfig-r014-20210522 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/19cc71cefb806ede6b171f67bc4143b3f34a44b7
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Dmitry-Osipenko/NVIDIA-Tegra-memory-and-power-management-changes-for-5-14/20210522-190541 git checkout 19cc71cefb806ede6b171f67bc4143b3f34a44b7
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

kernel/softirq.o: in function `spawn_ksoftirqd':
softirq.c:(.init.text+0x14): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o softirq.c:(.init.text+0x34): relocation truncated to fit: R_ARM_PC24 against symbol __cpuhp_setup_state' defined in .text section in kernel/cpu.o softirq.c:(.init.text+0x3c): relocation truncated to fit: R_ARM_PC24 against symbol smpboot_register_percpu_thread' defined in .text section in kernel/smpboot.o softirq.c:(.init.text+0x58): relocation truncated to fit: R_ARM_PC24 against symbol ftrace_likely_update' defined in .text section in kernel/trace/trace_branch.o kernel/softirq.o: in function `softirq_init':
softirq.c:(.init.text+0xb0): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o kernel/softirq.o: in function early_irq_init':
softirq.c:(.init.text+0x100): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o kernel/softirq.o: in function arch_probe_nr_irqs':
softirq.c:(.init.text+0x11c): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o kernel/softirq.o: in function arch_early_irq_init':
softirq.c:(.init.text+0x138): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o init/main.o: in function set_reset_devices':
main.c:(.init.text+0x10): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o init/main.o: in function debug_kernel':
main.c:(.init.text+0x38): relocation truncated to fit: R_ARM_PC24 against symbol __gnu_mcount_nc' defined in .text section in arch/arm/kernel/entry-ftrace.o init/main.o: in function quiet_kernel':
main.c:(.init.text+0x64): additional relocation overflows omitted from the output
arm-linux-gnueabi-ld: drivers/memory/tegra/tegra20-emc.o: in function `tegra_emc_probe':
tegra20-emc.c:(.text+0x14f8): undefined reference to `clk_set_rate_range'
arm-linux-gnueabi-ld: drivers/memory/tegra/tegra30-emc.o: in function `tegra_emc_resume':

Quoted 1 line
Quoted 1 line

tegra30-emc.c:(.text+0xf8): undefined reference to `clk_rate_exclusive_put'

arm-linux-gnueabi-ld: drivers/memory/tegra/tegra30-emc.o: in function `tegra_emc_suspend':

Quoted 1 line
Quoted 1 line

tegra30-emc.c:(.text+0x240): undefined reference to `clk_rate_exclusive_get'

arm-linux-gnueabi-ld: drivers/memory/tegra/tegra30-emc.o: in function `tegra_emc_probe':
tegra30-emc.c:(.text+0x2374): undefined reference to `clk_set_rate_range'
arm-linux-gnueabi-ld: drivers/memory/tegra/tegra124-emc.o: in function `tegra_emc_probe':

Quoted 7 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line

tegra124-emc.c:(.text+0x12b0): undefined reference to `clk_set_rate_range'

This missing clock symbols issue come over and over again for those ancient platforms that select CONFIG_HAVE_CLK, but not implement it fully. I think the best option will be to disable compile-testing for !HAVE_LEGACY_CLK, any objections?

init/Kconfig +1 -1
index 173a474012d7..42701b04be00 100644
@@ -131,7 +131,7 @@ config INIT_ENV_ARG_LIMIT
 
 config COMPILE_TEST
 	bool "Compile also drivers which will not load"
-	depends on HAS_IOMEM
+	depends on HAS_IOMEM && !HAVE_LEGACY_CLK
 	help
 	  Some drivers can be compiled on a different platform than they are
 	  intended to be run on. Despite they cannot be loaded there (or even
#13 lore raw

Re: [PATCH v1 08/13] memory: tegra: Enable compile testing for all drivers

In reply to Dmitry Osipenko
I love your patch! Yet something to improve:

Hi Dmitry,

I love your patch! Yet something to improve:

[auto build test ERROR on regulator/for-next]
[also build test ERROR on robh/for-next v5.13-rc2 next-20210521] [cannot apply to tegra/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Osipenko/NVIDIA-Tegra-memory-and-power-management-changes-for-5-14/20210522-190541
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next
config: nds32-randconfig-r005-20210522 (attached as .config)
compiler: nds32le-linux-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/19cc71cefb806ede6b171f67bc4143b3f34a44b7
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Dmitry-Osipenko/NVIDIA-Tegra-memory-and-power-management-changes-for-5-14/20210522-190541 git checkout 19cc71cefb806ede6b171f67bc4143b3f34a44b7
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=nds32

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

nds32le-linux-ld: drivers/memory/tegra/tegra210-emc-core.o: in function `tegra210_emc_remove':

>> tegra210-emc-core.c:(.text+0x11e): undefined reference to `tegra210_clk_emc_detach'
>> nds32le-linux-ld: tegra210-emc-core.c:(.text+0x122): undefined reference to `tegra210_clk_emc_detach'
   nds32le-linux-ld: drivers/memory/tegra/tegra210-emc-core.o: in function `tegra210_emc_probe':
>> tegra210-emc-core.c:(.text+0x5f6): undefined reference to `tegra210_clk_emc_attach'
>> nds32le-linux-ld: tegra210-emc-core.c:(.text+0x5fa): undefined reference to `tegra210_clk_emc_attach'
   nds32le-linux-ld: tegra210-emc-core.c:(.text+0x7a4): undefined reference to `tegra210_clk_emc_detach'
   nds32le-linux-ld: tegra210-emc-core.c:(.text+0x7a8): undefined reference to `tegra210_clk_emc_detach'
   nds32le-linux-ld: drivers/memory/tegra/tegra210-emc-core.o: in function `tegra210_emc_do_clock_change':
>> tegra210-emc-core.c:(.text+0xc8c): undefined reference to `tegra210_clk_emc_update_setting'
>> nds32le-linux-ld: tegra210-emc-core.c:(.text+0xc90): undefined reference to `tegra210_clk_emc_update_setting'
   nds32le-linux-ld: drivers/memory/tegra/tegra210-emc-core.o: in function `tegra210_emc_dll_prelock':
>> tegra210-emc-core.c:(.text+0x13dc): undefined reference to `tegra210_clk_emc_dll_update_setting'
>> nds32le-linux-ld: tegra210-emc-core.c:(.text+0x13e0): undefined reference to `tegra210_clk_emc_dll_update_setting'
>> nds32le-linux-ld: tegra210-emc-core.c:(.text+0x13f4): undefined reference to `tegra210_clk_emc_dll_enable'

nds32le-linux-ld: tegra210-emc-core.c:(.text+0x13f8): undefined reference to `tegra210_clk_emc_dll_enable'

Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for TEGRA210_EMC_TABLE Depends on MEMORY && TEGRA_MC && ARCH_TEGRA_210_SOC
Selected by
- TEGRA210_EMC && MEMORY && TEGRA_MC && (ARCH_TEGRA_210_SOC || COMPILE_TEST

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#14 lore raw

PATCH 9/13 memory: tegra20-emc: Use devm_tegra_core_dev_init_opp_table()

In reply to Dmitry Osipenko

Use common devm_tegra_core_dev_init_opp_table() helper for the OPP table initialization.

---
 drivers/memory/tegra/tegra20-emc.c | 48 +++---------------------------
 1 file changed, 4 insertions(+), 44 deletions(-)
drivers/memory/tegra/tegra20-emc.c +4 -44
index da8a0da8da79..a534197a5fb2 100644
@@ -908,49 +908,6 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
 	return err;
 }
 
-static int tegra_emc_opp_table_init(struct tegra_emc *emc)
-{
-	u32 hw_version = BIT(tegra_sku_info.soc_process_id);
-	struct opp_table *hw_opp_table;
-	int err;
-
-	hw_opp_table = dev_pm_opp_set_supported_hw(emc->dev, &hw_version, 1);
-	err = PTR_ERR_OR_ZERO(hw_opp_table);
-	if (err) {
-		dev_err(emc->dev, "failed to set OPP supported HW: %d\n", err);
-		return err;
-	}
-
-	err = dev_pm_opp_of_add_table(emc->dev);
-	if (err) {
-		if (err == -ENODEV)
-			dev_err(emc->dev, "OPP table not found, please update your device tree\n");
-		else
-			dev_err(emc->dev, "failed to add OPP table: %d\n", err);
-
-		goto put_hw_table;
-	}
-
-	dev_info_once(emc->dev, "OPP HW ver. 0x%x, current clock rate %lu MHz\n",
-		      hw_version, clk_get_rate(emc->clk) / 1000000);
-
-	/* first dummy rate-set initializes voltage state */
-	err = dev_pm_opp_set_rate(emc->dev, clk_get_rate(emc->clk));
-	if (err) {
-		dev_err(emc->dev, "failed to initialize OPP clock: %d\n", err);
-		goto remove_table;
-	}
-
-	return 0;
-
-remove_table:
-	dev_pm_opp_of_remove_table(emc->dev);
-put_hw_table:
-	dev_pm_opp_put_supported_hw(hw_opp_table);
-
-	return err;
-}
-
 static void devm_tegra_emc_unset_callback(void *data)
 {
 	tegra20_clk_set_emc_round_callback(NULL, NULL);
@@ -1077,6 +1034,7 @@ static int tegra_emc_devfreq_init(struct tegra_emc *emc)
 
 static int tegra_emc_probe(struct platform_device *pdev)
 {
+	struct tegra_core_opp_params opp_params = {};
 	struct device_node *np;
 	struct tegra_emc *emc;
 	int irq, err;
@@ -1122,7 +1080,9 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
-	err = tegra_emc_opp_table_init(emc);
+	opp_params.init_state = true;
+
+	err = devm_tegra_core_dev_init_opp_table(&pdev->dev, &opp_params);
 	if (err)
 		return err;
 
Signature · 1 line
2.30.2
Reviewed-by on v1 9/13
#15 lore raw

Re: [PATCH v1 09/13] memory: tegra20-emc: Use devm_tegra_core_dev_init_opp_table()

Quoted 10 lines · Dmitry Osipenko

Use common devm_tegra_core_dev_init_opp_table() helper for the OPP table initialization.

---
 drivers/memory/tegra/tegra20-emc.c | 48 +++---------------------------
 1 file changed, 4 insertions(+), 44 deletions(-)

Best regards,
Krzysztof

#16 lore raw

PATCH 10/13 memory: tegra30-emc: Use devm_tegra_core_dev_init_opp_table()

In reply to Dmitry Osipenko

Use common devm_tegra_core_dev_init_opp_table() helper for the OPP table initialization.

---
 drivers/memory/tegra/tegra30-emc.c | 48 +++---------------------------
 1 file changed, 4 insertions(+), 44 deletions(-)
drivers/memory/tegra/tegra30-emc.c +4 -44
index a2f2738ccb94..63e1983f8a0d 100644
@@ -1480,49 +1480,6 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc)
 	return err;
 }
 
-static int tegra_emc_opp_table_init(struct tegra_emc *emc)
-{
-	u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
-	struct opp_table *hw_opp_table;
-	int err;
-
-	hw_opp_table = dev_pm_opp_set_supported_hw(emc->dev, &hw_version, 1);
-	err = PTR_ERR_OR_ZERO(hw_opp_table);
-	if (err) {
-		dev_err(emc->dev, "failed to set OPP supported HW: %d\n", err);
-		return err;
-	}
-
-	err = dev_pm_opp_of_add_table(emc->dev);
-	if (err) {
-		if (err == -ENODEV)
-			dev_err(emc->dev, "OPP table not found, please update your device tree\n");
-		else
-			dev_err(emc->dev, "failed to add OPP table: %d\n", err);
-
-		goto put_hw_table;
-	}
-
-	dev_info_once(emc->dev, "OPP HW ver. 0x%x, current clock rate %lu MHz\n",
-		      hw_version, clk_get_rate(emc->clk) / 1000000);
-
-	/* first dummy rate-set initializes voltage state */
-	err = dev_pm_opp_set_rate(emc->dev, clk_get_rate(emc->clk));
-	if (err) {
-		dev_err(emc->dev, "failed to initialize OPP clock: %d\n", err);
-		goto remove_table;
-	}
-
-	return 0;
-
-remove_table:
-	dev_pm_opp_of_remove_table(emc->dev);
-put_hw_table:
-	dev_pm_opp_put_supported_hw(hw_opp_table);
-
-	return err;
-}
-
 static void devm_tegra_emc_unset_callback(void *data)
 {
 	tegra20_clk_set_emc_round_callback(NULL, NULL);
@@ -1568,6 +1525,7 @@ static int tegra_emc_init_clk(struct tegra_emc *emc)
 
 static int tegra_emc_probe(struct platform_device *pdev)
 {
+	struct tegra_core_opp_params opp_params = {};
 	struct device_node *np;
 	struct tegra_emc *emc;
 	int err;
@@ -1617,7 +1575,9 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
-	err = tegra_emc_opp_table_init(emc);
+	opp_params.init_state = true;
+
+	err = devm_tegra_core_dev_init_opp_table(&pdev->dev, &opp_params);
 	if (err)
 		return err;
 
Signature · 1 line
2.30.2
Reviewed-by on v1 10/13
#17 lore raw

Re: [PATCH v1 10/13] memory: tegra30-emc: Use devm_tegra_core_dev_init_opp_table()

Quoted 10 lines · Dmitry Osipenko

Use common devm_tegra_core_dev_init_opp_table() helper for the OPP table initialization.

---
 drivers/memory/tegra/tegra30-emc.c | 48 +++---------------------------
 1 file changed, 4 insertions(+), 44 deletions(-)

Best regards,
Krzysztof

#18 lore raw

PATCH 11/13 dt-bindings: soc: tegra-pmc: Document core power domain

In reply to Dmitry Osipenko

All NVIDIA Tegra SoCs have a core power domain where majority of hardware blocks reside. Document the new core power domain properties.

---
 .../arm/tegra/nvidia,tegra20-pmc.yaml         | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.yaml +35 -0
index 43fd2f8927d0..0afec83cc723 100644
@@ -301,6 +301,33 @@ patternProperties:
 
     additionalProperties: false
 
+  core-domain:
+    type: object
+    description: |
+      The vast majority of hardware blocks of Tegra SoC belong to a
+      Core power domain, which has a dedicated voltage rail that powers
+      the blocks.
+
+    properties:
+      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
+
+    required:
+      - operating-points-v2
+      - "#power-domain-cells"
+
+    additionalProperties: false
+
+  core-supply:
+    description:
+      Phandle to voltage regulator connected to the SoC Core power rail.
+
 required:
   - compatible
   - reg
@@ -325,6 +352,7 @@ examples:
     tegra_pmc: pmc@7000e400 {
               compatible = "nvidia,tegra210-pmc";
               reg = <0x7000e400 0x400>;
+              core-supply = <&regulator>;
               clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
               clock-names = "pclk", "clk32k_in";
               #clock-cells = <1>;
@@ -338,17 +366,24 @@ examples:
               nvidia,core-power-req-active-high;
               nvidia,sys-clock-req-active-high;
 
+              pd_core: core-domain {
+                      operating-points-v2 = <&core_opp_table>;
+                      #power-domain-cells = <0>;
+              };
+
               powergates {
                     pd_audio: aud {
                             clocks = <&tegra_car TEGRA210_CLK_APE>,
                                      <&tegra_car TEGRA210_CLK_APB2APE>;
                             resets = <&tegra_car 198>;
+                            power-domains = <&pd_core>;
                             #power-domain-cells = <0>;
                     };
 
                     pd_xusbss: xusba {
                             clocks = <&tegra_car TEGRA210_CLK_XUSB_SS>;
                             resets = <&tegra_car TEGRA210_CLK_XUSB_SS>;
+                            power-domains = <&pd_core>;
                             #power-domain-cells = <0>;
                     };
               };
Signature · 1 line
2.30.2
#19 lore raw

PATCH 12/13 soc/tegra: pmc: Add core power domain

In reply to Dmitry Osipenko

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 level which satisfies all devices within the power domain. Add support for the core power domain which controls voltage state of the domain. This allows us to support system-wide DVFS on Tegra20-210 SoCs. The PMC powergate domains now are sub-domains of the core domain, this requires device-tree updating, older DTBs are unaffected.

---
 drivers/soc/tegra/Kconfig  |  14 ++++
 drivers/soc/tegra/pmc.c    | 143 +++++++++++++++++++++++++++++++++++++
 include/soc/tegra/common.h |   7 ++
 3 files changed, 164 insertions(+)
drivers/soc/tegra/Kconfig +14 -0
index 976dee036470..7057254604ee 100644
@@ -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,11 @@ config ARCH_TEGRA_234_SOC
 endif
 endif
 
+config SOC_TEGRA_COMMON
+	bool
+	select PM_OPP
+	select PM_GENERIC_DOMAINS
+
 config SOC_TEGRA_FUSE
 	def_bool y
 	depends on ARCH_TEGRA
drivers/soc/tegra/pmc.c +143 -0

191 lines not on this page · raw message

include/soc/tegra/common.h +7 -0
index af41ad80ec21..135a6956a18c 100644
@@ -23,6 +23,8 @@ 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
@@ -31,6 +33,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)
Signature · 1 line
2.30.2
#20 lore raw

PATCH 13/13 soc/tegra: regulators: Support core domain state syncing

In reply to Dmitry Osipenko

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.

---
 drivers/soc/tegra/regulators-tegra20.c | 19 ++++++++++++++++++-
 drivers/soc/tegra/regulators-tegra30.c | 18 +++++++++++++++++-
 2 files changed, 35 insertions(+), 2 deletions(-)
drivers/soc/tegra/regulators-tegra20.c +18 -1
index 3479be5ee494..81787ae3d03e 100644
@@ -17,6 +17,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;
@@ -42,6 +44,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() && !tegra->sys_reboot_mode) {
+		pr_info_once("voltage state synced\n");
+		return 0;
+	}
+
 	if (tegra->core_min_uV > 0)
 		return tegra->core_min_uV;
 
@@ -62,7 +79,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;
 }
drivers/soc/tegra/regulators-tegra30.c +17 -1
index 6e4f3d9e7be1..e0203f78b396 100644
@@ -17,6 +17,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 {
@@ -43,6 +44,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() && !tegra->sys_reboot_mode) {
+		pr_info_once("voltage state synced\n");
+		return 0;
+	}
+
 	if (tegra->core_min_uV > 0)
 		return tegra->core_min_uV;
 
@@ -63,7 +79,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;
 }
Signature · 1 line
2.30.2