aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikko Perttunen <mperttunen@nvidia.com>2015-03-12 10:48:05 -0400
committerThierry Reding <treding@nvidia.com>2015-05-13 09:17:11 -0400
commit2db04f16b589c6c96bd07df3f1ef8558bfdb6810 (patch)
tree1aa1384bd34defda0a55f8e068d5d64aa8260b49
parent374ffadaf3abd4bf77073bd8f1acf0ada7dc797e (diff)
clk: tegra: Add EMC clock driver
The driver is currently only tested on Tegra124 Jetson TK1, but should work with other Tegra124 boards, provided that correct EMC tables are provided through the device tree. Older chip models have differing timing change sequences, so they are not currently supported. Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com> [treding@nvidia.com: use more consistent function names] Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/clk/tegra/Makefile2
-rw-r--r--drivers/clk/tegra/clk-emc.c527
-rw-r--r--drivers/clk/tegra/clk-tegra124.c5
-rw-r--r--drivers/clk/tegra/clk.h3
4 files changed, 535 insertions, 2 deletions
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index edb8358fa6ce..18c28d1ae400 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -14,5 +14,5 @@ obj-y += clk-tegra-super-gen4.o
14obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o 14obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o
15obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o 15obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o
16obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o 16obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o
17obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o 17obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o clk-emc.o
18obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o 18obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o
diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c
new file mode 100644
index 000000000000..32e5563711ac
--- /dev/null
+++ b/drivers/clk/tegra/clk-emc.c
@@ -0,0 +1,527 @@
1/*
2 * drivers/clk/tegra/clk-emc.c
3 *
4 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
5 *
6 * Author:
7 * Mikko Perttunen <mperttunen@nvidia.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/clk-provider.h>
20#include <linux/clk.h>
21#include <linux/clkdev.h>
22#include <linux/delay.h>
23#include <linux/module.h>
24#include <linux/of_address.h>
25#include <linux/of_platform.h>
26#include <linux/platform_device.h>
27#include <linux/sort.h>
28#include <linux/string.h>
29
30#include <soc/tegra/fuse.h>
31#include <soc/tegra/emc.h>
32
33#include "clk.h"
34
35#define CLK_SOURCE_EMC 0x19c
36
37#define CLK_SOURCE_EMC_EMC_2X_CLK_DIVISOR_SHIFT 0
38#define CLK_SOURCE_EMC_EMC_2X_CLK_DIVISOR_MASK 0xff
39#define CLK_SOURCE_EMC_EMC_2X_CLK_DIVISOR(x) (((x) & CLK_SOURCE_EMC_EMC_2X_CLK_DIVISOR_MASK) << \
40 CLK_SOURCE_EMC_EMC_2X_CLK_DIVISOR_SHIFT)
41
42#define CLK_SOURCE_EMC_EMC_2X_CLK_SRC_SHIFT 29
43#define CLK_SOURCE_EMC_EMC_2X_CLK_SRC_MASK 0x7
44#define CLK_SOURCE_EMC_EMC_2X_CLK_SRC(x) (((x) & CLK_SOURCE_EMC_EMC_2X_CLK_SRC_MASK) << \
45 CLK_SOURCE_EMC_EMC_2X_CLK_SRC_SHIFT)
46
47static const char * const emc_parent_clk_names[] = {
48 "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud",
49 "pll_c2", "pll_c3", "pll_c_ud"
50};
51
52/*
53 * List of clock sources for various parents the EMC clock can have.
54 * When we change the timing to a timing with a parent that has the same
55 * clock source as the current parent, we must first change to a backup
56 * timing that has a different clock source.
57 */
58
59#define EMC_SRC_PLL_M 0
60#define EMC_SRC_PLL_C 1
61#define EMC_SRC_PLL_P 2
62#define EMC_SRC_CLK_M 3
63#define EMC_SRC_PLL_C2 4
64#define EMC_SRC_PLL_C3 5
65
66static const char emc_parent_clk_sources[] = {
67 EMC_SRC_PLL_M, EMC_SRC_PLL_C, EMC_SRC_PLL_P, EMC_SRC_CLK_M,
68 EMC_SRC_PLL_M, EMC_SRC_PLL_C2, EMC_SRC_PLL_C3, EMC_SRC_PLL_C
69};
70
71struct emc_timing {
72 unsigned long rate, parent_rate;
73 u8 parent_index;
74 struct clk *parent;
75 u32 ram_code;
76};
77
78struct tegra_clk_emc {
79 struct clk_hw hw;
80 void __iomem *clk_regs;
81 struct clk *prev_parent;
82 bool changing_timing;
83
84 struct device_node *emc_node;
85 struct tegra_emc *emc;
86
87 int num_timings;
88 struct emc_timing *timings;
89 spinlock_t *lock;
90};
91
92/* Common clock framework callback implementations */
93
94static unsigned long emc_recalc_rate(struct clk_hw *hw,
95 unsigned long parent_rate)
96{
97 struct tegra_clk_emc *tegra;
98 u32 val, div;
99
100 tegra = container_of(hw, struct tegra_clk_emc, hw);
101
102 /*
103 * CCF wrongly assumes that the parent won't change during set_rate,
104 * so get the parent rate explicitly.
105 */
106 parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
107
108 val = readl(tegra->clk_regs + CLK_SOURCE_EMC);
109 div = val & CLK_SOURCE_EMC_EMC_2X_CLK_DIVISOR_MASK;
110
111 return parent_rate / (div + 2) * 2;
112}
113
114/*
115 * Rounds up unless no higher rate exists, in which case down. This way is
116 * safer since things have EMC rate floors. Also don't touch parent_rate
117 * since we don't want the CCF to play with our parent clocks.
118 */
119static long emc_round_rate(struct clk_hw *hw, unsigned long rate,
120 unsigned long *parent_rate)
121{
122 struct tegra_clk_emc *tegra;
123 u8 ram_code = tegra_read_ram_code();
124 struct emc_timing *timing = NULL;
125 int i;
126
127 tegra = container_of(hw, struct tegra_clk_emc, hw);
128
129 for (i = 0; i < tegra->num_timings; i++) {
130 if (tegra->timings[i].ram_code != ram_code)
131 continue;
132
133 timing = tegra->timings + i;
134
135 if (timing->rate >= rate)
136 return timing->rate;
137 }
138
139 if (timing)
140 return timing->rate;
141
142 return __clk_get_rate(hw->clk);
143}
144
145static u8 emc_get_parent(struct clk_hw *hw)
146{
147 struct tegra_clk_emc *tegra;
148 u32 val;
149
150 tegra = container_of(hw, struct tegra_clk_emc, hw);
151
152 val = readl(tegra->clk_regs + CLK_SOURCE_EMC);
153
154 return (val >> CLK_SOURCE_EMC_EMC_2X_CLK_SRC_SHIFT)
155 & CLK_SOURCE_EMC_EMC_2X_CLK_SRC_MASK;
156}
157
158static struct tegra_emc *emc_ensure_emc_driver(struct tegra_clk_emc *tegra)
159{
160 struct platform_device *pdev;
161
162 if (tegra->emc)
163 return tegra->emc;
164
165 if (!tegra->emc_node)
166 return NULL;
167
168 pdev = of_find_device_by_node(tegra->emc_node);
169 if (!pdev) {
170 pr_err("%s: could not get external memory controller\n",
171 __func__);
172 return NULL;
173 }
174
175 of_node_put(tegra->emc_node);
176 tegra->emc_node = NULL;
177
178 tegra->emc = platform_get_drvdata(pdev);
179 if (!tegra->emc) {
180 pr_err("%s: cannot find EMC driver\n", __func__);
181 return NULL;
182 }
183
184 return tegra->emc;
185}
186
187static int emc_set_timing(struct tegra_clk_emc *tegra,
188 struct emc_timing *timing)
189{
190 int err;
191 u8 div;
192 u32 car_value;
193 unsigned long flags = 0;
194 struct tegra_emc *emc = emc_ensure_emc_driver(tegra);
195
196 if (!emc)
197 return -ENOENT;
198
199 pr_debug("going to rate %ld prate %ld p %s\n", timing->rate,
200 timing->parent_rate, __clk_get_name(timing->parent));
201
202 if (emc_get_parent(&tegra->hw) == timing->parent_index &&
203 clk_get_rate(timing->parent) != timing->parent_rate) {
204 BUG();
205 return -EINVAL;
206 }
207
208 tegra->changing_timing = true;
209
210 err = clk_set_rate(timing->parent, timing->parent_rate);
211 if (err) {
212 pr_err("cannot change parent %s rate to %ld: %d\n",
213 __clk_get_name(timing->parent), timing->parent_rate,
214 err);
215
216 return err;
217 }
218
219 err = clk_prepare_enable(timing->parent);
220 if (err) {
221 pr_err("cannot enable parent clock: %d\n", err);
222 return err;
223 }
224
225 div = timing->parent_rate / (timing->rate / 2) - 2;
226
227 err = tegra_emc_prepare_timing_change(emc, timing->rate);
228 if (err)
229 return err;
230
231 spin_lock_irqsave(tegra->lock, flags);
232
233 car_value = readl(tegra->clk_regs + CLK_SOURCE_EMC);
234
235 car_value &= ~CLK_SOURCE_EMC_EMC_2X_CLK_SRC(~0);
236 car_value |= CLK_SOURCE_EMC_EMC_2X_CLK_SRC(timing->parent_index);
237
238 car_value &= ~CLK_SOURCE_EMC_EMC_2X_CLK_DIVISOR(~0);
239 car_value |= CLK_SOURCE_EMC_EMC_2X_CLK_DIVISOR(div);
240
241 writel(car_value, tegra->clk_regs + CLK_SOURCE_EMC);
242
243 spin_unlock_irqrestore(tegra->lock, flags);
244
245 tegra_emc_complete_timing_change(emc, timing->rate);
246
247 clk_hw_reparent(&tegra->hw, __clk_get_hw(timing->parent));
248 clk_disable_unprepare(tegra->prev_parent);
249
250 tegra->prev_parent = timing->parent;
251 tegra->changing_timing = false;
252
253 return 0;
254}
255
256/*
257 * Get backup timing to use as an intermediate step when a change between
258 * two timings with the same clock source has been requested. First try to
259 * find a timing with a higher clock rate to avoid a rate below any set rate
260 * floors. If that is not possible, find a lower rate.
261 */
262static struct emc_timing *get_backup_timing(struct tegra_clk_emc *tegra,
263 int timing_index)
264{
265 int i;
266 u32 ram_code = tegra_read_ram_code();
267 struct emc_timing *timing;
268
269 for (i = timing_index+1; i < tegra->num_timings; i++) {
270 timing = tegra->timings + i;
271 if (timing->ram_code != ram_code)
272 continue;
273
274 if (emc_parent_clk_sources[timing->parent_index] !=
275 emc_parent_clk_sources[
276 tegra->timings[timing_index].parent_index])
277 return timing;
278 }
279
280 for (i = timing_index-1; i >= 0; --i) {
281 timing = tegra->timings + i;
282 if (timing->ram_code != ram_code)
283 continue;
284
285 if (emc_parent_clk_sources[timing->parent_index] !=
286 emc_parent_clk_sources[
287 tegra->timings[timing_index].parent_index])
288 return timing;
289 }
290
291 return NULL;
292}
293
294static int emc_set_rate(struct clk_hw *hw, unsigned long rate,
295 unsigned long parent_rate)
296{
297 struct tegra_clk_emc *tegra;
298 struct emc_timing *timing = NULL;
299 int i, err;
300 u32 ram_code = tegra_read_ram_code();
301
302 tegra = container_of(hw, struct tegra_clk_emc, hw);
303
304 if (__clk_get_rate(hw->clk) == rate)
305 return 0;
306
307 /*
308 * When emc_set_timing changes the parent rate, CCF will propagate
309 * that downward to us, so ignore any set_rate calls while a rate
310 * change is already going on.
311 */
312 if (tegra->changing_timing)
313 return 0;
314
315 for (i = 0; i < tegra->num_timings; i++) {
316 if (tegra->timings[i].rate == rate &&
317 tegra->timings[i].ram_code == ram_code) {
318 timing = tegra->timings + i;
319 break;
320 }
321 }
322
323 if (!timing) {
324 pr_err("cannot switch to rate %ld without emc table\n", rate);
325 return -EINVAL;
326 }
327
328 if (emc_parent_clk_sources[emc_get_parent(hw)] ==
329 emc_parent_clk_sources[timing->parent_index] &&
330 clk_get_rate(timing->parent) != timing->parent_rate) {
331 /*
332 * Parent clock source not changed but parent rate has changed,
333 * need to temporarily switch to another parent
334 */
335
336 struct emc_timing *backup_timing;
337
338 backup_timing = get_backup_timing(tegra, i);
339 if (!backup_timing) {
340 pr_err("cannot find backup timing\n");
341 return -EINVAL;
342 }
343
344 pr_debug("using %ld as backup rate when going to %ld\n",
345 backup_timing->rate, rate);
346
347 err = emc_set_timing(tegra, backup_timing);
348 if (err) {
349 pr_err("cannot set backup timing: %d\n", err);
350 return err;
351 }
352 }
353
354 return emc_set_timing(tegra, timing);
355}
356
357/* Initialization and deinitialization */
358
359static int load_one_timing_from_dt(struct tegra_clk_emc *tegra,
360 struct emc_timing *timing,
361 struct device_node *node)
362{
363 int err, i;
364 u32 tmp;
365
366 err = of_property_read_u32(node, "clock-frequency", &tmp);
367 if (err) {
368 pr_err("timing %s: failed to read rate\n", node->full_name);
369 return err;
370 }
371
372 timing->rate = tmp;
373
374 err = of_property_read_u32(node, "nvidia,parent-clock-frequency", &tmp);
375 if (err) {
376 pr_err("timing %s: failed to read parent rate\n",
377 node->full_name);
378 return err;
379 }
380
381 timing->parent_rate = tmp;
382
383 timing->parent = of_clk_get_by_name(node, "emc-parent");
384 if (IS_ERR(timing->parent)) {
385 pr_err("timing %s: failed to get parent clock\n",
386 node->full_name);
387 return PTR_ERR(timing->parent);
388 }
389
390 timing->parent_index = 0xff;
391 for (i = 0; i < ARRAY_SIZE(emc_parent_clk_names); i++) {
392 if (!strcmp(emc_parent_clk_names[i],
393 __clk_get_name(timing->parent))) {
394 timing->parent_index = i;
395 break;
396 }
397 }
398 if (timing->parent_index == 0xff) {
399 pr_err("timing %s: %s is not a valid parent\n",
400 node->full_name, __clk_get_name(timing->parent));
401 clk_put(timing->parent);
402 return -EINVAL;
403 }
404
405 return 0;
406}
407
408static int cmp_timings(const void *_a, const void *_b)
409{
410 const struct emc_timing *a = _a;
411 const struct emc_timing *b = _b;
412
413 if (a->rate < b->rate)
414 return -1;
415 else if (a->rate == b->rate)
416 return 0;
417 else
418 return 1;
419}
420
421static int load_timings_from_dt(struct tegra_clk_emc *tegra,
422 struct device_node *node,
423 u32 ram_code)
424{
425 struct device_node *child;
426 int child_count = of_get_child_count(node);
427 int i = 0, err;
428
429 tegra->timings = kcalloc(child_count, sizeof(struct emc_timing),
430 GFP_KERNEL);
431 if (!tegra->timings)
432 return -ENOMEM;
433
434 tegra->num_timings = child_count;
435
436 for_each_child_of_node(node, child) {
437 struct emc_timing *timing = tegra->timings + (i++);
438
439 err = load_one_timing_from_dt(tegra, timing, child);
440 if (err)
441 return err;
442
443 timing->ram_code = ram_code;
444 }
445
446 sort(tegra->timings, tegra->num_timings, sizeof(struct emc_timing),
447 cmp_timings, NULL);
448
449 return 0;
450}
451
452static const struct clk_ops tegra_clk_emc_ops = {
453 .recalc_rate = emc_recalc_rate,
454 .round_rate = emc_round_rate,
455 .set_rate = emc_set_rate,
456 .get_parent = emc_get_parent,
457};
458
459struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
460 spinlock_t *lock)
461{
462 struct tegra_clk_emc *tegra;
463 struct clk_init_data init;
464 struct device_node *node;
465 u32 node_ram_code;
466 struct clk *clk;
467 int err;
468
469 tegra = kcalloc(1, sizeof(*tegra), GFP_KERNEL);
470 if (!tegra)
471 return ERR_PTR(-ENOMEM);
472
473 tegra->clk_regs = base;
474 tegra->lock = lock;
475
476 tegra->num_timings = 0;
477
478 for_each_child_of_node(np, node) {
479 err = of_property_read_u32(node, "nvidia,ram-code",
480 &node_ram_code);
481 if (err) {
482 of_node_put(node);
483 continue;
484 }
485
486 /*
487 * Store timings for all ram codes as we cannot read the
488 * fuses until the apbmisc driver is loaded.
489 */
490 err = load_timings_from_dt(tegra, node, node_ram_code);
491 if (err)
492 return ERR_PTR(err);
493 of_node_put(node);
494 break;
495 }
496
497 if (tegra->num_timings == 0)
498 pr_warn("%s: no memory timings registered\n", __func__);
499
500 tegra->emc_node = of_parse_phandle(np,
501 "nvidia,external-memory-controller", 0);
502 if (!tegra->emc_node)
503 pr_warn("%s: couldn't find node for EMC driver\n", __func__);
504
505 init.name = "emc";
506 init.ops = &tegra_clk_emc_ops;
507 init.flags = 0;
508 init.parent_names = emc_parent_clk_names;
509 init.num_parents = ARRAY_SIZE(emc_parent_clk_names);
510
511 tegra->hw.init = &init;
512
513 clk = clk_register(NULL, &tegra->hw);
514 if (IS_ERR(clk))
515 return clk;
516
517 tegra->prev_parent = clk_get_parent_by_index(
518 tegra->hw.clk, emc_get_parent(&tegra->hw));
519 tegra->changing_timing = false;
520
521 /* Allow debugging tools to see the EMC clock */
522 clk_register_clkdev(clk, "emc", "tegra-clk-debug");
523
524 clk_prepare_enable(clk);
525
526 return clk;
527};
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index 62fe3cf7fcb5..096261d0a44e 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -1388,7 +1388,6 @@ static struct tegra_clk_init_table common_init_table[] __initdata = {
1388 {TEGRA124_CLK_XUSB_HOST_SRC, TEGRA124_CLK_PLL_RE_OUT, 112000000, 0}, 1388 {TEGRA124_CLK_XUSB_HOST_SRC, TEGRA124_CLK_PLL_RE_OUT, 112000000, 0},
1389 {TEGRA124_CLK_SATA, TEGRA124_CLK_PLL_P, 104000000, 0}, 1389 {TEGRA124_CLK_SATA, TEGRA124_CLK_PLL_P, 104000000, 0},
1390 {TEGRA124_CLK_SATA_OOB, TEGRA124_CLK_PLL_P, 204000000, 0}, 1390 {TEGRA124_CLK_SATA_OOB, TEGRA124_CLK_PLL_P, 204000000, 0},
1391 {TEGRA124_CLK_EMC, TEGRA124_CLK_CLK_MAX, 0, 1},
1392 {TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1}, 1391 {TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1},
1393 {TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1}, 1392 {TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1},
1394 {TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0}, 1393 {TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0},
@@ -1512,6 +1511,10 @@ static void __init tegra124_132_clock_init_post(struct device_node *np)
1512 tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks, 1511 tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks,
1513 &pll_x_params); 1512 &pll_x_params);
1514 tegra_add_of_provider(np); 1513 tegra_add_of_provider(np);
1514
1515 clks[TEGRA124_CLK_EMC] = tegra_clk_register_emc(clk_base, np,
1516 &emc_lock);
1517
1515 tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); 1518 tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
1516 1519
1517 tegra_cpu_car_ops = &tegra124_cpu_car_ops; 1520 tegra_cpu_car_ops = &tegra124_cpu_car_ops;
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index d6ac00647faf..e69e98a7bc80 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -623,6 +623,9 @@ void tegra_super_clk_gen4_init(void __iomem *clk_base,
623 void __iomem *pmc_base, struct tegra_clk *tegra_clks, 623 void __iomem *pmc_base, struct tegra_clk *tegra_clks,
624 struct tegra_clk_pll_params *pll_params); 624 struct tegra_clk_pll_params *pll_params);
625 625
626struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
627 spinlock_t *lock);
628
626void tegra114_clock_tune_cpu_trimmers_high(void); 629void tegra114_clock_tune_cpu_trimmers_high(void);
627void tegra114_clock_tune_cpu_trimmers_low(void); 630void tegra114_clock_tune_cpu_trimmers_low(void);
628void tegra114_clock_tune_cpu_trimmers_init(void); 631void tegra114_clock_tune_cpu_trimmers_init(void);