diff options
| author | Miquel Raynal <miquel.raynal@bootlin.com> | 2018-07-13 09:44:46 -0400 |
|---|---|---|
| committer | Stephen Boyd <sboyd@kernel.org> | 2018-08-31 13:47:48 -0400 |
| commit | 5beb1e60dba973e0b9cfb54d9735d5d4385b9d90 (patch) | |
| tree | 1ebebd94ce6910f5c481613bb6ef3a43335ea060 /drivers/clk/mvebu | |
| parent | d9d95e78cff80c3fe43e757ba90644cd766302ac (diff) | |
clk: mvebu: armada-37xx-periph: add suspend/resume support
Add suspend/resume hooks in Armada 37xx peripheral clocks driver to
handle S2RAM operations.
One can think that these hooks are useless by comparing the register
values before and after a suspend/resume cycle: they will look the same
anyway. This is because of some scripts executed by the Cortex-M3 core
during ATF operations to init both the clocks and the DDR. These values
could be modified by the BL33 stage or by Linux itself and should be
preserved.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'drivers/clk/mvebu')
| -rw-r--r-- | drivers/clk/mvebu/armada-37xx-periph.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 78048c2e3774..1f1cff428d78 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c | |||
| @@ -57,6 +57,14 @@ struct clk_periph_driver_data { | |||
| 57 | struct clk_hw_onecell_data *hw_data; | 57 | struct clk_hw_onecell_data *hw_data; |
| 58 | spinlock_t lock; | 58 | spinlock_t lock; |
| 59 | void __iomem *reg; | 59 | void __iomem *reg; |
| 60 | |||
| 61 | /* Storage registers for suspend/resume operations */ | ||
| 62 | u32 tbg_sel; | ||
| 63 | u32 div_sel0; | ||
| 64 | u32 div_sel1; | ||
| 65 | u32 div_sel2; | ||
| 66 | u32 clk_sel; | ||
| 67 | u32 clk_dis; | ||
| 60 | }; | 68 | }; |
| 61 | 69 | ||
| 62 | struct clk_double_div { | 70 | struct clk_double_div { |
| @@ -673,6 +681,40 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data, | |||
| 673 | return PTR_ERR_OR_ZERO(*hw); | 681 | return PTR_ERR_OR_ZERO(*hw); |
| 674 | } | 682 | } |
| 675 | 683 | ||
| 684 | static int __maybe_unused armada_3700_periph_clock_suspend(struct device *dev) | ||
| 685 | { | ||
| 686 | struct clk_periph_driver_data *data = dev_get_drvdata(dev); | ||
| 687 | |||
| 688 | data->tbg_sel = readl(data->reg + TBG_SEL); | ||
| 689 | data->div_sel0 = readl(data->reg + DIV_SEL0); | ||
| 690 | data->div_sel1 = readl(data->reg + DIV_SEL1); | ||
| 691 | data->div_sel2 = readl(data->reg + DIV_SEL2); | ||
| 692 | data->clk_sel = readl(data->reg + CLK_SEL); | ||
| 693 | data->clk_dis = readl(data->reg + CLK_DIS); | ||
| 694 | |||
| 695 | return 0; | ||
| 696 | } | ||
| 697 | |||
| 698 | static int __maybe_unused armada_3700_periph_clock_resume(struct device *dev) | ||
| 699 | { | ||
| 700 | struct clk_periph_driver_data *data = dev_get_drvdata(dev); | ||
| 701 | |||
| 702 | /* Follow the same order than what the Cortex-M3 does (ATF code) */ | ||
| 703 | writel(data->clk_dis, data->reg + CLK_DIS); | ||
| 704 | writel(data->div_sel0, data->reg + DIV_SEL0); | ||
| 705 | writel(data->div_sel1, data->reg + DIV_SEL1); | ||
| 706 | writel(data->div_sel2, data->reg + DIV_SEL2); | ||
| 707 | writel(data->tbg_sel, data->reg + TBG_SEL); | ||
| 708 | writel(data->clk_sel, data->reg + CLK_SEL); | ||
| 709 | |||
| 710 | return 0; | ||
| 711 | } | ||
| 712 | |||
| 713 | static const struct dev_pm_ops armada_3700_periph_clock_pm_ops = { | ||
| 714 | SET_SYSTEM_SLEEP_PM_OPS(armada_3700_periph_clock_suspend, | ||
| 715 | armada_3700_periph_clock_resume) | ||
| 716 | }; | ||
| 717 | |||
| 676 | static int armada_3700_periph_clock_probe(struct platform_device *pdev) | 718 | static int armada_3700_periph_clock_probe(struct platform_device *pdev) |
| 677 | { | 719 | { |
| 678 | struct clk_periph_driver_data *driver_data; | 720 | struct clk_periph_driver_data *driver_data; |
| @@ -748,6 +790,7 @@ static struct platform_driver armada_3700_periph_clock_driver = { | |||
| 748 | .driver = { | 790 | .driver = { |
| 749 | .name = "marvell-armada-3700-periph-clock", | 791 | .name = "marvell-armada-3700-periph-clock", |
| 750 | .of_match_table = armada_3700_periph_clock_of_match, | 792 | .of_match_table = armada_3700_periph_clock_of_match, |
| 793 | .pm = &armada_3700_periph_clock_pm_ops, | ||
| 751 | }, | 794 | }, |
| 752 | }; | 795 | }; |
| 753 | 796 | ||
