From patchwork Mon Jul 22 23:49:19 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Figa X-Patchwork-Id: 2831630 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2F3B6C0319 for ; Mon, 22 Jul 2013 23:52:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2ED192021A for ; Mon, 22 Jul 2013 23:52:23 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id ED54D20208 for ; Mon, 22 Jul 2013 23:52:21 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1V1PsS-0002WT-5a; Mon, 22 Jul 2013 23:50:52 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1V1PsB-0001Dc-5q; Mon, 22 Jul 2013 23:50:35 +0000 Received: from mail-ee0-x22e.google.com ([2a00:1450:4013:c00::22e]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1V1Pre-00017D-GT for linux-arm-kernel@lists.infradead.org; Mon, 22 Jul 2013 23:50:07 +0000 Received: by mail-ee0-f46.google.com with SMTP id d41so4113656eek.33 for ; Mon, 22 Jul 2013 16:49:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=mAfv0rIoYEhZ6+RU8bSfXoEEUOdxKYTosGA1DNiqeLM=; b=IV/PtwXDsjaPkQa4TtdqzHBIM2ehzSFJGmOHs9bpz5bfO4VG8tSO9Lugp3phkPA/oP CoNjzbQ3nwpVDoyMCFWhZqscEwaEiMStOvl3wQlKXCRRcn5mSgT0wkIu8fUJaat80z9G C1XidNYJYtIIV2HKmcgdxUEGU7tAnY5ldAfahAsKYN+/wGhgC0zdy7zpArEcsKnt3HjB PbIH/IZH7krB7Fv1sPXireeLdbwzP0U7DaKvG3Noh9afMPg42oNHorXKR5Ra4Uk/PeRu fwHAaZF0MkM9jjdE/AOnS8weVeG2UCHWNG+/AbyXjsJXvx/yGfXT72CP1zGIAixmg9QG wUNw== X-Received: by 10.14.176.199 with SMTP id b47mr30066577eem.117.1374536977856; Mon, 22 Jul 2013 16:49:37 -0700 (PDT) Received: from flatron.tomeq (87-207-52-162.dynamic.chello.pl. [87.207.52.162]) by mx.google.com with ESMTPSA id n45sm54626864eew.1.2013.07.22.16.49.35 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 22 Jul 2013 16:49:36 -0700 (PDT) From: Tomasz Figa To: linux-samsung-soc@vger.kernel.org Subject: [PATCH v2 2/8] clk: samsung: pll: Add support for PLL6552 and PLL6553 Date: Tue, 23 Jul 2013 01:49:19 +0200 Message-Id: <1374536965-3545-3-git-send-email-tomasz.figa@gmail.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1374536965-3545-1-git-send-email-tomasz.figa@gmail.com> References: <1374536965-3545-1-git-send-email-tomasz.figa@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130722_195003_114753_48AABA4C X-CRM114-Status: GOOD ( 14.96 ) X-Spam-Score: -2.0 (--) Cc: devicetree@vger.kernel.org, Kukjin Kim , Mike Turquette , =?UTF-8?q?Heiko=20St=C3=BCbner?= , Arnd Bergmann , gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, Tomasz Figa , Mark Brown , stern@rowland.harvard.edu, Olof Johansson , Thomas Abraham , Sylwester Nawrocki , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds support for PLL6552 and PLL6553 PLLs present on Samsung S3C64xx SoCs. Signed-off-by: Tomasz Figa Acked-by: Mike Turquette --- drivers/clk/samsung/clk-pll.c | 160 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk-pll.h | 4 ++ 2 files changed, 164 insertions(+) diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 362f12d..698e562 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -337,6 +337,166 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name, } /* + * PLL6552 Clock Type + */ + +#define PLL6552_LOCK_REG 0x00 +#define PLL6552_CON_REG 0x0c + +#define PLL6552_MDIV_MASK 0x3ff +#define PLL6552_PDIV_MASK 0x3f +#define PLL6552_SDIV_MASK 0x7 +#define PLL6552_MDIV_SHIFT 16 +#define PLL6552_PDIV_SHIFT 8 +#define PLL6552_SDIV_SHIFT 0 + +struct samsung_clk_pll6552 { + struct clk_hw hw; + void __iomem *reg_base; +}; + +#define to_clk_pll6552(_hw) container_of(_hw, struct samsung_clk_pll6552, hw) + +static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct samsung_clk_pll6552 *pll = to_clk_pll6552(hw); + u32 mdiv, pdiv, sdiv, pll_con; + u64 fvco = parent_rate; + + pll_con = __raw_readl(pll->reg_base + PLL6552_CON_REG); + mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK; + pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK; + sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK; + + fvco *= mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned long)fvco; +} + +static const struct clk_ops samsung_pll6552_clk_ops = { + .recalc_rate = samsung_pll6552_recalc_rate, +}; + +struct clk * __init samsung_clk_register_pll6552(const char *name, + const char *pname, void __iomem *base) +{ + struct samsung_clk_pll6552 *pll; + struct clk *clk; + struct clk_init_data init; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) { + pr_err("%s: could not allocate pll clk %s\n", __func__, name); + return NULL; + } + + init.name = name; + init.ops = &samsung_pll6552_clk_ops; + init.parent_names = &pname; + init.num_parents = 1; + + pll->hw.init = &init; + pll->reg_base = base; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) { + pr_err("%s: failed to register pll clock %s\n", __func__, + name); + kfree(pll); + } + + if (clk_register_clkdev(clk, name, NULL)) + pr_err("%s: failed to register lookup for %s", __func__, name); + + return clk; +} + +/* + * PLL6553 Clock Type + */ + +#define PLL6553_LOCK_REG 0x00 +#define PLL6553_CON0_REG 0x0c +#define PLL6553_CON1_REG 0x10 + +#define PLL6553_MDIV_MASK 0xff +#define PLL6553_PDIV_MASK 0x3f +#define PLL6553_SDIV_MASK 0x7 +#define PLL6553_KDIV_MASK 0xffff +#define PLL6553_MDIV_SHIFT 16 +#define PLL6553_PDIV_SHIFT 8 +#define PLL6553_SDIV_SHIFT 0 +#define PLL6553_KDIV_SHIFT 0 + +struct samsung_clk_pll6553 { + struct clk_hw hw; + void __iomem *reg_base; +}; + +#define to_clk_pll6553(_hw) container_of(_hw, struct samsung_clk_pll6553, hw) + +static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct samsung_clk_pll6553 *pll = to_clk_pll6553(hw); + u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1; + u64 fvco = parent_rate; + + pll_con0 = __raw_readl(pll->reg_base + PLL6553_CON0_REG); + pll_con1 = __raw_readl(pll->reg_base + PLL6553_CON1_REG); + mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK; + pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK; + sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK; + kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK; + + fvco *= (mdiv << 16) + kdiv; + do_div(fvco, (pdiv << sdiv)); + fvco >>= 16; + + return (unsigned long)fvco; +} + +static const struct clk_ops samsung_pll6553_clk_ops = { + .recalc_rate = samsung_pll6553_recalc_rate, +}; + +struct clk * __init samsung_clk_register_pll6553(const char *name, + const char *pname, void __iomem *base) +{ + struct samsung_clk_pll6553 *pll; + struct clk *clk; + struct clk_init_data init; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) { + pr_err("%s: could not allocate pll clk %s\n", __func__, name); + return NULL; + } + + init.name = name; + init.ops = &samsung_pll6553_clk_ops; + init.parent_names = &pname; + init.num_parents = 1; + + pll->hw.init = &init; + pll->reg_base = base; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) { + pr_err("%s: failed to register pll clock %s\n", __func__, + name); + kfree(pll); + } + + if (clk_register_clkdev(clk, name, NULL)) + pr_err("%s: failed to register lookup for %s", __func__, name); + + return clk; +} + +/* * PLL2550x Clock Type */ diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index f33786e..1d68a68 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -34,6 +34,10 @@ extern struct clk * __init samsung_clk_register_pll45xx(const char *name, extern struct clk * __init samsung_clk_register_pll46xx(const char *name, const char *pname, const void __iomem *con_reg, enum pll46xx_type type); +extern struct clk *samsung_clk_register_pll6552(const char *name, + const char *pname, void __iomem *base); +extern struct clk *samsung_clk_register_pll6553(const char *name, + const char *pname, void __iomem *base); extern struct clk * __init samsung_clk_register_pll2550x(const char *name, const char *pname, const void __iomem *reg_base, const unsigned long offset);