Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
plldata.c
Go to the documentation of this file.
1 /*
2  * Port on Texas Instruments TMS320C6x architecture
3  *
4  * Copyright (C) 2011 Texas Instruments Incorporated
5  * Author: Mark Salter <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 #include <linux/kernel.h>
12 #include <linux/delay.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
15 #include <linux/ioport.h>
16 #include <linux/clkdev.h>
17 #include <linux/of.h>
18 #include <linux/of_address.h>
19 
20 #include <asm/clock.h>
21 #include <asm/setup.h>
22 #include <asm/irq.h>
23 
24 /*
25  * Common SoC clock support.
26  */
27 
28 /* Default input for PLL1 */
29 struct clk clkin1 = {
30  .name = "clkin1",
31  .node = LIST_HEAD_INIT(clkin1.node),
32  .children = LIST_HEAD_INIT(clkin1.children),
33  .childnode = LIST_HEAD_INIT(clkin1.childnode),
34 };
35 
37  .num = 1,
38  .sysclks = {
39  {
40  .name = "pll1",
41  .parent = &clkin1,
42  .pll_data = &c6x_soc_pll1,
43  .flags = CLK_PLL,
44  },
45  {
46  .name = "pll1_sysclk1",
47  .parent = &c6x_soc_pll1.sysclks[0],
48  .flags = CLK_PLL,
49  },
50  {
51  .name = "pll1_sysclk2",
52  .parent = &c6x_soc_pll1.sysclks[0],
53  .flags = CLK_PLL,
54  },
55  {
56  .name = "pll1_sysclk3",
57  .parent = &c6x_soc_pll1.sysclks[0],
58  .flags = CLK_PLL,
59  },
60  {
61  .name = "pll1_sysclk4",
62  .parent = &c6x_soc_pll1.sysclks[0],
63  .flags = CLK_PLL,
64  },
65  {
66  .name = "pll1_sysclk5",
67  .parent = &c6x_soc_pll1.sysclks[0],
68  .flags = CLK_PLL,
69  },
70  {
71  .name = "pll1_sysclk6",
72  .parent = &c6x_soc_pll1.sysclks[0],
73  .flags = CLK_PLL,
74  },
75  {
76  .name = "pll1_sysclk7",
77  .parent = &c6x_soc_pll1.sysclks[0],
78  .flags = CLK_PLL,
79  },
80  {
81  .name = "pll1_sysclk8",
82  .parent = &c6x_soc_pll1.sysclks[0],
83  .flags = CLK_PLL,
84  },
85  {
86  .name = "pll1_sysclk9",
87  .parent = &c6x_soc_pll1.sysclks[0],
88  .flags = CLK_PLL,
89  },
90  {
91  .name = "pll1_sysclk10",
92  .parent = &c6x_soc_pll1.sysclks[0],
93  .flags = CLK_PLL,
94  },
95  {
96  .name = "pll1_sysclk11",
97  .parent = &c6x_soc_pll1.sysclks[0],
98  .flags = CLK_PLL,
99  },
100  {
101  .name = "pll1_sysclk12",
102  .parent = &c6x_soc_pll1.sysclks[0],
103  .flags = CLK_PLL,
104  },
105  {
106  .name = "pll1_sysclk13",
107  .parent = &c6x_soc_pll1.sysclks[0],
108  .flags = CLK_PLL,
109  },
110  {
111  .name = "pll1_sysclk14",
112  .parent = &c6x_soc_pll1.sysclks[0],
113  .flags = CLK_PLL,
114  },
115  {
116  .name = "pll1_sysclk15",
117  .parent = &c6x_soc_pll1.sysclks[0],
118  .flags = CLK_PLL,
119  },
120  {
121  .name = "pll1_sysclk16",
122  .parent = &c6x_soc_pll1.sysclks[0],
123  .flags = CLK_PLL,
124  },
125  },
126 };
127 
128 /* CPU core clock */
129 struct clk c6x_core_clk = {
130  .name = "core",
131 };
132 
133 /* miscellaneous IO clocks */
134 struct clk c6x_i2c_clk = {
135  .name = "i2c",
136 };
137 
139  .name = "watchdog",
140 };
141 
142 struct clk c6x_mcbsp1_clk = {
143  .name = "mcbsp1",
144 };
145 
146 struct clk c6x_mcbsp2_clk = {
147  .name = "mcbsp2",
148 };
149 
150 struct clk c6x_mdio_clk = {
151  .name = "mdio",
152 };
153 
154 
155 #ifdef CONFIG_SOC_TMS320C6455
156 static struct clk_lookup c6455_clks[] = {
157  CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
158  CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
159  CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
160  CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
161  CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
162  CLK(NULL, "core", &c6x_core_clk),
163  CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
164  CLK("watchdog", NULL, &c6x_watchdog_clk),
165  CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
166  CLK("", NULL, NULL)
167 };
168 
169 
170 static void __init c6455_setup_clocks(struct device_node *node)
171 {
172  struct pll_data *pll = &c6x_soc_pll1;
173  struct clk *sysclks = pll->sysclks;
174 
175  pll->flags = PLL_HAS_PRE | PLL_HAS_MUL;
176 
177  sysclks[2].flags |= FIXED_DIV_PLL;
178  sysclks[2].div = 3;
179  sysclks[3].flags |= FIXED_DIV_PLL;
180  sysclks[3].div = 6;
181  sysclks[4].div = PLLDIV4;
182  sysclks[5].div = PLLDIV5;
183 
184  c6x_core_clk.parent = &sysclks[0];
185  c6x_i2c_clk.parent = &sysclks[3];
186  c6x_watchdog_clk.parent = &sysclks[3];
187  c6x_mdio_clk.parent = &sysclks[3];
188 
189  c6x_clks_init(c6455_clks);
190 }
191 #endif /* CONFIG_SOC_TMS320C6455 */
192 
193 #ifdef CONFIG_SOC_TMS320C6457
194 static struct clk_lookup c6457_clks[] = {
195  CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
196  CLK(NULL, "pll1_sysclk1", &c6x_soc_pll1.sysclks[1]),
197  CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
198  CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
199  CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
200  CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
201  CLK(NULL, "core", &c6x_core_clk),
202  CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
203  CLK("watchdog", NULL, &c6x_watchdog_clk),
204  CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
205  CLK("", NULL, NULL)
206 };
207 
208 static void __init c6457_setup_clocks(struct device_node *node)
209 {
210  struct pll_data *pll = &c6x_soc_pll1;
211  struct clk *sysclks = pll->sysclks;
212 
213  pll->flags = PLL_HAS_MUL | PLL_HAS_POST;
214 
215  sysclks[1].flags |= FIXED_DIV_PLL;
216  sysclks[1].div = 1;
217  sysclks[2].flags |= FIXED_DIV_PLL;
218  sysclks[2].div = 3;
219  sysclks[3].flags |= FIXED_DIV_PLL;
220  sysclks[3].div = 6;
221  sysclks[4].div = PLLDIV4;
222  sysclks[5].div = PLLDIV5;
223 
224  c6x_core_clk.parent = &sysclks[1];
225  c6x_i2c_clk.parent = &sysclks[3];
226  c6x_watchdog_clk.parent = &sysclks[5];
227  c6x_mdio_clk.parent = &sysclks[5];
228 
229  c6x_clks_init(c6457_clks);
230 }
231 #endif /* CONFIG_SOC_TMS320C6455 */
232 
233 #ifdef CONFIG_SOC_TMS320C6472
234 static struct clk_lookup c6472_clks[] = {
235  CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
236  CLK(NULL, "pll1_sysclk1", &c6x_soc_pll1.sysclks[1]),
237  CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
238  CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
239  CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
240  CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
241  CLK(NULL, "pll1_sysclk6", &c6x_soc_pll1.sysclks[6]),
242  CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]),
243  CLK(NULL, "pll1_sysclk8", &c6x_soc_pll1.sysclks[8]),
244  CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]),
245  CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]),
246  CLK(NULL, "core", &c6x_core_clk),
247  CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
248  CLK("watchdog", NULL, &c6x_watchdog_clk),
249  CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
250  CLK("", NULL, NULL)
251 };
252 
253 /* assumptions used for delay loop calculations */
254 #define MIN_CLKIN1_KHz 15625
255 #define MAX_CORE_KHz 700000
256 #define MIN_PLLOUT_KHz MIN_CLKIN1_KHz
257 
258 static void __init c6472_setup_clocks(struct device_node *node)
259 {
260  struct pll_data *pll = &c6x_soc_pll1;
261  struct clk *sysclks = pll->sysclks;
262  int i;
263 
264  pll->flags = PLL_HAS_MUL;
265 
266  for (i = 1; i <= 6; i++) {
267  sysclks[i].flags |= FIXED_DIV_PLL;
268  sysclks[i].div = 1;
269  }
270 
271  sysclks[7].flags |= FIXED_DIV_PLL;
272  sysclks[7].div = 3;
273  sysclks[8].flags |= FIXED_DIV_PLL;
274  sysclks[8].div = 6;
275  sysclks[9].flags |= FIXED_DIV_PLL;
276  sysclks[9].div = 2;
277  sysclks[10].div = PLLDIV10;
278 
279  c6x_core_clk.parent = &sysclks[get_coreid() + 1];
280  c6x_i2c_clk.parent = &sysclks[8];
281  c6x_watchdog_clk.parent = &sysclks[8];
282  c6x_mdio_clk.parent = &sysclks[5];
283 
284  c6x_clks_init(c6472_clks);
285 }
286 #endif /* CONFIG_SOC_TMS320C6472 */
287 
288 
289 #ifdef CONFIG_SOC_TMS320C6474
290 static struct clk_lookup c6474_clks[] = {
291  CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
292  CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]),
293  CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]),
294  CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]),
295  CLK(NULL, "pll1_sysclk11", &c6x_soc_pll1.sysclks[11]),
296  CLK(NULL, "pll1_sysclk12", &c6x_soc_pll1.sysclks[12]),
297  CLK(NULL, "pll1_sysclk13", &c6x_soc_pll1.sysclks[13]),
298  CLK(NULL, "core", &c6x_core_clk),
299  CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
300  CLK("mcbsp.1", NULL, &c6x_mcbsp1_clk),
301  CLK("mcbsp.2", NULL, &c6x_mcbsp2_clk),
302  CLK("watchdog", NULL, &c6x_watchdog_clk),
303  CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
304  CLK("", NULL, NULL)
305 };
306 
307 static void __init c6474_setup_clocks(struct device_node *node)
308 {
309  struct pll_data *pll = &c6x_soc_pll1;
310  struct clk *sysclks = pll->sysclks;
311 
312  pll->flags = PLL_HAS_MUL;
313 
314  sysclks[7].flags |= FIXED_DIV_PLL;
315  sysclks[7].div = 1;
316  sysclks[9].flags |= FIXED_DIV_PLL;
317  sysclks[9].div = 3;
318  sysclks[10].flags |= FIXED_DIV_PLL;
319  sysclks[10].div = 6;
320 
321  sysclks[11].div = PLLDIV11;
322 
323  sysclks[12].flags |= FIXED_DIV_PLL;
324  sysclks[12].div = 2;
325 
326  sysclks[13].div = PLLDIV13;
327 
328  c6x_core_clk.parent = &sysclks[7];
329  c6x_i2c_clk.parent = &sysclks[10];
330  c6x_watchdog_clk.parent = &sysclks[10];
331  c6x_mcbsp1_clk.parent = &sysclks[10];
332  c6x_mcbsp2_clk.parent = &sysclks[10];
333 
334  c6x_clks_init(c6474_clks);
335 }
336 #endif /* CONFIG_SOC_TMS320C6474 */
337 
338 #ifdef CONFIG_SOC_TMS320C6678
339 static struct clk_lookup c6678_clks[] = {
340  CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
341  CLK(NULL, "pll1_refclk", &c6x_soc_pll1.sysclks[1]),
342  CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
343  CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
344  CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
345  CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
346  CLK(NULL, "pll1_sysclk6", &c6x_soc_pll1.sysclks[6]),
347  CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]),
348  CLK(NULL, "pll1_sysclk8", &c6x_soc_pll1.sysclks[8]),
349  CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]),
350  CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]),
351  CLK(NULL, "pll1_sysclk11", &c6x_soc_pll1.sysclks[11]),
352  CLK(NULL, "core", &c6x_core_clk),
353  CLK("", NULL, NULL)
354 };
355 
356 static void __init c6678_setup_clocks(struct device_node *node)
357 {
358  struct pll_data *pll = &c6x_soc_pll1;
359  struct clk *sysclks = pll->sysclks;
360 
361  pll->flags = PLL_HAS_MUL;
362 
363  sysclks[1].flags |= FIXED_DIV_PLL;
364  sysclks[1].div = 1;
365 
366  sysclks[2].div = PLLDIV2;
367 
368  sysclks[3].flags |= FIXED_DIV_PLL;
369  sysclks[3].div = 2;
370 
371  sysclks[4].flags |= FIXED_DIV_PLL;
372  sysclks[4].div = 3;
373 
374  sysclks[5].div = PLLDIV5;
375 
376  sysclks[6].flags |= FIXED_DIV_PLL;
377  sysclks[6].div = 64;
378 
379  sysclks[7].flags |= FIXED_DIV_PLL;
380  sysclks[7].div = 6;
381 
382  sysclks[8].div = PLLDIV8;
383 
384  sysclks[9].flags |= FIXED_DIV_PLL;
385  sysclks[9].div = 12;
386 
387  sysclks[10].flags |= FIXED_DIV_PLL;
388  sysclks[10].div = 3;
389 
390  sysclks[11].flags |= FIXED_DIV_PLL;
391  sysclks[11].div = 6;
392 
393  c6x_core_clk.parent = &sysclks[0];
394  c6x_i2c_clk.parent = &sysclks[7];
395 
396  c6x_clks_init(c6678_clks);
397 }
398 #endif /* CONFIG_SOC_TMS320C6678 */
399 
400 static struct of_device_id c6x_clkc_match[] __initdata = {
401 #ifdef CONFIG_SOC_TMS320C6455
402  { .compatible = "ti,c6455-pll", .data = c6455_setup_clocks },
403 #endif
404 #ifdef CONFIG_SOC_TMS320C6457
405  { .compatible = "ti,c6457-pll", .data = c6457_setup_clocks },
406 #endif
407 #ifdef CONFIG_SOC_TMS320C6472
408  { .compatible = "ti,c6472-pll", .data = c6472_setup_clocks },
409 #endif
410 #ifdef CONFIG_SOC_TMS320C6474
411  { .compatible = "ti,c6474-pll", .data = c6474_setup_clocks },
412 #endif
413 #ifdef CONFIG_SOC_TMS320C6678
414  { .compatible = "ti,c6678-pll", .data = c6678_setup_clocks },
415 #endif
416  { .compatible = "ti,c64x+pll" },
417  {}
418 };
419 
421 {
422  void (*__setup_clocks)(struct device_node *np);
423  struct pll_data *pll = &c6x_soc_pll1;
424  struct device_node *node;
425  const struct of_device_id *id;
426  int err;
427  u32 val;
428 
429  node = of_find_matching_node(NULL, c6x_clkc_match);
430  if (!node)
431  return;
432 
433  pll->base = of_iomap(node, 0);
434  if (!pll->base)
435  goto out;
436 
437  err = of_property_read_u32(node, "clock-frequency", &val);
438  if (err || val == 0) {
439  pr_err("%s: no clock-frequency found! Using %dMHz\n",
440  node->full_name, (int)val / 1000000);
441  val = 25000000;
442  }
443  clkin1.rate = val;
444 
445  err = of_property_read_u32(node, "ti,c64x+pll-bypass-delay", &val);
446  if (err)
447  val = 5000;
448  pll->bypass_delay = val;
449 
450  err = of_property_read_u32(node, "ti,c64x+pll-reset-delay", &val);
451  if (err)
452  val = 30000;
453  pll->reset_delay = val;
454 
455  err = of_property_read_u32(node, "ti,c64x+pll-lock-delay", &val);
456  if (err)
457  val = 30000;
458  pll->lock_delay = val;
459 
460  /* id->data is a pointer to SoC-specific setup */
461  id = of_match_node(c6x_clkc_match, node);
462  if (id && id->data) {
463  __setup_clocks = id->data;
464  __setup_clocks(node);
465  }
466 
467 out:
468  of_node_put(node);
469 }