From: Lucas Stach <dev@lynxeye.de>
To: barebox@lists.infradead.org
Subject: [PATCH v2 10/19] clk: tegra: add PLLE setup functions
Date: Sat, 4 Oct 2014 19:40:16 +0200 [thread overview]
Message-ID: <1412444425-2569-11-git-send-email-dev@lynxeye.de> (raw)
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
From: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
arch/arm/mach-tegra/include/mach/tegra30-car.h | 2 +
drivers/clk/tegra/clk-pll.c | 116 +++++++++++++++++++++++++
drivers/clk/tegra/clk.h | 6 ++
3 files changed, 124 insertions(+)
diff --git a/arch/arm/mach-tegra/include/mach/tegra30-car.h b/arch/arm/mach-tegra/include/mach/tegra30-car.h
index c8f6c9f..7fb2238 100644
--- a/arch/arm/mach-tegra/include/mach/tegra30-car.h
+++ b/arch/arm/mach-tegra/include/mach/tegra30-car.h
@@ -33,3 +33,5 @@
#define CRC_RST_DEV_V_CLR 0x434
#define CRC_CLK_OUT_ENB_V_SET 0x440
+
+#define CRC_PLLE_AUX 0x48c
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index c18c67f..bff5651 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -17,12 +17,15 @@
*/
#include <common.h>
+#include <clock.h>
#include <io.h>
#include <malloc.h>
#include <asm-generic/div64.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <mach/iomap.h>
+
#include "clk.h"
#define PLL_BASE_BYPASS BIT(31)
@@ -393,6 +396,108 @@ const struct clk_ops tegra_clk_pll_ops = {
.set_rate = clk_pll_set_rate,
};
+static unsigned long clk_plle_recalc_rate(struct clk *hw,
+ unsigned long parent_rate)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ u32 val = pll_readl_base(pll);
+ u32 divn = 0, divm = 0, divp = 0;
+ u64 rate = parent_rate;
+
+ divp = (val >> 16) & 0x3f;
+ divn = (val >> 8) & (0xff);
+ divm = (val >> 0) & (0xff);
+ divm *= divp;
+
+ rate *= divn;
+ do_div(rate, divm);
+ return rate;
+}
+
+static int clk_plle_training(struct tegra_clk_pll *pll)
+{
+ u32 val;
+
+ /*
+ * PLLE is already disabled, and setup cleared;
+ * create falling edge on PLLE IDDQ input.
+ */
+ val = readl(TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+ val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+ writel(val, TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+
+ val = readl(TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+ val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
+ writel(val, TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+
+ val = readl(TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+ val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+ writel(val, TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+
+ return wait_on_timeout(100 * MSECOND,
+ (pll_readl_misc(pll) & PLLE_MISC_READY));
+}
+
+static int clk_plle_enable(struct clk *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ unsigned long input_rate = clk_get_rate(clk_get_parent(hw));
+ struct tegra_clk_pll_freq_table sel;
+ u32 val;
+ int err;
+
+ if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate))
+ return -EINVAL;
+
+ clk_pll_disable(hw);
+
+ val = pll_readl_misc(pll);
+ val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
+ pll_writel_misc(val, pll);
+
+ val = pll_readl_misc(pll);
+ if (!(val & PLLE_MISC_READY)) {
+ err = clk_plle_training(pll);
+ if (err)
+ return err;
+ }
+
+ /* configure dividers */
+ val = pll_readl_base(pll);
+ val &= ~(0x3fffff);
+ val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
+ val |= sel.m << 0;
+ val |= sel.n << 8;
+ val |= sel.p << 16;
+ val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
+ pll_writel_base(val, pll);
+
+ val = pll_readl_misc(pll);
+ val |= PLLE_MISC_SETUP_VALUE;
+ val |= PLLE_MISC_LOCK_ENABLE;
+ pll_writel_misc(val, pll);
+
+ val = readl(pll->clk_base + PLLE_SS_CTRL);
+ val |= PLLE_SS_DISABLE;
+ writel(val, pll->clk_base + PLLE_SS_CTRL);
+
+ val = pll_readl_base(pll);
+ val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+ pll_writel_base(val, pll);
+
+ clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->base_reg,
+ pll->params->lock_bit_idx);
+
+ return 0;
+}
+
+const struct clk_ops tegra_clk_plle_ops = {
+ .recalc_rate = clk_plle_recalc_rate,
+ .is_enabled = clk_pll_is_enabled,
+ .disable = clk_pll_disable,
+ .enable = clk_plle_enable,
+};
+
static struct clk *_tegra_clk_register_pll(const char *name,
const char *parent_name, void __iomem *clk_base,
unsigned long flags, unsigned long fixed_rate,
@@ -447,3 +552,14 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
flags, fixed_rate, pll_params, pll_flags, freq_table,
&tegra_clk_pll_ops);
}
+
+struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
+ void __iomem *clk_base,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table)
+{
+ return _tegra_clk_register_pll(name, parent_name, clk_base,
+ flags, fixed_rate, pll_params, pll_flags, freq_table,
+ &tegra_clk_plle_ops);
+}
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index d5d0730..85777a8 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -101,6 +101,12 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
struct tegra_clk_pll_params *pll_params, u8 pll_flags,
struct tegra_clk_pll_freq_table *freq_table);
+struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
+ void __iomem *clk_base,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table);
+
/* struct tegra_clk_pll_out - PLL output divider */
struct tegra_clk_pll_out {
struct clk hw;
--
1.9.3
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2014-10-04 17:35 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-04 17:40 [PATCH v2 00/19] PCI and Tegra series revamp Lucas Stach
2014-10-04 17:40 ` [PATCH v2 01/19] MIPS: malta: fix pci IO resource assignment Lucas Stach
2014-10-04 17:40 ` [PATCH v2 02/19] pci: split out device init Lucas Stach
2014-10-04 17:40 ` [PATCH v2 03/19] pci: add resource enum Lucas Stach
2014-10-04 17:40 ` [PATCH v2 04/19] pci: properly populate prefetchable BARs Lucas Stach
2014-10-04 17:40 ` [PATCH v2 05/19] pci: setup bridges and traverse buses behind them Lucas Stach
2014-10-04 17:40 ` [PATCH v2 06/19] pci: defer device registration until after bridge setup Lucas Stach
2014-10-04 17:40 ` [PATCH v2 07/19] pci: prettyprint device names Lucas Stach
2014-10-04 17:40 ` [PATCH v2 08/19] pci: track parent<->child relationship Lucas Stach
2014-10-04 17:40 ` [PATCH v2 09/19] commands: lspci: go down into subordinate busses Lucas Stach
2014-10-04 17:40 ` Lucas Stach [this message]
2014-10-04 17:40 ` [PATCH v2 11/19] clk: tegra30: add PCIe clocks Lucas Stach
2014-10-04 17:40 ` [PATCH v2 12/19] i2c: tegra: move to fs initcall Lucas Stach
2014-10-04 17:40 ` [PATCH v2 13/19] ARM: tegra: beaver: enable PEX voltage rail Lucas Stach
2014-10-04 17:40 ` [PATCH v2 14/19] tegra: pmc: add powerdomain handling Lucas Stach
2014-10-04 17:40 ` [PATCH v2 15/19] of: import pci range parser from linux Lucas Stach
2014-10-04 17:40 ` [PATCH v2 16/19] pci: add Tegra host controller driver Lucas Stach
2014-10-04 17:40 ` [PATCH v2 17/19] ARM: tegra: advertise PCI support Lucas Stach
2014-10-04 17:40 ` [PATCH v2 18/19] net: add rtl8169 driver Lucas Stach
2014-10-04 17:40 ` [PATCH v2 19/19] ARM: tegra: enable network related options in defconfig Lucas Stach
2014-10-08 6:39 ` [PATCH v2 00/19] PCI and Tegra series revamp Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1412444425-2569-11-git-send-email-dev@lynxeye.de \
--to=dev@lynxeye.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox