* [PATCH v5 00/10] Tegra114 clockframework @ 2013-02-01 10:18 Peter De Schrijver [not found] ` <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> ` (2 more replies) 0 siblings, 3 replies; 34+ messages in thread From: Peter De Schrijver @ 2013-02-01 10:18 UTC (permalink / raw) To: pdeschrijver-DDmLM1+adcrQT0dZR+AlfA Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Prashant Gaikwad, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-tegra-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r This is the fifth version of the Tegra114 clockframework. It is based on the for-next branch of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra.git and http://www.spinics.net/lists/arm-kernel/msg220452.html. It has been boottested on Pluto. Changes from v4: * Split the new PLL types patch into smaller patches * Fix some bugs in the PLL patches Changes from v3: * Merge with for-next branch * Provide empty tegra_cpu_car_ops to make SMP boot not crash Changes from v2: * Added missing PLLs * Added bindings to tegra114.dtsi * Moved the table patch for clk-mux.c to 'clk: add table lookup to mux' * Bugfixes Changes from v1: * Remove SATA and PCIe clocks. They don't appear in the internal TRM, so I assume they don't exist. * Rebase on top of Hiroshi's latest Tegra114 patches * More generic mux code. This is necessary for the AHUB and DAM clocks. TODO: * Remove clk_register_clkdev() where possible * PLL clock init functions are incomplete and/or need refactoring * Superclocks are missing * The audio clocks are almost the same then Tegra30. Refactor the code to avoid duplication. * Should blink and blink_override be clocks? Peter De Schrijver (10): clk: tegra: Refactor PLL programming code clk: tegra: Add TEGRA_PLL_BYPASS flag clk: tegra: Add PLL post divider table clk: tegra: Add new fields and PLL types for Tegra114 clk: tegra: Add flags to tegra_clk_periph() clk: tegra: Workaround for Tegra114 MSENC problem ARM: tegra: Define Tegra114 CAR binding ARM: dt: Add references to tegra_car clocks clk: tegra: Implement clocks for Tegra114 clk: tegra: devicetree match for nvidia,tegra114-car .../bindings/clock/nvidia,tegra114-car.txt | 311 +++ arch/arm/boot/dts/tegra114.dtsi | 7 +- drivers/clk/tegra/Makefile | 1 + drivers/clk/tegra/clk-periph-gate.c | 9 + drivers/clk/tegra/clk-periph.c | 11 +- drivers/clk/tegra/clk-pll.c | 940 +++++++++- drivers/clk/tegra/clk-tegra114.c | 2002 ++++++++++++++++++++ drivers/clk/tegra/clk-tegra20.c | 153 +- drivers/clk/tegra/clk-tegra30.c | 243 ++-- drivers/clk/tegra/clk.c | 1 + drivers/clk/tegra/clk.h | 85 +- 11 files changed, 3481 insertions(+), 282 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt create mode 100644 drivers/clk/tegra/clk-tegra114.c ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>]
* [PATCH v5 01/10] clk: tegra: Refactor PLL programming code [not found] ` <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> @ 2013-02-01 10:18 ` Peter De Schrijver [not found] ` <1359713962-16822-2-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-01 10:18 ` [PATCH v5 02/10] clk: tegra: Add TEGRA_PLL_BYPASS flag Peter De Schrijver ` (6 subsequent siblings) 7 siblings, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-01 10:18 UTC (permalink / raw) To: pdeschrijver-DDmLM1+adcrQT0dZR+AlfA Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Prashant Gaikwad, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-tegra-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r Refactor the PLL programming code to make it useable by the new PLL types introduced by Tegra114. The following changes were done: * Split programming the PLL into updating m,n,p and updating cpcon * Move locking from _update_pll_cpcon() to clk_pll_set_rate() * Introduce _get_pll_mnp() helper * Move check for identical m,n,p values to clk_pll_set_rate() * struct tegra_clk_pll_freq_table will always contain the values as defined by the hardware. * Simplify the arguments to clk_pll_wait_for_lock() Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> --- drivers/clk/tegra/clk-pll.c | 178 +++++++++++++++++------------ drivers/clk/tegra/clk-tegra20.c | 144 ++++++++++++------------ drivers/clk/tegra/clk-tegra30.c | 234 +++++++++++++++++++------------------- 3 files changed, 294 insertions(+), 262 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 165f247..912c977 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -113,20 +113,23 @@ static void clk_pll_enable_lock(struct tegra_clk_pll *pll) pll_writel_misc(val, pll); } -static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll, - void __iomem *lock_addr, u32 lock_bit_idx) +static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll) { int i; - u32 val; + u32 val, lock_bit; + void __iomem *lock_addr; if (!(pll->flags & TEGRA_PLL_USE_LOCK)) { udelay(pll->params->lock_delay); return 0; } + lock_addr = pll->clk_base + pll->params->base_reg; + lock_bit = BIT(pll->params->lock_bit_idx); + for (i = 0; i < pll->params->lock_delay; i++) { val = readl_relaxed(lock_addr); - if (val & BIT(lock_bit_idx)) { + if (val & lock_bit) { udelay(PLL_POST_LOCK_DELAY); return 0; } @@ -155,7 +158,7 @@ static int clk_pll_is_enabled(struct clk_hw *hw) return val & PLL_BASE_ENABLE ? 1 : 0; } -static int _clk_pll_enable(struct clk_hw *hw) +static void _clk_pll_enable(struct clk_hw *hw) { struct tegra_clk_pll *pll = to_clk_pll(hw); u32 val; @@ -172,11 +175,6 @@ static int _clk_pll_enable(struct clk_hw *hw) val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); } - - clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->base_reg, - pll->params->lock_bit_idx); - - return 0; } static void _clk_pll_disable(struct clk_hw *hw) @@ -204,7 +202,9 @@ static int clk_pll_enable(struct clk_hw *hw) if (pll->lock) spin_lock_irqsave(pll->lock, flags); - ret = _clk_pll_enable(hw); + _clk_pll_enable(hw); + + ret = clk_pll_wait_for_lock(pll); if (pll->lock) spin_unlock_irqrestore(pll->lock, flags); @@ -241,8 +241,6 @@ static int _get_table_rate(struct clk_hw *hw, if (sel->input_rate == 0) return -EINVAL; - BUG_ON(sel->p < 1); - cfg->input_rate = sel->input_rate; cfg->output_rate = sel->output_rate; cfg->m = sel->m; @@ -290,88 +288,109 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, cfg->output_rate <<= 1) p_div++; - cfg->p = 1 << p_div; + cfg->p = p_div; cfg->m = parent_rate / cfreq; cfg->n = cfg->output_rate / cfreq; cfg->cpcon = OUT_OF_TABLE_CPCON; if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) || - cfg->p > divp_max(pll) || cfg->output_rate > pll->params->vco_max) { + (1 << p_div) > divp_max(pll) + || cfg->output_rate > pll->params->vco_max) { pr_err("%s: Failed to set %s rate %lu\n", __func__, __clk_get_name(hw->clk), rate); return -EINVAL; } + if (pll->flags & TEGRA_PLLU) + cfg->p ^= 1; + return 0; } -static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, - unsigned long rate) +static void _update_pll_mnp(struct tegra_clk_pll *pll, + struct tegra_clk_pll_freq_table *cfg) { - struct tegra_clk_pll *pll = to_clk_pll(hw); - unsigned long flags = 0; - u32 divp, val, old_base; - int state; - - divp = __ffs(cfg->p); - - if (pll->flags & TEGRA_PLLU) - divp ^= 1; + u32 val; - if (pll->lock) - spin_lock_irqsave(pll->lock, flags); + val = pll_readl_base(pll); - old_base = val = pll_readl_base(pll); val &= ~((divm_mask(pll) << pll->divm_shift) | (divn_mask(pll) << pll->divn_shift) | (divp_mask(pll) << pll->divp_shift)); val |= ((cfg->m << pll->divm_shift) | (cfg->n << pll->divn_shift) | - (divp << pll->divp_shift)); - if (val == old_base) { - if (pll->lock) - spin_unlock_irqrestore(pll->lock, flags); - return 0; + (cfg->p << pll->divp_shift)); + + pll_writel_base(val, pll); +} + +static void _get_pll_mnp(struct tegra_clk_pll *pll, + struct tegra_clk_pll_freq_table *cfg) +{ + u32 val; + + val = pll_readl_base(pll); + + cfg->m = (val >> pll->divm_shift) & (divm_mask(pll)); + cfg->n = (val >> pll->divn_shift) & (divn_mask(pll)); + cfg->p = (val >> pll->divp_shift) & (divp_mask(pll)); +} + +static void _update_pll_cpcon(struct tegra_clk_pll *pll, + struct tegra_clk_pll_freq_table *cfg, + unsigned long rate) +{ + u32 val; + + val = pll_readl_misc(pll); + + val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT); + val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT; + + if (pll->flags & TEGRA_PLL_SET_LFCON) { + val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT); + if (cfg->n >= PLLDU_LFCON_SET_DIVN) + val |= 1 << PLL_MISC_LFCON_SHIFT; + } else if (pll->flags & TEGRA_PLL_SET_DCCON) { + val &= ~(1 << PLL_MISC_DCCON_SHIFT); + if (rate >= (pll->params->vco_max >> 1)) + val |= 1 << PLL_MISC_DCCON_SHIFT; } + pll_writel_misc(val, pll); +} + +static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, + unsigned long rate) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + int state, ret = 0; + state = clk_pll_is_enabled(hw); - if (state) { + if (state) _clk_pll_disable(hw); - val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); - } - pll_writel_base(val, pll); - if (pll->flags & TEGRA_PLL_HAS_CPCON) { - val = pll_readl_misc(pll); - val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT); - val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT; - if (pll->flags & TEGRA_PLL_SET_LFCON) { - val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT); - if (cfg->n >= PLLDU_LFCON_SET_DIVN) - val |= 0x1 << PLL_MISC_LFCON_SHIFT; - } else if (pll->flags & TEGRA_PLL_SET_DCCON) { - val &= ~(0x1 << PLL_MISC_DCCON_SHIFT); - if (rate >= (pll->params->vco_max >> 1)) - val |= 0x1 << PLL_MISC_DCCON_SHIFT; - } - pll_writel_misc(val, pll); - } + _update_pll_mnp(pll, cfg); - if (pll->lock) - spin_unlock_irqrestore(pll->lock, flags); + if (pll->flags & TEGRA_PLL_HAS_CPCON) + _update_pll_cpcon(pll, cfg, rate); - if (state) - clk_pll_enable(hw); + if (state) { + _clk_pll_enable(hw); + ret = clk_pll_wait_for_lock(pll); + } - return 0; + return ret; } static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct tegra_clk_pll *pll = to_clk_pll(hw); - struct tegra_clk_pll_freq_table cfg; + struct tegra_clk_pll_freq_table cfg, old_cfg; + unsigned long flags = 0; + int ret = 0; if (pll->flags & TEGRA_PLL_FIXED) { if (rate != pll->fixed_rate) { @@ -387,7 +406,18 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, _calc_rate(hw, &cfg, rate, parent_rate)) return -EINVAL; - return _program_pll(hw, &cfg, rate); + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + _get_pll_mnp(pll, &old_cfg); + + if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_cfg.p != cfg.p) + ret = _program_pll(hw, &cfg, rate); + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); + + return ret; } static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, @@ -409,7 +439,7 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, return -EINVAL; output_rate *= cfg.n; - do_div(output_rate, cfg.m * cfg.p); + do_div(output_rate, cfg.m * (1 << cfg.p)); return output_rate; } @@ -418,10 +448,12 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *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; + struct tegra_clk_pll_freq_table cfg; + u32 val; u64 rate = parent_rate; + val = pll_readl_base(pll); + if (val & PLL_BASE_BYPASS) return parent_rate; @@ -435,16 +467,16 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, return pll->fixed_rate; } - divp = (val >> pll->divp_shift) & (divp_mask(pll)); + _get_pll_mnp(pll, &cfg); + if (pll->flags & TEGRA_PLLU) - divp ^= 1; + cfg.p ^= 1; - divn = (val >> pll->divn_shift) & (divn_mask(pll)); - divm = (val >> pll->divm_shift) & (divm_mask(pll)); - divm *= (1 << divp); + cfg.m *= 1 << cfg.p; + + rate *= cfg.n; + do_div(rate, cfg.m); - rate *= divn; - do_div(rate, divm); return rate; } @@ -538,8 +570,8 @@ static int clk_plle_enable(struct clk_hw *hw) val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE); pll_writel_base(val, pll); - clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->misc_reg, - pll->params->lock_bit_idx); + clk_pll_wait_for_lock(pll); + return 0; } diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 5d41569..30bd3fd 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -247,125 +247,125 @@ static struct clk *clks[clk_max]; static struct clk_onecell_data clk_data; static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { - { 12000000, 600000000, 600, 12, 1, 8 }, - { 13000000, 600000000, 600, 13, 1, 8 }, - { 19200000, 600000000, 500, 16, 1, 6 }, - { 26000000, 600000000, 600, 26, 1, 8 }, + { 12000000, 600000000, 600, 12, 0, 8 }, + { 13000000, 600000000, 600, 13, 0, 8 }, + { 19200000, 600000000, 500, 16, 0, 6 }, + { 26000000, 600000000, 600, 26, 0, 8 }, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { - { 12000000, 666000000, 666, 12, 1, 8}, - { 13000000, 666000000, 666, 13, 1, 8}, - { 19200000, 666000000, 555, 16, 1, 8}, - { 26000000, 666000000, 666, 26, 1, 8}, - { 12000000, 600000000, 600, 12, 1, 8}, - { 13000000, 600000000, 600, 13, 1, 8}, - { 19200000, 600000000, 375, 12, 1, 6}, - { 26000000, 600000000, 600, 26, 1, 8}, + { 12000000, 666000000, 666, 12, 0, 8}, + { 13000000, 666000000, 666, 13, 0, 8}, + { 19200000, 666000000, 555, 16, 0, 8}, + { 26000000, 666000000, 666, 26, 0, 8}, + { 12000000, 600000000, 600, 12, 0, 8}, + { 13000000, 600000000, 600, 13, 0, 8}, + { 19200000, 600000000, 375, 12, 0, 6}, + { 26000000, 600000000, 600, 26, 0, 8}, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { - { 12000000, 216000000, 432, 12, 2, 8}, - { 13000000, 216000000, 432, 13, 2, 8}, - { 19200000, 216000000, 90, 4, 2, 1}, - { 26000000, 216000000, 432, 26, 2, 8}, - { 12000000, 432000000, 432, 12, 1, 8}, - { 13000000, 432000000, 432, 13, 1, 8}, - { 19200000, 432000000, 90, 4, 1, 1}, - { 26000000, 432000000, 432, 26, 1, 8}, + { 12000000, 216000000, 432, 12, 1, 8}, + { 13000000, 216000000, 432, 13, 1, 8}, + { 19200000, 216000000, 90, 4, 1, 1}, + { 26000000, 216000000, 432, 26, 1, 8}, + { 12000000, 432000000, 432, 12, 0, 8}, + { 13000000, 432000000, 432, 13, 0, 8}, + { 19200000, 432000000, 90, 4, 0, 1}, + { 26000000, 432000000, 432, 26, 0, 8}, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { - { 28800000, 56448000, 49, 25, 1, 1}, - { 28800000, 73728000, 64, 25, 1, 1}, - { 28800000, 24000000, 5, 6, 1, 1}, + { 28800000, 56448000, 49, 25, 0, 1}, + { 28800000, 73728000, 64, 25, 0, 1}, + { 28800000, 24000000, 5, 6, 0, 1}, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { - { 12000000, 216000000, 216, 12, 1, 4}, - { 13000000, 216000000, 216, 13, 1, 4}, - { 19200000, 216000000, 135, 12, 1, 3}, - { 26000000, 216000000, 216, 26, 1, 4}, + { 12000000, 216000000, 216, 12, 0, 4}, + { 13000000, 216000000, 216, 13, 0, 4}, + { 19200000, 216000000, 135, 12, 0, 3}, + { 26000000, 216000000, 216, 26, 0, 4}, - { 12000000, 594000000, 594, 12, 1, 8}, - { 13000000, 594000000, 594, 13, 1, 8}, - { 19200000, 594000000, 495, 16, 1, 8}, - { 26000000, 594000000, 594, 26, 1, 8}, + { 12000000, 594000000, 594, 12, 0, 8}, + { 13000000, 594000000, 594, 13, 0, 8}, + { 19200000, 594000000, 495, 16, 0, 8}, + { 26000000, 594000000, 594, 26, 0, 8}, - { 12000000, 1000000000, 1000, 12, 1, 12}, - { 13000000, 1000000000, 1000, 13, 1, 12}, - { 19200000, 1000000000, 625, 12, 1, 8}, - { 26000000, 1000000000, 1000, 26, 1, 12}, + { 12000000, 1000000000, 1000, 12, 0, 12}, + { 13000000, 1000000000, 1000, 13, 0, 12}, + { 19200000, 1000000000, 625, 12, 0, 8}, + { 26000000, 1000000000, 1000, 26, 0, 12}, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { - { 12000000, 480000000, 960, 12, 2, 0}, - { 13000000, 480000000, 960, 13, 2, 0}, - { 19200000, 480000000, 200, 4, 2, 0}, - { 26000000, 480000000, 960, 26, 2, 0}, + { 12000000, 480000000, 960, 12, 0, 0}, + { 13000000, 480000000, 960, 13, 0, 0}, + { 19200000, 480000000, 200, 4, 0, 0}, + { 26000000, 480000000, 960, 26, 0, 0}, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { /* 1 GHz */ - { 12000000, 1000000000, 1000, 12, 1, 12}, - { 13000000, 1000000000, 1000, 13, 1, 12}, - { 19200000, 1000000000, 625, 12, 1, 8}, - { 26000000, 1000000000, 1000, 26, 1, 12}, + { 12000000, 1000000000, 1000, 12, 0, 12}, + { 13000000, 1000000000, 1000, 13, 0, 12}, + { 19200000, 1000000000, 625, 12, 0, 8}, + { 26000000, 1000000000, 1000, 26, 0, 12}, /* 912 MHz */ - { 12000000, 912000000, 912, 12, 1, 12}, - { 13000000, 912000000, 912, 13, 1, 12}, - { 19200000, 912000000, 760, 16, 1, 8}, - { 26000000, 912000000, 912, 26, 1, 12}, + { 12000000, 912000000, 912, 12, 0, 12}, + { 13000000, 912000000, 912, 13, 0, 12}, + { 19200000, 912000000, 760, 16, 0, 8}, + { 26000000, 912000000, 912, 26, 0, 12}, /* 816 MHz */ - { 12000000, 816000000, 816, 12, 1, 12}, - { 13000000, 816000000, 816, 13, 1, 12}, - { 19200000, 816000000, 680, 16, 1, 8}, - { 26000000, 816000000, 816, 26, 1, 12}, + { 12000000, 816000000, 816, 12, 0, 12}, + { 13000000, 816000000, 816, 13, 0, 12}, + { 19200000, 816000000, 680, 16, 0, 8}, + { 26000000, 816000000, 816, 26, 0, 12}, /* 760 MHz */ - { 12000000, 760000000, 760, 12, 1, 12}, - { 13000000, 760000000, 760, 13, 1, 12}, - { 19200000, 760000000, 950, 24, 1, 8}, - { 26000000, 760000000, 760, 26, 1, 12}, + { 12000000, 760000000, 760, 12, 0, 12}, + { 13000000, 760000000, 760, 13, 0, 12}, + { 19200000, 760000000, 950, 24, 0, 8}, + { 26000000, 760000000, 760, 26, 0, 12}, /* 750 MHz */ - { 12000000, 750000000, 750, 12, 1, 12}, - { 13000000, 750000000, 750, 13, 1, 12}, - { 19200000, 750000000, 625, 16, 1, 8}, - { 26000000, 750000000, 750, 26, 1, 12}, + { 12000000, 750000000, 750, 12, 0, 12}, + { 13000000, 750000000, 750, 13, 0, 12}, + { 19200000, 750000000, 625, 16, 0, 8}, + { 26000000, 750000000, 750, 26, 0, 12}, /* 608 MHz */ - { 12000000, 608000000, 608, 12, 1, 12}, - { 13000000, 608000000, 608, 13, 1, 12}, - { 19200000, 608000000, 380, 12, 1, 8}, - { 26000000, 608000000, 608, 26, 1, 12}, + { 12000000, 608000000, 608, 12, 0, 12}, + { 13000000, 608000000, 608, 13, 0, 12}, + { 19200000, 608000000, 380, 12, 0, 8}, + { 26000000, 608000000, 608, 26, 0, 12}, /* 456 MHz */ - { 12000000, 456000000, 456, 12, 1, 12}, - { 13000000, 456000000, 456, 13, 1, 12}, - { 19200000, 456000000, 380, 16, 1, 8}, - { 26000000, 456000000, 456, 26, 1, 12}, + { 12000000, 456000000, 456, 12, 0, 12}, + { 13000000, 456000000, 456, 13, 0, 12}, + { 19200000, 456000000, 380, 16, 0, 8}, + { 26000000, 456000000, 456, 26, 0, 12}, /* 312 MHz */ - { 12000000, 312000000, 312, 12, 1, 12}, - { 13000000, 312000000, 312, 13, 1, 12}, - { 19200000, 312000000, 260, 16, 1, 8}, - { 26000000, 312000000, 312, 26, 1, 12}, + { 12000000, 312000000, 312, 12, 0, 12}, + { 13000000, 312000000, 312, 13, 0, 12}, + { 19200000, 312000000, 260, 16, 0, 8}, + { 26000000, 312000000, 312, 26, 0, 12}, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { - { 12000000, 100000000, 200, 24, 1, 0 }, + { 12000000, 100000000, 200, 24, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, }; diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index a163812..28a2997 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -373,164 +373,164 @@ static const struct utmi_clk_param utmi_parameters[] = { }; static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { - { 12000000, 1040000000, 520, 6, 1, 8}, - { 13000000, 1040000000, 480, 6, 1, 8}, - { 16800000, 1040000000, 495, 8, 1, 8}, /* actual: 1039.5 MHz */ - { 19200000, 1040000000, 325, 6, 1, 6}, - { 26000000, 1040000000, 520, 13, 1, 8}, - - { 12000000, 832000000, 416, 6, 1, 8}, - { 13000000, 832000000, 832, 13, 1, 8}, - { 16800000, 832000000, 396, 8, 1, 8}, /* actual: 831.6 MHz */ - { 19200000, 832000000, 260, 6, 1, 8}, - { 26000000, 832000000, 416, 13, 1, 8}, - - { 12000000, 624000000, 624, 12, 1, 8}, - { 13000000, 624000000, 624, 13, 1, 8}, - { 16800000, 600000000, 520, 14, 1, 8}, - { 19200000, 624000000, 520, 16, 1, 8}, - { 26000000, 624000000, 624, 26, 1, 8}, - - { 12000000, 600000000, 600, 12, 1, 8}, - { 13000000, 600000000, 600, 13, 1, 8}, - { 16800000, 600000000, 500, 14, 1, 8}, - { 19200000, 600000000, 375, 12, 1, 6}, - { 26000000, 600000000, 600, 26, 1, 8}, - - { 12000000, 520000000, 520, 12, 1, 8}, - { 13000000, 520000000, 520, 13, 1, 8}, - { 16800000, 520000000, 495, 16, 1, 8}, /* actual: 519.75 MHz */ - { 19200000, 520000000, 325, 12, 1, 6}, - { 26000000, 520000000, 520, 26, 1, 8}, - - { 12000000, 416000000, 416, 12, 1, 8}, - { 13000000, 416000000, 416, 13, 1, 8}, - { 16800000, 416000000, 396, 16, 1, 8}, /* actual: 415.8 MHz */ - { 19200000, 416000000, 260, 12, 1, 6}, - { 26000000, 416000000, 416, 26, 1, 8}, + { 12000000, 1040000000, 520, 6, 0, 8}, + { 13000000, 1040000000, 480, 6, 0, 8}, + { 16800000, 1040000000, 495, 8, 0, 8}, /* actual: 1039.5 MHz */ + { 19200000, 1040000000, 325, 6, 0, 6}, + { 26000000, 1040000000, 520, 13, 0, 8}, + + { 12000000, 832000000, 416, 6, 0, 8}, + { 13000000, 832000000, 832, 13, 0, 8}, + { 16800000, 832000000, 396, 8, 0, 8}, /* actual: 831.6 MHz */ + { 19200000, 832000000, 260, 6, 0, 8}, + { 26000000, 832000000, 416, 13, 0, 8}, + + { 12000000, 624000000, 624, 12, 0, 8}, + { 13000000, 624000000, 624, 13, 0, 8}, + { 16800000, 600000000, 520, 14, 0, 8}, + { 19200000, 624000000, 520, 16, 0, 8}, + { 26000000, 624000000, 624, 26, 0, 8}, + + { 12000000, 600000000, 600, 12, 0, 8}, + { 13000000, 600000000, 600, 13, 0, 8}, + { 16800000, 600000000, 500, 14, 0, 8}, + { 19200000, 600000000, 375, 12, 0, 6}, + { 26000000, 600000000, 600, 26, 0, 8}, + + { 12000000, 520000000, 520, 12, 0, 8}, + { 13000000, 520000000, 520, 13, 0, 8}, + { 16800000, 520000000, 495, 16, 0, 8}, /* actual: 519.75 MHz */ + { 19200000, 520000000, 325, 12, 0, 6}, + { 26000000, 520000000, 520, 26, 0, 8}, + + { 12000000, 416000000, 416, 12, 0, 8}, + { 13000000, 416000000, 416, 13, 0, 8}, + { 16800000, 416000000, 396, 16, 0, 8}, /* actual: 415.8 MHz */ + { 19200000, 416000000, 260, 12, 0, 6}, + { 26000000, 416000000, 416, 26, 0, 8}, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { - { 12000000, 666000000, 666, 12, 1, 8}, - { 13000000, 666000000, 666, 13, 1, 8}, - { 16800000, 666000000, 555, 14, 1, 8}, - { 19200000, 666000000, 555, 16, 1, 8}, - { 26000000, 666000000, 666, 26, 1, 8}, - { 12000000, 600000000, 600, 12, 1, 8}, - { 13000000, 600000000, 600, 13, 1, 8}, - { 16800000, 600000000, 500, 14, 1, 8}, - { 19200000, 600000000, 375, 12, 1, 6}, - { 26000000, 600000000, 600, 26, 1, 8}, + { 12000000, 666000000, 666, 12, 0, 8}, + { 13000000, 666000000, 666, 13, 0, 8}, + { 16800000, 666000000, 555, 14, 0, 8}, + { 19200000, 666000000, 555, 16, 0, 8}, + { 26000000, 666000000, 666, 26, 0, 8}, + { 12000000, 600000000, 600, 12, 0, 8}, + { 13000000, 600000000, 600, 13, 0, 8}, + { 16800000, 600000000, 500, 14, 0, 8}, + { 19200000, 600000000, 375, 12, 0, 6}, + { 26000000, 600000000, 600, 26, 0, 8}, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { - { 12000000, 216000000, 432, 12, 2, 8}, - { 13000000, 216000000, 432, 13, 2, 8}, - { 16800000, 216000000, 360, 14, 2, 8}, - { 19200000, 216000000, 360, 16, 2, 8}, - { 26000000, 216000000, 432, 26, 2, 8}, + { 12000000, 216000000, 432, 12, 1, 8}, + { 13000000, 216000000, 432, 13, 1, 8}, + { 16800000, 216000000, 360, 14, 1, 8}, + { 19200000, 216000000, 360, 16, 1, 8}, + { 26000000, 216000000, 432, 26, 1, 8}, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { - { 9600000, 564480000, 294, 5, 1, 4}, - { 9600000, 552960000, 288, 5, 1, 4}, - { 9600000, 24000000, 5, 2, 1, 1}, + { 9600000, 564480000, 294, 5, 0, 4}, + { 9600000, 552960000, 288, 5, 0, 4}, + { 9600000, 24000000, 5, 2, 0, 1}, - { 28800000, 56448000, 49, 25, 1, 1}, - { 28800000, 73728000, 64, 25, 1, 1}, - { 28800000, 24000000, 5, 6, 1, 1}, + { 28800000, 56448000, 49, 25, 0, 1}, + { 28800000, 73728000, 64, 25, 0, 1}, + { 28800000, 24000000, 5, 6, 0, 1}, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { - { 12000000, 216000000, 216, 12, 1, 4}, - { 13000000, 216000000, 216, 13, 1, 4}, - { 16800000, 216000000, 180, 14, 1, 4}, - { 19200000, 216000000, 180, 16, 1, 4}, - { 26000000, 216000000, 216, 26, 1, 4}, - - { 12000000, 594000000, 594, 12, 1, 8}, - { 13000000, 594000000, 594, 13, 1, 8}, - { 16800000, 594000000, 495, 14, 1, 8}, - { 19200000, 594000000, 495, 16, 1, 8}, - { 26000000, 594000000, 594, 26, 1, 8}, - - { 12000000, 1000000000, 1000, 12, 1, 12}, - { 13000000, 1000000000, 1000, 13, 1, 12}, - { 19200000, 1000000000, 625, 12, 1, 8}, - { 26000000, 1000000000, 1000, 26, 1, 12}, + { 12000000, 216000000, 216, 12, 0, 4}, + { 13000000, 216000000, 216, 13, 0, 4}, + { 16800000, 216000000, 180, 14, 0, 4}, + { 19200000, 216000000, 180, 16, 0, 4}, + { 26000000, 216000000, 216, 26, 0, 4}, + + { 12000000, 594000000, 594, 12, 0, 8}, + { 13000000, 594000000, 594, 13, 0, 8}, + { 16800000, 594000000, 495, 14, 0, 8}, + { 19200000, 594000000, 495, 16, 0, 8}, + { 26000000, 594000000, 594, 26, 0, 8}, + + { 12000000, 1000000000, 1000, 12, 0, 12}, + { 13000000, 1000000000, 1000, 13, 0, 12}, + { 19200000, 1000000000, 625, 12, 0, 8}, + { 26000000, 1000000000, 1000, 26, 0, 12}, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { - { 12000000, 480000000, 960, 12, 2, 12}, - { 13000000, 480000000, 960, 13, 2, 12}, - { 16800000, 480000000, 400, 7, 2, 5}, - { 19200000, 480000000, 200, 4, 2, 3}, - { 26000000, 480000000, 960, 26, 2, 12}, + { 12000000, 480000000, 960, 12, 0, 12}, + { 13000000, 480000000, 960, 13, 0, 12}, + { 16800000, 480000000, 400, 7, 0, 5}, + { 19200000, 480000000, 200, 4, 0, 3}, + { 26000000, 480000000, 960, 26, 0, 12}, { 0, 0, 0, 0, 0, 0 }, }; static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { /* 1.7 GHz */ - { 12000000, 1700000000, 850, 6, 1, 8}, - { 13000000, 1700000000, 915, 7, 1, 8}, /* actual: 1699.2 MHz */ - { 16800000, 1700000000, 708, 7, 1, 8}, /* actual: 1699.2 MHz */ - { 19200000, 1700000000, 885, 10, 1, 8}, /* actual: 1699.2 MHz */ - { 26000000, 1700000000, 850, 13, 1, 8}, + { 12000000, 1700000000, 850, 6, 0, 8}, + { 13000000, 1700000000, 915, 7, 0, 8}, /* actual: 1699.2 MHz */ + { 16800000, 1700000000, 708, 7, 0, 8}, /* actual: 1699.2 MHz */ + { 19200000, 1700000000, 885, 10, 0, 8}, /* actual: 1699.2 MHz */ + { 26000000, 1700000000, 850, 13, 0, 8}, /* 1.6 GHz */ - { 12000000, 1600000000, 800, 6, 1, 8}, - { 13000000, 1600000000, 738, 6, 1, 8}, /* actual: 1599.0 MHz */ - { 16800000, 1600000000, 857, 9, 1, 8}, /* actual: 1599.7 MHz */ - { 19200000, 1600000000, 500, 6, 1, 8}, - { 26000000, 1600000000, 800, 13, 1, 8}, + { 12000000, 1600000000, 800, 6, 0, 8}, + { 13000000, 1600000000, 738, 6, 0, 8}, /* actual: 1599.0 MHz */ + { 16800000, 1600000000, 857, 9, 0, 8}, /* actual: 1599.7 MHz */ + { 19200000, 1600000000, 500, 6, 0, 8}, + { 26000000, 1600000000, 800, 13, 0, 8}, /* 1.5 GHz */ - { 12000000, 1500000000, 750, 6, 1, 8}, - { 13000000, 1500000000, 923, 8, 1, 8}, /* actual: 1499.8 MHz */ - { 16800000, 1500000000, 625, 7, 1, 8}, - { 19200000, 1500000000, 625, 8, 1, 8}, - { 26000000, 1500000000, 750, 13, 1, 8}, + { 12000000, 1500000000, 750, 6, 0, 8}, + { 13000000, 1500000000, 923, 8, 0, 8}, /* actual: 1499.8 MHz */ + { 16800000, 1500000000, 625, 7, 0, 8}, + { 19200000, 1500000000, 625, 8, 0, 8}, + { 26000000, 1500000000, 750, 13, 0, 8}, /* 1.4 GHz */ - { 12000000, 1400000000, 700, 6, 1, 8}, - { 13000000, 1400000000, 969, 9, 1, 8}, /* actual: 1399.7 MHz */ - { 16800000, 1400000000, 1000, 12, 1, 8}, - { 19200000, 1400000000, 875, 12, 1, 8}, - { 26000000, 1400000000, 700, 13, 1, 8}, + { 12000000, 1400000000, 700, 6, 0, 8}, + { 13000000, 1400000000, 969, 9, 0, 8}, /* actual: 1399.7 MHz */ + { 16800000, 1400000000, 1000, 12, 0, 8}, + { 19200000, 1400000000, 875, 12, 0, 8}, + { 26000000, 1400000000, 700, 13, 0, 8}, /* 1.3 GHz */ - { 12000000, 1300000000, 975, 9, 1, 8}, - { 13000000, 1300000000, 1000, 10, 1, 8}, - { 16800000, 1300000000, 928, 12, 1, 8}, /* actual: 1299.2 MHz */ - { 19200000, 1300000000, 812, 12, 1, 8}, /* actual: 1299.2 MHz */ - { 26000000, 1300000000, 650, 13, 1, 8}, + { 12000000, 1300000000, 975, 9, 0, 8}, + { 13000000, 1300000000, 1000, 10, 0, 8}, + { 16800000, 1300000000, 928, 12, 0, 8}, /* actual: 1299.2 MHz */ + { 19200000, 1300000000, 812, 12, 0, 8}, /* actual: 1299.2 MHz */ + { 26000000, 1300000000, 650, 13, 0, 8}, /* 1.2 GHz */ - { 12000000, 1200000000, 1000, 10, 1, 8}, - { 13000000, 1200000000, 923, 10, 1, 8}, /* actual: 1199.9 MHz */ - { 16800000, 1200000000, 1000, 14, 1, 8}, - { 19200000, 1200000000, 1000, 16, 1, 8}, - { 26000000, 1200000000, 600, 13, 1, 8}, + { 12000000, 1200000000, 1000, 10, 0, 8}, + { 13000000, 1200000000, 923, 10, 0, 8}, /* actual: 1199.9 MHz */ + { 16800000, 1200000000, 1000, 14, 0, 8}, + { 19200000, 1200000000, 1000, 16, 0, 8}, + { 26000000, 1200000000, 600, 13, 0, 8}, /* 1.1 GHz */ - { 12000000, 1100000000, 825, 9, 1, 8}, - { 13000000, 1100000000, 846, 10, 1, 8}, /* actual: 1099.8 MHz */ - { 16800000, 1100000000, 982, 15, 1, 8}, /* actual: 1099.8 MHz */ - { 19200000, 1100000000, 859, 15, 1, 8}, /* actual: 1099.5 MHz */ - { 26000000, 1100000000, 550, 13, 1, 8}, + { 12000000, 1100000000, 825, 9, 0, 8}, + { 13000000, 1100000000, 846, 10, 0, 8}, /* actual: 1099.8 MHz */ + { 16800000, 1100000000, 982, 15, 0, 8}, /* actual: 1099.8 MHz */ + { 19200000, 1100000000, 859, 15, 0, 8}, /* actual: 1099.5 MHz */ + { 26000000, 1100000000, 550, 13, 0, 8}, /* 1 GHz */ - { 12000000, 1000000000, 1000, 12, 1, 8}, - { 13000000, 1000000000, 1000, 13, 1, 8}, - { 16800000, 1000000000, 833, 14, 1, 8}, /* actual: 999.6 MHz */ - { 19200000, 1000000000, 625, 12, 1, 8}, - { 26000000, 1000000000, 1000, 26, 1, 8}, + { 12000000, 1000000000, 1000, 12, 0, 8}, + { 13000000, 1000000000, 1000, 13, 0, 8}, + { 16800000, 1000000000, 833, 14, 0, 8}, /* actual: 999.6 MHz */ + { 19200000, 1000000000, 625, 12, 0, 8}, + { 26000000, 1000000000, 1000, 26, 0, 8}, { 0, 0, 0, 0, 0, 0 }, }; ^ permalink raw reply related [flat|nested] 34+ messages in thread
[parent not found: <1359713962-16822-2-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v5 01/10] clk: tegra: Refactor PLL programming code [not found] ` <1359713962-16822-2-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> @ 2013-02-04 6:06 ` Prashant Gaikwad 2013-02-04 14:32 ` Peter De Schrijver 2013-02-04 21:57 ` Stephen Warren 1 sibling, 1 reply; 34+ messages in thread From: Prashant Gaikwad @ 2013-02-04 6:06 UTC (permalink / raw) To: Peter De Schrijver Cc: Russell King, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring, Joseph Lo, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Mike Turquette, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: > Refactor the PLL programming code to make it useable by the new PLL types > introduced by Tegra114. > > The following changes were done: > > * Split programming the PLL into updating m,n,p and updating cpcon > * Move locking from _update_pll_cpcon() to clk_pll_set_rate() > * Introduce _get_pll_mnp() helper > * Move check for identical m,n,p values to clk_pll_set_rate() > * struct tegra_clk_pll_freq_table will always contain the values as defined > by the hardware. > * Simplify the arguments to clk_pll_wait_for_lock() > > Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> > --- > drivers/clk/tegra/clk-pll.c | 178 +++++++++++++++++------------ > drivers/clk/tegra/clk-tegra20.c | 144 ++++++++++++------------ > drivers/clk/tegra/clk-tegra30.c | 234 +++++++++++++++++++------------------- > 3 files changed, 294 insertions(+), 262 deletions(-) > > diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c > index 165f247..912c977 100644 > --- a/drivers/clk/tegra/clk-pll.c > +++ b/drivers/clk/tegra/clk-pll.c > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. > + * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. > * > * This program is free software; you can redistribute it and/or modify it > * under the terms and conditions of the GNU General Public License, > @@ -113,20 +113,23 @@ static void clk_pll_enable_lock(struct tegra_clk_pll *pll) > pll_writel_misc(val, pll); > } > > -static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll, > - void __iomem *lock_addr, u32 lock_bit_idx) > +static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll) > { > int i; > - u32 val; > + u32 val, lock_bit; > + void __iomem *lock_addr; > > if (!(pll->flags & TEGRA_PLL_USE_LOCK)) { > udelay(pll->params->lock_delay); > return 0; > } > > + lock_addr = pll->clk_base + pll->params->base_reg; This will not work for PLLE. Lock bit for PLLE is in misc register. > + lock_bit = BIT(pll->params->lock_bit_idx); > + > for (i = 0; i < pll->params->lock_delay; i++) { > val = readl_relaxed(lock_addr); > - if (val & BIT(lock_bit_idx)) { > + if (val & lock_bit) { Need to change the lock bit idx parameter for Tegra20 and Tegra30 PLLs else this patch will break those. > udelay(PLL_POST_LOCK_DELAY); > return 0; > } > @@ -155,7 +158,7 @@ static int clk_pll_is_enabled(struct clk_hw *hw) > return val & PLL_BASE_ENABLE ? 1 : 0; > } <snip> > @@ -538,8 +570,8 @@ static int clk_plle_enable(struct clk_hw *hw) > val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE); > pll_writel_base(val, pll); > > - clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->misc_reg, > - pll->params->lock_bit_idx); > + clk_pll_wait_for_lock(pll); > + > return 0; > } <snip> > static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { > /* 1.7 GHz */ > - { 12000000, 1700000000, 850, 6, 1, 8}, > - { 13000000, 1700000000, 915, 7, 1, 8}, /* actual: 1699.2 MHz */ > - { 16800000, 1700000000, 708, 7, 1, 8}, /* actual: 1699.2 MHz */ > - { 19200000, 1700000000, 885, 10, 1, 8}, /* actual: 1699.2 MHz */ > - { 26000000, 1700000000, 850, 13, 1, 8}, > + { 12000000, 1700000000, 850, 6, 0, 8}, > + { 13000000, 1700000000, 915, 7, 0, 8}, /* actual: 1699.2 MHz */ > + { 16800000, 1700000000, 708, 7, 0, 8}, /* actual: 1699.2 MHz */ > + { 19200000, 1700000000, 885, 10, 0, 8}, /* actual: 1699.2 MHz */ > + { 26000000, 1700000000, 850, 13, 0, 8}, > > /* 1.6 GHz */ > - { 12000000, 1600000000, 800, 6, 1, 8}, > - { 13000000, 1600000000, 738, 6, 1, 8}, /* actual: 1599.0 MHz */ > - { 16800000, 1600000000, 857, 9, 1, 8}, /* actual: 1599.7 MHz */ > - { 19200000, 1600000000, 500, 6, 1, 8}, > - { 26000000, 1600000000, 800, 13, 1, 8}, > + { 12000000, 1600000000, 800, 6, 0, 8}, > + { 13000000, 1600000000, 738, 6, 0, 8}, /* actual: 1599.0 MHz */ > + { 16800000, 1600000000, 857, 9, 0, 8}, /* actual: 1599.7 MHz */ > + { 19200000, 1600000000, 500, 6, 0, 8}, > + { 26000000, 1600000000, 800, 13, 0, 8}, > > /* 1.5 GHz */ > - { 12000000, 1500000000, 750, 6, 1, 8}, > - { 13000000, 1500000000, 923, 8, 1, 8}, /* actual: 1499.8 MHz */ > - { 16800000, 1500000000, 625, 7, 1, 8}, > - { 19200000, 1500000000, 625, 8, 1, 8}, > - { 26000000, 1500000000, 750, 13, 1, 8}, > + { 12000000, 1500000000, 750, 6, 0, 8}, > + { 13000000, 1500000000, 923, 8, 0, 8}, /* actual: 1499.8 MHz */ > + { 16800000, 1500000000, 625, 7, 0, 8}, > + { 19200000, 1500000000, 625, 8, 0, 8}, > + { 26000000, 1500000000, 750, 13, 0, 8}, > > /* 1.4 GHz */ > - { 12000000, 1400000000, 700, 6, 1, 8}, > - { 13000000, 1400000000, 969, 9, 1, 8}, /* actual: 1399.7 MHz */ > - { 16800000, 1400000000, 1000, 12, 1, 8}, > - { 19200000, 1400000000, 875, 12, 1, 8}, > - { 26000000, 1400000000, 700, 13, 1, 8}, > + { 12000000, 1400000000, 700, 6, 0, 8}, > + { 13000000, 1400000000, 969, 9, 0, 8}, /* actual: 1399.7 MHz */ > + { 16800000, 1400000000, 1000, 12, 0, 8}, > + { 19200000, 1400000000, 875, 12, 0, 8}, > + { 26000000, 1400000000, 700, 13, 0, 8}, > > /* 1.3 GHz */ > - { 12000000, 1300000000, 975, 9, 1, 8}, > - { 13000000, 1300000000, 1000, 10, 1, 8}, > - { 16800000, 1300000000, 928, 12, 1, 8}, /* actual: 1299.2 MHz */ > - { 19200000, 1300000000, 812, 12, 1, 8}, /* actual: 1299.2 MHz */ > - { 26000000, 1300000000, 650, 13, 1, 8}, > + { 12000000, 1300000000, 975, 9, 0, 8}, > + { 13000000, 1300000000, 1000, 10, 0, 8}, > + { 16800000, 1300000000, 928, 12, 0, 8}, /* actual: 1299.2 MHz */ > + { 19200000, 1300000000, 812, 12, 0, 8}, /* actual: 1299.2 MHz */ > + { 26000000, 1300000000, 650, 13, 0, 8}, > > /* 1.2 GHz */ > - { 12000000, 1200000000, 1000, 10, 1, 8}, > - { 13000000, 1200000000, 923, 10, 1, 8}, /* actual: 1199.9 MHz */ > - { 16800000, 1200000000, 1000, 14, 1, 8}, > - { 19200000, 1200000000, 1000, 16, 1, 8}, > - { 26000000, 1200000000, 600, 13, 1, 8}, > + { 12000000, 1200000000, 1000, 10, 0, 8}, > + { 13000000, 1200000000, 923, 10, 0, 8}, /* actual: 1199.9 MHz */ > + { 16800000, 1200000000, 1000, 14, 0, 8}, > + { 19200000, 1200000000, 1000, 16, 0, 8}, > + { 26000000, 1200000000, 600, 13, 0, 8}, > > /* 1.1 GHz */ > - { 12000000, 1100000000, 825, 9, 1, 8}, > - { 13000000, 1100000000, 846, 10, 1, 8}, /* actual: 1099.8 MHz */ > - { 16800000, 1100000000, 982, 15, 1, 8}, /* actual: 1099.8 MHz */ > - { 19200000, 1100000000, 859, 15, 1, 8}, /* actual: 1099.5 MHz */ > - { 26000000, 1100000000, 550, 13, 1, 8}, > + { 12000000, 1100000000, 825, 9, 0, 8}, > + { 13000000, 1100000000, 846, 10, 0, 8}, /* actual: 1099.8 MHz */ > + { 16800000, 1100000000, 982, 15, 0, 8}, /* actual: 1099.8 MHz */ > + { 19200000, 1100000000, 859, 15, 0, 8}, /* actual: 1099.5 MHz */ > + { 26000000, 1100000000, 550, 13, 0, 8}, > > /* 1 GHz */ > - { 12000000, 1000000000, 1000, 12, 1, 8}, > - { 13000000, 1000000000, 1000, 13, 1, 8}, > - { 16800000, 1000000000, 833, 14, 1, 8}, /* actual: 999.6 MHz */ > - { 19200000, 1000000000, 625, 12, 1, 8}, > - { 26000000, 1000000000, 1000, 26, 1, 8}, > + { 12000000, 1000000000, 1000, 12, 0, 8}, > + { 13000000, 1000000000, 1000, 13, 0, 8}, > + { 16800000, 1000000000, 833, 14, 0, 8}, /* actual: 999.6 MHz */ > + { 19200000, 1000000000, 625, 12, 0, 8}, > + { 26000000, 1000000000, 1000, 26, 0, 8}, > > { 0, 0, 0, 0, 0, 0 }, > }; > ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v5 01/10] clk: tegra: Refactor PLL programming code 2013-02-04 6:06 ` Prashant Gaikwad @ 2013-02-04 14:32 ` Peter De Schrijver 2013-02-05 5:42 ` Prashant Gaikwad 0 siblings, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-04 14:32 UTC (permalink / raw) To: Prashant Gaikwad Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org On Mon, Feb 04, 2013 at 07:06:47AM +0100, Prashant Gaikwad wrote: > On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: ... > > > > -static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll, > > - void __iomem *lock_addr, u32 lock_bit_idx) > > +static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll) > > { > > int i; > > - u32 val; > > + u32 val, lock_bit; > > + void __iomem *lock_addr; > > > > if (!(pll->flags & TEGRA_PLL_USE_LOCK)) { > > udelay(pll->params->lock_delay); > > return 0; > > } > > > > + lock_addr = pll->clk_base + pll->params->base_reg; > > This will not work for PLLE. Lock bit for PLLE is in misc register. > > > + lock_bit = BIT(pll->params->lock_bit_idx); > > + > > for (i = 0; i < pll->params->lock_delay; i++) { > > val = readl_relaxed(lock_addr); > > - if (val & BIT(lock_bit_idx)) { > > + if (val & lock_bit) { > > Need to change the lock bit idx parameter for Tegra20 and Tegra30 PLLs > else this patch will break those. > Looking at commit 37c26a906527b8a6a252614ca83d21ad318c4e84 and commit b08e8c0ecc42afa3a2e1019851af741980dd5a6b, these fields seem correctly initialized for both Tegra20 and Tegra30? Or am I missing something? Thanks, Peter. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v5 01/10] clk: tegra: Refactor PLL programming code 2013-02-04 14:32 ` Peter De Schrijver @ 2013-02-05 5:42 ` Prashant Gaikwad [not found] ` <51109BB3.8000706-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 0 siblings, 1 reply; 34+ messages in thread From: Prashant Gaikwad @ 2013-02-05 5:42 UTC (permalink / raw) To: Peter De Schrijver Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org On Monday 04 February 2013 08:02 PM, Peter De Schrijver wrote: > On Mon, Feb 04, 2013 at 07:06:47AM +0100, Prashant Gaikwad wrote: >> On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: > ... > >>> -static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll, >>> - void __iomem *lock_addr, u32 lock_bit_idx) >>> +static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll) >>> { >>> int i; >>> - u32 val; >>> + u32 val, lock_bit; >>> + void __iomem *lock_addr; >>> >>> if (!(pll->flags & TEGRA_PLL_USE_LOCK)) { >>> udelay(pll->params->lock_delay); >>> return 0; >>> } >>> >>> + lock_addr = pll->clk_base + pll->params->base_reg; >> This will not work for PLLE. Lock bit for PLLE is in misc register. >> >>> + lock_bit = BIT(pll->params->lock_bit_idx); >>> + >>> for (i = 0; i < pll->params->lock_delay; i++) { >>> val = readl_relaxed(lock_addr); >>> - if (val & BIT(lock_bit_idx)) { >>> + if (val & lock_bit) { >> Need to change the lock bit idx parameter for Tegra20 and Tegra30 PLLs >> else this patch will break those. >> > Looking at commit 37c26a906527b8a6a252614ca83d21ad318c4e84 and commit > b08e8c0ecc42afa3a2e1019851af741980dd5a6b, these fields seem correctly > initialized for both Tegra20 and Tegra30? Or am I missing something? Ohh, I missed to read lock_bit = BIT(pll->params->lock_bit_idx); Am I missing something about PLLE lock_addr also? > Thanks, > > Peter. ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <51109BB3.8000706-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v5 01/10] clk: tegra: Refactor PLL programming code [not found] ` <51109BB3.8000706-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> @ 2013-02-05 13:23 ` Peter De Schrijver [not found] ` <20130205132355.GD3073-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org> 0 siblings, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-05 13:23 UTC (permalink / raw) To: Prashant Gaikwad Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org On Tue, Feb 05, 2013 at 06:42:11AM +0100, Prashant Gaikwad wrote: > On Monday 04 February 2013 08:02 PM, Peter De Schrijver wrote: > > On Mon, Feb 04, 2013 at 07:06:47AM +0100, Prashant Gaikwad wrote: > >> On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: > > ... > > > >>> -static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll, > >>> - void __iomem *lock_addr, u32 lock_bit_idx) > >>> +static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll) > >>> { > >>> int i; > >>> - u32 val; > >>> + u32 val, lock_bit; > >>> + void __iomem *lock_addr; > >>> > >>> if (!(pll->flags & TEGRA_PLL_USE_LOCK)) { > >>> udelay(pll->params->lock_delay); > >>> return 0; > >>> } > >>> > >>> + lock_addr = pll->clk_base + pll->params->base_reg; > >> This will not work for PLLE. Lock bit for PLLE is in misc register. > >> > >>> + lock_bit = BIT(pll->params->lock_bit_idx); > >>> + > >>> for (i = 0; i < pll->params->lock_delay; i++) { > >>> val = readl_relaxed(lock_addr); > >>> - if (val & BIT(lock_bit_idx)) { > >>> + if (val & lock_bit) { > >> Need to change the lock bit idx parameter for Tegra20 and Tegra30 PLLs > >> else this patch will break those. > >> > > Looking at commit 37c26a906527b8a6a252614ca83d21ad318c4e84 and commit > > b08e8c0ecc42afa3a2e1019851af741980dd5a6b, these fields seem correctly > > initialized for both Tegra20 and Tegra30? Or am I missing something? > > Ohh, I missed to read > > lock_bit = BIT(pll->params->lock_bit_idx); > > > Am I missing something about PLLE lock_addr also? > Ah no indeed... my bad. So we need a lock_addr field. Cheers, Peter. ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <20130205132355.GD3073-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org>]
* Re: [PATCH v5 01/10] clk: tegra: Refactor PLL programming code [not found] ` <20130205132355.GD3073-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org> @ 2013-02-06 12:32 ` Peter De Schrijver 0 siblings, 0 replies; 34+ messages in thread From: Peter De Schrijver @ 2013-02-06 12:32 UTC (permalink / raw) To: Prashant Gaikwad Cc: Russell King, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring, Joseph Lo, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Mike Turquette, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org On Tue, Feb 05, 2013 at 02:23:55PM +0100, Peter De Schrijver wrote: > On Tue, Feb 05, 2013 at 06:42:11AM +0100, Prashant Gaikwad wrote: > > On Monday 04 February 2013 08:02 PM, Peter De Schrijver wrote: > > > On Mon, Feb 04, 2013 at 07:06:47AM +0100, Prashant Gaikwad wrote: > > >> On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: > > > ... > > > > > >>> -static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll, > > >>> - void __iomem *lock_addr, u32 lock_bit_idx) > > >>> +static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll) > > >>> { > > >>> int i; > > >>> - u32 val; > > >>> + u32 val, lock_bit; > > >>> + void __iomem *lock_addr; > > >>> > > >>> if (!(pll->flags & TEGRA_PLL_USE_LOCK)) { > > >>> udelay(pll->params->lock_delay); > > >>> return 0; > > >>> } > > >>> > > >>> + lock_addr = pll->clk_base + pll->params->base_reg; > > >> This will not work for PLLE. Lock bit for PLLE is in misc register. > > >> > > >>> + lock_bit = BIT(pll->params->lock_bit_idx); > > >>> + > > >>> for (i = 0; i < pll->params->lock_delay; i++) { > > >>> val = readl_relaxed(lock_addr); > > >>> - if (val & BIT(lock_bit_idx)) { > > >>> + if (val & lock_bit) { > > >> Need to change the lock bit idx parameter for Tegra20 and Tegra30 PLLs > > >> else this patch will break those. > > >> > > > Looking at commit 37c26a906527b8a6a252614ca83d21ad318c4e84 and commit > > > b08e8c0ecc42afa3a2e1019851af741980dd5a6b, these fields seem correctly > > > initialized for both Tegra20 and Tegra30? Or am I missing something? > > > > Ohh, I missed to read > > > > lock_bit = BIT(pll->params->lock_bit_idx); > > > > > > Am I missing something about PLLE lock_addr also? > > > > Ah no indeed... my bad. So we need a lock_addr field. > Or a flag. Flag seems less invasive for now. Cheers, Peter. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v5 01/10] clk: tegra: Refactor PLL programming code [not found] ` <1359713962-16822-2-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-04 6:06 ` Prashant Gaikwad @ 2013-02-04 21:57 ` Stephen Warren 1 sibling, 0 replies; 34+ messages in thread From: Stephen Warren @ 2013-02-04 21:57 UTC (permalink / raw) To: Peter De Schrijver Cc: Grant Likely, Rob Herring, Rob Landley, Russell King, Prashant Gaikwad, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-tegra-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r On 02/01/2013 03:18 AM, Peter De Schrijver wrote: > Refactor the PLL programming code to make it useable by the new PLL types > introduced by Tegra114. I tested this series on Tegra20 and Tegra30 for regressions and found none. Note that I didn't test on Tegra114. The series, Tested-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> Also, I briefly reviewed the code and aside from comments that have already been made, so the series, Reviewed-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v5 02/10] clk: tegra: Add TEGRA_PLL_BYPASS flag [not found] ` <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-01 10:18 ` [PATCH v5 01/10] clk: tegra: Refactor PLL programming code Peter De Schrijver @ 2013-02-01 10:18 ` Peter De Schrijver [not found] ` <1359713962-16822-3-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-01 10:18 ` [PATCH v5 04/10] clk: tegra: Add new fields and PLL types for Tegra114 Peter De Schrijver ` (5 subsequent siblings) 7 siblings, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-01 10:18 UTC (permalink / raw) To: pdeschrijver-DDmLM1+adcrQT0dZR+AlfA Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Prashant Gaikwad, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-tegra-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r Not all PLLs in Tegra114 have a bypass bit. Adapt the common code to only use this bit when available. Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> --- drivers/clk/tegra/clk-pll.c | 15 ++++++++++----- drivers/clk/tegra/clk.h | 8 +++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 912c977..3c3a25e 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -166,7 +166,8 @@ static void _clk_pll_enable(struct clk_hw *hw) clk_pll_enable_lock(pll); val = pll_readl_base(pll); - val &= ~PLL_BASE_BYPASS; + if (pll->flags & TEGRA_PLL_BYPASS) + val &= ~PLL_BASE_BYPASS; val |= PLL_BASE_ENABLE; pll_writel_base(val, pll); @@ -183,7 +184,9 @@ static void _clk_pll_disable(struct clk_hw *hw) u32 val; val = pll_readl_base(pll); - val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); + if (pll->flags & TEGRA_PLL_BYPASS) + val &= ~PLL_BASE_BYPASS; + val &= ~PLL_BASE_ENABLE; pll_writel_base(val, pll); if (pll->flags & TEGRA_PLLM) { @@ -454,7 +457,7 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, val = pll_readl_base(pll); - if (val & PLL_BASE_BYPASS) + if ((pll->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS)) return parent_rate; if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) { @@ -660,9 +663,10 @@ static struct clk *_tegra_clk_register_pll(const char *name, struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, unsigned long flags, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u8 pll_flags, + struct tegra_clk_pll_params *pll_params, u32 pll_flags, struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) { + pll_flags |= TEGRA_PLL_BYPASS; return _tegra_clk_register_pll(name, parent_name, clk_base, pmc, flags, fixed_rate, pll_params, pll_flags, freq_table, lock, &tegra_clk_pll_ops); @@ -671,9 +675,10 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, unsigned long flags, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u8 pll_flags, + struct tegra_clk_pll_params *pll_params, u32 pll_flags, struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) { + pll_flags |= TEGRA_PLL_BYPASS; return _tegra_clk_register_pll(name, parent_name, clk_base, pmc, flags, fixed_rate, pll_params, pll_flags, freq_table, lock, &tegra_clk_plle_ops); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index a09d7dc..3cff1df 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -182,12 +182,13 @@ struct tegra_clk_pll_params { * TEGRA_PLL_FIXED - We are not supposed to change output frequency * of some plls. * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling. + * TEGRA_PLL_BYPASS - PLL has bypass bit */ struct tegra_clk_pll { struct clk_hw hw; void __iomem *clk_base; void __iomem *pmc; - u8 flags; + u32 flags; unsigned long fixed_rate; spinlock_t *lock; u8 divn_shift; @@ -210,18 +211,19 @@ struct tegra_clk_pll { #define TEGRA_PLLM BIT(5) #define TEGRA_PLL_FIXED BIT(6) #define TEGRA_PLLE_CONFIGURE BIT(7) +#define TEGRA_PLL_BYPASS BIT(8) extern const struct clk_ops tegra_clk_pll_ops; extern const struct clk_ops tegra_clk_plle_ops; struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, unsigned long flags, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u8 pll_flags, + struct tegra_clk_pll_params *pll_params, u32 pll_flags, struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, unsigned long flags, unsigned long fixed_rate, - struct tegra_clk_pll_params *pll_params, u8 pll_flags, + struct tegra_clk_pll_params *pll_params, u32 pll_flags, struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); /** ^ permalink raw reply related [flat|nested] 34+ messages in thread
[parent not found: <1359713962-16822-3-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v5 02/10] clk: tegra: Add TEGRA_PLL_BYPASS flag [not found] ` <1359713962-16822-3-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> @ 2013-02-04 6:13 ` Prashant Gaikwad 0 siblings, 0 replies; 34+ messages in thread From: Prashant Gaikwad @ 2013-02-04 6:13 UTC (permalink / raw) To: Peter De Schrijver Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: > Not all PLLs in Tegra114 have a bypass bit. Adapt the common code to only use > this bit when available. > > Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> > --- Looks good to me. Reviewed-by: Prashant Gaikwad <pgaikwad-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> > drivers/clk/tegra/clk-pll.c | 15 ++++++++++----- > drivers/clk/tegra/clk.h | 8 +++++--- > 2 files changed, 15 insertions(+), 8 deletions(-) > > diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c > index 912c977..3c3a25e 100644 > --- a/drivers/clk/tegra/clk-pll.c > +++ b/drivers/clk/tegra/clk-pll.c > @@ -166,7 +166,8 @@ static void _clk_pll_enable(struct clk_hw *hw) > clk_pll_enable_lock(pll); > > val = pll_readl_base(pll); > - val &= ~PLL_BASE_BYPASS; > + if (pll->flags & TEGRA_PLL_BYPASS) > + val &= ~PLL_BASE_BYPASS; > val |= PLL_BASE_ENABLE; > pll_writel_base(val, pll); > > @@ -183,7 +184,9 @@ static void _clk_pll_disable(struct clk_hw *hw) > u32 val; > > val = pll_readl_base(pll); > - val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); > + if (pll->flags & TEGRA_PLL_BYPASS) > + val &= ~PLL_BASE_BYPASS; > + val &= ~PLL_BASE_ENABLE; > pll_writel_base(val, pll); > > if (pll->flags & TEGRA_PLLM) { > @@ -454,7 +457,7 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, > > val = pll_readl_base(pll); > > - if (val & PLL_BASE_BYPASS) > + if ((pll->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS)) > return parent_rate; > > if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) { > @@ -660,9 +663,10 @@ static struct clk *_tegra_clk_register_pll(const char *name, > struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, > void __iomem *clk_base, void __iomem *pmc, > unsigned long flags, unsigned long fixed_rate, > - struct tegra_clk_pll_params *pll_params, u8 pll_flags, > + struct tegra_clk_pll_params *pll_params, u32 pll_flags, > struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) > { > + pll_flags |= TEGRA_PLL_BYPASS; > return _tegra_clk_register_pll(name, parent_name, clk_base, pmc, > flags, fixed_rate, pll_params, pll_flags, freq_table, > lock, &tegra_clk_pll_ops); > @@ -671,9 +675,10 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, > struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, > void __iomem *clk_base, void __iomem *pmc, > unsigned long flags, unsigned long fixed_rate, > - struct tegra_clk_pll_params *pll_params, u8 pll_flags, > + struct tegra_clk_pll_params *pll_params, u32 pll_flags, > struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) > { > + pll_flags |= TEGRA_PLL_BYPASS; > return _tegra_clk_register_pll(name, parent_name, clk_base, pmc, > flags, fixed_rate, pll_params, pll_flags, freq_table, > lock, &tegra_clk_plle_ops); > diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h > index a09d7dc..3cff1df 100644 > --- a/drivers/clk/tegra/clk.h > +++ b/drivers/clk/tegra/clk.h > @@ -182,12 +182,13 @@ struct tegra_clk_pll_params { > * TEGRA_PLL_FIXED - We are not supposed to change output frequency > * of some plls. > * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling. > + * TEGRA_PLL_BYPASS - PLL has bypass bit > */ > struct tegra_clk_pll { > struct clk_hw hw; > void __iomem *clk_base; > void __iomem *pmc; > - u8 flags; > + u32 flags; > unsigned long fixed_rate; > spinlock_t *lock; > u8 divn_shift; > @@ -210,18 +211,19 @@ struct tegra_clk_pll { > #define TEGRA_PLLM BIT(5) > #define TEGRA_PLL_FIXED BIT(6) > #define TEGRA_PLLE_CONFIGURE BIT(7) > +#define TEGRA_PLL_BYPASS BIT(8) > > extern const struct clk_ops tegra_clk_pll_ops; > extern const struct clk_ops tegra_clk_plle_ops; > struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, > void __iomem *clk_base, void __iomem *pmc, > unsigned long flags, unsigned long fixed_rate, > - struct tegra_clk_pll_params *pll_params, u8 pll_flags, > + struct tegra_clk_pll_params *pll_params, u32 pll_flags, > struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); > struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, > void __iomem *clk_base, void __iomem *pmc, > unsigned long flags, unsigned long fixed_rate, > - struct tegra_clk_pll_params *pll_params, u8 pll_flags, > + struct tegra_clk_pll_params *pll_params, u32 pll_flags, > struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); > > /** ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v5 04/10] clk: tegra: Add new fields and PLL types for Tegra114 [not found] ` <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-01 10:18 ` [PATCH v5 01/10] clk: tegra: Refactor PLL programming code Peter De Schrijver 2013-02-01 10:18 ` [PATCH v5 02/10] clk: tegra: Add TEGRA_PLL_BYPASS flag Peter De Schrijver @ 2013-02-01 10:18 ` Peter De Schrijver [not found] ` <1359713962-16822-5-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-01 10:18 ` [PATCH v5 05/10] clk: tegra: Add flags to tegra_clk_periph() Peter De Schrijver ` (4 subsequent siblings) 7 siblings, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-01 10:18 UTC (permalink / raw) To: pdeschrijver-DDmLM1+adcrQT0dZR+AlfA Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Prashant Gaikwad, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-tegra-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r Tegra114 introduces new PLL types. This requires new clocktypes as well as some new fields in the pll structure. Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> --- drivers/clk/tegra/clk-pll.c | 719 +++++++++++++++++++++++++++++++++++++++++++ drivers/clk/tegra/clk.h | 47 +++ 2 files changed, 766 insertions(+), 0 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 87d2f34..50114b7 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -79,6 +79,36 @@ #define PLLE_SS_CTRL 0x68 #define PLLE_SS_DISABLE (7 << 10) +#define PLLE_AUX_PLLP_SEL BIT(2) +#define PLLE_AUX_ENABLE_SWCTL BIT(4) +#define PLLE_AUX_SEQ_ENABLE BIT(24) +#define PLLE_AUX_PLLRE_SEL BIT(28) + +#define PLLE_MISC_PLLE_PTS BIT(8) +#define PLLE_MISC_IDDQ_SW_VALUE BIT(13) +#define PLLE_MISC_IDDQ_SW_CTRL BIT(14) +#define PLLE_MISC_VREG_BG_CTRL_SHIFT 4 +#define PLLE_MISC_VREG_BG_CTRL_MASK (3 << PLLE_MISC_VREG_BG_CTRL_SHIFT) +#define PLLE_MISC_VREG_CTRL_SHIFT 2 +#define PLLE_MISC_VREG_CTRL_MASK (2 << PLLE_MISC_VREG_CTRL_SHIFT) + +#define PLLCX_MISC_STROBE BIT(31) +#define PLLCX_MISC_RESET BIT(30) +#define PLLCX_MISC_SDM_DIV_SHIFT 28 +#define PLLCX_MISC_SDM_DIV_MASK (0x3 << PLLCX_MISC_SDM_DIV_SHIFT) +#define PLLCX_MISC_FILT_DIV_SHIFT 26 +#define PLLCX_MISC_FILT_DIV_MASK (0x3 << PLLCX_MISC_FILT_DIV_SHIFT) +#define PLLCX_MISC_DIV_LOW_RANGE \ + ((0x2 << PLLCX_MISC_SDM_DIV_SHIFT) | \ + (0x2 << PLLCX_MISC_FILT_DIV_SHIFT)) +#define PLLCX_MISC_DIV_HIGH_RANGE \ + ((0x1 << PLLCX_MISC_SDM_DIV_SHIFT) | \ + (0x1 << PLLCX_MISC_FILT_DIV_SHIFT)) + +#define PMC_PLLM_WB0_OVERRIDE 0x1dc +#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0 +#define PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK BIT(27) + #define PMC_SATA_PWRGT 0x1ac #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5) #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4) @@ -101,6 +131,24 @@ #define divn_max(p) (divn_mask(p)) #define divp_max(p) (1 << (divp_mask(p))) + +#ifdef CONFIG_ARCH_TEGRA_114_SOC +/* PLLXC has 4-bit PDIV, but entry 15 is not allowed in h/w */ +#define PLLXC_PDIV_MAX 14 + +/* non-monotonic mapping below is not a typo */ +static u8 pllxc_p[PLLXC_PDIV_MAX + 1] = { + /* PDIV: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 */ + /* p: */ 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 12, 16, 20, 24, 32 +}; + +#define PLLCX_PDIV_MAX 7 +static u8 pllcx_p[PLLCX_PDIV_MAX + 1] = { + /* PDIV: 0, 1, 2, 3, 4, 5, 6, 7 */ + /* p: */ 1, 2, 3, 4, 6, 8, 12, 16 +}; +#endif + static void clk_pll_enable_lock(struct tegra_clk_pll *pll) { u32 val; @@ -638,6 +686,515 @@ const struct clk_ops tegra_clk_plle_ops = { .enable = clk_plle_enable, }; +#ifdef CONFIG_ARCH_TEGRA_114_SOC + +static int clk_pll_iddq_enable(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + unsigned long flags = 0; + + u32 val; + int ret; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + val = pll_readl(pll->params->iddq_reg, pll); + val &= ~BIT(pll->params->iddq_bit_idx); + pll_writel(val, pll->params->iddq_reg, pll); + udelay(2); + + _clk_pll_enable(hw); + + ret = clk_pll_wait_for_lock(pll); + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); + + return 0; +} + +static void clk_pll_iddq_disable(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + unsigned long flags = 0; + u32 val; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + _clk_pll_disable(hw); + + val = pll_readl(pll->params->iddq_reg, pll); + val |= BIT(pll->params->iddq_bit_idx); + pll_writel(val, pll->params->iddq_reg, pll); + udelay(2); + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); +} + +static int _calc_dynamic_ramp_rate(struct clk_hw *hw, + struct tegra_clk_pll_freq_table *cfg, + unsigned long rate, unsigned long parent_rate) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + unsigned int p; + + if (!rate) + return -EINVAL; + + p = DIV_ROUND_UP(pll->params->vco_min, rate); + cfg->m = (parent_rate > pll->params->cf_max) ? 2 : 1; + cfg->p = p; + cfg->output_rate = rate * cfg->p; + cfg->n = cfg->output_rate * cfg->m / parent_rate; + + if (cfg->n > divn_max(pll) || cfg->output_rate > pll->params->vco_max) + return -EINVAL; + + return 0; +} + +static int _pll_ramp_calc_pll(struct clk_hw *hw, + struct tegra_clk_pll_freq_table *cfg, + unsigned long rate, unsigned long parent_rate) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + int ret = 0; + + ret = _get_table_rate(hw, cfg, rate, parent_rate); + if (ret < 0) { + ret = _calc_dynamic_ramp_rate(hw, cfg, rate, parent_rate); + return ret; + } else { + int fixed_mdiv; + + fixed_mdiv = (parent_rate > pll->params->cf_max) ? 2 : 1; + if (cfg->m != fixed_mdiv) { + WARN_ON(1); + return -EINVAL; + } + } + + if (!cfg->p || (cfg->p > pll->params->max_p)) + return -EINVAL; + + return 0; +} + +static int clk_pllxc_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + struct tegra_clk_pll_freq_table cfg, old_cfg; + unsigned long flags = 0; + int ret = 0; + u8 old_p; + + ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate); + if (ret < 0) + return ret; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + _get_pll_mnp(pll, &old_cfg); + + old_p = pllxc_p[old_cfg.p]; + if (old_cfg.m != cfg.m && old_cfg.n != cfg.n && old_p != cfg.p) { + cfg.p -= 1; + ret = _program_pll(hw, &cfg, rate); + } + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); + + return ret; +} + +static long clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct tegra_clk_pll_freq_table cfg; + int ret = 0; + u64 output_rate = *prate; + + ret = _pll_ramp_calc_pll(hw, &cfg, rate, *prate); + if (ret < 0) + return ret; + + output_rate *= cfg.n; + do_div(output_rate, cfg.m * cfg.p); + + return output_rate; +} + +static int clk_pllm_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct tegra_clk_pll_freq_table cfg; + struct tegra_clk_pll *pll = to_clk_pll(hw); + unsigned long flags = 0; + int state, ret = 0; + u32 val; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + state = clk_pll_is_enabled(hw); + if (state) { + if (rate != clk_get_rate(hw->clk)) { + pr_err("%s: Cannot change active PLLM\n", __func__); + ret = -EINVAL; + goto out; + } + goto out; + } + + ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate); + if (ret < 0) + goto out; + + cfg.p -= 1; + + val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE); + if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) { + val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE_2); + val = cfg.p ? (val | PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK) : + (val & ~PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK); + writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE_2); + + val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE); + val &= ~(divn_mask(pll) | divm_mask(pll)); + val |= (cfg.m << pll->divm_shift) | (cfg.n << pll->divn_shift); + writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE); + } else + _update_pll_mnp(pll, &cfg); + + +out: + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); + + return ret; +} + +static void _pllcx_strobe(struct tegra_clk_pll *pll) +{ + u32 val; + + val = pll_readl_misc(pll); + val |= PLLCX_MISC_STROBE; + pll_writel_misc(val, pll); + udelay(2); + + val &= ~PLLCX_MISC_STROBE; + pll_writel_misc(val, pll); +} + +static int clk_pllc_enable(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + u32 val; + int ret = 0; + unsigned long flags = 0; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + _clk_pll_enable(hw); + udelay(2); + + val = pll_readl_misc(pll); + val &= ~PLLCX_MISC_RESET; + pll_writel_misc(val, pll); + udelay(2); + + _pllcx_strobe(pll); + + ret = clk_pll_wait_for_lock(pll); + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); + + return ret; +} + +static void _clk_pllc_disable(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + u32 val; + + _clk_pll_disable(hw); + + val = pll_readl_misc(pll); + val |= PLLCX_MISC_RESET; + pll_writel_misc(val, pll); + udelay(2); +} + +static void clk_pllc_disable(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + unsigned long flags = 0; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + _clk_pllc_disable(hw); + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); +} + +static int _pllcx_update_dynamic_coef(struct tegra_clk_pll *pll, + unsigned long input_rate, u32 n) +{ + u32 val, n_threshold; + + switch (input_rate) { + case 12000000: + n_threshold = 70; + break; + case 13000000: + case 26000000: + n_threshold = 71; + break; + case 16800000: + n_threshold = 55; + break; + case 19200000: + n_threshold = 48; + break; + default: + pr_err("%s: Unexpected reference rate %lu\n", + __func__, input_rate); + return -EINVAL; + } + + val = pll_readl_misc(pll); + val &= ~(PLLCX_MISC_SDM_DIV_MASK | PLLCX_MISC_FILT_DIV_MASK); + val |= n <= n_threshold ? + PLLCX_MISC_DIV_LOW_RANGE : PLLCX_MISC_DIV_HIGH_RANGE; + pll_writel_misc(val, pll); + + return 0; +} + +static int clk_pllc_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct tegra_clk_pll_freq_table cfg; + struct tegra_clk_pll *pll = to_clk_pll(hw); + unsigned long flags = 0; + int state, ret = 0; + u32 val; + u16 old_m, old_n; + u8 old_p; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate); + if (ret < 0) + goto out; + + val = pll_readl_base(pll); + old_m = (val >> pll->divm_shift) & (divm_mask(pll)); + old_n = (val >> pll->divn_shift) & (divn_mask(pll)); + old_p = pllcx_p[(val >> pll->divp_shift) & (divp_mask(pll))]; + + if (cfg.m != old_m) { + WARN_ON(1); + goto out; + } + + if (old_n == cfg.n && old_p == cfg.p) + goto out; + + cfg.p -= 1; + + state = clk_pll_is_enabled(hw); + if (state) + _clk_pllc_disable(hw); + + ret = _pllcx_update_dynamic_coef(pll, parent_rate, cfg.n); + if (ret < 0) + goto out; + + _update_pll_mnp(pll, &cfg); + + if (state) + ret = clk_pllc_enable(hw); + +out: + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); + + return ret; +} + +static long _pllre_calc_rate(struct tegra_clk_pll *pll, + struct tegra_clk_pll_freq_table *cfg, + unsigned long rate, unsigned long parent_rate) +{ + u16 m, n; + u64 output_rate = parent_rate; + + m = (parent_rate > pll->params->cf_max ? 2 : 1); + n = rate * m / parent_rate; + + output_rate *= n; + do_div(output_rate, m); + + if (cfg) { + cfg->m = m; + cfg->n = n; + } + + return output_rate; +} +static int clk_pllre_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct tegra_clk_pll_freq_table cfg, old_cfg; + struct tegra_clk_pll *pll = to_clk_pll(hw); + unsigned long flags = 0; + int state, ret = 0; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + _pllre_calc_rate(pll, &cfg, rate, parent_rate); + _get_pll_mnp(pll, &old_cfg); + cfg.p = old_cfg.p; + + if (cfg.m != old_cfg.m || cfg.n != old_cfg.n) { + state = clk_pll_is_enabled(hw); + if (state) + _clk_pll_disable(hw); + + _update_pll_mnp(pll, &cfg); + + if (state) { + _clk_pll_enable(hw); + ret = clk_pll_wait_for_lock(pll); + } + } + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); + + return ret; +} + +static unsigned long clk_pllre_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct tegra_clk_pll_freq_table cfg; + struct tegra_clk_pll *pll = to_clk_pll(hw); + u64 rate = parent_rate; + + _get_pll_mnp(pll, &cfg); + + rate *= cfg.n; + do_div(rate, cfg.m); + + return rate; +} + +static long clk_pllre_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + + return _pllre_calc_rate(pll, NULL, rate, *prate); +} + +static int clk_plle_tegra114_enable(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + struct tegra_clk_pll_freq_table sel; + u32 val; + int ret; + unsigned long flags = 0; + unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); + + if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate)) + return -EINVAL; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + val = pll_readl_base(pll); + val &= ~BIT(29); /* Disable lock override */ + pll_writel_base(val, pll); + + val = pll_readl(pll->params->aux_reg, pll); + val |= PLLE_AUX_ENABLE_SWCTL; + val &= ~PLLE_AUX_SEQ_ENABLE; + pll_writel(val, pll->params->aux_reg, pll); + udelay(1); + + val = pll_readl_misc(pll); + val |= PLLE_MISC_LOCK_ENABLE; + val |= PLLE_MISC_IDDQ_SW_CTRL; + val &= ~PLLE_MISC_IDDQ_SW_VALUE; + val |= PLLE_MISC_PLLE_PTS; + val |= PLLE_MISC_VREG_BG_CTRL_MASK | PLLE_MISC_VREG_CTRL_MASK; + pll_writel_misc(val, pll); + udelay(5); + + val = pll_readl(PLLE_SS_CTRL, pll); + val |= PLLE_SS_DISABLE; + pll_writel(val, PLLE_SS_CTRL, pll); + + val = pll_readl_base(pll); + val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); + val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); + val |= sel.m << pll->divm_shift; + val |= sel.n << pll->divn_shift; + val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; + pll_writel_base(val, pll); + udelay(1); + + _clk_pll_enable(hw); + ret = clk_pll_wait_for_lock(pll); + + if (ret < 0) + goto out; + + /* TODO: enable hw control of xusb brick pll */ + +out: + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); + + return ret; +} + +static void clk_plle_tegra114_disable(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + unsigned long flags = 0; + u32 val; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + _clk_pll_disable(hw); + + val = pll_readl_misc(pll); + val |= PLLE_MISC_IDDQ_SW_CTRL | PLLE_MISC_IDDQ_SW_VALUE; + pll_writel_misc(val, pll); + udelay(1); + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); +} +#endif + static struct clk *_tegra_clk_register_pll(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, unsigned long flags, @@ -709,3 +1266,165 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, flags, fixed_rate, pll_params, pll_flags, freq_table, lock, &tegra_clk_plle_ops); } + +#ifdef CONFIG_ARCH_TEGRA_114_SOC +const struct clk_ops tegra_clk_pllxc_ops = { + .is_enabled = clk_pll_is_enabled, + .enable = clk_pll_iddq_enable, + .disable = clk_pll_iddq_disable, + .recalc_rate = clk_pll_recalc_rate, + .round_rate = clk_pll_ramp_round_rate, + .set_rate = clk_pllxc_set_rate, +}; + +const struct clk_ops tegra_clk_pllm_ops = { + .is_enabled = clk_pll_is_enabled, + .enable = clk_pll_iddq_enable, + .disable = clk_pll_iddq_disable, + .recalc_rate = clk_pll_recalc_rate, + .round_rate = clk_pll_ramp_round_rate, + .set_rate = clk_pllm_set_rate, +}; + +const struct clk_ops tegra_clk_pllc_ops = { + .is_enabled = clk_pll_is_enabled, + .enable = clk_pllc_enable, + .disable = clk_pllc_disable, + .recalc_rate = clk_pll_recalc_rate, + .round_rate = clk_pll_ramp_round_rate, + .set_rate = clk_pllc_set_rate, +}; + +const struct clk_ops tegra_clk_pllre_ops = { + .is_enabled = clk_pll_is_enabled, + .enable = clk_pll_iddq_enable, + .disable = clk_pll_iddq_disable, + .recalc_rate = clk_pllre_recalc_rate, + .round_rate = clk_pllre_round_rate, + .set_rate = clk_pllre_set_rate, +}; + +const struct clk_ops tegra_clk_plle_tegra114_ops = { + .is_enabled = clk_pll_is_enabled, + .enable = clk_plle_tegra114_enable, + .disable = clk_plle_tegra114_disable, + .recalc_rate = clk_pll_recalc_rate, +}; + + +struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, + void __iomem *clk_base, void __iomem *pmc, + unsigned long flags, unsigned long fixed_rate, + struct tegra_clk_pll_params *pll_params, + u32 pll_flags, + struct tegra_clk_pll_freq_table *freq_table, + spinlock_t *lock) +{ + if (!pll_params->pdiv_tohw) + return -EINVAL; + + return _tegra_clk_register_pll(name, parent_name, clk_base, pmc, flags, + fixed_rate, pll_params, pll_flags, freq_table, + lock, &tegra_clk_pllxc_ops); +} + +struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, + void __iomem *clk_base, void __iomem *pmc, + unsigned long flags, unsigned long fixed_rate, + struct tegra_clk_pll_params *pll_params, + u32 pll_flags, + struct tegra_clk_pll_freq_table *freq_table, + spinlock_t *lock, unsigned long parent_rate) +{ + u32 val; + + /* program minimum rate by default */ + + val = readl_relaxed(clk_base + pll_params->base_reg); + if (val & PLL_BASE_ENABLE) + WARN_ON(val & pll_params->iddq_bit_idx); + else { + int m; + + m = (parent_rate > pll_params->cf_max) ? 2 : 1; + val = m << PLL_BASE_DIVM_SHIFT; + val |= (pll_params->vco_min / parent_rate) + << PLL_BASE_DIVN_SHIFT; + writel_relaxed(val, clk_base + pll_params->base_reg); + } + + /* disable lock override */ + + val = readl_relaxed(clk_base + pll_params->misc_reg); + val &= ~BIT(29); + writel_relaxed(val, clk_base + pll_params->misc_reg); + + return _tegra_clk_register_pll(name, parent_name, clk_base, pmc, flags, + fixed_rate, pll_params, pll_flags, freq_table, + lock, &tegra_clk_pllre_ops); +} + +struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, + void __iomem *clk_base, void __iomem *pmc, + unsigned long flags, unsigned long fixed_rate, + struct tegra_clk_pll_params *pll_params, + u32 pll_flags, + struct tegra_clk_pll_freq_table *freq_table, + spinlock_t *lock) +{ + if (!pll_params->pdiv_tohw) + return -EINVAL; + + pll_flags |= TEGRA_PLL_BYPASS; + return _tegra_clk_register_pll(name, parent_name, clk_base, pmc, flags, + fixed_rate, pll_params, pll_flags, freq_table, + lock, &tegra_clk_pllm_ops); +} + +struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, + void __iomem *clk_base, void __iomem *pmc, + unsigned long flags, unsigned long fixed_rate, + struct tegra_clk_pll_params *pll_params, + u32 pll_flags, + struct tegra_clk_pll_freq_table *freq_table, + spinlock_t *lock) +{ + if (!pll_params->pdiv_tohw) + return -EINVAL; + + pll_flags |= TEGRA_PLL_BYPASS; + return _tegra_clk_register_pll(name, parent_name, clk_base, pmc, flags, + fixed_rate, pll_params, pll_flags, freq_table, + lock, &tegra_clk_pllc_ops); + +} + +struct clk *tegra_clk_register_plle_tegra114(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, + struct tegra_clk_pll_freq_table *freq_table, + spinlock_t *lock) +{ + u32 val, val_aux; + + /* ensure parent is set to pll_re_vco */ + + val = readl_relaxed(clk_base + pll_params->base_reg); + val_aux = readl_relaxed(clk_base + pll_params->aux_reg); + + if (val & PLL_BASE_ENABLE) { + if (!(val_aux & PLLE_AUX_PLLRE_SEL)) + WARN(1, "pll_e enabled with unsupported parent %s\n", + (val & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : "pll_ref"); + } else { + val_aux |= PLLE_AUX_PLLRE_SEL; + writel_relaxed(val, clk_base + pll_params->aux_reg); + } + + return _tegra_clk_register_pll(name, parent_name, clk_base, NULL, flags, + fixed_rate, pll_params, 0, freq_table, lock, + &tegra_clk_plle_tegra114_ops); +} +#endif diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 1b9cbcd..4d0f556 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -156,6 +156,12 @@ struct tegra_clk_pll_params { u32 lock_reg; u32 lock_bit_idx; u32 lock_enable_bit_idx; + u32 iddq_reg; + u32 iddq_bit_idx; + u32 aux_reg; + u32 dyn_ramp_reg; + int stepa_shift; + int stepb_shift; int lock_delay; int max_p; struct pdiv_map *pdiv_tohw; @@ -233,12 +239,53 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, unsigned long flags, unsigned long fixed_rate, struct tegra_clk_pll_params *pll_params, u32 pll_flags, struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); + struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, void __iomem *clk_base, void __iomem *pmc, unsigned long flags, unsigned long fixed_rate, struct tegra_clk_pll_params *pll_params, u32 pll_flags, struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); +struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, + void __iomem *clk_base, void __iomem *pmc, + unsigned long flags, unsigned long fixed_rate, + struct tegra_clk_pll_params *pll_params, + u32 pll_flags, + struct tegra_clk_pll_freq_table *freq_table, + spinlock_t *lock); + +struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, + void __iomem *clk_base, void __iomem *pmc, + unsigned long flags, unsigned long fixed_rate, + struct tegra_clk_pll_params *pll_params, + u32 pll_flags, + struct tegra_clk_pll_freq_table *freq_table, + spinlock_t *lock); + +struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, + void __iomem *clk_base, void __iomem *pmc, + unsigned long flags, unsigned long fixed_rate, + struct tegra_clk_pll_params *pll_params, + u32 pll_flags, + struct tegra_clk_pll_freq_table *freq_table, + spinlock_t *lock); + +struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, + void __iomem *clk_base, void __iomem *pmc, + unsigned long flags, unsigned long fixed_rate, + struct tegra_clk_pll_params *pll_params, + u32 pll_flags, + struct tegra_clk_pll_freq_table *freq_table, + spinlock_t *lock, unsigned long parent_rate); + +struct clk *tegra_clk_register_plle_tegra114(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, + struct tegra_clk_pll_freq_table *freq_table, + spinlock_t *lock); + /** * struct tegra_clk_pll_out - PLL divider down clock * ^ permalink raw reply related [flat|nested] 34+ messages in thread
[parent not found: <1359713962-16822-5-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v5 04/10] clk: tegra: Add new fields and PLL types for Tegra114 [not found] ` <1359713962-16822-5-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> @ 2013-02-01 19:40 ` Rhyland Klein [not found] ` <510C1A2E.5010408-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 0 siblings, 1 reply; 34+ messages in thread From: Rhyland Klein @ 2013-02-01 19:40 UTC (permalink / raw) To: Peter De Schrijver Cc: Russell King, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring, Joseph Lo, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Mike Turquette, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org On 2/1/2013 5:18 AM, Peter De Schrijver wrote: > Tegra114 introduces new PLL types. This requires new clocktypes as well > as some new fields in the pll structure. > > Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> > --- > drivers/clk/tegra/clk-pll.c | 719 +++++++++++++++++++++++++++++++++++++++++++ > drivers/clk/tegra/clk.h | 47 +++ > 2 files changed, 766 insertions(+), 0 deletions(-) > > diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c > index 87d2f34..50114b7 100644 > --- a/drivers/clk/tegra/clk-pll.c > +++ b/drivers/clk/tegra/clk-pll.c > [snip] > +struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, > + void __iomem *clk_base, void __iomem *pmc, > + unsigned long flags, unsigned long fixed_rate, > + struct tegra_clk_pll_params *pll_params, > + u32 pll_flags, > + struct tegra_clk_pll_freq_table *freq_table, > + spinlock_t *lock) > +{ > + if (!pll_params->pdiv_tohw) > + return -EINVAL; > + This will cause the following warning: warning: return makes pointer from integer without a cast Same with occurrences in tegra_clk_register_pllm and tegra_clk_register_pllc. Should this instead be returning NULL? -rhyland -- nvpublic ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <510C1A2E.5010408-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v5 04/10] clk: tegra: Add new fields and PLL types for Tegra114 [not found] ` <510C1A2E.5010408-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> @ 2013-02-04 6:35 ` Prashant Gaikwad [not found] ` <510F56B1.5060409-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 0 siblings, 1 reply; 34+ messages in thread From: Prashant Gaikwad @ 2013-02-04 6:35 UTC (permalink / raw) To: Rhyland Klein Cc: Peter De Schrijver, Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org On Saturday 02 February 2013 01:10 AM, Rhyland Klein wrote: > On 2/1/2013 5:18 AM, Peter De Schrijver wrote: >> Tegra114 introduces new PLL types. This requires new clocktypes as well >> as some new fields in the pll structure. >> >> Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> >> --- >> drivers/clk/tegra/clk-pll.c | 719 +++++++++++++++++++++++++++++++++++++++++++ >> drivers/clk/tegra/clk.h | 47 +++ >> 2 files changed, 766 insertions(+), 0 deletions(-) >> >> diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c >> index 87d2f34..50114b7 100644 >> --- a/drivers/clk/tegra/clk-pll.c >> +++ b/drivers/clk/tegra/clk-pll.c >> [snip] >> +struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, >> + void __iomem *clk_base, void __iomem *pmc, >> + unsigned long flags, unsigned long fixed_rate, >> + struct tegra_clk_pll_params *pll_params, >> + u32 pll_flags, >> + struct tegra_clk_pll_freq_table *freq_table, >> + spinlock_t *lock) >> +{ >> + if (!pll_params->pdiv_tohw) >> + return -EINVAL; >> + > This will cause the following warning: > warning: return makes pointer from integer without a cast > > Same with occurrences in tegra_clk_register_pllm and > tegra_clk_register_pllc. > > Should this instead be returning NULL? return ERR_PTR(-EINVAL) > > -rhyland > ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <510F56B1.5060409-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v5 04/10] clk: tegra: Add new fields and PLL types for Tegra114 [not found] ` <510F56B1.5060409-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> @ 2013-02-04 10:37 ` Peter De Schrijver 0 siblings, 0 replies; 34+ messages in thread From: Peter De Schrijver @ 2013-02-04 10:37 UTC (permalink / raw) To: Prashant Gaikwad Cc: Russell King, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring, Joseph Lo, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Mike Turquette, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org On Mon, Feb 04, 2013 at 07:35:29AM +0100, Prashant Gaikwad wrote: > On Saturday 02 February 2013 01:10 AM, Rhyland Klein wrote: > > On 2/1/2013 5:18 AM, Peter De Schrijver wrote: > >> Tegra114 introduces new PLL types. This requires new clocktypes as well > >> as some new fields in the pll structure. > >> > >> Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> > >> --- > >> drivers/clk/tegra/clk-pll.c | 719 +++++++++++++++++++++++++++++++++++++++++++ > >> drivers/clk/tegra/clk.h | 47 +++ > >> 2 files changed, 766 insertions(+), 0 deletions(-) > >> > >> diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c > >> index 87d2f34..50114b7 100644 > >> --- a/drivers/clk/tegra/clk-pll.c > >> +++ b/drivers/clk/tegra/clk-pll.c > >> [snip] > >> +struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, > >> + void __iomem *clk_base, void __iomem *pmc, > >> + unsigned long flags, unsigned long fixed_rate, > >> + struct tegra_clk_pll_params *pll_params, > >> + u32 pll_flags, > >> + struct tegra_clk_pll_freq_table *freq_table, > >> + spinlock_t *lock) > >> +{ > >> + if (!pll_params->pdiv_tohw) > >> + return -EINVAL; > >> + > > This will cause the following warning: > > warning: return makes pointer from integer without a cast > > > > Same with occurrences in tegra_clk_register_pllm and > > tegra_clk_register_pllc. > > > > Should this instead be returning NULL? > > return ERR_PTR(-EINVAL) > Indeed. I noticed that only after I sent this patchset. Already fixed in my own tree. Cheers, Peter. ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v5 05/10] clk: tegra: Add flags to tegra_clk_periph() [not found] ` <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> ` (2 preceding siblings ...) 2013-02-01 10:18 ` [PATCH v5 04/10] clk: tegra: Add new fields and PLL types for Tegra114 Peter De Schrijver @ 2013-02-01 10:18 ` Peter De Schrijver [not found] ` <1359713962-16822-6-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-01 10:18 ` [PATCH v5 06/10] clk: tegra: Workaround for Tegra114 MSENC problem Peter De Schrijver ` (3 subsequent siblings) 7 siblings, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-01 10:18 UTC (permalink / raw) To: pdeschrijver-DDmLM1+adcrQT0dZR+AlfA Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Prashant Gaikwad, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-tegra-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r We will need some tegra peripheral clocks with the CLK_IGNORE_UNUSED flag, most notably mselect, which is a bridge between AXI and most peripherals. Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> --- drivers/clk/tegra/clk-periph.c | 11 ++++++----- drivers/clk/tegra/clk-tegra20.c | 2 +- drivers/clk/tegra/clk-tegra30.c | 2 +- drivers/clk/tegra/clk.h | 9 ++++++--- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index 788486e..067abb3 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -170,14 +170,15 @@ const struct clk_ops tegra_clk_periph_nodiv_ops = { static struct clk *_tegra_clk_register_periph(const char *name, const char **parent_names, int num_parents, struct tegra_clk_periph *periph, - void __iomem *clk_base, u32 offset, bool div) + void __iomem *clk_base, u32 offset, bool div, + unsigned long flags) { struct clk *clk; struct clk_init_data init; init.name = name; init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops; - init.flags = div ? 0 : CLK_SET_RATE_PARENT; + init.flags = flags; init.parent_names = parent_names; init.num_parents = num_parents; @@ -202,10 +203,10 @@ static struct clk *_tegra_clk_register_periph(const char *name, struct clk *tegra_clk_register_periph(const char *name, const char **parent_names, int num_parents, struct tegra_clk_periph *periph, void __iomem *clk_base, - u32 offset) + u32 offset, unsigned long flags) { return _tegra_clk_register_periph(name, parent_names, num_parents, - periph, clk_base, offset, true); + periph, clk_base, offset, true, flags); } struct clk *tegra_clk_register_periph_nodiv(const char *name, @@ -214,5 +215,5 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, u32 offset) { return _tegra_clk_register_periph(name, parent_names, num_parents, - periph, clk_base, offset, false); + periph, clk_base, offset, false, CLK_SET_RATE_PARENT); } diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 54c6777..870349e 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -1048,7 +1048,7 @@ static void __init tegra20_periph_clk_init(void) data = &tegra_periph_clk_list[i]; clk = tegra_clk_register_periph(data->name, data->parent_names, data->num_parents, &data->periph, - clk_base, data->offset); + clk_base, data->offset, data->flags); clk_register_clkdev(clk, data->con_id, data->dev_id); clks[data->clk_id] = clk; } diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 078f9b8..126747b 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -1665,7 +1665,7 @@ static void __init tegra30_periph_clk_init(void) data = &tegra_periph_clk_list[i]; clk = tegra_clk_register_periph(data->name, data->parent_names, data->num_parents, &data->periph, - clk_base, data->offset); + clk_base, data->offset, data->flags); clk_register_clkdev(clk, data->con_id, data->dev_id); clks[data->clk_id] = clk; } diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 4d0f556..79f5e2a 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -411,7 +411,7 @@ extern const struct clk_ops tegra_clk_periph_ops; struct clk *tegra_clk_register_periph(const char *name, const char **parent_names, int num_parents, struct tegra_clk_periph *periph, void __iomem *clk_base, - u32 offset); + u32 offset, unsigned long flags); struct clk *tegra_clk_register_periph_nodiv(const char *name, const char **parent_names, int num_parents, struct tegra_clk_periph *periph, void __iomem *clk_base, @@ -454,12 +454,14 @@ struct tegra_periph_init_data { u32 offset; const char *con_id; const char *dev_id; + unsigned long flags; }; #define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ _mux_shift, _mux_mask, _mux_flags, _div_shift, \ _div_width, _div_frac_width, _div_flags, _regs, \ - _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table) \ + _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table,\ + _flags) \ { \ .name = _name, \ .clk_id = _clk_id, \ @@ -474,6 +476,7 @@ struct tegra_periph_init_data { .offset = _offset, \ .con_id = _con_id, \ .dev_id = _dev_id, \ + .flags = _flags \ } #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\ @@ -484,7 +487,7 @@ struct tegra_periph_init_data { _mux_shift, BIT(_mux_width) - 1, _mux_flags, \ _div_shift, _div_width, _div_frac_width, _div_flags, \ _regs, _clk_num, _enb_refcnt, _gate_flags, _clk_id,\ - NULL) + NULL, 0) /** * struct clk_super_mux - super clock ^ permalink raw reply related [flat|nested] 34+ messages in thread
[parent not found: <1359713962-16822-6-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v5 05/10] clk: tegra: Add flags to tegra_clk_periph() [not found] ` <1359713962-16822-6-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> @ 2013-02-04 6:33 ` Prashant Gaikwad 0 siblings, 0 replies; 34+ messages in thread From: Prashant Gaikwad @ 2013-02-04 6:33 UTC (permalink / raw) To: Peter De Schrijver Cc: Russell King, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring, Joseph Lo, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Mike Turquette, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: > We will need some tegra peripheral clocks with the CLK_IGNORE_UNUSED flag, > most notably mselect, which is a bridge between AXI and most peripherals. > > Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> > --- Looks good to me. Reviewed-by: Prashant Gaikwad <pgaikwad-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> > drivers/clk/tegra/clk-periph.c | 11 ++++++----- > drivers/clk/tegra/clk-tegra20.c | 2 +- > drivers/clk/tegra/clk-tegra30.c | 2 +- > drivers/clk/tegra/clk.h | 9 ++++++--- > 4 files changed, 14 insertions(+), 10 deletions(-) > > diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c > index 788486e..067abb3 100644 > --- a/drivers/clk/tegra/clk-periph.c > +++ b/drivers/clk/tegra/clk-periph.c > @@ -170,14 +170,15 @@ const struct clk_ops tegra_clk_periph_nodiv_ops = { > static struct clk *_tegra_clk_register_periph(const char *name, > const char **parent_names, int num_parents, > struct tegra_clk_periph *periph, > - void __iomem *clk_base, u32 offset, bool div) > + void __iomem *clk_base, u32 offset, bool div, > + unsigned long flags) > { > struct clk *clk; > struct clk_init_data init; > > init.name = name; > init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops; > - init.flags = div ? 0 : CLK_SET_RATE_PARENT; > + init.flags = flags; > init.parent_names = parent_names; > init.num_parents = num_parents; > > @@ -202,10 +203,10 @@ static struct clk *_tegra_clk_register_periph(const char *name, > struct clk *tegra_clk_register_periph(const char *name, > const char **parent_names, int num_parents, > struct tegra_clk_periph *periph, void __iomem *clk_base, > - u32 offset) > + u32 offset, unsigned long flags) > { > return _tegra_clk_register_periph(name, parent_names, num_parents, > - periph, clk_base, offset, true); > + periph, clk_base, offset, true, flags); > } > > struct clk *tegra_clk_register_periph_nodiv(const char *name, > @@ -214,5 +215,5 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, > u32 offset) > { > return _tegra_clk_register_periph(name, parent_names, num_parents, > - periph, clk_base, offset, false); > + periph, clk_base, offset, false, CLK_SET_RATE_PARENT); > } > diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c > index 54c6777..870349e 100644 > --- a/drivers/clk/tegra/clk-tegra20.c > +++ b/drivers/clk/tegra/clk-tegra20.c > @@ -1048,7 +1048,7 @@ static void __init tegra20_periph_clk_init(void) > data = &tegra_periph_clk_list[i]; > clk = tegra_clk_register_periph(data->name, data->parent_names, > data->num_parents, &data->periph, > - clk_base, data->offset); > + clk_base, data->offset, data->flags); > clk_register_clkdev(clk, data->con_id, data->dev_id); > clks[data->clk_id] = clk; > } > diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c > index 078f9b8..126747b 100644 > --- a/drivers/clk/tegra/clk-tegra30.c > +++ b/drivers/clk/tegra/clk-tegra30.c > @@ -1665,7 +1665,7 @@ static void __init tegra30_periph_clk_init(void) > data = &tegra_periph_clk_list[i]; > clk = tegra_clk_register_periph(data->name, data->parent_names, > data->num_parents, &data->periph, > - clk_base, data->offset); > + clk_base, data->offset, data->flags); > clk_register_clkdev(clk, data->con_id, data->dev_id); > clks[data->clk_id] = clk; > } > diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h > index 4d0f556..79f5e2a 100644 > --- a/drivers/clk/tegra/clk.h > +++ b/drivers/clk/tegra/clk.h > @@ -411,7 +411,7 @@ extern const struct clk_ops tegra_clk_periph_ops; > struct clk *tegra_clk_register_periph(const char *name, > const char **parent_names, int num_parents, > struct tegra_clk_periph *periph, void __iomem *clk_base, > - u32 offset); > + u32 offset, unsigned long flags); > struct clk *tegra_clk_register_periph_nodiv(const char *name, > const char **parent_names, int num_parents, > struct tegra_clk_periph *periph, void __iomem *clk_base, > @@ -454,12 +454,14 @@ struct tegra_periph_init_data { > u32 offset; > const char *con_id; > const char *dev_id; > + unsigned long flags; > }; > > #define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ > _mux_shift, _mux_mask, _mux_flags, _div_shift, \ > _div_width, _div_frac_width, _div_flags, _regs, \ > - _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table) \ > + _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table,\ > + _flags) \ > { \ > .name = _name, \ > .clk_id = _clk_id, \ > @@ -474,6 +476,7 @@ struct tegra_periph_init_data { > .offset = _offset, \ > .con_id = _con_id, \ > .dev_id = _dev_id, \ > + .flags = _flags \ > } > > #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\ > @@ -484,7 +487,7 @@ struct tegra_periph_init_data { > _mux_shift, BIT(_mux_width) - 1, _mux_flags, \ > _div_shift, _div_width, _div_frac_width, _div_flags, \ > _regs, _clk_num, _enb_refcnt, _gate_flags, _clk_id,\ > - NULL) > + NULL, 0) > > /** > * struct clk_super_mux - super clock > ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v5 06/10] clk: tegra: Workaround for Tegra114 MSENC problem [not found] ` <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> ` (3 preceding siblings ...) 2013-02-01 10:18 ` [PATCH v5 05/10] clk: tegra: Add flags to tegra_clk_periph() Peter De Schrijver @ 2013-02-01 10:18 ` Peter De Schrijver 2013-02-04 6:39 ` Prashant Gaikwad 2013-02-01 10:18 ` [PATCH v5 07/10] ARM: tegra: Define Tegra114 CAR binding Peter De Schrijver ` (2 subsequent siblings) 7 siblings, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-01 10:18 UTC (permalink / raw) To: pdeschrijver-DDmLM1+adcrQT0dZR+AlfA Cc: Russell King, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Joseph Lo, linux-tegra-u79uwXL29TY76Z2rM5mHXA, Mike Turquette, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r Workaround a hardware bug in MSENC during clock enable. Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> --- drivers/clk/tegra/clk-periph-gate.c | 9 +++++++++ drivers/clk/tegra/clk.h | 1 + 2 files changed, 10 insertions(+), 0 deletions(-) diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c index 6dd5332..c9083fb 100644 --- a/drivers/clk/tegra/clk-periph-gate.c +++ b/drivers/clk/tegra/clk-periph-gate.c @@ -43,6 +43,8 @@ static DEFINE_SPINLOCK(periph_ref_lock); #define periph_clk_to_bit(periph) (1 << (gate->clk_num % 32)) +#define LVL2_CLK_GATE_OVRE 0x554 + /* Peripheral gate clock ops */ static int clk_periph_is_enabled(struct clk_hw *hw) { @@ -83,6 +85,13 @@ static int clk_periph_enable(struct clk_hw *hw) } } + if (gate->flags & TEGRA_PERIPH_WAR_1005168) { + writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); + writel_relaxed(BIT(22), gate->clk_base + LVL2_CLK_GATE_OVRE); + udelay(1); + writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); + } + spin_unlock_irqrestore(&periph_ref_lock, flags); return 0; diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 79f5e2a..8756d9f 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -371,6 +371,7 @@ struct tegra_clk_periph_gate { #define TEGRA_PERIPH_NO_RESET BIT(0) #define TEGRA_PERIPH_MANUAL_RESET BIT(1) #define TEGRA_PERIPH_ON_APB BIT(2) +#define TEGRA_PERIPH_WAR_1005168 BIT(3) void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert); extern const struct clk_ops tegra_clk_periph_gate_ops; ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [PATCH v5 06/10] clk: tegra: Workaround for Tegra114 MSENC problem 2013-02-01 10:18 ` [PATCH v5 06/10] clk: tegra: Workaround for Tegra114 MSENC problem Peter De Schrijver @ 2013-02-04 6:39 ` Prashant Gaikwad 0 siblings, 0 replies; 34+ messages in thread From: Prashant Gaikwad @ 2013-02-04 6:39 UTC (permalink / raw) To: Peter De Schrijver Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: > Workaround a hardware bug in MSENC during clock enable. > > Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> > --- > drivers/clk/tegra/clk-periph-gate.c | 9 +++++++++ > drivers/clk/tegra/clk.h | 1 + > 2 files changed, 10 insertions(+), 0 deletions(-) > > diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c > index 6dd5332..c9083fb 100644 > --- a/drivers/clk/tegra/clk-periph-gate.c > +++ b/drivers/clk/tegra/clk-periph-gate.c > @@ -43,6 +43,8 @@ static DEFINE_SPINLOCK(periph_ref_lock); > > #define periph_clk_to_bit(periph) (1 << (gate->clk_num % 32)) > > +#define LVL2_CLK_GATE_OVRE 0x554 > + > /* Peripheral gate clock ops */ > static int clk_periph_is_enabled(struct clk_hw *hw) > { > @@ -83,6 +85,13 @@ static int clk_periph_enable(struct clk_hw *hw) > } > } > > + if (gate->flags & TEGRA_PERIPH_WAR_1005168) { > + writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); > + writel_relaxed(BIT(22), gate->clk_base + LVL2_CLK_GATE_OVRE); > + udelay(1); > + writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); > + } > + > spin_unlock_irqrestore(&periph_ref_lock, flags); > > return 0; > diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h > index 79f5e2a..8756d9f 100644 > --- a/drivers/clk/tegra/clk.h > +++ b/drivers/clk/tegra/clk.h > @@ -371,6 +371,7 @@ struct tegra_clk_periph_gate { > #define TEGRA_PERIPH_NO_RESET BIT(0) > #define TEGRA_PERIPH_MANUAL_RESET BIT(1) > #define TEGRA_PERIPH_ON_APB BIT(2) > +#define TEGRA_PERIPH_WAR_1005168 BIT(3) > Comment for this flag, otherwise Reviewed-by: Prashant Gaikwad <pgaikwad@nvidia.com> > void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert); > extern const struct clk_ops tegra_clk_periph_gate_ops; > ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v5 07/10] ARM: tegra: Define Tegra114 CAR binding [not found] ` <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> ` (4 preceding siblings ...) 2013-02-01 10:18 ` [PATCH v5 06/10] clk: tegra: Workaround for Tegra114 MSENC problem Peter De Schrijver @ 2013-02-01 10:18 ` Peter De Schrijver 2013-02-04 21:16 ` Stephen Warren 2013-02-01 10:18 ` [PATCH v5 08/10] ARM: dt: Add references to tegra_car clocks Peter De Schrijver 2013-02-01 10:18 ` [PATCH v5 10/10] clk: tegra: devicetree match for nvidia,tegra114-car Peter De Schrijver 7 siblings, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-01 10:18 UTC (permalink / raw) To: pdeschrijver-DDmLM1+adcrQT0dZR+AlfA Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Prashant Gaikwad, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-tegra-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r The device tree binding models Tegra114 CAR (Clock And Reset) as a single monolithic clock provider. Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> --- .../bindings/clock/nvidia,tegra114-car.txt | 311 ++++++++++++++++++++ 1 files changed, 311 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt new file mode 100644 index 0000000..516b9d3 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt @@ -0,0 +1,311 @@ +NVIDIA Tegra114 Clock And Reset Controller + +This binding uses the common clock binding: +Documentation/devicetree/bindings/clock/clock-bindings.txt + +The CAR (Clock And Reset) Controller on Tegra is the HW module responsible +for muxing and gating Tegra's clocks, and setting their rates. + +Required properties : +- compatible : Should be "nvidia,tegra114-car" +- reg : Should contain CAR registers location and length +- clocks : Should contain phandle and clock specifiers for two clocks: + the 32 KHz "32k_in", and the board-specific oscillator "osc". +- #clock-cells : Should be 1. + In clock consumers, this cell represents the clock ID exposed by the CAR. + + The first 160 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB + registers. These IDs often match those in the CAR's RST_DEVICES registers, + but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In + this case, those clocks are assigned IDs above 160 in order to highlight + this issue. Implementations that interpret these clock IDs as bit values + within the CLK_OUT_ENB or RST_DEVICES registers should be careful to + explicitly handle these special cases. + + The balance of the clocks controlled by the CAR are assigned IDs of 160 and + above. + + 0 cpu + 1 unassigned + 2 unassigned + 3 unassigned + 4 rtc + 5 timer + 6 uarta + 7 unassigned (register bit affects uartb and vfir) + 8 unassigned + 9 sdmmc2 + 10 unassigned (register bit affects spdif_in and spdif_out) + 11 i2s1 + 12 i2c1 + 13 ndflash + 14 sdmmc1 + 15 sdmmc4 + 16 unassigned + 17 pwm + 18 i2s2 + 19 epp + 20 unassigned (register bit affects vi and vi_sensor) + 21 2d + 22 usbd + 23 isp + 24 3d + 25 unassigned + 26 disp2 + 27 disp1 + 28 host1x + 29 vcp + 30 i2s0 + 31 unassigned + + 32 unassigned + 33 unassigned + 34 apbdma + 35 unassigned + 36 kbc + 37 unassigned + 38 unassigned + 39 unassigned (register bit affects fuse and fuse_burn) + 40 kfuse + 41 sbc1 + 42 nor + 43 unassigned + 44 sbc2 + 45 unassigned + 46 sbc3 + 47 i2c5 + 48 dsia + 49 unassigned + 50 mipi + 51 hdmi + 52 csi + 53 unassigned + 54 i2c2 + 55 uartc + 56 mipi-cal + 57 unassigned + 58 usb2 + 59 usb3 + 60 msenc + 61 vde + 62 bsea + 63 bsev + + 64 unassigned + 65 uartd + 66 unassigned + 67 i2c3 + 68 sbc4 + 69 sdmmc3 + 70 unassigned + 71 owr + 72 afi + 73 csite + 74 unassigned + 75 unassigned + 76 la + 77 trace + 78 soc_therm + 79 dtv + 80 ndspeed + 81 i2cslow + 82 dsib + 83 tsec + 84 unassigned + 85 unassigned + 86 unassigned + 87 unassigned + 88 unassigned + 89 xusb_host + 90 unassigned + 91 msenc + 92 csus + 93 unassigned + 94 unassigned + 95 unassigned (bit affects xusb_dev and xusb_dev_src) + + 96 unassigned + 97 unassigned + 98 unassigned + 99 mselect + 100 tsensor + 101 i2s3 + 102 i2s4 + 103 i2c4 + 104 sbc5 + 105 sbc6 + 106 d_audio + 107 apbif + 108 dam0 + 109 dam1 + 110 dam2 + 111 hda2codec_2x + 112 unassigned + 113 audio0_2x + 114 audio1_2x + 115 audio2_2x + 116 audio3_2x + 117 audio4_2x + 118 spdif_2x + 119 actmon + 120 extern1 + 121 extern2 + 122 extern3 + 123 unassigned + 124 unassigned + 125 hda + 126 unassigned + 127 se + + 128 hda2hdmi + 129 unassigned + 130 unassigned + 131 unassigned + 132 unassigned + 133 unassigned + 134 unassigned + 135 unassigned + 136 unassigned + 137 unassigned + 138 unassigned + 139 unassigned + 140 unassigned + 141 unassigned + 142 unassigned + 143 unassigned (bit affects xusb_falcon_src, xusb_fs_src, + xusb_host_src and xusb_ss_src) + 144 cilab + 145 cilcd + 146 cile + 147 dsialp + 148 dsiblp + 149 unassigned + 150 dds + 151 unassigned + 152 dp2 + 153 amx + 154 adx + 155 unassigned + 156 xusb_ss + + 192 uartb + 193 vfir + 194 spdif_in + 195 spdif_out + 196 vi + 197 vi_sensor + 198 fuse + 199 fuse_burn + 200 clk_32k + 201 clk_m + 202 clk_m_div2 + 203 clk_m_div4 + 204 pll_ref + 205 pll_c + 206 pll_c_out1 + 207 pll_c2 + 208 pll_c3 + 209 pll_m + 210 pll_m_out1 + 211 pll_p + 212 pll_p_out1 + 213 pll_p_out2 + 214 pll_p_out3 + 215 pll_p_out4 + 216 pll_a + 217 pll_a_out1 + 218 pll_d + 219 pll_d_out0 + 220 pll_d2 + 221 pll_d2_out0 + 222 pll_u + 223 pll_u_480M + 224 pll_u_60M + 225 pll_u_48M + 226 pll_u_12M + 227 pll_x + 228 pll_x_out0 + 229 pll_re_vco + 230 pll_re_out + 231 pll_e_out0 + 232 spdif_in_sync + 233 i2s0_sync + 234 i2s1_sync + 235 i2s2_sync + 236 i2s3_sync + 237 i2s4_sync + 238 vimclk_sync + 239 audio0 + 240 audio1 + 241 audio2 + 242 audio3 + 243 audio4 + 244 spdif + 245 clk_out_1 + 246 clk_out_2 + 247 clk_out_3 + 248 blink + 249 mipi_cal_fast + 250 dsi1_fixed + 251 dsi2_fixed + 252 xusb_host_src + 253 xusb_falcon_src + 254 xusb_fs_src + 255 xusb_ss_src + 256 xusb_dev_src + 257 xusb_dev + 258 xusb_hs_src + +Mux clocks + + 300 audio0_mux + 301 audio1_mux + 302 audio2_mux + 303 audio3_mux + 304 audio4_mux + 305 spdif_mux + 306 clk_out_1_mux + 307 clk_out_2_mux + 308 clk_out_3_mux + +Example SoC include file: + +/ { + tegra_car: clock { + compatible = "nvidia,tegra114-car"; + reg = <0x60006000 0x1000>; + #clock-cells = <1>; + }; + + usb@c5004000 { + clocks = <&tegra_car 58>; /* usb2 */ + }; +}; + +Example board file: + +/ { + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + osc: clock@0 { + compatible = "fixed-clock"; + reg = <0>; + #clock-cells = <0>; + clock-frequency = <12000000>; + }; + + clk_32k: clock@1 { + compatible = "fixed-clock"; + reg = <1>; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + + &tegra_car { + clocks = <&clk_32k> <&osc>; + }; +}; ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [PATCH v5 07/10] ARM: tegra: Define Tegra114 CAR binding 2013-02-01 10:18 ` [PATCH v5 07/10] ARM: tegra: Define Tegra114 CAR binding Peter De Schrijver @ 2013-02-04 21:16 ` Stephen Warren 0 siblings, 0 replies; 34+ messages in thread From: Stephen Warren @ 2013-02-04 21:16 UTC (permalink / raw) To: Peter De Schrijver Cc: Grant Likely, Rob Herring, Rob Landley, Russell King, Prashant Gaikwad, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss, linux-doc, linux-kernel, linux-tegra, linux-arm-kernel On 02/01/2013 03:18 AM, Peter De Schrijver wrote: > The device tree binding models Tegra114 CAR (Clock And Reset) as a single > monolithic clock provider. ... > +- #clock-cells : Should be 1. > + In clock consumers, this cell represents the clock ID exposed by the CAR. ... > + 222 pll_u > + 223 pll_u_480M > + 224 pll_u_60M > + 225 pll_u_48M > + 226 pll_u_12M I notice here that we have separate clock IDs for the various PLL u outputs. We don't have this on Tegra20 or Tegra30, but I wonder if we should have them there too? ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v5 08/10] ARM: dt: Add references to tegra_car clocks [not found] ` <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> ` (5 preceding siblings ...) 2013-02-01 10:18 ` [PATCH v5 07/10] ARM: tegra: Define Tegra114 CAR binding Peter De Schrijver @ 2013-02-01 10:18 ` Peter De Schrijver 2013-02-04 6:45 ` Prashant Gaikwad 2013-02-01 10:18 ` [PATCH v5 10/10] clk: tegra: devicetree match for nvidia,tegra114-car Peter De Schrijver 7 siblings, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-01 10:18 UTC (permalink / raw) To: pdeschrijver-DDmLM1+adcrQT0dZR+AlfA Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Prashant Gaikwad, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-tegra-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r Add references to tegra_car clocks for the basic device nodes. Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> --- arch/arm/boot/dts/tegra114.dtsi | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi index 96a8235..1dec620 100644 --- a/arch/arm/boot/dts/tegra114.dtsi +++ b/arch/arm/boot/dts/tegra114.dtsi @@ -27,7 +27,7 @@ }; tegra_car: clock { - compatible = "nvidia,tegra114-car, nvidia,tegra30-car"; + compatible = "nvidia,tegra114-car"; reg = <0x60006000 0x1000>; #clock-cells = <1>; }; @@ -43,6 +43,7 @@ reg-shift = <2>; interrupts = <0 36 0x04>; status = "disabled"; + clocks = <&tegra_car 6>; }; serial@70006040 { @@ -51,6 +52,7 @@ reg-shift = <2>; interrupts = <0 37 0x04>; status = "disabled"; + clocks = <&tegra_car 192>; }; serial@70006200 { @@ -59,6 +61,7 @@ reg-shift = <2>; interrupts = <0 46 0x04>; status = "disabled"; + clocks = <&tegra_car 55>; }; serial@70006300 { @@ -67,12 +70,14 @@ reg-shift = <2>; interrupts = <0 90 0x04>; status = "disabled"; + clocks = <&tegra_car 65>; }; rtc { compatible = "nvidia,tegra114-rtc", "nvidia,tegra20-rtc"; reg = <0x7000e000 0x100>; interrupts = <0 2 0x04>; + clocks = <&tegra_car 4>; }; pmc { ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [PATCH v5 08/10] ARM: dt: Add references to tegra_car clocks 2013-02-01 10:18 ` [PATCH v5 08/10] ARM: dt: Add references to tegra_car clocks Peter De Schrijver @ 2013-02-04 6:45 ` Prashant Gaikwad 0 siblings, 0 replies; 34+ messages in thread From: Prashant Gaikwad @ 2013-02-04 6:45 UTC (permalink / raw) To: Peter De Schrijver Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: > Add references to tegra_car clocks for the basic device nodes. > > Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> > --- Reviewed-by: Prashant Gaikwad <pgaikwad@nvidia.com> > arch/arm/boot/dts/tegra114.dtsi | 7 ++++++- > 1 files changed, 6 insertions(+), 1 deletions(-) > > diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi > index 96a8235..1dec620 100644 > --- a/arch/arm/boot/dts/tegra114.dtsi > +++ b/arch/arm/boot/dts/tegra114.dtsi > @@ -27,7 +27,7 @@ > }; > > tegra_car: clock { > - compatible = "nvidia,tegra114-car, nvidia,tegra30-car"; > + compatible = "nvidia,tegra114-car"; > reg = <0x60006000 0x1000>; > #clock-cells = <1>; > }; > @@ -43,6 +43,7 @@ > reg-shift = <2>; > interrupts = <0 36 0x04>; > status = "disabled"; > + clocks = <&tegra_car 6>; > }; > > serial@70006040 { > @@ -51,6 +52,7 @@ > reg-shift = <2>; > interrupts = <0 37 0x04>; > status = "disabled"; > + clocks = <&tegra_car 192>; > }; > > serial@70006200 { > @@ -59,6 +61,7 @@ > reg-shift = <2>; > interrupts = <0 46 0x04>; > status = "disabled"; > + clocks = <&tegra_car 55>; > }; > > serial@70006300 { > @@ -67,12 +70,14 @@ > reg-shift = <2>; > interrupts = <0 90 0x04>; > status = "disabled"; > + clocks = <&tegra_car 65>; > }; > > rtc { > compatible = "nvidia,tegra114-rtc", "nvidia,tegra20-rtc"; > reg = <0x7000e000 0x100>; > interrupts = <0 2 0x04>; > + clocks = <&tegra_car 4>; > }; > > pmc { > ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v5 10/10] clk: tegra: devicetree match for nvidia,tegra114-car [not found] ` <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> ` (6 preceding siblings ...) 2013-02-01 10:18 ` [PATCH v5 08/10] ARM: dt: Add references to tegra_car clocks Peter De Schrijver @ 2013-02-01 10:18 ` Peter De Schrijver 2013-02-04 7:10 ` Prashant Gaikwad 7 siblings, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-01 10:18 UTC (permalink / raw) To: pdeschrijver-DDmLM1+adcrQT0dZR+AlfA Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Prashant Gaikwad, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, linux-doc-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-tegra-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> --- drivers/clk/tegra/clk.c | 1 + drivers/clk/tegra/clk.h | 7 +++++++ 2 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index a603b9a..a328365 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -76,6 +76,7 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl, static const struct of_device_id tegra_dt_clk_match[] = { { .compatible = "nvidia,tegra20-car", .data = tegra20_clock_init }, { .compatible = "nvidia,tegra30-car", .data = tegra30_clock_init }, + { .compatible = "nvidia,tegra114-car", .data = tegra114_clock_init }, { } }; diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 8756d9f..8097850 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -576,4 +576,11 @@ void tegra30_clock_init(struct device_node *np); static inline void tegra30_clock_init(struct device_node *np) {} #endif /* CONFIG_ARCH_TEGRA_3x_SOC */ +#ifdef CONFIG_ARCH_TEGRA_114_SOC +void tegra114_clock_init(struct device_node *np); +#else +static inline void tegra114_clock_init(struct device_node *np) {} +#endif /* CONFIG_ARCH_TEGRA114_SOC */ + + #endif /* TEGRA_CLK_H */ ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [PATCH v5 10/10] clk: tegra: devicetree match for nvidia,tegra114-car 2013-02-01 10:18 ` [PATCH v5 10/10] clk: tegra: devicetree match for nvidia,tegra114-car Peter De Schrijver @ 2013-02-04 7:10 ` Prashant Gaikwad 0 siblings, 0 replies; 34+ messages in thread From: Prashant Gaikwad @ 2013-02-04 7:10 UTC (permalink / raw) To: Peter De Schrijver Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: > Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> > --- Reviewed-by: Prashant Gaikwad <pgaikwad@nvidia.com> > drivers/clk/tegra/clk.c | 1 + > drivers/clk/tegra/clk.h | 7 +++++++ > 2 files changed, 8 insertions(+), 0 deletions(-) > > diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c > index a603b9a..a328365 100644 > --- a/drivers/clk/tegra/clk.c > +++ b/drivers/clk/tegra/clk.c > @@ -76,6 +76,7 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl, > static const struct of_device_id tegra_dt_clk_match[] = { > { .compatible = "nvidia,tegra20-car", .data = tegra20_clock_init }, > { .compatible = "nvidia,tegra30-car", .data = tegra30_clock_init }, > + { .compatible = "nvidia,tegra114-car", .data = tegra114_clock_init }, > { } > }; > > diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h > index 8756d9f..8097850 100644 > --- a/drivers/clk/tegra/clk.h > +++ b/drivers/clk/tegra/clk.h > @@ -576,4 +576,11 @@ void tegra30_clock_init(struct device_node *np); > static inline void tegra30_clock_init(struct device_node *np) {} > #endif /* CONFIG_ARCH_TEGRA_3x_SOC */ > > +#ifdef CONFIG_ARCH_TEGRA_114_SOC > +void tegra114_clock_init(struct device_node *np); > +#else > +static inline void tegra114_clock_init(struct device_node *np) {} > +#endif /* CONFIG_ARCH_TEGRA114_SOC */ > + > + > #endif /* TEGRA_CLK_H */ > ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v5 03/10] clk: tegra: Add PLL post divider table 2013-02-01 10:18 [PATCH v5 00/10] Tegra114 clockframework Peter De Schrijver [not found] ` <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> @ 2013-02-01 10:18 ` Peter De Schrijver [not found] ` <1359713962-16822-4-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-01 10:18 ` [PATCH v5 09/10] clk: tegra: Implement clocks for Tegra114 Peter De Schrijver 2 siblings, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-01 10:18 UTC (permalink / raw) To: pdeschrijver Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Prashant Gaikwad, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss, linux-doc, linux-kernel, linux-tegra, linux-arm-kernel Some PLLs in Tegra114 don't use a power of 2 mapping for the post divider. Introduce a table based approach and switch PLLU to it. Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> --- drivers/clk/tegra/clk-pll.c | 38 ++++++++++++++++++++++++++++++++------ drivers/clk/tegra/clk-tegra20.c | 7 +++++++ drivers/clk/tegra/clk-tegra30.c | 7 +++++++ drivers/clk/tegra/clk.h | 13 +++++++++++++ 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 3c3a25e..87d2f34 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -258,6 +258,7 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, unsigned long rate, unsigned long parent_rate) { struct tegra_clk_pll *pll = to_clk_pll(hw); + struct pdiv_map *p_tohw = pll->params->pdiv_tohw; unsigned long cfreq; u32 p_div = 0; @@ -291,7 +292,6 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, cfg->output_rate <<= 1) p_div++; - cfg->p = p_div; cfg->m = parent_rate / cfreq; cfg->n = cfg->output_rate / cfreq; cfg->cpcon = OUT_OF_TABLE_CPCON; @@ -304,8 +304,19 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, return -EINVAL; } - if (pll->flags & TEGRA_PLLU) - cfg->p ^= 1; + if (p_tohw) { + p_div = 1 << p_div; + while (p_tohw->pdiv) { + if (p_div <= p_tohw->pdiv) { + cfg->p = p_tohw->hw_val; + break; + } + p_tohw++; + } + if (!p_tohw->pdiv) + return -EINVAL; + } else + cfg->p = p_div; return 0; } @@ -452,8 +463,10 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, { struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll_freq_table cfg; + struct pdiv_map *p_tohw = pll->params->pdiv_tohw; u32 val; u64 rate = parent_rate; + int pdiv; val = pll_readl_base(pll); @@ -472,10 +485,23 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, _get_pll_mnp(pll, &cfg); - if (pll->flags & TEGRA_PLLU) - cfg.p ^= 1; + if (p_tohw) { + while (p_tohw->pdiv) { + if (cfg.p == p_tohw->hw_val) { + pdiv = p_tohw->pdiv; + break; + } + p_tohw++; + } + + if (!p_tohw->pdiv) { + WARN_ON(1); + pdiv = 1; + } + } else + pdiv = 1 << cfg.p; - cfg.m *= 1 << cfg.p; + cfg.m *= pdiv; rate *= cfg.n; do_div(rate, cfg.m); diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 30bd3fd..54c6777 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -440,6 +440,12 @@ static struct tegra_clk_pll_params pll_d_params = { .lock_delay = 1000, }; +static struct pdiv_map pllu_p[] = { + { .pdiv = 1, .hw_val = 1 }, + { .pdiv = 2, .hw_val = 0 }, + { .pdiv = 0, .hw_val = 0 }, +}; + static struct tegra_clk_pll_params pll_u_params = { .input_min = 2000000, .input_max = 40000000, @@ -452,6 +458,7 @@ static struct tegra_clk_pll_params pll_u_params = { .lock_bit_idx = PLL_BASE_LOCK, .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, + .pdiv_tohw = pllu_p, }; static struct tegra_clk_pll_params pll_x_params = { diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 28a2997..078f9b8 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -466,6 +466,12 @@ static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { { 0, 0, 0, 0, 0, 0 }, }; +static struct pdiv_map pllu_p[] = { + { .pdiv = 1, .hw_val = 1 }, + { .pdiv = 2, .hw_val = 0 }, + { .pdiv = 0, .hw_val = 0 }, +}; + static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { { 12000000, 480000000, 960, 12, 0, 12}, { 13000000, 480000000, 960, 13, 0, 12}, @@ -639,6 +645,7 @@ static struct tegra_clk_pll_params pll_u_params = { .lock_bit_idx = PLL_BASE_LOCK, .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, .lock_delay = 1000, + .pdiv_tohw = pllu_p, }; static struct tegra_clk_pll_params pll_x_params = { diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 3cff1df..1b9cbcd 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -117,6 +117,17 @@ struct tegra_clk_pll_freq_table { }; /** + * struct pdiv_map - map post divider to hw value + * + * @pdiv: post divider + * @hw_val: value to be written to the PLL hw + */ +struct pdiv_map { + u8 pdiv; + u8 hw_val; +}; + +/** * struct clk_pll_params - PLL parameters * * @input_min: Minimum input frequency @@ -146,6 +157,8 @@ struct tegra_clk_pll_params { u32 lock_bit_idx; u32 lock_enable_bit_idx; int lock_delay; + int max_p; + struct pdiv_map *pdiv_tohw; }; /** ^ permalink raw reply related [flat|nested] 34+ messages in thread
[parent not found: <1359713962-16822-4-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v5 03/10] clk: tegra: Add PLL post divider table [not found] ` <1359713962-16822-4-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> @ 2013-02-04 6:28 ` Prashant Gaikwad 0 siblings, 0 replies; 34+ messages in thread From: Prashant Gaikwad @ 2013-02-04 6:28 UTC (permalink / raw) To: Peter De Schrijver Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: > Some PLLs in Tegra114 don't use a power of 2 mapping for the post divider. > Introduce a table based approach and switch PLLU to it. > > Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> > --- Looks good to me. Reviewed-by: Prashant Gaikwad <pgaikwad-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> > drivers/clk/tegra/clk-pll.c | 38 ++++++++++++++++++++++++++++++++------ > drivers/clk/tegra/clk-tegra20.c | 7 +++++++ > drivers/clk/tegra/clk-tegra30.c | 7 +++++++ > drivers/clk/tegra/clk.h | 13 +++++++++++++ > 4 files changed, 59 insertions(+), 6 deletions(-) > > diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c > index 3c3a25e..87d2f34 100644 > --- a/drivers/clk/tegra/clk-pll.c > +++ b/drivers/clk/tegra/clk-pll.c > @@ -258,6 +258,7 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, > unsigned long rate, unsigned long parent_rate) > { > struct tegra_clk_pll *pll = to_clk_pll(hw); > + struct pdiv_map *p_tohw = pll->params->pdiv_tohw; > unsigned long cfreq; > u32 p_div = 0; > > @@ -291,7 +292,6 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, > cfg->output_rate <<= 1) > p_div++; > > - cfg->p = p_div; > cfg->m = parent_rate / cfreq; > cfg->n = cfg->output_rate / cfreq; > cfg->cpcon = OUT_OF_TABLE_CPCON; > @@ -304,8 +304,19 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, > return -EINVAL; > } > > - if (pll->flags & TEGRA_PLLU) > - cfg->p ^= 1; > + if (p_tohw) { > + p_div = 1 << p_div; > + while (p_tohw->pdiv) { > + if (p_div <= p_tohw->pdiv) { > + cfg->p = p_tohw->hw_val; > + break; > + } > + p_tohw++; > + } > + if (!p_tohw->pdiv) > + return -EINVAL; > + } else > + cfg->p = p_div; > > return 0; > } > @@ -452,8 +463,10 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, > { > struct tegra_clk_pll *pll = to_clk_pll(hw); > struct tegra_clk_pll_freq_table cfg; > + struct pdiv_map *p_tohw = pll->params->pdiv_tohw; > u32 val; > u64 rate = parent_rate; > + int pdiv; > > val = pll_readl_base(pll); > > @@ -472,10 +485,23 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, > > _get_pll_mnp(pll, &cfg); > > - if (pll->flags & TEGRA_PLLU) > - cfg.p ^= 1; > + if (p_tohw) { > + while (p_tohw->pdiv) { > + if (cfg.p == p_tohw->hw_val) { > + pdiv = p_tohw->pdiv; > + break; > + } > + p_tohw++; > + } > + > + if (!p_tohw->pdiv) { > + WARN_ON(1); > + pdiv = 1; > + } > + } else > + pdiv = 1 << cfg.p; > > - cfg.m *= 1 << cfg.p; > + cfg.m *= pdiv; > > rate *= cfg.n; > do_div(rate, cfg.m); > diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c > index 30bd3fd..54c6777 100644 > --- a/drivers/clk/tegra/clk-tegra20.c > +++ b/drivers/clk/tegra/clk-tegra20.c > @@ -440,6 +440,12 @@ static struct tegra_clk_pll_params pll_d_params = { > .lock_delay = 1000, > }; > > +static struct pdiv_map pllu_p[] = { > + { .pdiv = 1, .hw_val = 1 }, > + { .pdiv = 2, .hw_val = 0 }, > + { .pdiv = 0, .hw_val = 0 }, > +}; > + > static struct tegra_clk_pll_params pll_u_params = { > .input_min = 2000000, > .input_max = 40000000, > @@ -452,6 +458,7 @@ static struct tegra_clk_pll_params pll_u_params = { > .lock_bit_idx = PLL_BASE_LOCK, > .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, > .lock_delay = 1000, > + .pdiv_tohw = pllu_p, > }; > > static struct tegra_clk_pll_params pll_x_params = { > diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c > index 28a2997..078f9b8 100644 > --- a/drivers/clk/tegra/clk-tegra30.c > +++ b/drivers/clk/tegra/clk-tegra30.c > @@ -466,6 +466,12 @@ static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { > { 0, 0, 0, 0, 0, 0 }, > }; > > +static struct pdiv_map pllu_p[] = { > + { .pdiv = 1, .hw_val = 1 }, > + { .pdiv = 2, .hw_val = 0 }, > + { .pdiv = 0, .hw_val = 0 }, > +}; > + > static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { > { 12000000, 480000000, 960, 12, 0, 12}, > { 13000000, 480000000, 960, 13, 0, 12}, > @@ -639,6 +645,7 @@ static struct tegra_clk_pll_params pll_u_params = { > .lock_bit_idx = PLL_BASE_LOCK, > .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, > .lock_delay = 1000, > + .pdiv_tohw = pllu_p, > }; > > static struct tegra_clk_pll_params pll_x_params = { > diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h > index 3cff1df..1b9cbcd 100644 > --- a/drivers/clk/tegra/clk.h > +++ b/drivers/clk/tegra/clk.h > @@ -117,6 +117,17 @@ struct tegra_clk_pll_freq_table { > }; > > /** > + * struct pdiv_map - map post divider to hw value > + * > + * @pdiv: post divider > + * @hw_val: value to be written to the PLL hw > + */ > +struct pdiv_map { > + u8 pdiv; > + u8 hw_val; > +}; > + > +/** > * struct clk_pll_params - PLL parameters > * > * @input_min: Minimum input frequency > @@ -146,6 +157,8 @@ struct tegra_clk_pll_params { > u32 lock_bit_idx; > u32 lock_enable_bit_idx; > int lock_delay; > + int max_p; > + struct pdiv_map *pdiv_tohw; > }; > > /** > ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v5 09/10] clk: tegra: Implement clocks for Tegra114 2013-02-01 10:18 [PATCH v5 00/10] Tegra114 clockframework Peter De Schrijver [not found] ` <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-01 10:18 ` [PATCH v5 03/10] clk: tegra: Add PLL post divider table Peter De Schrijver @ 2013-02-01 10:18 ` Peter De Schrijver 2013-02-04 7:08 ` Prashant Gaikwad 2 siblings, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-01 10:18 UTC (permalink / raw) To: pdeschrijver Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Prashant Gaikwad, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss, linux-doc, linux-kernel, linux-tegra, linux-arm-kernel Implement most clocks for Tegra114. The super clocks for the CPU complex are still missing and will be implemented in a future version. Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> --- drivers/clk/tegra/Makefile | 1 + drivers/clk/tegra/clk-tegra114.c | 2002 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 2003 insertions(+), 0 deletions(-) create mode 100644 drivers/clk/tegra/clk-tegra114.c diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index 2b41b0f..f49fac2 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -9,3 +9,4 @@ obj-y += clk-super.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o +obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c new file mode 100644 index 0000000..f8165d2 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra114.c @@ -0,0 +1,2002 @@ +/* + * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/delay.h> +#include <linux/clk/tegra.h> + +#include "clk.h" + +#define RST_DEVICES_L 0x004 +#define RST_DEVICES_H 0x008 +#define RST_DEVICES_U 0x00C +#define RST_DEVICES_V 0x358 +#define RST_DEVICES_W 0x35C +#define RST_DEVICES_X 0x28C +#define RST_DEVICES_SET_L 0x300 +#define RST_DEVICES_CLR_L 0x304 +#define RST_DEVICES_SET_H 0x308 +#define RST_DEVICES_CLR_H 0x30c +#define RST_DEVICES_SET_U 0x310 +#define RST_DEVICES_CLR_U 0x314 +#define RST_DEVICES_SET_V 0x430 +#define RST_DEVICES_CLR_V 0x434 +#define RST_DEVICES_SET_W 0x438 +#define RST_DEVICES_CLR_W 0x43c +#define RST_DEVICES_NUM 5 + +#define CLK_OUT_ENB_L 0x010 +#define CLK_OUT_ENB_H 0x014 +#define CLK_OUT_ENB_U 0x018 +#define CLK_OUT_ENB_V 0x360 +#define CLK_OUT_ENB_W 0x364 +#define CLK_OUT_ENB_X 0x280 +#define CLK_OUT_ENB_SET_L 0x320 +#define CLK_OUT_ENB_CLR_L 0x324 +#define CLK_OUT_ENB_SET_H 0x328 +#define CLK_OUT_ENB_CLR_H 0x32c +#define CLK_OUT_ENB_SET_U 0x330 +#define CLK_OUT_ENB_CLR_U 0x334 +#define CLK_OUT_ENB_SET_V 0x440 +#define CLK_OUT_ENB_CLR_V 0x444 +#define CLK_OUT_ENB_SET_W 0x448 +#define CLK_OUT_ENB_CLR_W 0x44c +#define CLK_OUT_ENB_SET_X 0x284 +#define CLK_OUT_ENB_CLR_X 0x288 +#define CLK_OUT_ENB_NUM 6 + +#define PLLC_BASE 0x80 +#define PLLC_MISC2 0x88 +#define PLLC_MISC 0x8c +#define PLLC2_BASE 0x4e8 +#define PLLC2_MISC 0x4ec +#define PLLC3_BASE 0x4fc +#define PLLC3_MISC 0x500 +#define PLLM_BASE 0x90 +#define PLLM_MISC 0x9c +#define PLLP_BASE 0xa0 +#define PLLP_MISC 0xac +#define PLLX_BASE 0xe0 +#define PLLX_MISC 0xe4 +#define PLLX_MISC2 0x514 +#define PLLX_MISC3 0x518 +#define PLLD_BASE 0xd0 +#define PLLD_MISC 0xdc +#define PLLD2_BASE 0x4b8 +#define PLLD2_MISC 0x4bc +#define PLLE_BASE 0xe8 +#define PLLE_MISC 0xec +#define PLLA_BASE 0xb0 +#define PLLA_MISC 0xbc +#define PLLU_BASE 0xc0 +#define PLLU_MISC 0xcc +#define PLLRE_BASE 0x4c4 +#define PLLRE_MISC 0x4c8 + +#define PLL_MISC_LOCK_ENABLE 18 +#define PLLDU_MISC_LOCK_ENABLE 22 +#define PLLE_MISC_LOCK_ENABLE 9 +#define PLLRE_MISC_LOCK_ENABLE 30 + +#define PLLC_IDDQ_BIT 26 +#define PLLX_IDDQ_BIT 3 +#define PLLRE_IDDQ_BIT 16 + +#define PLL_BASE_LOCK 27 +#define PLLE_MISC_LOCK 11 +#define PLLRE_MISC_LOCK 24 + +#define PLLE_AUX 0x48c +#define PLLC_OUT 0x84 +#define PLLM_OUT 0x94 +#define PLLP_OUTA 0xa4 +#define PLLP_OUTB 0xa8 +#define PLLA_OUT 0xb4 + +#define AUDIO_SYNC_CLK_I2S0 0x4a0 +#define AUDIO_SYNC_CLK_I2S1 0x4a4 +#define AUDIO_SYNC_CLK_I2S2 0x4a8 +#define AUDIO_SYNC_CLK_I2S3 0x4ac +#define AUDIO_SYNC_CLK_I2S4 0x4b0 +#define AUDIO_SYNC_CLK_SPDIF 0x4b4 + +#define AUDIO_SYNC_DOUBLER 0x49c + +#define PMC_CLK_OUT_CNTRL 0x1a8 +#define PMC_DPD_PADS_ORIDE 0x1c +#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 +#define PMC_CTRL 0 +#define PMC_CTRL_BLINK_ENB 7 + +#define OSC_CTRL 0x50 +#define OSC_CTRL_OSC_FREQ_SHIFT 28 +#define OSC_CTRL_PLL_REF_DIV_SHIFT 26 + +#define PLLXC_SW_MAX_P 6 + +#define UTMIP_PLL_CFG2 0x488 +#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) +#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN BIT(0) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN BIT(2) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN BIT(4) + +#define UTMIP_PLL_CFG1 0x484 +#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 6) +#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) +#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP BIT(17) +#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN BIT(16) +#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP BIT(15) +#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14) +#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12) + +#define UTMIPLL_HW_PWRDN_CFG0 0x52c +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE BIT(25) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE BIT(24) +#define UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET BIT(6) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_RESET_INPUT_VALUE BIT(5) +#define UTMIPLL_HW_PWRDN_CFG0_SEQ_IN_SWCTL BIT(4) +#define UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL BIT(2) +#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1) +#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0) + +#define CLK_SOURCE_I2S0 0x1d8 +#define CLK_SOURCE_I2S1 0x100 +#define CLK_SOURCE_I2S2 0x104 +#define CLK_SOURCE_NDFLASH 0x160 +#define CLK_SOURCE_I2S3 0x3bc +#define CLK_SOURCE_I2S4 0x3c0 +#define CLK_SOURCE_SPDIF_OUT 0x108 +#define CLK_SOURCE_SPDIF_IN 0x10c +#define CLK_SOURCE_PWM 0x110 +#define CLK_SOURCE_ADX 0x638 +#define CLK_SOURCE_AMX 0x63c +#define CLK_SOURCE_HDA 0x428 +#define CLK_SOURCE_HDA2CODEC_2X 0x3e4 +#define CLK_SOURCE_SBC1 0x134 +#define CLK_SOURCE_SBC2 0x118 +#define CLK_SOURCE_SBC3 0x11c +#define CLK_SOURCE_SBC4 0x1b4 +#define CLK_SOURCE_SBC5 0x3c8 +#define CLK_SOURCE_SBC6 0x3cc +#define CLK_SOURCE_SATA_OOB 0x420 +#define CLK_SOURCE_SATA 0x424 +#define CLK_SOURCE_NDSPEED 0x3f8 +#define CLK_SOURCE_VFIR 0x168 +#define CLK_SOURCE_SDMMC1 0x150 +#define CLK_SOURCE_SDMMC2 0x154 +#define CLK_SOURCE_SDMMC3 0x1bc +#define CLK_SOURCE_SDMMC4 0x164 +#define CLK_SOURCE_VDE 0x1c8 +#define CLK_SOURCE_CSITE 0x1d4 +#define CLK_SOURCE_LA 0x1f8 +#define CLK_SOURCE_TRACE 0x634 +#define CLK_SOURCE_OWR 0x1cc +#define CLK_SOURCE_NOR 0x1d0 +#define CLK_SOURCE_MIPI 0x174 +#define CLK_SOURCE_I2C1 0x124 +#define CLK_SOURCE_I2C2 0x198 +#define CLK_SOURCE_I2C3 0x1b8 +#define CLK_SOURCE_I2C4 0x3c4 +#define CLK_SOURCE_I2C5 0x128 +#define CLK_SOURCE_UARTA 0x178 +#define CLK_SOURCE_UARTB 0x17c +#define CLK_SOURCE_UARTC 0x1a0 +#define CLK_SOURCE_UARTD 0x1c0 +#define CLK_SOURCE_UARTE 0x1c4 +#define CLK_SOURCE_UARTA_DBG 0x178 +#define CLK_SOURCE_UARTB_DBG 0x17c +#define CLK_SOURCE_UARTC_DBG 0x1a0 +#define CLK_SOURCE_UARTD_DBG 0x1c0 +#define CLK_SOURCE_UARTE_DBG 0x1c4 +#define CLK_SOURCE_3D 0x158 +#define CLK_SOURCE_2D 0x15c +#define CLK_SOURCE_VI_SENSOR 0x1a8 +#define CLK_SOURCE_VI 0x148 +#define CLK_SOURCE_EPP 0x16c +#define CLK_SOURCE_MSENC 0x1f0 +#define CLK_SOURCE_TSEC 0x1f4 +#define CLK_SOURCE_HOST1X 0x180 +#define CLK_SOURCE_HDMI 0x18c +#define CLK_SOURCE_DISP1 0x138 +#define CLK_SOURCE_DISP2 0x13c +#define CLK_SOURCE_CILAB 0x614 +#define CLK_SOURCE_CILCD 0x618 +#define CLK_SOURCE_CILE 0x61c +#define CLK_SOURCE_DSIALP 0x620 +#define CLK_SOURCE_DSIBLP 0x624 +#define CLK_SOURCE_TSENSOR 0x3b8 +#define CLK_SOURCE_D_AUDIO 0x3d0 +#define CLK_SOURCE_DAM0 0x3d8 +#define CLK_SOURCE_DAM1 0x3dc +#define CLK_SOURCE_DAM2 0x3e0 +#define CLK_SOURCE_ACTMON 0x3e8 +#define CLK_SOURCE_EXTERN1 0x3ec +#define CLK_SOURCE_EXTERN2 0x3f0 +#define CLK_SOURCE_EXTERN3 0x3f4 +#define CLK_SOURCE_I2CSLOW 0x3fc +#define CLK_SOURCE_SE 0x42c +#define CLK_SOURCE_MSELECT 0x3b4 +#define CLK_SOURCE_SOC_THERM 0x644 +#define CLK_SOURCE_XUSB_HOST_SRC 0x600 +#define CLK_SOURCE_XUSB_FALCON_SRC 0x604 +#define CLK_SOURCE_XUSB_FS_SRC 0x608 +#define CLK_SOURCE_XUSB_SS_SRC 0x610 +#define CLK_SOURCE_XUSB_DEV_SRC 0x60c + +static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32]; + +static void __iomem *clk_base; +static void __iomem *pmc_base; + +static DEFINE_SPINLOCK(pll_d_lock); +static DEFINE_SPINLOCK(pll_d2_lock); +static DEFINE_SPINLOCK(pll_u_lock); +static DEFINE_SPINLOCK(pll_div_lock); +static DEFINE_SPINLOCK(pll_re_lock); +static DEFINE_SPINLOCK(clk_doubler_lock); +static DEFINE_SPINLOCK(clk_out_lock); + +static struct pdiv_map pllxc_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 3, .hw_val = 2 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 5, .hw_val = 4 }, + { .pdiv = 6, .hw_val = 5 }, + { .pdiv = 8, .hw_val = 6 }, + { .pdiv = 10, .hw_val = 7 }, + { .pdiv = 12, .hw_val = 8 }, + { .pdiv = 16, .hw_val = 9 }, + { .pdiv = 12, .hw_val = 10 }, + { .pdiv = 16, .hw_val = 11 }, + { .pdiv = 20, .hw_val = 12 }, + { .pdiv = 24, .hw_val = 13 }, + { .pdiv = 32, .hw_val = 14 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { + { 12000000, 624000000, 104, 0, 2}, + { 12000000, 600000000, 100, 0, 2}, + { 13000000, 600000000, 92, 0, 2}, /* actual: 598.0 MHz */ + { 16800000, 600000000, 71, 0, 2}, /* actual: 596.4 MHz */ + { 19200000, 600000000, 62, 0, 2}, /* actual: 595.2 MHz */ + { 26000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */ + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct tegra_clk_pll_params pll_c_params = { + .input_min = 12000000, + .input_max = 800000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .vco_min = 600000000, + .vco_max = 1400000000, + .base_reg = PLLC_BASE, + .misc_reg = PLLC_MISC, + .lock_bit_idx = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLC_MISC, + .iddq_bit_idx = PLLC_IDDQ_BIT, + .max_p = PLLXC_SW_MAX_P, + .dyn_ramp_reg = PLLC_MISC2, + .stepa_shift = 17, + .stepb_shift = 9, + .pdiv_tohw = pllxc_p, +}; + +static struct pdiv_map pllc_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 4, .hw_val = 3 }, + { .pdiv = 8, .hw_val = 5 }, + { .pdiv = 16, .hw_val = 7 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_cx_freq_table[] = { + {12000000, 600000000, 100, 0, 2}, + {13000000, 600000000, 92, 0, 2}, /* actual: 598.0 MHz */ + {16800000, 600000000, 71, 0, 2}, /* actual: 596.4 MHz */ + {19200000, 600000000, 62, 0, 2}, /* actual: 595.2 MHz */ + {26000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */ + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_c2_params = { + .input_min = 12000000, + .input_max = 48000000, + .cf_min = 12000000, + .cf_max = 19200000, + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLC2_BASE, + .misc_reg = PLLC2_MISC, + .lock_bit_idx = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .pdiv_tohw = pllc_p, +}; + +static struct tegra_clk_pll_params pll_c3_params = { + .input_min = 12000000, + .input_max = 48000000, + .cf_min = 12000000, + .cf_max = 19200000, + .vco_min = 600000000, + .vco_max = 1200000000, + .base_reg = PLLC3_BASE, + .misc_reg = PLLC3_MISC, + .lock_bit_idx = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .pdiv_tohw = pllc_p, +}; + +static struct pdiv_map pllm_p[] = { + { .pdiv = 1, .hw_val = 0 }, + { .pdiv = 2, .hw_val = 1 }, + { .pdiv = 0, .hw_val = 0 }, +}; + +static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { + {12000000, 800000000, 66, 0, 1}, /* actual: 792.0 MHz */ + {13000000, 800000000, 61, 0, 1}, /* actual: 793.0 MHz */ + {16800000, 800000000, 47, 0, 1}, /* actual: 789.6 MHz */ + {19200000, 800000000, 41, 0, 1}, /* actual: 787.2 MHz */ + {26000000, 800000000, 61, 1, 1}, /* actual: 793.0 MHz */ + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_m_params = { + .input_min = 12000000, + .input_max = 500000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .vco_min = 400000000, + .vco_max = 1066000000, + .base_reg = PLLM_BASE, + .misc_reg = PLLM_MISC, + .lock_bit_idx = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .max_p = 2, + .pdiv_tohw = pllm_p, +}; + +static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { + {12000000, 216000000, 432, 12, 1, 8}, + {13000000, 216000000, 432, 13, 1, 8}, + {16800000, 216000000, 360, 14, 1, 8}, + {19200000, 216000000, 360, 16, 1, 8}, + {26000000, 216000000, 432, 26, 1, 8}, + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_p_params = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 200000000, + .vco_max = 700000000, + .base_reg = PLLP_BASE, + .misc_reg = PLLP_MISC, + .lock_bit_idx = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, +}; + +static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { + {9600000, 282240000, 147, 5, 0, 4}, + {9600000, 368640000, 192, 5, 0, 4}, + {9600000, 240000000, 200, 8, 0, 8}, + + {28800000, 282240000, 245, 25, 0, 8}, + {28800000, 368640000, 320, 25, 0, 8}, + {28800000, 240000000, 200, 24, 0, 8}, + {0, 0, 0, 0, 0, 0}, +}; + + +static struct tegra_clk_pll_params pll_a_params = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 200000000, + .vco_max = 700000000, + .base_reg = PLLA_BASE, + .misc_reg = PLLA_MISC, + .lock_bit_idx = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, +}; + +static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { + {12000000, 216000000, 864, 12, 2, 12}, + {13000000, 216000000, 864, 13, 2, 12}, + {16800000, 216000000, 720, 14, 2, 12}, + {19200000, 216000000, 720, 16, 2, 12}, + {26000000, 216000000, 864, 26, 2, 12}, + + {12000000, 594000000, 594, 12, 0, 12}, + {13000000, 594000000, 594, 13, 0, 12}, + {16800000, 594000000, 495, 14, 0, 12}, + {19200000, 594000000, 495, 16, 0, 12}, + {26000000, 594000000, 594, 26, 0, 12}, + + {12000000, 1000000000, 1000, 12, 0, 12}, + {13000000, 1000000000, 1000, 13, 0, 12}, + {19200000, 1000000000, 625, 12, 0, 12}, + {26000000, 1000000000, 1000, 26, 0, 12}, + + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_d_params = { + .input_min = 2000000, + .input_max = 40000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 500000000, + .vco_max = 1000000000, + .base_reg = PLLD_BASE, + .misc_reg = PLLD_MISC, + .lock_bit_idx = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, + .lock_delay = 1000, +}; + +static struct tegra_clk_pll_params pll_d2_params = { + .input_min = 2000000, + .input_max = 40000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 500000000, + .vco_max = 1000000000, + .base_reg = PLLD2_BASE, + .misc_reg = PLLD2_MISC, + .lock_bit_idx = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, + .lock_delay = 1000, +}; + +static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { + {12000000, 480000000, 960, 12, 0, 12}, + {13000000, 480000000, 960, 13, 0, 12}, + {16800000, 480000000, 400, 7, 0, 5}, + {19200000, 480000000, 200, 4, 0, 3}, + {26000000, 480000000, 960, 26, 0, 12}, + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_u_params = { + .input_min = 2000000, + .input_max = 40000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 480000000, + .vco_max = 960000000, + .base_reg = PLLU_BASE, + .misc_reg = PLLU_MISC, + .lock_bit_idx = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, + .lock_delay = 1000, +}; + +static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { + /* 1 GHz */ + {12000000, 1000000000, 83, 0, 1}, /* actual: 996.0 MHz */ + {13000000, 1000000000, 76, 0, 1}, /* actual: 988.0 MHz */ + {16800000, 1000000000, 59, 0, 1}, /* actual: 991.2 MHz */ + {19200000, 1000000000, 52, 0, 1}, /* actual: 998.4 MHz */ + {26000000, 1000000000, 76, 1, 1}, /* actual: 988.0 MHz */ + + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_x_params = { + .input_min = 12000000, + .input_max = 800000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ + .vco_min = 700000000, + .vco_max = 2400000000U, + .base_reg = PLLX_BASE, + .misc_reg = PLLX_MISC, + .lock_bit_idx = PLL_BASE_LOCK, + .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLX_MISC3, + .iddq_bit_idx = PLLX_IDDQ_BIT, + .max_p = PLLXC_SW_MAX_P, + .dyn_ramp_reg = PLLC_MISC2, + .stepa_shift = 16, + .stepb_shift = 24, + .pdiv_tohw = pllxc_p, +}; + +static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { + /* PLLE special case: use cpcon field to store cml divider value */ + {336000000, 100000000, 100, 21, 16, 11}, + {312000000, 100000000, 200, 26, 24, 13}, + {0, 0, 0, 0, 0, 0}, +}; + +static struct tegra_clk_pll_params pll_e_params = { + .input_min = 12000000, + .input_max = 1000000000, + .cf_min = 12000000, + .cf_max = 75000000, + .vco_min = 1600000000, + .vco_max = 2400000000U, + .base_reg = PLLE_BASE, + .misc_reg = PLLE_MISC, + .aux_reg = PLLE_AUX, + .lock_bit_idx = PLLE_MISC_LOCK, + .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, + .lock_delay = 300, +}; + +static struct tegra_clk_pll_params pll_re_vco_params = { + .input_min = 12000000, + .input_max = 1000000000, + .cf_min = 12000000, + .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ + .vco_min = 300000000, + .vco_max = 600000000, + .base_reg = PLLRE_BASE, + .misc_reg = PLLRE_MISC, + .lock_bit_idx = PLLRE_MISC_LOCK, + .lock_enable_bit_idx = PLLRE_MISC_LOCK_ENABLE, + .lock_delay = 300, + .iddq_reg = PLLRE_MISC, + .iddq_bit_idx = PLLRE_IDDQ_BIT, +}; + +/* Peripheral clock registers */ + +static struct tegra_clk_periph_regs periph_l_regs = { + .enb_reg = CLK_OUT_ENB_L, + .enb_set_reg = CLK_OUT_ENB_SET_L, + .enb_clr_reg = CLK_OUT_ENB_CLR_L, + .rst_reg = RST_DEVICES_L, + .rst_set_reg = RST_DEVICES_SET_L, + .rst_clr_reg = RST_DEVICES_CLR_L, +}; + +static struct tegra_clk_periph_regs periph_h_regs = { + .enb_reg = CLK_OUT_ENB_H, + .enb_set_reg = CLK_OUT_ENB_SET_H, + .enb_clr_reg = CLK_OUT_ENB_CLR_H, + .rst_reg = RST_DEVICES_H, + .rst_set_reg = RST_DEVICES_SET_H, + .rst_clr_reg = RST_DEVICES_CLR_H, +}; + +static struct tegra_clk_periph_regs periph_u_regs = { + .enb_reg = CLK_OUT_ENB_U, + .enb_set_reg = CLK_OUT_ENB_SET_U, + .enb_clr_reg = CLK_OUT_ENB_CLR_U, + .rst_reg = RST_DEVICES_U, + .rst_set_reg = RST_DEVICES_SET_U, + .rst_clr_reg = RST_DEVICES_CLR_U, +}; + +static struct tegra_clk_periph_regs periph_v_regs = { + .enb_reg = CLK_OUT_ENB_V, + .enb_set_reg = CLK_OUT_ENB_SET_V, + .enb_clr_reg = CLK_OUT_ENB_CLR_V, + .rst_reg = RST_DEVICES_V, + .rst_set_reg = RST_DEVICES_SET_V, + .rst_clr_reg = RST_DEVICES_CLR_V, +}; + +static struct tegra_clk_periph_regs periph_w_regs = { + .enb_reg = CLK_OUT_ENB_W, + .enb_set_reg = CLK_OUT_ENB_SET_W, + .enb_clr_reg = CLK_OUT_ENB_CLR_W, + .rst_reg = RST_DEVICES_W, + .rst_set_reg = RST_DEVICES_SET_W, + .rst_clr_reg = RST_DEVICES_CLR_W, +}; + +/* possible OSC frequencies in Hz */ +static unsigned long tegra114_input_freq[] = { + [0] = 13000000, + [1] = 16800000, + [4] = 19200000, + [5] = 38400000, + [8] = 12000000, + [9] = 48000000, + [12] = 260000000, +}; + +#define MASK(x) (BIT(x) - 1) + +#define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ + _clk_num, _regs, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + 30, MASK(2), 0, 0, 8, 1, 0, _regs, _clk_num, \ + periph_clk_enb_refcnt, _gate_flags, _clk_id, \ + _parents##_idx, 0) + +#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ + _clk_num, _regs, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + 29, MASK(3), 0, 0, 8, 1, 0, _regs, _clk_num, \ + periph_clk_enb_refcnt, _gate_flags, _clk_id, \ + _parents##_idx, 0) + +#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ + _clk_num, _regs, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\ + _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + _clk_id, _parents##_idx, 0) + +#define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ + _clk_num, _regs, _gate_flags, _clk_id, flags)\ + TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\ + _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + _clk_id, _parents##_idx, flags) + +#define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\ + _clk_num, _regs, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\ + _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + _clk_id, _parents##_idx, 0) + +#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ + _clk_num, _regs, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART, _regs,\ + _clk_num, periph_clk_enb_refcnt, 0, _clk_id, \ + _parents##_idx, 0) + +#define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\ + _clk_num, _regs, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + 30, MASK(2), 0, 0, 16, 0, 0, _regs, _clk_num, \ + periph_clk_enb_refcnt, 0, _clk_id, _parents##_idx, 0) + +#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ + _mux_shift, _mux_mask, _clk_num, _regs, \ + _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ + _mux_shift, _mux_mask, 0, 0, 0, 0, 0, _regs, \ + _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + _clk_id, _parents##_idx, 0) + +#define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \ + _clk_num, _regs, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \ + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \ + _clk_num, periph_clk_enb_refcnt, _gate_flags, \ + _clk_id, _parents##_idx, 0) + +#define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset, _clk_num,\ + _regs, _gate_flags, _clk_id) \ + TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \ + _offset, 16, 0xE01F, 0, 0, 8, 1, 0, _regs, _clk_num, \ + periph_clk_enb_refcnt, _gate_flags , _clk_id, \ + mux_d_audio_clk_idx, 0) + +enum tegra114_clk { + rtc = 4, timer = 5, uarta = 6, sdmmc2 = 9, i2s1 = 11, i2c1 = 12, + ndflash = 13, sdmmc1 = 14, sdmmc4 = 15, pwm = 17, i2s2 = 18, epp = 19, + gr_2d = 21, usbd = 22, isp = 23, gr_3d = 24, disp2 = 26, disp1 = 27, + host1x = 28, vcp = 29, i2s0 = 30, apbdma = 34, kbc = 36, kfuse = 40, + sbc1 = 41, nor = 42, sbc2 = 44, sbc3 = 46, i2c5 = 47, dsia = 48, + mipi = 50, hdmi = 51, csi = 52, i2c2 = 54, uartc = 55, mipi_cal = 56, + usb2 = 58, usb3 = 59, vde = 61, bsea = 62, bsev = 63, uartd = 65, + uarte = 66, i2c3 = 67, sbc4 = 68, sdmmc3 = 69, owr = 71, csite = 73, + la = 76, trace = 77, soc_therm = 78, dtv = 79, ndspeed = 80, + i2cslow = 81, dsib = 82, tsec = 83, xusb_host = 89, msenc = 91, + csus = 92, mselect = 99, tsensor = 100, i2s3 = 101, i2s4 = 102, + i2c4 = 103, sbc5 = 104, sbc6 = 105, apbif = 107, d_audio, dam0, dam1, + dam2, hda2codec_2x = 111, audio0_2x = 113, audio1_2x, audio2_2x, + audio3_2x, audio4_2x, spdif_2x, actmon = 119, extern1 = 120, + extern2 = 121, extern3 = 122, hda = 125, se = 127, hda2hdmi = 128, + cilab = 144, cilcd = 145, cile = 146, dsialp = 147, dsiblp = 148, + dds = 150, dp2 = 152, amx = 153, adx = 154, xusb_ss = 156, uartb = 192, + vfir, spdif_in, spdif_out, vi, vi_sensor, fuse, fuse_burn, clk_32k, + clk_m, clk_m_div2, clk_m_div4, pll_ref, pll_c, pll_c_out1, pll_c2, + pll_c3, pll_m, pll_m_out1, pll_p, pll_p_out1, pll_p_out2, pll_p_out3, + pll_p_out4, pll_a, pll_a_out0, pll_d, pll_d_out0, pll_d2, pll_d2_out0, + pll_u, pll_u_480M, pll_u_60M, pll_u_48M, pll_u_12M, pll_x, pll_x_out0, + pll_re_vco, pll_re_out, pll_e_out0, spdif_in_sync, i2s0_sync, + i2s1_sync, i2s2_sync, i2s3_sync, i2s4_sync, vimclk_sync, audio0, + audio1, audio2, audio3, audio4, spdif, clk_out_1, clk_out_2, clk_out_3, + blink, mipi_cal_fast, dsi1_fixed, dsi2_fixed, xusb_host_src, + xusb_falcon_src, xusb_fs_src, xusb_ss_src, xusb_dev_src, xusb_dev, + xusb_hs_src, + + /* Mux clocks */ + + audio0_mux = 300, audio1_mux, audio2_mux, audio3_mux, audio4_mux, + spdif_mux, clk_out_1_mux, clk_out_2_mux, clk_out_3_mux, dsia_mux, + dsib_mux, clk_max, +}; + +struct utmi_clk_param { + /* Oscillator Frequency in KHz */ + u32 osc_frequency; + /* UTMIP PLL Enable Delay Count */ + u8 enable_delay_count; + /* UTMIP PLL Stable count */ + u8 stable_count; + /* UTMIP PLL Active delay count */ + u8 active_delay_count; + /* UTMIP PLL Xtal frequency count */ + u8 xtal_freq_count; +}; + +static const struct utmi_clk_param utmi_parameters[] = { + {.osc_frequency = 13000000, .enable_delay_count = 0x02, + .stable_count = 0x33, .active_delay_count = 0x05, + .xtal_freq_count = 0x7F}, + {.osc_frequency = 19200000, .enable_delay_count = 0x03, + .stable_count = 0x4B, .active_delay_count = 0x06, + .xtal_freq_count = 0xBB}, + {.osc_frequency = 12000000, .enable_delay_count = 0x02, + .stable_count = 0x2F, .active_delay_count = 0x04, + .xtal_freq_count = 0x76}, + {.osc_frequency = 26000000, .enable_delay_count = 0x04, + .stable_count = 0x66, .active_delay_count = 0x09, + .xtal_freq_count = 0xFE}, + {.osc_frequency = 16800000, .enable_delay_count = 0x03, + .stable_count = 0x41, .active_delay_count = 0x0A, + .xtal_freq_count = 0xA4}, +}; + +/* peripheral mux definitions */ + +#define MUX_I2S_SPDIF(_id) \ +static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \ + #_id, "pll_p",\ + "clk_m"}; +MUX_I2S_SPDIF(audio0) +MUX_I2S_SPDIF(audio1) +MUX_I2S_SPDIF(audio2) +MUX_I2S_SPDIF(audio3) +MUX_I2S_SPDIF(audio4) +MUX_I2S_SPDIF(audio) + +#define mux_pllaout0_audio0_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio1_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio2_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio3_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio4_2x_pllp_clkm_idx NULL +#define mux_pllaout0_audio_2x_pllp_clkm_idx NULL + +static const char *mux_pllp_pllc_pllm_clkm[] = { + "pll_p", "pll_c", "pll_m", "clk_m" +}; +#define mux_pllp_pllc_pllm_clkm_idx NULL + +static const char *mux_pllp_pllc_pllm[] = { "pll_p", "pll_c", "pll_m" }; +#define mux_pllp_pllc_pllm_idx NULL + +static const char *mux_pllp_pllc_clk32_clkm[] = { + "pll_p", "pll_c", "clk_32k", "clk_m" +}; +#define mux_pllp_pllc_clk32_clkm_idx NULL + +static const char *mux_plla_pllc_pllp_clkm[] = { + "pll_a_out0", "pll_c", "pll_p", "clk_m" +}; +#define mux_plla_pllc_pllp_clkm_idx mux_pllp_pllc_pllm_clkm_idx + +static const char *mux_pllp_pllc2_c_c3_pllm_clkm[] = { + "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_m", "clk_m" +}; +static u32 mux_pllp_pllc2_c_c3_pllm_clkm_idx[] = { + [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, +}; + +static const char *mux_pllp_clkm[] = { + "pll_p", "clk_m" +}; +static u32 mux_pllp_clkm_idx[] = { + [0] = 0, [1] = 3, +}; + +static const char *mux_pllm_pllc2_c_c3_pllp_plla[] = { + "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0" +}; +#define mux_pllm_pllc2_c_c3_pllp_plla_idx mux_pllp_pllc2_c_c3_pllm_clkm_idx + +static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = { + "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c", + "pll_d2_out0", "clk_m" +}; +#define mux_pllp_pllm_plld_plla_pllc_plld2_clkm_idx NULL + +static const char *mux_pllm_pllc_pllp_plla[] = { + "pll_m", "pll_c", "pll_p", "pll_a_out0" +}; +#define mux_pllm_pllc_pllp_plla_idx mux_pllp_pllc_pllm_clkm_idx + +static const char *mux_pllp_pllc_clkm[] = { + "pll_p", "pll_c", "pll_m" +}; +static u32 mux_pllp_pllc_clkm_idx[] = { + [0] = 0, [1] = 1, [2] = 3, +}; + +static const char *mux_pllp_pllc_clkm_clk32[] = { + "pll_p", "pll_c", "clk_m", "clk_32k" +}; +#define mux_pllp_pllc_clkm_clk32_idx NULL + +static const char *mux_plla_clk32_pllp_clkm_plle[] = { + "pll_a_out0", "clk_32k", "pll_p", "clk_m", "pll_e_out0" +}; +#define mux_plla_clk32_pllp_clkm_plle_idx NULL + +static const char *mux_clkm_pllp_pllc_pllre[] = { + "clk_m", "pll_p", "pll_c", "pll_re_out" +}; +static u32 mux_clkm_pllp_pllc_pllre_idx[] = { + [0] = 0, [1] = 1, [2] = 3, [3] = 5, +}; + +static const char *mux_clkm_48M_pllp_480M[] = { + "clk_m", "pll_u_48M", "pll_p", "pll_u_480M" +}; +#define mux_clkm_48M_pllp_480M_idx NULL + +static const char *mux_clkm_pllre_clk32_480M_pllc_ref[] = { + "clk_m", "pll_re_out", "clk_32k", "pll_u_480M", "pll_c", "pll_ref" +}; +static u32 mux_clkm_pllre_clk32_480M_pllc_ref_idx[] = { + [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 4, [5] = 7, +}; + +static const char *mux_plld_out0_plld2_out0[] = { + "pll_d_out0", "pll_d2_out0", +}; +#define mux_plld_out0_plld2_out0_idx NULL + +static const char *mux_d_audio_clk[] = { + "pll_a_out0", "pll_p", "clk_m", "spdif_in_sync", "i2s0_sync", + "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", +}; +static u32 mux_d_audio_clk_idx[] = { + [0] = 0, [1] = 0x8000, [2] = 0xc000, [3] = 0xE000, [4] = 0xE001, + [5] = 0xE002, [6] = 0xE003, [7] = 0xE004, [8] = 0xE005, [9] = 0xE007, +}; + +static const struct clk_div_table pll_re_div_table[] = { + { .val = 0, .div = 1 }, + { .val = 1, .div = 2 }, + { .val = 2, .div = 3 }, + { .val = 3, .div = 4 }, + { .val = 4, .div = 5 }, + { .val = 5, .div = 6 }, + { .val = 0, .div = 0 }, +}; + +static struct clk *clks[clk_max]; +static struct clk_onecell_data clk_data; + +static unsigned long osc_freq; +static unsigned long pll_ref_freq; + +static int __init tegra114_osc_clk_init(void __iomem *clk_base) +{ + struct clk *clk; + u32 val, pll_ref_div; + + val = readl_relaxed(clk_base + OSC_CTRL); + + osc_freq = tegra114_input_freq[val >> OSC_CTRL_OSC_FREQ_SHIFT]; + if (!osc_freq) { + WARN_ON(1); + return -EINVAL; + } + + /* clk_m */ + clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, + osc_freq); + clk_register_clkdev(clk, "clk_m", NULL); + clks[clk_m] = clk; + + /* pll_ref */ + val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3; + pll_ref_div = 1 << val; + clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", + CLK_SET_RATE_PARENT, 1, pll_ref_div); + clk_register_clkdev(clk, "pll_ref", NULL); + clks[pll_ref] = clk; + + pll_ref_freq = osc_freq / pll_ref_div; + + return 0; +} + +static void __init tegra114_fixed_clk_init(void __iomem *clk_base) +{ + struct clk *clk; + + /* clk_32k */ + clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, + 32768); + clk_register_clkdev(clk, "clk_32k", NULL); + clks[clk_32k] = clk; + + /* clk_m_div2 */ + clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", + CLK_SET_RATE_PARENT, 1, 2); + clk_register_clkdev(clk, "clk_m_div2", NULL); + clks[clk_m_div2] = clk; + + /* clk_m_div4 */ + clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", + CLK_SET_RATE_PARENT, 1, 4); + clk_register_clkdev(clk, "clk_m_div4", NULL); + clks[clk_m_div4] = clk; + +} + +static __init void tegra114_utmi_param_configure(void __iomem *clk_base) +{ + u32 reg; + int i; + + for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { + if (osc_freq == utmi_parameters[i].osc_frequency) + break; + } + + if (i >= ARRAY_SIZE(utmi_parameters)) { + pr_err("%s: Unexpected oscillator freq %lu\n", __func__, + osc_freq); + return; + } + + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2); + + /* Program UTMIP PLL stable and active counts */ + /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */ + reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0); + reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count); + + reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0); + + reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i]. + active_delay_count); + + /* Remove power downs from UTMIP PLL control bits */ + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN; + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN; + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN; + + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2); + + /* Program UTMIP PLL delay and oscillator frequency counts */ + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); + reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0); + + reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i]. + enable_delay_count); + + reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0); + reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(utmi_parameters[i]. + xtal_freq_count); + + /* Remove power downs from UTMIP PLL control bits */ + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN; + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); + + /* Setup HW control of UTMIPLL */ + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); + reg |= UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET; + reg &= ~UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL; + reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE; + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); + + reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; + writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); + + udelay(1); + + /* Setup SW override of UTMIPLL assuming USB2.0 + ports are assigned to USB2 */ + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); + reg |= UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL; + reg &= ~UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE; + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); + + udelay(1); + + /* Enable HW control UTMIPLL */ + reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); + reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE; + writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); +} + +static void __init _clip_vco_min(struct tegra_clk_pll_params *pll_params) +{ + pll_params->vco_min = + DIV_ROUND_UP(pll_params->vco_min, pll_ref_freq) * pll_ref_freq; +} + +static int __init _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params, + void __iomem *clk_base) +{ + u32 val; + u32 step_a, step_b; + + switch (pll_ref_freq) { + case 12000000: + case 13000000: + case 26000000: + step_a = 0x2B; + step_b = 0x0B; + break; + case 16800000: + step_a = 0x1A; + step_b = 0x09; + break; + case 19200000: + step_a = 0x12; + step_b = 0x08; + break; + default: + pr_err("%s: Unexpected reference rate %lu\n", + __func__, pll_ref_freq); + WARN_ON(1); + return -EINVAL; + } + + val = step_a << pll_params->stepa_shift; + val |= step_b << pll_params->stepb_shift; + writel_relaxed(val, clk_base + pll_params->dyn_ramp_reg); + + return 0; +} + +static void __init _init_iddq(struct tegra_clk_pll_params *pll_params, + void __iomem *clk_base) +{ + u32 val, val_iddq; + + val = readl_relaxed(clk_base + pll_params->base_reg); + val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg); + + if (val & BIT(30)) + WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx)); + else { + val_iddq |= BIT(pll_params->iddq_bit_idx); + writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg); + } +} + +static void __init tegra114_pll_init(void __iomem *clk_base, + void __iomem *pmc) +{ + struct clk *clk; + + /* PLLC */ + _clip_vco_min(&pll_c_params); + if (_setup_dynamic_ramp(&pll_c_params, clk_base) >= 0) { + _init_iddq(&pll_c_params, clk_base); + clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, + pmc, 0, 0, &pll_c_params, TEGRA_PLL_USE_LOCK, + pll_c_freq_table, NULL); + clk_register_clkdev(clk, "pll_c", NULL); + clks[pll_c] = clk; + + /* PLLC_OUT1 */ + clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", + clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", + clk_base + PLLC_OUT, 1, 0, + CLK_SET_RATE_PARENT, 0, NULL); + clk_register_clkdev(clk, "pll_c_out1", NULL); + clks[pll_c_out1] = clk; + } + + /* PLLC2 */ + _clip_vco_min(&pll_c2_params); + clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, 0, + &pll_c2_params, TEGRA_PLL_USE_LOCK, + pll_cx_freq_table, NULL); + clk_register_clkdev(clk, "pll_c2", NULL); + clks[pll_c2] = clk; + + /* PLLC3 */ + _clip_vco_min(&pll_c3_params); + clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, 0, + &pll_c3_params, TEGRA_PLL_USE_LOCK, + pll_cx_freq_table, NULL); + clk_register_clkdev(clk, "pll_c3", NULL); + clks[pll_c3] = clk; + + /* PLLP */ + clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc, 0, + 408000000, &pll_p_params, + TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, + pll_p_freq_table, NULL); + clk_register_clkdev(clk, "pll_p", NULL); + clks[pll_p] = clk; + + /* PLLP_OUT1 */ + clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", + clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | + TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, &pll_div_lock); + clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div", + clk_base + PLLP_OUTA, 1, 0, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, + &pll_div_lock); + clk_register_clkdev(clk, "pll_p_out1", NULL); + clks[pll_p_out1] = clk; + + /* PLLP_OUT2 */ + clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", + clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | + TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, + &pll_div_lock); + clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", + clk_base + PLLP_OUTA, 17, 16, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, + &pll_div_lock); + clk_register_clkdev(clk, "pll_p_out2", NULL); + clks[pll_p_out2] = clk; + + /* PLLP_OUT3 */ + clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", + clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | + TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, &pll_div_lock); + clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div", + clk_base + PLLP_OUTB, 1, 0, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, + &pll_div_lock); + clk_register_clkdev(clk, "pll_p_out3", NULL); + clks[pll_p_out3] = clk; + + /* PLLP_OUT4 */ + clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", + clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | + TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, + &pll_div_lock); + clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div", + clk_base + PLLP_OUTB, 17, 16, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, + &pll_div_lock); + clk_register_clkdev(clk, "pll_p_out4", NULL); + clks[pll_p_out4] = clk; + + /* PLLM */ + _clip_vco_min(&pll_m_params); + clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, + &pll_m_params, TEGRA_PLL_USE_LOCK, + pll_m_freq_table, NULL); + clk_register_clkdev(clk, "pll_m", NULL); + clks[pll_m] = clk; + + /* PLLM_OUT1 */ + clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", + clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", + clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | + CLK_SET_RATE_PARENT, 0, NULL); + clk_register_clkdev(clk, "pll_m_out1", NULL); + clks[pll_m_out1] = clk; + + /* PLLX */ + _clip_vco_min(&pll_x_params); + if (_setup_dynamic_ramp(&pll_x_params, clk_base) >= 0) { + _init_iddq(&pll_c_params, clk_base); + clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, + pmc, CLK_IGNORE_UNUSED, 0, &pll_x_params, + TEGRA_PLL_USE_LOCK, pll_x_freq_table, NULL); + clk_register_clkdev(clk, "pll_x", NULL); + clks[pll_x] = clk; + } + + /* PLLX_OUT0 */ + clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", + CLK_SET_RATE_PARENT, 1, 2); + clk_register_clkdev(clk, "pll_x_out0", NULL); + clks[pll_x_out0] = clk; + + /* PLLU */ + clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc, 0, + 0, &pll_u_params, TEGRA_PLLU | + TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, pll_u_freq_table, &pll_u_lock); + clk_register_clkdev(clk, "pll_u", NULL); + clks[pll_u] = clk; + + tegra114_utmi_param_configure(clk_base); + + /* PLLU_480M */ + clk = clk_register_gate(NULL, "pll_u_480M", "pll_u", + CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, + 22, 0, &pll_u_lock); + clk_register_clkdev(clk, "pll_u_480M", NULL); + clks[pll_u_480M] = clk; + + /* PLLU_60M */ + clk = clk_register_fixed_factor(NULL, "pll_u_60M_div", "pll_u", + CLK_SET_RATE_PARENT, 1, 8); + clk = clk_register_gate(NULL, "pll_u_60M", "pll_u_60M_div", + CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, + 23, 0, &pll_u_lock); + clk_register_clkdev(clk, "pll_u_60M", NULL); + clks[pll_u_60M] = clk; + + /* PLLU_48M */ + clk = clk_register_fixed_factor(NULL, "pll_u_48M_div", "pll_u", + CLK_SET_RATE_PARENT, 1, 10); + clk = clk_register_gate(NULL, "pll_u_48M", "pll_u_48M_div", + CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, + 25, 0, &pll_u_lock); + clk_register_clkdev(clk, "pll_u_48M", NULL); + clks[pll_u_48M] = clk; + + /* PLLU_12M */ + clk = clk_register_fixed_factor(NULL, "pll_u_12M_div", "pll_u", + CLK_SET_RATE_PARENT, 1, 40); + clk = clk_register_gate(NULL, "pll_u_12M", "pll_u_12M_div", + CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, + 21, 0, &pll_u_lock); + clk_register_clkdev(clk, "pll_u_12M", NULL); + clks[pll_u_12M] = clk; + + /* PLLD */ + clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0, + 0, &pll_d_params, + TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d_lock); + clk_register_clkdev(clk, "pll_d", NULL); + clks[pll_d] = clk; + + /* PLLD_OUT0 */ + clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", + CLK_SET_RATE_PARENT, 1, 2); + clk_register_clkdev(clk, "pll_d_out0", NULL); + clks[pll_d_out0] = clk; + + /* PLLD2 */ + clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc, 0, + 0, &pll_d2_params, + TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | + TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d2_lock); + clk_register_clkdev(clk, "pll_d2", NULL); + clks[pll_d2] = clk; + + /* PLLD2_OUT0 */ + clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", + CLK_SET_RATE_PARENT, 1, 2); + clk_register_clkdev(clk, "pll_d2_out0", NULL); + clks[pll_d2_out0] = clk; + + /* PLLA */ + clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc, 0, + 0, &pll_a_params, TEGRA_PLL_HAS_CPCON | + TEGRA_PLL_USE_LOCK, pll_a_freq_table, NULL); + clk_register_clkdev(clk, "pll_a", NULL); + clks[pll_a] = clk; + + /* PLLA_OUT0 */ + clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", + clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP, + 8, 8, 1, NULL); + clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", + clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | + CLK_SET_RATE_PARENT, 0, NULL); + clk_register_clkdev(clk, "pll_a_out0", NULL); + clks[pll_a_out0] = clk; + + /* PLLRE */ + _clip_vco_min(&pll_re_vco_params); + clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, + 0, 0, &pll_re_vco_params, TEGRA_PLL_USE_LOCK, + NULL, &pll_re_lock, pll_ref_freq); + clk_register_clkdev(clk, "pll_re_vco", NULL); + clks[pll_re_vco] = clk; + + clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0, + clk_base + PLLRE_BASE, 16, 4, 0, + pll_re_div_table, &pll_re_lock); + clk_register_clkdev(clk, "pll_re_out", NULL); + clks[pll_re_out] = clk; + + /* PLLE */ + clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_re_vco", + clk_base, 0, 100000000, &pll_e_params, + pll_e_freq_table, NULL); + clk_register_clkdev(clk, "pll_e_out0", NULL); + clks[pll_e_out0] = clk; +} + +static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync", + "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", +}; + +static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", + "clk_m_div4", "extern1", +}; + +static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", + "clk_m_div4", "extern2", +}; + +static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", + "clk_m_div4", "extern3", +}; + +static void __init tegra114_audio_clk_init(void __iomem *clk_base) +{ + struct clk *clk; + + /* spdif_in_sync */ + clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000, + 24000000); + clk_register_clkdev(clk, "spdif_in_sync", NULL); + clks[spdif_in_sync] = clk; + + /* i2s0_sync */ + clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000); + clk_register_clkdev(clk, "i2s0_sync", NULL); + clks[i2s0_sync] = clk; + + /* i2s1_sync */ + clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000); + clk_register_clkdev(clk, "i2s1_sync", NULL); + clks[i2s1_sync] = clk; + + /* i2s2_sync */ + clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000); + clk_register_clkdev(clk, "i2s2_sync", NULL); + clks[i2s2_sync] = clk; + + /* i2s3_sync */ + clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000); + clk_register_clkdev(clk, "i2s3_sync", NULL); + clks[i2s3_sync] = clk; + + /* i2s4_sync */ + clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000); + clk_register_clkdev(clk, "i2s4_sync", NULL); + clks[i2s4_sync] = clk; + + /* vimclk_sync */ + clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000); + clk_register_clkdev(clk, "vimclk_sync", NULL); + clks[vimclk_sync] = clk; + + /* audio0 */ + clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk, + ARRAY_SIZE(mux_audio_sync_clk), 0, + clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0, + NULL); + clks[audio0_mux] = clk; + clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0, + clk_base + AUDIO_SYNC_CLK_I2S0, 4, + CLK_GATE_SET_TO_DISABLE, NULL); + clk_register_clkdev(clk, "audio0", NULL); + clks[audio0] = clk; + + /* audio1 */ + clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk, + ARRAY_SIZE(mux_audio_sync_clk), 0, + clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0, + NULL); + clks[audio1_mux] = clk; + clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0, + clk_base + AUDIO_SYNC_CLK_I2S1, 4, + CLK_GATE_SET_TO_DISABLE, NULL); + clk_register_clkdev(clk, "audio1", NULL); + clks[audio1] = clk; + + /* audio2 */ + clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk, + ARRAY_SIZE(mux_audio_sync_clk), 0, + clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0, + NULL); + clks[audio2_mux] = clk; + clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0, + clk_base + AUDIO_SYNC_CLK_I2S2, 4, + CLK_GATE_SET_TO_DISABLE, NULL); + clk_register_clkdev(clk, "audio2", NULL); + clks[audio2] = clk; + + /* audio3 */ + clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk, + ARRAY_SIZE(mux_audio_sync_clk), 0, + clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0, + NULL); + clks[audio3_mux] = clk; + clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0, + clk_base + AUDIO_SYNC_CLK_I2S3, 4, + CLK_GATE_SET_TO_DISABLE, NULL); + clk_register_clkdev(clk, "audio3", NULL); + clks[audio3] = clk; + + /* audio4 */ + clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk, + ARRAY_SIZE(mux_audio_sync_clk), 0, + clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0, + NULL); + clks[audio4_mux] = clk; + clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0, + clk_base + AUDIO_SYNC_CLK_I2S4, 4, + CLK_GATE_SET_TO_DISABLE, NULL); + clk_register_clkdev(clk, "audio4", NULL); + clks[audio4] = clk; + + /* spdif */ + clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk, + ARRAY_SIZE(mux_audio_sync_clk), 0, + clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0, + NULL); + clks[spdif_mux] = clk; + clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0, + clk_base + AUDIO_SYNC_CLK_SPDIF, 4, + CLK_GATE_SET_TO_DISABLE, NULL); + clk_register_clkdev(clk, "spdif", NULL); + clks[spdif] = clk; + + /* audio0_2x */ + clk = clk_register_fixed_factor(NULL, "audio0_doubler", "audio0", + CLK_SET_RATE_PARENT, 2, 1); + clk = tegra_clk_register_divider("audio0_div", "audio0_doubler", + clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 24, 1, + 0, &clk_doubler_lock); + clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div", + TEGRA_PERIPH_NO_RESET, clk_base, + CLK_SET_RATE_PARENT, 113, &periph_v_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "audio0_2x", NULL); + clks[audio0_2x] = clk; + + /* audio1_2x */ + clk = clk_register_fixed_factor(NULL, "audio1_doubler", "audio1", + CLK_SET_RATE_PARENT, 2, 1); + clk = tegra_clk_register_divider("audio1_div", "audio1_doubler", + clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 25, 1, + 0, &clk_doubler_lock); + clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div", + TEGRA_PERIPH_NO_RESET, clk_base, + CLK_SET_RATE_PARENT, 114, &periph_v_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "audio1_2x", NULL); + clks[audio1_2x] = clk; + + /* audio2_2x */ + clk = clk_register_fixed_factor(NULL, "audio2_doubler", "audio2", + CLK_SET_RATE_PARENT, 2, 1); + clk = tegra_clk_register_divider("audio2_div", "audio2_doubler", + clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 26, 1, + 0, &clk_doubler_lock); + clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div", + TEGRA_PERIPH_NO_RESET, clk_base, + CLK_SET_RATE_PARENT, 115, &periph_v_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "audio2_2x", NULL); + clks[audio2_2x] = clk; + + /* audio3_2x */ + clk = clk_register_fixed_factor(NULL, "audio3_doubler", "audio3", + CLK_SET_RATE_PARENT, 2, 1); + clk = tegra_clk_register_divider("audio3_div", "audio3_doubler", + clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 27, 1, + 0, &clk_doubler_lock); + clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div", + TEGRA_PERIPH_NO_RESET, clk_base, + CLK_SET_RATE_PARENT, 116, &periph_v_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "audio3_2x", NULL); + clks[audio3_2x] = clk; + + /* audio4_2x */ + clk = clk_register_fixed_factor(NULL, "audio4_doubler", "audio4", + CLK_SET_RATE_PARENT, 2, 1); + clk = tegra_clk_register_divider("audio4_div", "audio4_doubler", + clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 28, 1, + 0, &clk_doubler_lock); + clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div", + TEGRA_PERIPH_NO_RESET, clk_base, + CLK_SET_RATE_PARENT, 117, &periph_v_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "audio4_2x", NULL); + clks[audio4_2x] = clk; + + /* spdif_2x */ + clk = clk_register_fixed_factor(NULL, "spdif_doubler", "spdif", + CLK_SET_RATE_PARENT, 2, 1); + clk = tegra_clk_register_divider("spdif_div", "spdif_doubler", + clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 29, 1, + 0, &clk_doubler_lock); + clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div", + TEGRA_PERIPH_NO_RESET, clk_base, + CLK_SET_RATE_PARENT, 118, + &periph_v_regs, periph_clk_enb_refcnt); + clk_register_clkdev(clk, "spdif_2x", NULL); + clks[spdif_2x] = clk; +} + +static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) +{ + struct clk *clk; + + /* clk_out_1 */ + clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents, + ARRAY_SIZE(clk_out1_parents), 0, + pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0, + &clk_out_lock); + clks[clk_out_1_mux] = clk; + clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0, + pmc_base + PMC_CLK_OUT_CNTRL, 2, 0, + &clk_out_lock); + clk_register_clkdev(clk, "extern1", "clk_out_1"); + clks[clk_out_1] = clk; + + /* clk_out_2 */ + clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, + ARRAY_SIZE(clk_out1_parents), 0, + pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, + &clk_out_lock); + clks[clk_out_2_mux] = clk; + clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0, + pmc_base + PMC_CLK_OUT_CNTRL, 10, 0, + &clk_out_lock); + clk_register_clkdev(clk, "extern2", "clk_out_2"); + clks[clk_out_2] = clk; + + /* clk_out_3 */ + clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, + ARRAY_SIZE(clk_out1_parents), 0, + pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, + &clk_out_lock); + clks[clk_out_3_mux] = clk; + clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0, + pmc_base + PMC_CLK_OUT_CNTRL, 18, 0, + &clk_out_lock); + clk_register_clkdev(clk, "extern3", "clk_out_3"); + clks[clk_out_3] = clk; + + /* blink */ + clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, + pmc_base + PMC_DPD_PADS_ORIDE, + PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); + clk = clk_register_gate(NULL, "blink", "blink_override", 0, + pmc_base + PMC_CTRL, + PMC_CTRL_BLINK_ENB, 0, NULL); + clk_register_clkdev(clk, "blink", NULL); + clks[blink] = clk; + +} + +static __initdata struct tegra_periph_init_data tegra_periph_clk_list[] = { + TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s0), + TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1), + TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2), + TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s3), + TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s4), + TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out), + TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in), + TEGRA_INIT_DATA_MUX("pwm", NULL, "pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, &periph_l_regs, TEGRA_PERIPH_ON_APB, pwm), + TEGRA_INIT_DATA_MUX("adx", NULL, "adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, &periph_w_regs, TEGRA_PERIPH_ON_APB, adx), + TEGRA_INIT_DATA_MUX("amx", NULL, "amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, &periph_w_regs, TEGRA_PERIPH_ON_APB, amx), + TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, TEGRA_PERIPH_ON_APB, hda), + TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, TEGRA_PERIPH_ON_APB, hda2codec_2x), + TEGRA_INIT_DATA_MUX("sbc1", NULL, "tegra11-spi.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1), + TEGRA_INIT_DATA_MUX("sbc2", NULL, "tegra11-spi.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2), + TEGRA_INIT_DATA_MUX("sbc3", NULL, "tegra11-spi.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3), + TEGRA_INIT_DATA_MUX("sbc4", NULL, "tegra11-spi.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4), + TEGRA_INIT_DATA_MUX("sbc5", NULL, "tegra11-spi.4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc5), + TEGRA_INIT_DATA_MUX("sbc6", NULL, "tegra11-spi.5", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc6), + TEGRA_INIT_DATA_MUX8("ndflash", NULL, "tegra_nand", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed), + TEGRA_INIT_DATA_MUX8("ndspeed", NULL, "tegra_nand_speed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed), + TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir), + TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1), + TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2), + TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3), + TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4), + TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde), + TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, csite), + TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, la), + TEGRA_INIT_DATA_MUX("trace", NULL, "trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, &periph_u_regs, TEGRA_PERIPH_ON_APB, trace), + TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr), + TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor), + TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi), + TEGRA_INIT_DATA_I2C("i2c1", "div-clk", "tegra11-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, i2c1), + TEGRA_INIT_DATA_I2C("i2c2", "div-clk", "tegra11-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, i2c2), + TEGRA_INIT_DATA_I2C("i2c3", "div-clk", "tegra11-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, i2c3), + TEGRA_INIT_DATA_I2C("i2c4", "div-clk", "tegra11-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, i2c4), + TEGRA_INIT_DATA_I2C("i2c5", "div-clk", "tegra11-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, i2c5), + TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, uarta), + TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, uartb), + TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, uartc), + TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, uartd), + TEGRA_INIT_DATA_UART("uarte", NULL, "tegra_uart.4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTE, 66, &periph_u_regs, uarte), + TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, &periph_l_regs, 0, gr_3d), + TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr_2d), + TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), + TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), + TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), + TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, &periph_h_regs, TEGRA_PERIPH_WAR_1005168, msenc), + TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, &periph_u_regs, 0, tsec), + TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), + TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), + TEGRA_INIT_DATA_MUX("cilab", "cilab", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, &periph_w_regs, 0, cilab), + TEGRA_INIT_DATA_MUX("cilcd", "cilcd", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, &periph_w_regs, 0, cilcd), + TEGRA_INIT_DATA_MUX("cile", "cile", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, &periph_w_regs, 0, cile), + TEGRA_INIT_DATA_MUX("dsialp", "dsialp", "tegradc.0", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, &periph_w_regs, 0, dsialp), + TEGRA_INIT_DATA_MUX("dsiblp", "dsiblp", "tegradc.1", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, &periph_w_regs, 0, dsiblp), + TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, tsensor), + TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, actmon), + TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, extern1), + TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, extern2), + TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, extern3), + TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow), + TEGRA_INIT_DATA_INT8("se", NULL, "se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, TEGRA_PERIPH_ON_APB, se), + TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect, CLK_IGNORE_UNUSED), + TEGRA_INIT_DATA_MUX8("soc_therm", NULL, "soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, &periph_u_regs, TEGRA_PERIPH_ON_APB, soc_therm), + TEGRA_INIT_DATA_XUSB("xusb_host_src", "host_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, &periph_w_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_host_src), + TEGRA_INIT_DATA_XUSB("xusb_falcon_src", "falcon_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_falcon_src), + TEGRA_INIT_DATA_XUSB("xusb_fs_src", "fs_src", "tegra_xhci", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_fs_src), + TEGRA_INIT_DATA_XUSB("xusb_ss_src", "ss_src", "tegra_xhci", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_ss_src), + TEGRA_INIT_DATA_XUSB("xusb_dev_src", "dev_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, &periph_u_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_dev_src), + TEGRA_INIT_DATA_AUDIO("d_audio", "d_audio", "tegra30-ahub", CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, TEGRA_PERIPH_ON_APB, d_audio), + TEGRA_INIT_DATA_AUDIO("dam0", NULL, "tegra30-dam.0", CLK_SOURCE_DAM0, 108, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam0), + TEGRA_INIT_DATA_AUDIO("dam1", NULL, "tegra30-dam.1", CLK_SOURCE_DAM1, 109, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam1), + TEGRA_INIT_DATA_AUDIO("dam2", NULL, "tegra30-dam.2", CLK_SOURCE_DAM2, 110, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam2), +}; + +static __initdata struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { + TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 3, 27, &periph_l_regs, 0, disp1), + TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 3, 26, &periph_l_regs, 0, disp2), +}; + +static __init void tegra114_periph_clk_init(void __iomem *clk_base) +{ + struct tegra_periph_init_data *data; + struct clk *clk; + int i; + u32 val; + + /* apbdma */ + clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, + 0, 34, &periph_h_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "apbdma", "tegra-dma"); + clks[apbdma] = clk; + + /* rtc */ + clk = tegra_clk_register_periph_gate("rtc", "clk_32k", + TEGRA_PERIPH_ON_APB | + TEGRA_PERIPH_NO_RESET, clk_base, + 0, 4, &periph_l_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, NULL, "rtc-tegra"); + clks[rtc] = clk; + + /* kbc */ + clk = tegra_clk_register_periph_gate("kbc", "clk_32k", + TEGRA_PERIPH_ON_APB | + TEGRA_PERIPH_NO_RESET, clk_base, + 0, 36, &periph_h_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, NULL, "tegra-kbc"); + clks[kbc] = clk; + + /* timer */ + clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, + 0, 5, &periph_l_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, NULL, "timer"); + clks[timer] = clk; + + /* kfuse */ + clk = tegra_clk_register_periph_gate("kfuse", "clk_m", + TEGRA_PERIPH_ON_APB, clk_base, 0, 40, + &periph_h_regs, periph_clk_enb_refcnt); + clk_register_clkdev(clk, NULL, "kfuse-tegra"); + clks[kfuse] = clk; + + /* fuse */ + clk = tegra_clk_register_periph_gate("fuse", "clk_m", + TEGRA_PERIPH_ON_APB, clk_base, 0, 39, + &periph_h_regs, periph_clk_enb_refcnt); + clk_register_clkdev(clk, "fuse", "fuse-tegra"); + clks[fuse] = clk; + + /* fuse_burn */ + clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m", + TEGRA_PERIPH_ON_APB, clk_base, 0, 39, + &periph_h_regs, periph_clk_enb_refcnt); + clk_register_clkdev(clk, "fuse_burn", "fuse-tegra"); + clks[fuse_burn] = clk; + + /* apbif */ + clk = tegra_clk_register_periph_gate("apbif", "clk_m", + TEGRA_PERIPH_ON_APB, clk_base, 0, 107, + &periph_v_regs, periph_clk_enb_refcnt); + clk_register_clkdev(clk, "apbif", "tegra30-ahub"); + clks[apbif] = clk; + + /* hda2hdmi */ + clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m", + TEGRA_PERIPH_ON_APB, clk_base, 0, 128, + &periph_w_regs, periph_clk_enb_refcnt); + clk_register_clkdev(clk, "hda2hdmi", "tegra30-hda"); + clks[hda2hdmi] = clk; + + /* vcp */ + clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0, + 29, &periph_l_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "vcp", "tegra-avp"); + clks[vcp] = clk; + + /* bsea */ + clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base, + 0, 62, &periph_h_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "bsea", "tegra-avp"); + clks[bsea] = clk; + + /* bsev */ + clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base, + 0, 63, &periph_h_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "bsev", "tegra-aes"); + clks[bsev] = clk; + + /* mipi-cal */ + clk = tegra_clk_register_periph_gate("mipi-cal", "clk_m", 0, clk_base, + 0, 56, &periph_h_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "mipi-cal", "mipi-cal"); + clks[mipi_cal] = clk; + + /* usbd */ + clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, + 0, 22, &periph_l_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "usbd", "tegra-udc.0"); + clks[usbd] = clk; + + /* usb2 */ + clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, + 0, 58, &periph_h_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "usb2", "tegra-ehci.1"); + clks[usb2] = clk; + + /* usb3 */ + clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, + 0, 59, &periph_h_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "usb3", "tegra-ehci.2"); + clks[usb3] = clk; + + /* dsi1-fixed */ + clk = clk_register_fixed_factor(NULL, "dsi1-fixed", "pll_p_out3", + CLK_SET_RATE_PARENT, 1, 1); + clks[dsi1_fixed] = clk; + + /* dsi2-fixed */ + clk = clk_register_fixed_factor(NULL, "dsi2-fixed", "pll_p_out3", + CLK_SET_RATE_PARENT, 1, 1); + clks[dsi2_fixed] = clk; + + /* mipi-cal-fast */ + clk = clk_register_fixed_factor(NULL, "mipi-cal-fast", "pll_p_out3", + CLK_SET_RATE_PARENT, 1, 1); + clk_register_clkdev(clk, "fast-clk", "mipi-cal"); + clks[mipi_cal_fast] = clk; + + /* csi */ + clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, + 0, 52, &periph_h_regs, + periph_clk_enb_refcnt); + clks[csi] = clk; + + /* isp */ + clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, + 23, &periph_l_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "isp", "tegra_camera"); + clks[isp] = clk; + + /* csus */ + clk = tegra_clk_register_periph_gate("csus", "clk_m", + TEGRA_PERIPH_NO_RESET, clk_base, 0, 92, + &periph_u_regs, periph_clk_enb_refcnt); + clk_register_clkdev(clk, "csus", "tegra_camera"); + clks[csus] = clk; + + /* dds */ + clk = tegra_clk_register_periph_gate("dds", "clk_m", + TEGRA_PERIPH_ON_APB, clk_base, 0, 150, + &periph_w_regs, periph_clk_enb_refcnt); + clk_register_clkdev(clk, "dds", "dds"); + clks[dds] = clk; + + /* dp2 */ + clk = tegra_clk_register_periph_gate("dp2", "clk_m", + TEGRA_PERIPH_ON_APB, clk_base, 0, 152, + &periph_w_regs, periph_clk_enb_refcnt); + clk_register_clkdev(clk, "dp2", "dp2"); + clks[dp2] = clk; + + /* dtv */ + clk = tegra_clk_register_periph_gate("dtv", "clk_m", + TEGRA_PERIPH_ON_APB, clk_base, 0, 79, + &periph_u_regs, periph_clk_enb_refcnt); + clk_register_clkdev(clk, NULL, "dtv"); + clks[dtv] = clk; + + /* dsia */ + clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, + ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, + clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); + clks[dsia_mux] = clk; + clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base, + 0, 48, &periph_h_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "dsia", "tegradc.0"); + clks[dsia] = clk; + + /* dsib */ + clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0, + ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, + clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); + clks[dsib_mux] = clk; + clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base, + 0, 82, &periph_u_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "dsib", "tegradc.1"); + clks[dsib] = clk; + + /* xusb_hs_src */ + val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); + val |= BIT(25); /* always select PLLU_60M */ + writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); + + clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, + 1, 1); + clks[xusb_hs_src] = clk; + + /* xusb_host */ + clk = tegra_clk_register_periph_gate("xusb_host", "xusb_host_src", 0, + clk_base, 0, 89, &periph_u_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "tegra_xhci", "host"); + clks[xusb_host] = clk; + + /* xusb_ss */ + clk = tegra_clk_register_periph_gate("xusb_ss", "xusb_ss_src", 0, + clk_base, 0, 156, &periph_w_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "tegra_xhci", "ss"); + clks[xusb_host] = clk; + + /* xusb_dev */ + clk = tegra_clk_register_periph_gate("xusb_dev", "xusb_dev_src", 0, + clk_base, 0, 95, &periph_u_regs, + periph_clk_enb_refcnt); + clk_register_clkdev(clk, "tegra_xhci", "dev"); + + for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { + data = &tegra_periph_clk_list[i]; + clk = tegra_clk_register_periph(data->name, data->parent_names, + data->num_parents, &data->periph, + clk_base, data->offset, data->flags); + clk_register_clkdev(clk, data->con_id, data->dev_id); + clks[data->clk_id] = clk; + } + + for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { + data = &tegra_periph_nodiv_clk_list[i]; + clk = tegra_clk_register_periph_nodiv(data->name, + data->parent_names, data->num_parents, + &data->periph, clk_base, data->offset); + clk_register_clkdev(clk, data->con_id, data->dev_id); + clks[data->clk_id] = clk; + } +} + +static struct tegra_cpu_car_ops tegra114_cpu_car_ops; + +static const struct of_device_id pmc_match[] __initconst = { + { .compatible = "nvidia,tegra114-pmc" }, + {}, +}; + +static __initdata struct tegra_clk_init_table init_table[] = { + {uartd, pll_p, 408000000, 1}, + {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */ +}; + +void __init tegra114_clock_init(struct device_node *np) +{ + struct device_node *node; + int i; + + clk_base = of_iomap(np, 0); + if (!clk_base) { + pr_err("ioremap tegra114 CAR failed\n"); + return; + } + + node = of_find_matching_node(NULL, pmc_match); + if (!node) { + pr_err("Failed to find pmc node\n"); + WARN_ON(1); + return; + } + + pmc_base = of_iomap(node, 0); + if (!pmc_base) { + pr_err("Can't map pmc registers\n"); + WARN_ON(1); + return; + } + + if (tegra114_osc_clk_init(clk_base) < 0) + return; + + tegra114_fixed_clk_init(clk_base); + tegra114_pll_init(clk_base, pmc_base); + tegra114_periph_clk_init(clk_base); + tegra114_audio_clk_init(clk_base); + tegra114_pmc_clk_init(pmc_base); + + for (i = 0; i < ARRAY_SIZE(clks); i++) { + if (IS_ERR(clks[i])) { + pr_err + ("Tegra114 clk %d: register failed with %ld\n", + i, PTR_ERR(clks[i])); + } + if (!clks[i]) + clks[i] = ERR_PTR(-EINVAL); + } + + clk_data.clks = clks; + clk_data.clk_num = ARRAY_SIZE(clks); + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + + tegra_init_from_table(init_table, clks, clk_max); + + tegra_cpu_car_ops = &tegra114_cpu_car_ops; +} ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [PATCH v5 09/10] clk: tegra: Implement clocks for Tegra114 2013-02-01 10:18 ` [PATCH v5 09/10] clk: tegra: Implement clocks for Tegra114 Peter De Schrijver @ 2013-02-04 7:08 ` Prashant Gaikwad [not found] ` <510F5E87.90801-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-04 14:34 ` Peter De Schrijver 0 siblings, 2 replies; 34+ messages in thread From: Prashant Gaikwad @ 2013-02-04 7:08 UTC (permalink / raw) To: Peter De Schrijver Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: > Implement most clocks for Tegra114. The super clocks for the CPU complex > are still missing and will be implemented in a future version. > > Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> > --- > drivers/clk/tegra/Makefile | 1 + > drivers/clk/tegra/clk-tegra114.c | 2002 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 2003 insertions(+), 0 deletions(-) > create mode 100644 drivers/clk/tegra/clk-tegra114.c > > diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile > index 2b41b0f..f49fac2 100644 > --- a/drivers/clk/tegra/Makefile > +++ b/drivers/clk/tegra/Makefile > @@ -9,3 +9,4 @@ obj-y += clk-super.o > > obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o > obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o > +obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o > diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c > new file mode 100644 > index 0000000..f8165d2 > --- /dev/null > +++ b/drivers/clk/tegra/clk-tegra114.c > @@ -0,0 +1,2002 @@ > +/* > + * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#include <linux/io.h> > +#include <linux/clk.h> > +#include <linux/clk-provider.h> > +#include <linux/clkdev.h> > +#include <linux/of.h> > +#include <linux/of_address.h> > +#include <linux/delay.h> > +#include <linux/clk/tegra.h> > + > +#include "clk.h" > + > +#define RST_DEVICES_L 0x004 > +#define RST_DEVICES_H 0x008 > +#define RST_DEVICES_U 0x00C > +#define RST_DEVICES_V 0x358 > +#define RST_DEVICES_W 0x35C > +#define RST_DEVICES_X 0x28C > +#define RST_DEVICES_SET_L 0x300 > +#define RST_DEVICES_CLR_L 0x304 > +#define RST_DEVICES_SET_H 0x308 > +#define RST_DEVICES_CLR_H 0x30c > +#define RST_DEVICES_SET_U 0x310 > +#define RST_DEVICES_CLR_U 0x314 > +#define RST_DEVICES_SET_V 0x430 > +#define RST_DEVICES_CLR_V 0x434 > +#define RST_DEVICES_SET_W 0x438 > +#define RST_DEVICES_CLR_W 0x43c > +#define RST_DEVICES_NUM 5 RST_DEVICES_SET/CLR_X? > + > +#define CLK_OUT_ENB_L 0x010 > +#define CLK_OUT_ENB_H 0x014 > +#define CLK_OUT_ENB_U 0x018 > +#define CLK_OUT_ENB_V 0x360 > +#define CLK_OUT_ENB_W 0x364 > +#define CLK_OUT_ENB_X 0x280 > +#define CLK_OUT_ENB_SET_L 0x320 > +#define CLK_OUT_ENB_CLR_L 0x324 > +#define CLK_OUT_ENB_SET_H 0x328 > +#define CLK_OUT_ENB_CLR_H 0x32c > +#define CLK_OUT_ENB_SET_U 0x330 > +#define CLK_OUT_ENB_CLR_U 0x334 > +#define CLK_OUT_ENB_SET_V 0x440 > +#define CLK_OUT_ENB_CLR_V 0x444 > +#define CLK_OUT_ENB_SET_W 0x448 > +#define CLK_OUT_ENB_CLR_W 0x44c > +#define CLK_OUT_ENB_SET_X 0x284 > +#define CLK_OUT_ENB_CLR_X 0x288 > +#define CLK_OUT_ENB_NUM 6 <snip> > + > + /* dsia */ > + clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, > + ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, > + clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); > + clks[dsia_mux] = clk; > + clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base, > + 0, 48, &periph_h_regs, > + periph_clk_enb_refcnt); > + clk_register_clkdev(clk, "dsia", "tegradc.0"); > + clks[dsia] = clk; > + > + /* dsib */ > + clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0, > + ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, > + clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); > + clks[dsib_mux] = clk; > + clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base, > + 0, 82, &periph_u_regs, > + periph_clk_enb_refcnt); > + clk_register_clkdev(clk, "dsib", "tegradc.1"); > + clks[dsib] = clk; > + Can we use periph no div clock here for dsia and dsib? > + /* xusb_hs_src */ > + val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); > + val |= BIT(25); /* always select PLLU_60M */ > + writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); > + > + clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, > + 1, 1); > + clks[xusb_hs_src] = clk; > + With device tree we can directly use pll_u_60M, no need to register clock with fixed factor 1. Same comment for dis1-fixed, dsi2-fixed and mipi-cal-fast clocks. > + /* xusb_host */ > + clk = tegra_clk_register_periph_gate("xusb_host", "xusb_host_src", 0, > + clk_base, 0, 89, &periph_u_regs, > + periph_clk_enb_refcnt); > + clk_register_clkdev(clk, "tegra_xhci", "host"); > + clks[xusb_host] = clk; > + > + /* xusb_ss */ > + clk = tegra_clk_register_periph_gate("xusb_ss", "xusb_ss_src", 0, > + clk_base, 0, 156, &periph_w_regs, > + periph_clk_enb_refcnt); > + clk_register_clkdev(clk, "tegra_xhci", "ss"); > + clks[xusb_host] = clk; > + > + /* xusb_dev */ > + clk = tegra_clk_register_periph_gate("xusb_dev", "xusb_dev_src", 0, > + clk_base, 0, 95, &periph_u_regs, > + periph_clk_enb_refcnt); > + clk_register_clkdev(clk, "tegra_xhci", "dev"); clks[xusb_dev] = clk; > + > + for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { > + data = &tegra_periph_clk_list[i]; > + clk = tegra_clk_register_periph(data->name, data->parent_names, > + data->num_parents, &data->periph, > + clk_base, data->offset, data->flags); > + clk_register_clkdev(clk, data->con_id, data->dev_id); > + clks[data->clk_id] = clk; > + } > + > + for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { > + data = &tegra_periph_nodiv_clk_list[i]; > + clk = tegra_clk_register_periph_nodiv(data->name, > + data->parent_names, data->num_parents, > + &data->periph, clk_base, data->offset); > + clk_register_clkdev(clk, data->con_id, data->dev_id); > + clks[data->clk_id] = clk; > + } > +} > + > +static struct tegra_cpu_car_ops tegra114_cpu_car_ops; > + > +static const struct of_device_id pmc_match[] __initconst = { > + { .compatible = "nvidia,tegra114-pmc" }, > + {}, > +}; > + > +static __initdata struct tegra_clk_init_table init_table[] = { > + {uartd, pll_p, 408000000, 1}, > + {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */ > +}; > + > +void __init tegra114_clock_init(struct device_node *np) > +{ > + struct device_node *node; > + int i; > + > + clk_base = of_iomap(np, 0); > + if (!clk_base) { > + pr_err("ioremap tegra114 CAR failed\n"); > + return; > + } > + > + node = of_find_matching_node(NULL, pmc_match); > + if (!node) { > + pr_err("Failed to find pmc node\n"); > + WARN_ON(1); > + return; > + } > + > + pmc_base = of_iomap(node, 0); > + if (!pmc_base) { > + pr_err("Can't map pmc registers\n"); > + WARN_ON(1); > + return; > + } > + > + if (tegra114_osc_clk_init(clk_base) < 0) > + return; > + > + tegra114_fixed_clk_init(clk_base); > + tegra114_pll_init(clk_base, pmc_base); > + tegra114_periph_clk_init(clk_base); > + tegra114_audio_clk_init(clk_base); > + tegra114_pmc_clk_init(pmc_base); > + > + for (i = 0; i < ARRAY_SIZE(clks); i++) { > + if (IS_ERR(clks[i])) { > + pr_err > + ("Tegra114 clk %d: register failed with %ld\n", > + i, PTR_ERR(clks[i])); > + } > + if (!clks[i]) > + clks[i] = ERR_PTR(-EINVAL); > + } > + > + clk_data.clks = clks; > + clk_data.clk_num = ARRAY_SIZE(clks); > + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); > + > + tegra_init_from_table(init_table, clks, clk_max); > + > + tegra_cpu_car_ops = &tegra114_cpu_car_ops; > +} > ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <510F5E87.90801-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v5 09/10] clk: tegra: Implement clocks for Tegra114 [not found] ` <510F5E87.90801-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> @ 2013-02-04 10:45 ` Peter De Schrijver [not found] ` <20130204104531.GQ2364-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org> ` (2 more replies) 0 siblings, 3 replies; 34+ messages in thread From: Peter De Schrijver @ 2013-02-04 10:45 UTC (permalink / raw) To: Prashant Gaikwad Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org On Mon, Feb 04, 2013 at 08:08:55AM +0100, Prashant Gaikwad wrote: ... > > +#define RST_DEVICES_L 0x004 > > +#define RST_DEVICES_H 0x008 > > +#define RST_DEVICES_U 0x00C > > +#define RST_DEVICES_V 0x358 > > +#define RST_DEVICES_W 0x35C > > +#define RST_DEVICES_X 0x28C > > +#define RST_DEVICES_SET_L 0x300 > > +#define RST_DEVICES_CLR_L 0x304 > > +#define RST_DEVICES_SET_H 0x308 > > +#define RST_DEVICES_CLR_H 0x30c > > +#define RST_DEVICES_SET_U 0x310 > > +#define RST_DEVICES_CLR_U 0x314 > > +#define RST_DEVICES_SET_V 0x430 > > +#define RST_DEVICES_CLR_V 0x434 > > +#define RST_DEVICES_SET_W 0x438 > > +#define RST_DEVICES_CLR_W 0x43c > > +#define RST_DEVICES_NUM 5 > > RST_DEVICES_SET/CLR_X? > For all I can see (from the not yet public TRM), this is not actually used? So I decided to not mention it here. > > + > > +#define CLK_OUT_ENB_L 0x010 > > +#define CLK_OUT_ENB_H 0x014 > > +#define CLK_OUT_ENB_U 0x018 > > +#define CLK_OUT_ENB_V 0x360 > > +#define CLK_OUT_ENB_W 0x364 > > +#define CLK_OUT_ENB_X 0x280 > > +#define CLK_OUT_ENB_SET_L 0x320 > > +#define CLK_OUT_ENB_CLR_L 0x324 > > +#define CLK_OUT_ENB_SET_H 0x328 > > +#define CLK_OUT_ENB_CLR_H 0x32c > > +#define CLK_OUT_ENB_SET_U 0x330 > > +#define CLK_OUT_ENB_CLR_U 0x334 > > +#define CLK_OUT_ENB_SET_V 0x440 > > +#define CLK_OUT_ENB_CLR_V 0x444 > > +#define CLK_OUT_ENB_SET_W 0x448 > > +#define CLK_OUT_ENB_CLR_W 0x44c > > +#define CLK_OUT_ENB_SET_X 0x284 > > +#define CLK_OUT_ENB_CLR_X 0x288 > > +#define CLK_OUT_ENB_NUM 6 > > <snip> > > > + > > + /* dsia */ > > + clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, > > + ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, > > + clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); > > + clks[dsia_mux] = clk; > > + clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base, > > + 0, 48, &periph_h_regs, > > + periph_clk_enb_refcnt); > > + clk_register_clkdev(clk, "dsia", "tegradc.0"); > > + clks[dsia] = clk; > > + > > + /* dsib */ > > + clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0, > > + ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, > > + clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); > > + clks[dsib_mux] = clk; > > + clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base, > > + 0, 82, &periph_u_regs, > > + periph_clk_enb_refcnt); > > + clk_register_clkdev(clk, "dsib", "tegradc.1"); > > + clks[dsib] = clk; > > + > > Can we use periph no div clock here for dsia and dsib? > Will check. > > + /* xusb_hs_src */ > > + val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); > > + val |= BIT(25); /* always select PLLU_60M */ > > + writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); > > + > > + clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, > > + 1, 1); > > + clks[xusb_hs_src] = clk; > > + > > With device tree we can directly use pll_u_60M, no need to register > clock with fixed factor 1. This is true for now. In the future these clocks will need to be dvfs aware though. I think it makes sense to have a separate clock then? > Same comment for dis1-fixed, dsi2-fixed and mipi-cal-fast clocks. > Those might not need to become dvfs aware. > > + /* xusb_host */ > > + clk = tegra_clk_register_periph_gate("xusb_host", "xusb_host_src", 0, > > + clk_base, 0, 89, &periph_u_regs, > > + periph_clk_enb_refcnt); > > + clk_register_clkdev(clk, "tegra_xhci", "host"); > > + clks[xusb_host] = clk; > > + > > + /* xusb_ss */ > > + clk = tegra_clk_register_periph_gate("xusb_ss", "xusb_ss_src", 0, > > + clk_base, 0, 156, &periph_w_regs, > > + periph_clk_enb_refcnt); > > + clk_register_clkdev(clk, "tegra_xhci", "ss"); > > + clks[xusb_host] = clk; > > + > > + /* xusb_dev */ > > + clk = tegra_clk_register_periph_gate("xusb_dev", "xusb_dev_src", 0, > > + clk_base, 0, 95, &periph_u_regs, > > + periph_clk_enb_refcnt); > > + clk_register_clkdev(clk, "tegra_xhci", "dev"); > > clks[xusb_dev] = clk; > Missing indeed. Cheers, Peter. ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <20130204104531.GQ2364-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org>]
* Re: [PATCH v5 09/10] clk: tegra: Implement clocks for Tegra114 [not found] ` <20130204104531.GQ2364-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org> @ 2013-02-04 14:07 ` Peter De Schrijver 0 siblings, 0 replies; 34+ messages in thread From: Peter De Schrijver @ 2013-02-04 14:07 UTC (permalink / raw) To: Prashant Gaikwad Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org On Mon, Feb 04, 2013 at 11:45:31AM +0100, Peter De Schrijver wrote: > On Mon, Feb 04, 2013 at 08:08:55AM +0100, Prashant Gaikwad wrote: ... > > > + > > > + /* dsia */ > > > + clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, > > > + ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, > > > + clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); > > > + clks[dsia_mux] = clk; > > > + clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base, > > > + 0, 48, &periph_h_regs, > > > + periph_clk_enb_refcnt); > > > + clk_register_clkdev(clk, "dsia", "tegradc.0"); > > > + clks[dsia] = clk; > > > + > > > + /* dsib */ > > > + clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0, > > > + ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, > > > + clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); > > > + clks[dsib_mux] = clk; > > > + clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base, > > > + 0, 82, &periph_u_regs, > > > + periph_clk_enb_refcnt); > > > + clk_register_clkdev(clk, "dsib", "tegradc.1"); > > > + clks[dsib] = clk; > > > + > > > > Can we use periph no div clock here for dsia and dsib? > > > > Will check. > Not as such. As you can see the muxes need a lock to protect access to the PLLD_BASE and PLLD2_BASE registers respectively. The periph no div clock doesn't provide for these locks though. Do you think it makes sense to add the lock support for these 2 clocks? Cheers, Peter. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v5 09/10] clk: tegra: Implement clocks for Tegra114 2013-02-04 10:45 ` Peter De Schrijver [not found] ` <20130204104531.GQ2364-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org> @ 2013-02-04 21:01 ` Stephen Warren 2013-02-07 16:18 ` Peter De Schrijver 2 siblings, 0 replies; 34+ messages in thread From: Stephen Warren @ 2013-02-04 21:01 UTC (permalink / raw) To: Peter De Schrijver Cc: Prashant Gaikwad, Grant Likely, Rob Herring, Rob Landley, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org On 02/04/2013 03:45 AM, Peter De Schrijver wrote: > On Mon, Feb 04, 2013 at 08:08:55AM +0100, Prashant Gaikwad wrote: >>> + /* xusb_hs_src */ >>> + val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); >>> + val |= BIT(25); /* always select PLLU_60M */ >>> + writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); >>> + >>> + clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, >>> + 1, 1); >>> + clks[xusb_hs_src] = clk; >>> + >> >> With device tree we can directly use pll_u_60M, no need to register >> clock with fixed factor 1. > > This is true for now. In the future these clocks will need to be dvfs aware > though. I think it makes sense to have a separate clock then? Why does DVFS-awareness require it to be a different clock/ID? ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v5 09/10] clk: tegra: Implement clocks for Tegra114 2013-02-04 10:45 ` Peter De Schrijver [not found] ` <20130204104531.GQ2364-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org> 2013-02-04 21:01 ` Stephen Warren @ 2013-02-07 16:18 ` Peter De Schrijver 2 siblings, 0 replies; 34+ messages in thread From: Peter De Schrijver @ 2013-02-07 16:18 UTC (permalink / raw) To: Prashant Gaikwad Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org > > > > + /* xusb_hs_src */ > > > + val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); > > > + val |= BIT(25); /* always select PLLU_60M */ > > > + writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); > > > + > > > + clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, > > > + 1, 1); > > > + clks[xusb_hs_src] = clk; > > > + > > > > With device tree we can directly use pll_u_60M, no need to register > > clock with fixed factor 1. > > This is true for now. In the future these clocks will need to be dvfs aware > though. I think it makes sense to have a separate clock then? > As this seems to be a different clock (ie. the hw allows you to select a different parent), I think keeping this node makes sense. Cheers, Peter. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v5 09/10] clk: tegra: Implement clocks for Tegra114 2013-02-04 7:08 ` Prashant Gaikwad [not found] ` <510F5E87.90801-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> @ 2013-02-04 14:34 ` Peter De Schrijver [not found] ` <20130204143401.GW2364-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org> 1 sibling, 1 reply; 34+ messages in thread From: Peter De Schrijver @ 2013-02-04 14:34 UTC (permalink / raw) To: Prashant Gaikwad Cc: Grant Likely, Rob Herring, Rob Landley, Stephen Warren, Russell King, Simon Glass, Mike Turquette, Joseph Lo, devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org On Mon, Feb 04, 2013 at 08:08:55AM +0100, Prashant Gaikwad wrote: > On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: ... > > + /* xusb_hs_src */ > > + val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); > > + val |= BIT(25); /* always select PLLU_60M */ > > + writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); > > + > > + clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, > > + 1, 1); > > + clks[xusb_hs_src] = clk; > > + > > With device tree we can directly use pll_u_60M, no need to register > clock with fixed factor 1. > Same comment for dis1-fixed, dsi2-fixed and mipi-cal-fast clocks. > Does it make sense to have separate DT IDs at all then? Cheers, Peter. ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <20130204143401.GW2364-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org>]
* Re: [PATCH v5 09/10] clk: tegra: Implement clocks for Tegra114 [not found] ` <20130204143401.GW2364-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org> @ 2013-02-05 5:36 ` Prashant Gaikwad 0 siblings, 0 replies; 34+ messages in thread From: Prashant Gaikwad @ 2013-02-05 5:36 UTC (permalink / raw) To: Peter De Schrijver Cc: Russell King, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring, Joseph Lo, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Mike Turquette, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org On Monday 04 February 2013 08:04 PM, Peter De Schrijver wrote: > On Mon, Feb 04, 2013 at 08:08:55AM +0100, Prashant Gaikwad wrote: >> On Friday 01 February 2013 03:48 PM, Peter De Schrijver wrote: > ... > >>> + /* xusb_hs_src */ >>> + val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); >>> + val |= BIT(25); /* always select PLLU_60M */ >>> + writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); >>> + >>> + clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, >>> + 1, 1); >>> + clks[xusb_hs_src] = clk; >>> + >> With device tree we can directly use pll_u_60M, no need to register >> clock with fixed factor 1. >> Same comment for dis1-fixed, dsi2-fixed and mipi-cal-fast clocks. >> > Does it make sense to have separate DT IDs at all then? We can use same DT ID. > Cheers, > > Peter. ^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2013-02-07 16:18 UTC | newest] Thread overview: 34+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-02-01 10:18 [PATCH v5 00/10] Tegra114 clockframework Peter De Schrijver [not found] ` <1359713962-16822-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-01 10:18 ` [PATCH v5 01/10] clk: tegra: Refactor PLL programming code Peter De Schrijver [not found] ` <1359713962-16822-2-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-04 6:06 ` Prashant Gaikwad 2013-02-04 14:32 ` Peter De Schrijver 2013-02-05 5:42 ` Prashant Gaikwad [not found] ` <51109BB3.8000706-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-05 13:23 ` Peter De Schrijver [not found] ` <20130205132355.GD3073-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org> 2013-02-06 12:32 ` Peter De Schrijver 2013-02-04 21:57 ` Stephen Warren 2013-02-01 10:18 ` [PATCH v5 02/10] clk: tegra: Add TEGRA_PLL_BYPASS flag Peter De Schrijver [not found] ` <1359713962-16822-3-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-04 6:13 ` Prashant Gaikwad 2013-02-01 10:18 ` [PATCH v5 04/10] clk: tegra: Add new fields and PLL types for Tegra114 Peter De Schrijver [not found] ` <1359713962-16822-5-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-01 19:40 ` Rhyland Klein [not found] ` <510C1A2E.5010408-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-04 6:35 ` Prashant Gaikwad [not found] ` <510F56B1.5060409-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-04 10:37 ` Peter De Schrijver 2013-02-01 10:18 ` [PATCH v5 05/10] clk: tegra: Add flags to tegra_clk_periph() Peter De Schrijver [not found] ` <1359713962-16822-6-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-04 6:33 ` Prashant Gaikwad 2013-02-01 10:18 ` [PATCH v5 06/10] clk: tegra: Workaround for Tegra114 MSENC problem Peter De Schrijver 2013-02-04 6:39 ` Prashant Gaikwad 2013-02-01 10:18 ` [PATCH v5 07/10] ARM: tegra: Define Tegra114 CAR binding Peter De Schrijver 2013-02-04 21:16 ` Stephen Warren 2013-02-01 10:18 ` [PATCH v5 08/10] ARM: dt: Add references to tegra_car clocks Peter De Schrijver 2013-02-04 6:45 ` Prashant Gaikwad 2013-02-01 10:18 ` [PATCH v5 10/10] clk: tegra: devicetree match for nvidia,tegra114-car Peter De Schrijver 2013-02-04 7:10 ` Prashant Gaikwad 2013-02-01 10:18 ` [PATCH v5 03/10] clk: tegra: Add PLL post divider table Peter De Schrijver [not found] ` <1359713962-16822-4-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-04 6:28 ` Prashant Gaikwad 2013-02-01 10:18 ` [PATCH v5 09/10] clk: tegra: Implement clocks for Tegra114 Peter De Schrijver 2013-02-04 7:08 ` Prashant Gaikwad [not found] ` <510F5E87.90801-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> 2013-02-04 10:45 ` Peter De Schrijver [not found] ` <20130204104531.GQ2364-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org> 2013-02-04 14:07 ` Peter De Schrijver 2013-02-04 21:01 ` Stephen Warren 2013-02-07 16:18 ` Peter De Schrijver 2013-02-04 14:34 ` Peter De Schrijver [not found] ` <20130204143401.GW2364-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org> 2013-02-05 5:36 ` Prashant Gaikwad
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).