diff options
Diffstat (limited to 'drivers/clk/tegra')
| -rw-r--r-- | drivers/clk/tegra/Makefile | 1 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-dfll.c | 11 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-dfll.h | 22 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-id.h | 2 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-periph-fixed.c | 120 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-periph-gate.c | 2 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-periph.c | 2 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-pll.c | 46 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-tegra-fixed.c | 1 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-tegra-periph.c | 5 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-tegra114.c | 6 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-tegra124-dfll-fcpu.c | 103 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-tegra124.c | 4 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-tegra210.c | 29 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk-tegra30.c | 12 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk.c | 4 | ||||
| -rw-r--r-- | drivers/clk/tegra/clk.h | 27 | ||||
| -rw-r--r-- | drivers/clk/tegra/cvb.c | 71 | ||||
| -rw-r--r-- | drivers/clk/tegra/cvb.h | 15 |
19 files changed, 369 insertions, 114 deletions
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index 97984c503bbb..33fd0938d79e 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile | |||
| @@ -3,6 +3,7 @@ obj-y += clk-audio-sync.o | |||
| 3 | obj-y += clk-dfll.o | 3 | obj-y += clk-dfll.o |
| 4 | obj-y += clk-divider.o | 4 | obj-y += clk-divider.o |
| 5 | obj-y += clk-periph.o | 5 | obj-y += clk-periph.o |
| 6 | obj-y += clk-periph-fixed.o | ||
| 6 | obj-y += clk-periph-gate.o | 7 | obj-y += clk-periph-gate.o |
| 7 | obj-y += clk-pll.o | 8 | obj-y += clk-pll.o |
| 8 | obj-y += clk-pll-out.o | 9 | obj-y += clk-pll-out.o |
diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c index 19bfa07e24b1..f010562534eb 100644 --- a/drivers/clk/tegra/clk-dfll.c +++ b/drivers/clk/tegra/clk-dfll.c | |||
| @@ -55,6 +55,7 @@ | |||
| 55 | #include <linux/seq_file.h> | 55 | #include <linux/seq_file.h> |
| 56 | 56 | ||
| 57 | #include "clk-dfll.h" | 57 | #include "clk-dfll.h" |
| 58 | #include "cvb.h" | ||
| 58 | 59 | ||
| 59 | /* | 60 | /* |
| 60 | * DFLL control registers - access via dfll_{readl,writel} | 61 | * DFLL control registers - access via dfll_{readl,writel} |
| @@ -442,8 +443,8 @@ static void dfll_tune_low(struct tegra_dfll *td) | |||
| 442 | { | 443 | { |
| 443 | td->tune_range = DFLL_TUNE_LOW; | 444 | td->tune_range = DFLL_TUNE_LOW; |
| 444 | 445 | ||
| 445 | dfll_writel(td, td->soc->tune0_low, DFLL_TUNE0); | 446 | dfll_writel(td, td->soc->cvb->cpu_dfll_data.tune0_low, DFLL_TUNE0); |
| 446 | dfll_writel(td, td->soc->tune1, DFLL_TUNE1); | 447 | dfll_writel(td, td->soc->cvb->cpu_dfll_data.tune1, DFLL_TUNE1); |
| 447 | dfll_wmb(td); | 448 | dfll_wmb(td); |
| 448 | 449 | ||
| 449 | if (td->soc->set_clock_trimmers_low) | 450 | if (td->soc->set_clock_trimmers_low) |
| @@ -1449,7 +1450,7 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td) | |||
| 1449 | } | 1450 | } |
| 1450 | v_max = dev_pm_opp_get_voltage(opp); | 1451 | v_max = dev_pm_opp_get_voltage(opp); |
| 1451 | 1452 | ||
| 1452 | v = td->soc->min_millivolts * 1000; | 1453 | v = td->soc->cvb->min_millivolts * 1000; |
| 1453 | lut = find_vdd_map_entry_exact(td, v); | 1454 | lut = find_vdd_map_entry_exact(td, v); |
| 1454 | if (lut < 0) | 1455 | if (lut < 0) |
| 1455 | goto out; | 1456 | goto out; |
| @@ -1461,7 +1462,7 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td) | |||
| 1461 | break; | 1462 | break; |
| 1462 | v_opp = dev_pm_opp_get_voltage(opp); | 1463 | v_opp = dev_pm_opp_get_voltage(opp); |
| 1463 | 1464 | ||
| 1464 | if (v_opp <= td->soc->min_millivolts * 1000) | 1465 | if (v_opp <= td->soc->cvb->min_millivolts * 1000) |
| 1465 | td->dvco_rate_min = dev_pm_opp_get_freq(opp); | 1466 | td->dvco_rate_min = dev_pm_opp_get_freq(opp); |
| 1466 | 1467 | ||
| 1467 | for (;;) { | 1468 | for (;;) { |
| @@ -1490,7 +1491,7 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td) | |||
| 1490 | 1491 | ||
| 1491 | if (!td->dvco_rate_min) | 1492 | if (!td->dvco_rate_min) |
| 1492 | dev_err(td->dev, "no opp above DFLL minimum voltage %d mV\n", | 1493 | dev_err(td->dev, "no opp above DFLL minimum voltage %d mV\n", |
| 1493 | td->soc->min_millivolts); | 1494 | td->soc->cvb->min_millivolts); |
| 1494 | else | 1495 | else |
| 1495 | ret = 0; | 1496 | ret = 0; |
| 1496 | 1497 | ||
diff --git a/drivers/clk/tegra/clk-dfll.h b/drivers/clk/tegra/clk-dfll.h index 2e4c0772a5dc..ed2ad888268f 100644 --- a/drivers/clk/tegra/clk-dfll.h +++ b/drivers/clk/tegra/clk-dfll.h | |||
| @@ -24,22 +24,18 @@ | |||
| 24 | 24 | ||
| 25 | /** | 25 | /** |
| 26 | * struct tegra_dfll_soc_data - SoC-specific hooks/integration for the DFLL driver | 26 | * struct tegra_dfll_soc_data - SoC-specific hooks/integration for the DFLL driver |
| 27 | * @opp_dev: struct device * that holds the OPP table for the DFLL | 27 | * @dev: struct device * that holds the OPP table for the DFLL |
| 28 | * @min_millivolts: minimum voltage (in mV) that the DFLL can operate | 28 | * @max_freq: maximum frequency supported on this SoC |
| 29 | * @tune0_low: DFLL tuning register 0 (low voltage range) | 29 | * @cvb: CPU frequency table for this SoC |
| 30 | * @tune0_high: DFLL tuning register 0 (high voltage range) | 30 | * @init_clock_trimmers: callback to initialize clock trimmers |
| 31 | * @tune1: DFLL tuning register 1 | 31 | * @set_clock_trimmers_high: callback to tune clock trimmers for high voltage |
| 32 | * @assert_dvco_reset: fn ptr to place the DVCO in reset | 32 | * @set_clock_trimmers_low: callback to tune clock trimmers for low voltage |
| 33 | * @deassert_dvco_reset: fn ptr to release the DVCO reset | ||
| 34 | * @set_clock_trimmers_high: fn ptr to tune clock trimmers for high voltage | ||
| 35 | * @set_clock_trimmers_low: fn ptr to tune clock trimmers for low voltage | ||
| 36 | */ | 33 | */ |
| 37 | struct tegra_dfll_soc_data { | 34 | struct tegra_dfll_soc_data { |
| 38 | struct device *dev; | 35 | struct device *dev; |
| 39 | unsigned int min_millivolts; | 36 | unsigned long max_freq; |
| 40 | u32 tune0_low; | 37 | const struct cvb_table *cvb; |
| 41 | u32 tune0_high; | 38 | |
| 42 | u32 tune1; | ||
| 43 | void (*init_clock_trimmers)(void); | 39 | void (*init_clock_trimmers)(void); |
| 44 | void (*set_clock_trimmers_high)(void); | 40 | void (*set_clock_trimmers_high)(void); |
| 45 | void (*set_clock_trimmers_low)(void); | 41 | void (*set_clock_trimmers_low)(void); |
diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h index 62ea38187b71..36c974916d4f 100644 --- a/drivers/clk/tegra/clk-id.h +++ b/drivers/clk/tegra/clk-id.h | |||
| @@ -71,6 +71,7 @@ enum clk_id { | |||
| 71 | tegra_clk_disp2_8, | 71 | tegra_clk_disp2_8, |
| 72 | tegra_clk_dp2, | 72 | tegra_clk_dp2, |
| 73 | tegra_clk_dpaux, | 73 | tegra_clk_dpaux, |
| 74 | tegra_clk_dpaux1, | ||
| 74 | tegra_clk_dsialp, | 75 | tegra_clk_dsialp, |
| 75 | tegra_clk_dsia_mux, | 76 | tegra_clk_dsia_mux, |
| 76 | tegra_clk_dsiblp, | 77 | tegra_clk_dsiblp, |
| @@ -306,6 +307,7 @@ enum clk_id { | |||
| 306 | tegra_clk_xusb_ss_div2, | 307 | tegra_clk_xusb_ss_div2, |
| 307 | tegra_clk_xusb_ssp_src, | 308 | tegra_clk_xusb_ssp_src, |
| 308 | tegra_clk_sclk_mux, | 309 | tegra_clk_sclk_mux, |
| 310 | tegra_clk_sor_safe, | ||
| 309 | tegra_clk_max, | 311 | tegra_clk_max, |
| 310 | }; | 312 | }; |
| 311 | 313 | ||
diff --git a/drivers/clk/tegra/clk-periph-fixed.c b/drivers/clk/tegra/clk-periph-fixed.c new file mode 100644 index 000000000000..c57dfb037b10 --- /dev/null +++ b/drivers/clk/tegra/clk-periph-fixed.c | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/clk-provider.h> | ||
| 18 | |||
| 19 | #include "clk.h" | ||
| 20 | |||
| 21 | static inline struct tegra_clk_periph_fixed * | ||
| 22 | to_tegra_clk_periph_fixed(struct clk_hw *hw) | ||
| 23 | { | ||
| 24 | return container_of(hw, struct tegra_clk_periph_fixed, hw); | ||
| 25 | } | ||
| 26 | |||
| 27 | static int tegra_clk_periph_fixed_is_enabled(struct clk_hw *hw) | ||
| 28 | { | ||
| 29 | struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw); | ||
| 30 | u32 mask = 1 << (fixed->num % 32), value; | ||
| 31 | |||
| 32 | value = readl(fixed->base + fixed->regs->enb_reg); | ||
| 33 | if (value & mask) { | ||
| 34 | value = readl(fixed->base + fixed->regs->rst_reg); | ||
| 35 | if ((value & mask) == 0) | ||
| 36 | return 1; | ||
| 37 | } | ||
| 38 | |||
| 39 | return 0; | ||
| 40 | } | ||
| 41 | |||
| 42 | static int tegra_clk_periph_fixed_enable(struct clk_hw *hw) | ||
| 43 | { | ||
| 44 | struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw); | ||
| 45 | u32 mask = 1 << (fixed->num % 32); | ||
| 46 | |||
| 47 | writel(mask, fixed->base + fixed->regs->enb_set_reg); | ||
| 48 | |||
| 49 | return 0; | ||
| 50 | } | ||
| 51 | |||
| 52 | static void tegra_clk_periph_fixed_disable(struct clk_hw *hw) | ||
| 53 | { | ||
| 54 | struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw); | ||
| 55 | u32 mask = 1 << (fixed->num % 32); | ||
| 56 | |||
| 57 | writel(mask, fixed->base + fixed->regs->enb_clr_reg); | ||
| 58 | } | ||
| 59 | |||
| 60 | static unsigned long | ||
| 61 | tegra_clk_periph_fixed_recalc_rate(struct clk_hw *hw, | ||
| 62 | unsigned long parent_rate) | ||
| 63 | { | ||
| 64 | struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw); | ||
| 65 | unsigned long long rate; | ||
| 66 | |||
| 67 | rate = (unsigned long long)parent_rate * fixed->mul; | ||
| 68 | do_div(rate, fixed->div); | ||
| 69 | |||
| 70 | return (unsigned long)rate; | ||
| 71 | } | ||
| 72 | |||
| 73 | static const struct clk_ops tegra_clk_periph_fixed_ops = { | ||
| 74 | .is_enabled = tegra_clk_periph_fixed_is_enabled, | ||
| 75 | .enable = tegra_clk_periph_fixed_enable, | ||
| 76 | .disable = tegra_clk_periph_fixed_disable, | ||
| 77 | .recalc_rate = tegra_clk_periph_fixed_recalc_rate, | ||
| 78 | }; | ||
| 79 | |||
| 80 | struct clk *tegra_clk_register_periph_fixed(const char *name, | ||
| 81 | const char *parent, | ||
| 82 | unsigned long flags, | ||
| 83 | void __iomem *base, | ||
| 84 | unsigned int mul, | ||
| 85 | unsigned int div, | ||
| 86 | unsigned int num) | ||
| 87 | { | ||
| 88 | const struct tegra_clk_periph_regs *regs; | ||
| 89 | struct tegra_clk_periph_fixed *fixed; | ||
| 90 | struct clk_init_data init; | ||
| 91 | struct clk *clk; | ||
| 92 | |||
| 93 | regs = get_reg_bank(num); | ||
| 94 | if (!regs) | ||
| 95 | return ERR_PTR(-EINVAL); | ||
| 96 | |||
| 97 | fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); | ||
| 98 | if (!fixed) | ||
| 99 | return ERR_PTR(-ENOMEM); | ||
| 100 | |||
| 101 | init.name = name; | ||
| 102 | init.flags = flags; | ||
| 103 | init.parent_names = parent ? &parent : NULL; | ||
| 104 | init.num_parents = parent ? 1 : 0; | ||
| 105 | init.ops = &tegra_clk_periph_fixed_ops; | ||
| 106 | |||
| 107 | fixed->base = base; | ||
| 108 | fixed->regs = regs; | ||
| 109 | fixed->mul = mul; | ||
| 110 | fixed->div = div; | ||
| 111 | fixed->num = num; | ||
| 112 | |||
| 113 | fixed->hw.init = &init; | ||
| 114 | |||
| 115 | clk = clk_register(NULL, &fixed->hw); | ||
| 116 | if (IS_ERR(clk)) | ||
| 117 | kfree(fixed); | ||
| 118 | |||
| 119 | return clk; | ||
| 120 | } | ||
diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c index d28d6e95020f..88127828befe 100644 --- a/drivers/clk/tegra/clk-periph-gate.c +++ b/drivers/clk/tegra/clk-periph-gate.c | |||
| @@ -134,7 +134,7 @@ struct clk *tegra_clk_register_periph_gate(const char *name, | |||
| 134 | struct tegra_clk_periph_gate *gate; | 134 | struct tegra_clk_periph_gate *gate; |
| 135 | struct clk *clk; | 135 | struct clk *clk; |
| 136 | struct clk_init_data init; | 136 | struct clk_init_data init; |
| 137 | struct tegra_clk_periph_regs *pregs; | 137 | const struct tegra_clk_periph_regs *pregs; |
| 138 | 138 | ||
| 139 | pregs = get_reg_bank(clk_num); | 139 | pregs = get_reg_bank(clk_num); |
| 140 | if (!pregs) | 140 | if (!pregs) |
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index ec5b6113b012..a17ca6d7f649 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c | |||
| @@ -145,7 +145,7 @@ static struct clk *_tegra_clk_register_periph(const char *name, | |||
| 145 | { | 145 | { |
| 146 | struct clk *clk; | 146 | struct clk *clk; |
| 147 | struct clk_init_data init; | 147 | struct clk_init_data init; |
| 148 | struct tegra_clk_periph_regs *bank; | 148 | const struct tegra_clk_periph_regs *bank; |
| 149 | bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV); | 149 | bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV); |
| 150 | 150 | ||
| 151 | if (periph->gate.flags & TEGRA_PERIPH_NO_DIV) { | 151 | if (periph->gate.flags & TEGRA_PERIPH_NO_DIV) { |
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 6ac3f843e7ca..4e194ecc8d5e 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c | |||
| @@ -2013,6 +2013,52 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, | |||
| 2013 | #endif | 2013 | #endif |
| 2014 | 2014 | ||
| 2015 | #if defined(CONFIG_ARCH_TEGRA_210_SOC) | 2015 | #if defined(CONFIG_ARCH_TEGRA_210_SOC) |
| 2016 | struct clk *tegra_clk_register_pllre_tegra210(const char *name, | ||
| 2017 | const char *parent_name, void __iomem *clk_base, | ||
| 2018 | void __iomem *pmc, unsigned long flags, | ||
| 2019 | struct tegra_clk_pll_params *pll_params, | ||
| 2020 | spinlock_t *lock, unsigned long parent_rate) | ||
| 2021 | { | ||
| 2022 | u32 val; | ||
| 2023 | struct tegra_clk_pll *pll; | ||
| 2024 | struct clk *clk; | ||
| 2025 | |||
| 2026 | pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); | ||
| 2027 | |||
| 2028 | if (pll_params->adjust_vco) | ||
| 2029 | pll_params->vco_min = pll_params->adjust_vco(pll_params, | ||
| 2030 | parent_rate); | ||
| 2031 | |||
| 2032 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); | ||
| 2033 | if (IS_ERR(pll)) | ||
| 2034 | return ERR_CAST(pll); | ||
| 2035 | |||
| 2036 | /* program minimum rate by default */ | ||
| 2037 | |||
| 2038 | val = pll_readl_base(pll); | ||
| 2039 | if (val & PLL_BASE_ENABLE) | ||
| 2040 | WARN_ON(readl_relaxed(clk_base + pll_params->iddq_reg) & | ||
| 2041 | BIT(pll_params->iddq_bit_idx)); | ||
| 2042 | else { | ||
| 2043 | val = 0x4 << divm_shift(pll); | ||
| 2044 | val |= 0x41 << divn_shift(pll); | ||
| 2045 | pll_writel_base(val, pll); | ||
| 2046 | } | ||
| 2047 | |||
| 2048 | /* disable lock override */ | ||
| 2049 | |||
| 2050 | val = pll_readl_misc(pll); | ||
| 2051 | val &= ~BIT(29); | ||
| 2052 | pll_writel_misc(val, pll); | ||
| 2053 | |||
| 2054 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, | ||
| 2055 | &tegra_clk_pllre_ops); | ||
| 2056 | if (IS_ERR(clk)) | ||
| 2057 | kfree(pll); | ||
| 2058 | |||
| 2059 | return clk; | ||
| 2060 | } | ||
| 2061 | |||
| 2016 | static int clk_plle_tegra210_enable(struct clk_hw *hw) | 2062 | static int clk_plle_tegra210_enable(struct clk_hw *hw) |
| 2017 | { | 2063 | { |
| 2018 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 2064 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c index d64ec7a1b976..91c38f1666c1 100644 --- a/drivers/clk/tegra/clk-tegra-fixed.c +++ b/drivers/clk/tegra/clk-tegra-fixed.c | |||
| @@ -107,4 +107,3 @@ void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks) | |||
| 107 | *dt_clk = clk; | 107 | *dt_clk = clk; |
| 108 | } | 108 | } |
| 109 | } | 109 | } |
| 110 | |||
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index ea2b9cbf9e70..29d04c663abf 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c | |||
| @@ -803,7 +803,7 @@ static struct tegra_periph_init_data gate_clks[] = { | |||
| 803 | GATE("hda2hdmi", "clk_m", 128, TEGRA_PERIPH_ON_APB, tegra_clk_hda2hdmi, 0), | 803 | GATE("hda2hdmi", "clk_m", 128, TEGRA_PERIPH_ON_APB, tegra_clk_hda2hdmi, 0), |
| 804 | GATE("bsea", "clk_m", 62, 0, tegra_clk_bsea, 0), | 804 | GATE("bsea", "clk_m", 62, 0, tegra_clk_bsea, 0), |
| 805 | GATE("bsev", "clk_m", 63, 0, tegra_clk_bsev, 0), | 805 | GATE("bsev", "clk_m", 63, 0, tegra_clk_bsev, 0), |
| 806 | GATE("mipi-cal", "clk_m", 56, 0, tegra_clk_mipi_cal, 0), | 806 | GATE("mipi-cal", "clk72mhz", 56, 0, tegra_clk_mipi_cal, 0), |
| 807 | GATE("usbd", "clk_m", 22, 0, tegra_clk_usbd, 0), | 807 | GATE("usbd", "clk_m", 22, 0, tegra_clk_usbd, 0), |
| 808 | GATE("usb2", "clk_m", 58, 0, tegra_clk_usb2, 0), | 808 | GATE("usb2", "clk_m", 58, 0, tegra_clk_usb2, 0), |
| 809 | GATE("usb3", "clk_m", 59, 0, tegra_clk_usb3, 0), | 809 | GATE("usb3", "clk_m", 59, 0, tegra_clk_usb3, 0), |
| @@ -821,7 +821,6 @@ static struct tegra_periph_init_data gate_clks[] = { | |||
| 821 | GATE("ispb", "clk_m", 3, 0, tegra_clk_ispb, 0), | 821 | GATE("ispb", "clk_m", 3, 0, tegra_clk_ispb, 0), |
| 822 | GATE("vim2_clk", "clk_m", 11, 0, tegra_clk_vim2_clk, 0), | 822 | GATE("vim2_clk", "clk_m", 11, 0, tegra_clk_vim2_clk, 0), |
| 823 | GATE("pcie", "clk_m", 70, 0, tegra_clk_pcie, 0), | 823 | GATE("pcie", "clk_m", 70, 0, tegra_clk_pcie, 0), |
| 824 | GATE("dpaux", "clk_m", 181, 0, tegra_clk_dpaux, 0), | ||
| 825 | GATE("gpu", "pll_ref", 184, 0, tegra_clk_gpu, 0), | 824 | GATE("gpu", "pll_ref", 184, 0, tegra_clk_gpu, 0), |
| 826 | GATE("pllg_ref", "pll_ref", 189, 0, tegra_clk_pll_g_ref, 0), | 825 | GATE("pllg_ref", "pll_ref", 189, 0, tegra_clk_pll_g_ref, 0), |
| 827 | GATE("hsic_trk", "usb2_hsic_trk", 209, TEGRA_PERIPH_NO_RESET, tegra_clk_hsic_trk, 0), | 826 | GATE("hsic_trk", "usb2_hsic_trk", 209, TEGRA_PERIPH_NO_RESET, tegra_clk_hsic_trk, 0), |
| @@ -877,7 +876,7 @@ static void __init periph_clk_init(void __iomem *clk_base, | |||
| 877 | struct clk **dt_clk; | 876 | struct clk **dt_clk; |
| 878 | 877 | ||
| 879 | for (i = 0; i < ARRAY_SIZE(periph_clks); i++) { | 878 | for (i = 0; i < ARRAY_SIZE(periph_clks); i++) { |
| 880 | struct tegra_clk_periph_regs *bank; | 879 | const struct tegra_clk_periph_regs *bank; |
| 881 | struct tegra_periph_init_data *data; | 880 | struct tegra_periph_init_data *data; |
| 882 | 881 | ||
| 883 | data = periph_clks + i; | 882 | data = periph_clks + i; |
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index df47ec3169c3..b78054fac0a8 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c | |||
| @@ -743,7 +743,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = { | |||
| 743 | [tegra_clk_csi] = { .dt_id = TEGRA114_CLK_CSI, .present = true }, | 743 | [tegra_clk_csi] = { .dt_id = TEGRA114_CLK_CSI, .present = true }, |
| 744 | [tegra_clk_i2c2] = { .dt_id = TEGRA114_CLK_I2C2, .present = true }, | 744 | [tegra_clk_i2c2] = { .dt_id = TEGRA114_CLK_I2C2, .present = true }, |
| 745 | [tegra_clk_uartc] = { .dt_id = TEGRA114_CLK_UARTC, .present = true }, | 745 | [tegra_clk_uartc] = { .dt_id = TEGRA114_CLK_UARTC, .present = true }, |
| 746 | [tegra_clk_mipi_cal] = { .dt_id = TEGRA114_CLK_MIPI_CAL, .present = true }, | ||
| 747 | [tegra_clk_emc] = { .dt_id = TEGRA114_CLK_EMC, .present = true }, | 746 | [tegra_clk_emc] = { .dt_id = TEGRA114_CLK_EMC, .present = true }, |
| 748 | [tegra_clk_usb2] = { .dt_id = TEGRA114_CLK_USB2, .present = true }, | 747 | [tegra_clk_usb2] = { .dt_id = TEGRA114_CLK_USB2, .present = true }, |
| 749 | [tegra_clk_usb3] = { .dt_id = TEGRA114_CLK_USB3, .present = true }, | 748 | [tegra_clk_usb3] = { .dt_id = TEGRA114_CLK_USB3, .present = true }, |
| @@ -1237,6 +1236,11 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base, | |||
| 1237 | &emc_lock); | 1236 | &emc_lock); |
| 1238 | clks[TEGRA114_CLK_MC] = clk; | 1237 | clks[TEGRA114_CLK_MC] = clk; |
| 1239 | 1238 | ||
| 1239 | clk = tegra_clk_register_periph_gate("mipi-cal", "clk_m", 0, clk_base, | ||
| 1240 | CLK_SET_RATE_PARENT, 56, | ||
| 1241 | periph_clk_enb_refcnt); | ||
| 1242 | clks[TEGRA114_CLK_MIPI_CAL] = clk; | ||
| 1243 | |||
| 1240 | for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { | 1244 | for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { |
| 1241 | data = &tegra_periph_clk_list[i]; | 1245 | data = &tegra_periph_clk_list[i]; |
| 1242 | clk = tegra_clk_register_periph(data->name, | 1246 | clk = tegra_clk_register_periph(data->name, |
diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c index 61253330c12b..c205809ba580 100644 --- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c +++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c | |||
| @@ -47,32 +47,32 @@ static const struct cvb_table tegra124_cpu_cvb_tables[] = { | |||
| 47 | }, | 47 | }, |
| 48 | .speedo_scale = 100, | 48 | .speedo_scale = 100, |
| 49 | .voltage_scale = 1000, | 49 | .voltage_scale = 1000, |
| 50 | .cvb_table = { | 50 | .entries = { |
| 51 | {204000000UL, {1112619, -29295, 402} }, | 51 | { 204000000UL, { 1112619, -29295, 402 } }, |
| 52 | {306000000UL, {1150460, -30585, 402} }, | 52 | { 306000000UL, { 1150460, -30585, 402 } }, |
| 53 | {408000000UL, {1190122, -31865, 402} }, | 53 | { 408000000UL, { 1190122, -31865, 402 } }, |
| 54 | {510000000UL, {1231606, -33155, 402} }, | 54 | { 510000000UL, { 1231606, -33155, 402 } }, |
| 55 | {612000000UL, {1274912, -34435, 402} }, | 55 | { 612000000UL, { 1274912, -34435, 402 } }, |
| 56 | {714000000UL, {1320040, -35725, 402} }, | 56 | { 714000000UL, { 1320040, -35725, 402 } }, |
| 57 | {816000000UL, {1366990, -37005, 402} }, | 57 | { 816000000UL, { 1366990, -37005, 402 } }, |
| 58 | {918000000UL, {1415762, -38295, 402} }, | 58 | { 918000000UL, { 1415762, -38295, 402 } }, |
| 59 | {1020000000UL, {1466355, -39575, 402} }, | 59 | { 1020000000UL, { 1466355, -39575, 402 } }, |
| 60 | {1122000000UL, {1518771, -40865, 402} }, | 60 | { 1122000000UL, { 1518771, -40865, 402 } }, |
| 61 | {1224000000UL, {1573009, -42145, 402} }, | 61 | { 1224000000UL, { 1573009, -42145, 402 } }, |
| 62 | {1326000000UL, {1629068, -43435, 402} }, | 62 | { 1326000000UL, { 1629068, -43435, 402 } }, |
| 63 | {1428000000UL, {1686950, -44715, 402} }, | 63 | { 1428000000UL, { 1686950, -44715, 402 } }, |
| 64 | {1530000000UL, {1746653, -46005, 402} }, | 64 | { 1530000000UL, { 1746653, -46005, 402 } }, |
| 65 | {1632000000UL, {1808179, -47285, 402} }, | 65 | { 1632000000UL, { 1808179, -47285, 402 } }, |
| 66 | {1734000000UL, {1871526, -48575, 402} }, | 66 | { 1734000000UL, { 1871526, -48575, 402 } }, |
| 67 | {1836000000UL, {1936696, -49855, 402} }, | 67 | { 1836000000UL, { 1936696, -49855, 402 } }, |
| 68 | {1938000000UL, {2003687, -51145, 402} }, | 68 | { 1938000000UL, { 2003687, -51145, 402 } }, |
| 69 | {2014500000UL, {2054787, -52095, 402} }, | 69 | { 2014500000UL, { 2054787, -52095, 402 } }, |
| 70 | {2116500000UL, {2124957, -53385, 402} }, | 70 | { 2116500000UL, { 2124957, -53385, 402 } }, |
| 71 | {2218500000UL, {2196950, -54665, 402} }, | 71 | { 2218500000UL, { 2196950, -54665, 402 } }, |
| 72 | {2320500000UL, {2270765, -55955, 402} }, | 72 | { 2320500000UL, { 2270765, -55955, 402 } }, |
| 73 | {2422500000UL, {2346401, -57235, 402} }, | 73 | { 2422500000UL, { 2346401, -57235, 402 } }, |
| 74 | {2524500000UL, {2437299, -58535, 402} }, | 74 | { 2524500000UL, { 2437299, -58535, 402 } }, |
| 75 | {0, { 0, 0, 0} }, | 75 | { 0UL, { 0, 0, 0 } }, |
| 76 | }, | 76 | }, |
| 77 | .cpu_dfll_data = { | 77 | .cpu_dfll_data = { |
| 78 | .tune0_low = 0x005020ff, | 78 | .tune0_low = 0x005020ff, |
| @@ -84,9 +84,8 @@ static const struct cvb_table tegra124_cpu_cvb_tables[] = { | |||
| 84 | 84 | ||
| 85 | static int tegra124_dfll_fcpu_probe(struct platform_device *pdev) | 85 | static int tegra124_dfll_fcpu_probe(struct platform_device *pdev) |
| 86 | { | 86 | { |
| 87 | int process_id, speedo_id, speedo_value; | 87 | int process_id, speedo_id, speedo_value, err; |
| 88 | struct tegra_dfll_soc_data *soc; | 88 | struct tegra_dfll_soc_data *soc; |
| 89 | const struct cvb_table *cvb; | ||
| 90 | 89 | ||
| 91 | process_id = tegra_sku_info.cpu_process_id; | 90 | process_id = tegra_sku_info.cpu_process_id; |
| 92 | speedo_id = tegra_sku_info.cpu_speedo_id; | 91 | speedo_id = tegra_sku_info.cpu_speedo_id; |
| @@ -108,23 +107,41 @@ static int tegra124_dfll_fcpu_probe(struct platform_device *pdev) | |||
| 108 | return -ENODEV; | 107 | return -ENODEV; |
| 109 | } | 108 | } |
| 110 | 109 | ||
| 111 | cvb = tegra_cvb_build_opp_table(tegra124_cpu_cvb_tables, | 110 | soc->max_freq = cpu_max_freq_table[speedo_id]; |
| 112 | ARRAY_SIZE(tegra124_cpu_cvb_tables), | 111 | |
| 113 | process_id, speedo_id, speedo_value, | 112 | soc->cvb = tegra_cvb_add_opp_table(soc->dev, tegra124_cpu_cvb_tables, |
| 114 | cpu_max_freq_table[speedo_id], | 113 | ARRAY_SIZE(tegra124_cpu_cvb_tables), |
| 115 | soc->dev); | 114 | process_id, speedo_id, speedo_value, |
| 116 | if (IS_ERR(cvb)) { | 115 | soc->max_freq); |
| 117 | dev_err(&pdev->dev, "couldn't build OPP table: %ld\n", | 116 | if (IS_ERR(soc->cvb)) { |
| 118 | PTR_ERR(cvb)); | 117 | dev_err(&pdev->dev, "couldn't add OPP table: %ld\n", |
| 119 | return PTR_ERR(cvb); | 118 | PTR_ERR(soc->cvb)); |
| 119 | return PTR_ERR(soc->cvb); | ||
| 120 | } | ||
| 121 | |||
| 122 | err = tegra_dfll_register(pdev, soc); | ||
| 123 | if (err < 0) { | ||
| 124 | tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq); | ||
| 125 | return err; | ||
| 120 | } | 126 | } |
| 121 | 127 | ||
| 122 | soc->min_millivolts = cvb->min_millivolts; | 128 | platform_set_drvdata(pdev, soc); |
| 123 | soc->tune0_low = cvb->cpu_dfll_data.tune0_low; | 129 | |
| 124 | soc->tune0_high = cvb->cpu_dfll_data.tune0_high; | 130 | return 0; |
| 125 | soc->tune1 = cvb->cpu_dfll_data.tune1; | 131 | } |
| 132 | |||
| 133 | static int tegra124_dfll_fcpu_remove(struct platform_device *pdev) | ||
| 134 | { | ||
| 135 | struct tegra_dfll_soc_data *soc = platform_get_drvdata(pdev); | ||
| 136 | int err; | ||
| 137 | |||
| 138 | err = tegra_dfll_unregister(pdev); | ||
| 139 | if (err < 0) | ||
| 140 | dev_err(&pdev->dev, "failed to unregister DFLL: %d\n", err); | ||
| 141 | |||
| 142 | tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq); | ||
| 126 | 143 | ||
| 127 | return tegra_dfll_register(pdev, soc); | 144 | return 0; |
| 128 | } | 145 | } |
| 129 | 146 | ||
| 130 | static const struct of_device_id tegra124_dfll_fcpu_of_match[] = { | 147 | static const struct of_device_id tegra124_dfll_fcpu_of_match[] = { |
| @@ -140,7 +157,7 @@ static const struct dev_pm_ops tegra124_dfll_pm_ops = { | |||
| 140 | 157 | ||
| 141 | static struct platform_driver tegra124_dfll_fcpu_driver = { | 158 | static struct platform_driver tegra124_dfll_fcpu_driver = { |
| 142 | .probe = tegra124_dfll_fcpu_probe, | 159 | .probe = tegra124_dfll_fcpu_probe, |
| 143 | .remove = tegra_dfll_unregister, | 160 | .remove = tegra124_dfll_fcpu_remove, |
| 144 | .driver = { | 161 | .driver = { |
| 145 | .name = "tegra124-dfll", | 162 | .name = "tegra124-dfll", |
| 146 | .of_match_table = tegra124_dfll_fcpu_of_match, | 163 | .of_match_table = tegra124_dfll_fcpu_of_match, |
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 1627258292d2..f4fbbf16a056 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c | |||
| @@ -1155,6 +1155,10 @@ static __init void tegra124_periph_clk_init(void __iomem *clk_base, | |||
| 1155 | 1, 2); | 1155 | 1, 2); |
| 1156 | clks[TEGRA124_CLK_XUSB_SS_DIV2] = clk; | 1156 | clks[TEGRA124_CLK_XUSB_SS_DIV2] = clk; |
| 1157 | 1157 | ||
| 1158 | clk = tegra_clk_register_periph_fixed("dpaux", "pll_p", 0, clk_base, | ||
| 1159 | 1, 17, 181); | ||
| 1160 | clks[TEGRA124_CLK_DPAUX] = clk; | ||
| 1161 | |||
| 1158 | clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0, | 1162 | clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0, |
| 1159 | clk_base + PLLD_MISC, 30, 0, &pll_d_lock); | 1163 | clk_base + PLLD_MISC, 30, 0, &pll_d_lock); |
| 1160 | clks[TEGRA124_CLK_PLL_D_DSI_OUT] = clk; | 1164 | clks[TEGRA124_CLK_PLL_D_DSI_OUT] = clk; |
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 3d0edee1f9fe..b8551813ec43 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c | |||
| @@ -92,6 +92,7 @@ | |||
| 92 | #define PLLE_AUX 0x48c | 92 | #define PLLE_AUX 0x48c |
| 93 | #define PLLRE_BASE 0x4c4 | 93 | #define PLLRE_BASE 0x4c4 |
| 94 | #define PLLRE_MISC0 0x4c8 | 94 | #define PLLRE_MISC0 0x4c8 |
| 95 | #define PLLRE_OUT1 0x4cc | ||
| 95 | #define PLLDP_BASE 0x590 | 96 | #define PLLDP_BASE 0x590 |
| 96 | #define PLLDP_MISC 0x594 | 97 | #define PLLDP_MISC 0x594 |
| 97 | 98 | ||
| @@ -2150,6 +2151,7 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { | |||
| 2150 | [tegra_clk_clk72Mhz_8] = { .dt_id = TEGRA210_CLK_CLK72MHZ, .present = true }, | 2151 | [tegra_clk_clk72Mhz_8] = { .dt_id = TEGRA210_CLK_CLK72MHZ, .present = true }, |
| 2151 | [tegra_clk_vic03_8] = { .dt_id = TEGRA210_CLK_VIC03, .present = true }, | 2152 | [tegra_clk_vic03_8] = { .dt_id = TEGRA210_CLK_VIC03, .present = true }, |
| 2152 | [tegra_clk_dpaux] = { .dt_id = TEGRA210_CLK_DPAUX, .present = true }, | 2153 | [tegra_clk_dpaux] = { .dt_id = TEGRA210_CLK_DPAUX, .present = true }, |
| 2154 | [tegra_clk_dpaux1] = { .dt_id = TEGRA210_CLK_DPAUX1, .present = true }, | ||
| 2153 | [tegra_clk_sor0] = { .dt_id = TEGRA210_CLK_SOR0, .present = true }, | 2155 | [tegra_clk_sor0] = { .dt_id = TEGRA210_CLK_SOR0, .present = true }, |
| 2154 | [tegra_clk_sor0_lvds] = { .dt_id = TEGRA210_CLK_SOR0_LVDS, .present = true }, | 2156 | [tegra_clk_sor0_lvds] = { .dt_id = TEGRA210_CLK_SOR0_LVDS, .present = true }, |
| 2155 | [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, | 2157 | [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, |
| @@ -2461,6 +2463,18 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base, | |||
| 2461 | 1, 2); | 2463 | 1, 2); |
| 2462 | clks[TEGRA210_CLK_XUSB_SS_DIV2] = clk; | 2464 | clks[TEGRA210_CLK_XUSB_SS_DIV2] = clk; |
| 2463 | 2465 | ||
| 2466 | clk = tegra_clk_register_periph_fixed("dpaux", "pll_p", 0, clk_base, | ||
| 2467 | 1, 17, 181); | ||
| 2468 | clks[TEGRA210_CLK_DPAUX] = clk; | ||
| 2469 | |||
| 2470 | clk = tegra_clk_register_periph_fixed("dpaux1", "pll_p", 0, clk_base, | ||
| 2471 | 1, 17, 207); | ||
| 2472 | clks[TEGRA210_CLK_DPAUX1] = clk; | ||
| 2473 | |||
| 2474 | clk = tegra_clk_register_periph_fixed("sor_safe", "pll_p", 0, clk_base, | ||
| 2475 | 1, 17, 222); | ||
| 2476 | clks[TEGRA210_CLK_SOR_SAFE] = clk; | ||
| 2477 | |||
| 2464 | /* pll_d_dsi_out */ | 2478 | /* pll_d_dsi_out */ |
| 2465 | clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0, | 2479 | clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0, |
| 2466 | clk_base + PLLD_MISC0, 21, 0, &pll_d_lock); | 2480 | clk_base + PLLD_MISC0, 21, 0, &pll_d_lock); |
| @@ -2640,8 +2654,10 @@ static void __init tegra210_pll_init(void __iomem *clk_base, | |||
| 2640 | clks[TEGRA210_CLK_PLL_D_OUT0] = clk; | 2654 | clks[TEGRA210_CLK_PLL_D_OUT0] = clk; |
| 2641 | 2655 | ||
| 2642 | /* PLLRE */ | 2656 | /* PLLRE */ |
| 2643 | clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, | 2657 | clk = tegra_clk_register_pllre_tegra210("pll_re_vco", "pll_ref", |
| 2644 | 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); | 2658 | clk_base, pmc, 0, |
| 2659 | &pll_re_vco_params, | ||
| 2660 | &pll_re_lock, pll_ref_freq); | ||
| 2645 | clk_register_clkdev(clk, "pll_re_vco", NULL); | 2661 | clk_register_clkdev(clk, "pll_re_vco", NULL); |
| 2646 | clks[TEGRA210_CLK_PLL_RE_VCO] = clk; | 2662 | clks[TEGRA210_CLK_PLL_RE_VCO] = clk; |
| 2647 | 2663 | ||
| @@ -2651,6 +2667,15 @@ static void __init tegra210_pll_init(void __iomem *clk_base, | |||
| 2651 | clk_register_clkdev(clk, "pll_re_out", NULL); | 2667 | clk_register_clkdev(clk, "pll_re_out", NULL); |
| 2652 | clks[TEGRA210_CLK_PLL_RE_OUT] = clk; | 2668 | clks[TEGRA210_CLK_PLL_RE_OUT] = clk; |
| 2653 | 2669 | ||
| 2670 | clk = tegra_clk_register_divider("pll_re_out1_div", "pll_re_vco", | ||
| 2671 | clk_base + PLLRE_OUT1, 0, | ||
| 2672 | TEGRA_DIVIDER_ROUND_UP, | ||
| 2673 | 8, 8, 1, NULL); | ||
| 2674 | clk = tegra_clk_register_pll_out("pll_re_out1", "pll_re_out1_div", | ||
| 2675 | clk_base + PLLRE_OUT1, 1, 0, | ||
| 2676 | CLK_SET_RATE_PARENT, 0, NULL); | ||
| 2677 | clks[TEGRA210_CLK_PLL_RE_OUT1] = clk; | ||
| 2678 | |||
| 2654 | /* PLLE */ | 2679 | /* PLLE */ |
| 2655 | clk = tegra_clk_register_plle_tegra210("pll_e", "pll_ref", | 2680 | clk = tegra_clk_register_plle_tegra210("pll_e", "pll_ref", |
| 2656 | clk_base, 0, &pll_e_params, NULL); | 2681 | clk_base, 0, &pll_e_params, NULL); |
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 0478565cf292..9396f4930da7 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c | |||
| @@ -339,11 +339,11 @@ static const struct pdiv_map pllu_p[] = { | |||
| 339 | }; | 339 | }; |
| 340 | 340 | ||
| 341 | static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { | 341 | static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { |
| 342 | { 12000000, 480000000, 960, 12, 1, 12 }, | 342 | { 12000000, 480000000, 960, 12, 2, 12 }, |
| 343 | { 13000000, 480000000, 960, 13, 1, 12 }, | 343 | { 13000000, 480000000, 960, 13, 2, 12 }, |
| 344 | { 16800000, 480000000, 400, 7, 1, 5 }, | 344 | { 16800000, 480000000, 400, 7, 2, 5 }, |
| 345 | { 19200000, 480000000, 200, 4, 1, 3 }, | 345 | { 19200000, 480000000, 200, 4, 2, 3 }, |
| 346 | { 26000000, 480000000, 960, 26, 1, 12 }, | 346 | { 26000000, 480000000, 960, 26, 2, 12 }, |
| 347 | { 0, 0, 0, 0, 0, 0 }, | 347 | { 0, 0, 0, 0, 0, 0 }, |
| 348 | }; | 348 | }; |
| 349 | 349 | ||
| @@ -1372,6 +1372,7 @@ static struct tegra_clk_init_table init_table[] __initdata = { | |||
| 1372 | { TEGRA30_CLK_SBC4, TEGRA30_CLK_PLL_P, 100000000, 0 }, | 1372 | { TEGRA30_CLK_SBC4, TEGRA30_CLK_PLL_P, 100000000, 0 }, |
| 1373 | { TEGRA30_CLK_SBC5, TEGRA30_CLK_PLL_P, 100000000, 0 }, | 1373 | { TEGRA30_CLK_SBC5, TEGRA30_CLK_PLL_P, 100000000, 0 }, |
| 1374 | { TEGRA30_CLK_SBC6, TEGRA30_CLK_PLL_P, 100000000, 0 }, | 1374 | { TEGRA30_CLK_SBC6, TEGRA30_CLK_PLL_P, 100000000, 0 }, |
| 1375 | { TEGRA30_CLK_PLL_C, TEGRA30_CLK_CLK_MAX, 600000000, 0 }, | ||
| 1375 | { TEGRA30_CLK_HOST1X, TEGRA30_CLK_PLL_C, 150000000, 0 }, | 1376 | { TEGRA30_CLK_HOST1X, TEGRA30_CLK_PLL_C, 150000000, 0 }, |
| 1376 | { TEGRA30_CLK_DISP1, TEGRA30_CLK_PLL_P, 600000000, 0 }, | 1377 | { TEGRA30_CLK_DISP1, TEGRA30_CLK_PLL_P, 600000000, 0 }, |
| 1377 | { TEGRA30_CLK_DISP2, TEGRA30_CLK_PLL_P, 600000000, 0 }, | 1378 | { TEGRA30_CLK_DISP2, TEGRA30_CLK_PLL_P, 600000000, 0 }, |
| @@ -1379,6 +1380,7 @@ static struct tegra_clk_init_table init_table[] __initdata = { | |||
| 1379 | { TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0 }, | 1380 | { TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0 }, |
| 1380 | { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 }, | 1381 | { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 }, |
| 1381 | { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 }, | 1382 | { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 }, |
| 1383 | { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 }, | ||
| 1382 | /* must be the last entry */ | 1384 | /* must be the last entry */ |
| 1383 | { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 }, | 1385 | { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 }, |
| 1384 | }; | 1386 | }; |
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index f60fe2e344ca..b2cdd9a235f4 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c | |||
| @@ -84,7 +84,7 @@ static int (*special_reset_assert)(unsigned long); | |||
| 84 | static int (*special_reset_deassert)(unsigned long); | 84 | static int (*special_reset_deassert)(unsigned long); |
| 85 | static unsigned int num_special_reset; | 85 | static unsigned int num_special_reset; |
| 86 | 86 | ||
| 87 | static struct tegra_clk_periph_regs periph_regs[] = { | 87 | static const struct tegra_clk_periph_regs periph_regs[] = { |
| 88 | [0] = { | 88 | [0] = { |
| 89 | .enb_reg = CLK_OUT_ENB_L, | 89 | .enb_reg = CLK_OUT_ENB_L, |
| 90 | .enb_set_reg = CLK_OUT_ENB_SET_L, | 90 | .enb_set_reg = CLK_OUT_ENB_SET_L, |
| @@ -182,7 +182,7 @@ static int tegra_clk_rst_deassert(struct reset_controller_dev *rcdev, | |||
| 182 | return -EINVAL; | 182 | return -EINVAL; |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | struct tegra_clk_periph_regs *get_reg_bank(int clkid) | 185 | const struct tegra_clk_periph_regs *get_reg_bank(int clkid) |
| 186 | { | 186 | { |
| 187 | int reg_bank = clkid / 32; | 187 | int reg_bank = clkid / 32; |
| 188 | 188 | ||
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 4dbcfaec576a..9421f0310999 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h | |||
| @@ -386,6 +386,12 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, | |||
| 386 | struct tegra_clk_pll_params *pll_params, | 386 | struct tegra_clk_pll_params *pll_params, |
| 387 | spinlock_t *lock, unsigned long parent_rate); | 387 | spinlock_t *lock, unsigned long parent_rate); |
| 388 | 388 | ||
| 389 | struct clk *tegra_clk_register_pllre_tegra210(const char *name, | ||
| 390 | const char *parent_name, void __iomem *clk_base, | ||
| 391 | void __iomem *pmc, unsigned long flags, | ||
| 392 | struct tegra_clk_pll_params *pll_params, | ||
| 393 | spinlock_t *lock, unsigned long parent_rate); | ||
| 394 | |||
| 389 | struct clk *tegra_clk_register_plle_tegra114(const char *name, | 395 | struct clk *tegra_clk_register_plle_tegra114(const char *name, |
| 390 | const char *parent_name, | 396 | const char *parent_name, |
| 391 | void __iomem *clk_base, unsigned long flags, | 397 | void __iomem *clk_base, unsigned long flags, |
| @@ -496,7 +502,7 @@ struct tegra_clk_periph_gate { | |||
| 496 | u8 flags; | 502 | u8 flags; |
| 497 | int clk_num; | 503 | int clk_num; |
| 498 | int *enable_refcnt; | 504 | int *enable_refcnt; |
| 499 | struct tegra_clk_periph_regs *regs; | 505 | const struct tegra_clk_periph_regs *regs; |
| 500 | }; | 506 | }; |
| 501 | 507 | ||
| 502 | #define to_clk_periph_gate(_hw) \ | 508 | #define to_clk_periph_gate(_hw) \ |
| @@ -516,6 +522,23 @@ struct clk *tegra_clk_register_periph_gate(const char *name, | |||
| 516 | const char *parent_name, u8 gate_flags, void __iomem *clk_base, | 522 | const char *parent_name, u8 gate_flags, void __iomem *clk_base, |
| 517 | unsigned long flags, int clk_num, int *enable_refcnt); | 523 | unsigned long flags, int clk_num, int *enable_refcnt); |
| 518 | 524 | ||
| 525 | struct tegra_clk_periph_fixed { | ||
| 526 | struct clk_hw hw; | ||
| 527 | void __iomem *base; | ||
| 528 | const struct tegra_clk_periph_regs *regs; | ||
| 529 | unsigned int mul; | ||
| 530 | unsigned int div; | ||
| 531 | unsigned int num; | ||
| 532 | }; | ||
| 533 | |||
| 534 | struct clk *tegra_clk_register_periph_fixed(const char *name, | ||
| 535 | const char *parent, | ||
| 536 | unsigned long flags, | ||
| 537 | void __iomem *base, | ||
| 538 | unsigned int mul, | ||
| 539 | unsigned int div, | ||
| 540 | unsigned int num); | ||
| 541 | |||
| 519 | /** | 542 | /** |
| 520 | * struct clk-periph - peripheral clock | 543 | * struct clk-periph - peripheral clock |
| 521 | * | 544 | * |
| @@ -716,7 +739,7 @@ void tegra_init_from_table(struct tegra_clk_init_table *tbl, | |||
| 716 | void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, | 739 | void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, |
| 717 | struct clk *clks[], int clk_max); | 740 | struct clk *clks[], int clk_max); |
| 718 | 741 | ||
| 719 | struct tegra_clk_periph_regs *get_reg_bank(int clkid); | 742 | const struct tegra_clk_periph_regs *get_reg_bank(int clkid); |
| 720 | struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks); | 743 | struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks); |
| 721 | 744 | ||
| 722 | struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk); | 745 | struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk); |
diff --git a/drivers/clk/tegra/cvb.c b/drivers/clk/tegra/cvb.c index 69c74eec3a4b..624115e82ff9 100644 --- a/drivers/clk/tegra/cvb.c +++ b/drivers/clk/tegra/cvb.c | |||
| @@ -61,29 +61,28 @@ static int round_voltage(int mv, const struct rail_alignment *align, int up) | |||
| 61 | return mv; | 61 | return mv; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static int build_opp_table(const struct cvb_table *d, | 64 | static int build_opp_table(struct device *dev, const struct cvb_table *table, |
| 65 | int speedo_value, | 65 | int speedo_value, unsigned long max_freq) |
| 66 | unsigned long max_freq, | ||
| 67 | struct device *opp_dev) | ||
| 68 | { | 66 | { |
| 67 | const struct rail_alignment *align = &table->alignment; | ||
| 69 | int i, ret, dfll_mv, min_mv, max_mv; | 68 | int i, ret, dfll_mv, min_mv, max_mv; |
| 70 | const struct cvb_table_freq_entry *table = NULL; | ||
| 71 | const struct rail_alignment *align = &d->alignment; | ||
| 72 | 69 | ||
| 73 | min_mv = round_voltage(d->min_millivolts, align, UP); | 70 | min_mv = round_voltage(table->min_millivolts, align, UP); |
| 74 | max_mv = round_voltage(d->max_millivolts, align, DOWN); | 71 | max_mv = round_voltage(table->max_millivolts, align, DOWN); |
| 75 | 72 | ||
| 76 | for (i = 0; i < MAX_DVFS_FREQS; i++) { | 73 | for (i = 0; i < MAX_DVFS_FREQS; i++) { |
| 77 | table = &d->cvb_table[i]; | 74 | const struct cvb_table_freq_entry *entry = &table->entries[i]; |
| 78 | if (!table->freq || (table->freq > max_freq)) | 75 | |
| 76 | if (!entry->freq || (entry->freq > max_freq)) | ||
| 79 | break; | 77 | break; |
| 80 | 78 | ||
| 81 | dfll_mv = get_cvb_voltage( | 79 | dfll_mv = get_cvb_voltage(speedo_value, table->speedo_scale, |
| 82 | speedo_value, d->speedo_scale, &table->coefficients); | 80 | &entry->coefficients); |
| 83 | dfll_mv = round_cvb_voltage(dfll_mv, d->voltage_scale, align); | 81 | dfll_mv = round_cvb_voltage(dfll_mv, table->voltage_scale, |
| 82 | align); | ||
| 84 | dfll_mv = clamp(dfll_mv, min_mv, max_mv); | 83 | dfll_mv = clamp(dfll_mv, min_mv, max_mv); |
| 85 | 84 | ||
| 86 | ret = dev_pm_opp_add(opp_dev, table->freq, dfll_mv * 1000); | 85 | ret = dev_pm_opp_add(dev, entry->freq, dfll_mv * 1000); |
| 87 | if (ret) | 86 | if (ret) |
| 88 | return ret; | 87 | return ret; |
| 89 | } | 88 | } |
| @@ -92,7 +91,7 @@ static int build_opp_table(const struct cvb_table *d, | |||
| 92 | } | 91 | } |
| 93 | 92 | ||
| 94 | /** | 93 | /** |
| 95 | * tegra_cvb_build_opp_table - build OPP table from Tegra CVB tables | 94 | * tegra_cvb_add_opp_table - build OPP table from Tegra CVB tables |
| 96 | * @cvb_tables: array of CVB tables | 95 | * @cvb_tables: array of CVB tables |
| 97 | * @sz: size of the previously mentioned array | 96 | * @sz: size of the previously mentioned array |
| 98 | * @process_id: process id of the HW module | 97 | * @process_id: process id of the HW module |
| @@ -108,26 +107,42 @@ static int build_opp_table(const struct cvb_table *d, | |||
| 108 | * given @opp_dev. Returns a pointer to the struct cvb_table that matched | 107 | * given @opp_dev. Returns a pointer to the struct cvb_table that matched |
| 109 | * or an ERR_PTR on failure. | 108 | * or an ERR_PTR on failure. |
| 110 | */ | 109 | */ |
| 111 | const struct cvb_table *tegra_cvb_build_opp_table( | 110 | const struct cvb_table * |
| 112 | const struct cvb_table *cvb_tables, | 111 | tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *tables, |
| 113 | size_t sz, int process_id, | 112 | size_t count, int process_id, int speedo_id, |
| 114 | int speedo_id, int speedo_value, | 113 | int speedo_value, unsigned long max_freq) |
| 115 | unsigned long max_rate, | ||
| 116 | struct device *opp_dev) | ||
| 117 | { | 114 | { |
| 118 | int i, ret; | 115 | size_t i; |
| 116 | int ret; | ||
| 119 | 117 | ||
| 120 | for (i = 0; i < sz; i++) { | 118 | for (i = 0; i < count; i++) { |
| 121 | const struct cvb_table *d = &cvb_tables[i]; | 119 | const struct cvb_table *table = &tables[i]; |
| 122 | 120 | ||
| 123 | if (d->speedo_id != -1 && d->speedo_id != speedo_id) | 121 | if (table->speedo_id != -1 && table->speedo_id != speedo_id) |
| 124 | continue; | 122 | continue; |
| 125 | if (d->process_id != -1 && d->process_id != process_id) | 123 | |
| 124 | if (table->process_id != -1 && table->process_id != process_id) | ||
| 126 | continue; | 125 | continue; |
| 127 | 126 | ||
| 128 | ret = build_opp_table(d, speedo_value, max_rate, opp_dev); | 127 | ret = build_opp_table(dev, table, speedo_value, max_freq); |
| 129 | return ret ? ERR_PTR(ret) : d; | 128 | return ret ? ERR_PTR(ret) : table; |
| 130 | } | 129 | } |
| 131 | 130 | ||
| 132 | return ERR_PTR(-EINVAL); | 131 | return ERR_PTR(-EINVAL); |
| 133 | } | 132 | } |
| 133 | |||
| 134 | void tegra_cvb_remove_opp_table(struct device *dev, | ||
| 135 | const struct cvb_table *table, | ||
| 136 | unsigned long max_freq) | ||
| 137 | { | ||
| 138 | unsigned int i; | ||
| 139 | |||
| 140 | for (i = 0; i < MAX_DVFS_FREQS; i++) { | ||
| 141 | const struct cvb_table_freq_entry *entry = &table->entries[i]; | ||
| 142 | |||
| 143 | if (!entry->freq || (entry->freq > max_freq)) | ||
| 144 | break; | ||
| 145 | |||
| 146 | dev_pm_opp_remove(dev, entry->freq); | ||
| 147 | } | ||
| 148 | } | ||
diff --git a/drivers/clk/tegra/cvb.h b/drivers/clk/tegra/cvb.h index f62cdc4f4234..c1f077993b2a 100644 --- a/drivers/clk/tegra/cvb.h +++ b/drivers/clk/tegra/cvb.h | |||
| @@ -53,15 +53,16 @@ struct cvb_table { | |||
| 53 | 53 | ||
| 54 | int speedo_scale; | 54 | int speedo_scale; |
| 55 | int voltage_scale; | 55 | int voltage_scale; |
| 56 | struct cvb_table_freq_entry cvb_table[MAX_DVFS_FREQS]; | 56 | struct cvb_table_freq_entry entries[MAX_DVFS_FREQS]; |
| 57 | struct cvb_cpu_dfll_data cpu_dfll_data; | 57 | struct cvb_cpu_dfll_data cpu_dfll_data; |
| 58 | }; | 58 | }; |
| 59 | 59 | ||
| 60 | const struct cvb_table *tegra_cvb_build_opp_table( | 60 | const struct cvb_table * |
| 61 | const struct cvb_table *cvb_tables, | 61 | tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *cvb_tables, |
| 62 | size_t sz, int process_id, | 62 | size_t count, int process_id, int speedo_id, |
| 63 | int speedo_id, int speedo_value, | 63 | int speedo_value, unsigned long max_freq); |
| 64 | unsigned long max_rate, | 64 | void tegra_cvb_remove_opp_table(struct device *dev, |
| 65 | struct device *opp_dev); | 65 | const struct cvb_table *table, |
| 66 | unsigned long max_freq); | ||
| 66 | 67 | ||
| 67 | #endif | 68 | #endif |
