aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorGerhard Sittig <gsi@denx.de>2013-11-30 17:51:24 -0500
committerAnatolij Gustschin <agust@denx.de>2014-01-12 12:53:03 -0500
commit6d8cdb68249d2a5d2504a7bc79a8cfb517e07020 (patch)
tree52946f166cd29adbd3665892bc413ab9fe6ae319 /arch/powerpc
parentf87ccd2edcdbe86ffb7cf7286e1c7aa84d5e5af9 (diff)
clk: mpc512x: introduce COMMON_CLK for MPC512x (disabled)
this change implements a clock driver for the MPC512x PowerPC platform which follows the COMMON_CLK approach and uses common clock drivers shared with other platforms this driver implements the publicly announced set of clocks (those listed in the dt-bindings header file), as well as generates additional 'struct clk' items where the SoC hardware cannot easily get mapped to the common primitives (shared code) of the clock API, or requires "intermediate clock nodes" to represent clocks that have both gates and dividers the previous PPC_CLOCK implementation is kept in place and remains active for the moment, the newly introduced CCF clock driver will receive additional support for backwards compatibility in a subsequent patch before it gets enabled and will replace the PPC_CLOCK approach some of the clock items get pre-enabled in the clock driver to not have them automatically disabled by the underlying clock subsystem because of their being unused -- this approach is desirable because - some of the clocks are useful to have for diagnostics and information despite their not getting claimed by any drivers (CPU, internal and external RAM, internal busses, boot media) - some of the clocks aren't claimed by their peripheral drivers yet, either because of missing driver support or because device tree specs aren't available yet (but the workarounds will get removed as the drivers get adjusted and the device tree provides the clock specs) clkdev registration provides "alias names" for few clock items - to not break those peripheral drivers which encode their component index into the name that is used for clock lookup (UART, SPI, USB) - to not break those drivers which use names for the clock lookup which were encoded in the previous PPC_CLOCK implementation (NFC, VIU, CAN) this workaround will get removed as these drivers get adjusted after device tree based clock lookup has become available the COMMON_CLK implementation copes with device trees which lack an oscillator node (backwards compat), the REF clock is then derived from the IPS bus frequency and multiplier values fetched from hardware Cc: Mike Turquette <mturquette@linaro.org> Cc: Anatolij Gustschin <agust@denx.de> Cc: linux-arm-kernel@lists.infradead.org Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Gerhard Sittig <gsi@denx.de> Signed-off-by: Anatolij Gustschin <agust@denx.de>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/512x/Makefile4
-rw-r--r--arch/powerpc/platforms/512x/clock-commonclk.c798
2 files changed, 801 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile
index 72fb9340e09f..1e05f9def8a4 100644
--- a/arch/powerpc/platforms/512x/Makefile
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -1,7 +1,9 @@
1# 1#
2# Makefile for the Freescale PowerPC 512x linux kernel. 2# Makefile for the Freescale PowerPC 512x linux kernel.
3# 3#
4obj-y += clock.o mpc512x_shared.o 4obj-$(CONFIG_PPC_CLOCK) += clock.o
5obj-$(CONFIG_COMMON_CLK) += clock-commonclk.o
6obj-y += mpc512x_shared.o
5obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o 7obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o
6obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o 8obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o
7obj-$(CONFIG_PDM360NG) += pdm360ng.o 9obj-$(CONFIG_PDM360NG) += pdm360ng.o
diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c
new file mode 100644
index 000000000000..818927248392
--- /dev/null
+++ b/arch/powerpc/platforms/512x/clock-commonclk.c
@@ -0,0 +1,798 @@
1/*
2 * Copyright (C) 2013 DENX Software Engineering
3 *
4 * Gerhard Sittig, <gsi@denx.de>
5 *
6 * common clock driver support for the MPC512x platform
7 *
8 * This is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/clk-provider.h>
15#include <linux/clkdev.h>
16#include <linux/device.h>
17#include <linux/errno.h>
18#include <linux/io.h>
19#include <linux/of.h>
20#include <linux/of_address.h>
21
22#include <asm/mpc5121.h>
23#include <dt-bindings/clock/mpc512x-clock.h>
24
25#include "mpc512x.h" /* our public mpc5121_clk_init() API */
26
27/* helpers to keep the MCLK intermediates "somewhere" in our table */
28enum {
29 MCLK_IDX_MUX0,
30 MCLK_IDX_EN0,
31 MCLK_IDX_DIV0,
32 MCLK_MAX_IDX,
33};
34
35#define NR_PSCS 12
36#define NR_MSCANS 4
37#define NR_SPDIFS 1
38#define NR_MCLKS (NR_PSCS + NR_MSCANS + NR_SPDIFS)
39
40/* extend the public set of clocks by adding internal slots for management */
41enum {
42 /* arrange for adjacent numbers after the public set */
43 MPC512x_CLK_START_PRIVATE = MPC512x_CLK_LAST_PUBLIC,
44 /* clocks which aren't announced to the public */
45 MPC512x_CLK_DDR,
46 MPC512x_CLK_MEM,
47 MPC512x_CLK_IIM,
48 MPC512x_CLK_SDHC_2,
49 /* intermediates in div+gate combos or fractional dividers */
50 MPC512x_CLK_DDR_UG,
51 MPC512x_CLK_SDHC_x4,
52 MPC512x_CLK_SDHC_UG,
53 MPC512x_CLK_DIU_x4,
54 MPC512x_CLK_DIU_UG,
55 MPC512x_CLK_MBX_BUS_UG,
56 MPC512x_CLK_MBX_UG,
57 MPC512x_CLK_MBX_3D_UG,
58 MPC512x_CLK_PCI_UG,
59 MPC512x_CLK_NFC_UG,
60 MPC512x_CLK_LPC_UG,
61 MPC512x_CLK_SPDIF_TX_IN,
62 /* intermediates for the mux+gate+div+mux MCLK generation */
63 MPC512x_CLK_MCLKS_FIRST,
64 MPC512x_CLK_MCLKS_LAST = MPC512x_CLK_MCLKS_FIRST
65 + NR_MCLKS * MCLK_MAX_IDX,
66 /* internal, symbolic spec for the number of slots */
67 MPC512x_CLK_LAST_PRIVATE,
68};
69
70/* data required for the OF clock provider registration */
71static struct clk *clks[MPC512x_CLK_LAST_PRIVATE];
72static struct clk_onecell_data clk_data;
73
74/* CCM register access */
75static struct mpc512x_ccm __iomem *clkregs;
76static DEFINE_SPINLOCK(clklock);
77
78/* convenience wrappers around the common clk API */
79static inline struct clk *mpc512x_clk_fixed(const char *name, int rate)
80{
81 return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
82}
83
84static inline struct clk *mpc512x_clk_factor(
85 const char *name, const char *parent_name,
86 int mul, int div)
87{
88 int clkflags;
89
90 clkflags = CLK_SET_RATE_PARENT;
91 return clk_register_fixed_factor(NULL, name, parent_name, clkflags,
92 mul, div);
93}
94
95static inline struct clk *mpc512x_clk_divider(
96 const char *name, const char *parent_name, u8 clkflags,
97 u32 __iomem *reg, u8 pos, u8 len, int divflags)
98{
99 return clk_register_divider(NULL, name, parent_name, clkflags,
100 reg, pos, len, divflags, &clklock);
101}
102
103static inline struct clk *mpc512x_clk_divtable(
104 const char *name, const char *parent_name,
105 u32 __iomem *reg, u8 pos, u8 len,
106 const struct clk_div_table *divtab)
107{
108 u8 divflags;
109
110 divflags = 0;
111 return clk_register_divider_table(NULL, name, parent_name, 0,
112 reg, pos, len, divflags,
113 divtab, &clklock);
114}
115
116static inline struct clk *mpc512x_clk_gated(
117 const char *name, const char *parent_name,
118 u32 __iomem *reg, u8 pos)
119{
120 int clkflags;
121
122 clkflags = CLK_SET_RATE_PARENT;
123 return clk_register_gate(NULL, name, parent_name, clkflags,
124 reg, pos, 0, &clklock);
125}
126
127static inline struct clk *mpc512x_clk_muxed(const char *name,
128 const char **parent_names, int parent_count,
129 u32 __iomem *reg, u8 pos, u8 len)
130{
131 int clkflags;
132 u8 muxflags;
133
134 clkflags = CLK_SET_RATE_PARENT;
135 muxflags = 0;
136 return clk_register_mux(NULL, name,
137 parent_names, parent_count, clkflags,
138 reg, pos, len, muxflags, &clklock);
139}
140
141/* helper to isolate a bit field from a register */
142static inline int get_bit_field(uint32_t __iomem *reg, uint8_t pos, uint8_t len)
143{
144 uint32_t val;
145
146 val = in_be32(reg);
147 val >>= pos;
148 val &= (1 << len) - 1;
149 return val;
150}
151
152/* get the SPMF and translate it into the "sys pll" multiplier */
153static int get_spmf_mult(void)
154{
155 static int spmf_to_mult[] = {
156 68, 1, 12, 16, 20, 24, 28, 32,
157 36, 40, 44, 48, 52, 56, 60, 64,
158 };
159 int spmf;
160
161 spmf = get_bit_field(&clkregs->spmr, 24, 4);
162 return spmf_to_mult[spmf];
163}
164
165/*
166 * get the SYS_DIV value and translate it into a divide factor
167 *
168 * values returned from here are a multiple of the real factor since the
169 * divide ratio is fractional
170 */
171static int get_sys_div_x2(void)
172{
173 static int sysdiv_code_to_x2[] = {
174 4, 5, 6, 7, 8, 9, 10, 14,
175 12, 16, 18, 22, 20, 24, 26, 30,
176 28, 32, 34, 38, 36, 40, 42, 46,
177 44, 48, 50, 54, 52, 56, 58, 62,
178 60, 64, 66,
179 };
180 int divcode;
181
182 divcode = get_bit_field(&clkregs->scfr2, 26, 6);
183 return sysdiv_code_to_x2[divcode];
184}
185
186/*
187 * get the CPMF value and translate it into a multiplier factor
188 *
189 * values returned from here are a multiple of the real factor since the
190 * multiplier ratio is fractional
191 */
192static int get_cpmf_mult_x2(void)
193{
194 static int cpmf_to_mult[] = {
195 72, 2, 2, 3, 4, 5, 6, 7,
196 };
197 int cpmf;
198
199 cpmf = get_bit_field(&clkregs->spmr, 16, 4);
200 return cpmf_to_mult[cpmf];
201}
202
203/*
204 * some of the clock dividers do scale in a linear way, yet not all of
205 * their bit combinations are legal; use a divider table to get a
206 * resulting set of applicable divider values
207 */
208
209/* applies to the IPS_DIV, and PCI_DIV values */
210static struct clk_div_table divtab_2346[] = {
211 { .val = 2, .div = 2, },
212 { .val = 3, .div = 3, },
213 { .val = 4, .div = 4, },
214 { .val = 6, .div = 6, },
215 { .div = 0, },
216};
217
218/* applies to the MBX_DIV, LPC_DIV, and NFC_DIV values */
219static struct clk_div_table divtab_1234[] = {
220 { .val = 1, .div = 1, },
221 { .val = 2, .div = 2, },
222 { .val = 3, .div = 3, },
223 { .val = 4, .div = 4, },
224 { .div = 0, },
225};
226
227static int get_freq_from_dt(char *propname)
228{
229 struct device_node *np;
230 const unsigned int *prop;
231 int val;
232
233 val = 0;
234 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr");
235 if (np) {
236 prop = of_get_property(np, propname, NULL);
237 if (prop)
238 val = *prop;
239 of_node_put(np);
240 }
241 return val;
242}
243
244static void mpc512x_clk_preset_data(void)
245{
246 size_t i;
247
248 for (i = 0; i < ARRAY_SIZE(clks); i++)
249 clks[i] = ERR_PTR(-ENODEV);
250}
251
252/*
253 * - receives the "bus frequency" from the caller (that's the IPS clock
254 * rate, the historical source of clock information)
255 * - fetches the system PLL multiplier and divider values as well as the
256 * IPS divider value from hardware
257 * - determines the REF clock rate either from the XTAL/OSC spec (if
258 * there is a device tree node describing the oscillator) or from the
259 * IPS bus clock (supported for backwards compatibility, such that
260 * setups without XTAL/OSC specs keep working)
261 * - creates the "ref" clock item in the clock tree, such that
262 * subsequent code can create the remainder of the hierarchy (REF ->
263 * SYS -> CSB -> IPS) from the REF clock rate and the returned mul/div
264 * values
265 */
266static void mpc512x_clk_setup_ref_clock(struct device_node *np, int bus_freq,
267 int *sys_mul, int *sys_div,
268 int *ips_div)
269{
270 struct clk *osc_clk;
271 int calc_freq;
272
273 /* fetch mul/div factors from the hardware */
274 *sys_mul = get_spmf_mult();
275 *sys_mul *= 2; /* compensate for the fractional divider */
276 *sys_div = get_sys_div_x2();
277 *ips_div = get_bit_field(&clkregs->scfr1, 23, 3);
278
279 /* lookup the oscillator clock for its rate */
280 osc_clk = of_clk_get_by_name(np, "osc");
281
282 /*
283 * either descend from OSC to REF (and in bypassing verify the
284 * IPS rate), or backtrack from IPS and multiplier values that
285 * were fetched from hardware to REF and thus to the OSC value
286 *
287 * in either case the REF clock gets created here and the
288 * remainder of the clock tree can get spanned from there
289 */
290 if (!IS_ERR(osc_clk)) {
291 clks[MPC512x_CLK_REF] = mpc512x_clk_factor("ref", "osc", 1, 1);
292 calc_freq = clk_get_rate(clks[MPC512x_CLK_REF]);
293 calc_freq *= *sys_mul;
294 calc_freq /= *sys_div;
295 calc_freq /= 2;
296 calc_freq /= *ips_div;
297 if (bus_freq && calc_freq != bus_freq)
298 pr_warn("calc rate %d != OF spec %d\n",
299 calc_freq, bus_freq);
300 } else {
301 calc_freq = bus_freq; /* start with IPS */
302 calc_freq *= *ips_div; /* IPS -> CSB */
303 calc_freq *= 2; /* CSB -> SYS */
304 calc_freq *= *sys_div; /* SYS -> PLL out */
305 calc_freq /= *sys_mul; /* PLL out -> REF == OSC */
306 clks[MPC512x_CLK_REF] = mpc512x_clk_fixed("ref", calc_freq);
307 }
308}
309
310/*
311 * helper code for the MCLK subtree setup
312 *
313 * the overview in section 5.2.4 of the MPC5121e Reference Manual rev4
314 * suggests that all instances of the "PSC clock generation" are equal,
315 * and that one might re-use the PSC setup for MSCAN clock generation
316 * (section 5.2.5) as well, at least the logic if not the data for
317 * description
318 *
319 * the details (starting at page 5-20) show differences in the specific
320 * inputs of the first mux stage ("can clk in", "spdif tx"), and the
321 * factual non-availability of the second mux stage (it's present yet
322 * only one input is valid)
323 *
324 * the MSCAN clock related registers (starting at page 5-35) all
325 * reference "spdif clk" at the first mux stage and don't mention any
326 * "can clk" at all, which somehow is unexpected
327 *
328 * TODO re-check the document, and clarify whether the RM is correct in
329 * the overview or in the details, and whether the difference is a
330 * clipboard induced error or results from chip revisions
331 *
332 * it turns out that the RM rev4 as of 2012-06 talks about "can" for the
333 * PSCs while RM rev3 as of 2008-10 talks about "spdif", so I guess that
334 * first a doc update is required which better reflects reality in the
335 * SoC before the implementation should follow while no questions remain
336 */
337
338/*
339 * note that this declaration raises a checkpatch warning, but
340 * it's the very data type which <linux/clk-provider.h> expects,
341 * making this declaration pass checkpatch will break compilation
342 */
343static const char *parent_names_mux0[] = {
344 "sys", "ref", "psc-mclk-in", "spdif-tx",
345};
346
347enum mclk_type {
348 MCLK_TYPE_PSC,
349 MCLK_TYPE_MSCAN,
350 MCLK_TYPE_SPDIF,
351};
352
353struct mclk_setup_data {
354 enum mclk_type type;
355 bool has_mclk1;
356 const char *name_mux0;
357 const char *name_en0;
358 const char *name_div0;
359 const char *parent_names_mux1[2];
360 const char *name_mclk;
361};
362
363#define MCLK_SETUP_DATA_PSC(id) { \
364 MCLK_TYPE_PSC, 0, \
365 "psc" #id "-mux0", \
366 "psc" #id "-en0", \
367 "psc" #id "_mclk_div", \
368 { "psc" #id "_mclk_div", "dummy", }, \
369 "psc" #id "_mclk", \
370}
371
372#define MCLK_SETUP_DATA_MSCAN(id) { \
373 MCLK_TYPE_MSCAN, 0, \
374 "mscan" #id "-mux0", \
375 "mscan" #id "-en0", \
376 "mscan" #id "_mclk_div", \
377 { "mscan" #id "_mclk_div", "dummy", }, \
378 "mscan" #id "_mclk", \
379}
380
381#define MCLK_SETUP_DATA_SPDIF { \
382 MCLK_TYPE_SPDIF, 1, \
383 "spdif-mux0", \
384 "spdif-en0", \
385 "spdif_mclk_div", \
386 { "spdif_mclk_div", "spdif-rx", }, \
387 "spdif_mclk", \
388}
389
390static struct mclk_setup_data mclk_psc_data[] = {
391 MCLK_SETUP_DATA_PSC(0),
392 MCLK_SETUP_DATA_PSC(1),
393 MCLK_SETUP_DATA_PSC(2),
394 MCLK_SETUP_DATA_PSC(3),
395 MCLK_SETUP_DATA_PSC(4),
396 MCLK_SETUP_DATA_PSC(5),
397 MCLK_SETUP_DATA_PSC(6),
398 MCLK_SETUP_DATA_PSC(7),
399 MCLK_SETUP_DATA_PSC(8),
400 MCLK_SETUP_DATA_PSC(9),
401 MCLK_SETUP_DATA_PSC(10),
402 MCLK_SETUP_DATA_PSC(11),
403};
404
405static struct mclk_setup_data mclk_mscan_data[] = {
406 MCLK_SETUP_DATA_MSCAN(0),
407 MCLK_SETUP_DATA_MSCAN(1),
408 MCLK_SETUP_DATA_MSCAN(2),
409 MCLK_SETUP_DATA_MSCAN(3),
410};
411
412static struct mclk_setup_data mclk_spdif_data[] = {
413 MCLK_SETUP_DATA_SPDIF,
414};
415
416/* setup the MCLK clock subtree of an individual PSC/MSCAN/SPDIF */
417static void mpc512x_clk_setup_mclk(struct mclk_setup_data *entry, size_t idx)
418{
419 size_t clks_idx_pub, clks_idx_int;
420 u32 __iomem *mccr_reg; /* MCLK control register (mux, en, div) */
421 int div;
422
423 /* derive a few parameters from the component type and index */
424 switch (entry->type) {
425 case MCLK_TYPE_PSC:
426 clks_idx_pub = MPC512x_CLK_PSC0_MCLK + idx;
427 clks_idx_int = MPC512x_CLK_MCLKS_FIRST
428 + (idx) * MCLK_MAX_IDX;
429 mccr_reg = &clkregs->psc_ccr[idx];
430 break;
431 case MCLK_TYPE_MSCAN:
432 clks_idx_pub = MPC512x_CLK_MSCAN0_MCLK + idx;
433 clks_idx_int = MPC512x_CLK_MCLKS_FIRST
434 + (NR_PSCS + idx) * MCLK_MAX_IDX;
435 mccr_reg = &clkregs->mscan_ccr[idx];
436 break;
437 case MCLK_TYPE_SPDIF:
438 clks_idx_pub = MPC512x_CLK_SPDIF_MCLK;
439 clks_idx_int = MPC512x_CLK_MCLKS_FIRST
440 + (NR_PSCS + NR_MSCANS) * MCLK_MAX_IDX;
441 mccr_reg = &clkregs->spccr;
442 break;
443 default:
444 return;
445 }
446
447 /*
448 * this was grabbed from the PPC_CLOCK implementation, which
449 * enforced a specific MCLK divider while the clock was gated
450 * during setup (that's a documented hardware requirement)
451 *
452 * the PPC_CLOCK implementation might even have violated the
453 * "MCLK <= IPS" constraint, the fixed divider value of 1
454 * results in a divider of 2 and thus MCLK = SYS/2 which equals
455 * CSB which is greater than IPS; the serial port setup may have
456 * adjusted the divider which the clock setup might have left in
457 * an undesirable state
458 *
459 * initial setup is:
460 * - MCLK 0 from SYS
461 * - MCLK DIV such to not exceed the IPS clock
462 * - MCLK 0 enabled
463 * - MCLK 1 from MCLK DIV
464 */
465 div = clk_get_rate(clks[MPC512x_CLK_SYS]);
466 div /= clk_get_rate(clks[MPC512x_CLK_IPS]);
467 out_be32(mccr_reg, (0 << 16));
468 out_be32(mccr_reg, (0 << 16) | ((div - 1) << 17));
469 out_be32(mccr_reg, (1 << 16) | ((div - 1) << 17));
470
471 /*
472 * create the 'struct clk' items of the MCLK's clock subtree
473 *
474 * note that by design we always create all nodes and won't take
475 * shortcuts here, because
476 * - the "internal" MCLK_DIV and MCLK_OUT signal in turn are
477 * selectable inputs to the CFM while those who "actually use"
478 * the PSC/MSCAN/SPDIF (serial drivers et al) need the MCLK
479 * for their bitrate
480 * - in the absence of "aliases" for clocks we need to create
481 * individial 'struct clk' items for whatever might get
482 * referenced or looked up, even if several of those items are
483 * identical from the logical POV (their rate value)
484 * - for easier future maintenance and for better reflection of
485 * the SoC's documentation, it appears appropriate to generate
486 * clock items even for those muxers which actually are NOPs
487 * (those with two inputs of which one is reserved)
488 */
489 clks[clks_idx_int + MCLK_IDX_MUX0] = mpc512x_clk_muxed(
490 entry->name_mux0,
491 &parent_names_mux0[0], ARRAY_SIZE(parent_names_mux0),
492 mccr_reg, 14, 2);
493 clks[clks_idx_int + MCLK_IDX_EN0] = mpc512x_clk_gated(
494 entry->name_en0, entry->name_mux0,
495 mccr_reg, 16);
496 clks[clks_idx_int + MCLK_IDX_DIV0] = mpc512x_clk_divider(
497 entry->name_div0,
498 entry->name_en0, CLK_SET_RATE_GATE,
499 mccr_reg, 17, 15, 0);
500 if (entry->has_mclk1) {
501 clks[clks_idx_pub] = mpc512x_clk_muxed(
502 entry->name_mclk,
503 &entry->parent_names_mux1[0],
504 ARRAY_SIZE(entry->parent_names_mux1),
505 mccr_reg, 7, 1);
506 } else {
507 clks[clks_idx_pub] = mpc512x_clk_factor(
508 entry->name_mclk,
509 entry->parent_names_mux1[0],
510 1, 1);
511 }
512}
513
514static void mpc512x_clk_setup_clock_tree(struct device_node *np, int busfreq)
515{
516 int sys_mul, sys_div, ips_div;
517 int mul, div;
518 size_t mclk_idx;
519 int freq;
520
521 /*
522 * developer's notes:
523 * - consider whether to handle clocks which have both gates and
524 * dividers via intermediates or by means of composites
525 * - fractional dividers appear to not map well to composites
526 * since they can be seen as a fixed multiplier and an
527 * adjustable divider, while composites can only combine at
528 * most one of a mux, div, and gate each into one 'struct clk'
529 * item
530 * - PSC/MSCAN/SPDIF clock generation OTOH already is very
531 * specific and cannot get mapped to componsites (at least not
532 * a single one, maybe two of them, but then some of these
533 * intermediate clock signals get referenced elsewhere (e.g.
534 * in the clock frequency measurement, CFM) and thus need
535 * publicly available names
536 * - the current source layout appropriately reflects the
537 * hardware setup, and it works, so it's questionable whether
538 * further changes will result in big enough a benefit
539 */
540
541 /* regardless of whether XTAL/OSC exists, have REF created */
542 mpc512x_clk_setup_ref_clock(np, busfreq, &sys_mul, &sys_div, &ips_div);
543
544 /* now setup the REF -> SYS -> CSB -> IPS hierarchy */
545 clks[MPC512x_CLK_SYS] = mpc512x_clk_factor("sys", "ref",
546 sys_mul, sys_div);
547 clks[MPC512x_CLK_CSB] = mpc512x_clk_factor("csb", "sys", 1, 2);
548 clks[MPC512x_CLK_IPS] = mpc512x_clk_divtable("ips", "csb",
549 &clkregs->scfr1, 23, 3,
550 divtab_2346);
551
552 /* now setup anything below SYS and CSB and IPS */
553 clks[MPC512x_CLK_DDR_UG] = mpc512x_clk_factor("ddr-ug", "sys", 1, 2);
554 clks[MPC512x_CLK_SDHC_x4] = mpc512x_clk_factor("sdhc-x4", "csb", 4, 1);
555 clks[MPC512x_CLK_SDHC_UG] = mpc512x_clk_divider("sdhc-ug", "sdhc-x4", 0,
556 &clkregs->scfr2, 0, 8,
557 CLK_DIVIDER_ONE_BASED);
558 clks[MPC512x_CLK_DIU_x4] = mpc512x_clk_factor("diu-x4", "csb", 4, 1);
559 clks[MPC512x_CLK_DIU_UG] = mpc512x_clk_divider("diu-ug", "diu-x4", 0,
560 &clkregs->scfr1, 0, 8,
561 CLK_DIVIDER_ONE_BASED);
562
563 /*
564 * the "power architecture PLL" was setup from data which was
565 * sampled from the reset config word, at this point in time the
566 * configuration can be considered fixed and read only (i.e. no
567 * longer adjustable, or no longer in need of adjustment), which
568 * is why we don't register a PLL here but assume fixed factors
569 */
570 mul = get_cpmf_mult_x2();
571 div = 2; /* compensate for the fractional factor */
572 clks[MPC512x_CLK_E300] = mpc512x_clk_factor("e300", "csb", mul, div);
573
574 clks[MPC512x_CLK_MBX_BUS_UG] = mpc512x_clk_factor("mbx-bus-ug", "csb",
575 1, 2);
576 clks[MPC512x_CLK_MBX_UG] = mpc512x_clk_divtable("mbx-ug", "mbx-bus-ug",
577 &clkregs->scfr1, 14, 3,
578 divtab_1234);
579 clks[MPC512x_CLK_MBX_3D_UG] = mpc512x_clk_factor("mbx-3d-ug", "mbx-ug",
580 1, 1);
581 clks[MPC512x_CLK_PCI_UG] = mpc512x_clk_divtable("pci-ug", "csb",
582 &clkregs->scfr1, 20, 3,
583 divtab_2346);
584 clks[MPC512x_CLK_NFC_UG] = mpc512x_clk_divtable("nfc-ug", "ips",
585 &clkregs->scfr1, 8, 3,
586 divtab_1234);
587 clks[MPC512x_CLK_LPC_UG] = mpc512x_clk_divtable("lpc-ug", "ips",
588 &clkregs->scfr1, 11, 3,
589 divtab_1234);
590
591 clks[MPC512x_CLK_LPC] = mpc512x_clk_gated("lpc", "lpc-ug",
592 &clkregs->sccr1, 30);
593 clks[MPC512x_CLK_NFC] = mpc512x_clk_gated("nfc", "nfc-ug",
594 &clkregs->sccr1, 29);
595 clks[MPC512x_CLK_PATA] = mpc512x_clk_gated("pata", "ips",
596 &clkregs->sccr1, 28);
597 /* for PSCs there is a "registers" gate and a bitrate MCLK subtree */
598 for (mclk_idx = 0; mclk_idx < ARRAY_SIZE(mclk_psc_data); mclk_idx++) {
599 char name[12];
600 snprintf(name, sizeof(name), "psc%d", mclk_idx);
601 clks[MPC512x_CLK_PSC0 + mclk_idx] = mpc512x_clk_gated(
602 name, "ips", &clkregs->sccr1, 27 - mclk_idx);
603 mpc512x_clk_setup_mclk(&mclk_psc_data[mclk_idx], mclk_idx);
604 }
605 clks[MPC512x_CLK_PSC_FIFO] = mpc512x_clk_gated("psc-fifo", "ips",
606 &clkregs->sccr1, 15);
607 clks[MPC512x_CLK_SATA] = mpc512x_clk_gated("sata", "ips",
608 &clkregs->sccr1, 14);
609 clks[MPC512x_CLK_FEC] = mpc512x_clk_gated("fec", "ips",
610 &clkregs->sccr1, 13);
611 clks[MPC512x_CLK_PCI] = mpc512x_clk_gated("pci", "pci-ug",
612 &clkregs->sccr1, 11);
613 clks[MPC512x_CLK_DDR] = mpc512x_clk_gated("ddr", "ddr-ug",
614 &clkregs->sccr1, 10);
615
616 clks[MPC512x_CLK_DIU] = mpc512x_clk_gated("diu", "diu-ug",
617 &clkregs->sccr2, 31);
618 clks[MPC512x_CLK_AXE] = mpc512x_clk_gated("axe", "csb",
619 &clkregs->sccr2, 30);
620 clks[MPC512x_CLK_MEM] = mpc512x_clk_gated("mem", "ips",
621 &clkregs->sccr2, 29);
622 clks[MPC512x_CLK_USB1] = mpc512x_clk_gated("usb1", "csb",
623 &clkregs->sccr2, 28);
624 clks[MPC512x_CLK_USB2] = mpc512x_clk_gated("usb2", "csb",
625 &clkregs->sccr2, 27);
626 clks[MPC512x_CLK_I2C] = mpc512x_clk_gated("i2c", "ips",
627 &clkregs->sccr2, 26);
628 /* MSCAN differs from PSC with just one gate for multiple components */
629 clks[MPC512x_CLK_BDLC] = mpc512x_clk_gated("bdlc", "ips",
630 &clkregs->sccr2, 25);
631 for (mclk_idx = 0; mclk_idx < ARRAY_SIZE(mclk_mscan_data); mclk_idx++)
632 mpc512x_clk_setup_mclk(&mclk_mscan_data[mclk_idx], mclk_idx);
633 clks[MPC512x_CLK_SDHC] = mpc512x_clk_gated("sdhc", "sdhc-ug",
634 &clkregs->sccr2, 24);
635 /* there is only one SPDIF component, which shares MCLK support code */
636 clks[MPC512x_CLK_SPDIF] = mpc512x_clk_gated("spdif", "ips",
637 &clkregs->sccr2, 23);
638 mpc512x_clk_setup_mclk(&mclk_spdif_data[0], 0);
639 clks[MPC512x_CLK_MBX_BUS] = mpc512x_clk_gated("mbx-bus", "mbx-bus-ug",
640 &clkregs->sccr2, 22);
641 clks[MPC512x_CLK_MBX] = mpc512x_clk_gated("mbx", "mbx-ug",
642 &clkregs->sccr2, 21);
643 clks[MPC512x_CLK_MBX_3D] = mpc512x_clk_gated("mbx-3d", "mbx-3d-ug",
644 &clkregs->sccr2, 20);
645 clks[MPC512x_CLK_IIM] = mpc512x_clk_gated("iim", "csb",
646 &clkregs->sccr2, 19);
647 clks[MPC512x_CLK_VIU] = mpc512x_clk_gated("viu", "csb",
648 &clkregs->sccr2, 18);
649 clks[MPC512x_CLK_SDHC_2] = mpc512x_clk_gated("sdhc-2", "sdhc-ug",
650 &clkregs->sccr2, 17);
651
652 /*
653 * externally provided clocks (when implemented in hardware,
654 * device tree may specify values which otherwise were unknown)
655 */
656 freq = get_freq_from_dt("psc_mclk_in");
657 if (!freq)
658 freq = 25000000;
659 clks[MPC512x_CLK_PSC_MCLK_IN] = mpc512x_clk_fixed("psc_mclk_in", freq);
660 freq = get_freq_from_dt("spdif_tx_in");
661 clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed("spdif_tx_in", freq);
662 freq = get_freq_from_dt("spdif_rx_in");
663 clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed("spdif_rx_in", freq);
664
665 /* fixed frequency for AC97, always 24.567MHz */
666 clks[MPC512x_CLK_AC97] = mpc512x_clk_fixed("ac97", 24567000);
667
668 /*
669 * pre-enable those "internal" clock items which never get
670 * claimed by any peripheral driver, to not have the clock
671 * subsystem disable them late at startup
672 */
673 clk_prepare_enable(clks[MPC512x_CLK_DUMMY]);
674 clk_prepare_enable(clks[MPC512x_CLK_E300]); /* PowerPC CPU */
675 clk_prepare_enable(clks[MPC512x_CLK_DDR]); /* DRAM */
676 clk_prepare_enable(clks[MPC512x_CLK_MEM]); /* SRAM */
677 clk_prepare_enable(clks[MPC512x_CLK_IPS]); /* SoC periph */
678 clk_prepare_enable(clks[MPC512x_CLK_LPC]); /* boot media */
679}
680
681/*
682 * registers the set of public clocks (those listed in the dt-bindings/
683 * header file) for OF lookups, keeps the intermediates private to us
684 */
685static void mpc5121_clk_register_of_provider(struct device_node *np)
686{
687 clk_data.clks = clks;
688 clk_data.clk_num = MPC512x_CLK_LAST_PUBLIC + 1; /* _not_ ARRAY_SIZE() */
689 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
690}
691
692/*
693 * temporary support for the period of time between introduction of CCF
694 * support and the adjustment of peripheral drivers to OF based lookups
695 */
696static void mpc5121_clk_provide_migration_support(void)
697{
698 int idx;
699 char name[32];
700
701 /*
702 * provide "pre-CCF" alias clock names for peripheral drivers
703 * which have not yet been adjusted to do OF based clock lookups
704 */
705 clk_register_clkdev(clks[MPC512x_CLK_REF], "ref_clk", NULL);
706 clk_register_clkdev(clks[MPC512x_CLK_SYS], "sys_clk", NULL);
707 clk_register_clkdev(clks[MPC512x_CLK_VIU], "viu_clk", NULL);
708 clk_register_clkdev(clks[MPC512x_CLK_NFC], "nfc_clk", NULL);
709 clk_register_clkdev(clks[MPC512x_CLK_USB1], "usb1_clk", NULL);
710 clk_register_clkdev(clks[MPC512x_CLK_USB2], "usb2_clk", NULL);
711 for (idx = 0; idx < NR_PSCS; idx++) {
712 snprintf(name, sizeof(name), "psc%d_mclk", idx);
713 clk_register_clkdev(clks[MPC512x_CLK_PSC0_MCLK + idx],
714 name, NULL);
715 }
716 for (idx = 0; idx < NR_MSCANS; idx++) {
717 snprintf(name, sizeof(name), "mscan%d_mclk", idx);
718 clk_register_clkdev(clks[MPC512x_CLK_MSCAN0_MCLK + idx],
719 name, NULL);
720 }
721 clk_register_clkdev(clks[MPC512x_CLK_SPDIF_MCLK], "spdif_mclk", NULL);
722
723 /*
724 * pre-enable those clock items which are not yet appropriately
725 * acquired by their peripheral driver
726 */
727 clk_prepare_enable(clks[MPC512x_CLK_PSC_FIFO]);
728 clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console */
729 clk_prepare_enable(clks[MPC512x_CLK_FEC]); /* network, NFS */
730 clk_prepare_enable(clks[MPC512x_CLK_DIU]); /* display */
731 clk_prepare_enable(clks[MPC512x_CLK_I2C]); /* I2C */
732 for (idx = 0; idx < NR_PSCS; idx++) /* PSC ipg */
733 clk_prepare_enable(clks[MPC512x_CLK_PSC0 + idx]);
734 clk_prepare_enable(clks[MPC512x_CLK_BDLC]); /* MSCAN ipg */
735 for (idx = 0; idx < NR_MSCANS; idx++) /* MSCAN mclk */
736 clk_prepare_enable(clks[MPC512x_CLK_MSCAN0_MCLK + idx]);
737 clk_prepare_enable(clks[MPC512x_CLK_PCI]); /* PCI */
738}
739
740/*
741 * register source code provided fallback results for clock lookups,
742 * these get consulted when OF based clock lookup fails (that is in the
743 * case of not yet adjusted device tree data, where clock related specs
744 * are missing)
745 */
746static void mpc5121_clk_provide_backwards_compat(void)
747{
748 /* TODO */
749}
750
751int __init mpc5121_clk_init(void)
752{
753 struct device_node *clk_np;
754 int busfreq;
755
756 /* map the clock control registers */
757 clk_np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock");
758 if (!clk_np)
759 return -ENODEV;
760 clkregs = of_iomap(clk_np, 0);
761 WARN_ON(!clkregs);
762
763 /* invalidate all not yet registered clock slots */
764 mpc512x_clk_preset_data();
765
766 /*
767 * have the device tree scanned for "fixed-clock" nodes (which
768 * includes the oscillator node if the board's DT provides one)
769 */
770 of_clk_init(NULL);
771
772 /*
773 * add a dummy clock for those situations where a clock spec is
774 * required yet no real clock is involved
775 */
776 clks[MPC512x_CLK_DUMMY] = mpc512x_clk_fixed("dummy", 0);
777
778 /*
779 * have all the real nodes in the clock tree populated from REF
780 * down to all leaves, either starting from the OSC node or from
781 * a REF root that was created from the IPS bus clock input
782 */
783 busfreq = get_freq_from_dt("bus-frequency");
784 mpc512x_clk_setup_clock_tree(clk_np, busfreq);
785
786 /* register as an OF clock provider */
787 mpc5121_clk_register_of_provider(clk_np);
788
789 /*
790 * unbreak not yet adjusted peripheral drivers during migration
791 * towards fully operational common clock support, and allow
792 * operation in the absence of clock related device tree specs
793 */
794 mpc5121_clk_provide_migration_support();
795 mpc5121_clk_provide_backwards_compat();
796
797 return 0;
798}