Re: [PATCH v7 06/20] clk: tegra: Support for OSC context save and restore

From: Sowjanya Komatineni
Date: Thu Aug 01 2019 - 14:06:12 EST



On 8/1/19 3:53 AM, Dmitry Osipenko wrote:
01.08.2019 0:04, Sowjanya Komatineni ÐÐÑÐÑ:
On 7/31/19 4:11 AM, Dmitry Osipenko wrote:
31.07.2019 3:20, Sowjanya Komatineni ÐÐÑÐÑ:
This patch adds support for saving OSC clock frequency and the
drive-strength during OSC clock init and creates an API to restore
OSC control register value from the saved context.

This API is invoked by Tegra210 clock driver during system resume
to restore the OSC clock settings.

Acked-by: Thierry Reding <treding@xxxxxxxxxx>
Signed-off-by: Sowjanya Komatineni <skomatineni@xxxxxxxxxx>
---
 drivers/clk/tegra/clk-tegra-fixed.c | 15 +++++++++++++++
 drivers/clk/tegra/clk.h | 1 +
 2 files changed, 16 insertions(+)

diff --git a/drivers/clk/tegra/clk-tegra-fixed.c
b/drivers/clk/tegra/clk-tegra-fixed.c
index 8d91b2b191cf..7c6c8abfcde6 100644
--- a/drivers/clk/tegra/clk-tegra-fixed.c
+++ b/drivers/clk/tegra/clk-tegra-fixed.c
@@ -17,6 +17,10 @@
 #define OSC_CTRL 0x50
 #define OSC_CTRL_OSC_FREQ_SHIFT 28
 #define OSC_CTRL_PLL_REF_DIV_SHIFT 26
+#define OSC_CTRL_MASKÂÂÂÂÂÂÂÂÂÂÂ (0x3f2 |ÂÂÂ \
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ (0xf << OSC_CTRL_OSC_FREQ_SHIFT))
+
+static u32 osc_ctrl_ctx;
  int __init tegra_osc_clk_init(void __iomem *clk_base, struct
tegra_clk *clks,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ unsigned long *input_freqs, unsigned int num,
@@ -29,6 +33,7 @@ int __init tegra_osc_clk_init(void __iomem
*clk_base, struct tegra_clk *clks,
ÂÂÂÂÂ unsigned osc_idx;
 Â val = readl_relaxed(clk_base + OSC_CTRL);
+ÂÂÂ osc_ctrl_ctx = val & OSC_CTRL_MASK;
ÂÂÂÂÂ osc_idx = val >> OSC_CTRL_OSC_FREQ_SHIFT;
 Â if (osc_idx < num)
@@ -96,3 +101,13 @@ void __init tegra_fixed_clk_init(struct tegra_clk
*tegra_clks)
ÂÂÂÂÂÂÂÂÂ *dt_clk = clk;
ÂÂÂÂÂ }
 }
+
+void tegra_clk_osc_resume(void __iomem *clk_base)
+{
+ÂÂÂ u32 val;
+
+ÂÂÂ val = readl_relaxed(clk_base + OSC_CTRL) & ~OSC_CTRL_MASK;
+ÂÂÂ val |= osc_ctrl_ctx;
+ÂÂÂ writel_relaxed(val, clk_base + OSC_CTRL);
Why a full raw u32 OSC_CTRL value couldn't be simply saved and restored?
Storing and restoring only required fields to avoid accidental
misconfiguration.

OSC_CTRL register has other bits (PLL_REF_DIV) which are configured by
BR depending on OSC_FREQ and also setting PLL_REF_DIV while PLLS are in
use is not safe.
I'm looking at the clk-driver sources and see that none of the Tegra
drivers ever change the OSC_CTRL configuration, T30/114 even have
#defines for the OSC_CTRL that are unused.

So, this leads to a question.. does any bootloader really ever change
the OSC_CTRL such that it differs after resume from suspend in
comparison to the value at the time of kernel's booting up?

For Tegra210, bootloader programs OSC_CTRL register for drivestrength programming.

These settings need to be restored to the same on SC7 exit as they gets reset during SC7 entry.