From patchwork Fri Sep 21 15:20:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Brandt X-Patchwork-Id: 10610473 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BEEF65A4 for ; Fri, 21 Sep 2018 15:21:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF5962E4A6 for ; Fri, 21 Sep 2018 15:21:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A2CB02E4CA; Fri, 21 Sep 2018 15:21:15 +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=ham 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 EE6112E4AB for ; Fri, 21 Sep 2018 15:21:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390387AbeIUVKf (ORCPT ); Fri, 21 Sep 2018 17:10:35 -0400 Received: from relmlor3.renesas.com ([210.160.252.173]:54388 "EHLO relmlie2.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2390267AbeIUVKf (ORCPT ); Fri, 21 Sep 2018 17:10:35 -0400 Received: from unknown (HELO relmlir1.idc.renesas.com) ([10.200.68.151]) by relmlie2.idc.renesas.com with ESMTP; 22 Sep 2018 00:21:11 +0900 Received: from relmlii2.idc.renesas.com (relmlii2.idc.renesas.com [10.200.68.66]) by relmlir1.idc.renesas.com (Postfix) with ESMTP id C604F854D9; Sat, 22 Sep 2018 00:21:11 +0900 (JST) X-IronPort-AV: E=Sophos;i="5.54,285,1534777200"; d="scan'208";a="293152790" Received: from unknown (HELO rtamta01.rta.renesas.com) ([143.103.48.75]) by relmlii2.idc.renesas.com with ESMTP; 22 Sep 2018 00:21:10 +0900 Received: from ubuntu.localdomain (unknown [143.103.58.47]) by rtamta01.rta.renesas.com (Postfix) with ESMTP id 0668E1FF; Fri, 21 Sep 2018 15:21:06 +0000 (UTC) From: Chris Brandt To: Geert Uytterhoeven , Michael Turquette , Stephen Boyd Cc: linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Simon Horman , Chris Brandt Subject: [PATCH 1/2] clk: renesas: cpg-mssr: Add early clock support Date: Fri, 21 Sep 2018 10:20:53 -0500 Message-Id: <20180921152054.117774-2-chris.brandt@renesas.com> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180921152054.117774-1-chris.brandt@renesas.com> References: <20180921152054.117774-1-chris.brandt@renesas.com> Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add support for SoCs that need to register core and module clocks early in order to use OF drivers that exclusively use macros such as TIMER_OF_DECLARE. Signed-off-by: Chris Brandt --- drivers/clk/renesas/renesas-cpg-mssr.c | 106 ++++++++++++++++++++++++++------- drivers/clk/renesas/renesas-cpg-mssr.h | 6 ++ 2 files changed, 91 insertions(+), 21 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 3df764d3ab20..b4be3cc18505 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -127,6 +127,7 @@ struct cpg_mssr_priv { struct device *dev; void __iomem *base; spinlock_t rmw_lock; + struct device_node *np; struct clk **clks; unsigned int num_core_clks; @@ -141,6 +142,7 @@ struct cpg_mssr_priv { } smstpcr_saved[ARRAY_SIZE(smstpcr)]; }; +struct cpg_mssr_priv *early_priv; /** * struct mstp_clock - MSTP gating clock @@ -316,7 +318,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, switch (core->type) { case CLK_TYPE_IN: - clk = of_clk_get_by_name(priv->dev->of_node, core->name); + clk = of_clk_get_by_name(priv->np, core->name); break; case CLK_TYPE_FF: @@ -877,42 +879,49 @@ static const struct dev_pm_ops cpg_mssr_pm = { #define DEV_PM_OPS NULL #endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */ -static int __init cpg_mssr_probe(struct platform_device *pdev) +static int cpg_mssr_common_init(struct device *dev, struct device_node *np, + const struct cpg_mssr_info *info) { - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - const struct cpg_mssr_info *info; struct cpg_mssr_priv *priv; unsigned int nclks, i; - struct resource *res; - struct clk **clks; + struct clk **clks = NULL; int error; + bool early_init = dev ? false : true; - info = of_device_get_match_data(dev); if (info->init) { error = info->init(dev); if (error) return error; } - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + /* np is saved because dev->of_node doesn't exists during early init */ + priv->np = np; + priv->dev = dev; spin_lock_init(&priv->rmw_lock); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); + priv->base = of_iomap(np, 0); + if (IS_ERR(priv->base)) { + error = PTR_ERR(priv->base); + goto out_err; + } nclks = info->num_total_core_clks + info->num_hw_mod_clks; - clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL); - if (!clks) - return -ENOMEM; + clks = kmalloc_array(nclks, sizeof(*clks), GFP_KERNEL); + if (!clks) { + error = -ENOMEM; + goto out_err; + } + + if (early_init) + early_priv = priv; + else + dev_set_drvdata(dev, priv); - dev_set_drvdata(dev, priv); priv->clks = clks; priv->num_core_clks = info->num_total_core_clks; priv->num_mod_clks = info->num_hw_mod_clks; @@ -923,16 +932,71 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) for (i = 0; i < nclks; i++) clks[i] = ERR_PTR(-ENOENT); + error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); + if (error) + goto out_err; + + return 0; + +out_err: + kfree(clks); + if (priv->base) + iounmap(priv->base); + kfree(priv); + + return error; +} + +void __init cpg_mssr_early_init(struct device_node *np, + const struct cpg_mssr_info *info) +{ + int error; + int i; + + error = cpg_mssr_common_init(NULL, np, info); + if (error) + return; + + for (i = 0; i < info->num_early_core_clks; i++) + cpg_mssr_register_core_clk(&info->early_core_clks[i], info, + early_priv); + + for (i = 0; i < info->num_early_mod_clks; i++) + cpg_mssr_register_mod_clk(&info->early_mod_clks[i], info, + early_priv); + +} + +static int __init cpg_mssr_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + const struct cpg_mssr_info *info; + struct cpg_mssr_priv *priv; + unsigned int i; + int error; + + info = of_device_get_match_data(dev); + + if (early_priv) { + priv = early_priv; + priv->dev = &pdev->dev; + } else { + error = cpg_mssr_common_init(dev, dev->of_node, info); + } + + if (error) + return error; + + if (!early_priv) + dev_set_drvdata(dev, priv); + for (i = 0; i < info->num_core_clks; i++) cpg_mssr_register_core_clk(&info->core_clks[i], info, priv); for (i = 0; i < info->num_mod_clks; i++) cpg_mssr_register_mod_clk(&info->mod_clks[i], info, priv); - error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); - if (error) - return error; - error = devm_add_action_or_reset(dev, cpg_mssr_del_clk_provider, np); diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index ae0ab0f164f3..cfce0627b5b8 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -119,12 +119,16 @@ struct cpg_mssr_info { unsigned int num_core_clks; unsigned int last_dt_core_clk; unsigned int num_total_core_clks; + const struct cpg_core_clk *early_core_clks; + unsigned int num_early_core_clks; bool stbyctrl; /* Module Clocks */ const struct mssr_mod_clk *mod_clks; unsigned int num_mod_clks; unsigned int num_hw_mod_clks; + const struct mssr_mod_clk *early_mod_clks; + unsigned int num_early_mod_clks; /* Critical Module Clocks that should not be disabled */ const unsigned int *crit_mod_clks; @@ -160,6 +164,8 @@ extern const struct cpg_mssr_info r8a77980_cpg_mssr_info; extern const struct cpg_mssr_info r8a77990_cpg_mssr_info; extern const struct cpg_mssr_info r8a77995_cpg_mssr_info; +void __init cpg_mssr_early_init(struct device_node *np, + const struct cpg_mssr_info *info); /* * Helpers for fixing up clock tables depending on SoC revision From patchwork Fri Sep 21 15:20:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Brandt X-Patchwork-Id: 10610481 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 88D3314BD for ; Fri, 21 Sep 2018 15:21:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 79D722E49F for ; Fri, 21 Sep 2018 15:21:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6D88E2E4C5; Fri, 21 Sep 2018 15:21:17 +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 E95EB2E4A6 for ; Fri, 21 Sep 2018 15:21:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390324AbeIUVKh (ORCPT ); Fri, 21 Sep 2018 17:10:37 -0400 Received: from relmlor3.renesas.com ([210.160.252.173]:36070 "EHLO relmlie2.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2390076AbeIUVKh (ORCPT ); Fri, 21 Sep 2018 17:10:37 -0400 Received: from unknown (HELO relmlir4.idc.renesas.com) ([10.200.68.154]) by relmlie2.idc.renesas.com with ESMTP; 22 Sep 2018 00:21:13 +0900 Received: from relmlii1.idc.renesas.com (relmlii1.idc.renesas.com [10.200.68.65]) by relmlir4.idc.renesas.com (Postfix) with ESMTP id F178389C36; Sat, 22 Sep 2018 00:21:13 +0900 (JST) X-IronPort-AV: E=Sophos;i="5.54,285,1534777200"; d="scan'208";a="291585783" Received: from unknown (HELO rtamta01.rta.renesas.com) ([143.103.48.75]) by relmlii1.idc.renesas.com with ESMTP; 22 Sep 2018 00:21:12 +0900 Received: from ubuntu.localdomain (unknown [143.103.58.47]) by rtamta01.rta.renesas.com (Postfix) with ESMTP id CD0A5200; Fri, 21 Sep 2018 15:21:07 +0000 (UTC) From: Chris Brandt To: Geert Uytterhoeven , Michael Turquette , Stephen Boyd Cc: linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Simon Horman , Chris Brandt Subject: [PATCH 2/2] clk: renesas: r7s9210: Convert some clocks to early Date: Fri, 21 Sep 2018 10:20:54 -0500 Message-Id: <20180921152054.117774-3-chris.brandt@renesas.com> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180921152054.117774-1-chris.brandt@renesas.com> References: <20180921152054.117774-1-chris.brandt@renesas.com> Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The OSTM timer driver for RZ/A2 uses TIMER_OF_DECLARE which requires the ostm module clocks to be registers early in boot. Signed-off-by: Chris Brandt --- drivers/clk/renesas/r7s9210-cpg-mssr.c | 141 +++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 51 deletions(-) diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c index bd1dd4ff2051..eb9103cfa2ac 100644 --- a/drivers/clk/renesas/r7s9210-cpg-mssr.c +++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c @@ -55,25 +55,25 @@ enum clk_ids { static struct cpg_core_clk r7s9210_core_clks[] = { /* External Clock Inputs */ - DEF_INPUT("extal", CLK_EXTAL), + /* ".extal" exists as early clock */ /* Internal Core Clocks */ - DEF_BASE(".main", CLK_MAIN, CLK_TYPE_RZA_MAIN, CLK_EXTAL), - DEF_BASE(".pll", CLK_PLL, CLK_TYPE_RZA_PLL, CLK_MAIN), + /* ".main" exists as early clock */ + /* ".pll" exists as early clock */ /* Core Clock Outputs */ DEF_FIXED("i", R7S9210_CLK_I, CLK_PLL, 2, 1), DEF_FIXED("g", R7S9210_CLK_G, CLK_PLL, 4, 1), DEF_FIXED("b", R7S9210_CLK_B, CLK_PLL, 8, 1), DEF_FIXED("p1", R7S9210_CLK_P1, CLK_PLL, 16, 1), - DEF_FIXED("p1c", R7S9210_CLK_P1C, CLK_PLL, 16, 1), + /* "p1c" exists as early clock */ DEF_FIXED("p0", R7S9210_CLK_P0, CLK_PLL, 32, 1), }; static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = { - DEF_MOD_STB("ostm2", 34, R7S9210_CLK_P1C), - DEF_MOD_STB("ostm1", 35, R7S9210_CLK_P1C), - DEF_MOD_STB("ostm0", 36, R7S9210_CLK_P1C), + /* "ostm2" 36 exists as early clock */ + /* "ostm1" 35 exists as early clock */ + /* "ostm0" 34 exists as early clock */ DEF_MOD_STB("scif4", 43, R7S9210_CLK_P1C), DEF_MOD_STB("scif3", 44, R7S9210_CLK_P1C), @@ -91,6 +91,71 @@ static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = { }; +static struct cpg_core_clk r7s9210_early_core_clks[] = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_RZA_MAIN, CLK_EXTAL), + DEF_BASE(".pll", CLK_PLL, CLK_TYPE_RZA_PLL, CLK_MAIN), + + /* Core Clock Outputs */ + DEF_FIXED("p1c", R7S9210_CLK_P1C, CLK_PLL, 16, 1), +}; + +static const struct mssr_mod_clk r7s9210_early_mod_clks[] __initconst = { + DEF_MOD_STB("ostm2", 34, R7S9210_CLK_P1C), + DEF_MOD_STB("ostm1", 35, R7S9210_CLK_P1C), + DEF_MOD_STB("ostm0", 36, R7S9210_CLK_P1C), +}; + +/* The clock dividers in the table vary based on DT and register settings */ +static void r7s9210_update_clk_table(struct clk *extal_clk, void __iomem *base) +{ + int i; + u16 frqcr; + u8 index; + + /* If EXTAL is above 12MHz, then we know it is Mode 1 */ + if (clk_get_rate(extal_clk) > 12000000) + cpg_mode = 1; + + frqcr = clk_readl(base + CPG_FRQCR) & 0xFFF; + if (frqcr == 0x012) + index = 0; + else if (frqcr == 0x112) + index = 1; + else if (frqcr == 0x212) + index = 2; + else if (frqcr == 0x322) + index = 3; + else if (frqcr == 0x333) + index = 4; + else + BUG_ON(1); /* Illegal FRQCR value */ + + for (i = 0; i < ARRAY_SIZE(r7s9210_core_clks); i++) { + switch (r7s9210_core_clks[i].id) { + case R7S9210_CLK_I: + r7s9210_core_clks[i].div = ratio_tab[index].i; + break; + case R7S9210_CLK_G: + r7s9210_core_clks[i].div = ratio_tab[index].g; + break; + case R7S9210_CLK_B: + r7s9210_core_clks[i].div = ratio_tab[index].b; + break; + case R7S9210_CLK_P1: + case R7S9210_CLK_P1C: + r7s9210_core_clks[i].div = ratio_tab[index].p1; + break; + case R7S9210_CLK_P0: + r7s9210_core_clks[i].div = 32; + break; + } + } +} + struct clk * __init rza2_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, struct clk **clks, void __iomem *base, @@ -99,9 +164,6 @@ struct clk * __init rza2_cpg_clk_register(struct device *dev, struct clk *parent; unsigned int mult = 1; unsigned int div = 1; - u16 frqcr; - u8 index; - int i; parent = clks[core->parent]; if (IS_ERR(parent)) @@ -123,47 +185,8 @@ struct clk * __init rza2_cpg_clk_register(struct device *dev, } /* Adjust the dividers based on the current FRQCR setting */ - if (core->id == CLK_MAIN) { - - /* If EXTAL is above 12MHz, then we know it is Mode 1 */ - if (clk_get_rate(parent) > 12000000) - cpg_mode = 1; - - frqcr = clk_readl(base + CPG_FRQCR) & 0xFFF; - if (frqcr == 0x012) - index = 0; - else if (frqcr == 0x112) - index = 1; - else if (frqcr == 0x212) - index = 2; - else if (frqcr == 0x322) - index = 3; - else if (frqcr == 0x333) - index = 4; - else - BUG_ON(1); /* Illegal FRQCR value */ - - for (i = 0; i < ARRAY_SIZE(r7s9210_core_clks); i++) { - switch (r7s9210_core_clks[i].id) { - case R7S9210_CLK_I: - r7s9210_core_clks[i].div = ratio_tab[index].i; - break; - case R7S9210_CLK_G: - r7s9210_core_clks[i].div = ratio_tab[index].g; - break; - case R7S9210_CLK_B: - r7s9210_core_clks[i].div = ratio_tab[index].b; - break; - case R7S9210_CLK_P1: - case R7S9210_CLK_P1C: - r7s9210_core_clks[i].div = ratio_tab[index].p1; - break; - case R7S9210_CLK_P0: - r7s9210_core_clks[i].div = 32; - break; - } - } - } + if (core->id == CLK_MAIN) + r7s9210_update_clk_table(parent, base); return clk_register_fixed_factor(NULL, core->name, __clk_get_name(parent), 0, mult, div); @@ -181,9 +204,25 @@ const struct cpg_mssr_info r7s9210_cpg_mssr_info __initconst = { .num_mod_clks = ARRAY_SIZE(r7s9210_mod_clks), .num_hw_mod_clks = 11 * 32, /* includes STBCR0 which doesn't exist */ + /* Early Core Clocks */ + .early_core_clks = r7s9210_early_core_clks, + .num_early_core_clks = ARRAY_SIZE(r7s9210_early_core_clks), + + /* Early Module Clocks */ + .early_mod_clks = r7s9210_early_mod_clks, + .num_early_mod_clks = ARRAY_SIZE(r7s9210_early_mod_clks), + /* Callbacks */ .cpg_clk_register = rza2_cpg_clk_register, /* RZ/A2 has Standby Control Registers */ .stbyctrl = true, }; + +static void __init r7s9210_cpg_mssr_early_init(struct device_node *np) +{ + cpg_mssr_early_init(np, &r7s9210_cpg_mssr_info); +} + +CLK_OF_DECLARE_DRIVER(cpg_mstp_clks, "renesas,r7s9210-cpg-mssr", + r7s9210_cpg_mssr_early_init);