From patchwork Fri Oct 14 09:18:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel FERNANDEZ X-Patchwork-Id: 9376279 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 74C2C6075E for ; Fri, 14 Oct 2016 09:21:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6304929276 for ; Fri, 14 Oct 2016 09:21:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 56CD62A560; Fri, 14 Oct 2016 09:21:47 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 02AC929276 for ; Fri, 14 Oct 2016 09:21:47 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1buyeX-0006I6-4Z; Fri, 14 Oct 2016 09:19:45 +0000 Received: from mx07-00178001.pphosted.com ([62.209.51.94]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1buye8-0006DV-6C for linux-arm-kernel@lists.infradead.org; Fri, 14 Oct 2016 09:19:22 +0000 Received: from pps.filterd (m0046668.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u9E9HdrO016409; Fri, 14 Oct 2016 11:18:38 +0200 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-.pphosted.com with ESMTP id 2615d4qw3u-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Fri, 14 Oct 2016 11:18:38 +0200 Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 3E50542; Fri, 14 Oct 2016 09:18:37 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas22.st.com [10.75.90.92]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 1300A250A; Fri, 14 Oct 2016 09:18:37 +0000 (GMT) Received: from localhost (10.48.1.80) by Webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.279.2; Fri, 14 Oct 2016 11:18:36 +0200 From: To: Rob Herring , Mark Rutland , Russell King , Maxime Coquelin , Alexandre Torgue , Michael Turquette , Stephen Boyd , Nicolas Pitre , Arnd Bergmann , Subject: [PATCH v2 4/6] clk: stm32f4: Add RTC clock Date: Fri, 14 Oct 2016 11:18:17 +0200 Message-ID: <1476436699-21879-5-git-send-email-gabriel.fernandez@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1476436699-21879-1-git-send-email-gabriel.fernandez@st.com> References: <1476436699-21879-1-git-send-email-gabriel.fernandez@st.com> MIME-Version: 1.0 X-Originating-IP: [10.48.1.80] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-10-14_03:, , signatures=0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161014_021920_628442_6B128082 X-CRM114-Status: GOOD ( 13.80 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, amelie.delaunay@st.com, olivier.bideau@st.com, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org, gabriel.fernandez@st.com, ludovic.barre@st.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Gabriel Fernandez This patch introduces the support of the RTC clock. RTC clock can have 3 sources: lsi, lse and hse_rtc. Signed-off-by: Gabriel Fernandez --- drivers/clk/clk-stm32f4.c | 135 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index 789a8f77..bf9448d 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c @@ -126,7 +126,7 @@ struct stm32f4_gate_data { { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, }; -enum { SYSTICK, FCLK, CLK_LSI, CLK_LSE, END_PRIMARY_CLK }; +enum { SYSTICK, FCLK, CLK_LSI, CLK_LSE, CLK_HSE_RTC, CLK_RTC, END_PRIMARY_CLK }; /* * MAX_CLKS is the maximum value in the enumeration below plus the combined * hweight of stm32f42xx_gate_map (plus one). @@ -310,6 +310,15 @@ static inline void enable_power_domain_write_protection(void) regmap_update_bits(pdrm, 0x00, (1 << 8), (0 << 8)); } +static inline void sofware_reset_backup_domain(void) +{ + unsigned long val; + + val = readl(base + STM32F4_RCC_BDCR); + writel(val |= (1 << 16), base + STM32F4_RCC_BDCR); + writel(val & ~(1 << 16), base + STM32F4_RCC_BDCR); +} + struct stm32_rgate { struct clk_hw hw; struct clk_gate gate; @@ -396,6 +405,113 @@ static struct clk_hw *clk_register_rgate(struct device *dev, const char *name, return hw; } +static int cclk_gate_enable(struct clk_hw *hw) +{ + int ret; + + disable_power_domain_write_protection(); + + ret = clk_gate_ops.enable(hw); + + enable_power_domain_write_protection(); + + return ret; +} + +static void cclk_gate_disable(struct clk_hw *hw) +{ + disable_power_domain_write_protection(); + + clk_gate_ops.disable(hw); + + enable_power_domain_write_protection(); +} + +static int cclk_gate_is_enabled(struct clk_hw *hw) +{ + return clk_gate_ops.is_enabled(hw); +} + +static const struct clk_ops cclk_gate_ops = { + .enable = cclk_gate_enable, + .disable = cclk_gate_disable, + .is_enabled = cclk_gate_is_enabled, +}; + +static u8 cclk_mux_get_parent(struct clk_hw *hw) +{ + return clk_mux_ops.get_parent(hw); +} + + +static int cclk_mux_set_parent(struct clk_hw *hw, u8 index) +{ + int ret; + + disable_power_domain_write_protection(); + + sofware_reset_backup_domain(); + + ret = clk_mux_ops.set_parent(hw, index); + + enable_power_domain_write_protection(); + + return ret; +} + + +static const struct clk_ops cclk_mux_ops = { + .get_parent = cclk_mux_get_parent, + .set_parent = cclk_mux_set_parent, +}; + +static struct clk_hw *stm32_register_cclk(struct device *dev, const char *name, + const char * const *parent_names, int num_parents, + void __iomem *reg, u8 bit_idx, u8 shift, unsigned long flags, + spinlock_t *lock) +{ + struct clk_hw *hw; + struct clk_gate *gate; + struct clk_mux *mux; + + gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); + if (!gate) { + hw = ERR_PTR(-EINVAL); + goto fail; + } + + mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); + if (!mux) { + kfree(gate); + hw = ERR_PTR(-EINVAL); + goto fail; + } + + gate->reg = reg; + gate->bit_idx = bit_idx; + gate->flags = 0; + gate->lock = lock; + + mux->reg = reg; + mux->shift = shift; + mux->mask = 3; + mux->flags = 0; + + hw = clk_hw_register_composite(dev, name, parent_names, num_parents, + &mux->hw, &cclk_mux_ops, + NULL, NULL, + &gate->hw, &cclk_gate_ops, + flags); + + if (IS_ERR(hw)) { + kfree(gate); + kfree(mux); + } + +fail: + return hw; +} + static const char *sys_parents[] __initdata = { "hsi", NULL, "pll" }; const char *rtc_parents[4] = { @@ -501,6 +617,23 @@ static void __init stm32f4_rcc_init(struct device_node *np) goto fail; } + clks[CLK_HSE_RTC] = clk_hw_register_divider(NULL, "hse-rtc", "clk-hse", + 0, base + STM32F4_RCC_CFGR, 16, 5, 0, + &stm32f4_clk_lock); + + if (IS_ERR(clks[CLK_HSE_RTC])) { + pr_err("Unable to register hse-rtc clock\n"); + goto fail; + } + + clks[CLK_RTC] = stm32_register_cclk(NULL, "rtc", rtc_parents, 4, + base + STM32F4_RCC_BDCR, 15, 8, 0, &stm32f4_clk_lock); + + if (IS_ERR(clks[CLK_RTC])) { + pr_err("Unable to register rtc clock\n"); + goto fail; + } + of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL); return; fail: