aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig9
-rw-r--r--arch/arm/mach-mmp/Kconfig3
-rw-r--r--arch/arm/mach-prima2/Makefile1
-rw-r--r--arch/arm/mach-prima2/clock.c510
-rw-r--r--arch/arm/mach-prima2/prima2.c1
-rw-r--r--arch/arm/mach-prima2/timer.c8
-rw-r--r--arch/arm/mach-realview/core.c106
-rw-r--r--arch/arm/mach-realview/include/mach/clkdev.h16
-rw-r--r--arch/arm/mach-realview/realview_eb.c2
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c2
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c2
-rw-r--r--arch/arm/mach-realview/realview_pba8.c2
-rw-r--r--arch/arm/mach-realview/realview_pbx.c2
-rw-r--r--arch/arm/mach-ux500/Kconfig1
-rw-r--r--arch/arm/mach-ux500/Makefile2
-rw-r--r--arch/arm/mach-ux500/clock.c715
-rw-r--r--arch/arm/mach-ux500/clock.h164
-rw-r--r--arch/arm/mach-ux500/cpu.c14
18 files changed, 34 insertions, 1526 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2f88d8d97701..de325f4615bd 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -273,7 +273,7 @@ config ARCH_INTEGRATOR
273 select ARM_AMBA 273 select ARM_AMBA
274 select ARCH_HAS_CPUFREQ 274 select ARCH_HAS_CPUFREQ
275 select COMMON_CLK 275 select COMMON_CLK
276 select CLK_VERSATILE 276 select COMMON_CLK_VERSATILE
277 select HAVE_TCM 277 select HAVE_TCM
278 select ICST 278 select ICST
279 select GENERIC_CLOCKEVENTS 279 select GENERIC_CLOCKEVENTS
@@ -289,13 +289,12 @@ config ARCH_INTEGRATOR
289config ARCH_REALVIEW 289config ARCH_REALVIEW
290 bool "ARM Ltd. RealView family" 290 bool "ARM Ltd. RealView family"
291 select ARM_AMBA 291 select ARM_AMBA
292 select CLKDEV_LOOKUP 292 select COMMON_CLK
293 select HAVE_MACH_CLKDEV 293 select COMMON_CLK_VERSATILE
294 select ICST 294 select ICST
295 select GENERIC_CLOCKEVENTS 295 select GENERIC_CLOCKEVENTS
296 select ARCH_WANT_OPTIONAL_GPIOLIB 296 select ARCH_WANT_OPTIONAL_GPIOLIB
297 select PLAT_VERSATILE 297 select PLAT_VERSATILE
298 select PLAT_VERSATILE_CLOCK
299 select PLAT_VERSATILE_CLCD 298 select PLAT_VERSATILE_CLCD
300 select ARM_TIMER_SP804 299 select ARM_TIMER_SP804
301 select GPIO_PL061 if GPIOLIB 300 select GPIO_PL061 if GPIOLIB
@@ -413,7 +412,7 @@ config ARCH_PRIMA2
413 select NO_IOPORT 412 select NO_IOPORT
414 select ARCH_REQUIRE_GPIOLIB 413 select ARCH_REQUIRE_GPIOLIB
415 select GENERIC_CLOCKEVENTS 414 select GENERIC_CLOCKEVENTS
416 select CLKDEV_LOOKUP 415 select COMMON_CLK
417 select GENERIC_IRQ_CHIP 416 select GENERIC_IRQ_CHIP
418 select MIGHT_HAVE_CACHE_L2X0 417 select MIGHT_HAVE_CACHE_L2X0
419 select PINCTRL 418 select PINCTRL
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index 7fddd01b85b9..d697d07a1bf0 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -108,18 +108,21 @@ endmenu
108config CPU_PXA168 108config CPU_PXA168
109 bool 109 bool
110 select CPU_MOHAWK 110 select CPU_MOHAWK
111 select COMMON_CLK
111 help 112 help
112 Select code specific to PXA168 113 Select code specific to PXA168
113 114
114config CPU_PXA910 115config CPU_PXA910
115 bool 116 bool
116 select CPU_MOHAWK 117 select CPU_MOHAWK
118 select COMMON_CLK
117 help 119 help
118 Select code specific to PXA910 120 Select code specific to PXA910
119 121
120config CPU_MMP2 122config CPU_MMP2
121 bool 123 bool
122 select CPU_PJ4 124 select CPU_PJ4
125 select COMMON_CLK
123 help 126 help
124 Select code specific to MMP2. MMP2 is ARMv7 compatible. 127 Select code specific to MMP2. MMP2 is ARMv7 compatible.
125 128
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
index 13dd1604d951..841847d56032 100644
--- a/arch/arm/mach-prima2/Makefile
+++ b/arch/arm/mach-prima2/Makefile
@@ -1,6 +1,5 @@
1obj-y := timer.o 1obj-y := timer.o
2obj-y += irq.o 2obj-y += irq.o
3obj-y += clock.o
4obj-y += rstc.o 3obj-y += rstc.o
5obj-y += prima2.o 4obj-y += prima2.o
6obj-y += rtciobrg.o 5obj-y += rtciobrg.o
diff --git a/arch/arm/mach-prima2/clock.c b/arch/arm/mach-prima2/clock.c
deleted file mode 100644
index aebad7e565cf..000000000000
--- a/arch/arm/mach-prima2/clock.c
+++ /dev/null
@@ -1,510 +0,0 @@
1/*
2 * Clock tree for CSR SiRFprimaII
3 *
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#include <linux/module.h>
10#include <linux/bitops.h>
11#include <linux/err.h>
12#include <linux/errno.h>
13#include <linux/io.h>
14#include <linux/clkdev.h>
15#include <linux/clk.h>
16#include <linux/spinlock.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <asm/mach/map.h>
20#include <mach/map.h>
21
22#define SIRFSOC_CLKC_CLK_EN0 0x0000
23#define SIRFSOC_CLKC_CLK_EN1 0x0004
24#define SIRFSOC_CLKC_REF_CFG 0x0014
25#define SIRFSOC_CLKC_CPU_CFG 0x0018
26#define SIRFSOC_CLKC_MEM_CFG 0x001c
27#define SIRFSOC_CLKC_SYS_CFG 0x0020
28#define SIRFSOC_CLKC_IO_CFG 0x0024
29#define SIRFSOC_CLKC_DSP_CFG 0x0028
30#define SIRFSOC_CLKC_GFX_CFG 0x002c
31#define SIRFSOC_CLKC_MM_CFG 0x0030
32#define SIRFSOC_LKC_LCD_CFG 0x0034
33#define SIRFSOC_CLKC_MMC_CFG 0x0038
34#define SIRFSOC_CLKC_PLL1_CFG0 0x0040
35#define SIRFSOC_CLKC_PLL2_CFG0 0x0044
36#define SIRFSOC_CLKC_PLL3_CFG0 0x0048
37#define SIRFSOC_CLKC_PLL1_CFG1 0x004c
38#define SIRFSOC_CLKC_PLL2_CFG1 0x0050
39#define SIRFSOC_CLKC_PLL3_CFG1 0x0054
40#define SIRFSOC_CLKC_PLL1_CFG2 0x0058
41#define SIRFSOC_CLKC_PLL2_CFG2 0x005c
42#define SIRFSOC_CLKC_PLL3_CFG2 0x0060
43
44#define SIRFSOC_CLOCK_VA_BASE SIRFSOC_VA(0x005000)
45
46#define KHZ 1000
47#define MHZ (KHZ * KHZ)
48
49struct clk_ops {
50 unsigned long (*get_rate)(struct clk *clk);
51 long (*round_rate)(struct clk *clk, unsigned long rate);
52 int (*set_rate)(struct clk *clk, unsigned long rate);
53 int (*enable)(struct clk *clk);
54 int (*disable)(struct clk *clk);
55 struct clk *(*get_parent)(struct clk *clk);
56 int (*set_parent)(struct clk *clk, struct clk *parent);
57};
58
59struct clk {
60 struct clk *parent; /* parent clk */
61 unsigned long rate; /* clock rate in Hz */
62 signed char usage; /* clock enable count */
63 signed char enable_bit; /* enable bit: 0 ~ 63 */
64 unsigned short regofs; /* register offset */
65 struct clk_ops *ops; /* clock operation */
66};
67
68static DEFINE_SPINLOCK(clocks_lock);
69
70static inline unsigned long clkc_readl(unsigned reg)
71{
72 return readl(SIRFSOC_CLOCK_VA_BASE + reg);
73}
74
75static inline void clkc_writel(u32 val, unsigned reg)
76{
77 writel(val, SIRFSOC_CLOCK_VA_BASE + reg);
78}
79
80/*
81 * osc_rtc - real time oscillator - 32.768KHz
82 * osc_sys - high speed oscillator - 26MHz
83 */
84
85static struct clk clk_rtc = {
86 .rate = 32768,
87};
88
89static struct clk clk_osc = {
90 .rate = 26 * MHZ,
91};
92
93/*
94 * std pll
95 */
96static unsigned long std_pll_get_rate(struct clk *clk)
97{
98 unsigned long fin = clk_get_rate(clk->parent);
99 u32 regcfg2 = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 -
100 SIRFSOC_CLKC_PLL1_CFG0;
101
102 if (clkc_readl(regcfg2) & BIT(2)) {
103 /* pll bypass mode */
104 clk->rate = fin;
105 } else {
106 /* fout = fin * nf / nr / od */
107 u32 cfg0 = clkc_readl(clk->regofs);
108 u32 nf = (cfg0 & (BIT(13) - 1)) + 1;
109 u32 nr = ((cfg0 >> 13) & (BIT(6) - 1)) + 1;
110 u32 od = ((cfg0 >> 19) & (BIT(4) - 1)) + 1;
111 WARN_ON(fin % MHZ);
112 clk->rate = fin / MHZ * nf / nr / od * MHZ;
113 }
114
115 return clk->rate;
116}
117
118static int std_pll_set_rate(struct clk *clk, unsigned long rate)
119{
120 unsigned long fin, nf, nr, od, reg;
121
122 /*
123 * fout = fin * nf / (nr * od);
124 * set od = 1, nr = fin/MHz, so fout = nf * MHz
125 */
126
127 nf = rate / MHZ;
128 if (unlikely((rate % MHZ) || nf > BIT(13) || nf < 1))
129 return -EINVAL;
130
131 fin = clk_get_rate(clk->parent);
132 BUG_ON(fin < MHZ);
133
134 nr = fin / MHZ;
135 BUG_ON((fin % MHZ) || nr > BIT(6));
136
137 od = 1;
138
139 reg = (nf - 1) | ((nr - 1) << 13) | ((od - 1) << 19);
140 clkc_writel(reg, clk->regofs);
141
142 reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG1 - SIRFSOC_CLKC_PLL1_CFG0;
143 clkc_writel((nf >> 1) - 1, reg);
144
145 reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - SIRFSOC_CLKC_PLL1_CFG0;
146 while (!(clkc_readl(reg) & BIT(6)))
147 cpu_relax();
148
149 clk->rate = 0; /* set to zero will force recalculation */
150 return 0;
151}
152
153static struct clk_ops std_pll_ops = {
154 .get_rate = std_pll_get_rate,
155 .set_rate = std_pll_set_rate,
156};
157
158static struct clk clk_pll1 = {
159 .parent = &clk_osc,
160 .regofs = SIRFSOC_CLKC_PLL1_CFG0,
161 .ops = &std_pll_ops,
162};
163
164static struct clk clk_pll2 = {
165 .parent = &clk_osc,
166 .regofs = SIRFSOC_CLKC_PLL2_CFG0,
167 .ops = &std_pll_ops,
168};
169
170static struct clk clk_pll3 = {
171 .parent = &clk_osc,
172 .regofs = SIRFSOC_CLKC_PLL3_CFG0,
173 .ops = &std_pll_ops,
174};
175
176/*
177 * clock domains - cpu, mem, sys/io
178 */
179
180static struct clk clk_mem;
181
182static struct clk *dmn_get_parent(struct clk *clk)
183{
184 struct clk *clks[] = {
185 &clk_osc, &clk_rtc, &clk_pll1, &clk_pll2, &clk_pll3
186 };
187 u32 cfg = clkc_readl(clk->regofs);
188 WARN_ON((cfg & (BIT(3) - 1)) > 4);
189 return clks[cfg & (BIT(3) - 1)];
190}
191
192static int dmn_set_parent(struct clk *clk, struct clk *parent)
193{
194 const struct clk *clks[] = {
195 &clk_osc, &clk_rtc, &clk_pll1, &clk_pll2, &clk_pll3
196 };
197 u32 cfg = clkc_readl(clk->regofs);
198 int i;
199 for (i = 0; i < ARRAY_SIZE(clks); i++) {
200 if (clks[i] == parent) {
201 cfg &= ~(BIT(3) - 1);
202 clkc_writel(cfg | i, clk->regofs);
203 /* BIT(3) - switching status: 1 - busy, 0 - done */
204 while (clkc_readl(clk->regofs) & BIT(3))
205 cpu_relax();
206 return 0;
207 }
208 }
209 return -EINVAL;
210}
211
212static unsigned long dmn_get_rate(struct clk *clk)
213{
214 unsigned long fin = clk_get_rate(clk->parent);
215 u32 cfg = clkc_readl(clk->regofs);
216 if (cfg & BIT(24)) {
217 /* fcd bypass mode */
218 clk->rate = fin;
219 } else {
220 /*
221 * wait count: bit[19:16], hold count: bit[23:20]
222 */
223 u32 wait = (cfg >> 16) & (BIT(4) - 1);
224 u32 hold = (cfg >> 20) & (BIT(4) - 1);
225
226 clk->rate = fin / (wait + hold + 2);
227 }
228
229 return clk->rate;
230}
231
232static int dmn_set_rate(struct clk *clk, unsigned long rate)
233{
234 unsigned long fin;
235 unsigned ratio, wait, hold, reg;
236 unsigned bits = (clk == &clk_mem) ? 3 : 4;
237
238 fin = clk_get_rate(clk->parent);
239 ratio = fin / rate;
240
241 if (unlikely(ratio < 2 || ratio > BIT(bits + 1)))
242 return -EINVAL;
243
244 WARN_ON(fin % rate);
245
246 wait = (ratio >> 1) - 1;
247 hold = ratio - wait - 2;
248
249 reg = clkc_readl(clk->regofs);
250 reg &= ~(((BIT(bits) - 1) << 16) | ((BIT(bits) - 1) << 20));
251 reg |= (wait << 16) | (hold << 20) | BIT(25);
252 clkc_writel(reg, clk->regofs);
253
254 /* waiting FCD been effective */
255 while (clkc_readl(clk->regofs) & BIT(25))
256 cpu_relax();
257
258 clk->rate = 0; /* set to zero will force recalculation */
259
260 return 0;
261}
262
263/*
264 * cpu clock has no FCD register in Prima2, can only change pll
265 */
266static int cpu_set_rate(struct clk *clk, unsigned long rate)
267{
268 int ret1, ret2;
269 struct clk *cur_parent, *tmp_parent;
270
271 cur_parent = dmn_get_parent(clk);
272 BUG_ON(cur_parent == NULL || cur_parent->usage > 1);
273
274 /* switch to tmp pll before setting parent clock's rate */
275 tmp_parent = cur_parent == &clk_pll1 ? &clk_pll2 : &clk_pll1;
276 ret1 = dmn_set_parent(clk, tmp_parent);
277 BUG_ON(ret1);
278
279 ret2 = clk_set_rate(cur_parent, rate);
280
281 ret1 = dmn_set_parent(clk, cur_parent);
282
283 clk->rate = 0; /* set to zero will force recalculation */
284
285 return ret2 ? ret2 : ret1;
286}
287
288static struct clk_ops cpu_ops = {
289 .get_parent = dmn_get_parent,
290 .set_parent = dmn_set_parent,
291 .set_rate = cpu_set_rate,
292};
293
294static struct clk clk_cpu = {
295 .parent = &clk_pll1,
296 .regofs = SIRFSOC_CLKC_CPU_CFG,
297 .ops = &cpu_ops,
298};
299
300
301static struct clk_ops msi_ops = {
302 .set_rate = dmn_set_rate,
303 .get_rate = dmn_get_rate,
304 .set_parent = dmn_set_parent,
305 .get_parent = dmn_get_parent,
306};
307
308static struct clk clk_mem = {
309 .parent = &clk_pll2,
310 .regofs = SIRFSOC_CLKC_MEM_CFG,
311 .ops = &msi_ops,
312};
313
314static struct clk clk_sys = {
315 .parent = &clk_pll3,
316 .regofs = SIRFSOC_CLKC_SYS_CFG,
317 .ops = &msi_ops,
318};
319
320static struct clk clk_io = {
321 .parent = &clk_pll3,
322 .regofs = SIRFSOC_CLKC_IO_CFG,
323 .ops = &msi_ops,
324};
325
326/*
327 * on-chip clock sets
328 */
329static struct clk_lookup onchip_clks[] = {
330 {
331 .dev_id = "rtc",
332 .clk = &clk_rtc,
333 }, {
334 .dev_id = "osc",
335 .clk = &clk_osc,
336 }, {
337 .dev_id = "pll1",
338 .clk = &clk_pll1,
339 }, {
340 .dev_id = "pll2",
341 .clk = &clk_pll2,
342 }, {
343 .dev_id = "pll3",
344 .clk = &clk_pll3,
345 }, {
346 .dev_id = "cpu",
347 .clk = &clk_cpu,
348 }, {
349 .dev_id = "mem",
350 .clk = &clk_mem,
351 }, {
352 .dev_id = "sys",
353 .clk = &clk_sys,
354 }, {
355 .dev_id = "io",
356 .clk = &clk_io,
357 },
358};
359
360int clk_enable(struct clk *clk)
361{
362 unsigned long flags;
363
364 if (unlikely(IS_ERR_OR_NULL(clk)))
365 return -EINVAL;
366
367 if (clk->parent)
368 clk_enable(clk->parent);
369
370 spin_lock_irqsave(&clocks_lock, flags);
371 if (!clk->usage++ && clk->ops && clk->ops->enable)
372 clk->ops->enable(clk);
373 spin_unlock_irqrestore(&clocks_lock, flags);
374 return 0;
375}
376EXPORT_SYMBOL(clk_enable);
377
378void clk_disable(struct clk *clk)
379{
380 unsigned long flags;
381
382 if (unlikely(IS_ERR_OR_NULL(clk)))
383 return;
384
385 WARN_ON(!clk->usage);
386
387 spin_lock_irqsave(&clocks_lock, flags);
388 if (--clk->usage == 0 && clk->ops && clk->ops->disable)
389 clk->ops->disable(clk);
390 spin_unlock_irqrestore(&clocks_lock, flags);
391
392 if (clk->parent)
393 clk_disable(clk->parent);
394}
395EXPORT_SYMBOL(clk_disable);
396
397unsigned long clk_get_rate(struct clk *clk)
398{
399 if (unlikely(IS_ERR_OR_NULL(clk)))
400 return 0;
401
402 if (clk->rate)
403 return clk->rate;
404
405 if (clk->ops && clk->ops->get_rate)
406 return clk->ops->get_rate(clk);
407
408 return clk_get_rate(clk->parent);
409}
410EXPORT_SYMBOL(clk_get_rate);
411
412long clk_round_rate(struct clk *clk, unsigned long rate)
413{
414 if (unlikely(IS_ERR_OR_NULL(clk)))
415 return 0;
416
417 if (clk->ops && clk->ops->round_rate)
418 return clk->ops->round_rate(clk, rate);
419
420 return 0;
421}
422EXPORT_SYMBOL(clk_round_rate);
423
424int clk_set_rate(struct clk *clk, unsigned long rate)
425{
426 if (unlikely(IS_ERR_OR_NULL(clk)))
427 return -EINVAL;
428
429 if (!clk->ops || !clk->ops->set_rate)
430 return -EINVAL;
431
432 return clk->ops->set_rate(clk, rate);
433}
434EXPORT_SYMBOL(clk_set_rate);
435
436int clk_set_parent(struct clk *clk, struct clk *parent)
437{
438 int ret;
439 unsigned long flags;
440
441 if (unlikely(IS_ERR_OR_NULL(clk)))
442 return -EINVAL;
443
444 if (!clk->ops || !clk->ops->set_parent)
445 return -EINVAL;
446
447 spin_lock_irqsave(&clocks_lock, flags);
448 ret = clk->ops->set_parent(clk, parent);
449 if (!ret) {
450 parent->usage += clk->usage;
451 clk->parent->usage -= clk->usage;
452 BUG_ON(clk->parent->usage < 0);
453 clk->parent = parent;
454 }
455 spin_unlock_irqrestore(&clocks_lock, flags);
456 return ret;
457}
458EXPORT_SYMBOL(clk_set_parent);
459
460struct clk *clk_get_parent(struct clk *clk)
461{
462 unsigned long flags;
463
464 if (unlikely(IS_ERR_OR_NULL(clk)))
465 return NULL;
466
467 if (!clk->ops || !clk->ops->get_parent)
468 return clk->parent;
469
470 spin_lock_irqsave(&clocks_lock, flags);
471 clk->parent = clk->ops->get_parent(clk);
472 spin_unlock_irqrestore(&clocks_lock, flags);
473 return clk->parent;
474}
475EXPORT_SYMBOL(clk_get_parent);
476
477static void __init sirfsoc_clk_init(void)
478{
479 clkdev_add_table(onchip_clks, ARRAY_SIZE(onchip_clks));
480}
481
482static struct of_device_id clkc_ids[] = {
483 { .compatible = "sirf,prima2-clkc" },
484 {},
485};
486
487void __init sirfsoc_of_clk_init(void)
488{
489 struct device_node *np;
490 struct resource res;
491 struct map_desc sirfsoc_clkc_iodesc = {
492 .virtual = SIRFSOC_CLOCK_VA_BASE,
493 .type = MT_DEVICE,
494 };
495
496 np = of_find_matching_node(NULL, clkc_ids);
497 if (!np)
498 panic("unable to find compatible clkc node in dtb\n");
499
500 if (of_address_to_resource(np, 0, &res))
501 panic("unable to find clkc range in dtb");
502 of_node_put(np);
503
504 sirfsoc_clkc_iodesc.pfn = __phys_to_pfn(res.start);
505 sirfsoc_clkc_iodesc.length = 1 + res.end - res.start;
506
507 iotable_init(&sirfsoc_clkc_iodesc, 1);
508
509 sirfsoc_clk_init();
510}
diff --git a/arch/arm/mach-prima2/prima2.c b/arch/arm/mach-prima2/prima2.c
index 8f0429d4b79f..e9a17aebe0d6 100644
--- a/arch/arm/mach-prima2/prima2.c
+++ b/arch/arm/mach-prima2/prima2.c
@@ -38,7 +38,6 @@ static const char *prima2cb_dt_match[] __initdata = {
38MACHINE_START(PRIMA2_EVB, "prima2cb") 38MACHINE_START(PRIMA2_EVB, "prima2cb")
39 /* Maintainer: Barry Song <baohua.song@csr.com> */ 39 /* Maintainer: Barry Song <baohua.song@csr.com> */
40 .atag_offset = 0x100, 40 .atag_offset = 0x100,
41 .init_early = sirfsoc_of_clk_init,
42 .map_io = sirfsoc_map_lluart, 41 .map_io = sirfsoc_map_lluart,
43 .init_irq = sirfsoc_of_irq_init, 42 .init_irq = sirfsoc_of_irq_init,
44 .timer = &sirfsoc_timer, 43 .timer = &sirfsoc_timer,
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c
index f224107de7bc..d95bf252f694 100644
--- a/arch/arm/mach-prima2/timer.c
+++ b/arch/arm/mach-prima2/timer.c
@@ -21,6 +21,8 @@
21#include <asm/sched_clock.h> 21#include <asm/sched_clock.h>
22#include <asm/mach/time.h> 22#include <asm/mach/time.h>
23 23
24#include "common.h"
25
24#define SIRFSOC_TIMER_COUNTER_LO 0x0000 26#define SIRFSOC_TIMER_COUNTER_LO 0x0000
25#define SIRFSOC_TIMER_COUNTER_HI 0x0004 27#define SIRFSOC_TIMER_COUNTER_HI 0x0004
26#define SIRFSOC_TIMER_MATCH_0 0x0008 28#define SIRFSOC_TIMER_MATCH_0 0x0008
@@ -188,9 +190,13 @@ static void __init sirfsoc_clockevent_init(void)
188static void __init sirfsoc_timer_init(void) 190static void __init sirfsoc_timer_init(void)
189{ 191{
190 unsigned long rate; 192 unsigned long rate;
193 struct clk *clk;
194
195 /* initialize clocking early, we want to set the OS timer */
196 sirfsoc_of_clk_init();
191 197
192 /* timer's input clock is io clock */ 198 /* timer's input clock is io clock */
193 struct clk *clk = clk_get_sys("io", NULL); 199 clk = clk_get_sys("io", NULL);
194 200
195 BUG_ON(IS_ERR(clk)); 201 BUG_ON(IS_ERR(clk));
196 202
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 45868bb43cbd..ff007d15e0ec 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -30,7 +30,6 @@
30#include <linux/ata_platform.h> 30#include <linux/ata_platform.h>
31#include <linux/amba/mmci.h> 31#include <linux/amba/mmci.h>
32#include <linux/gfp.h> 32#include <linux/gfp.h>
33#include <linux/clkdev.h>
34#include <linux/mtd/physmap.h> 33#include <linux/mtd/physmap.h>
35 34
36#include <mach/hardware.h> 35#include <mach/hardware.h>
@@ -226,115 +225,10 @@ struct mmci_platform_data realview_mmc1_plat_data = {
226 .cd_invert = true, 225 .cd_invert = true,
227}; 226};
228 227
229/*
230 * Clock handling
231 */
232static const struct icst_params realview_oscvco_params = {
233 .ref = 24000000,
234 .vco_max = ICST307_VCO_MAX,
235 .vco_min = ICST307_VCO_MIN,
236 .vd_min = 4 + 8,
237 .vd_max = 511 + 8,
238 .rd_min = 1 + 2,
239 .rd_max = 127 + 2,
240 .s2div = icst307_s2div,
241 .idx2s = icst307_idx2s,
242};
243
244static void realview_oscvco_set(struct clk *clk, struct icst_vco vco)
245{
246 void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
247 u32 val;
248
249 val = readl(clk->vcoreg) & ~0x7ffff;
250 val |= vco.v | (vco.r << 9) | (vco.s << 16);
251
252 writel(0xa05f, sys_lock);
253 writel(val, clk->vcoreg);
254 writel(0, sys_lock);
255}
256
257static const struct clk_ops oscvco_clk_ops = {
258 .round = icst_clk_round,
259 .set = icst_clk_set,
260 .setvco = realview_oscvco_set,
261};
262
263static struct clk oscvco_clk = {
264 .ops = &oscvco_clk_ops,
265 .params = &realview_oscvco_params,
266};
267
268/*
269 * These are fixed clocks.
270 */
271static struct clk ref24_clk = {
272 .rate = 24000000,
273};
274
275static struct clk sp804_clk = {
276 .rate = 1000000,
277};
278
279static struct clk dummy_apb_pclk;
280
281static struct clk_lookup lookups[] = {
282 { /* Bus clock */
283 .con_id = "apb_pclk",
284 .clk = &dummy_apb_pclk,
285 }, { /* UART0 */
286 .dev_id = "dev:uart0",
287 .clk = &ref24_clk,
288 }, { /* UART1 */
289 .dev_id = "dev:uart1",
290 .clk = &ref24_clk,
291 }, { /* UART2 */
292 .dev_id = "dev:uart2",
293 .clk = &ref24_clk,
294 }, { /* UART3 */
295 .dev_id = "fpga:uart3",
296 .clk = &ref24_clk,
297 }, { /* UART3 is on the dev chip in PB1176 */
298 .dev_id = "dev:uart3",
299 .clk = &ref24_clk,
300 }, { /* UART4 only exists in PB1176 */
301 .dev_id = "fpga:uart4",
302 .clk = &ref24_clk,
303 }, { /* KMI0 */
304 .dev_id = "fpga:kmi0",
305 .clk = &ref24_clk,
306 }, { /* KMI1 */
307 .dev_id = "fpga:kmi1",
308 .clk = &ref24_clk,
309 }, { /* MMC0 */
310 .dev_id = "fpga:mmc0",
311 .clk = &ref24_clk,
312 }, { /* CLCD is in the PB1176 and EB DevChip */
313 .dev_id = "dev:clcd",
314 .clk = &oscvco_clk,
315 }, { /* PB:CLCD */
316 .dev_id = "issp:clcd",
317 .clk = &oscvco_clk,
318 }, { /* SSP */
319 .dev_id = "dev:ssp0",
320 .clk = &ref24_clk,
321 }, { /* SP804 timers */
322 .dev_id = "sp804",
323 .clk = &sp804_clk,
324 },
325};
326
327void __init realview_init_early(void) 228void __init realview_init_early(void)
328{ 229{
329 void __iomem *sys = __io_address(REALVIEW_SYS_BASE); 230 void __iomem *sys = __io_address(REALVIEW_SYS_BASE);
330 231
331 if (machine_is_realview_pb1176())
332 oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC0_OFFSET;
333 else
334 oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC4_OFFSET;
335
336 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
337
338 versatile_sched_clock_init(sys + REALVIEW_SYS_24MHz_OFFSET, 24000000); 232 versatile_sched_clock_init(sys + REALVIEW_SYS_24MHz_OFFSET, 24000000);
339} 233}
340 234
diff --git a/arch/arm/mach-realview/include/mach/clkdev.h b/arch/arm/mach-realview/include/mach/clkdev.h
deleted file mode 100644
index e58d0771b64e..000000000000
--- a/arch/arm/mach-realview/include/mach/clkdev.h
+++ /dev/null
@@ -1,16 +0,0 @@
1#ifndef __ASM_MACH_CLKDEV_H
2#define __ASM_MACH_CLKDEV_H
3
4#include <plat/clock.h>
5
6struct clk {
7 unsigned long rate;
8 const struct clk_ops *ops;
9 const struct icst_params *params;
10 void __iomem *vcoreg;
11};
12
13#define __clk_get(clk) ({ 1; })
14#define __clk_put(clk) do { } while (0)
15
16#endif
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index baf382c5e776..a33e33b76733 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -27,6 +27,7 @@
27#include <linux/amba/mmci.h> 27#include <linux/amba/mmci.h>
28#include <linux/amba/pl022.h> 28#include <linux/amba/pl022.h>
29#include <linux/io.h> 29#include <linux/io.h>
30#include <linux/platform_data/clk-realview.h>
30 31
31#include <mach/hardware.h> 32#include <mach/hardware.h>
32#include <asm/irq.h> 33#include <asm/irq.h>
@@ -414,6 +415,7 @@ static void __init realview_eb_timer_init(void)
414 else 415 else
415 timer_irq = IRQ_EB_TIMER0_1; 416 timer_irq = IRQ_EB_TIMER0_1;
416 417
418 realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
417 realview_timer_init(timer_irq); 419 realview_timer_init(timer_irq);
418 realview_eb_twd_init(); 420 realview_eb_twd_init();
419} 421}
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index b1d7cafa1a6d..f0298cbc203e 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -29,6 +29,7 @@
29#include <linux/mtd/physmap.h> 29#include <linux/mtd/physmap.h>
30#include <linux/mtd/partitions.h> 30#include <linux/mtd/partitions.h>
31#include <linux/io.h> 31#include <linux/io.h>
32#include <linux/platform_data/clk-realview.h>
32 33
33#include <mach/hardware.h> 34#include <mach/hardware.h>
34#include <asm/irq.h> 35#include <asm/irq.h>
@@ -326,6 +327,7 @@ static void __init realview_pb1176_timer_init(void)
326 timer2_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE); 327 timer2_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE);
327 timer3_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE) + 0x20; 328 timer3_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE) + 0x20;
328 329
330 realview_clk_init(__io_address(REALVIEW_SYS_BASE), true);
329 realview_timer_init(IRQ_DC1176_TIMER0); 331 realview_timer_init(IRQ_DC1176_TIMER0);
330} 332}
331 333
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index a98c536e3327..1f019f76f7b5 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -27,6 +27,7 @@
27#include <linux/amba/mmci.h> 27#include <linux/amba/mmci.h>
28#include <linux/amba/pl022.h> 28#include <linux/amba/pl022.h>
29#include <linux/io.h> 29#include <linux/io.h>
30#include <linux/platform_data/clk-realview.h>
30 31
31#include <mach/hardware.h> 32#include <mach/hardware.h>
32#include <asm/irq.h> 33#include <asm/irq.h>
@@ -312,6 +313,7 @@ static void __init realview_pb11mp_timer_init(void)
312 timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE); 313 timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE);
313 timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20; 314 timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20;
314 315
316 realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
315 realview_timer_init(IRQ_TC11MP_TIMER0_1); 317 realview_timer_init(IRQ_TC11MP_TIMER0_1);
316 realview_pb11mp_twd_init(); 318 realview_pb11mp_twd_init();
317} 319}
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 59650174e6ed..5032775dbfee 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -27,6 +27,7 @@
27#include <linux/amba/mmci.h> 27#include <linux/amba/mmci.h>
28#include <linux/amba/pl022.h> 28#include <linux/amba/pl022.h>
29#include <linux/io.h> 29#include <linux/io.h>
30#include <linux/platform_data/clk-realview.h>
30 31
31#include <asm/irq.h> 32#include <asm/irq.h>
32#include <asm/leds.h> 33#include <asm/leds.h>
@@ -261,6 +262,7 @@ static void __init realview_pba8_timer_init(void)
261 timer2_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE); 262 timer2_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE);
262 timer3_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE) + 0x20; 263 timer3_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE) + 0x20;
263 264
265 realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
264 realview_timer_init(IRQ_PBA8_TIMER0_1); 266 realview_timer_init(IRQ_PBA8_TIMER0_1);
265} 267}
266 268
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index 3f2f605624e9..de64ba0ddb95 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -26,6 +26,7 @@
26#include <linux/amba/mmci.h> 26#include <linux/amba/mmci.h>
27#include <linux/amba/pl022.h> 27#include <linux/amba/pl022.h>
28#include <linux/io.h> 28#include <linux/io.h>
29#include <linux/platform_data/clk-realview.h>
29 30
30#include <asm/irq.h> 31#include <asm/irq.h>
31#include <asm/leds.h> 32#include <asm/leds.h>
@@ -320,6 +321,7 @@ static void __init realview_pbx_timer_init(void)
320 timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE); 321 timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE);
321 timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20; 322 timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20;
322 323
324 realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
323 realview_timer_init(IRQ_PBX_TIMER0_1); 325 realview_timer_init(IRQ_PBX_TIMER0_1);
324 realview_pbx_twd_init(); 326 realview_pbx_twd_init();
325} 327}
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 53d3d46dec12..a258996d954b 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -11,6 +11,7 @@ config UX500_SOC_COMMON
11 select CACHE_L2X0 11 select CACHE_L2X0
12 select PINCTRL 12 select PINCTRL
13 select PINCTRL_NOMADIK 13 select PINCTRL_NOMADIK
14 select COMMON_CLK
14 15
15config UX500_SOC_DB8500 16config UX500_SOC_DB8500
16 bool 17 bool
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 026086ff9e6c..5691ef679d01 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the linux kernel, U8500 machine. 2# Makefile for the linux kernel, U8500 machine.
3# 3#
4 4
5obj-y := clock.o cpu.o devices.o devices-common.o \ 5obj-y := cpu.o devices.o devices-common.o \
6 id.o usb.o timer.o 6 id.o usb.o timer.o
7obj-$(CONFIG_CPU_IDLE) += cpuidle.o 7obj-$(CONFIG_CPU_IDLE) += cpuidle.o
8obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o 8obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
deleted file mode 100644
index 8d73b066a18d..000000000000
--- a/arch/arm/mach-ux500/clock.c
+++ /dev/null
@@ -1,715 +0,0 @@
1/*
2 * Copyright (C) 2009 ST-Ericsson
3 * Copyright (C) 2009 STMicroelectronics
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#include <linux/module.h>
10#include <linux/kernel.h>
11#include <linux/list.h>
12#include <linux/errno.h>
13#include <linux/err.h>
14#include <linux/clk.h>
15#include <linux/io.h>
16#include <linux/clkdev.h>
17#include <linux/cpufreq.h>
18
19#include <plat/mtu.h>
20#include <mach/hardware.h>
21#include "clock.h"
22
23#ifdef CONFIG_DEBUG_FS
24#include <linux/debugfs.h>
25#include <linux/uaccess.h> /* for copy_from_user */
26static LIST_HEAD(clk_list);
27#endif
28
29#define PRCC_PCKEN 0x00
30#define PRCC_PCKDIS 0x04
31#define PRCC_KCKEN 0x08
32#define PRCC_KCKDIS 0x0C
33
34#define PRCM_YYCLKEN0_MGT_SET 0x510
35#define PRCM_YYCLKEN1_MGT_SET 0x514
36#define PRCM_YYCLKEN0_MGT_CLR 0x518
37#define PRCM_YYCLKEN1_MGT_CLR 0x51C
38#define PRCM_YYCLKEN0_MGT_VAL 0x520
39#define PRCM_YYCLKEN1_MGT_VAL 0x524
40
41#define PRCM_SVAMMDSPCLK_MGT 0x008
42#define PRCM_SIAMMDSPCLK_MGT 0x00C
43#define PRCM_SGACLK_MGT 0x014
44#define PRCM_UARTCLK_MGT 0x018
45#define PRCM_MSP02CLK_MGT 0x01C
46#define PRCM_MSP1CLK_MGT 0x288
47#define PRCM_I2CCLK_MGT 0x020
48#define PRCM_SDMMCCLK_MGT 0x024
49#define PRCM_SLIMCLK_MGT 0x028
50#define PRCM_PER1CLK_MGT 0x02C
51#define PRCM_PER2CLK_MGT 0x030
52#define PRCM_PER3CLK_MGT 0x034
53#define PRCM_PER5CLK_MGT 0x038
54#define PRCM_PER6CLK_MGT 0x03C
55#define PRCM_PER7CLK_MGT 0x040
56#define PRCM_LCDCLK_MGT 0x044
57#define PRCM_BMLCLK_MGT 0x04C
58#define PRCM_HSITXCLK_MGT 0x050
59#define PRCM_HSIRXCLK_MGT 0x054
60#define PRCM_HDMICLK_MGT 0x058
61#define PRCM_APEATCLK_MGT 0x05C
62#define PRCM_APETRACECLK_MGT 0x060
63#define PRCM_MCDECLK_MGT 0x064
64#define PRCM_IPI2CCLK_MGT 0x068
65#define PRCM_DSIALTCLK_MGT 0x06C
66#define PRCM_DMACLK_MGT 0x074
67#define PRCM_B2R2CLK_MGT 0x078
68#define PRCM_TVCLK_MGT 0x07C
69#define PRCM_TCR 0x1C8
70#define PRCM_TCR_STOPPED (1 << 16)
71#define PRCM_TCR_DOZE_MODE (1 << 17)
72#define PRCM_UNIPROCLK_MGT 0x278
73#define PRCM_SSPCLK_MGT 0x280
74#define PRCM_RNGCLK_MGT 0x284
75#define PRCM_UICCCLK_MGT 0x27C
76
77#define PRCM_MGT_ENABLE (1 << 8)
78
79static DEFINE_SPINLOCK(clocks_lock);
80
81static void __clk_enable(struct clk *clk)
82{
83 if (clk->enabled++ == 0) {
84 if (clk->parent_cluster)
85 __clk_enable(clk->parent_cluster);
86
87 if (clk->parent_periph)
88 __clk_enable(clk->parent_periph);
89
90 if (clk->ops && clk->ops->enable)
91 clk->ops->enable(clk);
92 }
93}
94
95int clk_enable(struct clk *clk)
96{
97 unsigned long flags;
98
99 spin_lock_irqsave(&clocks_lock, flags);
100 __clk_enable(clk);
101 spin_unlock_irqrestore(&clocks_lock, flags);
102
103 return 0;
104}
105EXPORT_SYMBOL(clk_enable);
106
107static void __clk_disable(struct clk *clk)
108{
109 if (--clk->enabled == 0) {
110 if (clk->ops && clk->ops->disable)
111 clk->ops->disable(clk);
112
113 if (clk->parent_periph)
114 __clk_disable(clk->parent_periph);
115
116 if (clk->parent_cluster)
117 __clk_disable(clk->parent_cluster);
118 }
119}
120
121void clk_disable(struct clk *clk)
122{
123 unsigned long flags;
124
125 WARN_ON(!clk->enabled);
126
127 spin_lock_irqsave(&clocks_lock, flags);
128 __clk_disable(clk);
129 spin_unlock_irqrestore(&clocks_lock, flags);
130}
131EXPORT_SYMBOL(clk_disable);
132
133/*
134 * The MTU has a separate, rather complex muxing setup
135 * with alternative parents (peripheral cluster or
136 * ULP or fixed 32768 Hz) depending on settings
137 */
138static unsigned long clk_mtu_get_rate(struct clk *clk)
139{
140 void __iomem *addr;
141 u32 tcr;
142 int mtu = (int) clk->data;
143 /*
144 * One of these is selected eventually
145 * TODO: Replace the constant with a reference
146 * to the ULP source once this is modeled.
147 */
148 unsigned long clk32k = 32768;
149 unsigned long mturate;
150 unsigned long retclk;
151
152 if (cpu_is_u8500_family())
153 addr = __io_address(U8500_PRCMU_BASE);
154 else
155 ux500_unknown_soc();
156
157 /*
158 * On a startup, always conifgure the TCR to the doze mode;
159 * bootloaders do it for us. Do this in the kernel too.
160 */
161 writel(PRCM_TCR_DOZE_MODE, addr + PRCM_TCR);
162
163 tcr = readl(addr + PRCM_TCR);
164
165 /* Get the rate from the parent as a default */
166 if (clk->parent_periph)
167 mturate = clk_get_rate(clk->parent_periph);
168 else if (clk->parent_cluster)
169 mturate = clk_get_rate(clk->parent_cluster);
170 else
171 /* We need to be connected SOMEWHERE */
172 BUG();
173
174 /* Return the clock selected for this MTU */
175 if (tcr & (1 << mtu))
176 retclk = clk32k;
177 else
178 retclk = mturate;
179
180 pr_info("MTU%d clock rate: %lu Hz\n", mtu, retclk);
181 return retclk;
182}
183
184unsigned long clk_get_rate(struct clk *clk)
185{
186 unsigned long rate;
187
188 /*
189 * If there is a custom getrate callback for this clock,
190 * it will take precedence.
191 */
192 if (clk->get_rate)
193 return clk->get_rate(clk);
194
195 if (clk->ops && clk->ops->get_rate)
196 return clk->ops->get_rate(clk);
197
198 rate = clk->rate;
199 if (!rate) {
200 if (clk->parent_periph)
201 rate = clk_get_rate(clk->parent_periph);
202 else if (clk->parent_cluster)
203 rate = clk_get_rate(clk->parent_cluster);
204 }
205
206 return rate;
207}
208EXPORT_SYMBOL(clk_get_rate);
209
210long clk_round_rate(struct clk *clk, unsigned long rate)
211{
212 /*TODO*/
213 return rate;
214}
215EXPORT_SYMBOL(clk_round_rate);
216
217int clk_set_rate(struct clk *clk, unsigned long rate)
218{
219 clk->rate = rate;
220 return 0;
221}
222EXPORT_SYMBOL(clk_set_rate);
223
224int clk_set_parent(struct clk *clk, struct clk *parent)
225{
226 /*TODO*/
227 return -ENOSYS;
228}
229EXPORT_SYMBOL(clk_set_parent);
230
231static void clk_prcmu_enable(struct clk *clk)
232{
233 void __iomem *cg_set_reg = __io_address(U8500_PRCMU_BASE)
234 + PRCM_YYCLKEN0_MGT_SET + clk->prcmu_cg_off;
235
236 writel(1 << clk->prcmu_cg_bit, cg_set_reg);
237}
238
239static void clk_prcmu_disable(struct clk *clk)
240{
241 void __iomem *cg_clr_reg = __io_address(U8500_PRCMU_BASE)
242 + PRCM_YYCLKEN0_MGT_CLR + clk->prcmu_cg_off;
243
244 writel(1 << clk->prcmu_cg_bit, cg_clr_reg);
245}
246
247static struct clkops clk_prcmu_ops = {
248 .enable = clk_prcmu_enable,
249 .disable = clk_prcmu_disable,
250};
251
252static unsigned int clkrst_base[] = {
253 [1] = U8500_CLKRST1_BASE,
254 [2] = U8500_CLKRST2_BASE,
255 [3] = U8500_CLKRST3_BASE,
256 [5] = U8500_CLKRST5_BASE,
257 [6] = U8500_CLKRST6_BASE,
258};
259
260static void clk_prcc_enable(struct clk *clk)
261{
262 void __iomem *addr = __io_address(clkrst_base[clk->cluster]);
263
264 if (clk->prcc_kernel != -1)
265 writel(1 << clk->prcc_kernel, addr + PRCC_KCKEN);
266
267 if (clk->prcc_bus != -1)
268 writel(1 << clk->prcc_bus, addr + PRCC_PCKEN);
269}
270
271static void clk_prcc_disable(struct clk *clk)
272{
273 void __iomem *addr = __io_address(clkrst_base[clk->cluster]);
274
275 if (clk->prcc_bus != -1)
276 writel(1 << clk->prcc_bus, addr + PRCC_PCKDIS);
277
278 if (clk->prcc_kernel != -1)
279 writel(1 << clk->prcc_kernel, addr + PRCC_KCKDIS);
280}
281
282static struct clkops clk_prcc_ops = {
283 .enable = clk_prcc_enable,
284 .disable = clk_prcc_disable,
285};
286
287static struct clk clk_32khz = {
288 .name = "clk_32khz",
289 .rate = 32000,
290};
291
292/*
293 * PRCMU level clock gating
294 */
295
296/* Bank 0 */
297static DEFINE_PRCMU_CLK(svaclk, 0x0, 2, SVAMMDSPCLK);
298static DEFINE_PRCMU_CLK(siaclk, 0x0, 3, SIAMMDSPCLK);
299static DEFINE_PRCMU_CLK(sgaclk, 0x0, 4, SGACLK);
300static DEFINE_PRCMU_CLK_RATE(uartclk, 0x0, 5, UARTCLK, 38400000);
301static DEFINE_PRCMU_CLK(msp02clk, 0x0, 6, MSP02CLK);
302static DEFINE_PRCMU_CLK(msp1clk, 0x0, 7, MSP1CLK); /* v1 */
303static DEFINE_PRCMU_CLK_RATE(i2cclk, 0x0, 8, I2CCLK, 48000000);
304static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 100000000);
305static DEFINE_PRCMU_CLK(slimclk, 0x0, 10, SLIMCLK);
306static DEFINE_PRCMU_CLK(per1clk, 0x0, 11, PER1CLK);
307static DEFINE_PRCMU_CLK(per2clk, 0x0, 12, PER2CLK);
308static DEFINE_PRCMU_CLK(per3clk, 0x0, 13, PER3CLK);
309static DEFINE_PRCMU_CLK(per5clk, 0x0, 14, PER5CLK);
310static DEFINE_PRCMU_CLK_RATE(per6clk, 0x0, 15, PER6CLK, 133330000);
311static DEFINE_PRCMU_CLK(lcdclk, 0x0, 17, LCDCLK);
312static DEFINE_PRCMU_CLK(bmlclk, 0x0, 18, BMLCLK);
313static DEFINE_PRCMU_CLK(hsitxclk, 0x0, 19, HSITXCLK);
314static DEFINE_PRCMU_CLK(hsirxclk, 0x0, 20, HSIRXCLK);
315static DEFINE_PRCMU_CLK(hdmiclk, 0x0, 21, HDMICLK);
316static DEFINE_PRCMU_CLK(apeatclk, 0x0, 22, APEATCLK);
317static DEFINE_PRCMU_CLK(apetraceclk, 0x0, 23, APETRACECLK);
318static DEFINE_PRCMU_CLK(mcdeclk, 0x0, 24, MCDECLK);
319static DEFINE_PRCMU_CLK(ipi2clk, 0x0, 25, IPI2CCLK);
320static DEFINE_PRCMU_CLK(dsialtclk, 0x0, 26, DSIALTCLK); /* v1 */
321static DEFINE_PRCMU_CLK(dmaclk, 0x0, 27, DMACLK);
322static DEFINE_PRCMU_CLK(b2r2clk, 0x0, 28, B2R2CLK);
323static DEFINE_PRCMU_CLK(tvclk, 0x0, 29, TVCLK);
324static DEFINE_PRCMU_CLK(uniproclk, 0x0, 30, UNIPROCLK); /* v1 */
325static DEFINE_PRCMU_CLK_RATE(sspclk, 0x0, 31, SSPCLK, 48000000); /* v1 */
326
327/* Bank 1 */
328static DEFINE_PRCMU_CLK(rngclk, 0x4, 0, RNGCLK); /* v1 */
329static DEFINE_PRCMU_CLK(uiccclk, 0x4, 1, UICCCLK); /* v1 */
330
331/*
332 * PRCC level clock gating
333 * Format: per#, clk, PCKEN bit, KCKEN bit, parent
334 */
335
336/* Peripheral Cluster #1 */
337static DEFINE_PRCC_CLK(1, msp3, 11, 10, &clk_msp1clk);
338static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk);
339static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL);
340static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk);
341static DEFINE_PRCC_CLK(1, spi3, 7, -1, NULL);
342static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk);
343static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk);
344static DEFINE_PRCC_CLK(1, msp1, 4, 4, &clk_msp1clk);
345static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk);
346static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk);
347static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk);
348static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk);
349
350/* Peripheral Cluster #2 */
351static DEFINE_PRCC_CLK(2, gpio1, 11, -1, NULL);
352static DEFINE_PRCC_CLK(2, ssitx, 10, 7, NULL);
353static DEFINE_PRCC_CLK(2, ssirx, 9, 6, NULL);
354static DEFINE_PRCC_CLK(2, spi0, 8, -1, NULL);
355static DEFINE_PRCC_CLK(2, sdi3, 7, 5, &clk_sdmmcclk);
356static DEFINE_PRCC_CLK(2, sdi1, 6, 4, &clk_sdmmcclk);
357static DEFINE_PRCC_CLK(2, msp2, 5, 3, &clk_msp02clk);
358static DEFINE_PRCC_CLK(2, sdi4, 4, 2, &clk_sdmmcclk);
359static DEFINE_PRCC_CLK(2, pwl, 3, 1, NULL);
360static DEFINE_PRCC_CLK(2, spi1, 2, -1, NULL);
361static DEFINE_PRCC_CLK(2, spi2, 1, -1, NULL);
362static DEFINE_PRCC_CLK(2, i2c3, 0, 0, &clk_i2cclk);
363
364/* Peripheral Cluster #3 */
365static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL);
366static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk);
367static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk);
368static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz);
369static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk);
370static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk);
371static DEFINE_PRCC_CLK(3, ssp1, 2, 2, &clk_sspclk);
372static DEFINE_PRCC_CLK(3, ssp0, 1, 1, &clk_sspclk);
373static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL);
374
375/* Peripheral Cluster #4 is in the always on domain */
376
377/* Peripheral Cluster #5 */
378static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL);
379static DEFINE_PRCC_CLK(5, usb, 0, 0, NULL);
380
381/* Peripheral Cluster #6 */
382
383/* MTU ID in data */
384static DEFINE_PRCC_CLK_CUSTOM(6, mtu1, 9, -1, NULL, clk_mtu_get_rate, 1);
385static DEFINE_PRCC_CLK_CUSTOM(6, mtu0, 8, -1, NULL, clk_mtu_get_rate, 0);
386static DEFINE_PRCC_CLK(6, cfgreg, 7, 7, NULL);
387static DEFINE_PRCC_CLK(6, hash1, 6, -1, NULL);
388static DEFINE_PRCC_CLK(6, unipro, 5, 1, &clk_uniproclk);
389static DEFINE_PRCC_CLK(6, pka, 4, -1, NULL);
390static DEFINE_PRCC_CLK(6, hash0, 3, -1, NULL);
391static DEFINE_PRCC_CLK(6, cryp0, 2, -1, NULL);
392static DEFINE_PRCC_CLK(6, cryp1, 1, -1, NULL);
393static DEFINE_PRCC_CLK(6, rng, 0, 0, &clk_rngclk);
394
395static struct clk clk_dummy_apb_pclk = {
396 .name = "apb_pclk",
397};
398
399static struct clk_lookup u8500_clks[] = {
400 CLK(dummy_apb_pclk, NULL, "apb_pclk"),
401
402 /* Peripheral Cluster #1 */
403 CLK(gpio0, "gpio.0", NULL),
404 CLK(gpio0, "gpio.1", NULL),
405 CLK(slimbus0, "slimbus0", NULL),
406 CLK(i2c2, "nmk-i2c.2", NULL),
407 CLK(sdi0, "sdi0", NULL),
408 CLK(msp0, "ux500-msp-i2s.0", NULL),
409 CLK(i2c1, "nmk-i2c.1", NULL),
410 CLK(uart1, "uart1", NULL),
411 CLK(uart0, "uart0", NULL),
412
413 /* Peripheral Cluster #3 */
414 CLK(gpio2, "gpio.2", NULL),
415 CLK(gpio2, "gpio.3", NULL),
416 CLK(gpio2, "gpio.4", NULL),
417 CLK(gpio2, "gpio.5", NULL),
418 CLK(sdi5, "sdi5", NULL),
419 CLK(uart2, "uart2", NULL),
420 CLK(ske, "ske", NULL),
421 CLK(ske, "nmk-ske-keypad", NULL),
422 CLK(sdi2, "sdi2", NULL),
423 CLK(i2c0, "nmk-i2c.0", NULL),
424 CLK(fsmc, "fsmc", NULL),
425
426 /* Peripheral Cluster #5 */
427 CLK(gpio3, "gpio.8", NULL),
428
429 /* Peripheral Cluster #6 */
430 CLK(hash1, "hash1", NULL),
431 CLK(pka, "pka", NULL),
432 CLK(hash0, "hash0", NULL),
433 CLK(cryp0, "cryp0", NULL),
434 CLK(cryp1, "cryp1", NULL),
435
436 /* PRCMU level clock gating */
437
438 /* Bank 0 */
439 CLK(svaclk, "sva", NULL),
440 CLK(siaclk, "sia", NULL),
441 CLK(sgaclk, "sga", NULL),
442 CLK(slimclk, "slim", NULL),
443 CLK(lcdclk, "lcd", NULL),
444 CLK(bmlclk, "bml", NULL),
445 CLK(hsitxclk, "stm-hsi.0", NULL),
446 CLK(hsirxclk, "stm-hsi.1", NULL),
447 CLK(hdmiclk, "hdmi", NULL),
448 CLK(apeatclk, "apeat", NULL),
449 CLK(apetraceclk, "apetrace", NULL),
450 CLK(mcdeclk, "mcde", NULL),
451 CLK(ipi2clk, "ipi2", NULL),
452 CLK(dmaclk, "dma40.0", NULL),
453 CLK(b2r2clk, "b2r2", NULL),
454 CLK(tvclk, "tv", NULL),
455
456 /* Peripheral Cluster #1 */
457 CLK(i2c4, "nmk-i2c.4", NULL),
458 CLK(spi3, "spi3", NULL),
459 CLK(msp1, "ux500-msp-i2s.1", NULL),
460 CLK(msp3, "ux500-msp-i2s.3", NULL),
461
462 /* Peripheral Cluster #2 */
463 CLK(gpio1, "gpio.6", NULL),
464 CLK(gpio1, "gpio.7", NULL),
465 CLK(ssitx, "ssitx", NULL),
466 CLK(ssirx, "ssirx", NULL),
467 CLK(spi0, "spi0", NULL),
468 CLK(sdi3, "sdi3", NULL),
469 CLK(sdi1, "sdi1", NULL),
470 CLK(msp2, "ux500-msp-i2s.2", NULL),
471 CLK(sdi4, "sdi4", NULL),
472 CLK(pwl, "pwl", NULL),
473 CLK(spi1, "spi1", NULL),
474 CLK(spi2, "spi2", NULL),
475 CLK(i2c3, "nmk-i2c.3", NULL),
476
477 /* Peripheral Cluster #3 */
478 CLK(ssp1, "ssp1", NULL),
479 CLK(ssp0, "ssp0", NULL),
480
481 /* Peripheral Cluster #5 */
482 CLK(usb, "musb-ux500.0", "usb"),
483
484 /* Peripheral Cluster #6 */
485 CLK(mtu1, "mtu1", NULL),
486 CLK(mtu0, "mtu0", NULL),
487 CLK(cfgreg, "cfgreg", NULL),
488 CLK(hash1, "hash1", NULL),
489 CLK(unipro, "unipro", NULL),
490 CLK(rng, "rng", NULL),
491
492 /* PRCMU level clock gating */
493
494 /* Bank 0 */
495 CLK(uniproclk, "uniproclk", NULL),
496 CLK(dsialtclk, "dsialt", NULL),
497
498 /* Bank 1 */
499 CLK(rngclk, "rng", NULL),
500 CLK(uiccclk, "uicc", NULL),
501};
502
503#ifdef CONFIG_DEBUG_FS
504/*
505 * debugfs support to trace clock tree hierarchy and attributes with
506 * powerdebug
507 */
508static struct dentry *clk_debugfs_root;
509
510void __init clk_debugfs_add_table(struct clk_lookup *cl, size_t num)
511{
512 while (num--) {
513 /* Check that the clock has not been already registered */
514 if (!(cl->clk->list.prev != cl->clk->list.next))
515 list_add_tail(&cl->clk->list, &clk_list);
516
517 cl++;
518 }
519}
520
521static ssize_t usecount_dbg_read(struct file *file, char __user *buf,
522 size_t size, loff_t *off)
523{
524 struct clk *clk = file->f_dentry->d_inode->i_private;
525 char cusecount[128];
526 unsigned int len;
527
528 len = sprintf(cusecount, "%u\n", clk->enabled);
529 return simple_read_from_buffer(buf, size, off, cusecount, len);
530}
531
532static ssize_t rate_dbg_read(struct file *file, char __user *buf,
533 size_t size, loff_t *off)
534{
535 struct clk *clk = file->f_dentry->d_inode->i_private;
536 char crate[128];
537 unsigned int rate;
538 unsigned int len;
539
540 rate = clk_get_rate(clk);
541 len = sprintf(crate, "%u\n", rate);
542 return simple_read_from_buffer(buf, size, off, crate, len);
543}
544
545static const struct file_operations usecount_fops = {
546 .read = usecount_dbg_read,
547};
548
549static const struct file_operations set_rate_fops = {
550 .read = rate_dbg_read,
551};
552
553static struct dentry *clk_debugfs_register_dir(struct clk *c,
554 struct dentry *p_dentry)
555{
556 struct dentry *d, *clk_d;
557 const char *p = c->name;
558
559 if (!p)
560 p = "BUG";
561
562 clk_d = debugfs_create_dir(p, p_dentry);
563 if (!clk_d)
564 return NULL;
565
566 d = debugfs_create_file("usecount", S_IRUGO,
567 clk_d, c, &usecount_fops);
568 if (!d)
569 goto err_out;
570 d = debugfs_create_file("rate", S_IRUGO,
571 clk_d, c, &set_rate_fops);
572 if (!d)
573 goto err_out;
574 /*
575 * TODO : not currently available in ux500
576 * d = debugfs_create_x32("flags", S_IRUGO, clk_d, (u32 *)&c->flags);
577 * if (!d)
578 * goto err_out;
579 */
580
581 return clk_d;
582
583err_out:
584 debugfs_remove_recursive(clk_d);
585 return NULL;
586}
587
588static int clk_debugfs_register_one(struct clk *c)
589{
590 struct clk *pa = c->parent_periph;
591 struct clk *bpa = c->parent_cluster;
592
593 if (!(bpa && !pa)) {
594 c->dent = clk_debugfs_register_dir(c,
595 pa ? pa->dent : clk_debugfs_root);
596 if (!c->dent)
597 return -ENOMEM;
598 }
599
600 if (bpa) {
601 c->dent_bus = clk_debugfs_register_dir(c,
602 bpa->dent_bus ? bpa->dent_bus : bpa->dent);
603 if ((!c->dent_bus) && (c->dent)) {
604 debugfs_remove_recursive(c->dent);
605 c->dent = NULL;
606 return -ENOMEM;
607 }
608 }
609 return 0;
610}
611
612static int clk_debugfs_register(struct clk *c)
613{
614 int err;
615 struct clk *pa = c->parent_periph;
616 struct clk *bpa = c->parent_cluster;
617
618 if (pa && (!pa->dent && !pa->dent_bus)) {
619 err = clk_debugfs_register(pa);
620 if (err)
621 return err;
622 }
623
624 if (bpa && (!bpa->dent && !bpa->dent_bus)) {
625 err = clk_debugfs_register(bpa);
626 if (err)
627 return err;
628 }
629
630 if ((!c->dent) && (!c->dent_bus)) {
631 err = clk_debugfs_register_one(c);
632 if (err)
633 return err;
634 }
635 return 0;
636}
637
638int __init clk_debugfs_init(void)
639{
640 struct clk *c;
641 struct dentry *d;
642 int err;
643
644 d = debugfs_create_dir("clock", NULL);
645 if (!d)
646 return -ENOMEM;
647 clk_debugfs_root = d;
648
649 list_for_each_entry(c, &clk_list, list) {
650 err = clk_debugfs_register(c);
651 if (err)
652 goto err_out;
653 }
654 return 0;
655err_out:
656 debugfs_remove_recursive(clk_debugfs_root);
657 return err;
658}
659
660#endif /* defined(CONFIG_DEBUG_FS) */
661
662unsigned long clk_smp_twd_rate = 500000000;
663
664unsigned long clk_smp_twd_get_rate(struct clk *clk)
665{
666 return clk_smp_twd_rate;
667}
668
669static struct clk clk_smp_twd = {
670 .get_rate = clk_smp_twd_get_rate,
671 .name = "smp_twd",
672};
673
674static struct clk_lookup clk_smp_twd_lookup = {
675 .dev_id = "smp_twd",
676 .clk = &clk_smp_twd,
677};
678
679#ifdef CONFIG_CPU_FREQ
680
681static int clk_twd_cpufreq_transition(struct notifier_block *nb,
682 unsigned long state, void *data)
683{
684 struct cpufreq_freqs *f = data;
685
686 if (state == CPUFREQ_PRECHANGE) {
687 /* Save frequency in simple Hz */
688 clk_smp_twd_rate = (f->new * 1000) / 2;
689 }
690
691 return NOTIFY_OK;
692}
693
694static struct notifier_block clk_twd_cpufreq_nb = {
695 .notifier_call = clk_twd_cpufreq_transition,
696};
697
698int clk_init_smp_twd_cpufreq(void)
699{
700 return cpufreq_register_notifier(&clk_twd_cpufreq_nb,
701 CPUFREQ_TRANSITION_NOTIFIER);
702}
703
704#endif
705
706int __init clk_init(void)
707{
708 clkdev_add_table(u8500_clks, ARRAY_SIZE(u8500_clks));
709 clkdev_add(&clk_smp_twd_lookup);
710
711#ifdef CONFIG_DEBUG_FS
712 clk_debugfs_add_table(u8500_clks, ARRAY_SIZE(u8500_clks));
713#endif
714 return 0;
715}
diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h
deleted file mode 100644
index 65d27a13f46d..000000000000
--- a/arch/arm/mach-ux500/clock.h
+++ /dev/null
@@ -1,164 +0,0 @@
1/*
2 * Copyright (C) 2010 ST-Ericsson
3 * Copyright (C) 2009 STMicroelectronics
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10/**
11 * struct clkops - ux500 clock operations
12 * @enable: function to enable the clock
13 * @disable: function to disable the clock
14 * @get_rate: function to get the current clock rate
15 *
16 * This structure contains function pointers to functions that will be used to
17 * control the clock. All of these functions are optional. If get_rate is
18 * NULL, the rate in the struct clk will be used.
19 */
20struct clkops {
21 void (*enable) (struct clk *);
22 void (*disable) (struct clk *);
23 unsigned long (*get_rate) (struct clk *);
24 int (*set_parent)(struct clk *, struct clk *);
25};
26
27/**
28 * struct clk - ux500 clock structure
29 * @ops: pointer to clkops struct used to control this clock
30 * @name: name, for debugging
31 * @enabled: refcount. positive if enabled, zero if disabled
32 * @get_rate: custom callback for getting the clock rate
33 * @data: custom per-clock data for example for the get_rate
34 * callback
35 * @rate: fixed rate for clocks which don't implement
36 * ops->getrate
37 * @prcmu_cg_off: address offset of the combined enable/disable register
38 * (used on u8500v1)
39 * @prcmu_cg_bit: bit in the combined enable/disable register (used on
40 * u8500v1)
41 * @prcmu_cg_mgt: address of the enable/disable register (used on
42 * u8500ed)
43 * @cluster: peripheral cluster number
44 * @prcc_bus: bit for the bus clock in the peripheral's CLKRST
45 * @prcc_kernel: bit for the kernel clock in the peripheral's CLKRST.
46 * -1 if no kernel clock exists.
47 * @parent_cluster: pointer to parent's cluster clk struct
48 * @parent_periph: pointer to parent's peripheral clk struct
49 *
50 * Peripherals are organised into clusters, and each cluster has an associated
51 * bus clock. Some peripherals also have a parent peripheral clock.
52 *
53 * In order to enable a clock for a peripheral, we need to enable:
54 * (1) the parent cluster (bus) clock at the PRCMU level
55 * (2) the parent peripheral clock (if any) at the PRCMU level
56 * (3) the peripheral's bus & kernel clock at the PRCC level
57 *
58 * (1) and (2) are handled by defining clk structs (DEFINE_PRCMU_CLK) for each
59 * of the cluster and peripheral clocks, and hooking these as the parents of
60 * the individual peripheral clocks.
61 *
62 * (3) is handled by specifying the bits in the PRCC control registers required
63 * to enable these clocks and modifying them in the ->enable and
64 * ->disable callbacks of the peripheral clocks (DEFINE_PRCC_CLK).
65 *
66 * This structure describes both the PRCMU-level clocks and PRCC-level clocks.
67 * The prcmu_* fields are only used for the PRCMU clocks, and the cluster,
68 * prcc, and parent pointers are only used for the PRCC-level clocks.
69 */
70struct clk {
71 const struct clkops *ops;
72 const char *name;
73 unsigned int enabled;
74 unsigned long (*get_rate)(struct clk *);
75 void *data;
76
77 unsigned long rate;
78 struct list_head list;
79
80 /* These three are only for PRCMU clks */
81
82 unsigned int prcmu_cg_off;
83 unsigned int prcmu_cg_bit;
84 unsigned int prcmu_cg_mgt;
85
86 /* The rest are only for PRCC clks */
87
88 int cluster;
89 unsigned int prcc_bus;
90 unsigned int prcc_kernel;
91
92 struct clk *parent_cluster;
93 struct clk *parent_periph;
94#if defined(CONFIG_DEBUG_FS)
95 struct dentry *dent; /* For visible tree hierarchy */
96 struct dentry *dent_bus; /* For visible tree hierarchy */
97#endif
98};
99
100#define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg) \
101struct clk clk_##_name = { \
102 .name = #_name, \
103 .ops = &clk_prcmu_ops, \
104 .prcmu_cg_off = _cg_off, \
105 .prcmu_cg_bit = _cg_bit, \
106 .prcmu_cg_mgt = PRCM_##_reg##_MGT \
107 }
108
109#define DEFINE_PRCMU_CLK_RATE(_name, _cg_off, _cg_bit, _reg, _rate) \
110struct clk clk_##_name = { \
111 .name = #_name, \
112 .ops = &clk_prcmu_ops, \
113 .prcmu_cg_off = _cg_off, \
114 .prcmu_cg_bit = _cg_bit, \
115 .rate = _rate, \
116 .prcmu_cg_mgt = PRCM_##_reg##_MGT \
117 }
118
119#define DEFINE_PRCC_CLK(_pclust, _name, _bus_en, _kernel_en, _kernclk) \
120struct clk clk_##_name = { \
121 .name = #_name, \
122 .ops = &clk_prcc_ops, \
123 .cluster = _pclust, \
124 .prcc_bus = _bus_en, \
125 .prcc_kernel = _kernel_en, \
126 .parent_cluster = &clk_per##_pclust##clk, \
127 .parent_periph = _kernclk \
128 }
129
130#define DEFINE_PRCC_CLK_CUSTOM(_pclust, _name, _bus_en, _kernel_en, _kernclk, _callback, _data) \
131struct clk clk_##_name = { \
132 .name = #_name, \
133 .ops = &clk_prcc_ops, \
134 .cluster = _pclust, \
135 .prcc_bus = _bus_en, \
136 .prcc_kernel = _kernel_en, \
137 .parent_cluster = &clk_per##_pclust##clk, \
138 .parent_periph = _kernclk, \
139 .get_rate = _callback, \
140 .data = (void *) _data \
141 }
142
143
144#define CLK(_clk, _devname, _conname) \
145 { \
146 .clk = &clk_##_clk, \
147 .dev_id = _devname, \
148 .con_id = _conname, \
149 }
150
151int __init clk_db8500_ed_fixup(void);
152int __init clk_init(void);
153
154#ifdef CONFIG_DEBUG_FS
155int clk_debugfs_init(void);
156#else
157static inline int clk_debugfs_init(void) { return 0; }
158#endif
159
160#ifdef CONFIG_CPU_FREQ
161int clk_init_smp_twd_cpufreq(void);
162#else
163static inline int clk_init_smp_twd_cpufreq(void) { return 0; }
164#endif
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index e2360e7c770d..17a78ec516ff 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -8,7 +8,6 @@
8 8
9#include <linux/platform_device.h> 9#include <linux/platform_device.h>
10#include <linux/io.h> 10#include <linux/io.h>
11#include <linux/clk.h>
12#include <linux/mfd/db8500-prcmu.h> 11#include <linux/mfd/db8500-prcmu.h>
13#include <linux/clksrc-dbx500-prcmu.h> 12#include <linux/clksrc-dbx500-prcmu.h>
14#include <linux/sys_soc.h> 13#include <linux/sys_soc.h>
@@ -17,6 +16,7 @@
17#include <linux/stat.h> 16#include <linux/stat.h>
18#include <linux/of.h> 17#include <linux/of.h>
19#include <linux/of_irq.h> 18#include <linux/of_irq.h>
19#include <linux/platform_data/clk-ux500.h>
20 20
21#include <asm/hardware/gic.h> 21#include <asm/hardware/gic.h>
22#include <asm/mach/map.h> 22#include <asm/mach/map.h>
@@ -25,8 +25,6 @@
25#include <mach/setup.h> 25#include <mach/setup.h>
26#include <mach/devices.h> 26#include <mach/devices.h>
27 27
28#include "clock.h"
29
30void __iomem *_PRCMU_BASE; 28void __iomem *_PRCMU_BASE;
31 29
32/* 30/*
@@ -70,13 +68,17 @@ void __init ux500_init_irq(void)
70 */ 68 */
71 if (cpu_is_u8500_family()) 69 if (cpu_is_u8500_family())
72 db8500_prcmu_early_init(); 70 db8500_prcmu_early_init();
73 clk_init(); 71
72 if (cpu_is_u8500_family())
73 u8500_clk_init();
74 else if (cpu_is_u9540())
75 u9540_clk_init();
76 else if (cpu_is_u8540())
77 u8540_clk_init();
74} 78}
75 79
76void __init ux500_init_late(void) 80void __init ux500_init_late(void)
77{ 81{
78 clk_debugfs_init();
79 clk_init_smp_twd_cpufreq();
80} 82}
81 83
82static const char * __init ux500_get_machine(void) 84static const char * __init ux500_get_machine(void)