diff options
author | Dmitry Osipenko <digetx@gmail.com> | 2019-09-23 00:52:03 +0300 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2019-11-11 14:53:04 +0100 |
commit | 204ce75b897035447f29b1ec4423f9f25baf8a60 (patch) | |
tree | b69e868297e439d579722006d95ecd315800f9b3 /drivers/clk/tegra | |
parent | 535f296d47de327287fe65b5843713bd9b01a267 (diff) | |
download | linux-204ce75b897035447f29b1ec4423f9f25baf8a60.tar.gz linux-204ce75b897035447f29b1ec4423f9f25baf8a60.tar.bz2 linux-204ce75b897035447f29b1ec4423f9f25baf8a60.zip |
clk: tegra: Optimize PLLX restore on Tegra20/30
There is no need to re-configure PLLX if its configuration in unchanged
on return from suspend / cpuidle, this saves 300us if PLLX is already
enabled (common case for cpuidle).
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Acked-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/clk/tegra')
-rw-r--r-- | drivers/clk/tegra/clk-tegra20.c | 25 | ||||
-rw-r--r-- | drivers/clk/tegra/clk-tegra30.c | 25 |
2 files changed, 32 insertions, 18 deletions
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index cceefbd67a3b..4d8222f5c638 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -955,6 +955,7 @@ static void tegra20_cpu_clock_suspend(void) static void tegra20_cpu_clock_resume(void) { unsigned int reg, policy; + u32 misc, base; /* Is CPU complex already running on PLLX? */ reg = readl(clk_base + CCLK_BURST_POLICY); @@ -968,15 +969,21 @@ static void tegra20_cpu_clock_resume(void) BUG(); if (reg != CCLK_BURST_POLICY_PLLX) { - /* restore PLLX settings if CPU is on different PLL */ - writel(tegra20_cpu_clk_sctx.pllx_misc, - clk_base + PLLX_MISC); - writel(tegra20_cpu_clk_sctx.pllx_base, - clk_base + PLLX_BASE); - - /* wait for PLL stabilization if PLLX was enabled */ - if (tegra20_cpu_clk_sctx.pllx_base & (1 << 30)) - udelay(300); + misc = readl_relaxed(clk_base + PLLX_MISC); + base = readl_relaxed(clk_base + PLLX_BASE); + + if (misc != tegra20_cpu_clk_sctx.pllx_misc || + base != tegra20_cpu_clk_sctx.pllx_base) { + /* restore PLLX settings if CPU is on different PLL */ + writel(tegra20_cpu_clk_sctx.pllx_misc, + clk_base + PLLX_MISC); + writel(tegra20_cpu_clk_sctx.pllx_base, + clk_base + PLLX_BASE); + + /* wait for PLL stabilization if PLLX was enabled */ + if (tegra20_cpu_clk_sctx.pllx_base & (1 << 30)) + udelay(300); + } } /* diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 95b0e4a16dd5..c8bc18e4d7e5 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -1163,6 +1163,7 @@ static void tegra30_cpu_clock_suspend(void) static void tegra30_cpu_clock_resume(void) { unsigned int reg, policy; + u32 misc, base; /* Is CPU complex already running on PLLX? */ reg = readl(clk_base + CLK_RESET_CCLK_BURST); @@ -1176,15 +1177,21 @@ static void tegra30_cpu_clock_resume(void) BUG(); if (reg != CLK_RESET_CCLK_BURST_POLICY_PLLX) { - /* restore PLLX settings if CPU is on different PLL */ - writel(tegra30_cpu_clk_sctx.pllx_misc, - clk_base + CLK_RESET_PLLX_MISC); - writel(tegra30_cpu_clk_sctx.pllx_base, - clk_base + CLK_RESET_PLLX_BASE); - - /* wait for PLL stabilization if PLLX was enabled */ - if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30)) - udelay(300); + misc = readl_relaxed(clk_base + CLK_RESET_PLLX_MISC); + base = readl_relaxed(clk_base + CLK_RESET_PLLX_BASE); + + if (misc != tegra30_cpu_clk_sctx.pllx_misc || + base != tegra30_cpu_clk_sctx.pllx_base) { + /* restore PLLX settings if CPU is on different PLL */ + writel(tegra30_cpu_clk_sctx.pllx_misc, + clk_base + CLK_RESET_PLLX_MISC); + writel(tegra30_cpu_clk_sctx.pllx_base, + clk_base + CLK_RESET_PLLX_BASE); + + /* wait for PLL stabilization if PLLX was enabled */ + if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30)) + udelay(300); + } } /* |