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 } 294