From patchwork Wed May 29 13:37:55 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vikas C Sajjan X-Patchwork-Id: 17265 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-yh0-f71.google.com (mail-yh0-f71.google.com [209.85.213.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 5954D25D81 for ; Wed, 29 May 2013 13:38:35 +0000 (UTC) Received: by mail-yh0-f71.google.com with SMTP id a41sf7613564yho.10 for ; Wed, 29 May 2013 06:38:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:x-beenthere:x-forwarded-to:x-forwarded-for :delivered-to:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-google-group-id:list-post:list-help:list-archive:list-unsubscribe; bh=UHTSRksPN+elmlZ8kHeFB8iyaf58JgoiZfIE0r81N1M=; b=V1cV38yW98hZMwWe1SnAj12MDUO/kT2gUmMHquYmWm2a3Obm1V6gqo+3ekKzPv0/5F m71dO6vquTPN/elTpPEcjFKKxLNHpxYJQ58rr5O13a+ymQwPKRMyffsnC+DVeXFs4Za9 DmMc2HTySc3tTfQ2pXAhoTATz4fm5K1j4rT9smxxgKTykkm5kaxzg7T6PpJjSR3Zmgs0 5GShC0hBv61+VX1M4XEN6HlF4L3Tj9jOb0zL37sI7VtyrXvA13aJKAq2XJPHVZ+rz4jX x9WyxC31FTQeBskF1YBbC69ipgDD6XxvrorLKJB89Cwvp++8nf2rRbXyV0tDuxuA4dew tRvw== X-Received: by 10.224.200.202 with SMTP id ex10mr1742405qab.8.1369834714839; Wed, 29 May 2013 06:38:34 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.96.137 with SMTP id ds9ls3619397qeb.73.gmail; Wed, 29 May 2013 06:38:34 -0700 (PDT) X-Received: by 10.220.158.135 with SMTP id f7mr1554985vcx.34.1369834714663; Wed, 29 May 2013 06:38:34 -0700 (PDT) Received: from mail-vb0-x232.google.com (mail-vb0-x232.google.com [2607:f8b0:400c:c02::232]) by mx.google.com with ESMTPS id l10si21641920vet.1.2013.05.29.06.38.34 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 29 May 2013 06:38:34 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c02::232 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c02::232; Received: by mail-vb0-f50.google.com with SMTP id w16so6160004vbb.23 for ; Wed, 29 May 2013 06:38:34 -0700 (PDT) X-Received: by 10.58.225.228 with SMTP id rn4mr1548816vec.35.1369834714550; Wed, 29 May 2013 06:38:34 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.229.199 with SMTP id jj7csp11800vcb; Wed, 29 May 2013 06:38:34 -0700 (PDT) X-Received: by 10.66.80.40 with SMTP id o8mr3320090pax.214.1369834713507; Wed, 29 May 2013 06:38:33 -0700 (PDT) Received: from mail-pb0-x231.google.com (mail-pb0-x231.google.com [2607:f8b0:400e:c01::231]) by mx.google.com with ESMTPS id nb4si26392744pbc.234.2013.05.29.06.38.33 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 29 May 2013 06:38:33 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400e:c01::231 is neither permitted nor denied by best guess record for domain of vikas.sajjan@linaro.org) client-ip=2607:f8b0:400e:c01::231; Received: by mail-pb0-f49.google.com with SMTP id rp8so9234504pbb.36 for ; Wed, 29 May 2013 06:38:33 -0700 (PDT) X-Received: by 10.68.185.194 with SMTP id fe2mr2290196pbc.45.1369834713131; Wed, 29 May 2013 06:38:33 -0700 (PDT) Received: from localhost.localdomain ([115.113.119.130]) by mx.google.com with ESMTPSA id b7sm37356944pba.39.2013.05.29.06.38.28 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 29 May 2013 06:38:32 -0700 (PDT) From: Vikas Sajjan To: linux-samsung-soc@vger.kernel.org Cc: kgene.kim@samsung.com, t.figa@samsung.com, yadi.brar01@gmail.com, dianders@chromium.org, mturquette@linaro.org, linux-arm-kernel@lists.infradead.org, thomas.abraham@linaro.org, patches@linaro.org, linaro-kernel@lists.linaro.org Subject: [PATCH v2 3/5] clk: samsung: Add set_rate() clk_ops for PLL35xx Date: Wed, 29 May 2013 19:07:55 +0530 Message-Id: <1369834677-20312-4-git-send-email-vikas.sajjan@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1369834677-20312-1-git-send-email-vikas.sajjan@linaro.org> References: <1369834677-20312-1-git-send-email-vikas.sajjan@linaro.org> X-Gm-Message-State: ALoCoQmYia1iLxqFPQFf/JzQ4KObh4/YetlLpN99bli35FHBzFcMsmp+3ClTyQMFF2NfZzzN593c X-Original-Sender: vikas.sajjan@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c02::232 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Yadwinder Singh Brar This patch add set_rate() and round_rate() for PLL35xx Signed-off-by: Yadwinder Singh Brar Reviewed-by: Doug Anderson --- drivers/clk/samsung/clk-pll.c | 103 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 4b3b3f5..1fba7ef 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -27,6 +27,36 @@ struct samsung_clk_pll { #define pll_writel(pll, val, offset) \ __raw_writel(val, (void __iomem *)(pll->base + (offset))); +static const struct samsung_pll_rate_table *samsung_get_pll_settings( + struct samsung_clk_pll *pll, unsigned long rate) +{ + const struct samsung_pll_rate_table *rate_table = pll->rate_table; + int i; + + for (i = 0; i < pll->rate_count; i++) { + if (rate == rate_table[i].rate) + return &rate_table[i]; + } + + return NULL; +} + +static long samsung_pll_round_rate(struct clk_hw *hw, + unsigned long drate, unsigned long *prate) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + const struct samsung_pll_rate_table *rate_table = pll->rate_table; + int i; + + /* Assumming rate_table is in descending order */ + for (i = 0; i < pll->rate_count; i++) { + if (drate >= rate_table[i].rate) + return rate_table[i].rate; + } + + /* return minimum supported value */ + return rate_table[i - 1].rate; +} /* * PLL35xx Clock Type */ @@ -34,12 +64,17 @@ struct samsung_clk_pll { #define PLL35XX_CON0_OFFSET 0x100 #define PLL35XX_CON1_OFFSET 0x104 +/* Maximum lock time can be 270 * PDIV cycles */ +#define PLL35XX_LOCK_FACTOR 270 + #define PLL35XX_MDIV_MASK (0x3FF) #define PLL35XX_PDIV_MASK (0x3F) #define PLL35XX_SDIV_MASK (0x7) +#define PLL35XX_LOCK_STAT_MASK (0x1) #define PLL35XX_MDIV_SHIFT (16) #define PLL35XX_PDIV_SHIFT (8) #define PLL35XX_SDIV_SHIFT (0) +#define PLL35XX_LOCK_STAT_SHIFT (29) static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) @@ -59,8 +94,70 @@ static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw, return (unsigned long)fvco; } +static inline bool samsung_pll35xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con) +{ + if ((mdiv != ((pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK)) || + (pdiv != ((pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK))) + return 1; + else + return 0; +} + +static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + const struct samsung_pll_rate_table *rate; + u32 tmp; + + /* Get required rate settings from table */ + rate = samsung_get_pll_settings(pll, drate); + if (!rate) { + pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, + drate, __clk_get_name(hw->clk)); + return -EINVAL; + } + + tmp = pll_readl(pll, PLL35XX_CON0_OFFSET); + + if (!(samsung_pll35xx_mp_change(rate->mdiv, rate->pdiv, tmp))) { + /* If only s change, change just s value only*/ + tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT); + tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT; + pll_writel(pll, tmp, PLL35XX_CON0_OFFSET); + } else { + /* Set PLL lock time. */ + pll_writel(pll, rate->pdiv * PLL35XX_LOCK_FACTOR, + PLL35XX_LOCK_OFFSET); + + /* Change PLL PMS values */ + tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) | + (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) | + (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT)); + tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) | + (rate->pdiv << PLL35XX_PDIV_SHIFT) | + (rate->sdiv << PLL35XX_SDIV_SHIFT); + pll_writel(pll, tmp, PLL35XX_CON0_OFFSET); + + /* wait_lock_time */ + do { + cpu_relax(); + tmp = pll_readl(pll, PLL35XX_CON0_OFFSET); + } while (!(tmp & (PLL35XX_LOCK_STAT_MASK + << PLL35XX_LOCK_STAT_SHIFT))); + } + + return 0; +} + static const struct clk_ops samsung_pll35xx_clk_ops = { .recalc_rate = samsung_pll35xx_recalc_rate, + .round_rate = samsung_pll_round_rate, + .set_rate = samsung_pll35xx_set_rate, +}; + +static const struct clk_ops samsung_pll35xx_clk_min_ops = { + .recalc_rate = samsung_pll35xx_recalc_rate, }; struct clk * __init samsung_clk_register_pll35xx(const char *name, @@ -79,11 +176,15 @@ struct clk * __init samsung_clk_register_pll35xx(const char *name, } init.name = name; - init.ops = &samsung_pll35xx_clk_ops; init.flags = CLK_GET_RATE_NOCACHE; init.parent_names = &pname; init.num_parents = 1; + if (rate_table && rate_count) + init.ops = &samsung_pll35xx_clk_ops; + else + init.ops = &samsung_pll35xx_clk_min_ops; + pll->hw.init = &init; pll->base = base; pll->rate_table = rate_table;