All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/5] Tegra PMC driver fixes and improvements
@ 2021-03-02 12:24 Dmitry Osipenko
  2021-03-02 12:24 ` [PATCH v4 1/5] soc/tegra: pmc: Fix imbalanced clock disabling in error code path Dmitry Osipenko
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Dmitry Osipenko @ 2021-03-02 12:24 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter Geis, Matt Merhar
  Cc: linux-tegra, linux-kernel

Hi,

This is a continuation of [1]. I decided to factor out PMC patches into a
separate series to ease reviewing and applying of the patches. This series
is a prerequisite for enabling dynamic power management by Tegra drivers
that are using PMC domain.

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

Changelog:

v4: - Dropped "Link power domains to the parent Core domain" patch,
      moving it to the series which adds driver for the Core domain.

    - Added new minor patch "Rate-limit error message about failed to
      acquire of reset".

v3: - Added new patch "pmc: Fix completion of power-gate toggling",
      which fixes toggling power state of PMC domains.

Dmitry Osipenko (5):
  soc/tegra: pmc: Fix imbalanced clock disabling in error code path
  soc/tegra: pmc: Fix completion of power-gate toggling
  soc/tegra: pmc: Ensure that clock rates aren't too high
  soc/tegra: pmc: Print out domain name when reset fails to acquire
  soc/tegra: pmc: Rate-limit error message about failed to acquire of
    reset

 drivers/soc/tegra/pmc.c | 165 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 157 insertions(+), 8 deletions(-)

-- 
2.29.2


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

* [PATCH v4 1/5] soc/tegra: pmc: Fix imbalanced clock disabling in error code path
  2021-03-02 12:24 [PATCH v4 0/5] Tegra PMC driver fixes and improvements Dmitry Osipenko
@ 2021-03-02 12:24 ` Dmitry Osipenko
  2021-03-25 14:27   ` Thierry Reding
  2021-03-02 12:24 ` [PATCH v4 2/5] soc/tegra: pmc: Fix completion of power-gate toggling Dmitry Osipenko
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Dmitry Osipenko @ 2021-03-02 12:24 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter Geis, Matt Merhar
  Cc: linux-tegra, linux-kernel

The tegra_powergate_power_up() has a typo in the error code path where it
will try to disable clocks twice, fix it. In practice that error never
happens, so this is a minor correction.

Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
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 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index df9a5ca8c99c..fd2ba3c59178 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -638,7 +638,7 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg,
 
 	err = tegra_powergate_enable_clocks(pg);
 	if (err)
-		goto disable_clks;
+		goto powergate_off;
 
 	usleep_range(10, 20);
 
-- 
2.29.2


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

* [PATCH v4 2/5] soc/tegra: pmc: Fix completion of power-gate toggling
  2021-03-02 12:24 [PATCH v4 0/5] Tegra PMC driver fixes and improvements Dmitry Osipenko
  2021-03-02 12:24 ` [PATCH v4 1/5] soc/tegra: pmc: Fix imbalanced clock disabling in error code path Dmitry Osipenko
@ 2021-03-02 12:24 ` Dmitry Osipenko
  2021-03-25 14:32   ` Thierry Reding
  2021-03-02 12:25 ` [PATCH v4 3/5] soc/tegra: pmc: Ensure that clock rates aren't too high Dmitry Osipenko
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Dmitry Osipenko @ 2021-03-02 12:24 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter Geis, Matt Merhar
  Cc: linux-tegra, linux-kernel

The SW-initiated power gate toggling is dropped by PMC if there is
contention with a HW-initiated toggling, i.e. when one of CPU cores is
gated by cpuidle driver. Software should retry the toggling after 10
microseconds on Tegra20/30 SoCs, hence add the retrying. On Tegra114+ the
toggling method was changed in hardware, the TOGGLE_START bit indicates
whether PMC is busy or could accept the command to toggle, hence handle
that bit properly.

The problem pops up after enabling dynamic power gating of 3d hardware,
where 3d power domain fails to turn on/off "randomly".

The programming sequence and quirks are documented in TRMs, but PMC
driver obliviously re-used the Tegra20 logic for Tegra30+, which strikes
back now. The 10 microseconds and other timeouts aren't documented in TRM,
they are taken from downstream kernel.

Link: https://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=commit;h=311dd1c318b70e93bcefec15456a10ff2b9eb0ff
Link: https://nv-tegra.nvidia.com/gitweb/?p=linux-3.10.git;a=commit;h=7f36693c47cb23730a6b2822e0975be65fb0c51d
Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
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 | 70 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 65 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index fd2ba3c59178..f970b615ee27 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -317,6 +317,8 @@ struct tegra_pmc_soc {
 				   bool invert);
 	int (*irq_set_wake)(struct irq_data *data, unsigned int on);
 	int (*irq_set_type)(struct irq_data *data, unsigned int type);
+	int (*powergate_set)(struct tegra_pmc *pmc, unsigned int id,
+			     bool new_state);
 
 	const char * const *reset_sources;
 	unsigned int num_reset_sources;
@@ -517,6 +519,63 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name)
 	return -ENODEV;
 }
 
+static int tegra20_powergate_set(struct tegra_pmc *pmc, unsigned int id,
+				 bool new_state)
+{
+	unsigned int retries = 100;
+	bool status;
+	int ret;
+
+	/*
+	 * As per TRM documentation, the toggle command will be dropped by PMC
+	 * if there is contention with a HW-initiated toggling (i.e. CPU core
+	 * power-gated), the command should be retried in that case.
+	 */
+	do {
+		tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
+
+		/* wait for PMC to execute the command */
+		ret = readx_poll_timeout(tegra_powergate_state, id, status,
+					 status == new_state, 1, 10);
+	} while (ret == -ETIMEDOUT && retries--);
+
+	return ret;
+}
+
+static inline bool tegra_powergate_toggle_ready(struct tegra_pmc *pmc)
+{
+	return !(tegra_pmc_readl(pmc, PWRGATE_TOGGLE) & PWRGATE_TOGGLE_START);
+}
+
+static int tegra114_powergate_set(struct tegra_pmc *pmc, unsigned int id,
+				  bool new_state)
+{
+	bool status;
+	int err;
+
+	/* wait while PMC power gating is contented */
+	err = readx_poll_timeout(tegra_powergate_toggle_ready, pmc, status,
+				 status == true, 1, 100);
+	if (err)
+		return err;
+
+	tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
+
+	/* wait for PMC to accept the command */
+	err = readx_poll_timeout(tegra_powergate_toggle_ready, pmc, status,
+				 status == true, 1, 100);
+	if (err)
+		return err;
+
+	/* wait for PMC to execute the command */
+	err = readx_poll_timeout(tegra_powergate_state, id, status,
+				 status == new_state, 10, 100000);
+	if (err)
+		return err;
+
+	return 0;
+}
+
 /**
  * tegra_powergate_set() - set the state of a partition
  * @pmc: power management controller
@@ -526,7 +585,6 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name)
 static int tegra_powergate_set(struct tegra_pmc *pmc, unsigned int id,
 			       bool new_state)
 {
-	bool status;
 	int err;
 
 	if (id == TEGRA_POWERGATE_3D && pmc->soc->has_gpu_clamps)
@@ -539,10 +597,7 @@ static int tegra_powergate_set(struct tegra_pmc *pmc, unsigned int id,
 		return 0;
 	}
 
-	tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
-
-	err = readx_poll_timeout(tegra_powergate_state, id, status,
-				 status == new_state, 10, 100000);
+	err = pmc->soc->powergate_set(pmc, id, new_state);
 
 	mutex_unlock(&pmc->powergates_lock);
 
@@ -2699,6 +2754,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
 	.regs = &tegra20_pmc_regs,
 	.init = tegra20_pmc_init,
 	.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+	.powergate_set = tegra20_powergate_set,
 	.reset_sources = NULL,
 	.num_reset_sources = 0,
 	.reset_levels = NULL,
@@ -2757,6 +2813,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
 	.regs = &tegra20_pmc_regs,
 	.init = tegra20_pmc_init,
 	.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+	.powergate_set = tegra20_powergate_set,
 	.reset_sources = tegra30_reset_sources,
 	.num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
 	.reset_levels = NULL,
@@ -2811,6 +2868,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
 	.regs = &tegra20_pmc_regs,
 	.init = tegra20_pmc_init,
 	.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+	.powergate_set = tegra114_powergate_set,
 	.reset_sources = tegra30_reset_sources,
 	.num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
 	.reset_levels = NULL,
@@ -2925,6 +2983,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
 	.regs = &tegra20_pmc_regs,
 	.init = tegra20_pmc_init,
 	.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+	.powergate_set = tegra114_powergate_set,
 	.reset_sources = tegra30_reset_sources,
 	.num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
 	.reset_levels = NULL,
@@ -3048,6 +3107,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
 	.regs = &tegra20_pmc_regs,
 	.init = tegra20_pmc_init,
 	.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
+	.powergate_set = tegra114_powergate_set,
 	.irq_set_wake = tegra210_pmc_irq_set_wake,
 	.irq_set_type = tegra210_pmc_irq_set_type,
 	.reset_sources = tegra210_reset_sources,
-- 
2.29.2


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

* [PATCH v4 3/5] soc/tegra: pmc: Ensure that clock rates aren't too high
  2021-03-02 12:24 [PATCH v4 0/5] Tegra PMC driver fixes and improvements Dmitry Osipenko
  2021-03-02 12:24 ` [PATCH v4 1/5] soc/tegra: pmc: Fix imbalanced clock disabling in error code path Dmitry Osipenko
  2021-03-02 12:24 ` [PATCH v4 2/5] soc/tegra: pmc: Fix completion of power-gate toggling Dmitry Osipenko
@ 2021-03-02 12:25 ` Dmitry Osipenko
  2021-03-25 14:39   ` Thierry Reding
  2021-03-02 12:25 ` [PATCH v4 4/5] soc/tegra: pmc: Print out domain name when reset fails to acquire Dmitry Osipenko
  2021-03-02 12:25 ` [PATCH v4 5/5] soc/tegra: pmc: Rate-limit error message about failed to acquire of reset Dmitry Osipenko
  4 siblings, 1 reply; 14+ messages in thread
From: Dmitry Osipenko @ 2021-03-02 12:25 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter Geis, Matt Merhar
  Cc: linux-tegra, linux-kernel

Switch all clocks of a power domain to a safe rate which is suitable
for all possible voltages in order to ensure that hardware constraints
aren't violated when power domain state toggles.

Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
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 | 92 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 90 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index f970b615ee27..a87645fac735 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -237,6 +237,7 @@ struct tegra_powergate {
 	unsigned int id;
 	struct clk **clks;
 	unsigned int num_clks;
+	unsigned long *clk_rates;
 	struct reset_control *reset;
 };
 
@@ -641,6 +642,57 @@ static int __tegra_powergate_remove_clamping(struct tegra_pmc *pmc,
 	return 0;
 }
 
+static int tegra_powergate_prepare_clocks(struct tegra_powergate *pg)
+{
+	unsigned long safe_rate = 100 * 1000 * 1000;
+	unsigned int i;
+	int err;
+
+	for (i = 0; i < pg->num_clks; i++) {
+		pg->clk_rates[i] = clk_get_rate(pg->clks[i]);
+
+		if (!pg->clk_rates[i]) {
+			err = -EINVAL;
+			goto out;
+		}
+
+		if (pg->clk_rates[i] <= safe_rate)
+			continue;
+
+		/*
+		 * We don't know whether voltage state is okay for the
+		 * current clock rate, hence it's better to temporally
+		 * switch clock to a safe rate which is suitable for
+		 * all voltages, before enabling the clock.
+		 */
+		err = clk_set_rate(pg->clks[i], safe_rate);
+		if (err)
+			goto out;
+	}
+
+	return 0;
+
+out:
+	while (i--)
+		clk_set_rate(pg->clks[i], pg->clk_rates[i]);
+
+	return err;
+}
+
+static int tegra_powergate_unprepare_clocks(struct tegra_powergate *pg)
+{
+	unsigned int i;
+	int err;
+
+	for (i = 0; i < pg->num_clks; i++) {
+		err = clk_set_rate(pg->clks[i], pg->clk_rates[i]);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 static void tegra_powergate_disable_clocks(struct tegra_powergate *pg)
 {
 	unsigned int i;
@@ -691,10 +743,14 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg,
 
 	usleep_range(10, 20);
 
-	err = tegra_powergate_enable_clocks(pg);
+	err = tegra_powergate_prepare_clocks(pg);
 	if (err)
 		goto powergate_off;
 
+	err = tegra_powergate_enable_clocks(pg);
+	if (err)
+		goto unprepare_clks;
+
 	usleep_range(10, 20);
 
 	err = __tegra_powergate_remove_clamping(pg->pmc, pg->id);
@@ -717,12 +773,19 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg,
 	if (disable_clocks)
 		tegra_powergate_disable_clocks(pg);
 
+	err = tegra_powergate_unprepare_clocks(pg);
+	if (err)
+		return err;
+
 	return 0;
 
 disable_clks:
 	tegra_powergate_disable_clocks(pg);
 	usleep_range(10, 20);
 
+unprepare_clks:
+	tegra_powergate_unprepare_clocks(pg);
+
 powergate_off:
 	tegra_powergate_set(pg->pmc, pg->id, false);
 
@@ -733,10 +796,14 @@ static int tegra_powergate_power_down(struct tegra_powergate *pg)
 {
 	int err;
 
-	err = tegra_powergate_enable_clocks(pg);
+	err = tegra_powergate_prepare_clocks(pg);
 	if (err)
 		return err;
 
+	err = tegra_powergate_enable_clocks(pg);
+	if (err)
+		goto unprepare_clks;
+
 	usleep_range(10, 20);
 
 	err = reset_control_assert(pg->reset);
@@ -753,6 +820,10 @@ static int tegra_powergate_power_down(struct tegra_powergate *pg)
 	if (err)
 		goto assert_resets;
 
+	err = tegra_powergate_unprepare_clocks(pg);
+	if (err)
+		return err;
+
 	return 0;
 
 assert_resets:
@@ -764,6 +835,9 @@ static int tegra_powergate_power_down(struct tegra_powergate *pg)
 disable_clks:
 	tegra_powergate_disable_clocks(pg);
 
+unprepare_clks:
+	tegra_powergate_unprepare_clocks(pg);
+
 	return err;
 }
 
@@ -881,6 +955,12 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
 	if (!pg)
 		return -ENOMEM;
 
+	pg->clk_rates = kzalloc(sizeof(*pg->clk_rates), GFP_KERNEL);
+	if (!pg->clk_rates) {
+		kfree(pg->clks);
+		return -ENOMEM;
+	}
+
 	pg->id = id;
 	pg->clks = &clk;
 	pg->num_clks = 1;
@@ -892,6 +972,7 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
 		dev_err(pmc->dev, "failed to turn on partition %d: %d\n", id,
 			err);
 
+	kfree(pg->clk_rates);
 	kfree(pg);
 
 	return err;
@@ -1042,6 +1123,12 @@ static int tegra_powergate_of_get_clks(struct tegra_powergate *pg,
 	if (!pg->clks)
 		return -ENOMEM;
 
+	pg->clk_rates = kcalloc(count, sizeof(*pg->clk_rates), GFP_KERNEL);
+	if (!pg->clk_rates) {
+		kfree(pg->clks);
+		return -ENOMEM;
+	}
+
 	for (i = 0; i < count; i++) {
 		pg->clks[i] = of_clk_get(np, i);
 		if (IS_ERR(pg->clks[i])) {
@@ -1058,6 +1145,7 @@ static int tegra_powergate_of_get_clks(struct tegra_powergate *pg,
 	while (i--)
 		clk_put(pg->clks[i]);
 
+	kfree(pg->clk_rates);
 	kfree(pg->clks);
 
 	return err;
-- 
2.29.2


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

* [PATCH v4 4/5] soc/tegra: pmc: Print out domain name when reset fails to acquire
  2021-03-02 12:24 [PATCH v4 0/5] Tegra PMC driver fixes and improvements Dmitry Osipenko
                   ` (2 preceding siblings ...)
  2021-03-02 12:25 ` [PATCH v4 3/5] soc/tegra: pmc: Ensure that clock rates aren't too high Dmitry Osipenko
@ 2021-03-02 12:25 ` Dmitry Osipenko
  2021-03-25 14:40   ` Thierry Reding
  2021-03-02 12:25 ` [PATCH v4 5/5] soc/tegra: pmc: Rate-limit error message about failed to acquire of reset Dmitry Osipenko
  4 siblings, 1 reply; 14+ messages in thread
From: Dmitry Osipenko @ 2021-03-02 12:25 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter Geis, Matt Merhar
  Cc: linux-tegra, linux-kernel

Print out domain name when reset fails to acquire for debugging purposes
and to make formatting of GENPD errors consistent in the driver.

Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
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 | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index a87645fac735..bf29ea22480a 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -868,7 +868,8 @@ static int tegra_genpd_power_off(struct generic_pm_domain *domain)
 
 	err = reset_control_acquire(pg->reset);
 	if (err < 0) {
-		pr_err("failed to acquire resets: %d\n", err);
+		dev_err(dev, "failed to acquire resets for PM domain %s: %d\n",
+			pg->genpd.name, err);
 		return err;
 	}
 
-- 
2.29.2


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

* [PATCH v4 5/5] soc/tegra: pmc: Rate-limit error message about failed to acquire of reset
  2021-03-02 12:24 [PATCH v4 0/5] Tegra PMC driver fixes and improvements Dmitry Osipenko
                   ` (3 preceding siblings ...)
  2021-03-02 12:25 ` [PATCH v4 4/5] soc/tegra: pmc: Print out domain name when reset fails to acquire Dmitry Osipenko
@ 2021-03-02 12:25 ` Dmitry Osipenko
  2021-03-25 14:42   ` Thierry Reding
  4 siblings, 1 reply; 14+ messages in thread
From: Dmitry Osipenko @ 2021-03-02 12:25 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Peter Geis, Matt Merhar
  Cc: linux-tegra, linux-kernel

PMC domain could be easily bombarded with the enable requests if there is
a problem in regards to acquiring reset control of a domain and kernel
log will be flooded with the error message in this case. Hence rate-limit
the message in order to prevent missing other important messages.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/soc/tegra/pmc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index bf29ea22480a..84ab27d85d92 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -868,8 +868,8 @@ static int tegra_genpd_power_off(struct generic_pm_domain *domain)
 
 	err = reset_control_acquire(pg->reset);
 	if (err < 0) {
-		dev_err(dev, "failed to acquire resets for PM domain %s: %d\n",
-			pg->genpd.name, err);
+		dev_err_ratelimited(dev, "failed to acquire resets for PM domain %s: %d\n",
+				    pg->genpd.name, err);
 		return err;
 	}
 
-- 
2.29.2


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

* Re: [PATCH v4 1/5] soc/tegra: pmc: Fix imbalanced clock disabling in error code path
  2021-03-02 12:24 ` [PATCH v4 1/5] soc/tegra: pmc: Fix imbalanced clock disabling in error code path Dmitry Osipenko
@ 2021-03-25 14:27   ` Thierry Reding
  0 siblings, 0 replies; 14+ messages in thread
From: Thierry Reding @ 2021-03-25 14:27 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Peter Geis, Matt Merhar, linux-tegra, linux-kernel

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

On Tue, Mar 02, 2021 at 03:24:58PM +0300, Dmitry Osipenko wrote:
> The tegra_powergate_power_up() has a typo in the error code path where it
> will try to disable clocks twice, fix it. In practice that error never
> happens, so this is a minor correction.
> 
> Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
> 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 | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied, thanks.

Thierry

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

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

* Re: [PATCH v4 2/5] soc/tegra: pmc: Fix completion of power-gate toggling
  2021-03-02 12:24 ` [PATCH v4 2/5] soc/tegra: pmc: Fix completion of power-gate toggling Dmitry Osipenko
@ 2021-03-25 14:32   ` Thierry Reding
  0 siblings, 0 replies; 14+ messages in thread
From: Thierry Reding @ 2021-03-25 14:32 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Peter Geis, Matt Merhar, linux-tegra, linux-kernel

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

On Tue, Mar 02, 2021 at 03:24:59PM +0300, Dmitry Osipenko wrote:
> The SW-initiated power gate toggling is dropped by PMC if there is
> contention with a HW-initiated toggling, i.e. when one of CPU cores is
> gated by cpuidle driver. Software should retry the toggling after 10
> microseconds on Tegra20/30 SoCs, hence add the retrying. On Tegra114+ the
> toggling method was changed in hardware, the TOGGLE_START bit indicates
> whether PMC is busy or could accept the command to toggle, hence handle
> that bit properly.
> 
> The problem pops up after enabling dynamic power gating of 3d hardware,
> where 3d power domain fails to turn on/off "randomly".
> 
> The programming sequence and quirks are documented in TRMs, but PMC
> driver obliviously re-used the Tegra20 logic for Tegra30+, which strikes
> back now. The 10 microseconds and other timeouts aren't documented in TRM,
> they are taken from downstream kernel.
> 
> Link: https://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=commit;h=311dd1c318b70e93bcefec15456a10ff2b9eb0ff
> Link: https://nv-tegra.nvidia.com/gitweb/?p=linux-3.10.git;a=commit;h=7f36693c47cb23730a6b2822e0975be65fb0c51d
> Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
> 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 | 70 ++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 65 insertions(+), 5 deletions(-)

Applied, thanks.

Thierry

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

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

* Re: [PATCH v4 3/5] soc/tegra: pmc: Ensure that clock rates aren't too high
  2021-03-02 12:25 ` [PATCH v4 3/5] soc/tegra: pmc: Ensure that clock rates aren't too high Dmitry Osipenko
@ 2021-03-25 14:39   ` Thierry Reding
  2021-03-25 15:02     ` Dmitry Osipenko
  0 siblings, 1 reply; 14+ messages in thread
From: Thierry Reding @ 2021-03-25 14:39 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Peter Geis, Matt Merhar, linux-tegra, linux-kernel

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

On Tue, Mar 02, 2021 at 03:25:00PM +0300, Dmitry Osipenko wrote:
> Switch all clocks of a power domain to a safe rate which is suitable
> for all possible voltages in order to ensure that hardware constraints
> aren't violated when power domain state toggles.
> 
> Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
> 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 | 92 ++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 90 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
> index f970b615ee27..a87645fac735 100644
> --- a/drivers/soc/tegra/pmc.c
> +++ b/drivers/soc/tegra/pmc.c
> @@ -237,6 +237,7 @@ struct tegra_powergate {
>  	unsigned int id;
>  	struct clk **clks;
>  	unsigned int num_clks;
> +	unsigned long *clk_rates;
>  	struct reset_control *reset;
>  };
>  
> @@ -641,6 +642,57 @@ static int __tegra_powergate_remove_clamping(struct tegra_pmc *pmc,
>  	return 0;
>  }
>  
> +static int tegra_powergate_prepare_clocks(struct tegra_powergate *pg)
> +{
> +	unsigned long safe_rate = 100 * 1000 * 1000;

This seems a bit arbitrary. Where did you come up with that value?

I'm going to apply this to see how it fares in our testing.

Thierry

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

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

* Re: [PATCH v4 4/5] soc/tegra: pmc: Print out domain name when reset fails to acquire
  2021-03-02 12:25 ` [PATCH v4 4/5] soc/tegra: pmc: Print out domain name when reset fails to acquire Dmitry Osipenko
@ 2021-03-25 14:40   ` Thierry Reding
  0 siblings, 0 replies; 14+ messages in thread
From: Thierry Reding @ 2021-03-25 14:40 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Peter Geis, Matt Merhar, linux-tegra, linux-kernel

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

On Tue, Mar 02, 2021 at 03:25:01PM +0300, Dmitry Osipenko wrote:
> Print out domain name when reset fails to acquire for debugging purposes
> and to make formatting of GENPD errors consistent in the driver.
> 
> Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
> 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 | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Applied, thanks.

Thierry

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

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

* Re: [PATCH v4 5/5] soc/tegra: pmc: Rate-limit error message about failed to acquire of reset
  2021-03-02 12:25 ` [PATCH v4 5/5] soc/tegra: pmc: Rate-limit error message about failed to acquire of reset Dmitry Osipenko
@ 2021-03-25 14:42   ` Thierry Reding
  2021-03-25 14:53     ` Dmitry Osipenko
  0 siblings, 1 reply; 14+ messages in thread
From: Thierry Reding @ 2021-03-25 14:42 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Peter Geis, Matt Merhar, linux-tegra, linux-kernel

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

On Tue, Mar 02, 2021 at 03:25:02PM +0300, Dmitry Osipenko wrote:
> PMC domain could be easily bombarded with the enable requests if there is
> a problem in regards to acquiring reset control of a domain and kernel
> log will be flooded with the error message in this case. Hence rate-limit
> the message in order to prevent missing other important messages.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/soc/tegra/pmc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
> index bf29ea22480a..84ab27d85d92 100644
> --- a/drivers/soc/tegra/pmc.c
> +++ b/drivers/soc/tegra/pmc.c
> @@ -868,8 +868,8 @@ static int tegra_genpd_power_off(struct generic_pm_domain *domain)
>  
>  	err = reset_control_acquire(pg->reset);
>  	if (err < 0) {
> -		dev_err(dev, "failed to acquire resets for PM domain %s: %d\n",
> -			pg->genpd.name, err);
> +		dev_err_ratelimited(dev, "failed to acquire resets for PM domain %s: %d\n",
> +				    pg->genpd.name, err);

That doesn't look right. This is a serious error condition that
shouldn't happen at all. Ever. If this shows up even once we've got a
serious bug somewhere and we need to fix it rather than "downplay" it
by ratelimiting these errors.

What's the exact use-case where you see this?

Thierry

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

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

* Re: [PATCH v4 5/5] soc/tegra: pmc: Rate-limit error message about failed to acquire of reset
  2021-03-25 14:42   ` Thierry Reding
@ 2021-03-25 14:53     ` Dmitry Osipenko
  0 siblings, 0 replies; 14+ messages in thread
From: Dmitry Osipenko @ 2021-03-25 14:53 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Peter Geis, Matt Merhar, linux-tegra, linux-kernel

25.03.2021 17:42, Thierry Reding пишет:
> On Tue, Mar 02, 2021 at 03:25:02PM +0300, Dmitry Osipenko wrote:
>> PMC domain could be easily bombarded with the enable requests if there is
>> a problem in regards to acquiring reset control of a domain and kernel
>> log will be flooded with the error message in this case. Hence rate-limit
>> the message in order to prevent missing other important messages.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/soc/tegra/pmc.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
>> index bf29ea22480a..84ab27d85d92 100644
>> --- a/drivers/soc/tegra/pmc.c
>> +++ b/drivers/soc/tegra/pmc.c
>> @@ -868,8 +868,8 @@ static int tegra_genpd_power_off(struct generic_pm_domain *domain)
>>  
>>  	err = reset_control_acquire(pg->reset);
>>  	if (err < 0) {
>> -		dev_err(dev, "failed to acquire resets for PM domain %s: %d\n",
>> -			pg->genpd.name, err);
>> +		dev_err_ratelimited(dev, "failed to acquire resets for PM domain %s: %d\n",
>> +				    pg->genpd.name, err);
> 
> That doesn't look right. This is a serious error condition that
> shouldn't happen at all. Ever. If this shows up even once we've got a
> serious bug somewhere and we need to fix it rather than "downplay" it
> by ratelimiting these errors.
> 
> What's the exact use-case where you see this?

This was firing up badly while I was wiring up power management and
GENPD support to the GR3D and VDE drivers and testing them because of
the bugs that I was creating.

Looking back again at this now, I agree that the commit message isn't
good and could be improved. What about this variant:

"Rate-limit error message about failing to acquire reset in order to
prevent missing other important messages. This was proven to be very
useful to have for development and debugging purposes of a power
management support for various Tegra drivers".

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

* Re: [PATCH v4 3/5] soc/tegra: pmc: Ensure that clock rates aren't too high
  2021-03-25 14:39   ` Thierry Reding
@ 2021-03-25 15:02     ` Dmitry Osipenko
  2021-03-25 15:05       ` Dmitry Osipenko
  0 siblings, 1 reply; 14+ messages in thread
From: Dmitry Osipenko @ 2021-03-25 15:02 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Peter Geis, Matt Merhar, linux-tegra, linux-kernel

25.03.2021 17:39, Thierry Reding пишет:
> On Tue, Mar 02, 2021 at 03:25:00PM +0300, Dmitry Osipenko wrote:
>> Switch all clocks of a power domain to a safe rate which is suitable
>> for all possible voltages in order to ensure that hardware constraints
>> aren't violated when power domain state toggles.
>>
>> Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
>> 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 | 92 ++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 90 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
>> index f970b615ee27..a87645fac735 100644
>> --- a/drivers/soc/tegra/pmc.c
>> +++ b/drivers/soc/tegra/pmc.c
>> @@ -237,6 +237,7 @@ struct tegra_powergate {
>>  	unsigned int id;
>>  	struct clk **clks;
>>  	unsigned int num_clks;
>> +	unsigned long *clk_rates;
>>  	struct reset_control *reset;
>>  };
>>  
>> @@ -641,6 +642,57 @@ static int __tegra_powergate_remove_clamping(struct tegra_pmc *pmc,
>>  	return 0;
>>  }
>>  
>> +static int tegra_powergate_prepare_clocks(struct tegra_powergate *pg)
>> +{
>> +	unsigned long safe_rate = 100 * 1000 * 1000;
> 
> This seems a bit arbitrary. Where did you come up with that value?
> 
> I'm going to apply this to see how it fares in our testing.

This value is chosen based on the OPP table voltages and frequencies.

Maybe you could add this clarifying comment to the code(?):

"There is no hardware unit on any of Tegra SoCs which requires higher
voltages for the rates above 100MHz."

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

* Re: [PATCH v4 3/5] soc/tegra: pmc: Ensure that clock rates aren't too high
  2021-03-25 15:02     ` Dmitry Osipenko
@ 2021-03-25 15:05       ` Dmitry Osipenko
  0 siblings, 0 replies; 14+ messages in thread
From: Dmitry Osipenko @ 2021-03-25 15:05 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Peter Geis, Matt Merhar, linux-tegra, linux-kernel

25.03.2021 18:02, Dmitry Osipenko пишет:
> 25.03.2021 17:39, Thierry Reding пишет:
>> On Tue, Mar 02, 2021 at 03:25:00PM +0300, Dmitry Osipenko wrote:
>>> Switch all clocks of a power domain to a safe rate which is suitable
>>> for all possible voltages in order to ensure that hardware constraints
>>> aren't violated when power domain state toggles.
>>>
>>> Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
>>> 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 | 92 ++++++++++++++++++++++++++++++++++++++++-
>>>  1 file changed, 90 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
>>> index f970b615ee27..a87645fac735 100644
>>> --- a/drivers/soc/tegra/pmc.c
>>> +++ b/drivers/soc/tegra/pmc.c
>>> @@ -237,6 +237,7 @@ struct tegra_powergate {
>>>  	unsigned int id;
>>>  	struct clk **clks;
>>>  	unsigned int num_clks;
>>> +	unsigned long *clk_rates;
>>>  	struct reset_control *reset;
>>>  };
>>>  
>>> @@ -641,6 +642,57 @@ static int __tegra_powergate_remove_clamping(struct tegra_pmc *pmc,
>>>  	return 0;
>>>  }
>>>  
>>> +static int tegra_powergate_prepare_clocks(struct tegra_powergate *pg)
>>> +{
>>> +	unsigned long safe_rate = 100 * 1000 * 1000;
>>
>> This seems a bit arbitrary. Where did you come up with that value?
>>
>> I'm going to apply this to see how it fares in our testing.
> 
> This value is chosen based on the OPP table voltages and frequencies.
> 
> Maybe you could add this clarifying comment to the code(?):
> 
> "There is no hardware unit on any of Tegra SoCs which requires higher
> voltages for the rates above 100MHz."

I meant below, of course :)

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

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

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-02 12:24 [PATCH v4 0/5] Tegra PMC driver fixes and improvements Dmitry Osipenko
2021-03-02 12:24 ` [PATCH v4 1/5] soc/tegra: pmc: Fix imbalanced clock disabling in error code path Dmitry Osipenko
2021-03-25 14:27   ` Thierry Reding
2021-03-02 12:24 ` [PATCH v4 2/5] soc/tegra: pmc: Fix completion of power-gate toggling Dmitry Osipenko
2021-03-25 14:32   ` Thierry Reding
2021-03-02 12:25 ` [PATCH v4 3/5] soc/tegra: pmc: Ensure that clock rates aren't too high Dmitry Osipenko
2021-03-25 14:39   ` Thierry Reding
2021-03-25 15:02     ` Dmitry Osipenko
2021-03-25 15:05       ` Dmitry Osipenko
2021-03-02 12:25 ` [PATCH v4 4/5] soc/tegra: pmc: Print out domain name when reset fails to acquire Dmitry Osipenko
2021-03-25 14:40   ` Thierry Reding
2021-03-02 12:25 ` [PATCH v4 5/5] soc/tegra: pmc: Rate-limit error message about failed to acquire of reset Dmitry Osipenko
2021-03-25 14:42   ` Thierry Reding
2021-03-25 14:53     ` Dmitry Osipenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.