@@ -69,10 +69,38 @@ static void clk_pll_out_disable(struct clk_hw *hw)
spin_unlock_irqrestore(pll_out->lock, flags);
}
+static int tegra_clk_pll_out_save_context(struct clk_hw *hw)
+{
+ struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
+
+ if (pll_out->flags & TEGRA_PLLRE_OUT)
+ pll_out->pllout_ctx = readl_relaxed(pll_out->reg);
+ else
+ pll_out->pllout_ctx = clk_hw_get_rate(hw);
+
+ return 0;
+}
+
+static void tegra_clk_pll_out_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
+
+ if (pll_out->flags & TEGRA_PLLRE_OUT) {
+ writel_relaxed(pll_out->pllout_ctx, pll_out->reg);
+ } else {
+ if (!__clk_get_enable_count(hw->clk))
+ clk_pll_out_disable(hw);
+ else
+ clk_pll_out_enable(hw);
+ }
+}
+
const struct clk_ops tegra_clk_pll_out_ops = {
.is_enabled = clk_pll_out_is_enabled,
.enable = clk_pll_out_enable,
.disable = clk_pll_out_disable,
+ .save_context = tegra_clk_pll_out_save_context,
+ .restore_context = tegra_clk_pll_out_restore_context,
};
struct clk *tegra_clk_register_pll_out(const char *name,
@@ -3195,7 +3195,8 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
8, 8, 1, NULL);
clk = tegra_clk_register_pll_out("pll_re_out1", "pll_re_out1_div",
clk_base + PLLRE_OUT1, 1, 0,
- CLK_SET_RATE_PARENT, 0, NULL);
+ CLK_SET_RATE_PARENT, TEGRA_PLLRE_OUT,
+ NULL);
clks[TEGRA210_CLK_PLL_RE_OUT1] = clk;
/* PLLE */
@@ -439,6 +439,12 @@ struct clk *tegra_clk_register_pllu_tegra210(const char *name,
* @rst_bit_idx: bit to reset PLL divider
* @lock: register lock
* @flags: hardware-specific flags
+ * @pllout_ctx: pllout context to save and restore during suspend
+ * and resume
+ *
+ * Flags:
+ * TEGRA_PLLRE_OUT - This flag indicates that it is PLLRE_OUT and is used to
+ * identify PLLRE_OUT during clk_pll_out save and restore.
*/
struct tegra_clk_pll_out {
struct clk_hw hw;
@@ -447,8 +453,11 @@ struct tegra_clk_pll_out {
u8 rst_bit_idx;
spinlock_t *lock;
u8 flags;
+ unsigned int pllout_ctx;
};
+#define TEGRA_PLLRE_OUT BIT(0)
+
#define to_clk_pll_out(_hw) container_of(_hw, struct tegra_clk_pll_out, hw)
extern const struct clk_ops tegra_clk_pll_out_ops;