From patchwork Thu Jun 6 07:28:19 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 2677481 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 07393DFE82 for ; Thu, 6 Jun 2013 07:28:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757479Ab3FFH2p (ORCPT ); Thu, 6 Jun 2013 03:28:45 -0400 Received: from kirsty.vergenet.net ([202.4.237.240]:59353 "EHLO kirsty.vergenet.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757113Ab3FFH2n (ORCPT ); Thu, 6 Jun 2013 03:28:43 -0400 Received: from ayumi.isobedori.kobe.vergenet.net (p5212-ipbfp1903kobeminato.hyogo.ocn.ne.jp [114.172.132.212]) by kirsty.vergenet.net (Postfix) with ESMTP id D215E25C048; Thu, 6 Jun 2013 17:28:41 +1000 (EST) Received: by ayumi.isobedori.kobe.vergenet.net (Postfix, from userid 7100) id AB5786CE159; Thu, 6 Jun 2013 16:28:39 +0900 (JST) From: Simon Horman To: Arnd Bergmann , Olof Johansson Cc: linux-sh@vger.kernel.org, arm@kernel.org, linux-arm-kernel@lists.infradead.org, Magnus Damm , Kuninori Morimoto , Simon Horman Subject: [PATCH 06/23] ARM: shmobile: r8a73a4: add pll clocks Date: Thu, 6 Jun 2013 16:28:19 +0900 Message-Id: <1370503716-31155-7-git-send-email-horms+renesas@verge.net.au> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1370503716-31155-1-git-send-email-horms+renesas@verge.net.au> References: <1370503716-31155-1-git-send-email-horms+renesas@verge.net.au> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org From: Kuninori Morimoto PLL clocks are basis clock for other clock. Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/clock-r8a73a4.c | 101 +++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c index 42942b4..2be592f 100644 --- a/arch/arm/mach-shmobile/clock-r8a73a4.c +++ b/arch/arm/mach-shmobile/clock-r8a73a4.c @@ -33,6 +33,14 @@ #define SMSTPCR5 0xe6150144 #define CKSCR 0xE61500C0 +#define PLLECR 0xE61500D0 +#define PLL1CR 0xE6150028 +#define PLL2CR 0xE615002C +#define PLL2SCR 0xE61501F4 +#define PLL2HCR 0xE61501E4 + + +#define CPG_MAP(o) ((o - CPG_BASE) + cpg_mapping.base) static struct clk_mapping cpg_mapping = { .phys = CPG_BASE, @@ -71,6 +79,86 @@ SH_FIXED_RATIO_CLK(extal1_div2_clk, extal1_clk, div2); SH_FIXED_RATIO_CLK(extal2_div2_clk, extal2_clk, div2); SH_FIXED_RATIO_CLK(extal2_div4_clk, extal2_clk, div4); +/* + * PLL clocks + */ +static struct clk *pll_parent_main[] = { + [0] = &main_clk, + [1] = &main_div2_clk +}; + +static struct clk *pll_parent_main_extal[8] = { + [0] = &main_div2_clk, + [1] = &extal2_div2_clk, + [3] = &extal2_div4_clk, + [4] = &main_clk, + [5] = &extal2_clk, +}; + +static unsigned long pll_recalc(struct clk *clk) +{ + unsigned long mult = 1; + + if (ioread32(CPG_MAP(PLLECR)) & (1 << clk->enable_bit)) + mult = (((ioread32(clk->mapped_reg) >> 24) & 0x7f) + 1); + + return clk->parent->rate * mult; +} + +static int pll_set_parent(struct clk *clk, struct clk *parent) +{ + u32 val; + int i, ret; + + if (!clk->parent_table || !clk->parent_num) + return -EINVAL; + + /* Search the parent */ + for (i = 0; i < clk->parent_num; i++) + if (clk->parent_table[i] == parent) + break; + + if (i == clk->parent_num) + return -ENODEV; + + ret = clk_reparent(clk, parent); + if (ret < 0) + return ret; + + val = ioread32(clk->mapped_reg) & + ~(((1 << clk->src_width) - 1) << clk->src_shift); + + iowrite32(val | i << clk->src_shift, clk->mapped_reg); + + return 0; +} + +static struct sh_clk_ops pll_clk_ops = { + .recalc = pll_recalc, + .set_parent = pll_set_parent, +}; + +#define PLL_CLOCK(name, p, pt, w, s, reg, e) \ + static struct clk name = { \ + .ops = &pll_clk_ops, \ + .flags = CLK_ENABLE_ON_INIT, \ + .parent = p, \ + .parent_table = pt, \ + .parent_num = ARRAY_SIZE(pt), \ + .src_width = w, \ + .src_shift = s, \ + .enable_reg = (void __iomem *)reg, \ + .enable_bit = e, \ + .mapping = &cpg_mapping, \ + } + +PLL_CLOCK(pll1_clk, &main_clk, pll_parent_main, 1, 7, PLL1CR, 1); +PLL_CLOCK(pll2_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2CR, 2); +PLL_CLOCK(pll2s_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2SCR, 4); +PLL_CLOCK(pll2h_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2HCR, 5); + +SH_FIXED_RATIO_CLK(pll1_div2_clk, pll1_clk, div2); + static struct clk *main_clks[] = { &extalr_clk, &extal1_clk, @@ -80,6 +168,11 @@ static struct clk *main_clks[] = { &extal2_div4_clk, &main_clk, &main_div2_clk, + &pll1_clk, + &pll1_div2_clk, + &pll2_clk, + &pll2s_clk, + &pll2h_clk, }; enum { @@ -106,6 +199,14 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("extal2_div2", &extal2_div2_clk), CLKDEV_CON_ID("extal2_div4", &extal2_div4_clk), + /* pll clock */ + CLKDEV_CON_ID("pll1", &pll1_clk), + CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk), + CLKDEV_CON_ID("pll2", &pll2_clk), + CLKDEV_CON_ID("pll2s", &pll2s_clk), + CLKDEV_CON_ID("pll2h", &pll2h_clk), + + /* MSTP */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]),