From patchwork Sat Apr 21 14:23:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 10354185 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 63CFF601E7 for ; Sat, 21 Apr 2018 14:24:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5071A2891D for ; Sat, 21 Apr 2018 14:24:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 453662891C; Sat, 21 Apr 2018 14:24:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EA5472891D for ; Sat, 21 Apr 2018 14:24:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752700AbeDUOYA (ORCPT ); Sat, 21 Apr 2018 10:24:00 -0400 Received: from mail.bootlin.com ([62.4.15.54]:59966 "EHLO mail.bootlin.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752738AbeDUOYA (ORCPT ); Sat, 21 Apr 2018 10:24:00 -0400 Received: by mail.bootlin.com (Postfix, from userid 110) id 3C31B2073D; Sat, 21 Apr 2018 16:23:58 +0200 (CEST) Received: from localhost.localdomain (unknown [91.224.148.103]) by mail.bootlin.com (Postfix) with ESMTPSA id 968D120384; Sat, 21 Apr 2018 16:23:47 +0200 (CEST) From: Miquel Raynal To: Michael Turquette , Stephen Boyd Cc: Thomas Petazzoni , Antoine Tenart , Gregory Clement , Maxime Chevallier , Nadav Haklai , linux-clk@vger.kernel.org, linux-pm@vger.kernel.org, Miquel Raynal Subject: [PATCH 2/2] clk: mvebu: armada-37xx-periph: add suspend/resume support Date: Sat, 21 Apr 2018 16:23:44 +0200 Message-Id: <20180421142344.25944-2-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180421142344.25944-1-miquel.raynal@bootlin.com> References: <20180421142344.25944-1-miquel.raynal@bootlin.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- drivers/clk/mvebu/armada-37xx-periph.c | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 723bb7f6cea1..cd560bdcb8a9 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -59,6 +59,15 @@ struct clk_periph_driver_data { struct clk_hw_onecell_data *hw_data; spinlock_t lock; void __iomem *reg; +#if defined(CONFIG_PM) + /* Storage registers for suspend/resume operations */ + u32 tbg_sel; + u32 div_sel0; + u32 div_sel1; + u32 div_sel2; + u32 clk_sel; + u32 clk_dis; +#endif /* CONFIG_PM */ }; struct clk_double_div { @@ -642,6 +651,42 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data, return PTR_ERR_OR_ZERO(*hw); } +#if defined(CONFIG_PM) +static int armada_3700_periph_clock_suspend(struct device *dev) +{ + struct clk_periph_driver_data *data = dev_get_drvdata(dev); + + data->tbg_sel = readl(data->reg + TBG_SEL); + data->div_sel0 = readl(data->reg + DIV_SEL0); + data->div_sel1 = readl(data->reg + DIV_SEL1); + data->div_sel2 = readl(data->reg + DIV_SEL2); + data->clk_sel = readl(data->reg + CLK_SEL); + data->clk_dis = readl(data->reg + CLK_DIS); + + return 0; +} + +static int armada_3700_periph_clock_resume(struct device *dev) +{ + struct clk_periph_driver_data *data = dev_get_drvdata(dev); + + /* Follow the same order than what the Cortex-M3 does (ATF code) */ + writel(data->clk_dis, data->reg + CLK_DIS); + writel(data->div_sel0, data->reg + DIV_SEL0); + writel(data->div_sel1, data->reg + DIV_SEL1); + writel(data->div_sel2, data->reg + DIV_SEL2); + writel(data->tbg_sel, data->reg + TBG_SEL); + writel(data->clk_sel, data->reg + CLK_SEL); + + return 0; +} + +static const struct dev_pm_ops armada_3700_periph_clock_pm_ops = { + .suspend = armada_3700_periph_clock_suspend, + .resume = armada_3700_periph_clock_resume, +}; +#endif /* CONFIG_PM */ + static int armada_3700_periph_clock_probe(struct platform_device *pdev) { struct clk_periph_driver_data *driver_data; @@ -716,6 +761,9 @@ static struct platform_driver armada_3700_periph_clock_driver = { .driver = { .name = "marvell-armada-3700-periph-clock", .of_match_table = armada_3700_periph_clock_of_match, +#if defined(CONFIG_PM) + .pm = &armada_3700_periph_clock_pm_ops, +#endif /* CONFIG_PM */ }, };