Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-5.5/clk' into for-5.5/memory

+350 -52
+2
drivers/clk/tegra/Makefile
··· 17 17 obj-y += clk-tegra-super-gen4.o 18 18 obj-$(CONFIG_TEGRA_CLK_EMC) += clk-emc.o 19 19 obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o 20 + obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20-emc.o 20 21 obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o 22 + obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra20-emc.o 21 23 obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o 22 24 obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o 23 25 obj-$(CONFIG_TEGRA_CLK_DFLL) += clk-tegra124-dfll-fcpu.o
+293
drivers/clk/tegra/clk-tegra20-emc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Based on drivers/clk/tegra/clk-emc.c 4 + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. 5 + * 6 + * Author: Dmitry Osipenko <digetx@gmail.com> 7 + * Copyright (C) 2019 GRATE-DRIVER project 8 + */ 9 + 10 + #define pr_fmt(fmt) "tegra-emc-clk: " fmt 11 + 12 + #include <linux/bits.h> 13 + #include <linux/clk-provider.h> 14 + #include <linux/clk/tegra.h> 15 + #include <linux/err.h> 16 + #include <linux/io.h> 17 + #include <linux/kernel.h> 18 + #include <linux/slab.h> 19 + 20 + #include "clk.h" 21 + 22 + #define CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK GENMASK(7, 0) 23 + #define CLK_SOURCE_EMC_2X_CLK_SRC_MASK GENMASK(31, 30) 24 + #define CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT 30 25 + 26 + #define MC_EMC_SAME_FREQ BIT(16) 27 + #define USE_PLLM_UD BIT(29) 28 + 29 + #define EMC_SRC_PLL_M 0 30 + #define EMC_SRC_PLL_C 1 31 + #define EMC_SRC_PLL_P 2 32 + #define EMC_SRC_CLK_M 3 33 + 34 + static const char * const emc_parent_clk_names[] = { 35 + "pll_m", "pll_c", "pll_p", "clk_m", 36 + }; 37 + 38 + struct tegra_clk_emc { 39 + struct clk_hw hw; 40 + void __iomem *reg; 41 + bool mc_same_freq; 42 + bool want_low_jitter; 43 + 44 + tegra20_clk_emc_round_cb *round_cb; 45 + void *cb_arg; 46 + }; 47 + 48 + static inline struct tegra_clk_emc *to_tegra_clk_emc(struct clk_hw *hw) 49 + { 50 + return container_of(hw, struct tegra_clk_emc, hw); 51 + } 52 + 53 + static unsigned long emc_recalc_rate(struct clk_hw *hw, 54 + unsigned long parent_rate) 55 + { 56 + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); 57 + u32 val, div; 58 + 59 + val = readl_relaxed(emc->reg); 60 + div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; 61 + 62 + return DIV_ROUND_UP(parent_rate * 2, div + 2); 63 + } 64 + 65 + static u8 emc_get_parent(struct clk_hw *hw) 66 + { 67 + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); 68 + 69 + return readl_relaxed(emc->reg) >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; 70 + } 71 + 72 + static int emc_set_parent(struct clk_hw *hw, u8 index) 73 + { 74 + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); 75 + u32 val, div; 76 + 77 + val = readl_relaxed(emc->reg); 78 + val &= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK; 79 + val |= index << CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; 80 + 81 + div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; 82 + 83 + if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) 84 + val |= USE_PLLM_UD; 85 + else 86 + val &= ~USE_PLLM_UD; 87 + 88 + if (emc->mc_same_freq) 89 + val |= MC_EMC_SAME_FREQ; 90 + else 91 + val &= ~MC_EMC_SAME_FREQ; 92 + 93 + writel_relaxed(val, emc->reg); 94 + 95 + fence_udelay(1, emc->reg); 96 + 97 + return 0; 98 + } 99 + 100 + static int emc_set_rate(struct clk_hw *hw, unsigned long rate, 101 + unsigned long parent_rate) 102 + { 103 + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); 104 + unsigned int index; 105 + u32 val, div; 106 + 107 + div = div_frac_get(rate, parent_rate, 8, 1, 0); 108 + 109 + val = readl_relaxed(emc->reg); 110 + val &= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; 111 + val |= div; 112 + 113 + index = val >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; 114 + 115 + if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) 116 + val |= USE_PLLM_UD; 117 + else 118 + val &= ~USE_PLLM_UD; 119 + 120 + if (emc->mc_same_freq) 121 + val |= MC_EMC_SAME_FREQ; 122 + else 123 + val &= ~MC_EMC_SAME_FREQ; 124 + 125 + writel_relaxed(val, emc->reg); 126 + 127 + fence_udelay(1, emc->reg); 128 + 129 + return 0; 130 + } 131 + 132 + static int emc_set_rate_and_parent(struct clk_hw *hw, 133 + unsigned long rate, 134 + unsigned long parent_rate, 135 + u8 index) 136 + { 137 + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); 138 + u32 val, div; 139 + 140 + div = div_frac_get(rate, parent_rate, 8, 1, 0); 141 + 142 + val = readl_relaxed(emc->reg); 143 + 144 + val &= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK; 145 + val |= index << CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; 146 + 147 + val &= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; 148 + val |= div; 149 + 150 + if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) 151 + val |= USE_PLLM_UD; 152 + else 153 + val &= ~USE_PLLM_UD; 154 + 155 + if (emc->mc_same_freq) 156 + val |= MC_EMC_SAME_FREQ; 157 + else 158 + val &= ~MC_EMC_SAME_FREQ; 159 + 160 + writel_relaxed(val, emc->reg); 161 + 162 + fence_udelay(1, emc->reg); 163 + 164 + return 0; 165 + } 166 + 167 + static int emc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) 168 + { 169 + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); 170 + struct clk_hw *parent_hw; 171 + unsigned long divided_rate; 172 + unsigned long parent_rate; 173 + unsigned int i; 174 + long emc_rate; 175 + int div; 176 + 177 + emc_rate = emc->round_cb(req->rate, req->min_rate, req->max_rate, 178 + emc->cb_arg); 179 + if (emc_rate < 0) 180 + return emc_rate; 181 + 182 + for (i = 0; i < ARRAY_SIZE(emc_parent_clk_names); i++) { 183 + parent_hw = clk_hw_get_parent_by_index(hw, i); 184 + 185 + if (req->best_parent_hw == parent_hw) 186 + parent_rate = req->best_parent_rate; 187 + else 188 + parent_rate = clk_hw_get_rate(parent_hw); 189 + 190 + if (emc_rate > parent_rate) 191 + continue; 192 + 193 + div = div_frac_get(emc_rate, parent_rate, 8, 1, 0); 194 + divided_rate = DIV_ROUND_UP(parent_rate * 2, div + 2); 195 + 196 + if (divided_rate != emc_rate) 197 + continue; 198 + 199 + req->best_parent_rate = parent_rate; 200 + req->best_parent_hw = parent_hw; 201 + req->rate = emc_rate; 202 + break; 203 + } 204 + 205 + if (i == ARRAY_SIZE(emc_parent_clk_names)) { 206 + pr_err_once("can't find parent for rate %lu emc_rate %lu\n", 207 + req->rate, emc_rate); 208 + return -EINVAL; 209 + } 210 + 211 + return 0; 212 + } 213 + 214 + static const struct clk_ops tegra_clk_emc_ops = { 215 + .recalc_rate = emc_recalc_rate, 216 + .get_parent = emc_get_parent, 217 + .set_parent = emc_set_parent, 218 + .set_rate = emc_set_rate, 219 + .set_rate_and_parent = emc_set_rate_and_parent, 220 + .determine_rate = emc_determine_rate, 221 + }; 222 + 223 + void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb, 224 + void *cb_arg) 225 + { 226 + struct clk *clk = __clk_lookup("emc"); 227 + struct tegra_clk_emc *emc; 228 + struct clk_hw *hw; 229 + 230 + if (clk) { 231 + hw = __clk_get_hw(clk); 232 + emc = to_tegra_clk_emc(hw); 233 + 234 + emc->round_cb = round_cb; 235 + emc->cb_arg = cb_arg; 236 + } 237 + } 238 + 239 + bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw) 240 + { 241 + return to_tegra_clk_emc(emc_hw)->round_cb != NULL; 242 + } 243 + 244 + struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter) 245 + { 246 + struct tegra_clk_emc *emc; 247 + struct clk_init_data init; 248 + struct clk *clk; 249 + 250 + emc = kzalloc(sizeof(*emc), GFP_KERNEL); 251 + if (!emc) 252 + return NULL; 253 + 254 + /* 255 + * EMC stands for External Memory Controller. 256 + * 257 + * We don't want EMC clock to be disabled ever by gating its 258 + * parent and whatnot because system is busted immediately in that 259 + * case, hence the clock is marked as critical. 260 + */ 261 + init.name = "emc"; 262 + init.ops = &tegra_clk_emc_ops; 263 + init.flags = CLK_IS_CRITICAL; 264 + init.parent_names = emc_parent_clk_names; 265 + init.num_parents = ARRAY_SIZE(emc_parent_clk_names); 266 + 267 + emc->reg = ioaddr; 268 + emc->hw.init = &init; 269 + emc->want_low_jitter = low_jitter; 270 + 271 + clk = clk_register(NULL, &emc->hw); 272 + if (IS_ERR(clk)) { 273 + kfree(emc); 274 + return NULL; 275 + } 276 + 277 + return clk; 278 + } 279 + 280 + int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same) 281 + { 282 + struct tegra_clk_emc *emc; 283 + struct clk_hw *hw; 284 + 285 + if (!emc_clk) 286 + return -EINVAL; 287 + 288 + hw = __clk_get_hw(emc_clk); 289 + emc = to_tegra_clk_emc(hw); 290 + emc->mc_same_freq = same; 291 + 292 + return 0; 293 + }
+14 -41
drivers/clk/tegra/clk-tegra20.c
··· 130 130 static void __iomem *clk_base; 131 131 static void __iomem *pmc_base; 132 132 133 - static DEFINE_SPINLOCK(emc_lock); 134 - 135 133 #define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ 136 134 _clk_num, _gate_flags, _clk_id) \ 137 135 TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ ··· 758 760 static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" }; 759 761 static const char *mux_pllpdc_clkm[] = { "pll_p", "pll_d_out0", "pll_c", 760 762 "clk_m" }; 761 - static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" }; 762 763 763 764 static struct tegra_periph_init_data tegra_periph_clk_list[] = { 764 765 TEGRA_INIT_DATA_MUX("i2s1", i2s1_parents, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2S1), ··· 784 787 TEGRA_INIT_DATA_NODIV("disp2", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, 0, TEGRA20_CLK_DISP2), 785 788 }; 786 789 787 - static void __init tegra20_emc_clk_init(void) 788 - { 789 - const u32 use_pllm_ud = BIT(29); 790 - struct clk *clk; 791 - u32 emc_reg; 792 - 793 - clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, 794 - ARRAY_SIZE(mux_pllmcp_clkm), 795 - CLK_SET_RATE_NO_REPARENT, 796 - clk_base + CLK_SOURCE_EMC, 797 - 30, 2, 0, &emc_lock); 798 - 799 - clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, 800 - &emc_lock); 801 - clks[TEGRA20_CLK_MC] = clk; 802 - 803 - /* un-divided pll_m_out0 is currently unsupported */ 804 - emc_reg = readl_relaxed(clk_base + CLK_SOURCE_EMC); 805 - if (emc_reg & use_pllm_ud) { 806 - pr_err("%s: un-divided PllM_out0 used as clock source\n", 807 - __func__); 808 - return; 809 - } 810 - 811 - /* 812 - * Note that 'emc_mux' source and 'emc' rate shouldn't be changed at 813 - * the same time due to a HW bug, this won't happen because we're 814 - * defining 'emc_mux' and 'emc' as distinct clocks. 815 - */ 816 - clk = tegra_clk_register_divider("emc", "emc_mux", 817 - clk_base + CLK_SOURCE_EMC, CLK_IS_CRITICAL, 818 - TEGRA_DIVIDER_INT, 0, 8, 1, &emc_lock); 819 - clks[TEGRA20_CLK_EMC] = clk; 820 - } 821 - 822 790 static void __init tegra20_periph_clk_init(void) 823 791 { 824 792 struct tegra_periph_init_data *data; ··· 797 835 clks[TEGRA20_CLK_AC97] = clk; 798 836 799 837 /* emc */ 800 - tegra20_emc_clk_init(); 838 + clk = tegra20_clk_register_emc(clk_base + CLK_SOURCE_EMC, false); 839 + 840 + clks[TEGRA20_CLK_EMC] = clk; 841 + 842 + clk = tegra_clk_register_mc("mc", "emc", clk_base + CLK_SOURCE_EMC, 843 + NULL); 844 + clks[TEGRA20_CLK_MC] = clk; 801 845 802 846 /* dsi */ 803 847 clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0, ··· 1083 1115 if (IS_ERR(clk)) 1084 1116 return clk; 1085 1117 1118 + hw = __clk_get_hw(clk); 1119 + 1086 1120 /* 1087 1121 * Tegra20 CDEV1 and CDEV2 clocks are a bit special case, their parent 1088 1122 * clock is created by the pinctrl driver. It is possible for clk user ··· 1094 1124 */ 1095 1125 if (clkspec->args[0] == TEGRA20_CLK_CDEV1 || 1096 1126 clkspec->args[0] == TEGRA20_CLK_CDEV2) { 1097 - hw = __clk_get_hw(clk); 1098 - 1099 1127 parent_hw = clk_hw_get_parent(hw); 1100 1128 if (!parent_hw) 1129 + return ERR_PTR(-EPROBE_DEFER); 1130 + } 1131 + 1132 + if (clkspec->args[0] == TEGRA20_CLK_EMC) { 1133 + if (!tegra20_clk_emc_driver_available(hw)) 1101 1134 return ERR_PTR(-EPROBE_DEFER); 1102 1135 } 1103 1136
+27 -11
drivers/clk/tegra/clk-tegra30.c
··· 151 151 152 152 static DEFINE_SPINLOCK(cml_lock); 153 153 static DEFINE_SPINLOCK(pll_d_lock); 154 - static DEFINE_SPINLOCK(emc_lock); 155 154 156 155 #define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ 157 156 _clk_num, _gate_flags, _clk_id) \ ··· 807 808 [tegra_clk_pll_a] = { .dt_id = TEGRA30_CLK_PLL_A, .present = true }, 808 809 [tegra_clk_pll_a_out0] = { .dt_id = TEGRA30_CLK_PLL_A_OUT0, .present = true }, 809 810 [tegra_clk_cec] = { .dt_id = TEGRA30_CLK_CEC, .present = true }, 810 - [tegra_clk_emc] = { .dt_id = TEGRA30_CLK_EMC, .present = true }, 811 + [tegra_clk_emc] = { .dt_id = TEGRA30_CLK_EMC, .present = false }, 811 812 }; 812 813 813 814 static const char *pll_e_parents[] = { "pll_ref", "pll_p" }; ··· 994 995 static const char *mux_pllacp_clkm[] = { "pll_a_out0", "unused", "pll_p", 995 996 "clk_m" }; 996 997 static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" }; 997 - static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" }; 998 998 static const char *spdif_out_parents[] = { "pll_a_out0", "spdif_2x", "pll_p", 999 999 "clk_m" }; 1000 1000 static const char *mux_pllmcpa[] = { "pll_m", "pll_c", "pll_p", "pll_a_out0" }; ··· 1042 1044 clks[TEGRA30_CLK_AFI] = clk; 1043 1045 1044 1046 /* emc */ 1045 - clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, 1046 - ARRAY_SIZE(mux_pllmcp_clkm), 1047 - CLK_SET_RATE_NO_REPARENT, 1048 - clk_base + CLK_SOURCE_EMC, 1049 - 30, 2, 0, &emc_lock); 1047 + clk = tegra20_clk_register_emc(clk_base + CLK_SOURCE_EMC, true); 1050 1048 1051 - clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, 1052 - &emc_lock); 1049 + clks[TEGRA30_CLK_EMC] = clk; 1050 + 1051 + clk = tegra_clk_register_mc("mc", "emc", clk_base + CLK_SOURCE_EMC, 1052 + NULL); 1053 1053 clks[TEGRA30_CLK_MC] = clk; 1054 1054 1055 1055 /* cml0 */ ··· 1298 1302 { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" }, 1299 1303 }; 1300 1304 1305 + static struct clk *tegra30_clk_src_onecell_get(struct of_phandle_args *clkspec, 1306 + void *data) 1307 + { 1308 + struct clk_hw *hw; 1309 + struct clk *clk; 1310 + 1311 + clk = of_clk_src_onecell_get(clkspec, data); 1312 + if (IS_ERR(clk)) 1313 + return clk; 1314 + 1315 + hw = __clk_get_hw(clk); 1316 + 1317 + if (clkspec->args[0] == TEGRA30_CLK_EMC) { 1318 + if (!tegra20_clk_emc_driver_available(hw)) 1319 + return ERR_PTR(-EPROBE_DEFER); 1320 + } 1321 + 1322 + return clk; 1323 + } 1324 + 1301 1325 static void __init tegra30_clock_init(struct device_node *np) 1302 1326 { 1303 1327 struct device_node *node; ··· 1361 1345 1362 1346 tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX); 1363 1347 1364 - tegra_add_of_provider(np, of_clk_src_onecell_get); 1348 + tegra_add_of_provider(np, tegra30_clk_src_onecell_get); 1365 1349 tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); 1366 1350 1367 1351 tegra_clk_apply_init_table = tegra30_clock_apply_init_table;
+3
drivers/clk/tegra/clk.h
··· 838 838 udelay(delay); \ 839 839 } while (0) 840 840 841 + bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw); 842 + struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter); 843 + 841 844 #endif /* TEGRA_CLK_H */
+11
include/linux/clk/tegra.h
··· 119 119 extern void tegra210_put_utmipll_out_iddq(void); 120 120 extern int tegra210_clk_handle_mbist_war(unsigned int id); 121 121 122 + struct clk; 123 + 124 + typedef long (tegra20_clk_emc_round_cb)(unsigned long rate, 125 + unsigned long min_rate, 126 + unsigned long max_rate, 127 + void *arg); 128 + 129 + void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb, 130 + void *cb_arg); 131 + int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same); 132 + 122 133 #endif /* __LINUX_CLK_TEGRA_H_ */