Messages in this thread | | | Subject | Re: [PATCH v8 10/21] clk: tegra: clk-super: Add restore-context support | From | Sowjanya Komatineni <> | Date | Fri, 9 Aug 2019 10:08:50 -0700 |
| |
On 8/9/19 5:17 AM, Dmitry Osipenko wrote: > 09.08.2019 2:46, Sowjanya Komatineni пишет: >> This patch implements restore_context for clk_super_mux and clk_super. >> >> During system supend, core power goes off the and context of Tegra >> CAR registers is lost. >> >> So on system resume, context of super clock registers are restored >> to have them in same state as before suspend. >> >> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com> >> --- >> drivers/clk/tegra/clk-super.c | 21 +++++++++++++++++++++ >> 1 file changed, 21 insertions(+) >> >> diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c >> index e2a1e95a8db7..74c9e913e41c 100644 >> --- a/drivers/clk/tegra/clk-super.c >> +++ b/drivers/clk/tegra/clk-super.c >> @@ -124,9 +124,18 @@ static int clk_super_set_parent(struct clk_hw *hw, u8 index) >> return err; >> } >> >> +static void clk_super_mux_restore_context(struct clk_hw *hw) >> +{ >> + struct clk_hw *parent = clk_hw_get_parent(hw); >> + int parent_id = clk_hw_get_parent_index(hw, parent); >> + >> + clk_super_set_parent(hw, parent_id); > All Super clocks have a divider, including the "MUX". Thus I'm wondering > if there is a chance that divider's configuration may differ on resume > from what it was on suspend.
tegra_clk_register_super_mux which uses tegra_clk_super_mux_ops doesn't do divider rate programming.
I believe you are referring to sclk_divider, cclklp_divider, cclkg_divider...
these are registered as clk_divider and are restored during clk_divider resume.
>> +} >> + >> static const struct clk_ops tegra_clk_super_mux_ops = { >> .get_parent = clk_super_get_parent, >> .set_parent = clk_super_set_parent, >> + .restore_context = clk_super_mux_restore_context, >> }; >> >> static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate, >> @@ -162,12 +171,24 @@ static int clk_super_set_rate(struct clk_hw *hw, unsigned long rate, >> return super->div_ops->set_rate(div_hw, rate, parent_rate); >> } >> >> +static void clk_super_restore_context(struct clk_hw *hw) >> +{ >> + struct tegra_clk_super_mux *super = to_clk_super_mux(hw); >> + struct clk_hw *div_hw = &super->frac_div.hw; >> + struct clk_hw *parent = clk_hw_get_parent(hw); >> + int parent_id = clk_hw_get_parent_index(hw, parent); >> + >> + super->div_ops->restore_context(div_hw); >> + clk_super_set_parent(hw, parent_id); >> +} >> + >> const struct clk_ops tegra_clk_super_ops = { >> .get_parent = clk_super_get_parent, >> .set_parent = clk_super_set_parent, >> .set_rate = clk_super_set_rate, >> .round_rate = clk_super_round_rate, >> .recalc_rate = clk_super_recalc_rate, >> + .restore_context = clk_super_restore_context, >> }; >> >> struct clk *tegra_clk_register_super_mux(const char *name, >>
| |